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