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