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