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