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