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