* src/vm/jit/mips/linux/md-abi.h (REG_A0, REG_A1, REG_A2, REG_A3):
[cacao.git] / src / vm / jit / mips / codegen.c
1 /* src/vm/jit/mips/codegen.c - machine code generator for MIPS
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
30    Changes: Christian Thalinger
31             Christian Ullrich
32             Edwin Steiner
33
34    Contains the codegenerator for an MIPS (R4000 or higher) processor.
35    This module generates MIPS machine code for a sequence of
36    intermediate code commands (ICMDs).
37
38    $Id: codegen.c 5388 2006-09-06 22:34:46Z twisti $
39
40 */
41
42
43 #include "config.h"
44
45 #include <assert.h>
46 #include <stdio.h>
47
48 #include "vm/types.h"
49
50 #include "md.h"
51 #include "md-abi.h"
52
53 #include "vm/jit/mips/arch.h"
54 #include "vm/jit/mips/codegen.h"
55
56 #include "native/native.h"
57
58 #if defined(ENABLE_THREADS)
59 # include "threads/native/lock.h"
60 #endif
61
62 #include "vm/builtin.h"
63 #include "vm/class.h"
64 #include "vm/exceptions.h"
65 #include "vm/options.h"
66 #include "vm/stringlocal.h"
67 #include "vm/vm.h"
68 #include "vm/jit/asmpart.h"
69 #include "vm/jit/codegen-common.h"
70 #include "vm/jit/dseg.h"
71 #include "vm/jit/emit.h"
72 #include "vm/jit/jit.h"
73 #include "vm/jit/patcher.h"
74 #include "vm/jit/reg.h"
75 #include "vm/jit/replace.h"
76
77 #if defined(ENABLE_LSRA)
78 # include "vm/jit/allocator/lsra.h"
79 #endif
80
81
82 /* codegen *********************************************************************
83
84    Generates machine code.
85
86 *******************************************************************************/
87
88 bool codegen(jitdata *jd)
89 {
90         methodinfo         *m;
91         codeinfo           *code;
92         codegendata        *cd;
93         registerdata       *rd;
94         s4                  len, s1, s2, s3, d, disp;
95         ptrint              a;
96         stackptr            src;
97         varinfo            *var;
98         basicblock         *bptr;
99         instruction        *iptr;
100         exceptiontable     *ex;
101         u2                  currentline;
102         methodinfo         *lm;             /* local methodinfo for ICMD_INVOKE*  */
103         unresolved_method  *um;
104         builtintable_entry *bte;
105         methoddesc         *md;
106         rplpoint           *replacementpoint;
107         s4                  fieldtype;
108
109         /* get required compiler data */
110
111         m    = jd->m;
112         code = jd->code;
113         cd   = jd->cd;
114         rd   = jd->rd;
115
116         {
117         s4 i, p, t, l;
118         s4 savedregs_num;
119
120         savedregs_num = (jd->isleafmethod) ? 0 : 1;       /* space to save the RA */
121
122         /* space to save used callee saved registers */
123
124         savedregs_num += (INT_SAV_CNT - rd->savintreguse);
125         savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
126
127         cd->stackframesize = rd->memuse + savedregs_num;
128
129 #if defined(ENABLE_THREADS)
130         /* space to save argument of monitor_enter */
131
132         if (checksync && (m->flags & ACC_SYNCHRONIZED))
133                 cd->stackframesize++;
134 #endif
135
136         /* keep stack 16-byte aligned */
137
138         if (cd->stackframesize & 1)
139                 cd->stackframesize++;
140
141         /* create method header */
142
143 #if SIZEOF_VOID_P == 4
144         (void) dseg_addaddress(cd, code);                      /* Filler          */
145 #endif
146         (void) dseg_addaddress(cd, code);                      /* CodeinfoPointer */
147         (void) dseg_adds4(cd, cd->stackframesize * 8);         /* FrameSize       */
148
149 #if defined(ENABLE_THREADS)
150         /* IsSync contains the offset relative to the stack pointer for the
151            argument of monitor_exit used in the exception handler. Since the
152            offset could be zero and give a wrong meaning of the flag it is
153            offset by one.
154         */
155
156         if (checksync && (m->flags & ACC_SYNCHRONIZED))
157                 (void) dseg_adds4(cd, (rd->memuse + 1) * 8);       /* IsSync          */
158         else
159 #endif
160                 (void) dseg_adds4(cd, 0);                          /* IsSync          */
161                                                
162         (void) dseg_adds4(cd, jd->isleafmethod);               /* IsLeaf          */
163         (void) dseg_adds4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave         */
164         (void) dseg_adds4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave         */
165         dseg_addlinenumbertablesize(cd);
166         (void) dseg_adds4(cd, cd->exceptiontablelength);       /* ExTableSize     */
167
168         /* create exception table */
169
170         for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
171                 dseg_addtarget(cd, ex->start);
172                 dseg_addtarget(cd, ex->end);
173                 dseg_addtarget(cd, ex->handler);
174                 (void) dseg_addaddress(cd, ex->catchtype.cls);
175         }
176         
177         /* create stack frame (if necessary) */
178
179         if (cd->stackframesize)
180                 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8);
181
182         /* save return address and used callee saved registers */
183
184         p = cd->stackframesize;
185         if (!jd->isleafmethod) {
186                 p--; M_AST(REG_RA, REG_SP, p * 8);
187         }
188         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
189                 p--; M_AST(rd->savintregs[i], REG_SP, p * 8);
190         }
191         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
192                 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
193         }
194
195         /* take arguments out of register or stack frame */
196
197         md = m->parseddesc;
198
199         for (p = 0, l = 0; p < md->paramcount; p++) {
200                 t = md->paramtypes[p].type;
201                 var = &(rd->locals[l][t]);
202                 l++;
203                 if (IS_2_WORD_TYPE(t))    /* increment local counter for 2 word types */
204                         l++;
205                 if (var->type < 0)
206                         continue;
207                 s1 = md->params[p].regoff;
208                 if (IS_INT_LNG_TYPE(t)) {                    /* integer args          */
209                         if (!md->params[p].inmemory) {           /* register arguments    */
210                                 s2 = rd->argintregs[s1];
211                                 if (!(var->flags & INMEMORY)) {      /* reg arg -> register   */
212                                         M_INTMOVE(s2, var->regoff);
213                                 } else {                             /* reg arg -> spilled    */
214                                         M_LST(s2, REG_SP, var->regoff * 8);
215                                 }
216
217                         } else {                                 /* stack arguments       */
218                                 if (!(var->flags & INMEMORY)) {      /* stack arg -> register */
219                                         M_LLD(var->regoff, REG_SP, (cd->stackframesize + s1) * 8);
220                                 } else {                             /* stack arg -> spilled  */
221                                         var->regoff = cd->stackframesize + s1;
222                                 }
223                         }
224
225                 } else {                                     /* floating args         */
226                         if (!md->params[p].inmemory) {           /* register arguments    */
227                                 s2 = rd->argfltregs[s1];
228                                 if (!(var->flags & INMEMORY)) {      /* reg arg -> register   */
229                                         if (IS_2_WORD_TYPE(t))
230                                                 M_DMOV(s2, var->regoff);
231                                         else
232                                                 M_FMOV(s2, var->regoff);
233                                 } else {                                         /* reg arg -> spilled    */
234                                         if (IS_2_WORD_TYPE(t))
235                                                 M_DST(s2, REG_SP, var->regoff * 8);
236                                         else
237                                                 M_FST(s2, REG_SP, var->regoff * 8);
238                                 }
239
240                         } else {                                 /* stack arguments       */
241                                 if (!(var->flags & INMEMORY)) {      /* stack-arg -> register */
242                                         if (IS_2_WORD_TYPE(t))
243                                                 M_DLD(var->regoff, REG_SP, (cd->stackframesize + s1) * 8);
244                                         else
245                                                 M_FLD(var->regoff, REG_SP, (cd->stackframesize + s1) * 8);
246                                 } else                               /* stack-arg -> spilled  */
247                                         var->regoff = cd->stackframesize + s1;
248                         }
249                 }
250         } /* end for */
251
252         /* call monitorenter function */
253
254 #if defined(ENABLE_THREADS)
255         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
256                 /* stack offset for monitor argument */
257
258                 s1 = rd->memuse;
259
260 # if !defined(NDEBUG)
261                 if (opt_verbosecall) {
262                         M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
263
264                         for (p = 0; p < INT_ARG_CNT; p++)
265                                 M_LST(rd->argintregs[p], REG_SP, p * 8);
266
267                         for (p = 0; p < FLT_ARG_CNT; p++)
268                                 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
269
270                         s1 += INT_ARG_CNT + FLT_ARG_CNT;
271                 }
272 # endif
273
274                 /* get correct lock object */
275
276                 if (m->flags & ACC_STATIC) {
277                         p = dseg_addaddress(cd, &m->class->object.header);
278                         M_ALD(REG_A0, REG_PV, p);
279                 }
280                 else {
281                         M_BEQZ(REG_A0, 0);
282                         codegen_add_nullpointerexception_ref(cd);
283                 }
284
285                 p = dseg_addaddress(cd, LOCK_monitor_enter);
286                 M_ALD(REG_ITMP3, REG_PV, p);
287                 M_JSR(REG_RA, REG_ITMP3);
288                 M_AST(REG_A0, REG_SP, s1 * 8);         /* branch delay */
289
290 # if !defined(NDEBUG)
291                 if (opt_verbosecall) {
292                         for (p = 0; p < INT_ARG_CNT; p++)
293                                 M_LLD(rd->argintregs[p], REG_SP, p * 8);
294
295                         for (p = 0; p < FLT_ARG_CNT; p++)
296                                 M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
297
298
299                         M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
300                 }
301 # endif
302         }
303 #endif
304
305 #if !defined(NDEBUG)
306         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
307                 emit_verbosecall_enter(jd);
308 #endif
309
310         }
311
312         /* end of header generation */
313
314         replacementpoint = jd->code->rplpoints;
315
316         /* walk through all basic blocks */
317
318         for (bptr = jd->new_basicblocks; bptr != NULL; bptr = bptr->next) {
319
320                 /* handle replacement points */
321
322 #if 0
323                 if (bptr->bitflags & BBFLAG_REPLACEMENT && bptr->flags >= BBREACHED) {
324
325                         /* 8-byte align pc */
326                         if ((ptrint) cd->mcodeptr & 4) {
327                                 M_NOP;
328                         }
329                         
330                         replacementpoint->pc = (u1*)(ptrint) (cd->mcodeptr - cd->mcodebase);
331                         replacementpoint++;
332
333                         assert(cd->lastmcodeptr <= cd->mcodeptr);
334                         cd->lastmcodeptr = cd->mcodeptr + 2 * 4;       /* br + delay slot */
335                 }
336 #endif
337
338                 /* store relative start of block */
339
340                 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
341
342                 if (bptr->flags >= BBREACHED) {
343
344                         /* branch resolving */
345                         {
346                                 branchref *bref;
347                                 for (bref = bptr->branchrefs; bref != NULL; bref = bref->next) {
348                                         gen_resolvebranch(cd->mcodebase + bref->branchpos, 
349                                                                           bref->branchpos,
350                                                                           bptr->mpc);
351                                 }
352                         }
353
354                 /* copy interface registers to their destination */
355
356                 len = bptr->indepth;
357                 MCODECHECK(64+len);
358 #if defined(ENABLE_LSRA)
359                 if (opt_lsra) {
360                 while (len) {
361                         len--;
362                         src = bptr->invars[len];
363                         if ((len == 0) && (bptr->type != BBTYPE_STD)) {
364                                         /*                              d = reg_of_var(m, src, REG_ITMP1); */
365                                         if (!(src->flags & INMEMORY))
366                                                 d= src->regoff;
367                                         else
368                                                 d=REG_ITMP1;
369                                         M_INTMOVE(REG_ITMP1, d);
370                                         emit_store(jd, NULL, src, d);
371                                 }
372                         }
373                 } else {
374 #endif
375                 while (len) {
376                         len--;
377                         src = bptr->invars[len];
378                         if ((len == 0) && (bptr->type != BBTYPE_STD)) {
379                                 d = codegen_reg_of_var(rd, 0, src, REG_ITMP1);
380                                 M_INTMOVE(REG_ITMP1, d);
381                                 emit_store(jd, NULL, src, d);
382
383                         } else {
384                                 d = codegen_reg_of_var(rd, 0, src, REG_IFTMP);
385                                 if ((src->varkind != STACKVAR)) {
386                                         s2 = src->type;
387                                         s1 = rd->interfaces[len][s2].regoff;
388                                         if (IS_FLT_DBL_TYPE(s2)) {
389                                                 if (rd->interfaces[len][s2].flags & INMEMORY) {
390                                                         if (IS_2_WORD_TYPE(s2))
391                                                                 M_DLD(d, REG_SP, s1 * 8);
392                                                         else
393                                                                 M_FLD(d, REG_SP, s1 * 8);
394
395                                                 } else {
396                                                         if (IS_2_WORD_TYPE(s2))
397                                                                 M_DMOV(s1, d);
398                                                         else
399                                                                 M_FMOV(s1, d);
400                                                 }
401
402                                         } else {
403                                                 if (rd->interfaces[len][s2].flags & INMEMORY)
404                                                         M_LLD(d, REG_SP, s1 * 8);
405                                                 else
406                                                         M_INTMOVE(s1,d);
407                                         }
408
409                                         emit_store(jd, NULL, src, d);
410                                 }
411                         }
412                 }
413 #if defined(ENABLE_LSRA)
414                 }
415 #endif
416                 /* walk through all instructions */
417                 
418                 len = bptr->icount;
419                 currentline = 0;
420
421                 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
422                         if (iptr->line != currentline) {
423                                 dseg_addlinenumber(cd, iptr->line);
424                                 currentline = iptr->line;
425                         }
426
427                         MCODECHECK(64);   /* an instruction usually needs < 64 words      */
428
429                         switch (iptr->opc) {
430
431                 case ICMD_NOP:        /* ...  ==> ...                                 */
432                         break;
433
434                 case ICMD_CHECKNULL:  /* ..., objectref  ==> ..., objectref           */
435
436                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
437                         M_BEQZ(s1, 0);
438                         codegen_add_nullpointerexception_ref(cd);
439                         M_NOP;
440                         break;
441
442                 /* constant operations ************************************************/
443
444                 case ICMD_ICONST:     /* ...  ==> ..., constant                       */
445
446                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
447                         ICONST(d, iptr->sx.val.i);
448                         emit_store_dst(jd, iptr, d);
449                         break;
450
451                 case ICMD_LCONST:     /* ...  ==> ..., constant                       */
452
453                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
454                         LCONST(d, iptr->sx.val.l);
455                         emit_store_dst(jd, iptr, d);
456                         break;
457
458                 case ICMD_FCONST:     /* ...  ==> ..., constant                       */
459
460                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
461                         disp = dseg_addfloat(cd, iptr->sx.val.f);
462                         M_FLD(d, REG_PV, disp);
463                         emit_store_dst(jd, iptr, d);
464                         break;
465                         
466                 case ICMD_DCONST:     /* ...  ==> ..., constant                       */
467
468                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
469                         disp = dseg_adddouble(cd, iptr->sx.val.d);
470                         M_DLD(d, REG_PV, disp);
471                         emit_store_dst(jd, iptr, d);
472                         break;
473
474                 case ICMD_ACONST:     /* ...  ==> ..., constant                       */
475
476                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
477
478                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
479                                 disp = dseg_addaddress(cd, NULL);
480
481                                 codegen_addpatchref(cd, PATCHER_aconst,
482                                                                         iptr->sx.val.c.ref,
483                                                                     disp);
484
485                                 if (opt_showdisassemble) {
486                                         M_NOP; M_NOP;
487                                 }
488
489                                 M_ALD(d, REG_PV, disp);
490
491                         } else {
492                                 if (iptr->sx.val.anyptr == NULL) {
493                                         M_INTMOVE(REG_ZERO, d);
494                                 } else {
495                                         disp = dseg_addaddress(cd, iptr->sx.val.anyptr);
496                                         M_ALD(d, REG_PV, disp);
497                                 }
498                         }
499                         emit_store_dst(jd, iptr, d);
500                         break;
501
502
503                 /* load/store operations **********************************************/
504
505                 case ICMD_ILOAD:      /* ...  ==> ..., content of local variable      */
506                                       /* s1.localindex = local variable                         */
507
508                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
509                         if ((iptr->dst.var->varkind == LOCALVAR) &&
510                             (iptr->dst.var->varnum == iptr->s1.localindex))
511                                 break;
512                         var = &(rd->locals[iptr->s1.localindex][iptr->opc - ICMD_ILOAD]);
513                         if (var->flags & INMEMORY)
514 #if SIZEOF_VOID_P == 8
515                                 M_LLD(d, REG_SP, var->regoff * 8);
516 #else
517                                 M_ILD(d, REG_SP, var->regoff * 8);
518 #endif
519                         else
520                                 M_INTMOVE(var->regoff,d);
521                         emit_store_dst(jd, iptr, d);
522                         break;
523
524                 case ICMD_LLOAD:      /* ...  ==> ..., content of local variable      */
525                                       /* s1.localindex = local variable                         */
526
527                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
528                         if ((iptr->dst.var->varkind == LOCALVAR) &&
529                             (iptr->dst.var->varnum == iptr->s1.localindex))
530                                 break;
531                         var = &(rd->locals[iptr->s1.localindex][iptr->opc - ICMD_ILOAD]);
532                         if (var->flags & INMEMORY)
533                                 M_LLD(d, REG_SP, var->regoff * 8);
534                         else
535                                 M_INTMOVE(var->regoff,d);
536                         emit_store_dst(jd, iptr, d);
537                         break;
538
539                 case ICMD_ALOAD:      /* ...  ==> ..., content of local variable      */
540                                       /* s1.localindex = local variable                         */
541
542                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
543                         if ((iptr->dst.var->varkind == LOCALVAR) &&
544                             (iptr->dst.var->varnum == iptr->s1.localindex))
545                                 break;
546                         var = &(rd->locals[iptr->s1.localindex][iptr->opc - ICMD_ILOAD]);
547                         if (var->flags & INMEMORY)
548                                 M_ALD(d, REG_SP, var->regoff * 8);
549                         else
550                                 M_INTMOVE(var->regoff,d);
551                         emit_store_dst(jd, iptr, d);
552                         break;
553
554                 case ICMD_FLOAD:      /* ...  ==> ..., content of local variable      */
555                                       /* s1.localindex = local variable                         */
556
557                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
558                         if ((iptr->dst.var->varkind == LOCALVAR) &&
559                             (iptr->dst.var->varnum == iptr->s1.localindex))
560                                 break;
561                         var = &(rd->locals[iptr->s1.localindex][iptr->opc - ICMD_ILOAD]);
562                         if (var->flags & INMEMORY)
563                                 M_FLD(d, REG_SP, var->regoff * 8);
564                         else
565                                 M_FMOV(var->regoff, d);
566                         emit_store_dst(jd, iptr, d);
567                         break;
568
569                 case ICMD_DLOAD:      /* ...  ==> ..., content of local variable      */
570                                       /* s1.localindex = local variable                         */
571
572                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
573                         if ((iptr->dst.var->varkind == LOCALVAR) &&
574                             (iptr->dst.var->varnum == iptr->s1.localindex))
575                                 break;
576                         var = &(rd->locals[iptr->s1.localindex][iptr->opc - ICMD_ILOAD]);
577                         if (var->flags & INMEMORY)
578                                 M_DLD(d, REG_SP, var->regoff * 8);
579                         else
580                                 M_DMOV(var->regoff, d);
581                         emit_store_dst(jd, iptr, d);
582                         break;
583
584
585                 case ICMD_ISTORE:     /* ..., value  ==> ...                          */
586                                       /* dst.localindex = local variable                         */
587
588                         if ((iptr->s1.var->varkind == LOCALVAR) &&
589                             (iptr->s1.var->varnum == iptr->dst.localindex))
590                                 break;
591                         var = &(rd->locals[iptr->dst.localindex][iptr->opc - ICMD_ISTORE]);
592                         if (var->flags & INMEMORY) {
593                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
594 #if SIZEOF_VOID_P == 8
595                                 M_LST(s1, REG_SP, var->regoff * 8);
596 #else
597                                 M_IST(s1, REG_SP, var->regoff * 8);
598 #endif
599                         } else {
600                                 s1 = emit_load_s1(jd, iptr, var->regoff);
601                                 M_INTMOVE(s1, var->regoff);
602                         }
603                         break;
604
605                 case ICMD_LSTORE:     /* ..., value  ==> ...                          */
606                                       /* dst.localindex = local variable                         */
607
608                         if ((iptr->s1.var->varkind == LOCALVAR) &&
609                             (iptr->s1.var->varnum == iptr->dst.localindex))
610                                 break;
611                         var = &(rd->locals[iptr->dst.localindex][iptr->opc - ICMD_ISTORE]);
612                         if (var->flags & INMEMORY) {
613                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
614                                 M_LST(s1, REG_SP, var->regoff * 8);
615                         } else {
616                                 s1 = emit_load_s1(jd, iptr, var->regoff);
617                                 M_INTMOVE(s1, var->regoff);
618                         }
619                         break;
620
621                 case ICMD_ASTORE:     /* ..., value  ==> ...                          */
622                                       /* dst.localindex = local variable                         */
623
624                         if ((iptr->s1.var->varkind == LOCALVAR) &&
625                             (iptr->s1.var->varnum == iptr->dst.localindex))
626                                 break;
627                         var = &(rd->locals[iptr->dst.localindex][iptr->opc - ICMD_ISTORE]);
628                         if (var->flags & INMEMORY) {
629                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
630                                 M_AST(s1, REG_SP, var->regoff * 8);
631                         } else {
632                                 s1 = emit_load_s1(jd, iptr, var->regoff);
633                                 M_INTMOVE(s1, var->regoff);
634                         }
635                         break;
636
637                 case ICMD_FSTORE:     /* ..., value  ==> ...                          */
638                                       /* dst.localindex = local variable                         */
639
640                         if ((iptr->s1.var->varkind == LOCALVAR) &&
641                             (iptr->s1.var->varnum == iptr->dst.localindex))
642                                 break;
643                         var = &(rd->locals[iptr->dst.localindex][iptr->opc - ICMD_ISTORE]);
644                         if (var->flags & INMEMORY) {
645                                 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
646                                 M_FST(s1, REG_SP, var->regoff * 8);
647                         } else {
648                                 s1 = emit_load_s1(jd, iptr, var->regoff);
649                                 M_FMOV(s1, var->regoff);
650                         }
651                         break;
652
653                 case ICMD_DSTORE:     /* ..., value  ==> ...                          */
654                                       /* dst.localindex = local variable                         */
655
656                         if ((iptr->s1.var->varkind == LOCALVAR) &&
657                             (iptr->s1.var->varnum == iptr->dst.localindex))
658                                 break;
659                         var = &(rd->locals[iptr->dst.localindex][iptr->opc - ICMD_ISTORE]);
660                         if (var->flags & INMEMORY) {
661                                 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
662                                 M_DST(s1, REG_SP, var->regoff * 8);
663                         } else {
664                                 s1 = emit_load_s1(jd, iptr, var->regoff);
665                                 M_DMOV(s1, var->regoff);
666                         }
667                         break;
668
669
670                 /* pop/dup/swap operations ********************************************/
671
672                 /* attention: double and longs are only one entry in CACAO ICMDs      */
673
674                 case ICMD_POP:        /* ..., value  ==> ...                          */
675                 case ICMD_POP2:       /* ..., value, value  ==> ...                   */
676                         break;
677
678                 case ICMD_DUP:        /* ..., a ==> ..., a, a                         */
679
680                         M_COPY(iptr->s1.var, iptr->dst.var);
681                         break;
682
683                 case ICMD_DUP_X1:     /* ..., a, b ==> ..., b, a, b                   */
684
685                         M_COPY(iptr->dst.dupslots[  1], iptr->dst.dupslots[2+2]);
686                         M_COPY(iptr->dst.dupslots[  0], iptr->dst.dupslots[2+1]);
687                         M_COPY(iptr->dst.dupslots[2+2], iptr->dst.dupslots[2+0]);
688                         break;
689
690                 case ICMD_DUP_X2:     /* ..., a, b, c ==> ..., c, a, b, c             */
691
692                         M_COPY(iptr->dst.dupslots[  2], iptr->dst.dupslots[3+3]);
693                         M_COPY(iptr->dst.dupslots[  1], iptr->dst.dupslots[3+2]);
694                         M_COPY(iptr->dst.dupslots[  0], iptr->dst.dupslots[3+1]);
695                         M_COPY(iptr->dst.dupslots[3+3], iptr->dst.dupslots[3+0]);
696                         break;
697
698                 case ICMD_DUP2:       /* ..., a, b ==> ..., a, b, a, b                */
699
700                         M_COPY(iptr->dst.dupslots[  1], iptr->dst.dupslots[2+1]);
701                         M_COPY(iptr->dst.dupslots[  0], iptr->dst.dupslots[2+0]);
702                         break;
703
704                 case ICMD_DUP2_X1:    /* ..., a, b, c ==> ..., b, c, a, b, c          */
705
706                         M_COPY(iptr->dst.dupslots[  2], iptr->dst.dupslots[3+4]);
707                         M_COPY(iptr->dst.dupslots[  1], iptr->dst.dupslots[3+3]);
708                         M_COPY(iptr->dst.dupslots[  0], iptr->dst.dupslots[3+2]);
709                         M_COPY(iptr->dst.dupslots[3+4], iptr->dst.dupslots[3+1]);
710                         M_COPY(iptr->dst.dupslots[3+3], iptr->dst.dupslots[3+0]);
711                         break;
712
713                 case ICMD_DUP2_X2:    /* ..., a, b, c, d ==> ..., c, d, a, b, c, d    */
714
715                         M_COPY(iptr->dst.dupslots[  3], iptr->dst.dupslots[4+5]);
716                         M_COPY(iptr->dst.dupslots[  2], iptr->dst.dupslots[4+4]);
717                         M_COPY(iptr->dst.dupslots[  1], iptr->dst.dupslots[4+3]);
718                         M_COPY(iptr->dst.dupslots[  0], iptr->dst.dupslots[4+2]);
719                         M_COPY(iptr->dst.dupslots[4+5], iptr->dst.dupslots[4+1]);
720                         M_COPY(iptr->dst.dupslots[4+4], iptr->dst.dupslots[4+0]);
721                         break;
722
723                 case ICMD_SWAP:       /* ..., a, b ==> ..., b, a                      */
724
725                         M_COPY(iptr->dst.dupslots[  1], iptr->dst.dupslots[2+0]);
726                         M_COPY(iptr->dst.dupslots[  0], iptr->dst.dupslots[2+1]);
727                         break;
728
729
730                 /* integer operations *************************************************/
731
732                 case ICMD_INEG:       /* ..., value  ==> ..., - value                 */
733
734                         s1 = emit_load_s1(jd, iptr, REG_ITMP1); 
735                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
736                         M_ISUB(REG_ZERO, s1, d);
737                         emit_store_dst(jd, iptr, d);
738                         break;
739
740                 case ICMD_LNEG:       /* ..., value  ==> ..., - value                 */
741
742                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
743                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
744                         M_LSUB(REG_ZERO, s1, d);
745                         emit_store_dst(jd, iptr, d);
746                         break;
747
748                 case ICMD_I2L:        /* ..., value  ==> ..., value                   */
749
750                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
751                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
752                         M_INTMOVE(s1, d);
753                         emit_store_dst(jd, iptr, d);
754                         break;
755
756                 case ICMD_L2I:        /* ..., value  ==> ..., value                   */
757
758                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
759                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
760                         M_ISLL_IMM(s1, 0, d );
761                         emit_store_dst(jd, iptr, d);
762                         break;
763
764                 case ICMD_INT2BYTE:   /* ..., value  ==> ..., value                   */
765
766                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
767                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
768                         M_LSLL_IMM(s1, 56, d);
769                         M_LSRA_IMM( d, 56, d);
770                         emit_store_dst(jd, iptr, d);
771                         break;
772
773                 case ICMD_INT2CHAR:   /* ..., value  ==> ..., value                   */
774
775                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
776                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
777             M_CZEXT(s1, d);
778                         emit_store_dst(jd, iptr, d);
779                         break;
780
781                 case ICMD_INT2SHORT:  /* ..., value  ==> ..., value                   */
782
783                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
784                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
785                         M_LSLL_IMM(s1, 48, d);
786                         M_LSRA_IMM( d, 48, d);
787                         emit_store_dst(jd, iptr, d);
788                         break;
789
790
791                 case ICMD_IADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
792
793                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
794                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
795                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
796                         M_IADD(s1, s2, d);
797                         emit_store_dst(jd, iptr, d);
798                         break;
799
800                 case ICMD_IADDCONST:  /* ..., value  ==> ..., value + constant        */
801                                       /* sx.val.i = constant                             */
802
803                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
804                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
805                         if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767)) {
806                                 M_IADD_IMM(s1, iptr->sx.val.i, d);
807                         } else {
808                                 ICONST(REG_ITMP2, iptr->sx.val.i);
809                                 M_IADD(s1, REG_ITMP2, d);
810                         }
811                         emit_store_dst(jd, iptr, d);
812                         break;
813
814                 case ICMD_LADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
815
816                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
817                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
818                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
819                         M_LADD(s1, s2, d);
820                         emit_store_dst(jd, iptr, d);
821                         break;
822
823                 case ICMD_LADDCONST:  /* ..., value  ==> ..., value + constant        */
824                                       /* sx.val.l = constant                             */
825
826                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
827                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
828                         if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
829                                 M_LADD_IMM(s1, iptr->sx.val.l, d);
830                         } else {
831                                 LCONST(REG_ITMP2, iptr->sx.val.l);
832                                 M_LADD(s1, REG_ITMP2, d);
833                         }
834                         emit_store_dst(jd, iptr, d);
835                         break;
836
837                 case ICMD_ISUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
838
839                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
840                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
841                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
842                         M_ISUB(s1, s2, d);
843                         emit_store_dst(jd, iptr, d);
844                         break;
845
846                 case ICMD_ISUBCONST:  /* ..., value  ==> ..., value + constant        */
847                                       /* sx.val.i = constant                             */
848
849                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
850                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
851                         if ((iptr->sx.val.i >= -32767) && (iptr->sx.val.i <= 32768)) {
852                                 M_IADD_IMM(s1, -iptr->sx.val.i, d);
853                         } else {
854                                 ICONST(REG_ITMP2, iptr->sx.val.i);
855                                 M_ISUB(s1, REG_ITMP2, d);
856                         }
857                         emit_store_dst(jd, iptr, d);
858                         break;
859
860                 case ICMD_LSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
861
862                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
863                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
864                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
865                         M_LSUB(s1, s2, d);
866                         emit_store_dst(jd, iptr, d);
867                         break;
868
869                 case ICMD_LSUBCONST:  /* ..., value  ==> ..., value - constant        */
870                                       /* sx.val.l = constant                             */
871
872                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
873                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
874                         if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l <= 32768)) {
875                                 M_LADD_IMM(s1, -iptr->sx.val.l, d);
876                         } else {
877                                 LCONST(REG_ITMP2, iptr->sx.val.l);
878                                 M_LSUB(s1, REG_ITMP2, d);
879                         }
880                         emit_store_dst(jd, iptr, d);
881                         break;
882
883                 case ICMD_IMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
884
885                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
886                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
887                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
888                         M_IMUL(s1, s2);
889                         M_MFLO(d);
890                         M_NOP;
891                         M_NOP;
892                         emit_store_dst(jd, iptr, d);
893                         break;
894
895                 case ICMD_IMULCONST:  /* ..., value  ==> ..., value * constant        */
896                                       /* sx.val.i = constant                             */
897
898                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
899                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
900                         ICONST(REG_ITMP2, iptr->sx.val.i);
901                         M_IMUL(s1, REG_ITMP2);
902                         M_MFLO(d);
903                         M_NOP;
904                         M_NOP;
905                         emit_store_dst(jd, iptr, d);
906                         break;
907
908                 case ICMD_LMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
909
910                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
911                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
912                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
913                         M_LMUL(s1, s2);
914                         M_MFLO(d);
915                         M_NOP;
916                         M_NOP;
917                         emit_store_dst(jd, iptr, d);
918                         break;
919
920                 case ICMD_LMULCONST:  /* ..., value  ==> ..., value * constant        */
921                                       /* sx.val.l = constant                             */
922
923                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
924                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
925                         LCONST(REG_ITMP2, iptr->sx.val.l);
926                         M_LMUL(s1, REG_ITMP2);
927                         M_MFLO(d);
928                         M_NOP;
929                         M_NOP;
930                         emit_store_dst(jd, iptr, d);
931                         break;
932
933                 case ICMD_IDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
934
935                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
936                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
937                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
938                         gen_div_check(s2);
939                         M_IDIV(s1, s2);
940                         M_MFLO(d);
941                         M_NOP;
942                         M_NOP;
943                         emit_store_dst(jd, iptr, d);
944                         break;
945
946                 case ICMD_LDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
947
948                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
949                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
950                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
951                         gen_div_check(s2);
952                         M_LDIV(s1, s2);
953                         M_MFLO(d);
954                         M_NOP;
955                         M_NOP;
956                         emit_store_dst(jd, iptr, d);
957                         break;
958
959                 case ICMD_IREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
960
961                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
962                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
963                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
964                         gen_div_check(s2);
965                         M_IDIV(s1, s2);
966                         M_MFHI(d);
967                         M_NOP;
968                         M_NOP;
969                         emit_store_dst(jd, iptr, d);
970                         break;
971
972                 case ICMD_LREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
973
974                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
975                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
976                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
977                         gen_div_check(s2);
978                         M_LDIV(s1, s2);
979                         M_MFHI(d);
980                         M_NOP;
981                         M_NOP;
982                         emit_store_dst(jd, iptr, d);
983                         break;
984
985                 case ICMD_IDIVPOW2:   /* ..., value  ==> ..., value << constant       */
986                 case ICMD_LDIVPOW2:   /* val.i = constant                             */
987                                       
988                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
989                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
990                         M_LSRA_IMM(s1, 63, REG_ITMP2);
991                         M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
992                         M_LADD(s1, REG_ITMP2, REG_ITMP2);
993                         M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
994                         emit_store_dst(jd, iptr, d);
995                         break;
996
997                 case ICMD_ISHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
998
999                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1000                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1001                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1002                         M_ISLL(s1, s2, d);
1003                         emit_store_dst(jd, iptr, d);
1004                         break;
1005
1006                 case ICMD_ISHLCONST:  /* ..., value  ==> ..., value << constant       */
1007                                       /* sx.val.i = constant                             */
1008
1009                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1010                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1011                         M_ISLL_IMM(s1, iptr->sx.val.i, d);
1012                         emit_store_dst(jd, iptr, d);
1013                         break;
1014
1015                 case ICMD_ISHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
1016
1017                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1018                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1019                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1020                         M_ISRA(s1, s2, d);
1021                         emit_store_dst(jd, iptr, d);
1022                         break;
1023
1024                 case ICMD_ISHRCONST:  /* ..., value  ==> ..., value >> constant       */
1025                                       /* sx.val.i = constant                             */
1026
1027                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1028                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1029                         M_ISRA_IMM(s1, iptr->sx.val.i, d);
1030                         emit_store_dst(jd, iptr, d);
1031                         break;
1032
1033                 case ICMD_IUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
1034
1035                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1036                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1037                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1038                         M_ISRL(s1, s2, d);
1039                         emit_store_dst(jd, iptr, d);
1040                         break;
1041
1042                 case ICMD_IUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
1043                                       /* sx.val.i = constant                             */
1044
1045                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1046                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1047                         M_ISRL_IMM(s1, iptr->sx.val.i, d);
1048                         emit_store_dst(jd, iptr, d);
1049                         break;
1050
1051                 case ICMD_LSHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
1052
1053                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1054                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1055                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1056                         M_LSLL(s1, s2, d);
1057                         emit_store_dst(jd, iptr, d);
1058                         break;
1059
1060                 case ICMD_LSHLCONST:  /* ..., value  ==> ..., value << constant       */
1061                                       /* sx.val.i = constant                             */
1062
1063                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1064                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1065                         M_LSLL_IMM(s1, iptr->sx.val.i, d);
1066                         emit_store_dst(jd, iptr, d);
1067                         break;
1068
1069                 case ICMD_LSHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
1070
1071                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1072                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1073                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1074                         M_LSRA(s1, s2, d);
1075                         emit_store_dst(jd, iptr, d);
1076                         break;
1077
1078                 case ICMD_LSHRCONST:  /* ..., value  ==> ..., value >> constant       */
1079                                       /* sx.val.i = constant                             */
1080
1081                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1082                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1083                         M_LSRA_IMM(s1, iptr->sx.val.i, d);
1084                         emit_store_dst(jd, iptr, d);
1085                         break;
1086
1087                 case ICMD_LUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
1088
1089                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1090                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1091                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1092                         M_LSRL(s1, s2, d);
1093                         emit_store_dst(jd, iptr, d);
1094                         break;
1095
1096                 case ICMD_LUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
1097                                       /* sx.val.i = constant                             */
1098
1099                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1100                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1101                         M_LSRL_IMM(s1, iptr->sx.val.i, d);
1102                         emit_store_dst(jd, iptr, d);
1103                         break;
1104
1105                 case ICMD_IAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
1106                 case ICMD_LAND:
1107
1108                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1109                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1110                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1111                         M_AND(s1, s2, d);
1112                         emit_store_dst(jd, iptr, d);
1113                         break;
1114
1115                 case ICMD_IANDCONST:  /* ..., value  ==> ..., value & constant        */
1116                                       /* sx.val.i = constant                             */
1117
1118                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1119                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1120                         if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
1121                                 M_AND_IMM(s1, iptr->sx.val.i, d);
1122                         } else {
1123                                 ICONST(REG_ITMP2, iptr->sx.val.i);
1124                                 M_AND(s1, REG_ITMP2, d);
1125                         }
1126                         emit_store_dst(jd, iptr, d);
1127                         break;
1128
1129                 case ICMD_IREMPOW2:   /* ..., value  ==> ..., value % constant        */
1130                                       /* sx.val.i = constant                             */
1131
1132                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1133                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1134                         if (s1 == d) {
1135                                 M_MOV(s1, REG_ITMP1);
1136                                 s1 = REG_ITMP1;
1137                         }
1138                         if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
1139                                 M_AND_IMM(s1, iptr->sx.val.i, d);
1140                                 M_BGEZ(s1, 4);
1141                                 M_NOP;
1142                                 M_ISUB(REG_ZERO, s1, d);
1143                                 M_AND_IMM(d, iptr->sx.val.i, d);
1144                         } else {
1145                                 ICONST(REG_ITMP2, iptr->sx.val.i);
1146                                 M_AND(s1, REG_ITMP2, d);
1147                                 M_BGEZ(s1, 4);
1148                                 M_NOP;
1149                                 M_ISUB(REG_ZERO, s1, d);
1150                                 M_AND(d, REG_ITMP2, d);
1151                         }
1152                         M_ISUB(REG_ZERO, d, d);
1153                         emit_store_dst(jd, iptr, d);
1154                         break;
1155
1156                 case ICMD_LANDCONST:  /* ..., value  ==> ..., value & constant        */
1157                                       /* sx.val.l = constant                             */
1158
1159                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1160                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1161                         if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1162                                 M_AND_IMM(s1, iptr->sx.val.l, d);
1163                         } else {
1164                                 LCONST(REG_ITMP2, iptr->sx.val.l);
1165                                 M_AND(s1, REG_ITMP2, d);
1166                         }
1167                         emit_store_dst(jd, iptr, d);
1168                         break;
1169
1170                 case ICMD_LREMPOW2:   /* ..., value  ==> ..., value % constant        */
1171                                       /* sx.val.l = constant                             */
1172
1173                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1174                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1175                         if (s1 == d) {
1176                                 M_MOV(s1, REG_ITMP1);
1177                                 s1 = REG_ITMP1;
1178                         }
1179                         if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1180                                 M_AND_IMM(s1, iptr->sx.val.l, d);
1181                                 M_BGEZ(s1, 4);
1182                                 M_NOP;
1183                                 M_LSUB(REG_ZERO, s1, d);
1184                                 M_AND_IMM(d, iptr->sx.val.l, d);
1185                         } else {
1186                                 LCONST(REG_ITMP2, iptr->sx.val.l);
1187                                 M_AND(s1, REG_ITMP2, d);
1188                                 M_BGEZ(s1, 4);
1189                                 M_NOP;
1190                                 M_LSUB(REG_ZERO, s1, d);
1191                                 M_AND(d, REG_ITMP2, d);
1192                         }
1193                         M_LSUB(REG_ZERO, d, d);
1194                         emit_store_dst(jd, iptr, d);
1195                         break;
1196
1197                 case ICMD_IOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
1198                 case ICMD_LOR:
1199
1200                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1201                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1202                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1203                         M_OR(s1,s2, d);
1204                         emit_store_dst(jd, iptr, d);
1205                         break;
1206
1207                 case ICMD_IORCONST:   /* ..., value  ==> ..., value | constant        */
1208                                       /* sx.val.i = constant                             */
1209
1210                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1211                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1212                         if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
1213                                 M_OR_IMM(s1, iptr->sx.val.i, d);
1214                         } else {
1215                                 ICONST(REG_ITMP2, iptr->sx.val.i);
1216                                 M_OR(s1, REG_ITMP2, d);
1217                         }
1218                         emit_store_dst(jd, iptr, d);
1219                         break;
1220
1221                 case ICMD_LORCONST:   /* ..., value  ==> ..., value | constant        */
1222                                       /* sx.val.l = constant                             */
1223
1224                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1225                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1226                         if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1227                                 M_OR_IMM(s1, iptr->sx.val.l, d);
1228                         } else {
1229                                 LCONST(REG_ITMP2, iptr->sx.val.l);
1230                                 M_OR(s1, REG_ITMP2, d);
1231                         }
1232                         emit_store_dst(jd, iptr, d);
1233                         break;
1234
1235                 case ICMD_IXOR:       /* ..., val1, val2  ==> ..., val1 ^ val2        */
1236                 case ICMD_LXOR:
1237
1238                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1239                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1240                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1241                         M_XOR(s1, s2, d);
1242                         emit_store_dst(jd, iptr, d);
1243                         break;
1244
1245                 case ICMD_IXORCONST:  /* ..., value  ==> ..., value ^ constant        */
1246                                       /* sx.val.i = constant                             */
1247
1248                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1249                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1250                         if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
1251                                 M_XOR_IMM(s1, iptr->sx.val.i, d);
1252                         } else {
1253                                 ICONST(REG_ITMP2, iptr->sx.val.i);
1254                                 M_XOR(s1, REG_ITMP2, d);
1255                         }
1256                         emit_store_dst(jd, iptr, d);
1257                         break;
1258
1259                 case ICMD_LXORCONST:  /* ..., value  ==> ..., value ^ constant        */
1260                                       /* sx.val.l = constant                             */
1261
1262                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1263                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1264                         if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1265                                 M_XOR_IMM(s1, iptr->sx.val.l, d);
1266                         } else {
1267                                 LCONST(REG_ITMP2, iptr->sx.val.l);
1268                                 M_XOR(s1, REG_ITMP2, d);
1269                         }
1270                         emit_store_dst(jd, iptr, d);
1271                         break;
1272
1273
1274                 case ICMD_LCMP:       /* ..., val1, val2  ==> ..., val1 cmp val2      */
1275
1276                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1277                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1278                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1279                         M_CMPLT(s1, s2, REG_ITMP3);
1280                         M_CMPLT(s2, s1, REG_ITMP1);
1281                         M_LSUB(REG_ITMP1, REG_ITMP3, d);
1282                         emit_store_dst(jd, iptr, d);
1283                         break;
1284
1285
1286                 case ICMD_IINC:       /* ..., value  ==> ..., value + constant        */
1287                                       /* s1.localindex = variable, sx.val.i = constant             */
1288
1289                         var = &(rd->locals[iptr->s1.localindex][TYPE_INT]);
1290                         if (var->flags & INMEMORY) {
1291                                 s1 = REG_ITMP1;
1292                                 M_LLD(s1, REG_SP, var->regoff * 8);
1293                         } else
1294                                 s1 = var->regoff;
1295                         M_IADD_IMM(s1, iptr->sx.val.i, s1);
1296                         if (var->flags & INMEMORY)
1297                                 M_LST(s1, REG_SP, var->regoff * 8);
1298                         break;
1299
1300
1301                 /* floating operations ************************************************/
1302
1303                 case ICMD_FNEG:       /* ..., value  ==> ..., - value                 */
1304
1305                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1306                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1307                         M_FNEG(s1, d);
1308                         emit_store_dst(jd, iptr, d);
1309                         break;
1310
1311                 case ICMD_DNEG:       /* ..., value  ==> ..., - value                 */
1312
1313                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1314                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1315                         M_DNEG(s1, d);
1316                         emit_store_dst(jd, iptr, d);
1317                         break;
1318
1319                 case ICMD_FADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
1320
1321                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1322                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1323                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1324                         M_FADD(s1, s2, d);
1325                         emit_store_dst(jd, iptr, d);
1326                         break;
1327
1328                 case ICMD_DADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
1329
1330                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1331                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1332                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1333                         M_DADD(s1, s2, d);
1334                         emit_store_dst(jd, iptr, d);
1335                         break;
1336
1337                 case ICMD_FSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
1338
1339                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1340                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1341                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1342                         M_FSUB(s1, s2, d);
1343                         emit_store_dst(jd, iptr, d);
1344                         break;
1345
1346                 case ICMD_DSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
1347
1348                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1349                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1350                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1351                         M_DSUB(s1, s2, d);
1352                         emit_store_dst(jd, iptr, d);
1353                         break;
1354
1355                 case ICMD_FMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
1356
1357                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1358                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1359                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1360                         M_FMUL(s1, s2, d);
1361                         emit_store_dst(jd, iptr, d);
1362                         break;
1363
1364                 case ICMD_DMUL:       /* ..., val1, val2  ==> ..., val1 *** val2      */
1365
1366                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1367                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1368                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1369                         M_DMUL(s1, s2, d);
1370                         emit_store_dst(jd, iptr, d);
1371                         break;
1372
1373                 case ICMD_FDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1374
1375                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1376                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1377                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1378                         M_FDIV(s1, s2, d);
1379                         emit_store_dst(jd, iptr, d);
1380                         break;
1381
1382                 case ICMD_DDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1383
1384                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1385                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1386                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1387                         M_DDIV(s1, s2, d);
1388                         emit_store_dst(jd, iptr, d);
1389                         break;
1390
1391 #if 0           
1392                 case ICMD_FREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
1393
1394                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1395                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1396                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1397                         M_FDIV(s1,s2, REG_FTMP3);
1398                         M_FLOORFL(REG_FTMP3, REG_FTMP3);
1399                         M_CVTLF(REG_FTMP3, REG_FTMP3);
1400                         M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1401                         M_FSUB(s1, REG_FTMP3, d);
1402                         emit_store_dst(jd, iptr, d);
1403                     break;
1404
1405                 case ICMD_DREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
1406
1407                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1408                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1409                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1410                         M_DDIV(s1,s2, REG_FTMP3);
1411                         M_FLOORDL(REG_FTMP3, REG_FTMP3);
1412                         M_CVTLD(REG_FTMP3, REG_FTMP3);
1413                         M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1414                         M_DSUB(s1, REG_FTMP3, d);
1415                         emit_store_dst(jd, iptr, d);
1416                     break;
1417 #endif
1418
1419                 case ICMD_I2F:       /* ..., value  ==> ..., (float) value            */
1420                 case ICMD_L2F:
1421                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1422                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1423                         M_MOVLD(s1, d);
1424                         M_CVTLF(d, d);
1425                         emit_store_dst(jd, iptr, d);
1426                         break;
1427
1428                 case ICMD_I2D:       /* ..., value  ==> ..., (double) value           */
1429                 case ICMD_L2D:
1430                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1431                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1432                         M_MOVLD(s1, d);
1433                         M_CVTLD(d, d);
1434                         emit_store_dst(jd, iptr, d);
1435                         break;
1436
1437 #if 0
1438                 /* XXX these do not work correctly */
1439
1440                 case ICMD_F2I:       /* ..., (float) value  ==> ..., (int) value      */
1441
1442                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1443                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1444                         M_TRUNCFI(s1, REG_FTMP1);
1445                         M_MOVDI(REG_FTMP1, d);
1446                         M_NOP;
1447                         emit_store_dst(jd, iptr, d);
1448                         break;
1449                 
1450                 case ICMD_D2I:       /* ..., (double) value  ==> ..., (int) value     */
1451
1452                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1453                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1454                         M_TRUNCDI(s1, REG_FTMP1);
1455                         M_MOVDI(REG_FTMP1, d);
1456                         M_NOP;
1457                         emit_store_dst(jd, iptr, d);
1458                         break;
1459                 
1460                 case ICMD_F2L:       /* ..., (float) value  ==> ..., (long) value     */
1461
1462                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1463                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1464                         M_TRUNCFL(s1, REG_FTMP1);
1465                         M_MOVDL(REG_FTMP1, d);
1466                         M_NOP;
1467                         emit_store_dst(jd, iptr, d);
1468                         break;
1469
1470                 case ICMD_D2L:       /* ..., (double) value  ==> ..., (long) value    */
1471
1472                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1473                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1474                         M_TRUNCDL(s1, REG_FTMP1);
1475                         M_MOVDL(REG_FTMP1, d);
1476                         M_NOP;
1477                         emit_store_dst(jd, iptr, d);
1478                         break;
1479 #endif
1480
1481                 case ICMD_F2D:       /* ..., value  ==> ..., (double) value           */
1482
1483                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1484                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1485                         M_CVTFD(s1, d);
1486                         emit_store_dst(jd, iptr, d);
1487                         break;
1488                                         
1489                 case ICMD_D2F:       /* ..., value  ==> ..., (double) value           */
1490
1491                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1492                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1493                         M_CVTDF(s1, d);
1494                         emit_store_dst(jd, iptr, d);
1495                         break;
1496                 
1497                 case ICMD_FCMPL:      /* ..., val1, val2  ==> ..., val1 fcmpl val2    */
1498
1499                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1500                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1501                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1502                         M_FCMPULEF(s1, s2);
1503                         M_FBT(3);
1504                         M_LADD_IMM(REG_ZERO, 1, d);
1505                         M_BR(4);
1506                         M_NOP;
1507                         M_FCMPEQF(s1, s2);
1508                         M_LSUB_IMM(REG_ZERO, 1, d);
1509                         M_CMOVT(REG_ZERO, d);
1510                         emit_store_dst(jd, iptr, d);
1511                         break;
1512
1513                 case ICMD_DCMPL:      /* ..., val1, val2  ==> ..., val1 fcmpl val2    */
1514
1515                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1516                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1517                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1518                         M_FCMPULED(s1, s2);
1519                         M_FBT(3);
1520                         M_LADD_IMM(REG_ZERO, 1, d);
1521                         M_BR(4);
1522                         M_NOP;
1523                         M_FCMPEQD(s1, s2);
1524                         M_LSUB_IMM(REG_ZERO, 1, d);
1525                         M_CMOVT(REG_ZERO, d);
1526                         emit_store_dst(jd, iptr, d);
1527                         break;
1528                         
1529                 case ICMD_FCMPG:      /* ..., val1, val2  ==> ..., val1 fcmpg val2    */
1530
1531                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1532                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1533                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1534                         M_FCMPOLTF(s1, s2);
1535                         M_FBF(3);
1536                         M_LSUB_IMM(REG_ZERO, 1, d);
1537                         M_BR(4);
1538                         M_NOP;
1539                         M_FCMPEQF(s1, s2);
1540                         M_LADD_IMM(REG_ZERO, 1, d);
1541                         M_CMOVT(REG_ZERO, d);
1542                         emit_store_dst(jd, iptr, d);
1543                         break;
1544
1545                 case ICMD_DCMPG:      /* ..., val1, val2  ==> ..., val1 fcmpg val2    */
1546
1547                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1548                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1549                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1550                         M_FCMPOLTD(s1, s2);
1551                         M_FBF(3);
1552                         M_LSUB_IMM(REG_ZERO, 1, d);
1553                         M_BR(4);
1554                         M_NOP;
1555                         M_FCMPEQD(s1, s2);
1556                         M_LADD_IMM(REG_ZERO, 1, d);
1557                         M_CMOVT(REG_ZERO, d);
1558                         emit_store_dst(jd, iptr, d);
1559                         break;
1560
1561
1562                 /* memory operations **************************************************/
1563
1564                 case ICMD_ARRAYLENGTH: /* ..., arrayref  ==> ..., length              */
1565
1566                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1567                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1568                         gen_nullptr_check(s1);
1569                         M_ILD(d, s1, OFFSET(java_arrayheader, size));
1570                         emit_store_dst(jd, iptr, d);
1571                         break;
1572
1573                 case ICMD_BALOAD:     /* ..., arrayref, index  ==> ..., value         */
1574
1575                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1576                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1577                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1578                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1579                                 gen_nullptr_check(s1);
1580                                 gen_bound_check;
1581                         }
1582                         M_AADD(s2, s1, REG_ITMP3);
1583                         M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray, data[0]));
1584                         emit_store_dst(jd, iptr, d);
1585                         break;
1586
1587                 case ICMD_CALOAD:     /* ..., arrayref, index  ==> ..., value         */
1588
1589                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1590                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1591                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1592                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1593                                 gen_nullptr_check(s1);
1594                                 gen_bound_check;
1595                         }
1596                         M_AADD(s2, s1, REG_ITMP3);
1597                         M_AADD(s2, REG_ITMP3, REG_ITMP3);
1598                         M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1599                         emit_store_dst(jd, iptr, d);
1600                         break;                  
1601
1602                 case ICMD_SALOAD:     /* ..., arrayref, index  ==> ..., value         */
1603
1604                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1605                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1606                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1607                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1608                                 gen_nullptr_check(s1);
1609                                 gen_bound_check;
1610                         }
1611                         M_AADD(s2, s1, REG_ITMP3);
1612                         M_AADD(s2, REG_ITMP3, REG_ITMP3);
1613                         M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray, data[0]));
1614                         emit_store_dst(jd, iptr, d);
1615                         break;
1616
1617                 case ICMD_IALOAD:     /* ..., arrayref, index  ==> ..., value         */
1618
1619                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1620                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1621                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1622                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1623                                 gen_nullptr_check(s1);
1624                                 gen_bound_check;
1625                         }
1626                         M_ASLL_IMM(s2, 2, REG_ITMP3);
1627                         M_AADD(REG_ITMP3, s1, REG_ITMP3);
1628                         M_ILD(d, REG_ITMP3, OFFSET(java_intarray, data[0]));
1629                         emit_store_dst(jd, iptr, d);
1630                         break;
1631
1632                 case ICMD_LALOAD:     /* ..., arrayref, index  ==> ..., value         */
1633
1634                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1635                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1636                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1637                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1638                                 gen_nullptr_check(s1);
1639                                 gen_bound_check;
1640                         }
1641                         M_ASLL_IMM(s2, 3, REG_ITMP3);
1642                         M_AADD(REG_ITMP3, s1, REG_ITMP3);
1643                         M_LLD(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
1644                         emit_store_dst(jd, iptr, d);
1645                         break;
1646
1647                 case ICMD_FALOAD:     /* ..., arrayref, index  ==> ..., value         */
1648
1649                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1650                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1651                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1652                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1653                                 gen_nullptr_check(s1);
1654                                 gen_bound_check;
1655                         }
1656                         M_ASLL_IMM(s2, 2, REG_ITMP3);
1657                         M_AADD(REG_ITMP3, s1, REG_ITMP3);
1658                         M_FLD(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
1659                         emit_store_dst(jd, iptr, d);
1660                         break;
1661
1662                 case ICMD_DALOAD:     /* ..., arrayref, index  ==> ..., value         */
1663
1664                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1665                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1666                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1667                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1668                                 gen_nullptr_check(s1);
1669                                 gen_bound_check;
1670                         }
1671                         M_ASLL_IMM(s2, 3, REG_ITMP3);
1672                         M_AADD(REG_ITMP3, s1, REG_ITMP3);
1673                         M_DLD(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
1674                         emit_store_dst(jd, iptr, d);
1675                         break;
1676
1677                 case ICMD_AALOAD:     /* ..., arrayref, index  ==> ..., value         */
1678
1679                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1680                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1681                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1682                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1683                                 gen_nullptr_check(s1);
1684                                 gen_bound_check;
1685                         }
1686                         M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1687                         M_AADD(REG_ITMP3, s1, REG_ITMP3);
1688                         M_ALD(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
1689                         emit_store_dst(jd, iptr, d);
1690                         break;
1691
1692
1693                 case ICMD_BASTORE:    /* ..., arrayref, index, value  ==> ...         */
1694
1695                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1696                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1697                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1698                                 gen_nullptr_check(s1);
1699                                 gen_bound_check;
1700                         }
1701                         M_AADD(s2, s1, REG_ITMP1);
1702                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1703                         M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1704                         break;
1705
1706                 case ICMD_CASTORE:    /* ..., arrayref, index, value  ==> ...         */
1707                 case ICMD_SASTORE:    /* ..., arrayref, index, value  ==> ...         */
1708
1709                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1710                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1711                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1712                                 gen_nullptr_check(s1);
1713                                 gen_bound_check;
1714                         }
1715                         M_AADD(s2, s1, REG_ITMP1);
1716                         M_AADD(s2, REG_ITMP1, REG_ITMP1);
1717                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1718                         M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1719                         break;
1720
1721                 case ICMD_IASTORE:    /* ..., arrayref, index, value  ==> ...         */
1722
1723                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1724                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1725                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1726                                 gen_nullptr_check(s1);
1727                                 gen_bound_check;
1728                         }
1729                         M_ASLL_IMM(s2, 2, REG_ITMP2);
1730                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1731                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1732                         M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1733                         break;
1734
1735                 case ICMD_LASTORE:    /* ..., arrayref, index, value  ==> ...         */
1736
1737                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1738                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1739                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1740                                 gen_nullptr_check(s1);
1741                                 gen_bound_check;
1742                         }
1743                         M_ASLL_IMM(s2, 3, REG_ITMP2);
1744                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1745                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1746                         M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1747                         break;
1748
1749                 case ICMD_FASTORE:    /* ..., arrayref, index, value  ==> ...         */
1750
1751                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1752                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1753                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1754                                 gen_nullptr_check(s1);
1755                                 gen_bound_check;
1756                         }
1757                         M_ASLL_IMM(s2, 2, REG_ITMP2);
1758                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1759                         s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1760                         M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1761                         break;
1762
1763                 case ICMD_DASTORE:    /* ..., arrayref, index, value  ==> ...         */
1764
1765                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1766                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1767                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1768                                 gen_nullptr_check(s1);
1769                                 gen_bound_check;
1770                         }
1771                         M_ASLL_IMM(s2, 3, REG_ITMP2);
1772                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1773                         s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1774                         M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1775                         break;
1776
1777
1778                 case ICMD_AASTORE:    /* ..., arrayref, index, value  ==> ...         */
1779
1780                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1781                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1782                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1783                                 gen_nullptr_check(s1);
1784                                 gen_bound_check;
1785                         }
1786                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1787
1788                         M_MOV(s1, REG_A0);
1789                         M_MOV(s3, REG_A1);
1790                         disp = dseg_addaddress(cd, BUILTIN_canstore);
1791                         M_ALD(REG_ITMP3, REG_PV, disp);
1792                         M_JSR(REG_RA, REG_ITMP3);
1793                         M_NOP;
1794
1795                         M_BEQZ(REG_RESULT, 0);
1796                         codegen_add_arraystoreexception_ref(cd);
1797                         M_NOP;
1798
1799                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1800                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1801                         M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1802                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1803                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1804                         M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1805                         break;
1806
1807
1808                 case ICMD_BASTORECONST:   /* ..., arrayref, index  ==> ...            */
1809
1810                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1811                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1812                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1813                                 gen_nullptr_check(s1);
1814                                 gen_bound_check;
1815                         }
1816                         M_AADD(s2, s1, REG_ITMP1);
1817                         M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1818                         break;
1819
1820                 case ICMD_CASTORECONST:   /* ..., arrayref, index  ==> ...            */
1821                 case ICMD_SASTORECONST:   /* ..., arrayref, index  ==> ...            */
1822
1823                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1824                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1825                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1826                                 gen_nullptr_check(s1);
1827                                 gen_bound_check;
1828                         }
1829                         M_AADD(s2, s1, REG_ITMP1);
1830                         M_AADD(s2, REG_ITMP1, REG_ITMP1);
1831                         M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1832                         break;
1833
1834                 case ICMD_IASTORECONST:   /* ..., arrayref, index  ==> ...            */
1835
1836                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1837                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1838                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1839                                 gen_nullptr_check(s1);
1840                                 gen_bound_check;
1841                         }
1842                         M_ASLL_IMM(s2, 2, REG_ITMP2);
1843                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1844                         M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1845                         break;
1846
1847                 case ICMD_LASTORECONST:   /* ..., arrayref, index  ==> ...            */
1848
1849                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1850                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1851                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1852                                 gen_nullptr_check(s1);
1853                                 gen_bound_check;
1854                         }
1855                         M_ASLL_IMM(s2, 3, REG_ITMP2);
1856                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1857                         M_LST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1858                         break;
1859
1860                 case ICMD_AASTORECONST:   /* ..., arrayref, index  ==> ...            */
1861
1862                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1863                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1864                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1865                                 gen_nullptr_check(s1);
1866                                 gen_bound_check;
1867                         }
1868                         M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1869                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1870                         M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1871                         break;
1872
1873
1874                 case ICMD_GETSTATIC:  /* ...  ==> ..., value                          */
1875
1876                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1877                                 unresolved_field *uf = iptr->sx.s23.s3.uf;
1878
1879                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1880                                 disp = dseg_addaddress(cd, NULL);
1881
1882                                 codegen_addpatchref(cd, PATCHER_get_putstatic,
1883                                                                         iptr->sx.s23.s3.uf, disp);
1884
1885                                 if (opt_showdisassemble) {
1886                                         M_NOP; M_NOP;
1887                                 }
1888
1889                         } else {
1890                                 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1891
1892                                 fieldtype = fi->type;
1893                                 disp = dseg_addaddress(cd, &(fi->value));
1894
1895                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1896                                         codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
1897
1898                                         if (opt_showdisassemble) {
1899                                                 M_NOP; M_NOP;
1900                                         }
1901                                 }
1902                         }
1903
1904                         M_ALD(REG_ITMP1, REG_PV, disp);
1905                         switch (fieldtype) {
1906                         case TYPE_INT:
1907                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1908                                 M_ILD_INTERN(d, REG_ITMP1, 0);
1909                                 emit_store_dst(jd, iptr, d);
1910                                 break;
1911                         case TYPE_LNG:
1912                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1913                                 M_LLD_INTERN(d, REG_ITMP1, 0);
1914                                 emit_store_dst(jd, iptr, d);
1915                                 break;
1916                         case TYPE_ADR:
1917                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1918                                 M_ALD_INTERN(d, REG_ITMP1, 0);
1919                                 emit_store_dst(jd, iptr, d);
1920                                 break;
1921                         case TYPE_FLT:
1922                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1923                                 M_FLD_INTERN(d, REG_ITMP1, 0);
1924                                 emit_store_dst(jd, iptr, d);
1925                                 break;
1926                         case TYPE_DBL:                          
1927                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1928                                 M_DLD_INTERN(d, REG_ITMP1, 0);
1929                                 emit_store_dst(jd, iptr, d);
1930                                 break;
1931                         }
1932                         break;
1933
1934                 case ICMD_PUTSTATIC:  /* ..., value  ==> ...                          */
1935
1936                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1937                                 unresolved_field *uf = iptr->sx.s23.s3.uf;
1938
1939                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1940                                 disp = dseg_addaddress(cd, NULL);
1941
1942                                 codegen_addpatchref(cd, PATCHER_get_putstatic,
1943                                                                         iptr->sx.s23.s3.uf, disp);
1944
1945                                 if (opt_showdisassemble) {
1946                                         M_NOP; M_NOP;
1947                                 }
1948
1949                         } else {
1950                                 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1951
1952                                 fieldtype = fi->type;
1953                                 disp = dseg_addaddress(cd, &(fi->value));
1954
1955                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1956                                         codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
1957
1958                                         if (opt_showdisassemble) {
1959                                                 M_NOP; M_NOP;
1960                                         }
1961                                 }
1962                         }
1963
1964                         M_ALD(REG_ITMP1, REG_PV, disp);
1965                         switch (fieldtype) {
1966                         case TYPE_INT:
1967                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1968                                 M_IST_INTERN(s1, REG_ITMP1, 0);
1969                                 break;
1970                         case TYPE_LNG:
1971                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1972                                 M_LST_INTERN(s1, REG_ITMP1, 0);
1973                                 break;
1974                         case TYPE_ADR:
1975                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1976                                 M_AST_INTERN(s1, REG_ITMP1, 0);
1977                                 break;
1978                         case TYPE_FLT:
1979                                 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1980                                 M_FST_INTERN(s1, REG_ITMP1, 0);
1981                                 break;
1982                         case TYPE_DBL:
1983                                 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1984                                 M_DST_INTERN(s1, REG_ITMP1, 0);
1985                                 break;
1986                         }
1987                         break;
1988
1989                 case ICMD_PUTSTATICCONST: /* ...  ==> ...                             */
1990                                           /* val = value (in current instruction)     */
1991                                           /* following NOP)                           */
1992
1993                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1994                                 unresolved_field *uf = iptr->sx.s23.s3.uf;
1995
1996                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1997                                 disp = dseg_addaddress(cd, NULL);
1998
1999                                 codegen_addpatchref(cd, PATCHER_get_putstatic,
2000                                                                         uf, disp);
2001
2002                                 if (opt_showdisassemble) {
2003                                         M_NOP; M_NOP;
2004                                 }
2005
2006                         } else {
2007                                 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2008
2009                                 fieldtype = fi->type;
2010                                 disp = dseg_addaddress(cd, &(fi->value));
2011
2012                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2013                                         codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2014
2015                                         if (opt_showdisassemble) {
2016                                                 M_NOP; M_NOP;
2017                                         }
2018                                 }
2019                         }
2020
2021                         M_ALD(REG_ITMP1, REG_PV, disp);
2022                         switch (fieldtype) {
2023                         case TYPE_INT:
2024                                 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
2025                                 break;
2026                         case TYPE_LNG:
2027                                 M_LST_INTERN(REG_ZERO, REG_ITMP1, 0);
2028                                 break;
2029                         case TYPE_ADR:
2030                                 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
2031                                 break;
2032                         case TYPE_FLT:
2033                                 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
2034                                 break;
2035                         case TYPE_DBL:
2036                                 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
2037                                 break;
2038                         }
2039                         break;
2040
2041
2042                 case ICMD_GETFIELD:   /* ...  ==> ..., value                          */
2043
2044                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2045                         gen_nullptr_check(s1);
2046
2047                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2048                                 unresolved_field *uf = iptr->sx.s23.s3.uf;
2049
2050                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2051
2052                                 codegen_addpatchref(cd, PATCHER_get_putfield,
2053                                                                         iptr->sx.s23.s3.uf, 0);
2054
2055                                 if (opt_showdisassemble) {
2056                                         M_NOP; M_NOP;
2057                                 }
2058
2059                                 a = 0;
2060
2061                         } else {
2062                                 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2063                                 fieldtype = fi->type;
2064                                 a = fi->offset;
2065                         }
2066
2067                         switch (fieldtype) {
2068                         case TYPE_INT:
2069                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2070                                 M_ILD(d, s1, a);
2071                                 emit_store_dst(jd, iptr, d);
2072                                 break;
2073                         case TYPE_LNG:
2074                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2075                                 M_LLD(d, s1, a);
2076                                 emit_store_dst(jd, iptr, d);
2077                                 break;
2078                         case TYPE_ADR:
2079                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2080                                 M_ALD(d, s1, a);
2081                                 emit_store_dst(jd, iptr, d);
2082                                 break;
2083                         case TYPE_FLT:
2084                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2085                                 M_FLD(d, s1, a);
2086                                 emit_store_dst(jd, iptr, d);
2087                                 break;
2088                         case TYPE_DBL:                          
2089                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2090                                 M_DLD(d, s1, a);
2091                                 emit_store_dst(jd, iptr, d);
2092                                 break;
2093                         }
2094                         break;
2095
2096                 case ICMD_PUTFIELD:   /* ..., objectref, value  ==> ...               */
2097
2098                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2099                         gen_nullptr_check(s1);
2100
2101                         if (!IS_FLT_DBL_TYPE(fieldtype)) {
2102                                 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2103                         } else {
2104                                 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
2105                         }
2106
2107                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2108                                 unresolved_field *uf = iptr->sx.s23.s3.uf;
2109
2110                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2111
2112                                 codegen_addpatchref(cd, PATCHER_get_putfield,
2113                                                                         iptr->sx.s23.s3.uf, 0);
2114
2115                                 if (opt_showdisassemble) {
2116                                         M_NOP; M_NOP;
2117                                 }
2118
2119                                 a = 0;
2120
2121                         } else {
2122                                 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2123                                 fieldtype = fi->type;
2124                                 a = fi->offset;
2125                         }
2126
2127                         switch (fieldtype) {
2128                         case TYPE_INT:
2129                                 M_IST(s2, s1, a);
2130                                 break;
2131                         case TYPE_LNG:
2132                                 M_LST(s2, s1, a);
2133                                 break;
2134                         case TYPE_ADR:
2135                                 M_AST(s2, s1, a);
2136                                 break;
2137                         case TYPE_FLT:
2138                                 M_FST(s2, s1, a);
2139                                 break;
2140                         case TYPE_DBL:
2141                                 M_DST(s2, s1, a);
2142                                 break;
2143                         }
2144                         break;
2145
2146                 case ICMD_PUTFIELDCONST:  /* ..., objectref  ==> ...                  */
2147                                           /* val = value (in current instruction)     */
2148                                           /* following NOP)                           */
2149
2150                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2151                         gen_nullptr_check(s1);
2152
2153                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2154                                 unresolved_field *uf = iptr->sx.s23.s3.uf;
2155
2156                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2157
2158                                 codegen_addpatchref(cd, PATCHER_get_putfield,
2159                                                                         uf, 0);
2160
2161                                 if (opt_showdisassemble) {
2162                                         M_NOP; M_NOP;
2163                                 }
2164
2165                                 a = 0;
2166
2167                         } else {
2168                                 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2169                                 fieldtype = fi->type;
2170                                 a = fi->offset;
2171                         }
2172
2173                         switch (fieldtype) {
2174                         case TYPE_INT:
2175                                 M_IST(REG_ZERO, s1, a);
2176                                 break;
2177                         case TYPE_LNG:
2178                                 M_LST(REG_ZERO, s1, a);
2179                                 break;
2180                         case TYPE_ADR:
2181                                 M_AST(REG_ZERO, s1, a);
2182                                 break;
2183                         case TYPE_FLT:
2184                                 M_FST(REG_ZERO, s1, a);
2185                                 break;
2186                         case TYPE_DBL:
2187                                 M_DST(REG_ZERO, s1, a);
2188                                 break;
2189                         }
2190                         break;
2191
2192
2193                 /* branch operations **************************************************/
2194
2195                 case ICMD_ATHROW:       /* ..., objectref ==> ... (, objectref)       */
2196
2197                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2198                         M_INTMOVE(s1, REG_ITMP1_XPTR);
2199                         
2200 #ifdef ENABLE_VERIFIER
2201                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2202                                 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2203                                                                         iptr->sx.s23.s2.uc, 0);
2204
2205                                 if (opt_showdisassemble) {
2206                                         M_NOP; M_NOP;
2207                                 }
2208                         }
2209 #endif /* ENABLE_VERIFIER */
2210
2211                         disp = dseg_addaddress(cd, asm_handle_exception);
2212                         M_ALD(REG_ITMP2, REG_PV, disp);
2213                         M_JSR(REG_ITMP2_XPC, REG_ITMP2);
2214                         M_NOP;
2215                         M_NOP;              /* nop ensures that XPC is less than the end */
2216                                             /* of basic block                            */
2217                         ALIGNCODENOP;
2218                         break;
2219
2220                 case ICMD_GOTO:         /* ... ==> ...                                */
2221                         M_BR(0);
2222                         codegen_addreference(cd, iptr->dst.block);
2223                         M_NOP;
2224                         ALIGNCODENOP;
2225                         break;
2226
2227                 case ICMD_JSR:          /* ... ==> ...                                */
2228
2229                         dseg_addtarget(cd, iptr->sx.s23.s3.jsrtarget.block);
2230                         M_ALD(REG_ITMP1, REG_PV, -(cd->dseglen));
2231                         M_JSR(REG_ITMP1, REG_ITMP1);        /* REG_ITMP1 = return address */
2232                         M_NOP;
2233                         break;
2234                         
2235                 case ICMD_RET:          /* ... ==> ...                                */
2236                                         /* s1.localindex = local variable                       */
2237                         var = &(rd->locals[iptr->s1.localindex][TYPE_ADR]);
2238                         if (var->flags & INMEMORY) {
2239                                 M_ALD(REG_ITMP1, REG_SP, var->regoff * 8);
2240                                 M_RET(REG_ITMP1);
2241                         } else
2242                                 M_RET(var->regoff);
2243                         M_NOP;
2244                         ALIGNCODENOP;
2245                         break;
2246
2247                 case ICMD_IFNULL:       /* ..., value ==> ...                         */
2248
2249                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2250                         M_BEQZ(s1, 0);
2251                         codegen_addreference(cd, iptr->dst.block);
2252                         M_NOP;
2253                         break;
2254
2255                 case ICMD_IFNONNULL:    /* ..., value ==> ...                         */
2256
2257                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2258                         M_BNEZ(s1, 0);
2259                         codegen_addreference(cd, iptr->dst.block);
2260                         M_NOP;
2261                         break;
2262
2263                 case ICMD_IFEQ:         /* ..., value ==> ...                         */
2264
2265                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2266                         if (iptr->sx.val.i == 0) {
2267                                 M_BEQZ(s1, 0);
2268                         } else {
2269                                 ICONST(REG_ITMP2, iptr->sx.val.i);
2270                                 M_BEQ(s1, REG_ITMP2, 0);
2271                         }
2272                         codegen_addreference(cd, iptr->dst.block);
2273                         M_NOP;
2274                         break;
2275
2276                 case ICMD_IFLT:         /* ..., value ==> ...                         */
2277
2278                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2279                         if (iptr->sx.val.i == 0) {
2280                                 M_BLTZ(s1, 0);
2281                         } else {
2282                                 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767)) {
2283                                         M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2284                                 } else {
2285                                         ICONST(REG_ITMP2, iptr->sx.val.i);
2286                                         M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2287                                 }
2288                                 M_BNEZ(REG_ITMP1, 0);
2289                         }
2290                         codegen_addreference(cd, iptr->dst.block);
2291                         M_NOP;
2292                         break;
2293
2294                 case ICMD_IFLE:         /* ..., value ==> ...                         */
2295
2296                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2297                         if (iptr->sx.val.i == 0) {
2298                                 M_BLEZ(s1, 0);
2299                                 }
2300                         else {
2301                                 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2302                                         M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2303                                         M_BNEZ(REG_ITMP1, 0);
2304                                         }
2305                                 else {
2306                                         ICONST(REG_ITMP2, iptr->sx.val.i);
2307                                         M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2308                                         M_BEQZ(REG_ITMP1, 0);
2309                                         }
2310                                 }
2311                         codegen_addreference(cd, iptr->dst.block);
2312                         M_NOP;
2313                         break;
2314
2315                 case ICMD_IFNE:         /* ..., value ==> ...                         */
2316
2317                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2318                         if (iptr->sx.val.i == 0) {
2319                                 M_BNEZ(s1, 0);
2320                                 }
2321                         else {
2322                                 ICONST(REG_ITMP2, iptr->sx.val.i);
2323                                 M_BNE(s1, REG_ITMP2, 0);
2324                                 }
2325                         codegen_addreference(cd, iptr->dst.block);
2326                         M_NOP;
2327                         break;
2328
2329                 case ICMD_IFGT:         /* ..., value ==> ...                         */
2330
2331                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2332                         if (iptr->sx.val.i == 0) {
2333                                 M_BGTZ(s1, 0);
2334                                 }
2335                         else {
2336                                 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2337                                         M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2338                                         M_BEQZ(REG_ITMP1, 0);
2339                                         }
2340                                 else {
2341                                         ICONST(REG_ITMP2, iptr->sx.val.i);
2342                                         M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2343                                         M_BNEZ(REG_ITMP1, 0);
2344                                         }
2345                                 }
2346                         codegen_addreference(cd, iptr->dst.block);
2347                         M_NOP;
2348                         break;
2349
2350                 case ICMD_IFGE:         /* ..., value ==> ...                         */
2351
2352                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2353                         if (iptr->sx.val.i == 0) {
2354                                 M_BGEZ(s1, 0);
2355                                 }
2356                         else {
2357                                 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767)) {
2358                                         M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2359                                         }
2360                                 else {
2361                                         ICONST(REG_ITMP2, iptr->sx.val.i);
2362                                         M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2363                                         }
2364                                 M_BEQZ(REG_ITMP1, 0);
2365                                 }
2366                         codegen_addreference(cd, iptr->dst.block);
2367                         M_NOP;
2368                         break;
2369
2370                 case ICMD_IF_LEQ:       /* ..., value ==> ...                         */
2371
2372                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2373                         if (iptr->sx.val.l == 0) {
2374                                 M_BEQZ(s1, 0);
2375                                 }
2376                         else {
2377                                 LCONST(REG_ITMP2, iptr->sx.val.l);
2378                                 M_BEQ(s1, REG_ITMP2, 0);
2379                                 }
2380                         codegen_addreference(cd, iptr->dst.block);
2381                         M_NOP;
2382                         break;
2383
2384                 case ICMD_IF_LLT:       /* ..., value ==> ...                         */
2385
2386                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2387                         if (iptr->sx.val.l == 0) {
2388                                 M_BLTZ(s1, 0);
2389                                 }
2390                         else {
2391                                 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
2392                                         M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2393                                         }
2394                                 else {
2395                                         LCONST(REG_ITMP2, iptr->sx.val.l);
2396                                         M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2397                                         }
2398                                 M_BNEZ(REG_ITMP1, 0);
2399                                 }
2400                         codegen_addreference(cd, iptr->dst.block);
2401                         M_NOP;
2402                         break;
2403
2404                 case ICMD_IF_LLE:       /* ..., value ==> ...                         */
2405
2406                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2407                         if (iptr->sx.val.l == 0) {
2408                                 M_BLEZ(s1, 0);
2409                                 }
2410                         else {
2411                                 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2412                                         M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP1);
2413                                         M_BNEZ(REG_ITMP1, 0);
2414                                         }
2415                                 else {
2416                                         LCONST(REG_ITMP2, iptr->sx.val.l);
2417                                         M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2418                                         M_BEQZ(REG_ITMP1, 0);
2419                                         }
2420                                 }
2421                         codegen_addreference(cd, iptr->dst.block);
2422                         M_NOP;
2423                         break;
2424
2425                 case ICMD_IF_LNE:       /* ..., value ==> ...                         */
2426
2427                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2428                         if (iptr->sx.val.l == 0) {
2429                                 M_BNEZ(s1, 0);
2430                                 }
2431                         else {
2432                                 LCONST(REG_ITMP2, iptr->sx.val.l);
2433                                 M_BNE(s1, REG_ITMP2, 0);
2434                                 }
2435                         codegen_addreference(cd, iptr->dst.block);
2436                         M_NOP;
2437                         break;
2438
2439                 case ICMD_IF_LGT:       /* ..., value ==> ...                         */
2440
2441                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2442                         if (iptr->sx.val.l == 0) {
2443                                 M_BGTZ(s1, 0);
2444                                 }
2445                         else {
2446                                 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2447                                         M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP1);
2448                                         M_BEQZ(REG_ITMP1, 0);
2449                                         }
2450                                 else {
2451                                         LCONST(REG_ITMP2, iptr->sx.val.l);
2452                                         M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2453                                         M_BNEZ(REG_ITMP1, 0);
2454                                         }
2455                                 }
2456                         codegen_addreference(cd, iptr->dst.block);
2457                         M_NOP;
2458                         break;
2459
2460                 case ICMD_IF_LGE:       /* ..., value ==> ...                         */
2461
2462                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2463                         if (iptr->sx.val.l == 0) {
2464                                 M_BGEZ(s1, 0);
2465                                 }
2466                         else {
2467                                 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
2468                                         M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2469                                         }
2470                                 else {
2471                                         LCONST(REG_ITMP2, iptr->sx.val.l);
2472                                         M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2473                                         }
2474                                 M_BEQZ(REG_ITMP1, 0);
2475                                 }
2476                         codegen_addreference(cd, iptr->dst.block);
2477                         M_NOP;
2478                         break;
2479
2480                 case ICMD_IF_ICMPEQ:    /* ..., value, value ==> ...                  */
2481                 case ICMD_IF_LCMPEQ:    /* op1 = target JavaVM pc                     */
2482                 case ICMD_IF_ACMPEQ:
2483
2484                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2485                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2486                         M_BEQ(s1, s2, 0);
2487                         codegen_addreference(cd, iptr->dst.block);
2488                         M_NOP;
2489                         break;
2490
2491                 case ICMD_IF_ICMPNE:    /* ..., value, value ==> ...                  */
2492                 case ICMD_IF_LCMPNE:    /* op1 = target JavaVM pc                     */
2493                 case ICMD_IF_ACMPNE:
2494
2495                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2496                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2497                         M_BNE(s1, s2, 0);
2498                         codegen_addreference(cd, iptr->dst.block);
2499                         M_NOP;
2500                         break;
2501
2502                 case ICMD_IF_ICMPLT:    /* ..., value, value ==> ...                  */
2503                 case ICMD_IF_LCMPLT:    /* op1 = target JavaVM pc                     */
2504
2505                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2506                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2507                         M_CMPLT(s1, s2, REG_ITMP1);
2508                         M_BNEZ(REG_ITMP1, 0);
2509                         codegen_addreference(cd, iptr->dst.block);
2510                         M_NOP;
2511                         break;
2512
2513                 case ICMD_IF_ICMPGT:    /* ..., value, value ==> ...                  */
2514                 case ICMD_IF_LCMPGT:    /* op1 = target JavaVM pc                     */
2515
2516                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2517                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2518                         M_CMPGT(s1, s2, REG_ITMP1);
2519                         M_BNEZ(REG_ITMP1, 0);
2520                         codegen_addreference(cd, iptr->dst.block);
2521                         M_NOP;
2522                         break;
2523
2524                 case ICMD_IF_ICMPLE:    /* ..., value, value ==> ...                  */
2525                 case ICMD_IF_LCMPLE:    /* op1 = target JavaVM pc                     */
2526
2527                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2528                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2529                         M_CMPGT(s1, s2, REG_ITMP1);
2530                         M_BEQZ(REG_ITMP1, 0);
2531                         codegen_addreference(cd, iptr->dst.block);
2532                         M_NOP;
2533                         break;
2534
2535                 case ICMD_IF_ICMPGE:    /* ..., value, value ==> ...                  */
2536                 case ICMD_IF_LCMPGE:    /* op1 = target JavaVM pc                     */
2537
2538                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2539                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2540                         M_CMPLT(s1, s2, REG_ITMP1);
2541                         M_BEQZ(REG_ITMP1, 0);
2542                         codegen_addreference(cd, iptr->dst.block);
2543                         M_NOP;
2544                         break;
2545
2546
2547                 case ICMD_IRETURN:      /* ..., retvalue ==> ...                      */
2548                 case ICMD_LRETURN:
2549
2550                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
2551                         M_INTMOVE(s1, REG_RESULT);
2552                         goto nowperformreturn;
2553
2554                 case ICMD_ARETURN:      /* ..., retvalue ==> ...                      */
2555
2556                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
2557                         M_INTMOVE(s1, REG_RESULT);
2558
2559 #ifdef ENABLE_VERIFIER
2560                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2561                                 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2562                                                                         iptr->sx.s23.s2.uc, 0);
2563
2564                                 if (opt_showdisassemble) {
2565                                         M_NOP; M_NOP;
2566                                 }
2567                         }
2568 #endif /* ENABLE_VERIFIER */
2569                         goto nowperformreturn;
2570
2571             case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
2572
2573                         s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2574                         M_FLTMOVE(s1, REG_FRESULT);
2575                         goto nowperformreturn;
2576
2577             case ICMD_DRETURN:      /* ..., retvalue ==> ...                      */
2578
2579                         s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2580                         M_DBLMOVE(s1, REG_FRESULT);
2581                         goto nowperformreturn;
2582
2583                 case ICMD_RETURN:      /* ...  ==> ...                                */
2584
2585 nowperformreturn:
2586                         {
2587                         s4 i, p;
2588                         
2589                         p = cd->stackframesize;
2590
2591 #if !defined(NDEBUG)
2592                         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2593                                 emit_verbosecall_exit(jd);
2594 #endif
2595
2596 #if defined(ENABLE_THREADS)
2597                         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2598                                 disp = dseg_addaddress(cd, LOCK_monitor_exit);
2599                                 M_ALD(REG_ITMP3, REG_PV, disp);
2600
2601                                 /* we need to save the proper return value */
2602
2603                                 switch (iptr->opc) {
2604                                 case ICMD_IRETURN:
2605                                 case ICMD_ARETURN:
2606                                 case ICMD_LRETURN:
2607                                         M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2608                                         M_JSR(REG_RA, REG_ITMP3);
2609                                         M_LST(REG_RESULT, REG_SP, rd->memuse * 8);  /* delay slot */
2610                                         break;
2611                                 case ICMD_FRETURN:
2612                                 case ICMD_DRETURN:
2613                                         M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2614                                         M_JSR(REG_RA, REG_ITMP3);
2615                                         M_DST(REG_FRESULT, REG_SP, rd->memuse * 8); /* delay slot */
2616                                         break;
2617                                 case ICMD_RETURN:
2618                                         M_JSR(REG_RA, REG_ITMP3);
2619                                         M_ALD(REG_A0, REG_SP, rd->memuse * 8); /* delay*/
2620                                         break;
2621                                 }
2622
2623                                 /* and now restore the proper return value */
2624
2625                                 switch (iptr->opc) {
2626                                 case ICMD_IRETURN:
2627                                 case ICMD_ARETURN:
2628                                 case ICMD_LRETURN:
2629                                         M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2630                                         break;
2631                                 case ICMD_FRETURN:
2632                                 case ICMD_DRETURN:
2633                                         M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2634                                         break;
2635                                 }
2636                         }
2637 #endif
2638
2639                         /* restore return address                                         */
2640
2641                         if (!jd->isleafmethod) {
2642                                 p--; M_ALD(REG_RA, REG_SP, p * 8);
2643                         }
2644
2645                         /* restore saved registers                                        */
2646
2647                         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2648                                 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2649                         }
2650                         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2651                                 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2652                         }
2653
2654                         /* deallocate stack and return                                    */
2655
2656                         if (cd->stackframesize) {
2657                                 s4 lo, hi;
2658
2659                                 disp = cd->stackframesize * 8;
2660                                 lo = (short) (disp);
2661                                 hi = (short) (((disp) - lo) >> 16);
2662
2663                                 if (hi == 0) {
2664                                         M_RET(REG_RA);
2665                                         M_LADD_IMM(REG_SP, lo, REG_SP);             /* delay slot */
2666                                 } else {
2667                                         M_LUI(REG_ITMP3,hi);
2668                                         M_LADD_IMM(REG_ITMP3,lo,REG_ITMP3);
2669                                         M_RET(REG_RA);
2670                                         M_LADD(REG_ITMP3,REG_SP,REG_SP);            /* delay slot */
2671                                 }
2672
2673                         } else {
2674                                 M_RET(REG_RA);
2675                                 M_NOP;
2676                         }
2677
2678                         ALIGNCODENOP;
2679                         }
2680                         break;
2681
2682
2683                 case ICMD_TABLESWITCH:  /* ..., index ==> ...                         */
2684                         {
2685                         s4 i, l;
2686                         branch_target_t *table;
2687
2688                         table = iptr->dst.table;
2689
2690                         l = iptr->sx.s23.s2.tablelow;
2691                         i = iptr->sx.s23.s3.tablehigh;
2692
2693                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2694                         if (l == 0)
2695                                 {M_INTMOVE(s1, REG_ITMP1);}
2696                         else if (l <= 32768) {
2697                                 M_IADD_IMM(s1, -l, REG_ITMP1);
2698                                 }
2699                         else {
2700                                 ICONST(REG_ITMP2, l);
2701                                 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2702                                 }
2703
2704                         /* number of targets */
2705                         i = i - l + 1;
2706
2707                         /* range check */
2708
2709                         M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
2710                         M_BEQZ(REG_ITMP2, 0);
2711                         codegen_addreference(cd, table[0].block); /* default target */
2712                         M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);      /* delay slot*/
2713
2714                         /* build jump table top down and use address of lowest entry */
2715
2716                         table += i;
2717
2718                         while (--i >= 0) {
2719                                 dseg_addtarget(cd, table->block); 
2720                                 --table;
2721                                 }
2722                         }
2723
2724                         /* length of dataseg after last dseg_addtarget is used by load */
2725
2726                         M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2727                         M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2728                         M_JMP(REG_ITMP2);
2729                         M_NOP;
2730                         ALIGNCODENOP;
2731                         break;
2732
2733
2734                 case ICMD_LOOKUPSWITCH: /* ..., key ==> ...                           */
2735                         {
2736                         s4 i;
2737                         lookup_target_t *lookup;
2738
2739                         lookup = iptr->dst.lookup;
2740
2741                         i = iptr->sx.s23.s2.lookupcount;
2742                         
2743                         MCODECHECK((i<<2)+8);
2744                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2745
2746                         while (--i >= 0) {
2747                                 ICONST(REG_ITMP2, lookup->value);
2748                                 M_BEQ(s1, REG_ITMP2, 0);
2749                                 codegen_addreference(cd, lookup->target.block); 
2750                                 M_NOP;
2751                                 ++lookup;
2752                         }
2753
2754                         M_BR(0);
2755                         codegen_addreference(cd, iptr->sx.s23.s3.lookupdefault.block);
2756                         M_NOP;
2757                         ALIGNCODENOP;
2758                         break;
2759                         }
2760
2761
2762                 case ICMD_BUILTIN:      /* ..., arg1 ==> ...                          */
2763
2764                         bte = iptr->sx.s23.s3.bte;
2765                         md  = bte->md;
2766                         goto gen_method;
2767
2768                 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ...            */
2769
2770                 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2771                 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer    */
2772                 case ICMD_INVOKEINTERFACE:
2773
2774                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2775                                 lm = NULL;
2776                                 um = iptr->sx.s23.s3.um;
2777                                 md = um->methodref->parseddesc.md;
2778                         }
2779                         else {
2780                                 lm = iptr->sx.s23.s3.fmiref->p.method;
2781                                 um = NULL;
2782                                 md = lm->parseddesc;
2783                         }
2784
2785 gen_method:
2786                         s3 = md->paramcount;
2787
2788                         MCODECHECK((s3 << 1) + 64);
2789
2790                         /* copy arguments to registers or stack location                  */
2791
2792                         for (s3 = s3 - 1; s3 >= 0; s3--) {
2793                                 src = iptr->sx.s23.s2.args[s3];
2794
2795                                 if (src->varkind == ARGVAR)
2796                                         continue;
2797
2798                                 if (IS_INT_LNG_TYPE(src->type)) {
2799                                         if (!md->params[s3].inmemory) {
2800                                                 s1 = rd->argintregs[md->params[s3].regoff];
2801                                                 d = emit_load(jd, iptr, src, s1);
2802                                                 M_INTMOVE(d, s1);
2803                                         }
2804                                         else  {
2805                                                 d = emit_load(jd, iptr, src, REG_ITMP1);
2806                                                 M_LST(d, REG_SP, md->params[s3].regoff * 8);
2807                                         }
2808                                 }
2809                                 else {
2810                                         if (!md->params[s3].inmemory) {
2811                                                 s1 = rd->argfltregs[md->params[s3].regoff];
2812                                                 d = emit_load(jd, iptr, src, s1);
2813                                                 if (IS_2_WORD_TYPE(src->type))
2814                                                         M_DMOV(d, s1);
2815                                                 else
2816                                                         M_FMOV(d, s1);
2817                                         }
2818                                         else {
2819                                                 d = emit_load(jd, iptr, src, REG_FTMP1);
2820                                                 if (IS_2_WORD_TYPE(src->type))
2821                                                         M_DST(d, REG_SP, md->params[s3].regoff * 8);
2822                                                 else
2823                                                         M_FST(d, REG_SP, md->params[s3].regoff * 8);
2824                                         }
2825                                 }
2826                         }
2827
2828                         switch (iptr->opc) {
2829                         case ICMD_BUILTIN:
2830                                 disp = dseg_addaddress(cd, bte->fp);
2831
2832                                 M_ALD(REG_ITMP3, REG_PV, disp);  /* built-in-function pointer */
2833
2834                                 /* TWISTI: i actually don't know the reason for using
2835                                    REG_ITMP3 here instead of REG_PV. */
2836                                 s1 = REG_ITMP3;
2837                                 break;
2838
2839                         case ICMD_INVOKESPECIAL:
2840                                 M_BEQZ(REG_A0, 0);
2841                                 codegen_add_nullpointerexception_ref(cd);
2842                                 M_NOP;
2843                                 /* fall through */
2844
2845                         case ICMD_INVOKESTATIC:
2846                                 if (lm == NULL) {
2847                                         disp = dseg_addaddress(cd, NULL);
2848
2849                                         codegen_addpatchref(cd, PATCHER_invokestatic_special,
2850                                                                                 um, disp);
2851
2852                                         if (opt_showdisassemble) {
2853                                                 M_NOP; M_NOP;
2854                                         }
2855                                 }
2856                                 else
2857                                         disp = dseg_addaddress(cd, lm->stubroutine);
2858
2859                                 M_ALD(REG_PV, REG_PV, disp);          /* method pointer in pv */
2860                                 s1 = REG_PV;
2861                                 break;
2862
2863                         case ICMD_INVOKEVIRTUAL:
2864                                 gen_nullptr_check(REG_A0);
2865
2866                                 if (lm == NULL) {
2867                                         codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
2868
2869                                         if (opt_showdisassemble) {
2870                                                 M_NOP; M_NOP;
2871                                         }
2872
2873                                         s1 = 0;
2874                                 }
2875                                 else
2876                                         s1 = OFFSET(vftbl_t, table[0]) +
2877                                                 sizeof(methodptr) * lm->vftblindex;
2878
2879                                 M_ALD(REG_METHODPTR, REG_A0,
2880                                           OFFSET(java_objectheader, vftbl));
2881                                 M_ALD(REG_PV, REG_METHODPTR, s1);
2882                                 s1 = REG_PV;
2883                                 break;
2884
2885                         case ICMD_INVOKEINTERFACE:
2886                                 gen_nullptr_check(REG_A0);
2887
2888                                 if (lm == NULL) {
2889                                         codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
2890
2891                                         if (opt_showdisassemble) {
2892                                                 M_NOP; M_NOP;
2893                                         }
2894
2895                                         s1 = 0;
2896                                         s2 = 0;
2897                                 }
2898                                 else {
2899                                         s1 = OFFSET(vftbl_t, interfacetable[0]) -
2900                                                 sizeof(methodptr*) * lm->class->index;
2901
2902                                         s2 = sizeof(methodptr) * (lm - lm->class->methods);
2903                                 }
2904
2905                                 M_ALD(REG_METHODPTR, REG_A0,
2906                                           OFFSET(java_objectheader, vftbl));
2907                                 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2908                                 M_ALD(REG_PV, REG_METHODPTR, s2);
2909                                 s1 = REG_PV;
2910                                 break;
2911                         }
2912
2913                         /* generate the actual call */
2914
2915                         M_JSR(REG_RA, s1);
2916                         M_NOP;
2917                         disp = (s4) (cd->mcodeptr - cd->mcodebase);
2918                         M_LDA(REG_PV, REG_RA, -disp);
2919
2920                         /* actually only used for ICMD_BUILTIN */
2921
2922                         if (INSTRUCTION_MUST_CHECK(iptr)) {
2923                                 M_BEQZ(REG_RESULT, 0);
2924                                 codegen_add_fillinstacktrace_ref(cd);
2925                                 M_NOP;
2926                         }
2927
2928                         /* store return value */
2929
2930                         d = md->returntype.type;
2931
2932                         if (d != TYPE_VOID) {
2933                                 if (IS_INT_LNG_TYPE(d)) {
2934                                         s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2935                                         M_INTMOVE(REG_RESULT, s1);
2936                                 }
2937                                 else {
2938                                         s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2939                                         if (IS_2_WORD_TYPE(d))
2940                                                 M_DMOV(REG_FRESULT, s1);
2941                                         else
2942                                                 M_FMOV(REG_FRESULT, s1);
2943                                 }
2944                                 emit_store_dst(jd, iptr, s1);
2945                         }
2946                         break;
2947
2948
2949                 case ICMD_CHECKCAST:  /* ..., objectref ==> ..., objectref            */
2950                                       /* val.a: (classinfo*) superclass               */
2951
2952                         /*  superclass is an interface:
2953                          *
2954                          *  OK if ((sub == NULL) ||
2955                          *         (sub->vftbl->interfacetablelength > super->index) &&
2956                          *         (sub->vftbl->interfacetable[-super->index] != NULL));
2957                          *
2958                          *  superclass is a class:
2959                          *
2960                          *  OK if ((sub == NULL) || (0
2961                          *         <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2962                          *         super->vftbl->diffvall));
2963                          */
2964
2965                         if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2966                                 classinfo *super;
2967                                 vftbl_t   *supervftbl;
2968                                 s4         superindex;
2969
2970                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2971                                         super = NULL;
2972                                         superindex = 0;
2973                                         supervftbl = NULL;
2974                                 }
2975                                 else {
2976                                         super = iptr->sx.s23.s3.c.cls;
2977                                         superindex = super->index;
2978                                         supervftbl = super->vftbl;
2979                                 }
2980                         
2981 #if defined(ENABLE_THREADS)
2982                                 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2983 #endif
2984
2985                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2986
2987                                 /* calculate interface checkcast code size */
2988
2989                                 s2 = 8;
2990                                 if (super == NULL)
2991                                         s2 += (opt_showdisassemble ? 2 : 0);
2992
2993                                 /* calculate class checkcast code size */
2994
2995                                 s3 = 10 /* 10 + (s1 == REG_ITMP1) */;
2996                                 if (super == NULL)
2997                                         s3 += (opt_showdisassemble ? 2 : 0);
2998
2999                                 /* if class is not resolved, check which code to call */
3000
3001                                 if (super == NULL) {
3002                                         M_BEQZ(s1, 5 + (opt_showdisassemble ? 2 : 0) + s2 + 2 + s3);
3003                                         M_NOP;
3004
3005                                         disp = dseg_adds4(cd, 0);                 /* super->flags */
3006
3007                                         codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3008                                                                                 iptr->sx.s23.s3.c.ref,
3009                                                                                 disp);
3010
3011                                         if (opt_showdisassemble) {
3012                                                 M_NOP; M_NOP;
3013                                         }
3014
3015                                         /* XXX TWISTI M_ILD can be 2 instructions long (jump offset) */
3016                                         M_ILD(REG_ITMP2, REG_PV, disp);
3017                                         M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
3018                                         M_BEQZ(REG_ITMP2, 1 + s2 + 2);
3019                                         M_NOP;
3020                                 }
3021
3022                                 /* interface checkcast code */
3023
3024                                 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3025                                         if (super != NULL) {
3026                                                 M_BEQZ(s1, 1 + s2);
3027                                                 M_NOP;
3028                                         }
3029                                         else {
3030                                                 codegen_addpatchref(cd,
3031                                                                                         PATCHER_checkcast_instanceof_interface,
3032                                                                                         iptr->sx.s23.s3.c.ref,
3033                                                                                         0);
3034
3035                                                 if (opt_showdisassemble) {
3036                                                         M_NOP; M_NOP;
3037                                                 }
3038                                         }
3039
3040                                         M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3041                                         M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
3042                                         M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3043                                         M_BLEZ(REG_ITMP3, 0);
3044                                         codegen_add_classcastexception_ref(cd, s1);
3045                                         M_NOP;
3046                                         M_ALD(REG_ITMP3, REG_ITMP2,
3047                                                   OFFSET(vftbl_t, interfacetable[0]) -
3048                                                   superindex * sizeof(methodptr*));
3049                                         M_BEQZ(REG_ITMP3, 0);
3050                                         codegen_add_classcastexception_ref(cd, s1);
3051                                         M_NOP;
3052
3053                                         if (super == NULL) {
3054                                                 M_BR(1 + s3);
3055                                                 M_NOP;
3056                                         }
3057                                 }
3058
3059                                 /* class checkcast code */
3060
3061                                 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3062                                         disp = dseg_addaddress(cd, (void *) supervftbl);
3063
3064                                         if (super != NULL) {
3065                                                 M_BEQZ(s1, 1 + s3);
3066                                                 M_NOP;
3067                                         }
3068                                         else {
3069                                                 codegen_addpatchref(cd,
3070                                                                                         PATCHER_checkcast_instanceof_class,
3071                                                                                         iptr->sx.s23.s3.c.ref,
3072                                                                                         disp);
3073
3074                                                 if (opt_showdisassemble) {
3075                                                         M_NOP; M_NOP;
3076                                                 }
3077                                         }
3078
3079                                         M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3080                                         M_ALD(REG_ITMP3, REG_PV, disp);
3081 #if defined(ENABLE_THREADS)
3082                                         codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3083 #endif
3084                                         M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3085                                         /*                              if (s1 != REG_ITMP1) { */
3086                                         /*                                      M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3087                                         /*                                      M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3088                                         /* #if defined(ENABLE_THREADS) */
3089                                         /*                                      codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3090                                         /* #endif */
3091                                         /*                                      M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3092                                         /*                              } else { */
3093                                         M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3094                                         M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2); 
3095                                         M_ALD(REG_ITMP3, REG_PV, disp);
3096                                         M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3097 #if defined(ENABLE_THREADS)
3098                                         codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3099 #endif
3100                                         /*                              } */
3101                                         M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3102                                         M_BNEZ(REG_ITMP3, 0);
3103                                         codegen_add_classcastexception_ref(cd, s1);
3104                                         M_NOP;
3105                                 }
3106
3107                                 d = codegen_reg_of_dst(jd, iptr, s1);
3108                         }
3109                         else {
3110                                 s1 = emit_load_s1(jd, iptr, REG_A0);
3111                                 M_INTMOVE(s1, REG_A0);
3112
3113                                 disp = dseg_addaddress(cd, iptr->sx.s23.s3.c.cls);
3114
3115                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3116                                         codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast,
3117                                                                                 iptr->sx.s23.s3.c.ref,
3118                                                                                 disp);
3119
3120                                         if (opt_showdisassemble) {
3121                                                 M_NOP; M_NOP;
3122                                         }
3123                                 }
3124
3125                                 M_ALD(REG_A1, REG_PV, disp);
3126                                 disp = dseg_addaddress(cd, BUILTIN_arraycheckcast);
3127                                 M_ALD(REG_ITMP3, REG_PV, disp);
3128                                 M_JSR(REG_RA, REG_ITMP3);
3129                                 M_NOP;
3130
3131                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3132                                 M_BEQZ(REG_RESULT, 0);
3133                                 codegen_add_classcastexception_ref(cd, s1);
3134                                 M_NOP;
3135
3136                                 d = codegen_reg_of_dst(jd, iptr, s1);
3137                         }
3138
3139                         M_INTMOVE(s1, d);
3140                         emit_store_dst(jd, iptr, d);
3141                         break;
3142
3143                 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
3144                                       /* val.a: (classinfo*) superclass               */
3145
3146                         /*  superclass is an interface:
3147                          *
3148                          *  return (sub != NULL) &&
3149                          *         (sub->vftbl->interfacetablelength > super->index) &&
3150                          *         (sub->vftbl->interfacetable[-super->index] != NULL);
3151                          *
3152                          *  superclass is a class:
3153                          *
3154                          *  return ((sub != NULL) && (0
3155                          *          <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3156                          *          super->vftbl->diffvall));
3157                          */
3158
3159                         {
3160                         classinfo *super;
3161                         vftbl_t   *supervftbl;
3162                         s4         superindex;
3163
3164                         super = iptr->sx.s23.s3.c.cls;
3165
3166                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3167                                 super = NULL;
3168                                 superindex = 0;
3169                                 supervftbl = NULL;
3170                         }
3171                         else {
3172                                 super = iptr->sx.s23.s3.c.cls;
3173                                 superindex = super->index;
3174                                 supervftbl = super->vftbl;
3175                         }
3176                         
3177 #if defined(ENABLE_THREADS)
3178                         codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3179 #endif
3180
3181                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3182                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3183                         if (s1 == d) {
3184                                 M_MOV(s1, REG_ITMP1);
3185                                 s1 = REG_ITMP1;
3186                         }
3187
3188                         /* calculate interface instanceof code size */
3189
3190                         s2 = 7;
3191                         if (super == NULL)
3192                                 s2 += (opt_showdisassemble ? 2 : 0);
3193
3194                         /* calculate class instanceof code size */
3195
3196                         s3 = 8;
3197                         if (super == NULL)
3198                                 s3 += (opt_showdisassemble ? 2 : 0);
3199
3200                         M_CLR(d);
3201
3202                         /* if class is not resolved, check which code to call */
3203
3204                         if (super == NULL) {
3205                                 M_BEQZ(s1, 5 + (opt_showdisassemble ? 2 : 0) + s2 + 2 + s3);
3206                                 M_NOP;
3207
3208                                 disp = dseg_adds4(cd, 0);                     /* super->flags */
3209
3210                                 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3211                                                                         iptr->sx.s23.s3.c.ref, disp);
3212
3213                                 if (opt_showdisassemble) {
3214                                         M_NOP; M_NOP;
3215                                 }
3216
3217                                 /* XXX TWISTI M_ILD can be 2 instructions long (jump offset) */
3218                                 M_ILD(REG_ITMP3, REG_PV, disp);
3219                                 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
3220                                 M_BEQZ(REG_ITMP3, 1 + s2 + 2);
3221                                 M_NOP;
3222                         }
3223
3224                         /* interface instanceof code */
3225
3226                         if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3227                                 if (super != NULL) {
3228                                         M_BEQZ(s1, 1 + s2);
3229                                         M_NOP;
3230                                 }
3231                                 else {
3232                                         codegen_addpatchref(cd,
3233                                                                                 PATCHER_checkcast_instanceof_interface,
3234                                                                                 iptr->sx.s23.s3.c.ref, 0);
3235
3236                                         if (opt_showdisassemble) {
3237                                                 M_NOP; M_NOP;
3238                                         }
3239                                 }
3240
3241                                 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3242                                 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3243                                 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3244                                 M_BLEZ(REG_ITMP3, 3);
3245                                 M_NOP;
3246                                 M_ALD(REG_ITMP1, REG_ITMP1,
3247                                           OFFSET(vftbl_t, interfacetable[0]) -
3248                                           superindex * sizeof(methodptr*));
3249                                 M_CMPULT(REG_ZERO, REG_ITMP1, d);      /* REG_ITMP1 != 0  */
3250
3251                                 if (super == NULL) {
3252                                         M_BR(1 + s3);
3253                                         M_NOP;
3254                                 }
3255                         }
3256
3257                         /* class instanceof code */
3258
3259                         if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3260                                 disp = dseg_addaddress(cd, supervftbl);
3261
3262                                 if (super != NULL) {
3263                                         M_BEQZ(s1, 1 + s3);
3264                                         M_NOP;
3265                                 }
3266                                 else {
3267                                         codegen_addpatchref(cd, PATCHER_checkcast_instanceof_class,
3268                                                                                 iptr->sx.s23.s3.c.ref,
3269                                                                                 disp);
3270
3271                                         if (opt_showdisassemble) {
3272                                                 M_NOP; M_NOP;
3273                                         }
3274                                 }
3275
3276                                 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3277                                 M_ALD(REG_ITMP2, REG_PV, disp);
3278 #if defined(ENABLE_THREADS)
3279                                 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3280 #endif
3281                                 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3282                                 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3283                                 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3284 #if defined(ENABLE_THREADS)
3285                                 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3286 #endif
3287                                 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1); 
3288                                 M_CMPULT(REG_ITMP2, REG_ITMP1, d);
3289                                 M_XOR_IMM(d, 1, d);
3290                         }
3291                         emit_store_dst(jd, iptr, d);
3292                         }
3293                         break;
3294
3295                 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref  */
3296
3297                         /* check for negative sizes and copy sizes to stack if necessary  */
3298
3299                         MCODECHECK((iptr->s1.argcount << 1) + 64);
3300
3301                         for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3302
3303                                 src = iptr->sx.s23.s2.args[s1];
3304
3305                                 /* copy SAVEDVAR sizes to stack */
3306
3307                                 if (src->varkind != ARGVAR) {
3308                                         s2 = emit_load(jd, iptr, src, REG_ITMP1);
3309                                         M_LST(s2, REG_SP, s1 * 8);
3310                                 }
3311                         }
3312
3313                         /* a0 = dimension count */
3314
3315                         ICONST(REG_A0, iptr->s1.argcount);
3316
3317                         /* is patcher function set? */
3318
3319                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3320                                 disp = dseg_addaddress(cd, NULL);
3321
3322                                 codegen_addpatchref(cd, PATCHER_builtin_multianewarray,
3323                                                                         iptr->sx.s23.s3.c.ref, disp);
3324
3325                                 if (opt_showdisassemble) {
3326                                         M_NOP; M_NOP;
3327                                 }
3328
3329                         } else {
3330                                 disp = dseg_addaddress(cd, iptr->sx.s23.s3.c.cls);
3331                         }
3332
3333                         /* a1 = arraydescriptor */
3334
3335                         M_ALD(REG_A1, REG_PV, disp);
3336
3337                         /* a2 = pointer to dimensions = stack pointer */
3338
3339                         M_INTMOVE(REG_SP, REG_A2);
3340
3341                         disp = dseg_addaddress(cd, BUILTIN_multianewarray);
3342                         M_ALD(REG_ITMP3, REG_PV, disp);
3343                         M_JSR(REG_RA, REG_ITMP3);
3344                         M_NOP;
3345
3346                         /* check for exception before result assignment */
3347
3348                         M_BEQZ(REG_RESULT, 0);
3349                         codegen_add_fillinstacktrace_ref(cd);
3350                         M_NOP;
3351
3352                         d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3353                         M_INTMOVE(REG_RESULT, d);
3354                         emit_store_dst(jd, iptr, d);
3355                         break;
3356
3357                 default:
3358                         *exceptionptr = new_internalerror("Unknown ICMD %d", iptr->opc);
3359                         return false;
3360         } /* switch */
3361                 
3362         } /* for instruction */
3363                 
3364         /* copy values to interface registers */
3365
3366         len = bptr->outdepth;
3367         MCODECHECK(64+len);
3368 #if defined(ENABLE_LSRA)
3369         if (!opt_lsra) 
3370 #endif
3371         while (len) {
3372                 len--;
3373                 src = bptr->outvars[len];
3374                 if ((src->varkind != STACKVAR)) {
3375                         s2 = src->type;
3376                         if (IS_FLT_DBL_TYPE(s2)) {
3377                                 s1 = emit_load(jd, iptr, src, REG_FTMP1);
3378                                 if (rd->interfaces[len][s2].flags & INMEMORY) {
3379                                         if (IS_2_WORD_TYPE(s2))
3380                                                 M_DST(s1, REG_SP, rd->interfaces[len][s2].regoff * 8);
3381                                         else
3382                                                 M_FST(s1, REG_SP, rd->interfaces[len][s2].regoff * 8);
3383
3384                                 } else {
3385                                         if (IS_2_WORD_TYPE(s2))
3386                                                 M_DMOV(s1, rd->interfaces[len][s2].regoff);
3387                                         else
3388                                                 M_FMOV(s1, rd->interfaces[len][s2].regoff);
3389                                 }
3390
3391                         } else {
3392                                 s1 = emit_load(jd, iptr, src, REG_ITMP1);
3393                                 if (rd->interfaces[len][s2].flags & INMEMORY)
3394                                         M_LST(s1, REG_SP, rd->interfaces[len][s2].regoff * 8);
3395                                 else
3396                                         M_INTMOVE(s1, rd->interfaces[len][s2].regoff);
3397                         }
3398                 }
3399         }
3400
3401         /* At the end of a basic block we may have to append some nops,
3402            because the patcher stub calling code might be longer than the
3403            actual instruction. So codepatching does not change the
3404            following block unintentionally. */
3405
3406         if (cd->mcodeptr < cd->lastmcodeptr) {
3407                 while (cd->mcodeptr < cd->lastmcodeptr)
3408                         M_NOP;
3409         }
3410
3411         } /* if (bptr -> flags >= BBREACHED) */
3412         } /* for basic block */
3413
3414         dseg_createlinenumbertable(cd);
3415
3416         /* generate exception and patcher stubs */
3417
3418         emit_exception_stubs(jd);
3419         emit_patcher_stubs(jd);
3420
3421 #if 0
3422         emit_replacement_stubs(jd);
3423 #endif
3424
3425         codegen_finish(jd);
3426
3427         /* everything's ok */
3428
3429         return true;
3430 }
3431
3432
3433 /* createcompilerstub **********************************************************
3434
3435    Creates a stub routine which calls the compiler.
3436         
3437 *******************************************************************************/
3438
3439 #define COMPILERSTUB_DATASIZE    3 * SIZEOF_VOID_P
3440 #define COMPILERSTUB_CODESIZE    4 * 4
3441
3442 #define COMPILERSTUB_SIZE        COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
3443
3444
3445 u1 *createcompilerstub(methodinfo *m)
3446 {
3447         u1          *s;                     /* memory to hold the stub            */
3448         ptrint      *d;
3449         codeinfo    *code;
3450         codegendata *cd;
3451         s4           dumpsize;
3452
3453         s = CNEW(u1, COMPILERSTUB_SIZE);
3454
3455         /* set data pointer and code pointer */
3456
3457         d = (ptrint *) s;
3458         s = s + COMPILERSTUB_DATASIZE;
3459
3460         /* mark start of dump memory area */
3461
3462         dumpsize = dump_size();
3463
3464         cd = DNEW(codegendata);
3465         cd->mcodeptr = s;
3466
3467         /* Store the codeinfo pointer in the same place as in the
3468            methodheader for compiled methods. */
3469
3470         code = code_codeinfo_new(m);
3471
3472         d[0] = (ptrint) asm_call_jit_compiler;
3473         d[1] = (ptrint) m;
3474         d[2] = (ptrint) code;
3475
3476         M_ALD_INTERN(REG_ITMP1, REG_PV, -2 * SIZEOF_VOID_P);  /* codeinfo pointer */
3477         M_ALD_INTERN(REG_PV, REG_PV, -3 * SIZEOF_VOID_P);  /* pointer to compiler */
3478         M_JMP(REG_PV);
3479         M_NOP;
3480
3481         md_cacheflush(s, (s4) (cd->mcodeptr - (u1 *) d));
3482
3483 #if defined(ENABLE_STATISTICS)
3484         if (opt_stat)
3485                 count_cstub_len += COMPILERSTUB_SIZE;
3486 #endif
3487
3488         /* release dump area */
3489
3490         dump_release(dumpsize);
3491
3492         return s;
3493 }
3494
3495
3496 /* createnativestub ************************************************************
3497
3498    Creates a stub routine which calls a native method.
3499
3500 *******************************************************************************/
3501
3502 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
3503 {
3504         methodinfo   *m;
3505         codeinfo     *code;
3506         codegendata  *cd;
3507         registerdata *rd;
3508         methoddesc   *md;
3509         s4            nativeparams;
3510         s4            i, j;                 /* count variables                    */
3511         s4            t;
3512         s4            s1, s2, disp;
3513         s4            funcdisp;             /* displacement of the function       */
3514
3515         /* get required compiler data */
3516
3517         m    = jd->m;
3518         code = jd->code;
3519         cd   = jd->cd;
3520         rd   = jd->rd;
3521
3522         /* initialize variables */
3523
3524         md = m->parseddesc;
3525         nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3526
3527         /* calculate stack frame size */
3528
3529         cd->stackframesize =
3530                 1 +                             /* return address                     */
3531                 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3532                 sizeof(localref_table) / SIZEOF_VOID_P +
3533                 md->paramcount +                /* for saving arguments over calls    */
3534                 1 +                             /* for saving return address          */
3535                 nmd->memuse;
3536
3537         /* create method header */
3538
3539 #if SIZEOF_VOID_P == 4
3540         (void) dseg_addaddress(cd, code);                      /* CodeinfoPointer */
3541 #endif
3542         (void) dseg_addaddress(cd, code);                      /* MethodPointer   */
3543         (void) dseg_adds4(cd, cd->stackframesize * 8);         /* FrameSize       */
3544         (void) dseg_adds4(cd, 0);                              /* IsSync          */
3545         (void) dseg_adds4(cd, 0);                              /* IsLeaf          */
3546         (void) dseg_adds4(cd, 0);                              /* IntSave         */
3547         (void) dseg_adds4(cd, 0);                              /* FltSave         */
3548         (void) dseg_addlinenumbertablesize(cd);
3549         (void) dseg_adds4(cd, 0);                              /* ExTableSize     */
3550
3551         /* generate stub code */
3552
3553         M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8); /* build up stackframe    */
3554         M_AST(REG_RA, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P); /* store RA*/
3555
3556 #if !defined(NDEBUG)
3557         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3558                 emit_verbosecall_enter(jd);
3559 #endif
3560
3561         /* get function address (this must happen before the stackframeinfo) */
3562
3563         funcdisp = dseg_addaddress(cd, f);
3564
3565 #if !defined(WITH_STATIC_CLASSPATH)
3566         if (f == NULL) {
3567                 codegen_addpatchref(cd, PATCHER_resolve_native, m, funcdisp);
3568
3569                 if (opt_showdisassemble) {
3570                         M_NOP; M_NOP;
3571                 }
3572         }
3573 #endif
3574
3575         /* save integer and float argument registers */
3576
3577         for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3578                 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
3579                         M_LST(rd->argintregs[i], REG_SP, j * 8);
3580                         j++;
3581                 }
3582         }
3583
3584         for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3585                 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3586                         M_DST(rd->argfltregs[i], REG_SP, j * 8);
3587                         j++;
3588                 }
3589         }
3590
3591         /* prepare data structures for native function call */
3592
3593         M_AADD_IMM(REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P, REG_A0);
3594         M_MOV(REG_PV, REG_A1);
3595         M_AADD_IMM(REG_SP, cd->stackframesize * 8, REG_A2);
3596         M_ALD(REG_A3, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3597         disp = dseg_addaddress(cd, codegen_start_native_call);
3598         M_ALD(REG_ITMP3, REG_PV, disp);
3599         M_JSR(REG_RA, REG_ITMP3);
3600         M_NOP; /* XXX fill me! */
3601
3602         /* restore integer and float argument registers */
3603
3604         for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3605                 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
3606                         M_LLD(rd->argintregs[i], REG_SP, j * 8);
3607                         j++;
3608                 }
3609         }
3610
3611         for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3612                 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3613                         M_DLD(rd->argfltregs[i], REG_SP, j * 8);
3614                         j++;
3615                 }
3616         }
3617
3618         /* copy or spill arguments to new locations */
3619
3620         for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3621                 t = md->paramtypes[i].type;
3622
3623                 if (IS_INT_LNG_TYPE(t)) {
3624                         if (!md->params[i].inmemory) {
3625                                 s1 = rd->argintregs[md->params[i].regoff];
3626
3627                                 if (!nmd->params[j].inmemory) {
3628                                         s2 = rd->argintregs[nmd->params[j].regoff];
3629                                         M_INTMOVE(s1, s2);
3630                                 } else {
3631                                         s2 = nmd->params[j].regoff;
3632                                         M_AST(s1, REG_SP, s2 * 8);
3633                                 }
3634
3635                         } else {
3636                                 s1 = md->params[i].regoff + cd->stackframesize;
3637                                 s2 = nmd->params[j].regoff;
3638                                 M_ALD(REG_ITMP1, REG_SP, s1 * 8);
3639                                 M_AST(REG_ITMP1, REG_SP, s2 * 8);
3640                         }
3641
3642                 } else {
3643                         if (!md->params[i].inmemory) {
3644                                 s1 = rd->argfltregs[md->params[i].regoff];
3645
3646                                 if (!nmd->params[j].inmemory) {
3647                                         s2 = rd->argfltregs[nmd->params[j].regoff];
3648                                         if (IS_2_WORD_TYPE(t))
3649                                                 M_DMOV(s1, s2);
3650                                         else
3651                                                 M_FMOV(s1, s2);
3652
3653                                 } else {
3654                                         s2 = nmd->params[j].regoff;
3655                                         if (IS_2_WORD_TYPE(t))
3656                                                 M_DST(s1, REG_SP, s2 * 8);
3657                                         else
3658                                                 M_FST(s1, REG_SP, s2 * 8);
3659                                 }
3660
3661                         } else {
3662                                 s1 = md->params[i].regoff + cd->stackframesize;
3663                                 s2 = nmd->params[j].regoff;
3664                                 if (IS_2_WORD_TYPE(t)) {
3665                                         M_DLD(REG_FTMP1, REG_SP, s1 * 8);
3666                                         M_DST(REG_FTMP1, REG_SP, s2 * 8);
3667                                 } else {
3668                                         M_FLD(REG_FTMP1, REG_SP, s1 * 8);
3669                                         M_FST(REG_FTMP1, REG_SP, s2 * 8);
3670                                 }
3671                         }
3672                 }
3673         }
3674
3675         /* put class into second argument register */
3676
3677         if (m->flags & ACC_STATIC) {
3678                 disp = dseg_addaddress(cd, m->class);
3679                 M_ALD(REG_A1, REG_PV, disp);
3680         }
3681
3682         /* put env into first argument register */
3683
3684         disp = dseg_addaddress(cd, _Jv_env);
3685         M_ALD(REG_A0, REG_PV, disp);
3686
3687         /* do the native function call */
3688
3689         M_ALD(REG_ITMP3, REG_PV, funcdisp); /* load adress of native method       */
3690         M_JSR(REG_RA, REG_ITMP3);           /* call native method                 */
3691         M_NOP;                              /* delay slot                         */
3692
3693         /* save return value */
3694
3695         if (md->returntype.type != TYPE_VOID) {
3696                 if (IS_INT_LNG_TYPE(md->returntype.type))
3697                         M_LST(REG_RESULT, REG_SP, 0 * 8);
3698                 else
3699                         M_DST(REG_FRESULT, REG_SP, 0 * 8);
3700         }
3701
3702 #if !defined(NDEBUG)
3703         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3704                 emit_verbosecall_exit(jd);
3705 #endif
3706
3707         /* remove native stackframe info */
3708
3709         M_AADD_IMM(REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P, REG_A0);
3710         disp = dseg_addaddress(cd, codegen_finish_native_call);
3711         M_ALD(REG_ITMP3, REG_PV, disp);
3712         M_JSR(REG_RA, REG_ITMP3);
3713         M_NOP; /* XXX fill me! */
3714         M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3715
3716         /* restore return value */
3717
3718         if (md->returntype.type != TYPE_VOID) {
3719                 if (IS_INT_LNG_TYPE(md->returntype.type))
3720                         M_LLD(REG_RESULT, REG_SP, 0 * 8);
3721                 else
3722                         M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3723         }
3724
3725         M_ALD(REG_RA, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P); /* load RA */
3726
3727         /* check for exception */
3728
3729         M_BNEZ(REG_ITMP1_XPTR, 2);          /* if no exception then return        */
3730         M_LDA(REG_SP, REG_SP, cd->stackframesize * 8); /* DELAY SLOT              */
3731
3732         M_RET(REG_RA);                      /* return to caller                   */
3733         M_NOP;                              /* DELAY SLOT                         */
3734
3735         /* handle exception */
3736         
3737         disp = dseg_addaddress(cd, asm_handle_nat_exception);
3738         M_ALD(REG_ITMP3, REG_PV, disp);     /* load asm exception handler address */
3739         M_JMP(REG_ITMP3);                   /* jump to asm exception handler      */
3740         M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address (DELAY)    */
3741
3742         /* generate patcher stubs */
3743
3744         emit_patcher_stubs(jd);
3745
3746         codegen_finish(jd);
3747
3748         return code->entrypoint;
3749 }
3750
3751
3752 /*
3753  * These are local overrides for various environment variables in Emacs.
3754  * Please do not remove this and leave it at the end of the file, where
3755  * Emacs will automagically detect them.
3756  * ---------------------------------------------------------------------
3757  * Local variables:
3758  * mode: c
3759  * indent-tabs-mode: t
3760  * c-basic-offset: 4
3761  * tab-width: 4
3762  * End:
3763  * vim:noexpandtab:sw=4:ts=4:
3764  */