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