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