1 /* src/vm/jit/mips/codegen.c - machine code generator for MIPS
3 Copyright (C) 1996-2005, 2006, 2007, 2008, 2009
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
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.
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.
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
35 #include "vm/jit/mips/arch.h"
36 #include "vm/jit/mips/codegen.h"
38 #include "mm/memory.hpp"
40 #include "native/localref.hpp"
41 #include "native/native.hpp"
43 #include "threads/lock.hpp"
45 #include "vm/jit/builtin.hpp"
46 #include "vm/class.hpp"
47 #include "vm/exceptions.hpp"
48 #include "vm/options.h"
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"
66 * Generates machine code for the method prolog.
68 void codegen_emit_prolog(jitdata* jd)
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;
83 /* create stack frame (if necessary) */
85 if (cd->stackframesize)
86 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8);
88 /* save return address and used callee saved registers */
90 p = cd->stackframesize;
91 if (!code_is_leafmethod(code)) {
92 p--; M_AST(REG_RA, REG_SP, p * 8);
94 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
95 p--; M_AST(rd->savintregs[i], REG_SP, p * 8);
97 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
98 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
101 /* take arguments out of register or stack frame */
105 for (p = 0, l = 0; p < md->paramcount; p++) {
106 t = md->paramtypes[p].type;
108 varindex = jd->local_map[l * 5 + t];
111 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
114 if (varindex == UNUSED)
118 s1 = md->params[p].regoff;
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);
126 M_LST(s1, REG_SP, var->vv.regoff);
128 if (!(var->flags & INMEMORY)) {
129 if (IS_2_WORD_TYPE(t))
130 M_LNGMOVE(s1, var->vv.regoff);
132 M_INTMOVE(s1, var->vv.regoff);
135 if (IS_2_WORD_TYPE(t))
136 M_LST(s1, REG_SP, var->vv.regoff);
138 M_IST(s1, REG_SP, var->vv.regoff);
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);
147 if (IS_2_WORD_TYPE(t))
148 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
150 M_ILD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
154 var->vv.regoff = cd->stackframesize * 8 + s1;
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);
163 emit_fmove(cd, s1, var->vv.regoff);
166 if (IS_2_WORD_TYPE(t))
167 M_DST(s1, REG_SP, var->vv.regoff);
169 M_FST(s1, REG_SP, var->vv.regoff);
173 if (!(var->flags & INMEMORY)) {
174 if (IS_2_WORD_TYPE(t))
175 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
177 M_FLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
180 var->vv.regoff = cd->stackframesize * 8 + s1;
188 * Generates machine code for the method epilog.
190 void codegen_emit_epilog(jitdata* jd)
195 // Get required compiler data.
196 codeinfo* code = jd->code;
197 codegendata* cd = jd->cd;
198 registerdata* rd = jd->rd;
200 p = cd->stackframesize;
202 /* restore return address */
204 if (!code_is_leafmethod(code)) {
205 p--; M_ALD(REG_RA, REG_SP, p * 8);
208 /* restore saved registers */
210 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
211 p--; M_ALD(rd->savintregs[i], REG_SP, p * 8);
213 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
214 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
217 /* deallocate stack and return */
219 if (cd->stackframesize) {
220 int32_t lo, hi, disp;
222 disp = cd->stackframesize * 8;
224 hi = (short) (((disp) - lo) >> 16);
228 M_AADD_IMM(REG_SP, lo, REG_SP); /* delay slot */
231 M_AADD_IMM(REG_ITMP3,lo,REG_ITMP3);
233 M_AADD(REG_ITMP3,REG_SP,REG_SP); /* delay slot */
244 * Generates machine code for one ICMD.
246 void codegen_emit_instruction(jitdata* jd, instruction* iptr)
249 builtintable_entry* bte;
250 methodinfo* lm; // Local methodinfo for ICMD_INVOKE*.
251 unresolved_method* um;
253 unresolved_field* uf;
255 int32_t s1, s2, s3, d;
258 // Get required compiler data.
259 codeinfo* code = jd->code;
260 codegendata* cd = jd->cd;
264 /* constant operations ************************************************/
266 case ICMD_LCONST: /* ... ==> ..., constant */
268 #if SIZEOF_VOID_P == 8
269 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
271 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
273 LCONST(d, iptr->sx.val.l);
274 emit_store_dst(jd, iptr, d);
277 case ICMD_FCONST: /* ... ==> ..., constant */
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);
285 case ICMD_DCONST: /* ... ==> ..., constant */
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);
293 case ICMD_ACONST: /* ... ==> ..., constant */
295 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
297 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
298 constant_classref *cr = iptr->sx.val.c.ref;
299 disp = dseg_add_unique_address(cd, cr);
301 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
304 M_ALD(d, REG_PV, disp);
307 if (iptr->sx.val.anyptr == NULL)
308 M_INTMOVE(REG_ZERO, d);
310 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
311 M_ALD(d, REG_PV, disp);
314 emit_store_dst(jd, iptr, d);
318 /* integer operations *************************************************/
320 case ICMD_INEG: /* ..., value ==> ..., - value */
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);
328 case ICMD_LNEG: /* ..., value ==> ..., - value */
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);
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));
342 emit_store_dst(jd, iptr, d);
345 case ICMD_I2L: /* ..., value ==> ..., value */
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);
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));
356 emit_store_dst(jd, iptr, d);
359 case ICMD_L2I: /* ..., value ==> ..., value */
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);
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);
370 emit_store_dst(jd, iptr, d);
373 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
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);
381 M_ISLL_IMM(s1, 24, d);
382 M_ISRA_IMM( d, 24, d);
384 emit_store_dst(jd, iptr, d);
387 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
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);
395 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
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);
403 M_ISLL_IMM(s1, 16, d);
404 M_ISRA_IMM( d, 16, d);
406 emit_store_dst(jd, iptr, d);
410 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
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);
416 emit_store_dst(jd, iptr, d);
420 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
421 /* sx.val.i = constant */
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);
428 ICONST(REG_ITMP2, iptr->sx.val.i);
429 M_IADD(s1, REG_ITMP2, d);
431 emit_store_dst(jd, iptr, d);
434 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
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);
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);
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));
456 emit_store_dst(jd, iptr, d);
459 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
460 /* sx.val.l = constant */
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);
468 LCONST(REG_ITMP2, iptr->sx.val.l);
469 M_LADD(s1, REG_ITMP2, d);
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));
479 else if ((iptr->sx.val.l >= (-32768 + 1)) && (iptr->sx.val.l < 0)) {
480 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
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_ITMP1);
484 M_ISUB_IMM(s1, 1, GET_HIGH_REG(d));
485 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
488 ICONST(REG_ITMP1, iptr->sx.val.l & 0xffffffff);
489 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
490 M_IADD(s1, REG_ITMP1, GET_LOW_REG(d));
491 M_CMPULT(GET_LOW_REG(d), s1, REG_ITMP3);
492 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
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));
498 emit_store_dst(jd, iptr, d);
501 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
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);
507 emit_store_dst(jd, iptr, d);
510 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
511 /* sx.val.i = constant */
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);
518 ICONST(REG_ITMP2, iptr->sx.val.i);
519 M_ISUB(s1, REG_ITMP2, d);
521 emit_store_dst(jd, iptr, d);
524 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
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);
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_ITMP2);
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 */
543 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
544 M_ISUB(s1, s2, GET_LOW_REG(d));
547 emit_store_dst(jd, iptr, d);
550 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
551 /* sx.val.l = constant */
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);
559 LCONST(REG_ITMP2, iptr->sx.val.l);
560 M_LSUB(s1, REG_ITMP2, d);
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_ITMP1);
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_ITMP1);
569 M_ISUB_IMM(s1, 1, GET_HIGH_REG(d));
570 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
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));
579 ICONST(REG_ITMP1, iptr->sx.val.l & 0xffffffff);
580 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
581 M_ISUB(s1, REG_ITMP1, GET_LOW_REG(d));
582 M_CMPULT(s1, REG_ITMP1, REG_ITMP3);
583 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
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));
589 emit_store_dst(jd, iptr, d);
592 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
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);
601 emit_store_dst(jd, iptr, d);
604 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
605 /* sx.val.i = constant */
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);
614 emit_store_dst(jd, iptr, d);
617 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
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);
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);
635 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
637 M_MFHI(GET_HIGH_REG(d));
638 M_MFLO(GET_LOW_REG(d));
641 M_IADD(GET_HIGH_REG(d), REG_ITMP3, REG_ITMP3);
643 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
644 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
647 /* XXX do we need nops here? */
649 emit_store_dst(jd, iptr, d);
652 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
653 /* sx.val.l = constant */
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);
662 emit_store_dst(jd, iptr, d);
665 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
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);
675 emit_store_dst(jd, iptr, d);
678 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
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);
688 emit_store_dst(jd, iptr, d);
691 #if SIZEOF_VOID_P == 8
693 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
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);
703 emit_store_dst(jd, iptr, d);
706 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
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);
716 emit_store_dst(jd, iptr, d);
719 #else /* SIZEOF_VOID_P == 8 */
721 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
722 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
724 s1 = emit_load_s1(jd, iptr, REG_A0_A1_PACKED);
725 s2 = emit_load_s2(jd, iptr, REG_A2_A3_PACKED);
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);
731 M_LNGMOVE(s1, REG_A0_A1_PACKED);
732 M_LNGMOVE(s2, REG_A2_A3_PACKED);
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);
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);
745 #endif /* SIZEOF_VOID_P == 8 */
747 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
748 /* val.i = constant */
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);
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);
763 emit_store_dst(jd, iptr, d);
766 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
767 /* val.i = constant */
769 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
770 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
772 M_MOV(s1, REG_ITMP1);
775 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
776 M_AND_IMM(s1, iptr->sx.val.i, d);
779 M_ISUB(REG_ZERO, s1, d);
780 M_AND_IMM(d, iptr->sx.val.i, d);
783 ICONST(REG_ITMP3, iptr->sx.val.i);
784 M_AND(s1, REG_ITMP3, d);
787 M_ISUB(REG_ZERO, s1, d);
788 M_AND(d, REG_ITMP3, d);
790 M_ISUB(REG_ZERO, d, d);
791 emit_store_dst(jd, iptr, d);
794 #if SIZEOF_VOID_P == 8
796 case ICMD_LDIVPOW2: /* ..., value ==> ..., value << constant */
797 /* val.i = constant */
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);
808 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
809 /* val.l = constant */
811 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
812 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
814 M_MOV(s1, REG_ITMP1);
817 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
818 M_AND_IMM(s1, iptr->sx.val.l, d);
821 M_LSUB(REG_ZERO, s1, d);
822 M_AND_IMM(d, iptr->sx.val.l, d);
825 LCONST(REG_ITMP2, iptr->sx.val.l);
826 M_AND(s1, REG_ITMP2, d);
829 M_LSUB(REG_ZERO, s1, d);
830 M_AND(d, REG_ITMP2, d);
832 M_LSUB(REG_ZERO, d, d);
833 emit_store_dst(jd, iptr, d);
836 #endif /* SIZEOF_VOID_P == 8 */
838 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
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);
844 emit_store_dst(jd, iptr, d);
847 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
848 /* sx.val.i = constant */
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);
856 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
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);
862 emit_store_dst(jd, iptr, d);
865 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
866 /* sx.val.i = constant */
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);
874 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
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);
880 emit_store_dst(jd, iptr, d);
883 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
884 /* sx.val.i = constant */
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);
892 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
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);
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);
904 M_ISLL(s2, 26, REG_ITMP1);
905 M_BGEZ(REG_ITMP1, 3);
908 M_ISLL(GET_LOW_REG(s1), s2, GET_HIGH_REG(d));
910 M_MOV(REG_ZERO, GET_LOW_REG(d)); /* delay slot */
913 M_ISLL(GET_LOW_REG(s1), s2, GET_LOW_REG(d));
915 M_BEQZ(REG_ITMP1, 4);
916 M_ISLL(GET_HIGH_REG(s1), s2, GET_HIGH_REG(d)); /* delay slot */
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));
923 M_ISLL(GET_LOW_REG(s1), s2, GET_LOW_REG(d));
926 emit_store_dst(jd, iptr, d);
929 #if SIZEOF_VOID_P == 8
931 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
932 /* sx.val.i = constant */
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);
940 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
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);
946 emit_store_dst(jd, iptr, d);
949 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
950 /* sx.val.i = constant */
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);
958 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
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);
964 emit_store_dst(jd, iptr, d);
967 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
968 /* sx.val.i = constant */
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);
976 #endif /* SIZEOF_VOID_P == 8 */
978 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
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);
984 emit_store_dst(jd, iptr, d);
987 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
988 /* sx.val.i = constant */
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);
995 ICONST(REG_ITMP2, iptr->sx.val.i);
996 M_AND(s1, REG_ITMP2, d);
998 emit_store_dst(jd, iptr, d);
1001 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
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);
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));
1017 emit_store_dst(jd, iptr, d);
1020 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1021 /* sx.val.l = constant */
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);
1029 LCONST(REG_ITMP2, iptr->sx.val.l);
1030 M_AND(s1, REG_ITMP2, d);
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));
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));
1047 emit_store_dst(jd, iptr, d);
1050 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
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);
1056 emit_store_dst(jd, iptr, d);
1059 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1060 /* sx.val.i = constant */
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);
1067 ICONST(REG_ITMP2, iptr->sx.val.i);
1068 M_OR(s1, REG_ITMP2, d);
1070 emit_store_dst(jd, iptr, d);
1073 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
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);
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));
1089 emit_store_dst(jd, iptr, d);
1092 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1093 /* sx.val.l = constant */
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);
1101 LCONST(REG_ITMP2, iptr->sx.val.l);
1102 M_OR(s1, REG_ITMP2, d);
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));
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));
1119 emit_store_dst(jd, iptr, d);
1122 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
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);
1128 emit_store_dst(jd, iptr, d);
1131 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1132 /* sx.val.i = constant */
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);
1139 ICONST(REG_ITMP2, iptr->sx.val.i);
1140 M_XOR(s1, REG_ITMP2, d);
1142 emit_store_dst(jd, iptr, d);
1145 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
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);
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));
1161 emit_store_dst(jd, iptr, d);
1164 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1165 /* sx.val.l = constant */
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);
1173 LCONST(REG_ITMP2, iptr->sx.val.l);
1174 M_XOR(s1, REG_ITMP2, d);
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));
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));
1191 emit_store_dst(jd, iptr, d);
1195 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
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);
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);
1219 emit_store_dst(jd, iptr, d);
1223 /* floating operations ************************************************/
1225 case ICMD_FNEG: /* ..., value ==> ..., - value */
1227 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1228 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1230 emit_store_dst(jd, iptr, d);
1233 case ICMD_DNEG: /* ..., value ==> ..., - value */
1235 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1236 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1238 emit_store_dst(jd, iptr, d);
1241 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
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);
1247 emit_store_dst(jd, iptr, d);
1250 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
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);
1256 emit_store_dst(jd, iptr, d);
1259 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
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);
1265 emit_store_dst(jd, iptr, d);
1268 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
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);
1274 emit_store_dst(jd, iptr, d);
1277 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
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);
1283 emit_store_dst(jd, iptr, d);
1286 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
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);
1292 emit_store_dst(jd, iptr, d);
1295 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
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);
1301 emit_store_dst(jd, iptr, d);
1304 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
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);
1310 emit_store_dst(jd, iptr, d);
1314 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
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);
1327 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
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);
1341 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1343 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1344 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1347 emit_store_dst(jd, iptr, d);
1350 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1352 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1353 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1356 emit_store_dst(jd, iptr, d);
1360 /* XXX these do not work correctly */
1362 case ICMD_F2I: /* ..., (float) value ==> ..., (int) value */
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);
1369 emit_store_dst(jd, iptr, d);
1372 case ICMD_D2I: /* ..., (double) value ==> ..., (int) value */
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);
1379 emit_store_dst(jd, iptr, d);
1382 case ICMD_F2L: /* ..., (float) value ==> ..., (long) value */
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);
1389 emit_store_dst(jd, iptr, d);
1392 case ICMD_D2L: /* ..., (double) value ==> ..., (long) value */
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);
1399 emit_store_dst(jd, iptr, d);
1403 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1405 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1406 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1408 emit_store_dst(jd, iptr, d);
1411 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1413 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1414 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1416 emit_store_dst(jd, iptr, d);
1419 #if SUPPORT_FLOAT_CMP
1420 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
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);
1427 M_AADD_IMM(REG_ZERO, 1, d);
1431 M_ASUB_IMM(REG_ZERO, 1, d);
1432 M_CMOVT(REG_ZERO, d);
1433 emit_store_dst(jd, iptr, d);
1436 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
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);
1443 M_ASUB_IMM(REG_ZERO, 1, d);
1447 M_AADD_IMM(REG_ZERO, 1, d);
1448 M_CMOVT(REG_ZERO, d);
1449 emit_store_dst(jd, iptr, d);
1453 #if SUPPORT_DOUBLE_CMP
1454 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
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);
1461 M_AADD_IMM(REG_ZERO, 1, d);
1465 M_ASUB_IMM(REG_ZERO, 1, d);
1466 M_CMOVT(REG_ZERO, d);
1467 emit_store_dst(jd, iptr, d);
1470 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
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);
1477 M_ASUB_IMM(REG_ZERO, 1, d);
1481 M_AADD_IMM(REG_ZERO, 1, d);
1482 M_CMOVT(REG_ZERO, d);
1483 emit_store_dst(jd, iptr, d);
1488 /* memory operations **************************************************/
1490 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
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);
1499 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
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);
1511 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
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);
1524 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
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);
1537 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
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);
1550 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
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);
1557 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
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);
1567 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
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);
1580 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
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);
1593 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
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);
1607 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
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]));
1618 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1619 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
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]));
1631 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
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]));
1643 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
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);
1653 s3 = emit_load_s3(jd, iptr, REG_ITMP23_PACKED);
1655 /* implicit null-pointer check */
1656 M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1659 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
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]));
1671 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
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]));
1684 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
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);
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);
1697 emit_arraystore_check(cd, iptr);
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]));
1709 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
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]));
1719 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1720 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
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]));
1731 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
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]));
1742 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
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]));
1753 M_LST_INTERN(PACK_REGS(REG_ZERO, REG_ZERO), REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1757 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
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]));
1769 case ICMD_GETSTATIC: /* ... ==> ..., value */
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);
1776 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1779 fi = iptr->sx.s23.s3.fmiref->p.field;
1780 fieldtype = fi->type;
1781 disp = dseg_add_address(cd, fi->value);
1783 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
1784 patcher_add_patch_ref(jd, PATCHER_initialize_class,
1788 M_ALD(REG_ITMP1, REG_PV, disp);
1790 switch (fieldtype) {
1792 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1793 M_ILD_INTERN(d, REG_ITMP1, 0);
1796 #if SIZEOF_VOID_P == 8
1797 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1799 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
1801 M_LLD_INTERN(d, REG_ITMP1, 0);
1804 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1805 M_ALD_INTERN(d, REG_ITMP1, 0);
1808 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1809 M_FLD_INTERN(d, REG_ITMP1, 0);
1812 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1813 M_DLD_INTERN(d, REG_ITMP1, 0);
1816 emit_store_dst(jd, iptr, d);
1819 case ICMD_PUTSTATIC: /* ..., value ==> ... */
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);
1826 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1829 fi = iptr->sx.s23.s3.fmiref->p.field;
1830 fieldtype = fi->type;
1831 disp = dseg_add_address(cd, fi->value);
1833 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
1834 patcher_add_patch_ref(jd, PATCHER_initialize_class,
1838 M_ALD(REG_ITMP1, REG_PV, disp);
1840 switch (fieldtype) {
1842 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1843 M_IST_INTERN(s1, REG_ITMP1, 0);
1846 #if SIZEOF_VOID_P == 8
1847 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1849 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
1851 M_LST_INTERN(s1, REG_ITMP1, 0);
1854 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1855 M_AST_INTERN(s1, REG_ITMP1, 0);
1858 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1859 M_FST_INTERN(s1, REG_ITMP1, 0);
1862 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1863 M_DST_INTERN(s1, REG_ITMP1, 0);
1868 case ICMD_PUTSTATICCONST: /* ... ==> ... */
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);
1875 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1878 fi = iptr->sx.s23.s3.fmiref->p.field;
1879 fieldtype = fi->type;
1880 disp = dseg_add_address(cd, fi->value);
1882 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
1883 patcher_add_patch_ref(jd, PATCHER_initialize_class,
1887 M_ALD(REG_ITMP1, REG_PV, disp);
1889 switch (fieldtype) {
1891 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
1894 M_LST_INTERN(REG_ZERO, REG_ITMP1, 0);
1897 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
1900 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
1903 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
1909 case ICMD_GETFIELD: /* ... ==> ..., value */
1911 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1912 emit_nullpointer_check(cd, iptr, s1);
1914 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1915 uf = iptr->sx.s23.s3.uf;
1916 fieldtype = uf->fieldref->parseddesc.fd->type;
1919 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1922 fi = iptr->sx.s23.s3.fmiref->p.field;
1923 fieldtype = fi->type;
1927 switch (fieldtype) {
1929 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1933 #if SIZEOF_VOID_P == 8
1934 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1937 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
1938 M_LLD_GETFIELD(d, s1, disp);
1942 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1946 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1950 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1954 emit_store_dst(jd, iptr, d);
1957 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1959 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1960 emit_nullpointer_check(cd, iptr, s1);
1962 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1963 uf = iptr->sx.s23.s3.uf;
1964 fieldtype = uf->fieldref->parseddesc.fd->type;
1968 fi = iptr->sx.s23.s3.fmiref->p.field;
1969 fieldtype = fi->type;
1973 #if SIZEOF_VOID_P == 8
1974 if (IS_INT_LNG_TYPE(fieldtype))
1975 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1977 s2 = emit_load_s2(jd, iptr, REG_FTMP1);
1979 if (IS_INT_LNG_TYPE(fieldtype)) {
1980 if (IS_2_WORD_TYPE(fieldtype))
1981 s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
1983 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1986 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1989 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1990 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1992 switch (fieldtype) {
1994 M_IST(s2, s1, disp);
1997 M_LST(s2, s1, disp);
2000 M_AST(s2, s1, disp);
2003 M_FST(s2, s1, disp);
2006 M_DST(s2, s1, disp);
2011 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2013 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2014 emit_nullpointer_check(cd, iptr, s1);
2016 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2017 uf = iptr->sx.s23.s3.uf;
2018 fieldtype = uf->fieldref->parseddesc.fd->type;
2021 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2024 fi = iptr->sx.s23.s3.fmiref->p.field;
2025 fieldtype = fi->type;
2029 switch (fieldtype) {
2031 M_IST(REG_ZERO, s1, disp);
2034 M_LST(REG_ZERO, s1, disp);
2037 M_AST(REG_ZERO, s1, disp);
2040 M_FST(REG_ZERO, s1, disp);
2043 M_DST(REG_ZERO, s1, disp);
2049 /* branch operations **************************************************/
2051 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
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);
2059 M_NOP; /* nop ensures that XPC is less than the end */
2060 /* of basic block */
2063 case ICMD_IFEQ: /* ..., value ==> ... */
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);
2070 case ICMD_IFLT: /* ..., value ==> ... */
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);
2076 ICONST(REG_ITMP2, iptr->sx.val.i);
2077 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2079 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2082 case ICMD_IFLE: /* ..., value ==> ... */
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);
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);
2096 case ICMD_IFNE: /* ..., value ==> ... */
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);
2103 case ICMD_IFGT: /* ..., value ==> ... */
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);
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);
2117 case ICMD_IFGE: /* ..., value ==> ... */
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);
2123 ICONST(REG_ITMP2, iptr->sx.val.i);
2124 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2126 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2129 case ICMD_IF_LEQ: /* ..., value ==> ... */
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);
2136 LCONST(REG_ITMP2, iptr->sx.val.l);
2137 emit_beq(cd, iptr->dst.block, s1, REG_ITMP2);
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);
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);
2158 case ICMD_IF_LLT: /* ..., value ==> ... */
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);
2165 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767))
2166 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP3);
2168 LCONST(REG_ITMP2, iptr->sx.val.l);
2169 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2171 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
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);
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);
2194 case ICMD_IF_LLE: /* ..., value ==> ... */
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);
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);
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);
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);
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);
2234 case ICMD_IF_LNE: /* ..., value ==> ... */
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);
2241 LCONST(REG_ITMP2, iptr->sx.val.l);
2242 emit_bne(cd, iptr->dst.block, s1, REG_ITMP2);
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);
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);
2263 case ICMD_IF_LGT: /* ..., value ==> ... */
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);
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);
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);
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);
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);
2303 case ICMD_IF_LGE: /* ..., value ==> ... */
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);
2310 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
2311 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP3);
2314 LCONST(REG_ITMP2, iptr->sx.val.l);
2315 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2317 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
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);
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);
2340 #if SIZEOF_VOID_P == 8
2341 case ICMD_IF_LCMPEQ:
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);
2349 #if SIZEOF_VOID_P == 4
2350 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2351 /* op1 = target JavaVM pc */
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);
2363 #if SIZEOF_VOID_P == 8
2364 case ICMD_IF_LCMPNE:
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);
2372 #if SIZEOF_VOID_P == 4
2373 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
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);
2385 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2386 #if SIZEOF_VOID_P == 8
2387 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
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);
2396 #if SIZEOF_VOID_P == 4
2397 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
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);
2413 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2414 #if SIZEOF_VOID_P == 8
2415 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
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);
2424 #if SIZEOF_VOID_P == 4
2425 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
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);
2441 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2442 #if SIZEOF_VOID_P == 8
2443 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
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);
2452 #if SIZEOF_VOID_P == 4
2453 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
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);
2469 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2470 #if SIZEOF_VOID_P == 8
2471 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
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);
2480 #if SIZEOF_VOID_P == 4
2481 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
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);
2497 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2500 branch_target_t *table;
2502 table = iptr->dst.table;
2504 l = iptr->sx.s23.s2.tablelow;
2505 i = iptr->sx.s23.s3.tablehigh;
2507 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2509 {M_INTMOVE(s1, REG_ITMP1);}
2510 else if (l <= 32768) {
2511 M_IADD_IMM(s1, -l, REG_ITMP1);
2514 ICONST(REG_ITMP2, l);
2515 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2518 /* number of targets */
2523 M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
2524 emit_beqz(cd, table[0].block, REG_ITMP2);
2526 /* build jump table top down and use address of lowest entry */
2531 dseg_add_target(cd, table->block);
2536 /* length of dataseg after last dseg_add_target is used by load */
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));
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 */
2552 /* generate the actual call */
2554 /* TWISTI: i actually don't know the reason for using
2555 REG_ITMP3 here instead of REG_PV. */
2557 M_JSR(REG_RA, REG_ITMP3);
2561 disp = dseg_add_functionptr(cd, bte->stub);
2562 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
2564 /* generate the actual call */
2566 M_JSR(REG_RA, REG_PV);
2571 case ICMD_INVOKESPECIAL:
2572 emit_nullpointer_check(cd, iptr, REG_A0);
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);
2580 patcher_add_patch_ref(jd, PATCHER_invokestatic_special, um,
2584 lm = iptr->sx.s23.s3.fmiref->p.method;
2585 disp = dseg_add_address(cd, lm->stubroutine);
2588 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
2590 /* generate the actual call */
2592 M_JSR(REG_RA, REG_PV);
2596 case ICMD_INVOKEVIRTUAL:
2597 emit_nullpointer_check(cd, iptr, REG_A0);
2599 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2600 um = iptr->sx.s23.s3.um;
2601 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
2606 lm = iptr->sx.s23.s3.fmiref->p.method;
2607 s1 = OFFSET(vftbl_t, table[0]) +
2608 sizeof(methodptr) * lm->vftblindex;
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);
2615 /* generate the actual call */
2617 M_JSR(REG_RA, REG_PV);
2621 case ICMD_INVOKEINTERFACE:
2622 emit_nullpointer_check(cd, iptr, REG_A0);
2624 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2625 um = iptr->sx.s23.s3.um;
2626 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
2632 lm = iptr->sx.s23.s3.fmiref->p.method;
2633 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2634 sizeof(methodptr*) * lm->clazz->index;
2636 s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
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);
2644 /* generate the actual call */
2646 M_JSR(REG_RA, REG_PV);
2652 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2654 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2658 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2663 super = iptr->sx.s23.s3.c.cls;
2664 superindex = super->index;
2667 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2669 /* if class is not resolved, check which code to call */
2671 if (super == NULL) {
2672 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2674 constant_classref *cr = iptr->sx.s23.s3.c.ref;
2675 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2677 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
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);
2685 /* interface checkcast code */
2687 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2688 if (super == NULL) {
2689 constant_classref *cr = iptr->sx.s23.s3.c.ref;
2691 patcher_add_patch_ref(jd, PATCHER_checkcast_interface,
2695 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
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);
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);
2710 emit_label_br(cd, BRANCH_LABEL_4);
2712 emit_label(cd, BRANCH_LABEL_3);
2715 /* class checkcast code */
2717 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2718 if (super == NULL) {
2719 emit_label(cd, BRANCH_LABEL_2);
2721 constant_classref *cr = iptr->sx.s23.s3.c.ref;
2722 disp = dseg_add_unique_address(cd, NULL);
2724 patcher_add_patch_ref(jd,
2725 PATCHER_resolve_classref_to_vftbl,
2729 disp = dseg_add_address(cd, super->vftbl);
2731 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
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;
2738 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2739 M_ALD(REG_ITMP3, REG_PV, disp);
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;
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 */
2751 // Represents the following semantic:
2752 // if (t->vftbl->subtype_offset != OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE])) throw;
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 */
2761 // Represents the following semantic:
2762 // if (s->vftbl->subtype_depth < t->vftbl->subtype_depth) throw;
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 */
2770 // Represents the following semantic:
2771 // if (s->vftbl->subtype_overflow[t->vftbl->subtype_depth - DISPLAY_SIZE] != t->vftbl) throw;
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 */
2782 emit_label(cd, BRANCH_LABEL_8);
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);
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 */
2794 // Represents the following semantic:
2795 // if (*(s->vftbl + t->vftbl->subtype_offset) != t->vftbl) throw;
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);
2805 emit_label(cd, BRANCH_LABEL_5);
2808 if (super == NULL) {
2809 emit_label(cd, BRANCH_LABEL_1);
2810 emit_label(cd, BRANCH_LABEL_4);
2813 d = codegen_reg_of_dst(jd, iptr, s1);
2816 s1 = emit_load_s1(jd, iptr, REG_A0);
2817 M_INTMOVE(s1, REG_A0);
2819 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2820 constant_classref *cr = iptr->sx.s23.s3.c.ref;
2821 disp = dseg_add_unique_address(cd, NULL);
2823 patcher_add_patch_ref(jd,
2824 PATCHER_resolve_classref_to_classinfo,
2828 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
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);
2837 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2838 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT, s1);
2840 d = codegen_reg_of_dst(jd, iptr, s1);
2844 emit_store_dst(jd, iptr, d);
2847 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2853 super = iptr->sx.s23.s3.c.cls;
2855 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2860 super = iptr->sx.s23.s3.c.cls;
2861 superindex = super->index;
2864 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2865 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2868 M_MOV(s1, REG_ITMP1);
2874 /* if class is not resolved, check which code to call */
2876 if (super == NULL) {
2877 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2879 constant_classref *cr = iptr->sx.s23.s3.c.ref;
2880 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2882 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
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);
2890 /* interface instanceof code */
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);
2898 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
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);
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 */
2913 emit_label_br(cd, BRANCH_LABEL_4);
2915 emit_label(cd, BRANCH_LABEL_3);
2918 /* class instanceof code */
2920 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2921 if (super == NULL) {
2922 emit_label(cd, BRANCH_LABEL_2);
2924 constant_classref *cr = iptr->sx.s23.s3.c.ref;
2925 disp = dseg_add_unique_address(cd, NULL);
2927 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl,
2931 disp = dseg_add_address(cd, super->vftbl);
2933 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
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));
2940 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2941 M_ALD(REG_ITMP3, REG_PV, disp);
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;
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 */
2953 // Represents the following semantic:
2954 // if (t->vftbl->subtype_offset != OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE])) false;
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 */
2963 // Represents the following semantic:
2964 // if (s->vftbl->subtype_depth < t->vftbl->subtype_depth) false;
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 */
2972 // Represents the following semantic:
2973 // if (s->vftbl->subtype_overflow[t->vftbl->subtype_depth - DISPLAY_SIZE] != t->vftbl) false;
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 */
2984 emit_label(cd, BRANCH_LABEL_6);
2986 if (d == REG_ITMP2) {
2987 M_BR(2); /* branch over M_CLR */
2988 M_NOP; /* delay slot */
2991 // False (fall-through) case
2992 emit_label(cd, BRANCH_LABEL_7);
2993 emit_label(cd, BRANCH_LABEL_8);
2995 emit_label(cd, BRANCH_LABEL_9);
2997 M_CLR(d); /* if d == REG_ITMP2, it was destroyed */
3000 // Represents the following semantic:
3001 // *(s->vftbl + t->vftbl->subtype_offset) == t->vftbl;
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);
3010 emit_label(cd, BRANCH_LABEL_5);
3013 if (super == NULL) {
3014 emit_label(cd, BRANCH_LABEL_1);
3015 emit_label(cd, BRANCH_LABEL_4);
3018 emit_store_dst(jd, iptr, d);
3022 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3024 /* check for negative sizes and copy sizes to stack if necessary */
3026 MCODECHECK((iptr->s1.argcount << 1) + 64);
3028 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3030 var = VAR(iptr->sx.s23.s2.args[s1]);
3032 /* copy SAVEDVAR sizes to stack */
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);
3039 M_IST(s2, REG_SP, (s1 + 2) * 8);
3044 /* a0 = dimension count */
3046 ICONST(REG_A0, iptr->s1.argcount);
3048 /* is patcher function set? */
3050 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3051 constant_classref *cr = iptr->sx.s23.s3.c.ref;
3052 disp = dseg_add_unique_address(cd, NULL);
3054 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
3058 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3061 /* a1 = arraydescriptor */
3063 M_ALD(REG_A1, REG_PV, disp);
3065 /* a2 = pointer to dimensions = stack pointer */
3067 #if SIZEOF_VOID_P == 8
3068 M_MOV(REG_SP, REG_A2);
3070 M_AADD_IMM(REG_SP, 4*4, REG_A2);
3073 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3074 M_ALD(REG_ITMP3, REG_PV, disp);
3075 M_JSR(REG_RA, REG_ITMP3);
3078 /* check for exception before result assignment */
3080 emit_exception_check(cd, iptr);
3082 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3083 M_INTMOVE(REG_RESULT, d);
3084 emit_store_dst(jd, iptr, d);
3088 vm_abort("Unknown ICMD %d during code generation", iptr->opc);
3093 /* codegen_emit_stub_native ****************************************************
3095 Emits a stub routine which calls a native method.
3097 *******************************************************************************/
3099 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
3110 /* get required compiler data */
3116 /* initialize variables */
3120 /* calculate stack frame size */
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) */
3130 1 + /* for saving return address */
3133 /* adjust stackframe size for 16-byte alignment */
3135 if (cd->stackframesize & 1)
3136 cd->stackframesize++;
3138 /* create method header */
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 */
3146 /* generate stub code */
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 */
3151 /* save integer and float argument registers */
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);
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;
3167 if (IS_2_WORD_TYPE(md->params[i].type))
3168 M_LST(s1, REG_SP, j * 8);
3170 M_IST(s1, REG_SP, j * 8);
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;
3182 if (IS_2_WORD_TYPE(md->params[i].type))
3183 M_DST(s1, REG_SP, j * 8);
3185 M_FST(s1, REG_SP, j * 8);
3191 /* prepare data structures for native function call */
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! */
3200 /* remember class argument */
3202 if (m->flags & ACC_STATIC)
3203 M_MOV(REG_RESULT, REG_ITMP3);
3205 /* restore integer and float argument registers */
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);
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;
3221 if (IS_2_WORD_TYPE(md->params[i].type))
3222 M_LLD(s1, REG_SP, j * 8);
3224 M_ILD(s1, REG_SP, j * 8);
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;
3236 if (IS_2_WORD_TYPE(md->params[i].type))
3237 M_DLD(s1, REG_SP, j * 8);
3239 M_FLD(s1, REG_SP, j * 8);
3245 /* copy or spill arguments to new locations */
3247 for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
3248 t = md->params[i].type;
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;
3255 if (!nmd->params[j].inmemory) {
3256 #if SIZEOF_VOID_P == 8
3259 if (IS_2_WORD_TYPE(t))
3266 #if SIZEOF_VOID_P == 8
3267 M_LST(s1, REG_SP, s2);
3269 if (IS_2_WORD_TYPE(t))
3270 M_LST(s1, REG_SP, s2);
3272 M_IST(s1, REG_SP, s2);
3277 s1 = md->params[i].regoff + cd->stackframesize * 8;
3278 s2 = nmd->params[j].regoff;
3280 #if SIZEOF_VOID_P == 8
3281 M_LLD(REG_ITMP1, REG_SP, s1);
3282 M_LST(REG_ITMP1, REG_SP, s2);
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);
3289 M_ILD(REG_ITMP1, REG_SP, s1);
3290 M_IST(REG_ITMP1, REG_SP, s2);
3296 if (!md->params[i].inmemory) {
3297 s1 = md->params[i].regoff;
3298 s2 = nmd->params[j].regoff;
3300 if (!nmd->params[j].inmemory) {
3301 #if SIZEOF_VOID_P == 8
3302 if (IS_2_WORD_TYPE(t))
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) */
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 */
3317 M_MFC1(GET_LOW_REG(s2), s1); /* low 32-bits */
3318 M_MFC1(GET_HIGH_REG(s2), s1 + 1); /* high 32-bits */
3325 #if SIZEOF_VOID_P == 8
3326 if (IS_2_WORD_TYPE(t))
3327 M_DST(s1, REG_SP, s2);
3329 M_FST(s1, REG_SP, s2);
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 */
3335 if (IS_2_WORD_TYPE(t))
3336 M_DST(GET_LOW_REG(s1), REG_SP, s2);
3338 M_FST(GET_LOW_REG(s1), REG_SP, s2);
3343 s1 = md->params[i].regoff + cd->stackframesize * 8;
3344 s2 = nmd->params[j].regoff;
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);
3352 M_FLD(REG_FTMP1, REG_SP, s1);
3353 M_FST(REG_FTMP1, REG_SP, s2);
3356 if (IS_2_WORD_TYPE(t)) {
3357 M_DLD(REG_FTMP1, REG_SP, s1);
3358 M_DST(REG_FTMP1, REG_SP, s2);
3361 M_FLD(REG_FTMP1, REG_SP, s1);
3362 M_FST(REG_FTMP1, REG_SP, s2);
3369 /* Handle native Java methods. */
3371 if (m->flags & ACC_NATIVE) {
3372 /* put class into second argument register */
3374 if (m->flags & ACC_STATIC)
3375 M_MOV(REG_ITMP3, REG_A1);
3377 /* put env into first argument register */
3379 disp = dseg_add_address(cd, VM_get_jnienv());
3380 M_ALD(REG_A0, REG_PV, disp);
3383 /* Call the native function. */
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 */
3390 /* save return value */
3392 switch (md->returntype.type) {
3393 #if SIZEOF_VOID_P == 8
3397 M_LST(REG_RESULT, REG_SP, 0 * 8);
3401 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3406 M_IST(REG_RESULT, REG_SP, 2*4 + 0 * 8);
3409 M_LST(REG_RESULT_PACKED, REG_SP, 2*4 + 0 * 8);
3413 M_DST(REG_FRESULT, REG_SP, 2*4 + 0 * 8);
3420 /* remove native stackframe info */
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);
3430 /* restore return value */
3432 switch (md->returntype.type) {
3433 #if SIZEOF_VOID_P == 8
3437 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3441 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3446 M_ILD(REG_RESULT, REG_SP, 2*4 + 0 * 8);
3449 M_LLD(REG_RESULT_PACKED, REG_SP, 2*4 + 0 * 8);
3453 M_DLD(REG_FRESULT, REG_SP, 2*4 + 0 * 8);
3460 M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* load RA */
3462 /* check for exception */
3464 M_BNEZ(REG_ITMP1_XPTR, 2); /* if no exception then return */
3465 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8); /* DELAY SLOT */
3467 M_RET(REG_RA); /* return to caller */
3468 M_NOP; /* DELAY SLOT */
3470 /* handle exception */
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) */
3477 /* Generate patcher traps. */
3479 emit_patcher_traps(jd);
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 * ---------------------------------------------------------------------
3490 * indent-tabs-mode: t
3494 * vim:noexpandtab:sw=4:ts=4: