* Merged with michi branch at rev 21fd42e049a3.
[cacao.git] / src / vm / jit / m68k / codegen.c
1 /* src/vm/jit/m68k/codegen.c
2
3    Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25 */
26
27
28 #include "config.h"
29
30 #include <assert.h>
31 #include <stdint.h>
32
33 #include "md-abi.h"
34 #include "md-os.h"
35
36 #include "vm/types.h"
37 #include "vm/jit/m68k/codegen.h"
38 #include "vm/jit/m68k/emit.h"
39
40 #include "mm/memory.h"
41 #include "native/jni.h"
42 #include "native/localref.h"
43 #include "native/native.h"
44
45 #include "threads/lock-common.h"
46
47 #include "vm/builtin.h"
48 #include "vm/exceptions.h"
49 #include "vm/global.h"
50 #include "vm/stringlocal.h"
51 #include "vm/vm.h"
52
53 #include "vm/jit/asmpart.h"
54 #include "vm/jit/codegen-common.h"
55 #include "vm/jit/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
1120                 case ICMD_GETSTATIC:  /* ...  ==> ..., value                          */
1121
1122                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1123                                 uf        = iptr->sx.s23.s3.uf;
1124                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1125                                 disp      = 0;
1126
1127                                 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, 0);
1128                         }
1129                         else {
1130                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1131                                 fieldtype = fi->type;
1132                                 disp      = (intptr_t) fi->value;
1133
1134                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1135                                         codegen_addpatchref(cd, PATCHER_initialize_class, fi->class,
1136                                                                                 0);
1137                                 }
1138                         }
1139
1140                         M_AMOV_IMM(disp, REG_ATMP1);
1141                         switch (fieldtype) {
1142 #if defined(ENABLE_SOFTFLOAT)
1143                         case TYPE_FLT:
1144 #endif
1145                         case TYPE_INT:
1146                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1147                                 M_ILD(d, REG_ATMP1, 0);
1148                                 break;
1149                         case TYPE_ADR:
1150                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1151                                 M_ALD(d, REG_ATMP1, 0);
1152                                 break;
1153 #if defined(ENABLE_SOFTFLOAT)
1154                         case TYPE_DBL:
1155 #endif
1156                         case TYPE_LNG:
1157                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
1158                                 M_LLD(d, REG_ATMP1, 0);
1159                                 break;
1160 #if !defined(ENABLE_SOFTFLOAT)
1161                         case TYPE_FLT:
1162                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1163                                 M_FLD(d, REG_ATMP1, 0);
1164                                 break;
1165                         case TYPE_DBL:                          
1166                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1167                                 M_DLD(d, REG_ATMP1, 0);
1168                                 break;
1169 #endif
1170                         }
1171                         emit_store_dst(jd, iptr, d);
1172                         break;
1173
1174                 case ICMD_PUTSTATIC:  /* ..., value  ==> ...                          */
1175
1176                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1177                                 uf        = iptr->sx.s23.s3.uf;
1178                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1179                                 disp      = 0;
1180
1181                                 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, 0);
1182                         }
1183                         else {
1184                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1185                                 fieldtype = fi->type;
1186                                 disp      = (intptr_t) fi->value;
1187
1188                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1189                                         codegen_addpatchref(cd, PATCHER_initialize_class, fi->class,
1190                                                                                 0);
1191                         }
1192                 
1193                         M_AMOV_IMM(disp, REG_ATMP1);
1194                         switch (fieldtype) {
1195 #if defined(ENABLE_SOFTFLOAT)
1196                         case TYPE_FLT:
1197 #endif
1198                         case TYPE_INT:
1199                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1200                                 M_IST(s1, REG_ATMP1, 0);
1201                                 break;
1202 #if defined(ENABLE_SOFTFLOAT)
1203                         case TYPE_DBL:
1204 #endif
1205                         case TYPE_LNG:
1206                                 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
1207                                 M_LST(s1, REG_ATMP1, 0);
1208                                 break;
1209                         case TYPE_ADR:
1210                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1211                                 M_AST(s1, REG_ATMP1, 0);
1212                                 break;
1213 #if !defined(ENABLE_SOFTFLOAT)
1214                         case TYPE_FLT:
1215                                 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1216                                 M_FST(s1, REG_ATMP1, 0);
1217                                 break;
1218                         case TYPE_DBL:
1219                                 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1220                                 M_DST(s1, REG_ATMP1, 0);
1221                                 break;
1222 #endif
1223                         default: assert(0);
1224                         }
1225                         break;
1226
1227                 case ICMD_GETFIELD:   /* ...  ==> ..., value                          */
1228
1229                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1230
1231                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1232                                 uf        = iptr->sx.s23.s3.uf;
1233                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1234                                 disp      = 0;
1235
1236                                 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
1237                         }
1238                         else {
1239                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1240                                 fieldtype = fi->type;
1241                                 disp      = fi->offset;
1242                         }
1243
1244                         /* implicit null-pointer check */
1245                         switch (fieldtype) {
1246 #if defined(ENABLE_SOFTFLOAT)
1247                         case TYPE_FLT:
1248 #endif
1249                         case TYPE_INT:
1250                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1251                                 M_ILD(d, s1, disp);
1252                                 break;
1253 #if defined(ENABLE_SOFTFLOAT)
1254                         case TYPE_DBL:
1255 #endif
1256                         case TYPE_LNG:
1257                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1258                                 M_LLD(d, s1, disp);
1259                                 break;
1260                         case TYPE_ADR:
1261                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1262                                 M_ALD(d, s1, disp);
1263                                 break;
1264 #if !defined(ENABLE_SOFTFLOAT)
1265                         case TYPE_FLT:
1266                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1267                                 M_FLD(d, s1, disp);
1268                                 break;
1269                         case TYPE_DBL:                          
1270                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1271                                 M_DLD(d, s1, disp);
1272                                 break;
1273 #endif
1274                         }
1275                         emit_store_dst(jd, iptr, d);
1276                         break;
1277
1278                 case ICMD_PUTFIELD:   /* ..., value  ==> ...                          */
1279
1280                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1281
1282                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1283                                 uf        = iptr->sx.s23.s3.uf;
1284                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1285                                 disp      = 0;
1286                         }
1287                         else {
1288                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1289                                 fieldtype = fi->type;
1290                                 disp      = fi->offset;
1291                         }
1292
1293                         if (IS_INT_LNG_TYPE(fieldtype)) {
1294                                 if (IS_2_WORD_TYPE(fieldtype)) {
1295                                         s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
1296                                 } else {
1297                                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1298                                 }
1299                         } else {
1300                                 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1301                         }
1302
1303                         if (INSTRUCTION_IS_UNRESOLVED(iptr))
1304                                 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
1305
1306                         /* implicit null-pointer check */
1307                         switch (fieldtype) {
1308 #if defined(ENABLE_SOFTFLOAT)
1309                         case TYPE_FLT:
1310 #endif
1311                         case TYPE_INT:
1312                                 M_IST(s2, s1, disp);
1313                                 break;
1314
1315 #if defined(ENABLE_SOFTFLOAT)
1316                         case TYPE_DBL:
1317 #endif
1318                         case TYPE_LNG:
1319                                 M_LST(s2, s1, disp);  
1320                                 break;
1321                         case TYPE_ADR:
1322                                 M_AST(s2, s1, disp);
1323                                 break;
1324 #if !defined(ENABLE_SOFTFLOAT)
1325                         case TYPE_FLT:
1326                                 M_FST(s2, s1, disp);
1327                                 break;
1328                         case TYPE_DBL:
1329                                 M_DST(s2, s1, disp);
1330                                 break;
1331 #endif
1332                         }
1333                         break;
1334
1335                 case ICMD_ARRAYLENGTH: /* ..., arrayref  ==> ..., length              */
1336
1337                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1338                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1339                         /* implicit null-pointer check */
1340                         M_ILD(d, s1, OFFSET(java_array_t, size));
1341                         emit_store_dst(jd, iptr, d);
1342                         break;
1343
1344                 case ICMD_BALOAD:     /* ..., arrayref, index  ==> ..., value         */
1345
1346                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1347                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1348                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1349                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1350                         M_INTMOVE(s2, REG_ITMP2);
1351                         M_IADD_IMM(OFFSET(java_bytearray_t, data[0]), REG_ITMP2);
1352                         M_ADRMOVE(s1, REG_ATMP1);
1353                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1354                         /* implicit null-pointer check */
1355                         M_LBZX(REG_ATMP1, d);
1356                         M_BSEXT(d, d);
1357                         emit_store_dst(jd, iptr, d);
1358                         break;                  
1359
1360                 case ICMD_CALOAD:     /* ..., arrayref, index  ==> ..., value         */
1361
1362                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1363                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1364                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1365                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1366                         M_INTMOVE(s2, REG_ITMP2);
1367                         M_ISSL_IMM(1, REG_ITMP2);
1368                         M_IADD_IMM(OFFSET(java_chararray_t, data[0]), REG_ITMP2);
1369                         M_ADRMOVE(s1, REG_ATMP1);
1370                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1371                         /* implicit null-pointer check */
1372                         M_LHZX(REG_ATMP1, d);
1373                         M_CZEXT(d, d);
1374                         emit_store_dst(jd, iptr, d);
1375                         break;
1376
1377                 case ICMD_SALOAD:     /* ..., arrayref, index  ==> ..., value         */
1378
1379                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1380                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1381                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1382                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1383                         M_INTMOVE(s2, REG_ITMP2);
1384                         M_ISSL_IMM(1, REG_ITMP2);
1385                         M_IADD_IMM(OFFSET(java_shortarray_t, data[0]), REG_ITMP2);
1386                         M_ADRMOVE(s1, REG_ATMP1);
1387                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1388                 
1389                         /* implicit null-pointer check */
1390                         M_LHZX(REG_ATMP1, d);
1391                         M_SSEXT(d, d);
1392                         emit_store_dst(jd, iptr, d);
1393                         break;
1394
1395                 case ICMD_IALOAD:     /* ..., arrayref, index  ==> ..., value         */
1396
1397                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1398                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1399                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1400                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1401                         M_INTMOVE(s2, REG_ITMP2);
1402                         M_ISSL_IMM(2, REG_ITMP2);
1403                         M_IADD_IMM(OFFSET(java_intarray_t, data[0]), REG_ITMP2);
1404                         M_ADRMOVE(s1, REG_ATMP1);
1405                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1406                         /* implicit null-pointer check */
1407                         M_LWZX(REG_ATMP1, d);
1408                         emit_store_dst(jd, iptr, d);
1409                         break;
1410
1411                 case ICMD_LALOAD:     /* ..., arrayref, index  ==> ..., value         */
1412                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1413                         s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1414                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1415                         /* implicit null-pointer check */
1416                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1417                         M_INTMOVE(s2, REG_ITMP1);
1418                         M_ISSL_IMM(3, REG_ITMP1);
1419                         M_IADD_IMM(OFFSET(java_longarray_t, data[0]), REG_ITMP1);
1420                         M_ADRMOVE(s1, REG_ATMP1);
1421                         M_AADDINT(REG_ITMP1, REG_ATMP1);
1422                         /* implicit null-pointer check */
1423                         M_LLD(d, REG_ATMP1, 0);
1424                         emit_store_dst(jd, iptr, d);
1425                         break;
1426
1427                 case ICMD_FALOAD:     /* ..., arrayref, index  ==> ..., value         */
1428                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1429                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1430                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1431                         M_INTMOVE(s2, REG_ITMP2);
1432                         M_ISSL_IMM(2, REG_ITMP2);
1433                         M_IADD_IMM(OFFSET(java_floatarray_t, data[0]), REG_ITMP2);
1434                         M_ADRMOVE(s1, REG_ATMP1);
1435                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1436                         /* implicit null-pointer check */
1437 #if !defined(ENABLE_SOFTFLOAT)
1438                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1439                         M_FLD(d, REG_ATMP1, 0);
1440 #else
1441                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1442                         M_LWZX(REG_ATMP1, d);
1443 #endif
1444                         emit_store_dst(jd, iptr, d);
1445                         break;
1446
1447                 case ICMD_DALOAD:     /* ..., arrayref, index  ==> ..., value         */
1448                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1449                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1450                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1451                         M_INTMOVE(s2, REG_ITMP2);
1452                         M_ISSL_IMM(3, REG_ITMP2);
1453                         M_IADD_IMM(OFFSET(java_doublearray_t, data[0]), REG_ITMP2);
1454                         M_ADRMOVE(s1, REG_ATMP1);
1455                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1456                         /* implicit null-pointer check */
1457 #if !defined(ENABLE_SOFTFLOAT)
1458                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1459                         M_DLD(d, REG_ATMP1, 0);
1460 #else
1461                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1462                         M_LLD(d, REG_ATMP1, 0);
1463 #endif
1464                         emit_store_dst(jd, iptr, d);
1465                         break;
1466
1467                 case ICMD_AALOAD:     /* ..., arrayref, index  ==> ..., value         */
1468                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1469                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1470                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1471                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1472                         M_INTMOVE(s2, REG_ITMP2);
1473                         M_ISSL_IMM(2, REG_ITMP2);
1474                         M_IADD_IMM(OFFSET(java_objectarray_t, data[0]), REG_ITMP2);
1475                         M_ADRMOVE(s1, REG_ATMP1);
1476                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1477         
1478                         /* implicit null-pointer check */
1479                         M_LAX(REG_ATMP1, d);
1480                         emit_store_dst(jd, iptr, d);
1481                         break;
1482
1483
1484                 case ICMD_BASTORE:    /* ..., arrayref, index, value  ==> ...         */
1485                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1486                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1487                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1488                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1489                         M_INTMOVE(s2, REG_ITMP2);
1490                         M_IADD_IMM(OFFSET(java_bytearray_t, data[0]), REG_ITMP2);
1491                         M_ADRMOVE(s1, REG_ATMP1);
1492                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1493                         /* implicit null-pointer check */
1494                         M_STBX(REG_ATMP1, s3);
1495                         break;
1496
1497                 case ICMD_CASTORE:    /* ..., arrayref, index, value  ==> ...         */
1498                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1499                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1500                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1501                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1502                         M_INTMOVE(s2, REG_ITMP2);
1503                         M_ISSL_IMM(1, REG_ITMP2);
1504                         M_IADD_IMM(OFFSET(java_chararray_t, data[0]), REG_ITMP2); 
1505                         M_ADRMOVE(s1, REG_ATMP1);
1506                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1507                         /* implicit null-pointer check */
1508                         M_STHX(REG_ATMP1, s3);
1509                         break;
1510
1511                 case ICMD_SASTORE:    /* ..., arrayref, index, value  ==> ...         */
1512                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1513                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1514                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1515                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1516                         M_INTMOVE(s2, REG_ITMP2);
1517                         M_ISSL_IMM(1, REG_ITMP2);
1518                         M_IADD_IMM(OFFSET(java_shortarray_t, data[0]), REG_ITMP2);
1519                         M_ADRMOVE(s1, REG_ATMP1);
1520                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1521                         /* implicit null-pointer check */
1522                         M_STHX(REG_ATMP1, s3);
1523                         break;
1524
1525                 case ICMD_IASTORE:    /* ..., arrayref, index, value  ==> ...         */
1526                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1527                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1528                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1529                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1530                         M_INTMOVE(s2, REG_ITMP2);
1531                         M_ISSL_IMM(2, REG_ITMP2);
1532                         M_IADD_IMM(OFFSET(java_intarray_t, data[0]), REG_ITMP2);
1533                         M_ADRMOVE(s1, REG_ATMP1);
1534                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1535                         /* implicit null-pointer check */
1536                         M_STWX(REG_ATMP1, s3);
1537                         break;
1538
1539                 case ICMD_LASTORE:    /* ..., arrayref, index, value  ==> ...         */
1540                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1541                         s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1542                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1543
1544                         M_INTMOVE(s2, REG_ITMP1);
1545                         M_ISSL_IMM(3, REG_ITMP1);
1546                         M_IADD_IMM(OFFSET(java_longarray_t, data[0]), REG_ITMP1);
1547                         M_ADRMOVE(s1, REG_ATMP1);
1548                         M_AADDINT(REG_ITMP1, REG_ATMP1);
1549                         /* implicit null-pointer check */
1550                         s3 = emit_load_s3(jd, iptr, REG_ITMP12_PACKED);
1551                         M_LST(s3, REG_ATMP1, 0);
1552                         break;
1553
1554                 case ICMD_FASTORE:    /* ..., arrayref, index, value  ==> ...         */
1555                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1556                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1557                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1558                         M_INTMOVE(s2, REG_ITMP2);
1559                         M_ISSL_IMM(2, REG_ITMP2);
1560                         M_IADD_IMM(OFFSET(java_floatarray_t, data[0]), REG_ITMP2);
1561                         M_ADRMOVE(s1, REG_ATMP1);
1562                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1563                         /* implicit null-pointer check */
1564 #if !defined(ENABLE_SOFTFLOAT)
1565                         s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1566                         M_FST(s3, REG_ATMP1, 0);
1567 #else
1568                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1569                         M_STWX(REG_ATMP1, s3);
1570 #endif
1571                         break;
1572
1573                 case ICMD_DASTORE:    /* ..., arrayref, index, value  ==> ...         */
1574                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1575                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1576                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1577                         M_INTMOVE(s2, REG_ITMP2);
1578                         M_ISSL_IMM(3, REG_ITMP2);
1579                         M_IADD_IMM(OFFSET(java_doublearray_t, data[0]), REG_ITMP2);
1580                         M_ADRMOVE(s1, REG_ATMP1);
1581                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1582                         /* implicit null-pointer check */
1583 #if !defined(ENABLE_SOFTFLOAT)
1584                         s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1585                         M_DST(s3, REG_ATMP1, 0);
1586 #else
1587                         s3 = emit_load_s3(jd, iptr, REG_ITMP12_PACKED);
1588                         /* implicit null-pointer check */
1589                         M_LST(s3, REG_ATMP1, 0);
1590 #endif
1591                         break;
1592
1593                 case ICMD_AASTORE:    /* ..., arrayref, index, value  ==> ...         */
1594
1595                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1596                         s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1597                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1598                         s3 = emit_load_s3(jd, iptr, REG_ATMP2);
1599
1600                         /* XXX what if array is NULL */
1601                         disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
1602
1603                         M_AST(s1, REG_SP, 0*4);
1604                         M_AST(s3, REG_SP, 1*4);
1605                         M_JSR_IMM(BUILTIN_FAST_canstore);
1606                         emit_arraystore_check(cd, iptr);
1607
1608                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1609                         s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1610                         s3 = emit_load_s3(jd, iptr, REG_ATMP2);
1611                         M_INTMOVE(s2, REG_ITMP1);
1612                         M_ISSL_IMM(2, REG_ITMP1);
1613                         M_IADD_IMM(OFFSET(java_objectarray_t, data[0]), REG_ITMP1);
1614                         M_ADRMOVE(s1, REG_ATMP1);
1615                         M_AADDINT(REG_ITMP1, REG_ATMP1);
1616                         /* implicit null-pointer check */
1617                         M_STAX(REG_ATMP1, s3);
1618                         break;
1619
1620
1621
1622                 /* METHOD INVOCATION *********************************************************/
1623                 case ICMD_BUILTIN:      /* ..., [arg1, [arg2 ...]] ==> ...            */
1624                         REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr);
1625
1626                         bte = iptr->sx.s23.s3.bte;
1627                         md  = bte->md;
1628                         goto gen_method;
1629
1630                 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ...            */
1631                 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
1632                 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer    */
1633                 case ICMD_INVOKEINTERFACE:
1634                         REPLACEMENT_POINT_INVOKE(cd, iptr);
1635
1636                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1637                                 lm = NULL;
1638                                 um = iptr->sx.s23.s3.um;
1639                                 md = um->methodref->parseddesc.md;
1640                         }
1641                         else {
1642                                 lm = iptr->sx.s23.s3.fmiref->p.method;
1643                                 um = NULL;
1644                                 md = lm->parseddesc;
1645                         }
1646         gen_method:
1647                         s3 = md->paramcount;
1648         
1649                         MCODECHECK((s3 << 1) + 64);
1650
1651                         /* copy arguments to stack */
1652                         for (s3 = s3 - 1; s3 >= 0; s3--)        {
1653                                 var = VAR(iptr->sx.s23.s2.args[s3]);
1654                                 /* already preallocated */
1655                                 if (var->flags & PREALLOC) continue;
1656                 
1657                                 if (!md->params[s3].inmemory) assert(0);
1658
1659                                 switch (var->type)      {
1660 #if defined(ENABLE_SOFTFLOAT)
1661                                         case TYPE_DBL:
1662 #endif
1663                                         case TYPE_LNG:
1664                                                 d = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
1665                                                 M_LST(d, REG_SP, md->params[s3].regoff);
1666                                                 break;
1667 #if defined(ENABLE_SOFTFLOAT)
1668                                         case TYPE_FLT:
1669 #endif
1670                                         case TYPE_INT:
1671                                                 d = emit_load(jd, iptr, var, REG_ITMP1);
1672                                                 M_IST(d, REG_SP, md->params[s3].regoff);
1673                                                 break;
1674                                         case TYPE_ADR:
1675                                                 d = emit_load(jd, iptr, var, REG_ATMP1);
1676                                                 M_AST(d, REG_SP, md->params[s3].regoff);
1677                                                 break;
1678 #if !defined(ENABLE_SOFTFLOAT)
1679                                         case TYPE_FLT:
1680                                                 d = emit_load(jd, iptr, var, REG_FTMP1);
1681                                                 M_FST(d, REG_SP, md->params[s3].regoff);
1682                                                 break;
1683                                         case TYPE_DBL:
1684                                                 d = emit_load(jd, iptr, var, REG_FTMP1);
1685                                                 M_DST(d, REG_SP, md->params[s3].regoff);
1686                                                 break;
1687 #endif
1688                                         default:
1689                                                 assert(0);
1690                                 }
1691                         }
1692
1693                         /* arguments in place now */
1694                         switch(iptr->opc)       {
1695                                 case ICMD_BUILTIN:
1696                                         if (bte->stub == NULL)
1697                                                 disp = (ptrint) bte->fp;
1698                                         else
1699                                                 disp = (ptrint) bte->stub;
1700                                         d = md->returntype.type;
1701                                         M_JSR_IMM(disp);
1702
1703                                         REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1704                                         break;
1705
1706                                 case ICMD_INVOKESPECIAL: 
1707                                         /* adress register for sure */
1708                                         M_ALD(REG_ATMP1, REG_SP, 0);
1709                                         emit_nullpointer_check(cd, iptr, REG_ATMP1);
1710                                         /* fall through */
1711                                 case ICMD_INVOKESTATIC: 
1712                                         if (lm == NULL) {
1713                                                 codegen_addpatchref(cd, PATCHER_invokestatic_special, um, 0);
1714                                                 disp = 0;
1715                                                 M_AMOV_IMM(disp, REG_ATMP1);
1716                                         } else  {
1717                                                 disp = lm->stubroutine;
1718                                                 M_AMOV_IMM(disp, REG_ATMP1);
1719                                         }
1720
1721                                         /* generate the actual call */
1722                                         M_JSR(REG_ATMP1);
1723                                         REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1724                                         break;
1725
1726
1727                                 case ICMD_INVOKEVIRTUAL:
1728                                         if (lm == NULL) {
1729                                                 codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
1730                                                 s1 = 0;
1731                                         } else {
1732                                                 s1 = OFFSET(vftbl_t, table[0]) + sizeof(methodptr) * lm->vftblindex;
1733                                         }
1734                                         /* load object pointer (==argument 0) */
1735                                         M_ALD(REG_ATMP1, REG_SP, 0);
1736                                         /* implicit null-pointer check */
1737                                         M_ALD(REG_METHODPTR, REG_ATMP1, OFFSET(java_object_t, vftbl));
1738                                         M_ALD(REG_ATMP3, REG_METHODPTR, s1);
1739                                         /* generate the actual call */
1740                                         M_JSR(REG_ATMP3);
1741                                         break;
1742                                 case ICMD_INVOKEINTERFACE: 
1743                                         if (lm == NULL) {
1744                                                 codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
1745
1746                                                 s1 = 0;
1747                                                 s2 = 0;
1748                                         } else {
1749                                                 s1 = OFFSET(vftbl_t, interfacetable[0]) - sizeof(methodptr*) * lm->class->index;
1750                                                 s2 = sizeof(methodptr) * (lm - lm->class->methods);
1751                                         }
1752                                         /* load object pointer (==argument 0) */
1753                                         M_ALD(REG_ATMP1, REG_SP, 0);
1754
1755                                         /* implicit null-pointer check */
1756                                         M_ALD(REG_METHODPTR, REG_ATMP1, OFFSET(java_object_t, vftbl));
1757                                         M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
1758                                         M_ALD(REG_ATMP3, REG_METHODPTR, s2);
1759
1760                                         /* generate the actual call */
1761                                         M_JSR(REG_ATMP3);
1762                                         REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1763                                         break;
1764
1765                                 default: assert(0);
1766                                 }       /* switch (iptr->opc) */
1767
1768                                 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1769                                 REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr);
1770                                 
1771                                 /* store return value */
1772                                 d = md->returntype.type;
1773
1774                                 switch (d)      {
1775                                         case TYPE_VOID: break;
1776 #if defined(ENABLE_SOFTFLOAT)
1777                                         case TYPE_FLT:
1778 #endif
1779                                         case TYPE_INT:
1780                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
1781                                                 M_INTMOVE(REG_RESULT, s1);
1782                                                 break;
1783 #if defined(ENABLE_SOFTFLOAT)
1784                                         case TYPE_DBL:
1785 #endif
1786                                         case TYPE_LNG:
1787                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
1788                                                 M_LNGMOVE(REG_RESULT_PACKED, s1);
1789                                                 break;
1790                                         case TYPE_ADR:
1791                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_ATMP1);
1792                                                 /* all stuff is returned in %d0 */
1793                                                 M_INT2ADRMOVE(REG_RESULT, s1);
1794                                                 break;
1795 #if !defined(ENABLE_SOFTFLOAT)
1796                                         /*
1797                                          *      for BUILTINS float values are returned in %d0,%d1
1798                                          *      within cacao we use %fp0 for that.
1799                                          */
1800                                         case TYPE_FLT:
1801                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1802                                                 if (iptr->opc == ICMD_BUILTIN)  {
1803                                                         M_INT2FLTMOVE(REG_FRESULT, s1);
1804                                                 } else  {
1805                                                         M_FLTMOVE(REG_FRESULT, s1);
1806                                                 }
1807                                                 break;
1808                                         case TYPE_DBL:
1809                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1810                                                 if (iptr->opc == ICMD_BUILTIN)  {
1811                                                         M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 4 + 4);
1812                                                         M_DLD(s1, REG_SP, rd->memuse * 4 + 4);
1813                                                 } else  {
1814                                                         M_DBLMOVE(REG_FRESULT, s1);
1815                                                 }
1816                                                 break;
1817 #endif
1818                                         default:
1819                                                 assert(0);
1820                                 }
1821                                 if (d != TYPE_VOID) emit_store_dst(jd, iptr, s1);
1822                         break; /* ICMD_INVOKE* */
1823
1824 #if defined(ENABLE_SOFTFLOAT)
1825                 case ICMD_FRETURN:
1826 #endif
1827                 case ICMD_IRETURN:      /* ..., retvalue ==> ...                      */
1828
1829                         REPLACEMENT_POINT_RETURN(cd, iptr);
1830                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
1831                         M_INTMOVE(s1, REG_RESULT);
1832                         goto nowperformreturn;
1833
1834                 case ICMD_ARETURN:      /* ..., retvalue ==> ...                      */
1835
1836                         REPLACEMENT_POINT_RETURN(cd, iptr);
1837                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
1838                         assert(VAROP(iptr->s1)->type == TYPE_ADR);
1839                         M_ADR2INTMOVE(s1, REG_RESULT);
1840
1841 #ifdef ENABLE_VERIFIER
1842                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1843                                 unresolved_class *uc = iptr->sx.s23.s2.uc;
1844
1845                                 codegen_addpatchref(cd, PATCHER_resolve_class, uc, 0);
1846                         }
1847 #endif /* ENABLE_VERIFIER */
1848                         goto nowperformreturn;
1849
1850 #if defined(ENABLE_SOFTFLOAT)
1851                 case ICMD_DRETURN:
1852 #endif
1853                 case ICMD_LRETURN:      /* ..., retvalue ==> ...                      */
1854                         REPLACEMENT_POINT_RETURN(cd, iptr);
1855                         s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
1856                         M_LNGMOVE(s1, REG_RESULT_PACKED);
1857                         goto nowperformreturn;
1858
1859 #if !defined(ENABLE_SOFTFLOAT)
1860                 case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
1861                         REPLACEMENT_POINT_RETURN(cd, iptr);
1862                         s1 = emit_load_s1(jd, iptr, REG_FRESULT);
1863                         M_FLTMOVE(s1, REG_FRESULT);
1864                         goto nowperformreturn;
1865
1866                 case ICMD_DRETURN:
1867                         REPLACEMENT_POINT_RETURN(cd, iptr);
1868                         s1 = emit_load_s1(jd, iptr, REG_FRESULT);
1869                         M_DBLMOVE(s1, REG_FRESULT);
1870                         goto nowperformreturn;
1871
1872 #endif
1873
1874                 case ICMD_RETURN:      /* ...  ==> ...                                */
1875
1876                         REPLACEMENT_POINT_RETURN(cd, iptr);
1877
1878 nowperformreturn:
1879                         {
1880                         s4 i, p;
1881                         
1882                         p = cd->stackframesize;
1883
1884                         /* call trace function */
1885 #if !defined(NDEBUG)
1886                         emit_verbosecall_exit(jd);
1887 #endif
1888
1889 #if defined(ENABLE_THREADS)
1890                         /* call lock_monitor_exit */
1891                         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
1892                                 M_ILD(REG_ITMP3, REG_SP, rd->memuse * 8);
1893
1894                                 /* we need to save the proper return value */
1895                                 /* we do not care for the long -> doubel convert space here */
1896                                 switch (iptr->opc) {
1897 #if defined(ENABLE_SOFTFLOAT)
1898                                 case ICMD_DRETURN:
1899 #endif
1900                                 case ICMD_LRETURN:
1901                                         M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 8 + 8);
1902                                         break;
1903 #if defined(ENABLE_SOFTFLOAT)
1904                                 case ICMD_FRETURN:
1905 #endif
1906                                 case ICMD_IRETURN:
1907                                 case ICMD_ARETURN:
1908                                         M_IST(REG_RESULT , REG_SP, rd->memuse * 8 + 8);
1909                                         break;
1910 #if !defined(ENABLE_SOFTFLOAT)
1911                                 case ICMD_FRETURN:
1912                                         M_FST(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1913                                         break;
1914                                 case ICMD_DRETURN:
1915                                         M_DST(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1916                                         break;
1917 #endif
1918                                 }
1919
1920                                 M_IST(REG_ITMP3, REG_SP, 0 * 4);
1921                                 M_JSR_IMM(LOCK_monitor_exit);
1922
1923                                 /* and now restore the proper return value */
1924                                 switch (iptr->opc) {
1925
1926 #if defined(ENABLE_SOFTFLOAT)
1927                                 case ICMD_DRETURN:
1928 #endif
1929                                 case ICMD_LRETURN:
1930                                         M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 8 + 8);
1931                                         break;
1932 #if defined(ENABLE_SOFTFLOAT)
1933                                 case ICMD_FRETURN:
1934 #endif
1935                                 case ICMD_IRETURN:
1936                                 case ICMD_ARETURN:
1937                                         M_ILD(REG_RESULT , REG_SP, rd->memuse * 8 + 8);
1938                                         break;
1939 #if !defined(ENABLE_SOFTFLOAT)
1940                                 case ICMD_FRETURN:
1941                                         M_FLD(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1942                                         break;
1943                                 case ICMD_DRETURN:
1944                                         M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1945                                         break;
1946 #endif
1947                                 }
1948                         }
1949 #endif
1950
1951
1952                         /* restore return address                                         */
1953 #if 0
1954                         if (!jd->isleafmethod) {
1955                                 /* ATTENTION: Don't use REG_ZERO (r0) here, as M_ALD
1956                                    may have a displacement overflow. */
1957
1958                                 M_ALD(REG_ITMP1, REG_SP, p * 4 + LA_LR_OFFSET);
1959                                 M_MTLR(REG_ITMP1);
1960                         }
1961 #endif
1962                         /* restore saved registers                                        */
1963
1964                         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
1965                                 p-=8; M_ILD(rd->savintregs[i], REG_SP, p);
1966                         }
1967                         for (i=ADR_SAV_CNT-1; i>=rd->savadrreguse; --i) {
1968                                 p-=8; M_ALD(rd->savadrregs[i], REG_SP, p);
1969                         }
1970 #if !defined(ENABLE_SOFTFLOAT)
1971                         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
1972                                 p-=8; M_FLOAD(rd->savfltregs[i], REG_SP, p);
1973                         }
1974 #endif
1975                         /* deallocate stack                                               */
1976                         M_AADD_IMM(cd->stackframesize, REG_SP);
1977                         M_RET;
1978                         }
1979                         break;
1980
1981                 /* the evil ones */
1982                 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
1983                                       /* val.a: (classinfo*) superclass               */
1984
1985                         /*  superclass is an interface:
1986                          *
1987                          *  return (sub != NULL) &&
1988                          *         (sub->vftbl->interfacetablelength > super->index) &&
1989                          *         (sub->vftbl->interfacetable[-super->index] != NULL);
1990                          *
1991                          *  superclass is a class:
1992                          *
1993                          *  return ((sub != NULL) && (0
1994                          *          <= (sub->vftbl->baseval - super->vftbl->baseval) <=
1995                          *          super->vftbl->diffvall));
1996                          */
1997
1998                         {
1999                         classinfo *super;
2000                         s4         superindex;
2001
2002                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2003                                 super      = NULL;
2004                                 superindex = 0;
2005                         }
2006                         else {
2007                                 super      = iptr->sx.s23.s3.c.cls;
2008                                 superindex = super->index;
2009                         }
2010                         
2011                         if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2012                                 CODEGEN_CRITICAL_SECTION_NEW;
2013
2014                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
2015                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2016
2017                         assert(VAROP(iptr->s1 )->type == TYPE_ADR);
2018                         assert(VAROP(iptr->dst)->type == TYPE_INT);
2019
2020                         M_ICLR(d);
2021
2022                         /* if class is not resolved, check which code to call */
2023
2024                         if (super == NULL) {
2025                                 M_ATST(s1);
2026                                 emit_label_beq(cd, BRANCH_LABEL_1);
2027
2028                                 codegen_addpatchref(cd, PATCHER_resolve_classref_to_flags, iptr->sx.s23.s3.c.ref, 0);
2029
2030                                 M_IMOV_IMM32(0, REG_ITMP3);
2031                                 M_IAND_IMM(ACC_INTERFACE, REG_ITMP3);
2032                                 emit_label_beq(cd, BRANCH_LABEL_2);
2033                         }
2034
2035                         /* interface instanceof code */
2036
2037                         if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2038                                 if (super == NULL) {
2039                                         codegen_addpatchref(cd, PATCHER_instanceof_interface, iptr->sx.s23.s3.c.ref, 0);
2040                                 } else {
2041                                         M_ATST(s1);
2042                                         emit_label_beq(cd, BRANCH_LABEL_3);
2043                                 }
2044
2045                                 M_ALD(REG_ATMP1, s1, OFFSET(java_object_t, vftbl));
2046                                 M_ILD(REG_ITMP3, REG_ATMP1, OFFSET(vftbl_t, interfacetablelength));
2047                                 M_IADD_IMM(-superindex, REG_ITMP3);     /* -superindex may be patched patched */
2048                                 M_ITST(REG_ITMP3);
2049                                 M_BLE(10);
2050                                 M_ALD(REG_ATMP1, REG_ATMP1, OFFSET(vftbl_t, interfacetable[0]) - superindex * sizeof(methodptr*));      /* patch here too! */
2051                                 M_ATST(REG_ATMP1);
2052                                 M_BEQ(2);
2053                                 M_IMOV_IMM(1, d);
2054
2055                                 if (super == NULL)
2056                                         emit_label_br(cd, BRANCH_LABEL_4);
2057                                 else
2058                                         emit_label(cd, BRANCH_LABEL_3);
2059                         }
2060
2061                         /* class instanceof code */
2062
2063                         if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2064                                 if (super == NULL) {
2065                                         emit_label(cd, BRANCH_LABEL_2);
2066
2067                                         codegen_addpatchref(cd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, 0);
2068                                         M_AMOV_IMM(0, REG_ATMP2);
2069                                 } else {
2070                                         M_AMOV_IMM(super->vftbl, REG_ATMP2);
2071                                         M_ATST(s1);
2072                                         emit_label_beq(cd, BRANCH_LABEL_5);
2073                                 }
2074
2075                                 M_ALD(REG_ATMP1, s1, OFFSET(java_object_t, vftbl));
2076
2077                                 CODEGEN_CRITICAL_SECTION_START;
2078
2079                                 M_ILD(REG_ITMP1, REG_ATMP1, OFFSET(vftbl_t, baseval));
2080                                 M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, baseval));
2081                                 M_ILD(REG_ITMP2, REG_ATMP2, OFFSET(vftbl_t, diffval));
2082
2083                                 CODEGEN_CRITICAL_SECTION_END;
2084
2085                                 M_ISUB(REG_ITMP3, REG_ITMP1);
2086                                 M_ICMP(REG_ITMP2, REG_ITMP1);
2087                                 M_BHI(4);
2088                                 M_IMOV_IMM(1, d);
2089                                 M_TPFW;                 /* overlaps next instruction */
2090                                 M_ICLR(d);
2091
2092                                 if (super != NULL)
2093                                         emit_label(cd, BRANCH_LABEL_5);
2094                         }
2095
2096                         if (super == NULL) {
2097                                 emit_label(cd, BRANCH_LABEL_1);
2098                                 emit_label(cd, BRANCH_LABEL_4);
2099                         }
2100
2101                         emit_store_dst(jd, iptr, d);
2102                         }
2103                         break;
2104
2105                 case ICMD_CHECKCAST:  /* ..., objectref ==> ..., objectref            */
2106                                       /* val.a: (classinfo*) superclass               */
2107
2108                         /*  superclass is an interface:
2109                          *
2110                          *  OK if ((sub == NULL) ||
2111                          *         (sub->vftbl->interfacetablelength > super->index) &&
2112                          *         (sub->vftbl->interfacetable[-super->index] != NULL));
2113                          *
2114                          *  superclass is a class:
2115                          *
2116                          *  OK if ((sub == NULL) || (0
2117                          *         <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2118                          *         super->vftbl->diffvall));
2119                          */
2120
2121                         if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2122                                 /* object type cast-check */
2123
2124                                 classinfo *super;
2125                                 s4         superindex;
2126
2127                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2128                                         super      = NULL;
2129                                         superindex = 0;
2130                                 }
2131                                 else {
2132                                         super      = iptr->sx.s23.s3.c.cls;
2133                                         superindex = super->index;
2134                                 }
2135
2136                                 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2137                                         CODEGEN_CRITICAL_SECTION_NEW;
2138
2139                                 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
2140                                 assert(VAROP(iptr->s1)->type == TYPE_ADR);
2141
2142                                 /* if class is not resolved, check which code to call */
2143
2144                                 if (super == NULL) {
2145                                         M_ATST(s1);
2146                                         emit_label_beq(cd, BRANCH_LABEL_1);
2147
2148                                         codegen_addpatchref(cd, PATCHER_resolve_classref_to_flags, iptr->sx.s23.s3.c.ref, 0);
2149                         
2150                                         M_IMOV_IMM32(0, REG_ITMP2);
2151                                         M_IAND_IMM(ACC_INTERFACE, REG_ITMP2);
2152                                         emit_label_beq(cd, BRANCH_LABEL_2);
2153                                 }
2154
2155                                 /* interface checkcast code */
2156
2157                                 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2158                                         if (super == NULL) {
2159                                                 codegen_addpatchref(cd, PATCHER_checkcast_interface, iptr->sx.s23.s3.c.ref, 0);
2160                                         } else {
2161                                                 M_ATST(s1);
2162                                                 emit_label_beq(cd, BRANCH_LABEL_3);
2163                                         }
2164
2165                                         M_ALD(REG_ATMP2, s1, OFFSET(java_object_t, vftbl));
2166                                         M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, interfacetablelength));
2167         
2168                                         M_IADD_IMM(-superindex, REG_ITMP3);     /* superindex patched */
2169                                         M_ITST(REG_ITMP3);
2170                                         emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2171
2172                                         M_ALD(REG_ATMP3, REG_ATMP2, OFFSET(vftbl_t, interfacetable[0]) - superindex * sizeof(methodptr*));      /* patched*/
2173                                         M_ATST(REG_ATMP3);
2174                                         emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ATMP3, s1);
2175
2176                                         if (super == NULL)
2177                                                 emit_label_br(cd, BRANCH_LABEL_4);
2178                                         else
2179                                                 emit_label(cd, BRANCH_LABEL_3);
2180                                 }
2181
2182                                 /* class checkcast code */
2183
2184                                 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2185                                         if (super == NULL) {
2186                                                 emit_label(cd, BRANCH_LABEL_2);
2187
2188                                                 codegen_addpatchref(cd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, 0);
2189                                                 M_AMOV_IMM(0, REG_ATMP3);
2190                                         } else {
2191                                                 M_AMOV_IMM(super->vftbl, REG_ATMP3);
2192                                                 M_ATST(s1);
2193                                                 emit_label_beq(cd, BRANCH_LABEL_5);
2194                                         }
2195
2196                                         M_ALD(REG_ATMP2, s1, OFFSET(java_object_t, vftbl));
2197
2198                                         CODEGEN_CRITICAL_SECTION_START;
2199
2200                                         M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, baseval));  /* REG_ITMP3 == sub->vftbl->baseval */
2201                                         M_ILD(REG_ITMP1, REG_ATMP3, OFFSET(vftbl_t, baseval));
2202                                         M_ILD(REG_ITMP2, REG_ATMP3, OFFSET(vftbl_t, diffval));
2203
2204                                         CODEGEN_CRITICAL_SECTION_END;
2205
2206                                         M_ISUB(REG_ITMP1, REG_ITMP3);
2207                                         M_ICMP(REG_ITMP2, REG_ITMP3);   /* XXX was CMPU */
2208
2209                                         emit_classcast_check(cd, iptr, BRANCH_UGT, REG_ITMP3, s1); /* XXX was BRANCH_GT */
2210
2211                                         if (super != NULL)
2212                                                 emit_label(cd, BRANCH_LABEL_5);
2213                                 }
2214
2215                                 if (super == NULL) {
2216                                         emit_label(cd, BRANCH_LABEL_1);
2217                                         emit_label(cd, BRANCH_LABEL_4);
2218                                 }
2219
2220                                 d = codegen_reg_of_dst(jd, iptr, s1);
2221                         } else {
2222                                 /* array type cast-check */
2223
2224                                 s1 = emit_load_s1(jd, iptr, REG_ATMP2);
2225
2226                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2227                                         codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo, iptr->sx.s23.s3.c.ref, 0);
2228                                         M_AMOV_IMM(0, REG_ATMP1);
2229                                 } else {
2230                                         M_AMOV_IMM(iptr->sx.s23.s3.c.cls, REG_ATMP1);
2231                                 }
2232         
2233                                 M_APUSH(REG_ATMP1);
2234                                 M_APUSH(s1);
2235                                 M_JSR_IMM(BUILTIN_arraycheckcast);
2236                                 M_AADD_IMM(2*4, REG_SP);                /* pop arguments off stack */
2237                                 M_ITST(REG_RESULT);
2238                                 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2239
2240                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2241                                 d = codegen_reg_of_dst(jd, iptr, s1);
2242                         }
2243                         assert(VAROP(iptr->dst)->type == TYPE_ADR);
2244                         M_ADRMOVE(s1, d);
2245                         emit_store_dst(jd, iptr, d);
2246                         break;
2247
2248                 case ICMD_TABLESWITCH:  /* ..., index ==> ...                         */
2249                         {
2250                         s4 i, l;
2251                         branch_target_t *table;
2252
2253                         table = iptr->dst.table;
2254
2255                         l = iptr->sx.s23.s2.tablelow;
2256                         i = iptr->sx.s23.s3.tablehigh;
2257                         
2258                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2259                         M_INTMOVE(s1, REG_ITMP1);
2260                         if (l != 0) M_ISUB_IMM(l, REG_ITMP1);
2261
2262                         i = i - l + 1;
2263
2264                         /* range check */
2265                         M_ICMP_IMM(i - 1, REG_ITMP1);
2266                         emit_bugt(cd, table[0].block);
2267
2268                         /* build jump table top down and use address of lowest entry */
2269                         table += i;
2270
2271                         while (--i >= 0) {
2272                                 dseg_add_target(cd, table->block); 
2273                                 --table;
2274                         }
2275
2276                         /* length of dataseg after last dseg_add_target is used by load */
2277                         M_AMOV_IMM(0, REG_ATMP2);
2278                         dseg_adddata(cd);
2279
2280                         M_ISSL_IMM(2, REG_ITMP1);                       /* index * 4 == offset in table */
2281                         M_AADDINT(REG_ITMP1, REG_ATMP2);                /* offset in table */
2282                         M_AADD_IMM(-(cd->dseglen), REG_ATMP2);          /* start of table in dseg */
2283                         M_ALD(REG_ATMP1, REG_ATMP2, 0);
2284
2285                         M_JMP(REG_ATMP1);
2286                         ALIGNCODENOP;
2287                         }
2288                         break;
2289
2290                 case ICMD_LOOKUPSWITCH: /* ..., key ==> ...                           */
2291                         {
2292                         s4 i;
2293                         lookup_target_t *lookup;
2294
2295                         lookup = iptr->dst.lookup;
2296
2297                         i = iptr->sx.s23.s2.lookupcount;
2298                         
2299                         MCODECHECK((i<<2)+8);
2300                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2301
2302                         while (--i >= 0) {
2303                                 M_ICMP_IMM(lookup->value, s1);
2304                                 emit_beq(cd, lookup->target.block);
2305                                 lookup++;
2306                         }
2307
2308                         emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2309                         ALIGNCODENOP;
2310                         break;
2311                         }
2312
2313                 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref  */
2314
2315                         /* check for negative sizes and copy sizes to stack if necessary  */
2316                         MCODECHECK((iptr->s1.argcount << 1) + 64);
2317
2318                         for (s1 = iptr->s1.argcount; --s1 >= 0;) {
2319                                 var = VAR(iptr->sx.s23.s2.args[s1]);
2320
2321                                 /* Already Preallocated? */
2322                                 if (!(var->flags & PREALLOC)) {
2323                                         s2 = emit_load(jd, iptr, var, REG_ITMP1);
2324                                         M_IST(s2, REG_SP, (s1 + 3) * 4);
2325                                 }
2326                         }
2327
2328                         /* a0 = dimension count */
2329                         M_IMOV_IMM(iptr->s1.argcount, REG_ITMP1);
2330                         M_IST(REG_ITMP1, REG_SP, 0*4);
2331
2332                         /* a1 = arraydescriptor */
2333                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2334                                 codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo, iptr->sx.s23.s3.c.ref, 0);
2335                                 M_AMOV_IMM(0, REG_ATMP1);
2336                         } else  {
2337                                 M_AMOV_IMM(iptr->sx.s23.s3.c.cls, REG_ATMP1);
2338                         }
2339                         M_AST(REG_ATMP1, REG_SP, 1*4);
2340
2341                         /* a2 = pointer to dimensions = stack pointer */
2342                         M_AMOV(REG_SP, REG_ATMP1);
2343                         M_AADD_IMM(3*4, REG_ATMP1);
2344                         M_AST(REG_ATMP1, REG_SP, 2*4);
2345
2346                         M_JSR_IMM(BUILTIN_multianewarray);
2347
2348                         /* check for exception before result assignment */
2349                         emit_exception_check(cd, iptr);
2350
2351                         assert(VAROP(iptr->dst)->type == TYPE_ADR);
2352                         d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2353                         M_INT2ADRMOVE(REG_RESULT, d);
2354                         emit_store_dst(jd, iptr, d);
2355                         break;
2356
2357
2358
2359                 default:
2360                         printf("UNKNOWN OPCODE %d\n", iptr->opc);
2361                         exceptions_throw_internalerror("Unknown ICMD %d during code generation", iptr->opc);
2362                         return false;
2363         } /* switch */
2364         /* M_TPF; */ /* nop after each ICMD */
2365         } /* for each instruction */
2366
2367         /* At the end of a basic block we may have to append some nops,
2368            because the patcher stub calling code might be longer than the
2369            actual instruction. So codepatching does not change the
2370            following block unintentionally. */
2371
2372         if (cd->mcodeptr < cd->lastmcodeptr) {
2373                 while (cd->mcodeptr < cd->lastmcodeptr) {
2374                         M_NOP;
2375                 }
2376         }
2377
2378
2379         } /* if (btpre->flags >= BBREACHED) */
2380         } /* for each basic block */
2381
2382         dseg_createlinenumbertable(cd);
2383
2384         /* generate stubs */
2385         emit_patcher_stubs(jd);
2386
2387         return true;
2388 }
2389
2390
2391 /* codegen_emit_stub_compiler **************************************************
2392
2393    Emits a stub routine which calls the compiler.
2394         
2395 *******************************************************************************/
2396
2397 void codegen_emit_stub_compiler(jitdata *jd)
2398 {
2399         methodinfo  *m;
2400         codegendata *cd;
2401
2402         /* get required compiler data */
2403
2404         m  = jd->m;
2405         cd = jd->cd;
2406
2407         /* code for the stub */
2408
2409         M_AMOV_IMM(m, REG_ATMP1);
2410         M_AMOV_IMM(asm_call_jit_compiler, REG_ATMP3);
2411         M_JMP(REG_ATMP3);
2412 }
2413
2414 /* codegen_emit_stub_builtin ***************************************************
2415
2416    Creates a stub routine which calls a builtin function.
2417
2418 *******************************************************************************/
2419
2420 void codegen_emit_stub_builtin(jitdata *jd, builtintable_entry *bte)
2421 {
2422         codeinfo    *code;
2423         codegendata *cd;
2424         methoddesc  *md;
2425         s4           i;
2426         s4           disp;
2427         s4           s1, s2;
2428
2429         /* get required compiler data */
2430         code = jd->code;
2431         cd   = jd->cd;
2432
2433         /* set some variables */
2434         md = bte->md;
2435
2436         /* calculate stack frame size */
2437         cd->stackframesize =
2438                 sizeof(stackframeinfo) / SIZEOF_VOID_P +
2439                 4;                              /* 4 arguments or return value        */
2440
2441         /* create method header */
2442         (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
2443         (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize       */
2444         (void) dseg_add_unique_s4(cd, 0);                      /* IsSync          */
2445         (void) dseg_add_unique_s4(cd, 0);                      /* IsLeaf          */
2446         (void) dseg_add_unique_s4(cd, 0);                      /* IntSave         */
2447         (void) dseg_add_unique_s4(cd, 0);                      /* FltSave         */
2448         (void) dseg_addlinenumbertablesize(cd);
2449         (void) dseg_add_unique_s4(cd, 0);                      /* ExTableSize     */
2450
2451         /* generate stub code */
2452         M_AADD_IMM(-(cd->stackframesize*4), REG_SP);
2453
2454 #if defined(ENABLE_GC_CACAO)
2455         /* Save callee saved integer registers in stackframeinfo (GC may
2456            need to recover them during a collection). */
2457
2458         disp = cd->stackframesize * 4 - sizeof(stackframeinfo) +
2459                 OFFSET(stackframeinfo, adrregs);
2460
2461         for (i = 0; i < ADR_SAV_CNT; i++)
2462                 M_AST(abi_registers_address_saved[i], REG_SP, disp + i * 4);
2463 #endif
2464
2465         /* create dynamic stack info */
2466
2467         M_AMOV(REG_SP, REG_ATMP1);
2468         M_AADD_IMM(cd->stackframesize * 4, REG_ATMP1);
2469         M_AST(REG_ATMP1, REG_SP, 0 * 4);        /* datasp */
2470
2471         M_AMOV_IMM(0, REG_ATMP1);                       /* we need pv patched in */
2472         dseg_adddata(cd);                                       /* this does the trick */
2473         M_AST(REG_ATMP1, REG_SP, 1 * 4);        /* pv */
2474
2475         M_AMOV(REG_SP, REG_ATMP1);
2476         M_AADD_IMM(cd->stackframesize * 4 + SIZEOF_VOID_P, REG_ATMP1);
2477         M_AST(REG_ATMP1, REG_SP, 2 * 4);                        /* sp */
2478
2479         M_ALD(REG_ATMP3, REG_SP, cd->stackframesize * 4);
2480         M_AST(REG_ATMP3, REG_SP, 3 * 4);                        /* ra */
2481
2482         M_JSR_IMM(codegen_stub_builtin_enter);
2483
2484         /* copy arguments into new stackframe */
2485
2486         for (i = 0; i < md->paramcount; i++) {
2487                 if (!md->params[i].inmemory) {
2488                         log_text("No integer argument registers available!");
2489                         assert(0);
2490
2491                 } else {       /* float/double in memory can be copied like int/longs */
2492                         s1 = md->params[i].regoff + cd->stackframesize * 4 + 4;
2493                         s2 = md->params[i].regoff;
2494
2495                         M_ILD(REG_ITMP1, REG_SP, s1);
2496                         M_IST(REG_ITMP1, REG_SP, s2);
2497                         if (IS_2_WORD_TYPE(md->paramtypes[i].type)) {
2498                                 M_ILD(REG_ITMP1, REG_SP, s1 + 4);
2499                                 M_IST(REG_ITMP1, REG_SP, s2 + 4);
2500                         }
2501
2502                 }
2503         }
2504
2505         /* call the builtin function */
2506
2507         M_AMOV_IMM(bte->fp, REG_ATMP3);
2508         M_JSR(REG_ATMP3);
2509
2510         /* save return value */
2511         switch (md->returntype.type)    {
2512                 case TYPE_VOID: break;
2513
2514                 /* natives return float arguments in %d0, %d1, cacao expects them in %fp0 */
2515                 case TYPE_DBL:
2516                 case TYPE_LNG:
2517                         M_IST(REG_D1, REG_SP, 2 * 4);
2518                         /* fall through */
2519
2520                 case TYPE_FLT:
2521                 case TYPE_INT:
2522                 case TYPE_ADR:
2523                         M_IST(REG_D0, REG_SP, 1 * 4);
2524                         break;
2525
2526                 default: assert(0);
2527         }
2528
2529         /* remove native stackframe info */
2530
2531         M_AMOV(REG_SP, REG_ATMP1);
2532         M_AADD_IMM(cd->stackframesize * 4, REG_ATMP1);
2533         M_AST(REG_ATMP1, REG_SP, 0 * 4);
2534
2535         M_JSR_IMM(codegen_stub_builtin_exit);
2536
2537         /* restore return value */
2538         switch (md->returntype.type)    {
2539                 case TYPE_VOID: break;
2540
2541                 case TYPE_DBL:
2542                 case TYPE_LNG:
2543                         M_ILD(REG_D1, REG_SP, 2 * 4);
2544                         /* fall through */
2545
2546                 case TYPE_FLT:
2547                 case TYPE_INT:
2548                 case TYPE_ADR:
2549                         M_ILD(REG_D0, REG_SP, 1 * 4);
2550                         break;
2551
2552                 default: assert(0);
2553         }
2554
2555 #if defined(ENABLE_GC_CACAO)
2556         /* Restore callee saved integer registers from stackframeinfo (GC
2557            might have modified them during a collection). */
2558         
2559         disp = cd->stackframesize * 4 - sizeof(stackframeinfo) +
2560                 OFFSET(stackframeinfo, adrregs);
2561
2562         for (i = 0; i < ADR_SAV_CNT; i++)
2563                 M_ALD(abi_registers_address_saved[i], REG_SP, disp + i * 4);
2564 #endif
2565
2566         /* remove stackframe */
2567         M_AADD_IMM(cd->stackframesize * 4, REG_SP);
2568         M_RET;
2569 }
2570
2571
2572
2573
2574 /* codegen_emit_stub_native ****************************************************
2575
2576    Emits a stub routine which calls a native method.
2577
2578 *******************************************************************************/
2579
2580 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
2581 {
2582         methodinfo   *m;
2583         codeinfo     *code;
2584         codegendata  *cd;
2585         registerdata *rd;
2586         methoddesc   *md;
2587         s4 nativeparams, i, j, t, s1, s2;
2588         
2589         /* get required compiler data */
2590
2591         m    = jd->m;
2592         code = jd->code;
2593         cd   = jd->cd;
2594         rd   = jd->rd;
2595
2596         md = m->parseddesc;
2597         nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
2598
2599         /* calc stackframe size */
2600         cd->stackframesize =    sizeof(stackframeinfo) / SIZEOF_VOID_P +
2601                                 sizeof(localref_table) / SIZEOF_VOID_P +
2602                                 nmd->memuse +
2603                                 1 +                                             /* functionptr */
2604                                 4;                                              /* args for codegen_start_native_call */
2605
2606         /* create method header */
2607         (void) dseg_add_unique_address(cd, code);                      /* CodeinfoPointer */
2608         (void) dseg_add_unique_s4(cd, cd->stackframesize * 4);         /* FrameSize       */
2609         (void) dseg_add_unique_s4(cd, 0);                              /* IsSync          */
2610         (void) dseg_add_unique_s4(cd, 0);                              /* IsLeaf          */
2611         (void) dseg_add_unique_s4(cd, 0);                              /* IntSave         */
2612         (void) dseg_add_unique_s4(cd, 0);                              /* FltSave         */
2613         (void) dseg_addlinenumbertablesize(cd);
2614         (void) dseg_add_unique_s4(cd, 0);                              /* ExTableSize     */
2615
2616         /* print call trace */
2617 #if !defined(NDEBUG)
2618         if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
2619                 emit_verbosecall_enter(jd);
2620         }
2621 #endif
2622
2623         /* generate code */
2624         M_AADD_IMM(-(cd->stackframesize*4), REG_SP);
2625
2626         /* get function address (this must happen before the stackframeinfo) */
2627         if (f == NULL)  {
2628                 codegen_addpatchref(cd, PATCHER_resolve_native_function, m, 0);
2629         }
2630
2631         M_AMOV_IMM(f, REG_ATMP2); /* do not move this line, the patcher is needed */
2632
2633         M_AST(REG_ATMP2, REG_SP, 4 * 4);
2634
2635         /* put arguments for codegen_start_native_call onto stack */
2636         /* void codegen_start_native_call(u1 *datasp, u1 *pv, u1 *sp, u1 *ra) */
2637         
2638         M_AMOV(REG_SP, REG_ATMP1);
2639         M_AST(REG_ATMP1, REG_SP, 0 * 4);                /* currentsp */
2640
2641         M_AMOV_IMM(0, REG_ATMP2);                       /* 0 needs to patched */
2642         dseg_adddata(cd);                                   /* this patches it */
2643
2644         M_AST(REG_ATMP2, REG_SP, 1 * 4);                /* pv */
2645
2646         M_JSR_IMM(codegen_start_native_call);
2647
2648         /* remember class argument */
2649         if (m->flags & ACC_STATIC)
2650                 M_INT2ADRMOVE(REG_RESULT, REG_ATMP3);
2651
2652         /* load function pointer */
2653         M_ALD(REG_ATMP2, REG_SP, 4 * 4);
2654
2655         /* copy arguments into stackframe */
2656         for (i = md->paramcount -1, j = i + nativeparams; i >= 0; --i, --j)     {
2657                 t = md->paramtypes[i].type;
2658                 /* all arguments via stack */
2659                 assert(md->params[i].inmemory);                                         
2660
2661                 s1 = md->params[i].regoff + cd->stackframesize * 4 + 4;
2662                 s2 = nmd->params[j].regoff;
2663
2664                 /* simply copy argument stack */
2665                 M_ILD(REG_ITMP1, REG_SP, s1);
2666                 M_IST(REG_ITMP1, REG_SP, s2);
2667                 if (IS_2_WORD_TYPE(t))  {
2668                         M_ILD(REG_ITMP1, REG_SP, s1 + 4);
2669                         M_IST(REG_ITMP1, REG_SP, s2 + 4);
2670                 }
2671         }
2672
2673         /* for static function class as second arg */
2674         if (m->flags & ACC_STATIC)
2675                 M_AST(REG_ATMP3, 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, 2 * 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_ATMP1);
2713         M_AST(REG_ATMP1, REG_SP, 0 * 4);                /* currentsp */
2714
2715         M_AMOV_IMM(0, REG_ATMP2);                       /* 0 needs to patched */
2716         dseg_adddata(cd);                                   /* this patches it */
2717
2718         M_AST(REG_ATMP2, REG_SP, 1 * 4);                /* pv */
2719
2720         M_JSR_IMM(codegen_finish_native_call);
2721         
2722         M_INT2ADRMOVE(REG_RESULT, REG_ATMP1);
2723         /* restore return value */
2724         switch (md->returntype.type)    {
2725                 case TYPE_VOID: break;
2726
2727                 case TYPE_DBL:
2728                 case TYPE_LNG:
2729                         M_ILD(REG_D1, REG_SP, 2 * 4);
2730                         /* fall through */
2731                 case TYPE_FLT:
2732                 case TYPE_INT:
2733                 case TYPE_ADR:
2734                         M_ILD(REG_D0, REG_SP, 2 * 4);
2735                         break;
2736
2737                 default: assert(0);
2738         }
2739 #if !defined(ENABLE_SOFTFLOAT)
2740                 /* additionally load values into floating points registers
2741                  * as cacao jit code expects them there */
2742         switch (md->returntype.type)    {
2743                 case TYPE_FLT:
2744                         M_FLD(REG_D0, REG_SP, 2 * 4);
2745                         break;
2746                 case TYPE_DBL:  
2747                         M_DLD(REG_D0, REG_SP, 2 * 4);
2748                         break;
2749         }
2750 #endif
2751         /* restore saved registers */
2752
2753         M_AADD_IMM(cd->stackframesize*4, REG_SP);
2754         /* check for exception */
2755         M_ATST(REG_ATMP1);
2756         M_BNE(2);
2757         M_RET;
2758
2759         /* handle exception, REG_ATMP1 already contains exception object, REG_ATMP2 holds address */
2760         
2761         M_ALD(REG_ATMP2_XPC, REG_SP, 0);                /* take return address as faulting instruction */
2762         M_AADD_IMM(-2, REG_ATMP2_XPC);                  /* which is off by 2 */
2763         M_JMP_IMM(asm_handle_nat_exception);
2764
2765         /* should never be reached from within jit code*/
2766         M_JSR_IMM(0);
2767
2768         /* generate patcher stub call code */
2769         emit_patcher_stubs(jd);
2770 }
2771
2772
2773 /*
2774  * These are local overrides for various environment variables in Emacs.
2775  * Please do not remove this and leave it at the end of the file, where
2776  * Emacs will automagically detect them.
2777  * ---------------------------------------------------------------------
2778  * Local variables:
2779  * mode: c
2780  * indent-tabs-mode: t
2781  * c-basic-offset: 4
2782  * tab-width: 4
2783  * End:
2784  * vim:noexpandtab:sw=4:ts=4:
2785  */