* Removed all Id tags.
[cacao.git] / src / vm / jit / m68k / codegen.c
1 /* src/vm/jit/m68k/codegen.c
2
3    Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25 */
26
27
28 #include "config.h"
29
30 #include <assert.h>
31 #include <stdint.h>
32
33 #include "md-abi.h"
34 #include "md-os.h"
35
36 #include "vm/types.h"
37 #include "vm/jit/m68k/codegen.h"
38 #include "vm/jit/m68k/emit.h"
39
40 #include "mm/memory.h"
41 #include "native/jni.h"
42 #include "native/localref.h"
43 #include "native/native.h"
44
45 #include "threads/lock-common.h"
46
47 #include "vm/builtin.h"
48 #include "vm/exceptions.h"
49 #include "vm/global.h"
50 #include "vm/stringlocal.h"
51 #include "vm/vm.h"
52
53 #include "vm/jit/asmpart.h"
54 #include "vm/jit/codegen-common.h"
55 #include "vm/jit/dseg.h"
56 #include "vm/jit/emit-common.h"
57 #include "vm/jit/jit.h"
58 #include "vm/jit/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
1119                 case ICMD_GETSTATIC:  /* ...  ==> ..., value                          */
1120
1121                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1122                                 uf        = iptr->sx.s23.s3.uf;
1123                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1124                                 disp      = 0;
1125
1126                                 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, 0);
1127                         }
1128                         else {
1129                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1130                                 fieldtype = fi->type;
1131                                 disp      = (intptr_t) fi->value;
1132
1133                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1134                                         codegen_addpatchref(cd, PATCHER_initialize_class, fi->class,
1135                                                                                 0);
1136                                 }
1137                         }
1138
1139                         M_AMOV_IMM(disp, REG_ATMP1);
1140                         switch (fieldtype) {
1141 #if defined(ENABLE_SOFTFLOAT)
1142                         case TYPE_FLT:
1143 #endif
1144                         case TYPE_INT:
1145                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1146                                 M_ILD(d, REG_ATMP1, 0);
1147                                 break;
1148                         case TYPE_ADR:
1149                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1150                                 M_ALD(d, REG_ATMP1, 0);
1151                                 break;
1152 #if defined(ENABLE_SOFTFLOAT)
1153                         case TYPE_DBL:
1154 #endif
1155                         case TYPE_LNG:
1156                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
1157                                 M_LLD(d, REG_ATMP1, 0);
1158                                 break;
1159 #if !defined(ENABLE_SOFTFLOAT)
1160                         case TYPE_FLT:
1161                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1162                                 M_FLD(d, REG_ATMP1, 0);
1163                                 break;
1164                         case TYPE_DBL:                          
1165                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1166                                 M_DLD(d, REG_ATMP1, 0);
1167                                 break;
1168 #endif
1169                         }
1170                         emit_store_dst(jd, iptr, d);
1171                         break;
1172
1173                 case ICMD_PUTSTATIC:  /* ..., value  ==> ...                          */
1174
1175                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1176                                 uf        = iptr->sx.s23.s3.uf;
1177                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1178                                 disp      = 0;
1179
1180                                 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, 0);
1181                         }
1182                         else {
1183                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1184                                 fieldtype = fi->type;
1185                                 disp      = (intptr_t) fi->value;
1186
1187                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1188                                         codegen_addpatchref(cd, PATCHER_initialize_class, fi->class,
1189                                                                                 0);
1190                         }
1191                 
1192                         M_AMOV_IMM(disp, REG_ATMP1);
1193                         switch (fieldtype) {
1194 #if defined(ENABLE_SOFTFLOAT)
1195                         case TYPE_FLT:
1196 #endif
1197                         case TYPE_INT:
1198                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1199                                 M_IST(s1, REG_ATMP1, 0);
1200                                 break;
1201 #if defined(ENABLE_SOFTFLOAT)
1202                         case TYPE_DBL:
1203 #endif
1204                         case TYPE_LNG:
1205                                 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
1206                                 M_LST(s1, REG_ATMP1, 0);
1207                                 break;
1208                         case TYPE_ADR:
1209                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1210                                 M_AST(s1, REG_ATMP1, 0);
1211                                 break;
1212 #if !defined(ENABLE_SOFTFLOAT)
1213                         case TYPE_FLT:
1214                                 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1215                                 M_FST(s1, REG_ATMP1, 0);
1216                                 break;
1217                         case TYPE_DBL:
1218                                 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1219                                 M_DST(s1, REG_ATMP1, 0);
1220                                 break;
1221 #endif
1222                         default: assert(0);
1223                         }
1224                         break;
1225
1226                 case ICMD_GETFIELD:   /* ...  ==> ..., value                          */
1227
1228                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1229
1230                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1231                                 uf        = iptr->sx.s23.s3.uf;
1232                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1233                                 disp      = 0;
1234
1235                                 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
1236                         }
1237                         else {
1238                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1239                                 fieldtype = fi->type;
1240                                 disp      = fi->offset;
1241                         }
1242
1243                         /* implicit null-pointer check */
1244                         switch (fieldtype) {
1245 #if defined(ENABLE_SOFTFLOAT)
1246                         case TYPE_FLT:
1247 #endif
1248                         case TYPE_INT:
1249                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1250                                 M_ILD(d, s1, disp);
1251                                 break;
1252 #if defined(ENABLE_SOFTFLOAT)
1253                         case TYPE_DBL:
1254 #endif
1255                         case TYPE_LNG:
1256                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1257                                 M_LLD(d, s1, disp);
1258                                 break;
1259                         case TYPE_ADR:
1260                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1261                                 M_ALD(d, s1, disp);
1262                                 break;
1263 #if !defined(ENABLE_SOFTFLOAT)
1264                         case TYPE_FLT:
1265                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1266                                 M_FLD(d, s1, disp);
1267                                 break;
1268                         case TYPE_DBL:                          
1269                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1270                                 M_DLD(d, s1, disp);
1271                                 break;
1272 #endif
1273                         }
1274                         emit_store_dst(jd, iptr, d);
1275                         break;
1276
1277                 case ICMD_PUTFIELD:   /* ..., value  ==> ...                          */
1278
1279                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1280
1281                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1282                                 uf        = iptr->sx.s23.s3.uf;
1283                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1284                                 disp      = 0;
1285                         }
1286                         else {
1287                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1288                                 fieldtype = fi->type;
1289                                 disp      = fi->offset;
1290                         }
1291
1292                         if (IS_INT_LNG_TYPE(fieldtype)) {
1293                                 if (IS_2_WORD_TYPE(fieldtype)) {
1294                                         s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
1295                                 } else {
1296                                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1297                                 }
1298                         } else {
1299                                 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1300                         }
1301
1302                         if (INSTRUCTION_IS_UNRESOLVED(iptr))
1303                                 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
1304
1305                         /* implicit null-pointer check */
1306                         switch (fieldtype) {
1307 #if defined(ENABLE_SOFTFLOAT)
1308                         case TYPE_FLT:
1309 #endif
1310                         case TYPE_INT:
1311                                 M_IST(s2, s1, disp);
1312                                 break;
1313
1314 #if defined(ENABLE_SOFTFLOAT)
1315                         case TYPE_DBL:
1316 #endif
1317                         case TYPE_LNG:
1318                                 M_LST(s2, s1, disp);  
1319                                 break;
1320                         case TYPE_ADR:
1321                                 M_AST(s2, s1, disp);
1322                                 break;
1323 #if !defined(ENABLE_SOFTFLOAT)
1324                         case TYPE_FLT:
1325                                 M_FST(s2, s1, disp);
1326                                 break;
1327                         case TYPE_DBL:
1328                                 M_DST(s2, s1, disp);
1329                                 break;
1330 #endif
1331                         }
1332                         break;
1333
1334                 case ICMD_ARRAYLENGTH: /* ..., arrayref  ==> ..., length              */
1335
1336                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1337                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1338                         /* implicit null-pointer check */
1339                         M_ILD(d, s1, OFFSET(java_array_t, size));
1340                         emit_store_dst(jd, iptr, d);
1341                         break;
1342
1343                 case ICMD_BALOAD:     /* ..., arrayref, index  ==> ..., value         */
1344
1345                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1346                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1347                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1348                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1349                         M_INTMOVE(s2, REG_ITMP2);
1350                         M_IADD_IMM(OFFSET(java_bytearray_t, data[0]), REG_ITMP2);
1351                         M_ADRMOVE(s1, REG_ATMP1);
1352                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1353                         /* implicit null-pointer check */
1354                         M_LBZX(REG_ATMP1, d);
1355                         M_BSEXT(d, d);
1356                         emit_store_dst(jd, iptr, d);
1357                         break;                  
1358
1359                 case ICMD_CALOAD:     /* ..., arrayref, index  ==> ..., value         */
1360
1361                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1362                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1363                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1364                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1365                         M_INTMOVE(s2, REG_ITMP2);
1366                         M_ISSL_IMM(1, REG_ITMP2);
1367                         M_IADD_IMM(OFFSET(java_chararray_t, data[0]), REG_ITMP2);
1368                         M_ADRMOVE(s1, REG_ATMP1);
1369                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1370                         /* implicit null-pointer check */
1371                         M_LHZX(REG_ATMP1, d);
1372                         M_CZEXT(d, d);
1373                         emit_store_dst(jd, iptr, d);
1374                         break;
1375
1376                 case ICMD_SALOAD:     /* ..., arrayref, index  ==> ..., value         */
1377
1378                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1379                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1380                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1381                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1382                         M_INTMOVE(s2, REG_ITMP2);
1383                         M_ISSL_IMM(1, REG_ITMP2);
1384                         M_IADD_IMM(OFFSET(java_shortarray_t, data[0]), REG_ITMP2);
1385                         M_ADRMOVE(s1, REG_ATMP1);
1386                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1387                 
1388                         /* implicit null-pointer check */
1389                         M_LHZX(REG_ATMP1, d);
1390                         M_SSEXT(d, d);
1391                         emit_store_dst(jd, iptr, d);
1392                         break;
1393
1394                 case ICMD_IALOAD:     /* ..., arrayref, index  ==> ..., value         */
1395
1396                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1397                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1398                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1399                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1400                         M_INTMOVE(s2, REG_ITMP2);
1401                         M_ISSL_IMM(2, REG_ITMP2);
1402                         M_IADD_IMM(OFFSET(java_intarray_t, data[0]), REG_ITMP2);
1403                         M_ADRMOVE(s1, REG_ATMP1);
1404                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1405                         /* implicit null-pointer check */
1406                         M_LWZX(REG_ATMP1, d);
1407                         emit_store_dst(jd, iptr, d);
1408                         break;
1409
1410                 case ICMD_LALOAD:     /* ..., arrayref, index  ==> ..., value         */
1411                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1412                         s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1413                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1414                         /* implicit null-pointer check */
1415                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1416                         M_INTMOVE(s2, REG_ITMP1);
1417                         M_ISSL_IMM(3, REG_ITMP1);
1418                         M_IADD_IMM(OFFSET(java_longarray_t, data[0]), REG_ITMP1);
1419                         M_ADRMOVE(s1, REG_ATMP1);
1420                         M_AADDINT(REG_ITMP1, REG_ATMP1);
1421                         /* implicit null-pointer check */
1422                         M_LLD(d, REG_ATMP1, 0);
1423                         emit_store_dst(jd, iptr, d);
1424                         break;
1425
1426                 case ICMD_FALOAD:     /* ..., arrayref, index  ==> ..., value         */
1427                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1428                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1429                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1430                         M_INTMOVE(s2, REG_ITMP2);
1431                         M_ISSL_IMM(2, REG_ITMP2);
1432                         M_IADD_IMM(OFFSET(java_floatarray_t, data[0]), REG_ITMP2);
1433                         M_ADRMOVE(s1, REG_ATMP1);
1434                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1435                         /* implicit null-pointer check */
1436 #if !defined(ENABLE_SOFTFLOAT)
1437                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1438                         M_FLD(d, REG_ATMP1, 0);
1439 #else
1440                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1441                         M_LWZX(REG_ATMP1, d);
1442 #endif
1443                         emit_store_dst(jd, iptr, d);
1444                         break;
1445
1446                 case ICMD_DALOAD:     /* ..., arrayref, index  ==> ..., value         */
1447                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1448                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1449                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1450                         M_INTMOVE(s2, REG_ITMP2);
1451                         M_ISSL_IMM(3, REG_ITMP2);
1452                         M_IADD_IMM(OFFSET(java_doublearray_t, data[0]), REG_ITMP2);
1453                         M_ADRMOVE(s1, REG_ATMP1);
1454                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1455                         /* implicit null-pointer check */
1456 #if !defined(ENABLE_SOFTFLOAT)
1457                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1458                         M_DLD(d, REG_ATMP1, 0);
1459 #else
1460                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1461                         M_LLD(d, REG_ATMP1, 0);
1462 #endif
1463                         emit_store_dst(jd, iptr, d);
1464                         break;
1465
1466                 case ICMD_AALOAD:     /* ..., arrayref, index  ==> ..., value         */
1467                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1468                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1469                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1470                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1471                         M_INTMOVE(s2, REG_ITMP2);
1472                         M_ISSL_IMM(2, REG_ITMP2);
1473                         M_IADD_IMM(OFFSET(java_objectarray_t, data[0]), REG_ITMP2);
1474                         M_ADRMOVE(s1, REG_ATMP1);
1475                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1476         
1477                         /* implicit null-pointer check */
1478                         M_LAX(REG_ATMP1, d);
1479                         emit_store_dst(jd, iptr, d);
1480                         break;
1481
1482
1483                 case ICMD_BASTORE:    /* ..., arrayref, index, value  ==> ...         */
1484                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1485                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1486                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1487                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1488                         M_INTMOVE(s2, REG_ITMP2);
1489                         M_IADD_IMM(OFFSET(java_bytearray_t, data[0]), REG_ITMP2);
1490                         M_ADRMOVE(s1, REG_ATMP1);
1491                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1492                         /* implicit null-pointer check */
1493                         M_STBX(REG_ATMP1, s3);
1494                         break;
1495
1496                 case ICMD_CASTORE:    /* ..., arrayref, index, value  ==> ...         */
1497                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1498                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1499                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1500                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1501                         M_INTMOVE(s2, REG_ITMP2);
1502                         M_ISSL_IMM(1, REG_ITMP2);
1503                         M_IADD_IMM(OFFSET(java_chararray_t, data[0]), REG_ITMP2); 
1504                         M_ADRMOVE(s1, REG_ATMP1);
1505                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1506                         /* implicit null-pointer check */
1507                         M_STHX(REG_ATMP1, s3);
1508                         break;
1509
1510                 case ICMD_SASTORE:    /* ..., arrayref, index, value  ==> ...         */
1511                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1512                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1513                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1514                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1515                         M_INTMOVE(s2, REG_ITMP2);
1516                         M_ISSL_IMM(1, REG_ITMP2);
1517                         M_IADD_IMM(OFFSET(java_shortarray_t, data[0]), REG_ITMP2);
1518                         M_ADRMOVE(s1, REG_ATMP1);
1519                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1520                         /* implicit null-pointer check */
1521                         M_STHX(REG_ATMP1, s3);
1522                         break;
1523
1524                 case ICMD_IASTORE:    /* ..., arrayref, index, value  ==> ...         */
1525                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1526                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1527                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1528                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1529                         M_INTMOVE(s2, REG_ITMP2);
1530                         M_ISSL_IMM(2, REG_ITMP2);
1531                         M_IADD_IMM(OFFSET(java_intarray_t, data[0]), REG_ITMP2);
1532                         M_ADRMOVE(s1, REG_ATMP1);
1533                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1534                         /* implicit null-pointer check */
1535                         M_STWX(REG_ATMP1, s3);
1536                         break;
1537
1538                 case ICMD_LASTORE:    /* ..., arrayref, index, value  ==> ...         */
1539                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1540                         s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1541                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1542
1543                         M_INTMOVE(s2, REG_ITMP1);
1544                         M_ISSL_IMM(3, REG_ITMP1);
1545                         M_IADD_IMM(OFFSET(java_longarray_t, data[0]), REG_ITMP1);
1546                         M_ADRMOVE(s1, REG_ATMP1);
1547                         M_AADDINT(REG_ITMP1, REG_ATMP1);
1548                         /* implicit null-pointer check */
1549                         s3 = emit_load_s3(jd, iptr, REG_ITMP12_PACKED);
1550                         M_LST(s3, REG_ATMP1, 0);
1551                         break;
1552
1553                 case ICMD_FASTORE:    /* ..., arrayref, index, value  ==> ...         */
1554                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1555                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1556                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1557                         M_INTMOVE(s2, REG_ITMP2);
1558                         M_ISSL_IMM(2, REG_ITMP2);
1559                         M_IADD_IMM(OFFSET(java_floatarray_t, data[0]), REG_ITMP2);
1560                         M_ADRMOVE(s1, REG_ATMP1);
1561                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1562                         /* implicit null-pointer check */
1563 #if !defined(ENABLE_SOFTFLOAT)
1564                         s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1565                         M_FST(s3, REG_ATMP1, 0);
1566 #else
1567                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1568                         M_STWX(REG_ATMP1, s3);
1569 #endif
1570                         break;
1571
1572                 case ICMD_DASTORE:    /* ..., arrayref, index, value  ==> ...         */
1573                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1574                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1575                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1576                         M_INTMOVE(s2, REG_ITMP2);
1577                         M_ISSL_IMM(3, REG_ITMP2);
1578                         M_IADD_IMM(OFFSET(java_doublearray_t, data[0]), REG_ITMP2);
1579                         M_ADRMOVE(s1, REG_ATMP1);
1580                         M_AADDINT(REG_ITMP2, REG_ATMP1);
1581                         /* implicit null-pointer check */
1582 #if !defined(ENABLE_SOFTFLOAT)
1583                         s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1584                         M_DST(s3, REG_ATMP1, 0);
1585 #else
1586                         s3 = emit_load_s3(jd, iptr, REG_ITMP12_PACKED);
1587                         /* implicit null-pointer check */
1588                         M_LST(s3, REG_ATMP1, 0);
1589 #endif
1590                         break;
1591
1592                 case ICMD_AASTORE:    /* ..., arrayref, index, value  ==> ...         */
1593
1594                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1595                         s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1596                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1597                         s3 = emit_load_s3(jd, iptr, REG_ATMP2);
1598
1599                         /* XXX what if array is NULL */
1600                         disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1601
1602                         M_AST(s1, REG_SP, 0*4);
1603                         M_AST(s3, REG_SP, 1*4);
1604                         M_JSR_IMM(BUILTIN_canstore);    
1605                         emit_exception_check(cd, iptr);
1606
1607                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1608                         s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1609                         s3 = emit_load_s3(jd, iptr, REG_ATMP2);
1610                         M_INTMOVE(s2, REG_ITMP1);
1611                         M_ISSL_IMM(2, REG_ITMP1);
1612                         M_IADD_IMM(OFFSET(java_objectarray_t, data[0]), REG_ITMP1);
1613                         M_ADRMOVE(s1, REG_ATMP1);
1614                         M_AADDINT(REG_ITMP1, REG_ATMP1);
1615                         /* implicit null-pointer check */
1616                         M_STAX(REG_ATMP1, s3);
1617                         break;
1618
1619
1620
1621                 /* METHOD INVOCATION *********************************************************/
1622                 case ICMD_BUILTIN:      /* ..., [arg1, [arg2 ...]] ==> ...            */
1623                         bte = iptr->sx.s23.s3.bte;
1624                         md  = bte->md;
1625                         goto gen_method;
1626
1627                 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ...            */
1628                 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
1629                 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer    */
1630                 case ICMD_INVOKEINTERFACE:
1631                         REPLACEMENT_POINT_INVOKE(cd, iptr);
1632
1633                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1634                                 lm = NULL;
1635                                 um = iptr->sx.s23.s3.um;
1636                                 md = um->methodref->parseddesc.md;
1637                         }
1638                         else {
1639                                 lm = iptr->sx.s23.s3.fmiref->p.method;
1640                                 um = NULL;
1641                                 md = lm->parseddesc;
1642                         }
1643         gen_method:
1644                         s3 = md->paramcount;
1645         
1646                         MCODECHECK((s3 << 1) + 64);
1647
1648                         /* copy arguments to stack */
1649                         for (s3 = s3 - 1; s3 >= 0; s3--)        {
1650                                 var = VAR(iptr->sx.s23.s2.args[s3]);
1651                                 /* already preallocated */
1652                                 if (var->flags & PREALLOC) continue;
1653                 
1654                                 if (!md->params[s3].inmemory) assert(0);
1655
1656                                 switch (var->type)      {
1657 #if defined(ENABLE_SOFTFLOAT)
1658                                         case TYPE_DBL:
1659 #endif
1660                                         case TYPE_LNG:
1661                                                 d = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
1662                                                 M_LST(d, REG_SP, md->params[s3].regoff);
1663                                                 break;
1664 #if defined(ENABLE_SOFTFLOAT)
1665                                         case TYPE_FLT:
1666 #endif
1667                                         case TYPE_INT:
1668                                                 d = emit_load(jd, iptr, var, REG_ITMP1);
1669                                                 M_IST(d, REG_SP, md->params[s3].regoff);
1670                                                 break;
1671                                         case TYPE_ADR:
1672                                                 d = emit_load(jd, iptr, var, REG_ATMP1);
1673                                                 M_AST(d, REG_SP, md->params[s3].regoff);
1674                                                 break;
1675 #if !defined(ENABLE_SOFTFLOAT)
1676                                         case TYPE_FLT:
1677                                                 d = emit_load(jd, iptr, var, REG_FTMP1);
1678                                                 M_FST(d, REG_SP, md->params[s3].regoff);
1679                                                 break;
1680                                         case TYPE_DBL:
1681                                                 d = emit_load(jd, iptr, var, REG_FTMP1);
1682                                                 M_DST(d, REG_SP, md->params[s3].regoff);
1683                                                 break;
1684 #endif
1685                                         default:
1686                                                 assert(0);
1687                                 }
1688                         }
1689
1690                         /* arguments in place now */
1691                         switch(iptr->opc)       {
1692                                 case ICMD_BUILTIN: 
1693                                         disp = (ptrint) bte->fp;
1694                                         d = md->returntype.type;
1695                                         M_JSR_IMM(disp);
1696
1697                                         REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1698                                         emit_exception_check(cd, iptr);
1699                                         break;
1700
1701                                 case ICMD_INVOKESPECIAL: 
1702                                         /* adress register for sure */
1703                                         M_ALD(REG_ATMP1, REG_SP, 0);
1704                                         emit_nullpointer_check(cd, iptr, REG_ATMP1);
1705                                         /* fall through */
1706                                 case ICMD_INVOKESTATIC: 
1707                                         if (lm == NULL) {
1708                                                 codegen_addpatchref(cd, PATCHER_invokestatic_special, um, 0);
1709                                                 disp = 0;
1710                                                 M_AMOV_IMM(disp, REG_ATMP1);
1711                                         } else  {
1712                                                 disp = lm->stubroutine;
1713                                                 M_AMOV_IMM(disp, REG_ATMP1);
1714                                         }
1715
1716                                         /* generate the actual call */
1717                                         M_JSR(REG_ATMP1);
1718                                         REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1719                                         break;
1720
1721
1722                                 case ICMD_INVOKEVIRTUAL:
1723                                         if (lm == NULL) {
1724                                                 codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
1725                                                 s1 = 0;
1726                                         } else {
1727                                                 s1 = OFFSET(vftbl_t, table[0]) + sizeof(methodptr) * lm->vftblindex;
1728                                         }
1729                                         /* load object pointer (==argument 0) */
1730                                         M_ALD(REG_ATMP1, REG_SP, 0);
1731                                         /* implicit null-pointer check */
1732                                         M_ALD(REG_METHODPTR, REG_ATMP1, OFFSET(java_object_t, vftbl));
1733                                         M_ALD(REG_ATMP3, REG_METHODPTR, s1);
1734                                         /* generate the actual call */
1735                                         M_JSR(REG_ATMP3);
1736                                         break;
1737                                 case ICMD_INVOKEINTERFACE: 
1738                                         if (lm == NULL) {
1739                                                 codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
1740
1741                                                 s1 = 0;
1742                                                 s2 = 0;
1743                                         } else {
1744                                                 s1 = OFFSET(vftbl_t, interfacetable[0]) - sizeof(methodptr*) * lm->class->index;
1745                                                 s2 = sizeof(methodptr) * (lm - lm->class->methods);
1746                                         }
1747                                         /* load object pointer (==argument 0) */
1748                                         M_ALD(REG_ATMP1, REG_SP, 0);
1749
1750                                         /* implicit null-pointer check */
1751                                         M_ALD(REG_METHODPTR, REG_ATMP1, OFFSET(java_object_t, vftbl));
1752                                         M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
1753                                         M_ALD(REG_ATMP3, REG_METHODPTR, s2);
1754
1755                                         /* generate the actual call */
1756                                         M_JSR(REG_ATMP3);
1757                                         REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1758                                         break;
1759
1760                                 default: assert(0);
1761                                 }       /* switch (iptr->opc) */
1762
1763                                 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1764                                 
1765                                 /* store return value */
1766                                 d = md->returntype.type;
1767
1768                                 switch (d)      {
1769                                         case TYPE_VOID: break;
1770 #if defined(ENABLE_SOFTFLOAT)
1771                                         case TYPE_FLT:
1772 #endif
1773                                         case TYPE_INT:
1774                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
1775                                                 M_INTMOVE(REG_RESULT, s1);
1776                                                 break;
1777 #if defined(ENABLE_SOFTFLOAT)
1778                                         case TYPE_DBL:
1779 #endif
1780                                         case TYPE_LNG:
1781                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
1782                                                 M_LNGMOVE(REG_RESULT_PACKED, s1);
1783                                                 break;
1784                                         case TYPE_ADR:
1785                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_ATMP1);
1786                                                 /* all stuff is returned in %d0 */
1787                                                 M_INT2ADRMOVE(REG_RESULT, s1);
1788                                                 break;
1789 #if !defined(ENABLE_SOFTFLOAT)
1790                                         /*
1791                                          *      for BUILTINS float values are returned in %d0,%d1
1792                                          *      within cacao we use %fp0 for that.
1793                                          */
1794                                         case TYPE_FLT:
1795                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1796                                                 if (iptr->opc == ICMD_BUILTIN)  {
1797                                                         M_INT2FLTMOVE(REG_FRESULT, s1);
1798                                                 } else  {
1799                                                         M_FLTMOVE(REG_FRESULT, s1);
1800                                                 }
1801                                                 break;
1802                                         case TYPE_DBL:
1803                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1804                                                 if (iptr->opc == ICMD_BUILTIN)  {
1805                                                         M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 4 + 4);
1806                                                         M_DLD(s1, REG_SP, rd->memuse * 4 + 4);
1807                                                 } else  {
1808                                                         M_DBLMOVE(REG_FRESULT, s1);
1809                                                 }
1810                                                 break;
1811 #endif
1812                                         default:
1813                                                 assert(0);
1814                                 }
1815                                 if (d != TYPE_VOID) emit_store_dst(jd, iptr, s1);
1816                         break; /* ICMD_INVOKE* */
1817
1818 #if defined(ENABLE_SOFTFLOAT)
1819                 case ICMD_FRETURN:
1820 #endif
1821                 case ICMD_IRETURN:      /* ..., retvalue ==> ...                      */
1822
1823                         REPLACEMENT_POINT_RETURN(cd, iptr);
1824                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
1825                         M_INTMOVE(s1, REG_RESULT);
1826                         goto nowperformreturn;
1827
1828                 case ICMD_ARETURN:      /* ..., retvalue ==> ...                      */
1829
1830                         REPLACEMENT_POINT_RETURN(cd, iptr);
1831                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
1832                         assert(VAROP(iptr->s1)->type == TYPE_ADR);
1833                         M_ADR2INTMOVE(s1, REG_RESULT);
1834
1835 #ifdef ENABLE_VERIFIER
1836                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1837                                 unresolved_class *uc = iptr->sx.s23.s2.uc;
1838
1839                                 codegen_addpatchref(cd, PATCHER_resolve_class, uc, 0);
1840                         }
1841 #endif /* ENABLE_VERIFIER */
1842                         goto nowperformreturn;
1843
1844 #if defined(ENABLE_SOFTFLOAT)
1845                 case ICMD_DRETURN:
1846 #endif
1847                 case ICMD_LRETURN:      /* ..., retvalue ==> ...                      */
1848                         REPLACEMENT_POINT_RETURN(cd, iptr);
1849                         s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
1850                         M_LNGMOVE(s1, REG_RESULT_PACKED);
1851                         goto nowperformreturn;
1852
1853 #if !defined(ENABLE_SOFTFLOAT)
1854                 case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
1855                         REPLACEMENT_POINT_RETURN(cd, iptr);
1856                         s1 = emit_load_s1(jd, iptr, REG_FRESULT);
1857                         M_FLTMOVE(s1, REG_FRESULT);
1858                         goto nowperformreturn;
1859
1860                 case ICMD_DRETURN:
1861                         REPLACEMENT_POINT_RETURN(cd, iptr);
1862                         s1 = emit_load_s1(jd, iptr, REG_FRESULT);
1863                         M_DBLMOVE(s1, REG_FRESULT);
1864                         goto nowperformreturn;
1865
1866 #endif
1867
1868                 case ICMD_RETURN:      /* ...  ==> ...                                */
1869
1870                         REPLACEMENT_POINT_RETURN(cd, iptr);
1871
1872 nowperformreturn:
1873                         {
1874                         s4 i, p;
1875                         
1876                         p = cd->stackframesize;
1877
1878                         /* call trace function */
1879 #if !defined(NDEBUG)
1880                         emit_verbosecall_exit(jd);
1881 #endif
1882
1883 #if defined(ENABLE_THREADS)
1884                         /* call lock_monitor_exit */
1885                         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
1886                                 M_ILD(REG_ITMP3, REG_SP, rd->memuse * 8);
1887
1888                                 /* we need to save the proper return value */
1889                                 /* we do not care for the long -> doubel convert space here */
1890                                 switch (iptr->opc) {
1891 #if defined(ENABLE_SOFTFLOAT)
1892                                 case ICMD_DRETURN:
1893 #endif
1894                                 case ICMD_LRETURN:
1895                                         M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 8 + 8);
1896                                         break;
1897 #if defined(ENABLE_SOFTFLOAT)
1898                                 case ICMD_FRETURN:
1899 #endif
1900                                 case ICMD_IRETURN:
1901                                 case ICMD_ARETURN:
1902                                         M_IST(REG_RESULT , REG_SP, rd->memuse * 8 + 8);
1903                                         break;
1904 #if !defined(ENABLE_SOFTFLOAT)
1905                                 case ICMD_FRETURN:
1906                                         M_FST(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1907                                         break;
1908                                 case ICMD_DRETURN:
1909                                         M_DST(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1910                                         break;
1911 #endif
1912                                 }
1913
1914                                 M_IST(REG_ITMP3, REG_SP, 0 * 4);
1915                                 M_JSR_IMM(LOCK_monitor_exit);
1916
1917                                 /* and now restore the proper return value */
1918                                 switch (iptr->opc) {
1919
1920 #if defined(ENABLE_SOFTFLOAT)
1921                                 case ICMD_DRETURN:
1922 #endif
1923                                 case ICMD_LRETURN:
1924                                         M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 8 + 8);
1925                                         break;
1926 #if defined(ENABLE_SOFTFLOAT)
1927                                 case ICMD_FRETURN:
1928 #endif
1929                                 case ICMD_IRETURN:
1930                                 case ICMD_ARETURN:
1931                                         M_ILD(REG_RESULT , REG_SP, rd->memuse * 8 + 8);
1932                                         break;
1933 #if !defined(ENABLE_SOFTFLOAT)
1934                                 case ICMD_FRETURN:
1935                                         M_FLD(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1936                                         break;
1937                                 case ICMD_DRETURN:
1938                                         M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1939                                         break;
1940 #endif
1941                                 }
1942                         }
1943 #endif
1944
1945
1946                         /* restore return address                                         */
1947 #if 0
1948                         if (!jd->isleafmethod) {
1949                                 /* ATTENTION: Don't use REG_ZERO (r0) here, as M_ALD
1950                                    may have a displacement overflow. */
1951
1952                                 M_ALD(REG_ITMP1, REG_SP, p * 4 + LA_LR_OFFSET);
1953                                 M_MTLR(REG_ITMP1);
1954                         }
1955 #endif
1956                         /* restore saved registers                                        */
1957
1958                         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
1959                                 p-=8; M_ILD(rd->savintregs[i], REG_SP, p);
1960                         }
1961                         for (i=ADR_SAV_CNT-1; i>=rd->savadrreguse; --i) {
1962                                 p-=8; M_ALD(rd->savadrregs[i], REG_SP, p);
1963                         }
1964 #if !defined(ENABLE_SOFTFLOAT)
1965                         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
1966                                 p-=8; M_FLOAD(rd->savfltregs[i], REG_SP, p);
1967                         }
1968 #endif
1969                         /* deallocate stack                                               */
1970                         M_AADD_IMM(cd->stackframesize, REG_SP);
1971                         M_RET;
1972                         }
1973                         break;
1974
1975                 /* the evil ones */
1976                 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
1977                                       /* val.a: (classinfo*) superclass               */
1978
1979                         /*  superclass is an interface:
1980                          *
1981                          *  return (sub != NULL) &&
1982                          *         (sub->vftbl->interfacetablelength > super->index) &&
1983                          *         (sub->vftbl->interfacetable[-super->index] != NULL);
1984                          *
1985                          *  superclass is a class:
1986                          *
1987                          *  return ((sub != NULL) && (0
1988                          *          <= (sub->vftbl->baseval - super->vftbl->baseval) <=
1989                          *          super->vftbl->diffvall));
1990                          */
1991
1992                         {
1993                         classinfo *super;
1994                         s4         superindex;
1995
1996                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1997                                 super      = NULL;
1998                                 superindex = 0;
1999                         }
2000                         else {
2001                                 super      = iptr->sx.s23.s3.c.cls;
2002                                 superindex = super->index;
2003                         }
2004                         
2005                         if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2006                                 CODEGEN_CRITICAL_SECTION_NEW;
2007
2008                         s1 = emit_load_s1(jd, iptr, REG_ATMP1);
2009                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2010
2011                         assert(VAROP(iptr->s1 )->type == TYPE_ADR);
2012                         assert(VAROP(iptr->dst)->type == TYPE_INT);
2013
2014                         M_ICLR(d);
2015
2016                         /* if class is not resolved, check which code to call */
2017
2018                         if (super == NULL) {
2019                                 M_ATST(s1);
2020                                 emit_label_beq(cd, BRANCH_LABEL_1);
2021
2022                                 codegen_addpatchref(cd, PATCHER_resolve_classref_to_flags, iptr->sx.s23.s3.c.ref, 0);
2023
2024                                 M_IMOV_IMM32(0, REG_ITMP3);
2025                                 M_IAND_IMM(ACC_INTERFACE, REG_ITMP3);
2026                                 emit_label_beq(cd, BRANCH_LABEL_2);
2027                         }
2028
2029                         /* interface instanceof code */
2030
2031                         if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2032                                 if (super == NULL) {
2033                                         codegen_addpatchref(cd, PATCHER_instanceof_interface, iptr->sx.s23.s3.c.ref, 0);
2034                                 } else {
2035                                         M_ATST(s1);
2036                                         emit_label_beq(cd, BRANCH_LABEL_3);
2037                                 }
2038
2039                                 M_ALD(REG_ATMP1, s1, OFFSET(java_object_t, vftbl));
2040                                 M_ILD(REG_ITMP3, REG_ATMP1, OFFSET(vftbl_t, interfacetablelength));
2041                                 M_IADD_IMM(-superindex, REG_ITMP3);     /* -superindex may be patched patched */
2042                                 M_ITST(REG_ITMP3);
2043                                 M_BLE(10);
2044                                 M_ALD(REG_ATMP1, REG_ATMP1, OFFSET(vftbl_t, interfacetable[0]) - superindex * sizeof(methodptr*));      /* patch here too! */
2045                                 M_ATST(REG_ATMP1);
2046                                 M_BEQ(2);
2047                                 M_IMOV_IMM(1, d);
2048
2049                                 if (super == NULL)
2050                                         emit_label_br(cd, BRANCH_LABEL_4);
2051                                 else
2052                                         emit_label(cd, BRANCH_LABEL_3);
2053                         }
2054
2055                         /* class instanceof code */
2056
2057                         if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2058                                 if (super == NULL) {
2059                                         emit_label(cd, BRANCH_LABEL_2);
2060
2061                                         codegen_addpatchref(cd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, 0);
2062                                         M_AMOV_IMM(0, REG_ATMP2);
2063                                 } else {
2064                                         M_AMOV_IMM(super->vftbl, REG_ATMP2);
2065                                         M_ATST(s1);
2066                                         emit_label_beq(cd, BRANCH_LABEL_5);
2067                                 }
2068
2069                                 M_ALD(REG_ATMP1, s1, OFFSET(java_object_t, vftbl));
2070
2071                                 CODEGEN_CRITICAL_SECTION_START;
2072
2073                                 M_ILD(REG_ITMP1, REG_ATMP1, OFFSET(vftbl_t, baseval));
2074                                 M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, baseval));
2075                                 M_ILD(REG_ITMP2, REG_ATMP2, OFFSET(vftbl_t, diffval));
2076
2077                                 CODEGEN_CRITICAL_SECTION_END;
2078
2079                                 M_ISUB(REG_ITMP3, REG_ITMP1);
2080                                 M_ICMP(REG_ITMP2, REG_ITMP1);
2081                                 M_BHI(4);
2082                                 M_IMOV_IMM(1, d);
2083                                 M_TPFW;                 /* overlaps next instruction */
2084                                 M_ICLR(d);
2085
2086                                 if (super != NULL)
2087                                         emit_label(cd, BRANCH_LABEL_5);
2088                         }
2089
2090                         if (super == NULL) {
2091                                 emit_label(cd, BRANCH_LABEL_1);
2092                                 emit_label(cd, BRANCH_LABEL_4);
2093                         }
2094
2095                         emit_store_dst(jd, iptr, d);
2096                         }
2097                         break;
2098
2099                 case ICMD_CHECKCAST:  /* ..., objectref ==> ..., objectref            */
2100                                       /* val.a: (classinfo*) superclass               */
2101
2102                         /*  superclass is an interface:
2103                          *
2104                          *  OK if ((sub == NULL) ||
2105                          *         (sub->vftbl->interfacetablelength > super->index) &&
2106                          *         (sub->vftbl->interfacetable[-super->index] != NULL));
2107                          *
2108                          *  superclass is a class:
2109                          *
2110                          *  OK if ((sub == NULL) || (0
2111                          *         <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2112                          *         super->vftbl->diffvall));
2113                          */
2114
2115                         if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2116                                 /* object type cast-check */
2117
2118                                 classinfo *super;
2119                                 s4         superindex;
2120
2121                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2122                                         super      = NULL;
2123                                         superindex = 0;
2124                                 }
2125                                 else {
2126                                         super      = iptr->sx.s23.s3.c.cls;
2127                                         superindex = super->index;
2128                                 }
2129
2130                                 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2131                                         CODEGEN_CRITICAL_SECTION_NEW;
2132
2133                                 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
2134                                 assert(VAROP(iptr->s1)->type == TYPE_ADR);
2135
2136                                 /* if class is not resolved, check which code to call */
2137
2138                                 if (super == NULL) {
2139                                         M_ATST(s1);
2140                                         emit_label_beq(cd, BRANCH_LABEL_1);
2141
2142                                         codegen_addpatchref(cd, PATCHER_resolve_classref_to_flags, iptr->sx.s23.s3.c.ref, 0);
2143                         
2144                                         M_IMOV_IMM32(0, REG_ITMP2);
2145                                         M_IAND_IMM(ACC_INTERFACE, REG_ITMP2);
2146                                         emit_label_beq(cd, BRANCH_LABEL_2);
2147                                 }
2148
2149                                 /* interface checkcast code */
2150
2151                                 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2152                                         if (super == NULL) {
2153                                                 codegen_addpatchref(cd, PATCHER_checkcast_interface, iptr->sx.s23.s3.c.ref, 0);
2154                                         } else {
2155                                                 M_ATST(s1);
2156                                                 emit_label_beq(cd, BRANCH_LABEL_3);
2157                                         }
2158
2159                                         M_ALD(REG_ATMP2, s1, OFFSET(java_object_t, vftbl));
2160                                         M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, interfacetablelength));
2161         
2162                                         M_IADD_IMM(-superindex, REG_ITMP3);     /* superindex patched */
2163                                         M_ITST(REG_ITMP3);
2164                                         emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2165
2166                                         M_ALD(REG_ATMP3, REG_ATMP2, OFFSET(vftbl_t, interfacetable[0]) - superindex * sizeof(methodptr*));      /* patched*/
2167                                         M_ATST(REG_ATMP3);
2168                                         emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ATMP3, s1);
2169
2170                                         if (super == NULL)
2171                                                 emit_label_br(cd, BRANCH_LABEL_4);
2172                                         else
2173                                                 emit_label(cd, BRANCH_LABEL_3);
2174                                 }
2175
2176                                 /* class checkcast code */
2177
2178                                 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2179                                         if (super == NULL) {
2180                                                 emit_label(cd, BRANCH_LABEL_2);
2181
2182                                                 codegen_addpatchref(cd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, 0);
2183                                                 M_AMOV_IMM(0, REG_ATMP3);
2184                                         } else {
2185                                                 M_AMOV_IMM(super->vftbl, REG_ATMP3);
2186                                                 M_ATST(s1);
2187                                                 emit_label_beq(cd, BRANCH_LABEL_5);
2188                                         }
2189
2190                                         M_ALD(REG_ATMP2, s1, OFFSET(java_object_t, vftbl));
2191
2192                                         CODEGEN_CRITICAL_SECTION_START;
2193
2194                                         M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, baseval));  /* REG_ITMP3 == sub->vftbl->baseval */
2195                                         M_ILD(REG_ITMP1, REG_ATMP3, OFFSET(vftbl_t, baseval));
2196                                         M_ILD(REG_ITMP2, REG_ATMP3, OFFSET(vftbl_t, diffval));
2197
2198                                         CODEGEN_CRITICAL_SECTION_END;
2199
2200                                         M_ISUB(REG_ITMP1, REG_ITMP3);
2201                                         M_ICMP(REG_ITMP2, REG_ITMP3);   /* XXX was CMPU */
2202
2203                                         emit_classcast_check(cd, iptr, BRANCH_UGT, REG_ITMP3, s1); /* XXX was BRANCH_GT */
2204
2205                                         if (super != NULL)
2206                                                 emit_label(cd, BRANCH_LABEL_5);
2207                                 }
2208
2209                                 if (super == NULL) {
2210                                         emit_label(cd, BRANCH_LABEL_1);
2211                                         emit_label(cd, BRANCH_LABEL_4);
2212                                 }
2213
2214                                 d = codegen_reg_of_dst(jd, iptr, s1);
2215                         } else {
2216                                 /* array type cast-check */
2217
2218                                 s1 = emit_load_s1(jd, iptr, REG_ATMP2);
2219
2220                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2221                                         codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo, iptr->sx.s23.s3.c.ref, 0);
2222                                         M_AMOV_IMM(0, REG_ATMP1);
2223                                 } else {
2224                                         M_AMOV_IMM(iptr->sx.s23.s3.c.cls, REG_ATMP1);
2225                                 }
2226         
2227                                 M_APUSH(REG_ATMP1);
2228                                 M_APUSH(s1);
2229                                 M_JSR_IMM(BUILTIN_arraycheckcast);
2230                                 M_AADD_IMM(2*4, REG_SP);                /* pop arguments off stack */
2231                                 M_ITST(REG_RESULT);
2232                                 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2233
2234                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2235                                 d = codegen_reg_of_dst(jd, iptr, s1);
2236                         }
2237                         assert(VAROP(iptr->dst)->type == TYPE_ADR);
2238                         M_ADRMOVE(s1, d);
2239                         emit_store_dst(jd, iptr, d);
2240                         break;
2241
2242                 case ICMD_TABLESWITCH:  /* ..., index ==> ...                         */
2243                         {
2244                         s4 i, l;
2245                         branch_target_t *table;
2246
2247                         table = iptr->dst.table;
2248
2249                         l = iptr->sx.s23.s2.tablelow;
2250                         i = iptr->sx.s23.s3.tablehigh;
2251                         
2252                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2253                         M_INTMOVE(s1, REG_ITMP1);
2254                         if (l != 0) M_ISUB_IMM(l, REG_ITMP1);
2255
2256                         i = i - l + 1;
2257
2258                         /* range check */
2259                         M_ICMP_IMM(i - 1, REG_ITMP1);
2260                         emit_bugt(cd, table[0].block);
2261
2262                         /* build jump table top down and use address of lowest entry */
2263                         table += i;
2264
2265                         while (--i >= 0) {
2266                                 dseg_add_target(cd, table->block); 
2267                                 --table;
2268                         }
2269
2270                         /* length of dataseg after last dseg_add_target is used by load */
2271                         M_AMOV_IMM(0, REG_ATMP2);
2272                         dseg_adddata(cd);
2273
2274                         M_ISSL_IMM(2, REG_ITMP1);                       /* index * 4 == offset in table */
2275                         M_AADDINT(REG_ITMP1, REG_ATMP2);                /* offset in table */
2276                         M_AADD_IMM(-(cd->dseglen), REG_ATMP2);          /* start of table in dseg */
2277                         M_ALD(REG_ATMP1, REG_ATMP2, 0);
2278
2279                         M_JMP(REG_ATMP1);
2280                         ALIGNCODENOP;
2281                         }
2282                         break;
2283
2284                 case ICMD_LOOKUPSWITCH: /* ..., key ==> ...                           */
2285                         {
2286                         s4 i;
2287                         lookup_target_t *lookup;
2288
2289                         lookup = iptr->dst.lookup;
2290
2291                         i = iptr->sx.s23.s2.lookupcount;
2292                         
2293                         MCODECHECK((i<<2)+8);
2294                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2295
2296                         while (--i >= 0) {
2297                                 M_ICMP_IMM(lookup->value, s1);
2298                                 emit_beq(cd, lookup->target.block);
2299                                 lookup++;
2300                         }
2301
2302                         emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2303                         ALIGNCODENOP;
2304                         break;
2305                         }
2306
2307                 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref  */
2308
2309                         /* check for negative sizes and copy sizes to stack if necessary  */
2310                         MCODECHECK((iptr->s1.argcount << 1) + 64);
2311
2312                         for (s1 = iptr->s1.argcount; --s1 >= 0;) {
2313                                 var = VAR(iptr->sx.s23.s2.args[s1]);
2314
2315                                 /* Already Preallocated? */
2316                                 if (!(var->flags & PREALLOC)) {
2317                                         s2 = emit_load(jd, iptr, var, REG_ITMP1);
2318                                         M_IST(s2, REG_SP, (s1 + 3) * 4);
2319                                 }
2320                         }
2321
2322                         /* a0 = dimension count */
2323                         M_IMOV_IMM(iptr->s1.argcount, REG_ITMP1);
2324                         M_IST(REG_ITMP1, REG_SP, 0*4);
2325
2326                         /* a1 = arraydescriptor */
2327                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2328                                 codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo, iptr->sx.s23.s3.c.ref, 0);
2329                                 M_AMOV_IMM(0, REG_ATMP1);
2330                         } else  {
2331                                 M_AMOV_IMM(iptr->sx.s23.s3.c.cls, REG_ATMP1);
2332                         }
2333                         M_AST(REG_ATMP1, REG_SP, 1*4);
2334
2335                         /* a2 = pointer to dimensions = stack pointer */
2336                         M_AMOV(REG_SP, REG_ATMP1);
2337                         M_AADD_IMM(3*4, REG_ATMP1);
2338                         M_AST(REG_ATMP1, REG_SP, 2*4);
2339
2340                         M_JSR_IMM(BUILTIN_multianewarray);
2341
2342                         /* check for exception before result assignment */
2343                         emit_exception_check(cd, iptr);
2344
2345                         assert(VAROP(iptr->dst)->type == TYPE_ADR);
2346                         d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2347                         M_INT2ADRMOVE(REG_RESULT, d);
2348                         emit_store_dst(jd, iptr, d);
2349                         break;
2350
2351
2352
2353                 default:
2354                         printf("UNKNOWN OPCODE %d\n", iptr->opc);
2355                         exceptions_throw_internalerror("Unknown ICMD %d during code generation", iptr->opc);
2356                         return false;
2357         } /* switch */
2358         /* M_TPF; */ /* nop after each ICMD */
2359         } /* for each instruction */
2360
2361         /* At the end of a basic block we may have to append some nops,
2362            because the patcher stub calling code might be longer than the
2363            actual instruction. So codepatching does not change the
2364            following block unintentionally. */
2365
2366         if (cd->mcodeptr < cd->lastmcodeptr) {
2367                 while (cd->mcodeptr < cd->lastmcodeptr) {
2368                         M_NOP;
2369                 }
2370         }
2371
2372
2373         } /* if (btpre->flags >= BBREACHED) */
2374         } /* for each basic block */
2375
2376         dseg_createlinenumbertable(cd);
2377
2378         /* generate stubs */
2379         emit_patcher_stubs(jd);
2380
2381         return true;
2382 }
2383
2384
2385 /* codegen_emit_stub_compiler **************************************************
2386
2387    Emits a stub routine which calls the compiler.
2388         
2389 *******************************************************************************/
2390
2391 void codegen_emit_stub_compiler(jitdata *jd)
2392 {
2393         methodinfo  *m;
2394         codegendata *cd;
2395
2396         /* get required compiler data */
2397
2398         m  = jd->m;
2399         cd = jd->cd;
2400
2401         /* code for the stub */
2402
2403         M_AMOV_IMM(m, REG_ATMP1);
2404         M_AMOV_IMM(asm_call_jit_compiler, REG_ATMP3);
2405         M_JMP(REG_ATMP3);
2406 }
2407
2408
2409 /* codegen_emit_stub_native ****************************************************
2410
2411    Emits a stub routine which calls a native method.
2412
2413 *******************************************************************************/
2414
2415 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
2416 {
2417         methodinfo   *m;
2418         codeinfo     *code;
2419         codegendata  *cd;
2420         registerdata *rd;
2421         methoddesc   *md;
2422         s4 nativeparams, i, j, t, s1, s2;
2423         
2424         /* get required compiler data */
2425
2426         m    = jd->m;
2427         code = jd->code;
2428         cd   = jd->cd;
2429         rd   = jd->rd;
2430
2431         md = m->parseddesc;
2432         nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
2433
2434         /* calc stackframe size */
2435         cd->stackframesize =    sizeof(stackframeinfo) / SIZEOF_VOID_P +
2436                                 sizeof(localref_table) / SIZEOF_VOID_P +
2437                                 nmd->memuse +
2438                                 1 +                                             /* functionptr */
2439                                 4;                                              /* args for codegen_start_native_call */
2440
2441         /* create method header */
2442         (void) dseg_add_unique_address(cd, code);                      /* CodeinfoPointer */
2443         (void) dseg_add_unique_s4(cd, cd->stackframesize * 4);         /* FrameSize       */
2444         (void) dseg_add_unique_s4(cd, 0);                              /* IsSync          */
2445         (void) dseg_add_unique_s4(cd, 0);                              /* IsLeaf          */
2446         (void) dseg_add_unique_s4(cd, 0);                              /* IntSave         */
2447         (void) dseg_add_unique_s4(cd, 0);                              /* FltSave         */
2448         (void) dseg_addlinenumbertablesize(cd);
2449         (void) dseg_add_unique_s4(cd, 0);                              /* ExTableSize     */
2450
2451         /* print call trace */
2452 #if !defined(NDEBUG)
2453         if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
2454                 emit_verbosecall_enter(jd);
2455         }
2456 #endif
2457
2458         /* generate code */
2459         M_AADD_IMM(-(cd->stackframesize*4), REG_SP);
2460
2461         /* get function address (this must happen before the stackframeinfo) */
2462 #if !defined(WITH_STATIC_CLASSPATH)
2463         if (f == NULL)  {
2464                 codegen_addpatchref(cd, PATCHER_resolve_native_function, m, 0);
2465         }
2466 #endif
2467         M_AMOV_IMM(f, REG_ATMP2); /* do not move this line, the patcher is needed */
2468
2469         M_AST(REG_ATMP2, REG_SP, 4 * 4);
2470
2471         /* put arguments for codegen_start_native_call onto stack */
2472         /* void codegen_start_native_call(u1 *datasp, u1 *pv, u1 *sp, u1 *ra) */
2473         
2474         M_AMOV(REG_SP, REG_ATMP1);
2475         M_AADD_IMM(cd->stackframesize * 4, REG_ATMP1);
2476
2477         M_ALD(REG_ATMP3, REG_ATMP1, 0 * 4);
2478         M_AST(REG_ATMP3, REG_SP, 3 * 4);                /* ra */
2479
2480         M_AST(REG_ATMP1, REG_SP, 0 * 4);                /* datasp */
2481
2482         M_AADD_IMM(1 * 4 , REG_ATMP1);                  
2483         M_AST(REG_ATMP1, REG_SP, 2 * 4);                /* sp */
2484
2485         M_AMOV_IMM(0, REG_ATMP2);                       /* 0 needs to patched */
2486         dseg_adddata(cd);                                   /* this patches it */
2487
2488         M_AST(REG_ATMP2, REG_SP, 1 * 4);                /* pv */
2489
2490         M_JSR_IMM(codegen_start_native_call);
2491
2492         /* load function pointer */
2493         M_ALD(REG_ATMP2, REG_SP, 4 * 4);
2494
2495         /* copy arguments into stackframe */
2496         for (i = md->paramcount -1, j = i + nativeparams; i >= 0; --i, --j)     {
2497                 t = md->paramtypes[i].type;
2498                 /* all arguments via stack */
2499                 assert(md->params[i].inmemory);                                         
2500
2501                 s1 = md->params[i].regoff + cd->stackframesize * 4 + 4;
2502                 s2 = nmd->params[j].regoff;
2503
2504                 /* simply copy argument stack */
2505                 M_ILD(REG_ITMP1, REG_SP, s1);
2506                 M_IST(REG_ITMP1, REG_SP, s2);
2507                 if (IS_2_WORD_TYPE(t))  {
2508                         M_ILD(REG_ITMP1, REG_SP, s1 + 4);
2509                         M_IST(REG_ITMP1, REG_SP, s2 + 4);
2510                 }
2511         }
2512
2513         /* for static function class as second arg */
2514         if (m->flags & ACC_STATIC)      {
2515                 M_AMOV_IMM(m->class, REG_ATMP1);
2516                 M_AST(REG_ATMP1, REG_SP, 1 * 4);
2517         }
2518         /* env ist first argument */
2519         M_AMOV_IMM(_Jv_env, REG_ATMP1);
2520         M_AST(REG_ATMP1, REG_SP, 0 * 4);
2521
2522         /* call the native function */
2523         M_JSR(REG_ATMP2);
2524
2525         /* save return value */
2526         switch (md->returntype.type)    {
2527                 case TYPE_VOID: break;
2528
2529                 /* natives return float arguments in %d0, %d1, cacao expects them in %fp0 */
2530                 case TYPE_DBL:
2531                 case TYPE_LNG:
2532                         M_IST(REG_D1, REG_SP, 2 * 4);
2533                         /* fall through */
2534
2535                 case TYPE_FLT:
2536                 case TYPE_INT:
2537                 case TYPE_ADR:
2538                         M_IST(REG_D0, REG_SP, 1 * 4);
2539                         break;
2540
2541                 default: assert(0);
2542         }
2543         
2544         /* print call trace */
2545 #if ! defined(NDEBUG)
2546         if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
2547                 emit_verbosecall_exit(jd);
2548         }
2549 #endif
2550         /* remove native stackframe info */
2551         /* therefore we call: java_objectheader *codegen_finish_native_call(u1 *datasp) */
2552
2553         M_AMOV(REG_SP, REG_ATMP3);
2554         M_AADD_IMM(cd->stackframesize * 4, REG_ATMP3);
2555         M_AST(REG_ATMP3, REG_SP, 0 * 4);                        /* datasp */
2556         M_JSR_IMM(codegen_finish_native_call);
2557         
2558         M_INT2ADRMOVE(REG_RESULT, REG_ATMP1);
2559         /* restore return value */
2560         switch (md->returntype.type)    {
2561                 case TYPE_VOID: break;
2562
2563                 case TYPE_DBL:
2564                 case TYPE_LNG:
2565                         M_ILD(REG_D1, REG_SP, 2 * 4);
2566                         /* fall through */
2567                 case TYPE_FLT:
2568                 case TYPE_INT:
2569                 case TYPE_ADR:
2570                         M_ILD(REG_D0, REG_SP, 1 * 4);
2571                         break;
2572
2573                 default: assert(0);
2574         }
2575 #if !defined(ENABLE_SOFTFLOAT)
2576                 /* additionally load values into floating points registers
2577                  * as cacao jit code expects them there */
2578         switch (md->returntype.type)    {
2579                 case TYPE_FLT:
2580                         M_FLD(REG_D0, REG_SP, 1 * 4);
2581                         break;
2582                 case TYPE_DBL:  
2583                         M_DLD(REG_D0, REG_SP, 1 * 4);
2584                         break;
2585         }
2586 #endif
2587         /* restore saved registers */
2588
2589         M_AADD_IMM(cd->stackframesize*4, REG_SP);
2590         /* check for exception */
2591         M_ATST(REG_ATMP1);
2592         M_BNE(2);
2593         M_RET;
2594
2595         /* handle exception, REG_ATMP1 already contains exception object, REG_ATMP2 holds address */
2596         
2597         M_ALD(REG_ATMP2_XPC, REG_SP, 0);                /* take return address as faulting instruction */
2598         M_AADD_IMM(-2, REG_ATMP2_XPC);                  /* which is off by 2 */
2599         M_JMP_IMM(asm_handle_nat_exception);
2600
2601         /* should never be reached from within jit code*/
2602         M_JSR_IMM(0);
2603
2604         /* generate patcher stub call code */
2605         emit_patcher_stubs(jd);
2606 }
2607
2608
2609 /*
2610  * These are local overrides for various environment variables in Emacs.
2611  * Please do not remove this and leave it at the end of the file, where
2612  * Emacs will automagically detect them.
2613  * ---------------------------------------------------------------------
2614  * Local variables:
2615  * mode: c
2616  * indent-tabs-mode: t
2617  * c-basic-offset: 4
2618  * tab-width: 4
2619  * End:
2620  * vim:noexpandtab:sw=4:ts=4:
2621  */