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