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