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