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