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