36d01bb245f118cf8d0c7d3bc46f1dabf0fa1cc9
[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                 case ICMD_D2F:       /* ..., value  ==> ..., (float) value           */
901                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
902                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
903                         M_D2F(s1, d);
904                         emit_store_dst(jd, iptr, d);
905                         break;
906
907
908
909                 #endif
910
911                 /* load/store/copy/move operations ************************************/
912
913                 case ICMD_ILOAD:      /* ...  ==> ..., content of local variable      */
914                 case ICMD_ALOAD:      /* s1 = local variable                          */
915                 case ICMD_LLOAD:
916                 case ICMD_FLOAD:  
917                 case ICMD_DLOAD:  
918                 case ICMD_ISTORE:     /* ..., value  ==> ...                          */
919                 case ICMD_LSTORE:
920                 case ICMD_FSTORE:
921                 case ICMD_DSTORE: 
922                 case ICMD_COPY:
923                 case ICMD_MOVE:
924
925                         emit_copy(jd, iptr);
926                         break;
927
928                 case ICMD_ASTORE:
929
930                         if (!(iptr->flags.bits & INS_FLAG_RETADDR))
931                                 emit_copy(jd, iptr);
932                         break;
933
934
935                 case ICMD_ACONST:     /* ...  ==> ..., constant                       */
936                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
937
938                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
939                                 constant_classref *cr = iptr->sx.val.c.ref;;
940                                 codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo, cr, 0);
941                                 M_AMOV_IMM(0, d);
942                         } else {
943                                 M_AMOV_IMM(iptr->sx.val.anyptr, d);
944                         }
945                         emit_store_dst(jd, iptr, d);
946                         break;
947                 /* BRANCH *************************************************************/
948
949                 case ICMD_ATHROW:       /* ..., objectref ==> ... (, objectref)       */
950
951                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
952                         M_ADRMOVE(s1, REG_ATMP1_XPTR);
953
954 #ifdef ENABLE_VERIFIER
955                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
956                                 unresolved_class *uc = iptr->sx.s23.s2.uc;
957
958                                 codegen_addpatchref(cd, PATCHER_resolve_class, uc, 0);
959                         }
960 #endif /* ENABLE_VERIFIER */
961                         M_JSR_PCREL(2);                         /* get current PC */
962                         M_APOP(REG_ATMP2);              
963
964                         M_AMOV_IMM(asm_handle_exception, REG_ATMP3);
965                         M_JMP(REG_ATMP3);
966                         ALIGNCODENOP;
967                         break;
968
969                 case ICMD_GOTO:         /* ... ==> ...                                */
970                 case ICMD_RET:          /* ... ==> ...                                */
971
972                         emit_br(cd, iptr->dst.block);
973                         ALIGNCODENOP;
974                         break;
975
976                 case ICMD_JSR:          /* ... ==> ...                                */
977
978                         emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
979                         ALIGNCODENOP;
980                         break;
981
982
983
984                 case ICMD_IFNULL:       /* ..., value ==> ...                         */
985                 case ICMD_IFNONNULL:
986                         assert(IS_ADR_TYPE(VAROP(iptr->s1)->type));
987                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
988                         M_ATST(s1);
989                         emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, BRANCH_OPT_NONE);
990                         break;
991
992                 case ICMD_IFLT:
993                 case ICMD_IFLE:
994                 case ICMD_IFNE:
995                 case ICMD_IFGT:
996                 case ICMD_IFGE:
997                 case ICMD_IFEQ:         /* ..., value ==> ...                         */
998
999                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1000                         assert (VAROP(iptr->s1)->type == TYPE_INT);
1001                         M_ICMP_IMM(iptr->sx.val.i, s1); 
1002                         emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFEQ, BRANCH_OPT_NONE);
1003                         break;
1004
1005                 case ICMD_IF_ICMPEQ:    /* ..., value, value ==> ...                  */
1006                 case ICMD_IF_ICMPNE:
1007                 case ICMD_IF_ICMPLT:
1008                 case ICMD_IF_ICMPGT:
1009                 case ICMD_IF_ICMPLE:
1010                 case ICMD_IF_ICMPGE:
1011
1012                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1013                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1014                         M_ICMP(s2, s1);
1015                         emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ICMPEQ, BRANCH_OPT_NONE);
1016                         break;
1017
1018                 case ICMD_IF_ACMPEQ:    /* op1 = target JavaVM pc                     */
1019                 case ICMD_IF_ACMPNE:
1020
1021                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1022                         s2 = emit_load_s2(jd, iptr, REG_ATMP2);
1023                         M_ACMP(s1, s2);
1024                         emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ACMPEQ, BRANCH_OPT_NONE);
1025                         break;
1026
1027
1028                 /* MEMORY *************************************************************/
1029                 case ICMD_GETSTATIC:
1030                         if (INSTRUCTION_IS_UNRESOLVED(iptr))    {
1031                                 uf        = iptr->sx.s23.s3.uf;
1032                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1033                                 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, 0);
1034                         } else  {
1035                                 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1036
1037                                 fieldtype = fi->type;
1038                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1039                                         codegen_addpatchref(cd, PATCHER_initialize_class, fi->class, 0);
1040                                 }
1041
1042                                 disp = (ptrint) &(fi->value);
1043                         }
1044                         M_AMOV_IMM(disp, REG_ATMP1);
1045                         switch (fieldtype) {
1046 #if defined(ENABLE_SOFTFLOAT)
1047                         case TYPE_FLT:
1048 #endif
1049                         case TYPE_INT:
1050                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1051                                 M_ILD(d, REG_ATMP1, 0);
1052                                 break;
1053                         case TYPE_ADR:
1054                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1055                                 M_ALD(d, REG_ATMP1, 0);
1056                                 break;
1057 #if defined(ENABLE_SOFTFLOAT)
1058                         case TYPE_DBL:
1059 #endif
1060                         case TYPE_LNG:
1061                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
1062                                 M_LLD(d, REG_ATMP1, 0);
1063                                 break;
1064 #if !defined(ENABLE_SOFTFLOAT)
1065                         case TYPE_FLT:
1066                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1067                                 M_FLD(d, REG_ATMP1, 0);
1068                                 break;
1069                         case TYPE_DBL:                          
1070                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1071                                 M_DLD(d, REG_ATMP1, 0);
1072                                 break;
1073 #endif
1074                         }
1075                         emit_store_dst(jd, iptr, d);
1076                         break;
1077
1078                 case ICMD_PUTSTATIC:  /* ..., value  ==> ...                          */
1079
1080                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1081                                 uf        = iptr->sx.s23.s3.uf;
1082                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1083
1084                                 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, 0);
1085                         } else {
1086                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1087                                 fieldtype = fi->type;
1088                                 disp      = &(fi->value);
1089
1090                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1091                                         codegen_addpatchref(cd, PATCHER_initialize_class, fi->class, 0);
1092                         }
1093                 
1094                         M_AMOV_IMM(disp, REG_ATMP1);
1095                         switch (fieldtype) {
1096 #if defined(ENABLE_SOFTFLOAT)
1097                         case TYPE_FLT:
1098 #endif
1099                         case TYPE_INT:
1100                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1101                                 M_IST(s1, REG_ATMP1, 0);
1102                                 break;
1103 #if defined(ENABLE_SOFTFLOAT)
1104                         case TYPE_DBL:
1105 #endif
1106                         case TYPE_LNG:
1107                                 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
1108                                 M_LST(s1, REG_ATMP1, 0);
1109                                 break;
1110                         case TYPE_ADR:
1111                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1112                                 M_AST(s1, REG_ATMP1, 0);
1113                                 break;
1114 #if !defined(ENABLE_SOFTFLOAT)
1115                         case TYPE_FLT:
1116                                 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1117                                 M_FST(s1, REG_ATMP1, 0);
1118                                 break;
1119                         case TYPE_DBL:
1120                                 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1121                                 M_DST(s1, REG_ATMP1, 0);
1122                                 break;
1123 #endif
1124                         default: assert(0);
1125                         }
1126                         break;
1127
1128                 case ICMD_GETFIELD:   /* ...  ==> ..., value                          */
1129
1130                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1131
1132                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1133                                 uf        = iptr->sx.s23.s3.uf;
1134                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1135                                 disp      = 0;
1136
1137                                 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
1138                         }
1139                         else {
1140                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1141                                 fieldtype = fi->type;
1142                                 disp      = fi->offset;
1143                         }
1144
1145                         /* implicit null-pointer check */
1146                         switch (fieldtype) {
1147 #if defined(ENABLE_SOFTFLOAT)
1148                         case TYPE_FLT:
1149 #endif
1150                         case TYPE_INT:
1151                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1152                                 M_ILD(d, s1, disp);
1153                                 break;
1154 #if defined(ENABLE_SOFTFLOAT)
1155                         case TYPE_DBL:
1156 #endif
1157                         case TYPE_LNG:
1158                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1159                                 M_LLD(d, s1, disp);
1160                                 break;
1161                         case TYPE_ADR:
1162                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1163                                 M_ALD(d, s1, disp);
1164                                 break;
1165 #if !defined(ENABLE_SOFTFLOAT)
1166                         case TYPE_FLT:
1167                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1168                                 M_FLD(d, s1, disp);
1169                                 break;
1170                         case TYPE_DBL:                          
1171                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1172                                 M_DLD(d, s1, disp);
1173                                 break;
1174 #endif
1175                         }
1176                         emit_store_dst(jd, iptr, d);
1177                         break;
1178
1179                 case ICMD_PUTFIELD:   /* ..., value  ==> ...                          */
1180
1181                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1182
1183                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1184                                 uf        = iptr->sx.s23.s3.uf;
1185                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1186                                 disp      = 0;
1187                         }
1188                         else {
1189                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1190                                 fieldtype = fi->type;
1191                                 disp      = fi->offset;
1192                         }
1193
1194                         if (IS_INT_LNG_TYPE(fieldtype)) {
1195                                 if (IS_2_WORD_TYPE(fieldtype)) {
1196                                         s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
1197                                 } else {
1198                                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1199                                 }
1200                         } else {
1201                                 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1202                         }
1203
1204                         if (INSTRUCTION_IS_UNRESOLVED(iptr))
1205                                 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
1206
1207                         /* implicit null-pointer check */
1208                         switch (fieldtype) {
1209 #if defined(ENABLE_SOFTFLOAT)
1210                         case TYPE_FLT:
1211 #endif
1212                         case TYPE_INT:
1213                                 M_IST(s2, s1, disp);
1214                                 break;
1215
1216 #if defined(ENABLE_SOFTFLOAT)
1217                         case TYPE_DBL:
1218 #endif
1219                         case TYPE_LNG:
1220                                 M_LST(s2, s1, disp);  
1221                                 break;
1222                         case TYPE_ADR:
1223                                 M_AST(s2, s1, disp);
1224                                 break;
1225 #if !defined(ENABLE_SOFTFLOAT)
1226                         case TYPE_FLT:
1227                                 M_FST(s2, s1, disp);
1228                                 break;
1229                         case TYPE_DBL:
1230                                 M_DST(s2, s1, disp);
1231                                 break;
1232 #endif
1233                         }
1234                         break;
1235
1236                 case ICMD_ARRAYLENGTH: /* ..., arrayref  ==> ..., length              */
1237
1238                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1239                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1240                         /* implicit null-pointer check */
1241                         M_ILD(d, s1, OFFSET(java_arrayheader, size));
1242                         emit_store_dst(jd, iptr, d);
1243                         break;
1244
1245                 case ICMD_BALOAD:     /* ..., arrayref, index  ==> ..., value         */
1246
1247                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1248                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1249                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1250                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1251                         M_INTMOVE(s2, REG_ITMP2);
1252                         M_IADD_IMM(OFFSET(java_bytearray, data[0]), REG_ITMP2);
1253                         M_ADRMOVE(s1, REG_ATMP1);
1254                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1255                         /* implicit null-pointer check */
1256                         M_LBZX(REG_ATMP1, d);
1257                         M_BSEXT(d, d);
1258                         emit_store_dst(jd, iptr, d);
1259                         break;                  
1260
1261                 case ICMD_CALOAD:     /* ..., arrayref, index  ==> ..., value         */
1262
1263                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1264                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1265                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1266                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1267                         M_INTMOVE(s2, REG_ITMP2);
1268                         M_ISSL_IMM(1, REG_ITMP2);
1269                         M_IADD_IMM(OFFSET(java_chararray, data[0]), REG_ITMP2);
1270                         M_ADRMOVE(s1, REG_ATMP1);
1271                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1272                         /* implicit null-pointer check */
1273                         M_LHZX(REG_ATMP1, d);
1274                         M_CZEXT(d, d);
1275                         emit_store_dst(jd, iptr, d);
1276                         break;
1277
1278                 case ICMD_SALOAD:     /* ..., arrayref, index  ==> ..., value         */
1279
1280                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1281                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1282                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1283                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1284                         M_INTMOVE(s2, REG_ITMP2);
1285                         M_ISSL_IMM(1, REG_ITMP2);
1286                         M_IADD_IMM(OFFSET(java_shortarray, data[0]), REG_ITMP2);
1287                         M_ADRMOVE(s1, REG_ATMP1);
1288                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1289                 
1290                         /* implicit null-pointer check */
1291                         M_LHZX(REG_ATMP1, d);
1292                         M_SSEXT(d, d);
1293                         emit_store_dst(jd, iptr, d);
1294                         break;
1295
1296                 case ICMD_IALOAD:     /* ..., arrayref, index  ==> ..., value         */
1297
1298                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1299                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1300                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1301                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1302                         M_INTMOVE(s2, REG_ITMP2);
1303                         M_ISSL_IMM(2, REG_ITMP2);
1304                         M_IADD_IMM(OFFSET(java_intarray, data[0]), REG_ITMP2);
1305                         M_ADRMOVE(s1, REG_ATMP1);
1306                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1307                         /* implicit null-pointer check */
1308                         M_LWZX(REG_ATMP1, d);
1309                         emit_store_dst(jd, iptr, d);
1310                         break;
1311
1312                 case ICMD_LALOAD:     /* ..., arrayref, index  ==> ..., value         */
1313                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1314                         s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1315                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1316                         /* implicit null-pointer check */
1317                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1318                         M_INTMOVE(s2, REG_ITMP1);
1319                         M_ISSL_IMM(3, REG_ITMP1);
1320                         M_IADD_IMM(OFFSET(java_longarray, data[0]), REG_ITMP1);
1321                         M_ADRMOVE(s1, REG_ATMP1);
1322                         M_AADDINT(REG_ITMP1, REG_ATMP1);
1323                         /* implicit null-pointer check */
1324                         M_LLD(d, REG_ATMP1, 0);
1325                         emit_store_dst(jd, iptr, d);
1326                         break;
1327
1328                 case ICMD_FALOAD:     /* ..., arrayref, index  ==> ..., value         */
1329                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1330                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1331                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1332                         M_INTMOVE(s2, REG_ITMP2);
1333                         M_ISSL_IMM(2, REG_ITMP2);
1334                         M_IADD_IMM(OFFSET(java_floatarray, data[0]), REG_ITMP2);
1335                         M_ADRMOVE(s1, REG_ATMP1);
1336                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1337                         /* implicit null-pointer check */
1338 #if !defined(ENABLE_SOFTFLOAT)
1339                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1340                         M_FLD(d, REG_ATMP1, 0);
1341 #else
1342                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1343                         M_LWZX(REG_ATMP1, d);
1344 #endif
1345                         emit_store_dst(jd, iptr, d);
1346                         break;
1347
1348                 case ICMD_DALOAD:     /* ..., arrayref, index  ==> ..., value         */
1349                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1350                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1351                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1352                         M_INTMOVE(s2, REG_ITMP2);
1353                         M_ISSL_IMM(3, REG_ITMP2);
1354                         M_IADD_IMM(OFFSET(java_doublearray, data[0]), REG_ITMP2);
1355                         M_ADRMOVE(s1, REG_ATMP1);
1356                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1357                         /* implicit null-pointer check */
1358 #if !defined(ENABLE_SOFTFLOAT)
1359                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1360                         M_DLD(d, REG_ATMP1, 0);
1361 #else
1362                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1363                         M_LLD(d, REG_ATMP1, 0);
1364 #endif
1365                         emit_store_dst(jd, iptr, d);
1366                         break;
1367
1368                 case ICMD_AALOAD:     /* ..., arrayref, index  ==> ..., value         */
1369                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1370                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1371                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1372                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1373                         M_INTMOVE(s2, REG_ITMP2);
1374                         M_ISSL_IMM(2, REG_ITMP2);
1375                         M_IADD_IMM(OFFSET(java_objectarray, data[0]), REG_ITMP2);
1376                         M_ADRMOVE(s1, REG_ATMP1);
1377                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1378         
1379                         /* implicit null-pointer check */
1380                         M_LAX(REG_ATMP1, d);
1381                         emit_store_dst(jd, iptr, d);
1382                         break;
1383
1384
1385                 case ICMD_BASTORE:    /* ..., arrayref, index, value  ==> ...         */
1386                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1387                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1388                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1389                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1390                         M_INTMOVE(s2, REG_ITMP2);
1391                         M_IADD_IMM(OFFSET(java_bytearray, data[0]), REG_ITMP2);
1392                         M_ADRMOVE(s1, REG_ATMP1);
1393                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1394                         /* implicit null-pointer check */
1395                         M_STBX(REG_ATMP1, s3);
1396                         break;
1397
1398                 case ICMD_CASTORE:    /* ..., arrayref, index, value  ==> ...         */
1399                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
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_ISSL_IMM(1, REG_ITMP2);
1405                         M_IADD_IMM(OFFSET(java_chararray, data[0]), REG_ITMP2); 
1406                         M_ADRMOVE(s1, REG_ATMP1);
1407                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1408                         /* implicit null-pointer check */
1409                         M_STHX(REG_ATMP1, s3);
1410                         break;
1411
1412                 case ICMD_SASTORE:    /* ..., arrayref, index, value  ==> ...         */
1413                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1414                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1415                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1416                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1417                         M_INTMOVE(s2, REG_ITMP2);
1418                         M_ISSL_IMM(1, REG_ITMP2);
1419                         M_IADD_IMM(OFFSET(java_shortarray, data[0]), REG_ITMP2);
1420                         M_ADRMOVE(s1, REG_ATMP1);
1421                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1422                         /* implicit null-pointer check */
1423                         M_STHX(REG_ATMP1, s3);
1424                         break;
1425
1426                 case ICMD_IASTORE:    /* ..., arrayref, index, value  ==> ...         */
1427                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1428                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1429                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1430                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1431                         M_INTMOVE(s2, REG_ITMP2);
1432                         M_ISSL_IMM(2, REG_ITMP2);
1433                         M_IADD_IMM(OFFSET(java_intarray, data[0]), REG_ITMP2);
1434                         M_ADRMOVE(s1, REG_ATMP1);
1435                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1436                         /* implicit null-pointer check */
1437                         M_STWX(REG_ATMP1, s3);
1438                         break;
1439
1440                 case ICMD_LASTORE:    /* ..., arrayref, index, value  ==> ...         */
1441                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1442                         s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1443                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1444
1445                         M_INTMOVE(s2, REG_ITMP1);
1446                         M_ISSL_IMM(3, REG_ITMP1);
1447                         M_IADD_IMM(OFFSET(java_longarray, data[0]), REG_ITMP1);
1448                         M_ADRMOVE(s1, REG_ATMP1);
1449                         M_AADDINT(REG_ITMP1, REG_ATMP1);
1450                         /* implicit null-pointer check */
1451                         s3 = emit_load_s3(jd, iptr, REG_ITMP12_PACKED);
1452                         M_LST(s3, REG_ATMP1, 0);
1453                         break;
1454
1455                 case ICMD_FASTORE:    /* ..., arrayref, index, value  ==> ...         */
1456                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1457                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1458                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1459                         M_INTMOVE(s2, REG_ITMP2);
1460                         M_ISSL_IMM(2, REG_ITMP2);
1461                         M_IADD_IMM(OFFSET(java_floatarray, data[0]), REG_ITMP2);
1462                         M_ADRMOVE(s1, REG_ATMP1);
1463                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1464                         /* implicit null-pointer check */
1465 #if !defined(ENABLE_SOFTFLOAT)
1466                         s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1467                         M_FST(s3, REG_ATMP1, 0);
1468 #else
1469                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1470                         M_STWX(REG_ATMP1, s3);
1471 #endif
1472                         break;
1473
1474                 case ICMD_DASTORE:    /* ..., arrayref, index, value  ==> ...         */
1475                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1476                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1477                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1478                         M_INTMOVE(s2, REG_ITMP2);
1479                         M_ISSL_IMM(3, REG_ITMP2);
1480                         M_IADD_IMM(OFFSET(java_doublearray, data[0]), REG_ITMP2);
1481                         M_ADRMOVE(s1, REG_ATMP1);
1482                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1483                         /* implicit null-pointer check */
1484 #if !defined(ENABLE_SOFTFLOAT)
1485                         s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1486                         M_DST(s3, REG_ATMP1, 0);
1487 #else
1488                         s3 = emit_load_s3(jd, iptr, REG_ITMP12_PACKED);
1489                         /* implicit null-pointer check */
1490                         M_LST(s3, REG_ATMP1, 0);
1491 #endif
1492                         break;
1493
1494                 case ICMD_AASTORE:    /* ..., arrayref, index, value  ==> ...         */
1495
1496                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1497                         s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1498                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1499                         s3 = emit_load_s3(jd, iptr, REG_ATMP2);
1500
1501                         /* XXX what if array is NULL */
1502                         disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1503
1504                         M_AST(s1, REG_SP, 0*4);
1505                         M_AST(s3, REG_SP, 1*4);
1506                         M_JSR_IMM(BUILTIN_canstore);    
1507                         emit_exception_check(cd, iptr);
1508
1509                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1510                         s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1511                         s3 = emit_load_s3(jd, iptr, REG_ATMP2);
1512                         M_INTMOVE(s2, REG_ITMP1);
1513                         M_ISSL_IMM(2, REG_ITMP1);
1514                         M_IADD_IMM(OFFSET(java_objectarray, data[0]), REG_ITMP1);
1515                         M_ADRMOVE(s1, REG_ATMP1);
1516                         M_AADDINT(REG_ITMP1, REG_ATMP1);
1517                         /* implicit null-pointer check */
1518                         M_STAX(REG_ATMP1, s3);
1519                         break;
1520
1521
1522
1523                 /* METHOD INVOCATION *********************************************************/
1524                 case ICMD_BUILTIN:      /* ..., [arg1, [arg2 ...]] ==> ...            */
1525                         bte = iptr->sx.s23.s3.bte;
1526                         md  = bte->md;
1527                         goto gen_method;
1528
1529                 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ...            */
1530                 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
1531                 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer    */
1532                 case ICMD_INVOKEINTERFACE:
1533                         REPLACEMENT_POINT_INVOKE(cd, iptr);
1534
1535                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1536                                 lm = NULL;
1537                                 um = iptr->sx.s23.s3.um;
1538                                 md = um->methodref->parseddesc.md;
1539                         }
1540                         else {
1541                                 lm = iptr->sx.s23.s3.fmiref->p.method;
1542                                 um = NULL;
1543                                 md = lm->parseddesc;
1544                         }
1545         gen_method:
1546                         s3 = md->paramcount;
1547         
1548                         MCODECHECK((s3 << 1) + 64);
1549
1550                         /* copy arguments to stack */
1551                         for (s3 = s3 - 1; s3 >= 0; s3--)        {
1552                                 var = VAR(iptr->sx.s23.s2.args[s3]);
1553                                 /* already preallocated */
1554                                 if (var->flags & PREALLOC) continue;
1555                 
1556                                 if (!md->params[s3].inmemory) assert(0);
1557
1558                                 switch (var->type)      {
1559 #if defined(ENABLE_SOFTFLOAT)
1560                                         case TYPE_DBL:
1561 #endif
1562                                         case TYPE_LNG:
1563                                                 d = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
1564                                                 M_LST(d, REG_SP, md->params[s3].regoff*4);
1565                                                 break;
1566 #if defined(ENABLE_SOFTFLOAT)
1567                                         case TYPE_FLT:
1568 #endif
1569                                         case TYPE_INT:
1570                                                 d = emit_load(jd, iptr, var, REG_ITMP1);
1571                                                 M_IST(d, REG_SP, md->params[s3].regoff*4);
1572                                                 break;
1573                                         case TYPE_ADR:
1574                                                 d = emit_load(jd, iptr, var, REG_ATMP1);
1575                                                 M_AST(d, REG_SP, md->params[s3].regoff*4);
1576                                                 break;
1577 #if !defined(ENABLE_SOFTFLOAT)
1578                                         case TYPE_FLT:
1579                                                 d = emit_load(jd, iptr, var, REG_FTMP1);
1580                                                 M_FST(d, REG_SP, md->params[s3].regoff*4);
1581                                                 break;
1582                                         case TYPE_DBL:
1583                                                 d = emit_load(jd, iptr, var, REG_FTMP1);
1584                                                 M_DST(d, REG_SP, md->params[s3].regoff*4);
1585                                                 break;
1586 #endif
1587                                         default:
1588                                                 assert(0);
1589                                 }
1590                         }
1591
1592                         /* arguments in place now */
1593                         switch(iptr->opc)       {
1594                                 case ICMD_BUILTIN: 
1595                                         disp = (ptrint) bte->fp;
1596                                         d = md->returntype.type;
1597                                         M_JSR_IMM(disp);
1598
1599                                         REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1600                                         emit_exception_check(cd, iptr);
1601                                         break;
1602
1603                                 case ICMD_INVOKESPECIAL: 
1604                                         /* adress register for sure */
1605                                         M_ALD(REG_ATMP1, REG_SP, 0);
1606                                         emit_nullpointer_check(cd, iptr, REG_ATMP1);
1607                                         /* fall through */
1608                                 case ICMD_INVOKESTATIC: 
1609                                         if (lm == NULL) {
1610                                                 codegen_addpatchref(cd, PATCHER_invokestatic_special, um, 0);
1611                                                 disp = 0;
1612                                                 M_AMOV_IMM(disp, REG_ATMP1);
1613                                         } else  {
1614                                                 disp = lm->stubroutine;
1615                                                 M_AMOV_IMM(disp, REG_ATMP1);
1616                                         }
1617
1618                                         /* generate the actual call */
1619                                         M_JSR(REG_ATMP1);
1620                                         REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1621                                         break;
1622
1623
1624                                 case ICMD_INVOKEVIRTUAL:
1625                                         if (lm == NULL) {
1626                                                 codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
1627                                                 s1 = 0;
1628                                         } else {
1629                                                 s1 = OFFSET(vftbl_t, table[0]) + sizeof(methodptr) * lm->vftblindex;
1630                                         }
1631                                         /* load object pointer (==argument 0) */
1632                                         M_ALD(REG_ATMP1, REG_SP, 0);
1633                                         /* implicit null-pointer check */
1634                                         M_ALD(REG_METHODPTR, REG_ATMP1, OFFSET(java_objectheader, vftbl));
1635                                         M_ALD(REG_ATMP3, REG_METHODPTR, s1);
1636                                         /* generate the actual call */
1637                                         M_JSR(REG_ATMP3);
1638                                         break;
1639                                 case ICMD_INVOKEINTERFACE: 
1640                                         if (lm == NULL) {
1641                                                 codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
1642
1643                                                 s1 = 0;
1644                                                 s2 = 0;
1645                                         } else {
1646                                                 s1 = OFFSET(vftbl_t, interfacetable[0]) - sizeof(methodptr*) * lm->class->index;
1647                                                 s2 = sizeof(methodptr) * (lm - lm->class->methods);
1648                                         }
1649                                         /* load object pointer (==argument 0) */
1650                                         M_ALD(REG_ATMP1, REG_SP, 0);
1651
1652                                         /* implicit null-pointer check */
1653                                         M_ALD(REG_METHODPTR, REG_ATMP1, OFFSET(java_objectheader, vftbl));
1654                                         M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
1655                                         M_ALD(REG_ATMP3, REG_METHODPTR, s2);
1656
1657                                         /* generate the actual call */
1658                                         M_JSR(REG_ATMP3);
1659                                         REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1660                                         break;
1661
1662                                 default: assert(0);
1663                                 }       /* switch (iptr->opc) */
1664
1665                                 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1666                                 
1667                                 /* store return value */
1668                                 d = md->returntype.type;
1669
1670                                 switch (d)      {
1671                                         case TYPE_VOID: break;
1672 #if defined(ENABLE_SOFTFLOAT)
1673                                         case TYPE_FLT:
1674 #endif
1675                                         case TYPE_INT:
1676                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
1677                                                 M_INTMOVE(REG_RESULT, s1);
1678                                                 break;
1679 #if defined(ENABLE_SOFTFLOAT)
1680                                         case TYPE_DBL:
1681 #endif
1682                                         case TYPE_LNG:
1683                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
1684                                                 M_LNGMOVE(REG_RESULT_PACKED, s1);
1685                                                 break;
1686                                         case TYPE_ADR:
1687                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_ATMP1);
1688                                                 /* all stuff is returned in %d0 */
1689                                                 M_INT2ADRMOVE(REG_RESULT, s1);
1690                                                 break;
1691 #if !defined(ENABLE_SOFTFLOAT)
1692                                         /*
1693                                          *      for BUILTINS float values are returned in %d0,%d1
1694                                          *      within cacao we use %fp0 for that.
1695                                          */
1696                                         case TYPE_FLT:
1697                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1698                                                 if (iptr->opc == ICMD_BUILTIN)  {
1699                                                         M_INT2FLTMOVE(REG_FRESULT, s1);
1700                                                 } else  {
1701                                                         M_FLTMOVE(REG_FRESULT, s1);
1702                                                 }
1703                                                 break;
1704                                         case TYPE_DBL:
1705                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1706                                                 if (iptr->opc == ICMD_BUILTIN)  {
1707                                                         M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 4);
1708                                                         M_DLD(s1, REG_SP, rd->memuse * 4);
1709                                                 } else  {
1710                                                         M_DBLMOVE(REG_FRESULT, s1);
1711                                                 }
1712                                                 break;
1713 #endif
1714                                         default:
1715                                                 assert(0);
1716                                 }
1717                                 if (d != TYPE_VOID) emit_store_dst(jd, iptr, s1);
1718                         break; /* ICMD_INVOKE* */
1719
1720 #if defined(ENABLE_SOFTFLOAT)
1721                 case ICMD_FRETURN:
1722 #endif
1723                 case ICMD_IRETURN:      /* ..., retvalue ==> ...                      */
1724
1725                         REPLACEMENT_POINT_RETURN(cd, iptr);
1726                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
1727                         M_INTMOVE(s1, REG_RESULT);
1728                         goto nowperformreturn;
1729
1730                 case ICMD_ARETURN:      /* ..., retvalue ==> ...                      */
1731
1732                         REPLACEMENT_POINT_RETURN(cd, iptr);
1733                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
1734                         assert(VAROP(iptr->s1)->type == TYPE_ADR);
1735                         M_ADR2INTMOVE(s1, REG_RESULT);
1736
1737 #ifdef ENABLE_VERIFIER
1738                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1739                                 unresolved_class *uc = iptr->sx.s23.s2.uc;
1740
1741                                 codegen_addpatchref(cd, PATCHER_resolve_class, uc, 0);
1742                         }
1743 #endif /* ENABLE_VERIFIER */
1744                         goto nowperformreturn;
1745
1746 #if defined(ENABLE_SOFTFLOAT)
1747                 case ICMD_DRETURN:
1748 #endif
1749                 case ICMD_LRETURN:      /* ..., retvalue ==> ...                      */
1750                         REPLACEMENT_POINT_RETURN(cd, iptr);
1751                         s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
1752                         M_LNGMOVE(s1, REG_RESULT_PACKED);
1753                         goto nowperformreturn;
1754
1755 #if !defined(ENABLE_SOFTFLOAT)
1756                 case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
1757                         REPLACEMENT_POINT_RETURN(cd, iptr);
1758                         s1 = emit_load_s1(jd, iptr, REG_FRESULT);
1759                         M_FLTMOVE(s1, REG_FRESULT);
1760                         goto nowperformreturn;
1761
1762                 case ICMD_DRETURN:
1763                         REPLACEMENT_POINT_RETURN(cd, iptr);
1764                         s1 = emit_load_s1(jd, iptr, REG_FRESULT);
1765                         M_DBLMOVE(s1, REG_FRESULT);
1766                         goto nowperformreturn;
1767
1768 #endif
1769
1770                 case ICMD_RETURN:      /* ...  ==> ...                                */
1771
1772                         REPLACEMENT_POINT_RETURN(cd, iptr);
1773
1774 nowperformreturn:
1775                         {
1776                         s4 i, p;
1777                         
1778                         p = cd->stackframesize;
1779
1780                         /* call trace function */
1781 #if !defined(NDEBUG)
1782                         emit_verbosecall_exit(jd);
1783 #endif
1784
1785 #if defined(ENABLE_THREADS)
1786                         /* call lock_monitor_exit */
1787                         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
1788                                 M_ILD(REG_ITMP3, REG_SP, rd->memuse * 4 + 2*4);
1789
1790                                 /* we need to save the proper return value */
1791                                 /* we do not care for the long -> doubel convert space here */
1792                                 switch (iptr->opc) {
1793 #if defined(ENABLE_SOFTFLOAT)
1794                                 case ICMD_DRETURN:
1795 #endif
1796                                 case ICMD_LRETURN:
1797                                         M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 4);
1798                                         break;
1799 #if defined(ENABLE_SOFTFLOAT)
1800                                 case ICMD_FRETURN:
1801 #endif
1802                                 case ICMD_IRETURN:
1803                                 case ICMD_ARETURN:
1804                                         M_IST(REG_RESULT , REG_SP, rd->memuse * 4);
1805                                         break;
1806 #if !defined(ENABLE_SOFTFLOAT)
1807                                 case ICMD_FRETURN:
1808                                         M_FST(REG_FRESULT, REG_SP, rd->memuse * 4);
1809                                         break;
1810                                 case ICMD_DRETURN:
1811                                         M_DST(REG_FRESULT, REG_SP, rd->memuse * 4);
1812                                         break;
1813 #endif
1814                                 }
1815
1816                                 M_IST(REG_ITMP3, REG_SP, 0 * 4);
1817                                 M_JSR_IMM(LOCK_monitor_exit);
1818
1819                                 /* and now restore the proper return value */
1820                                 switch (iptr->opc) {
1821
1822 #if defined(ENABLE_SOFTFLOAT)
1823                                 case ICMD_DRETURN:
1824 #endif
1825                                 case ICMD_LRETURN:
1826                                         M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 4);
1827                                         break;
1828 #if defined(ENABLE_SOFTFLOAT)
1829                                 case ICMD_FRETURN:
1830 #endif
1831                                 case ICMD_IRETURN:
1832                                 case ICMD_ARETURN:
1833                                         M_ILD(REG_RESULT , REG_SP, rd->memuse * 4);
1834                                         break;
1835 #if !defined(ENABLE_SOFTFLOAT)
1836                                 case ICMD_FRETURN:
1837                                         M_FLD(REG_FRESULT, REG_SP, rd->memuse * 4);
1838                                         break;
1839                                 case ICMD_DRETURN:
1840                                         M_DLD(REG_FRESULT, REG_SP, rd->memuse * 4);
1841                                         break;
1842 #endif
1843                                 }
1844                         }
1845 #endif
1846
1847
1848                         /* restore return address                                         */
1849 #if 0
1850                         if (!jd->isleafmethod) {
1851                                 /* ATTENTION: Don't use REG_ZERO (r0) here, as M_ALD
1852                                    may have a displacement overflow. */
1853
1854                                 M_ALD(REG_ITMP1, REG_SP, p * 4 + LA_LR_OFFSET);
1855                                 M_MTLR(REG_ITMP1);
1856                         }
1857 #endif
1858                         /* restore saved registers                                        */
1859
1860                         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
1861                                 p--; M_ILD(rd->savintregs[i], REG_SP, p * 4);
1862                         }
1863                         for (i=ADR_SAV_CNT-1; i>=rd->savadrreguse; --i) {
1864                                 p--; M_ALD(rd->savadrregs[i], REG_SP, p*4);
1865                         }
1866 #if !defined(ENABLE_SOFTFLOAT)
1867                         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
1868                                 p -= 2; M_DLD(rd->savfltregs[i], REG_SP, p * 4);
1869                         }
1870 #endif
1871                         /* deallocate stack                                               */
1872                         M_AADD_IMM(cd->stackframesize*4, REG_SP);
1873                         M_RET;
1874                         }
1875                         break;
1876
1877                 /* the evil ones */
1878                 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
1879                                       /* val.a: (classinfo*) superclass               */
1880
1881                         /*  superclass is an interface:
1882                          *
1883                          *  return (sub != NULL) &&
1884                          *         (sub->vftbl->interfacetablelength > super->index) &&
1885                          *         (sub->vftbl->interfacetable[-super->index] != NULL);
1886                          *
1887                          *  superclass is a class:
1888                          *
1889                          *  return ((sub != NULL) && (0
1890                          *          <= (sub->vftbl->baseval - super->vftbl->baseval) <=
1891                          *          super->vftbl->diffvall));
1892                          */
1893
1894                         {
1895                         classinfo *super;
1896                         s4         superindex;
1897
1898                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1899                                 super      = NULL;
1900                                 superindex = 0;
1901                         }
1902                         else {
1903                                 super      = iptr->sx.s23.s3.c.cls;
1904                                 superindex = super->index;
1905                         }
1906                         
1907                         if ((super == NULL) || !(super->flags & ACC_INTERFACE))
1908                                 CODEGEN_CRITICAL_SECTION_NEW;
1909
1910                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1911                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1912
1913                         assert(VAROP(iptr->s1 )->type == TYPE_ADR);
1914                         assert(VAROP(iptr->dst)->type == TYPE_INT);
1915
1916                         M_ICLR(d);
1917
1918                         /* if class is not resolved, check which code to call */
1919
1920                         if (super == NULL) {
1921                                 M_ATST(s1);
1922                                 emit_label_beq(cd, BRANCH_LABEL_1);
1923
1924                                 codegen_addpatchref(cd, PATCHER_resolve_classref_to_flags, iptr->sx.s23.s3.c.ref, 0);
1925
1926                                 M_IMOV_IMM32(0, REG_ITMP3);
1927                                 M_IAND_IMM(ACC_INTERFACE, REG_ITMP3);
1928                                 emit_label_beq(cd, BRANCH_LABEL_2);
1929                         }
1930
1931                         /* interface instanceof code */
1932
1933                         if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
1934                                 if (super == NULL) {
1935                                         codegen_addpatchref(cd, PATCHER_instanceof_interface, iptr->sx.s23.s3.c.ref, 0);
1936                                 } else {
1937                                         M_ATST(s1);
1938                                         emit_label_beq(cd, BRANCH_LABEL_3);
1939                                 }
1940
1941                                 M_ALD(REG_ATMP1, s1, OFFSET(java_objectheader, vftbl));
1942                                 M_ILD(REG_ITMP3, REG_ATMP1, OFFSET(vftbl_t, interfacetablelength));
1943                                 M_IADD_IMM(-superindex, REG_ITMP3);     /* -superindex may be patched patched */
1944                                 M_ITST(REG_ITMP3);
1945                                 M_BLE(10);
1946                                 M_ALD(REG_ATMP1, REG_ATMP1, OFFSET(vftbl_t, interfacetable[0]) - superindex * sizeof(methodptr*));      /* patch here too! */
1947                                 M_ATST(REG_ATMP1);
1948                                 M_BEQ(2);
1949                                 M_IMOV_IMM(1, d);
1950
1951                                 if (super == NULL)
1952                                         emit_label_br(cd, BRANCH_LABEL_4);
1953                                 else
1954                                         emit_label(cd, BRANCH_LABEL_3);
1955                         }
1956
1957                         /* class instanceof code */
1958
1959                         if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
1960                                 if (super == NULL) {
1961                                         emit_label(cd, BRANCH_LABEL_2);
1962
1963                                         codegen_addpatchref(cd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, 0);
1964                                         M_AMOV_IMM(0, REG_ATMP2);
1965                                 } else {
1966                                         M_AMOV_IMM(super->vftbl, REG_ATMP2);
1967                                         M_ATST(s1);
1968                                         emit_label_beq(cd, BRANCH_LABEL_5);
1969                                 }
1970
1971                                 M_ALD(REG_ATMP1, s1, OFFSET(java_objectheader, vftbl));
1972
1973                                 CODEGEN_CRITICAL_SECTION_START;
1974
1975                                 M_ILD(REG_ITMP1, REG_ATMP1, OFFSET(vftbl_t, baseval));
1976                                 M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, baseval));
1977                                 M_ILD(REG_ITMP2, REG_ATMP2, OFFSET(vftbl_t, diffval));
1978
1979                                 CODEGEN_CRITICAL_SECTION_END;
1980
1981                                 M_ISUB(REG_ITMP3, REG_ITMP1);
1982                                 M_ICMP(REG_ITMP2, REG_ITMP1);
1983                                 M_BHI(4);
1984                                 M_IMOV_IMM(1, d);
1985                                 M_TPFW;                 /* overlaps next instruction */
1986                                 M_ICLR(d);
1987
1988                                 if (super != NULL)
1989                                         emit_label(cd, BRANCH_LABEL_5);
1990                         }
1991
1992                         if (super == NULL) {
1993                                 emit_label(cd, BRANCH_LABEL_1);
1994                                 emit_label(cd, BRANCH_LABEL_4);
1995                         }
1996
1997                         emit_store_dst(jd, iptr, d);
1998                         }
1999                         break;
2000
2001                 case ICMD_CHECKCAST:  /* ..., objectref ==> ..., objectref            */
2002                                       /* val.a: (classinfo*) superclass               */
2003
2004                         /*  superclass is an interface:
2005                          *
2006                          *  OK if ((sub == NULL) ||
2007                          *         (sub->vftbl->interfacetablelength > super->index) &&
2008                          *         (sub->vftbl->interfacetable[-super->index] != NULL));
2009                          *
2010                          *  superclass is a class:
2011                          *
2012                          *  OK if ((sub == NULL) || (0
2013                          *         <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2014                          *         super->vftbl->diffvall));
2015                          */
2016
2017                         if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2018                                 /* object type cast-check */
2019
2020                                 classinfo *super;
2021                                 s4         superindex;
2022
2023                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2024                                         super      = NULL;
2025                                         superindex = 0;
2026                                 }
2027                                 else {
2028                                         super      = iptr->sx.s23.s3.c.cls;
2029                                         superindex = super->index;
2030                                 }
2031
2032                                 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2033                                         CODEGEN_CRITICAL_SECTION_NEW;
2034
2035                                 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
2036                                 assert(VAROP(iptr->s1)->type == TYPE_ADR);
2037
2038                                 /* if class is not resolved, check which code to call */
2039
2040                                 if (super == NULL) {
2041                                         M_ATST(s1);
2042                                         emit_label_beq(cd, BRANCH_LABEL_1);
2043
2044                                         codegen_addpatchref(cd, PATCHER_resolve_classref_to_flags, iptr->sx.s23.s3.c.ref, 0);
2045                         
2046                                         M_IMOV_IMM32(0, REG_ITMP2);
2047                                         M_IAND_IMM(ACC_INTERFACE, REG_ITMP2);
2048                                         emit_label_beq(cd, BRANCH_LABEL_2);
2049                                 }
2050
2051                                 /* interface checkcast code */
2052
2053                                 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2054                                         if (super == NULL) {
2055                                                 codegen_addpatchref(cd, PATCHER_checkcast_interface, iptr->sx.s23.s3.c.ref, 0);
2056                                         } else {
2057                                                 M_ATST(s1);
2058                                                 emit_label_beq(cd, BRANCH_LABEL_3);
2059                                         }
2060
2061                                         M_ALD(REG_ATMP2, s1, OFFSET(java_objectheader, vftbl));
2062                                         M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, interfacetablelength));
2063         
2064                                         M_IADD_IMM(-superindex, REG_ITMP3);     /* superindex patched */
2065                                         M_ITST(REG_ITMP3);
2066                                         emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2067
2068                                         M_ALD(REG_ATMP3, REG_ATMP2, OFFSET(vftbl_t, interfacetable[0]) - superindex * sizeof(methodptr*));      /* patched*/
2069                                         M_ATST(REG_ATMP3);
2070                                         emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ATMP3, s1);
2071
2072                                         if (super == NULL)
2073                                                 emit_label_br(cd, BRANCH_LABEL_4);
2074                                         else
2075                                                 emit_label(cd, BRANCH_LABEL_3);
2076                                 }
2077
2078                                 /* class checkcast code */
2079
2080                                 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2081                                         if (super == NULL) {
2082                                                 emit_label(cd, BRANCH_LABEL_2);
2083
2084                                                 codegen_addpatchref(cd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, 0);
2085                                                 M_AMOV_IMM(0, REG_ATMP3);
2086                                         } else {
2087                                                 M_AMOV_IMM(super->vftbl, REG_ATMP3);
2088                                                 M_ATST(s1);
2089                                                 emit_label_beq(cd, BRANCH_LABEL_5);
2090                                         }
2091
2092                                         M_ALD(REG_ATMP2, s1, OFFSET(java_objectheader, vftbl));
2093
2094                                         CODEGEN_CRITICAL_SECTION_START;
2095
2096                                         M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, baseval));  /* REG_ITMP3 == sub->vftbl->baseval */
2097                                         M_ILD(REG_ITMP1, REG_ATMP3, OFFSET(vftbl_t, baseval));
2098                                         M_ILD(REG_ITMP2, REG_ATMP3, OFFSET(vftbl_t, diffval));
2099
2100                                         CODEGEN_CRITICAL_SECTION_END;
2101
2102                                         M_ISUB(REG_ITMP1, REG_ITMP3);
2103                                         M_ICMP(REG_ITMP2, REG_ITMP3);   /* XXX was CMPU */
2104
2105                                         emit_classcast_check(cd, iptr, BRANCH_UGT, REG_ITMP3, s1); /* XXX was BRANCH_GT */
2106
2107                                         if (super != NULL)
2108                                                 emit_label(cd, BRANCH_LABEL_5);
2109                                 }
2110
2111                                 if (super == NULL) {
2112                                         emit_label(cd, BRANCH_LABEL_1);
2113                                         emit_label(cd, BRANCH_LABEL_4);
2114                                 }
2115
2116                                 d = codegen_reg_of_dst(jd, iptr, s1);
2117                         } else {
2118                                 /* array type cast-check */
2119
2120                                 s1 = emit_load_s1(jd, iptr, REG_ATMP2);
2121
2122                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2123                                         codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo, iptr->sx.s23.s3.c.ref, 0);
2124                                         M_AMOV_IMM(0, REG_ATMP1);
2125                                 } else {
2126                                         M_AMOV_IMM(iptr->sx.s23.s3.c.cls, REG_ATMP1);
2127                                 }
2128         
2129                                 M_APUSH(REG_ATMP1);
2130                                 M_APUSH(s1);
2131                                 M_JSR_IMM(BUILTIN_arraycheckcast);
2132                                 M_AADD_IMM(2*4, REG_SP);                /* pop arguments off stack */
2133                                 M_ITST(REG_RESULT);
2134                                 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2135
2136                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2137                                 d = codegen_reg_of_dst(jd, iptr, s1);
2138                         }
2139                         assert(VAROP(iptr->dst)->type == TYPE_ADR);
2140                         M_ADRMOVE(s1, d);
2141                         emit_store_dst(jd, iptr, d);
2142                         break;
2143
2144                 case ICMD_TABLESWITCH:  /* ..., index ==> ...                         */
2145                         {
2146                         s4 i, l;
2147                         branch_target_t *table;
2148
2149                         table = iptr->dst.table;
2150
2151                         l = iptr->sx.s23.s2.tablelow;
2152                         i = iptr->sx.s23.s3.tablehigh;
2153                         
2154                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2155                         M_INTMOVE(s1, REG_ITMP1);
2156                         if (l != 0) M_ISUB_IMM(l, REG_ITMP1);
2157
2158                         i = i - l + 1;
2159
2160                         /* range check */
2161                         M_ICMP_IMM(i - 1, REG_ITMP1);
2162                         emit_bugt(cd, table[0].block);
2163
2164                         /* build jump table top down and use address of lowest entry */
2165                         table += i;
2166
2167                         while (--i >= 0) {
2168                                 dseg_add_target(cd, table->block); 
2169                                 --table;
2170                         }
2171
2172                         /* length of dataseg after last dseg_add_target is used by load */
2173                         M_AMOV_IMM(0, REG_ATMP2);
2174                         dseg_adddata(cd);
2175
2176                         M_ISSL_IMM(2, REG_ITMP1);                       /* index * 4 == offset in table */
2177                         M_AADDINT(REG_ITMP1, REG_ATMP2);                /* offset in table */
2178                         M_AADD_IMM(-(cd->dseglen), REG_ATMP2);          /* start of table in dseg */
2179                         M_ALD(REG_ATMP1, REG_ATMP2, 0);
2180
2181                         M_JMP(REG_ATMP1);
2182                         ALIGNCODENOP;
2183                         }
2184                         break;
2185
2186                 case ICMD_LOOKUPSWITCH: /* ..., key ==> ...                           */
2187                         {
2188                         s4 i;
2189                         lookup_target_t *lookup;
2190
2191                         lookup = iptr->dst.lookup;
2192
2193                         i = iptr->sx.s23.s2.lookupcount;
2194                         
2195                         MCODECHECK((i<<2)+8);
2196                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2197
2198                         while (--i >= 0) {
2199                                 M_ICMP_IMM(lookup->value, s1);
2200                                 emit_beq(cd, lookup->target.block);
2201                                 lookup++;
2202                         }
2203
2204                         emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2205                         ALIGNCODENOP;
2206                         break;
2207                         }
2208
2209                 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref  */
2210
2211                         /* check for negative sizes and copy sizes to stack if necessary  */
2212                         MCODECHECK((iptr->s1.argcount << 1) + 64);
2213
2214                         for (s1 = iptr->s1.argcount; --s1 >= 0;) {
2215                                 var = VAR(iptr->sx.s23.s2.args[s1]);
2216
2217                                 /* Already Preallocated? */
2218                                 if (!(var->flags & PREALLOC)) {
2219                                         s2 = emit_load(jd, iptr, var, REG_ITMP1);
2220                                         M_IST(s2, REG_SP, (s1 + 3) * 4);
2221                                 }
2222                         }
2223
2224                         /* a0 = dimension count */
2225                         M_IMOV_IMM(iptr->s1.argcount, REG_ITMP1);
2226                         M_IST(REG_ITMP1, REG_SP, 0*4);
2227
2228                         /* a1 = arraydescriptor */
2229                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2230                                 codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo, iptr->sx.s23.s3.c.ref, 0);
2231                                 M_AMOV_IMM(0, REG_ATMP1);
2232                         } else  {
2233                                 M_AMOV_IMM(iptr->sx.s23.s3.c.cls, REG_ATMP1);
2234                         }
2235                         M_AST(REG_ATMP1, REG_SP, 1*4);
2236
2237                         /* a2 = pointer to dimensions = stack pointer */
2238                         M_AMOV(REG_SP, REG_ATMP1);
2239                         M_AADD_IMM(3*4, REG_ATMP1);
2240                         M_AST(REG_ATMP1, REG_SP, 2*4);
2241
2242                         M_JSR_IMM(BUILTIN_multianewarray);
2243
2244                         /* check for exception before result assignment */
2245                         emit_exception_check(cd, iptr);
2246
2247                         assert(VAROP(iptr->dst)->type == TYPE_ADR);
2248                         d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2249                         M_INT2ADRMOVE(REG_RESULT, d);
2250                         emit_store_dst(jd, iptr, d);
2251                         break;
2252
2253
2254
2255                 default:
2256                         printf("UNKNOWN OPCODE %d\n", iptr->opc);
2257                         exceptions_throw_internalerror("Unknown ICMD %d during code generation", iptr->opc);
2258                         return false;
2259         } /* switch */
2260         M_TPF;
2261         } /* for each instruction */
2262         } /* if (btpre->flags >= BBREACHED) */
2263         } /* for each basic block */
2264
2265         dseg_createlinenumbertable(cd);
2266
2267         /* generate stubs */
2268         emit_patcher_stubs(jd);
2269         REPLACEMENT_EMIT_STUBS(jd);
2270
2271         return true;
2272 }
2273
2274
2275 /* codegen_emit_stub_compiler **************************************************
2276
2277    Emits a stub routine which calls the compiler.
2278         
2279 *******************************************************************************/
2280
2281 void codegen_emit_stub_compiler(jitdata *jd)
2282 {
2283         methodinfo  *m;
2284         codegendata *cd;
2285
2286         /* get required compiler data */
2287
2288         m  = jd->m;
2289         cd = jd->cd;
2290
2291         /* code for the stub */
2292
2293         M_AMOV_IMM(m, REG_ATMP1);
2294         M_AMOV_IMM(asm_call_jit_compiler, REG_ATMP3);
2295         M_JMP(REG_ATMP3);
2296 }
2297
2298
2299 /* codegen_emit_stub_native ****************************************************
2300
2301    Emits a stub routine which calls a native method.
2302
2303 *******************************************************************************/
2304
2305 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
2306 {
2307         methodinfo   *m;
2308         codeinfo     *code;
2309         codegendata  *cd;
2310         registerdata *rd;
2311         methoddesc   *md;
2312         s4 nativeparams, i, j, t, s1, s2;
2313         
2314         /* get required compiler data */
2315
2316         m    = jd->m;
2317         code = jd->code;
2318         cd   = jd->cd;
2319         rd   = jd->rd;
2320
2321         md = m->parseddesc;
2322         nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
2323
2324         /* calc stackframe size */
2325         cd->stackframesize =    sizeof(stackframeinfo) / SIZEOF_VOID_P +
2326                                 sizeof(localref_table) / SIZEOF_VOID_P +
2327                                 nmd->memuse +
2328                                 1 +                                             /* functionptr */
2329                                 4;                                              /* args for codegen_start_native_call */
2330
2331         /* create method header */
2332         (void) dseg_add_unique_address(cd, code);                      /* CodeinfoPointer */
2333         (void) dseg_add_unique_s4(cd, cd->stackframesize * 4);         /* FrameSize       */
2334         (void) dseg_add_unique_s4(cd, 0);                              /* IsSync          */
2335         (void) dseg_add_unique_s4(cd, 0);                              /* IsLeaf          */
2336         (void) dseg_add_unique_s4(cd, 0);                              /* IntSave         */
2337         (void) dseg_add_unique_s4(cd, 0);                              /* FltSave         */
2338         (void) dseg_addlinenumbertablesize(cd);
2339         (void) dseg_add_unique_s4(cd, 0);                              /* ExTableSize     */
2340
2341         /* print call trace */
2342 #if !defined(NDEBUG)
2343         if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
2344                 emit_verbosecall_enter(jd);
2345         }
2346 #endif
2347
2348         /* generate code */
2349         M_AADD_IMM(-(cd->stackframesize*4), REG_SP);
2350
2351         /* get function address (this must happen before the stackframeinfo) */
2352 #if !defined(WITH_STATIC_CLASSPATH)
2353         if (f == NULL)  {
2354                 codegen_addpatchref(cd, PATCHER_resolve_native_function, m, 0);
2355         }
2356 #endif
2357         M_AMOV_IMM(f, REG_ATMP2); /* do not move this line, the patcher is needed */
2358
2359         M_AST(REG_ATMP2, REG_SP, 4 * 4);
2360
2361         /* put arguments for codegen_start_native_call onto stack */
2362         /* void codegen_start_native_call(u1 *datasp, u1 *pv, u1 *sp, u1 *ra) */
2363         
2364         M_AMOV(REG_SP, REG_ATMP1);
2365         M_AADD_IMM(cd->stackframesize * 4, REG_ATMP1);
2366
2367         M_ALD(REG_ATMP3, REG_ATMP1, 0 * 4);
2368         M_AST(REG_ATMP3, REG_SP, 3 * 4);                /* ra */
2369
2370         M_AST(REG_ATMP1, REG_SP, 0 * 4);                /* datasp */
2371
2372         M_AADD_IMM(1 * 4 , REG_ATMP1);                  
2373         M_AST(REG_ATMP1, REG_SP, 2 * 4);                /* sp */
2374
2375         M_AMOV_IMM(0, REG_ATMP2);                       /* 0 needs to patched */
2376         dseg_adddata(cd);                                   /* this patches it */
2377
2378         M_AST(REG_ATMP2, REG_SP, 1 * 4);                /* pv */
2379
2380         M_JSR_IMM(codegen_start_native_call);
2381
2382         /* load function pointer */
2383         M_ALD(REG_ATMP2, REG_SP, 4 * 4);
2384
2385         /* copy arguments into stackframe */
2386         for (i = md->paramcount -1, j = i + nativeparams; i >= 0; --i, --j)     {
2387                 t = md->paramtypes[i].type;
2388                 /* all arguments via stack */
2389                 assert(md->params[i].inmemory);                                         
2390
2391                 s1 = (md->params[i].regoff + cd->stackframesize + 1) * 4;
2392                 s2 = nmd->params[j].regoff * 4;
2393
2394                 /* simply copy argument stack */
2395                 M_ILD(REG_ITMP1, REG_SP, s1);
2396                 M_IST(REG_ITMP1, REG_SP, s2);
2397                 if (IS_2_WORD_TYPE(t))  {
2398                         M_ILD(REG_ITMP1, REG_SP, s1 + 4);
2399                         M_IST(REG_ITMP1, REG_SP, s2 + 4);
2400                 }
2401         }
2402
2403         /* for static function class as second arg */
2404         if (m->flags & ACC_STATIC)      {
2405                 M_AMOV_IMM(m->class, REG_ATMP1);
2406                 M_AST(REG_ATMP1, REG_SP, 1 * 4);
2407         }
2408         /* env ist first argument */
2409         M_AMOV_IMM(_Jv_env, REG_ATMP1);
2410         M_AST(REG_ATMP1, REG_SP, 0 * 4);
2411
2412         /* call the native function */
2413         M_JSR(REG_ATMP2);
2414
2415         /* save return value */
2416         switch (md->returntype.type)    {
2417                 case TYPE_VOID: break;
2418
2419 #if defined(ENABLE_SOFTFLOAT)
2420                 case TYPE_DBL:
2421 #endif
2422                 case TYPE_LNG:
2423                         M_IST(REG_D1, REG_SP, 2 * 4);
2424                         /* fall through */
2425
2426 #if defined(ENABLE_SOFTFLOAT)
2427                 case TYPE_FLT:
2428 #endif
2429                 case TYPE_INT:
2430                 case TYPE_ADR:
2431                         M_IST(REG_D0, REG_SP, 1 * 4);
2432                         break;
2433
2434 #if !defined(ENABLE_SOFTFLOAT)
2435                 /* natives return float arguments in %d0, %d1, cacao expects them in %fp0 */
2436                 case TYPE_FLT:
2437                         M_INT2FLTMOVE(REG_D0, REG_D0);
2438                         M_FST(REG_D0, REG_SP, 1 * 4);
2439                         break;
2440                 case TYPE_DBL:  
2441                         /* to convert %d0, %d1 to dbl we need 2 memory slots
2442                          * it is safe reuse argument stack slots here */
2443                         M_IST(REG_D0, REG_SP, 1 * 4);
2444                         M_IST(REG_D1, REG_SP, 2 * 4);
2445                         /*M_DST(REG_D0, REG_SP, 1 * 4);*/
2446                         break;
2447 #endif
2448                 default: assert(0);
2449         }
2450         
2451         /* print call trace */
2452 #if ! defined(NDEBUG)
2453         if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
2454                 emit_verbosecall_exit(jd);
2455         }
2456 #endif
2457         /* remove native stackframe info */
2458         /* therefore we call: java_objectheader *codegen_finish_native_call(u1 *datasp) */
2459
2460         M_AMOV(REG_SP, REG_ATMP3);
2461         M_AADD_IMM(cd->stackframesize * 4, REG_ATMP3);
2462         M_AST(REG_ATMP3, REG_SP, 0 * 4);                        /* datasp */
2463         M_JSR_IMM(codegen_finish_native_call);
2464         
2465         M_INT2ADRMOVE(REG_RESULT, REG_ATMP1);
2466         /* restore return value */
2467         switch (md->returntype.type)    {
2468                 case TYPE_VOID: break;
2469
2470 #if defined(ENABLE_SOFTFLOAT)
2471                 case TYPE_DBL:
2472 #endif
2473                 case TYPE_LNG:
2474                         M_ILD(REG_D1, REG_SP, 2 * 4);
2475                         /* fall through */
2476 #if defined(ENABLE_SOFTFLOAT)
2477                 case TYPE_FLT:
2478 #endif
2479                 case TYPE_INT:
2480                 case TYPE_ADR:
2481                         M_ILD(REG_D0, REG_SP, 1 * 4);
2482                         break;
2483
2484 #if !defined(ENABLE_SOFTFLOAT)
2485                 case TYPE_FLT:
2486                         M_FLD(REG_D0, REG_SP, 1 * 4);
2487                         break;
2488                 case TYPE_DBL:  
2489                         M_DLD(REG_D0, REG_SP, 1 * 4);
2490                         break;
2491 #endif
2492                 default: assert(0);
2493         }
2494         /* restore saved registers */
2495
2496         M_AADD_IMM(cd->stackframesize*4, REG_SP);
2497         /* check for exception */
2498         M_ATST(REG_ATMP1);
2499         M_BNE(2);
2500         M_RET;
2501
2502         /* handle exception, REG_ATMP1 already contains exception object, REG_ATMP2 holds address */
2503         
2504         M_ALD(REG_ATMP2_XPC, REG_SP, 0);                /* take return address as faulting instruction */
2505         M_AADD_IMM(-2, REG_ATMP2_XPC);                  /* which is off by 2 */
2506         M_JMP_IMM(asm_handle_nat_exception);
2507
2508         /* should never be reached from within jit code*/
2509         M_JSR_IMM(0);
2510
2511         /* generate patcher stub call code */
2512         emit_patcher_stubs(jd);
2513 }
2514
2515
2516 /*
2517  * These are local overrides for various environment variables in Emacs.
2518  * Please do not remove this and leave it at the end of the file, where
2519  * Emacs will automagically detect them.
2520  * ---------------------------------------------------------------------
2521  * Local variables:
2522  * mode: c
2523  * indent-tabs-mode: t
2524  * c-basic-offset: 4
2525  * tab-width: 4
2526  * End:
2527  * vim:noexpandtab:sw=4:ts=4:
2528  */