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