* Merged with default branch at rev 16f3633aaa5a.
[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_canstore);
1602
1603                         M_AST(s1, REG_SP, 0*4);
1604                         M_AST(s3, REG_SP, 1*4);
1605                         M_JSR_IMM(BUILTIN_canstore);    
1606                         emit_exception_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                                         disp = (ptrint) bte->fp;
1697                                         d = md->returntype.type;
1698                                         M_JSR_IMM(disp);
1699
1700                                         REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1701                                         emit_exception_check(cd, iptr);
1702                                         break;
1703
1704                                 case ICMD_INVOKESPECIAL: 
1705                                         /* adress register for sure */
1706                                         M_ALD(REG_ATMP1, REG_SP, 0);
1707                                         emit_nullpointer_check(cd, iptr, REG_ATMP1);
1708                                         /* fall through */
1709                                 case ICMD_INVOKESTATIC: 
1710                                         if (lm == NULL) {
1711                                                 codegen_addpatchref(cd, PATCHER_invokestatic_special, um, 0);
1712                                                 disp = 0;
1713                                                 M_AMOV_IMM(disp, REG_ATMP1);
1714                                         } else  {
1715                                                 disp = lm->stubroutine;
1716                                                 M_AMOV_IMM(disp, REG_ATMP1);
1717                                         }
1718
1719                                         /* generate the actual call */
1720                                         M_JSR(REG_ATMP1);
1721                                         REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1722                                         break;
1723
1724
1725                                 case ICMD_INVOKEVIRTUAL:
1726                                         if (lm == NULL) {
1727                                                 codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
1728                                                 s1 = 0;
1729                                         } else {
1730                                                 s1 = OFFSET(vftbl_t, table[0]) + sizeof(methodptr) * lm->vftblindex;
1731                                         }
1732                                         /* load object pointer (==argument 0) */
1733                                         M_ALD(REG_ATMP1, REG_SP, 0);
1734                                         /* implicit null-pointer check */
1735                                         M_ALD(REG_METHODPTR, REG_ATMP1, OFFSET(java_object_t, vftbl));
1736                                         M_ALD(REG_ATMP3, REG_METHODPTR, s1);
1737                                         /* generate the actual call */
1738                                         M_JSR(REG_ATMP3);
1739                                         break;
1740                                 case ICMD_INVOKEINTERFACE: 
1741                                         if (lm == NULL) {
1742                                                 codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
1743
1744                                                 s1 = 0;
1745                                                 s2 = 0;
1746                                         } else {
1747                                                 s1 = OFFSET(vftbl_t, interfacetable[0]) - sizeof(methodptr*) * lm->class->index;
1748                                                 s2 = sizeof(methodptr) * (lm - lm->class->methods);
1749                                         }
1750                                         /* load object pointer (==argument 0) */
1751                                         M_ALD(REG_ATMP1, REG_SP, 0);
1752
1753                                         /* implicit null-pointer check */
1754                                         M_ALD(REG_METHODPTR, REG_ATMP1, OFFSET(java_object_t, vftbl));
1755                                         M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
1756                                         M_ALD(REG_ATMP3, REG_METHODPTR, s2);
1757
1758                                         /* generate the actual call */
1759                                         M_JSR(REG_ATMP3);
1760                                         REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1761                                         break;
1762
1763                                 default: assert(0);
1764                                 }       /* switch (iptr->opc) */
1765
1766                                 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1767                                 REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr);
1768                                 
1769                                 /* store return value */
1770                                 d = md->returntype.type;
1771
1772                                 switch (d)      {
1773                                         case TYPE_VOID: break;
1774 #if defined(ENABLE_SOFTFLOAT)
1775                                         case TYPE_FLT:
1776 #endif
1777                                         case TYPE_INT:
1778                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
1779                                                 M_INTMOVE(REG_RESULT, s1);
1780                                                 break;
1781 #if defined(ENABLE_SOFTFLOAT)
1782                                         case TYPE_DBL:
1783 #endif
1784                                         case TYPE_LNG:
1785                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
1786                                                 M_LNGMOVE(REG_RESULT_PACKED, s1);
1787                                                 break;
1788                                         case TYPE_ADR:
1789                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_ATMP1);
1790                                                 /* all stuff is returned in %d0 */
1791                                                 M_INT2ADRMOVE(REG_RESULT, s1);
1792                                                 break;
1793 #if !defined(ENABLE_SOFTFLOAT)
1794                                         /*
1795                                          *      for BUILTINS float values are returned in %d0,%d1
1796                                          *      within cacao we use %fp0 for that.
1797                                          */
1798                                         case TYPE_FLT:
1799                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1800                                                 if (iptr->opc == ICMD_BUILTIN)  {
1801                                                         M_INT2FLTMOVE(REG_FRESULT, s1);
1802                                                 } else  {
1803                                                         M_FLTMOVE(REG_FRESULT, s1);
1804                                                 }
1805                                                 break;
1806                                         case TYPE_DBL:
1807                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1808                                                 if (iptr->opc == ICMD_BUILTIN)  {
1809                                                         M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 4 + 4);
1810                                                         M_DLD(s1, REG_SP, rd->memuse * 4 + 4);
1811                                                 } else  {
1812                                                         M_DBLMOVE(REG_FRESULT, s1);
1813                                                 }
1814                                                 break;
1815 #endif
1816                                         default:
1817                                                 assert(0);
1818                                 }
1819                                 if (d != TYPE_VOID) emit_store_dst(jd, iptr, s1);
1820                         break; /* ICMD_INVOKE* */
1821
1822 #if defined(ENABLE_SOFTFLOAT)
1823                 case ICMD_FRETURN:
1824 #endif
1825                 case ICMD_IRETURN:      /* ..., retvalue ==> ...                      */
1826
1827                         REPLACEMENT_POINT_RETURN(cd, iptr);
1828                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
1829                         M_INTMOVE(s1, REG_RESULT);
1830                         goto nowperformreturn;
1831
1832                 case ICMD_ARETURN:      /* ..., retvalue ==> ...                      */
1833
1834                         REPLACEMENT_POINT_RETURN(cd, iptr);
1835                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
1836                         assert(VAROP(iptr->s1)->type == TYPE_ADR);
1837                         M_ADR2INTMOVE(s1, REG_RESULT);
1838
1839 #ifdef ENABLE_VERIFIER
1840                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1841                                 unresolved_class *uc = iptr->sx.s23.s2.uc;
1842
1843                                 codegen_addpatchref(cd, PATCHER_resolve_class, uc, 0);
1844                         }
1845 #endif /* ENABLE_VERIFIER */
1846                         goto nowperformreturn;
1847
1848 #if defined(ENABLE_SOFTFLOAT)
1849                 case ICMD_DRETURN:
1850 #endif
1851                 case ICMD_LRETURN:      /* ..., retvalue ==> ...                      */
1852                         REPLACEMENT_POINT_RETURN(cd, iptr);
1853                         s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
1854                         M_LNGMOVE(s1, REG_RESULT_PACKED);
1855                         goto nowperformreturn;
1856
1857 #if !defined(ENABLE_SOFTFLOAT)
1858                 case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
1859                         REPLACEMENT_POINT_RETURN(cd, iptr);
1860                         s1 = emit_load_s1(jd, iptr, REG_FRESULT);
1861                         M_FLTMOVE(s1, REG_FRESULT);
1862                         goto nowperformreturn;
1863
1864                 case ICMD_DRETURN:
1865                         REPLACEMENT_POINT_RETURN(cd, iptr);
1866                         s1 = emit_load_s1(jd, iptr, REG_FRESULT);
1867                         M_DBLMOVE(s1, REG_FRESULT);
1868                         goto nowperformreturn;
1869
1870 #endif
1871
1872                 case ICMD_RETURN:      /* ...  ==> ...                                */
1873
1874                         REPLACEMENT_POINT_RETURN(cd, iptr);
1875
1876 nowperformreturn:
1877                         {
1878                         s4 i, p;
1879                         
1880                         p = cd->stackframesize;
1881
1882                         /* call trace function */
1883 #if !defined(NDEBUG)
1884                         emit_verbosecall_exit(jd);
1885 #endif
1886
1887 #if defined(ENABLE_THREADS)
1888                         /* call lock_monitor_exit */
1889                         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
1890                                 M_ILD(REG_ITMP3, REG_SP, rd->memuse * 8);
1891
1892                                 /* we need to save the proper return value */
1893                                 /* we do not care for the long -> doubel convert space here */
1894                                 switch (iptr->opc) {
1895 #if defined(ENABLE_SOFTFLOAT)
1896                                 case ICMD_DRETURN:
1897 #endif
1898                                 case ICMD_LRETURN:
1899                                         M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 8 + 8);
1900                                         break;
1901 #if defined(ENABLE_SOFTFLOAT)
1902                                 case ICMD_FRETURN:
1903 #endif
1904                                 case ICMD_IRETURN:
1905                                 case ICMD_ARETURN:
1906                                         M_IST(REG_RESULT , REG_SP, rd->memuse * 8 + 8);
1907                                         break;
1908 #if !defined(ENABLE_SOFTFLOAT)
1909                                 case ICMD_FRETURN:
1910                                         M_FST(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1911                                         break;
1912                                 case ICMD_DRETURN:
1913                                         M_DST(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1914                                         break;
1915 #endif
1916                                 }
1917
1918                                 M_IST(REG_ITMP3, REG_SP, 0 * 4);
1919                                 M_JSR_IMM(LOCK_monitor_exit);
1920
1921                                 /* and now restore the proper return value */
1922                                 switch (iptr->opc) {
1923
1924 #if defined(ENABLE_SOFTFLOAT)
1925                                 case ICMD_DRETURN:
1926 #endif
1927                                 case ICMD_LRETURN:
1928                                         M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 8 + 8);
1929                                         break;
1930 #if defined(ENABLE_SOFTFLOAT)
1931                                 case ICMD_FRETURN:
1932 #endif
1933                                 case ICMD_IRETURN:
1934                                 case ICMD_ARETURN:
1935                                         M_ILD(REG_RESULT , REG_SP, rd->memuse * 8 + 8);
1936                                         break;
1937 #if !defined(ENABLE_SOFTFLOAT)
1938                                 case ICMD_FRETURN:
1939                                         M_FLD(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1940                                         break;
1941                                 case ICMD_DRETURN:
1942                                         M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1943                                         break;
1944 #endif
1945                                 }
1946                         }
1947 #endif
1948
1949
1950                         /* restore return address                                         */
1951 #if 0
1952                         if (!jd->isleafmethod) {
1953                                 /* ATTENTION: Don't use REG_ZERO (r0) here, as M_ALD
1954                                    may have a displacement overflow. */
1955
1956                                 M_ALD(REG_ITMP1, REG_SP, p * 4 + LA_LR_OFFSET);
1957                                 M_MTLR(REG_ITMP1);
1958                         }
1959 #endif
1960                         /* restore saved registers                                        */
1961
1962                         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
1963                                 p-=8; M_ILD(rd->savintregs[i], REG_SP, p);
1964                         }
1965                         for (i=ADR_SAV_CNT-1; i>=rd->savadrreguse; --i) {
1966                                 p-=8; M_ALD(rd->savadrregs[i], REG_SP, p);
1967                         }
1968 #if !defined(ENABLE_SOFTFLOAT)
1969                         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
1970                                 p-=8; M_FLOAD(rd->savfltregs[i], REG_SP, p);
1971                         }
1972 #endif
1973                         /* deallocate stack                                               */
1974                         M_AADD_IMM(cd->stackframesize, REG_SP);
1975                         M_RET;
1976                         }
1977                         break;
1978
1979                 /* the evil ones */
1980                 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
1981                                       /* val.a: (classinfo*) superclass               */
1982
1983                         /*  superclass is an interface:
1984                          *
1985                          *  return (sub != NULL) &&
1986                          *         (sub->vftbl->interfacetablelength > super->index) &&
1987                          *         (sub->vftbl->interfacetable[-super->index] != NULL);
1988                          *
1989                          *  superclass is a class:
1990                          *
1991                          *  return ((sub != NULL) && (0
1992                          *          <= (sub->vftbl->baseval - super->vftbl->baseval) <=
1993                          *          super->vftbl->diffvall));
1994                          */
1995
1996                         {
1997                         classinfo *super;
1998                         s4         superindex;
1999
2000                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2001                                 super      = NULL;
2002                                 superindex = 0;
2003                         }
2004                         else {
2005                                 super      = iptr->sx.s23.s3.c.cls;
2006                                 superindex = super->index;
2007                         }
2008                         
2009                         if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2010                                 CODEGEN_CRITICAL_SECTION_NEW;
2011
2012                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
2013                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2014
2015                         assert(VAROP(iptr->s1 )->type == TYPE_ADR);
2016                         assert(VAROP(iptr->dst)->type == TYPE_INT);
2017
2018                         M_ICLR(d);
2019
2020                         /* if class is not resolved, check which code to call */
2021
2022                         if (super == NULL) {
2023                                 M_ATST(s1);
2024                                 emit_label_beq(cd, BRANCH_LABEL_1);
2025
2026                                 codegen_addpatchref(cd, PATCHER_resolve_classref_to_flags, iptr->sx.s23.s3.c.ref, 0);
2027
2028                                 M_IMOV_IMM32(0, REG_ITMP3);
2029                                 M_IAND_IMM(ACC_INTERFACE, REG_ITMP3);
2030                                 emit_label_beq(cd, BRANCH_LABEL_2);
2031                         }
2032
2033                         /* interface instanceof code */
2034
2035                         if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2036                                 if (super == NULL) {
2037                                         codegen_addpatchref(cd, PATCHER_instanceof_interface, iptr->sx.s23.s3.c.ref, 0);
2038                                 } else {
2039                                         M_ATST(s1);
2040                                         emit_label_beq(cd, BRANCH_LABEL_3);
2041                                 }
2042
2043                                 M_ALD(REG_ATMP1, s1, OFFSET(java_object_t, vftbl));
2044                                 M_ILD(REG_ITMP3, REG_ATMP1, OFFSET(vftbl_t, interfacetablelength));
2045                                 M_IADD_IMM(-superindex, REG_ITMP3);     /* -superindex may be patched patched */
2046                                 M_ITST(REG_ITMP3);
2047                                 M_BLE(10);
2048                                 M_ALD(REG_ATMP1, REG_ATMP1, OFFSET(vftbl_t, interfacetable[0]) - superindex * sizeof(methodptr*));      /* patch here too! */
2049                                 M_ATST(REG_ATMP1);
2050                                 M_BEQ(2);
2051                                 M_IMOV_IMM(1, d);
2052
2053                                 if (super == NULL)
2054                                         emit_label_br(cd, BRANCH_LABEL_4);
2055                                 else
2056                                         emit_label(cd, BRANCH_LABEL_3);
2057                         }
2058
2059                         /* class instanceof code */
2060
2061                         if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2062                                 if (super == NULL) {
2063                                         emit_label(cd, BRANCH_LABEL_2);
2064
2065                                         codegen_addpatchref(cd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, 0);
2066                                         M_AMOV_IMM(0, REG_ATMP2);
2067                                 } else {
2068                                         M_AMOV_IMM(super->vftbl, REG_ATMP2);
2069                                         M_ATST(s1);
2070                                         emit_label_beq(cd, BRANCH_LABEL_5);
2071                                 }
2072
2073                                 M_ALD(REG_ATMP1, s1, OFFSET(java_object_t, vftbl));
2074
2075                                 CODEGEN_CRITICAL_SECTION_START;
2076
2077                                 M_ILD(REG_ITMP1, REG_ATMP1, OFFSET(vftbl_t, baseval));
2078                                 M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, baseval));
2079                                 M_ILD(REG_ITMP2, REG_ATMP2, OFFSET(vftbl_t, diffval));
2080
2081                                 CODEGEN_CRITICAL_SECTION_END;
2082
2083                                 M_ISUB(REG_ITMP3, REG_ITMP1);
2084                                 M_ICMP(REG_ITMP2, REG_ITMP1);
2085                                 M_BHI(4);
2086                                 M_IMOV_IMM(1, d);
2087                                 M_TPFW;                 /* overlaps next instruction */
2088                                 M_ICLR(d);
2089
2090                                 if (super != NULL)
2091                                         emit_label(cd, BRANCH_LABEL_5);
2092                         }
2093
2094                         if (super == NULL) {
2095                                 emit_label(cd, BRANCH_LABEL_1);
2096                                 emit_label(cd, BRANCH_LABEL_4);
2097                         }
2098
2099                         emit_store_dst(jd, iptr, d);
2100                         }
2101                         break;
2102
2103                 case ICMD_CHECKCAST:  /* ..., objectref ==> ..., objectref            */
2104                                       /* val.a: (classinfo*) superclass               */
2105
2106                         /*  superclass is an interface:
2107                          *
2108                          *  OK if ((sub == NULL) ||
2109                          *         (sub->vftbl->interfacetablelength > super->index) &&
2110                          *         (sub->vftbl->interfacetable[-super->index] != NULL));
2111                          *
2112                          *  superclass is a class:
2113                          *
2114                          *  OK if ((sub == NULL) || (0
2115                          *         <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2116                          *         super->vftbl->diffvall));
2117                          */
2118
2119                         if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2120                                 /* object type cast-check */
2121
2122                                 classinfo *super;
2123                                 s4         superindex;
2124
2125                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2126                                         super      = NULL;
2127                                         superindex = 0;
2128                                 }
2129                                 else {
2130                                         super      = iptr->sx.s23.s3.c.cls;
2131                                         superindex = super->index;
2132                                 }
2133
2134                                 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2135                                         CODEGEN_CRITICAL_SECTION_NEW;
2136
2137                                 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
2138                                 assert(VAROP(iptr->s1)->type == TYPE_ADR);
2139
2140                                 /* if class is not resolved, check which code to call */
2141
2142                                 if (super == NULL) {
2143                                         M_ATST(s1);
2144                                         emit_label_beq(cd, BRANCH_LABEL_1);
2145
2146                                         codegen_addpatchref(cd, PATCHER_resolve_classref_to_flags, iptr->sx.s23.s3.c.ref, 0);
2147                         
2148                                         M_IMOV_IMM32(0, REG_ITMP2);
2149                                         M_IAND_IMM(ACC_INTERFACE, REG_ITMP2);
2150                                         emit_label_beq(cd, BRANCH_LABEL_2);
2151                                 }
2152
2153                                 /* interface checkcast code */
2154
2155                                 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2156                                         if (super == NULL) {
2157                                                 codegen_addpatchref(cd, PATCHER_checkcast_interface, iptr->sx.s23.s3.c.ref, 0);
2158                                         } else {
2159                                                 M_ATST(s1);
2160                                                 emit_label_beq(cd, BRANCH_LABEL_3);
2161                                         }
2162
2163                                         M_ALD(REG_ATMP2, s1, OFFSET(java_object_t, vftbl));
2164                                         M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, interfacetablelength));
2165         
2166                                         M_IADD_IMM(-superindex, REG_ITMP3);     /* superindex patched */
2167                                         M_ITST(REG_ITMP3);
2168                                         emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2169
2170                                         M_ALD(REG_ATMP3, REG_ATMP2, OFFSET(vftbl_t, interfacetable[0]) - superindex * sizeof(methodptr*));      /* patched*/
2171                                         M_ATST(REG_ATMP3);
2172                                         emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ATMP3, s1);
2173
2174                                         if (super == NULL)
2175                                                 emit_label_br(cd, BRANCH_LABEL_4);
2176                                         else
2177                                                 emit_label(cd, BRANCH_LABEL_3);
2178                                 }
2179
2180                                 /* class checkcast code */
2181
2182                                 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2183                                         if (super == NULL) {
2184                                                 emit_label(cd, BRANCH_LABEL_2);
2185
2186                                                 codegen_addpatchref(cd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, 0);
2187                                                 M_AMOV_IMM(0, REG_ATMP3);
2188                                         } else {
2189                                                 M_AMOV_IMM(super->vftbl, REG_ATMP3);
2190                                                 M_ATST(s1);
2191                                                 emit_label_beq(cd, BRANCH_LABEL_5);
2192                                         }
2193
2194                                         M_ALD(REG_ATMP2, s1, OFFSET(java_object_t, vftbl));
2195
2196                                         CODEGEN_CRITICAL_SECTION_START;
2197
2198                                         M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, baseval));  /* REG_ITMP3 == sub->vftbl->baseval */
2199                                         M_ILD(REG_ITMP1, REG_ATMP3, OFFSET(vftbl_t, baseval));
2200                                         M_ILD(REG_ITMP2, REG_ATMP3, OFFSET(vftbl_t, diffval));
2201
2202                                         CODEGEN_CRITICAL_SECTION_END;
2203
2204                                         M_ISUB(REG_ITMP1, REG_ITMP3);
2205                                         M_ICMP(REG_ITMP2, REG_ITMP3);   /* XXX was CMPU */
2206
2207                                         emit_classcast_check(cd, iptr, BRANCH_UGT, REG_ITMP3, s1); /* XXX was BRANCH_GT */
2208
2209                                         if (super != NULL)
2210                                                 emit_label(cd, BRANCH_LABEL_5);
2211                                 }
2212
2213                                 if (super == NULL) {
2214                                         emit_label(cd, BRANCH_LABEL_1);
2215                                         emit_label(cd, BRANCH_LABEL_4);
2216                                 }
2217
2218                                 d = codegen_reg_of_dst(jd, iptr, s1);
2219                         } else {
2220                                 /* array type cast-check */
2221
2222                                 s1 = emit_load_s1(jd, iptr, REG_ATMP2);
2223
2224                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2225                                         codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo, iptr->sx.s23.s3.c.ref, 0);
2226                                         M_AMOV_IMM(0, REG_ATMP1);
2227                                 } else {
2228                                         M_AMOV_IMM(iptr->sx.s23.s3.c.cls, REG_ATMP1);
2229                                 }
2230         
2231                                 M_APUSH(REG_ATMP1);
2232                                 M_APUSH(s1);
2233                                 M_JSR_IMM(BUILTIN_arraycheckcast);
2234                                 M_AADD_IMM(2*4, REG_SP);                /* pop arguments off stack */
2235                                 M_ITST(REG_RESULT);
2236                                 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2237
2238                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2239                                 d = codegen_reg_of_dst(jd, iptr, s1);
2240                         }
2241                         assert(VAROP(iptr->dst)->type == TYPE_ADR);
2242                         M_ADRMOVE(s1, d);
2243                         emit_store_dst(jd, iptr, d);
2244                         break;
2245
2246                 case ICMD_TABLESWITCH:  /* ..., index ==> ...                         */
2247                         {
2248                         s4 i, l;
2249                         branch_target_t *table;
2250
2251                         table = iptr->dst.table;
2252
2253                         l = iptr->sx.s23.s2.tablelow;
2254                         i = iptr->sx.s23.s3.tablehigh;
2255                         
2256                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2257                         M_INTMOVE(s1, REG_ITMP1);
2258                         if (l != 0) M_ISUB_IMM(l, REG_ITMP1);
2259
2260                         i = i - l + 1;
2261
2262                         /* range check */
2263                         M_ICMP_IMM(i - 1, REG_ITMP1);
2264                         emit_bugt(cd, table[0].block);
2265
2266                         /* build jump table top down and use address of lowest entry */
2267                         table += i;
2268
2269                         while (--i >= 0) {
2270                                 dseg_add_target(cd, table->block); 
2271                                 --table;
2272                         }
2273
2274                         /* length of dataseg after last dseg_add_target is used by load */
2275                         M_AMOV_IMM(0, REG_ATMP2);
2276                         dseg_adddata(cd);
2277
2278                         M_ISSL_IMM(2, REG_ITMP1);                       /* index * 4 == offset in table */
2279                         M_AADDINT(REG_ITMP1, REG_ATMP2);                /* offset in table */
2280                         M_AADD_IMM(-(cd->dseglen), REG_ATMP2);          /* start of table in dseg */
2281                         M_ALD(REG_ATMP1, REG_ATMP2, 0);
2282
2283                         M_JMP(REG_ATMP1);
2284                         ALIGNCODENOP;
2285                         }
2286                         break;
2287
2288                 case ICMD_LOOKUPSWITCH: /* ..., key ==> ...                           */
2289                         {
2290                         s4 i;
2291                         lookup_target_t *lookup;
2292
2293                         lookup = iptr->dst.lookup;
2294
2295                         i = iptr->sx.s23.s2.lookupcount;
2296                         
2297                         MCODECHECK((i<<2)+8);
2298                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2299
2300                         while (--i >= 0) {
2301                                 M_ICMP_IMM(lookup->value, s1);
2302                                 emit_beq(cd, lookup->target.block);
2303                                 lookup++;
2304                         }
2305
2306                         emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2307                         ALIGNCODENOP;
2308                         break;
2309                         }
2310
2311                 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref  */
2312
2313                         /* check for negative sizes and copy sizes to stack if necessary  */
2314                         MCODECHECK((iptr->s1.argcount << 1) + 64);
2315
2316                         for (s1 = iptr->s1.argcount; --s1 >= 0;) {
2317                                 var = VAR(iptr->sx.s23.s2.args[s1]);
2318
2319                                 /* Already Preallocated? */
2320                                 if (!(var->flags & PREALLOC)) {
2321                                         s2 = emit_load(jd, iptr, var, REG_ITMP1);
2322                                         M_IST(s2, REG_SP, (s1 + 3) * 4);
2323                                 }
2324                         }
2325
2326                         /* a0 = dimension count */
2327                         M_IMOV_IMM(iptr->s1.argcount, REG_ITMP1);
2328                         M_IST(REG_ITMP1, REG_SP, 0*4);
2329
2330                         /* a1 = arraydescriptor */
2331                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2332                                 codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo, iptr->sx.s23.s3.c.ref, 0);
2333                                 M_AMOV_IMM(0, REG_ATMP1);
2334                         } else  {
2335                                 M_AMOV_IMM(iptr->sx.s23.s3.c.cls, REG_ATMP1);
2336                         }
2337                         M_AST(REG_ATMP1, REG_SP, 1*4);
2338
2339                         /* a2 = pointer to dimensions = stack pointer */
2340                         M_AMOV(REG_SP, REG_ATMP1);
2341                         M_AADD_IMM(3*4, REG_ATMP1);
2342                         M_AST(REG_ATMP1, REG_SP, 2*4);
2343
2344                         M_JSR_IMM(BUILTIN_multianewarray);
2345
2346                         /* check for exception before result assignment */
2347                         emit_exception_check(cd, iptr);
2348
2349                         assert(VAROP(iptr->dst)->type == TYPE_ADR);
2350                         d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2351                         M_INT2ADRMOVE(REG_RESULT, d);
2352                         emit_store_dst(jd, iptr, d);
2353                         break;
2354
2355
2356
2357                 default:
2358                         printf("UNKNOWN OPCODE %d\n", iptr->opc);
2359                         exceptions_throw_internalerror("Unknown ICMD %d during code generation", iptr->opc);
2360                         return false;
2361         } /* switch */
2362         /* M_TPF; */ /* nop after each ICMD */
2363         } /* for each instruction */
2364
2365         /* At the end of a basic block we may have to append some nops,
2366            because the patcher stub calling code might be longer than the
2367            actual instruction. So codepatching does not change the
2368            following block unintentionally. */
2369
2370         if (cd->mcodeptr < cd->lastmcodeptr) {
2371                 while (cd->mcodeptr < cd->lastmcodeptr) {
2372                         M_NOP;
2373                 }
2374         }
2375
2376
2377         } /* if (btpre->flags >= BBREACHED) */
2378         } /* for each basic block */
2379
2380         dseg_createlinenumbertable(cd);
2381
2382         /* generate stubs */
2383         emit_patcher_stubs(jd);
2384
2385         return true;
2386 }
2387
2388
2389 /* codegen_emit_stub_compiler **************************************************
2390
2391    Emits a stub routine which calls the compiler.
2392         
2393 *******************************************************************************/
2394
2395 void codegen_emit_stub_compiler(jitdata *jd)
2396 {
2397         methodinfo  *m;
2398         codegendata *cd;
2399
2400         /* get required compiler data */
2401
2402         m  = jd->m;
2403         cd = jd->cd;
2404
2405         /* code for the stub */
2406
2407         M_AMOV_IMM(m, REG_ATMP1);
2408         M_AMOV_IMM(asm_call_jit_compiler, REG_ATMP3);
2409         M_JMP(REG_ATMP3);
2410 }
2411
2412 /* codegen_emit_stub_builtin ***************************************************
2413
2414    Creates a stub routine which calls a builtin function.
2415
2416 *******************************************************************************/
2417
2418 void codegen_emit_stub_builtin(jitdata *jd, builtintable_entry *bte)
2419 {
2420         codeinfo    *code;
2421         codegendata *cd;
2422         methoddesc  *md;
2423         s4           i;
2424         s4           disp;
2425         s4           s1, s2;
2426
2427         /* get required compiler data */
2428         code = jd->code;
2429         cd   = jd->cd;
2430
2431         /* set some variables */
2432         md = bte->md;
2433
2434         /* calculate stack frame size */
2435         cd->stackframesize =
2436                 sizeof(stackframeinfo) / SIZEOF_VOID_P +
2437                 4;                              /* 4 arguments or return value        */
2438
2439         /* create method header */
2440         (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
2441         (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize       */
2442         (void) dseg_add_unique_s4(cd, 0);                      /* IsSync          */
2443         (void) dseg_add_unique_s4(cd, 0);                      /* IsLeaf          */
2444         (void) dseg_add_unique_s4(cd, 0);                      /* IntSave         */
2445         (void) dseg_add_unique_s4(cd, 0);                      /* FltSave         */
2446         (void) dseg_addlinenumbertablesize(cd);
2447         (void) dseg_add_unique_s4(cd, 0);                      /* ExTableSize     */
2448
2449         /* generate stub code */
2450         M_AADD_IMM(-(cd->stackframesize*4), REG_SP);
2451
2452 #if defined(ENABLE_GC_CACAO)
2453         /* Save callee saved integer registers in stackframeinfo (GC may
2454            need to recover them during a collection). */
2455
2456         disp = cd->stackframesize * 4 - sizeof(stackframeinfo) +
2457                 OFFSET(stackframeinfo, adrregs);
2458
2459         for (i = 0; i < ADR_SAV_CNT; i++)
2460                 M_AST(abi_registers_address_saved[i], REG_SP, disp + i * 4);
2461 #endif
2462
2463         /* create dynamic stack info */
2464
2465         M_AMOV(REG_SP, REG_ATMP1);
2466         M_AADD_IMM(cd->stackframesize * 4, REG_ATMP1);
2467         M_AST(REG_ATMP1, REG_SP, 0 * 4);        /* datasp */
2468
2469         M_AMOV_IMM(0, REG_ATMP1);                       /* we need pv patched in */
2470         dseg_adddata(cd);                                       /* this does the trick */
2471         M_AST(REG_ATMP1, REG_SP, 1 * 4);        /* pv */
2472
2473         M_AMOV(REG_SP, REG_ATMP1);
2474         M_AADD_IMM(cd->stackframesize * 4 + SIZEOF_VOID_P, REG_ATMP1);
2475         M_AST(REG_ATMP1, REG_SP, 2 * 4);                        /* sp */
2476
2477         M_ALD(REG_ATMP3, REG_SP, cd->stackframesize * 4);
2478         M_AST(REG_ATMP3, REG_SP, 3 * 4);                        /* ra */
2479
2480         M_JSR_IMM(codegen_stub_builtin_enter);
2481
2482         /* builtins are allowed to have 4 arguments max */
2483
2484         assert(md->paramcount <= 4);
2485
2486         /* copy arguments into new stackframe */
2487
2488         for (i = 0; i < md->paramcount; i++) {
2489                 if (!md->params[i].inmemory) {
2490                         log_text("No integer argument registers available!");
2491                         assert(0);
2492
2493                 } else {       /* float/double in memory can be copied like int/longs */
2494                         s1 = md->params[i].regoff + cd->stackframesize * 4 + 4;
2495                         s2 = md->params[i].regoff;
2496
2497                         M_ILD(REG_ITMP1, REG_SP, s1);
2498                         M_IST(REG_ITMP1, REG_SP, s2);
2499                         if (IS_2_WORD_TYPE(md->paramtypes[i].type)) {
2500                                 M_ILD(REG_ITMP1, REG_SP, s1 + 4);
2501                                 M_IST(REG_ITMP1, REG_SP, s2 + 4);
2502                         }
2503
2504                 }
2505         }
2506
2507         /* call the builtin function */
2508
2509         M_AMOV_IMM(bte->fp, REG_ATMP3);
2510         M_JSR(REG_ATMP3);
2511
2512         /* save return value */
2513         switch (md->returntype.type)    {
2514                 case TYPE_VOID: break;
2515
2516                 /* natives return float arguments in %d0, %d1, cacao expects them in %fp0 */
2517                 case TYPE_DBL:
2518                 case TYPE_LNG:
2519                         M_IST(REG_D1, REG_SP, 2 * 4);
2520                         /* fall through */
2521
2522                 case TYPE_FLT:
2523                 case TYPE_INT:
2524                 case TYPE_ADR:
2525                         M_IST(REG_D0, REG_SP, 1 * 4);
2526                         break;
2527
2528                 default: assert(0);
2529         }
2530
2531         /* remove native stackframe info */
2532
2533         M_AMOV(REG_SP, REG_ATMP1);
2534         M_AADD_IMM(cd->stackframesize * 4, REG_ATMP1);
2535         M_AST(REG_ATMP1, REG_SP, 0 * 4);
2536
2537         M_JSR_IMM(codegen_stub_builtin_exit);
2538
2539         /* restore return value */
2540         switch (md->returntype.type)    {
2541                 case TYPE_VOID: break;
2542
2543                 case TYPE_DBL:
2544                 case TYPE_LNG:
2545                         M_ILD(REG_D1, REG_SP, 2 * 4);
2546                         /* fall through */
2547
2548                 case TYPE_FLT:
2549                 case TYPE_INT:
2550                 case TYPE_ADR:
2551                         M_ILD(REG_D0, REG_SP, 1 * 4);
2552                         break;
2553
2554                 default: assert(0);
2555         }
2556
2557 #if defined(ENABLE_GC_CACAO)
2558         /* Restore callee saved integer registers from stackframeinfo (GC
2559            might have modified them during a collection). */
2560         
2561         disp = cd->stackframesize * 4 - sizeof(stackframeinfo) +
2562                 OFFSET(stackframeinfo, adrregs);
2563
2564         for (i = 0; i < ADR_SAV_CNT; i++)
2565                 M_ALD(abi_registers_address_saved[i], REG_SP, disp + i * 4);
2566 #endif
2567
2568         /* remove stackframe */
2569         M_AADD_IMM(cd->stackframesize * 4, REG_SP);
2570         M_RET;
2571 }
2572
2573
2574
2575
2576 /* codegen_emit_stub_native ****************************************************
2577
2578    Emits a stub routine which calls a native method.
2579
2580 *******************************************************************************/
2581
2582 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
2583 {
2584         methodinfo   *m;
2585         codeinfo     *code;
2586         codegendata  *cd;
2587         registerdata *rd;
2588         methoddesc   *md;
2589         s4 nativeparams, i, j, t, s1, s2;
2590         
2591         /* get required compiler data */
2592
2593         m    = jd->m;
2594         code = jd->code;
2595         cd   = jd->cd;
2596         rd   = jd->rd;
2597
2598         md = m->parseddesc;
2599         nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
2600
2601         /* calc stackframe size */
2602         cd->stackframesize =    sizeof(stackframeinfo) / SIZEOF_VOID_P +
2603                                 sizeof(localref_table) / SIZEOF_VOID_P +
2604                                 nmd->memuse +
2605                                 1 +                                             /* functionptr */
2606                                 4;                                              /* args for codegen_start_native_call */
2607
2608         /* create method header */
2609         (void) dseg_add_unique_address(cd, code);                      /* CodeinfoPointer */
2610         (void) dseg_add_unique_s4(cd, cd->stackframesize * 4);         /* FrameSize       */
2611         (void) dseg_add_unique_s4(cd, 0);                              /* IsSync          */
2612         (void) dseg_add_unique_s4(cd, 0);                              /* IsLeaf          */
2613         (void) dseg_add_unique_s4(cd, 0);                              /* IntSave         */
2614         (void) dseg_add_unique_s4(cd, 0);                              /* FltSave         */
2615         (void) dseg_addlinenumbertablesize(cd);
2616         (void) dseg_add_unique_s4(cd, 0);                              /* ExTableSize     */
2617
2618         /* print call trace */
2619 #if !defined(NDEBUG)
2620         if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
2621                 emit_verbosecall_enter(jd);
2622         }
2623 #endif
2624
2625         /* generate code */
2626         M_AADD_IMM(-(cd->stackframesize*4), REG_SP);
2627
2628         /* get function address (this must happen before the stackframeinfo) */
2629 #if !defined(WITH_STATIC_CLASSPATH)
2630         if (f == NULL)  {
2631                 codegen_addpatchref(cd, PATCHER_resolve_native_function, m, 0);
2632         }
2633 #endif
2634         M_AMOV_IMM(f, REG_ATMP2); /* do not move this line, the patcher is needed */
2635
2636         M_AST(REG_ATMP2, REG_SP, 4 * 4);
2637
2638         /* put arguments for codegen_start_native_call onto stack */
2639         /* void codegen_start_native_call(u1 *datasp, u1 *pv, u1 *sp, u1 *ra) */
2640         
2641         M_AMOV(REG_SP, REG_ATMP1);
2642         M_AADD_IMM(cd->stackframesize * 4, REG_ATMP1);
2643
2644         M_ALD(REG_ATMP3, REG_ATMP1, 0 * 4);
2645         M_AST(REG_ATMP3, REG_SP, 3 * 4);                /* ra */
2646
2647         M_AST(REG_ATMP1, REG_SP, 0 * 4);                /* datasp */
2648
2649         M_AADD_IMM(1 * 4 , REG_ATMP1);                  
2650         M_AST(REG_ATMP1, REG_SP, 2 * 4);                /* sp */
2651
2652         M_AMOV_IMM(0, REG_ATMP2);                       /* 0 needs to patched */
2653         dseg_adddata(cd);                                   /* this patches it */
2654
2655         M_AST(REG_ATMP2, REG_SP, 1 * 4);                /* pv */
2656
2657         M_JSR_IMM(codegen_start_native_call);
2658
2659         /* load function pointer */
2660         M_ALD(REG_ATMP2, REG_SP, 4 * 4);
2661
2662         /* copy arguments into stackframe */
2663         for (i = md->paramcount -1, j = i + nativeparams; i >= 0; --i, --j)     {
2664                 t = md->paramtypes[i].type;
2665                 /* all arguments via stack */
2666                 assert(md->params[i].inmemory);                                         
2667
2668                 s1 = md->params[i].regoff + cd->stackframesize * 4 + 4;
2669                 s2 = nmd->params[j].regoff;
2670
2671                 /* simply copy argument stack */
2672                 M_ILD(REG_ITMP1, REG_SP, s1);
2673                 M_IST(REG_ITMP1, REG_SP, s2);
2674                 if (IS_2_WORD_TYPE(t))  {
2675                         M_ILD(REG_ITMP1, REG_SP, s1 + 4);
2676                         M_IST(REG_ITMP1, REG_SP, s2 + 4);
2677                 }
2678         }
2679
2680         /* for static function class as second arg */
2681         if (m->flags & ACC_STATIC)      {
2682                 M_AMOV_IMM(m->class, REG_ATMP1);
2683                 M_AST(REG_ATMP1, REG_SP, 1 * 4);
2684         }
2685         /* env ist first argument */
2686         M_AMOV_IMM(_Jv_env, REG_ATMP1);
2687         M_AST(REG_ATMP1, REG_SP, 0 * 4);
2688
2689         /* call the native function */
2690         M_JSR(REG_ATMP2);
2691
2692         /* save return value */
2693         switch (md->returntype.type)    {
2694                 case TYPE_VOID: break;
2695
2696                 /* natives return float arguments in %d0, %d1, cacao expects them in %fp0 */
2697                 case TYPE_DBL:
2698                 case TYPE_LNG:
2699                         M_IST(REG_D1, REG_SP, 2 * 4);
2700                         /* fall through */
2701
2702                 case TYPE_FLT:
2703                 case TYPE_INT:
2704                 case TYPE_ADR:
2705                         M_IST(REG_D0, REG_SP, 1 * 4);
2706                         break;
2707
2708                 default: assert(0);
2709         }
2710         
2711         /* print call trace */
2712 #if ! defined(NDEBUG)
2713         if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
2714                 emit_verbosecall_exit(jd);
2715         }
2716 #endif
2717         /* remove native stackframe info */
2718         /* therefore we call: java_objectheader *codegen_finish_native_call(u1 *datasp) */
2719
2720         M_AMOV(REG_SP, REG_ATMP3);
2721         M_AADD_IMM(cd->stackframesize * 4, REG_ATMP3);
2722         M_AST(REG_ATMP3, REG_SP, 0 * 4);                        /* datasp */
2723         M_JSR_IMM(codegen_finish_native_call);
2724         
2725         M_INT2ADRMOVE(REG_RESULT, REG_ATMP1);
2726         /* restore return value */
2727         switch (md->returntype.type)    {
2728                 case TYPE_VOID: break;
2729
2730                 case TYPE_DBL:
2731                 case TYPE_LNG:
2732                         M_ILD(REG_D1, REG_SP, 2 * 4);
2733                         /* fall through */
2734                 case TYPE_FLT:
2735                 case TYPE_INT:
2736                 case TYPE_ADR:
2737                         M_ILD(REG_D0, REG_SP, 1 * 4);
2738                         break;
2739
2740                 default: assert(0);
2741         }
2742 #if !defined(ENABLE_SOFTFLOAT)
2743                 /* additionally load values into floating points registers
2744                  * as cacao jit code expects them there */
2745         switch (md->returntype.type)    {
2746                 case TYPE_FLT:
2747                         M_FLD(REG_D0, REG_SP, 1 * 4);
2748                         break;
2749                 case TYPE_DBL:  
2750                         M_DLD(REG_D0, REG_SP, 1 * 4);
2751                         break;
2752         }
2753 #endif
2754         /* restore saved registers */
2755
2756         M_AADD_IMM(cd->stackframesize*4, REG_SP);
2757         /* check for exception */
2758         M_ATST(REG_ATMP1);
2759         M_BNE(2);
2760         M_RET;
2761
2762         /* handle exception, REG_ATMP1 already contains exception object, REG_ATMP2 holds address */
2763         
2764         M_ALD(REG_ATMP2_XPC, REG_SP, 0);                /* take return address as faulting instruction */
2765         M_AADD_IMM(-2, REG_ATMP2_XPC);                  /* which is off by 2 */
2766         M_JMP_IMM(asm_handle_nat_exception);
2767
2768         /* should never be reached from within jit code*/
2769         M_JSR_IMM(0);
2770
2771         /* generate patcher stub call code */
2772         emit_patcher_stubs(jd);
2773 }
2774
2775
2776 /*
2777  * These are local overrides for various environment variables in Emacs.
2778  * Please do not remove this and leave it at the end of the file, where
2779  * Emacs will automagically detect them.
2780  * ---------------------------------------------------------------------
2781  * Local variables:
2782  * mode: c
2783  * indent-tabs-mode: t
2784  * c-basic-offset: 4
2785  * tab-width: 4
2786  * End:
2787  * vim:noexpandtab:sw=4:ts=4:
2788  */