41bd7c7f7f83e459c527546e81fe368a01bbdf8b
[cacao.git] / src / vm / jit / m68k / codegen.c
1 /* src/vm/jit/m68k/codegen.c
2
3    Copyright (C) 1996-2005, 2006, 2007, 2008
4    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5
6    This file is part of CACAO.
7
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2, or (at
11    your option) any later version.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23 */
24
25
26 #include "config.h"
27
28 #include <assert.h>
29 #include <stdint.h>
30
31 #include "md-abi.h"
32
33 #include "vm/types.h"
34 #include "vm/jit/m68k/codegen.h"
35 #include "vm/jit/m68k/emit.h"
36
37 #include "mm/memory.h"
38 #include "native/jni.h"
39 #include "native/localref.h"
40 #include "native/native.h"
41
42 #include "threads/lock-common.h"
43
44 #include "vm/builtin.h"
45 #include "vm/exceptions.h"
46 #include "vm/global.h"
47 #include "vm/stringlocal.h"
48 #include "vm/vm.h"
49
50 #include "vm/jit/asmpart.h"
51 #include "vm/jit/codegen-common.h"
52 #include "vm/jit/patcher-common.h"
53 #include "vm/jit/dseg.h"
54 #include "vm/jit/linenumbertable.h"
55 #include "vm/jit/emit-common.h"
56 #include "vm/jit/jit.h"
57 #include "vm/jit/abi.h"
58 #include "vm/jit/parse.h"
59 #include "vm/jit/reg.h"
60 #include "vm/jit/replace.h"
61 #include "vm/jit/stacktrace.h"
62 #include "vm/jit/trap.h"
63
64 #include "vmcore/loader.h"
65 #include "vmcore/options.h"
66 #include "vmcore/utf8.h"
67
68
69 bool codegen_emit(jitdata *jd) 
70 {       
71         methodinfo         *m;
72         codeinfo           *code;
73         codegendata        *cd;
74         registerdata       *rd;
75         s4                  len, s1, s2, s3, d, disp;
76         varinfo            *var;
77         basicblock         *bptr;
78         instruction        *iptr;
79         u2                  currentline;
80         methodinfo         *lm;             /* local methodinfo for ICMD_INVOKE*  */
81         unresolved_method  *um;
82         builtintable_entry *bte;
83         methoddesc         *md;
84         s4                  fieldtype;
85         s4                  varindex;
86         unresolved_field   *uf;
87         fieldinfo          *fi;
88
89         /* get required compiler data */
90
91         m    = jd->m;
92         code = jd->code;
93         cd   = jd->cd;
94         rd   = jd->rd;
95
96         /* prevent compiler warnings */
97
98         d = 0;
99         lm = NULL;
100         bte = NULL;
101
102         {
103                 s4 i, p, t, l;
104                 /* save calle saved registers */
105                 s4 savedregs_num = 0;
106
107                 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
108                 savedregs_num += (ADR_SAV_CNT - rd->savadrreguse);
109                 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
110
111                 cd->stackframesize = rd->memuse + savedregs_num;
112         
113                 /* we always add 2 stack slots.
114                  * 1 word the lock word, which may be unused and resides @ rd->memuse * 8
115                  * + 2 words to either save the return value for LOCK_monitor_exit @ rd->memuse * 8 + 8
116                  * on the other hand we could use 2 words when a builtin returns a doulbe which are
117                  * returned in %d0, %d1 and need to be stored onto the stack and read in used a fmovemd
118                  * so we always _need_ at least 2 slots, and this keeps the code simple */
119                 cd->stackframesize += 2;        
120
121                 cd->stackframesize *= 8;        /* we use 8 byte stack slots */
122
123 #if 0
124 #if defined(ENABLE_THREADS)
125                 /* we need additional space to save argument of monitor_enter */
126                 if (checksync && code_is_synchronized(code))    {
127                         if (IS_2_WORD_TYPE(m->parseddesc->returntype.type))     {
128                                 cd->stackframesize += 2;
129                         } else  {
130                                 cd->stackframesize += 1;
131                         }
132                 }
133 #endif
134 #endif  
135         
136                 /* create method header */
137                 (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
138                 (void) dseg_add_unique_s4(cd, cd->stackframesize);         /* FrameSize       */
139
140                 code->synchronizedoffset = rd->memuse * 8;
141
142                 /* REMOVEME: We still need it for exception handling in assembler. */
143
144                 if (code_is_leafmethod(code))
145                         (void) dseg_add_unique_s4(cd, 1);
146                 else
147                         (void) dseg_add_unique_s4(cd, 0);
148
149                 /* XXX we use the IntSave a split field for the adr now */
150                 (void) dseg_add_unique_s4(cd, (ADR_SAV_CNT - rd->savadrreguse) << 16 | (INT_SAV_CNT - rd->savintreguse)); /* IntSave */
151                 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
152
153 #if defined(ENABLE_PROFILING)
154                 assert(0);
155 #endif
156
157 #if !defined(NDEBUG)
158                 emit_verbosecall_enter(jd);
159 #endif
160                 /* create stack frame */
161                 M_AADD_IMM(-(cd->stackframesize), REG_SP);
162
163                 /* save used callee saved registers */
164                 p = cd->stackframesize;
165                 for (i=INT_SAV_CNT-1; i>=rd->savintreguse; --i) {
166                         p-=8; M_IST(rd->savintregs[i], REG_SP, p);
167                 }
168                 for (i=ADR_SAV_CNT-1; i>=rd->savadrreguse; --i) {
169                         p-=8; M_AST(rd->savadrregs[i], REG_SP, p);
170                 }
171 #if !defined(ENABLE_SOFTFLOAT)
172                 for (i=FLT_SAV_CNT-1; i>=rd->savfltreguse; --i) {
173                         p-=8; M_FSTORE(rd->savfltregs[i], REG_SP, p);
174                 }       
175 #else
176                 assert(FLT_SAV_CNT == 0);
177                 assert(rd->savfltreguse == 0);
178 #endif
179                 /* take arguments out of stack frame */
180                 md = m->parseddesc;
181                 for (p = 0, l = 0; p < md->paramcount; p++) {
182                         t = md->paramtypes[p].type;
183                         varindex = jd->local_map[l * 5 + t];
184         
185                         l++;
186                         if (IS_2_WORD_TYPE(t))    /* increment local counter for 2 word types */
187                                 l++;
188
189                         if (varindex == UNUSED)
190                                 continue;
191
192                         var = VAR(varindex);
193         
194                         s1 = md->params[p].regoff;
195                         assert(md->params[p].inmemory);                 /* all args are on stack */
196
197                         switch (t)      {
198 #if defined(ENABLE_SOFTFLOAT)
199                         case TYPE_FLT:
200                         case TYPE_DBL:
201 #endif
202                         case TYPE_LNG:
203                         case TYPE_INT:
204                                 if (!IS_INMEMORY(var->flags)) {      /* stack arg -> register */
205                                         if (IS_2_WORD_TYPE(t))  {
206                                                 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
207                                         } else {
208                                                 M_ILD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
209                                         }
210                                 } else {                             /* stack arg -> spilled  */
211                                         M_ILD(REG_ITMP1, REG_SP, cd->stackframesize + s1 + 4);
212                                         M_IST(REG_ITMP1, REG_SP, var->vv.regoff);
213                                         if (IS_2_WORD_TYPE(t)) {
214                                                 M_ILD(REG_ITMP1, REG_SP, cd->stackframesize  + s1 + 4 + 4);
215                                                 M_IST(REG_ITMP1, REG_SP, var->vv.regoff + 4);
216                                         }
217                                 } 
218                                 break;
219 #if !defined(ENABLE_SOFTFLOAT)
220                         case TYPE_FLT:
221                         case TYPE_DBL:
222                                 if (!IS_INMEMORY(var->flags)) {      /* stack-arg -> register */
223                                         if (IS_2_WORD_TYPE(t))  {
224                                                 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
225                                         } else {
226                                                 M_FLD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
227                                         }
228                                 } else {                             /* stack-arg -> spilled  */
229                                         if (IS_2_WORD_TYPE(t)) {
230                                                 M_DLD(REG_FTMP1, REG_SP, cd->stackframesize + s1 + 4);
231                                                 M_DST(REG_FTMP1, REG_SP, var->vv.regoff);
232                                         } else {
233                                                 M_FLD(REG_FTMP1, REG_SP, cd->stackframesize + s1 + 4);
234                                                 M_FST(REG_FTMP1, REG_SP, var->vv.regoff);
235                                         }
236                                 }
237                                 break;
238 #endif /* SOFTFLOAT */
239                         case TYPE_ADR:
240                                 if (!IS_INMEMORY(var->flags)) {      /* stack-arg -> register */
241                                         M_ALD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
242                                 } else {                             /* stack-arg -> spilled  */
243                                         M_ALD(REG_ATMP1, REG_SP, cd->stackframesize + s1 + 4);
244                                         M_AST(REG_ATMP1, REG_SP, var->vv.regoff);
245                                 }
246                                 break;
247                         default: assert(0);
248                         }
249                 } /* end for argument out of stack*/
250
251 #if defined(ENABLE_THREADS)
252         /* call lock_monitor_enter function */
253         if (checksync && code_is_synchronized(code))    {
254                 if (m->flags & ACC_STATIC)      {
255                         M_AMOV_IMM((&m->clazz->object.header), REG_ATMP1);
256                 } else  {
257                         /* for non-static case the first arg is the object */
258                         M_ALD(REG_ATMP1, REG_SP, cd->stackframesize + 4);
259                         M_ATST(REG_ATMP1);
260                         M_BNE(2);
261                         M_TRAP(TRAP_NullPointerException);
262                 }
263
264                 M_AST(REG_ATMP1, REG_SP, rd->memuse * 8);
265                 M_AST(REG_ATMP1, REG_SP, 0 * 4);
266                 M_JSR_IMM(LOCK_monitor_enter);
267         }
268 #endif
269
270         }
271
272         /* create replacement points */
273         REPLACEMENT_POINTS_INIT(cd, jd);
274
275         /* foreach basic block */
276         for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
277         
278         bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
279
280         if (bptr->flags >= BBREACHED)   {
281         
282         /* branch resolving */
283         codegen_resolve_branchrefs(cd, bptr);
284
285         /* handle replacement points */
286         REPLACEMENT_POINT_BLOCK_START(cd, bptr);
287
288 #if defined(ENABLE_PROFILING)
289         assert(0);
290 #endif
291         /* FIXME there are still some constrcuts to copy in here */
292
293 #if defined(ENABLE_LSRA)
294         assert(0);
295 #endif
296
297         /* copy interface registers to their destination */
298         len = bptr->indepth;
299         MCODECHECK(64+len);
300
301         while (len > 0) {
302                 len--;
303                 var = VAR(bptr->invars[len]);
304                 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
305                         d = codegen_reg_of_var(0, var, REG_ATMP1_XPTR);
306                         M_ADRMOVE(REG_ATMP1_XPTR, d);
307                         emit_store(jd, NULL, var, d);
308                 }
309                 else {
310                         assert((var->flags & INOUT));
311                 }
312         }
313
314         /* walk through all instructions */
315         len = bptr->icount;
316         currentline = 0;
317
318         for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
319                 if (iptr->line != currentline) {
320                         linenumbertable_list_entry_add(cd, iptr->line);
321                         currentline = iptr->line;
322                 }
323
324                 MCODECHECK(1024);                         /* 1kB should be enough */
325
326                 switch (iptr->opc) {
327                 case ICMD_NOP:        /* ...  ==> ...                                 */
328                 case ICMD_POP:        /* ..., value  ==> ...                          */
329                 case ICMD_POP2:       /* ..., value, value  ==> ...                   */
330                         break;
331
332                 case ICMD_INLINE_START:
333
334                         REPLACEMENT_POINT_INLINE_START(cd, iptr);
335                         break;
336
337                 case ICMD_INLINE_BODY:
338
339                         REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
340                         linenumbertable_list_entry_add_intern(cd, iptr);
341                         linenumbertable_list_entry_add(cd, iptr->line);
342                         break;
343
344                 case ICMD_INLINE_END:
345
346                         linenumbertable_list_entry_add_inline(cd, iptr);
347                         linenumbertable_list_entry_add(cd, iptr->line);
348                         break;
349
350                 case ICMD_CHECKNULL:  /* ..., objectref  ==> ..., objectref           */
351
352                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
353                         assert(VAROP(iptr->s1)->type == TYPE_ADR);
354                         emit_nullpointer_check(cd, iptr, s1);
355                         break;
356
357
358                 /* CONST **************************************************************/
359                 case ICMD_ICONST:     /* ...  ==> ..., constant                       */
360                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
361                         M_IMOV_IMM(iptr->sx.val.i, d);
362                         emit_store_dst(jd, iptr, d);
363                         break;
364
365                 case ICMD_LCONST:     /* ...  ==> ..., constant                       */
366
367                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
368                         LCONST(iptr->sx.val.l, d);
369                         emit_store_dst(jd, iptr, d);
370                         break;
371
372                 case ICMD_FCONST:     /* ...  ==> ..., constant                       */
373
374 #if defined(ENABLE_SOFTFLOAT)
375                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
376                         M_IMOV_IMM(iptr->sx.val.i, d);
377                         emit_store_dst(jd, iptr, d);
378 #else
379                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
380                         FCONST(iptr->sx.val.i, d);
381                         emit_store_dst(jd, iptr, d);
382 #endif
383                         break;
384
385                 case ICMD_DCONST:     /* ...  ==> ..., constant                       */
386
387 #if defined(ENABLE_SOFTFLOAT)
388                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
389                         LCONST(iptr->sx.val.l, d);
390                         emit_store_dst(jd, iptr, d);
391 #else
392                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
393                         disp = dseg_add_double(cd, iptr->sx.val.d);
394                         M_AMOV_IMM(0, REG_ATMP1);
395                         dseg_adddata(cd);
396                         M_DLD(d, REG_ATMP1, disp);
397                         emit_store_dst(jd, iptr, d);
398 #endif
399                         break;
400
401
402                 /* some long operations *********************************************/
403                 case ICMD_LADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
404                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
405                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP1);
406                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
407                         M_INTMOVE(s2, REG_ITMP1);
408                         M_IADD(s1, REG_ITMP1);                  /* low word */
409                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
410                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
411                         M_INTMOVE(s2, REG_ITMP2);
412                         M_IADDX(s1, REG_ITMP2);                 /* high word */
413                         emit_store_dst(jd, iptr, d);
414                         break;
415                         
416                 case ICMD_LADDCONST:  /* ..., value  ==> ..., value + constant        */
417                                       /* sx.val.l = constant                          */
418                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
419                         s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
420                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
421                         
422                         M_IMOV_IMM(iptr->sx.val.l >> 32, REG_ITMP3);
423
424                         s3 = iptr->sx.val.l & 0xffffffff;
425                         M_INTMOVE(s1, REG_ITMP1);
426                         M_IADD_IMM(s3, REG_ITMP1);              /* lower word in REG_ITMP1 now */
427
428                         M_IADDX(REG_ITMP3, REG_ITMP2);  /* high word in REG_ITMP2 now */
429                         M_LNGMOVE(REG_ITMP12_PACKED, d);
430                         emit_store_dst(jd, iptr, d);
431                         break;
432
433                 case ICMD_LSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
434                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
435                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
436                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
437                         M_INTMOVE(s1, REG_ITMP1);
438                         M_ISUB(s2, REG_ITMP1);                  /* low word */
439                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
440                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
441                         M_INTMOVE(s1, REG_ITMP2);
442                         M_ISUBX(s2, REG_ITMP2);                 /* high word */
443                         emit_store_dst(jd, iptr, d);
444                         break;
445
446                 case ICMD_LSUBCONST:  /* ..., value  ==> ..., value - constant        */
447                                       /* sx.val.l = constant                          */
448                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
449                         s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
450                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
451                         
452                         M_IMOV_IMM( (-iptr->sx.val.l) >> 32, REG_ITMP3);
453
454                         s3 = (-iptr->sx.val.l) & 0xffffffff;
455                         M_INTMOVE(s1, REG_ITMP1);
456                         M_IADD_IMM(s3, REG_ITMP1);              /* lower word in REG_ITMP1 now */
457
458                         M_IADDX(REG_ITMP3, REG_ITMP2);  /* high word in REG_ITMP2 now */
459                         M_LNGMOVE(REG_ITMP12_PACKED, d);
460                         emit_store_dst(jd, iptr, d);
461                         break;
462
463                 case ICMD_LNEG:       /* ..., value  ==> ..., - value                 */
464                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
465                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
466                         M_LNGMOVE(s1, REG_ITMP12_PACKED);
467                         M_INEG(GET_LOW_REG(REG_ITMP12_PACKED));
468                         M_INEGX(GET_HIGH_REG(REG_ITMP12_PACKED));
469                         M_LNGMOVE(REG_ITMP12_PACKED, d);
470                         emit_store_dst(jd, iptr, d);
471                         break;
472
473                 /* integer operations ************************************************/
474                 case ICMD_INEG:       /* ..., value  ==> ..., - value                 */
475
476                         s1 = emit_load_s1(jd, iptr, REG_ITMP1); 
477                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
478                         M_INTMOVE(s1, REG_ITMP1);
479                         M_INEG(REG_ITMP1);
480                         M_INTMOVE(REG_ITMP1, d);
481                         emit_store_dst(jd, iptr, d);
482                         break;
483
484                 case ICMD_I2L:        /* ..., value  ==> ..., value                   */
485
486                         s1 = emit_load_s1(jd, iptr, REG_ITMP3);
487                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
488                         M_IMOV(s1, GET_LOW_REG(d));                             /* sets negativ bit */
489                         M_BPL(4);
490                         M_ISET(GET_HIGH_REG(d));
491                         M_TPFW;
492                         M_ICLR(GET_HIGH_REG(d));
493
494                         emit_store_dst(jd, iptr, d);
495                         break;
496
497                 case ICMD_L2I:        /* ..., value  ==> ..., value                   */
498
499                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
500                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
501                         M_INTMOVE(s1, d);
502                         emit_store_dst(jd, iptr, d);
503                         break;
504                 case ICMD_INT2BYTE:   /* ..., value  ==> ..., value                   */
505
506                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
507                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
508                         M_BSEXT(s1, d);
509                         emit_store_dst(jd, iptr, d);
510                         break;
511
512                 case ICMD_INT2CHAR:   /* ..., value  ==> ..., value                   */
513
514                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
515                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
516                         M_CZEXT(s1, d);
517                         emit_store_dst(jd, iptr, d);
518                         break;
519
520                 case ICMD_INT2SHORT:  /* ..., value  ==> ..., value                   */
521
522                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
523                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
524                         M_SSEXT(s1, d);
525                         emit_store_dst(jd, iptr, d);
526                         break;
527
528
529
530                 case ICMD_IADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
531
532                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
533                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
534                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
535                         M_INTMOVE(s2, REG_ITMP2);
536                         M_IADD(s1, REG_ITMP2);
537                         M_INTMOVE(REG_ITMP2, d);
538                         emit_store_dst(jd, iptr, d);
539                         break;
540
541                                       /* s1.localindex = variable, sx.val.i = constant*/
542
543                 case ICMD_IINC:
544                 case ICMD_IADDCONST:
545
546                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
547                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
548                         M_INTMOVE(s1, REG_ITMP1);
549                         M_IADD_IMM(iptr->sx.val.i, REG_ITMP1);
550                         M_INTMOVE(REG_ITMP1, d);
551                         emit_store_dst(jd, iptr, d);
552                         break;
553
554                 case ICMD_ISUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
555
556                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
557                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
558                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
559                         M_INTMOVE(s1, REG_ITMP1);
560                         M_ISUB(s2, REG_ITMP1);
561                         M_INTMOVE(REG_ITMP1, d);
562                         emit_store_dst(jd, iptr, d);
563                         break;
564
565                 case ICMD_ISUBCONST:  /* ..., value  ==> ..., value + constant        */
566                                       /* sx.val.i = constant                          */
567
568                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
569                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
570                         M_INTMOVE(s1, REG_ITMP1);
571                         M_IADD_IMM(-iptr->sx.val.i, REG_ITMP1);
572                         M_INTMOVE(REG_ITMP1, d);
573                         emit_store_dst(jd, iptr, d);
574                         break;
575
576                 case ICMD_IDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
577                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
578                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
579                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
580                         emit_arithmetic_check(cd, iptr, s2);
581                         M_INTMOVE(s1, REG_ITMP1);
582                         M_IDIV(s2, REG_ITMP1);
583                         M_INTMOVE(REG_ITMP1, d);
584                         emit_store_dst(jd, iptr, d);
585                         break;
586
587                 case ICMD_IDIVPOW2:             /* ..., value  ==> ..., value << constant       */
588                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
589                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
590                         M_INTMOVE(s1, REG_ITMP1);
591
592                         M_ITST(REG_ITMP1);
593                         M_BPL(6);
594                         M_IADD_IMM((1 << iptr->sx.val.i) - 1, REG_ITMP1);
595
596                         M_IMOV_IMM(iptr->sx.val.i, REG_ITMP2);
597                         M_ISSR(REG_ITMP2, REG_ITMP1);
598                         M_INTMOVE(REG_ITMP1, d);
599                         emit_store_dst(jd, iptr, d);
600                         break;
601
602                 case ICMD_IREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
603                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
604                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
605                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
606                         emit_arithmetic_check(cd, iptr, s2);
607
608                         M_ICMP_IMM(0x80000000, s1);
609                         M_BNE(4+8);
610                         M_ICMP_IMM(-1, s2);
611                         M_BNE(4);
612                         M_ICLR(REG_ITMP3);
613                         M_TPFL;                                 /* hides the next instruction */
614                         M_IREM(s2, s1, REG_ITMP3);
615
616                         M_INTMOVE(REG_ITMP3, d);
617
618                         emit_store_dst(jd, iptr, d);
619                         break;
620
621                 case ICMD_IREMPOW2:             /* ..., value  ==> ..., value << constant       */
622                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
623                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
624                         if (s1 == d) {
625                                 M_IMOV(s1, REG_ITMP1);
626                                 s1 = REG_ITMP1;
627                         } 
628                         M_INTMOVE(s1, d);
629                         M_IAND_IMM(iptr->sx.val.i, d);
630                         M_ITST(s1);
631                         M_BGE(2 + 2 + 6 + 2);
632                         M_IMOV(s1, d);  /* don't use M_INTMOVE, so we know the jump offset */
633                         M_INEG(d);
634                         M_IAND_IMM(iptr->sx.val.i, d);     /* use 32-bit for jump offset */
635                         M_INEG(d);
636
637                         emit_store_dst(jd, iptr, d);
638                         break;
639
640
641                 case ICMD_LDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
642                 case ICMD_LREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
643
644                         bte = iptr->sx.s23.s3.bte;
645                         md  = bte->md;
646
647                         s2 = emit_load_s2(jd, iptr, REG_ITMP12_PACKED);
648                         M_INTMOVE(GET_LOW_REG(s2), REG_ITMP3);
649                         M_IOR(GET_HIGH_REG(s2), REG_ITMP3);
650                         /* XXX could be optimized */
651                         emit_arithmetic_check(cd, iptr, REG_ITMP3);
652
653                         M_LST(s2, REG_SP, 2 * 4);
654                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
655                         M_LST(s1, REG_SP, 0 * 4);
656
657                         M_JSR_IMM(bte->fp);
658
659                         d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
660                         M_LNGMOVE(REG_RESULT_PACKED, d);
661                         emit_store_dst(jd, iptr, d);
662                         break;
663
664                 case ICMD_IMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
665
666                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
667                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
668                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
669                         M_INTMOVE(s2, REG_ITMP2);
670                         M_IMUL(s1, REG_ITMP2);
671                         M_INTMOVE(REG_ITMP2, d);
672                         emit_store_dst(jd, iptr, d);
673                         break;
674
675                 case ICMD_IMULCONST:  /* ..., value  ==> ..., value * constant        */
676                                       /* sx.val.i = constant                          */
677                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
678                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
679                         M_IMOV_IMM(iptr->sx.val.i, REG_ITMP2);
680                         M_IMUL(s1, REG_ITMP2);
681                         M_INTMOVE(REG_ITMP2, d);
682                         emit_store_dst(jd, iptr, d);
683                         break;
684
685                 case ICMD_ISHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
686
687                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
688                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
689                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
690                         M_INTMOVE(s1, REG_ITMP1);
691                         M_INTMOVE(s2, REG_ITMP2);
692                         M_IAND_IMM(0x1f, REG_ITMP2);
693                         M_ISSL(REG_ITMP2, REG_ITMP1);
694                         M_INTMOVE(REG_ITMP1, d);
695                         emit_store_dst(jd, iptr, d);
696                         break;
697
698                 case ICMD_ISHLCONST:  /* ..., value  ==> ..., value << constant       */
699                                       /* sx.val.i = constant                          */
700
701                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
702                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
703                         if (iptr->sx.val.i & 0x1f)      {
704                                 M_INTMOVE(s1, REG_ITMP1)
705                                 if ((iptr->sx.val.i & 0x1f) <= 7)       {
706                                         M_ISSL_IMM(iptr->sx.val.i & 0x1f, REG_ITMP1);
707                                 } else  {
708                                         M_IMOV_IMM(iptr->sx.val.i & 0x1f, REG_ITMP2);
709                                         M_ISSL(REG_ITMP2, REG_ITMP1);
710                                 }
711                                 M_INTMOVE(REG_ITMP1, d);
712                         } else  {
713                                 M_INTMOVE(s1, d);
714                         }
715                         emit_store_dst(jd, iptr, d);
716                         break;
717
718                 case ICMD_ISHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
719
720                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
721                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
722                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
723                         M_INTMOVE(s1, REG_ITMP1);
724                         M_INTMOVE(s2, REG_ITMP2);
725                         M_IAND_IMM(0x1f, REG_ITMP2);
726                         M_ISSR(REG_ITMP2, REG_ITMP1);
727                         M_INTMOVE(REG_ITMP1, d);
728                         emit_store_dst(jd, iptr, d);
729                         break;
730
731                 case ICMD_ISHRCONST:  /* ..., value  ==> ..., value >> constant       */
732                                       /* sx.val.i = constant                          */
733
734                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
735                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
736                         if (iptr->sx.val.i & 0x1f)      {
737                                 M_INTMOVE(s1, REG_ITMP1)
738                                 if ((iptr->sx.val.i & 0x1f) <= 7)       {
739                                         M_ISSR_IMM(iptr->sx.val.i & 0x1f, REG_ITMP1);
740                                 } else  {
741                                         M_IMOV_IMM(iptr->sx.val.i & 0x1f, REG_ITMP2);
742                                         M_ISSR(REG_ITMP2, REG_ITMP1);
743                                 }
744                                 M_INTMOVE(REG_ITMP1, d);
745                         } else  {
746                                 M_INTMOVE(s1, d);
747                         }
748                         emit_store_dst(jd, iptr, d);
749                         break;
750
751                 case ICMD_IUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
752
753                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
754                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
755                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
756                         M_INTMOVE(s1, REG_ITMP1);
757                         M_INTMOVE(s2, REG_ITMP2);
758                         M_IAND_IMM(0x1f, REG_ITMP2);
759                         M_IUSR(REG_ITMP2, REG_ITMP1);
760                         M_INTMOVE(REG_ITMP1, d);
761                         emit_store_dst(jd, iptr, d);
762                         break;
763
764                 case ICMD_IUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
765                                       /* sx.val.i = constant                          */
766                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
767                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
768                         if (iptr->sx.val.i & 0x1f)      {
769                                 M_INTMOVE(s1, REG_ITMP1)
770                                 if ((iptr->sx.val.i & 0x1f) <= 7)       {
771                                         M_IUSR_IMM(iptr->sx.val.i & 0x1f, REG_ITMP1);
772                                 } else  {
773                                         M_IMOV_IMM(iptr->sx.val.i & 0x1f, REG_ITMP2);
774                                         M_IUSR(REG_ITMP2, REG_ITMP1);
775                                 }
776                                 M_INTMOVE(REG_ITMP1, d);
777                         } else  {
778                                 M_INTMOVE(s1, d);
779                         }
780                         emit_store_dst(jd, iptr, d);
781                         break;
782
783                 case ICMD_IAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
784
785                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
786                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
787                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
788                         M_INTMOVE(s2, REG_ITMP2);
789                         M_IAND(s1, REG_ITMP2);
790                         M_INTMOVE(REG_ITMP2, d);
791                         emit_store_dst(jd, iptr, d);
792                         break;
793
794                 case ICMD_IANDCONST:  /* ..., value  ==> ..., value & constant        */
795                                       /* sx.val.i = constant                          */
796
797                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
798                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
799                         M_INTMOVE(s1, REG_ITMP1);
800                         M_IAND_IMM(iptr->sx.val.i, REG_ITMP1);
801                         M_INTMOVE(REG_ITMP1, d);
802                         emit_store_dst(jd, iptr, d);
803                         break;
804
805                 case ICMD_IOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
806                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
807                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
808                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
809                         M_INTMOVE(s2, REG_ITMP2);
810                         M_IOR(s1, REG_ITMP2);
811                         M_INTMOVE(REG_ITMP2, d);
812                         emit_store_dst(jd, iptr, d);
813                         break;
814
815                 case ICMD_IORCONST:   /* ..., value  ==> ..., value | constant        */
816                                       /* sx.val.i = constant                          */
817                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
818                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
819                         M_INTMOVE(s1, REG_ITMP1);
820                         M_IOR_IMM(iptr->sx.val.i, REG_ITMP1);
821                         M_INTMOVE(REG_ITMP1, d);
822                         emit_store_dst(jd, iptr, d);
823                         break;
824
825                 case ICMD_IXOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
826                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
827                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
828                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
829                         M_INTMOVE(s2, REG_ITMP2);
830                         M_IXOR(s1, REG_ITMP2);
831                         M_INTMOVE(REG_ITMP2, d);
832                         emit_store_dst(jd, iptr, d);
833                         break;
834
835                 case ICMD_IXORCONST:   /* ..., value  ==> ..., value | constant        */
836                                       /* sx.val.i = constant                          */
837                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
838                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
839                         M_INTMOVE(s1, REG_ITMP1);
840                         M_IXOR_IMM(iptr->sx.val.i, REG_ITMP1);
841                         M_INTMOVE(REG_ITMP1, d);
842                         emit_store_dst(jd, iptr, d);
843                         break;
844
845                 /* floating point operations ******************************************/
846                 #if !defined(ENABLE_SOFTFLOAT)
847                 case ICMD_FCMPL:                /* ..., val1, val2  ==> ..., val1 fcmpl val2  */
848                 case ICMD_DCMPL:
849                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
850                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
851                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
852                         M_IMOV_IMM(-1, d);
853                         M_FCMP(s1, s2);
854                         M_BFUN(14);     /* result is -1, branch to end */
855                         M_BFLT(10);     /* result is -1, branch to end */
856                         M_IMOV_IMM(0, d);
857                         M_BFEQ(4)       /* result is 0, branch to end */
858                         M_IMOV_IMM(1, d);
859                         emit_store_dst(jd, iptr, d);
860                         break;
861
862                 case ICMD_FCMPG:                /* ..., val1, val2  ==> ..., val1 fcmpg val2  */
863                 case ICMD_DCMPG:
864                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
865                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
866                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
867                         M_IMOV_IMM(1, d);
868                         M_FCMP(s1, s2);
869                         M_BFUN(16);     /* result is +1, branch to end */
870                         M_BFGT(14);     /* result is +1, branch to end */
871                         M_IMOV_IMM(0, d);
872                         M_BFEQ(8)       /* result is 0, branch to end */
873                         M_IMOV_IMM(-1, d);
874                         emit_store_dst(jd, iptr, d);
875                         break;
876
877                 case ICMD_FMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
878                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
879                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
880                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
881                         M_FLTMOVE(s2, REG_FTMP2);
882                         M_FMUL(s1, REG_FTMP2);
883                         M_FLTMOVE(REG_FTMP2, d);
884                         emit_store_dst(jd, iptr, d);
885                         break;
886
887                 case ICMD_DMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
888                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
889                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
890                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
891                         M_DBLMOVE(s2, REG_FTMP2);
892                         M_DMUL(s1, REG_FTMP2);
893                         M_DBLMOVE(REG_FTMP2, d);
894                         emit_store_dst(jd, iptr, d);
895                         break;
896
897                 case ICMD_FDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
898                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
899                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
900                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
901                         M_FLTMOVE(s1, REG_FTMP1);
902                         M_FDIV(s2, REG_FTMP1);
903                         M_FLTMOVE(REG_FTMP1, d);
904                         emit_store_dst(jd, iptr, d);
905                         break;
906
907                 case ICMD_DDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
908                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
909                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
910                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
911                         M_DBLMOVE(s1, REG_FTMP1);
912                         M_DDIV(s2, REG_FTMP1);
913                         M_DBLMOVE(REG_FTMP1, d);
914                         emit_store_dst(jd, iptr, d);
915                         break;
916
917                 case ICMD_FADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
918                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
919                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
920                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
921                         M_FLTMOVE(s2, REG_FTMP2);
922                         M_FADD(s1, REG_FTMP2);
923                         M_FLTMOVE(REG_FTMP2, d);
924                         emit_store_dst(jd, iptr, d);
925                         break;
926
927                 case ICMD_DADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
928                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
929                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
930                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
931                         M_DBLMOVE(s2, REG_FTMP2);
932                         M_DADD(s1, REG_FTMP2);
933                         M_DBLMOVE(REG_FTMP2, d);
934                         emit_store_dst(jd, iptr, d);
935                         break;
936
937                 case ICMD_FSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
938                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
939                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
940                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
941                         M_FLTMOVE(s1, REG_FTMP1);
942                         M_FSUB(s2, REG_FTMP1);
943                         M_FLTMOVE(REG_FTMP1, d);
944                         emit_store_dst(jd, iptr, d);
945                         break;
946
947                 case ICMD_DSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
948                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
949                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
950                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
951                         M_DBLMOVE(s1, REG_FTMP1);
952                         M_DSUB(s2, REG_FTMP1);
953                         M_DBLMOVE(REG_FTMP1, d);
954                         emit_store_dst(jd, iptr, d);
955                         break;
956
957                 case ICMD_F2D:       /* ..., value  ==> ..., (double) value           */
958                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
959                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
960                         M_F2D(s1, d);
961                         emit_store_dst(jd, iptr, d);
962                         break;
963
964                 case ICMD_D2F:       /* ..., value  ==> ..., (float) value           */
965                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
966                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
967                         M_D2F(s1, d);
968                         emit_store_dst(jd, iptr, d);
969                         break;
970
971                 case ICMD_FNEG:       /* ..., value  ==> ..., - value                 */
972                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
973                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
974                         M_FNEG(s1, d);
975                         emit_store_dst(jd, iptr, d);
976                         break;
977
978                 case ICMD_DNEG:       /* ..., value  ==> ..., - value                 */
979                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
980                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
981                         M_DNEG(s1, d);
982                         emit_store_dst(jd, iptr, d);
983                         break;
984
985                 #endif
986
987                 /* load/store/copy/move operations ************************************/
988
989                 case ICMD_ILOAD:      /* ...  ==> ..., content of local variable      */
990                 case ICMD_ALOAD:      /* s1 = local variable                          */
991                 case ICMD_LLOAD:
992                 case ICMD_FLOAD:  
993                 case ICMD_DLOAD:  
994                 case ICMD_ISTORE:     /* ..., value  ==> ...                          */
995                 case ICMD_LSTORE:
996                 case ICMD_FSTORE:
997                 case ICMD_DSTORE: 
998                 case ICMD_COPY:
999                 case ICMD_MOVE:
1000
1001                         emit_copy(jd, iptr);
1002                         break;
1003
1004                 case ICMD_ASTORE:
1005
1006                         if (!(iptr->flags.bits & INS_FLAG_RETADDR))
1007                                 emit_copy(jd, iptr);
1008                         break;
1009
1010
1011                 case ICMD_ACONST:     /* ...  ==> ..., constant                       */
1012                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1013
1014                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1015                                 constant_classref *cr = iptr->sx.val.c.ref;;
1016                                 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo, cr, 0);
1017                                 M_AMOV_IMM(0, d);
1018                         } else {
1019                                 M_AMOV_IMM(iptr->sx.val.anyptr, d);
1020                         }
1021                         emit_store_dst(jd, iptr, d);
1022                         break;
1023                 /* BRANCH *************************************************************/
1024
1025                 case ICMD_ATHROW:       /* ..., objectref ==> ... (, objectref)       */
1026
1027                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1028                         M_ADRMOVE(s1, REG_ATMP1_XPTR);
1029
1030 #ifdef ENABLE_VERIFIER
1031                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1032                                 unresolved_class *uc = iptr->sx.s23.s2.uc;
1033
1034                                 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
1035                         }
1036 #endif /* ENABLE_VERIFIER */
1037                         M_JSR_PCREL(2);                         /* get current PC */
1038                         M_APOP(REG_ATMP2);              
1039
1040                         M_AMOV_IMM(asm_handle_exception, REG_ATMP3);
1041                         M_JMP(REG_ATMP3);
1042                         ALIGNCODENOP;
1043                         break;
1044
1045                 case ICMD_GOTO:         /* ... ==> ...                                */
1046                 case ICMD_RET:          /* ... ==> ...                                */
1047
1048                         emit_br(cd, iptr->dst.block);
1049                         ALIGNCODENOP;
1050                         break;
1051
1052                 case ICMD_JSR:          /* ... ==> ...                                */
1053
1054                         emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
1055                         ALIGNCODENOP;
1056                         break;
1057
1058
1059
1060                 case ICMD_IFNULL:       /* ..., value ==> ...                         */
1061                 case ICMD_IFNONNULL:
1062                         assert(IS_ADR_TYPE(VAROP(iptr->s1)->type));
1063                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1064                         M_ATST(s1);
1065                         emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, BRANCH_OPT_NONE);
1066                         break;
1067
1068                 case ICMD_IFLT:
1069                 case ICMD_IFLE:
1070                 case ICMD_IFNE:
1071                 case ICMD_IFGT:
1072                 case ICMD_IFGE:
1073                 case ICMD_IFEQ:         /* ..., value ==> ...                         */
1074
1075                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1076                         assert (VAROP(iptr->s1)->type == TYPE_INT);
1077                         M_ICMP_IMM(iptr->sx.val.i, s1); 
1078                         emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFEQ, BRANCH_OPT_NONE);
1079                         break;
1080
1081                 case ICMD_IF_ICMPEQ:    /* ..., value, value ==> ...                  */
1082                 case ICMD_IF_ICMPNE:
1083                 case ICMD_IF_ICMPLT:
1084                 case ICMD_IF_ICMPGT:
1085                 case ICMD_IF_ICMPLE:
1086                 case ICMD_IF_ICMPGE:
1087
1088                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1089                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1090                         M_ICMP(s2, s1);
1091                         emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ICMPEQ, BRANCH_OPT_NONE);
1092                         break;
1093
1094                 case ICMD_IF_ACMPEQ:    /* op1 = target JavaVM pc                     */
1095                 case ICMD_IF_ACMPNE:
1096
1097                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1098                         s2 = emit_load_s2(jd, iptr, REG_ATMP2);
1099                         M_ACMP(s1, s2);
1100                         emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ACMPEQ, BRANCH_OPT_NONE);
1101                         break;
1102
1103
1104                 /* MEMORY *************************************************************/
1105
1106                 case ICMD_GETSTATIC:  /* ...  ==> ..., value                          */
1107
1108                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1109                                 uf        = iptr->sx.s23.s3.uf;
1110                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1111                                 disp      = 0;
1112
1113                                 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, 0);
1114                         }
1115                         else {
1116                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1117                                 fieldtype = fi->type;
1118                                 disp      = (intptr_t) fi->value;
1119
1120                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) {
1121                                         patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz,
1122                                                                                 0);
1123                                 }
1124                         }
1125
1126                         M_AMOV_IMM(disp, REG_ATMP1);
1127                         switch (fieldtype) {
1128 #if defined(ENABLE_SOFTFLOAT)
1129                         case TYPE_FLT:
1130 #endif
1131                         case TYPE_INT:
1132                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1133                                 M_ILD(d, REG_ATMP1, 0);
1134                                 break;
1135                         case TYPE_ADR:
1136                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1137                                 M_ALD(d, REG_ATMP1, 0);
1138                                 break;
1139 #if defined(ENABLE_SOFTFLOAT)
1140                         case TYPE_DBL:
1141 #endif
1142                         case TYPE_LNG:
1143                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
1144                                 M_LLD(d, REG_ATMP1, 0);
1145                                 break;
1146 #if !defined(ENABLE_SOFTFLOAT)
1147                         case TYPE_FLT:
1148                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1149                                 M_FLD(d, REG_ATMP1, 0);
1150                                 break;
1151                         case TYPE_DBL:                          
1152                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1153                                 M_DLD(d, REG_ATMP1, 0);
1154                                 break;
1155 #endif
1156                         }
1157                         emit_store_dst(jd, iptr, d);
1158                         break;
1159
1160                 case ICMD_PUTSTATIC:  /* ..., value  ==> ...                          */
1161
1162                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1163                                 uf        = iptr->sx.s23.s3.uf;
1164                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1165                                 disp      = 0;
1166
1167                                 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, 0);
1168                         }
1169                         else {
1170                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1171                                 fieldtype = fi->type;
1172                                 disp      = (intptr_t) fi->value;
1173
1174                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
1175                                         patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz,
1176                                                                                 0);
1177                         }
1178                 
1179                         M_AMOV_IMM(disp, REG_ATMP1);
1180                         switch (fieldtype) {
1181 #if defined(ENABLE_SOFTFLOAT)
1182                         case TYPE_FLT:
1183 #endif
1184                         case TYPE_INT:
1185                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1186                                 M_IST(s1, REG_ATMP1, 0);
1187                                 break;
1188 #if defined(ENABLE_SOFTFLOAT)
1189                         case TYPE_DBL:
1190 #endif
1191                         case TYPE_LNG:
1192                                 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
1193                                 M_LST(s1, REG_ATMP1, 0);
1194                                 break;
1195                         case TYPE_ADR:
1196                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1197                                 M_AST(s1, REG_ATMP1, 0);
1198                                 break;
1199 #if !defined(ENABLE_SOFTFLOAT)
1200                         case TYPE_FLT:
1201                                 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1202                                 M_FST(s1, REG_ATMP1, 0);
1203                                 break;
1204                         case TYPE_DBL:
1205                                 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1206                                 M_DST(s1, REG_ATMP1, 0);
1207                                 break;
1208 #endif
1209                         default: assert(0);
1210                         }
1211                         break;
1212
1213                 case ICMD_GETFIELD:   /* ...  ==> ..., value                          */
1214
1215                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1216
1217                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1218                                 uf        = iptr->sx.s23.s3.uf;
1219                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1220                                 disp      = 0;
1221
1222                                 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1223                         }
1224                         else {
1225                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1226                                 fieldtype = fi->type;
1227                                 disp      = fi->offset;
1228                         }
1229
1230                         /* implicit null-pointer check */
1231                         switch (fieldtype) {
1232 #if defined(ENABLE_SOFTFLOAT)
1233                         case TYPE_FLT:
1234 #endif
1235                         case TYPE_INT:
1236                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1237                                 M_ILD(d, s1, disp);
1238                                 break;
1239 #if defined(ENABLE_SOFTFLOAT)
1240                         case TYPE_DBL:
1241 #endif
1242                         case TYPE_LNG:
1243                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1244                                 M_LLD(d, s1, disp);
1245                                 break;
1246                         case TYPE_ADR:
1247                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1248                                 M_ALD(d, s1, disp);
1249                                 break;
1250 #if !defined(ENABLE_SOFTFLOAT)
1251                         case TYPE_FLT:
1252                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1253                                 M_FLD(d, s1, disp);
1254                                 break;
1255                         case TYPE_DBL:                          
1256                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1257                                 M_DLD(d, s1, disp);
1258                                 break;
1259 #endif
1260                         }
1261                         emit_store_dst(jd, iptr, d);
1262                         break;
1263
1264                 case ICMD_PUTFIELD:   /* ..., value  ==> ...                          */
1265
1266                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1267
1268                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1269                                 uf        = iptr->sx.s23.s3.uf;
1270                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1271                                 disp      = 0;
1272                         }
1273                         else {
1274                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1275                                 fieldtype = fi->type;
1276                                 disp      = fi->offset;
1277                         }
1278
1279                         if (IS_INT_LNG_TYPE(fieldtype)) {
1280                                 if (IS_2_WORD_TYPE(fieldtype)) {
1281                                         s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
1282                                 } else {
1283                                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1284                                 }
1285                         } else {
1286                                 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1287                         }
1288
1289                         if (INSTRUCTION_IS_UNRESOLVED(iptr))
1290                                 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1291
1292                         /* implicit null-pointer check */
1293                         switch (fieldtype) {
1294 #if defined(ENABLE_SOFTFLOAT)
1295                         case TYPE_FLT:
1296 #endif
1297                         case TYPE_INT:
1298                                 M_IST(s2, s1, disp);
1299                                 break;
1300
1301 #if defined(ENABLE_SOFTFLOAT)
1302                         case TYPE_DBL:
1303 #endif
1304                         case TYPE_LNG:
1305                                 M_LST(s2, s1, disp);  
1306                                 break;
1307                         case TYPE_ADR:
1308                                 M_AST(s2, s1, disp);
1309                                 break;
1310 #if !defined(ENABLE_SOFTFLOAT)
1311                         case TYPE_FLT:
1312                                 M_FST(s2, s1, disp);
1313                                 break;
1314                         case TYPE_DBL:
1315                                 M_DST(s2, s1, disp);
1316                                 break;
1317 #endif
1318                         }
1319                         break;
1320
1321                 case ICMD_ARRAYLENGTH: /* ..., arrayref  ==> ..., length              */
1322
1323                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1324                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1325                         /* implicit null-pointer check */
1326                         M_ILD(d, s1, OFFSET(java_array_t, size));
1327                         emit_store_dst(jd, iptr, d);
1328                         break;
1329
1330                 case ICMD_BALOAD:     /* ..., arrayref, index  ==> ..., value         */
1331
1332                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1333                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1334                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1335                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1336                         M_INTMOVE(s2, REG_ITMP2);
1337                         M_IADD_IMM(OFFSET(java_bytearray_t, data[0]), REG_ITMP2);
1338                         M_ADRMOVE(s1, REG_ATMP1);
1339                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1340                         /* implicit null-pointer check */
1341                         M_LBZX(REG_ATMP1, d);
1342                         M_BSEXT(d, d);
1343                         emit_store_dst(jd, iptr, d);
1344                         break;                  
1345
1346                 case ICMD_CALOAD:     /* ..., arrayref, index  ==> ..., value         */
1347
1348                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1349                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1350                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1351                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1352                         M_INTMOVE(s2, REG_ITMP2);
1353                         M_ISSL_IMM(1, REG_ITMP2);
1354                         M_IADD_IMM(OFFSET(java_chararray_t, data[0]), REG_ITMP2);
1355                         M_ADRMOVE(s1, REG_ATMP1);
1356                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1357                         /* implicit null-pointer check */
1358                         M_LHZX(REG_ATMP1, d);
1359                         M_CZEXT(d, d);
1360                         emit_store_dst(jd, iptr, d);
1361                         break;
1362
1363                 case ICMD_SALOAD:     /* ..., arrayref, index  ==> ..., value         */
1364
1365                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1366                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1367                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1368                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1369                         M_INTMOVE(s2, REG_ITMP2);
1370                         M_ISSL_IMM(1, REG_ITMP2);
1371                         M_IADD_IMM(OFFSET(java_shortarray_t, data[0]), REG_ITMP2);
1372                         M_ADRMOVE(s1, REG_ATMP1);
1373                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1374                 
1375                         /* implicit null-pointer check */
1376                         M_LHZX(REG_ATMP1, d);
1377                         M_SSEXT(d, d);
1378                         emit_store_dst(jd, iptr, d);
1379                         break;
1380
1381                 case ICMD_IALOAD:     /* ..., arrayref, index  ==> ..., value         */
1382
1383                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1384                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1385                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1386                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1387                         M_INTMOVE(s2, REG_ITMP2);
1388                         M_ISSL_IMM(2, REG_ITMP2);
1389                         M_IADD_IMM(OFFSET(java_intarray_t, data[0]), REG_ITMP2);
1390                         M_ADRMOVE(s1, REG_ATMP1);
1391                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1392                         /* implicit null-pointer check */
1393                         M_LWZX(REG_ATMP1, d);
1394                         emit_store_dst(jd, iptr, d);
1395                         break;
1396
1397                 case ICMD_LALOAD:     /* ..., arrayref, index  ==> ..., value         */
1398                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1399                         s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1400                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1401                         /* implicit null-pointer check */
1402                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1403                         M_INTMOVE(s2, REG_ITMP1);
1404                         M_ISSL_IMM(3, REG_ITMP1);
1405                         M_IADD_IMM(OFFSET(java_longarray_t, data[0]), REG_ITMP1);
1406                         M_ADRMOVE(s1, REG_ATMP1);
1407                         M_AADDINT(REG_ITMP1, REG_ATMP1);
1408                         /* implicit null-pointer check */
1409                         M_LLD(d, REG_ATMP1, 0);
1410                         emit_store_dst(jd, iptr, d);
1411                         break;
1412
1413                 case ICMD_FALOAD:     /* ..., arrayref, index  ==> ..., value         */
1414                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1415                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1416                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1417                         M_INTMOVE(s2, REG_ITMP2);
1418                         M_ISSL_IMM(2, REG_ITMP2);
1419                         M_IADD_IMM(OFFSET(java_floatarray_t, data[0]), REG_ITMP2);
1420                         M_ADRMOVE(s1, REG_ATMP1);
1421                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1422                         /* implicit null-pointer check */
1423 #if !defined(ENABLE_SOFTFLOAT)
1424                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1425                         M_FLD(d, REG_ATMP1, 0);
1426 #else
1427                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1428                         M_LWZX(REG_ATMP1, d);
1429 #endif
1430                         emit_store_dst(jd, iptr, d);
1431                         break;
1432
1433                 case ICMD_DALOAD:     /* ..., arrayref, index  ==> ..., value         */
1434                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1435                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1436                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1437                         M_INTMOVE(s2, REG_ITMP2);
1438                         M_ISSL_IMM(3, REG_ITMP2);
1439                         M_IADD_IMM(OFFSET(java_doublearray_t, data[0]), REG_ITMP2);
1440                         M_ADRMOVE(s1, REG_ATMP1);
1441                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1442                         /* implicit null-pointer check */
1443 #if !defined(ENABLE_SOFTFLOAT)
1444                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1445                         M_DLD(d, REG_ATMP1, 0);
1446 #else
1447                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1448                         M_LLD(d, REG_ATMP1, 0);
1449 #endif
1450                         emit_store_dst(jd, iptr, d);
1451                         break;
1452
1453                 case ICMD_AALOAD:     /* ..., arrayref, index  ==> ..., value         */
1454                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1455                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1456                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1457                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1458                         M_INTMOVE(s2, REG_ITMP2);
1459                         M_ISSL_IMM(2, REG_ITMP2);
1460                         M_IADD_IMM(OFFSET(java_objectarray_t, data[0]), REG_ITMP2);
1461                         M_ADRMOVE(s1, REG_ATMP1);
1462                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1463         
1464                         /* implicit null-pointer check */
1465                         M_LAX(REG_ATMP1, d);
1466                         emit_store_dst(jd, iptr, d);
1467                         break;
1468
1469
1470                 case ICMD_BASTORE:    /* ..., arrayref, index, value  ==> ...         */
1471                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1472                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1473                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1474                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1475                         M_INTMOVE(s2, REG_ITMP2);
1476                         M_IADD_IMM(OFFSET(java_bytearray_t, data[0]), REG_ITMP2);
1477                         M_ADRMOVE(s1, REG_ATMP1);
1478                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1479                         /* implicit null-pointer check */
1480                         M_STBX(REG_ATMP1, s3);
1481                         break;
1482
1483                 case ICMD_CASTORE:    /* ..., arrayref, index, value  ==> ...         */
1484                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1485                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1486                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1487                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1488                         M_INTMOVE(s2, REG_ITMP2);
1489                         M_ISSL_IMM(1, REG_ITMP2);
1490                         M_IADD_IMM(OFFSET(java_chararray_t, data[0]), REG_ITMP2); 
1491                         M_ADRMOVE(s1, REG_ATMP1);
1492                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1493                         /* implicit null-pointer check */
1494                         M_STHX(REG_ATMP1, s3);
1495                         break;
1496
1497                 case ICMD_SASTORE:    /* ..., arrayref, index, value  ==> ...         */
1498                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1499                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1500                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1501                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1502                         M_INTMOVE(s2, REG_ITMP2);
1503                         M_ISSL_IMM(1, REG_ITMP2);
1504                         M_IADD_IMM(OFFSET(java_shortarray_t, data[0]), REG_ITMP2);
1505                         M_ADRMOVE(s1, REG_ATMP1);
1506                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1507                         /* implicit null-pointer check */
1508                         M_STHX(REG_ATMP1, s3);
1509                         break;
1510
1511                 case ICMD_IASTORE:    /* ..., arrayref, index, value  ==> ...         */
1512                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1513                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1514                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1515                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1516                         M_INTMOVE(s2, REG_ITMP2);
1517                         M_ISSL_IMM(2, REG_ITMP2);
1518                         M_IADD_IMM(OFFSET(java_intarray_t, data[0]), REG_ITMP2);
1519                         M_ADRMOVE(s1, REG_ATMP1);
1520                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1521                         /* implicit null-pointer check */
1522                         M_STWX(REG_ATMP1, s3);
1523                         break;
1524
1525                 case ICMD_LASTORE:    /* ..., arrayref, index, value  ==> ...         */
1526                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1527                         s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1528                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1529
1530                         M_INTMOVE(s2, REG_ITMP1);
1531                         M_ISSL_IMM(3, REG_ITMP1);
1532                         M_IADD_IMM(OFFSET(java_longarray_t, data[0]), REG_ITMP1);
1533                         M_ADRMOVE(s1, REG_ATMP1);
1534                         M_AADDINT(REG_ITMP1, REG_ATMP1);
1535                         /* implicit null-pointer check */
1536                         s3 = emit_load_s3(jd, iptr, REG_ITMP12_PACKED);
1537                         M_LST(s3, REG_ATMP1, 0);
1538                         break;
1539
1540                 case ICMD_FASTORE:    /* ..., arrayref, index, value  ==> ...         */
1541                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1542                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1543                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1544                         M_INTMOVE(s2, REG_ITMP2);
1545                         M_ISSL_IMM(2, REG_ITMP2);
1546                         M_IADD_IMM(OFFSET(java_floatarray_t, data[0]), REG_ITMP2);
1547                         M_ADRMOVE(s1, REG_ATMP1);
1548                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1549                         /* implicit null-pointer check */
1550 #if !defined(ENABLE_SOFTFLOAT)
1551                         s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1552                         M_FST(s3, REG_ATMP1, 0);
1553 #else
1554                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1555                         M_STWX(REG_ATMP1, s3);
1556 #endif
1557                         break;
1558
1559                 case ICMD_DASTORE:    /* ..., arrayref, index, value  ==> ...         */
1560                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1561                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1562                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1563                         M_INTMOVE(s2, REG_ITMP2);
1564                         M_ISSL_IMM(3, REG_ITMP2);
1565                         M_IADD_IMM(OFFSET(java_doublearray_t, data[0]), REG_ITMP2);
1566                         M_ADRMOVE(s1, REG_ATMP1);
1567                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1568                         /* implicit null-pointer check */
1569 #if !defined(ENABLE_SOFTFLOAT)
1570                         s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1571                         M_DST(s3, REG_ATMP1, 0);
1572 #else
1573                         s3 = emit_load_s3(jd, iptr, REG_ITMP12_PACKED);
1574                         /* implicit null-pointer check */
1575                         M_LST(s3, REG_ATMP1, 0);
1576 #endif
1577                         break;
1578
1579                 case ICMD_AASTORE:    /* ..., arrayref, index, value  ==> ...         */
1580
1581                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1582                         s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1583                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1584                         s3 = emit_load_s3(jd, iptr, REG_ATMP2);
1585
1586                         /* XXX what if array is NULL */
1587                         disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
1588
1589                         M_AST(s1, REG_SP, 0*4);
1590                         M_AST(s3, REG_SP, 1*4);
1591                         M_JSR_IMM(BUILTIN_FAST_canstore);
1592                         emit_arraystore_check(cd, iptr);
1593
1594                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1595                         s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1596                         s3 = emit_load_s3(jd, iptr, REG_ATMP2);
1597                         M_INTMOVE(s2, REG_ITMP1);
1598                         M_ISSL_IMM(2, REG_ITMP1);
1599                         M_IADD_IMM(OFFSET(java_objectarray_t, data[0]), REG_ITMP1);
1600                         M_ADRMOVE(s1, REG_ATMP1);
1601                         M_AADDINT(REG_ITMP1, REG_ATMP1);
1602                         /* implicit null-pointer check */
1603                         M_STAX(REG_ATMP1, s3);
1604                         break;
1605
1606
1607
1608                 /* METHOD INVOCATION *********************************************************/
1609                 case ICMD_BUILTIN:      /* ..., [arg1, [arg2 ...]] ==> ...            */
1610                         REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr);
1611
1612                         bte = iptr->sx.s23.s3.bte;
1613                         md  = bte->md;
1614                         goto gen_method;
1615
1616                 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ...            */
1617                 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
1618                 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer    */
1619                 case ICMD_INVOKEINTERFACE:
1620                         REPLACEMENT_POINT_INVOKE(cd, iptr);
1621
1622                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1623                                 lm = NULL;
1624                                 um = iptr->sx.s23.s3.um;
1625                                 md = um->methodref->parseddesc.md;
1626                         }
1627                         else {
1628                                 lm = iptr->sx.s23.s3.fmiref->p.method;
1629                                 um = NULL;
1630                                 md = lm->parseddesc;
1631                         }
1632         gen_method:
1633                         s3 = md->paramcount;
1634         
1635                         MCODECHECK((s3 << 1) + 64);
1636
1637                         /* copy arguments to stack */
1638                         for (s3 = s3 - 1; s3 >= 0; s3--)        {
1639                                 var = VAR(iptr->sx.s23.s2.args[s3]);
1640                                 /* already preallocated */
1641                                 if (var->flags & PREALLOC) continue;
1642                 
1643                                 if (!md->params[s3].inmemory) assert(0);
1644
1645                                 switch (var->type)      {
1646 #if defined(ENABLE_SOFTFLOAT)
1647                                         case TYPE_DBL:
1648 #endif
1649                                         case TYPE_LNG:
1650                                                 d = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
1651                                                 M_LST(d, REG_SP, md->params[s3].regoff);
1652                                                 break;
1653 #if defined(ENABLE_SOFTFLOAT)
1654                                         case TYPE_FLT:
1655 #endif
1656                                         case TYPE_INT:
1657                                                 d = emit_load(jd, iptr, var, REG_ITMP1);
1658                                                 M_IST(d, REG_SP, md->params[s3].regoff);
1659                                                 break;
1660                                         case TYPE_ADR:
1661                                                 d = emit_load(jd, iptr, var, REG_ATMP1);
1662                                                 M_AST(d, REG_SP, md->params[s3].regoff);
1663                                                 break;
1664 #if !defined(ENABLE_SOFTFLOAT)
1665                                         case TYPE_FLT:
1666                                                 d = emit_load(jd, iptr, var, REG_FTMP1);
1667                                                 M_FST(d, REG_SP, md->params[s3].regoff);
1668                                                 break;
1669                                         case TYPE_DBL:
1670                                                 d = emit_load(jd, iptr, var, REG_FTMP1);
1671                                                 M_DST(d, REG_SP, md->params[s3].regoff);
1672                                                 break;
1673 #endif
1674                                         default:
1675                                                 assert(0);
1676                                 }
1677                         }
1678
1679                         /* arguments in place now */
1680                         switch(iptr->opc)       {
1681                                 case ICMD_BUILTIN:
1682                                         if (bte->stub == NULL)
1683                                                 disp = (ptrint) bte->fp;
1684                                         else
1685                                                 disp = (ptrint) bte->stub;
1686                                         d = md->returntype.type;
1687                                         M_JSR_IMM(disp);
1688
1689                                         REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1690                                         break;
1691
1692                                 case ICMD_INVOKESPECIAL: 
1693                                         /* adress register for sure */
1694                                         M_ALD(REG_ATMP1, REG_SP, 0);
1695                                         emit_nullpointer_check(cd, iptr, REG_ATMP1);
1696                                         /* fall through */
1697                                 case ICMD_INVOKESTATIC: 
1698                                         if (lm == NULL) {
1699                                                 patcher_add_patch_ref(jd, PATCHER_invokestatic_special, um, 0);
1700                                                 disp = 0;
1701                                                 M_AMOV_IMM(disp, REG_ATMP1);
1702                                         } else  {
1703                                                 disp = lm->stubroutine;
1704                                                 M_AMOV_IMM(disp, REG_ATMP1);
1705                                         }
1706
1707                                         /* generate the actual call */
1708                                         M_JSR(REG_ATMP1);
1709                                         REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1710                                         break;
1711
1712
1713                                 case ICMD_INVOKEVIRTUAL:
1714                                         if (lm == NULL) {
1715                                                 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
1716                                                 s1 = 0;
1717                                         } else {
1718                                                 s1 = OFFSET(vftbl_t, table[0]) + sizeof(methodptr) * lm->vftblindex;
1719                                         }
1720                                         /* load object pointer (==argument 0) */
1721                                         M_ALD(REG_ATMP1, REG_SP, 0);
1722                                         /* implicit null-pointer check */
1723                                         M_ALD(REG_METHODPTR, REG_ATMP1, OFFSET(java_object_t, vftbl));
1724                                         M_ALD(REG_ATMP3, REG_METHODPTR, s1);
1725                                         /* generate the actual call */
1726                                         M_JSR(REG_ATMP3);
1727                                         break;
1728                                 case ICMD_INVOKEINTERFACE: 
1729                                         if (lm == NULL) {
1730                                                 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
1731
1732                                                 s1 = 0;
1733                                                 s2 = 0;
1734                                         } else {
1735                                                 s1 = OFFSET(vftbl_t, interfacetable[0]) - sizeof(methodptr*) * lm->clazz->index;
1736                                                 s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
1737                                         }
1738                                         /* load object pointer (==argument 0) */
1739                                         M_ALD(REG_ATMP1, REG_SP, 0);
1740
1741                                         /* implicit null-pointer check */
1742                                         M_ALD(REG_METHODPTR, REG_ATMP1, OFFSET(java_object_t, vftbl));
1743                                         M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
1744                                         M_ALD(REG_ATMP3, REG_METHODPTR, s2);
1745
1746                                         /* generate the actual call */
1747                                         M_JSR(REG_ATMP3);
1748                                         REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1749                                         break;
1750
1751                                 default: assert(0);
1752                                 }       /* switch (iptr->opc) */
1753
1754                                 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1755                                 REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr);
1756                                 
1757                                 /* store return value */
1758                                 d = md->returntype.type;
1759
1760                                 switch (d)      {
1761                                         case TYPE_VOID: break;
1762 #if defined(ENABLE_SOFTFLOAT)
1763                                         case TYPE_FLT:
1764 #endif
1765                                         case TYPE_INT:
1766                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
1767                                                 M_INTMOVE(REG_RESULT, s1);
1768                                                 break;
1769 #if defined(ENABLE_SOFTFLOAT)
1770                                         case TYPE_DBL:
1771 #endif
1772                                         case TYPE_LNG:
1773                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
1774                                                 M_LNGMOVE(REG_RESULT_PACKED, s1);
1775                                                 break;
1776                                         case TYPE_ADR:
1777                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_ATMP1);
1778                                                 /* all stuff is returned in %d0 */
1779                                                 M_INT2ADRMOVE(REG_RESULT, s1);
1780                                                 break;
1781 #if !defined(ENABLE_SOFTFLOAT)
1782                                         /*
1783                                          *      for BUILTINS float values are returned in %d0,%d1
1784                                          *      within cacao we use %fp0 for that.
1785                                          */
1786                                         case TYPE_FLT:
1787                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1788                                                 if (iptr->opc == ICMD_BUILTIN)  {
1789                                                         M_INT2FLTMOVE(REG_FRESULT, s1);
1790                                                 } else  {
1791                                                         M_FLTMOVE(REG_FRESULT, s1);
1792                                                 }
1793                                                 break;
1794                                         case TYPE_DBL:
1795                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1796                                                 if (iptr->opc == ICMD_BUILTIN)  {
1797                                                         M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 4 + 4);
1798                                                         M_DLD(s1, REG_SP, rd->memuse * 4 + 4);
1799                                                 } else  {
1800                                                         M_DBLMOVE(REG_FRESULT, s1);
1801                                                 }
1802                                                 break;
1803 #endif
1804                                         default:
1805                                                 assert(0);
1806                                 }
1807                                 if (d != TYPE_VOID) emit_store_dst(jd, iptr, s1);
1808                         break; /* ICMD_INVOKE* */
1809
1810 #if defined(ENABLE_SOFTFLOAT)
1811                 case ICMD_FRETURN:
1812 #endif
1813                 case ICMD_IRETURN:      /* ..., retvalue ==> ...                      */
1814
1815                         REPLACEMENT_POINT_RETURN(cd, iptr);
1816                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
1817                         M_INTMOVE(s1, REG_RESULT);
1818                         goto nowperformreturn;
1819
1820                 case ICMD_ARETURN:      /* ..., retvalue ==> ...                      */
1821
1822                         REPLACEMENT_POINT_RETURN(cd, iptr);
1823                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
1824                         assert(VAROP(iptr->s1)->type == TYPE_ADR);
1825                         M_ADR2INTMOVE(s1, REG_RESULT);
1826
1827 #ifdef ENABLE_VERIFIER
1828                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1829                                 unresolved_class *uc = iptr->sx.s23.s2.uc;
1830
1831                                 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
1832                         }
1833 #endif /* ENABLE_VERIFIER */
1834                         goto nowperformreturn;
1835
1836 #if defined(ENABLE_SOFTFLOAT)
1837                 case ICMD_DRETURN:
1838 #endif
1839                 case ICMD_LRETURN:      /* ..., retvalue ==> ...                      */
1840                         REPLACEMENT_POINT_RETURN(cd, iptr);
1841                         s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
1842                         M_LNGMOVE(s1, REG_RESULT_PACKED);
1843                         goto nowperformreturn;
1844
1845 #if !defined(ENABLE_SOFTFLOAT)
1846                 case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
1847                         REPLACEMENT_POINT_RETURN(cd, iptr);
1848                         s1 = emit_load_s1(jd, iptr, REG_FRESULT);
1849                         M_FLTMOVE(s1, REG_FRESULT);
1850                         goto nowperformreturn;
1851
1852                 case ICMD_DRETURN:
1853                         REPLACEMENT_POINT_RETURN(cd, iptr);
1854                         s1 = emit_load_s1(jd, iptr, REG_FRESULT);
1855                         M_DBLMOVE(s1, REG_FRESULT);
1856                         goto nowperformreturn;
1857
1858 #endif
1859
1860                 case ICMD_RETURN:      /* ...  ==> ...                                */
1861
1862                         REPLACEMENT_POINT_RETURN(cd, iptr);
1863
1864 nowperformreturn:
1865                         {
1866                         s4 i, p;
1867                         
1868                         p = cd->stackframesize;
1869
1870                         /* call trace function */
1871 #if !defined(NDEBUG)
1872                         emit_verbosecall_exit(jd);
1873 #endif
1874
1875 #if defined(ENABLE_THREADS)
1876                         /* call lock_monitor_exit */
1877                         if (checksync && code_is_synchronized(code)) {
1878                                 M_ILD(REG_ITMP3, REG_SP, rd->memuse * 8);
1879
1880                                 /* we need to save the proper return value */
1881                                 /* we do not care for the long -> doubel convert space here */
1882                                 switch (iptr->opc) {
1883 #if defined(ENABLE_SOFTFLOAT)
1884                                 case ICMD_DRETURN:
1885 #endif
1886                                 case ICMD_LRETURN:
1887                                         M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 8 + 8);
1888                                         break;
1889 #if defined(ENABLE_SOFTFLOAT)
1890                                 case ICMD_FRETURN:
1891 #endif
1892                                 case ICMD_IRETURN:
1893                                 case ICMD_ARETURN:
1894                                         M_IST(REG_RESULT , REG_SP, rd->memuse * 8 + 8);
1895                                         break;
1896 #if !defined(ENABLE_SOFTFLOAT)
1897                                 case ICMD_FRETURN:
1898                                         M_FST(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1899                                         break;
1900                                 case ICMD_DRETURN:
1901                                         M_DST(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1902                                         break;
1903 #endif
1904                                 }
1905
1906                                 M_IST(REG_ITMP3, REG_SP, 0 * 4);
1907                                 M_JSR_IMM(LOCK_monitor_exit);
1908
1909                                 /* and now restore the proper return value */
1910                                 switch (iptr->opc) {
1911
1912 #if defined(ENABLE_SOFTFLOAT)
1913                                 case ICMD_DRETURN:
1914 #endif
1915                                 case ICMD_LRETURN:
1916                                         M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 8 + 8);
1917                                         break;
1918 #if defined(ENABLE_SOFTFLOAT)
1919                                 case ICMD_FRETURN:
1920 #endif
1921                                 case ICMD_IRETURN:
1922                                 case ICMD_ARETURN:
1923                                         M_ILD(REG_RESULT , REG_SP, rd->memuse * 8 + 8);
1924                                         break;
1925 #if !defined(ENABLE_SOFTFLOAT)
1926                                 case ICMD_FRETURN:
1927                                         M_FLD(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1928                                         break;
1929                                 case ICMD_DRETURN:
1930                                         M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1931                                         break;
1932 #endif
1933                                 }
1934                         }
1935 #endif
1936
1937
1938                         /* restore return address                                         */
1939 #if 0
1940                         if (!code_is_leafmethod(code)) {
1941                                 /* ATTENTION: Don't use REG_ZERO (r0) here, as M_ALD
1942                                    may have a displacement overflow. */
1943
1944                                 M_ALD(REG_ITMP1, REG_SP, p * 4 + LA_LR_OFFSET);
1945                                 M_MTLR(REG_ITMP1);
1946                         }
1947 #endif
1948                         /* restore saved registers                                        */
1949
1950                         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
1951                                 p-=8; M_ILD(rd->savintregs[i], REG_SP, p);
1952                         }
1953                         for (i=ADR_SAV_CNT-1; i>=rd->savadrreguse; --i) {
1954                                 p-=8; M_ALD(rd->savadrregs[i], REG_SP, p);
1955                         }
1956 #if !defined(ENABLE_SOFTFLOAT)
1957                         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
1958                                 p-=8; M_FLOAD(rd->savfltregs[i], REG_SP, p);
1959                         }
1960 #endif
1961                         /* deallocate stack                                               */
1962                         M_AADD_IMM(cd->stackframesize, REG_SP);
1963                         M_RET;
1964                         }
1965                         break;
1966
1967                 /* the evil ones */
1968                 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
1969                                       /* val.a: (classinfo*) superclass               */
1970
1971                         /*  superclass is an interface:
1972                          *
1973                          *  return (sub != NULL) &&
1974                          *         (sub->vftbl->interfacetablelength > super->index) &&
1975                          *         (sub->vftbl->interfacetable[-super->index] != NULL);
1976                          *
1977                          *  superclass is a class:
1978                          *
1979                          *  return ((sub != NULL) && (0
1980                          *          <= (sub->vftbl->baseval - super->vftbl->baseval) <=
1981                          *          super->vftbl->diffvall));
1982                          */
1983
1984                         {
1985                         classinfo *super;
1986                         s4         superindex;
1987
1988                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1989                                 super      = NULL;
1990                                 superindex = 0;
1991                         }
1992                         else {
1993                                 super      = iptr->sx.s23.s3.c.cls;
1994                                 superindex = super->index;
1995                         }
1996                         
1997                         if ((super == NULL) || !(super->flags & ACC_INTERFACE))
1998                                 CODEGEN_CRITICAL_SECTION_NEW;
1999
2000                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
2001                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2002
2003                         assert(VAROP(iptr->s1 )->type == TYPE_ADR);
2004                         assert(VAROP(iptr->dst)->type == TYPE_INT);
2005
2006                         M_ICLR(d);
2007
2008                         /* if class is not resolved, check which code to call */
2009
2010                         if (super == NULL) {
2011                                 M_ATST(s1);
2012                                 emit_label_beq(cd, BRANCH_LABEL_1);
2013
2014                                 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags, iptr->sx.s23.s3.c.ref, 0);
2015
2016                                 M_IMOV_IMM32(0, REG_ITMP3);
2017                                 M_IAND_IMM(ACC_INTERFACE, REG_ITMP3);
2018                                 emit_label_beq(cd, BRANCH_LABEL_2);
2019                         }
2020
2021                         /* interface instanceof code */
2022
2023                         if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2024                                 if (super == NULL) {
2025                                         patcher_add_patch_ref(jd, PATCHER_instanceof_interface, iptr->sx.s23.s3.c.ref, 0);
2026                                 } else {
2027                                         M_ATST(s1);
2028                                         emit_label_beq(cd, BRANCH_LABEL_3);
2029                                 }
2030
2031                                 M_ALD(REG_ATMP1, s1, OFFSET(java_object_t, vftbl));
2032                                 M_ILD(REG_ITMP3, REG_ATMP1, OFFSET(vftbl_t, interfacetablelength));
2033                                 M_IADD_IMM(-superindex, REG_ITMP3);     /* -superindex may be patched patched */
2034                                 M_ITST(REG_ITMP3);
2035                                 M_BLE(10);
2036                                 M_ALD(REG_ATMP1, REG_ATMP1, OFFSET(vftbl_t, interfacetable[0]) - superindex * sizeof(methodptr*));      /* patch here too! */
2037                                 M_ATST(REG_ATMP1);
2038                                 M_BEQ(2);
2039                                 M_IMOV_IMM(1, d);
2040
2041                                 if (super == NULL)
2042                                         emit_label_br(cd, BRANCH_LABEL_4);
2043                                 else
2044                                         emit_label(cd, BRANCH_LABEL_3);
2045                         }
2046
2047                         /* class instanceof code */
2048
2049                         if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2050                                 if (super == NULL) {
2051                                         emit_label(cd, BRANCH_LABEL_2);
2052
2053                                         patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, 0);
2054                                         M_AMOV_IMM(0, REG_ATMP2);
2055                                 } else {
2056                                         M_AMOV_IMM(super->vftbl, REG_ATMP2);
2057                                         M_ATST(s1);
2058                                         emit_label_beq(cd, BRANCH_LABEL_5);
2059                                 }
2060
2061                                 M_ALD(REG_ATMP1, s1, OFFSET(java_object_t, vftbl));
2062
2063                                 CODEGEN_CRITICAL_SECTION_START;
2064
2065                                 M_ILD(REG_ITMP1, REG_ATMP1, OFFSET(vftbl_t, baseval));
2066                                 M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, baseval));
2067                                 M_ILD(REG_ITMP2, REG_ATMP2, OFFSET(vftbl_t, diffval));
2068
2069                                 CODEGEN_CRITICAL_SECTION_END;
2070
2071                                 M_ISUB(REG_ITMP3, REG_ITMP1);
2072                                 M_ICMP(REG_ITMP2, REG_ITMP1);
2073                                 M_BHI(4);
2074                                 M_IMOV_IMM(1, d);
2075                                 M_TPFW;                 /* overlaps next instruction */
2076                                 M_ICLR(d);
2077
2078                                 if (super != NULL)
2079                                         emit_label(cd, BRANCH_LABEL_5);
2080                         }
2081
2082                         if (super == NULL) {
2083                                 emit_label(cd, BRANCH_LABEL_1);
2084                                 emit_label(cd, BRANCH_LABEL_4);
2085                         }
2086
2087                         emit_store_dst(jd, iptr, d);
2088                         }
2089                         break;
2090
2091                 case ICMD_CHECKCAST:  /* ..., objectref ==> ..., objectref            */
2092                                       /* val.a: (classinfo*) superclass               */
2093
2094                         /*  superclass is an interface:
2095                          *
2096                          *  OK if ((sub == NULL) ||
2097                          *         (sub->vftbl->interfacetablelength > super->index) &&
2098                          *         (sub->vftbl->interfacetable[-super->index] != NULL));
2099                          *
2100                          *  superclass is a class:
2101                          *
2102                          *  OK if ((sub == NULL) || (0
2103                          *         <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2104                          *         super->vftbl->diffvall));
2105                          */
2106
2107                         if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2108                                 /* object type cast-check */
2109
2110                                 classinfo *super;
2111                                 s4         superindex;
2112
2113                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2114                                         super      = NULL;
2115                                         superindex = 0;
2116                                 }
2117                                 else {
2118                                         super      = iptr->sx.s23.s3.c.cls;
2119                                         superindex = super->index;
2120                                 }
2121
2122                                 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2123                                         CODEGEN_CRITICAL_SECTION_NEW;
2124
2125                                 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
2126                                 assert(VAROP(iptr->s1)->type == TYPE_ADR);
2127
2128                                 /* if class is not resolved, check which code to call */
2129
2130                                 if (super == NULL) {
2131                                         M_ATST(s1);
2132                                         emit_label_beq(cd, BRANCH_LABEL_1);
2133
2134                                         patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags, iptr->sx.s23.s3.c.ref, 0);
2135                         
2136                                         M_IMOV_IMM32(0, REG_ITMP2);
2137                                         M_IAND_IMM(ACC_INTERFACE, REG_ITMP2);
2138                                         emit_label_beq(cd, BRANCH_LABEL_2);
2139                                 }
2140
2141                                 /* interface checkcast code */
2142
2143                                 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2144                                         if (super == NULL) {
2145                                                 patcher_add_patch_ref(jd, PATCHER_checkcast_interface, iptr->sx.s23.s3.c.ref, 0);
2146                                         } else {
2147                                                 M_ATST(s1);
2148                                                 emit_label_beq(cd, BRANCH_LABEL_3);
2149                                         }
2150
2151                                         M_ALD(REG_ATMP2, s1, OFFSET(java_object_t, vftbl));
2152                                         M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, interfacetablelength));
2153         
2154                                         M_IADD_IMM(-superindex, REG_ITMP3);     /* superindex patched */
2155                                         M_ITST(REG_ITMP3);
2156                                         emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2157
2158                                         M_ALD(REG_ATMP3, REG_ATMP2, OFFSET(vftbl_t, interfacetable[0]) - superindex * sizeof(methodptr*));      /* patched*/
2159                                         M_ATST(REG_ATMP3);
2160                                         emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ATMP3, s1);
2161
2162                                         if (super == NULL)
2163                                                 emit_label_br(cd, BRANCH_LABEL_4);
2164                                         else
2165                                                 emit_label(cd, BRANCH_LABEL_3);
2166                                 }
2167
2168                                 /* class checkcast code */
2169
2170                                 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2171                                         if (super == NULL) {
2172                                                 emit_label(cd, BRANCH_LABEL_2);
2173
2174                                                 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, 0);
2175                                                 M_AMOV_IMM(0, REG_ATMP3);
2176                                         } else {
2177                                                 M_AMOV_IMM(super->vftbl, REG_ATMP3);
2178                                                 M_ATST(s1);
2179                                                 emit_label_beq(cd, BRANCH_LABEL_5);
2180                                         }
2181
2182                                         M_ALD(REG_ATMP2, s1, OFFSET(java_object_t, vftbl));
2183
2184                                         CODEGEN_CRITICAL_SECTION_START;
2185
2186                                         M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, baseval));  /* REG_ITMP3 == sub->vftbl->baseval */
2187                                         M_ILD(REG_ITMP1, REG_ATMP3, OFFSET(vftbl_t, baseval));
2188                                         M_ILD(REG_ITMP2, REG_ATMP3, OFFSET(vftbl_t, diffval));
2189
2190                                         CODEGEN_CRITICAL_SECTION_END;
2191
2192                                         M_ISUB(REG_ITMP1, REG_ITMP3);
2193                                         M_ICMP(REG_ITMP2, REG_ITMP3);   /* XXX was CMPU */
2194
2195                                         emit_classcast_check(cd, iptr, BRANCH_UGT, REG_ITMP3, s1); /* XXX was BRANCH_GT */
2196
2197                                         if (super != NULL)
2198                                                 emit_label(cd, BRANCH_LABEL_5);
2199                                 }
2200
2201                                 if (super == NULL) {
2202                                         emit_label(cd, BRANCH_LABEL_1);
2203                                         emit_label(cd, BRANCH_LABEL_4);
2204                                 }
2205
2206                                 d = codegen_reg_of_dst(jd, iptr, s1);
2207                         } else {
2208                                 /* array type cast-check */
2209
2210                                 s1 = emit_load_s1(jd, iptr, REG_ATMP2);
2211
2212                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2213                                         patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo, iptr->sx.s23.s3.c.ref, 0);
2214                                         M_AMOV_IMM(0, REG_ATMP1);
2215                                 } else {
2216                                         M_AMOV_IMM(iptr->sx.s23.s3.c.cls, REG_ATMP1);
2217                                 }
2218         
2219                                 M_APUSH(REG_ATMP1);
2220                                 M_APUSH(s1);
2221                                 M_JSR_IMM(BUILTIN_arraycheckcast);
2222                                 M_AADD_IMM(2*4, REG_SP);                /* pop arguments off stack */
2223                                 M_ITST(REG_RESULT);
2224                                 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2225
2226                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2227                                 d = codegen_reg_of_dst(jd, iptr, s1);
2228                         }
2229                         assert(VAROP(iptr->dst)->type == TYPE_ADR);
2230                         M_ADRMOVE(s1, d);
2231                         emit_store_dst(jd, iptr, d);
2232                         break;
2233
2234                 case ICMD_TABLESWITCH:  /* ..., index ==> ...                         */
2235                         {
2236                         s4 i, l;
2237                         branch_target_t *table;
2238
2239                         table = iptr->dst.table;
2240
2241                         l = iptr->sx.s23.s2.tablelow;
2242                         i = iptr->sx.s23.s3.tablehigh;
2243                         
2244                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2245                         M_INTMOVE(s1, REG_ITMP1);
2246                         if (l != 0) M_ISUB_IMM(l, REG_ITMP1);
2247
2248                         i = i - l + 1;
2249
2250                         /* range check */
2251                         M_ICMP_IMM(i - 1, REG_ITMP1);
2252                         emit_bugt(cd, table[0].block);
2253
2254                         /* build jump table top down and use address of lowest entry */
2255                         table += i;
2256
2257                         while (--i >= 0) {
2258                                 dseg_add_target(cd, table->block); 
2259                                 --table;
2260                         }
2261
2262                         /* length of dataseg after last dseg_add_target is used by load */
2263                         M_AMOV_IMM(0, REG_ATMP2);
2264                         dseg_adddata(cd);
2265
2266                         M_ISSL_IMM(2, REG_ITMP1);                       /* index * 4 == offset in table */
2267                         M_AADDINT(REG_ITMP1, REG_ATMP2);                /* offset in table */
2268                         M_AADD_IMM(-(cd->dseglen), REG_ATMP2);          /* start of table in dseg */
2269                         M_ALD(REG_ATMP1, REG_ATMP2, 0);
2270
2271                         M_JMP(REG_ATMP1);
2272                         ALIGNCODENOP;
2273                         }
2274                         break;
2275
2276                 case ICMD_LOOKUPSWITCH: /* ..., key ==> ...                           */
2277                         {
2278                         s4 i;
2279                         lookup_target_t *lookup;
2280
2281                         lookup = iptr->dst.lookup;
2282
2283                         i = iptr->sx.s23.s2.lookupcount;
2284                         
2285                         MCODECHECK((i<<2)+8);
2286                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2287
2288                         while (--i >= 0) {
2289                                 M_ICMP_IMM(lookup->value, s1);
2290                                 emit_beq(cd, lookup->target.block);
2291                                 lookup++;
2292                         }
2293
2294                         emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2295                         ALIGNCODENOP;
2296                         break;
2297                         }
2298
2299                 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref  */
2300
2301                         /* check for negative sizes and copy sizes to stack if necessary  */
2302                         MCODECHECK((iptr->s1.argcount << 1) + 64);
2303
2304                         for (s1 = iptr->s1.argcount; --s1 >= 0;) {
2305                                 var = VAR(iptr->sx.s23.s2.args[s1]);
2306
2307                                 /* Already Preallocated? */
2308                                 if (!(var->flags & PREALLOC)) {
2309                                         s2 = emit_load(jd, iptr, var, REG_ITMP1);
2310                                         M_IST(s2, REG_SP, (s1 + 3) * 4);
2311                                 }
2312                         }
2313
2314                         /* a0 = dimension count */
2315                         M_IMOV_IMM(iptr->s1.argcount, REG_ITMP1);
2316                         M_IST(REG_ITMP1, REG_SP, 0*4);
2317
2318                         /* a1 = arraydescriptor */
2319                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2320                                 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo, iptr->sx.s23.s3.c.ref, 0);
2321                                 M_AMOV_IMM(0, REG_ATMP1);
2322                         } else  {
2323                                 M_AMOV_IMM(iptr->sx.s23.s3.c.cls, REG_ATMP1);
2324                         }
2325                         M_AST(REG_ATMP1, REG_SP, 1*4);
2326
2327                         /* a2 = pointer to dimensions = stack pointer */
2328                         M_AMOV(REG_SP, REG_ATMP1);
2329                         M_AADD_IMM(3*4, REG_ATMP1);
2330                         M_AST(REG_ATMP1, REG_SP, 2*4);
2331
2332                         M_JSR_IMM(BUILTIN_multianewarray);
2333
2334                         /* check for exception before result assignment */
2335                         emit_exception_check(cd, iptr);
2336
2337                         assert(VAROP(iptr->dst)->type == TYPE_ADR);
2338                         d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2339                         M_INT2ADRMOVE(REG_RESULT, d);
2340                         emit_store_dst(jd, iptr, d);
2341                         break;
2342
2343
2344
2345                 default:
2346                         printf("UNKNOWN OPCODE %d\n", iptr->opc);
2347                         exceptions_throw_internalerror("Unknown ICMD %d during code generation", iptr->opc);
2348                         return false;
2349         } /* switch */
2350         /* M_TPF; */ /* nop after each ICMD */
2351         } /* for each instruction */
2352
2353         /* At the end of a basic block we may have to append some nops,
2354            because the patcher stub calling code might be longer than the
2355            actual instruction. So codepatching does not change the
2356            following block unintentionally. */
2357
2358         if (cd->mcodeptr < cd->lastmcodeptr) {
2359                 while (cd->mcodeptr < cd->lastmcodeptr) {
2360                         M_NOP;
2361                 }
2362         }
2363
2364
2365         } /* if (btpre->flags >= BBREACHED) */
2366         } /* for each basic block */
2367
2368         /* generate stubs */
2369         emit_patcher_traps(jd);
2370
2371         return true;
2372 }
2373
2374 /* codegen_emit_stub_native ****************************************************
2375
2376    Emits a stub routine which calls a native method.
2377
2378 *******************************************************************************/
2379
2380 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
2381 {
2382         methodinfo   *m;
2383         codeinfo     *code;
2384         codegendata  *cd;
2385         registerdata *rd;
2386         methoddesc   *md;
2387         s4 i, j, t, s1, s2;
2388         
2389         /* get required compiler data */
2390
2391         m    = jd->m;
2392         code = jd->code;
2393         cd   = jd->cd;
2394         rd   = jd->rd;
2395
2396         md = m->parseddesc;
2397
2398         /* calc stackframe size */
2399         cd->stackframesize =
2400                 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
2401                 sizeof(localref_table) / SIZEOF_VOID_P +
2402                 nmd->memuse +
2403                 1 +                                             /* functionptr */
2404                 4;                                              /* args for codegen_start_native_call */
2405
2406         /* create method header */
2407         (void) dseg_add_unique_address(cd, code);                      /* CodeinfoPointer */
2408         (void) dseg_add_unique_s4(cd, cd->stackframesize * 8);         /* FrameSize       */
2409         (void) dseg_add_unique_s4(cd, 0);                              /* IsLeaf          */
2410         (void) dseg_add_unique_s4(cd, 0);                              /* IntSave         */
2411         (void) dseg_add_unique_s4(cd, 0);                              /* FltSave         */
2412
2413         /* generate code */
2414         M_AADD_IMM(-(cd->stackframesize*8), REG_SP);
2415
2416         /* put arguments for codegen_start_native_call onto stack */
2417         /* void codegen_start_native_call(u1 *datasp, u1 *pv, u1 *sp, u1 *ra) */
2418         
2419         M_AMOV(REG_SP, REG_ATMP1);
2420         M_AST(REG_ATMP1, REG_SP, 0 * 4);                /* currentsp */
2421
2422         M_AMOV_IMM(0, REG_ATMP2);                       /* 0 needs to patched */
2423         dseg_adddata(cd);                                   /* this patches it */
2424
2425         M_AST(REG_ATMP2, REG_SP, 1 * 4);                /* pv */
2426
2427         M_JSR_IMM(codegen_start_native_call);
2428
2429         /* remember class argument */
2430         if (m->flags & ACC_STATIC)
2431                 M_INT2ADRMOVE(REG_RESULT, REG_ATMP3);
2432
2433         /* copy arguments into stackframe */
2434         for (i = md->paramcount -1, j = i + skipparams; i >= 0; --i, --j)       {
2435                 t = md->paramtypes[i].type;
2436                 /* all arguments via stack */
2437                 assert(md->params[i].inmemory);                                         
2438
2439                 s1 = md->params[i].regoff + cd->stackframesize * 8 + 4;
2440                 s2 = nmd->params[j].regoff;
2441
2442                 /* simply copy argument stack */
2443                 M_ILD(REG_ITMP1, REG_SP, s1);
2444                 M_IST(REG_ITMP1, REG_SP, s2);
2445                 if (IS_2_WORD_TYPE(t))  {
2446                         M_ILD(REG_ITMP1, REG_SP, s1 + 4);
2447                         M_IST(REG_ITMP1, REG_SP, s2 + 4);
2448                 }
2449         }
2450
2451         /* builtins are not invoked like natives, environemtn and clazz are only needed for natives */
2452         if (m->flags & ACC_NATIVE)      {
2453                 /* for static function class as second arg */
2454                 if (m->flags & ACC_STATIC)
2455                         M_AST(REG_ATMP3, REG_SP, 1 * 4);
2456
2457                 /* env ist first argument */
2458                 M_AMOV_IMM(_Jv_env, REG_ATMP1);
2459                 M_AST(REG_ATMP1, REG_SP, 0 * 4);
2460         }
2461
2462         /* call the native function */
2463         M_AMOV_IMM(f, REG_ATMP2);
2464         M_JSR(REG_ATMP2);
2465
2466         /* save return value */
2467         switch (md->returntype.type)    {
2468                 case TYPE_VOID: break;
2469
2470                 /* natives return float arguments in %d0, %d1, cacao expects them in %fp0 */
2471                 case TYPE_DBL:
2472                 case TYPE_LNG:
2473                         M_IST(REG_D1, REG_SP, 2 * 8);
2474                         /* fall through */
2475
2476                 case TYPE_FLT:
2477                 case TYPE_INT:
2478                 case TYPE_ADR:
2479                         M_IST(REG_D0, REG_SP, 2 * 8);   /* XXX can this be correct ? */
2480                         break;
2481
2482                 default: assert(0);
2483         }
2484
2485         /* remove native stackframe info */
2486         /* therefore we call: java_objectheader *codegen_finish_native_call(u1 *datasp) */
2487
2488         M_AMOV(REG_SP, REG_ATMP1);
2489         M_AST(REG_ATMP1, REG_SP, 0 * 4);                /* currentsp */
2490
2491         M_AMOV_IMM(0, REG_ATMP2);                       /* 0 needs to patched */
2492         dseg_adddata(cd);                                   /* this patches it */
2493
2494         M_AST(REG_ATMP2, REG_SP, 1 * 4);                /* pv */
2495
2496         M_JSR_IMM(codegen_finish_native_call);
2497         
2498         M_INT2ADRMOVE(REG_RESULT, REG_ATMP1);
2499         /* restore return value */
2500         switch (md->returntype.type)    {
2501                 case TYPE_VOID: break;
2502
2503                 case TYPE_DBL:
2504                 case TYPE_LNG:          M_ILD(REG_D1, REG_SP, 2 * 8);
2505                         /* fall through */
2506                 case TYPE_FLT:
2507                 case TYPE_INT:
2508                 case TYPE_ADR:
2509                         M_ILD(REG_D0, REG_SP, 2 * 8);   /* XXX */
2510                         break;
2511
2512                 default: assert(0);
2513         }
2514 #if !defined(ENABLE_SOFTFLOAT)
2515                 /* additionally load values into floating points registers
2516                  * as cacao jit code expects them there */
2517         switch (md->returntype.type)    {
2518                 case TYPE_FLT:
2519                         M_FLD(REG_D0, REG_SP, 2 * 8);
2520                         break;
2521                 case TYPE_DBL:  
2522                         M_DLD(REG_D0, REG_SP, 2 * 8);   /* XXX */
2523                         break;
2524         }
2525 #endif
2526         /* restore saved registers */
2527
2528         M_AADD_IMM(cd->stackframesize*8, REG_SP);
2529         /* check for exception */
2530         M_ATST(REG_ATMP1);
2531         M_BNE(2);
2532         M_RET;
2533
2534         /* handle exception, REG_ATMP1 already contains exception object, REG_ATMP2 holds address */
2535         
2536         M_ALD(REG_ATMP2_XPC, REG_SP, 0);                /* take return address as faulting instruction */
2537         M_AADD_IMM(-2, REG_ATMP2_XPC);                  /* which is off by 2 */
2538         M_JMP_IMM(asm_handle_nat_exception);
2539
2540         /* should never be reached from within jit code*/
2541         M_JSR_IMM(0);
2542 }
2543
2544
2545 /*
2546  * These are local overrides for various environment variables in Emacs.
2547  * Please do not remove this and leave it at the end of the file, where
2548  * Emacs will automagically detect them.
2549  * ---------------------------------------------------------------------
2550  * Local variables:
2551  * mode: c
2552  * indent-tabs-mode: t
2553  * c-basic-offset: 4
2554  * tab-width: 4
2555  * End:
2556  * vim:noexpandtab:sw=4:ts=4:
2557  */