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