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