* Merged in new trap code (twisti-branch).
[cacao.git] / src / vm / jit / s390 / codegen.c
1 /* src/vm/jit/s390/codegen.c - machine code generator for s390
2
3    Copyright (C) 1996-2005, 2006, 2007, 2008
4    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5
6    This file is part of CACAO.
7
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2, or (at
11    your option) any later version.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23 */
24
25
26 #include "config.h"
27
28 #include <assert.h>
29 #include <stdint.h>
30 #include <stdio.h>
31
32 #include "vm/jit/s390/arch.h"
33 #include "vm/jit/s390/codegen.h"
34 #include "vm/jit/s390/emit.h"
35 #include "vm/jit/s390/md-abi.h"
36
37 #include "native/jni.h"
38 #include "native/localref.h"
39 #include "native/native.h"
40
41 #include "mm/memory.h"
42
43 #include "threads/lock-common.h"
44
45 #include "vmcore/loader.h"
46 #include "vmcore/options.h"
47 #include "vmcore/statistics.h"
48
49 #include "vm/builtin.h"
50 #include "vm/exceptions.h"
51 #include "vm/global.h"
52 #include "vm/types.h"
53 #include "vm/stringlocal.h"
54 #include "vm/vm.h"
55
56 #include "vm/jit/abi.h"
57 #if defined(ENABLE_LSRA)
58 # include "vm/jit/allocator/lsra.h"
59 #endif
60 #include "vm/jit/asmpart.h"
61 #include "vm/jit/codegen-common.h"
62 #include "vm/jit/dseg.h"
63 #include "vm/jit/emit-common.h"
64 #include "vm/jit/jit.h"
65 #include "vm/jit/linenumbertable.h"
66 #include "vm/jit/methodheader.h"
67 #include "vm/jit/parse.h"
68 #include "vm/jit/patcher-common.h"
69 #include "vm/jit/reg.h"
70 #include "vm/jit/replace.h"
71 #include "vm/jit/stacktrace.h"
72 #include "vm/jit/trap.h"
73
74
75 /* DO__LOG generates a call to do__log. No registers are destroyed,
76  * so you may use it anywhere. regs is an array containing all general
77  * purpose registers.
78  */
79
80 /*
81 static void do__log(u4 *regs) {
82 }
83 */
84
85 #define DO__LOG \
86         N_AHI(REG_SP, -200); \
87         N_STM(R0, R15, 96, REG_SP); \
88         M_ALD_DSEG(R14, dseg_add_address(cd, &do__log)); \
89         N_LA(R2, 96, RN, REG_SP); \
90         N_BASR(R14, R14); \
91         N_LM(R0, R15, 96, REG_SP); \
92         N_AHI(REG_SP, 200);
93
94 /* If the following macro is defined, workaround code for hercules quirks
95  * is generated
96  */
97
98 /* #define SUPPORT_HERCULES 1 */
99
100 /* codegen *********************************************************************
101
102    Generates machine code.
103
104 *******************************************************************************/
105
106 /*
107
108 Layout of stackframe:
109
110 Meaning                                Offset
111 ===============================================================================
112 return_address                         (stackframesize - 1) * 8 
113 saved_int_reg[INT_SAV_CNT - 1]         (stackframseize - 2) * 8
114 ...
115 saved_int_reg[rd->savintreguse]  
116 saved_flt_reg[FLT_SAV_CNT - 1]
117 ...
118 saved_flt_reg[rd->savfltreguse]        (stackframesize - 1 - savedregs_num) * 8
119
120 return_value_tmp                       (rd->memuse + 1) * 8
121 monitorenter_argument                  (rd->memuse) * 8 
122 ???
123 local[rd->memuse - 1]                  (rd->memuse - 1) * 8
124 ....
125 local[2]                               2 * 8
126 local[1]                               1 * 8
127 local[0]                               0 * 8
128
129 */
130
131 bool codegen_emit(jitdata *jd)
132 {
133         methodinfo         *m;
134         codeinfo           *code;
135         codegendata        *cd;
136         registerdata       *rd;
137         s4                  len, s1, s2, s3, d, dd, disp;
138         u2                  currentline;
139         varinfo            *var;
140         basicblock         *bptr;
141         instruction        *iptr;
142         constant_classref  *cr;
143         unresolved_class   *uc;
144         methodinfo         *lm;             /* local methodinfo for ICMD_INVOKE*  */
145         unresolved_method  *um;
146         builtintable_entry *bte;
147         methoddesc         *md;
148         fieldinfo          *fi;
149         unresolved_field   *uf;
150         s4                  fieldtype;
151 #if 0
152         rplpoint           *replacementpoint;
153 #endif
154         s4                 varindex;
155
156         /* get required compiler data */
157
158         m    = jd->m;
159         code = jd->code;
160         cd   = jd->cd;
161         rd   = jd->rd;
162
163         /* prevent compiler warnings */
164
165         d   = 0;
166         lm  = NULL;
167         um  = NULL;
168         bte = NULL;
169
170         {
171         s4 i, p, t, l;
172         s4 savedregs_num;
173
174         savedregs_num = 0; 
175
176         /* space to save used callee saved registers */
177
178         savedregs_num += (INT_SAV_CNT - rd->savintreguse);
179         savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
180
181         cd->stackframesize = rd->memuse + savedregs_num + 1  /* space to save RA */;
182
183         /* CAUTION:
184          * As REG_ITMP2 == REG_RA, do not touch REG_ITMP2, until it has been saved.
185          */
186
187 #if defined(ENABLE_THREADS)
188         /* Space to save argument of monitor_enter and Return Values to
189            survive monitor_exit. The stack position for the argument can
190            not be shared with place to save the return register
191            since both values reside in R2. */
192
193         if (checksync && code_is_synchronized(code)) {
194                 /* 1 slot space to save argument of monitor_enter */
195                 /* 1 slot to temporary store return value before monitor_exit */
196                 cd->stackframesize += 2;
197         }
198 #endif
199
200         /* Keep stack of non-leaf functions 16-byte aligned for calls into
201            native code e.g. libc or jni (alignment problems with
202            movaps). */
203
204         if (!code_is_leafmethod(code) || opt_verbosecall )
205                 /* TODO really 16 bytes ? */
206                 cd->stackframesize = (cd->stackframesize + 2) & ~2;
207
208         /* create method header */
209
210         (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
211         (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize       */
212
213         code->synchronizedoffset = rd->memuse * 8;
214
215         /* REMOVEME: We still need it for exception handling in assembler. */
216
217         if (code_is_leafmethod(code))
218                 (void) dseg_add_unique_s4(cd, 1);
219         else
220                 (void) dseg_add_unique_s4(cd, 0);
221
222         (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
223         (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
224
225         /* Offset PV */
226
227         M_AADD_IMM(N_PV_OFFSET, REG_PV);
228
229         /* create stack frame (if necessary) */
230
231         if (cd->stackframesize) {
232                 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
233         }
234
235         /* store return address */
236
237         M_AST(REG_RA, REG_SP, (cd->stackframesize - 1) * 8);
238
239         /* generate method profiling code */
240
241 #if defined(ENABLE_PROFILING)
242         if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
243                 /* count frequency */
244                 M_ALD_DSEG(REG_ITMP1, CodeinfoPointer);
245                 ICONST(REG_ITMP2, 1);
246                 N_AL(REG_ITMP2, OFFSET(codeinfo, frequency), RN, REG_ITMP1);
247                 M_IST(REG_ITMP2, REG_ITMP1, OFFSET(codeinfo, frequency));
248
249                 PROFILE_CYCLE_START;
250         }
251 #endif
252
253         /* save used callee saved registers and return address */
254
255         p = cd->stackframesize - 1;
256
257         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
258                 p--; M_IST(rd->savintregs[i], REG_SP, p * 8);
259         }
260         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
261                 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
262         }
263
264         /* take arguments out of register or stack frame */
265
266         md = m->parseddesc;
267
268         for (p = 0, l = 0; p < md->paramcount; p++) {
269                 t = md->paramtypes[p].type;
270                 varindex = jd->local_map[l * 5 + t];
271
272                 l++;
273
274                 if (IS_2_WORD_TYPE(t))
275                         l++;
276
277                 if (varindex == UNUSED)
278                         continue;
279
280                 var = VAR(varindex);
281
282                 s1 = md->params[p].regoff;
283
284                 if (IS_INT_LNG_TYPE(t)) {                    /* integer args          */
285                         if (IS_2_WORD_TYPE(t)) {
286                                 s2 = PACK_REGS(
287                                         GET_LOW_REG(s1),
288                                         GET_HIGH_REG(s1)
289                                 );
290                         } else {
291                                 s2 = s1;
292                         }
293                         if (!md->params[p].inmemory) {           /* register arguments    */
294                                 if (!IS_INMEMORY(var->flags)) {      /* reg arg -> register   */
295                                         if (IS_2_WORD_TYPE(t)) {
296                                                 M_LNGMOVE(s2, var->vv.regoff);
297                                         } else {
298                                                 M_INTMOVE(s2, var->vv.regoff);
299                                         }
300                                 } else {                             /* reg arg -> spilled    */
301                                         if (IS_2_WORD_TYPE(t)) {
302                                                 M_LST(s2, REG_SP, var->vv.regoff);
303                                         } else {
304                                                 M_IST(s2, REG_SP, var->vv.regoff);
305                                         }
306                                 }
307
308                         } else {                                 /* stack arguments       */
309                                 if (!IS_INMEMORY(var->flags)) {      /* stack arg -> register */
310                                         if (IS_2_WORD_TYPE(t)) {
311                                                 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
312                                         } else {
313                                                 M_ILD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
314                                         }
315                                 } else {                             /* stack arg -> spilled  */
316                                         N_MVC(var->vv.regoff, 8, REG_SP, cd->stackframesize * 8 + s1, REG_SP);
317                                 }
318                         }
319
320                 } else {                                     /* floating args         */
321                         if (!md->params[p].inmemory) {           /* register arguments    */
322                                 s2 = s1;
323                                 if (!IS_INMEMORY(var->flags)) {      /* reg arg -> register   */
324                                         M_FLTMOVE(s2, var->vv.regoff);
325
326                                 } else {                                         /* reg arg -> spilled    */
327                                         if (IS_2_WORD_TYPE(t))
328                                                 M_DST(s2, REG_SP, var->vv.regoff);
329                                         else
330                                                 M_FST(s2, REG_SP, var->vv.regoff);
331                                 }
332
333                         } else {                                 /* stack arguments       */
334                                 if (!IS_INMEMORY(var->flags)) {      /* stack-arg -> register */
335                                         if (IS_2_WORD_TYPE(t))
336                                                 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
337
338                                         else
339                                                 M_FLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
340
341                                 } else {                             /* stack-arg -> spilled  */
342                                         N_MVC(var->vv.regoff, 8, REG_SP, cd->stackframesize * 8 + s1, REG_SP);
343                                         var->vv.regoff = cd->stackframesize * 8 + s1;
344                                 }
345                         }
346                 }
347         } /* end for */
348
349         /* save monitorenter argument */
350
351 #if defined(ENABLE_THREADS)
352         if (checksync && code_is_synchronized(code)) {
353                 /* stack offset for monitor argument */
354
355                 s1 = rd->memuse;
356
357 #if !defined(NDEBUG)
358                 if (opt_verbosecall) {
359                         M_ASUB_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
360
361                         for (p = 0; p < INT_ARG_CNT; p++)
362                                 M_IST(abi_registers_integer_argument[p], REG_SP, p * 8);
363
364                         for (p = 0; p < FLT_ARG_CNT; p++)
365                                 M_DST(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
366
367                         s1 += ((INT_ARG_CNT + FLT_ARG_CNT));
368                 }
369 #endif
370
371                 /* decide which monitor enter function to call */
372
373                 if (m->flags & ACC_STATIC) {
374                         disp = dseg_add_address(cd, &m->clazz->object.header);
375                         M_ALD_DSEG(REG_A0, disp);
376                 }
377                 else {
378                         M_TEST(REG_A0);
379                         M_BNE(SZ_BRC + SZ_ILL);
380                         M_ILL(TRAP_NullPointerException);
381                 }
382
383                 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
384                 M_ALD_DSEG(REG_ITMP2, disp);
385
386                 M_AST(REG_A0, REG_SP, s1 * 8);
387
388                 M_ASUB_IMM(96, REG_SP); 
389                 M_CALL(REG_ITMP2);
390                 M_AADD_IMM(96, REG_SP); 
391
392 #if !defined(NDEBUG)
393                 if (opt_verbosecall) {
394                         for (p = 0; p < INT_ARG_CNT; p++)
395                                 M_ILD(abi_registers_integer_argument[p], REG_SP, p * 8);
396
397                         for (p = 0; p < FLT_ARG_CNT; p++)
398                                 M_DLD(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
399
400                         M_AADD_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
401                 }
402 #endif
403         }
404 #endif
405
406 #if !defined(NDEBUG)
407         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
408                 emit_verbosecall_enter(jd);
409 #endif /* !defined(NDEBUG) */
410
411         }
412
413         /* end of header generation */
414
415         /* create replacement points */
416
417         REPLACEMENT_POINTS_INIT(cd, jd);
418
419         /* walk through all basic blocks */
420
421         for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
422
423                 bptr->mpc = (u4) ((u1 *) cd->mcodeptr - cd->mcodebase);
424
425                 if (bptr->flags >= BBREACHED) {
426
427                 /* branch resolving */
428
429                 codegen_resolve_branchrefs(cd, bptr);
430
431                 /* handle replacement points */
432
433                 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
434
435                 /* copy interface registers to their destination */
436
437                 len = bptr->indepth;
438                 MCODECHECK(512);
439
440 #if defined(ENABLE_PROFILING)
441                 /* generate basicblock profiling code */
442
443                 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
444                         /* count frequency */
445
446                         M_ALD_DSEG(REG_ITMP1, CodeinfoPointer);
447                         M_ALD(REG_ITMP1, REG_ITMP1, OFFSET(codeinfo, bbfrequency));
448                         ICONST(REG_ITMP2, 1);
449                         N_AL(REG_ITMP2, bptr->nr * 4, RN, REG_ITMP1);
450                         M_IST(REG_ITMP2, REG_ITMP1, bptr->nr * 4);
451
452                         /* if this is an exception handler, start profiling again */
453
454                         if (bptr->type == BBTYPE_EXH)
455                                 PROFILE_CYCLE_START;
456                 }
457 #endif
458
459 #if defined(ENABLE_LSRA)
460                 if (opt_lsra) {
461                         while (len) {
462                                 len--;
463                                 src = bptr->invars[len];
464                                 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
465                                         if (bptr->type == BBTYPE_EXH) {
466 /*                                      d = reg_of_var(rd, src, REG_ITMP1); */
467                                                 if (!IS_INMEMORY(src->flags))
468                                                         d = src->vv.regoff;
469                                                 else
470                                                         d = REG_ITMP3_XPTR;
471                                                 M_INTMOVE(REG_ITMP3_XPTR, d);
472                                                 emit_store(jd, NULL, src, d);
473                                         }
474                                 }
475                         }
476                         
477                 } else {
478 #endif
479
480                 while (len) {
481                         len--;
482                         var = VAR(bptr->invars[len]);
483                         if ((len ==  bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
484                                 if (bptr->type == BBTYPE_EXH) {
485                                         d = codegen_reg_of_var(0, var, REG_ITMP3_XPTR);
486                                         M_INTMOVE(REG_ITMP3_XPTR, d);
487                                         emit_store(jd, NULL, var, d);
488                                 }
489                         } 
490                         else {
491                                 assert((var->flags & INOUT));
492                         }
493                 }
494 #if defined(ENABLE_LSRA)
495                 }
496 #endif
497                 /* walk through all instructions */
498                 
499                 len = bptr->icount;
500                 currentline = 0;
501
502                 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
503                         if (iptr->line != currentline) {
504                                 linenumbertable_list_entry_add(cd, iptr->line);
505                                 currentline = iptr->line;
506                         }
507
508                         MCODECHECK(1024);                         /* 1KB should be enough */
509
510                 switch (iptr->opc) {
511                 case ICMD_NOP:        /* ...  ==> ...                                 */
512                 case ICMD_POP:        /* ..., value  ==> ...                          */
513                 case ICMD_POP2:       /* ..., value, value  ==> ...                   */
514                         break;
515
516                 case ICMD_INLINE_START:
517
518                         REPLACEMENT_POINT_INLINE_START(cd, iptr);
519                         break;
520
521                 case ICMD_INLINE_BODY:
522
523                         REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
524                         linenumbertable_list_entry_add_inline_start(cd, iptr);
525                         linenumbertable_list_entry_add(cd, iptr->line);
526                         break;
527
528                 case ICMD_INLINE_END:
529
530                         linenumbertable_list_entry_add_inline_end(cd, iptr);
531                         linenumbertable_list_entry_add(cd, iptr->line);
532                         break;
533
534                 case ICMD_CHECKNULL:  /* ..., objectref  ==> ..., objectref           */
535                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
536                         emit_nullpointer_check(cd, iptr, s1);
537                         break;
538
539                 /* constant operations ************************************************/
540
541                 case ICMD_ICONST:     /* ...  ==> ..., constant                       */
542                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
543                         ICONST(d, iptr->sx.val.i);
544                         emit_store_dst(jd, iptr, d);
545                         break;
546
547                 case ICMD_LCONST:     /* ...  ==> ..., constant                       */
548
549                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
550                         LCONST(d, iptr->sx.val.l);
551                         emit_store_dst(jd, iptr, d);
552                         break;
553
554                 case ICMD_FCONST:     /* ...  ==> ..., constant                       */
555                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
556                         disp = dseg_add_float(cd, iptr->sx.val.f);
557                         M_FLD_DSEG(d, disp, REG_ITMP1);
558                         emit_store_dst(jd, iptr, d);
559                         break;
560                 
561                 case ICMD_DCONST:     /* ...  ==> ..., constant                       */
562                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
563                         disp = dseg_add_double(cd, iptr->sx.val.d);
564                         M_DLD_DSEG(d, disp, REG_ITMP1);
565                         emit_store_dst(jd, iptr, d);
566                         break;
567
568                 case ICMD_ACONST:     /* ...  ==> ..., constant                       */
569                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
570
571                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
572                                 cr = iptr->sx.val.c.ref;
573                                 disp = dseg_add_unique_address(cd, cr);
574
575 /*                              PROFILE_CYCLE_STOP; */
576
577                                 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
578                                                                           cr, disp);
579
580 /*                              PROFILE_CYCLE_START; */
581
582                                 M_ALD_DSEG(d, disp);
583                         } else {
584                                 if (iptr->sx.val.anyptr == 0) {
585                                         M_CLR(d);
586                                 } else {
587                                         disp = dseg_add_unique_address(cd, iptr->sx.val.anyptr);
588                                         M_ALD_DSEG(d, disp);
589                                         /*
590                                         if (((u4)(iptr->sx.val.anyptr) & 0x00008000) == 0) {
591                                                 N_LHI(d, ((u4)(iptr->sx.val.anyptr) >> 16) & 0xFFFF);
592                                                 M_SLL_IMM(16, d);
593                                                 N_AHI(d, (u4)(iptr->sx.val.anyptr) & 0xFFFF);
594                                         } else {
595                                                 disp = dseg_add_unique_address(cd, iptr->sx.val.anyptr);
596                                                 M_ALD_DSEG(d, disp);
597                                         }
598                                         */
599                                 }
600                         }
601                         emit_store_dst(jd, iptr, d);
602                         break;
603
604
605                 /* load/store/copy/move operations ************************************/
606
607                 case ICMD_ILOAD:      /* ...  ==> ..., content of local variable      */
608                 case ICMD_ALOAD:      /* s1 = local variable                          */
609                 case ICMD_LLOAD:
610                 case ICMD_FLOAD:  
611                 case ICMD_DLOAD:  
612                 case ICMD_ISTORE:     /* ..., value  ==> ...                          */
613                 case ICMD_LSTORE:
614                 case ICMD_FSTORE:
615                 case ICMD_DSTORE: 
616                 case ICMD_COPY:
617                 case ICMD_MOVE:
618
619                         emit_copy(jd, iptr);
620                         break;
621
622                 case ICMD_ASTORE:
623                         if (!(iptr->flags.bits & INS_FLAG_RETADDR))
624                                 emit_copy(jd, iptr);
625                         break;
626
627                 /* integer operations *************************************************/
628
629                 case ICMD_INEG:       /* ..., value  ==> ..., - value                 */
630
631                         s1 = emit_load_s1(jd, iptr, REG_ITMP1); 
632                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
633                         M_INEG(s1, d);
634                         emit_store_dst(jd, iptr, d);
635
636                         break;
637
638                 case ICMD_LNEG:       /* ..., value  ==> ..., - value                 */
639
640                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
641                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
642                         M_INEG(GET_HIGH_REG(s1), GET_HIGH_REG(d));
643                         M_INEG(GET_LOW_REG(s1), GET_LOW_REG(d));
644                         N_BRC(8 /* result zero, no overflow */, SZ_BRC + SZ_AHI); 
645                         N_AHI(GET_HIGH_REG(d), -1);
646                         emit_store_dst(jd, iptr, d);
647                         break;
648
649                 case ICMD_I2L:        /* ..., value  ==> ..., value                   */
650
651                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP31_PACKED); /* even-odd */
652                         if (! N_IS_EVEN_ODD(d)) {
653                                 d = REG_ITMP31_PACKED;
654                         }
655                         assert(N_IS_EVEN_ODD(d));
656
657                         s1 = emit_load_s1(jd, iptr, REG_ITMP2);
658
659                         M_INTMOVE(s1, GET_HIGH_REG(d));
660                         M_SRDA_IMM(32, GET_HIGH_REG(d));
661
662                         emit_copy_dst(jd, iptr, d);
663                         emit_store_dst(jd, iptr, d);
664                         break;
665
666                 case ICMD_L2I:        /* ..., value  ==> ..., value                   */
667                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
668                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
669                         M_INTMOVE(GET_LOW_REG(s1), d);
670                         emit_store_dst(jd, iptr, d);
671                         break;
672
673                 case ICMD_INT2BYTE:   /* ..., value  ==> ..., value                   */
674                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
675                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
676                         M_INTMOVE(s1, d);
677                         M_SLL_IMM(24, d);
678                         M_SRA_IMM(24, d);
679                         emit_store_dst(jd, iptr, d);
680                         break;
681
682                 case ICMD_INT2CHAR:   /* ..., value  ==> ..., value                   */
683                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
684                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
685                         M_INTMOVE(s1, d);
686                         M_SLL_IMM(16, d);
687                         M_SRL_IMM(16, d);
688                         emit_store_dst(jd, iptr, d);
689                         break;
690
691                 case ICMD_INT2SHORT:  /* ..., value  ==> ..., value                   */
692
693                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
694                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
695                         M_INTMOVE(s1, d);
696                         M_SLL_IMM(16, d);
697                         M_SRA_IMM(16, d);
698                         emit_store_dst(jd, iptr, d);
699                         break;
700
701                 case ICMD_IADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
702
703                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
704                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
705                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
706                         if (s2 == d)
707                                 M_IADD(s1, d);
708                         else {
709                                 M_INTMOVE(s1, d);
710                                 M_IADD(s2, d);
711                         }
712                         emit_store_dst(jd, iptr, d);
713
714                         break;
715
716                 case ICMD_IINC:
717                 case ICMD_IADDCONST:  /* ..., value  ==> ..., value + constant        */
718                                       /* sx.val.i = constant                             */
719                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
720                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
721                         M_INTMOVE(s1, d);
722
723                         if (N_VALID_IMM(iptr->sx.val.i)) {
724                                 M_IADD_IMM(iptr->sx.val.i, d);
725                         } else {
726                                 ICONST(REG_ITMP2, iptr->sx.val.i);
727                                 M_IADD(REG_ITMP2, d);   
728                         }
729                         emit_store_dst(jd, iptr, d);
730                         break;
731
732                 case ICMD_LADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
733
734                         /* M, (r, q) -> (r, q) */
735
736                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
737
738                         s1 = emit_load_s1_high(jd, iptr, GET_HIGH_REG(REG_ITMP12_PACKED));
739                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
740                         dd = GET_HIGH_REG(d);
741
742                         if (s2 == dd) {
743                                 M_IADD(s1, dd);
744                         } else {
745                                 M_INTMOVE(s1, dd);
746                                 M_IADD(s2, dd);
747                         }
748
749                         s1 = emit_load_s1_low(jd, iptr, GET_LOW_REG(REG_ITMP12_PACKED));
750                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
751                         dd = GET_LOW_REG(d);
752
753                         if (s2 == dd) {
754                                 N_ALR(dd, s1);
755                         } else {
756                                 M_INTMOVE(s1, dd);
757                                 N_ALR(dd, s2);
758                         }
759
760                         N_BRC(8 | 4, SZ_BRC + SZ_AHI); 
761                         N_AHI(GET_HIGH_REG(d), 1);
762
763                         emit_store_dst(jd, iptr, d);
764                         break;
765
766                 case ICMD_LADDCONST:  /* ..., value  ==> ..., value + constant        */
767                                       /* sx.val.l = constant                             */
768
769                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
770                         dd = GET_HIGH_REG(d);
771
772                         s1 = emit_load_s1_high(jd, iptr, dd);
773                         s3 = iptr->sx.val.l >> 32;
774
775                         M_INTMOVE(s1, dd);
776
777                         if (N_VALID_IMM(s3)) {
778                                 M_IADD_IMM(s3, dd);
779                         } else {
780                                 ICONST(REG_ITMP3, s3);
781                                 M_IADD(REG_ITMP3, dd);
782                         }
783
784                         dd = GET_LOW_REG(d);
785                         s1 = emit_load_s1_low(jd, iptr, dd);
786                         s3 = iptr->sx.val.l & 0xffffffff;
787                         ICONST(REG_ITMP3, s3);
788
789                         M_INTMOVE(s1, dd);
790                         N_ALR(dd, REG_ITMP3);
791
792                         N_BRC(8 | 4, SZ_BRC + SZ_AHI); 
793                         N_AHI(GET_HIGH_REG(d), 1);
794
795                         emit_store_dst(jd, iptr, d);
796                         break;
797
798                 case ICMD_ISUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
799                                                                  
800                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
801                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
802                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
803                         if (s2 == d) {
804                                 M_INTMOVE(s1, REG_ITMP1);
805                                 M_ISUB(s2, REG_ITMP1);
806                                 M_INTMOVE(REG_ITMP1, d);
807                         } else {
808                                 M_INTMOVE(s1, d);
809                                 M_ISUB(s2, d);
810                         }
811                         emit_store_dst(jd, iptr, d);
812
813                         break;
814
815                 case ICMD_ISUBCONST:  /* ..., value  ==> ..., value + constant        */
816                                       /* sx.val.i = constant                             */
817
818                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
819                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
820                         M_INTMOVE(s1, d);
821
822                         if (N_VALID_IMM(-iptr->sx.val.i)) {
823                                 M_ISUB_IMM(iptr->sx.val.i, d);
824                         } else {
825                                 ICONST(REG_ITMP2, iptr->sx.val.i);
826                                 M_ISUB(REG_ITMP2, d);
827                         }
828                         emit_store_dst(jd, iptr, d);
829
830                         break;
831
832                 case ICMD_LSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
833
834                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
835
836                         s1 = emit_load_s1_high(jd, iptr, GET_HIGH_REG(REG_ITMP12_PACKED));
837                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
838                         dd = GET_HIGH_REG(d);
839
840                         if (s2 == dd) {
841                                 M_INTMOVE(s2, REG_ITMP3);
842                                 s2 = REG_ITMP3;
843                         }
844
845                         M_INTMOVE(s1, dd);
846                         M_ISUB(s2, dd);
847
848                         s1 = emit_load_s1_low(jd, iptr, GET_LOW_REG(REG_ITMP12_PACKED));
849                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
850                         dd = GET_LOW_REG(d);
851
852                         if (s2 == dd) {
853                                 M_INTMOVE(s2, REG_ITMP3);
854                                 s2 = REG_ITMP3;
855                         } 
856
857                         M_INTMOVE(s1, dd);
858                         N_SLR(dd, s2);
859
860                         N_BRC(1 | 2, SZ_BRC + SZ_AHI); 
861                         N_AHI(GET_HIGH_REG(d), -1);
862
863                         emit_store_dst(jd, iptr, d);
864                         break;
865
866                 case ICMD_LSUBCONST:  /* ..., value  ==> ..., value - constant        */
867                                       /* sx.val.l = constant                             */
868
869                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
870
871                         dd = GET_HIGH_REG(d);
872                         s1 = emit_load_s1_high(jd, iptr, dd);
873                         s3 = iptr->sx.val.l >> 32;
874
875                         M_INTMOVE(s1, dd);
876
877                         if (N_VALID_IMM(-s3)) {
878                                 M_IADD_IMM(-s3, dd);
879                         } else {
880                                 ICONST(REG_ITMP3, s3);
881                                 M_ISUB(REG_ITMP3, dd);
882                         }
883
884                         dd = GET_LOW_REG(d);
885                         s1 = emit_load_s1_low(jd, iptr, dd);
886                         s3 = iptr->sx.val.l & 0xffffffff;
887                         ICONST(REG_ITMP3, s3);
888
889                         M_INTMOVE(s1, dd);
890                         N_SLR(dd, REG_ITMP3);
891
892                         N_BRC(1 | 2, SZ_BRC + SZ_AHI); 
893                         N_AHI(GET_HIGH_REG(d), -1);
894
895                         emit_store_dst(jd, iptr, d);
896                         break;
897
898                 case ICMD_IMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
899
900                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
901                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
902                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
903                         if (s2 == d)
904                                 M_IMUL(s1, d);
905                         else {
906                                 M_INTMOVE(s1, d);
907                                 M_IMUL(s2, d);
908                         }
909                         emit_store_dst(jd, iptr, d);
910
911                         break;
912
913                 case ICMD_IMULCONST:  /* ..., value  ==> ..., value * constant        */
914                                       /* sx.val.i = constant                             */
915                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
916                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
917                         M_INTMOVE(s1, d);
918                         if (iptr->sx.val.i == 2) {
919                                 M_SLL_IMM(1, d);
920                         } else if (N_VALID_IMM(iptr->sx.val.i)) {
921                                 M_IMUL_IMM(iptr->sx.val.i, d);
922                         } else {
923                                 disp = dseg_add_s4(cd, iptr->sx.val.i);
924                                 M_ILD_DSEG(REG_ITMP2, disp);
925                                 M_IMUL(REG_ITMP2, d);   
926                         }
927                         emit_store_dst(jd, iptr, d);
928                         break;
929
930                 case ICMD_IDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
931                 case ICMD_IREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
932
933                         /* load s1 into r0 */
934
935                         s1 = emit_load_s1(jd, iptr, GET_HIGH_REG(REG_ITMP31_PACKED));
936                         M_INTMOVE(s1, GET_HIGH_REG(REG_ITMP31_PACKED));
937                         s1 = GET_HIGH_REG(REG_ITMP31_PACKED);
938
939                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
940
941                         /* extend s1 to long */
942
943                         M_SRDA_IMM(32, GET_HIGH_REG(REG_ITMP31_PACKED));
944
945                         /* divide */
946
947                         N_DR(GET_HIGH_REG(REG_ITMP31_PACKED), s2);
948
949                         /* take result */
950
951                         switch (iptr->opc) {
952                                 case ICMD_IREM:
953                                         d = codegen_reg_of_dst(jd, iptr, GET_HIGH_REG(REG_ITMP31_PACKED));
954                                         M_INTMOVE(GET_HIGH_REG(REG_ITMP31_PACKED), d);
955                                         break;
956                                 case ICMD_IDIV:
957                                         d = codegen_reg_of_dst(jd, iptr, GET_LOW_REG(REG_ITMP31_PACKED));
958                                         M_INTMOVE(GET_LOW_REG(REG_ITMP31_PACKED), d);
959                                         break;
960                         }
961
962                         emit_store_dst(jd, iptr, d);
963
964                         break;
965
966                 case ICMD_LDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
967                 case ICMD_LREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
968
969                         bte = iptr->sx.s23.s3.bte;
970                         md  = bte->md;
971
972                         /* test s2 for zero */
973
974                         s2 = emit_load_s2(jd, iptr, REG_ITMP12_PACKED);
975                         M_INTMOVE(GET_LOW_REG(s2), REG_ITMP3);
976                         M_IOR(GET_HIGH_REG(s2), REG_ITMP3);
977                         emit_arithmetic_check(cd, iptr, REG_ITMP3);
978
979                         /* TODO SIGFPE? */
980
981                         disp = dseg_add_functionptr(cd, bte->fp);
982
983                         /* load arguments */
984
985                         M_LNGMOVE(s2, PACK_REGS(REG_A3, REG_A2));
986
987                         s1 = emit_load_s1(jd, iptr, PACK_REGS(REG_A1, REG_A0));
988                         M_LNGMOVE(s1, PACK_REGS(REG_A1, REG_A0));
989
990                         /* call builtin */
991
992                         M_ASUB_IMM(96, REG_SP);
993                         M_ALD_DSEG(REG_ITMP2, disp);
994                         M_JSR(REG_RA, REG_ITMP2);
995                         M_AADD_IMM(96, REG_SP);
996
997                         /* store result */
998
999                         d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
1000                         M_LNGMOVE(REG_RESULT_PACKED, d);
1001                         emit_store_dst(jd, iptr, d);
1002
1003                         break;
1004
1005                 case ICMD_ISHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
1006                 case ICMD_ISHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
1007                 case ICMD_IUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
1008
1009                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1010                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1011                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1012
1013                         /* Use only 5 bits of sencond operand. */
1014
1015                         M_INTMOVE(s2, REG_ITMP2);
1016                         s2 = REG_ITMP2;
1017                         ICONST(REG_ITMP3, 0x1F);
1018                         M_IAND(REG_ITMP3, s2);
1019
1020                         M_INTMOVE(s1, d);
1021
1022                         switch (iptr->opc) {
1023                                 case ICMD_ISHL:
1024                                         M_SLL(s2, d);
1025                                         break;
1026                                 case ICMD_ISHR:
1027                                         M_SRA(s2, d);
1028                                         break;
1029                                 case ICMD_IUSHR:
1030                                         M_SRL(s2, d);
1031                                         break;
1032                                 default:
1033                                         assert(0);
1034                         }
1035                         emit_store_dst(jd, iptr, d);
1036                         break;
1037
1038                 case ICMD_IDIVPOW2:   /* ..., value  ==> ..., value >> constant       */
1039                                       /* sx.val.i = constant                             */
1040                         {
1041                                 u1 *ref;
1042
1043                                 assert(iptr->sx.val.i <= 32);
1044
1045                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1046                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1047
1048                                 M_INTMOVE(s1, d);
1049                                 M_TEST(d);
1050                                 ref = cd->mcodeptr;
1051                                 M_BGE(0);
1052
1053                                 s3 = (1 << iptr->sx.val.i) - 1;
1054
1055                                 if (N_VALID_IMM(s3)) {
1056                                         M_IADD_IMM(s3, d);
1057                                 } else  {
1058                                         ICONST(REG_ITMP1, -1);
1059                                         M_SRL_IMM(32 - iptr->sx.val.i, REG_ITMP1);
1060                                         M_IADD(REG_ITMP1, d);
1061                                 }
1062
1063                                 N_BRC_BACK_PATCH(ref);
1064
1065                                 M_SRA_IMM(iptr->sx.val.i, d);
1066
1067                                 emit_store_dst(jd, iptr, d);
1068                         }
1069
1070                         break;
1071         
1072                 case ICMD_IREMPOW2:   /* ..., value  ==> ..., value % constant        */
1073                                       /* sx.val.i = constant                             */
1074
1075                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1076                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1077
1078                         if (s1 == d) {
1079                                 M_MOV(s1, REG_ITMP1);
1080                                 s1 = REG_ITMP1;
1081                         }
1082                                 
1083                         ICONST(REG_ITMP3, iptr->sx.val.i);
1084
1085                         M_INTMOVE(s1, d);
1086                         M_IAND(REG_ITMP3, d);
1087
1088                         M_TEST(s1);
1089                         M_BGE(SZ_BRC + SZ_LCR + SZ_NR + SZ_LCR);
1090
1091                         N_LCR(d, s1);
1092                         N_NR(d, REG_ITMP3);
1093                         N_LCR(d, d);
1094
1095                         emit_store_dst(jd, iptr, d);
1096
1097                         break;
1098
1099                 case ICMD_ISHLCONST:  /* ..., value  ==> ..., value << constant       */
1100                                       /* sx.val.i = constant                             */
1101                 case ICMD_ISHRCONST:  /* ..., value  ==> ..., value >> constant       */
1102                                       /* sx.val.i = constant                             */
1103                 case ICMD_IUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
1104                                       /* sx.val.i = constant                             */
1105                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1106                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1107
1108                         M_INTMOVE(s1, d);
1109
1110                         disp = iptr->sx.val.i & 0x1F; /* Use only 5 bits of value */
1111
1112                         switch (iptr->opc) {
1113                                 case ICMD_ISHLCONST:
1114                                         N_SLL(d, disp, RN);
1115                                         break;
1116                                 case ICMD_ISHRCONST:
1117                                         N_SRA(d, disp, RN);
1118                                         break;
1119                                 case ICMD_IUSHRCONST:
1120                                         N_SRL(d, disp, RN);
1121                                         break;
1122                                 default:
1123                                         assert(0);
1124                         }
1125
1126                         emit_store_dst(jd, iptr, d);
1127                         break;
1128
1129                 case ICMD_LSHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
1130
1131                 case ICMD_LSHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
1132
1133                 case ICMD_LUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
1134
1135                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1136
1137                         /* Use only 6 bits of second operand */
1138
1139                         M_INTMOVE(s2, REG_ITMP2);
1140                         s2 = REG_ITMP2;
1141                         ICONST(REG_ITMP1, 0x3F);
1142                         M_IAND(REG_ITMP1, s2);
1143
1144                         s1 = emit_load_s1(jd, iptr, REG_ITMP31_PACKED); /* even-odd pair */
1145                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP31_PACKED);
1146
1147                         /* Destination must be even-odd pair */
1148
1149                         if (! N_IS_EVEN_ODD(d)) {
1150                                 d = REG_ITMP31_PACKED;
1151                         }
1152
1153                         assert(N_IS_EVEN_ODD(d));
1154
1155                         M_LNGMOVE(s1, d);
1156
1157                         switch (iptr->opc) {
1158                                 case ICMD_LSHL:
1159                                         M_SLDL(s2, GET_HIGH_REG(d));
1160                                         break;
1161                                 case ICMD_LSHR:
1162                                         M_SRDA(s2, GET_HIGH_REG(d));
1163                                         break;
1164                                 case ICMD_LUSHR:
1165                                         M_SRDL(s2, GET_HIGH_REG(d));
1166                                         break;
1167                                 default:
1168                                         assert(0);
1169                         }
1170
1171                         emit_copy_dst(jd, iptr, d);
1172                         emit_store_dst(jd, iptr, d);
1173
1174                         break;
1175
1176         case ICMD_LSHLCONST:  /* ..., value  ==> ..., value << constant       */
1177                                           /* sx.val.i = constant                             */
1178                 case ICMD_LSHRCONST:  /* ..., value  ==> ..., value >> constant       */
1179                                       /* sx.val.i = constant                             */
1180                 case ICMD_LUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
1181                                       /* sx.val.l = constant                             */
1182                 case ICMD_LMULPOW2:
1183                 
1184                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP31_PACKED); /* even-odd */
1185                         if (! N_IS_EVEN_ODD(d)) {
1186                                 d = REG_ITMP31_PACKED;
1187                         }
1188                         assert(N_IS_EVEN_ODD(d));
1189
1190                         s1 = emit_load_s1(jd, iptr, d);
1191                 
1192                         M_LNGMOVE(s1, d);
1193
1194                         disp = iptr->sx.val.i & 0x3F; /* Use only 6 bits of operand */
1195
1196                         switch (iptr->opc) {
1197                                 case ICMD_LSHLCONST:
1198                                         N_SLDL(GET_HIGH_REG(d), disp, RN);
1199                                         break;
1200                                 case ICMD_LSHRCONST:
1201                                         N_SRDA(GET_HIGH_REG(d), disp, RN);
1202                                         break;
1203                                 case ICMD_LUSHRCONST:
1204                                         N_SRDL(GET_HIGH_REG(d), disp, RN);
1205                                         break;
1206                                 case ICMD_LMULPOW2:
1207                                         N_SLDL(GET_HIGH_REG(d), disp, RN);
1208                                         break;
1209                                 default:
1210                                         assert(0);
1211                         }
1212
1213                         emit_copy_dst(jd, iptr, d);
1214                         emit_store_dst(jd, iptr, d);
1215                         break;
1216
1217                 case ICMD_IAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
1218
1219                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1220                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1221                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1222                         if (s2 == d)
1223                                 M_IAND(s1, d);
1224                         else {
1225                                 M_INTMOVE(s1, d);
1226                                 M_IAND(s2, d);
1227                         }
1228                         emit_store_dst(jd, iptr, d);
1229
1230                         break;
1231
1232                 case ICMD_IOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
1233
1234                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1235                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1236                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1237                         if (s2 == d)
1238                                 M_IOR(s1, d);
1239                         else {
1240                                 M_INTMOVE(s1, d);
1241                                 M_IOR(s2, d);
1242                         }
1243                         emit_store_dst(jd, iptr, d);
1244
1245                         break;
1246
1247                 case ICMD_IXOR:       /* ..., val1, val2  ==> ..., val1 ^ val2        */
1248
1249                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1250                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1251                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1252                         if (s2 == d)
1253                                 M_IXOR(s1, d);
1254                         else {
1255                                 M_INTMOVE(s1, d);
1256                                 M_IXOR(s2, d);
1257                         }
1258                         emit_store_dst(jd, iptr, d);
1259
1260                         break;
1261
1262
1263
1264                 case ICMD_IORCONST:   /* ..., value  ==> ..., value | constant        */
1265                                       /* sx.val.i = constant                             */
1266                 case ICMD_IANDCONST:  /* ..., value  ==> ..., value & constant        */
1267                                       /* sx.val.i = constant                             */
1268                 case ICMD_IXORCONST:  /* ..., value  ==> ..., value ^ constant        */
1269                                       /* sx.val.i = constant                             */
1270
1271                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1272                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1273
1274                         M_INTMOVE(s1, d);
1275                         ICONST(REG_ITMP2, iptr->sx.val.i);
1276
1277                         switch (iptr->opc) {
1278                                 case ICMD_IANDCONST:
1279                                         M_IAND(REG_ITMP2, d);
1280                                         break;
1281                                 case ICMD_IXORCONST:
1282                                         M_IXOR(REG_ITMP2, d);
1283                                         break;
1284                                 case ICMD_IORCONST:
1285                                         M_IOR(REG_ITMP2, d);
1286                                         break;
1287                                 default:
1288                                         assert(0);
1289                         }
1290
1291                         emit_store_dst(jd, iptr, d);
1292
1293                         break;
1294
1295                 case ICMD_LOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
1296                 case ICMD_LXOR:       /* ..., val1, val2  ==> ..., val1 ^ val2        */
1297                 case ICMD_LAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
1298
1299                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1300
1301                         s1 = emit_load_s1_low(jd, iptr, GET_LOW_REG(REG_ITMP12_PACKED));
1302                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1303                         dd = GET_LOW_REG(d);
1304
1305                         switch (iptr->opc) {
1306                                 case ICMD_LAND:
1307                                         if (s2 == dd) {
1308                                                 M_IAND(s1, dd);
1309                                         } else {
1310                                                 M_INTMOVE(s1, dd);
1311                                                 M_IAND(s2, dd);
1312                                         }
1313                                         break;
1314                                 case ICMD_LXOR:
1315                                         if (s2 == dd) {
1316                                                 M_IXOR(s1, dd);
1317                                         } else {
1318                                                 M_INTMOVE(s1, dd);
1319                                                 M_IXOR(s2, dd);
1320                                         }
1321                                         break;
1322                                 case ICMD_LOR:
1323                                         if (s2 == dd) {
1324                                                 M_IOR(s1, dd);
1325                                         } else {
1326                                                 M_INTMOVE(s1, dd);
1327                                                 M_IOR(s2, dd);
1328                                         }
1329                                         break;
1330                                 default:
1331                                         assert(0);
1332                         }
1333
1334                         s1 = emit_load_s1_high(jd, iptr, GET_HIGH_REG(REG_ITMP12_PACKED));
1335                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1336                         dd = GET_HIGH_REG(d);
1337
1338                         switch (iptr->opc) {
1339                                 case ICMD_LAND:
1340                                         if (s2 == dd) {
1341                                                 M_IAND(s1, dd);
1342                                         } else {
1343                                                 M_INTMOVE(s1, dd);
1344                                                 M_IAND(s2, dd);
1345                                         }
1346                                         break;
1347                                 case ICMD_LXOR:
1348                                         if (s2 == dd) {
1349                                                 M_IXOR(s1, dd);
1350                                         } else {
1351                                                 M_INTMOVE(s1, dd);
1352                                                 M_IXOR(s2, dd);
1353                                         }
1354                                         break;
1355                                 case ICMD_LOR:
1356                                         if (s2 == dd) {
1357                                                 M_IOR(s1, dd);
1358                                         } else {
1359                                                 M_INTMOVE(s1, dd);
1360                                                 M_IOR(s2, dd);
1361                                         }
1362                                         break;
1363                                 default:
1364                                         assert(0);
1365                         }
1366
1367                         emit_store_dst(jd, iptr, d);
1368                         break;
1369
1370                 case ICMD_LORCONST:   /* ..., value  ==> ..., value | constant        */
1371                                       /* sx.val.l = constant                             */
1372                 case ICMD_LXORCONST:  /* ..., value  ==> ..., value ^ constant        */
1373                                       /* sx.val.l = constant                             */
1374                 case ICMD_LANDCONST:  /* ..., value  ==> ..., value & constant        */
1375                                       /* sx.val.l = constant                             */
1376
1377                         /* TODO should use memory operand to access data segment, not load */
1378
1379                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1380
1381                         s1 = emit_load_s1_low(jd, iptr, GET_LOW_REG(d));
1382                         s3 = iptr->sx.val.l & 0xffffffff;
1383
1384                         M_INTMOVE(s1, GET_LOW_REG(d));
1385
1386                         ICONST(REG_ITMP3, s3);
1387
1388                         switch (iptr->opc) {
1389                                 case ICMD_LANDCONST:
1390                                         M_IAND(REG_ITMP3, GET_LOW_REG(d));
1391                                         break;
1392                                 case ICMD_LXORCONST:
1393                                         M_IXOR(REG_ITMP3, GET_LOW_REG(d));
1394                                         break;
1395                                 case ICMD_LORCONST:
1396                                         M_IOR(REG_ITMP3, GET_LOW_REG(d));
1397                                         break;
1398                                 default:
1399                                         assert(0);
1400                         }
1401
1402                         s1 = emit_load_s1_high(jd, iptr, GET_HIGH_REG(d));
1403                         s3 = iptr->sx.val.l >> 32;
1404
1405                         M_INTMOVE(s1, GET_HIGH_REG(d));
1406
1407                         ICONST(REG_ITMP3, s3);
1408
1409                         switch (iptr->opc) {
1410                                 case ICMD_LANDCONST:
1411                                         M_IAND(REG_ITMP3, GET_HIGH_REG(d));
1412                                         break;
1413                                 case ICMD_LXORCONST:
1414                                         M_IXOR(REG_ITMP3, GET_HIGH_REG(d));
1415                                         break;
1416                                 case ICMD_LORCONST:
1417                                         M_IOR(REG_ITMP3, GET_HIGH_REG(d));
1418                                         break;
1419                                 default:
1420                                         assert(0);
1421                         }
1422
1423                         emit_store_dst(jd, iptr, d);
1424
1425                         break;
1426
1427                 /* floating operations ************************************************/
1428
1429                 case ICMD_FNEG:       /* ..., value  ==> ..., - value                 */
1430                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1431                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1432                         M_FMOVN(s1, d);
1433                         emit_store_dst(jd, iptr, d);
1434                         break;
1435
1436                 case ICMD_DNEG:       /* ..., value  ==> ..., - value                 */
1437                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1438                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1439                         M_DMOVN(s1, d);
1440                         emit_store_dst(jd, iptr, d);
1441                         break;
1442
1443                 case ICMD_FADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
1444                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1445                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1446                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1447                         if (s2 == d)
1448                                 M_FADD(s1, d);
1449                         else {
1450                                 M_FLTMOVE(s1, d);
1451                                 M_FADD(s2, d);
1452                         }
1453                         emit_store_dst(jd, iptr, d);
1454                         break;
1455
1456                 case ICMD_DADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
1457                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1458                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1459                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1460                         if (s2 == d)
1461                                 M_DADD(s1, d);
1462                         else {
1463                                 M_FLTMOVE(s1, d);
1464                                 M_DADD(s2, d);
1465                         }
1466                         emit_store_dst(jd, iptr, d);
1467                         break;
1468
1469                 case ICMD_FSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
1470                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1471                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1472                         s2 = emit_load_s2_but(jd, iptr, REG_FTMP2, d);
1473
1474                         M_FLTMOVE(s1, d);
1475                         M_FSUB(s2, d);
1476                         emit_store_dst(jd, iptr, d);
1477                         break;
1478
1479                 case ICMD_DSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
1480                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1481                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1482                         s2 = emit_load_s2_but(jd, iptr, REG_FTMP2, d);
1483
1484                         M_FLTMOVE(s1, d);
1485                         M_DSUB(s2, d);
1486                         emit_store_dst(jd, iptr, d);
1487                         break;
1488
1489                 case ICMD_FMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
1490                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1491                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1492                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1493                         if (s2 == d)
1494                                 M_FMUL(s1, d);
1495                         else {
1496                                 M_FLTMOVE(s1, d);
1497                                 M_FMUL(s2, d);
1498                         }
1499                         emit_store_dst(jd, iptr, d);
1500                         break;
1501
1502                 case ICMD_DMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
1503                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1504                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1505                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1506                         if (s2 == d)
1507                                 M_DMUL(s1, d);
1508                         else {
1509                                 M_FLTMOVE(s1, d);
1510                                 M_DMUL(s2, d);
1511                         }
1512                         emit_store_dst(jd, iptr, d);
1513                         break;
1514
1515                 case ICMD_FDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1516                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1517                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1518                         s2 = emit_load_s2_but(jd, iptr, REG_FTMP2, d);
1519
1520                         M_FLTMOVE(s1, d);
1521                         M_FDIV(s2, d);
1522                         emit_store_dst(jd, iptr, d);
1523                         break;
1524
1525                 case ICMD_DDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1526                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1527                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1528                         s2 = emit_load_s2_but(jd, iptr, REG_FTMP2, d);
1529
1530                         M_FLTMOVE(s1, d);
1531                         M_DDIV(s2, d);
1532                         emit_store_dst(jd, iptr, d);
1533                         break;
1534
1535                 case ICMD_I2F:       /* ..., value  ==> ..., (float) value            */
1536                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1537                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1538                         M_CVTIF(s1, d);
1539                         emit_store_dst(jd, iptr, d);
1540                         break;
1541
1542                 case ICMD_I2D:       /* ..., value  ==> ..., (double) value           */
1543                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1544                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1545                         M_CVTID(s1, d);
1546                         emit_store_dst(jd, iptr, d);
1547                         break;
1548
1549                 case ICMD_F2I:       /* ..., value  ==> ..., (int) value              */
1550                 case ICMD_D2I:
1551                         {
1552                                 u1 *ref1;
1553 #ifdef SUPPORT_HERCULES
1554                                 u1 *ref2, *ref3;
1555 #endif
1556
1557                                 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1558                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1559
1560                                 /* Test if NAN */
1561
1562                                 switch (iptr->opc) {
1563                                         case ICMD_F2I:
1564                                                 N_LTEBR(s1, s1); 
1565                                                 break;
1566                                         case ICMD_D2I:
1567                                                 N_LTDBR(s1, s1);
1568                                                 break;
1569                                 }
1570
1571                                 N_BRC(DD_0 | DD_1 | DD_2, SZ_BRC + SZ_LHI + SZ_BRC); /* Non a NaN */
1572                                 N_LHI(d, 0); /* Load 0 */
1573                                 ref1 = cd->mcodeptr;
1574                                 N_BRC(DD_ANY, 0); /* Exit */
1575
1576                                 /* Convert */
1577
1578                                 switch (iptr->opc) {
1579                                         case ICMD_F2I:
1580                                                 M_CVTFI(s1, d); 
1581                                                 break;
1582                                         case ICMD_D2I:
1583                                                 M_CVTDI(s1, d); 
1584                                                 break;
1585                                 }
1586
1587 #ifdef SUPPORT_HERCULES
1588                                 /* Hercules does the conversion using a plain C conversion.
1589                                  * According to manual, real hardware should *NOT* require this.
1590                                  *
1591                                  * Corner case: Positive float leads to INT_MIN (overflow).
1592                                  */
1593
1594                                 switch (iptr->opc) {
1595                                         case ICMD_F2I:
1596                                                 N_LTEBR(s1, s1); 
1597                                                 break;
1598                                         case ICMD_D2I:
1599                                                 N_LTDBR(s1, s1);
1600                                                 break;
1601                                 }
1602
1603                                 ref2 = cd->mcodeptr;
1604                                 N_BRC(DD_0 | DD_1 | DD_3, 0); /* If operand is positive, continue */
1605
1606                                 M_TEST(d);
1607
1608                                 ref3 = cd->mcodeptr;
1609                                 M_BGE(0); /* If integer result is negative, continue */
1610
1611                                 disp = dseg_add_s4(cd, 0x7fffffff); /* Load INT_MAX */
1612                                 M_ILD_DSEG(d, disp);
1613 #endif
1614                                 N_BRC_BACK_PATCH(ref1);
1615 #ifdef SUPPORT_HERCULES
1616                                 N_BRC_BACK_PATCH(ref2);
1617                                 N_BRC_BACK_PATCH(ref3);
1618 #endif
1619                                 emit_store_dst(jd, iptr, d);
1620                         }
1621                         break;
1622
1623                 case ICMD_F2D:       /* ..., value  ==> ..., (double) value           */
1624                         {
1625 #ifdef SUPPORT_HERCULES
1626                                 u1 *ref;
1627 #endif
1628                                 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1629                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1630 #ifdef SUPPORT_HERCULES
1631                                 N_LTEBR(s1, s1);
1632                                 ref = cd->mcodeptr;
1633                                 N_BRC(DD_0 | DD_1 | DD_2, 0); /* Non a NaN */
1634                                 disp = dseg_add_double(cd, 0.0 / 0.0);
1635                                 M_DLD_DSEG(d, disp, REG_ITMP1);
1636                                 emit_label_br(cd, BRANCH_LABEL_1);
1637                                 N_BRC_BACK_PATCH(ref);
1638 #endif
1639                                 M_CVTFD(s1, d);
1640 #ifdef SUPPORT_HERCULES
1641                                 emit_label(cd, BRANCH_LABEL_1);
1642 #endif
1643                                 emit_store_dst(jd, iptr, d);
1644                         }
1645                         break;
1646
1647                 case ICMD_D2F:       /* ..., value  ==> ..., (float) value            */
1648                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1649                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1650                         M_CVTDF(s1, d);
1651                         emit_store_dst(jd, iptr, d);
1652                         break;
1653
1654                 case ICMD_FCMPL:      /* ..., val1, val2  ==> ..., val1 fcmpl val2    */
1655                                           /* == => 0, < => 1, > => -1 */
1656                 case ICMD_DCMPL:
1657
1658
1659                 case ICMD_FCMPG:      /* ..., val1, val2  ==> ..., val1 fcmpg val2    */
1660                                           /* == => 0, < => 1, > => -1 */
1661                 case ICMD_DCMPG:
1662
1663                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1664                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1665                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1666
1667                         switch (iptr->opc) {
1668                                 case ICMD_FCMPG:
1669                                 case ICMD_FCMPL:
1670                                         M_FCMP(s1, s2);
1671                                         break;
1672                                 case ICMD_DCMPG:
1673                                 case ICMD_DCMPL:
1674                                         M_DCMP(s1, s2);
1675                                         break;  
1676                         }
1677
1678                         N_BRC( /* load 1 */
1679                                 DD_H | (iptr->opc == ICMD_FCMPG || iptr->opc == ICMD_DCMPG ? DD_O : 0),
1680                                 SZ_BRC + SZ_BRC + SZ_BRC
1681                         );
1682
1683                         N_BRC( /* load -1 */
1684                                 DD_L | (iptr->opc == ICMD_FCMPL || iptr->opc == ICMD_DCMPL ? DD_O : 0),
1685                                 SZ_BRC + SZ_BRC + SZ_LHI + SZ_BRC
1686                         );
1687
1688                         N_BRC( /* load 0 */
1689                                 DD_E,
1690                                 SZ_BRC + SZ_LHI + SZ_BRC + SZ_LHI + SZ_BRC
1691                         );
1692
1693                         N_LHI(d, 1); /* GT */
1694                         M_BR(SZ_BRC + SZ_LHI + SZ_BRC + SZ_LHI);
1695                         N_LHI(d, -1); /* LT */
1696                         M_BR(SZ_BRC + SZ_LHI);
1697                         N_LHI(d, 0); /* EQ */
1698
1699                         emit_store_dst(jd, iptr, d);
1700
1701                         break;
1702
1703
1704                 /* memory operations **************************************************/
1705
1706                 case ICMD_ARRAYLENGTH: /* ..., arrayref  ==> ..., (int) length        */
1707
1708                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1709                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1710                         /* TODO softnull */
1711                         /* implicit null-pointer check */
1712                         M_ILD(d, s1, OFFSET(java_array_t, size));
1713                         emit_store_dst(jd, iptr, d);
1714
1715                         break;
1716
1717                 case ICMD_BALOAD:     /* ..., arrayref, index  ==> ..., value         */
1718                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1719                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1720                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1721
1722                         /* implicit null-pointer check */
1723                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1724
1725                         N_IC(d, OFFSET(java_bytearray_t, data[0]), s2, s1);
1726
1727                         M_SLL_IMM(24, d);
1728                         M_SRA_IMM(24, d);
1729
1730                         emit_store_dst(jd, iptr, d);
1731                         break;
1732
1733                 case ICMD_CALOAD:     /* ..., arrayref, index  ==> ..., value         */
1734
1735                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1736                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1737                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1738
1739                         /* implicit null-pointer check */
1740                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1741
1742                         M_INTMOVE(s2, REG_ITMP2);
1743                         M_SLL_IMM(1, REG_ITMP2);
1744
1745                         N_LH(d, OFFSET(java_chararray_t, data[0]), REG_ITMP2, s1);
1746
1747                         /* N_LH does sign extends, undo ! */
1748
1749                         M_SLL_IMM(16, d);
1750                         M_SRL_IMM(16, d);
1751
1752                         emit_store_dst(jd, iptr, d);
1753                         break;                  
1754
1755                 case ICMD_SALOAD:     /* ..., arrayref, index  ==> ..., value         */
1756                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1757                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1758                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1759
1760                         /* implicit null-pointer check */
1761                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1762
1763                         M_INTMOVE(s2, REG_ITMP2);
1764                         M_SLL_IMM(1, REG_ITMP2);
1765
1766                         N_LH(d, OFFSET(java_shortarray_t, data[0]), REG_ITMP2, s1);
1767                         emit_store_dst(jd, iptr, d);
1768                         break;
1769
1770                 case ICMD_IALOAD:     /* ..., arrayref, index  ==> ..., value         */
1771                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1772                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1773                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1774
1775                         /* implicit null-pointer check */
1776                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1777                         
1778                         M_INTMOVE(s2, REG_ITMP2);
1779                         M_SLL_IMM(2, REG_ITMP2); /* scale index by 4 */
1780                         N_L(d, OFFSET(java_intarray_t, data[0]), REG_ITMP2, s1);
1781                         emit_store_dst(jd, iptr, d);
1782                         break;
1783
1784                 case ICMD_LALOAD:     /* ..., arrayref, index  ==> ..., value         */
1785
1786                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1787                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1788
1789                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP13_PACKED);
1790
1791                         /* implicit null-pointer check */
1792                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1793                         
1794                         M_INTMOVE(s2, REG_ITMP2);
1795                         M_SLL_IMM(3, REG_ITMP2); /* scale index by 8 */
1796
1797                         N_L(
1798                                 GET_LOW_REG(d) /* maybe itmp3 */, 
1799                                 OFFSET(java_intarray_t, data[0]) + 4, 
1800                                 REG_ITMP2, s1 /* maybe itmp1 */
1801                         );
1802
1803                         N_L(
1804                                 GET_HIGH_REG(d) /* maybe itmp1 */, 
1805                                 OFFSET(java_intarray_t, data[0]), 
1806                                 REG_ITMP2, s1 /* maybe itmp1 */
1807                         );
1808
1809                         emit_store_dst(jd, iptr, d);
1810
1811                         break;
1812
1813                 case ICMD_FALOAD:     /* ..., arrayref, index  ==> ..., value         */
1814
1815                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1816                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1817                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1818
1819                         /* implicit null-pointer check */
1820                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1821
1822                         M_INTMOVE(s2, REG_ITMP2);
1823                         M_SLL_IMM(2, REG_ITMP2); /* scale index by 4 */
1824         
1825                         N_LE(d, OFFSET(java_floatarray_t, data[0]), REG_ITMP2, s1);
1826
1827                         emit_store_dst(jd, iptr, d);
1828                         break;
1829
1830                 case ICMD_DALOAD:     /* ..., arrayref, index  ==> ..., value         */
1831                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1832                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1833                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1834
1835                         /* implicit null-pointer check */
1836                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1837
1838                         M_INTMOVE(s2, REG_ITMP2);
1839                         M_SLL_IMM(3, REG_ITMP2); /* scale index by 8 */
1840         
1841                         N_LD(d, OFFSET(java_floatarray_t, data[0]), REG_ITMP2, s1);
1842
1843                         emit_store_dst(jd, iptr, d);
1844                         break;
1845
1846                 case ICMD_AALOAD:     /* ..., arrayref, index  ==> ..., value         */
1847                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1848                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1849                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1850
1851                         /* implicit null-pointer check */
1852                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1853                         
1854                         M_INTMOVE(s2, REG_ITMP2);
1855                         M_SLL_IMM(2, REG_ITMP2); /* scale index by 4 */
1856                         N_L(d, OFFSET(java_objectarray_t, data[0]), REG_ITMP2, s1);
1857                         emit_store_dst(jd, iptr, d);
1858                         break;
1859
1860                 case ICMD_BASTORE:    /* ..., arrayref, index, value  ==> ...         */
1861                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1862                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1863                         /* implicit null-pointer check */
1864                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1865                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1866
1867                         N_STC(s3, OFFSET(java_bytearray_t, data[0]), s2, s1);
1868                         break;
1869
1870                 case ICMD_CASTORE:    /* ..., arrayref, index, value  ==> ...         */
1871
1872                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1873                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1874                         /* implicit null-pointer check */
1875                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1876                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1877
1878                         M_INTMOVE(s2, REG_ITMP2);
1879                         M_SLL_IMM(1, REG_ITMP2);
1880
1881                         N_STH(s3, OFFSET(java_chararray_t, data[0]), REG_ITMP2, s1);
1882
1883                         break;
1884
1885                 case ICMD_SASTORE:    /* ..., arrayref, index, value  ==> ...         */
1886                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1887                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1888                         /* implicit null-pointer check */
1889                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1890                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1891
1892                         M_INTMOVE(s2, REG_ITMP2);
1893                         M_SLL_IMM(1, REG_ITMP2);
1894
1895                         N_STH(s3, OFFSET(java_shortarray_t, data[0]), REG_ITMP2, s1);
1896                         break;
1897
1898                 case ICMD_IASTORE:    /* ..., arrayref, index, value  ==> ...         */
1899
1900                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1901                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1902                         /* implicit null-pointer check */
1903                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1904
1905                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1906
1907                         M_INTMOVE(s2, REG_ITMP2);
1908                         M_SLL_IMM(2, REG_ITMP2);
1909
1910                         N_ST(s3, OFFSET(java_intarray_t, data[0]), REG_ITMP2, s1);
1911                         break;
1912
1913                 case ICMD_LASTORE:    /* ..., arrayref, index, value  ==> ...         */
1914
1915                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1916                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1917                         /* implicit null-pointer check */
1918                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1919
1920                         M_INTMOVE(s2, REG_ITMP2);
1921                         M_SLL_IMM(3, REG_ITMP2);
1922
1923                         s3 = emit_load_s3_high(jd, iptr, REG_ITMP3);
1924                         N_ST(s3, OFFSET(java_intarray_t, data[0]), REG_ITMP2, s1);
1925                         s3 = emit_load_s3_low(jd, iptr, REG_ITMP3);
1926                         N_ST(s3, OFFSET(java_intarray_t, data[0]) + 4, REG_ITMP2, s1);
1927                         break;
1928
1929                 case ICMD_FASTORE:    /* ..., arrayref, index, value  ==> ...         */
1930                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1931                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1932                         /* implicit null-pointer check */
1933                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1934                         s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1935
1936                         M_INTMOVE(s2, REG_ITMP2);
1937                         M_SLL_IMM(2, REG_ITMP2);
1938
1939                         N_STE(s3, OFFSET(java_floatarray_t, data[0]), REG_ITMP2, s1);
1940                         break;
1941
1942                 case ICMD_DASTORE:    /* ..., arrayref, index, value  ==> ...         */
1943                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1944                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1945                         /* implicit null-pointer check */
1946                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1947                         s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1948
1949                         M_INTMOVE(s2, REG_ITMP2);
1950                         M_SLL_IMM(3, REG_ITMP2);
1951
1952                         N_STD(s3, OFFSET(java_doublearray_t, data[0]), REG_ITMP2, s1);
1953                         break;
1954
1955                 case ICMD_AASTORE:    /* ..., arrayref, index, value  ==> ...         */
1956
1957                         s1 = emit_load_s1(jd, iptr, REG_A0);
1958                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1959                         /* implicit null-pointer check */
1960                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1961                         s3 = emit_load_s3(jd, iptr, REG_A1);
1962
1963                         M_INTMOVE(s1, REG_A0);
1964                         M_INTMOVE(s3, REG_A1);
1965
1966                         disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
1967                         M_ALD_DSEG(REG_ITMP2, disp);
1968                         M_ASUB_IMM(96, REG_SP);
1969                         M_JSR(REG_RA, REG_ITMP2);
1970                         M_AADD_IMM(96, REG_SP);
1971
1972                         emit_arraystore_check(cd, iptr);
1973
1974                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1975                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1976                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1977
1978                         M_INTMOVE(s2, REG_ITMP2);
1979                         M_SLL_IMM(2, REG_ITMP2);
1980                         N_ST(s3, OFFSET(java_objectarray_t, data[0]), REG_ITMP2, s1);
1981
1982                         /*
1983                         M_SAADDQ(s2, s1, REG_ITMP1); itmp1 := 4 * s2 + s1
1984                         M_AST(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1985                         */
1986                         break;
1987
1988
1989                 case ICMD_GETSTATIC:  /* ...  ==> ..., value                          */
1990
1991                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1992                                 uf        = iptr->sx.s23.s3.uf;
1993                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1994                                 disp      = dseg_add_unique_address(cd, NULL);
1995
1996 /*                              PROFILE_CYCLE_STOP; */
1997
1998                                 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1999
2000 /*                              PROFILE_CYCLE_START; */
2001                         }
2002                         else {
2003                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
2004                                 fieldtype = fi->type;
2005                                 disp      = dseg_add_address(cd, fi->value);
2006
2007                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) {
2008                                         PROFILE_CYCLE_STOP;
2009
2010                                         patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz, 0);
2011
2012                                         PROFILE_CYCLE_START;
2013                                 }
2014                         }
2015
2016                         M_ALD_DSEG(REG_ITMP1, disp);
2017
2018                         switch (fieldtype) {
2019                         case TYPE_INT:
2020                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2021                                 M_ILD(d, REG_ITMP1, 0);
2022                                 break;
2023                         case TYPE_LNG:
2024                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2025                                 M_LLD(d, REG_ITMP1, 0);
2026                                 break;
2027                         case TYPE_ADR:
2028                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2029                                 M_ALD(d, REG_ITMP1, 0);
2030                                 break;
2031                         case TYPE_FLT:
2032                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2033                                 M_FLD(d, REG_ITMP1, 0);
2034                                 break;
2035                         case TYPE_DBL:                          
2036                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2037                                 M_DLD(d, REG_ITMP1, 0);
2038                                 break;
2039                         }
2040
2041                         emit_store_dst(jd, iptr, d);
2042
2043                         break;
2044
2045                 case ICMD_PUTSTATIC:  /* ..., value  ==> ...                          */
2046
2047                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2048                                 uf        = iptr->sx.s23.s3.uf;
2049                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2050                                 disp      = dseg_add_unique_address(cd, uf);
2051
2052                                 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
2053                         }
2054                         else {
2055                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
2056                                 fieldtype = fi->type;
2057                                 disp      = dseg_add_address(cd, fi->value);
2058
2059                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) {
2060                                         PROFILE_CYCLE_STOP;
2061                                         patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz, disp);
2062                                         PROFILE_CYCLE_START;
2063                                 }
2064                         }
2065
2066                         M_ALD_DSEG(REG_ITMP1, disp);
2067                         switch (fieldtype) {
2068                         case TYPE_INT:
2069                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2070                                 M_IST(s1, REG_ITMP1, 0);
2071                                 break;
2072                         case TYPE_LNG:
2073                                 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
2074                                 M_LST(s1, REG_ITMP1, 0);
2075                                 break;
2076                         case TYPE_ADR:
2077                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2078                                 M_AST(s1, REG_ITMP1, 0);
2079                                 break;
2080                         case TYPE_FLT:
2081                                 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2082                                 M_FST(s1, REG_ITMP1, 0);
2083                                 break;
2084                         case TYPE_DBL:
2085                                 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2086                                 M_DST(s1, REG_ITMP1, 0);
2087                                 break;
2088                         }
2089                         break;
2090
2091                 case ICMD_GETFIELD:   /* ...  ==> ..., value                          */
2092
2093                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2094                         emit_nullpointer_check(cd, iptr, s1);
2095
2096                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2097                                 uf        = iptr->sx.s23.s3.uf;
2098                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2099                                 disp      = 0;
2100
2101                                 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2102                         }
2103                         else {
2104                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
2105                                 fieldtype = fi->type;
2106                                 disp      = fi->offset;
2107                         }
2108
2109                         switch (fieldtype) {
2110                         case TYPE_INT:
2111                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2112                                 M_ILD(d, s1, disp);
2113                                 break;
2114                         case TYPE_LNG:
2115                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2116                                 if (GET_HIGH_REG(d) == s1) {
2117                                         M_ILD(GET_LOW_REG(d), s1, disp + 4);
2118                                         M_ILD(GET_HIGH_REG(d), s1, disp);
2119                                 }
2120                                 else {
2121                                         M_ILD(GET_LOW_REG(d), s1, disp + 4);
2122                                         M_ILD(GET_HIGH_REG(d), s1, disp);
2123                                 }
2124                                 break;
2125                         case TYPE_ADR:
2126                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2127                                 M_ALD(d, s1, disp);
2128                                 break;
2129                         case TYPE_FLT:
2130                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2131                                 M_FLD(d, s1, disp);
2132                                 break;
2133                         case TYPE_DBL:                          
2134                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2135                                 M_DLD(d, s1, disp);
2136                                 break;
2137                         }
2138                         emit_store_dst(jd, iptr, d);
2139                         break;
2140
2141                 case ICMD_PUTFIELD:   /* ..., objectref, value  ==> ...               */
2142                         {
2143                         u1 *ref;
2144
2145                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2146                         emit_nullpointer_check(cd, iptr, s1);
2147
2148                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2149                                 uf        = iptr->sx.s23.s3.uf;
2150                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2151                                 disp      = 0;
2152                         } 
2153                         else {
2154                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
2155                                 fieldtype = fi->type;
2156                                 disp      = fi->offset;
2157                         }
2158
2159                         /* We can't add a patcher ref behind this load,
2160                          * because the patcher would destroy REG_ITMP3.
2161                          *
2162                          * We pass in the disp parameter, how many bytes
2163                          * to skip to the to the actual store.
2164                          *
2165                          * XXX this relies on patcher_add_patch_ref internals
2166                          */
2167
2168                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2169                                 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2170                                 ref = cd->mcodeptr;
2171                         }
2172
2173
2174                         if (IS_INT_LNG_TYPE(fieldtype)) {
2175                                 if (IS_2_WORD_TYPE(fieldtype))
2176                                         s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
2177                                 else
2178                                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2179                         } else {
2180                                 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
2181                         }
2182
2183                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2184                                 ((patchref_t *)list_first(jd->code->patchers))->disp = (cd->mcodeptr - ref);
2185                         }
2186
2187                         switch (fieldtype) {
2188                                 case TYPE_INT:
2189                                         M_IST(s2, s1, disp);
2190                                         break;
2191                                 case TYPE_LNG:
2192                                         M_IST(GET_LOW_REG(s2), s1, disp + 4);      /* keep this order */
2193                                         M_IST(GET_HIGH_REG(s2), s1, disp);         /* keep this order */
2194                                         break;
2195                                 case TYPE_ADR:
2196                                         M_AST(s2, s1, disp);
2197                                         break;
2198                                 case TYPE_FLT:
2199                                         M_FST(s2, s1, disp);
2200                                         break;
2201                                 case TYPE_DBL:
2202                                         M_DST(s2, s1, disp);
2203                                         break;
2204                         }
2205
2206                         }
2207                         break;
2208
2209                 /* branch operations **************************************************/
2210
2211                 case ICMD_ATHROW:       /* ..., objectref ==> ... (, objectref)       */
2212
2213                         /* PROFILE_CYCLE_STOP; */
2214                 
2215                         s1 = emit_load_s1(jd, iptr, REG_ITMP3);
2216                         M_INTMOVE(s1, REG_ITMP3_XPTR);
2217
2218 #ifdef ENABLE_VERIFIER
2219                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2220                                 uc = iptr->sx.s23.s2.uc;
2221
2222                                 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2223                         }
2224 #endif /* ENABLE_VERIFIER */
2225
2226                         disp = dseg_add_functionptr(cd, asm_handle_exception);
2227                         M_ALD_DSEG(REG_ITMP1, disp);
2228                         M_JMP(REG_ITMP1_XPC, REG_ITMP1);
2229                         M_NOP;
2230
2231                         break;
2232
2233                 case ICMD_GOTO:         /* ... ==> ...                                */
2234                 case ICMD_RET:          /* ... ==> ...                                */
2235
2236                         emit_br(cd, iptr->dst.block);
2237
2238                         break;
2239
2240                 case ICMD_JSR:          /* ... ==> ...                                */
2241
2242                         emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
2243
2244                         break;
2245                         
2246                 case ICMD_IFNULL:       /* ..., value ==> ...                         */
2247                 case ICMD_IFNONNULL:    /* ..., value ==> ...                         */
2248                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2249                         M_TEST(s1);
2250                         switch (iptr->opc) {    
2251                                 case ICMD_IFNULL:
2252                                         emit_beq(cd, iptr->dst.block);
2253                                         break;
2254                                 case ICMD_IFNONNULL:
2255                                         emit_bne(cd, iptr->dst.block);
2256                                         break;
2257                         }
2258                         break;
2259
2260                 case ICMD_IFEQ:         /* ..., value ==> ...                         */
2261                 case ICMD_IFLT:         /* ..., value ==> ...                         */
2262                 case ICMD_IFLE:         /* ..., value ==> ...                         */
2263                 case ICMD_IFNE:         /* ..., value ==> ...                         */
2264                 case ICMD_IFGT:         /* ..., value ==> ...                         */
2265                 case ICMD_IFGE:         /* ..., value ==> ...                         */
2266                         
2267                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2268
2269                         if (N_VALID_IMM(iptr->sx.val.i))
2270                                 M_ICMP_IMM(s1, iptr->sx.val.i);
2271                         else {
2272                                 disp = dseg_add_s4(cd, iptr->sx.val.i);
2273                                 if (N_VALID_DSEG_DISP(disp)) {
2274                                         N_C(s1, N_DSEG_DISP(disp), RN, REG_PV);
2275                                 } else {
2276                                         ICONST(REG_ITMP2, disp);
2277                                         N_C(s1, -N_PV_OFFSET, REG_ITMP2, REG_PV);
2278                                 }
2279                         }
2280
2281                         switch (iptr->opc) {
2282                         case ICMD_IFLT:
2283                                 emit_blt(cd, iptr->dst.block);
2284                                 break;
2285                         case ICMD_IFLE:
2286                                 emit_ble(cd, iptr->dst.block);
2287                                 break;
2288                         case ICMD_IFNE:
2289                                 emit_bne(cd, iptr->dst.block);
2290                                 break;
2291                         case ICMD_IFGT:
2292                                 emit_bgt(cd, iptr->dst.block);
2293                                 break;
2294                         case ICMD_IFGE:
2295                                 emit_bge(cd, iptr->dst.block);
2296                                 break;
2297                         case ICMD_IFEQ:
2298                                 emit_beq(cd, iptr->dst.block);
2299                                 break;
2300                         }
2301
2302                         break;
2303
2304                 case ICMD_IF_LLT:       /* ..., value ==> ...                         */
2305                 case ICMD_IF_LLE:       /* op1 = target JavaVM pc, val.l = constant   */
2306                 case ICMD_IF_LGT:
2307                 case ICMD_IF_LGE:
2308                 case ICMD_IF_LEQ:
2309                 case ICMD_IF_LNE:
2310
2311                         /* ATTENTION: compare high words signed and low words unsigned */
2312
2313 #                       define LABEL_OUT BRANCH_LABEL_1
2314
2315                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2316
2317                         if (N_VALID_IMM(iptr->sx.val.l >> 32))
2318                                 M_ICMP_IMM(s1, iptr->sx.val.l >> 32);
2319                         else {
2320                                 disp = dseg_add_s4(cd, iptr->sx.val.l >> 32);
2321                                 if (N_VALID_DSEG_DISP(disp)) {
2322                                         N_C(s1, N_DSEG_DISP(disp), RN, REG_PV);
2323                                 } else {
2324                                         ICONST(REG_ITMP2, disp);
2325                                         N_C(s1, -N_PV_OFFSET, REG_ITMP2, REG_PV);
2326                                 }
2327                         }
2328
2329                         switch(iptr->opc) {
2330                                 case ICMD_IF_LLT:
2331                                 case ICMD_IF_LLE:
2332                                         emit_blt(cd, iptr->dst.block);
2333                                         /* EQ ... fall through */
2334                                         emit_label_bgt(cd, LABEL_OUT);
2335                                         break;
2336                                 case ICMD_IF_LGT:
2337                                 case ICMD_IF_LGE:
2338                                         emit_bgt(cd, iptr->dst.block);
2339                                         /* EQ ... fall through */
2340                                         emit_label_blt(cd, LABEL_OUT);
2341                                         break;
2342                                 case ICMD_IF_LEQ: 
2343                                         /* EQ ... fall through */
2344                                         emit_label_bne(cd, LABEL_OUT);
2345                                         break;
2346                                 case ICMD_IF_LNE:
2347                                         /* EQ ... fall through */
2348                                         emit_bne(cd, iptr->dst.block);
2349                                         break;
2350                                 default:
2351                                         assert(0);
2352                         }
2353
2354                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2355
2356                         disp = dseg_add_s4(cd, (s4)(iptr->sx.val.l & 0xffffffff));
2357                         if (N_VALID_DSEG_DISP(disp)) {
2358                                 N_CL(s1, N_DSEG_DISP(disp), RN, REG_PV);
2359                         } else {
2360                                 ICONST(REG_ITMP2, disp);
2361                                 N_CL(s1, -N_PV_OFFSET, REG_ITMP2, REG_PV);
2362                         }
2363
2364                         switch(iptr->opc) {
2365                                 case ICMD_IF_LLT:
2366                                         emit_blt(cd, iptr->dst.block);
2367                                         emit_label(cd, LABEL_OUT);
2368                                         break;
2369                                 case ICMD_IF_LLE:
2370                                         emit_ble(cd, iptr->dst.block);
2371                                         emit_label(cd, LABEL_OUT);
2372                                         break;
2373                                 case ICMD_IF_LGT:
2374                                         emit_bgt(cd, iptr->dst.block);
2375                                         emit_label(cd, LABEL_OUT);
2376                                         break;
2377                                 case ICMD_IF_LGE:
2378                                         emit_bge(cd, iptr->dst.block);
2379                                         emit_label(cd, LABEL_OUT);
2380                                         break;
2381                                 case ICMD_IF_LEQ:
2382                                         emit_beq(cd, iptr->dst.block);
2383                                         emit_label(cd, LABEL_OUT);
2384                                         break;
2385                                 case ICMD_IF_LNE:
2386                                         emit_bne(cd, iptr->dst.block);
2387                                         break;
2388                                 default:
2389                                         assert(0);
2390                         }
2391
2392 #                       undef LABEL_OUT
2393                         break;
2394
2395                 case ICMD_IF_ACMPEQ:    /* ..., value, value ==> ...                  */
2396                 case ICMD_IF_ACMPNE:    /* op1 = target JavaVM pc                     */
2397
2398                         /* Compare addresses as 31 bit unsigned integers */
2399
2400                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2401                         M_LDA(REG_ITMP1, s1, 0);
2402
2403                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2404                         M_LDA(REG_ITMP2, s2, 0);
2405
2406                         M_CMP(REG_ITMP1, REG_ITMP2);
2407
2408                         switch (iptr->opc) {
2409                                 case ICMD_IF_ACMPEQ:
2410                                         emit_beq(cd, iptr->dst.block);
2411                                         break;
2412                                 case ICMD_IF_ACMPNE:
2413                                         emit_bne(cd, iptr->dst.block);
2414                                         break;
2415                         }
2416
2417                         break;
2418
2419                 case ICMD_IF_ICMPEQ:    /* ..., value, value ==> ...                  */
2420                 case ICMD_IF_ICMPNE:    /* ..., value, value ==> ...                  */
2421                 case ICMD_IF_ICMPLT:    /* ..., value, value ==> ...                  */
2422                 case ICMD_IF_ICMPGT:    /* ..., value, value ==> ...                  */
2423                 case ICMD_IF_ICMPLE:    /* ..., value, value ==> ...                  */
2424                 case ICMD_IF_ICMPGE:    /* ..., value, value ==> ...                  */
2425
2426                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2427                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2428                         M_CMP(s1, s2);
2429                         switch (iptr->opc) {
2430                                 case ICMD_IF_ICMPEQ:
2431                                         emit_beq(cd, iptr->dst.block);
2432                                         break;
2433                                 case ICMD_IF_ICMPNE:
2434                                         emit_bne(cd, iptr->dst.block);
2435                                         break;
2436                                 case ICMD_IF_ICMPLT:
2437                                         emit_blt(cd, iptr->dst.block);
2438                                         break;
2439                                 case ICMD_IF_ICMPGT:
2440                                         emit_bgt(cd, iptr->dst.block);
2441                                         break;
2442                                 case ICMD_IF_ICMPLE:
2443                                         emit_ble(cd, iptr->dst.block);
2444                                         break;
2445                                 case ICMD_IF_ICMPGE:
2446                                         emit_bge(cd, iptr->dst.block);
2447                                         break;
2448                         }
2449
2450                         break;
2451
2452                 case ICMD_IF_LCMPLE:    /* ..., value, value ==> ...                  */
2453                 case ICMD_IF_LCMPLT:    /* ..., value, value ==> ...                  */
2454                 case ICMD_IF_LCMPGT:    /* ..., value, value ==> ...                  */
2455                 case ICMD_IF_LCMPGE:    /* ..., value, value ==> ...                  */
2456                 case ICMD_IF_LCMPNE:    /* ..., value, value ==> ...                  */
2457                 case ICMD_IF_LCMPEQ:    /* ..., value, value ==> ...                  */
2458                         {
2459
2460                                 u1 *out_ref = NULL;
2461
2462                                 /* ATTENTION: compare high words signed and low words unsigned */
2463         
2464                                 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2465                                 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2466
2467                                 M_ICMP(s1, s2);
2468
2469                                 switch(iptr->opc) {
2470                                 case ICMD_IF_LCMPLT:
2471                                 case ICMD_IF_LCMPLE:
2472                                         emit_blt(cd, iptr->dst.block);
2473                                         /* EQ ... fall through */
2474                                         out_ref = cd->mcodeptr;
2475                                         M_BGT(0);
2476                                         break;
2477                                 case ICMD_IF_LCMPGT:
2478                                 case ICMD_IF_LCMPGE:
2479                                         emit_bgt(cd, iptr->dst.block);
2480                                         /* EQ ... fall through */
2481                                         out_ref = cd->mcodeptr;
2482                                         M_BLT(0);
2483                                         break;
2484                                 case ICMD_IF_LCMPEQ: 
2485                                         /* EQ ... fall through */
2486                                         out_ref = cd->mcodeptr;
2487                                         M_BNE(0);
2488                                         break;
2489                                 case ICMD_IF_LCMPNE:
2490                                         /* EQ ... fall through */
2491                                         emit_bne(cd, iptr->dst.block);
2492                                         break;
2493                                 default:
2494                                         assert(0);
2495                                 }
2496
2497                                 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2498                                 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2499         
2500                                 M_ICMPU(s1, s2);
2501
2502                                 switch(iptr->opc) {
2503                                 case ICMD_IF_LCMPLT:
2504                                         emit_blt(cd, iptr->dst.block);
2505                                         break;
2506                                 case ICMD_IF_LCMPLE:
2507                                         emit_ble(cd, iptr->dst.block);
2508                                         break;
2509                                 case ICMD_IF_LCMPGT:
2510                                         emit_bgt(cd, iptr->dst.block);
2511                                         break;
2512                                 case ICMD_IF_LCMPGE:
2513                                         emit_bge(cd, iptr->dst.block);
2514                                         break;
2515                                 case ICMD_IF_LCMPEQ:
2516                                         emit_beq(cd, iptr->dst.block);
2517                                         break;
2518                                 case ICMD_IF_LCMPNE:
2519                                         emit_bne(cd, iptr->dst.block);
2520                                         break;
2521                                 default:
2522                                         assert(0);
2523                                 }
2524
2525                                 if (out_ref != NULL) {
2526                                         N_BRC_BACK_PATCH(out_ref);
2527                                 }
2528
2529                         }
2530                         break;
2531
2532                 case ICMD_IRETURN:      /* ..., retvalue ==> ...                      */
2533
2534                         REPLACEMENT_POINT_RETURN(cd, iptr);
2535                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
2536                         M_INTMOVE(s1, REG_RESULT);
2537                         goto nowperformreturn;
2538
2539                 case ICMD_ARETURN:      /* ..., retvalue ==> ...                      */
2540
2541                         REPLACEMENT_POINT_RETURN(cd, iptr);
2542                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
2543                         M_INTMOVE(s1, REG_RESULT);
2544
2545 #ifdef ENABLE_VERIFIER
2546                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2547                                 unresolved_class *uc = iptr->sx.s23.s2.uc;
2548
2549                                 PROFILE_CYCLE_STOP;
2550                                 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2551                                 PROFILE_CYCLE_START;
2552                         }
2553 #endif /* ENABLE_VERIFIER */
2554                         goto nowperformreturn;
2555
2556                 case ICMD_LRETURN:      /* ..., retvalue ==> ...                      */
2557
2558                         REPLACEMENT_POINT_RETURN(cd, iptr);
2559                         s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
2560                         M_LNGMOVE(s1, REG_RESULT_PACKED);
2561                         goto nowperformreturn;
2562
2563                 case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
2564                 case ICMD_DRETURN:
2565
2566                         REPLACEMENT_POINT_RETURN(cd, iptr);
2567                         s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2568                         M_FLTMOVE(s1, REG_FRESULT);
2569                         goto nowperformreturn;
2570
2571                 case ICMD_RETURN:      /* ...  ==> ...                                */
2572
2573                         REPLACEMENT_POINT_RETURN(cd, iptr);
2574
2575 nowperformreturn:
2576                         {
2577                         s4 i, p;
2578                         
2579                         p = cd->stackframesize;
2580
2581                         /* call trace function */
2582
2583 #if !defined(NDEBUG)
2584                         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2585                                 emit_verbosecall_exit(jd);
2586 #endif /* !defined(NDEBUG) */
2587
2588 #if defined(ENABLE_THREADS)
2589                         if (checksync && code_is_synchronized(code)) {
2590                                 /* we need to save the proper return value */
2591
2592                                 switch (iptr->opc) {
2593                                 case ICMD_LRETURN:
2594                                         M_IST(REG_RESULT2, REG_SP, ((rd->memuse + 1) * 8) + 4);
2595                                         /* fall through */
2596                                 case ICMD_IRETURN:
2597                                 case ICMD_ARETURN:
2598                                         M_IST(REG_RESULT , REG_SP, (rd->memuse + 1) * 8);
2599                                         break;
2600                                 case ICMD_FRETURN:
2601                                         M_FST(REG_FRESULT, REG_SP, (rd->memuse + 1) * 8);
2602                                         break;
2603                                 case ICMD_DRETURN:
2604                                         M_DST(REG_FRESULT, REG_SP, (rd->memuse + 1) * 8);
2605                                         break;
2606                                 }
2607
2608                                 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2609
2610                                 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2611                                 M_ALD_DSEG(REG_ITMP2, disp);
2612
2613                                 M_ASUB_IMM(96, REG_SP);
2614                                 M_CALL(REG_ITMP2);
2615                                 M_AADD_IMM(96, REG_SP);
2616
2617                                 /* and now restore the proper return value */
2618
2619                                 switch (iptr->opc) {
2620                                 case ICMD_LRETURN:
2621                                         M_ILD(REG_RESULT2, REG_SP, ((rd->memuse + 1) * 8) + 4);
2622                                         /* fall through */
2623                                 case ICMD_IRETURN:
2624                                 case ICMD_ARETURN:
2625                                         M_ILD(REG_RESULT , REG_SP, (rd->memuse + 1) * 8);
2626                                         break;
2627                                 case ICMD_FRETURN:
2628                                         M_FLD(REG_FRESULT, REG_SP, (rd->memuse + 1) * 8);
2629                                         break;
2630                                 case ICMD_DRETURN:
2631                                         M_DLD(REG_FRESULT, REG_SP, (rd->memuse + 1) * 8);
2632                                         break;
2633                                 }
2634                         }
2635 #endif
2636
2637                         /* restore return address                                         */
2638
2639                         p--; M_ALD(REG_RA, REG_SP, p * 8);
2640
2641                         /* restore saved registers                                        */
2642
2643                         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2644                                 p--; M_ILD(rd->savintregs[i], REG_SP, p * 8);
2645                         }
2646                         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2647                                 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2648                         }
2649
2650                         /* deallocate stack                                               */
2651
2652                         if (cd->stackframesize)
2653                                 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
2654
2655                         /* generate method profiling code */
2656
2657                         PROFILE_CYCLE_STOP;
2658
2659                         M_RET;
2660                         }
2661                         break;
2662
2663                 case ICMD_TABLESWITCH:  /* ..., index ==> ...                         */
2664                         {
2665                                 s4 i, l;
2666                                 branch_target_t *table;
2667
2668                                 table = iptr->dst.table;
2669
2670                                 l = iptr->sx.s23.s2.tablelow;
2671                                 i = iptr->sx.s23.s3.tablehigh;
2672
2673                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2674                                 M_INTMOVE(s1, REG_ITMP1);
2675
2676                                 if (l == 0) {
2677                                         /* do nothing */
2678                                 } else if (N_VALID_IMM(-l)) {
2679                                         M_ISUB_IMM(l, REG_ITMP1);
2680                                 } else {
2681                                         ICONST(REG_ITMP2, l);
2682                                         M_ISUB(REG_ITMP2, REG_ITMP1);
2683                                 }
2684
2685                                 /* number of targets */
2686
2687                                 i = i - l + 1;
2688
2689                                 /* range check */
2690
2691                                 ICONST(REG_ITMP2, i);
2692                                 M_ICMPU(REG_ITMP1, REG_ITMP2);
2693                                 emit_bge(cd, table[0].block);
2694
2695                                 /* build jump table top down and use address of lowest entry */
2696
2697                                 table += i;
2698
2699                                 while (--i >= 0) {
2700                                         dseg_add_target(cd, table->block); 
2701                                         --table;
2702                                 }
2703                         }
2704
2705                         /* length of dataseg after last dseg_add_target is used by load */
2706
2707                         M_SLL_IMM(2, REG_ITMP1); /* scale by 4 */
2708                         M_ASUB_IMM(cd->dseglen, REG_ITMP1);
2709                         N_L(REG_ITMP1, -N_PV_OFFSET, REG_ITMP1, REG_PV);
2710                         M_JMP(RN, REG_ITMP1);
2711
2712                         break;
2713
2714
2715                 case ICMD_LOOKUPSWITCH: /* ..., key ==> ...                           */
2716                         {
2717                                 s4 i;
2718                                 lookup_target_t *lookup;
2719
2720                                 lookup = iptr->dst.lookup;
2721
2722                                 i = iptr->sx.s23.s2.lookupcount;
2723                         
2724                                 MCODECHECK(8 + ((7 + 6) * i) + 5);
2725                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2726
2727                                 while (--i >= 0) {
2728                                         if (N_VALID_IMM(lookup->value)) {
2729                                                 M_ICMP_IMM(s1, lookup->value);
2730                                         } else {
2731                                                 ICONST(REG_ITMP2, lookup->value);
2732                                                 M_ICMP(REG_ITMP2, s1);
2733                                         }
2734                                         emit_beq(cd, lookup->target.block);
2735                                         lookup++;
2736                                 }
2737
2738                                 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2739                         }
2740                         break;
2741
2742
2743                 case ICMD_BUILTIN:      /* ..., [arg1, [arg2 ...]] ==> ...            */
2744
2745                         bte = iptr->sx.s23.s3.bte;
2746                         md  = bte->md;
2747                         goto gen_method;
2748
2749                 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ...            */
2750                 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2751                 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer    */
2752                 case ICMD_INVOKEINTERFACE:
2753
2754                         REPLACEMENT_POINT_INVOKE(cd, iptr);
2755
2756                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2757                                 lm = NULL;
2758                                 um = iptr->sx.s23.s3.um;
2759                                 md = um->methodref->parseddesc.md;
2760                         }
2761                         else {
2762                                 lm = iptr->sx.s23.s3.fmiref->p.method;
2763                                 um = NULL;
2764                                 md = lm->parseddesc;
2765                         }
2766
2767 gen_method:
2768                         s3 = md->paramcount;
2769
2770                         MCODECHECK((s3 << 1) + 64);
2771
2772                         /* copy arguments to registers or stack location */
2773
2774                         for (s3 = s3 - 1; s3 >= 0; s3--) {
2775                                 var = VAR(iptr->sx.s23.s2.args[s3]);
2776
2777                                 /* Already Preallocated? */
2778                                 if (var->flags & PREALLOC)
2779                                         continue;
2780
2781                                 if (IS_INT_LNG_TYPE(var->type)) {
2782                                         if (!md->params[s3].inmemory) {
2783                                                 if (IS_2_WORD_TYPE(var->type)) {
2784                                                         s1 = PACK_REGS(
2785                                                                 GET_LOW_REG(md->params[s3].regoff),
2786                                                                 GET_HIGH_REG(md->params[s3].regoff)
2787                                                         );
2788                                                         d = emit_load(jd, iptr, var, s1);
2789                                                         M_LNGMOVE(d, s1);
2790                                                 }
2791                                                 else {
2792                                                         s1 = md->params[s3].regoff;
2793                                                         d = emit_load(jd, iptr, var, s1);
2794                                                         M_INTMOVE(d, s1);
2795                                                 }
2796                                         }
2797                                         else {
2798                                                 if (IS_2_WORD_TYPE(var->type)) {
2799                                                         d = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
2800                                                         M_LST(d, REG_SP, md->params[s3].regoff);
2801                                                 }
2802                                                 else {
2803                                                         d = emit_load(jd, iptr, var, REG_ITMP1);
2804                                                         M_IST(d, REG_SP, md->params[s3].regoff);
2805                                                 }
2806                                         }
2807                                 }
2808                                 else {
2809                                         if (!md->params[s3].inmemory) {
2810                                                 s1 = md->params[s3].regoff;
2811                                                 d = emit_load(jd, iptr, var, s1);
2812                                                 M_FLTMOVE(d, s1);
2813                                         }
2814                                         else {
2815                                                 d = emit_load(jd, iptr, var, REG_FTMP1);
2816                                                 if (IS_2_WORD_TYPE(var->type))
2817                                                         M_DST(d, REG_SP, md->params[s3].regoff);
2818                                                 else
2819                                                         M_FST(d, REG_SP, md->params[s3].regoff);
2820                                         }
2821                                 }
2822                         }
2823
2824                         /* generate method profiling code */
2825
2826                         PROFILE_CYCLE_STOP;
2827
2828                         switch (iptr->opc) {
2829                         case ICMD_BUILTIN:
2830                                 if (bte->stub == NULL) {
2831                                         disp = dseg_add_functionptr(cd, bte->fp);
2832                                         M_ASUB_IMM(96, REG_SP); /* register save area as required by C abi */   
2833                                 } else {
2834                                         disp = dseg_add_functionptr(cd, bte->stub);
2835                                 }
2836
2837                                 if (N_VALID_DSEG_DISP(disp)) {
2838                                         N_L(REG_PV, N_DSEG_DISP(disp), RN, REG_PV);
2839                                 } else {
2840                                         N_LHI(REG_ITMP1, disp);
2841                                         N_L(REG_PV, -N_PV_OFFSET, REG_ITMP1, REG_PV);
2842                                 }
2843                                 break;
2844
2845                         case ICMD_INVOKESPECIAL:
2846                                 /* TODO softnull */
2847                                 /* Implicit NULL pointer check */
2848                                 M_ILD(REG_ITMP1, REG_A0, 0);
2849
2850                                 /* fall through */
2851
2852                         case ICMD_INVOKESTATIC:
2853                                 if (lm == NULL) {
2854                                         disp = dseg_add_unique_address(cd, um);
2855
2856                                         patcher_add_patch_ref(jd, PATCHER_invokestatic_special,
2857                                                                                 um, disp);
2858                                 }
2859                                 else
2860                                         disp = dseg_add_address(cd, lm->stubroutine);
2861
2862                                 if (N_VALID_DSEG_DISP(disp)) {
2863                                         N_L(REG_PV, N_DSEG_DISP(disp), RN, REG_PV);
2864                                 } else {
2865                                         N_LHI(REG_ITMP1, disp);
2866                                         N_L(REG_PV, -N_PV_OFFSET, REG_ITMP1, REG_PV);
2867                                 }
2868                                 break;
2869
2870                         case ICMD_INVOKEVIRTUAL:
2871                                 /* TODO softnull REG_A0 */
2872
2873                                 if (lm == NULL) {
2874                                         patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
2875
2876                                         s1 = 0;
2877                                 }
2878                                 else {
2879                                         s1 = OFFSET(vftbl_t, table[0]) +
2880                                                 sizeof(methodptr) * lm->vftblindex;
2881                                 }
2882
2883                                 /* implicit null-pointer check */
2884
2885                                 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2886                                 M_ALD(REG_PV, REG_METHODPTR, s1);
2887                                 break;
2888
2889                         case ICMD_INVOKEINTERFACE:
2890                                 /* TODO softnull REG_A0 */
2891
2892                                 /* s1 will be negative here, so use (0xFFF + s1) as displacement
2893                                  * and -0xFFF in index register (itmp1)
2894                                  */
2895
2896                                 if (lm == NULL) {
2897                                         patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
2898
2899                                         s1 = 0;
2900                                         s2 = 0;
2901                                 }
2902                                 else {
2903                                         s1 = OFFSET(vftbl_t, interfacetable[0]) -
2904                                                 sizeof(methodptr*) * lm->clazz->index;
2905
2906                                         s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
2907                                 }
2908
2909                                 /* Implicit null-pointer check */
2910                                 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2911                                 N_LHI(REG_ITMP2, s1);
2912                                 N_L(REG_METHODPTR, 0, REG_ITMP2, REG_METHODPTR);
2913                                 M_ALD(REG_PV, REG_METHODPTR, s2);
2914                                 break;
2915                         }
2916
2917                         /* generate the actual call */
2918
2919                         M_CALL(REG_PV);
2920                         emit_restore_pv(cd);
2921
2922                         /* post call finalization */
2923
2924                         switch (iptr->opc) {
2925                                 case ICMD_BUILTIN:
2926                                         if (bte->stub == NULL) {
2927                                                 M_AADD_IMM(96, REG_SP); /* remove C abi register save area */
2928                                         }
2929                                         break;
2930                         }
2931
2932                         /* generate method profiling code */
2933
2934                         PROFILE_CYCLE_START;
2935
2936                         /* store size of call code in replacement point */
2937
2938                         REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2939         
2940                         /* store return value */
2941
2942                         d = md->returntype.type;
2943
2944                         if (d != TYPE_VOID) {
2945                                 if (IS_INT_LNG_TYPE(d)) {
2946                                         if (IS_2_WORD_TYPE(d)) {
2947                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
2948                                                 M_LNGMOVE(REG_RESULT_PACKED, s1);
2949                                         }
2950                                         else {
2951                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2952                                                 M_INTMOVE(REG_RESULT, s1);
2953                                         }
2954                                 }
2955                                 else {
2956                                         s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2957                                         M_FLTMOVE(REG_FRESULT, s1);
2958                                 }
2959                                 emit_store_dst(jd, iptr, s1);
2960                         }
2961
2962                         break;
2963
2964
2965                 case ICMD_CHECKCAST:  /* ..., objectref ==> ..., objectref            */
2966
2967                                       /* val.a: (classinfo*) superclass               */
2968
2969                         /*  superclass is an interface:
2970                          *      
2971                          *  OK if ((sub == NULL) ||
2972                          *         (sub->vftbl->interfacetablelength > super->index) &&
2973                          *         (sub->vftbl->interfacetable[-super->index] != NULL));
2974                          *      
2975                          *  superclass is a class:
2976                          *      
2977                          *  OK if ((sub == NULL) || (0
2978                          *         <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2979                          *         super->vftbl->diffval));
2980                          */
2981
2982                         if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2983                                 /* object type cast-check */
2984
2985                                 classinfo *super;
2986                                 vftbl_t   *supervftbl;
2987                                 s4         superindex;
2988
2989 #                               define LABEL_EXIT_CHECK_NULL BRANCH_LABEL_1
2990 #                               define LABEL_CLASS BRANCH_LABEL_2
2991 #                               define LABEL_EXIT_INTERFACE_NULL BRANCH_LABEL_3
2992 #                               define LABEL_EXIT_INTERFACE_DONE BRANCH_LABEL_4
2993 #                               define LABEL_EXIT_CLASS_NULL BRANCH_LABEL_5
2994
2995                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2996                                         super = NULL;
2997                                         superindex = 0;
2998                                         supervftbl = NULL;
2999                                 }
3000                                 else {
3001                                         super = iptr->sx.s23.s3.c.cls;
3002                                         superindex = super->index;
3003                                         supervftbl = super->vftbl;
3004                                 }
3005
3006                                 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
3007                                         CODEGEN_CRITICAL_SECTION_NEW;
3008
3009                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3010
3011                                 /* if class is not resolved, check which code to call */
3012
3013                                 if (super == NULL) {
3014                                         M_TEST(s1);
3015                                         emit_label_beq(cd, LABEL_EXIT_CHECK_NULL);
3016
3017                                         disp = dseg_add_unique_s4(cd, 0);         /* super->flags */
3018
3019                                         patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
3020                                                                                   iptr->sx.s23.s3.c.ref,
3021                                                                                   disp);
3022
3023                                         ICONST(REG_ITMP3, ACC_INTERFACE);
3024
3025                                         if (N_VALID_DSEG_DISP(disp)) {
3026                                                 N_N(REG_ITMP3, N_DSEG_DISP(disp), RN, REG_PV);
3027                                         } else {
3028                                                 ICONST(REG_ITMP2, disp);
3029                                                 N_N(REG_ITMP3, -N_PV_OFFSET, REG_ITMP2, REG_PV);
3030                                         }
3031                                         emit_label_beq(cd, LABEL_CLASS);
3032                                 }
3033
3034                                 /* interface checkcast code */
3035
3036                                 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3037                                         if (super == NULL) {
3038                                                 patcher_add_patch_ref(jd,
3039                                                                                           PATCHER_checkcast_instanceof_interface,
3040                                                                                           iptr->sx.s23.s3.c.ref,
3041                                                                                           0);
3042                                         } else {
3043                                                 M_TEST(s1);
3044                                                 emit_label_beq(cd, LABEL_EXIT_INTERFACE_NULL);
3045                                         }
3046
3047                                         M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
3048                                         M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
3049                                         M_ISUB_IMM(superindex, REG_ITMP3);
3050                                         emit_classcast_check(cd, iptr, BRANCH_LE, RN, s1);
3051                                         N_AHI(
3052                                                 REG_ITMP2,
3053                                                 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
3054                                                         superindex * sizeof(methodptr*))
3055                                         );
3056                                         M_ALD(REG_ITMP2, REG_ITMP2, 0);
3057                                         emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP2, s1);
3058
3059                                         if (super == NULL) {
3060                                                 emit_label_br(cd, LABEL_EXIT_INTERFACE_DONE);
3061                                         }
3062                                 }
3063
3064                                 /* class checkcast code */
3065                                 
3066                                 if (super == NULL) {
3067                                         emit_label(cd, LABEL_CLASS);
3068                                 }
3069
3070                                 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3071                                         if (super == NULL) {
3072                                                 disp = dseg_add_unique_address(cd, NULL);
3073
3074                                                 patcher_add_patch_ref(jd,
3075                                                                                           PATCHER_resolve_classref_to_vftbl,
3076                                                                                           iptr->sx.s23.s3.c.ref,
3077                                                                                           disp);
3078                                         }
3079                                         else {
3080                                                 disp = dseg_add_address(cd, supervftbl);
3081                                                 M_TEST(s1);
3082                                                 emit_label_beq(cd, LABEL_EXIT_CLASS_NULL);
3083                                         }
3084
3085 #if 1
3086                                         CODEGEN_CRITICAL_SECTION_START;
3087
3088                                         /* REG_ITMP3 := baseval(s1) */
3089                                         M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
3090                                         M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3091
3092                                         /* REG_ITMP2 := baseval(class) */
3093                                         M_ALD_DSEG(REG_ITMP2, disp);
3094                                         M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3095
3096                                         /* REG_ITMP3 := REG_ITMP3 - REG_ITMP2 */
3097                                         M_ISUB(REG_ITMP2, REG_ITMP3);
3098
3099                                         /* REG_ITMP2 := diffval(class) */
3100                                         M_ALD_DSEG(REG_ITMP2, disp);
3101                                         M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3102
3103                                         CODEGEN_CRITICAL_SECTION_END;
3104
3105                                         M_CMPU(REG_ITMP3, REG_ITMP2); /* Unsigned compare */
3106
3107                                         /* M_CMPULE(REG_ITMP2, REG_ITMP3, REG_ITMP3); itmp3 = (itmp2 <= itmp3) */
3108                                         /* M_BEQZ(REG_ITMP3, 0); branch if (! itmp) -> branch if > */
3109                                         /* Branch if greater then */
3110 #else
3111                                         M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
3112                                         M_ALD_DSEG(REG_ITMP3, disp);
3113
3114                                         CODEGEN_CRITICAL_SECTION_START;
3115
3116                                         M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3117                                         M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3118                                         M_ISUB(REG_ITMP3, REG_ITMP2);
3119                                         M_ALD_DSEG(REG_ITMP3, disp);
3120                                         M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3121
3122                                         CODEGEN_CRITICAL_SECTION_END;
3123                                         
3124                                         M_CMPU(REG_ITMP2, REG_ITMP3); /* Unsigned compare */
3125                                         /* M_CMPULE(REG_ITMP2, REG_ITMP3, REG_ITMP3); itmp3 = (itmp2 <= itmp3) */
3126                                         /* M_BEQZ(REG_ITMP3, 0); branch if (! itmp) -> branch if > */
3127                                         /* Branch if greater then */
3128 #endif
3129                                         emit_classcast_check(cd, iptr, BRANCH_GT, RN, s1);
3130                                 }
3131
3132                                 if (super == NULL) {
3133                                         emit_label(cd, LABEL_EXIT_CHECK_NULL);
3134                                         emit_label(cd, LABEL_EXIT_INTERFACE_DONE);
3135                                 } else if (super->flags & ACC_INTERFACE) {
3136                                         emit_label(cd, LABEL_EXIT_INTERFACE_NULL);
3137                                 } else {
3138                                         emit_label(cd, LABEL_EXIT_CLASS_NULL);
3139                                 }
3140
3141                                 d = codegen_reg_of_dst(jd, iptr, s1);
3142
3143 #                               undef LABEL_EXIT_CHECK_NULL
3144 #                               undef LABEL_CLASS
3145 #                               undef LABEL_EXIT_INTERFACE_NULL
3146 #                               undef LABEL_EXIT_INTERFACE_DONE
3147 #                               undef LABEL_EXIT_CLASS_NULL
3148                         }
3149                         else {
3150                                 /* array type cast-check */
3151
3152                                 s1 = emit_load_s1(jd, iptr, REG_A0);
3153                                 M_INTMOVE(s1, REG_A0);
3154
3155                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3156                                         disp = dseg_add_unique_address(cd, NULL);
3157
3158                                         patcher_add_patch_ref(jd,
3159                                                                                   PATCHER_resolve_classref_to_classinfo,
3160                                                                                   iptr->sx.s23.s3.c.ref,
3161                                                                                   disp);
3162                                 }
3163                                 else
3164                                         disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3165
3166                                 M_ALD_DSEG(REG_A1, disp);
3167                                 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
3168                                 M_ALD_DSEG(REG_ITMP1, disp);
3169                                 M_ASUB_IMM(96, REG_SP);
3170                                 M_JSR(REG_RA, REG_ITMP1);
3171                                 M_AADD_IMM(96, REG_SP);
3172
3173                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3174                                 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
3175
3176                                 d = codegen_reg_of_dst(jd, iptr, s1);
3177                         }
3178
3179                         M_INTMOVE(s1, d);
3180                         emit_store_dst(jd, iptr, d);
3181                         break;
3182
3183                 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
3184                                       /* val.a: (classinfo*) superclass               */
3185
3186                         /*  superclass is an interface:
3187                          *      
3188                          *  return (sub != NULL) &&
3189                          *         (sub->vftbl->interfacetablelength > super->index) &&
3190                          *         (sub->vftbl->interfacetable[-super->index] != NULL);
3191                          *      
3192                          *  superclass is a class:
3193                          *      
3194                          *  return ((sub != NULL) && (0
3195                          *          <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3196                          *          super->vftbl->diffvall));
3197                          *
3198                          *  If superclass is unresolved, we include both code snippets 
3199                          *  above, a patcher resolves the class' flags and we select
3200                          *  the right code at runtime.
3201                          */
3202
3203                         {
3204                         classinfo *super;
3205                         vftbl_t   *supervftbl;
3206                         s4         superindex;
3207
3208                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3209                                 super = NULL;
3210                                 superindex = 0;
3211                                 supervftbl = NULL;
3212
3213                         } else {
3214                                 super = iptr->sx.s23.s3.c.cls;
3215                                 superindex = super->index;
3216                                 supervftbl = super->vftbl;
3217                         }
3218
3219 #                       define LABEL_EXIT_CHECK_NULL BRANCH_LABEL_1
3220 #                       define LABEL_CLASS BRANCH_LABEL_2
3221 #                       define LABEL_EXIT_INTERFACE_NULL BRANCH_LABEL_3
3222 #                       define LABEL_EXIT_INTERFACE_INDEX_NOT_IN_TABLE BRANCH_LABEL_4
3223 #                       define LABEL_EXIT_INTERFACE_DONE BRANCH_LABEL_5
3224 #                       define LABEL_EXIT_CLASS_NULL BRANCH_LABEL_6
3225
3226                         if ((super == NULL) || !(super->flags & ACC_INTERFACE))
3227                                 CODEGEN_CRITICAL_SECTION_NEW;
3228
3229                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3230                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3231                         if (s1 == d) {
3232                                 M_MOV(s1, REG_ITMP1);
3233                                 s1 = REG_ITMP1;
3234                         }
3235
3236                         /* if class is not resolved, check which code to call */
3237
3238                         if (super == NULL) {
3239                                 M_CLR(d);
3240                                 
3241                                 M_TEST(s1);
3242                                 emit_label_beq(cd, LABEL_EXIT_CHECK_NULL);
3243
3244                                 disp = dseg_add_unique_s4(cd, 0);             /* super->flags */
3245
3246                                 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
3247                                                                           iptr->sx.s23.s3.c.ref, disp);
3248
3249                                 ICONST(REG_ITMP3, ACC_INTERFACE);
3250
3251                                 if (N_VALID_DSEG_DISP(disp)) {
3252                                         N_N(REG_ITMP3, N_DSEG_DISP(disp), RN, REG_PV);
3253                                 } else {
3254                                         ICONST(REG_ITMP2, disp);
3255                                         N_N(REG_ITMP3, -N_PV_OFFSET, REG_ITMP2, REG_PV);
3256                                 }
3257
3258                                 emit_label_beq(cd, LABEL_CLASS);
3259                         }
3260
3261                         /* interface instanceof code */
3262
3263                         if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3264                                 if (super == NULL) {
3265                                         /* If d == REG_ITMP2, then it's destroyed in check
3266                                            code above. */
3267                                         if (d == REG_ITMP2)
3268                                                 M_CLR(d);
3269
3270                                         patcher_add_patch_ref(jd,
3271                                                                                   PATCHER_checkcast_instanceof_interface,
3272                                                                                   iptr->sx.s23.s3.c.ref, 0);
3273                                 }
3274                                 else {
3275                                         M_CLR(d);
3276                                         M_TEST(s1);
3277                                         emit_label_beq(cd, LABEL_EXIT_INTERFACE_NULL);
3278                                 }
3279
3280                                 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
3281                                 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3282                                 M_ISUB_IMM(superindex, REG_ITMP3);
3283
3284                                 emit_label_ble(cd, LABEL_EXIT_INTERFACE_INDEX_NOT_IN_TABLE);
3285
3286                                 N_AHI(
3287                                         REG_ITMP1,
3288                                         (s4) (OFFSET(vftbl_t, interfacetable[0]) -
3289                                                 superindex * sizeof(methodptr*))
3290                                 );
3291                                 M_ALD(REG_ITMP1, REG_ITMP1, 0);
3292                                 
3293                                 /* d := (REG_ITMP1 != 0)  */
3294
3295                                 N_LTR(d, REG_ITMP1);
3296                                 M_BEQ(SZ_BRC + SZ_LHI);
3297                                 N_LHI(d, 1);
3298
3299                                 if (super == NULL) {
3300                                         emit_label_br(cd, LABEL_EXIT_INTERFACE_DONE);
3301                                 }
3302                         }
3303
3304                         /* class instanceof code */
3305
3306                         if (super == NULL) {
3307                                 emit_label(cd, LABEL_CLASS);
3308                         }
3309
3310                         if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3311                                 if (super == NULL) {
3312                                         disp = dseg_add_unique_address(cd, NULL);
3313
3314                                         patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl,
3315                                                                                   iptr->sx.s23.s3.c.ref,
3316                                                                                   disp);
3317                                 }
3318                                 else {
3319                                         disp = dseg_add_address(cd, supervftbl);
3320
3321                                         M_CLR(d);
3322
3323                                         M_TEST(s1);
3324                                         emit_label_beq(cd, LABEL_EXIT_CLASS_NULL);
3325                                 }
3326
3327                                 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
3328                                 M_ALD_DSEG(REG_ITMP2, disp);
3329
3330                                 CODEGEN_CRITICAL_SECTION_START;
3331
3332                                 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3333                                 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3334                                 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3335
3336                                 CODEGEN_CRITICAL_SECTION_END;
3337
3338                                 M_ISUB(REG_ITMP3, REG_ITMP1); /* itmp1 :=  itmp1 (sub.baseval) - itmp3 (super.baseval) */
3339
3340                                 M_CMPU(REG_ITMP1, REG_ITMP2); /* d := (uint)REG_ITMP1 <= (uint)REG_ITMP2 */
3341                                 N_LHI(d, 0);
3342                                 M_BGT(SZ_BRC + SZ_LHI);
3343                                 N_LHI(d, 1);
3344                         }
3345
3346                         if (super == NULL) {
3347                                 emit_label(cd, LABEL_EXIT_CHECK_NULL);
3348                                 emit_label(cd, LABEL_EXIT_INTERFACE_DONE);
3349                                 emit_label(cd, LABEL_EXIT_INTERFACE_INDEX_NOT_IN_TABLE);
3350                         } else if (super->flags & ACC_INTERFACE) {
3351                                 emit_label(cd, LABEL_EXIT_INTERFACE_NULL);
3352                                 emit_label(cd, LABEL_EXIT_INTERFACE_INDEX_NOT_IN_TABLE);
3353                         } else {
3354                                 emit_label(cd, LABEL_EXIT_CLASS_NULL);
3355                         }
3356
3357 #                       undef LABEL_EXIT_CHECK_NULL
3358 #                       undef LABEL_CLASS
3359 #                       undef LABEL_EXIT_INTERFACE_NULL
3360 #                       undef LABEL_EXIT_INTERFACE_INDEX_NOT_IN_TABLE
3361 #                       undef LABEL_EXIT_INTERFACE_DONE
3362 #                       undef LABEL_EXIT_CLASS_NULL
3363                                 
3364                         emit_store_dst(jd, iptr, d);
3365
3366                         }
3367
3368                         break;
3369
3370                 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref  */
3371
3372                         /* check for negative sizes and copy sizes to stack if necessary  */
3373
3374                         /*MCODECHECK((10 * 4 * iptr->s1.argcount) + 5 + 10 * 8);*/
3375                         MCODECHECK(512);
3376
3377                         for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3378
3379                                 /* copy SAVEDVAR sizes to stack */
3380                                 var = VAR(iptr->sx.s23.s2.args[s1]);
3381
3382                                 /* Already Preallocated? */
3383                                 if (!(var->flags & PREALLOC)) {
3384                                         s2 = emit_load(jd, iptr, var, REG_ITMP1);
3385                                         M_IST(s2, REG_SP, s1 * 4);
3386                                 }
3387                         }
3388
3389                         /* is a patcher function set? */
3390
3391                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3392                                 disp = dseg_add_unique_address(cd, 0);
3393
3394                                 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
3395                                                                           iptr->sx.s23.s3.c.ref,
3396                                                                           disp);
3397                         }
3398                         else
3399                                 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3400
3401                         /* a0 = dimension count */
3402
3403                         ICONST(REG_A0, iptr->s1.argcount);
3404
3405                         /* a1 = classinfo */
3406
3407                         M_ALD_DSEG(REG_A1, disp);
3408
3409                         /* a2 = pointer to dimensions = stack pointer */
3410
3411                         M_MOV(REG_SP, REG_A2);
3412
3413                         disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3414                         M_ALD_DSEG(REG_ITMP1, disp);
3415                         M_ASUB_IMM(96, REG_SP);
3416                         M_JSR(REG_RA, REG_ITMP1);
3417                         M_AADD_IMM(96, REG_SP);
3418
3419                         /* check for exception before result assignment */
3420
3421                         emit_exception_check(cd, iptr);
3422
3423                         s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3424                         M_INTMOVE(REG_RESULT, s1);
3425                         emit_store_dst(jd, iptr, s1);
3426
3427                         break;
3428
3429                 default:
3430                         exceptions_throw_internalerror("Unknown ICMD %d", iptr->opc);
3431                         return false;
3432         } /* switch */
3433
3434         } /* for instruction */
3435                 
3436         MCODECHECK(512); /* XXX require a lower number? */
3437
3438         /* At the end of a basic block we may have to append some nops,
3439            because the patcher stub calling code might be longer than the
3440            actual instruction. So codepatching does not change the
3441            following block unintentionally. */
3442
3443         if (cd->mcodeptr < cd->lastmcodeptr) {
3444                 while (cd->mcodeptr < cd->lastmcodeptr) {
3445                         M_NOP;
3446                 }
3447         }
3448
3449         } /* if (bptr -> flags >= BBREACHED) */
3450         } /* for basic block */
3451
3452         /* generate stubs */
3453
3454         emit_patcher_traps(jd);
3455
3456         /* everything's ok */
3457
3458         return true;
3459 }
3460
3461 /* codegen_emit_stub_native ****************************************************
3462
3463    Emits a stub routine which calls a native method.
3464
3465 *******************************************************************************/
3466
3467 /*
3468            arguments on stack                   \
3469 -------------------------------------------------| <- SP on nativestub entry
3470            return address                        |
3471            callee saved int regs (none)          |
3472            callee saved float regs (none)        | stack frame like in cacao
3473            local variable slots (none)           |
3474            arguments for calling methods (none) /
3475 ------------------------------------------------------------------ <- datasp 
3476            stackframe info
3477            locaref table
3478            integer arguments
3479            float arguments
3480 96 - ...   on stack parameters (nmd->memuse slots) \ stack frame like in ABI         
3481 0 - 96     register save area for callee           /
3482 -------------------------------------------------------- <- SP native method
3483                                                             ==
3484                                                             SP after method entry
3485 */
3486
3487 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
3488 {
3489         methodinfo  *m;
3490         codeinfo    *code;
3491         codegendata *cd;
3492         methoddesc  *md;
3493         int          i, j;
3494         int          t;
3495         int          s1, s2;
3496         int          disp;
3497
3498         /* get required compiler data */
3499
3500         m    = jd->m;
3501         code = jd->code;
3502         cd   = jd->cd;
3503
3504         /* set some variables */
3505
3506         md = m->parseddesc;
3507
3508         /* calculate stackframe size */
3509
3510         cd->stackframesize =
3511                 1 + /* return address */
3512                 sizeof(stackframeinfo_t) / 8 +
3513                 sizeof(localref_table) / 8 +
3514                 nmd->paramcount +
3515                 nmd->memuse +
3516                 (96 / 8); /* linkage area */
3517
3518         /* keep stack 8-byte aligned */
3519
3520         /*ALIGN_2(cd->stackframesize);*/
3521
3522         /* create method header */
3523
3524         (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
3525         (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize       */
3526         (void) dseg_add_unique_s4(cd, 0);                      /* IsLeaf          */
3527         (void) dseg_add_unique_s4(cd, 0);                      /* IntSave         */
3528         (void) dseg_add_unique_s4(cd, 0);                      /* FltSave         */
3529
3530         /* generate code */
3531
3532         M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
3533         M_AADD_IMM(N_PV_OFFSET, REG_PV);
3534
3535         /* store return address */
3536
3537         M_AST(REG_RA, REG_SP, (cd->stackframesize - 1) * 8);
3538
3539 #if defined(ENABLE_GC_CACAO)
3540         /* Save callee saved integer registers in stackframeinfo (GC may
3541            need to recover them during a collection). */
3542
3543         disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
3544                 OFFSET(stackframeinfo_t, intregs);
3545
3546         for (i = 0; i < INT_SAV_CNT; i++)
3547                 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 4);
3548 #endif
3549
3550         /* save integer and float argument registers */
3551
3552         for (i = 0; i < md->paramcount; i++) {
3553                 if (!md->params[i].inmemory) {
3554                         s1 = md->params[i].regoff;
3555
3556                         switch (md->paramtypes[i].type) {
3557                         case TYPE_INT:
3558                         case TYPE_ADR:
3559                                 M_IST(s1, REG_SP, 96 + i * 8);
3560                                 break;
3561                         case TYPE_LNG:
3562                                 M_LST(s1, REG_SP, 96 + i * 8);
3563                                 break;
3564                         case TYPE_FLT:
3565                         case TYPE_DBL:
3566                                 M_DST(s1, REG_SP, 96 + i * 8);
3567                                 break;
3568                         }
3569                 }
3570         }
3571
3572         /* create native stack info */
3573
3574         M_MOV(REG_SP, REG_A0);
3575         M_LDA(REG_A1, REG_PV, -N_PV_OFFSET);
3576         disp = dseg_add_functionptr(cd, codegen_start_native_call);
3577         M_ALD_DSEG(REG_ITMP2, disp);
3578         M_CALL(REG_ITMP2);
3579
3580         /* remember class argument */
3581
3582         if (m->flags & ACC_STATIC)
3583                 M_MOV(REG_RESULT, REG_ITMP3);
3584
3585         /* restore integer and float argument registers */
3586
3587         for (i = 0; i < md->paramcount; i++) {
3588                 if (!md->params[i].inmemory) {
3589                         s1 = md->params[i].regoff;
3590
3591                         switch (md->paramtypes[i].type) {
3592                         case TYPE_INT:
3593                         case TYPE_ADR:
3594                                 M_ILD(s1, REG_SP, 96 + i * 8);
3595                                 break;
3596                         case TYPE_LNG:
3597                                 M_LLD(s1, REG_SP, 96 + i * 8);
3598                                 break;
3599                         case TYPE_FLT:
3600                         case TYPE_DBL:
3601                                 M_DLD(s1, REG_SP, 96 + i * 8);
3602                                 break;
3603                         }
3604                 }
3605         }
3606
3607         /* copy or spill arguments to new locations */
3608
3609         for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
3610                 t = md->paramtypes[i].type;
3611
3612                 if (IS_INT_LNG_TYPE(t)) {
3613                         if (!md->params[i].inmemory) {
3614                                 s1 = md->params[i].regoff;
3615                                 s2 = nmd->params[j].regoff;
3616
3617                                 if (!nmd->params[j].inmemory) {
3618                                         if (IS_2_WORD_TYPE(t))
3619                                                 M_LNGMOVE(s1, s2);
3620                                         else
3621                                                 M_INTMOVE(s1, s2);
3622                                 }
3623                                 else {
3624                                         if (IS_2_WORD_TYPE(t))
3625                                                 M_LST(s1, REG_SP, s2);
3626                                         else
3627                                                 M_IST(s1, REG_SP, s2);
3628                                 }
3629                         }
3630                         else {
3631                                 s1 = md->params[i].regoff + cd->stackframesize * 8;
3632                                 s2 = nmd->params[j].regoff;
3633
3634                                 if (IS_2_WORD_TYPE(t)) {
3635                                         N_MVC(s2, 8, REG_SP, s1, REG_SP);
3636                                 } else {
3637                                         N_MVC(s2, 4, REG_SP, s1, REG_SP);
3638                                 }
3639                         }
3640                 }
3641                 else {
3642                         /* We only copy spilled float arguments, as the float
3643                            argument registers keep unchanged. */
3644
3645                         if (md->params[i].inmemory) {
3646                                 s1 = md->params[i].regoff + cd->stackframesize * 8;
3647                                 s2 = nmd->params[j].regoff;
3648
3649                                 if (IS_2_WORD_TYPE(t)) {
3650                                         N_MVC(s2, 8, REG_SP, s1, REG_SP);
3651                                 } else {
3652                                         N_MVC(s2, 4, REG_SP, s1, REG_SP);
3653                                 }
3654                         }
3655                 }
3656         }
3657
3658         /* Handle native Java methods. */
3659
3660         if (m->flags & ACC_NATIVE) {
3661                 /* put class into second argument register */
3662
3663                 if (m->flags & ACC_STATIC)
3664                         M_MOV(REG_ITMP3, REG_A1);
3665
3666                 /* put env into first argument register */
3667
3668                 disp = dseg_add_address(cd, _Jv_env);
3669                 M_ALD_DSEG(REG_A0, disp);
3670         }
3671
3672         /* Call native function. */
3673
3674         disp = dseg_add_functionptr(cd, f);
3675         M_ALD_DSEG(REG_ITMP2, disp);
3676         M_CALL(REG_ITMP2);
3677
3678         /* save return value */
3679
3680         switch (md->returntype.type) {
3681         case TYPE_INT:
3682         case TYPE_ADR:
3683                 M_IST(REG_RESULT, REG_SP, 96);
3684                 break;
3685         case TYPE_LNG:
3686                 M_LST(REG_RESULT_PACKED, REG_SP, 96);
3687                 break;
3688         case TYPE_FLT:
3689         case TYPE_DBL:
3690                 M_DST(REG_FRESULT, REG_SP, 96);
3691                 break;
3692         case TYPE_VOID:
3693                 break;
3694         }
3695
3696         /* remove native stackframe info */
3697
3698         M_MOV(REG_SP, REG_A0);
3699         M_LDA(REG_A1, REG_PV, -N_PV_OFFSET);
3700         disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3701         M_ALD_DSEG(REG_ITMP1, disp);
3702         M_CALL(REG_ITMP1);
3703
3704         M_MOV(REG_RESULT, REG_ITMP3_XPTR);
3705
3706         /* restore return value */
3707
3708         switch (md->returntype.type) {
3709         case TYPE_INT:
3710         case TYPE_ADR:
3711                 M_ILD(REG_RESULT, REG_SP, 96);
3712                 break;
3713         case TYPE_LNG:
3714                 M_LLD(REG_RESULT_PACKED, REG_SP, 96);
3715                 break;
3716         case TYPE_FLT:
3717         case TYPE_DBL:
3718                 M_DLD(REG_FRESULT, REG_SP, 96);
3719                 break;
3720         case TYPE_VOID:
3721                 break;
3722         }
3723
3724 #if defined(ENABLE_GC_CACAO)
3725         /* Restore callee saved integer registers from stackframeinfo (GC
3726            might have modified them during a collection). */
3727          
3728         disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
3729                 OFFSET(stackframeinfo_t, intregs);
3730
3731         for (i = 0; i < INT_SAV_CNT; i++)
3732                 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 4);
3733 #endif
3734
3735         /* load return address */
3736
3737         M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8);
3738
3739         /* remove stackframe       */
3740
3741         M_AADD_IMM(cd->stackframesize * 8, REG_SP);
3742
3743         /* check for exception */
3744
3745         M_TEST(REG_ITMP3_XPTR);
3746         M_BNE(SZ_BRC + SZ_BCR);                     /* if no exception then return        */
3747
3748         M_RET;
3749
3750         /* handle exception */
3751
3752         M_MOV(REG_RA, REG_ITMP1_XPC);
3753         M_ASUB_IMM(2, REG_ITMP1_XPC);
3754
3755         disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3756         M_ALD_DSEG(REG_ITMP2, disp);
3757         M_JMP(RN, REG_ITMP2);
3758 }
3759
3760 /*
3761  * These are local overrides for various environment variables in Emacs.
3762  * Please do not remove this and leave it at the end of the file, where
3763  * Emacs will automagically detect them.
3764  * ---------------------------------------------------------------------
3765  * Local variables:
3766  * mode: c
3767  * indent-tabs-mode: t
3768  * c-basic-offset: 4
3769  * tab-width: 4
3770  * End:
3771  * vim:noexpandtab:sw=4:ts=4:
3772  */