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