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