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