31cba6edb0681137f9f5117932b9deb4986e0c7f
[cacao.git] / src / vm / jit / sparc64 / codegen.c
1 /* src/vm/jit/sparc64/codegen.c - machine code generator for Sparc
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    $Id: codegen.c 4644 2006-03-16 18:44:46Z edwin $
26
27 */
28
29
30 #include "config.h"
31
32 #include <assert.h>
33 #include <stdio.h>
34
35 #include "vm/types.h"
36
37 #include "md-abi.h"
38
39 /* #include "vm/jit/sparc64/arch.h" */
40 #include "vm/jit/sparc64/codegen.h"
41
42 #include "mm/memory.h"
43
44 #include "native/jni.h"
45 #include "native/native.h"
46 #include "vm/builtin.h"
47 #include "vm/exceptions.h"
48 #include "vm/global.h"
49
50 #include "vm/jit/abi.h"
51 #include "vm/jit/asmpart.h"
52 #include "vm/jit/codegen-common.h"
53 #include "vm/jit/dseg.h"
54 #include "vm/jit/emit-common.h"
55 #include "vm/jit/sparc64/emit.h"
56 #include "vm/jit/jit.h"
57 #include "vm/jit/parse.h"
58 #include "vm/jit/patcher.h"
59 #include "vm/jit/reg.h"
60 #include "vm/jit/replace.h"
61 #include "vm/jit/stacktrace.h"
62 #include "vmcore/loader.h"
63 #include "vmcore/options.h"
64
65 /* XXX use something like this for window control ? 
66  * #define REG_PV (own_window?REG_PV_CALLEE:REG_PV_CALLER)
67  */
68 #define REG_PV REG_PV_CALLEE
69
70 bool fits_13(s4 disp)
71 {
72         /*
73         if ((disp < -4096) || (disp > 4095))
74                 printf("disp %d\n", disp);
75         */
76
77         return (disp >= -4096) && (disp <= 4095);
78 }
79
80 s4 get_lopart_disp(disp)
81 {
82         s4 lodisp;
83         
84         if (disp > 0)
85                 lodisp = setlo_part(disp);
86         else {
87                 if (setlo_part(disp) == 0)
88                         lodisp = 0;
89                 else
90                         lodisp = setlo_part(disp) | 0x1c00;
91         }
92                 
93         return lodisp;
94 }
95         
96
97 /* codegen_emit ****************************************************************
98
99    Generates machine code.
100
101 *******************************************************************************/
102
103 bool codegen_emit(jitdata *jd)
104 {
105         methodinfo         *m;
106         codeinfo           *code;
107         codegendata        *cd;
108         registerdata       *rd;
109         s4                  len, s1, s2, s3, d, disp;
110         varinfo            *var;
111         basicblock         *bptr;
112         instruction        *iptr;
113         exception_entry    *ex;
114         u2                  currentline;
115         constant_classref  *cr;
116         methodinfo         *lm;             /* local methodinfo for ICMD_INVOKE*  */
117         unresolved_method  *um;
118         builtintable_entry *bte;
119         methoddesc         *md;
120         fieldinfo          *fi;
121         unresolved_field   *uf;
122         s4                  fieldtype;
123         s4                  varindex;
124
125         /* get required compiler data */
126
127         m  = jd->m;
128         code = jd->code;
129         cd = jd->cd;
130         rd = jd->rd;
131         
132         /* prevent compiler warnings */
133
134         d = 0;
135         currentline = 0;
136         lm = NULL;
137         bte = NULL;
138
139         {
140         s4 i, p, t, l;
141         s4 savedregs_num, localbase;
142
143 #if 0 /* no leaf optimization yet */
144         savedregs_num = (jd->isleafmethod) ? 0 : 1;       /* space to save the RA */
145 #endif
146         savedregs_num = WINSAVE_CNT + ABIPARAMS_CNT; /* register-window save area */ 
147
148
149         /* space to save used callee saved registers */
150
151         savedregs_num += (INT_SAV_CNT - rd->savintreguse);
152         savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
153
154         cd->stackframesize = rd->memuse + savedregs_num;
155
156 #if defined(ENABLE_THREADS)        /* space to save argument of monitor_enter */
157         if (checksync && (m->flags & ACC_SYNCHRONIZED))
158                 cd->stackframesize++;
159 #endif
160
161         /* keep stack 16-byte aligned (ABI requirement) */
162
163         if (cd->stackframesize & 1)
164                 cd->stackframesize++;
165
166         /* create method header */
167
168         (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
169         (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize       */
170
171 #if defined(ENABLE_THREADS)
172         /* IsSync contains the offset relative to the stack pointer for the
173            argument of monitor_exit used in the exception handler. Since the
174            offset could be zero and give a wrong meaning of the flag it is
175            offset by one.
176         */
177
178         if (checksync && (m->flags & ACC_SYNCHRONIZED))
179                 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync        */
180         else
181 #endif
182                 (void) dseg_add_unique_s4(cd, 0);                  /* IsSync          */
183                                                
184         (void) dseg_add_unique_s4(cd, jd->isleafmethod);       /* IsLeaf          */
185         (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
186         (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
187         dseg_addlinenumbertablesize(cd);
188         (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize   */
189
190         /* create exception table */
191
192         for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
193                 dseg_add_target(cd, ex->start);
194                 dseg_add_target(cd, ex->end);
195                 dseg_add_target(cd, ex->handler);
196                 (void) dseg_add_unique_address(cd, ex->catchtype.any);
197         }
198
199         /* save register window and create stack frame (if necessary) */
200
201         if (cd->stackframesize)
202                 M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP);
203
204
205         /* save callee saved float registers (none right now) */
206 #if 0
207         p = cd->stackframesize;
208         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
209                 p--; M_DST(rd->savfltregs[i], REG_SP, USESTACK + (p * 8));
210         }
211 #endif
212
213 #if !defined(NDEBUG)
214         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
215                 emit_verbosecall_enter(jd);
216 #endif
217         
218         
219         
220         /* take arguments out of register or stack frame */
221         
222         md = m->parseddesc;
223
224         /* when storing locals, use this as base */
225         localbase = JITSTACK;
226         
227         /* since the register allocator does not know about the shifting window
228          * arg regs need to be copied via the stack
229          */
230         if (md->argintreguse > 0) {
231                 /* allocate scratch space for copying in to save(i&l) regs */
232                 M_SUB_IMM(REG_SP, INT_ARG_CNT * 8, REG_SP);
233                 
234                 localbase += INT_ARG_CNT * 8;
235                 
236                 /* XXX could use the param slots on the stack for this! */
237                 for (p = 0; p < INT_ARG_CNT; p++)
238                         M_STX(REG_WINDOW_TRANSPOSE(abi_registers_integer_argument[p]), REG_SP, JITSTACK + (p * 8));
239         }
240         
241
242         for (p = 0, l = 0; p < md->paramcount; p++) {
243                 t = md->paramtypes[p].type;
244
245                 varindex = jd->local_map[l * 5 + t];
246
247                 l++;
248                 if (IS_2_WORD_TYPE(t))    /* increment local counter for 2 word types */
249                         l++;
250
251                 if (varindex == UNUSED)
252                         continue;
253
254                 var = VAR(varindex);
255                 s1 = md->params[p].regoff;
256                 
257                 if (IS_INT_LNG_TYPE(t)) {                    /* integer args          */                        
258                         
259                         if (!md->params[p].inmemory) {           /* register arguments    */
260                                 /*s2 = rd->argintregs[s1];*/
261                                 /*s2 = REG_WINDOW_TRANSPOSE(s2);*/
262                                 
263                                 /* need the argument index here, not the register number */
264                                 s1 = md->params[p].regoff - abi_registers_integer_argument[0];
265                                 
266                                 if (!(var->flags & INMEMORY)) {      /* reg arg -> register   */
267                                         /*M_INTMOVE(s2, var->vv.regoff);*/                                      
268                                         M_LDX(var->vv.regoff, REG_SP, JITSTACK + (s1 * 8));
269
270                                 } else {                             /* reg arg -> spilled    */
271                                         /*M_STX(s2, REG_SP, (WINSAVE_CNT + var->vv.regoff) * 8);*/
272                                         
273                                         M_LDX(REG_ITMP1, REG_SP, JITSTACK + (s1 * 8));
274                                         M_STX(REG_ITMP1, REG_SP, localbase + (var->vv.regoff * 8));
275                                 }
276
277                         } else {                                 /* stack arguments       */
278                                 if (!(var->flags & INMEMORY)) {      /* stack arg -> register */
279                                         M_LDX(var->vv.regoff, REG_FP, JITSTACK + (s1 * 8));
280
281                                 } else {                             /* stack arg -> spilled  */
282                                         /* add the callers window save registers */
283                                         var->vv.regoff = cd->stackframesize + s1;
284                                 }
285                         }
286                 
287                 } else {                                     /* floating args         */
288                         if (!md->params[p].inmemory) {           /* register arguments    */
289                                 if (!(var->flags & INMEMORY)) {      /* reg arg -> register   */
290                                         M_FLTMOVE(s1, var->vv.regoff);
291
292                                 } else {                                         /* reg arg -> spilled    */
293                                         M_DST(s1, REG_SP, localbase + (var->vv.regoff) * 8);
294                                 }
295
296                         } else {                                 /* stack arguments       */
297                                 if (!(var->flags & INMEMORY)) {      /* stack-arg -> register */
298                                         M_DLD(var->vv.regoff, REG_FP, JITSTACK + (s1 * 8));
299
300                                 } else {                             /* stack-arg -> spilled  */
301                                         var->vv.regoff = cd->stackframesize + s1;
302                                 }
303                         }
304                 }
305         } /* end for */
306         
307         if (md->argintreguse > 0) {
308                 /* release scratch space */
309                 M_ADD_IMM(REG_SP, INT_ARG_CNT * 8, REG_SP);
310         }
311         
312         
313         /* XXX monitor enter */
314
315
316
317         
318         }
319         
320         /* end of header generation */ 
321         
322         /* create replacement points */
323
324         REPLACEMENT_POINTS_INIT(cd, jd);
325
326         /* walk through all basic blocks */
327
328         for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
329
330                 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
331
332                 if (bptr->flags >= BBREACHED) {
333
334                 /* branch resolving */
335
336                 codegen_resolve_branchrefs(cd, bptr);
337                 
338                 /* handle replacement points */
339
340 #if 0
341                 if (bptr->bitflags & BBFLAG_REPLACEMENT) {
342                         replacementpoint->pc = (u1*)(ptrint)bptr->mpc; /* will be resolved later */
343                         
344                         replacementpoint++;
345                 }
346 #endif
347
348                 /* copy interface registers to their destination */
349
350                 len = bptr->indepth;
351                 MCODECHECK(64+len);
352                 
353 #if defined(ENABLE_LSRA)
354 #error XXX LSRA not tested yet
355                 if (opt_lsra) {
356                 while (len) {
357                         len--;
358                         src = bptr->invars[len];
359                         if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
360                                         /*                              d = reg_of_var(m, src, REG_ITMP1); */
361                                         if (!(src->flags & INMEMORY))
362                                                 d = src->vv.regoff;
363                                         else
364                                                 d = REG_ITMP1;
365                                         M_INTMOVE(REG_ITMP1, d);
366                                         emit_store(jd, NULL, src, d);
367                                 }
368                         }
369                 } else {
370 #endif
371                 while (len) {
372                         len--;
373                         var = VAR(bptr->invars[len]);
374                         if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
375                                 d = codegen_reg_of_var(0, var, REG_ITMP1);
376                                 M_INTMOVE(REG_ITMP2_XPTR, d);
377                                 emit_store(jd, NULL, var, d);
378                         }
379                         else {
380                                 assert((var->flags & INOUT));
381                         }
382                 }
383 #if defined(ENABLE_LSRA)
384                 }
385 #endif
386                 /* walk through all instructions */
387                 
388                 len = bptr->icount;
389
390                 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
391                         if (iptr->line != currentline) {
392                                 dseg_addlinenumber(cd, iptr->line);
393                                 currentline = iptr->line;
394                         }
395
396                 MCODECHECK(64);       /* an instruction usually needs < 64 words      */
397
398                 switch (iptr->opc) {
399
400                 case ICMD_INLINE_START:
401                 case ICMD_INLINE_END:
402                         break;
403
404                 case ICMD_NOP:        /* ...  ==> ...                                 */
405                         break;
406
407                 case ICMD_CHECKNULL:  /* ..., objectref  ==> ..., objectref           */
408
409                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
410                         emit_nullpointer_check(cd, iptr, s1);
411                         break;
412         
413                 /* constant operations ************************************************/
414
415                 case ICMD_ICONST:     /* ...  ==> ..., constant                       */
416
417                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
418                         ICONST(d, iptr->sx.val.i);
419                         emit_store_dst(jd, iptr, d);
420                         break;
421
422                 case ICMD_LCONST:     /* ...  ==> ..., constant                       */
423
424                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
425                         LCONST(d, iptr->sx.val.l);
426                         emit_store_dst(jd, iptr, d);
427                         break;  
428
429                 case ICMD_FCONST:     /* ...  ==> ..., constant                       */
430
431                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
432                         disp = dseg_add_float(cd, iptr->sx.val.f);
433                         M_FLD(d, REG_PV, disp);
434                         emit_store_dst(jd, iptr, d);
435                         break;
436                         
437                 case ICMD_DCONST:     /* ...  ==> ..., constant                       */
438
439                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
440                         disp = dseg_add_double(cd, iptr->sx.val.d);
441                         M_DLD(d, REG_PV, disp);
442                         emit_store_dst(jd, iptr, d);
443                         break;
444
445                 case ICMD_ACONST:     /* ...  ==> ..., constant                       */
446
447                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
448
449                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
450                                 cr   = iptr->sx.val.c.ref;
451                                 disp = dseg_add_unique_address(cd, cr);
452
453                                 codegen_add_patch_ref(cd, PATCHER_aconst, cr, disp);
454
455                                 M_ALD(d, REG_PV, disp);
456
457                         } 
458                         else {
459                                 if (iptr->sx.val.anyptr == NULL) {
460                                         M_INTMOVE(REG_ZERO, d);
461                                 } 
462                                 else {
463                                         disp = dseg_add_address(cd, iptr->sx.val.anyptr);
464                                         M_ALD(d, REG_PV, disp);
465                                 }
466                         }
467                         emit_store_dst(jd, iptr, d);
468                         break;
469
470
471                 /* load/store/copy/move operations ************************************/
472
473                 case ICMD_ILOAD:      /* ...  ==> ..., content of local variable      */
474                 case ICMD_LLOAD:
475                 case ICMD_ALOAD:
476                 case ICMD_FLOAD:
477                 case ICMD_DLOAD:
478                 case ICMD_ISTORE:     /* ..., value  ==> ...                          */
479                 case ICMD_LSTORE:
480                 case ICMD_FSTORE:
481                 case ICMD_DSTORE:
482                 case ICMD_COPY:
483                 case ICMD_MOVE:
484
485                         emit_copy(jd, iptr);
486                         break;
487         
488                 case ICMD_ASTORE:
489                         if (!(iptr->flags.bits & INS_FLAG_RETADDR))
490                                 emit_copy(jd, iptr);
491                         break;
492
493
494                 /* pop/dup/swap operations ********************************************/
495
496                 /* attention: double and longs are only one entry in CACAO ICMDs      */
497
498                 case ICMD_POP:        /* ..., value  ==> ...                          */
499                 case ICMD_POP2:       /* ..., value, value  ==> ...                   */
500                         break;
501
502
503                 /* integer operations *************************************************/
504
505                 case ICMD_INEG:       /* ..., value  ==> ..., - value                 */
506                 case ICMD_LNEG:
507
508                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
509                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
510                         M_SUB(REG_ZERO, s1, d);
511                         emit_store_dst(jd, iptr, d);
512                         break;
513
514                 case ICMD_I2L:        /* ..., value  ==> ..., value                   */
515
516                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
517                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
518                         M_INTMOVE(s1, d);
519                         emit_store_dst(jd, iptr, d);
520                         break;
521
522                 case ICMD_L2I:        /* ..., value  ==> ..., value                   */
523
524                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
525                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
526                         M_SRA_IMM(s1, 0, d); /* sign extend upper 32 bits */
527                         emit_store_dst(jd, iptr, d);
528                         break;
529
530                 case ICMD_INT2BYTE:   /* ..., value  ==> ..., value                   */
531
532                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
533                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
534                         M_SLLX_IMM(s1, 56, d);
535                         M_SRAX_IMM( d, 56, d);
536                         emit_store_dst(jd, iptr, d);
537                         break;
538
539                 case ICMD_INT2CHAR:   /* ..., value  ==> ..., value                   */
540                 
541                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
542                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
543                         M_SLLX_IMM(s1, 48, d);
544                         M_SRLX_IMM( d, 48, d);
545                         emit_store_dst(jd, iptr, d);
546                         break;
547                         
548                 case ICMD_INT2SHORT:   /* ..., value  ==> ..., value                   */
549
550                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
551                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
552                         M_SLLX_IMM(s1, 48, d);
553                         M_SRAX_IMM( d, 48, d);
554                         emit_store_dst(jd, iptr, d);
555                         break;
556
557                 case ICMD_IADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
558                 case ICMD_LADD:
559
560                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
561                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
562                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
563                         M_ADD(s1, s2, d);
564                         emit_store_dst(jd, iptr, d);
565                         break;
566
567                 case ICMD_IINC:
568                 case ICMD_IADDCONST:  /* ..., value  ==> ..., value + constant        */
569                                       /* sx.val.i = constant                             */
570
571                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
572                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
573                         if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
574                                 M_ADD_IMM(s1, iptr->sx.val.i, d);
575                         } else {
576                                 ICONST(REG_ITMP2, iptr->sx.val.i);
577                                 M_ADD(s1, REG_ITMP2, d);
578                         }
579                         emit_store_dst(jd, iptr, d);
580                         break;
581
582                 case ICMD_LADDCONST:  /* ..., value  ==> ..., value + constant        */
583                                       /* sx.val.l = constant                             */
584
585                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
586                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
587                         if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
588                                 M_ADD_IMM(s1, iptr->sx.val.l, d);
589                         } else {
590                                 LCONST(REG_ITMP2, iptr->sx.val.l);
591                                 M_ADD(s1, REG_ITMP2, d);
592                         }
593                         emit_store_dst(jd, iptr, d);
594                         break;
595
596                 case ICMD_ISUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
597                 case ICMD_LSUB: 
598
599                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
600                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
601                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
602                         M_SUB(s1, s2, d);
603                         emit_store_dst(jd, iptr, d);
604                         break;
605
606                 case ICMD_ISUBCONST:  /* ..., value  ==> ..., value + constant        */
607                                       /* sx.val.i = constant                             */
608
609                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
610                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
611                         if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
612                                 M_SUB_IMM(s1, iptr->sx.val.i, d);
613                         } else {
614                                 ICONST(REG_ITMP2, iptr->sx.val.i);
615                                 M_SUB(s1, REG_ITMP2, d);
616                         }
617                         emit_store_dst(jd, iptr, d);
618                         break;
619
620                 case ICMD_LSUBCONST:  /* ..., value  ==> ..., value - constant        */
621                                       /* sx.val.l = constant                             */
622
623                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
624                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
625                         if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
626                                 M_SUB_IMM(s1, iptr->sx.val.l, d);
627                         } else {
628                                 LCONST(REG_ITMP2, iptr->sx.val.l);
629                                 M_SUB(s1, REG_ITMP2, d);
630                         }
631                         emit_store_dst(jd, iptr, d);
632                         break;
633
634                 case ICMD_IMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
635                 case ICMD_LMUL:
636
637                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
638                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
639                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
640                         M_MULX(s1, s2, d);
641                         emit_store_dst(jd, iptr, d);
642                         break;
643
644                 case ICMD_IMULCONST:  /* ..., value  ==> ..., value * constant        */
645                                       /* sx.val.i = constant                             */
646
647                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
648                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
649                         if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
650                                 M_MULX_IMM(s1, iptr->sx.val.i, d);
651                         } else {
652                                 ICONST(REG_ITMP2, iptr->sx.val.i);
653                                 M_MULX(s1, REG_ITMP2, d);
654                         }
655                         emit_store_dst(jd, iptr, d);
656                         break;
657
658                 case ICMD_LMULCONST:  /* ..., value  ==> ..., value * constant        */
659                                       /* sx.val.l = constant                             */
660
661                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
662                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
663                         if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
664                                 M_MULX_IMM(s1, iptr->sx.val.l, d);
665                         } else {
666                                 LCONST(REG_ITMP2, iptr->sx.val.l);
667                                 M_MULX(s1, REG_ITMP2, d);
668                         }
669                         emit_store_dst(jd, iptr, d);
670                         break;
671
672                 case ICMD_IDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
673 /* XXX could also clear Y and use 32bit div */
674                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
675                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
676                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
677                         emit_arithmetic_check(cd, iptr, s2);
678                         M_ISEXT(s1, s1);
679                         /* XXX trim s2 like s1 ? */
680                         M_DIVX(s1, s2, d);
681                         emit_store_dst(jd, iptr, d);
682                         break;
683
684                 case ICMD_LDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
685
686                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
687                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
688                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
689                         emit_arithmetic_check(cd, iptr, s2);
690                         M_DIVX(s1, s2, d);
691                         emit_store_dst(jd, iptr, d);
692                         break;
693
694                 case ICMD_IREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
695
696                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
697                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
698                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
699                         emit_arithmetic_check(cd, iptr, s2);
700                         M_ISEXT(s1, s1);
701                         /* XXX trim s2 like s1 ? */
702                         M_DIVX(s1, s2, REG_ITMP3);
703                         M_MULX(s2, REG_ITMP3, REG_ITMP3);
704                         M_SUB(s1, REG_ITMP3, d);
705                         emit_store_dst(jd, iptr, d);
706                         break;
707
708                 case ICMD_LREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
709
710                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
711                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
712                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
713                         emit_arithmetic_check(cd, iptr, s2);
714                         M_DIVX(s1, s2, REG_ITMP3);
715                         M_MULX(s2, REG_ITMP3, REG_ITMP3);
716                         M_SUB(s1, REG_ITMP3, d);
717                         emit_store_dst(jd, iptr, d);
718                         break;
719
720                 case ICMD_IDIVPOW2:   /* ..., value  ==> ..., value << constant       */
721                 case ICMD_LDIVPOW2:   /* val.i = constant                             */
722                                       
723                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
724                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
725                         M_SRAX_IMM(s1, 63, REG_ITMP2);
726                         M_SRLX_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
727                         M_ADD(s1, REG_ITMP2, REG_ITMP2);
728                         M_SRAX_IMM(REG_ITMP2, iptr->sx.val.i, d);
729                         emit_store_dst(jd, iptr, d);
730                         break;
731
732                 case ICMD_ISHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
733
734                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
735                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
736                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
737                         M_SLL(s1, s2, d);
738                         emit_store_dst(jd, iptr, d);
739                         break;
740                         
741                 case ICMD_LSHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
742
743                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
744                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
745                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
746                         M_SLLX(s1, s2, d);
747                         emit_store_dst(jd, iptr, d);
748                         break;
749
750                 case ICMD_ISHLCONST:  /* ..., value  ==> ..., value << constant       */
751                                       /* val.i = constant                             */
752
753                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
754                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
755                         M_SLL_IMM(s1, iptr->sx.val.i, d);
756                         emit_store_dst(jd, iptr, d);
757                         break;
758                         
759                 case ICMD_LSHLCONST:  /* ..., value  ==> ..., value << constant       */
760                                       /* val.i = constant                             */
761
762                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
763                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
764                         M_SLLX_IMM(s1, iptr->sx.val.i, d);
765                         emit_store_dst(jd, iptr, d);
766                         break;
767
768                 case ICMD_ISHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
769
770                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
771                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
772                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
773                         M_SRA(s1, s2, d);
774                         emit_store_dst(jd, iptr, d);
775                         break;
776
777                 case ICMD_ISHRCONST:  /* ..., value  ==> ..., value >> constant       */
778                                       /* sx.val.i = constant                             */
779
780                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
781                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
782                         M_SRA_IMM(s1, iptr->sx.val.i, d);
783                         emit_store_dst(jd, iptr, d);
784                         break;
785
786                 case ICMD_IUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
787
788                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
789                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
790                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
791                         M_SRL(s1, s2, d);
792                         emit_store_dst(jd, iptr, d);
793                         break;
794
795                 case ICMD_IUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
796                                       /* sx.val.i = constant                             */
797
798                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
799                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
800                         M_SRL_IMM(s1, iptr->sx.val.i, d);
801                         emit_store_dst(jd, iptr, d);
802                         break;
803
804                 case ICMD_LSHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
805
806                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
807                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
808                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
809                         M_SRAX(s1, s2, d);
810                         emit_store_dst(jd, iptr, d);
811                         break;
812
813                 case ICMD_LSHRCONST:  /* ..., value  ==> ..., value >> constant       */
814                                       /* sx.val.i = constant                             */
815
816                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
817                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
818                         M_SRAX_IMM(s1, iptr->sx.val.i, d);
819                         emit_store_dst(jd, iptr, d);
820                         break;
821
822                 case ICMD_LUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
823
824                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
825                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
826                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
827                         M_SRLX(s1, s2, d);
828                         emit_store_dst(jd, iptr, d);
829                         break;
830
831                 case ICMD_LUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
832                                       /* sx.val.i = constant                             */
833
834                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
835                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
836                         M_SRLX_IMM(s1, iptr->sx.val.i, d);
837                         emit_store_dst(jd, iptr, d);
838                         break;
839
840                 case ICMD_IAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
841                 case ICMD_LAND:
842
843                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
844                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
845                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
846                         M_AND(s1, s2, d);
847                         emit_store_dst(jd, iptr, d);
848                         break;
849
850                 case ICMD_IANDCONST:  /* ..., value  ==> ..., value & constant        */
851                                       /* sx.val.i = constant                             */
852
853                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
854                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
855                         if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
856                                 M_AND_IMM(s1, iptr->sx.val.i, d);
857                         } else {
858                                 ICONST(REG_ITMP2, iptr->sx.val.i);
859                                 M_AND(s1, REG_ITMP2, d);
860                         }
861                         emit_store_dst(jd, iptr, d);
862                         break;
863
864                 case ICMD_IREMPOW2:   /* ..., value  ==> ..., value % constant           */
865                                       /* sx.val.i = constant                             */
866                                       /* constant is actually constant - 1               */
867
868                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
869                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
870                         if (s1 == d) {
871                                 M_MOV(s1, REG_ITMP1);
872                                 s1 = REG_ITMP1;
873                         }
874                         M_ISEXT(s1, s1); /* trim for 32-bit compare (BGEZ) */
875                         if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 4095)) {
876                                 M_AND_IMM(s1, iptr->sx.val.i, d);
877                                 M_BGEZ(s1, 5);
878                                 M_NOP;
879                                 M_SUB(REG_ZERO, s1, d);
880                                 M_AND_IMM(d, iptr->sx.val.i, d);
881                         } else {
882                                 ICONST(REG_ITMP2, iptr->sx.val.i);
883                                 M_AND(s1, REG_ITMP2, d);
884                                 M_BGEZ(s1, 5);
885                                 M_NOP;
886                                 M_SUB(REG_ZERO, s1, d);
887                                 M_AND(d, REG_ITMP2, d);
888                         }
889                         M_SUB(REG_ZERO, d, d);
890                         emit_store_dst(jd, iptr, d);
891                         break;
892
893                 case ICMD_LANDCONST:  /* ..., value  ==> ..., value & constant        */
894                                       /* sx.val.l = constant                             */
895
896                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
897                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
898                         if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
899                                 M_AND_IMM(s1, iptr->sx.val.l, d);
900                         } else {
901                                 LCONST(REG_ITMP2, iptr->sx.val.l);
902                                 M_AND(s1, REG_ITMP2, d);
903                         }
904                         emit_store_dst(jd, iptr, d);
905                         break;
906
907                 case ICMD_LREMPOW2:   /* ..., value  ==> ..., value % constant        */
908                                       /* sx.val.l = constant                             */
909
910                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
911                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
912                         if (s1 == d) {
913                                 M_MOV(s1, REG_ITMP1);
914                                 s1 = REG_ITMP1;
915                         }
916                         if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
917                                 M_AND_IMM(s1, iptr->sx.val.l, d);
918                                 M_BGEZ(s1, 4);
919                                 M_NOP;
920                                 M_SUB(REG_ZERO, s1, d);
921                                 M_AND_IMM(d, iptr->sx.val.l, d);
922                         } else {
923                                 LCONST(REG_ITMP2, iptr->sx.val.l);
924                                 M_AND(s1, REG_ITMP2, d);
925                                 M_BGEZ(s1, 4);
926                                 M_NOP;
927                                 M_SUB(REG_ZERO, s1, d);
928                                 M_AND(d, REG_ITMP2, d);
929                         }
930                         M_SUB(REG_ZERO, d, d);
931                         emit_store_dst(jd, iptr, d);
932                         break;
933
934                 case ICMD_IOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
935                 case ICMD_LOR:
936
937                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
938                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
939                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
940                         M_OR(s1,s2, d);
941                         emit_store_dst(jd, iptr, d);
942                         break;
943
944                 case ICMD_IORCONST:   /* ..., value  ==> ..., value | constant        */
945                                       /* sx.val.i = constant                             */
946
947                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
948                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
949                         if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
950                                 M_OR_IMM(s1, iptr->sx.val.i, d);
951                         } else {
952                                 ICONST(REG_ITMP2, iptr->sx.val.i);
953                                 M_OR(s1, REG_ITMP2, d);
954                         }
955                         emit_store_dst(jd, iptr, d);
956                         break;
957
958                 case ICMD_LORCONST:   /* ..., value  ==> ..., value | constant        */
959                                       /* sx.val.l = constant                             */
960
961                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
962                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
963                         if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
964                                 M_OR_IMM(s1, iptr->sx.val.l, d);
965                         } else {
966                                 LCONST(REG_ITMP2, iptr->sx.val.l);
967                                 M_OR(s1, REG_ITMP2, d);
968                         }
969                         emit_store_dst(jd, iptr, d);
970                         break;
971
972                 case ICMD_IXOR:       /* ..., val1, val2  ==> ..., val1 ^ val2        */
973                 case ICMD_LXOR:
974
975                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
976                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
977                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
978                         M_XOR(s1, s2, d);
979                         emit_store_dst(jd, iptr, d);
980                         break;
981
982                 case ICMD_IXORCONST:  /* ..., value  ==> ..., value ^ constant        */
983                                       /* sx.val.i = constant                             */
984
985                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
986                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
987                         if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
988                                 M_XOR_IMM(s1, iptr->sx.val.i, d);
989                         } else {
990                                 ICONST(REG_ITMP2, iptr->sx.val.i);
991                                 M_XOR(s1, REG_ITMP2, d);
992                         }
993                         emit_store_dst(jd, iptr, d);
994                         break;
995
996                 case ICMD_LXORCONST:  /* ..., value  ==> ..., value ^ constant        */
997                                       /* sx.val.l = constant                             */
998
999                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1000                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1001                         if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1002                                 M_XOR_IMM(s1, iptr->sx.val.l, d);
1003                         } else {
1004                                 LCONST(REG_ITMP2, iptr->sx.val.l);
1005                                 M_XOR(s1, REG_ITMP2, d);
1006                         }
1007                         emit_store_dst(jd, iptr, d);
1008                         break;
1009
1010
1011                 case ICMD_LCMP:       /* ..., val1, val2  ==> ..., val1 cmp val2      */
1012
1013                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1014                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1015                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1016                         M_CMP(s1, s2);
1017                         M_MOV(REG_ZERO, d);
1018                         M_XCMOVLT_IMM(-1, d);
1019                         M_XCMOVGT_IMM(1, d);
1020                         emit_store_dst(jd, iptr, d);
1021                         break;
1022
1023
1024                 /* floating operations ************************************************/
1025
1026                 case ICMD_FNEG:       /* ..., value  ==> ..., - value                 */
1027
1028                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1029                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1030                         M_FNEG(s1, d);
1031                         emit_store_dst(jd, iptr, d);
1032                         break;
1033
1034                 case ICMD_DNEG:       /* ..., value  ==> ..., - value                 */
1035
1036                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1037                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1038                         M_DNEG(s1, d);
1039                         emit_store_dst(jd, iptr, d);
1040                         break;
1041
1042                 case ICMD_FADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
1043
1044                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1045                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1046                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1047                         M_FADD(s1, s2, d);
1048                         emit_store_dst(jd, iptr, d);
1049                         break;
1050
1051                 case ICMD_DADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
1052
1053                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1054                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1055                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1056                         M_DADD(s1, s2, d);
1057                         emit_store_dst(jd, iptr, d);
1058                         break;
1059
1060                 case ICMD_FSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
1061
1062                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1063                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1064                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1065                         M_FSUB(s1, s2, d);
1066                         emit_store_dst(jd, iptr, d);
1067                         break;
1068
1069                 case ICMD_DSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
1070
1071                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1072                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1073                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1074                         M_DSUB(s1, s2, d);
1075                         emit_store_dst(jd, iptr, d);
1076                         break;
1077
1078                 case ICMD_FMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
1079
1080                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1081                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1082                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1083                         M_FMUL(s1, s2, d);
1084                         emit_store_dst(jd, iptr, d);
1085                         break;
1086
1087                 case ICMD_DMUL:       /* ..., val1, val2  ==> ..., val1 *** val2      */
1088
1089                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1090                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1091                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1092                         M_DMUL(s1, s2, d);
1093                         emit_store_dst(jd, iptr, d);
1094                         break;
1095
1096                 case ICMD_FDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1097
1098                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1099                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1100                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1101                         M_FDIV(s1, s2, d);
1102                         emit_store_dst(jd, iptr, d);
1103                         break;
1104
1105                 case ICMD_DDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1106
1107                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1108                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1109                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1110                         M_DDIV(s1, s2, d);
1111                         emit_store_dst(jd, iptr, d);
1112                         break;  
1113
1114                 case ICMD_I2F:
1115                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1116                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1117                         disp = dseg_add_float(cd, 0.0);
1118                         M_IST (s1, REG_PV_CALLEE, disp);
1119                         M_FLD (d, REG_PV_CALLEE, disp);
1120                         M_CVTIF (d, d); /* rd gets translated to double target register */
1121                         emit_store_dst(jd, iptr, d);
1122                         break;
1123                         
1124                 case ICMD_I2D:
1125                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1126                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1127                         disp = dseg_add_float(cd, 0.0);
1128                         M_IST(s1, REG_PV_CALLEE, disp);
1129                         M_FLD(REG_FTMP2, REG_PV_CALLEE, disp); /* REG_FTMP2 needs to be a double temp */
1130                         M_CVTID (REG_FTMP2, d); /* rd gets translated to double target register */
1131                         emit_store_dst(jd, iptr, d);
1132                         break;
1133                         
1134                 case ICMD_L2F:
1135                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1136                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1137                         disp = dseg_add_double(cd, 0.0);
1138                         M_STX(s1, REG_PV_CALLEE, disp);
1139                         M_DLD(REG_FTMP3, REG_PV_CALLEE, disp);
1140                         M_CVTLF(REG_FTMP3, d);
1141                         emit_store_dst(jd, iptr, d);
1142                         break;
1143                         
1144                 case ICMD_L2D:
1145                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1146                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1147                         disp = dseg_add_double(cd, 0.0);
1148                         M_STX(s1, REG_PV_CALLEE, disp);
1149                         M_DLD(d, REG_PV_CALLEE, disp);
1150                         M_CVTLD(d, d);
1151                         emit_store_dst(jd, iptr, d);
1152                         break;
1153
1154                 case ICMD_F2I:       /* ..., value  ==> ..., (int) value              */
1155                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1156                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1157                         disp = dseg_add_float(cd, 0.0);
1158                         M_CVTFI(s1, REG_FTMP2);
1159                         M_FST(REG_FTMP2, REG_PV_CALLEE, disp);
1160                         M_ILD(d, REG_PV, disp);
1161                         emit_store_dst(jd, iptr, d);
1162                         break;
1163                         
1164                                
1165                 case ICMD_D2I:       /* ..., value  ==> ..., (int) value             */
1166                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1167                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1168                         disp = dseg_add_float(cd, 0.0);
1169                         M_CVTDI(s1, REG_FTMP2);
1170                         M_FST(REG_FTMP2, REG_PV, disp);
1171                         M_ILD(d, REG_PV, disp);
1172                         emit_store_dst(jd, iptr, d);
1173                         break;
1174
1175                 case ICMD_F2L:       /* ..., value  ==> ..., (long) value             */
1176                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1177                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1178                         disp = dseg_add_double(cd, 0.0);
1179                         M_CVTFL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
1180                         M_DST(REG_FTMP2, REG_PV, disp);
1181                         M_LDX(d, REG_PV, disp);
1182                         emit_store_dst(jd, iptr, d);
1183                         break;
1184                         
1185                 case ICMD_D2L:       /* ..., value  ==> ..., (long) value             */
1186                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1187                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1188                         disp = dseg_add_double(cd, 0.0);
1189                         M_CVTDL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
1190                         M_DST(REG_FTMP2, REG_PV, disp);
1191                         M_LDX(d, REG_PV, disp);
1192                         emit_store_dst(jd, iptr, d);
1193                         break;
1194
1195                 case ICMD_F2D:       /* ..., value  ==> ..., (double) value           */
1196
1197                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1198                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1199                         M_CVTFD(s1, d);
1200                         emit_store_dst(jd, iptr, d);
1201                         break;
1202                                         
1203                 case ICMD_D2F:       /* ..., value  ==> ..., (float) value            */
1204
1205                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1206                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1207                         M_CVTDF(s1, d);
1208                         emit_store_dst(jd, iptr, d);
1209                         break;
1210         
1211         /* XXX merge F/D versions? only compare instr. is different */
1212                 case ICMD_FCMPL:      /* ..., val1, val2  ==> ..., val1 fcmpl val2    */
1213
1214                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1215                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1216                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1217                         M_FCMP(s1,s2);
1218                         M_OR_IMM(REG_ZERO, -1, d); /* less by default (less or unordered) */
1219                         M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1220                         M_CMOVFGT_IMM(1, d); /* 1 if greater */
1221                         emit_store_dst(jd, iptr, d);
1222                         break;
1223                         
1224                 case ICMD_DCMPL:      /* ..., val1, val2  ==> ..., val1 fcmpl val2    */
1225
1226                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1227                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1228                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1229                         M_DCMP(s1,s2);
1230                         M_OR_IMM(REG_ZERO, -1, d); /* less by default (less or unordered) */
1231                         M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1232                         M_CMOVFGT_IMM(1, d); /* 1 if greater */
1233                         emit_store_dst(jd, iptr, d);
1234                         break;
1235                         
1236                 case ICMD_FCMPG:      /* ..., val1, val2  ==> ..., val1 fcmpg val2    */
1237
1238                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1239                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1240                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);    
1241                         M_FCMP(s1,s2);
1242                         M_OR_IMM(REG_ZERO, 1, d); /* greater by default (greater or unordered) */
1243                         M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1244                         M_CMOVFLT_IMM(-1, d); /* -1 if less */
1245                         emit_store_dst(jd, iptr, d);
1246                         break;
1247                         
1248                 case ICMD_DCMPG:      /* ..., val1, val2  ==> ..., val1 fcmpg val2    */
1249
1250                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1251                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1252                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);    
1253                         M_DCMP(s1,s2);
1254                         M_OR_IMM(REG_ZERO, 1, d); /* greater by default (greater or unordered) */
1255                         M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1256                         M_CMOVFLT_IMM(-1, d); /* -1 if less */
1257                         emit_store_dst(jd, iptr, d);
1258                         break;
1259                         
1260
1261                 /* memory operations **************************************************/
1262
1263                 case ICMD_ARRAYLENGTH: /* ..., arrayref  ==> ..., length              */
1264
1265                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1266                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1267                         emit_nullpointer_check(cd, iptr, s1);
1268                         M_ILD(d, s1, OFFSET(java_arrayheader, size));
1269                         emit_store_dst(jd, iptr, d);
1270                         break;
1271
1272                 case ICMD_BALOAD:     /* ..., arrayref, index  ==> ..., value         */
1273
1274                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1275                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1276                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1277                         /* implicit null-pointer check */
1278                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1279                         M_AADD(s2, s1, REG_ITMP3);
1280                         M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray, data[0]));
1281                         emit_store_dst(jd, iptr, d);
1282                         break;
1283
1284                 case ICMD_CALOAD:     /* ..., arrayref, index  ==> ..., value         */
1285
1286                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1287                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1288                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1289                         /* implicit null-pointer check */
1290                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1291                         M_AADD(s2, s1, REG_ITMP3);
1292                         M_AADD(s2, REG_ITMP3, REG_ITMP3);
1293                         M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1294                         emit_store_dst(jd, iptr, d);
1295                         break;                  
1296
1297                 case ICMD_SALOAD:     /* ..., arrayref, index  ==> ..., value         */
1298
1299                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1300                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1301                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1302                         /* implicit null-pointer check */
1303                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1304                         M_AADD(s2, s1, REG_ITMP3);
1305                         M_AADD(s2, REG_ITMP3, REG_ITMP3);
1306                         M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray, data[0]));
1307                         emit_store_dst(jd, iptr, d);
1308                         break;
1309
1310                 case ICMD_IALOAD:     /* ..., arrayref, index  ==> ..., value         */
1311
1312                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1313                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1314                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1315                         /* implicit null-pointer check */
1316                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1317                         M_ASLL_IMM(s2, 2, REG_ITMP3);
1318                         M_AADD(REG_ITMP3, s1, REG_ITMP3);
1319                         M_ILD(d, REG_ITMP3, OFFSET(java_intarray, data[0]));
1320                         emit_store_dst(jd, iptr, d);
1321                         break;
1322
1323                 case ICMD_LALOAD:     /* ..., arrayref, index  ==> ..., value         */
1324
1325                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1326                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1327                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1328                         /* implicit null-pointer check */
1329                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1330                         M_ASLL_IMM(s2, 3, REG_ITMP3);
1331                         M_AADD(REG_ITMP3, s1, REG_ITMP3);
1332                         M_LDX(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
1333                         emit_store_dst(jd, iptr, d);
1334                         break;
1335
1336                 case ICMD_FALOAD:     /* ..., arrayref, index  ==> ..., value         */
1337
1338                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1339                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1340                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1341                         /* implicit null-pointer check */
1342                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1343                         M_ASLL_IMM(s2, 2, REG_ITMP3);
1344                         M_AADD(REG_ITMP3, s1, REG_ITMP3);
1345                         M_FLD(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
1346                         emit_store_dst(jd, iptr, d);
1347                         break;
1348
1349                 case ICMD_DALOAD:     /* ..., arrayref, index  ==> ..., value         */
1350
1351                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1352                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1353                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1354                         /* implicit null-pointer check */
1355                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1356                         M_ASLL_IMM(s2, 3, REG_ITMP3);
1357                         M_AADD(REG_ITMP3, s1, REG_ITMP3);
1358                         M_DLD(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
1359                         emit_store_dst(jd, iptr, d);
1360                         break;
1361
1362                 case ICMD_AALOAD:     /* ..., arrayref, index  ==> ..., value         */
1363
1364                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1365                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1366                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1367                         /* implicit null-pointer check */
1368                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1369                         M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1370                         M_AADD(REG_ITMP3, s1, REG_ITMP3);
1371                         M_ALD(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
1372                         emit_store_dst(jd, iptr, d);
1373                         break;
1374
1375         
1376                 case ICMD_BASTORE:    /* ..., arrayref, index, value  ==> ...         */
1377
1378                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1379                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1380                         /* implicit null-pointer check */
1381                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1382                         M_AADD(s2, s1, REG_ITMP1);
1383                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1384                         M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1385                         break;
1386
1387                 case ICMD_CASTORE:    /* ..., arrayref, index, value  ==> ...         */
1388                 case ICMD_SASTORE:    /* ..., arrayref, index, value  ==> ...         */
1389
1390                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1391                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1392                         /* implicit null-pointer check */
1393                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1394                         M_AADD(s2, s1, REG_ITMP1);
1395                         M_AADD(s2, REG_ITMP1, REG_ITMP1);
1396                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1397                         M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1398                         break;
1399
1400                 case ICMD_IASTORE:    /* ..., arrayref, index, value  ==> ...         */
1401
1402                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1403                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1404                         /* implicit null-pointer check */
1405                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1406                         M_ASLL_IMM(s2, 2, REG_ITMP2);
1407                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1408                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1409                         M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1410                         break;
1411
1412                 case ICMD_LASTORE:    /* ..., arrayref, index, value  ==> ...         */
1413
1414                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1415                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1416                         /* implicit null-pointer check */
1417                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1418                         M_ASLL_IMM(s2, 3, REG_ITMP2);
1419                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1420                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1421                         M_STX_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1422                         break;
1423
1424                 case ICMD_FASTORE:    /* ..., arrayref, index, value  ==> ...         */
1425
1426                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1427                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1428                         /* implicit null-pointer check */
1429                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1430                         M_ASLL_IMM(s2, 2, REG_ITMP2);
1431                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1432                         s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1433                         M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1434                         break;
1435
1436                 case ICMD_DASTORE:    /* ..., arrayref, index, value  ==> ...         */
1437
1438                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1439                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1440                         /* implicit null-pointer check */
1441                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1442                         M_ASLL_IMM(s2, 3, REG_ITMP2);
1443                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1444                         s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1445                         M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1446                         break;
1447
1448
1449                 case ICMD_AASTORE:    /* ..., arrayref, index, value  ==> ...         */
1450
1451                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1452                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1453                         /* implicit null-pointer check */
1454                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1455                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1456
1457                         M_MOV(s1, REG_OUT0);
1458                         M_MOV(s3, REG_OUT1);
1459                         disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1460                         M_ALD(REG_ITMP3, REG_PV, disp);
1461                         M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
1462                         M_NOP;
1463                         emit_exception_check(cd, iptr);
1464
1465                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1466                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1467                         M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1468                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1469                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1470                         /* implicit null-pointer check */
1471                         M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1472                         break;
1473
1474
1475                 case ICMD_BASTORECONST:   /* ..., arrayref, index  ==> ...            */
1476
1477                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1478                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1479                         /* implicit null-pointer check */
1480                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1481                         M_AADD(s2, s1, REG_ITMP1);
1482                         M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1483                         break;
1484
1485                 case ICMD_CASTORECONST:   /* ..., arrayref, index  ==> ...            */
1486                 case ICMD_SASTORECONST:   /* ..., arrayref, index  ==> ...            */
1487
1488                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1489                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1490                         /* implicit null-pointer check */
1491                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1492                         M_AADD(s2, s1, REG_ITMP1);
1493                         M_AADD(s2, REG_ITMP1, REG_ITMP1);
1494                         M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1495                         break;
1496
1497                 case ICMD_IASTORECONST:   /* ..., arrayref, index  ==> ...            */
1498
1499                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1500                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1501                         /* implicit null-pointer check */
1502                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1503                         M_ASLL_IMM(s2, 2, REG_ITMP2);
1504                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1505                         M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1506                         break;
1507
1508                 case ICMD_LASTORECONST:   /* ..., arrayref, index  ==> ...            */
1509
1510                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1511                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1512                         /* implicit null-pointer check */
1513                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1514                         M_ASLL_IMM(s2, 3, REG_ITMP2);
1515                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1516                         M_STX_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1517                         break;
1518
1519                 case ICMD_AASTORECONST:   /* ..., arrayref, index  ==> ...            */
1520
1521                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1522                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1523                         /* implicit null-pointer check */
1524                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1525                         M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1526                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1527                         M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1528                         break;
1529                 
1530
1531                 case ICMD_GETSTATIC:  /* ...  ==> ..., value                          */
1532
1533                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1534                                 uf = iptr->sx.s23.s3.uf;
1535                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1536                                 disp      = dseg_add_unique_address(cd, uf);
1537
1538                                 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1539                         } 
1540                         else {
1541                                 fi = iptr->sx.s23.s3.fmiref->p.field;
1542                                 fieldtype = fi->type;
1543                                 disp = dseg_add_address(cd, &(fi->value));
1544
1545                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1546                                         codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1547                         }
1548
1549                         M_ALD(REG_ITMP1, REG_PV, disp);
1550
1551                         switch (fieldtype) {
1552                         case TYPE_INT:
1553                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1554                                 M_ILD_INTERN(d, REG_ITMP1, 0);
1555                                 break;
1556                         case TYPE_LNG:
1557                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1558                                 M_LDX_INTERN(d, REG_ITMP1, 0);
1559                                 break;
1560                         case TYPE_ADR:
1561                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1562                                 M_ALD_INTERN(d, REG_ITMP1, 0);
1563                                 break;
1564                         case TYPE_FLT:
1565                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1566                                 M_FLD_INTERN(d, REG_ITMP1, 0);
1567                                 break;
1568                         case TYPE_DBL:                          
1569                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1570                                 M_DLD_INTERN(d, REG_ITMP1, 0);
1571                                 break;
1572                         }
1573                         emit_store_dst(jd, iptr, d);
1574                         break;
1575
1576                 case ICMD_PUTSTATIC:  /* ..., value  ==> ...                          */
1577
1578                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1579                                 uf = iptr->sx.s23.s3.uf;
1580                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1581                                 disp      = dseg_add_unique_address(cd, uf);
1582
1583                                 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1584                         } 
1585                         else {
1586                                 fi = iptr->sx.s23.s3.fmiref->p.field;
1587                                 fieldtype = fi->type;
1588                                 disp = dseg_add_address(cd, &(fi->value));
1589
1590                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1591                                         codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1592                         }
1593
1594                         M_ALD(REG_ITMP1, REG_PV, disp);
1595
1596                         switch (fieldtype) {
1597                         case TYPE_INT:
1598                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1599                                 M_IST_INTERN(s1, REG_ITMP1, 0);
1600                                 break;
1601                         case TYPE_LNG:
1602                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1603                                 M_STX_INTERN(s1, REG_ITMP1, 0);
1604                                 break;
1605                         case TYPE_ADR:
1606                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1607                                 M_AST_INTERN(s1, REG_ITMP1, 0);
1608                                 break;
1609                         case TYPE_FLT:
1610                                 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1611                                 M_FST_INTERN(s1, REG_ITMP1, 0);
1612                                 break;
1613                         case TYPE_DBL:
1614                                 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1615                                 M_DST_INTERN(s1, REG_ITMP1, 0);
1616                                 break;
1617                         }
1618                         break;
1619
1620                 case ICMD_PUTSTATICCONST: /* ...  ==> ...                             */
1621                                           /* val = value (in current instruction)     */
1622                                           /* following NOP)                           */
1623
1624                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1625                                 uf        = iptr->sx.s23.s3.uf;
1626                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1627                                 disp = dseg_add_unique_address(cd, uf);
1628
1629                                 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1630                         } 
1631                         else {
1632                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1633                                 fieldtype = fi->type;
1634                                 disp      = dseg_add_address(cd, &(fi->value));
1635
1636                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1637                                         codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1638                         }
1639
1640                         M_ALD(REG_ITMP1, REG_PV, disp);
1641
1642                         switch (fieldtype) {
1643                         case TYPE_INT:
1644                                 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
1645                                 break;
1646                         case TYPE_LNG:
1647                                 M_STX_INTERN(REG_ZERO, REG_ITMP1, 0);
1648                                 break;
1649                         case TYPE_ADR:
1650                                 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
1651                                 break;
1652                         case TYPE_FLT:
1653                                 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
1654                                 break;
1655                         case TYPE_DBL:
1656                                 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
1657                                 break;
1658                         }
1659                         break;
1660
1661
1662                 case ICMD_GETFIELD:   /* ...  ==> ..., value                          */
1663
1664                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1665                         emit_nullpointer_check(cd, iptr, s1);
1666
1667                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1668                                 uf = iptr->sx.s23.s3.uf;
1669
1670                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1671                                 disp      = 0;
1672
1673                                 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1674                         } 
1675                         else {
1676                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1677                                 fieldtype = fi->type;
1678                                 disp      = fi->offset;
1679                         }
1680
1681                         switch (fieldtype) {
1682                         case TYPE_INT:
1683                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1684                                 M_ILD(d, s1, disp);
1685                                 break;
1686                         case TYPE_LNG:
1687                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1688                                 M_LDX(d, s1, disp);
1689                                 break;
1690                         case TYPE_ADR:
1691                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1692                                 M_ALD(d, s1, disp);
1693                                 break;
1694                         case TYPE_FLT:
1695                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1696                                 M_FLD(d, s1, disp);
1697                                 break;
1698                         case TYPE_DBL:                          
1699                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1700                                 M_DLD(d, s1, disp);
1701                                 break;
1702                         default:
1703                                 assert(0);
1704                                 break;
1705                         }
1706                         emit_store_dst(jd, iptr, d);
1707                         break;
1708
1709                 case ICMD_PUTFIELD:   /* ..., objectref, value  ==> ...               */
1710
1711                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1712                         emit_nullpointer_check(cd, iptr, s1);
1713
1714                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1715                                 uf = iptr->sx.s23.s3.uf;
1716                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1717                                 disp      = 0;
1718                         }
1719                         else {
1720                                 uf        = NULL;
1721                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1722                                 fieldtype = fi->type;
1723                                 disp      = fi->offset;
1724                                 }
1725
1726                         if (IS_INT_LNG_TYPE(fieldtype))
1727                                 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1728                         else
1729                                 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1730
1731                         if (INSTRUCTION_IS_UNRESOLVED(iptr))
1732                                 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1733
1734                         switch (fieldtype) {
1735                         case TYPE_INT:
1736                                 M_IST(s2, s1, disp);
1737                                 break;
1738                         case TYPE_LNG:
1739                                 M_STX(s2, s1, disp);
1740                                 break;
1741                         case TYPE_ADR:
1742                                 M_AST(s2, s1, disp);
1743                                 break;
1744                         case TYPE_FLT:
1745                                 M_FST(s2, s1, disp);
1746                                 break;
1747                         case TYPE_DBL:
1748                                 M_DST(s2, s1, disp);
1749                                 break;
1750                         default:
1751                                 assert(0);
1752                                 break;
1753                         }
1754                         break;
1755
1756                 case ICMD_PUTFIELDCONST:  /* ..., objectref  ==> ...                  */
1757                                           /* val = value (in current instruction)     */
1758                                           /* following NOP)                           */
1759
1760                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1761                         emit_nullpointer_check(cd, iptr, s1);
1762
1763                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1764                                 unresolved_field *uf = iptr->sx.s23.s3.uf;
1765
1766                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1767
1768                                 codegen_addpatchref(cd, PATCHER_get_putfield,
1769                                                                         uf, 0);
1770
1771                                 if (opt_showdisassemble) {
1772                                         M_NOP; M_NOP;
1773                                 }
1774
1775                                 disp = 0;
1776
1777                         } else {
1778                         {
1779                                 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1780
1781                                 fieldtype = fi->type;
1782                                 disp = fi->offset;
1783                         }
1784
1785                         }
1786
1787                         switch (fieldtype) {
1788                         case TYPE_INT:
1789                                 M_IST(REG_ZERO, s1, disp);
1790                                 break;
1791                         case TYPE_LNG:
1792                                 M_STX(REG_ZERO, s1, disp);
1793                                 break;
1794                         case TYPE_ADR:
1795                                 M_AST(REG_ZERO, s1, disp);
1796                                 break;
1797                         case TYPE_FLT:
1798                                 M_FST(REG_ZERO, s1, disp);
1799                                 break;
1800                         case TYPE_DBL:
1801                                 M_DST(REG_ZERO, s1, disp);
1802                                 break;
1803                         }
1804                         break;
1805
1806
1807                 /* branch operations **************************************************/
1808
1809                 case ICMD_ATHROW:       /* ..., objectref ==> ... (, objectref)       */
1810
1811                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1812                         M_INTMOVE(s1, REG_ITMP2_XPTR);
1813
1814 #ifdef ENABLE_VERIFIER
1815                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1816                                 unresolved_class *uc = iptr->sx.s23.s2.uc;
1817
1818                                 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
1819                         }
1820 #endif /* ENABLE_VERIFIER */
1821
1822                         disp = dseg_add_functionptr(cd, asm_handle_exception);
1823                         M_ALD(REG_ITMP1, REG_PV, disp);
1824                         M_JMP(REG_ITMP3_XPC, REG_ITMP1, REG_ZERO);
1825                         M_NOP;
1826                         M_NOP;              /* nop ensures that XPC is less than the end */
1827                                             /* of basic block                            */
1828                         ALIGNCODENOP;
1829                         break;
1830
1831                 case ICMD_GOTO:         /* ... ==> ...                                */
1832                 case ICMD_RET:          /* ... ==> ...                                */
1833
1834                         emit_br(cd, iptr->dst.block);
1835                         ALIGNCODENOP;
1836                         break;
1837
1838                 case ICMD_JSR:          /* ... ==> ...                                */
1839
1840                         emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
1841                         ALIGNCODENOP;
1842                         break;
1843
1844                 case ICMD_IFNULL:       /* ..., value ==> ...                         */
1845                 case ICMD_IFNONNULL:
1846
1847                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1848                         emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE);
1849                         break;
1850                         
1851                 /* Note: int compares must not branch on the register directly.       */
1852                 /* Reason is, that register content is not 32-bit clean.              */
1853
1854                 case ICMD_IFEQ:         /* ..., value ==> ...                         */
1855
1856                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1857                         
1858                         if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1859                                 M_CMP_IMM(s1, iptr->sx.val.i);
1860                         }
1861                         else {
1862                                 ICONST(REG_ITMP2, iptr->sx.val.i);
1863                                 M_CMP(s1, REG_ITMP2);
1864                         }
1865                         emit_beq(cd, iptr->dst.block);
1866                         break;
1867
1868                 case ICMD_IFLT:         /* ..., value ==> ...                         */
1869
1870                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1871                         
1872                         if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1873                                 M_CMP_IMM(s1, iptr->sx.val.i);
1874                         } 
1875                         else {
1876                                 ICONST(REG_ITMP2, iptr->sx.val.i);
1877                                 M_CMP(s1, REG_ITMP2);
1878                         }
1879                         emit_blt(cd, iptr->dst.block);
1880                         break;
1881
1882                 case ICMD_IFLE:         /* ..., value ==> ...                         */
1883
1884                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1885
1886                         if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1887                                 M_CMP_IMM(s1, iptr->sx.val.i);
1888                         }
1889                         else {
1890                                 ICONST(REG_ITMP2, iptr->sx.val.i);
1891                                 M_CMP(s1, REG_ITMP2);
1892                         }
1893                         emit_ble(cd, iptr->dst.block);
1894                         break;
1895
1896                 case ICMD_IFNE:         /* ..., value ==> ...                         */
1897
1898                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1899                 
1900                         if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1901                                 M_CMP_IMM(s1, iptr->sx.val.i);
1902                         }
1903                         else {
1904                                 ICONST(REG_ITMP2, iptr->sx.val.i);
1905                                 M_CMP(s1, REG_ITMP2);
1906                         }
1907                         emit_bne(cd, iptr->dst.block);
1908                         break;
1909                                                 
1910                 case ICMD_IFGT:         /* ..., value ==> ...                         */
1911
1912                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1913                 
1914                         if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1915                                 M_CMP_IMM(s1, iptr->sx.val.i);
1916                         } 
1917                         else {
1918                                 ICONST(REG_ITMP2, iptr->sx.val.i);
1919                                 M_CMP(s1, REG_ITMP2);
1920                         }
1921                         emit_bgt(cd, iptr->dst.block);          
1922                         break;
1923
1924                 case ICMD_IFGE:         /* ..., value ==> ...                         */
1925
1926                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1927
1928                         if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1929                                 M_CMP_IMM(s1, iptr->sx.val.i);
1930                         }
1931                         else {
1932                                 ICONST(REG_ITMP2, iptr->sx.val.i);
1933                                 M_CMP(s1, REG_ITMP2);
1934                         }
1935                         emit_bge(cd, iptr->dst.block);
1936                         break;
1937                         
1938                 case ICMD_IF_LEQ:       /* ..., value ==> ...                         */
1939
1940                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1941                         if (iptr->sx.val.l == 0)
1942                                 emit_beqz(cd, iptr->dst.block, s1);
1943                         else {
1944                                 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1945                                         M_CMP_IMM(s1, iptr->sx.val.l);
1946                                 }
1947                                 else {
1948                                         LCONST(REG_ITMP2, iptr->sx.val.l);
1949                                         M_CMP(s1, REG_ITMP2);
1950                                 }
1951                                 emit_beq_xcc(cd, iptr->dst.block);
1952                         }
1953                         break;
1954                         
1955                 case ICMD_IF_LLT:       /* ..., value ==> ...                         */
1956
1957                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1958                         if (iptr->sx.val.l == 0)
1959                                 emit_bltz(cd, iptr->dst.block, s1);
1960                         else {
1961                                 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1962                                         M_CMP_IMM(s1, iptr->sx.val.l);
1963                                 } 
1964                                 else {
1965                                         LCONST(REG_ITMP2, iptr->sx.val.l);
1966                                         M_CMP(s1, REG_ITMP2);
1967                                 }
1968                                 emit_blt_xcc(cd, iptr->dst.block);
1969                         }
1970                         break;
1971
1972                 case ICMD_IF_LLE:       /* ..., value ==> ...                         */
1973
1974                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1975                         if (iptr->sx.val.l == 0)
1976                                 emit_blez(cd, iptr->dst.block, s1);
1977                         else {
1978                                 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1979                                         M_CMP_IMM(s1, iptr->sx.val.l);
1980                                 }
1981                                 else {
1982                                         LCONST(REG_ITMP2, iptr->sx.val.l);
1983                                         M_CMP(s1, REG_ITMP2);
1984                                 }
1985                                 emit_ble_xcc(cd, iptr->dst.block);
1986                         }
1987                         break;
1988                         
1989                 case ICMD_IF_LNE:       /* ..., value ==> ...                         */
1990
1991                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1992                         if (iptr->sx.val.l == 0)
1993                                 emit_bnez(cd, iptr->dst.block, s1);
1994                         else {
1995                                 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1996                                         M_CMP_IMM(s1, iptr->sx.val.l);
1997                                 }
1998                                 else {
1999                                         LCONST(REG_ITMP2, iptr->sx.val.l);
2000                                         M_CMP(s1, REG_ITMP2);
2001                                 }
2002                                 emit_bne_xcc(cd, iptr->dst.block);
2003                         }
2004                         break;
2005                                                 
2006                 case ICMD_IF_LGT:       /* ..., value ==> ...                         */
2007
2008                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2009                         if (iptr->sx.val.l == 0)
2010                                 emit_bgtz(cd, iptr->dst.block, s1);
2011                         else {
2012                                 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2013                                         M_CMP_IMM(s1, iptr->sx.val.l);
2014                                 } 
2015                                 else {
2016                                         LCONST(REG_ITMP2, iptr->sx.val.l);
2017                                         M_CMP(s1, REG_ITMP2);
2018                                 }
2019                                 emit_bgt_xcc(cd, iptr->dst.block);
2020                         }
2021                         break;
2022
2023                 case ICMD_IF_LGE:       /* ..., value ==> ...                         */
2024
2025                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2026                         if (iptr->sx.val.l == 0)
2027                                 emit_bgez(cd, iptr->dst.block, s1);
2028                         else {
2029                                 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2030                                         M_CMP_IMM(s1, iptr->sx.val.l);
2031                                 }
2032                                 else {
2033                                         LCONST(REG_ITMP2, iptr->sx.val.l);
2034                                         M_CMP(s1, REG_ITMP2);
2035                                 }
2036                                 emit_bge_xcc(cd, iptr->dst.block);
2037                         }
2038                         break;                  
2039                         
2040
2041                 case ICMD_IF_ACMPEQ:    /* ..., value, value ==> ...                  */
2042                 case ICMD_IF_LCMPEQ:    /* op1 = target JavaVM pc                     */
2043
2044                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2045                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2046                         M_CMP(s1, s2);
2047                         emit_beq_xcc(cd, iptr->dst.block);
2048                         break;
2049
2050                 case ICMD_IF_ICMPEQ:    /* 32-bit compare                             */
2051
2052                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2053                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2054                         M_CMP(s1, s2);
2055                         emit_beq(cd, iptr->dst.block);
2056                         break;
2057
2058                 case ICMD_IF_ACMPNE:    /* ..., value, value ==> ...                  */
2059                 case ICMD_IF_LCMPNE:    /* op1 = target JavaVM pc                     */
2060
2061                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2062                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2063                         M_CMP(s1, s2);
2064                         emit_bne_xcc(cd, iptr->dst.block);
2065                         break;
2066                         
2067                 case ICMD_IF_ICMPNE:    /* 32-bit compare                             */
2068
2069                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2070                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2071                         M_CMP(s1, s2);
2072                         emit_bne(cd, iptr->dst.block);
2073                         break;
2074
2075                 case ICMD_IF_LCMPLT:    /* ..., value, value ==> ...                  */
2076
2077                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2078                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2079                         M_CMP(s1, s2);
2080                         emit_blt_xcc(cd, iptr->dst.block);
2081                         break;
2082                         
2083                 case ICMD_IF_ICMPLT:    /* 32-bit compare                             */
2084
2085                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2086                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2087                         M_CMP(s1, s2);
2088                         emit_blt(cd, iptr->dst.block);
2089                         break;
2090
2091                 case ICMD_IF_LCMPGT:    /* ..., value, value ==> ...                  */
2092
2093                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2094                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2095                         M_CMP(s1, s2);
2096                         emit_bgt_xcc(cd, iptr->dst.block);
2097                         break;
2098                         
2099                 case ICMD_IF_ICMPGT:    /* 32-bit compare                             */
2100
2101                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2102                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2103                         M_CMP(s1, s2);
2104                         emit_bgt(cd, iptr->dst.block);
2105                         break;
2106
2107                 case ICMD_IF_LCMPLE:    /* ..., value, value ==> ...                  */
2108
2109                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2110                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2111                         M_CMP(s1, s2);
2112                         emit_ble_xcc(cd, iptr->dst.block);
2113                         break;
2114                         
2115                 case ICMD_IF_ICMPLE:    /* 32-bit compare                             */
2116
2117                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2118                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2119                         M_CMP(s1, s2);
2120                         emit_ble(cd, iptr->dst.block);
2121                         break;                  
2122         
2123
2124                 case ICMD_IF_LCMPGE:    /* ..., value, value ==> ...                  */
2125
2126                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2127                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2128                         M_CMP(s1, s2);
2129                         emit_bge_xcc(cd, iptr->dst.block);
2130                         break;
2131                         
2132                 case ICMD_IF_ICMPGE:    /* 32-bit compare                             */
2133
2134                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2135                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2136                         M_CMP(s1, s2);
2137                         emit_bge(cd, iptr->dst.block);
2138                         break;
2139
2140
2141                 case ICMD_IRETURN:      /* ..., retvalue ==> ...                      */
2142                 case ICMD_LRETURN:
2143
2144                         s1 = emit_load_s1(jd, iptr, REG_RESULT_CALLEE);
2145                         M_INTMOVE(s1, REG_RESULT_CALLEE);
2146                         goto nowperformreturn;
2147
2148                 case ICMD_ARETURN:      /* ..., retvalue ==> ...                      */
2149
2150                         s1 = emit_load_s1(jd, iptr, REG_RESULT_CALLEE);
2151                         M_INTMOVE(s1, REG_RESULT_CALLEE);
2152
2153 #ifdef ENABLE_VERIFIER
2154                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2155                                 unresolved_class *uc = iptr->sx.s23.s2.uc;
2156
2157                                 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2158                         }
2159 #endif /* ENABLE_VERIFIER */
2160                         goto nowperformreturn;
2161
2162                 case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
2163                 case ICMD_DRETURN:
2164
2165                         s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2166                         M_DBLMOVE(s1, REG_FRESULT);
2167                         goto nowperformreturn;
2168
2169                 case ICMD_RETURN:       /* ...  ==> ...                               */
2170
2171 nowperformreturn:
2172                         {
2173                         s4 i, p;
2174                         
2175                         p = cd->stackframesize;
2176
2177 #if !defined(NDEBUG)
2178                         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2179                                 emit_verbosecall_exit(jd);
2180 #endif
2181
2182 #if defined(ENABLE_THREADS)
2183                         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2184 /* XXX: REG_RESULT is save, but what about FRESULT? */
2185                                 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8); /* XXX: what for ? */
2186
2187                                 switch (iptr->opc) {
2188                                 case ICMD_FRETURN:
2189                                 case ICMD_DRETURN:
2190                                         M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2191                                         break;
2192                                 }
2193
2194                                 disp = dseg_add_functionptr(cd, BUILTIN_monitorexit);
2195                                 M_ALD(REG_ITMP3, REG_PV, disp);
2196                                 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); /*REG_RA_CALLER */
2197
2198                                 switch (iptr->opc) {
2199                                 case ICMD_FRETURN:
2200                                 case ICMD_DRETURN:
2201                                         M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2202                                         break;
2203                                 }
2204                         }
2205 #endif
2206
2207
2208
2209                         M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
2210                         M_NOP;
2211                         ALIGNCODENOP;
2212                         }
2213                         break;
2214
2215                 case ICMD_TABLESWITCH:  /* ..., index ==> ...                         */
2216                         {
2217                         s4 i, l;
2218                         branch_target_t *table;
2219
2220                         table = iptr->dst.table;
2221
2222                         l = iptr->sx.s23.s2.tablelow;
2223                         i = iptr->sx.s23.s3.tablehigh;
2224                         
2225                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2226                         if (l == 0) {
2227                                 M_INTMOVE(s1, REG_ITMP1);
2228                         }
2229                         else if (l <= 4095) {
2230                                 M_ADD_IMM(s1, -l, REG_ITMP1);
2231                         }
2232                         else {
2233                                 ICONST(REG_ITMP2, l);
2234                                 /* XXX: do I need to truncate s1 to 32-bit ? */
2235                                 M_SUB(s1, REG_ITMP2, REG_ITMP1);
2236                         }
2237                         i = i - l + 1;
2238
2239
2240                         /* range check */
2241                                         
2242                         if (i <= 4095) {
2243                                 M_CMP_IMM(REG_ITMP1, i - 1);
2244                         }
2245                         else {
2246                                 ICONST(REG_ITMP2, i - 1);
2247                                 M_CMP(REG_ITMP1, REG_ITMP2);
2248                         }               
2249                         emit_bugt(cd, table[0].block); /* default target */
2250
2251                         /* build jump table top down and use address of lowest entry */
2252
2253                         table += i;
2254
2255                         while (--i >= 0) {
2256                                 dseg_add_target(cd, table->block); 
2257                                 --table;
2258                                 }
2259                         }
2260
2261                         /* length of dataseg after last dseg_addtarget is used by load */
2262
2263                         M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);
2264                         M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2265                         M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2266                         M_JMP(REG_ZERO, REG_ITMP2, REG_ZERO);
2267                         M_NOP;
2268                         ALIGNCODENOP;
2269                         break;
2270                         
2271                 case ICMD_LOOKUPSWITCH: /* ..., key ==> ...                           */
2272                         {
2273                         s4 i;
2274                         lookup_target_t *lookup;
2275
2276                         lookup = iptr->dst.lookup;
2277
2278                         i = iptr->sx.s23.s2.lookupcount;
2279                         
2280                         MCODECHECK((i<<2)+8);
2281                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2282
2283                         while (--i >= 0) {
2284                                 if ((lookup->value >= -4096) && (lookup->value <= 4095)) {
2285                                         M_CMP_IMM(s1, lookup->value);
2286                                 } else {                                        
2287                                         ICONST(REG_ITMP2, lookup->value);
2288                                         M_CMP(s1, REG_ITMP2);
2289                                 }
2290                                 emit_beq(cd, lookup->target.block);
2291                                 ++lookup;
2292                         }
2293
2294                         emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2295                         ALIGNCODENOP;
2296                         break;
2297                         }
2298
2299
2300                 case ICMD_BUILTIN:      /* ..., arg1, arg2, arg3 ==> ...              */
2301
2302                         bte = iptr->sx.s23.s3.bte;
2303                         md = bte->md;
2304                         
2305                         /* XXX: builtin calling with stack arguments not implemented */
2306                         assert(md->paramcount <= 5 && md->argfltreguse <= 16);
2307                         
2308                         s3 = md->paramcount;
2309
2310                         MCODECHECK((s3 << 1) + 64);
2311
2312                         /* copy float arguments according to ABI convention */
2313
2314                         int num_fltregargs = 0;
2315                         int fltregarg_inswap[16];
2316
2317                         for (s3 = s3 - 1; s3 >= 0; s3--) {
2318                                 var = VAR(iptr->sx.s23.s2.args[s3]);
2319
2320                                 if (IS_FLT_DBL_TYPE(var->type)) {
2321                                         if (!md->params[s3].inmemory) {
2322                                                 s1 = s3; /*native flt args use argument index directly*/
2323                                                 d = emit_load(jd, iptr, var, REG_FTMP1);
2324                                                 
2325                                                 M_DMOV(d, s1 + 16);
2326                                                 fltregarg_inswap[num_fltregargs] = s1;
2327                                                 num_fltregargs++;
2328                                                 /*printf("builtin: flt arg swap to %d\n", s1 + 16);*/
2329                                         }
2330                                         else {
2331                                                 assert(0);
2332                                         }
2333                                 }
2334                         }
2335                         
2336                         int i;
2337                         /* move swapped float args to target regs */
2338                         for (i = 0; i < num_fltregargs; i++) {
2339                                 s1 = fltregarg_inswap[i];
2340                                 M_DMOV(s1 + 16, s1);
2341                                 /*printf("builtin float arg to target reg: %d ==> %d\n", s1+16, s1);*/
2342                         }
2343                         
2344                         goto gen_method;
2345
2346                 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ...            */
2347
2348                 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2349                 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer    */
2350                 case ICMD_INVOKEINTERFACE:
2351
2352                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2353                                 lm = NULL;
2354                                 um = iptr->sx.s23.s3.um;
2355                                 md = um->methodref->parseddesc.md;
2356                         }
2357                         else {
2358                                 lm = iptr->sx.s23.s3.fmiref->p.method;
2359                                 um = NULL;
2360                                 md = lm->parseddesc;
2361                         }
2362
2363 gen_method:
2364                         s3 = md->paramcount;
2365
2366                         MCODECHECK((s3 << 1) + 64);
2367
2368                         /* copy arguments to registers or stack location                  */
2369
2370                         for (s3 = s3 - 1; s3 >= 0; s3--) {
2371                                 var = VAR(iptr->sx.s23.s2.args[s3]);
2372                                 d  = md->params[s3].regoff;
2373
2374                                 if (var->flags & PREALLOC)
2375                                         continue;
2376
2377                                 if (IS_INT_LNG_TYPE(var->type)) {
2378                                         if (!md->params[s3].inmemory) {
2379                                                 s1 = emit_load(jd, iptr, var, d);
2380                                                 M_INTMOVE(s1, d);
2381                                         } 
2382                                         else {
2383                                                 s1 = emit_load(jd, iptr, var, REG_ITMP1);
2384                                                 M_STX(s1, REG_SP, JITSTACK + d * 8);
2385                                         }
2386                                 }
2387                                 else {
2388                                         if (iptr->opc == ICMD_BUILTIN)
2389                                                 continue;
2390                                                 
2391                                         if (!md->params[s3].inmemory) {
2392                                                 s1 = emit_load(jd, iptr, var, d);
2393                                                 if (IS_2_WORD_TYPE(var->type))
2394                                                         M_DMOV(s1, d);
2395                                                 else
2396                                                         M_FMOV(s1, d);
2397                                         }
2398                                         else {
2399                                                 s1 = emit_load(jd, iptr, var, REG_FTMP1);
2400                                                 if (IS_2_WORD_TYPE(var->type))
2401                                                         M_DST(s1, REG_SP, JITSTACK + d * 8);
2402                                                 else
2403                                                         M_FST(s1, REG_SP, JITSTACK + d * 8);
2404                                         }
2405                                 }
2406                         }
2407
2408                         switch (iptr->opc) {
2409                         case ICMD_BUILTIN:
2410                                 disp = dseg_add_functionptr(cd, bte->fp);
2411
2412                                 M_ALD(REG_PV_CALLER, REG_PV, disp);  /* built-in-function pointer */
2413
2414                                 /* XXX jit-c-call */
2415                                 /* generate the actual call */
2416     
2417                             M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2418                             M_NOP;
2419                             disp = (s4) (cd->mcodeptr - cd->mcodebase);
2420                             /* REG_RA holds the value of the jmp instruction, therefore +8 */
2421                             M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8); 
2422
2423                                 emit_exception_check(cd, iptr);
2424                                 if (md->returntype.type == TYPE_FLT) {
2425                                         /* special handling for float return value in %f0 */
2426                                         M_FMOV_INTERN(0,1);
2427                                 }
2428                                 break;
2429
2430                         case ICMD_INVOKESPECIAL:
2431                                 emit_nullpointer_check(cd, iptr, REG_OUT0);
2432                                 /* fall-through */
2433
2434                         case ICMD_INVOKESTATIC:
2435                                 if (lm == NULL) {
2436                                         disp = dseg_add_unique_address(cd, NULL);
2437
2438                                         codegen_add_patch_ref(cd, PATCHER_invokestatic_special,
2439                                                                                 um, disp);
2440                                 }
2441                                 else
2442                                         disp = dseg_add_address(cd, lm->stubroutine);
2443
2444                                 M_ALD(REG_PV_CALLER, REG_PV, disp);          /* method pointer in pv */
2445                                 
2446                                 /* generate the actual call */
2447     
2448                             M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2449                             M_NOP;
2450                             disp = (s4) (cd->mcodeptr - cd->mcodebase);
2451                             /* REG_RA holds the value of the jmp instruction, therefore +8 */
2452                             M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8); 
2453                                 break;
2454
2455                         case ICMD_INVOKEVIRTUAL:
2456                                 emit_nullpointer_check(cd, iptr, REG_OUT0);
2457
2458                                 if (lm == NULL) {
2459                                         codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
2460
2461                                         s1 = 0;
2462                                 }
2463                                 else
2464                                         s1 = OFFSET(vftbl_t, table[0]) +
2465                                                 sizeof(methodptr) * lm->vftblindex;
2466
2467                                 /* implicit null-pointer check */
2468                                 M_ALD(REG_METHODPTR, REG_OUT0,OFFSET(java_objectheader, vftbl));
2469                                 M_ALD(REG_PV_CALLER, REG_METHODPTR, s1);
2470                                 
2471                                 /* generate the actual call */
2472     
2473                             M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2474                             M_NOP;
2475                             disp = (s4) (cd->mcodeptr - cd->mcodebase);
2476                             /* REG_RA holds the value of the jmp instruction, therefore +8 */
2477                             M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8); 
2478                                 break;
2479
2480                         case ICMD_INVOKEINTERFACE:
2481                                 emit_nullpointer_check(cd, iptr, REG_OUT0);
2482
2483                                 if (lm == NULL) {
2484                                         codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
2485
2486                                         s1 = 0;
2487                                         s2 = 0;
2488                                 } 
2489                                 else {
2490                                         s1 = OFFSET(vftbl_t, interfacetable[0]) -
2491                                                 sizeof(methodptr*) * lm->class->index;
2492
2493                                         s2 = sizeof(methodptr) * (lm - lm->class->methods);
2494                                 }
2495
2496                                 /* implicit null-pointer check */
2497                                 M_ALD(REG_METHODPTR, REG_OUT0, OFFSET(java_objectheader, vftbl));
2498                                 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2499                                 M_ALD(REG_PV_CALLER, REG_METHODPTR, s2);
2500
2501                             /* generate the actual call */
2502     
2503                             M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2504                             M_NOP;
2505                             disp = (s4) (cd->mcodeptr - cd->mcodebase);
2506                             /* REG_RA holds the value of the jmp instruction, therefore +8 */
2507                             M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2508                                 break;
2509                         }
2510
2511                         /* store return value */
2512
2513                         d = md->returntype.type;
2514
2515                         if (d != TYPE_VOID) {
2516                                 if (IS_INT_LNG_TYPE(d)) {
2517                                         s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_CALLER);
2518                                         M_INTMOVE(REG_RESULT_CALLER, s1);
2519                                 } 
2520                                 else {
2521                                         s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2522                                         if (IS_2_WORD_TYPE(d)) {
2523                                                 M_DBLMOVE(REG_FRESULT, s1);
2524                                         } else {
2525                                                 M_FLTMOVE(REG_FRESULT, s1);
2526                                         }
2527                                 }
2528                                 emit_store_dst(jd, iptr, s1);
2529                         }
2530                         break;
2531
2532
2533                 case ICMD_CHECKCAST:  /* ..., objectref ==> ..., objectref            */
2534                                       /* val.a: (classinfo*) superclass               */
2535
2536                         /*  superclass is an interface:
2537                          *
2538                          *  OK if ((sub == NULL) ||
2539                          *         (sub->vftbl->interfacetablelength > super->index) &&
2540                          *         (sub->vftbl->interfacetable[-super->index] != NULL));
2541                          *
2542                          *  superclass is a class:
2543                          *
2544                          *  OK if ((sub == NULL) || (0
2545                          *         <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2546                          *         super->vftbl->diffvall));
2547                          */
2548
2549                         if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2550                                 classinfo *super;
2551                                 s4         superindex;
2552
2553                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2554                                         super      = NULL;
2555                                         superindex = 0;
2556                                 }
2557                                 else {
2558                                         super = iptr->sx.s23.s3.c.cls;
2559                                         superindex = super->index;
2560                                 }
2561
2562 #if defined(ENABLE_THREADS)
2563                                 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2564 #endif
2565
2566                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2567
2568                                 /* if class is not resolved, check which code to call */
2569
2570                                 if (super == NULL) {
2571                                         emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2572
2573                                         cr   = iptr->sx.s23.s3.c.ref;
2574                                         disp = dseg_add_unique_s4(cd, 0);         /* super->flags */
2575
2576                                         codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2577                                                                                   cr, disp);
2578
2579                                         M_ILD(REG_ITMP2, REG_PV, disp);
2580                                         M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
2581                                         emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
2582                                 }
2583
2584                                 /* interface checkcast code */
2585
2586                                 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2587                                         if (super == NULL) {
2588                                                 cr = iptr->sx.s23.s3.c.ref;
2589
2590                                                 codegen_add_patch_ref(cd, PATCHER_checkcast_interface,
2591                                                                                           cr, 0);
2592                                         }
2593                                         else {
2594                                                 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2595                                         }
2596
2597                                         M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2598                                         M_ILD(REG_ITMP3, REG_ITMP2,
2599                                                         OFFSET(vftbl_t, interfacetablelength));
2600                                         M_ADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
2601                                         emit_classcast_check(cd, iptr, ICMD_IFLE, REG_ITMP3, s1);
2602
2603                                         M_ALD(REG_ITMP3, REG_ITMP2,
2604                                                   OFFSET(vftbl_t, interfacetable[0]) -
2605                                                   superindex * sizeof(methodptr*));
2606                                         emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_ITMP3, s1);
2607
2608                                         if (super == NULL)
2609                                                 emit_label_br(cd, BRANCH_LABEL_4);
2610                                         else
2611                                                 emit_label(cd, BRANCH_LABEL_3);
2612                                 }
2613
2614                                 /* class checkcast code */
2615
2616                                 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2617                                         if (super == NULL) {
2618                                                 emit_label(cd, BRANCH_LABEL_2);
2619
2620                                                 cr   = iptr->sx.s23.s3.c.ref;
2621                                                 disp = dseg_add_unique_address(cd, NULL);
2622
2623                                                 codegen_add_patch_ref(cd,
2624                                                                                         PATCHER_checkcast_instanceof_class,
2625                                                                                           cr, disp);
2626                                         }
2627                                         else {
2628                                                 disp = dseg_add_address(cd, super->vftbl);
2629
2630                                                 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2631                                         }
2632
2633                                         M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2634                                         M_ALD(REG_ITMP3, REG_PV, disp);
2635 #if defined(ENABLE_THREADS)
2636                                         codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
2637 #endif
2638                                         M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2639                                         M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2640                                         M_SUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2641                                         M_ALD(REG_ITMP3, REG_PV, disp);
2642                                         M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2643 #if defined(ENABLE_THREADS)
2644                                         codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
2645 #endif
2646                                         /*                              } */
2647                                         M_CMP(REG_ITMP3, REG_ITMP2);
2648                                         emit_classcast_check(cd, iptr, BRANCH_ULT, REG_ITMP3, s1);
2649
2650                                         if (super != NULL)
2651                                                 emit_label(cd, BRANCH_LABEL_5);
2652                                 }
2653
2654                                 if (super == NULL) {
2655                                         emit_label(cd, BRANCH_LABEL_1);
2656                                         emit_label(cd, BRANCH_LABEL_4);
2657                                 }
2658
2659                                 d = codegen_reg_of_dst(jd, iptr, s1);
2660                         }
2661                         else {
2662                                 /* array type cast-check */
2663
2664                                 s1 = emit_load_s1(jd, iptr, REG_OUT0);
2665                                 M_INTMOVE(s1, REG_OUT0);
2666
2667                                 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2668
2669                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2670                                         cr   = iptr->sx.s23.s3.c.ref;
2671                                         disp = dseg_add_unique_address(cd, NULL);
2672
2673                                         codegen_add_patch_ref(cd, PATCHER_builtin_arraycheckcast,
2674                                                                                   cr, disp);
2675                                 }
2676                                 else
2677                                         disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2678
2679                                 M_ALD(REG_OUT1, REG_PV, disp);
2680                                 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
2681                                 M_ALD(REG_ITMP3, REG_PV, disp);
2682                                 /* XXX jit-c-call */
2683                                 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2684                                 M_NOP;
2685
2686                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2687                                 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT_CALLER, s1);
2688
2689                                 d = codegen_reg_of_dst(jd, iptr, s1);
2690                         }
2691
2692                         M_INTMOVE(s1, d);
2693                         emit_store_dst(jd, iptr, d);
2694                         break;
2695
2696                 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
2697                                       /* val.a: (classinfo*) superclass               */
2698
2699                         /*  superclass is an interface:
2700                          *      
2701                          *  return (sub != NULL) &&
2702                          *         (sub->vftbl->interfacetablelength > super->index) &&
2703                          *         (sub->vftbl->interfacetable[-super->index] != NULL);
2704                          *      
2705                          *  superclass is a class:
2706                          *      
2707                          *  return ((sub != NULL) && (0
2708                          *          <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2709                          *          super->vftbl->diffvall));
2710                          */
2711
2712                         {
2713                         classinfo *super;
2714                         vftbl_t   *supervftbl;
2715                         s4         superindex;
2716
2717                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2718                                 super = NULL;
2719                                 superindex = 0;
2720                                 supervftbl = NULL;
2721
2722                         } else {
2723                                 super = iptr->sx.s23.s3.c.cls;
2724                                 superindex = super->index;
2725                                 supervftbl = super->vftbl;
2726                         }
2727
2728 #if defined(ENABLE_THREADS)
2729                         codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2730 #endif
2731                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2732                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2733                         if (s1 == d) {
2734                                 M_MOV(s1, REG_ITMP1);
2735                                 s1 = REG_ITMP1;
2736                         }
2737
2738                         M_CLR(d);
2739
2740                         /* if class is not resolved, check which code to call */
2741
2742                         if (super == NULL) {
2743                                 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2744
2745                                 cr   = iptr->sx.s23.s3.c.ref;
2746                                 disp = dseg_add_unique_s4(cd, 0);             /* super->flags */
2747
2748                                 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2749                                                                           cr, disp);
2750
2751                                 M_ILD(REG_ITMP3, REG_PV, disp);
2752                                 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
2753                                 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
2754                         }
2755
2756                         /* interface instanceof code */
2757
2758                         if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2759                                 if (super == NULL) {
2760                                         cr = iptr->sx.s23.s3.c.ref;
2761
2762                                         codegen_add_patch_ref(cd, PATCHER_instanceof_interface,
2763                                                                                   cr, 0);
2764                                 }
2765                                 else {
2766                                         emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2767                                 }
2768
2769                                 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2770                                 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2771                                 M_CMP_IMM(REG_ITMP3, superindex);
2772                                 M_BLE(4);
2773                                 M_NOP;
2774                                 M_ALD(REG_ITMP1, REG_ITMP1,
2775                                           (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2776                                                         superindex * sizeof(methodptr*)));
2777                                 M_CMOVRNE_IMM(REG_ITMP1, 1, d);      /* REG_ITMP1 != 0  */
2778
2779                                 if (super == NULL)
2780                                         emit_label_br(cd, BRANCH_LABEL_4);
2781                                 else
2782                                         emit_label(cd, BRANCH_LABEL_3);
2783                         }
2784
2785                         /* class instanceof code */
2786
2787                         if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2788                                 if (super == NULL) {
2789                                         emit_label(cd, BRANCH_LABEL_2);
2790
2791                                         cr   = iptr->sx.s23.s3.c.ref;
2792                                         disp = dseg_add_unique_address(cd, NULL);
2793
2794                                         codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_class,
2795                                                                                   cr, disp);
2796                                 }
2797                                 else {
2798                                         disp = dseg_add_address(cd, supervftbl);
2799
2800                                         emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2801                                 }
2802
2803                                 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2804                                 M_ALD(REG_ITMP2, REG_PV, disp);
2805 #if defined(ENABLE_THREADS)
2806                                 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
2807 #endif
2808                                 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
2809                                 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
2810                                 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
2811 #if defined(ENABLE_THREADS)
2812                                 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
2813 #endif
2814                                 M_SUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
2815                                 M_CMP(REG_ITMP1, REG_ITMP2);
2816                                 M_XCMOVULE_IMM(1, d);
2817
2818                                 if (super != NULL)
2819                                         emit_label(cd, BRANCH_LABEL_5);
2820                         }
2821
2822                         if (super == NULL) {
2823                                 emit_label(cd, BRANCH_LABEL_1);
2824                                 emit_label(cd, BRANCH_LABEL_4);
2825                         }
2826
2827                         emit_store_dst(jd, iptr, d);
2828                         }
2829                         break;
2830
2831                 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref  */
2832
2833                         /* check for negative sizes and copy sizes to stack if necessary  */
2834
2835                         MCODECHECK((iptr->s1.argcount << 1) + 64);
2836
2837                         for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2838
2839                                 var = VAR(iptr->sx.s23.s2.args[s1]);
2840         
2841                                 /* copy SAVEDVAR sizes to stack */
2842
2843                                 /* Already Preallocated? */
2844
2845                                 if (!(var->flags & PREALLOC)) {
2846                                         s2 = emit_load(jd, iptr, var, REG_ITMP1);
2847                                         M_STX(s2, REG_SP, CSTACK + (s1 * 8));
2848                                 }
2849                         }
2850
2851                         /* arg 0 = dimension count */
2852
2853                         ICONST(REG_OUT0, iptr->s1.argcount);
2854
2855                         /* is patcher function set? */
2856
2857                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2858                                 disp = dseg_add_unique_address(cd, 0);
2859
2860                                 codegen_add_patch_ref(cd, PATCHER_builtin_multianewarray,
2861                                                                           iptr->sx.s23.s3.c.ref,
2862                                                                           disp);
2863                         }
2864                         else
2865                                 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2866
2867                         /* arg 1 = arraydescriptor */
2868
2869                         M_ALD(REG_OUT1, REG_PV, disp);
2870
2871                         /* arg 2 = pointer to dimensions = stack pointer (absolute) */
2872
2873                         M_ADD_IMM(REG_SP, CSTACK, REG_OUT2);
2874
2875                         /* XXX c abi call */
2876                         disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
2877                         M_ALD(REG_ITMP3, REG_PV, disp);
2878                         M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2879                         M_NOP;
2880
2881                         /* check for exception before result assignment */
2882
2883                         emit_exception_check(cd, iptr);
2884
2885                         d = codegen_reg_of_dst(jd, iptr, REG_RESULT_CALLER);
2886                         M_INTMOVE(REG_RESULT_CALLER, d);
2887                         emit_store_dst(jd, iptr, d);
2888                         break;
2889
2890                 default:
2891                         exceptions_throw_internalerror("Unknown ICMD %d during code generation",
2892                                                                                    iptr->opc);
2893                         return false;
2894                         
2895         } /* switch */
2896                 
2897         } /* for instruction */
2898         
2899
2900                 
2901         } /* if (bptr -> flags >= BBREACHED) */
2902         } /* for basic block */
2903         
2904         dseg_createlinenumbertable(cd);
2905
2906         /* generate stubs */
2907
2908         emit_patcher_stubs(jd);
2909         REPLACEMENT_EMIT_STUBS(jd);
2910         
2911         /* everything's ok */
2912
2913         return true;    
2914 }
2915
2916
2917 /* codegen_emit_stub_compiler **************************************************
2918
2919    Emits a stub routine which calls the compiler.
2920         
2921 *******************************************************************************/
2922
2923 void codegen_emit_stub_compiler(jitdata *jd)
2924 {
2925         methodinfo  *m;
2926         codegendata *cd;
2927
2928         /* get required compiler data */
2929
2930         m  = jd->m;
2931         cd = jd->cd;
2932
2933         /* code for the stub */
2934
2935         /* no window save yet, user caller's PV */
2936         M_ALD_INTERN(REG_ITMP1, REG_PV_CALLER, -2 * SIZEOF_VOID_P);  /* codeinfo pointer */
2937         M_ALD_INTERN(REG_PV_CALLER, REG_PV_CALLER, -3 * SIZEOF_VOID_P);  /* pointer to compiler */
2938         M_JMP(REG_ZERO, REG_PV_CALLER, REG_ZERO);  /* jump to the compiler, RA is wasted */
2939         M_NOP;
2940 }
2941
2942
2943 /* codegen_emit_stub_native ****************************************************
2944
2945    Emits a stub routine which calls a native method.
2946
2947 *******************************************************************************/
2948
2949 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
2950 {
2951         methodinfo   *m;
2952         codeinfo     *code;
2953         codegendata  *cd;
2954         methoddesc   *md;
2955         s4            nativeparams;
2956         s4            i, j;                 /* count variables                    */
2957         s4            t;
2958         s4            s1, s2, disp;
2959         s4            funcdisp;             /* displacement of the function       */
2960
2961         /* get required compiler data */
2962
2963         m    = jd->m;
2964         code = jd->code;
2965         cd   = jd->cd;
2966
2967         /* initialize variables */
2968
2969         md = m->parseddesc;
2970         nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
2971
2972         /* calculate stack frame size */
2973
2974         cd->stackframesize =
2975                 sizeof(stackframeinfo) / SIZEOF_VOID_P +
2976                 sizeof(localref_table) / SIZEOF_VOID_P +
2977                 md->paramcount +                /* for saving arguments over calls    */
2978                 nmd->memuse +  /* nmd knows about the native stackframe layout */
2979                 WINSAVE_CNT;
2980
2981         /* create method header */
2982
2983         (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
2984         (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize       */
2985         (void) dseg_add_unique_s4(cd, 0);                      /* IsSync          */
2986         (void) dseg_add_unique_s4(cd, 0);                      /* IsLeaf          */
2987         (void) dseg_add_unique_s4(cd, 0);                      /* IntSave         */
2988         (void) dseg_add_unique_s4(cd, 0);                      /* FltSave         */
2989         (void) dseg_addlinenumbertablesize(cd);
2990         (void) dseg_add_unique_s4(cd, 0);                      /* ExTableSize     */
2991
2992         /* generate stub code */
2993
2994         M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP); /* build up stackframe    */
2995
2996 #if !defined(NDEBUG)
2997         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2998                 emit_verbosecall_enter(jd);
2999 #endif
3000
3001         /* get function address (this must happen before the stackframeinfo) */
3002
3003         funcdisp = dseg_add_functionptr(cd, f);
3004
3005 #if !defined(WITH_STATIC_CLASSPATH)
3006         if (f == NULL) {
3007                 codegen_add_patch_ref(cd, PATCHER_resolve_native, m, funcdisp);
3008         }
3009 #endif
3010
3011         /* save float argument registers */
3012
3013         for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3014                 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3015                         M_DST(abi_registers_float_argument[i], REG_SP, CSTACK + (j * 8));
3016                         j++;
3017                 }
3018         }
3019
3020         /* prepare data structures for native function call */
3021
3022         M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp == top of the stack frame (absolute == +BIAS) */
3023         M_MOV(REG_PV_CALLEE, REG_OUT1);
3024         M_MOV(REG_FP, REG_OUT2); /* java sp */
3025         M_MOV(REG_RA_CALLEE, REG_OUT3);
3026         disp = dseg_add_functionptr(cd, codegen_start_native_call);
3027         M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3028         M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3029         M_NOP; /* XXX fill me! */
3030
3031         /* restore float argument registers */
3032
3033         for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3034                 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3035                         M_DLD(abi_registers_float_argument[i], REG_SP, CSTACK + (j * 8));
3036                         j++;
3037                 }
3038         }
3039
3040         /* copy or spill arguments to new locations */
3041         int num_fltregargs = 0;
3042         int fltregarg_inswap[16];
3043         for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3044                 t = md->paramtypes[i].type;
3045
3046                 if (IS_INT_LNG_TYPE(t)) {
3047                         if (!md->params[i].inmemory) {
3048                                 s1 = md->params[i].regoff;
3049                                 /* s1 refers to the old window, transpose */
3050                                 s1 = REG_WINDOW_TRANSPOSE(s1);
3051
3052                                 if (!nmd->params[j].inmemory) {
3053                                         s2 = nat_argintregs[nmd->params[j].regoff];
3054                                         M_INTMOVE(s1, s2);
3055                                 } else {
3056                                         s2 = nmd->params[j].regoff - 6;
3057                                         M_AST(s1, REG_SP, CSTACK + s2 * 8);
3058                                 }
3059
3060                         } else {
3061                                 /*assert(false);*/
3062                                 s1 = md->params[i].regoff + cd->stackframesize;
3063                                 s2 = nmd->params[j].regoff - 6;
3064                                 M_ALD(REG_ITMP1, REG_SP, CSTACK + s1 * 8);
3065                                 M_AST(REG_ITMP1, REG_SP, CSTACK + s2 * 8);
3066                         }
3067
3068                 } else {
3069                         if (!md->params[i].inmemory) {
3070                                 s1 = md->params[i].regoff;
3071
3072                                 if (!nmd->params[j].inmemory) {
3073                                         /* no mapping to regs needed, native flt args use regoff */
3074                                         s2 = nmd->params[j].regoff;
3075                                         
3076                                         /* we cannot move flt regs to their native arg locations directly */
3077                                         M_DMOV(s1, s2 + 16);
3078                                         fltregarg_inswap[num_fltregargs] = s2;
3079                                         num_fltregargs++;
3080                                         /*printf("flt arg swap to %d\n", s2 + 16);*/
3081
3082                                 } else {
3083                                         s2 = nmd->params[j].regoff;
3084                                         if (IS_2_WORD_TYPE(t))
3085                                                 M_DST(s1, REG_SP, CSTACK + (s2 * 8));
3086                                         else
3087                                                 M_FST(s1, REG_SP, CSTACK + (s2 * 8));
3088                                 }
3089
3090                         } else {
3091                                 /*assert(false);*/
3092                                 s1 = md->params[i].regoff + cd->stackframesize;
3093                                 s2 = nmd->params[j].regoff - 6;
3094                                 if (IS_2_WORD_TYPE(t)) {
3095                                         M_DLD(REG_FTMP1, REG_SP, CSTACK + s1 * 8);
3096                                         M_DST(REG_FTMP1, REG_SP, CSTACK + s2 * 8);
3097                                 } else {
3098                                         M_FLD(REG_FTMP1, REG_SP, CSTACK + s1 * 8);
3099                                         M_FST(REG_FTMP1, REG_SP, CSTACK + s2 * 8);
3100                                 }
3101                         }
3102                 }
3103         }
3104         
3105         /* move swapped float args to target regs */
3106         for (i = 0; i < num_fltregargs; i++) {
3107                 s1 = fltregarg_inswap[i];
3108                 M_DMOV(s1 + 16, s1);
3109                 /*printf("float arg to target reg: %d ==> %d\n", s1+16, s1);*/
3110         }
3111
3112
3113         /* put class into second argument register */
3114
3115         if (m->flags & ACC_STATIC) {
3116                 disp = dseg_add_address(cd, m->class);
3117                 M_ALD(REG_OUT1, REG_PV_CALLEE, disp);
3118         }
3119
3120         /* put env into first argument register */
3121
3122         disp = dseg_add_address(cd, _Jv_env);
3123         M_ALD(REG_OUT0, REG_PV_CALLEE, disp);
3124
3125         /* do the native function call */
3126
3127         M_ALD(REG_ITMP3, REG_PV_CALLEE, funcdisp); /* load adress of native method       */
3128         M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); /* call native method                 */
3129         M_NOP;                              /* delay slot                         */
3130
3131         /* save return value */
3132
3133         if (md->returntype.type != TYPE_VOID) {
3134                 if (IS_INT_LNG_TYPE(md->returntype.type))
3135                         M_MOV(REG_RESULT_CALLER, REG_RESULT_CALLEE);
3136                 else
3137                         M_DST(REG_FRESULT, REG_SP, CSTACK);
3138         }
3139         
3140         /* Note: native functions return float values in %f0 (see ABI) */
3141         /* we handle this by doing M_FLD below. (which will load the lower word into %f1) */
3142
3143 #if !defined(NDEBUG)
3144         /* But for the trace function we need to put a flt result into %f1 */
3145         if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
3146                 if (!IS_2_WORD_TYPE(md->returntype.type))
3147                         M_FLD(REG_FRESULT, REG_SP, CSTACK);
3148                 emit_verbosecall_exit(jd);
3149         }
3150 #endif
3151
3152         /* remove native stackframe info */
3153
3154         M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp, like above */
3155         disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3156         M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3157         M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3158         M_NOP; /* XXX fill me! */
3159         M_MOV(REG_RESULT_CALLER, REG_ITMP2_XPTR);
3160
3161         /* restore float return value, int return value already in our return reg */
3162
3163         if (md->returntype.type != TYPE_VOID) {
3164                 if (IS_FLT_DBL_TYPE(md->returntype.type)) {
3165                         if (IS_2_WORD_TYPE(md->returntype.type))
3166                                 M_DLD(REG_FRESULT, REG_SP, CSTACK);
3167                         else
3168                                 M_FLD(REG_FRESULT, REG_SP, CSTACK);
3169                 }
3170         }
3171
3172         /* check for exception */
3173         M_BNEZ(REG_ITMP2_XPTR, 4);          /* if no exception then return        */
3174         M_NOP;
3175
3176         M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
3177         M_NOP;
3178
3179         /* handle exception */
3180         
3181         disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3182         M_ALD(REG_ITMP1, REG_PV, disp);     /* load asm exception handler address */
3183         M_MOV(REG_RA_CALLEE, REG_ITMP3_XPC); /* get exception address             */
3184         M_JMP(REG_ZERO, REG_ITMP1, REG_ZERO);/* jump to asm exception handler     */
3185         M_RESTORE(REG_ZERO, 0, REG_ZERO);   /* restore callers window (DELAY)     */
3186         
3187         /* generate patcher stubs */
3188
3189         emit_patcher_stubs(jd);
3190 }
3191
3192 /*
3193  * These are local overrides for various environment variables in Emacs.
3194  * Please do not remove this and leave it at the end of the file, where
3195  * Emacs will automagically detect them.
3196  * ---------------------------------------------------------------------
3197  * Local variables:
3198  * mode: c
3199  * indent-tabs-mode: t
3200  * c-basic-offset: 4
3201  * tab-width: 4
3202  * End:
3203  * vim:noexpandtab:sw=4:ts=4:
3204  */