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