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