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