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