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