1 /* src/vm/jit/alpha/codegen.c - machine code generator for Alpha
3 Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
38 #include "vm/jit/alpha/arch.h"
39 #include "vm/jit/alpha/codegen.h"
41 #include "mm/memory.h"
43 #include "native/jni.h"
44 #include "native/localref.h"
45 #include "native/native.h"
47 #include "threads/lock-common.h"
49 #include "vm/builtin.h"
50 #include "vm/exceptions.h"
51 #include "vm/global.h"
54 #include "vm/jit/abi.h"
55 #include "vm/jit/asmpart.h"
56 #include "vm/jit/codegen-common.h"
57 #include "vm/jit/dseg.h"
58 #include "vm/jit/emit-common.h"
59 #include "vm/jit/jit.h"
60 #include "vm/jit/linenumbertable.h"
61 #include "vm/jit/parse.h"
62 #include "vm/jit/patcher-common.h"
63 #include "vm/jit/reg.h"
64 #include "vm/jit/replace.h"
65 #include "vm/jit/stacktrace.h"
67 #if defined(ENABLE_SSA)
68 # include "vm/jit/optimizing/lsra.h"
69 # include "vm/jit/optimizing/ssa.h"
70 #elif defined(ENABLE_LSRA)
71 # include "vm/jit/allocator/lsra.h"
74 #include "vmcore/loader.h"
75 #include "vmcore/options.h"
78 /* codegen_emit ****************************************************************
80 Generates machine code.
82 *******************************************************************************/
84 bool codegen_emit(jitdata *jd)
90 s4 len, s1, s2, s3, d, disp;
95 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
96 unresolved_method *um;
97 builtintable_entry *bte;
100 unresolved_field *uf;
104 /* get required compiler data */
111 /* prevent compiler warnings */
124 savedregs_num = code_is_leafmethod(code) ? 0 : 1; /* space to save the RA */
126 /* space to save used callee saved registers */
128 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
129 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
131 cd->stackframesize = rd->memuse + savedregs_num;
133 #if defined(ENABLE_THREADS) /* space to save argument of monitor_enter */
134 if (checksync && code_is_synchronized(code))
135 cd->stackframesize++;
138 /* create method header */
141 cd->stackframesize = (cd->stackframesize + 1) & ~1; /* align stack to 16-bytes */
144 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
145 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
147 code->synchronizedoffset = rd->memuse * 8;
149 /* REMOVEME: We still need it for exception handling in assembler. */
151 if (code_is_leafmethod(code))
152 (void) dseg_add_unique_s4(cd, 1);
154 (void) dseg_add_unique_s4(cd, 0);
156 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
157 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
159 /* create stack frame (if necessary) */
161 if (cd->stackframesize)
162 M_LDA(REG_SP, REG_SP, -(cd->stackframesize * 8));
164 /* save return address and used callee saved registers */
166 p = cd->stackframesize;
167 if (!code_is_leafmethod(code)) {
168 p--; M_AST(REG_RA, REG_SP, p * 8);
170 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
171 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
173 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
174 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
177 /* take arguments out of register or stack frame */
181 for (p = 0, l = 0; p < md->paramcount; p++) {
182 t = md->paramtypes[p].type;
184 varindex = jd->local_map[l * 5 + t];
187 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
190 if (varindex == UNUSED)
195 s1 = md->params[p].regoff;
197 if (IS_INT_LNG_TYPE(t)) { /* integer args */
198 if (!md->params[p].inmemory) { /* register arguments */
199 if (!IS_INMEMORY(var->flags))
200 M_INTMOVE(s1, var->vv.regoff);
202 M_LST(s1, REG_SP, var->vv.regoff);
204 else { /* stack arguments */
205 if (!IS_INMEMORY(var->flags))
206 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
208 var->vv.regoff = cd->stackframesize * 8 + s1;
211 else { /* floating args */
212 if (!md->params[p].inmemory) { /* register arguments */
213 if (!IS_INMEMORY(var->flags))
214 M_FLTMOVE(s1, var->vv.regoff);
216 M_DST(s1, REG_SP, var->vv.regoff * 8);
218 else { /* stack arguments */
219 if (!(var->flags & INMEMORY))
220 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
222 var->vv.regoff = cd->stackframesize * 8 + s1;
227 /* call monitorenter function */
229 #if defined(ENABLE_THREADS)
230 if (checksync && code_is_synchronized(code)) {
231 /* stack offset for monitor argument */
236 if (opt_verbosecall) {
237 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
239 for (p = 0; p < INT_ARG_CNT; p++)
240 M_LST(abi_registers_integer_argument[p], REG_SP, p * 8);
242 for (p = 0; p < FLT_ARG_CNT; p++)
243 M_DST(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
245 s1 += INT_ARG_CNT + FLT_ARG_CNT;
247 #endif /* !defined(NDEBUG) */
249 /* decide which monitor enter function to call */
251 if (m->flags & ACC_STATIC) {
252 disp = dseg_add_address(cd, &m->class->object.header);
253 M_ALD(REG_A0, REG_PV, disp);
257 M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
260 M_AST(REG_A0, REG_SP, s1 * 8);
261 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
262 M_ALD(REG_PV, REG_PV, disp);
263 M_JSR(REG_RA, REG_PV);
264 disp = (s4) (cd->mcodeptr - cd->mcodebase);
265 M_LDA(REG_PV, REG_RA, -disp);
268 if (opt_verbosecall) {
269 for (p = 0; p < INT_ARG_CNT; p++)
270 M_LLD(abi_registers_integer_argument[p], REG_SP, p * 8);
272 for (p = 0; p < FLT_ARG_CNT; p++)
273 M_DLD(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
275 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
277 #endif /* !defined(NDEBUG) */
281 /* call trace function */
284 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
285 emit_verbosecall_enter(jd);
290 /* end of header generation */
292 /* create replacement points */
294 REPLACEMENT_POINTS_INIT(cd, jd);
296 /* walk through all basic blocks */
298 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
300 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
302 if (bptr->flags >= BBREACHED) {
304 /* branch resolving */
306 codegen_resolve_branchrefs(cd, bptr);
308 /* handle replacement points */
310 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
312 /* copy interface registers to their destination */
316 #if defined(ENABLE_LSRA)
320 src = bptr->invars[len];
321 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
322 /* d = reg_of_var(m, src, REG_ITMP1); */
323 if (!(src->flags & INMEMORY))
327 M_INTMOVE(REG_ITMP1, d);
328 emit_store(jd, NULL, src, d);
335 var = VAR(bptr->invars[len]);
336 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
337 d = codegen_reg_of_var(0, var, REG_ITMP1);
338 M_INTMOVE(REG_ITMP1, d);
339 emit_store(jd, NULL, var, d);
342 assert((var->flags & INOUT));
345 #if defined(ENABLE_LSRA)
349 /* walk through all instructions */
353 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
354 if (iptr->line != currentline) {
355 linenumbertable_list_entry_add(cd, iptr->line);
356 currentline = iptr->line;
359 MCODECHECK(64); /* an instruction usually needs < 64 words */
362 case ICMD_NOP: /* ... ==> ... */
363 case ICMD_POP: /* ..., value ==> ... */
364 case ICMD_POP2: /* ..., value, value ==> ... */
367 case ICMD_INLINE_START:
369 REPLACEMENT_POINT_INLINE_START(cd, iptr);
372 case ICMD_INLINE_BODY:
374 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
375 linenumbertable_list_entry_add_inline_start(cd, iptr);
376 linenumbertable_list_entry_add(cd, iptr->line);
379 case ICMD_INLINE_END:
381 linenumbertable_list_entry_add_inline_end(cd, iptr);
382 linenumbertable_list_entry_add(cd, iptr->line);
385 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
387 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
388 emit_nullpointer_check(cd, iptr, s1);
391 /* constant operations ************************************************/
393 case ICMD_ICONST: /* ... ==> ..., constant */
395 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
396 ICONST(d, iptr->sx.val.i);
397 emit_store_dst(jd, iptr, d);
400 case ICMD_LCONST: /* ... ==> ..., constant */
402 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
403 LCONST(d, iptr->sx.val.l);
404 emit_store_dst(jd, iptr, d);
407 case ICMD_FCONST: /* ... ==> ..., constant */
409 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
410 disp = dseg_add_float(cd, iptr->sx.val.f);
411 M_FLD(d, REG_PV, disp);
412 emit_store_dst(jd, iptr, d);
415 case ICMD_DCONST: /* ... ==> ..., constant */
417 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
418 disp = dseg_add_double(cd, iptr->sx.val.d);
419 M_DLD(d, REG_PV, disp);
420 emit_store_dst(jd, iptr, d);
423 case ICMD_ACONST: /* ... ==> ..., constant */
425 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
427 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
428 constant_classref *cr = iptr->sx.val.c.ref;
430 disp = dseg_add_unique_address(cd, cr);
432 /* XXX Only add the patcher, if this position needs to
433 be patched. If there was a previous position which
434 resolved the same class, the returned displacement
435 of dseg_add_address is ok to use. */
437 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
440 M_ALD(d, REG_PV, disp);
443 if (iptr->sx.val.anyptr == NULL)
444 M_INTMOVE(REG_ZERO, d);
446 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
447 M_ALD(d, REG_PV, disp);
450 emit_store_dst(jd, iptr, d);
454 /* load/store/move/copy operations ************************************/
456 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
457 case ICMD_ALOAD: /* s1 = local variable */
461 case ICMD_ISTORE: /* ..., value ==> ... */
473 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
478 /* integer operations *************************************************/
480 case ICMD_INEG: /* ..., value ==> ..., - value */
482 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
483 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
484 M_ISUB(REG_ZERO, s1, d);
485 emit_store_dst(jd, iptr, d);
488 case ICMD_LNEG: /* ..., value ==> ..., - value */
490 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
491 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
492 M_LSUB(REG_ZERO, s1, d);
493 emit_store_dst(jd, iptr, d);
496 case ICMD_I2L: /* ..., value ==> ..., value */
498 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
499 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
501 emit_store_dst(jd, iptr, d);
504 case ICMD_L2I: /* ..., value ==> ..., value */
506 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
507 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
508 M_IADD(s1, REG_ZERO, d);
509 emit_store_dst(jd, iptr, d);
512 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
514 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
515 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
516 if (has_ext_instr_set) {
519 M_SLL_IMM(s1, 56, d);
520 M_SRA_IMM( d, 56, d);
522 emit_store_dst(jd, iptr, d);
525 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
527 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
528 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
530 emit_store_dst(jd, iptr, d);
533 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
535 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
536 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
537 if (has_ext_instr_set) {
540 M_SLL_IMM(s1, 48, d);
541 M_SRA_IMM( d, 48, d);
543 emit_store_dst(jd, iptr, d);
547 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
549 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
550 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
551 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
553 emit_store_dst(jd, iptr, d);
557 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
558 /* sx.val.i = constant */
560 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
561 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
562 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
563 M_IADD_IMM(s1, iptr->sx.val.i, d);
564 } else if ((iptr->sx.val.i > -256) && (iptr->sx.val.i < 0)) {
565 M_ISUB_IMM(s1, (-iptr->sx.val.i), d);
567 /* XXX maybe use M_LDA? */
568 ICONST(REG_ITMP2, iptr->sx.val.i);
569 M_IADD(s1, REG_ITMP2, d);
571 emit_store_dst(jd, iptr, d);
574 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
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);
580 emit_store_dst(jd, iptr, d);
583 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
584 /* sx.val.l = constant */
586 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
587 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
588 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
589 M_LADD_IMM(s1, iptr->sx.val.l, d);
591 LCONST(REG_ITMP2, iptr->sx.val.l);
592 M_LADD(s1, REG_ITMP2, d);
594 emit_store_dst(jd, iptr, d);
597 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
599 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
600 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
601 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
603 emit_store_dst(jd, iptr, d);
606 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
607 /* sx.val.i = constant */
609 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
610 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
611 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
612 M_ISUB_IMM(s1, iptr->sx.val.i, d);
614 ICONST(REG_ITMP2, iptr->sx.val.i);
615 M_ISUB(s1, REG_ITMP2, d);
617 emit_store_dst(jd, iptr, d);
620 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
622 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
623 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
624 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
626 emit_store_dst(jd, iptr, d);
629 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
630 /* sx.val.l = constant */
632 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
633 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
634 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
635 M_LSUB_IMM(s1, iptr->sx.val.l, d);
637 LCONST(REG_ITMP2, iptr->sx.val.l);
638 M_LSUB(s1, REG_ITMP2, d);
640 emit_store_dst(jd, iptr, d);
643 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
645 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
646 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
647 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
649 emit_store_dst(jd, iptr, d);
652 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
653 /* sx.val.i = constant */
655 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
656 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
657 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
658 M_IMUL_IMM(s1, iptr->sx.val.i, d);
660 ICONST(REG_ITMP2, iptr->sx.val.i);
661 M_IMUL(s1, REG_ITMP2, d);
663 emit_store_dst(jd, iptr, d);
666 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
668 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
669 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
670 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
672 emit_store_dst(jd, iptr, d);
675 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
676 /* sx.val.l = constant */
678 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
679 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
680 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
681 M_LMUL_IMM(s1, iptr->sx.val.l, d);
683 LCONST(REG_ITMP2, iptr->sx.val.l);
684 M_LMUL(s1, REG_ITMP2, d);
686 emit_store_dst(jd, iptr, d);
689 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
690 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
692 s1 = emit_load_s1(jd, iptr, REG_A0);
693 s2 = emit_load_s2(jd, iptr, REG_A1);
694 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
695 emit_arithmetic_check(cd, iptr, s2);
697 M_INTMOVE(s1, REG_A0);
698 M_INTMOVE(s2, REG_A1);
699 bte = iptr->sx.s23.s3.bte;
700 disp = dseg_add_functionptr(cd, bte->fp);
701 M_ALD(REG_PV, REG_PV, disp);
702 M_JSR(REG_RA, REG_PV);
703 disp = (s4) (cd->mcodeptr - cd->mcodebase);
704 M_LDA(REG_PV, REG_RA, -disp);
706 M_IADD(REG_RESULT, REG_ZERO, d); /* sign extend (bugfix for gcc -O2) */
707 emit_store_dst(jd, iptr, d);
710 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
711 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
713 s1 = emit_load_s1(jd, iptr, REG_A0);
714 s2 = emit_load_s2(jd, iptr, REG_A1);
715 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
716 emit_arithmetic_check(cd, iptr, s2);
718 M_INTMOVE(s1, REG_A0);
719 M_INTMOVE(s2, REG_A1);
720 bte = iptr->sx.s23.s3.bte;
721 disp = dseg_add_functionptr(cd, bte->fp);
722 M_ALD(REG_PV, REG_PV, disp);
723 M_JSR(REG_RA, REG_PV);
724 disp = (s4) (cd->mcodeptr - cd->mcodebase);
725 M_LDA(REG_PV, REG_RA, -disp);
727 M_INTMOVE(REG_RESULT, d);
728 emit_store_dst(jd, iptr, d);
731 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
732 case ICMD_LDIVPOW2: /* val.i = constant */
734 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
735 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
736 if (iptr->sx.val.i <= 15) {
737 M_LDA(REG_ITMP2, s1, (1 << iptr->sx.val.i) -1);
738 M_CMOVGE(s1, s1, REG_ITMP2);
740 M_SRA_IMM(s1, 63, REG_ITMP2);
741 M_SRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
742 M_LADD(s1, REG_ITMP2, REG_ITMP2);
744 M_SRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
745 emit_store_dst(jd, iptr, d);
748 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
750 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
751 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
752 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
753 M_AND_IMM(s2, 0x1f, REG_ITMP3);
754 M_SLL(s1, REG_ITMP3, d);
755 M_IADD(d, REG_ZERO, d);
756 emit_store_dst(jd, iptr, d);
759 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
760 /* sx.val.i = constant */
762 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
763 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
764 M_SLL_IMM(s1, iptr->sx.val.i & 0x1f, d);
765 M_IADD(d, REG_ZERO, d);
766 emit_store_dst(jd, iptr, d);
769 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
771 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
772 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
773 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
774 M_AND_IMM(s2, 0x1f, REG_ITMP3);
775 M_SRA(s1, REG_ITMP3, d);
776 emit_store_dst(jd, iptr, d);
779 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
780 /* sx.val.i = constant */
782 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
783 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
784 M_SRA_IMM(s1, iptr->sx.val.i & 0x1f, d);
785 emit_store_dst(jd, iptr, d);
788 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
790 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
791 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
792 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
793 M_AND_IMM(s2, 0x1f, REG_ITMP2);
795 M_SRL(d, REG_ITMP2, d);
796 M_IADD(d, REG_ZERO, d);
797 emit_store_dst(jd, iptr, d);
800 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
801 /* sx.val.i = constant */
803 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
804 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
806 M_SRL_IMM(d, iptr->sx.val.i & 0x1f, d);
807 M_IADD(d, REG_ZERO, d);
808 emit_store_dst(jd, iptr, d);
811 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
813 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
814 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
815 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
817 emit_store_dst(jd, iptr, d);
820 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
821 /* sx.val.i = constant */
823 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
824 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
825 M_SLL_IMM(s1, iptr->sx.val.i & 0x3f, d);
826 emit_store_dst(jd, iptr, d);
829 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
831 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
832 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
833 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
835 emit_store_dst(jd, iptr, d);
838 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
839 /* sx.val.i = constant */
841 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
842 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
843 M_SRA_IMM(s1, iptr->sx.val.i & 0x3f, d);
844 emit_store_dst(jd, iptr, d);
847 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
849 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
850 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
851 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
853 emit_store_dst(jd, iptr, d);
856 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
857 /* sx.val.i = constant */
859 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
860 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
861 M_SRL_IMM(s1, iptr->sx.val.i & 0x3f, d);
862 emit_store_dst(jd, iptr, d);
865 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
868 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
869 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
870 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
872 emit_store_dst(jd, iptr, d);
875 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
876 /* sx.val.i = constant */
878 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
879 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
880 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
881 M_AND_IMM(s1, iptr->sx.val.i, d);
882 } else if (iptr->sx.val.i == 0xffff) {
884 } else if (iptr->sx.val.i == 0xffffff) {
885 M_ZAPNOT_IMM(s1, 0x07, d);
887 ICONST(REG_ITMP2, iptr->sx.val.i);
888 M_AND(s1, REG_ITMP2, d);
890 emit_store_dst(jd, iptr, d);
893 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
894 /* sx.val.i = constant */
896 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
897 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
899 M_MOV(s1, REG_ITMP1);
902 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
903 M_AND_IMM(s1, iptr->sx.val.i, d);
905 M_ISUB(REG_ZERO, s1, d);
906 M_AND_IMM(d, iptr->sx.val.i, d);
907 } else if (iptr->sx.val.i == 0xffff) {
910 M_ISUB(REG_ZERO, s1, d);
912 } else if (iptr->sx.val.i == 0xffffff) {
913 M_ZAPNOT_IMM(s1, 0x07, d);
915 M_ISUB(REG_ZERO, s1, d);
916 M_ZAPNOT_IMM(d, 0x07, d);
918 ICONST(REG_ITMP2, iptr->sx.val.i);
919 M_AND(s1, REG_ITMP2, d);
921 M_ISUB(REG_ZERO, s1, d);
922 M_AND(d, REG_ITMP2, d);
924 M_ISUB(REG_ZERO, d, d);
925 emit_store_dst(jd, iptr, d);
928 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
929 /* sx.val.l = constant */
931 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
932 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
933 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
934 M_AND_IMM(s1, iptr->sx.val.l, d);
935 } else if (iptr->sx.val.l == 0xffffL) {
937 } else if (iptr->sx.val.l == 0xffffffL) {
938 M_ZAPNOT_IMM(s1, 0x07, d);
939 } else if (iptr->sx.val.l == 0xffffffffL) {
941 } else if (iptr->sx.val.l == 0xffffffffffL) {
942 M_ZAPNOT_IMM(s1, 0x1f, d);
943 } else if (iptr->sx.val.l == 0xffffffffffffL) {
944 M_ZAPNOT_IMM(s1, 0x3f, d);
945 } else if (iptr->sx.val.l == 0xffffffffffffffL) {
946 M_ZAPNOT_IMM(s1, 0x7f, d);
948 LCONST(REG_ITMP2, iptr->sx.val.l);
949 M_AND(s1, REG_ITMP2, d);
951 emit_store_dst(jd, iptr, d);
954 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
955 /* sx.val.l = constant */
957 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
958 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
960 M_MOV(s1, REG_ITMP1);
963 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
964 M_AND_IMM(s1, iptr->sx.val.l, d);
966 M_LSUB(REG_ZERO, s1, d);
967 M_AND_IMM(d, iptr->sx.val.l, d);
968 } else if (iptr->sx.val.l == 0xffffL) {
971 M_LSUB(REG_ZERO, s1, d);
973 } else if (iptr->sx.val.l == 0xffffffL) {
974 M_ZAPNOT_IMM(s1, 0x07, d);
976 M_LSUB(REG_ZERO, s1, d);
977 M_ZAPNOT_IMM(d, 0x07, d);
978 } else if (iptr->sx.val.l == 0xffffffffL) {
981 M_LSUB(REG_ZERO, s1, d);
983 } else if (iptr->sx.val.l == 0xffffffffffL) {
984 M_ZAPNOT_IMM(s1, 0x1f, d);
986 M_LSUB(REG_ZERO, s1, d);
987 M_ZAPNOT_IMM(d, 0x1f, d);
988 } else if (iptr->sx.val.l == 0xffffffffffffL) {
989 M_ZAPNOT_IMM(s1, 0x3f, d);
991 M_LSUB(REG_ZERO, s1, d);
992 M_ZAPNOT_IMM(d, 0x3f, d);
993 } else if (iptr->sx.val.l == 0xffffffffffffffL) {
994 M_ZAPNOT_IMM(s1, 0x7f, d);
996 M_LSUB(REG_ZERO, s1, d);
997 M_ZAPNOT_IMM(d, 0x7f, d);
999 LCONST(REG_ITMP2, iptr->sx.val.l);
1000 M_AND(s1, REG_ITMP2, d);
1002 M_LSUB(REG_ZERO, s1, d);
1003 M_AND(d, REG_ITMP2, d);
1005 M_LSUB(REG_ZERO, d, d);
1006 emit_store_dst(jd, iptr, d);
1009 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1012 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1013 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1014 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1016 emit_store_dst(jd, iptr, d);
1019 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1020 /* sx.val.i = constant */
1022 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1023 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1024 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
1025 M_OR_IMM(s1, iptr->sx.val.i, d);
1027 ICONST(REG_ITMP2, iptr->sx.val.i);
1028 M_OR(s1, REG_ITMP2, d);
1030 emit_store_dst(jd, iptr, d);
1033 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1034 /* sx.val.l = constant */
1036 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1037 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1038 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
1039 M_OR_IMM(s1, iptr->sx.val.l, d);
1041 LCONST(REG_ITMP2, iptr->sx.val.l);
1042 M_OR(s1, REG_ITMP2, d);
1044 emit_store_dst(jd, iptr, d);
1047 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1050 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1051 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1052 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1054 emit_store_dst(jd, iptr, d);
1057 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1058 /* sx.val.i = constant */
1060 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1061 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1062 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
1063 M_XOR_IMM(s1, iptr->sx.val.i, d);
1065 ICONST(REG_ITMP2, iptr->sx.val.i);
1066 M_XOR(s1, REG_ITMP2, d);
1068 emit_store_dst(jd, iptr, d);
1071 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1072 /* sx.val.l = constant */
1074 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1075 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1076 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
1077 M_XOR_IMM(s1, iptr->sx.val.l, d);
1079 LCONST(REG_ITMP2, iptr->sx.val.l);
1080 M_XOR(s1, REG_ITMP2, d);
1082 emit_store_dst(jd, iptr, d);
1086 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1088 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1089 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1090 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1091 M_CMPLT(s1, s2, REG_ITMP3);
1092 M_CMPLT(s2, s1, REG_ITMP1);
1093 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1094 emit_store_dst(jd, iptr, d);
1098 /* floating operations ************************************************/
1100 case ICMD_FNEG: /* ..., value ==> ..., - value */
1102 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1103 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1105 emit_store_dst(jd, iptr, d);
1108 case ICMD_DNEG: /* ..., value ==> ..., - value */
1110 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1111 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1113 emit_store_dst(jd, iptr, d);
1116 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1118 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1119 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1120 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1124 if (d == s1 || d == s2) {
1125 M_FADDS(s1, s2, REG_FTMP3);
1127 M_FMOV(REG_FTMP3, d);
1133 emit_store_dst(jd, iptr, d);
1136 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1138 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1139 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1140 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1144 if (d == s1 || d == s2) {
1145 M_DADDS(s1, s2, REG_FTMP3);
1147 M_FMOV(REG_FTMP3, d);
1153 emit_store_dst(jd, iptr, d);
1156 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1158 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1159 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1160 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1164 if (d == s1 || d == s2) {
1165 M_FSUBS(s1, s2, REG_FTMP3);
1167 M_FMOV(REG_FTMP3, d);
1173 emit_store_dst(jd, iptr, d);
1176 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1178 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1179 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1180 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1184 if (d == s1 || d == s2) {
1185 M_DSUBS(s1, s2, REG_FTMP3);
1187 M_FMOV(REG_FTMP3, d);
1193 emit_store_dst(jd, iptr, d);
1196 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1198 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1199 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1200 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1204 if (d == s1 || d == s2) {
1205 M_FMULS(s1, s2, REG_FTMP3);
1207 M_FMOV(REG_FTMP3, d);
1213 emit_store_dst(jd, iptr, d);
1216 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1218 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1219 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1220 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1224 if (d == s1 || d == s2) {
1225 M_DMULS(s1, s2, REG_FTMP3);
1227 M_FMOV(REG_FTMP3, d);
1233 emit_store_dst(jd, iptr, d);
1236 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1238 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1239 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1240 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1244 if (d == s1 || d == s2) {
1245 M_FDIVS(s1, s2, REG_FTMP3);
1247 M_FMOV(REG_FTMP3, d);
1253 emit_store_dst(jd, iptr, d);
1256 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1258 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1259 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1260 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1264 if (d == s1 || d == s2) {
1265 M_DDIVS(s1, s2, REG_FTMP3);
1267 M_FMOV(REG_FTMP3, d);
1273 emit_store_dst(jd, iptr, d);
1276 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1278 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1279 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1280 disp = dseg_add_unique_double(cd, 0.0); /* FIXME Not thread safe! */
1281 M_LST(s1, REG_PV, disp);
1282 M_DLD(d, REG_PV, disp);
1284 emit_store_dst(jd, iptr, d);
1287 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1289 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1290 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1291 disp = dseg_add_unique_double(cd, 0.0); /* FIXME Not thread safe! */
1292 M_LST(s1, REG_PV, disp);
1293 M_DLD(d, REG_PV, disp);
1295 emit_store_dst(jd, iptr, d);
1298 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1300 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1301 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1302 disp = dseg_add_unique_double(cd, 0.0); /* FIXME Not thread safe! */
1303 M_CVTDL_C(s1, REG_FTMP2);
1304 M_CVTLI(REG_FTMP2, REG_FTMP3);
1305 M_DST(REG_FTMP3, REG_PV, disp);
1306 M_ILD(d, REG_PV, disp);
1307 emit_store_dst(jd, iptr, d);
1310 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1312 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1313 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1314 disp = dseg_add_unique_double(cd, 0.0); /* FIXME Not thread safe! */
1315 M_CVTDL_C(s1, REG_FTMP2);
1316 M_DST(REG_FTMP2, REG_PV, disp);
1317 M_LLD(d, REG_PV, disp);
1318 emit_store_dst(jd, iptr, d);
1321 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1323 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1324 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1327 emit_store_dst(jd, iptr, d);
1330 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1332 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1333 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1340 emit_store_dst(jd, iptr, d);
1343 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1345 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1346 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1347 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1349 M_LSUB_IMM(REG_ZERO, 1, d);
1350 M_FCMPEQ(s1, s2, REG_FTMP3);
1351 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1353 M_FCMPLT(s2, s1, REG_FTMP3);
1354 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1355 M_LADD_IMM(REG_ZERO, 1, d);
1357 M_LSUB_IMM(REG_ZERO, 1, d);
1358 M_FCMPEQS(s1, s2, REG_FTMP3);
1360 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1362 M_FCMPLTS(s2, s1, REG_FTMP3);
1364 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1365 M_LADD_IMM(REG_ZERO, 1, d);
1367 emit_store_dst(jd, iptr, d);
1370 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1372 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1373 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1374 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1376 M_LADD_IMM(REG_ZERO, 1, d);
1377 M_FCMPEQ(s1, s2, REG_FTMP3);
1378 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1380 M_FCMPLT(s1, s2, REG_FTMP3);
1381 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1382 M_LSUB_IMM(REG_ZERO, 1, d);
1384 M_LADD_IMM(REG_ZERO, 1, d);
1385 M_FCMPEQS(s1, s2, REG_FTMP3);
1387 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1389 M_FCMPLTS(s1, s2, REG_FTMP3);
1391 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1392 M_LSUB_IMM(REG_ZERO, 1, d);
1394 emit_store_dst(jd, iptr, d);
1398 /* memory operations **************************************************/
1400 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1402 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1403 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1404 /* implicit null-pointer check */
1405 M_ILD(d, s1, OFFSET(java_array_t, size));
1406 emit_store_dst(jd, iptr, d);
1409 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1411 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1412 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1413 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1414 /* implicit null-pointer check */
1415 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1416 if (has_ext_instr_set) {
1417 M_LADD(s2, s1, REG_ITMP1);
1418 M_BLDU(d, REG_ITMP1, OFFSET (java_bytearray_t, data[0]));
1422 M_LADD(s2, s1, REG_ITMP1);
1423 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1424 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray_t, data[0])+1);
1425 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1426 M_SRA_IMM(d, 56, d);
1428 emit_store_dst(jd, iptr, d);
1431 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1433 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1434 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1435 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1436 /* implicit null-pointer check */
1437 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1438 if (has_ext_instr_set) {
1439 M_LADD(s2, s1, REG_ITMP1);
1440 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1441 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1444 M_LADD (s2, s1, REG_ITMP1);
1445 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1446 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1447 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1448 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
1450 emit_store_dst(jd, iptr, d);
1453 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1455 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1456 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1457 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1458 /* implicit null-pointer check */
1459 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1460 if (has_ext_instr_set) {
1461 M_LADD(s2, s1, REG_ITMP1);
1462 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1463 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray_t, data[0]));
1466 M_LADD(s2, s1, REG_ITMP1);
1467 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1468 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1469 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray_t, data[0])+2);
1470 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1471 M_SRA_IMM(d, 48, d);
1473 emit_store_dst(jd, iptr, d);
1476 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1478 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1479 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1480 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1481 /* implicit null-pointer check */
1482 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1483 M_S4ADDQ(s2, s1, REG_ITMP1);
1484 M_ILD(d, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1485 emit_store_dst(jd, iptr, d);
1488 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1490 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1491 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1492 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1493 /* implicit null-pointer check */
1494 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1495 M_S8ADDQ(s2, s1, REG_ITMP1);
1496 M_LLD(d, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1497 emit_store_dst(jd, iptr, d);
1500 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1502 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1503 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1504 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1505 /* implicit null-pointer check */
1506 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1507 M_S4ADDQ(s2, s1, REG_ITMP1);
1508 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray_t, data[0]));
1509 emit_store_dst(jd, iptr, d);
1512 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1514 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1515 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1516 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1517 /* implicit null-pointer check */
1518 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1519 M_S8ADDQ(s2, s1, REG_ITMP1);
1520 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray_t, data[0]));
1521 emit_store_dst(jd, iptr, d);
1524 case ICMD_AALOAD: /* ..., 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 /* implicit null-pointer check */
1530 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1531 M_SAADDQ(s2, s1, REG_ITMP1);
1532 M_ALD(d, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1533 emit_store_dst(jd, iptr, d);
1537 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1539 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1540 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1541 /* implicit null-pointer check */
1542 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1543 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1544 if (has_ext_instr_set) {
1545 M_LADD(s2, s1, REG_ITMP1);
1546 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1549 M_LADD(s2, s1, REG_ITMP1);
1550 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1551 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1552 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
1553 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1554 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1555 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1559 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1561 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1562 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1563 /* implicit null-pointer check */
1564 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1565 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1566 if (has_ext_instr_set) {
1567 M_LADD(s2, s1, REG_ITMP1);
1568 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1569 M_SST(s3, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1572 M_LADD(s2, s1, REG_ITMP1);
1573 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1574 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1575 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1576 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1577 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1578 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1579 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1583 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1585 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1586 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1587 /* implicit null-pointer check */
1588 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1589 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1590 if (has_ext_instr_set) {
1591 M_LADD(s2, s1, REG_ITMP1);
1592 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1593 M_SST(s3, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1596 M_LADD(s2, s1, REG_ITMP1);
1597 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1598 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1599 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1600 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1601 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1602 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1603 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1607 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1609 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1610 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1611 /* implicit null-pointer check */
1612 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1613 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1614 M_S4ADDQ(s2, s1, REG_ITMP1);
1615 M_IST(s3, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1618 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1620 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1621 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1622 /* implicit null-pointer check */
1623 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1624 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1625 M_S8ADDQ(s2, s1, REG_ITMP1);
1626 M_LST(s3, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1629 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1631 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1632 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1633 /* implicit null-pointer check */
1634 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1635 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1636 M_S4ADDQ(s2, s1, REG_ITMP1);
1637 M_FST(s3, REG_ITMP1, OFFSET(java_floatarray_t, data[0]));
1640 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1642 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1643 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1644 /* implicit null-pointer check */
1645 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1646 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1647 M_S8ADDQ(s2, s1, REG_ITMP1);
1648 M_DST(s3, REG_ITMP1, OFFSET(java_doublearray_t, data[0]));
1651 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1653 s1 = emit_load_s1(jd, iptr, REG_A0);
1654 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1655 /* implicit null-pointer check */
1656 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1657 s3 = emit_load_s3(jd, iptr, REG_A1);
1659 M_INTMOVE(s1, REG_A0);
1660 M_INTMOVE(s3, REG_A1);
1662 disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
1663 M_ALD(REG_PV, REG_PV, disp);
1664 M_JSR(REG_RA, REG_PV);
1665 disp = (s4) (cd->mcodeptr - cd->mcodebase);
1666 M_LDA(REG_PV, REG_RA, -disp);
1667 emit_arraystore_check(cd, iptr);
1669 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1670 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1671 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1672 M_SAADDQ(s2, s1, REG_ITMP1);
1673 M_AST(s3, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1677 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1679 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1680 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1681 /* implicit null-pointer check */
1682 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1683 if (has_ext_instr_set) {
1684 M_LADD(s2, s1, REG_ITMP1);
1685 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1688 M_LADD(s2, s1, REG_ITMP1);
1689 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1690 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1691 M_INSBL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1692 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1693 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1694 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1698 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1700 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1701 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1702 /* implicit null-pointer check */
1703 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1704 if (has_ext_instr_set) {
1705 M_LADD(s2, s1, REG_ITMP1);
1706 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1707 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1710 M_LADD(s2, s1, REG_ITMP1);
1711 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1712 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1713 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1714 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1715 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1716 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1717 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1721 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1723 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1724 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1725 /* implicit null-pointer check */
1726 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1727 if (has_ext_instr_set) {
1728 M_LADD(s2, s1, REG_ITMP1);
1729 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1730 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1733 M_LADD(s2, s1, REG_ITMP1);
1734 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1735 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1736 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1737 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1738 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1739 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1740 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1744 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1746 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1747 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1748 /* implicit null-pointer check */
1749 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1750 M_S4ADDQ(s2, s1, REG_ITMP1);
1751 M_IST(REG_ZERO, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1754 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1756 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1757 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1758 /* implicit null-pointer check */
1759 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1760 M_S8ADDQ(s2, s1, REG_ITMP1);
1761 M_LST(REG_ZERO, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1764 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1766 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1767 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1768 /* implicit null-pointer check */
1769 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1770 M_SAADDQ(s2, s1, REG_ITMP1);
1771 M_AST(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1775 case ICMD_GETSTATIC: /* ... ==> ..., value */
1777 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1778 uf = iptr->sx.s23.s3.uf;
1779 fieldtype = uf->fieldref->parseddesc.fd->type;
1780 disp = dseg_add_unique_address(cd, uf);
1782 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1785 fi = iptr->sx.s23.s3.fmiref->p.field;
1786 fieldtype = fi->type;
1787 disp = dseg_add_address(cd, fi->value);
1789 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1790 patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class,
1794 M_ALD(REG_ITMP1, REG_PV, disp);
1795 switch (fieldtype) {
1797 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1798 M_ILD(d, REG_ITMP1, 0);
1801 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1802 M_LLD(d, REG_ITMP1, 0);
1805 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1806 M_ALD(d, REG_ITMP1, 0);
1809 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1810 M_FLD(d, REG_ITMP1, 0);
1813 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1814 M_DLD(d, REG_ITMP1, 0);
1817 emit_store_dst(jd, iptr, d);
1820 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1822 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1823 uf = iptr->sx.s23.s3.uf;
1824 fieldtype = uf->fieldref->parseddesc.fd->type;
1825 disp = dseg_add_unique_address(cd, uf);
1827 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1830 fi = iptr->sx.s23.s3.fmiref->p.field;
1831 fieldtype = fi->type;
1832 disp = dseg_add_address(cd, fi->value);
1834 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1835 patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class,
1839 M_ALD(REG_ITMP1, REG_PV, disp);
1840 switch (fieldtype) {
1842 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1843 M_IST(s1, REG_ITMP1, 0);
1846 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1847 M_LST(s1, REG_ITMP1, 0);
1850 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1851 M_AST(s1, REG_ITMP1, 0);
1854 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1855 M_FST(s1, REG_ITMP1, 0);
1858 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1859 M_DST(s1, REG_ITMP1, 0);
1864 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1865 /* val = value (in current instruction) */
1866 /* following NOP) */
1868 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1869 uf = iptr->sx.s23.s3.uf;
1870 fieldtype = uf->fieldref->parseddesc.fd->type;
1871 disp = dseg_add_unique_address(cd, uf);
1873 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1876 fi = iptr->sx.s23.s3.fmiref->p.field;
1877 fieldtype = fi->type;
1878 disp = dseg_add_address(cd, fi->value);
1880 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1881 patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class,
1885 M_ALD(REG_ITMP1, REG_PV, disp);
1886 switch (fieldtype) {
1888 M_IST(REG_ZERO, REG_ITMP1, 0);
1891 M_LST(REG_ZERO, REG_ITMP1, 0);
1894 M_AST(REG_ZERO, REG_ITMP1, 0);
1897 M_FST(REG_ZERO, REG_ITMP1, 0);
1900 M_DST(REG_ZERO, REG_ITMP1, 0);
1906 case ICMD_GETFIELD: /* ... ==> ..., value */
1908 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1910 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1911 uf = iptr->sx.s23.s3.uf;
1912 fieldtype = uf->fieldref->parseddesc.fd->type;
1915 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1918 fi = iptr->sx.s23.s3.fmiref->p.field;
1919 fieldtype = fi->type;
1923 /* implicit null-pointer check */
1924 switch (fieldtype) {
1926 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1930 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1934 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1938 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1942 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1946 emit_store_dst(jd, iptr, d);
1949 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1951 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1953 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1954 uf = iptr->sx.s23.s3.uf;
1955 fieldtype = uf->fieldref->parseddesc.fd->type;
1960 fi = iptr->sx.s23.s3.fmiref->p.field;
1961 fieldtype = fi->type;
1965 if (IS_INT_LNG_TYPE(fieldtype))
1966 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1968 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1970 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1971 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1973 /* implicit null-pointer check */
1974 switch (fieldtype) {
1976 M_IST(s2, s1, disp);
1979 M_LST(s2, s1, disp);
1982 M_AST(s2, s1, disp);
1985 M_FST(s2, s1, disp);
1988 M_DST(s2, s1, disp);
1993 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
1994 /* val = value (in current instruction) */
1995 /* following NOP) */
1997 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1999 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2000 uf = iptr->sx.s23.s3.uf;
2001 fieldtype = uf->fieldref->parseddesc.fd->type;
2004 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2007 fi = iptr->sx.s23.s3.fmiref->p.field;
2008 fieldtype = fi->type;
2012 /* implicit null-pointer check */
2013 switch (fieldtype) {
2015 M_IST(REG_ZERO, s1, disp);
2018 M_LST(REG_ZERO, s1, disp);
2021 M_AST(REG_ZERO, s1, disp);
2024 M_FST(REG_ZERO, s1, disp);
2027 M_DST(REG_ZERO, s1, disp);
2033 /* branch operations **************************************************/
2035 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2037 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2038 M_INTMOVE(s1, REG_ITMP1_XPTR);
2040 #ifdef ENABLE_VERIFIER
2041 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2042 unresolved_class *uc = iptr->sx.s23.s2.uc;
2044 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2046 #endif /* ENABLE_VERIFIER */
2048 disp = dseg_add_functionptr(cd, asm_handle_exception);
2049 M_ALD(REG_ITMP2, REG_PV, disp);
2050 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2051 M_NOP; /* nop ensures that XPC is less than the end */
2052 /* of basic block */
2056 case ICMD_GOTO: /* ... ==> ... */
2057 case ICMD_RET: /* ... ==> ... */
2059 emit_br(cd, iptr->dst.block);
2063 case ICMD_JSR: /* ... ==> ... */
2065 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
2069 case ICMD_IFNULL: /* ..., value ==> ... */
2070 case ICMD_IFNONNULL:
2072 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2073 emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE);
2076 case ICMD_IFEQ: /* ..., value ==> ... */
2078 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2079 if (iptr->sx.val.i == 0)
2080 emit_beqz(cd, iptr->dst.block, s1);
2082 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2083 M_CMPEQ_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2085 ICONST(REG_ITMP2, iptr->sx.val.i);
2086 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2088 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2092 case ICMD_IFLT: /* ..., value ==> ... */
2094 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2095 if (iptr->sx.val.i == 0)
2096 emit_bltz(cd, iptr->dst.block, s1);
2098 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2099 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2101 ICONST(REG_ITMP2, iptr->sx.val.i);
2102 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2104 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2108 case ICMD_IFLE: /* ..., value ==> ... */
2110 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2111 if (iptr->sx.val.i == 0)
2112 emit_blez(cd, iptr->dst.block, s1);
2114 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2115 M_CMPLE_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2117 ICONST(REG_ITMP2, iptr->sx.val.i);
2118 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2120 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2124 case ICMD_IFNE: /* ..., value ==> ... */
2126 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2127 if (iptr->sx.val.i == 0)
2128 emit_bnez(cd, iptr->dst.block, s1);
2130 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2131 M_CMPEQ_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2133 ICONST(REG_ITMP2, iptr->sx.val.i);
2134 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2136 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2140 case ICMD_IFGT: /* ..., value ==> ... */
2142 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2143 if (iptr->sx.val.i == 0)
2144 emit_bgtz(cd, iptr->dst.block, s1);
2146 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2147 M_CMPLE_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2149 ICONST(REG_ITMP2, iptr->sx.val.i);
2150 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2152 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2156 case ICMD_IFGE: /* ..., value ==> ... */
2158 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2159 if (iptr->sx.val.i == 0)
2160 emit_bgez(cd, iptr->dst.block, s1);
2162 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2163 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2165 ICONST(REG_ITMP2, iptr->sx.val.i);
2166 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2168 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2172 case ICMD_IF_LEQ: /* ..., value ==> ... */
2174 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2175 if (iptr->sx.val.l == 0)
2176 emit_beqz(cd, iptr->dst.block, s1);
2178 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2179 M_CMPEQ_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2181 LCONST(REG_ITMP2, iptr->sx.val.l);
2182 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2184 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2188 case ICMD_IF_LLT: /* ..., value ==> ... */
2190 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2191 if (iptr->sx.val.l == 0)
2192 emit_bltz(cd, iptr->dst.block, s1);
2194 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2195 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2197 LCONST(REG_ITMP2, iptr->sx.val.l);
2198 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2200 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2204 case ICMD_IF_LLE: /* ..., value ==> ... */
2206 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2207 if (iptr->sx.val.l == 0)
2208 emit_blez(cd, iptr->dst.block, s1);
2210 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2211 M_CMPLE_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2213 LCONST(REG_ITMP2, iptr->sx.val.l);
2214 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2216 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2220 case ICMD_IF_LNE: /* ..., value ==> ... */
2222 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2223 if (iptr->sx.val.l == 0)
2224 emit_bnez(cd, iptr->dst.block, s1);
2226 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2227 M_CMPEQ_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2229 LCONST(REG_ITMP2, iptr->sx.val.l);
2230 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2232 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2236 case ICMD_IF_LGT: /* ..., value ==> ... */
2238 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2239 if (iptr->sx.val.l == 0)
2240 emit_bgtz(cd, iptr->dst.block, s1);
2242 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2243 M_CMPLE_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2245 LCONST(REG_ITMP2, iptr->sx.val.l);
2246 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2248 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2252 case ICMD_IF_LGE: /* ..., value ==> ... */
2254 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2255 if (iptr->sx.val.l == 0)
2256 emit_bgez(cd, iptr->dst.block, s1);
2258 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2259 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2261 LCONST(REG_ITMP2, iptr->sx.val.l);
2262 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2264 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2268 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2269 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2270 case ICMD_IF_ACMPEQ:
2272 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2273 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2274 M_CMPEQ(s1, s2, REG_ITMP1);
2275 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2278 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2279 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2280 case ICMD_IF_ACMPNE:
2282 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2283 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2284 M_CMPEQ(s1, s2, REG_ITMP1);
2285 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2288 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2289 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2291 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2292 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2293 M_CMPLT(s1, s2, REG_ITMP1);
2294 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2297 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2298 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2300 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2301 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2302 M_CMPLE(s1, s2, REG_ITMP1);
2303 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2306 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2307 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2309 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2310 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2311 M_CMPLE(s1, s2, REG_ITMP1);
2312 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2315 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2316 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2318 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2319 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2320 M_CMPLT(s1, s2, REG_ITMP1);
2321 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2325 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2328 REPLACEMENT_POINT_RETURN(cd, iptr);
2329 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2330 M_INTMOVE(s1, REG_RESULT);
2331 goto nowperformreturn;
2333 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2335 REPLACEMENT_POINT_RETURN(cd, iptr);
2336 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2337 M_INTMOVE(s1, REG_RESULT);
2339 #ifdef ENABLE_VERIFIER
2340 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2341 unresolved_class *uc = iptr->sx.s23.s2.uc;
2343 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2345 #endif /* ENABLE_VERIFIER */
2346 goto nowperformreturn;
2348 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2351 REPLACEMENT_POINT_RETURN(cd, iptr);
2352 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2353 M_FLTMOVE(s1, REG_FRESULT);
2354 goto nowperformreturn;
2356 case ICMD_RETURN: /* ... ==> ... */
2358 REPLACEMENT_POINT_RETURN(cd, iptr);
2364 p = cd->stackframesize;
2366 /* call trace function */
2368 #if !defined(NDEBUG)
2369 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2370 emit_verbosecall_exit(jd);
2373 #if defined(ENABLE_THREADS)
2374 if (checksync && code_is_synchronized(code)) {
2375 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2377 switch (iptr->opc) {
2381 M_LST(REG_RESULT, REG_SP, rd->memuse * 8);
2385 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2389 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2390 M_ALD(REG_PV, REG_PV, disp);
2391 M_JSR(REG_RA, REG_PV);
2392 disp = -(s4) (cd->mcodeptr - cd->mcodebase);
2393 M_LDA(REG_PV, REG_RA, disp);
2395 switch (iptr->opc) {
2399 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2403 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2409 /* restore return address */
2411 if (!code_is_leafmethod(code)) {
2412 p--; M_LLD(REG_RA, REG_SP, p * 8);
2415 /* restore saved registers */
2417 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2418 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2420 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2421 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2424 /* deallocate stack */
2426 if (cd->stackframesize)
2427 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8);
2429 M_RET(REG_ZERO, REG_RA);
2435 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2438 branch_target_t *table;
2440 table = iptr->dst.table;
2442 l = iptr->sx.s23.s2.tablelow;
2443 i = iptr->sx.s23.s3.tablehigh;
2445 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2447 M_INTMOVE(s1, REG_ITMP1);
2448 } else if (l <= 32768) {
2449 M_LDA(REG_ITMP1, s1, -l);
2451 ICONST(REG_ITMP2, l);
2452 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2455 /* number of targets */
2461 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
2463 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
2464 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
2466 emit_beqz(cd, table[0].block, REG_ITMP2);
2468 /* build jump table top down and use address of lowest entry */
2473 dseg_add_target(cd, table->block);
2478 /* length of dataseg after last dseg_add_target is used by load */
2480 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
2481 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2482 M_JMP(REG_ZERO, REG_ITMP2);
2487 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2490 lookup_target_t *lookup;
2492 lookup = iptr->dst.lookup;
2494 i = iptr->sx.s23.s2.lookupcount;
2496 MCODECHECK((i<<2)+8);
2497 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2500 val = lookup->value;
2501 if ((val >= 0) && (val <= 255)) {
2502 M_CMPEQ_IMM(s1, val, REG_ITMP2);
2504 if ((val >= -32768) && (val <= 32767)) {
2505 M_LDA(REG_ITMP2, REG_ZERO, val);
2507 disp = dseg_add_s4(cd, val);
2508 M_ILD(REG_ITMP2, REG_PV, disp);
2510 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
2512 emit_bnez(cd, lookup->target.block, REG_ITMP2);
2516 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2522 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
2524 REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr);
2526 bte = iptr->sx.s23.s3.bte;
2530 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2532 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2533 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2534 case ICMD_INVOKEINTERFACE:
2536 REPLACEMENT_POINT_INVOKE(cd, iptr);
2538 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2540 um = iptr->sx.s23.s3.um;
2541 md = um->methodref->parseddesc.md;
2544 lm = iptr->sx.s23.s3.fmiref->p.method;
2546 md = lm->parseddesc;
2550 s3 = md->paramcount;
2552 MCODECHECK((s3 << 1) + 64);
2554 /* copy arguments to registers or stack location */
2556 for (s3 = s3 - 1; s3 >= 0; s3--) {
2557 var = VAR(iptr->sx.s23.s2.args[s3]);
2558 d = md->params[s3].regoff;
2560 /* already preallocated (ARGVAR)? */
2562 if (var->flags & PREALLOC)
2565 if (IS_INT_LNG_TYPE(var->type)) {
2566 if (!md->params[s3].inmemory) {
2567 s1 = emit_load(jd, iptr, var, d);
2571 s1 = emit_load(jd, iptr, var, REG_ITMP1);
2572 M_LST(s1, REG_SP, d);
2576 if (!md->params[s3].inmemory) {
2577 s1 = emit_load(jd, iptr, var, d);
2581 s1 = emit_load(jd, iptr, var, REG_FTMP1);
2582 M_DST(s1, REG_SP, d);
2587 switch (iptr->opc) {
2589 if (bte->stub == NULL)
2590 disp = dseg_add_functionptr(cd, bte->fp);
2592 disp = dseg_add_functionptr(cd, bte->stub);
2594 M_ALD(REG_PV, REG_PV, disp); /* Pointer to built-in-function */
2596 /* generate the actual call */
2598 M_JSR(REG_RA, REG_PV);
2599 REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr);
2600 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2601 M_LDA(REG_PV, REG_RA, -disp);
2604 case ICMD_INVOKESPECIAL:
2605 emit_nullpointer_check(cd, iptr, REG_A0);
2608 case ICMD_INVOKESTATIC:
2610 disp = dseg_add_unique_address(cd, um);
2612 patcher_add_patch_ref(jd, PATCHER_invokestatic_special,
2616 disp = dseg_add_address(cd, lm->stubroutine);
2618 M_ALD(REG_PV, REG_PV, disp); /* method pointer in r27 */
2620 /* generate the actual call */
2622 M_JSR(REG_RA, REG_PV);
2623 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2624 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2625 M_LDA(REG_PV, REG_RA, -disp);
2628 case ICMD_INVOKEVIRTUAL:
2630 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
2635 s1 = OFFSET(vftbl_t, table[0]) +
2636 sizeof(methodptr) * lm->vftblindex;
2638 /* implicit null-pointer check */
2639 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2640 M_ALD(REG_PV, REG_METHODPTR, s1);
2642 /* generate the actual call */
2644 M_JSR(REG_RA, REG_PV);
2645 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2646 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2647 M_LDA(REG_PV, REG_RA, -disp);
2650 case ICMD_INVOKEINTERFACE:
2652 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
2658 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2659 sizeof(methodptr*) * lm->class->index;
2661 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2664 /* implicit null-pointer check */
2665 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2666 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2667 M_ALD(REG_PV, REG_METHODPTR, s2);
2669 /* generate the actual call */
2671 M_JSR(REG_RA, REG_PV);
2672 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2673 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2674 M_LDA(REG_PV, REG_RA, -disp);
2678 /* store the return value */
2680 d = md->returntype.type;
2682 if (d != TYPE_VOID) {
2683 if (IS_INT_LNG_TYPE(d)) {
2684 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2685 M_INTMOVE(REG_RESULT, s1);
2688 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2689 M_FLTMOVE(REG_FRESULT, s1);
2691 emit_store_dst(jd, iptr, s1);
2696 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2698 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2699 /* object type cast-check */
2704 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2709 super = iptr->sx.s23.s3.c.cls;
2710 superindex = super->index;
2713 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2714 CODEGEN_CRITICAL_SECTION_NEW;
2716 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2718 /* if class is not resolved, check which code to call */
2720 if (super == NULL) {
2721 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2723 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2725 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
2726 iptr->sx.s23.s3.c.ref,
2729 M_ILD(REG_ITMP2, REG_PV, disp);
2730 disp = dseg_add_s4(cd, ACC_INTERFACE);
2731 M_ILD(REG_ITMP3, REG_PV, disp);
2732 M_AND(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2733 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
2736 /* interface checkcast code */
2738 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2739 if (super == NULL) {
2740 patcher_add_patch_ref(jd,
2741 PATCHER_checkcast_interface,
2742 iptr->sx.s23.s3.c.ref,
2746 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2748 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2749 M_ILD(REG_ITMP3, REG_ITMP2,
2750 OFFSET(vftbl_t, interfacetablelength));
2751 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
2752 emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2754 M_ALD(REG_ITMP3, REG_ITMP2,
2755 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2756 superindex * sizeof(methodptr*)));
2757 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
2760 emit_label_br(cd, BRANCH_LABEL_4);
2762 emit_label(cd, BRANCH_LABEL_3);
2765 /* class checkcast code */
2767 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2768 if (super == NULL) {
2769 emit_label(cd, BRANCH_LABEL_2);
2771 disp = dseg_add_unique_address(cd, NULL);
2773 patcher_add_patch_ref(jd,
2774 PATCHER_resolve_classref_to_vftbl,
2775 iptr->sx.s23.s3.c.ref,
2779 disp = dseg_add_address(cd, super->vftbl);
2781 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2784 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2785 M_ALD(REG_ITMP3, REG_PV, disp);
2787 CODEGEN_CRITICAL_SECTION_START;
2789 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2790 /* if (s1 != REG_ITMP1) { */
2791 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
2792 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
2793 /* #if defined(ENABLE_THREADS) */
2794 /* codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase); */
2796 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
2799 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2800 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2801 M_ALD(REG_ITMP3, REG_PV, disp);
2802 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2804 CODEGEN_CRITICAL_SECTION_END;
2807 M_CMPULE(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2808 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
2811 emit_label(cd, BRANCH_LABEL_5);
2814 if (super == NULL) {
2815 emit_label(cd, BRANCH_LABEL_1);
2816 emit_label(cd, BRANCH_LABEL_4);
2819 d = codegen_reg_of_dst(jd, iptr, s1);
2822 /* array type cast-check */
2824 s1 = emit_load_s1(jd, iptr, REG_A0);
2825 M_INTMOVE(s1, REG_A0);
2827 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2828 disp = dseg_add_unique_address(cd, NULL);
2830 patcher_add_patch_ref(jd,
2831 PATCHER_resolve_classref_to_classinfo,
2832 iptr->sx.s23.s3.c.ref,
2836 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2838 M_ALD(REG_A1, REG_PV, disp);
2839 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
2840 M_ALD(REG_PV, REG_PV, disp);
2841 M_JSR(REG_RA, REG_PV);
2842 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2843 M_LDA(REG_PV, REG_RA, -disp);
2845 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2846 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2848 d = codegen_reg_of_dst(jd, iptr, s1);
2852 emit_store_dst(jd, iptr, d);
2855 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2859 vftbl_t *supervftbl;
2862 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2868 super = iptr->sx.s23.s3.c.cls;
2869 superindex = super->index;
2870 supervftbl = super->vftbl;
2873 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2874 CODEGEN_CRITICAL_SECTION_NEW;
2876 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2877 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2880 M_MOV(s1, REG_ITMP1);
2884 /* if class is not resolved, check which code to call */
2886 if (super == NULL) {
2888 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2890 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2892 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
2893 iptr->sx.s23.s3.c.ref, disp);
2895 M_ILD(REG_ITMP3, REG_PV, disp);
2897 disp = dseg_add_s4(cd, ACC_INTERFACE);
2898 M_ILD(REG_ITMP2, REG_PV, disp);
2899 M_AND(REG_ITMP3, REG_ITMP2, REG_ITMP3);
2900 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
2903 /* interface instanceof code */
2905 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2906 if (super == NULL) {
2907 /* If d == REG_ITMP2, then it's destroyed in check
2912 patcher_add_patch_ref(jd,
2913 PATCHER_instanceof_interface,
2914 iptr->sx.s23.s3.c.ref, 0);
2918 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2921 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2922 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2923 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
2924 M_BLEZ(REG_ITMP3, 2);
2925 M_ALD(REG_ITMP1, REG_ITMP1,
2926 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2927 superindex * sizeof(methodptr*)));
2928 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
2931 emit_label_br(cd, BRANCH_LABEL_4);
2933 emit_label(cd, BRANCH_LABEL_3);
2936 /* class instanceof code */
2938 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2939 if (super == NULL) {
2940 emit_label(cd, BRANCH_LABEL_2);
2942 disp = dseg_add_unique_address(cd, NULL);
2944 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl,
2945 iptr->sx.s23.s3.c.ref,
2949 disp = dseg_add_address(cd, supervftbl);
2952 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2955 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2956 M_ALD(REG_ITMP2, REG_PV, disp);
2958 CODEGEN_CRITICAL_SECTION_START;
2960 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
2961 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
2962 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
2964 CODEGEN_CRITICAL_SECTION_END;
2966 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
2967 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
2970 emit_label(cd, BRANCH_LABEL_5);
2973 if (super == NULL) {
2974 emit_label(cd, BRANCH_LABEL_1);
2975 emit_label(cd, BRANCH_LABEL_4);
2978 emit_store_dst(jd, iptr, d);
2982 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2984 /* check for negative sizes and copy sizes to stack if necessary */
2986 MCODECHECK((iptr->s1.argcount << 1) + 64);
2988 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2990 var = VAR(iptr->sx.s23.s2.args[s1]);
2992 /* copy SAVEDVAR sizes to stack */
2994 /* Already Preallocated? */
2996 if (!(var->flags & PREALLOC)) {
2997 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2998 M_LST(s2, REG_SP, s1 * 8);
3002 /* a0 = dimension count */
3004 ICONST(REG_A0, iptr->s1.argcount);
3006 /* is patcher function set? */
3008 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3009 disp = dseg_add_unique_address(cd, 0);
3011 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
3012 iptr->sx.s23.s3.c.ref,
3016 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3018 /* a1 = arraydescriptor */
3020 M_ALD(REG_A1, REG_PV, disp);
3022 /* a2 = pointer to dimensions = stack pointer */
3024 M_INTMOVE(REG_SP, REG_A2);
3026 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3027 M_ALD(REG_PV, REG_PV, disp);
3028 M_JSR(REG_RA, REG_PV);
3029 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3030 M_LDA(REG_PV, REG_RA, -disp);
3032 /* check for exception before result assignment */
3034 emit_exception_check(cd, iptr);
3036 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3037 M_INTMOVE(REG_RESULT, d);
3038 emit_store_dst(jd, iptr, d);
3042 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3047 } /* for instruction */
3049 } /* if (bptr -> flags >= BBREACHED) */
3050 } /* for basic block */
3052 /* generate traps */
3054 emit_patcher_traps(jd);
3056 /* everything's ok */
3062 /* codegen_emit_stub_native ****************************************************
3064 Emits a stub routine which calls a native method.
3066 *******************************************************************************/
3068 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
3079 /* get required compiler data */
3085 /* initialize variables */
3089 /* calculate stack frame size */
3091 cd->stackframesize =
3092 1 + /* return address */
3093 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
3094 sizeof(localref_table) / SIZEOF_VOID_P +
3095 1 + /* methodinfo for call trace */
3099 /* create method header */
3101 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3102 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3103 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3104 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3105 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3107 /* generate stub code */
3109 M_LDA(REG_SP, REG_SP, -(cd->stackframesize * 8));
3110 M_AST(REG_RA, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3112 #if defined(ENABLE_GC_CACAO)
3113 /* Save callee saved integer registers in stackframeinfo (GC may
3114 need to recover them during a collection). */
3116 disp = cd->stackframesize * 8 - SIZEOF_VOID_P - sizeof(stackframeinfo_t) +
3117 OFFSET(stackframeinfo_t, intregs);
3119 for (i = 0; i < INT_SAV_CNT; i++)
3120 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3123 /* save integer and float argument registers */
3125 for (i = 0; i < md->paramcount; i++) {
3126 if (!md->params[i].inmemory) {
3127 s1 = md->params[i].regoff;
3129 switch (md->paramtypes[i].type) {
3133 M_LST(s1, REG_SP, i * 8);
3136 M_FST(s1, REG_SP, i * 8);
3139 M_DST(s1, REG_SP, i * 8);
3145 /* prepare data structures for native function call */
3147 M_MOV(REG_SP, REG_A0);
3148 M_MOV(REG_PV, REG_A1);
3149 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3150 M_ALD(REG_PV, REG_PV, disp);
3151 M_JSR(REG_RA, REG_PV);
3152 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3153 M_LDA(REG_PV, REG_RA, -disp);
3155 /* remember class argument */
3157 if (m->flags & ACC_STATIC)
3158 M_MOV(REG_RESULT, REG_ITMP3);
3160 /* restore integer and float argument registers */
3162 for (i = 0; i < md->paramcount; i++) {
3163 if (!md->params[i].inmemory) {
3164 s1 = md->params[i].regoff;
3166 switch (md->paramtypes[i].type) {
3170 M_LLD(s1, REG_SP, i * 8);
3173 M_FLD(s1, REG_SP, i * 8);
3176 M_DLD(s1, REG_SP, i * 8);
3182 /* copy or spill arguments to new locations */
3184 for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
3185 t = md->paramtypes[i].type;
3187 if (IS_INT_LNG_TYPE(t)) {
3188 if (!md->params[i].inmemory) {
3189 s1 = md->params[i].regoff;
3190 s2 = nmd->params[j].regoff;
3192 if (!nmd->params[j].inmemory)
3195 M_LST(s1, REG_SP, s2);
3198 s1 = md->params[i].regoff + cd->stackframesize * 8;
3199 s2 = nmd->params[j].regoff;
3200 M_LLD(REG_ITMP1, REG_SP, s1);
3201 M_LST(REG_ITMP1, REG_SP, s2);
3205 if (!md->params[i].inmemory) {
3206 s1 = md->params[i].regoff;
3207 s2 = nmd->params[j].regoff;
3209 if (!nmd->params[j].inmemory)
3212 if (IS_2_WORD_TYPE(t))
3213 M_DST(s1, REG_SP, s2);
3215 M_FST(s1, REG_SP, s2);
3219 s1 = md->params[i].regoff + cd->stackframesize * 8;
3220 s2 = nmd->params[j].regoff;
3221 M_DLD(REG_FTMP1, REG_SP, s1);
3222 if (IS_2_WORD_TYPE(t))
3223 M_DST(REG_FTMP1, REG_SP, s2);
3225 M_FST(REG_FTMP1, REG_SP, s2);
3230 /* Handle native Java methods. */
3232 if (m->flags & ACC_NATIVE) {
3233 /* put class into second argument register */
3235 if (m->flags & ACC_STATIC)
3236 M_MOV(REG_ITMP3, REG_A1);
3238 /* put env into first argument register */
3240 disp = dseg_add_address(cd, _Jv_env);
3241 M_ALD(REG_A0, REG_PV, disp);
3244 /* Call the native function. */
3246 disp = dseg_add_functionptr(cd, f);
3247 M_ALD(REG_PV, REG_PV, disp);
3248 M_JSR(REG_RA, REG_PV); /* call native method */
3249 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3250 M_LDA(REG_PV, REG_RA, -disp); /* recompute pv from ra */
3252 /* save return value */
3254 switch (md->returntype.type) {
3258 M_LST(REG_RESULT, REG_SP, 0 * 8);
3261 M_FST(REG_FRESULT, REG_SP, 0 * 8);
3264 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3270 /* remove native stackframe info */
3272 M_MOV(REG_SP, REG_A0);
3273 M_MOV(REG_PV, REG_A1);
3274 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3275 M_ALD(REG_PV, REG_PV, disp);
3276 M_JSR(REG_RA, REG_PV);
3277 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3278 M_LDA(REG_PV, REG_RA, -disp);
3279 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3281 /* restore return value */
3283 switch (md->returntype.type) {
3287 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3290 M_FLD(REG_FRESULT, REG_SP, 0 * 8);
3293 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3299 #if defined(ENABLE_GC_CACAO)
3300 /* Restore callee saved integer registers from stackframeinfo (GC
3301 might have modified them during a collection). */
3303 disp = cd->stackframesize * 8 - SIZEOF_VOID_P - sizeof(stackframeinfo_t) +
3304 OFFSET(stackframeinfo_t, intregs);
3306 for (i = 0; i < INT_SAV_CNT; i++)
3307 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3310 M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* get RA */
3311 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8);
3313 /* check for exception */
3315 M_BNEZ(REG_ITMP1_XPTR, 1); /* if no exception then return */
3316 M_RET(REG_ZERO, REG_RA); /* return to caller */
3318 /* handle exception */
3320 M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address */
3322 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3323 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
3324 M_JMP(REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
3329 * These are local overrides for various environment variables in Emacs.
3330 * Please do not remove this and leave it at the end of the file, where
3331 * Emacs will automagically detect them.
3332 * ---------------------------------------------------------------------
3335 * indent-tabs-mode: t
3339 * vim:noexpandtab:sw=4:ts=4: