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