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