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