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