1 /* src/vm/jit/mips/codegen.c - machine code generator for MIPS
3 Copyright (C) 1996-2005, 2006, 2007, 2008
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/patcher-common.hpp"
59 #include "vm/jit/reg.h"
60 #include "vm/jit/trap.hpp"
62 #if defined(ENABLE_LSRA)
63 # include "vm/jit/allocator/lsra.h"
67 /* codegen_emit ****************************************************************
69 Generates machine code.
71 *******************************************************************************/
73 bool codegen_emit(jitdata *jd)
77 savedregs_num = code_is_leafmethod(code) ? 0 : 1; /* space to save the RA */
80 #if defined(ENABLE_THREADS)
81 /* space to save argument of monitor_enter */
83 if (checksync && code_is_synchronized(code)) {
84 # if SIZEOF_VOID_P == 8
88 cd->stackframesize += 2;
93 /* keep stack 16-byte aligned */
95 if (cd->stackframesize & 1)
115 * Generates machine code for the method prolog.
117 void codegen_emit_prolog(jitdata* jd)
126 // Get required compiler data.
127 methodinfo* m = jd->m;
128 codeinfo* code = jd->code;
129 codegendata* cd = jd->cd;
130 registerdata* rd = jd->rd;
132 /* create stack frame (if necessary) */
134 if (cd->stackframesize)
135 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8);
137 /* save return address and used callee saved registers */
139 p = cd->stackframesize;
140 if (!code_is_leafmethod(code)) {
141 p--; M_AST(REG_RA, REG_SP, p * 8);
143 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
144 p--; M_AST(rd->savintregs[i], REG_SP, p * 8);
146 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
147 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
150 /* take arguments out of register or stack frame */
154 for (p = 0, l = 0; p < md->paramcount; p++) {
155 t = md->paramtypes[p].type;
157 varindex = jd->local_map[l * 5 + t];
160 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
163 if (varindex == UNUSED)
167 s1 = md->params[p].regoff;
169 if (IS_INT_LNG_TYPE(t)) { /* integer args */
170 if (!md->params[p].inmemory) { /* register arguments */
171 #if SIZEOF_VOID_P == 8
172 if (!(var->flags & INMEMORY))
173 M_INTMOVE(s1, var->vv.regoff);
175 M_LST(s1, REG_SP, var->vv.regoff);
177 if (!(var->flags & INMEMORY)) {
178 if (IS_2_WORD_TYPE(t))
179 M_LNGMOVE(s1, var->vv.regoff);
181 M_INTMOVE(s1, var->vv.regoff);
184 if (IS_2_WORD_TYPE(t))
185 M_LST(s1, REG_SP, var->vv.regoff);
187 M_IST(s1, REG_SP, var->vv.regoff);
191 else { /* stack arguments */
192 if (!(var->flags & INMEMORY)) {
193 #if SIZEOF_VOID_P == 8
194 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
196 if (IS_2_WORD_TYPE(t))
197 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
199 M_ILD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
203 var->vv.regoff = cd->stackframesize * 8 + s1;
206 else { /* floating args */
207 if (!md->params[p].inmemory) {
208 if (!(var->flags & INMEMORY)) {
209 if (IS_2_WORD_TYPE(t))
210 emit_dmove(cd, s1, var->vv.regoff);
212 emit_fmove(cd, s1, var->vv.regoff);
215 if (IS_2_WORD_TYPE(t))
216 M_DST(s1, REG_SP, var->vv.regoff);
218 M_FST(s1, REG_SP, var->vv.regoff);
222 if (!(var->flags & INMEMORY)) {
223 if (IS_2_WORD_TYPE(t))
224 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
226 M_FLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
229 var->vv.regoff = cd->stackframesize * 8 + s1;
237 * Generates machine code for the method epilog.
239 void codegen_emit_epilog(jitdata* jd)
244 // Get required compiler data.
245 codeinfo* code = jd->code;
246 codegendata* cd = jd->cd;
247 registerdata* rd = jd->rd;
249 p = cd->stackframesize;
251 /* restore return address */
253 if (!code_is_leafmethod(code)) {
254 p--; M_ALD(REG_RA, REG_SP, p * 8);
257 /* restore saved registers */
259 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
260 p--; M_ALD(rd->savintregs[i], REG_SP, p * 8);
262 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
263 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
266 /* deallocate stack and return */
268 if (cd->stackframesize) {
271 disp = cd->stackframesize * 8;
273 hi = (short) (((disp) - lo) >> 16);
277 M_AADD_IMM(REG_SP, lo, REG_SP); /* delay slot */
280 M_AADD_IMM(REG_ITMP3,lo,REG_ITMP3);
282 M_AADD(REG_ITMP3,REG_SP,REG_SP); /* delay slot */
293 * Generates machine code for one ICMD.
295 void codegen_emit_instruction(jitdata* jd, instruction* iptr)
298 builtintable_entry* bte;
299 methodinfo* lm; // Local methodinfo for ICMD_INVOKE*.
300 unresolved_method* um;
302 unresolved_field* uf;
304 int32_t s1, s2, s3, d;
307 // Get required compiler data.
308 codeinfo* code = jd->code;
309 codegendata* cd = jd->cd;
313 /* constant operations ************************************************/
315 case ICMD_LCONST: /* ... ==> ..., constant */
317 #if SIZEOF_VOID_P == 8
318 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
320 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
322 LCONST(d, iptr->sx.val.l);
323 emit_store_dst(jd, iptr, d);
326 case ICMD_FCONST: /* ... ==> ..., constant */
328 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
329 disp = dseg_add_float(cd, iptr->sx.val.f);
330 M_FLD(d, REG_PV, disp);
331 emit_store_dst(jd, iptr, d);
334 case ICMD_DCONST: /* ... ==> ..., constant */
336 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
337 disp = dseg_add_double(cd, iptr->sx.val.d);
338 M_DLD(d, REG_PV, disp);
339 emit_store_dst(jd, iptr, d);
342 case ICMD_ACONST: /* ... ==> ..., constant */
344 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
346 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
347 constant_classref *cr = iptr->sx.val.c.ref;
348 disp = dseg_add_unique_address(cd, cr);
350 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
353 M_ALD(d, REG_PV, disp);
356 if (iptr->sx.val.anyptr == NULL)
357 M_INTMOVE(REG_ZERO, d);
359 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
360 M_ALD(d, REG_PV, disp);
363 emit_store_dst(jd, iptr, d);
367 /* integer operations *************************************************/
369 case ICMD_INEG: /* ..., value ==> ..., - value */
371 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
372 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
373 M_ISUB(REG_ZERO, s1, d);
374 emit_store_dst(jd, iptr, d);
377 case ICMD_LNEG: /* ..., value ==> ..., - value */
379 #if SIZEOF_VOID_P == 8
380 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
381 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
382 M_LSUB(REG_ZERO, s1, d);
384 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
385 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
386 M_ISUB(REG_ZERO, GET_LOW_REG(s1), GET_LOW_REG(d));
387 M_ISUB(REG_ZERO, GET_HIGH_REG(s1), GET_HIGH_REG(d));
388 M_CMPULT(REG_ZERO, GET_LOW_REG(d), REG_ITMP3);
389 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
391 emit_store_dst(jd, iptr, d);
394 case ICMD_I2L: /* ..., value ==> ..., value */
396 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
397 #if SIZEOF_VOID_P == 8
398 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
401 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
402 M_INTMOVE(s1, GET_LOW_REG(d));
403 M_ISRA_IMM(GET_LOW_REG(d), 31, GET_HIGH_REG(d));
405 emit_store_dst(jd, iptr, d);
408 case ICMD_L2I: /* ..., value ==> ..., value */
410 #if SIZEOF_VOID_P == 8
411 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
412 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
413 M_ISLL_IMM(s1, 0, d);
415 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
416 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
417 M_INTMOVE(GET_LOW_REG(s1), d);
419 emit_store_dst(jd, iptr, d);
422 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
424 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
425 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
426 #if SIZEOF_VOID_P == 8
427 M_LSLL_IMM(s1, 56, d);
428 M_LSRA_IMM( d, 56, d);
430 M_ISLL_IMM(s1, 24, d);
431 M_ISRA_IMM( d, 24, d);
433 emit_store_dst(jd, iptr, d);
436 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
438 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
439 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
440 M_AND_IMM(s1, 0xffff, d);
441 emit_store_dst(jd, iptr, d);
444 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
446 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
447 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
448 #if SIZEOF_VOID_P == 8
449 M_LSLL_IMM(s1, 48, d);
450 M_LSRA_IMM( d, 48, d);
452 M_ISLL_IMM(s1, 16, d);
453 M_ISRA_IMM( d, 16, d);
455 emit_store_dst(jd, iptr, d);
459 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
461 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
462 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
463 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
465 emit_store_dst(jd, iptr, d);
469 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
470 /* sx.val.i = constant */
472 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
473 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
474 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
475 M_IADD_IMM(s1, iptr->sx.val.i, d);
477 ICONST(REG_ITMP2, iptr->sx.val.i);
478 M_IADD(s1, REG_ITMP2, d);
480 emit_store_dst(jd, iptr, d);
483 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
485 #if SIZEOF_VOID_P == 8
486 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
487 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
488 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
491 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
492 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
493 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
494 M_IADD(s1, s2, GET_HIGH_REG(d));
495 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
496 s2 = emit_load_s2_low(jd, iptr, GET_LOW_REG(REG_ITMP12_PACKED));
497 if (s1 == GET_LOW_REG(d)) {
498 M_MOV(s1, REG_ITMP3);
501 M_IADD(s1, s2, GET_LOW_REG(d));
502 M_CMPULT(GET_LOW_REG(d), s1, REG_ITMP3);
503 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
505 emit_store_dst(jd, iptr, d);
508 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
509 /* sx.val.l = constant */
511 #if SIZEOF_VOID_P == 8
512 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
513 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
514 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767))
515 M_LADD_IMM(s1, iptr->sx.val.l, d);
517 LCONST(REG_ITMP2, iptr->sx.val.l);
518 M_LADD(s1, REG_ITMP2, d);
521 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
522 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 32767)) {
523 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
524 M_IADD_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
525 M_CMPULT_IMM(GET_LOW_REG(d), iptr->sx.val.l, REG_ITMP3);
526 M_IADD(GET_HIGH_REG(s1), REG_ITMP3, GET_HIGH_REG(d));
528 else if ((iptr->sx.val.l >= (-32768 + 1)) && (iptr->sx.val.l < 0)) {
529 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
530 M_ISUB_IMM(s1, -(iptr->sx.val.l), GET_LOW_REG(d));
531 M_CMPULT_IMM(GET_LOW_REG(d), iptr->sx.val.l, REG_ITMP3);
532 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
533 M_ISUB_IMM(s1, 1, GET_HIGH_REG(d));
534 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
537 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
538 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
539 M_IADD(s1, REG_ITMP2, GET_LOW_REG(d));
540 M_CMPULT(GET_LOW_REG(d), s1, REG_ITMP3);
541 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
542 M_IADD(s1, REG_ITMP3, GET_HIGH_REG(d));
543 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
544 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
547 emit_store_dst(jd, iptr, d);
550 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
552 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
553 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
554 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
556 emit_store_dst(jd, iptr, d);
559 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
560 /* sx.val.i = constant */
562 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
563 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
564 if ((iptr->sx.val.i >= -32767) && (iptr->sx.val.i <= 32768))
565 M_IADD_IMM(s1, -iptr->sx.val.i, d);
567 ICONST(REG_ITMP2, iptr->sx.val.i);
568 M_ISUB(s1, REG_ITMP2, d);
570 emit_store_dst(jd, iptr, d);
573 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
575 #if SIZEOF_VOID_P == 8
576 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
577 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
578 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
581 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
582 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
583 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
584 M_ISUB(s1, s2, GET_HIGH_REG(d));
585 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
586 s2 = emit_load_s2_low(jd, iptr, REG_ITMP1);
587 M_CMPULT(s1, s2, REG_ITMP3);
588 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
589 /* if s1 is equal to REG_ITMP3 we have to reload it, since
590 the CMPULT instruction destroyed it */
592 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
593 M_ISUB(s1, s2, GET_LOW_REG(d));
596 emit_store_dst(jd, iptr, d);
599 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
600 /* sx.val.l = constant */
602 #if SIZEOF_VOID_P == 8
603 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
604 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
605 if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l <= 32768))
606 M_LADD_IMM(s1, -iptr->sx.val.l, d);
608 LCONST(REG_ITMP2, iptr->sx.val.l);
609 M_LSUB(s1, REG_ITMP2, d);
612 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
613 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 32768)) {
614 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
615 M_ISUB_IMM(s1, iptr->sx.val.l, GET_LOW_REG(d));
616 M_CMPULT_IMM(GET_LOW_REG(d), -(iptr->sx.val.l), REG_ITMP3);
617 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
618 M_ISUB_IMM(s1, 1, GET_HIGH_REG(d));
619 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
621 else if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l < 0)) {
622 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
623 M_IADD_IMM(GET_LOW_REG(s1), -(iptr->sx.val.l), GET_LOW_REG(d));
624 M_CMPULT_IMM(GET_LOW_REG(d), -(iptr->sx.val.l), REG_ITMP3);
625 M_IADD(GET_HIGH_REG(s1), REG_ITMP3, GET_HIGH_REG(d));
628 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
629 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
630 M_ISUB(s1, REG_ITMP2, GET_LOW_REG(d));
631 M_CMPULT(s1, REG_ITMP2, REG_ITMP3);
632 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
633 M_ISUB(s1, REG_ITMP3, GET_HIGH_REG(d));
634 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
635 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
638 emit_store_dst(jd, iptr, d);
641 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
643 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
644 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
645 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
650 emit_store_dst(jd, iptr, d);
653 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
654 /* sx.val.i = constant */
656 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
657 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
658 ICONST(REG_ITMP2, iptr->sx.val.i);
659 M_IMUL(s1, REG_ITMP2);
663 emit_store_dst(jd, iptr, d);
666 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
668 #if SIZEOF_VOID_P == 8
669 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
670 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
671 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
677 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
678 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
679 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
684 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
686 M_MFHI(GET_HIGH_REG(d));
687 M_MFLO(GET_LOW_REG(d));
690 M_IADD(GET_HIGH_REG(d), REG_ITMP3, REG_ITMP3);
692 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
693 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
696 /* XXX do we need nops here? */
698 emit_store_dst(jd, iptr, d);
701 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
702 /* sx.val.l = constant */
704 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
705 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
706 LCONST(REG_ITMP2, iptr->sx.val.l);
707 M_LMUL(s1, REG_ITMP2);
711 emit_store_dst(jd, iptr, d);
714 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
716 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
717 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
718 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
719 emit_arithmetic_check(cd, iptr, s2);
724 emit_store_dst(jd, iptr, d);
727 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
729 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
730 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
731 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
732 emit_arithmetic_check(cd, iptr, s2);
737 emit_store_dst(jd, iptr, d);
740 #if SIZEOF_VOID_P == 8
742 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
744 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
745 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
746 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
747 emit_arithmetic_check(cd, iptr, s2);
752 emit_store_dst(jd, iptr, d);
755 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
757 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
758 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
759 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
760 emit_arithmetic_check(cd, iptr, s2);
765 emit_store_dst(jd, iptr, d);
768 #else /* SIZEOF_VOID_P == 8 */
770 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
771 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
773 s1 = emit_load_s1(jd, iptr, REG_A0_A1_PACKED);
774 s2 = emit_load_s2(jd, iptr, REG_A2_A3_PACKED);
776 /* XXX TODO: only do this if arithmetic check is really done! */
777 M_OR(GET_HIGH_REG(s2), GET_LOW_REG(s2), REG_ITMP3);
778 emit_arithmetic_check(cd, iptr, REG_ITMP3);
780 M_LNGMOVE(s1, REG_A0_A1_PACKED);
781 M_LNGMOVE(s2, REG_A2_A3_PACKED);
783 bte = iptr->sx.s23.s3.bte;
784 disp = dseg_add_functionptr(cd, bte->fp);
785 M_ALD(REG_ITMP3, REG_PV, disp);
786 M_JSR(REG_RA, REG_ITMP3);
789 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
790 M_LNGMOVE(REG_RESULT_PACKED, d);
791 emit_store_dst(jd, iptr, d);
794 #endif /* SIZEOF_VOID_P == 8 */
796 case ICMD_IDIVPOW2: /* ..., 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 #if SIZEOF_VOID_P == 8
802 M_LSRA_IMM(s1, 63, REG_ITMP2);
803 M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
804 M_LADD(s1, REG_ITMP2, REG_ITMP2);
805 M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
807 M_ISRA_IMM(s1, 31, REG_ITMP2);
808 M_ISRL_IMM(REG_ITMP2, 32 - iptr->sx.val.i, REG_ITMP2);
809 M_IADD(s1, REG_ITMP2, REG_ITMP2);
810 M_ISRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
812 emit_store_dst(jd, iptr, d);
815 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
816 /* val.i = constant */
818 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
819 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
821 M_MOV(s1, REG_ITMP1);
824 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
825 M_AND_IMM(s1, iptr->sx.val.i, d);
828 M_ISUB(REG_ZERO, s1, d);
829 M_AND_IMM(d, iptr->sx.val.i, d);
832 ICONST(REG_ITMP2, iptr->sx.val.i);
833 M_AND(s1, REG_ITMP2, d);
836 M_ISUB(REG_ZERO, s1, d);
837 M_AND(d, REG_ITMP2, d);
839 M_ISUB(REG_ZERO, d, d);
840 emit_store_dst(jd, iptr, d);
843 #if SIZEOF_VOID_P == 8
845 case ICMD_LDIVPOW2: /* ..., value ==> ..., value << constant */
846 /* val.i = constant */
848 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
849 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
850 M_LSRA_IMM(s1, 63, REG_ITMP2);
851 M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
852 M_LADD(s1, REG_ITMP2, REG_ITMP2);
853 M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
854 emit_store_dst(jd, iptr, d);
857 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
858 /* val.l = constant */
860 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
861 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
863 M_MOV(s1, REG_ITMP1);
866 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
867 M_AND_IMM(s1, iptr->sx.val.l, d);
870 M_LSUB(REG_ZERO, s1, d);
871 M_AND_IMM(d, iptr->sx.val.l, d);
874 LCONST(REG_ITMP2, iptr->sx.val.l);
875 M_AND(s1, REG_ITMP2, d);
878 M_LSUB(REG_ZERO, s1, d);
879 M_AND(d, REG_ITMP2, d);
881 M_LSUB(REG_ZERO, d, d);
882 emit_store_dst(jd, iptr, d);
885 #endif /* SIZEOF_VOID_P == 8 */
887 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
889 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
890 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
891 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
893 emit_store_dst(jd, iptr, d);
896 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
897 /* sx.val.i = constant */
899 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
900 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
901 M_ISLL_IMM(s1, iptr->sx.val.i, d);
902 emit_store_dst(jd, iptr, d);
905 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
907 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
908 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
909 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
911 emit_store_dst(jd, iptr, d);
914 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
915 /* sx.val.i = constant */
917 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
918 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
919 M_ISRA_IMM(s1, iptr->sx.val.i, d);
920 emit_store_dst(jd, iptr, d);
923 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
925 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
926 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
927 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
929 emit_store_dst(jd, iptr, d);
932 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
933 /* sx.val.i = constant */
935 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
936 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
937 M_ISRL_IMM(s1, iptr->sx.val.i, d);
938 emit_store_dst(jd, iptr, d);
941 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
943 #if SIZEOF_VOID_P == 8
944 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
945 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
946 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
949 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
950 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
951 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
953 M_ISLL(s2, 26, REG_ITMP1);
954 M_BGEZ(REG_ITMP1, 3);
957 M_ISLL(GET_LOW_REG(s1), s2, GET_HIGH_REG(d));
959 M_MOV(REG_ZERO, GET_LOW_REG(d)); /* delay slot */
962 M_ISLL(GET_LOW_REG(s1), s2, GET_LOW_REG(d));
964 M_BEQZ(REG_ITMP1, 4);
965 M_ISLL(GET_HIGH_REG(s1), s2, GET_HIGH_REG(d)); /* delay slot */
967 M_ISUB(s2, REG_ZERO, REG_ITMP3);
968 M_ISRL(GET_LOW_REG(s1), REG_ITMP3, REG_ITMP3);
969 M_OR(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
972 M_ISLL(GET_LOW_REG(s1), s2, GET_LOW_REG(d));
975 emit_store_dst(jd, iptr, d);
978 #if SIZEOF_VOID_P == 8
980 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
981 /* sx.val.i = constant */
983 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
984 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
985 M_LSLL_IMM(s1, iptr->sx.val.i, d);
986 emit_store_dst(jd, iptr, d);
989 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
991 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
992 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
993 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
995 emit_store_dst(jd, iptr, d);
998 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
999 /* sx.val.i = constant */
1001 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1002 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1003 M_LSRA_IMM(s1, iptr->sx.val.i, d);
1004 emit_store_dst(jd, iptr, d);
1007 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1009 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1010 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1011 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1013 emit_store_dst(jd, iptr, d);
1016 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1017 /* sx.val.i = constant */
1019 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1020 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1021 M_LSRL_IMM(s1, iptr->sx.val.i, d);
1022 emit_store_dst(jd, iptr, d);
1025 #endif /* SIZEOF_VOID_P == 8 */
1027 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1029 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1030 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1031 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1033 emit_store_dst(jd, iptr, d);
1036 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1037 /* sx.val.i = constant */
1039 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1040 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1041 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1042 M_AND_IMM(s1, iptr->sx.val.i, d);
1044 ICONST(REG_ITMP2, iptr->sx.val.i);
1045 M_AND(s1, REG_ITMP2, d);
1047 emit_store_dst(jd, iptr, d);
1050 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1052 #if SIZEOF_VOID_P == 8
1053 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1054 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1055 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1058 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1059 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1060 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1061 M_AND(s1, s2, GET_LOW_REG(d));
1062 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1063 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1064 M_AND(s1, s2, GET_HIGH_REG(d));
1066 emit_store_dst(jd, iptr, d);
1069 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1070 /* sx.val.l = constant */
1072 #if SIZEOF_VOID_P == 8
1073 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1074 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1075 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1076 M_AND_IMM(s1, iptr->sx.val.l, d);
1078 LCONST(REG_ITMP2, iptr->sx.val.l);
1079 M_AND(s1, REG_ITMP2, d);
1082 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1083 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1084 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1085 M_AND_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1086 M_AND_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1089 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1090 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1091 M_AND(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1092 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1093 M_AND(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1096 emit_store_dst(jd, iptr, d);
1099 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1101 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1102 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1103 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1105 emit_store_dst(jd, iptr, d);
1108 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1109 /* sx.val.i = constant */
1111 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1112 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1113 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1114 M_OR_IMM(s1, iptr->sx.val.i, d);
1116 ICONST(REG_ITMP2, iptr->sx.val.i);
1117 M_OR(s1, REG_ITMP2, d);
1119 emit_store_dst(jd, iptr, d);
1122 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1124 #if SIZEOF_VOID_P == 8
1125 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1126 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1127 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1130 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1131 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1132 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1133 M_OR(s1, s2, GET_LOW_REG(d));
1134 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1135 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1136 M_OR(s1, s2, GET_HIGH_REG(d));
1138 emit_store_dst(jd, iptr, d);
1141 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1142 /* sx.val.l = constant */
1144 #if SIZEOF_VOID_P == 8
1145 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1146 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1147 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1148 M_OR_IMM(s1, iptr->sx.val.l, d);
1150 LCONST(REG_ITMP2, iptr->sx.val.l);
1151 M_OR(s1, REG_ITMP2, d);
1154 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1155 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1156 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1157 M_OR_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1158 M_OR_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1161 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1162 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1163 M_OR(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1164 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1165 M_OR(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1168 emit_store_dst(jd, iptr, d);
1171 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1173 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1174 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1175 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1177 emit_store_dst(jd, iptr, d);
1180 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1181 /* sx.val.i = constant */
1183 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1184 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1185 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1186 M_XOR_IMM(s1, iptr->sx.val.i, d);
1188 ICONST(REG_ITMP2, iptr->sx.val.i);
1189 M_XOR(s1, REG_ITMP2, d);
1191 emit_store_dst(jd, iptr, d);
1194 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1196 #if SIZEOF_VOID_P == 8
1197 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1198 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1199 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1202 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1203 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1204 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1205 M_XOR(s1, s2, GET_LOW_REG(d));
1206 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1207 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1208 M_XOR(s1, s2, GET_HIGH_REG(d));
1210 emit_store_dst(jd, iptr, d);
1213 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1214 /* sx.val.l = constant */
1216 #if SIZEOF_VOID_P == 8
1217 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1218 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1219 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1220 M_XOR_IMM(s1, iptr->sx.val.l, d);
1222 LCONST(REG_ITMP2, iptr->sx.val.l);
1223 M_XOR(s1, REG_ITMP2, d);
1226 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1227 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1228 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1229 M_XOR_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1230 M_XOR_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1233 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1234 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1235 M_XOR(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1236 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1237 M_XOR(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1240 emit_store_dst(jd, iptr, d);
1244 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1246 #if SIZEOF_VOID_P == 8
1247 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1248 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1249 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1250 M_CMPLT(s1, s2, REG_ITMP3);
1251 M_CMPLT(s2, s1, REG_ITMP1);
1252 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1254 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1255 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
1256 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1257 M_CMPLT(s1, s2, REG_ITMP3);
1258 M_CMPLT(s2, s1, REG_ITMP1);
1259 M_ISUB(REG_ITMP1, REG_ITMP3, d);
1260 emit_label_bnez(cd, BRANCH_LABEL_1, d);
1261 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1262 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1263 M_CMPULT(s1, s2, REG_ITMP3);
1264 M_CMPULT(s2, s1, REG_ITMP1);
1265 M_ISUB(REG_ITMP1, REG_ITMP3, d);
1266 emit_label(cd, BRANCH_LABEL_1);
1268 emit_store_dst(jd, iptr, d);
1272 /* floating operations ************************************************/
1274 case ICMD_FNEG: /* ..., value ==> ..., - value */
1276 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1277 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1279 emit_store_dst(jd, iptr, d);
1282 case ICMD_DNEG: /* ..., value ==> ..., - value */
1284 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1285 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1287 emit_store_dst(jd, iptr, d);
1290 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1292 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1293 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1294 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1296 emit_store_dst(jd, iptr, d);
1299 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1301 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1302 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1303 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1305 emit_store_dst(jd, iptr, d);
1308 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1310 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1311 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1312 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1314 emit_store_dst(jd, iptr, d);
1317 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1319 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1320 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1321 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1323 emit_store_dst(jd, iptr, d);
1326 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1328 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1329 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1330 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1332 emit_store_dst(jd, iptr, d);
1335 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1337 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1338 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1339 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1341 emit_store_dst(jd, iptr, d);
1344 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1346 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1347 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1348 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1350 emit_store_dst(jd, iptr, d);
1353 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1355 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1356 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1357 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1359 emit_store_dst(jd, iptr, d);
1363 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1365 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1366 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1367 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1368 M_FDIV(s1,s2, REG_FTMP3);
1369 M_FLOORFL(REG_FTMP3, REG_FTMP3);
1370 M_CVTLF(REG_FTMP3, REG_FTMP3);
1371 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1372 M_FSUB(s1, REG_FTMP3, d);
1373 emit_store_dst(jd, iptr, d);
1376 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1378 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1379 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1380 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1381 M_DDIV(s1,s2, REG_FTMP3);
1382 M_FLOORDL(REG_FTMP3, REG_FTMP3);
1383 M_CVTLD(REG_FTMP3, REG_FTMP3);
1384 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1385 M_DSUB(s1, REG_FTMP3, d);
1386 emit_store_dst(jd, iptr, d);
1390 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1392 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1393 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1396 emit_store_dst(jd, iptr, d);
1399 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1401 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1402 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1405 emit_store_dst(jd, iptr, d);
1409 /* XXX these do not work correctly */
1411 case ICMD_F2I: /* ..., (float) value ==> ..., (int) value */
1413 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1414 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1415 M_TRUNCFI(s1, REG_FTMP1);
1416 M_MOVDI(REG_FTMP1, d);
1418 emit_store_dst(jd, iptr, d);
1421 case ICMD_D2I: /* ..., (double) value ==> ..., (int) value */
1423 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1424 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1425 M_TRUNCDI(s1, REG_FTMP1);
1426 M_MOVDI(REG_FTMP1, d);
1428 emit_store_dst(jd, iptr, d);
1431 case ICMD_F2L: /* ..., (float) value ==> ..., (long) value */
1433 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1434 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1435 M_TRUNCFL(s1, REG_FTMP1);
1436 M_MOVDL(REG_FTMP1, d);
1438 emit_store_dst(jd, iptr, d);
1441 case ICMD_D2L: /* ..., (double) value ==> ..., (long) value */
1443 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1444 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1445 M_TRUNCDL(s1, REG_FTMP1);
1446 M_MOVDL(REG_FTMP1, d);
1448 emit_store_dst(jd, iptr, d);
1452 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1454 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1455 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1457 emit_store_dst(jd, iptr, d);
1460 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1462 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1463 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1465 emit_store_dst(jd, iptr, d);
1468 #if SUPPORT_FLOAT_CMP
1469 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1471 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1472 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1473 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1476 M_AADD_IMM(REG_ZERO, 1, d);
1480 M_ASUB_IMM(REG_ZERO, 1, d);
1481 M_CMOVT(REG_ZERO, d);
1482 emit_store_dst(jd, iptr, d);
1485 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1487 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1488 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1489 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1492 M_ASUB_IMM(REG_ZERO, 1, d);
1496 M_AADD_IMM(REG_ZERO, 1, d);
1497 M_CMOVT(REG_ZERO, d);
1498 emit_store_dst(jd, iptr, d);
1502 #if SUPPORT_DOUBLE_CMP
1503 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1505 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1506 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1507 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1510 M_AADD_IMM(REG_ZERO, 1, d);
1514 M_ASUB_IMM(REG_ZERO, 1, d);
1515 M_CMOVT(REG_ZERO, d);
1516 emit_store_dst(jd, iptr, d);
1519 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1521 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1522 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1523 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1526 M_ASUB_IMM(REG_ZERO, 1, d);
1530 M_AADD_IMM(REG_ZERO, 1, d);
1531 M_CMOVT(REG_ZERO, d);
1532 emit_store_dst(jd, iptr, d);
1537 /* memory operations **************************************************/
1539 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1541 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1542 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1543 /* implicit null-pointer check */
1544 M_ILD(d, s1, OFFSET(java_array_t, size));
1545 emit_store_dst(jd, iptr, d);
1548 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1550 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1551 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1552 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1553 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1554 M_AADD(s2, s1, REG_ITMP3);
1555 /* implicit null-pointer check */
1556 M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray_t, data[0]));
1557 emit_store_dst(jd, iptr, d);
1560 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1562 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1563 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1564 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1565 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1566 M_AADD(s2, s1, REG_ITMP3);
1567 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1568 /* implicit null-pointer check */
1569 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray_t, data[0]));
1570 emit_store_dst(jd, iptr, d);
1573 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1575 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1576 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1577 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1578 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1579 M_AADD(s2, s1, REG_ITMP3);
1580 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1581 /* implicit null-pointer check */
1582 M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray_t, data[0]));
1583 emit_store_dst(jd, iptr, d);
1586 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1588 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1589 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1590 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1591 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1592 M_ASLL_IMM(s2, 2, REG_ITMP3);
1593 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1594 /* implicit null-pointer check */
1595 M_ILD_INTERN(d, REG_ITMP3, OFFSET(java_intarray_t, data[0]));
1596 emit_store_dst(jd, iptr, d);
1599 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1601 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1602 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1603 #if SIZEOF_VOID_P == 8
1604 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1606 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1608 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1609 M_ASLL_IMM(s2, 3, REG_ITMP3);
1610 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1611 /* implicit null-pointer check */
1612 M_LLD_INTERN(d, REG_ITMP3, OFFSET(java_longarray_t, data[0]));
1613 emit_store_dst(jd, iptr, d);
1616 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1618 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1619 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1620 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1621 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1622 M_ASLL_IMM(s2, 2, REG_ITMP3);
1623 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1624 /* implicit null-pointer check */
1625 M_FLD_INTERN(d, REG_ITMP3, OFFSET(java_floatarray_t, data[0]));
1626 emit_store_dst(jd, iptr, d);
1629 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1631 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1632 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1633 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1634 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1635 M_ASLL_IMM(s2, 3, REG_ITMP3);
1636 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1637 /* implicit null-pointer check */
1638 M_DLD_INTERN(d, REG_ITMP3, OFFSET(java_doublearray_t, data[0]));
1639 emit_store_dst(jd, iptr, d);
1642 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1644 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1645 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1646 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1647 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1648 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1649 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1650 /* implicit null-pointer check */
1651 M_ALD_INTERN(d, REG_ITMP3, OFFSET(java_objectarray_t, data[0]));
1652 emit_store_dst(jd, iptr, d);
1656 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1658 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1659 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1660 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1661 M_AADD(s2, s1, REG_ITMP1);
1662 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1663 /* implicit null-pointer check */
1664 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1667 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1668 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1670 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1671 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1672 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1673 M_AADD(s2, s1, REG_ITMP1);
1674 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1675 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1676 /* implicit null-pointer check */
1677 M_SST(s3, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1680 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1682 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1683 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1684 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1685 M_ASLL_IMM(s2, 2, REG_ITMP2);
1686 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1687 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1688 /* implicit null-pointer check */
1689 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1692 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1694 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1695 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1696 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1697 M_ASLL_IMM(s2, 3, REG_ITMP2);
1698 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1699 #if SIZEOF_VOID_P == 8
1700 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1702 s3 = emit_load_s3(jd, iptr, REG_ITMP23_PACKED);
1704 /* implicit null-pointer check */
1705 M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1708 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1710 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1711 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1712 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1713 M_ASLL_IMM(s2, 2, REG_ITMP2);
1714 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1715 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1716 /* implicit null-pointer check */
1717 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray_t, data[0]));
1720 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
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_ASLL_IMM(s2, 3, REG_ITMP2);
1726 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1727 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1728 /* implicit null-pointer check */
1729 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray_t, data[0]));
1733 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1735 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1736 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1737 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1738 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1740 M_INTMOVE(s1, REG_A0);
1741 M_INTMOVE(s3, REG_A1);
1742 disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
1743 M_ALD(REG_ITMP3, REG_PV, disp);
1744 M_JSR(REG_RA, REG_ITMP3);
1746 emit_arraystore_check(cd, iptr);
1748 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1749 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1750 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1751 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1752 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1753 /* implicit null-pointer check */
1754 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1758 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1760 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1761 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1762 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1763 M_AADD(s2, s1, REG_ITMP1);
1764 /* implicit null-pointer check */
1765 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1768 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1769 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1771 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1772 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1773 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1774 M_AADD(s2, s1, REG_ITMP1);
1775 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1776 /* implicit null-pointer check */
1777 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1780 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1782 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1783 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1784 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1785 M_ASLL_IMM(s2, 2, REG_ITMP2);
1786 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1787 /* implicit null-pointer check */
1788 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1791 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1793 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1794 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1795 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1796 M_ASLL_IMM(s2, 3, REG_ITMP2);
1797 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1798 /* implicit null-pointer check */
1799 #if SIZEOF_VOID_P == 8
1800 M_LST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1802 M_LST_INTERN(PACK_REGS(REG_ZERO, REG_ZERO), REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1806 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1808 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1809 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1810 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1811 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1812 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1813 /* implicit null-pointer check */
1814 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1818 case ICMD_GETSTATIC: /* ... ==> ..., value */
1820 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1821 uf = iptr->sx.s23.s3.uf;
1822 fieldtype = uf->fieldref->parseddesc.fd->type;
1823 disp = dseg_add_unique_address(cd, uf);
1825 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1828 fi = iptr->sx.s23.s3.fmiref->p.field;
1829 fieldtype = fi->type;
1830 disp = dseg_add_address(cd, fi->value);
1832 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
1833 patcher_add_patch_ref(jd, PATCHER_initialize_class,
1837 M_ALD(REG_ITMP1, REG_PV, disp);
1839 switch (fieldtype) {
1841 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1842 M_ILD_INTERN(d, REG_ITMP1, 0);
1845 #if SIZEOF_VOID_P == 8
1846 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1848 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
1850 M_LLD_INTERN(d, REG_ITMP1, 0);
1853 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1854 M_ALD_INTERN(d, REG_ITMP1, 0);
1857 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1858 M_FLD_INTERN(d, REG_ITMP1, 0);
1861 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1862 M_DLD_INTERN(d, REG_ITMP1, 0);
1865 emit_store_dst(jd, iptr, d);
1868 case ICMD_PUTSTATIC: /* ..., value ==> ... */
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 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1892 M_IST_INTERN(s1, REG_ITMP1, 0);
1895 #if SIZEOF_VOID_P == 8
1896 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1898 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
1900 M_LST_INTERN(s1, REG_ITMP1, 0);
1903 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1904 M_AST_INTERN(s1, REG_ITMP1, 0);
1907 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1908 M_FST_INTERN(s1, REG_ITMP1, 0);
1911 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1912 M_DST_INTERN(s1, REG_ITMP1, 0);
1917 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1919 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1920 uf = iptr->sx.s23.s3.uf;
1921 fieldtype = uf->fieldref->parseddesc.fd->type;
1922 disp = dseg_add_unique_address(cd, uf);
1924 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1927 fi = iptr->sx.s23.s3.fmiref->p.field;
1928 fieldtype = fi->type;
1929 disp = dseg_add_address(cd, fi->value);
1931 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
1932 patcher_add_patch_ref(jd, PATCHER_initialize_class,
1936 M_ALD(REG_ITMP1, REG_PV, disp);
1938 switch (fieldtype) {
1940 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
1943 M_LST_INTERN(REG_ZERO, REG_ITMP1, 0);
1946 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
1949 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
1952 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
1958 case ICMD_GETFIELD: /* ... ==> ..., value */
1960 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1961 emit_nullpointer_check(cd, iptr, s1);
1963 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1964 uf = iptr->sx.s23.s3.uf;
1965 fieldtype = uf->fieldref->parseddesc.fd->type;
1968 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1971 fi = iptr->sx.s23.s3.fmiref->p.field;
1972 fieldtype = fi->type;
1976 switch (fieldtype) {
1978 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1982 #if SIZEOF_VOID_P == 8
1983 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1986 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
1987 M_LLD_GETFIELD(d, s1, disp);
1991 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1995 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1999 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2003 emit_store_dst(jd, iptr, d);
2006 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2008 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2009 emit_nullpointer_check(cd, iptr, s1);
2011 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2012 uf = iptr->sx.s23.s3.uf;
2013 fieldtype = uf->fieldref->parseddesc.fd->type;
2017 fi = iptr->sx.s23.s3.fmiref->p.field;
2018 fieldtype = fi->type;
2022 #if SIZEOF_VOID_P == 8
2023 if (IS_INT_LNG_TYPE(fieldtype))
2024 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2026 s2 = emit_load_s2(jd, iptr, REG_FTMP1);
2028 if (IS_INT_LNG_TYPE(fieldtype)) {
2029 if (IS_2_WORD_TYPE(fieldtype))
2030 s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
2032 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2035 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
2038 if (INSTRUCTION_IS_UNRESOLVED(iptr))
2039 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2041 switch (fieldtype) {
2043 M_IST(s2, s1, disp);
2046 M_LST(s2, s1, disp);
2049 M_AST(s2, s1, disp);
2052 M_FST(s2, s1, disp);
2055 M_DST(s2, s1, disp);
2060 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2062 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2063 emit_nullpointer_check(cd, iptr, s1);
2065 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2066 uf = iptr->sx.s23.s3.uf;
2067 fieldtype = uf->fieldref->parseddesc.fd->type;
2070 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2073 fi = iptr->sx.s23.s3.fmiref->p.field;
2074 fieldtype = fi->type;
2078 switch (fieldtype) {
2080 M_IST(REG_ZERO, s1, disp);
2083 M_LST(REG_ZERO, s1, disp);
2086 M_AST(REG_ZERO, s1, disp);
2089 M_FST(REG_ZERO, s1, disp);
2092 M_DST(REG_ZERO, s1, disp);
2098 /* branch operations **************************************************/
2100 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2102 // Some processor implementations seem to have a problem when using
2103 // the JALR instruction with (reg_dest == reg_src), so avoid that.
2104 disp = dseg_add_functionptr(cd, asm_handle_exception);
2105 M_ALD(REG_ITMP3, REG_PV, disp);
2106 M_JSR(REG_ITMP2_XPC, REG_ITMP3);
2108 M_NOP; /* nop ensures that XPC is less than the end */
2109 /* of basic block */
2112 case ICMD_IFEQ: /* ..., value ==> ... */
2114 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2115 ICONST(REG_ITMP2, iptr->sx.val.i);
2116 emit_beq(cd, iptr->dst.block, s1, REG_ITMP2);
2119 case ICMD_IFLT: /* ..., value ==> ... */
2121 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2122 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
2123 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2125 ICONST(REG_ITMP2, iptr->sx.val.i);
2126 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2128 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2131 case ICMD_IFLE: /* ..., value ==> ... */
2133 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2134 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2135 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2136 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2139 ICONST(REG_ITMP2, iptr->sx.val.i);
2140 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2141 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2145 case ICMD_IFNE: /* ..., value ==> ... */
2147 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2148 ICONST(REG_ITMP2, iptr->sx.val.i);
2149 emit_bne(cd, iptr->dst.block, s1, REG_ITMP2);
2152 case ICMD_IFGT: /* ..., value ==> ... */
2154 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2155 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2156 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2157 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2160 ICONST(REG_ITMP2, iptr->sx.val.i);
2161 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2162 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2166 case ICMD_IFGE: /* ..., value ==> ... */
2168 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2169 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
2170 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2172 ICONST(REG_ITMP2, iptr->sx.val.i);
2173 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2175 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2178 case ICMD_IF_LEQ: /* ..., value ==> ... */
2180 #if SIZEOF_VOID_P == 8
2181 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2182 if (iptr->sx.val.l == 0)
2183 emit_beqz(cd, iptr->dst.block, s1);
2185 LCONST(REG_ITMP2, iptr->sx.val.l);
2186 emit_beq(cd, iptr->dst.block, s1, REG_ITMP2);
2189 if (iptr->sx.val.l == 0) {
2190 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2191 M_OR(GET_LOW_REG(s1), GET_HIGH_REG(s1), REG_ITMP3);
2192 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2195 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2196 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2197 M_XOR(s1, REG_ITMP2, REG_ITMP2);
2198 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2199 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2200 M_XOR(s1, REG_ITMP3, REG_ITMP3);
2201 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2202 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2207 case ICMD_IF_LLT: /* ..., value ==> ... */
2209 #if SIZEOF_VOID_P == 8
2210 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2211 if (iptr->sx.val.l == 0)
2212 emit_bltz(cd, iptr->dst.block, s1);
2214 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767))
2215 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP3);
2217 LCONST(REG_ITMP2, iptr->sx.val.l);
2218 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2220 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2223 if (iptr->sx.val.l == 0) {
2224 /* if high word is less than zero, the whole long is too */
2225 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2226 emit_bltz(cd, iptr->dst.block, s1);
2229 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2230 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2231 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2232 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2233 emit_label_bne(cd, BRANCH_LABEL_1, s1, REG_ITMP2);
2234 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2235 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2236 M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
2237 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2238 emit_label(cd, BRANCH_LABEL_1);
2243 case ICMD_IF_LLE: /* ..., value ==> ... */
2245 #if SIZEOF_VOID_P == 8
2246 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2247 if (iptr->sx.val.l == 0)
2248 emit_blez(cd, iptr->dst.block, s1);
2250 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2251 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP2);
2252 emit_bnez(cd, iptr->dst.block, REG_ITMP2);
2255 LCONST(REG_ITMP2, iptr->sx.val.l);
2256 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2257 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2261 if (iptr->sx.val.l == 0) {
2262 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2263 emit_label_bgtz(cd, BRANCH_LABEL_1, GET_HIGH_REG(s1));
2264 emit_bltz(cd, iptr->dst.block, GET_HIGH_REG(s1));
2265 emit_beqz(cd, iptr->dst.block, GET_LOW_REG(s1));
2266 emit_label(cd, BRANCH_LABEL_1);
2269 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2270 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2271 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2272 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2273 emit_label_bne(cd, BRANCH_LABEL_1, s1, REG_ITMP2);
2274 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2275 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2276 M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
2277 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2278 emit_label(cd, BRANCH_LABEL_1);
2283 case ICMD_IF_LNE: /* ..., value ==> ... */
2285 #if SIZEOF_VOID_P == 8
2286 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2287 if (iptr->sx.val.l == 0)
2288 emit_bnez(cd, iptr->dst.block, s1);
2290 LCONST(REG_ITMP2, iptr->sx.val.l);
2291 emit_bne(cd, iptr->dst.block, s1, REG_ITMP2);
2294 if (iptr->sx.val.l == 0) {
2295 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2296 M_OR(GET_LOW_REG(s1), GET_HIGH_REG(s1), REG_ITMP3);
2297 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2300 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2301 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2302 M_XOR(s1, REG_ITMP2, REG_ITMP2);
2303 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2304 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2305 M_XOR(s1, REG_ITMP3, REG_ITMP3);
2306 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2307 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2312 case ICMD_IF_LGT: /* ..., value ==> ... */
2314 #if SIZEOF_VOID_P == 8
2315 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2316 if (iptr->sx.val.l == 0)
2317 emit_bgtz(cd, iptr->dst.block, s1);
2319 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2320 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP2);
2321 emit_beqz(cd, iptr->dst.block, REG_ITMP2);
2324 LCONST(REG_ITMP2, iptr->sx.val.l);
2325 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2326 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2330 if (iptr->sx.val.l == 0) {
2331 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2332 emit_bgtz(cd, iptr->dst.block, GET_HIGH_REG(s1));
2333 emit_label_bltz(cd, BRANCH_LABEL_1, GET_HIGH_REG(s1));
2334 emit_bnez(cd, iptr->dst.block, GET_LOW_REG(s1));
2335 emit_label(cd, BRANCH_LABEL_1);
2338 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2339 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2340 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2341 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2342 emit_label_bne(cd, BRANCH_LABEL_1, s1, REG_ITMP2);
2343 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2344 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2345 M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
2346 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2347 emit_label(cd, BRANCH_LABEL_1);
2352 case ICMD_IF_LGE: /* ..., value ==> ... */
2354 #if SIZEOF_VOID_P == 8
2355 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2356 if (iptr->sx.val.l == 0)
2357 emit_bgez(cd, iptr->dst.block, s1);
2359 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
2360 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP3);
2363 LCONST(REG_ITMP2, iptr->sx.val.l);
2364 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2366 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2369 if (iptr->sx.val.l == 0) {
2370 /* if high word is greater equal zero, the whole long is too */
2371 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2372 emit_bgez(cd, iptr->dst.block, s1);
2375 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2376 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2377 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2378 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2379 emit_label_bne(cd, BRANCH_LABEL_1, s1, REG_ITMP2);
2380 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2381 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2382 M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
2383 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2384 emit_label(cd, BRANCH_LABEL_1);
2389 #if SIZEOF_VOID_P == 8
2390 case ICMD_IF_LCMPEQ:
2393 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2394 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2395 emit_beq(cd, iptr->dst.block, s1, s2);
2398 #if SIZEOF_VOID_P == 4
2399 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2400 /* op1 = target JavaVM pc */
2402 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2403 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2404 emit_label_bne(cd, BRANCH_LABEL_1, s1, s2);
2405 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2406 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2407 emit_beq(cd, iptr->dst.block, s1, s2);
2408 emit_label(cd, BRANCH_LABEL_1);
2412 #if SIZEOF_VOID_P == 8
2413 case ICMD_IF_LCMPNE:
2416 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2417 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2418 emit_bne(cd, iptr->dst.block, s1, s2);
2421 #if SIZEOF_VOID_P == 4
2422 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
2424 /* TODO: could be optimized (XOR or SUB) */
2425 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2426 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2427 emit_bne(cd, iptr->dst.block, s1, s2);
2428 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2429 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2430 emit_bne(cd, iptr->dst.block, s1, s2);
2434 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2435 #if SIZEOF_VOID_P == 8
2436 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2439 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2440 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2441 M_CMPLT(s1, s2, REG_ITMP3);
2442 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2445 #if SIZEOF_VOID_P == 4
2446 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2448 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2449 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2450 M_CMPLT(s1, s2, REG_ITMP3);
2451 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2452 M_CMPGT(s1, s2, REG_ITMP3);
2453 emit_label_bnez(cd, BRANCH_LABEL_1, REG_ITMP3);
2454 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2455 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2456 M_CMPULT(s1, s2, REG_ITMP3);
2457 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2458 emit_label(cd, BRANCH_LABEL_1);
2462 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2463 #if SIZEOF_VOID_P == 8
2464 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2467 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2468 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2469 M_CMPGT(s1, s2, REG_ITMP3);
2470 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2473 #if SIZEOF_VOID_P == 4
2474 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2476 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2477 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2478 M_CMPGT(s1, s2, REG_ITMP3);
2479 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2480 M_CMPLT(s1, s2, REG_ITMP3);
2481 emit_label_bnez(cd, BRANCH_LABEL_1, REG_ITMP3);
2482 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2483 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2484 M_CMPUGT(s1, s2, REG_ITMP3);
2485 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2486 emit_label(cd, BRANCH_LABEL_1);
2490 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2491 #if SIZEOF_VOID_P == 8
2492 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2495 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2496 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2497 M_CMPGT(s1, s2, REG_ITMP3);
2498 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2501 #if SIZEOF_VOID_P == 4
2502 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2504 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2505 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2506 M_CMPLT(s1, s2, REG_ITMP3);
2507 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2508 M_CMPGT(s1, s2, REG_ITMP3);
2509 emit_label_bnez(cd, BRANCH_LABEL_1, REG_ITMP3);
2510 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2511 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2512 M_CMPUGT(s1, s2, REG_ITMP3);
2513 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2514 emit_label(cd, BRANCH_LABEL_1);
2518 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2519 #if SIZEOF_VOID_P == 8
2520 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2523 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2524 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2525 M_CMPLT(s1, s2, REG_ITMP3);
2526 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2529 #if SIZEOF_VOID_P == 4
2530 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2532 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2533 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2534 M_CMPGT(s1, s2, REG_ITMP3);
2535 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2536 M_CMPLT(s1, s2, REG_ITMP3);
2537 emit_label_bnez(cd, BRANCH_LABEL_1, REG_ITMP3);
2538 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2539 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2540 M_CMPULT(s1, s2, REG_ITMP3);
2541 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2542 emit_label(cd, BRANCH_LABEL_1);
2546 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2549 branch_target_t *table;
2551 table = iptr->dst.table;
2553 l = iptr->sx.s23.s2.tablelow;
2554 i = iptr->sx.s23.s3.tablehigh;
2556 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2558 {M_INTMOVE(s1, REG_ITMP1);}
2559 else if (l <= 32768) {
2560 M_IADD_IMM(s1, -l, REG_ITMP1);
2563 ICONST(REG_ITMP2, l);
2564 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2567 /* number of targets */
2572 M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
2573 emit_beqz(cd, table[0].block, REG_ITMP2);
2575 /* build jump table top down and use address of lowest entry */
2580 dseg_add_target(cd, table->block);
2585 /* length of dataseg after last dseg_add_target is used by load */
2587 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);
2588 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2589 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2596 bte = iptr->sx.s23.s3.bte;
2597 if (bte->stub == NULL) {
2598 disp = dseg_add_functionptr(cd, bte->fp);
2599 M_ALD(REG_ITMP3, REG_PV, disp); /* built-in-function pointer */
2601 /* generate the actual call */
2603 /* TWISTI: i actually don't know the reason for using
2604 REG_ITMP3 here instead of REG_PV. */
2606 M_JSR(REG_RA, REG_ITMP3);
2610 disp = dseg_add_functionptr(cd, bte->stub);
2611 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
2613 /* generate the actual call */
2615 M_JSR(REG_RA, REG_PV);
2620 case ICMD_INVOKESPECIAL:
2621 emit_nullpointer_check(cd, iptr, REG_A0);
2624 case ICMD_INVOKESTATIC:
2625 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2626 um = iptr->sx.s23.s3.um;
2627 disp = dseg_add_unique_address(cd, um);
2629 patcher_add_patch_ref(jd, PATCHER_invokestatic_special, um,
2633 lm = iptr->sx.s23.s3.fmiref->p.method;
2634 disp = dseg_add_address(cd, lm->stubroutine);
2637 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
2639 /* generate the actual call */
2641 M_JSR(REG_RA, REG_PV);
2645 case ICMD_INVOKEVIRTUAL:
2646 emit_nullpointer_check(cd, iptr, REG_A0);
2648 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2649 um = iptr->sx.s23.s3.um;
2650 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
2655 lm = iptr->sx.s23.s3.fmiref->p.method;
2656 s1 = OFFSET(vftbl_t, table[0]) +
2657 sizeof(methodptr) * lm->vftblindex;
2660 /* implicit null-pointer check */
2661 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2662 M_ALD(REG_PV, REG_METHODPTR, s1);
2664 /* generate the actual call */
2666 M_JSR(REG_RA, REG_PV);
2670 case ICMD_INVOKEINTERFACE:
2671 emit_nullpointer_check(cd, iptr, REG_A0);
2673 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2674 um = iptr->sx.s23.s3.um;
2675 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
2681 lm = iptr->sx.s23.s3.fmiref->p.method;
2682 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2683 sizeof(methodptr*) * lm->clazz->index;
2685 s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
2688 /* implicit null-pointer check */
2689 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2690 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2691 M_ALD(REG_PV, REG_METHODPTR, s2);
2693 /* generate the actual call */
2695 M_JSR(REG_RA, REG_PV);
2703 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2704 if (IS_2_WORD_TYPE(d))
2705 M_DMOV(REG_FRESULT, s1);
2707 M_FMOV(REG_FRESULT, s1);
2709 emit_store_dst(jd, iptr, s1);
2714 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2716 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2720 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2725 super = iptr->sx.s23.s3.c.cls;
2726 superindex = super->index;
2729 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2731 /* if class is not resolved, check which code to call */
2733 if (super == NULL) {
2734 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2736 constant_classref *cr = iptr->sx.s23.s3.c.ref;
2737 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2739 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
2742 M_ILD(REG_ITMP2, REG_PV, disp);
2743 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
2744 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
2747 /* interface checkcast code */
2749 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2750 if (super == NULL) {
2751 constant_classref *cr = iptr->sx.s23.s3.c.ref;
2753 patcher_add_patch_ref(jd, PATCHER_checkcast_interface,
2757 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2760 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2761 M_ILD(REG_ITMP3, REG_ITMP2,
2762 OFFSET(vftbl_t, interfacetablelength));
2763 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
2764 emit_classcast_check(cd, iptr, ICMD_IFLE, REG_ITMP3, s1);
2766 M_ALD(REG_ITMP3, REG_ITMP2,
2767 OFFSET(vftbl_t, interfacetable[0]) -
2768 superindex * sizeof(methodptr*));
2769 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_ITMP3, s1);
2772 emit_label_br(cd, BRANCH_LABEL_4);
2774 emit_label(cd, BRANCH_LABEL_3);
2777 /* class checkcast code */
2779 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2780 if (super == NULL) {
2781 emit_label(cd, BRANCH_LABEL_2);
2783 constant_classref *cr = iptr->sx.s23.s3.c.ref;
2784 disp = dseg_add_unique_address(cd, NULL);
2786 patcher_add_patch_ref(jd,
2787 PATCHER_resolve_classref_to_vftbl,
2791 disp = dseg_add_address(cd, super->vftbl);
2793 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2796 // The following code checks whether object s is a subtype of class t.
2797 // Represents the following semantic:
2798 // if (!fast_subtype_check(s->vftbl, t->vftbl)) throw;
2800 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2801 M_ALD(REG_ITMP3, REG_PV, disp);
2803 if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
2804 // Represents the following semantic:
2805 // if (*(s->vftbl + t->vftbl->subtype_offset) == t->vftbl) good;
2807 // REG_ITMP2==s->vftbl; REG_ITMP3==t->vftbl;
2808 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
2809 M_AADD(REG_ITMP1, REG_ITMP2, REG_ITMP1);
2810 M_ALD(REG_ITMP1, REG_ITMP1, 0);
2811 emit_label_beq(cd, BRANCH_LABEL_6, REG_ITMP1, REG_ITMP3); /* good */
2813 // Represents the following semantic:
2814 // if (t->vftbl->subtype_offset != OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE])) throw;
2816 // REG_ITMP3==t->vftbl;
2817 if (super == NULL) {
2818 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
2819 M_ISUB_IMM(REG_ITMP1, OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]), REG_ITMP1);
2820 emit_label_bnez(cd, BRANCH_LABEL_9, REG_ITMP1); /* throw */
2823 // Represents the following semantic:
2824 // if (s->vftbl->subtype_depth < t->vftbl->subtype_depth) throw;
2826 // REG_ITMP2==s->vftbl; REG_ITMP3==t->vftbl;
2827 M_ILD(REG_ITMP1, REG_ITMP2, OFFSET(vftbl_t, subtype_depth));
2828 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, subtype_depth));
2829 M_CMPULT(REG_ITMP1, REG_ITMP3, REG_ITMP1);
2830 emit_label_bnez(cd, BRANCH_LABEL_8, REG_ITMP1); /* throw */
2832 // Represents the following semantic:
2833 // if (s->vftbl->subtype_overflow[t->vftbl->subtype_depth - DISPLAY_SIZE] != t->vftbl) throw;
2835 // REG_ITMP2==s->vftbl; REG_ITMP3==t->vftbl->subtype_depth;
2836 M_ALD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow));
2837 M_ASLL_IMM(REG_ITMP3, POINTERSHIFT, REG_ITMP3);
2838 M_AADD(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2839 M_ALD(REG_ITMP2, REG_ITMP2, -DISPLAY_SIZE * SIZEOF_VOID_P);
2840 M_ALD(REG_ITMP3, REG_PV, disp); /* reload REG_ITMP3, was destroyed */
2841 emit_label_beq(cd, BRANCH_LABEL_7, REG_ITMP2, REG_ITMP3); /* good */
2844 emit_label(cd, BRANCH_LABEL_8);
2846 emit_label(cd, BRANCH_LABEL_9);
2847 emit_load_s1(jd, iptr, REG_ITMP1); /* reload s1, might have been destroyed */
2848 M_ALD_INTERN(s1, REG_ZERO, TRAP_ClassCastException);
2851 emit_label(cd, BRANCH_LABEL_7);
2852 emit_label(cd, BRANCH_LABEL_6);
2853 emit_load_s1(jd, iptr, REG_ITMP1); /* reload s1, might have been destroyed */
2856 // Represents the following semantic:
2857 // if (*(s->vftbl + t->vftbl->subtype_offset) != t->vftbl) throw;
2859 // REG_ITMP2==s->vftbl; REG_ITMP3==t->vftbl;
2860 M_ALD(REG_ITMP2, REG_ITMP2, super->vftbl->subtype_offset);
2861 M_BEQ(REG_ITMP2, REG_ITMP3, 2);
2862 M_NOP; /* delay slot */
2863 M_ALD_INTERN(s1, REG_ZERO, TRAP_ClassCastException);
2867 emit_label(cd, BRANCH_LABEL_5);
2870 if (super == NULL) {
2871 emit_label(cd, BRANCH_LABEL_1);
2872 emit_label(cd, BRANCH_LABEL_4);
2875 d = codegen_reg_of_dst(jd, iptr, s1);
2878 s1 = emit_load_s1(jd, iptr, REG_A0);
2879 M_INTMOVE(s1, REG_A0);
2881 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2882 constant_classref *cr = iptr->sx.s23.s3.c.ref;
2883 disp = dseg_add_unique_address(cd, NULL);
2885 patcher_add_patch_ref(jd,
2886 PATCHER_resolve_classref_to_classinfo,
2890 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2893 M_ALD(REG_A1, REG_PV, disp);
2894 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
2895 M_ALD(REG_ITMP3, REG_PV, disp);
2896 M_JSR(REG_RA, REG_ITMP3);
2899 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2900 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT, s1);
2902 d = codegen_reg_of_dst(jd, iptr, s1);
2906 emit_store_dst(jd, iptr, d);
2909 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2915 super = iptr->sx.s23.s3.c.cls;
2917 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2922 super = iptr->sx.s23.s3.c.cls;
2923 superindex = super->index;
2926 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2927 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2930 M_MOV(s1, REG_ITMP1);
2936 /* if class is not resolved, check which code to call */
2938 if (super == NULL) {
2939 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2941 constant_classref *cr = iptr->sx.s23.s3.c.ref;
2942 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2944 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
2947 M_ILD(REG_ITMP3, REG_PV, disp);
2948 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
2949 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
2952 /* interface instanceof code */
2954 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2955 if (super == NULL) {
2956 constant_classref * iptr->sx.s23.s3.c.ref;
2958 patcher_add_patch_ref(jd, PATCHER_instanceof_interface,
2962 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2965 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2966 M_ILD(REG_ITMP3, REG_ITMP1,
2967 OFFSET(vftbl_t, interfacetablelength));
2968 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
2969 M_BLEZ(REG_ITMP3, 3);
2971 M_ALD(REG_ITMP1, REG_ITMP1,
2972 OFFSET(vftbl_t, interfacetable[0]) -
2973 superindex * sizeof(methodptr*));
2974 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
2977 emit_label_br(cd, BRANCH_LABEL_4);
2979 emit_label(cd, BRANCH_LABEL_3);
2982 /* class instanceof code */
2984 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2985 if (super == NULL) {
2986 emit_label(cd, BRANCH_LABEL_2);
2988 constant_classref *cr = iptr->sx.s23.s3.c.ref;
2989 disp = dseg_add_unique_address(cd, NULL);
2991 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl,
2995 disp = dseg_add_address(cd, super->vftbl);
2997 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
3000 // The following code checks whether object s is a subtype of class t.
3001 // Represents the following semantic:
3002 // fast_subtype_check(s->vftbl, t->vftbl));
3004 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
3005 M_ALD(REG_ITMP3, REG_PV, disp);
3007 if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
3008 // Represents the following semantic:
3009 // if (*(s->vftbl + t->vftbl->subtype_offset) == t->vftbl) true;
3011 // REG_ITMP1==s->vftbl; REG_ITMP3==t->vftbl;
3012 M_ILD(REG_ITMP2, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
3013 M_AADD(REG_ITMP2, REG_ITMP1, REG_ITMP2);
3014 M_ALD(REG_ITMP2, REG_ITMP2, 0);
3015 emit_label_beq(cd, BRANCH_LABEL_6, REG_ITMP2, REG_ITMP3); /* true */
3017 // Represents the following semantic:
3018 // if (t->vftbl->subtype_offset != OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE])) false;
3020 // REG_ITMP3==t->vftbl;
3021 if (super == NULL) {
3022 M_ILD(REG_ITMP2, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
3023 M_ISUB_IMM(REG_ITMP2, OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]), REG_ITMP2);
3024 emit_label_bnez(cd, BRANCH_LABEL_9, REG_ITMP2); /* false */
3027 // Represents the following semantic:
3028 // if (s->vftbl->subtype_depth < t->vftbl->subtype_depth) false;
3030 // REG_ITMP1==s->vftbl; REG_ITMP3==t->vftbl;
3031 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl_t, subtype_depth));
3032 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, subtype_depth));
3033 M_CMPULT(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3034 emit_label_bnez(cd, BRANCH_LABEL_8, REG_ITMP2); /* false */
3036 // Represents the following semantic:
3037 // if (s->vftbl->subtype_overflow[t->vftbl->subtype_depth - DISPLAY_SIZE] != t->vftbl) false;
3039 // REG_ITMP1==s->vftbl; REG_ITMP3==t->vftbl->subtype_depth;
3040 M_ALD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, subtype_overflow));
3041 M_ASLL_IMM(REG_ITMP3, POINTERSHIFT, REG_ITMP3);
3042 M_AADD(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3043 M_ALD(REG_ITMP1, REG_ITMP1, -DISPLAY_SIZE * SIZEOF_VOID_P);
3044 M_ALD(REG_ITMP3, REG_PV, disp); /* reload REG_ITMP3, was destroyed */
3045 emit_label_bne(cd, BRANCH_LABEL_7, REG_ITMP1, REG_ITMP3); /* false */
3048 emit_label(cd, BRANCH_LABEL_6);
3050 if (d == REG_ITMP2) {
3051 M_BR(2); /* branch over M_CLR */
3052 M_NOP; /* delay slot */
3055 // False (fall-through) case
3056 emit_label(cd, BRANCH_LABEL_7);
3057 emit_label(cd, BRANCH_LABEL_8);
3059 emit_label(cd, BRANCH_LABEL_9);
3061 M_CLR(d); /* if d == REG_ITMP2, it was destroyed */
3064 // Represents the following semantic:
3065 // *(s->vftbl + t->vftbl->subtype_offset) == t->vftbl;
3067 // REG_ITMP1==s->vftbl; REG_ITMP3==t->vftbl;
3068 M_ALD(REG_ITMP1, REG_ITMP1, super->vftbl->subtype_offset);
3069 M_XOR(REG_ITMP1, REG_ITMP3, d);
3070 M_CMPULT_IMM(d, 1, d);
3074 emit_label(cd, BRANCH_LABEL_5);
3077 if (super == NULL) {
3078 emit_label(cd, BRANCH_LABEL_1);
3079 emit_label(cd, BRANCH_LABEL_4);
3082 emit_store_dst(jd, iptr, d);
3086 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3088 /* check for negative sizes and copy sizes to stack if necessary */
3090 MCODECHECK((iptr->s1.argcount << 1) + 64);
3092 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3094 var = VAR(iptr->sx.s23.s2.args[s1]);
3096 /* copy SAVEDVAR sizes to stack */
3098 if (!(var->flags & PREALLOC)) {
3099 s2 = emit_load(jd, iptr, var, REG_ITMP1);
3100 #if SIZEOF_VOID_P == 8
3101 M_LST(s2, REG_SP, s1 * 8);
3103 M_IST(s2, REG_SP, (s1 + 2) * 8);
3108 /* a0 = dimension count */
3110 ICONST(REG_A0, iptr->s1.argcount);
3112 /* is patcher function set? */
3114 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3115 constant_classref *cr = iptr->sx.s23.s3.c.ref;
3116 disp = dseg_add_unique_address(cd, NULL);
3118 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
3122 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3125 /* a1 = arraydescriptor */
3127 M_ALD(REG_A1, REG_PV, disp);
3129 /* a2 = pointer to dimensions = stack pointer */
3131 #if SIZEOF_VOID_P == 8
3132 M_MOV(REG_SP, REG_A2);
3134 M_AADD_IMM(REG_SP, 4*4, REG_A2);
3137 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3138 M_ALD(REG_ITMP3, REG_PV, disp);
3139 M_JSR(REG_RA, REG_ITMP3);
3142 /* check for exception before result assignment */
3144 emit_exception_check(cd, iptr);
3146 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3147 M_INTMOVE(REG_RESULT, d);
3148 emit_store_dst(jd, iptr, d);
3152 vm_abort("Unknown ICMD %d during code generation", iptr->opc);
3157 /* codegen_emit_stub_native ****************************************************
3159 Emits a stub routine which calls a native method.
3161 *******************************************************************************/
3163 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
3174 /* get required compiler data */
3180 /* initialize variables */
3184 /* calculate stack frame size */
3186 cd->stackframesize =
3187 1 + /* return address */
3188 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
3189 sizeof(localref_table) / SIZEOF_VOID_P +
3190 md->paramcount + /* for saving arguments over calls */
3191 #if SIZEOF_VOID_P == 4
3192 5 + /* additional save space (MIPS32) */
3194 1 + /* for saving return address */
3197 /* adjust stackframe size for 16-byte alignment */
3199 if (cd->stackframesize & 1)
3200 cd->stackframesize++;
3202 /* create method header */
3204 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3205 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3206 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3207 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3208 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3210 /* generate stub code */
3212 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8); /* build up stackframe */
3213 M_AST(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* store RA */
3215 /* save integer and float argument registers */
3217 #if SIZEOF_VOID_P == 8
3218 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3219 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3220 s1 = md->params[i].regoff;
3221 M_AST(s1, REG_SP, j * 8);
3226 for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3227 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3228 if (!md->params[i].inmemory) {
3229 s1 = md->params[i].regoff;
3231 if (IS_2_WORD_TYPE(md->params[i].type))
3232 M_LST(s1, REG_SP, j * 8);
3234 M_IST(s1, REG_SP, j * 8);
3242 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3243 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3244 s1 = md->params[i].regoff;
3246 if (IS_2_WORD_TYPE(md->params[i].type))
3247 M_DST(s1, REG_SP, j * 8);
3249 M_FST(s1, REG_SP, j * 8);
3255 /* prepare data structures for native function call */
3257 M_MOV(REG_SP, REG_A0);
3258 M_MOV(REG_PV, REG_A1);
3259 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3260 M_ALD(REG_ITMP3, REG_PV, disp);
3261 M_JSR(REG_RA, REG_ITMP3);
3262 M_NOP; /* XXX fill me! */
3264 /* remember class argument */
3266 if (m->flags & ACC_STATIC)
3267 M_MOV(REG_RESULT, REG_ITMP3);
3269 /* restore integer and float argument registers */
3271 #if SIZEOF_VOID_P == 8
3272 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3273 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3274 s1 = md->params[i].regoff;
3275 M_LLD(s1, REG_SP, j * 8);
3280 for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3281 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3282 if (!md->params[i].inmemory) {
3283 s1 = md->params[i].regoff;
3285 if (IS_2_WORD_TYPE(md->params[i].type))
3286 M_LLD(s1, REG_SP, j * 8);
3288 M_ILD(s1, REG_SP, j * 8);
3296 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3297 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3298 s1 = md->params[i].regoff;
3300 if (IS_2_WORD_TYPE(md->params[i].type))
3301 M_DLD(s1, REG_SP, j * 8);
3303 M_FLD(s1, REG_SP, j * 8);
3309 /* copy or spill arguments to new locations */
3311 for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
3312 t = md->params[i].type;
3314 if (IS_INT_LNG_TYPE(t)) {
3315 if (!md->params[i].inmemory) {
3316 s1 = md->params[i].regoff;
3317 s2 = nmd->params[j].regoff;
3319 if (!nmd->params[j].inmemory) {
3320 #if SIZEOF_VOID_P == 8
3323 if (IS_2_WORD_TYPE(t))
3330 #if SIZEOF_VOID_P == 8
3331 M_LST(s1, REG_SP, s2);
3333 if (IS_2_WORD_TYPE(t))
3334 M_LST(s1, REG_SP, s2);
3336 M_IST(s1, REG_SP, s2);
3341 s1 = md->params[i].regoff + cd->stackframesize * 8;
3342 s2 = nmd->params[j].regoff;
3344 #if SIZEOF_VOID_P == 8
3345 M_LLD(REG_ITMP1, REG_SP, s1);
3346 M_LST(REG_ITMP1, REG_SP, s2);
3348 if (IS_2_WORD_TYPE(t)) {
3349 M_LLD(REG_ITMP12_PACKED, REG_SP, s1);
3350 M_LST(REG_ITMP12_PACKED, REG_SP, s2);
3353 M_ILD(REG_ITMP1, REG_SP, s1);
3354 M_IST(REG_ITMP1, REG_SP, s2);
3360 if (!md->params[i].inmemory) {
3361 s1 = md->params[i].regoff;
3362 s2 = nmd->params[j].regoff;
3364 if (!nmd->params[j].inmemory) {
3365 #if SIZEOF_VOID_P == 8
3366 if (IS_2_WORD_TYPE(t))
3371 /* On MIPS32 float arguments for native functions
3372 can never be in float argument registers, since
3373 the first argument is _always_ an integer
3374 argument (JNIEnv) */
3376 if (IS_2_WORD_TYPE(t)) {
3377 /* double high/low order is endian
3378 independent: even numbered holds low
3379 32-bits, odd numbered high 32-bits */
3381 M_MFC1(GET_LOW_REG(s2), s1); /* low 32-bits */
3382 M_MFC1(GET_HIGH_REG(s2), s1 + 1); /* high 32-bits */
3389 #if SIZEOF_VOID_P == 8
3390 if (IS_2_WORD_TYPE(t))
3391 M_DST(s1, REG_SP, s2);
3393 M_FST(s1, REG_SP, s2);
3395 /* s1 may have been originally in 2 int registers,
3396 but was moved out by the native function
3397 argument(s), just get low register */
3399 if (IS_2_WORD_TYPE(t))
3400 M_DST(GET_LOW_REG(s1), REG_SP, s2);
3402 M_FST(GET_LOW_REG(s1), REG_SP, s2);
3407 s1 = md->params[i].regoff + cd->stackframesize * 8;
3408 s2 = nmd->params[j].regoff;
3410 #if SIZEOF_VOID_P == 8
3411 if (IS_2_WORD_TYPE(t)) {
3412 M_DLD(REG_FTMP1, REG_SP, s1);
3413 M_DST(REG_FTMP1, REG_SP, s2);
3416 M_FLD(REG_FTMP1, REG_SP, s1);
3417 M_FST(REG_FTMP1, REG_SP, s2);
3420 if (IS_2_WORD_TYPE(t)) {
3421 M_DLD(REG_FTMP1, REG_SP, s1);
3422 M_DST(REG_FTMP1, REG_SP, s2);
3425 M_FLD(REG_FTMP1, REG_SP, s1);
3426 M_FST(REG_FTMP1, REG_SP, s2);
3433 /* Handle native Java methods. */
3435 if (m->flags & ACC_NATIVE) {
3436 /* put class into second argument register */
3438 if (m->flags & ACC_STATIC)
3439 M_MOV(REG_ITMP3, REG_A1);
3441 /* put env into first argument register */
3443 disp = dseg_add_address(cd, VM_get_jnienv());
3444 M_ALD(REG_A0, REG_PV, disp);
3447 /* Call the native function. */
3449 disp = dseg_add_functionptr(cd, f);
3450 M_ALD(REG_ITMP3, REG_PV, disp); /* load adress of native method */
3451 M_JSR(REG_RA, REG_ITMP3); /* call native method */
3452 M_NOP; /* delay slot */
3454 /* save return value */
3456 switch (md->returntype.type) {
3457 #if SIZEOF_VOID_P == 8
3461 M_LST(REG_RESULT, REG_SP, 0 * 8);
3465 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3470 M_IST(REG_RESULT, REG_SP, 2*4 + 0 * 8);
3473 M_LST(REG_RESULT_PACKED, REG_SP, 2*4 + 0 * 8);
3477 M_DST(REG_FRESULT, REG_SP, 2*4 + 0 * 8);
3484 /* remove native stackframe info */
3486 M_MOV(REG_SP, REG_A0);
3487 M_MOV(REG_PV, REG_A1);
3488 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3489 M_ALD(REG_ITMP3, REG_PV, disp);
3490 M_JSR(REG_RA, REG_ITMP3);
3491 M_NOP; /* XXX fill me! */
3492 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3494 /* restore return value */
3496 switch (md->returntype.type) {
3497 #if SIZEOF_VOID_P == 8
3501 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3505 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3510 M_ILD(REG_RESULT, REG_SP, 2*4 + 0 * 8);
3513 M_LLD(REG_RESULT_PACKED, REG_SP, 2*4 + 0 * 8);
3517 M_DLD(REG_FRESULT, REG_SP, 2*4 + 0 * 8);
3524 M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* load RA */
3526 /* check for exception */
3528 M_BNEZ(REG_ITMP1_XPTR, 2); /* if no exception then return */
3529 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8); /* DELAY SLOT */
3531 M_RET(REG_RA); /* return to caller */
3532 M_NOP; /* DELAY SLOT */
3534 /* handle exception */
3536 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3537 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
3538 M_JMP(REG_ITMP3); /* jump to asm exception handler */
3539 M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address (DELAY) */
3541 /* Generate patcher traps. */
3543 emit_patcher_traps(jd);
3548 * These are local overrides for various environment variables in Emacs.
3549 * Please do not remove this and leave it at the end of the file, where
3550 * Emacs will automagically detect them.
3551 * ---------------------------------------------------------------------
3554 * indent-tabs-mode: t
3558 * vim:noexpandtab:sw=4:ts=4: