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