Merged with tip.
[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                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1998                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1999
2000                         assert(VAROP(iptr->s1 )->type == TYPE_ADR);
2001                         assert(VAROP(iptr->dst)->type == TYPE_INT);
2002
2003                         M_ICLR(d);
2004
2005                         /* if class is not resolved, check which code to call */
2006
2007                         if (super == NULL) {
2008                                 M_ATST(s1);
2009                                 emit_label_beq(cd, BRANCH_LABEL_1);
2010
2011                                 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags, iptr->sx.s23.s3.c.ref, 0);
2012
2013                                 M_IMOV_IMM32(0, REG_ITMP3);
2014                                 M_IAND_IMM(ACC_INTERFACE, REG_ITMP3);
2015                                 emit_label_beq(cd, BRANCH_LABEL_2);
2016                         }
2017
2018                         /* interface instanceof code */
2019
2020                         if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2021                                 if (super == NULL) {
2022                                         patcher_add_patch_ref(jd, PATCHER_instanceof_interface, iptr->sx.s23.s3.c.ref, 0);
2023                                 } else {
2024                                         M_ATST(s1);
2025                                         emit_label_beq(cd, BRANCH_LABEL_3);
2026                                 }
2027
2028                                 M_ALD(REG_ATMP1, s1, OFFSET(java_object_t, vftbl));
2029                                 M_ILD(REG_ITMP3, REG_ATMP1, OFFSET(vftbl_t, interfacetablelength));
2030                                 M_IADD_IMM(-superindex, REG_ITMP3);     /* -superindex may be patched patched */
2031                                 M_ITST(REG_ITMP3);
2032                                 M_BLE(10);
2033                                 M_ALD(REG_ATMP1, REG_ATMP1, OFFSET(vftbl_t, interfacetable[0]) - superindex * sizeof(methodptr*));      /* patch here too! */
2034                                 M_ATST(REG_ATMP1);
2035                                 M_BEQ(2);
2036                                 M_IMOV_IMM(1, d);
2037
2038                                 if (super == NULL)
2039                                         emit_label_br(cd, BRANCH_LABEL_4);
2040                                 else
2041                                         emit_label(cd, BRANCH_LABEL_3);
2042                         }
2043
2044                         /* class instanceof code */
2045
2046                         if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2047                                 if (super == NULL) {
2048                                         emit_label(cd, BRANCH_LABEL_2);
2049
2050                                         patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, 0);
2051                                         M_AMOV_IMM(0, REG_ATMP2);
2052                                 } else {
2053                                         M_AMOV_IMM(super->vftbl, REG_ATMP2);
2054                                         M_ATST(s1);
2055                                         emit_label_beq(cd, BRANCH_LABEL_5);
2056                                 }
2057
2058                                 M_ALD(REG_ATMP1, s1, OFFSET(java_object_t, vftbl));
2059
2060                                 M_ILD(REG_ITMP1, REG_ATMP1, OFFSET(vftbl_t, baseval));
2061                                 M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, baseval));
2062                                 M_ILD(REG_ITMP2, REG_ATMP2, OFFSET(vftbl_t, diffval));
2063
2064                                 M_ISUB(REG_ITMP3, REG_ITMP1);
2065                                 M_ICMP(REG_ITMP2, REG_ITMP1);
2066                                 M_BHI(4);
2067                                 M_IMOV_IMM(1, d);
2068                                 M_TPFW;                 /* overlaps next instruction */
2069                                 M_ICLR(d);
2070
2071                                 if (super != NULL)
2072                                         emit_label(cd, BRANCH_LABEL_5);
2073                         }
2074
2075                         if (super == NULL) {
2076                                 emit_label(cd, BRANCH_LABEL_1);
2077                                 emit_label(cd, BRANCH_LABEL_4);
2078                         }
2079
2080                         emit_store_dst(jd, iptr, d);
2081                         }
2082                         break;
2083
2084                 case ICMD_CHECKCAST:  /* ..., objectref ==> ..., objectref            */
2085                                       /* val.a: (classinfo*) superclass               */
2086
2087                         /*  superclass is an interface:
2088                          *
2089                          *  OK if ((sub == NULL) ||
2090                          *         (sub->vftbl->interfacetablelength > super->index) &&
2091                          *         (sub->vftbl->interfacetable[-super->index] != NULL));
2092                          *
2093                          *  superclass is a class:
2094                          *
2095                          *  OK if ((sub == NULL) || (0
2096                          *         <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2097                          *         super->vftbl->diffvall));
2098                          */
2099
2100                         if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2101                                 /* object type cast-check */
2102
2103                                 classinfo *super;
2104                                 s4         superindex;
2105
2106                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2107                                         super      = NULL;
2108                                         superindex = 0;
2109                                 }
2110                                 else {
2111                                         super      = iptr->sx.s23.s3.c.cls;
2112                                         superindex = super->index;
2113                                 }
2114
2115                                 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
2116                                 assert(VAROP(iptr->s1)->type == TYPE_ADR);
2117
2118                                 /* if class is not resolved, check which code to call */
2119
2120                                 if (super == NULL) {
2121                                         M_ATST(s1);
2122                                         emit_label_beq(cd, BRANCH_LABEL_1);
2123
2124                                         patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags, iptr->sx.s23.s3.c.ref, 0);
2125                         
2126                                         M_IMOV_IMM32(0, REG_ITMP2);
2127                                         M_IAND_IMM(ACC_INTERFACE, REG_ITMP2);
2128                                         emit_label_beq(cd, BRANCH_LABEL_2);
2129                                 }
2130
2131                                 /* interface checkcast code */
2132
2133                                 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2134                                         if (super == NULL) {
2135                                                 patcher_add_patch_ref(jd, PATCHER_checkcast_interface, iptr->sx.s23.s3.c.ref, 0);
2136                                         } else {
2137                                                 M_ATST(s1);
2138                                                 emit_label_beq(cd, BRANCH_LABEL_3);
2139                                         }
2140
2141                                         M_ALD(REG_ATMP2, s1, OFFSET(java_object_t, vftbl));
2142                                         M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, interfacetablelength));
2143         
2144                                         M_IADD_IMM(-superindex, REG_ITMP3);     /* superindex patched */
2145                                         M_ITST(REG_ITMP3);
2146                                         emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2147
2148                                         M_ALD(REG_ATMP3, REG_ATMP2, OFFSET(vftbl_t, interfacetable[0]) - superindex * sizeof(methodptr*));      /* patched*/
2149                                         M_ATST(REG_ATMP3);
2150                                         emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ATMP3, s1);
2151
2152                                         if (super == NULL)
2153                                                 emit_label_br(cd, BRANCH_LABEL_4);
2154                                         else
2155                                                 emit_label(cd, BRANCH_LABEL_3);
2156                                 }
2157
2158                                 /* class checkcast code */
2159
2160                                 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2161                                         if (super == NULL) {
2162                                                 emit_label(cd, BRANCH_LABEL_2);
2163
2164                                                 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, 0);
2165                                                 M_AMOV_IMM(0, REG_ATMP3);
2166                                         } else {
2167                                                 M_AMOV_IMM(super->vftbl, REG_ATMP3);
2168                                                 M_ATST(s1);
2169                                                 emit_label_beq(cd, BRANCH_LABEL_5);
2170                                         }
2171
2172                                         M_ALD(REG_ATMP2, s1, OFFSET(java_object_t, vftbl));
2173
2174                                         M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, baseval));  /* REG_ITMP3 == sub->vftbl->baseval */
2175                                         M_ILD(REG_ITMP1, REG_ATMP3, OFFSET(vftbl_t, baseval));
2176                                         M_ILD(REG_ITMP2, REG_ATMP3, OFFSET(vftbl_t, diffval));
2177
2178                                         M_ISUB(REG_ITMP1, REG_ITMP3);
2179                                         M_ICMP(REG_ITMP2, REG_ITMP3);   /* XXX was CMPU */
2180
2181                                         emit_classcast_check(cd, iptr, BRANCH_UGT, REG_ITMP3, s1); /* XXX was BRANCH_GT */
2182
2183                                         if (super != NULL)
2184                                                 emit_label(cd, BRANCH_LABEL_5);
2185                                 }
2186
2187                                 if (super == NULL) {
2188                                         emit_label(cd, BRANCH_LABEL_1);
2189                                         emit_label(cd, BRANCH_LABEL_4);
2190                                 }
2191
2192                                 d = codegen_reg_of_dst(jd, iptr, s1);
2193                         } else {
2194                                 /* array type cast-check */
2195
2196                                 s1 = emit_load_s1(jd, iptr, REG_ATMP2);
2197
2198                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2199                                         patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo, iptr->sx.s23.s3.c.ref, 0);
2200                                         M_AMOV_IMM(0, REG_ATMP1);
2201                                 } else {
2202                                         M_AMOV_IMM(iptr->sx.s23.s3.c.cls, REG_ATMP1);
2203                                 }
2204         
2205                                 M_APUSH(REG_ATMP1);
2206                                 M_APUSH(s1);
2207                                 M_JSR_IMM(BUILTIN_arraycheckcast);
2208                                 M_AADD_IMM(2*4, REG_SP);                /* pop arguments off stack */
2209                                 M_ITST(REG_RESULT);
2210                                 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2211
2212                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2213                                 d = codegen_reg_of_dst(jd, iptr, s1);
2214                         }
2215                         assert(VAROP(iptr->dst)->type == TYPE_ADR);
2216                         M_ADRMOVE(s1, d);
2217                         emit_store_dst(jd, iptr, d);
2218                         break;
2219
2220                 case ICMD_TABLESWITCH:  /* ..., index ==> ...                         */
2221                         {
2222                         s4 i, l;
2223                         branch_target_t *table;
2224
2225                         table = iptr->dst.table;
2226
2227                         l = iptr->sx.s23.s2.tablelow;
2228                         i = iptr->sx.s23.s3.tablehigh;
2229                         
2230                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2231                         M_INTMOVE(s1, REG_ITMP1);
2232                         if (l != 0) M_ISUB_IMM(l, REG_ITMP1);
2233
2234                         i = i - l + 1;
2235
2236                         /* range check */
2237                         M_ICMP_IMM(i - 1, REG_ITMP1);
2238                         emit_bugt(cd, table[0].block);
2239
2240                         /* build jump table top down and use address of lowest entry */
2241                         table += i;
2242
2243                         while (--i >= 0) {
2244                                 dseg_add_target(cd, table->block); 
2245                                 --table;
2246                         }
2247
2248                         /* length of dataseg after last dseg_add_target is used by load */
2249                         M_AMOV_IMM(0, REG_ATMP2);
2250                         dseg_adddata(cd);
2251
2252                         M_ISSL_IMM(2, REG_ITMP1);                       /* index * 4 == offset in table */
2253                         M_AADDINT(REG_ITMP1, REG_ATMP2);                /* offset in table */
2254                         M_AADD_IMM(-(cd->dseglen), REG_ATMP2);          /* start of table in dseg */
2255                         M_ALD(REG_ATMP1, REG_ATMP2, 0);
2256
2257                         M_JMP(REG_ATMP1);
2258                         ALIGNCODENOP;
2259                         }
2260                         break;
2261
2262                 case ICMD_LOOKUPSWITCH: /* ..., key ==> ...                           */
2263                         {
2264                         s4 i;
2265                         lookup_target_t *lookup;
2266
2267                         lookup = iptr->dst.lookup;
2268
2269                         i = iptr->sx.s23.s2.lookupcount;
2270                         
2271                         MCODECHECK((i<<2)+8);
2272                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2273
2274                         while (--i >= 0) {
2275                                 M_ICMP_IMM(lookup->value, s1);
2276                                 emit_beq(cd, lookup->target.block);
2277                                 lookup++;
2278                         }
2279
2280                         emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2281                         ALIGNCODENOP;
2282                         break;
2283                         }
2284
2285                 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref  */
2286
2287                         /* check for negative sizes and copy sizes to stack if necessary  */
2288                         MCODECHECK((iptr->s1.argcount << 1) + 64);
2289
2290                         for (s1 = iptr->s1.argcount; --s1 >= 0;) {
2291                                 var = VAR(iptr->sx.s23.s2.args[s1]);
2292
2293                                 /* Already Preallocated? */
2294                                 if (!(var->flags & PREALLOC)) {
2295                                         s2 = emit_load(jd, iptr, var, REG_ITMP1);
2296                                         M_IST(s2, REG_SP, (s1 + 3) * 4);
2297                                 }
2298                         }
2299
2300                         /* a0 = dimension count */
2301                         M_IMOV_IMM(iptr->s1.argcount, REG_ITMP1);
2302                         M_IST(REG_ITMP1, REG_SP, 0*4);
2303
2304                         /* a1 = arraydescriptor */
2305                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2306                                 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo, iptr->sx.s23.s3.c.ref, 0);
2307                                 M_AMOV_IMM(0, REG_ATMP1);
2308                         } else  {
2309                                 M_AMOV_IMM(iptr->sx.s23.s3.c.cls, REG_ATMP1);
2310                         }
2311                         M_AST(REG_ATMP1, REG_SP, 1*4);
2312
2313                         /* a2 = pointer to dimensions = stack pointer */
2314                         M_AMOV(REG_SP, REG_ATMP1);
2315                         M_AADD_IMM(3*4, REG_ATMP1);
2316                         M_AST(REG_ATMP1, REG_SP, 2*4);
2317
2318                         M_JSR_IMM(BUILTIN_multianewarray);
2319
2320                         /* check for exception before result assignment */
2321                         emit_exception_check(cd, iptr);
2322
2323                         assert(VAROP(iptr->dst)->type == TYPE_ADR);
2324                         d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2325                         M_INT2ADRMOVE(REG_RESULT, d);
2326                         emit_store_dst(jd, iptr, d);
2327                         break;
2328
2329
2330
2331                 default:
2332                         printf("UNKNOWN OPCODE %d\n", iptr->opc);
2333                         exceptions_throw_internalerror("Unknown ICMD %d during code generation", iptr->opc);
2334                         return false;
2335         } /* switch */
2336         /* M_TPF; */ /* nop after each ICMD */
2337         } /* for each instruction */
2338
2339         /* At the end of a basic block we may have to append some nops,
2340            because the patcher stub calling code might be longer than the
2341            actual instruction. So codepatching does not change the
2342            following block unintentionally. */
2343
2344         if (cd->mcodeptr < cd->lastmcodeptr) {
2345                 while (cd->mcodeptr < cd->lastmcodeptr) {
2346                         M_NOP;
2347                 }
2348         }
2349
2350
2351         } /* if (btpre->flags >= BBREACHED) */
2352         } /* for each basic block */
2353
2354         /* generate stubs */
2355         emit_patcher_traps(jd);
2356
2357         return true;
2358 }
2359
2360 /* codegen_emit_stub_native ****************************************************
2361
2362    Emits a stub routine which calls a native method.
2363
2364 *******************************************************************************/
2365
2366 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
2367 {
2368         methodinfo   *m;
2369         codeinfo     *code;
2370         codegendata  *cd;
2371         registerdata *rd;
2372         methoddesc   *md;
2373         s4 i, j, t, s1, s2;
2374         
2375         /* get required compiler data */
2376
2377         m    = jd->m;
2378         code = jd->code;
2379         cd   = jd->cd;
2380         rd   = jd->rd;
2381
2382         md = m->parseddesc;
2383
2384         /* calc stackframe size */
2385         cd->stackframesize =
2386                 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
2387                 sizeof(localref_table) / SIZEOF_VOID_P +
2388                 nmd->memuse +
2389                 1 +                                             /* functionptr */
2390                 4;                                              /* args for codegen_start_native_call */
2391
2392         /* create method header */
2393         (void) dseg_add_unique_address(cd, code);                      /* CodeinfoPointer */
2394         (void) dseg_add_unique_s4(cd, cd->stackframesize * 8);         /* FrameSize       */
2395         (void) dseg_add_unique_s4(cd, 0);                              /* IsLeaf          */
2396         (void) dseg_add_unique_s4(cd, 0);                              /* IntSave         */
2397         (void) dseg_add_unique_s4(cd, 0);                              /* FltSave         */
2398
2399         /* generate code */
2400         M_AADD_IMM(-(cd->stackframesize*8), REG_SP);
2401
2402         /* put arguments for codegen_start_native_call onto stack */
2403         /* void codegen_start_native_call(u1 *datasp, u1 *pv, u1 *sp, u1 *ra) */
2404         
2405         M_AMOV(REG_SP, REG_ATMP1);
2406         M_AST(REG_ATMP1, REG_SP, 0 * 4);                /* currentsp */
2407
2408         M_AMOV_IMM(0, REG_ATMP2);                       /* 0 needs to patched */
2409         dseg_adddata(cd);                                   /* this patches it */
2410
2411         M_AST(REG_ATMP2, REG_SP, 1 * 4);                /* pv */
2412
2413         M_JSR_IMM(codegen_start_native_call);
2414
2415         /* remember class argument */
2416         if (m->flags & ACC_STATIC)
2417                 M_INT2ADRMOVE(REG_RESULT, REG_ATMP3);
2418
2419         /* copy arguments into stackframe */
2420         for (i = md->paramcount -1, j = i + skipparams; i >= 0; --i, --j)       {
2421                 t = md->paramtypes[i].type;
2422                 /* all arguments via stack */
2423                 assert(md->params[i].inmemory);                                         
2424
2425                 s1 = md->params[i].regoff + cd->stackframesize * 8 + 4;
2426                 s2 = nmd->params[j].regoff;
2427
2428                 /* simply copy argument stack */
2429                 M_ILD(REG_ITMP1, REG_SP, s1);
2430                 M_IST(REG_ITMP1, REG_SP, s2);
2431                 if (IS_2_WORD_TYPE(t))  {
2432                         M_ILD(REG_ITMP1, REG_SP, s1 + 4);
2433                         M_IST(REG_ITMP1, REG_SP, s2 + 4);
2434                 }
2435         }
2436
2437         /* builtins are not invoked like natives, environemtn and clazz are only needed for natives */
2438         if (m->flags & ACC_NATIVE)      {
2439                 /* for static function class as second arg */
2440                 if (m->flags & ACC_STATIC)
2441                         M_AST(REG_ATMP3, REG_SP, 1 * 4);
2442
2443                 /* env ist first argument */
2444                 M_AMOV_IMM(_Jv_env, REG_ATMP1);
2445                 M_AST(REG_ATMP1, REG_SP, 0 * 4);
2446         }
2447
2448         /* call the native function */
2449         M_AMOV_IMM(f, REG_ATMP2);
2450         M_JSR(REG_ATMP2);
2451
2452         /* save return value */
2453         switch (md->returntype.type)    {
2454                 case TYPE_VOID: break;
2455
2456                 /* natives return float arguments in %d0, %d1, cacao expects them in %fp0 */
2457                 case TYPE_DBL:
2458                 case TYPE_LNG:
2459                         M_IST(REG_D1, REG_SP, 2 * 8);
2460                         /* fall through */
2461
2462                 case TYPE_FLT:
2463                 case TYPE_INT:
2464                 case TYPE_ADR:
2465                         M_IST(REG_D0, REG_SP, 2 * 8);   /* XXX can this be correct ? */
2466                         break;
2467
2468                 default: assert(0);
2469         }
2470
2471         /* remove native stackframe info */
2472         /* therefore we call: java_objectheader *codegen_finish_native_call(u1 *datasp) */
2473
2474         M_AMOV(REG_SP, REG_ATMP1);
2475         M_AST(REG_ATMP1, REG_SP, 0 * 4);                /* currentsp */
2476
2477         M_AMOV_IMM(0, REG_ATMP2);                       /* 0 needs to patched */
2478         dseg_adddata(cd);                                   /* this patches it */
2479
2480         M_AST(REG_ATMP2, REG_SP, 1 * 4);                /* pv */
2481
2482         M_JSR_IMM(codegen_finish_native_call);
2483         
2484         M_INT2ADRMOVE(REG_RESULT, REG_ATMP1);
2485         /* restore return value */
2486         switch (md->returntype.type)    {
2487                 case TYPE_VOID: break;
2488
2489                 case TYPE_DBL:
2490                 case TYPE_LNG:          M_ILD(REG_D1, REG_SP, 2 * 8);
2491                         /* fall through */
2492                 case TYPE_FLT:
2493                 case TYPE_INT:
2494                 case TYPE_ADR:
2495                         M_ILD(REG_D0, REG_SP, 2 * 8);   /* XXX */
2496                         break;
2497
2498                 default: assert(0);
2499         }
2500 #if !defined(ENABLE_SOFTFLOAT)
2501                 /* additionally load values into floating points registers
2502                  * as cacao jit code expects them there */
2503         switch (md->returntype.type)    {
2504                 case TYPE_FLT:
2505                         M_FLD(REG_D0, REG_SP, 2 * 8);
2506                         break;
2507                 case TYPE_DBL:  
2508                         M_DLD(REG_D0, REG_SP, 2 * 8);   /* XXX */
2509                         break;
2510         }
2511 #endif
2512         /* restore saved registers */
2513
2514         M_AADD_IMM(cd->stackframesize*8, REG_SP);
2515         /* check for exception */
2516         M_ATST(REG_ATMP1);
2517         M_BNE(2);
2518         M_RET;
2519
2520         /* handle exception, REG_ATMP1 already contains exception object, REG_ATMP2 holds address */
2521         
2522         M_ALD(REG_ATMP2_XPC, REG_SP, 0);                /* take return address as faulting instruction */
2523         M_AADD_IMM(-2, REG_ATMP2_XPC);                  /* which is off by 2 */
2524         M_JMP_IMM(asm_handle_nat_exception);
2525
2526         /* should never be reached from within jit code*/
2527         M_JSR_IMM(0);
2528 }
2529
2530
2531 /*
2532  * These are local overrides for various environment variables in Emacs.
2533  * Please do not remove this and leave it at the end of the file, where
2534  * Emacs will automagically detect them.
2535  * ---------------------------------------------------------------------
2536  * Local variables:
2537  * mode: c
2538  * indent-tabs-mode: t
2539  * c-basic-offset: 4
2540  * tab-width: 4
2541  * End:
2542  * vim:noexpandtab:sw=4:ts=4:
2543  */