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