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