Merged changes 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 #include <stdio.h>
38
39 #include "config.h"
40 #include "vm/types.h"
41
42 #include "md-abi.h"
43
44 /* #include "vm/jit/sparc64/arch.h" */
45 #include "vm/jit/sparc64/codegen.h"
46
47 #include "mm/memory.h"
48
49 #include "native/jni.h"
50 #include "native/native.h"
51 #include "vm/builtin.h"
52 #include "vm/exceptions.h"
53 #include "vm/global.h"
54 #include "vm/loader.h"
55 #include "vm/options.h"
56 #include "vm/stringlocal.h"
57 #include "vm/jit/asmpart.h"
58 #include "vm/jit/codegen-common.h"
59 #include "vm/jit/dseg.h"
60 #include "vm/jit/emit.h"
61 #include "vm/jit/jit.h"
62 #include "vm/jit/parse.h"
63 #include "vm/jit/patcher.h"
64 #include "vm/jit/reg.h"
65
66
67 #define REG_PV (own_window?REG_PV_CALLEE:REG_PV_CALLER)
68
69 static int fabort(char *x)
70 {
71     fprintf(stderr, "sparc64 abort because: %s\n", x);
72     exit(1);
73     abort();
74     return 0;
75                             
76 }
77
78
79 bool codegen(jitdata *jd)
80 {
81         methodinfo         *m;
82         codegendata        *cd;
83         registerdata       *rd;
84         s4                  len, s1, s2, s3, d, disp;
85         s4                  stackframesize;
86         s4                 *mcodeptr;
87         stackptr            src;
88         varinfo            *var;
89         basicblock         *bptr;
90         instruction        *iptr;
91         exceptiontable     *ex;
92         u2                  currentline;
93         methodinfo         *lm;             /* local methodinfo for ICMD_INVOKE*  */
94         builtintable_entry *bte;
95         methoddesc         *md;
96         rplpoint           *replacementpoint;
97
98         bool                            own_window = true; /* currently assumes immediate save*/
99         
100         /* get required compiler data */
101
102         m  = jd->m;
103         cd = jd->cd;
104         rd = jd->rd;
105         
106         
107         (void) dseg_addaddress(cd, m);                          /* MethodPointer  */
108         (void) dseg_adds4(cd, stackframesize * 8);              /* FrameSize      */
109
110 #if defined(USE_THREADS)
111         /* IsSync contains the offset relative to the stack pointer for the
112            argument of monitor_exit used in the exception handler. Since the
113            offset could be zero and give a wrong meaning of the flag it is
114            offset by one.
115         */
116
117         if (checksync && (m->flags & ACC_SYNCHRONIZED))
118                 (void) dseg_adds4(cd, (rd->memuse + 1) * 8);        /* IsSync         */
119         else
120 #endif
121                 (void) dseg_adds4(cd, 0);                           /* IsSync         */
122                                                
123         (void) dseg_adds4(cd, m->isleafmethod);                 /* IsLeaf         */
124         (void) dseg_adds4(cd, INT_SAV_CNT - rd->savintreguse);  /* IntSave        */
125         (void) dseg_adds4(cd, FLT_SAV_CNT - rd->savfltreguse);  /* FltSave        */
126         
127         
128         dseg_addlinenumbertablesize(cd);
129
130         (void) dseg_adds4(cd, cd->exceptiontablelength);        /* ExTableSize    */
131         
132         
133         
134         
135         /* XXX create exception table */
136         
137         /* initialize mcode variables */
138         mcodeptr = (s4 *) cd->mcodeptr;
139         
140         
141         /* XXX stack setup */
142         
143         
144         /* XXX copy arguments */
145         
146         
147         /* XXX monitor enter and tracing */
148         
149         
150         /* end of header generation */ 
151         
152         replacementpoint = jd->code->rplpoints;
153
154         /* walk through all basic blocks */
155
156         for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
157
158                 bptr->mpc = (s4) ((u1 *) mcodeptr - cd->mcodebase);
159
160                 if (bptr->flags >= BBREACHED) {
161
162                 /* branch resolving */
163
164                 {
165                 branchref *brefs;
166                 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
167                         gen_resolvebranch((u1*) cd->mcodebase + brefs->branchpos, 
168                                           brefs->branchpos, bptr->mpc);
169                         }
170                 }
171                 
172                 /* handle replacement points */
173
174                 if (bptr->bitflags & BBFLAG_REPLACEMENT) {
175                         replacementpoint->pc = (u1*)(ptrint)bptr->mpc; /* will be resolved later */
176                         
177                         replacementpoint++;
178                 }
179
180                 /* copy interface registers to their destination */
181
182                 src = bptr->instack;
183                 len = bptr->indepth;
184                 MCODECHECK(64+len);
185                 
186 #if defined(ENABLE_LSRA)
187                 if (opt_lsra) {
188                 while (src != NULL) {
189                         len--;
190                         if ((len == 0) && (bptr->type != BBTYPE_STD)) {
191                                         /*                              d = reg_of_var(m, src, REG_ITMP1); */
192                                         if (!(src->flags & INMEMORY))
193                                                 d = src->regoff;
194                                         else
195                                                 d = REG_ITMP1;
196                                         M_INTMOVE(REG_ITMP1, d);
197                                         emit_store(jd, NULL, src, d);
198                                 }
199                                 src = src->prev;
200                         }
201                 } else {
202 #endif
203                         while (src != NULL) {
204                                 len--;
205                                 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
206                                         d = codegen_reg_of_var(rd, 0, src, REG_ITMP1);
207                                         M_INTMOVE(REG_ITMP1, d);
208                                         emit_store(jd, NULL, src, d);
209
210                                 } else {
211                                         d = codegen_reg_of_var(rd, 0, src, REG_IFTMP);
212                                         if ((src->varkind != STACKVAR)) {
213                                                 s2 = src->type;
214                                                 if (IS_FLT_DBL_TYPE(s2)) {
215                                                         if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
216                                                                 s1 = rd->interfaces[len][s2].regoff;
217                                                                 M_DBLMOVE(s1, d);
218                                                         } else {
219                                                                 M_DLD(d, REG_SP, rd->interfaces[len][s2].regoff * 8);
220                                                         }
221                                                         emit_store(jd, NULL, src, d);
222
223                                                 } else {
224                                                         if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
225                                                                 s1 = rd->interfaces[len][s2].regoff;
226                                                                 M_INTMOVE(s1, d);
227                                                         } else {
228                                                                 M_LDX(d, REG_SP, rd->interfaces[len][s2].regoff * 8);
229                                                         }
230                                                         emit_store(jd, NULL, src, d);
231                                                 }
232                                         }
233                                 }
234                                 src = src->prev;
235                         }
236 #if defined(ENABLE_LSRA)
237                 }
238 #endif
239
240                 /* walk through all instructions */
241                 
242                 src = bptr->instack;
243                 len = bptr->icount;
244
245                 for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
246                         if (iptr->line != currentline) {
247                                 dseg_addlinenumber(cd, iptr->line);
248                                 currentline = iptr->line;
249                         }
250
251                 MCODECHECK(64);       /* an instruction usually needs < 64 words      */
252                 switch (iptr->opc) {
253
254                 case ICMD_INLINE_START:
255                 case ICMD_INLINE_END:
256                         break;
257
258                 case ICMD_NOP:        /* ...  ==> ...                                 */
259                         break;
260         
261                 /* constant operations ************************************************/
262
263                 case ICMD_ICONST:     /* ...  ==> ..., constant                       */
264                                       /* op1 = 0, val.i = constant                    */
265
266                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
267                         ICONST(d, iptr->val.i);
268                         emit_store(jd, iptr, iptr->dst, d);
269                         break;
270
271                 case ICMD_LCONST:     /* ...  ==> ..., constant                       */
272                                       /* op1 = 0, val.l = constant                    */
273
274                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
275                         LCONST(d, iptr->val.l);
276                         emit_store(jd, iptr, iptr->dst, d);
277                         break;  
278
279                 case ICMD_FCONST:     /* ...  ==> ..., constant                       */
280                                       /* op1 = 0, val.f = constant                    */
281
282                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
283                         disp = dseg_addfloat(cd, iptr->val.f);
284                         M_FLD(d, REG_PV, disp);
285                         emit_store(jd, iptr, iptr->dst, d);
286                         break;
287                         
288                 case ICMD_DCONST:     /* ...  ==> ..., constant                       */
289                                       /* op1 = 0, val.d = constant                    */
290
291                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
292                         disp = dseg_adddouble(cd, iptr->val.d);
293                         M_DLD(d, REG_PV, disp);
294                         emit_store(jd, iptr, iptr->dst, d);
295                         break;
296
297                 case ICMD_ACONST:     /* ...  ==> ..., constant                       */
298                                       /* op1 = 0, val.a = constant                    */
299
300                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
301
302                         if ((iptr->target != NULL) && (iptr->val.a == NULL)) {
303                                 disp = dseg_addaddress(cd, iptr->val.a);
304
305                                 codegen_addpatchref(cd, PATCHER_aconst,
306                                                                         (unresolved_class *) iptr->target, disp);
307
308                                 if (opt_showdisassemble) {
309                                         M_NOP;
310                                 }
311
312                                 M_ALD(REG_PV, disp, d);
313
314                         } else {
315                                 if (iptr->val.a == NULL) {
316                                         M_INTMOVE(REG_ZERO, d);
317                                 } else {
318                                         disp = dseg_addaddress(cd, iptr->val.a);
319                                         M_ALD(d, REG_PV, disp);
320                                 }
321                         }
322                         emit_store(jd, iptr, iptr->dst, d);
323                         break;
324
325
326                 /* load/store operations **********************************************/
327
328                 case ICMD_ILOAD:      /* ...  ==> ..., content of local variable      */
329                 case ICMD_LLOAD:      /* op1 = local variable                         */
330                 case ICMD_ALOAD:
331
332                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
333                         if ((iptr->dst->varkind == LOCALVAR) &&
334                             (iptr->dst->varnum == iptr->op1))
335                                 break;
336                         var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
337                         if (var->flags & INMEMORY) {
338                                 M_ALD(REG_SP, var->regoff * 8, d);
339                         } else {
340                                 M_INTMOVE(var->regoff, d);
341                         }
342                         emit_store(jd, iptr, iptr->dst, d);
343                         break;
344         
345                 case ICMD_FLOAD:      /* ...  ==> ..., content of local variable      */
346                 case ICMD_DLOAD:      /* op1 = local variable                         */
347
348                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
349                         if ((iptr->dst->varkind == LOCALVAR) &&
350                             (iptr->dst->varnum == iptr->op1))
351                                 break;
352                         var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
353                         if (var->flags & INMEMORY) {
354                                 M_DLD(d, REG_SP, var->regoff * 8);
355                         } else {
356                                 M_FLTMOVE(var->regoff, d);
357                         }
358                         emit_store(jd, iptr, iptr->dst, d);
359                         break;
360
361
362                 case ICMD_ISTORE:     /* ..., value  ==> ...                          */
363                 case ICMD_LSTORE:     /* op1 = local variable                         */
364                 case ICMD_ASTORE:
365
366                         if ((src->varkind == LOCALVAR) &&
367                             (src->varnum == iptr->op1))
368                                 break;
369                         var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
370                         if (var->flags & INMEMORY) {
371                                 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
372                                 M_STX(s1, REG_SP, var->regoff * 8);
373                         } else {
374                                 s1 = emit_load_s1(jd, iptr, src, var->regoff);
375                                 M_INTMOVE(s1, var->regoff);
376                         }
377                         break;
378
379                 case ICMD_FSTORE:     /* ..., value  ==> ...                          */
380                 case ICMD_DSTORE:     /* op1 = local variable                         */
381
382                         if ((src->varkind == LOCALVAR) &&
383                             (src->varnum == iptr->op1))
384                                 break;
385                         var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
386                         if (var->flags & INMEMORY) {
387                                 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
388                                 M_DST(s1, REG_SP, var->regoff * 8);
389                         } else {
390                                 s1 = emit_load_s1(jd, iptr, src, var->regoff);
391                                 M_FLTMOVE(s1, var->regoff);
392                         }
393                         break;
394         
395
396                 /* pop/dup/swap operations ********************************************/
397
398                 /* attention: double and longs are only one entry in CACAO ICMDs      */
399
400                 case ICMD_POP:        /* ..., value  ==> ...                          */
401                 case ICMD_POP2:       /* ..., value, value  ==> ...                   */
402                         break;
403
404                 case ICMD_DUP:        /* ..., a ==> ..., a, a                         */
405                         M_COPY(src, iptr->dst);
406                         break;
407
408                 case ICMD_DUP_X1:     /* ..., a, b ==> ..., b, a, b                   */
409
410                         M_COPY(src,       iptr->dst);
411                         M_COPY(src->prev, iptr->dst->prev);
412                         M_COPY(iptr->dst, iptr->dst->prev->prev);
413                         break;
414
415                 case ICMD_DUP_X2:     /* ..., a, b, c ==> ..., c, a, b, c             */
416
417                         M_COPY(src,             iptr->dst);
418                         M_COPY(src->prev,       iptr->dst->prev);
419                         M_COPY(src->prev->prev, iptr->dst->prev->prev);
420                         M_COPY(iptr->dst,       iptr->dst->prev->prev->prev);
421                         break;
422
423                 case ICMD_DUP2:       /* ..., a, b ==> ..., a, b, a, b                */
424
425                         M_COPY(src,       iptr->dst);
426                         M_COPY(src->prev, iptr->dst->prev);
427                         break;
428
429                 case ICMD_DUP2_X1:    /* ..., a, b, c ==> ..., b, c, a, b, c          */
430
431                         M_COPY(src,             iptr->dst);
432                         M_COPY(src->prev,       iptr->dst->prev);
433                         M_COPY(src->prev->prev, iptr->dst->prev->prev);
434                         M_COPY(iptr->dst,       iptr->dst->prev->prev->prev);
435                         M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev);
436                         break;
437
438                 case ICMD_DUP2_X2:    /* ..., a, b, c, d ==> ..., c, d, a, b, c, d    */
439
440                         M_COPY(src,                   iptr->dst);
441                         M_COPY(src->prev,             iptr->dst->prev);
442                         M_COPY(src->prev->prev,       iptr->dst->prev->prev);
443                         M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
444                         M_COPY(iptr->dst,             iptr->dst->prev->prev->prev->prev);
445                         M_COPY(iptr->dst->prev,       iptr->dst->prev->prev->prev->prev->prev);
446                         break;
447
448                 case ICMD_SWAP:       /* ..., a, b ==> ..., b, a                      */
449
450                         M_COPY(src,       iptr->dst->prev);
451                         M_COPY(src->prev, iptr->dst);
452                         break;
453
454
455                 /* integer operations *************************************************/
456
457                 case ICMD_INEG:       /* ..., value  ==> ..., - value                 */
458                 case ICMD_LNEG:
459
460                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
461                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
462                         M_SUB(REG_ZERO, s1, d);
463                         emit_store(jd, iptr, iptr->dst, d);
464                         break;
465
466                 case ICMD_I2L:        /* ..., value  ==> ..., value                   */
467
468                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
469                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
470                         M_INTMOVE(s1, d);
471                         emit_store(jd, iptr, iptr->dst, d);
472                         break;
473
474                 case ICMD_L2I:        /* ..., value  ==> ..., value                   */
475
476                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
477                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
478                         M_SRA_IMM(s1, 0, d); /* sign extend upper 32 bits */
479                         emit_store(jd, iptr, iptr->dst, d);
480                         break;
481
482                 case ICMD_INT2BYTE:   /* ..., value  ==> ..., value                   */
483
484                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
485                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
486                         M_SLLX_IMM(s1, 56, d);
487                         M_SRAX_IMM( d, 56, d);
488                         emit_store(jd, iptr, iptr->dst, d);
489                         break;
490
491                 case ICMD_INT2CHAR:   /* ..., value  ==> ..., value                   */
492                 case ICMD_INT2SHORT:
493
494                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
495                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
496                         M_SLLX_IMM(s1, 48, d);
497                         M_SRAX_IMM( d, 48, d);
498                         emit_store(jd, iptr, iptr->dst, d);
499                         break;
500
501                 case ICMD_IADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
502                 case ICMD_LADD:
503
504                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
505                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
506                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
507                         M_ADD(s1, s2, d);
508                         emit_store(jd, iptr, iptr->dst, d);
509                         break;
510
511                 case ICMD_IADDCONST:  /* ..., value  ==> ..., value + constant        */
512                                       /* val.i = constant                             */
513
514                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
515                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
516                         if ((iptr->val.i >= -4096) && (iptr->val.i <= 4095)) {
517                                 M_ADD_IMM(s1, iptr->val.i, d);
518                         } else {
519                                 ICONST(REG_ITMP2, iptr->val.i);
520                                 M_ADD(s1, REG_ITMP2, d);
521                         }
522                         emit_store(jd, iptr, iptr->dst, d);
523                         break;
524
525                 case ICMD_LADDCONST:  /* ..., value  ==> ..., value + constant        */
526                                       /* val.l = constant                             */
527
528                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
529                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
530                         if ((iptr->val.l >= -4096) && (iptr->val.l <= 4095)) {
531                                 M_ADD_IMM(s1, iptr->val.l, d);
532                         } else {
533                                 LCONST(REG_ITMP2, iptr->val.l);
534                                 M_ADD(s1, REG_ITMP2, d);
535                         }
536                         emit_store(jd, iptr, iptr->dst, d);
537                         break;
538
539                 case ICMD_ISUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
540                 case ICMD_LSUB: 
541
542                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
543                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
544                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
545                         M_SUB(s1, s2, d);
546                         emit_store(jd, iptr, iptr->dst, d);
547                         break;
548
549                 case ICMD_ISUBCONST:  /* ..., value  ==> ..., value + constant        */
550                                       /* val.i = constant                             */
551
552                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
553                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
554                         if ((iptr->val.i >= -4096) && (iptr->val.i <= 4095)) {
555                                 M_SUB_IMM(s1, iptr->val.i, d);
556                         } else {
557                                 ICONST(REG_ITMP2, iptr->val.i);
558                                 M_SUB(s1, REG_ITMP2, d);
559                         }
560                         emit_store(jd, iptr, iptr->dst, d);
561                         break;
562
563                 case ICMD_LSUBCONST:  /* ..., value  ==> ..., value - constant        */
564                                       /* val.l = constant                             */
565
566                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
567                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
568                         if ((iptr->val.l >= -4096) && (iptr->val.l <= 4095)) {
569                                 M_SUB_IMM(s1, iptr->val.l, d);
570                         } else {
571                                 LCONST(REG_ITMP2, iptr->val.l);
572                                 M_SUB(s1, REG_ITMP2, d);
573                         }
574                         emit_store(jd, iptr, iptr->dst, d);
575                         break;
576
577                 case ICMD_IMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
578                 case ICMD_LMUL:
579
580                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
581                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
582                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
583                         M_MULX(s1, s2, d);
584                         emit_store(jd, iptr, iptr->dst, d);
585                         break;
586
587                 case ICMD_IMULCONST:  /* ..., value  ==> ..., value * constant        */
588                                       /* val.i = constant                             */
589
590                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
591                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
592                         if ((iptr->val.i >= -4096) && (iptr->val.i <= 4095)) {
593                                 M_MULX_IMM(s1, iptr->val.i, d);
594                         } else {
595                                 ICONST(REG_ITMP2, iptr->val.i);
596                                 M_MULX(s1, REG_ITMP2, d);
597                         }
598                         emit_store(jd, iptr, iptr->dst, d);
599                         break;
600
601                 case ICMD_LMULCONST:  /* ..., value  ==> ..., value * constant        */
602                                       /* val.l = constant                             */
603
604                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
605                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
606                         if ((iptr->val.l >= -4096) && (iptr->val.l <= 4095)) {
607                                 M_MULX_IMM(s1, iptr->val.l, d);
608                         } else {
609                                 LCONST(REG_ITMP2, iptr->val.l);
610                                 M_MULX(s1, REG_ITMP2, d);
611                         }
612                         emit_store(jd, iptr, iptr->dst, d);
613                         break;
614
615                 case ICMD_IDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
616 /* XXX could also clear Y and use 32bit div */
617                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
618                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
619                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
620                         gen_div_check(s2);
621                         M_ISEXT(s1, s1);
622                         /* XXX trim s2 like s1 ? */
623                         M_DIVX(s1, s2, d);
624                         emit_store(jd, iptr, iptr->dst, d);
625                         break;
626
627                 case ICMD_LDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
628
629                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
630                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
631                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
632                         gen_div_check(s2);
633                         M_DIVX(s1, s2, d);
634                         emit_store(jd, iptr, iptr->dst, d);
635                         break;
636
637                 case ICMD_IREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
638
639                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
640                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
641                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP3);
642                         gen_div_check(s2);
643                         M_ISEXT(s1, s1);
644                         /* XXX trim s2 like s1 ? */
645                         M_DIVX(s1, s2, d);
646                         M_MULX(s2, d, d);
647                         M_SUB(s1, d, d);
648                         emit_store(jd, iptr, iptr->dst, d);
649                         break;
650
651                 case ICMD_LREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
652
653                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
654                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
655                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP3);
656                         gen_div_check(s2);
657                         M_DIVX(s1, s2, d);
658                         M_MULX(s2, d, d);
659                         M_SUB(s1, d, d);
660                         emit_store(jd, iptr, iptr->dst, d);
661                         break;
662
663                 case ICMD_IDIVPOW2:   /* ..., value  ==> ..., value << constant       */
664                 case ICMD_LDIVPOW2:   /* val.i = constant                             */
665                                       
666                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
667                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
668                         M_SRAX_IMM(s1, 63, REG_ITMP2);
669                         M_SRLX_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
670                         M_ADD(s1, REG_ITMP2, REG_ITMP2);
671                         M_SRAX_IMM(REG_ITMP2, iptr->val.i, d);
672                         emit_store(jd, iptr, iptr->dst, d);
673                         break;
674
675                 case ICMD_ISHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
676                 case ICMD_LSHL:
677
678                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
679                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
680                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
681                         M_SLLX(s1, s2, d);
682                         emit_store(jd, iptr, iptr->dst, d);
683                         break;
684
685                 case ICMD_ISHLCONST:  /* ..., value  ==> ..., value << constant       */
686                 case ICMD_LSHLCONST:  /* val.i = constant                             */
687
688                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
689                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
690                         M_SLLX_IMM(s1, iptr->val.i, d);
691                         emit_store(jd, iptr, iptr->dst, d);
692                         break;
693
694                 case ICMD_ISHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
695
696                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
697                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
698                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
699                         M_SRA(s1, s2, d);
700                         emit_store(jd, iptr, iptr->dst, d);
701                         break;
702
703                 case ICMD_ISHRCONST:  /* ..., value  ==> ..., value >> constant       */
704                                       /* val.i = constant                             */
705
706                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
707                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
708                         M_SRA_IMM(s1, iptr->val.i, d);
709                         emit_store(jd, iptr, iptr->dst, d);
710                         break;
711
712                 case ICMD_IUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
713
714                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
715                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
716                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
717                         M_SRL(s1, s2, d);
718                         emit_store(jd, iptr, iptr->dst, d);
719                         break;
720
721                 case ICMD_IUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
722                                       /* val.i = constant                             */
723
724                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
725                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
726                         M_SRL_IMM(s1, iptr->val.i, d);
727                         emit_store(jd, iptr, iptr->dst, d);
728                         break;
729
730                 case ICMD_LSHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
731
732                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
733                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
734                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
735                         M_SRAX(s1, s2, d);
736                         emit_store(jd, iptr, iptr->dst, d);
737                         break;
738
739                 case ICMD_LSHRCONST:  /* ..., value  ==> ..., value >> constant       */
740                                       /* val.i = constant                             */
741
742                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
743                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
744                         M_SRAX_IMM(s1, iptr->val.i, d);
745                         emit_store(jd, iptr, iptr->dst, d);
746                         break;
747
748                 case ICMD_LUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
749
750                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
751                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
752                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
753                         M_SRLX(s1, s2, d);
754                         emit_store(jd, iptr, iptr->dst, d);
755                         break;
756
757                 case ICMD_LUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
758                                       /* val.i = constant                             */
759
760                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
761                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
762                         M_SRLX_IMM(s1, iptr->val.i, d);
763                         emit_store(jd, iptr, iptr->dst, d);
764                         break;
765
766                 case ICMD_IAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
767                 case ICMD_LAND:
768
769                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
770                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
771                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
772                         M_AND(s1, s2, d);
773                         emit_store(jd, iptr, iptr->dst, d);
774                         break;
775
776                 case ICMD_IANDCONST:  /* ..., value  ==> ..., value & constant        */
777                                       /* val.i = constant                             */
778
779                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
780                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
781                         if ((iptr->val.i >= -4096) && (iptr->val.i <= 4095)) {
782                                 M_AND_IMM(s1, iptr->val.i, d);
783                         } else {
784                                 ICONST(REG_ITMP2, iptr->val.i);
785                                 M_AND(s1, REG_ITMP2, d);
786                         }
787                         emit_store(jd, iptr, iptr->dst, d);
788                         break;
789
790                 case ICMD_IREMPOW2:   /* ..., value  ==> ..., value % constant        */
791                                       /* val.i = constant                             */
792
793                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
794                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
795                         M_ISEXT(s1, s1); /* trim for 32-bit compare (BGEZ) */
796                         if (s1 == d) {
797                                 M_MOV(s1, REG_ITMP1);
798                                 s1 = REG_ITMP1;
799                         }
800                         if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
801                                 M_AND_IMM(s1, iptr->val.i, d);
802                                 M_BGEZ(s1, 4);
803                                 M_NOP;
804                                 M_SUB(REG_ZERO, s1, d);
805                                 M_AND_IMM(d, iptr->val.i, d);
806                         } else {
807                                 ICONST(REG_ITMP2, iptr->val.i);
808                                 M_AND(s1, REG_ITMP2, d);
809                                 M_BGEZ(s1, 4);
810                                 M_NOP;
811                                 M_SUB(REG_ZERO, s1, d);
812                                 M_AND(d, REG_ITMP2, d);
813                         }
814                         M_SUB(REG_ZERO, d, d);
815                         emit_store(jd, iptr, iptr->dst, d);
816                         break;
817
818                 case ICMD_LANDCONST:  /* ..., value  ==> ..., value & constant        */
819                                       /* val.l = constant                             */
820
821                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
822                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
823                         if ((iptr->val.l >= -4096) && (iptr->val.l <= 4095)) {
824                                 M_AND_IMM(s1, iptr->val.l, d);
825                         } else {
826                                 LCONST(REG_ITMP2, iptr->val.l);
827                                 M_AND(s1, REG_ITMP2, d);
828                         }
829                         emit_store(jd, iptr, iptr->dst, d);
830                         break;
831
832                 case ICMD_LREMPOW2:   /* ..., value  ==> ..., value % constant        */
833                                       /* val.l = constant                             */
834
835                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
836                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
837                         if (s1 == d) {
838                                 M_MOV(s1, REG_ITMP1);
839                                 s1 = REG_ITMP1;
840                         }
841                         if ((iptr->val.l >= -4096) && (iptr->val.l <= 4095)) {
842                                 M_AND_IMM(s1, iptr->val.l, d);
843                                 M_BGEZ(s1, 4);
844                                 M_NOP;
845                                 M_SUB(REG_ZERO, s1, d);
846                                 M_AND_IMM(d, iptr->val.l, d);
847                         } else {
848                                 LCONST(REG_ITMP2, iptr->val.l);
849                                 M_AND(s1, REG_ITMP2, d);
850                                 M_BGEZ(s1, 4);
851                                 M_NOP;
852                                 M_SUB(REG_ZERO, s1, d);
853                                 M_AND(d, REG_ITMP2, d);
854                         }
855                         M_SUB(REG_ZERO, d, d);
856                         emit_store(jd, iptr, iptr->dst, d);
857                         break;
858
859                 case ICMD_IOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
860                 case ICMD_LOR:
861
862                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
863                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
864                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
865                         M_OR(s1,s2, d);
866                         emit_store(jd, iptr, iptr->dst, d);
867                         break;
868
869                 case ICMD_IORCONST:   /* ..., value  ==> ..., value | constant        */
870                                       /* val.i = constant                             */
871
872                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
873                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
874                         if ((iptr->val.i >= -4096) && (iptr->val.i <= 4095)) {
875                                 M_OR_IMM(s1, iptr->val.i, d);
876                         } else {
877                                 ICONST(REG_ITMP2, iptr->val.i);
878                                 M_OR(s1, REG_ITMP2, d);
879                         }
880                         emit_store(jd, iptr, iptr->dst, d);
881                         break;
882
883                 case ICMD_LORCONST:   /* ..., value  ==> ..., value | constant        */
884                                       /* val.l = constant                             */
885
886                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
887                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
888                         if ((iptr->val.l >= -4096) && (iptr->val.l <= 4095)) {
889                                 M_OR_IMM(s1, iptr->val.l, d);
890                         } else {
891                                 LCONST(REG_ITMP2, iptr->val.l);
892                                 M_OR(s1, REG_ITMP2, d);
893                         }
894                         emit_store(jd, iptr, iptr->dst, d);
895                         break;
896
897                 case ICMD_IXOR:       /* ..., val1, val2  ==> ..., val1 ^ val2        */
898                 case ICMD_LXOR:
899
900                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
901                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
902                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
903                         M_XOR(s1, s2, d);
904                         emit_store(jd, iptr, iptr->dst, d);
905                         break;
906
907                 case ICMD_IXORCONST:  /* ..., value  ==> ..., value ^ constant        */
908                                       /* val.i = constant                             */
909
910                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
911                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
912                         if ((iptr->val.i >= -4096) && (iptr->val.i <= 4095)) {
913                                 M_XOR_IMM(s1, iptr->val.i, d);
914                         } else {
915                                 ICONST(REG_ITMP2, iptr->val.i);
916                                 M_XOR(s1, REG_ITMP2, d);
917                         }
918                         emit_store(jd, iptr, iptr->dst, d);
919                         break;
920
921                 case ICMD_LXORCONST:  /* ..., value  ==> ..., value ^ constant        */
922                                       /* val.l = constant                             */
923
924                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
925                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
926                         if ((iptr->val.l >= -4096) && (iptr->val.l <= 4095)) {
927                                 M_XOR_IMM(s1, iptr->val.l, d);
928                         } else {
929                                 LCONST(REG_ITMP2, iptr->val.l);
930                                 M_XOR(s1, REG_ITMP2, d);
931                         }
932                         emit_store(jd, iptr, iptr->dst, d);
933                         break;
934
935
936                 case ICMD_LCMP:       /* ..., val1, val2  ==> ..., val1 cmp val2      */
937
938                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
939                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
940                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
941                         M_CMP(s1, s2);
942                         M_MOV(REG_ZERO, d);
943                         M_XCMOVLT_IMM(-1, d);
944                         M_XCMOVGT_IMM(1, d);
945                         emit_store(jd, iptr, iptr->dst, d);
946                         break;
947
948
949                 case ICMD_IINC:       /* ..., value  ==> ..., value + constant        */
950                                       /* op1 = variable, val.i = constant             */
951
952                         var = &(rd->locals[iptr->op1][TYPE_INT]);
953                         if (var->flags & INMEMORY) {
954                                 s1 = REG_ITMP1;
955                                 M_LDX(s1, REG_SP, var->regoff * 8);
956                         } else
957                                 s1 = var->regoff;
958                         if ((iptr->val.i >= -4096) && (iptr->val.i <= 4095)) {
959                                 M_ADD_IMM(s1, iptr->val.i, s1);
960                         } else {
961                                 ICONST(REG_ITMP2, iptr->val.i);
962                                 M_ADD(s1, REG_ITMP2, s1);
963                         }
964                         if (var->flags & INMEMORY)
965                                 M_STX(s1, REG_SP, var->regoff * 8);
966                         break;
967
968
969                 /* floating operations ************************************************/
970
971                 case ICMD_FNEG:       /* ..., value  ==> ..., - value                 */
972
973                         s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
974                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
975                         M_FNEG(s1, d);
976                         emit_store(jd, iptr, iptr->dst, d);
977                         break;
978
979                 case ICMD_DNEG:       /* ..., value  ==> ..., - value                 */
980
981                         s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
982                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
983                         M_DNEG(s1, d);
984                         emit_store(jd, iptr, iptr->dst, d);
985                         break;
986
987                 case ICMD_FADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
988
989                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
990                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
991                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
992                         M_FADD(s1, s2, d);
993                         emit_store(jd, iptr, iptr->dst, d);
994                         break;
995
996                 case ICMD_DADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
997
998                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
999                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1000                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1001                         M_DADD(s1, s2, d);
1002                         emit_store(jd, iptr, iptr->dst, d);
1003                         break;
1004
1005                 case ICMD_FSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
1006
1007                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1008                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1009                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1010                         M_FSUB(s1, s2, d);
1011                         emit_store(jd, iptr, iptr->dst, d);
1012                         break;
1013
1014                 case ICMD_DSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
1015
1016                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1017                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1018                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1019                         M_DSUB(s1, s2, d);
1020                         emit_store(jd, iptr, iptr->dst, d);
1021                         break;
1022
1023                 case ICMD_FMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
1024
1025                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1026                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1027                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1028                         M_FMUL(s1, s2, d);
1029                         emit_store(jd, iptr, iptr->dst, d);
1030                         break;
1031
1032                 case ICMD_DMUL:       /* ..., val1, val2  ==> ..., val1 *** val2      */
1033
1034                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1035                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1036                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1037                         M_DMUL(s1, s2, d);
1038                         emit_store(jd, iptr, iptr->dst, d);
1039                         break;
1040
1041                 case ICMD_FDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1042
1043                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1044                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1045                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1046                         M_FDIV(s1, s2, d);
1047                         emit_store(jd, iptr, iptr->dst, d);
1048                         break;
1049
1050                 case ICMD_DDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1051
1052                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1053                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1054                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1055                         M_DDIV(s1, s2, d);
1056                         emit_store(jd, iptr, iptr->dst, d);
1057                         break;  
1058
1059                 case ICMD_I2F:
1060                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1061                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1062                         disp = dseg_addfloat(cd, 0.0);
1063                         M_IST (s1, REG_PV_CALLEE, disp);
1064                         M_FLD (d, REG_PV_CALLEE, disp);
1065                         M_CVTIF (d, d); /* rd gets translated to double target register */
1066                         emit_store(jd, iptr, iptr->dst, d);
1067                         break;
1068                         
1069                 case ICMD_I2D:
1070                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1071                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1072                         disp = dseg_adddouble(cd, 0.0);
1073                         M_STX (s1, REG_PV_CALLEE, disp);
1074                         M_DLD (REG_FTMP2, REG_PV_CALLEE, disp); /* REG_FTMP2 needs to be a double temp */
1075                         M_CVTLF (REG_FTMP2, d); /* rd gets translated to double target register */
1076                         emit_store(jd, iptr, iptr->dst, d);
1077                         break;
1078
1079                 case ICMD_F2I:       /* ..., value  ==> ..., (int) value              */
1080                         s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1081                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP3);
1082                         disp = dseg_addfloat(cd, 0.0);
1083                         M_CVTFI(s1, REG_FTMP2);
1084                         M_FST(REG_FTMP2, REG_PV_CALLEE, disp);
1085                         M_ILD(d, REG_PV, disp);
1086                         emit_store(jd, iptr, iptr->dst, d);
1087                         break;
1088                         
1089                                
1090                 case ICMD_D2I:       /* ..., value  ==> ..., (int) value             */
1091                         s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1092                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP3);
1093                         disp = dseg_addfloat(cd, 0.0);
1094                         M_CVTDI(s1, REG_FTMP2);
1095                         M_FST(REG_FTMP2, REG_PV, disp);
1096                         M_ILD(d, REG_PV, disp);
1097                         emit_store(jd, iptr, iptr->dst, d);
1098                         break;
1099
1100                 case ICMD_F2L:       /* ..., value  ==> ..., (long) value             */
1101                         s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1102                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP3);
1103                         disp = dseg_adddouble(cd, 0.0);
1104                         M_CVTFL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
1105                         M_DST(REG_FTMP2, REG_PV, disp);
1106                         M_LDX(d, REG_PV, disp);
1107                         emit_store(jd, iptr, iptr->dst, d);
1108                         break;
1109                         
1110                 case ICMD_D2L:       /* ..., value  ==> ..., (long) value             */
1111                         s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1112                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP3);
1113                         disp = dseg_adddouble(cd, 0.0);
1114                         M_CVTDL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
1115                         M_DST(REG_FTMP2, REG_PV, disp);
1116                         M_LDX(d, REG_PV, disp);
1117                         emit_store(jd, iptr, iptr->dst, d);
1118                         break;
1119
1120                 case ICMD_F2D:       /* ..., value  ==> ..., (double) value           */
1121
1122                         s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1123                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1124                         M_CVTFD(s1, d);
1125                         emit_store(jd, iptr, iptr->dst, d);
1126                         break;
1127                                         
1128                 case ICMD_D2F:       /* ..., value  ==> ..., (float) value            */
1129
1130                         s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1131                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1132                         M_CVTDF(s1, d);
1133                         emit_store(jd, iptr, iptr->dst, d);
1134                         break;
1135         
1136         /* XXX merge F/D versions? only compare instr. is different */
1137                 case ICMD_FCMPL:      /* ..., val1, val2  ==> ..., val1 fcmpl val2    */
1138
1139                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1140                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1141                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP3);
1142                         M_FCMP(s1,s2);
1143                         M_OR_IMM(REG_ZERO, -1, REG_ITMP3); /* less by default (less or unordered) */
1144                         M_CMOVFEQ_IMM(0, REG_ITMP3); /* 0 if equal */
1145                         M_CMOVFGT_IMM(1, REG_ITMP3); /* 1 if greater */
1146                         emit_store(jd, iptr, iptr->dst, d);
1147                         break;
1148                         
1149                 case ICMD_DCMPL:      /* ..., val1, val2  ==> ..., val1 fcmpl val2    */
1150
1151                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1152                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1153                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP3);
1154                         M_DCMP(s1,s2);
1155                         M_OR_IMM(REG_ZERO, -1, REG_ITMP3); /* less by default (less or unordered) */
1156                         M_CMOVFEQ_IMM(0, REG_ITMP3); /* 0 if equal */
1157                         M_CMOVFGT_IMM(1, REG_ITMP3); /* 1 if greater */
1158                         emit_store(jd, iptr, iptr->dst, d);
1159                         break;
1160                         
1161                 case ICMD_FCMPG:      /* ..., val1, val2  ==> ..., val1 fcmpg val2    */
1162
1163                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1164                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1165                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP3);    
1166                         M_FCMP(s1,s2);
1167                         M_OR_IMM(REG_ZERO, 1, REG_ITMP3); /* greater by default (greater or unordered) */
1168                         M_CMOVFEQ_IMM(0, REG_ITMP3); /* 0 if equal */
1169                         M_CMOVFLT_IMM(-1, REG_ITMP3); /* -1 if less */
1170                         emit_store(jd, iptr, iptr->dst, d);
1171                         break;
1172                         
1173                 case ICMD_DCMPG:      /* ..., val1, val2  ==> ..., val1 fcmpg val2    */
1174
1175                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1176                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1177                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP3);    
1178                         M_DCMP(s1,s2);
1179                         M_OR_IMM(REG_ZERO, 1, REG_ITMP3); /* greater by default (greater or unordered) */
1180                         M_CMOVFEQ_IMM(0, REG_ITMP3); /* 0 if equal */
1181                         M_CMOVFLT_IMM(-1, REG_ITMP3); /* -1 if less */
1182                         emit_store(jd, iptr, iptr->dst, d);
1183                         break;
1184                         
1185
1186                 /* memory operations **************************************************/
1187
1188                 case ICMD_ARRAYLENGTH: /* ..., arrayref  ==> ..., length              */
1189
1190                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1191                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1192                         gen_nullptr_check(s1);
1193                         M_ILD(d, s1, OFFSET(java_arrayheader, size));
1194                         emit_store(jd, iptr, iptr->dst, d);
1195                         break;
1196
1197                 case ICMD_BALOAD:     /* ..., arrayref, index  ==> ..., value         */
1198
1199                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1200                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1201                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1202                         if (iptr->op1 == 0) {
1203                                 gen_nullptr_check(s1);
1204                                 gen_bound_check;
1205                         }
1206                         M_AADD(s2, s1, REG_ITMP3);
1207                         M_BLDS(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1208                         emit_store(jd, iptr, iptr->dst, d);
1209                         break;
1210
1211                 case ICMD_CALOAD:     /* ..., arrayref, index  ==> ..., value         */
1212
1213                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1214                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1215                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1216                         if (iptr->op1 == 0) {
1217                                 gen_nullptr_check(s1);
1218                                 gen_bound_check;
1219                         }
1220                         M_AADD(s2, s1, REG_ITMP3);
1221                         M_AADD(s2, REG_ITMP3, REG_ITMP3);
1222                         M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1223                         emit_store(jd, iptr, iptr->dst, d);
1224                         break;                  
1225
1226                 case ICMD_SALOAD:     /* ..., arrayref, index  ==> ..., value         */
1227
1228                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1229                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1230                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1231                         if (iptr->op1 == 0) {
1232                                 gen_nullptr_check(s1);
1233                                 gen_bound_check;
1234                         }
1235                         M_AADD(s2, s1, REG_ITMP3);
1236                         M_AADD(s2, REG_ITMP3, REG_ITMP3);
1237                         M_SLDS(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1238                         emit_store(jd, iptr, iptr->dst, d);
1239                         break;
1240
1241                 case ICMD_IALOAD:     /* ..., arrayref, index  ==> ..., value         */
1242
1243                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1244                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1245                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1246                         if (iptr->op1 == 0) {
1247                                 gen_nullptr_check(s1);
1248                                 gen_bound_check;
1249                         }
1250                         M_ASLL_IMM(s2, 2, REG_ITMP3);
1251                         M_AADD(REG_ITMP3, s1, REG_ITMP3);
1252                         M_ILD(d, REG_ITMP3, OFFSET(java_intarray, data[0]));
1253                         emit_store(jd, iptr, iptr->dst, d);
1254                         break;
1255
1256                 case ICMD_LALOAD:     /* ..., arrayref, index  ==> ..., value         */
1257
1258                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1259                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1260                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1261                         if (iptr->op1 == 0) {
1262                                 gen_nullptr_check(s1);
1263                                 gen_bound_check;
1264                         }
1265                         M_ASLL_IMM(s2, 3, REG_ITMP3);
1266                         M_AADD(REG_ITMP3, s1, REG_ITMP3);
1267                         M_LDX(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
1268                         emit_store(jd, iptr, iptr->dst, d);
1269                         break;
1270
1271                 case ICMD_FALOAD:     /* ..., arrayref, index  ==> ..., value         */
1272
1273                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1274                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1275                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1276                         if (iptr->op1 == 0) {
1277                                 gen_nullptr_check(s1);
1278                                 gen_bound_check;
1279                         }
1280                         M_ASLL_IMM(s2, 2, REG_ITMP3);
1281                         M_AADD(REG_ITMP3, s1, REG_ITMP3);
1282                         M_FLD(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
1283                         emit_store(jd, iptr, iptr->dst, d);
1284                         break;
1285
1286                 case ICMD_DALOAD:     /* ..., arrayref, index  ==> ..., value         */
1287
1288                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1289                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1290                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1291                         if (iptr->op1 == 0) {
1292                                 gen_nullptr_check(s1);
1293                                 gen_bound_check;
1294                         }
1295                         M_ASLL_IMM(s2, 3, REG_ITMP3);
1296                         M_AADD(REG_ITMP3, s1, REG_ITMP3);
1297                         M_DLD(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
1298                         emit_store(jd, iptr, iptr->dst, d);
1299                         break;
1300
1301                 case ICMD_AALOAD:     /* ..., arrayref, index  ==> ..., value         */
1302
1303                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1304                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1305                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1306                         if (iptr->op1 == 0) {
1307                                 gen_nullptr_check(s1);
1308                                 gen_bound_check;
1309                         }
1310                         M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1311                         M_AADD(REG_ITMP3, s1, REG_ITMP3);
1312                         M_ALD(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
1313                         emit_store(jd, iptr, iptr->dst, d);
1314                         break;
1315
1316         
1317                 case ICMD_BASTORE:    /* ..., arrayref, index, value  ==> ...         */
1318
1319                         s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1320                         s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1321                         if (iptr->op1 == 0) {
1322                                 gen_nullptr_check(s1);
1323                                 gen_bound_check;
1324                         }
1325                         M_AADD(s2, s1, REG_ITMP1);
1326                         s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1327                         M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1328                         break;
1329
1330                 case ICMD_CASTORE:    /* ..., arrayref, index, value  ==> ...         */
1331                 case ICMD_SASTORE:    /* ..., arrayref, index, value  ==> ...         */
1332
1333                         s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1334                         s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1335                         if (iptr->op1 == 0) {
1336                                 gen_nullptr_check(s1);
1337                                 gen_bound_check;
1338                         }
1339                         M_AADD(s2, s1, REG_ITMP1);
1340                         M_AADD(s2, REG_ITMP1, REG_ITMP1);
1341                         s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1342                         M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1343                         break;
1344
1345                 case ICMD_IASTORE:    /* ..., arrayref, index, value  ==> ...         */
1346
1347                         s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1348                         s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1349                         if (iptr->op1 == 0) {
1350                                 gen_nullptr_check(s1);
1351                                 gen_bound_check;
1352                         }
1353                         M_ASLL_IMM(s2, 2, REG_ITMP2);
1354                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1355                         s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1356                         M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1357                         break;
1358
1359                 case ICMD_LASTORE:    /* ..., arrayref, index, value  ==> ...         */
1360
1361                         s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1362                         s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1363                         if (iptr->op1 == 0) {
1364                                 gen_nullptr_check(s1);
1365                                 gen_bound_check;
1366                         }
1367                         M_ASLL_IMM(s2, 3, REG_ITMP2);
1368                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1369                         s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1370                         M_STX_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1371                         break;
1372
1373                 case ICMD_FASTORE:    /* ..., arrayref, index, value  ==> ...         */
1374
1375                         s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1376                         s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1377                         if (iptr->op1 == 0) {
1378                                 gen_nullptr_check(s1);
1379                                 gen_bound_check;
1380                         }
1381                         M_ASLL_IMM(s2, 2, REG_ITMP2);
1382                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1383                         s3 = emit_load_s3(jd, iptr, src, REG_FTMP1);
1384                         M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1385                         break;
1386
1387                 case ICMD_DASTORE:    /* ..., arrayref, index, value  ==> ...         */
1388
1389                         s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1390                         s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1391                         if (iptr->op1 == 0) {
1392                                 gen_nullptr_check(s1);
1393                                 gen_bound_check;
1394                         }
1395                         M_ASLL_IMM(s2, 3, REG_ITMP2);
1396                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1397                         s3 = emit_load_s3(jd, iptr, src, REG_FTMP1);
1398                         M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1399                         break;
1400
1401
1402                 case ICMD_AASTORE:    /* ..., arrayref, index, value  ==> ...         */
1403
1404                         s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1405                         s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1406                         if (iptr->op1 == 0) {
1407                                 gen_nullptr_check(s1);
1408                                 gen_bound_check;
1409                         }
1410                         s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1411
1412                         M_MOV(s1, rd->argintregs[0]);
1413                         M_MOV(s3, rd->argintregs[1]);
1414                         disp = dseg_addaddress(cd, BUILTIN_canstore);
1415                         M_ALD(REG_ITMP3, REG_PV, disp);
1416                         M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
1417                         M_NOP;
1418
1419                         M_BEQZ(REG_RESULT_CALLER, 0);
1420                         codegen_add_arraystoreexception_ref(cd);
1421                         M_NOP;
1422
1423                         s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1424                         s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1425                         M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1426                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1427                         s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1428                         M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1429                         break;
1430
1431
1432                 case ICMD_BASTORECONST:   /* ..., arrayref, index  ==> ...            */
1433
1434                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1435                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1436                         if (iptr->op1 == 0) {
1437                                 gen_nullptr_check(s1);
1438                                 gen_bound_check;
1439                         }
1440                         M_AADD(s2, s1, REG_ITMP1);
1441                         M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1442                         break;
1443
1444                 case ICMD_CASTORECONST:   /* ..., arrayref, index  ==> ...            */
1445                 case ICMD_SASTORECONST:   /* ..., arrayref, index  ==> ...            */
1446
1447                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1448                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1449                         if (iptr->op1 == 0) {
1450                                 gen_nullptr_check(s1);
1451                                 gen_bound_check;
1452                         }
1453                         M_AADD(s2, s1, REG_ITMP1);
1454                         M_AADD(s2, REG_ITMP1, REG_ITMP1);
1455                         M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1456                         break;
1457
1458                 case ICMD_IASTORECONST:   /* ..., arrayref, index  ==> ...            */
1459
1460                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1461                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1462                         if (iptr->op1 == 0) {
1463                                 gen_nullptr_check(s1);
1464                                 gen_bound_check;
1465                         }
1466                         M_ASLL_IMM(s2, 2, REG_ITMP2);
1467                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1468                         M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1469                         break;
1470
1471                 case ICMD_LASTORECONST:   /* ..., arrayref, index  ==> ...            */
1472
1473                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1474                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1475                         if (iptr->op1 == 0) {
1476                                 gen_nullptr_check(s1);
1477                                 gen_bound_check;
1478                         }
1479                         M_ASLL_IMM(s2, 3, REG_ITMP2);
1480                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1481                         M_STX_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1482                         break;
1483
1484                 case ICMD_AASTORECONST:   /* ..., arrayref, index  ==> ...            */
1485
1486                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1487                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1488                         if (iptr->op1 == 0) {
1489                                 gen_nullptr_check(s1);
1490                                 gen_bound_check;
1491                         }
1492                         M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1493                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1494                         M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1495                         break;
1496                 
1497
1498                 case ICMD_GETSTATIC:  /* ...  ==> ..., value                          */
1499                                       /* op1 = type, val.a = field address            */
1500
1501                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1502                                 disp = dseg_addaddress(cd, NULL);
1503
1504                                 codegen_addpatchref(cd, PATCHER_get_putstatic,
1505                                                                         INSTRUCTION_UNRESOLVED_FIELD(iptr), disp);
1506
1507                                 if (opt_showdisassemble) {
1508                                         M_NOP; M_NOP;
1509                                 }
1510
1511                         } else {
1512                                 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
1513
1514                                 disp = dseg_addaddress(cd, &(fi->value));
1515
1516                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1517                                         codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
1518
1519                                         if (opt_showdisassemble) {
1520                                                 M_NOP; M_NOP;
1521                                         }
1522                                 }
1523                         }
1524
1525                         M_ALD(REG_ITMP1, REG_PV, disp);
1526                         switch (iptr->op1) {
1527                         case TYPE_INT:
1528                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1529                                 M_ILD_INTERN(d, REG_ITMP1, 0);
1530                                 emit_store(jd, iptr, iptr->dst, d);
1531                                 break;
1532                         case TYPE_LNG:
1533                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1534                                 M_LDX_INTERN(d, REG_ITMP1, 0);
1535                                 emit_store(jd, iptr, iptr->dst, d);
1536                                 break;
1537                         case TYPE_ADR:
1538                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1539                                 M_ALD_INTERN(d, REG_ITMP1, 0);
1540                                 emit_store(jd, iptr, iptr->dst, d);
1541                                 break;
1542                         case TYPE_FLT:
1543                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1544                                 M_FLD_INTERN(d, REG_ITMP1, 0);
1545                                 emit_store(jd, iptr, iptr->dst, d);
1546                                 break;
1547                         case TYPE_DBL:                          
1548                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1549                                 M_DLD_INTERN(d, REG_ITMP1, 0);
1550                                 emit_store(jd, iptr, iptr->dst, d);
1551                                 break;
1552                         }
1553                         break;
1554
1555                 case ICMD_PUTSTATIC:  /* ..., value  ==> ...                          */
1556                                       /* op1 = type, val.a = field address            */
1557
1558                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1559                                 disp = dseg_addaddress(cd, NULL);
1560
1561                                 codegen_addpatchref(cd, PATCHER_get_putstatic,
1562                                                                         INSTRUCTION_UNRESOLVED_FIELD(iptr), disp);
1563
1564                                 if (opt_showdisassemble) {
1565                                         M_NOP; M_NOP;
1566                                 }
1567
1568                         } else {
1569                                 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
1570
1571                                 disp = dseg_addaddress(cd, &(fi->value));
1572
1573                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1574                                         codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
1575
1576                                         if (opt_showdisassemble) {
1577                                                 M_NOP; M_NOP;
1578                                         }
1579                                 }
1580                         }
1581
1582                         M_ALD(REG_ITMP1, REG_PV, disp);
1583                         switch (iptr->op1) {
1584                         case TYPE_INT:
1585                                 s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
1586                                 M_IST_INTERN(s1, REG_ITMP1, 0);
1587                                 break;
1588                         case TYPE_LNG:
1589                                 s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
1590                                 M_STX_INTERN(s1, REG_ITMP1, 0);
1591                                 break;
1592                         case TYPE_ADR:
1593                                 s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
1594                                 M_AST_INTERN(s1, REG_ITMP1, 0);
1595                                 break;
1596                         case TYPE_FLT:
1597                                 s1 = emit_load_s1(jd, iptr, src, REG_FTMP2);
1598                                 M_FST_INTERN(s1, REG_ITMP1, 0);
1599                                 break;
1600                         case TYPE_DBL:
1601                                 s1 = emit_load_s1(jd, iptr, src, REG_FTMP2);
1602                                 M_DST_INTERN(s1, REG_ITMP1, 0);
1603                                 break;
1604                         }
1605                         break;
1606
1607                 case ICMD_PUTSTATICCONST: /* ...  ==> ...                             */
1608                                           /* val = value (in current instruction)     */
1609                                           /* op1 = type, val.a = field address (in    */
1610                                           /* following NOP)                           */
1611
1612                         if (INSTRUCTION_IS_UNRESOLVED(iptr + 1)) {
1613                                 disp = dseg_addaddress(cd, NULL);
1614
1615                                 codegen_addpatchref(cd, PATCHER_get_putstatic,
1616                                                                         INSTRUCTION_UNRESOLVED_FIELD(iptr + 1), disp);
1617
1618                                 if (opt_showdisassemble) {
1619                                         M_NOP; M_NOP;
1620                                 }
1621
1622                         } else {
1623                                 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr + 1);
1624
1625                                 disp = dseg_addaddress(cd, &(fi->value));
1626
1627                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1628                                         codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
1629
1630                                         if (opt_showdisassemble) {
1631                                                 M_NOP; M_NOP;
1632                                         }
1633                                 }
1634                         }
1635
1636                         M_ALD(REG_ITMP1, REG_PV, disp);
1637                         switch (iptr->op1) {
1638                         case TYPE_INT:
1639                                 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
1640                                 break;
1641                         case TYPE_LNG:
1642                                 M_STX_INTERN(REG_ZERO, REG_ITMP1, 0);
1643                                 break;
1644                         case TYPE_ADR:
1645                                 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
1646                                 break;
1647                         case TYPE_FLT:
1648                                 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
1649                                 break;
1650                         case TYPE_DBL:
1651                                 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
1652                                 break;
1653                         }
1654                         break;
1655
1656
1657                 case ICMD_GETFIELD:   /* ...  ==> ..., value                          */
1658                                       /* op1 = type, val.i = field offset             */
1659
1660                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1661                         gen_nullptr_check(s1);
1662
1663                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1664                                 codegen_addpatchref(cd, PATCHER_get_putfield,
1665                                                                         INSTRUCTION_UNRESOLVED_FIELD(iptr), 0);
1666
1667                                 if (opt_showdisassemble) {
1668                                         M_NOP; M_NOP;
1669                                 }
1670
1671                                 disp = 0;
1672
1673                         } else {
1674                                 disp = INSTRUCTION_RESOLVED_FIELDINFO(iptr)->offset;
1675                         }
1676
1677                         switch (iptr->op1) {
1678                         case TYPE_INT:
1679                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1680                                 M_ILD(d, s1, disp);
1681                                 emit_store(jd, iptr, iptr->dst, d);
1682                                 break;
1683                         case TYPE_LNG:
1684                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1685                                 M_LDX(d, s1, disp);
1686                                 emit_store(jd, iptr, iptr->dst, d);
1687                                 break;
1688                         case TYPE_ADR:
1689                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1690                                 M_ALD(d, s1, disp);
1691                                 emit_store(jd, iptr, iptr->dst, d);
1692                                 break;
1693                         case TYPE_FLT:
1694                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1695                                 M_FLD(d, s1, disp);
1696                                 emit_store(jd, iptr, iptr->dst, d);
1697                                 break;
1698                         case TYPE_DBL:                          
1699                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1700                                 M_DLD(d, s1, disp);
1701                                 emit_store(jd, iptr, iptr->dst, d);
1702                                 break;
1703                         }
1704                         break;
1705
1706                 case ICMD_PUTFIELD:   /* ..., objectref, value  ==> ...               */
1707                                       /* op1 = type, val.a = field address            */
1708
1709                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP2);
1710                         gen_nullptr_check(s1);
1711
1712                         /*if (!IS_FLT_DBL_TYPE(iptr->op1)) {
1713                                 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1714                         } else {*/
1715                                 s2 = emit_load_s2(jd, iptr, src, REG_IFTMP);
1716                         /*}*/
1717
1718                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1719                                 codegen_addpatchref(cd, PATCHER_get_putfield,
1720                                                                         INSTRUCTION_UNRESOLVED_FIELD(iptr), 0);
1721
1722                                 if (opt_showdisassemble) {
1723                                         M_NOP; M_NOP;
1724                                 }
1725
1726                                 disp = 0;
1727
1728                         } else {
1729                                 disp = INSTRUCTION_RESOLVED_FIELDINFO(iptr)->offset;
1730                         }
1731
1732                         switch (iptr->op1) {
1733                         case TYPE_INT:
1734                                 M_IST(s2, s1, disp);
1735                                 break;
1736                         case TYPE_LNG:
1737                                 M_STX(s2, s1, disp);
1738                                 break;
1739                         case TYPE_ADR:
1740                                 M_AST(s2, s1, disp);
1741                                 break;
1742                         case TYPE_FLT:
1743                                 M_FST(s2, s1, disp);
1744                                 break;
1745                         case TYPE_DBL:
1746                                 M_DST(s2, s1, disp);
1747                                 break;
1748                         }
1749                         break;
1750
1751                 case ICMD_PUTFIELDCONST:  /* ..., objectref  ==> ...                  */
1752                                           /* val = value (in current instruction)     */
1753                                           /* op1 = type, val.a = field address (in    */
1754                                           /* following NOP)                           */
1755
1756                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1757                         gen_nullptr_check(s1);
1758
1759                         if (INSTRUCTION_IS_UNRESOLVED(iptr + 1)) {
1760                                 codegen_addpatchref(cd, PATCHER_get_putfield,
1761                                                                         INSTRUCTION_UNRESOLVED_FIELD(iptr + 1), 0);
1762
1763                                 if (opt_showdisassemble) {
1764                                         M_NOP; M_NOP;
1765                                 }
1766
1767                                 disp = 0;
1768
1769                         } else {
1770                                 disp = INSTRUCTION_RESOLVED_FIELDINFO(iptr + 1)->offset;
1771                         }
1772
1773                         switch (iptr[1].op1) {
1774                         case TYPE_INT:
1775                                 M_IST(REG_ZERO, s1, disp);
1776                                 break;
1777                         case TYPE_LNG:
1778                                 M_STX(REG_ZERO, s1, disp);
1779                                 break;
1780                         case TYPE_ADR:
1781                                 M_AST(REG_ZERO, s1, disp);
1782                                 break;
1783                         case TYPE_FLT:
1784                                 M_FST(REG_ZERO, s1, disp);
1785                                 break;
1786                         case TYPE_DBL:
1787                                 M_DST(REG_ZERO, s1, disp);
1788                                 break;
1789                         }
1790                         break;
1791
1792
1793                 /* branch operations **************************************************/
1794
1795                 case ICMD_ATHROW:       /* ..., objectref ==> ... (, objectref)       */
1796
1797                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1798                         M_INTMOVE(s1, REG_ITMP2_XPTR);
1799
1800 #ifdef ENABLE_VERIFIER
1801                         if (iptr->val.a) {
1802                                 codegen_addpatchref(cd, PATCHER_athrow_areturn,
1803                                                                         (unresolved_class *) iptr->val.a, 0);
1804
1805                                 if (opt_showdisassemble)
1806                                         M_NOP;
1807                         }
1808 #endif /* ENABLE_VERIFIER */
1809
1810                         disp = dseg_addaddress(cd, asm_handle_exception);
1811                         M_ALD(REG_ITMP2, REG_PV, disp);
1812                         M_JMP(REG_ITMP3_XPC, REG_ITMP2, REG_ZERO);
1813                         M_NOP;
1814                         M_NOP;              /* nop ensures that XPC is less than the end */
1815                                             /* of basic block                            */
1816                         ALIGNCODENOP;
1817                         break;
1818
1819                 case ICMD_GOTO:         /* ... ==> ...                                */
1820                                         /* op1 = target JavaVM pc                     */
1821                         M_BR(0);
1822                         codegen_addreference(cd, (basicblock *) iptr->target);
1823                         M_NOP;
1824                         ALIGNCODENOP;
1825                         break;
1826
1827                 case ICMD_JSR:          /* ... ==> ...                                */
1828                                         /* op1 = target JavaVM pc                     */
1829
1830                         dseg_addtarget(cd, (basicblock *) iptr->target);
1831                         M_ALD(REG_ITMP1, REG_PV, -(cd->dseglen));
1832                         M_JMP(REG_ITMP1, REG_ITMP1, REG_ZERO);        /* REG_ITMP1 = return address */
1833                         M_NOP;
1834                         break;
1835
1836                 case ICMD_RET:          /* ... ==> ...                                */
1837                                         /* op1 = local variable                       */
1838                         var = &(rd->locals[iptr->op1][TYPE_ADR]);
1839                         if (var->flags & INMEMORY) {
1840                                 M_ALD(REG_ITMP1, REG_SP, var->regoff * 8);
1841                                 M_RET(REG_ITMP1);
1842                         } else
1843                                 M_RET(var->regoff);
1844                         M_NOP;
1845                         ALIGNCODENOP;
1846                         break;
1847
1848                 case ICMD_IFNULL:       /* ..., value ==> ...                         */
1849                                         /* op1 = target JavaVM pc                     */
1850
1851                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1852                         M_BEQZ(s1, 0);
1853                         codegen_addreference(cd, (basicblock *) iptr->target);
1854                         M_NOP;
1855                         break;
1856
1857                 case ICMD_IFNONNULL:    /* ..., value ==> ...                         */
1858                                         /* op1 = target JavaVM pc                     */
1859
1860                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1861                         M_BNEZ(s1, 0);
1862                         codegen_addreference(cd, (basicblock *) iptr->target);
1863                         M_NOP;
1864                         break;
1865 /* XXX: CMP_IMM */
1866                 case ICMD_IFEQ:         /* ..., value ==> ...                         */
1867                                         /* op1 = target JavaVM pc, val.i = constant   */
1868
1869                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1870                         if (iptr->val.i == 0) {
1871                                 M_BEQZ(s1, 0);
1872                         } else {
1873                                 if ((iptr->val.i >= -4096) && (iptr->val.i <= 4095)) {
1874                                         M_CMP_IMM(s1, iptr->val.i);
1875                                         }
1876                                 else {
1877                                         ICONST(REG_ITMP2, iptr->val.i);
1878                                         M_CMP(s1, REG_ITMP2);
1879                                         }
1880                                 M_BEQ(0);
1881                                 }
1882                         codegen_addreference(cd, (basicblock *) iptr->target);
1883                         M_NOP;
1884                         break;
1885
1886                 case ICMD_IFLT:         /* ..., value ==> ...                         */
1887                                         /* op1 = target JavaVM pc, val.i = constant   */
1888
1889                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1890                         if (iptr->val.i == 0) {
1891                                 M_BLTZ(s1, 0);
1892                         } else {
1893                                 if ((iptr->val.i >= -4096) && (iptr->val.i <= 4095)) {
1894                                         M_CMP_IMM(s1, iptr->val.i);
1895                                 } else {
1896                                         ICONST(REG_ITMP2, iptr->val.i);
1897                                         M_CMP(s1, REG_ITMP2);
1898                                 }
1899                                 M_BLT(0);
1900                         }
1901                         codegen_addreference(cd, (basicblock *) iptr->target);
1902                         M_NOP;
1903                         break;
1904
1905                 case ICMD_IFLE:         /* ..., value ==> ...                         */
1906                                         /* op1 = target JavaVM pc, val.i = constant   */
1907
1908                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1909                         if (iptr->val.i == 0) {
1910                                 M_BLEZ(s1, 0);
1911                                 }
1912                         else {
1913                                 if ((iptr->val.i >= -4096) && (iptr->val.i <= 4095)) {
1914                                         M_CMP_IMM(s1, iptr->val.i);
1915                                         }
1916                                 else {
1917                                         ICONST(REG_ITMP2, iptr->val.i);
1918                                         M_CMP(s1, REG_ITMP2);
1919                                 }
1920                                 M_BLE(0);
1921                         }
1922                         codegen_addreference(cd, (basicblock *) iptr->target);
1923                         M_NOP;
1924                         break;
1925
1926                 case ICMD_IFNE:         /* ..., value ==> ...                         */
1927                                         /* op1 = target JavaVM pc, val.i = constant   */
1928
1929                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1930                         if (iptr->val.i == 0) {
1931                                 M_BNEZ(s1, 0);
1932                                 }
1933                         else {
1934                                 if ((iptr->val.i >= -4096) && (iptr->val.i <= 4095)) {
1935                                         M_CMP_IMM(s1, iptr->val.i);
1936                                 }
1937                                 else {
1938                                         ICONST(REG_ITMP2, iptr->val.i);
1939                                         M_CMP(s1, REG_ITMP2);
1940                                 }
1941                                 M_BNE(0);
1942                         }
1943                         codegen_addreference(cd, (basicblock *) iptr->target);
1944                         M_NOP;
1945                         break;
1946
1947                 case ICMD_IF_ACMPEQ:    /* ..., value, value ==> ...                  */
1948                 case ICMD_IF_LCMPEQ:    /* op1 = target JavaVM pc                     */
1949
1950                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1951                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1952                         M_CMP(s1, s2);
1953                         M_XBEQ(0);
1954                         codegen_addreference(cd, (basicblock *) iptr->target);
1955                         M_NOP;
1956                         break;
1957
1958                 case ICMD_IF_ICMPEQ:    /* 32-bit compare                             */
1959
1960                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1961                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1962                         M_CMP(s1, s2);
1963                         M_BEQ(0);
1964                         codegen_addreference(cd, (basicblock *) iptr->target);
1965                         M_NOP;
1966                         break;
1967
1968                 case ICMD_IF_ACMPNE:    /* ..., value, value ==> ...                  */
1969                 case ICMD_IF_LCMPNE:    /* op1 = target JavaVM pc                     */
1970
1971                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1972                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1973                         M_CMP(s1, s2);
1974                         M_XBNE(0);
1975                         codegen_addreference(cd, (basicblock *) iptr->target);
1976                         M_NOP;
1977                         break;
1978                         
1979                 case ICMD_IF_ICMPNE:    /* 32-bit compare                             */
1980
1981                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1982                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1983                         M_CMP(s1, s2);
1984                         M_BNE(0);
1985                         codegen_addreference(cd, (basicblock *) iptr->target);
1986                         M_NOP;
1987                         break;
1988
1989                 case ICMD_IF_LCMPLT:    /* ..., value, value ==> ...                  */
1990                                         /* op1 = target JavaVM pc                     */
1991
1992                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1993                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1994                         M_CMP(s1, s2);
1995                         M_XBLT(0);
1996                         codegen_addreference(cd, (basicblock *) iptr->target);
1997                         M_NOP;
1998                         break;
1999                         
2000                 case ICMD_IF_ICMPLT:    /* 32-bit compare                             */
2001
2002                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2003                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2004                         M_CMP(s1, s2);
2005                         M_BLT(0);
2006                         codegen_addreference(cd, (basicblock *) iptr->target);
2007                         M_NOP;
2008                         break;
2009
2010                 case ICMD_IF_LCMPGT:    /* ..., value, value ==> ...                  */
2011                                         /* op1 = target JavaVM pc                     */
2012
2013                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2014                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2015                         M_CMP(s1, s2);
2016                         M_XBGT(0);
2017                         codegen_addreference(cd, (basicblock *) iptr->target);
2018                         M_NOP;
2019                         break;
2020                         
2021                 case ICMD_IF_ICMPGT:    /* 32-bit compare                             */
2022
2023                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2024                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2025                         M_CMP(s1, s2);
2026                         M_BGT(0);
2027                         codegen_addreference(cd, (basicblock *) iptr->target);
2028                         M_NOP;
2029                         break;
2030
2031                 case ICMD_IF_LCMPLE:    /* ..., value, value ==> ...                  */
2032                                         /* op1 = target JavaVM pc                     */
2033
2034                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2035                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2036                         M_CMP(s1, s2);
2037                         M_BLE(0);
2038                         codegen_addreference(cd, (basicblock *) iptr->target);
2039                         M_NOP;
2040                         break;
2041                         
2042                 case ICMD_IF_ICMPLE:    /* 32-bit compare                             */
2043
2044                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2045                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2046                         M_CMP(s1, s2);
2047                         M_BLE(0);
2048                         codegen_addreference(cd, (basicblock *) iptr->target);
2049                         M_NOP;
2050                         break;                  
2051         
2052
2053                 case ICMD_IF_LCMPGE:    /* ..., value, value ==> ...                  */
2054                                         /* op1 = target JavaVM pc                     */
2055
2056                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2057                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2058                         M_CMP(s1, s2);
2059                         M_BGE(0);
2060                         codegen_addreference(cd, (basicblock *) iptr->target);
2061                         M_NOP;
2062                         break;
2063                         
2064                 case ICMD_IF_ICMPGE:    /* 32-bit compare                             */
2065
2066                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2067                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2068                         M_CMP(s1, s2);
2069                         M_BGE(0);
2070                         codegen_addreference(cd, (basicblock *) iptr->target);
2071                         M_NOP;
2072                         break;
2073
2074
2075                 case ICMD_IRETURN:      /* ..., retvalue ==> ...                      */
2076                 case ICMD_LRETURN:
2077
2078                         s1 = emit_load_s1(jd, iptr, src, REG_RESULT_CALLEE);
2079                         M_INTMOVE(s1, REG_RESULT_CALLEE);
2080                         goto nowperformreturn;
2081
2082                 case ICMD_ARETURN:      /* ..., retvalue ==> ...                      */
2083
2084                         s1 = emit_load_s1(jd, iptr, src, REG_RESULT_CALLEE);
2085                         M_INTMOVE(s1, REG_RESULT_CALLEE);
2086
2087 #ifdef ENABLE_VERIFIER
2088                         if (iptr->val.a) {
2089                                 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2090                                                                         (unresolved_class *) iptr->val.a, 0);
2091
2092                                 if (opt_showdisassemble)
2093                                         M_NOP;
2094                         }
2095 #endif /* ENABLE_VERIFIER */
2096                         goto nowperformreturn;
2097
2098                 case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
2099                 case ICMD_DRETURN:
2100
2101                         s1 = emit_load_s1(jd, iptr, src, REG_FRESULT);
2102                         M_FLTMOVE(s1, REG_FRESULT);
2103                         goto nowperformreturn;
2104
2105                 case ICMD_RETURN:       /* ...  ==> ...                               */
2106
2107 nowperformreturn:
2108                         {
2109                         s4 i, p;
2110                         
2111                         p = stackframesize;
2112                         
2113                         /* call trace function */
2114
2115 #if !defined(NDEBUG)
2116                         if (opt_verbosecall) {
2117                                 M_LDA(REG_SP, REG_SP, -3 * 8);
2118                                 M_AST(REG_RA_CALLEE, REG_SP, 0 * 8); /* XXX: no need to save anything but FRES ? */
2119                 /*              M_STX(REG_RESULT, REG_SP, 1 * 8); */
2120                                 M_DST(REG_FRESULT, REG_SP, 2 * 8);
2121
2122                                 disp = dseg_addaddress(cd, m);
2123                                 M_ALD(rd->argintregs[0], REG_PV, disp);
2124                                 M_MOV(REG_RESULT_CALLEE, rd->argintregs[1]);
2125                                 M_FLTMOVE(REG_FRESULT, rd->argfltregs[2]);
2126                                 M_FLTMOVE(REG_FRESULT, rd->argfltregs[3]);
2127
2128                                 disp = dseg_addaddress(cd, (void *) builtin_displaymethodstop);
2129                                 M_ALD(REG_ITMP3, REG_PV, disp);
2130                                 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2131                                 M_NOP;
2132
2133                                 M_DLD(REG_FRESULT, REG_SP, 2 * 8);
2134                 /*              M_LDX(REG_RESULT, REG_SP, 1 * 8); */
2135                                 M_ALD(REG_RA_CALLEE, REG_SP, 0 * 8);
2136                                 M_LDA(REG_SP, REG_SP, 3 * 8);
2137                         }
2138 #endif
2139
2140 #if defined(ENABLE_THREADS)
2141                         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2142 /* XXX: REG_RESULT is save, but what about FRESULT? */
2143                                 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8); /* XXX: what for ? */
2144
2145                                 switch (iptr->opc) {
2146                                 case ICMD_FRETURN:
2147                                 case ICMD_DRETURN:
2148                                         M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2149                                         break;
2150                                 }
2151
2152                                 disp = dseg_addaddress(cd, BUILTIN_monitorexit);
2153                                 M_ALD(REG_ITMP3, REG_PV, disp);
2154                                 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); /*REG_RA_CALLER */
2155
2156                                 switch (iptr->opc) {
2157                                 case ICMD_FRETURN:
2158                                 case ICMD_DRETURN:
2159                                         M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2160                                         break;
2161                                 }
2162                         }
2163 #endif
2164
2165
2166
2167                         M_RETURN(REG_RA_CALLEE); /* implicit window restore */
2168                         M_NOP;
2169                         ALIGNCODENOP;
2170                         }
2171                         break;
2172
2173
2174                 default:
2175                         *exceptionptr = new_internalerror("Unknown ICMD %d", iptr->opc);
2176                         return false;
2177                         
2178         } /* switch */
2179                 
2180         } /* for instruction */
2181         
2182         
2183         /* copy values to interface registers */
2184
2185         src = bptr->outstack;
2186         len = bptr->outdepth;
2187         MCODECHECK(64+len);
2188 #if defined(ENABLE_LSRA)
2189         if (!opt_lsra) 
2190 #endif
2191         while (src) {
2192                 len--;
2193                 if ((src->varkind != STACKVAR)) {
2194                         s2 = src->type;
2195                         if (IS_FLT_DBL_TYPE(s2)) {
2196                                 var_to_reg_flt(s1, src, REG_FTMP1);
2197                                 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
2198                                         M_FLTMOVE(s1,rd->interfaces[len][s2].regoff);
2199                                         }
2200                                 else {
2201                                         M_DST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
2202                                         }
2203                                 }
2204                         else {
2205                                 var_to_reg_int(s1, src, REG_ITMP1);
2206                                 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
2207                                         M_INTMOVE(s1,rd->interfaces[len][s2].regoff);
2208                                         }
2209                                 else {
2210                                         M_STX(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
2211                                         }
2212                                 }
2213                         }
2214                 src = src->prev;
2215                 }
2216         } /* if (bptr -> flags >= BBREACHED) */
2217         } /* for basic block */
2218         
2219         
2220         
2221 }
2222
2223
2224
2225
2226
2227 /* createcompilerstub **********************************************************
2228
2229    Creates a stub routine which calls the compiler.
2230         
2231 *******************************************************************************/
2232
2233 #define COMPILERSTUB_DATASIZE    2 * SIZEOF_VOID_P
2234 #define COMPILERSTUB_CODESIZE    3 * 4
2235
2236 #define COMPILERSTUB_SIZE        COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
2237
2238
2239 u1 *createcompilerstub(methodinfo *m)
2240 {
2241         u1     *s;                          /* memory to hold the stub            */
2242         ptrint *d;
2243         s4     *mcodeptr;                   /* code generation pointer            */
2244
2245         s = CNEW(u1, COMPILERSTUB_SIZE);
2246
2247         /* set data pointer and code pointer */
2248
2249         d = (ptrint *) s;
2250         s = s + COMPILERSTUB_DATASIZE;
2251
2252         mcodeptr = (s4 *) s;
2253         
2254         /* Store the methodinfo* in the same place as in the methodheader
2255            for compiled methods. */
2256
2257         d[0] = (ptrint) asm_call_jit_compiler;
2258         d[1] = (ptrint) m;
2259
2260         /* code for the stub */
2261
2262         M_LDX(REG_ITMP1, REG_PV_CALLER, -1 * 8);   /* load methodinfo pointer            */
2263         /* XXX CALLER PV ??? */
2264         M_LDX(REG_PV_CALLER ,REG_PV_CALLER, -2 * 8);      /* load pointer to the compiler       */
2265         M_JMP(REG_ZERO, REG_PV_CALLER, REG_ZERO);  /* jump to the compiler, RA is wasted */
2266
2267 #if defined(ENABLE_STATISTICS)
2268         if (opt_stat)
2269                 count_cstub_len += COMPILERSTUB_SIZE;
2270 #endif
2271
2272         return s;
2273 }
2274
2275
2276
2277 /* createnativestub ************************************************************
2278
2279    Creates a stub routine which calls a native method.
2280
2281 *******************************************************************************/
2282
2283 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
2284 {
2285         fabort("help me!");
2286         return NULL;
2287 }
2288
2289 /*
2290  * These are local overrides for various environment variables in Emacs.
2291  * Please do not remove this and leave it at the end of the file, where
2292  * Emacs will automagically detect them.
2293  * ---------------------------------------------------------------------
2294  * Local variables:
2295  * mode: c
2296  * indent-tabs-mode: t
2297  * c-basic-offset: 4
2298  * tab-width: 4
2299  * End:
2300  * vim:noexpandtab:sw=4:ts=4:
2301  */