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