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