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