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