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