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