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