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