1 /* src/vm/jit/alpha/codegen.c - machine code generator for Alpha
3 Copyright (C) 1996-2005, 2006 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
25 Contact: cacao@cacaojvm.org
27 Authors: Andreas Krall
30 Changes: Joseph Wenninger
35 $Id: codegen.c 4908 2006-05-12 16:49:50Z edwin $
50 #include "vm/jit/alpha/arch.h"
51 #include "vm/jit/alpha/codegen.h"
53 #include "native/jni.h"
54 #include "native/native.h"
55 #include "vm/builtin.h"
56 #include "vm/exceptions.h"
57 #include "vm/global.h"
58 #include "vm/loader.h"
59 #include "vm/options.h"
60 #include "vm/stringlocal.h"
62 #include "vm/jit/asmpart.h"
63 #include "vm/jit/codegen-common.h"
64 #include "vm/jit/dseg.h"
65 #include "vm/jit/emit.h"
66 #include "vm/jit/jit.h"
67 #include "vm/jit/parse.h"
68 #include "vm/jit/patcher.h"
69 #include "vm/jit/reg.h"
70 #include "vm/jit/replace.h"
72 #if defined(ENABLE_LSRA)
73 # include "vm/jit/allocator/lsra.h"
77 /* codegen *********************************************************************
79 Generates machine code.
81 *******************************************************************************/
83 bool codegen(jitdata *jd)
88 s4 len, s1, s2, s3, d, disp;
96 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
97 builtintable_entry *bte;
99 rplpoint *replacementpoint;
101 /* get required compiler data */
107 /* prevent compiler warnings */
118 savedregs_num = (m->isleafmethod) ? 0 : 1; /* space to save the RA */
120 /* space to save used callee saved registers */
122 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
123 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
125 stackframesize = rd->memuse + savedregs_num;
127 #if defined(USE_THREADS) /* space to save argument of monitor_enter */
128 if (checksync && (m->flags & ACC_SYNCHRONIZED))
132 /* create method header */
135 stackframesize = (stackframesize + 1) & ~1; /* align stack to 16-bytes */
138 (void) dseg_addaddress(cd, m); /* MethodPointer */
139 (void) dseg_adds4(cd, stackframesize * 8); /* FrameSize */
141 #if defined(USE_THREADS)
142 /* IsSync contains the offset relative to the stack pointer for the
143 argument of monitor_exit used in the exception handler. Since the
144 offset could be zero and give a wrong meaning of the flag it is
148 if (checksync && (m->flags & ACC_SYNCHRONIZED))
149 (void) dseg_adds4(cd, (rd->memuse + 1) * 8); /* IsSync */
152 (void) dseg_adds4(cd, 0); /* IsSync */
154 (void) dseg_adds4(cd, m->isleafmethod); /* IsLeaf */
155 (void) dseg_adds4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
156 (void) dseg_adds4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
158 dseg_addlinenumbertablesize(cd);
160 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
162 /* create exception table */
164 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
165 dseg_addtarget(cd, ex->start);
166 dseg_addtarget(cd, ex->end);
167 dseg_addtarget(cd, ex->handler);
168 (void) dseg_addaddress(cd, ex->catchtype.cls);
171 /* create stack frame (if necessary) */
174 M_LDA(REG_SP, REG_SP, -stackframesize * 8);
176 /* save return address and used callee saved registers */
179 if (!m->isleafmethod) {
180 p--; M_AST(REG_RA, REG_SP, p * 8);
182 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
183 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
185 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
186 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
189 /* take arguments out of register or stack frame */
193 for (p = 0, l = 0; p < md->paramcount; p++) {
194 t = md->paramtypes[p].type;
195 var = &(rd->locals[l][t]);
197 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
201 s1 = md->params[p].regoff;
202 if (IS_INT_LNG_TYPE(t)) { /* integer args */
203 if (!md->params[p].inmemory) { /* register arguments */
204 s2 = rd->argintregs[s1];
205 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
206 M_INTMOVE(s2, var->regoff);
208 } else { /* reg arg -> spilled */
209 M_LST(s2, REG_SP, var->regoff * 8);
212 } else { /* stack arguments */
213 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
214 M_LLD(var->regoff, REG_SP, (stackframesize + s1) * 8);
216 } else { /* stack arg -> spilled */
217 var->regoff = stackframesize + s1;
221 } else { /* floating args */
222 if (!md->params[p].inmemory) { /* register arguments */
223 s2 = rd->argfltregs[s1];
224 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
225 M_FLTMOVE(s2, var->regoff);
227 } else { /* reg arg -> spilled */
228 M_DST(s2, REG_SP, var->regoff * 8);
231 } else { /* stack arguments */
232 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
233 M_DLD(var->regoff, REG_SP, (stackframesize + s1) * 8);
235 } else { /* stack-arg -> spilled */
236 var->regoff = stackframesize + s1;
242 /* call monitorenter function */
244 #if defined(USE_THREADS)
245 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
246 /* stack offset for monitor argument */
251 if (opt_verbosecall) {
252 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
254 for (p = 0; p < INT_ARG_CNT; p++)
255 M_LST(rd->argintregs[p], REG_SP, p * 8);
257 for (p = 0; p < FLT_ARG_CNT; p++)
258 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
260 s1 += INT_ARG_CNT + FLT_ARG_CNT;
262 #endif /* !defined(NDEBUG) */
264 /* decide which monitor enter function to call */
266 if (m->flags & ACC_STATIC) {
267 disp = dseg_addaddress(cd, m->class);
268 M_ALD(rd->argintregs[0], REG_PV, disp);
269 M_AST(rd->argintregs[0], REG_SP, s1 * 8);
270 disp = dseg_addaddress(cd, BUILTIN_staticmonitorenter);
271 M_ALD(REG_PV, REG_PV, disp);
272 M_JSR(REG_RA, REG_PV);
273 disp = (s4) (cd->mcodeptr - cd->mcodebase);
274 M_LDA(REG_PV, REG_RA, -disp);
277 M_BEQZ(rd->argintregs[0], 0);
278 codegen_add_nullpointerexception_ref(cd);
279 M_AST(rd->argintregs[0], REG_SP, s1 * 8);
280 disp = dseg_addaddress(cd, BUILTIN_monitorenter);
281 M_ALD(REG_PV, REG_PV, disp);
282 M_JSR(REG_RA, REG_PV);
283 disp = (s4) (cd->mcodeptr - cd->mcodebase);
284 M_LDA(REG_PV, REG_RA, -disp);
288 if (opt_verbosecall) {
289 for (p = 0; p < INT_ARG_CNT; p++)
290 M_LLD(rd->argintregs[p], REG_SP, p * 8);
292 for (p = 0; p < FLT_ARG_CNT; p++)
293 M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
295 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
297 #endif /* !defined(NDEBUG) */
301 /* call trace function */
304 if (opt_verbosecall) {
305 M_LDA(REG_SP, REG_SP, -((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
306 M_AST(REG_RA, REG_SP, 1 * 8);
308 /* save integer argument registers */
310 for (p = 0; p < md->paramcount && p < INT_ARG_CNT; p++)
311 M_LST(rd->argintregs[p], REG_SP, (2 + p) * 8);
313 /* save and copy float arguments into integer registers */
315 for (p = 0; p < md->paramcount && p < FLT_ARG_CNT; p++) {
316 t = md->paramtypes[p].type;
318 if (IS_FLT_DBL_TYPE(t)) {
319 if (IS_2_WORD_TYPE(t)) {
320 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
323 M_FST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
326 M_LLD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
329 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
333 disp = dseg_addaddress(cd, m);
334 M_ALD(REG_ITMP1, REG_PV, disp);
335 M_AST(REG_ITMP1, REG_SP, 0 * 8);
336 disp = dseg_addaddress(cd, (void *) builtin_trace_args);
337 M_ALD(REG_PV, REG_PV, disp);
338 M_JSR(REG_RA, REG_PV);
339 disp = (s4) (cd->mcodeptr - cd->mcodebase);
340 M_LDA(REG_PV, REG_RA, -disp);
341 M_ALD(REG_RA, REG_SP, 1 * 8);
343 /* restore integer argument registers */
345 for (p = 0; p < md->paramcount && p < INT_ARG_CNT; p++)
346 M_LLD(rd->argintregs[p], REG_SP, (2 + p) * 8);
348 /* restore float argument registers */
350 for (p = 0; p < md->paramcount && p < FLT_ARG_CNT; p++) {
351 t = md->paramtypes[p].type;
353 if (IS_FLT_DBL_TYPE(t)) {
354 if (IS_2_WORD_TYPE(t)) {
355 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
358 M_FLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
362 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
366 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT + 2) * 8);
368 #endif /* !defined(NDEBUG) */
372 /* end of header generation */
374 replacementpoint = jd->code->rplpoints;
376 /* walk through all basic blocks */
378 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
380 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
382 if (bptr->flags >= BBREACHED) {
384 /* branch resolving */
388 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
389 gen_resolvebranch((u1*) cd->mcodebase + brefs->branchpos,
390 brefs->branchpos, bptr->mpc);
394 /* handle replacement points */
396 if (bptr->bitflags & BBFLAG_REPLACEMENT) {
397 replacementpoint->pc = (u1*)(ptrint)bptr->mpc; /* will be resolved later */
402 /* copy interface registers to their destination */
407 #if defined(ENABLE_LSRA)
409 while (src != NULL) {
411 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
412 /* d = reg_of_var(m, src, REG_ITMP1); */
413 if (!(src->flags & INMEMORY))
417 M_INTMOVE(REG_ITMP1, d);
418 emit_store(jd, NULL, src, d);
424 while (src != NULL) {
426 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
427 d = codegen_reg_of_var(rd, 0, src, REG_ITMP1);
428 M_INTMOVE(REG_ITMP1, d);
429 emit_store(jd, NULL, src, d);
432 d = codegen_reg_of_var(rd, 0, src, REG_IFTMP);
433 if ((src->varkind != STACKVAR)) {
435 if (IS_FLT_DBL_TYPE(s2)) {
436 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
437 s1 = rd->interfaces[len][s2].regoff;
440 M_DLD(d, REG_SP, rd->interfaces[len][s2].regoff * 8);
442 emit_store(jd, NULL, src, d);
445 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
446 s1 = rd->interfaces[len][s2].regoff;
449 M_LLD(d, REG_SP, rd->interfaces[len][s2].regoff * 8);
451 emit_store(jd, NULL, src, d);
457 #if defined(ENABLE_LSRA)
461 /* walk through all instructions */
466 for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
467 if (iptr->line != currentline) {
468 dseg_addlinenumber(cd, iptr->line);
469 currentline = iptr->line;
472 MCODECHECK(64); /* an instruction usually needs < 64 words */
475 case ICMD_INLINE_START:
476 case ICMD_INLINE_END:
479 case ICMD_NOP: /* ... ==> ... */
482 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
484 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
486 codegen_add_nullpointerexception_ref(cd);
489 /* constant operations ************************************************/
491 case ICMD_ICONST: /* ... ==> ..., constant */
492 /* op1 = 0, val.i = constant */
494 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
495 ICONST(d, iptr->val.i);
496 emit_store(jd, iptr, iptr->dst, d);
499 case ICMD_LCONST: /* ... ==> ..., constant */
500 /* op1 = 0, val.l = constant */
502 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
503 LCONST(d, iptr->val.l);
504 emit_store(jd, iptr, iptr->dst, d);
507 case ICMD_FCONST: /* ... ==> ..., constant */
508 /* op1 = 0, val.f = constant */
510 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
511 disp = dseg_addfloat(cd, iptr->val.f);
512 M_FLD(d, REG_PV, disp);
513 emit_store(jd, iptr, iptr->dst, d);
516 case ICMD_DCONST: /* ... ==> ..., constant */
517 /* op1 = 0, val.d = constant */
519 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
520 disp = dseg_adddouble(cd, iptr->val.d);
521 M_DLD(d, REG_PV, disp);
522 emit_store(jd, iptr, iptr->dst, d);
525 case ICMD_ACONST: /* ... ==> ..., constant */
526 /* op1 = 0, val.a = constant */
528 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
530 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
531 disp = dseg_addaddress(cd, NULL);
533 codegen_addpatchref(cd, PATCHER_aconst,
534 ICMD_ACONST_UNRESOLVED_CLASSREF(iptr),
537 if (opt_showdisassemble)
540 M_ALD(d, REG_PV, disp);
543 if (iptr->val.a == NULL) {
544 M_INTMOVE(REG_ZERO, d);
546 disp = dseg_addaddress(cd, iptr->val.a);
547 M_ALD(d, REG_PV, disp);
550 emit_store(jd, iptr, iptr->dst, d);
554 /* load/store operations **********************************************/
556 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
557 case ICMD_LLOAD: /* op1 = local variable */
560 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
561 if ((iptr->dst->varkind == LOCALVAR) &&
562 (iptr->dst->varnum == iptr->op1))
564 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
565 if (var->flags & INMEMORY) {
566 M_LLD(d, REG_SP, var->regoff * 8);
568 M_INTMOVE(var->regoff, d);
570 emit_store(jd, iptr, iptr->dst, d);
573 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
574 case ICMD_DLOAD: /* op1 = local variable */
576 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
577 if ((iptr->dst->varkind == LOCALVAR) &&
578 (iptr->dst->varnum == iptr->op1))
580 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
581 if (var->flags & INMEMORY) {
582 M_DLD(d, REG_SP, var->regoff * 8);
584 M_FLTMOVE(var->regoff, d);
586 emit_store(jd, iptr, iptr->dst, d);
590 case ICMD_ISTORE: /* ..., value ==> ... */
591 case ICMD_LSTORE: /* op1 = local variable */
594 if ((src->varkind == LOCALVAR) &&
595 (src->varnum == iptr->op1))
597 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
598 if (var->flags & INMEMORY) {
599 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
600 M_LST(s1, REG_SP, var->regoff * 8);
602 s1 = emit_load_s1(jd, iptr, src, var->regoff);
603 M_INTMOVE(s1, var->regoff);
607 case ICMD_FSTORE: /* ..., value ==> ... */
608 case ICMD_DSTORE: /* op1 = local variable */
610 if ((src->varkind == LOCALVAR) &&
611 (src->varnum == iptr->op1))
613 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
614 if (var->flags & INMEMORY) {
615 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
616 M_DST(s1, REG_SP, var->regoff * 8);
618 s1 = emit_load_s1(jd, iptr, src, var->regoff);
619 M_FLTMOVE(s1, var->regoff);
624 /* pop/dup/swap operations ********************************************/
626 /* attention: double and longs are only one entry in CACAO ICMDs */
628 case ICMD_POP: /* ..., value ==> ... */
629 case ICMD_POP2: /* ..., value, value ==> ... */
632 case ICMD_DUP: /* ..., a ==> ..., a, a */
633 M_COPY(src, iptr->dst);
636 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
638 M_COPY(src, iptr->dst);
639 M_COPY(src->prev, iptr->dst->prev);
640 M_COPY(iptr->dst, iptr->dst->prev->prev);
643 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
645 M_COPY(src, iptr->dst);
646 M_COPY(src->prev, iptr->dst->prev);
647 M_COPY(src->prev->prev, iptr->dst->prev->prev);
648 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
651 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
653 M_COPY(src, iptr->dst);
654 M_COPY(src->prev, iptr->dst->prev);
657 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
659 M_COPY(src, iptr->dst);
660 M_COPY(src->prev, iptr->dst->prev);
661 M_COPY(src->prev->prev, iptr->dst->prev->prev);
662 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
663 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev);
666 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
668 M_COPY(src, iptr->dst);
669 M_COPY(src->prev, iptr->dst->prev);
670 M_COPY(src->prev->prev, iptr->dst->prev->prev);
671 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
672 M_COPY(iptr->dst, iptr->dst->prev->prev->prev->prev);
673 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev->prev);
676 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
678 M_COPY(src, iptr->dst->prev);
679 M_COPY(src->prev, iptr->dst);
683 /* integer operations *************************************************/
685 case ICMD_INEG: /* ..., value ==> ..., - value */
687 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
688 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
689 M_ISUB(REG_ZERO, s1, d);
690 emit_store(jd, iptr, iptr->dst, d);
693 case ICMD_LNEG: /* ..., value ==> ..., - value */
695 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
696 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
697 M_LSUB(REG_ZERO, s1, d);
698 emit_store(jd, iptr, iptr->dst, d);
701 case ICMD_I2L: /* ..., value ==> ..., value */
703 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
704 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
706 emit_store(jd, iptr, iptr->dst, d);
709 case ICMD_L2I: /* ..., value ==> ..., value */
711 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
712 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
713 M_IADD(s1, REG_ZERO, d);
714 emit_store(jd, iptr, iptr->dst, d);
717 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
719 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
720 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
721 if (has_ext_instr_set) {
724 M_SLL_IMM(s1, 56, d);
725 M_SRA_IMM( d, 56, d);
727 emit_store(jd, iptr, iptr->dst, d);
730 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
732 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
733 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
735 emit_store(jd, iptr, iptr->dst, d);
738 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
740 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
741 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
742 if (has_ext_instr_set) {
745 M_SLL_IMM(s1, 48, d);
746 M_SRA_IMM( d, 48, d);
748 emit_store(jd, iptr, iptr->dst, d);
752 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
754 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
755 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
756 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
758 emit_store(jd, iptr, iptr->dst, d);
761 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
762 /* val.i = constant */
764 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
765 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
766 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
767 M_IADD_IMM(s1, iptr->val.i, d);
769 ICONST(REG_ITMP2, iptr->val.i);
770 M_IADD(s1, REG_ITMP2, d);
772 emit_store(jd, iptr, iptr->dst, d);
775 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
777 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
778 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
779 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
781 emit_store(jd, iptr, iptr->dst, d);
784 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
785 /* val.l = constant */
787 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
788 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
789 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
790 M_LADD_IMM(s1, iptr->val.l, d);
792 LCONST(REG_ITMP2, iptr->val.l);
793 M_LADD(s1, REG_ITMP2, d);
795 emit_store(jd, iptr, iptr->dst, d);
798 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
800 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
801 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
802 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
804 emit_store(jd, iptr, iptr->dst, d);
807 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
808 /* val.i = constant */
810 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
811 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
812 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
813 M_ISUB_IMM(s1, iptr->val.i, d);
815 ICONST(REG_ITMP2, iptr->val.i);
816 M_ISUB(s1, REG_ITMP2, d);
818 emit_store(jd, iptr, iptr->dst, d);
821 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
823 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
824 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
825 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
827 emit_store(jd, iptr, iptr->dst, d);
830 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
831 /* val.l = constant */
833 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
834 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
835 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
836 M_LSUB_IMM(s1, iptr->val.l, d);
838 LCONST(REG_ITMP2, iptr->val.l);
839 M_LSUB(s1, REG_ITMP2, d);
841 emit_store(jd, iptr, iptr->dst, d);
844 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
846 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
847 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
848 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
850 emit_store(jd, iptr, iptr->dst, d);
853 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
854 /* val.i = constant */
856 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
857 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
858 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
859 M_IMUL_IMM(s1, iptr->val.i, d);
861 ICONST(REG_ITMP2, iptr->val.i);
862 M_IMUL(s1, REG_ITMP2, d);
864 emit_store(jd, iptr, iptr->dst, d);
867 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
869 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
870 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
871 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
873 emit_store(jd, iptr, iptr->dst, d);
876 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
877 /* val.l = constant */
879 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
880 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
881 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
882 M_LMUL_IMM(s1, iptr->val.l, d);
884 LCONST(REG_ITMP2, iptr->val.l);
885 M_LMUL(s1, REG_ITMP2, d);
887 emit_store(jd, iptr, iptr->dst, d);
890 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
891 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
893 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
894 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
895 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT);
897 codegen_add_arithmeticexception_ref(cd);
899 M_MOV(s1, rd->argintregs[0]);
900 M_MOV(s2, rd->argintregs[1]);
902 disp = dseg_addaddress(cd, bte->fp);
903 M_ALD(REG_PV, REG_PV, disp);
904 M_JSR(REG_RA, REG_PV);
905 disp = (s4) (cd->mcodeptr - cd->mcodebase);
906 M_LDA(REG_PV, REG_RA, -disp);
908 M_IADD(REG_RESULT, REG_ZERO, d); /* sign extend (bugfix for gcc -O2) */
909 emit_store(jd, iptr, iptr->dst, d);
912 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
913 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
915 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
916 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
917 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT);
919 codegen_add_arithmeticexception_ref(cd);
921 M_MOV(s1, rd->argintregs[0]);
922 M_MOV(s2, rd->argintregs[1]);
924 disp = dseg_addaddress(cd, bte->fp);
925 M_ALD(REG_PV, REG_PV, disp);
926 M_JSR(REG_RA, REG_PV);
927 disp = (s4) (cd->mcodeptr - cd->mcodebase);
928 M_LDA(REG_PV, REG_RA, -disp);
930 M_INTMOVE(REG_RESULT, d);
931 emit_store(jd, iptr, iptr->dst, d);
934 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
935 case ICMD_LDIVPOW2: /* val.i = constant */
937 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
938 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
939 if (iptr->val.i <= 15) {
940 M_LDA(REG_ITMP2, s1, (1 << iptr->val.i) -1);
941 M_CMOVGE(s1, s1, REG_ITMP2);
943 M_SRA_IMM(s1, 63, REG_ITMP2);
944 M_SRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
945 M_LADD(s1, REG_ITMP2, REG_ITMP2);
947 M_SRA_IMM(REG_ITMP2, iptr->val.i, d);
948 emit_store(jd, iptr, iptr->dst, d);
951 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
953 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
954 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
955 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
956 M_AND_IMM(s2, 0x1f, REG_ITMP3);
957 M_SLL(s1, REG_ITMP3, d);
958 M_IADD(d, REG_ZERO, d);
959 emit_store(jd, iptr, iptr->dst, d);
962 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
963 /* val.i = constant */
965 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
966 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
967 M_SLL_IMM(s1, iptr->val.i & 0x1f, d);
968 M_IADD(d, REG_ZERO, d);
969 emit_store(jd, iptr, iptr->dst, d);
972 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
974 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
975 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
976 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
977 M_AND_IMM(s2, 0x1f, REG_ITMP3);
978 M_SRA(s1, REG_ITMP3, d);
979 emit_store(jd, iptr, iptr->dst, d);
982 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
983 /* val.i = constant */
985 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
986 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
987 M_SRA_IMM(s1, iptr->val.i & 0x1f, d);
988 emit_store(jd, iptr, iptr->dst, d);
991 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
993 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
994 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
995 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
996 M_AND_IMM(s2, 0x1f, REG_ITMP2);
998 M_SRL(d, REG_ITMP2, d);
999 M_IADD(d, REG_ZERO, d);
1000 emit_store(jd, iptr, iptr->dst, d);
1003 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1004 /* val.i = constant */
1006 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1007 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1009 M_SRL_IMM(d, iptr->val.i & 0x1f, d);
1010 M_IADD(d, REG_ZERO, d);
1011 emit_store(jd, iptr, iptr->dst, d);
1014 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1016 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1017 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1018 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1020 emit_store(jd, iptr, iptr->dst, d);
1023 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1024 /* val.i = constant */
1026 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1027 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1028 M_SLL_IMM(s1, iptr->val.i & 0x3f, d);
1029 emit_store(jd, iptr, iptr->dst, d);
1032 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1034 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1035 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1036 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1038 emit_store(jd, iptr, iptr->dst, d);
1041 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1042 /* val.i = constant */
1044 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1045 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1046 M_SRA_IMM(s1, iptr->val.i & 0x3f, d);
1047 emit_store(jd, iptr, iptr->dst, d);
1050 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1052 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1053 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1054 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1056 emit_store(jd, iptr, iptr->dst, d);
1059 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1060 /* val.i = constant */
1062 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1063 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1064 M_SRL_IMM(s1, iptr->val.i & 0x3f, d);
1065 emit_store(jd, iptr, iptr->dst, d);
1068 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1071 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1072 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1073 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1075 emit_store(jd, iptr, iptr->dst, d);
1078 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1079 /* val.i = constant */
1081 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1082 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1083 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1084 M_AND_IMM(s1, iptr->val.i, d);
1085 } else if (iptr->val.i == 0xffff) {
1087 } else if (iptr->val.i == 0xffffff) {
1088 M_ZAPNOT_IMM(s1, 0x07, d);
1090 ICONST(REG_ITMP2, iptr->val.i);
1091 M_AND(s1, REG_ITMP2, d);
1093 emit_store(jd, iptr, iptr->dst, d);
1096 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1097 /* val.i = constant */
1099 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1100 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1102 M_MOV(s1, REG_ITMP1);
1105 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1106 M_AND_IMM(s1, iptr->val.i, d);
1108 M_ISUB(REG_ZERO, s1, d);
1109 M_AND_IMM(d, iptr->val.i, d);
1110 } else if (iptr->val.i == 0xffff) {
1113 M_ISUB(REG_ZERO, s1, d);
1115 } else if (iptr->val.i == 0xffffff) {
1116 M_ZAPNOT_IMM(s1, 0x07, d);
1118 M_ISUB(REG_ZERO, s1, d);
1119 M_ZAPNOT_IMM(d, 0x07, d);
1121 ICONST(REG_ITMP2, iptr->val.i);
1122 M_AND(s1, REG_ITMP2, d);
1124 M_ISUB(REG_ZERO, s1, d);
1125 M_AND(d, REG_ITMP2, d);
1127 M_ISUB(REG_ZERO, d, d);
1128 emit_store(jd, iptr, iptr->dst, d);
1131 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1132 /* val.l = constant */
1134 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1135 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1136 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1137 M_AND_IMM(s1, iptr->val.l, d);
1138 } else if (iptr->val.l == 0xffffL) {
1140 } else if (iptr->val.l == 0xffffffL) {
1141 M_ZAPNOT_IMM(s1, 0x07, d);
1142 } else if (iptr->val.l == 0xffffffffL) {
1144 } else if (iptr->val.l == 0xffffffffffL) {
1145 M_ZAPNOT_IMM(s1, 0x1f, d);
1146 } else if (iptr->val.l == 0xffffffffffffL) {
1147 M_ZAPNOT_IMM(s1, 0x3f, d);
1148 } else if (iptr->val.l == 0xffffffffffffffL) {
1149 M_ZAPNOT_IMM(s1, 0x7f, d);
1151 LCONST(REG_ITMP2, iptr->val.l);
1152 M_AND(s1, REG_ITMP2, d);
1154 emit_store(jd, iptr, iptr->dst, d);
1157 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1158 /* val.l = constant */
1160 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1161 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1163 M_MOV(s1, REG_ITMP1);
1166 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1167 M_AND_IMM(s1, iptr->val.l, d);
1169 M_LSUB(REG_ZERO, s1, d);
1170 M_AND_IMM(d, iptr->val.l, d);
1171 } else if (iptr->val.l == 0xffffL) {
1174 M_LSUB(REG_ZERO, s1, d);
1176 } else if (iptr->val.l == 0xffffffL) {
1177 M_ZAPNOT_IMM(s1, 0x07, d);
1179 M_LSUB(REG_ZERO, s1, d);
1180 M_ZAPNOT_IMM(d, 0x07, d);
1181 } else if (iptr->val.l == 0xffffffffL) {
1184 M_LSUB(REG_ZERO, s1, d);
1186 } else if (iptr->val.l == 0xffffffffffL) {
1187 M_ZAPNOT_IMM(s1, 0x1f, d);
1189 M_LSUB(REG_ZERO, s1, d);
1190 M_ZAPNOT_IMM(d, 0x1f, d);
1191 } else if (iptr->val.l == 0xffffffffffffL) {
1192 M_ZAPNOT_IMM(s1, 0x3f, d);
1194 M_LSUB(REG_ZERO, s1, d);
1195 M_ZAPNOT_IMM(d, 0x3f, d);
1196 } else if (iptr->val.l == 0xffffffffffffffL) {
1197 M_ZAPNOT_IMM(s1, 0x7f, d);
1199 M_LSUB(REG_ZERO, s1, d);
1200 M_ZAPNOT_IMM(d, 0x7f, d);
1202 LCONST(REG_ITMP2, iptr->val.l);
1203 M_AND(s1, REG_ITMP2, d);
1205 M_LSUB(REG_ZERO, s1, d);
1206 M_AND(d, REG_ITMP2, d);
1208 M_LSUB(REG_ZERO, d, d);
1209 emit_store(jd, iptr, iptr->dst, d);
1212 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1215 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1216 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1217 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1219 emit_store(jd, iptr, iptr->dst, d);
1222 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1223 /* val.i = constant */
1225 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1226 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1227 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1228 M_OR_IMM(s1, iptr->val.i, d);
1230 ICONST(REG_ITMP2, iptr->val.i);
1231 M_OR(s1, REG_ITMP2, d);
1233 emit_store(jd, iptr, iptr->dst, d);
1236 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1237 /* val.l = constant */
1239 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1240 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1241 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1242 M_OR_IMM(s1, iptr->val.l, d);
1244 LCONST(REG_ITMP2, iptr->val.l);
1245 M_OR(s1, REG_ITMP2, d);
1247 emit_store(jd, iptr, iptr->dst, d);
1250 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1253 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1254 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1255 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1257 emit_store(jd, iptr, iptr->dst, d);
1260 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1261 /* val.i = constant */
1263 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1264 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1265 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1266 M_XOR_IMM(s1, iptr->val.i, d);
1268 ICONST(REG_ITMP2, iptr->val.i);
1269 M_XOR(s1, REG_ITMP2, d);
1271 emit_store(jd, iptr, iptr->dst, d);
1274 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1275 /* val.l = constant */
1277 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1278 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1279 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1280 M_XOR_IMM(s1, iptr->val.l, d);
1282 LCONST(REG_ITMP2, iptr->val.l);
1283 M_XOR(s1, REG_ITMP2, d);
1285 emit_store(jd, iptr, iptr->dst, d);
1289 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1291 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1292 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1293 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1294 M_CMPLT(s1, s2, REG_ITMP3);
1295 M_CMPLT(s2, s1, REG_ITMP1);
1296 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1297 emit_store(jd, iptr, iptr->dst, d);
1301 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1302 /* op1 = variable, val.i = constant */
1304 var = &(rd->locals[iptr->op1][TYPE_INT]);
1305 if (var->flags & INMEMORY) {
1307 M_LLD(s1, REG_SP, var->regoff * 8);
1310 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1311 M_IADD_IMM(s1, iptr->val.i, s1);
1312 } else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1313 M_ISUB_IMM(s1, (-iptr->val.i), s1);
1315 M_LDA (s1, s1, iptr->val.i);
1316 M_IADD(s1, REG_ZERO, s1);
1318 if (var->flags & INMEMORY)
1319 M_LST(s1, REG_SP, var->regoff * 8);
1323 /* floating operations ************************************************/
1325 case ICMD_FNEG: /* ..., value ==> ..., - value */
1327 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1328 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1330 emit_store(jd, iptr, iptr->dst, d);
1333 case ICMD_DNEG: /* ..., value ==> ..., - value */
1335 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1336 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1338 emit_store(jd, iptr, iptr->dst, d);
1341 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1343 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1344 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1345 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1349 if (d == s1 || d == s2) {
1350 M_FADDS(s1, s2, REG_FTMP3);
1352 M_FMOV(REG_FTMP3, d);
1358 emit_store(jd, iptr, iptr->dst, d);
1361 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1363 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1364 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1365 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1369 if (d == s1 || d == s2) {
1370 M_DADDS(s1, s2, REG_FTMP3);
1372 M_FMOV(REG_FTMP3, d);
1378 emit_store(jd, iptr, iptr->dst, d);
1381 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1383 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1384 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1385 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1389 if (d == s1 || d == s2) {
1390 M_FSUBS(s1, s2, REG_FTMP3);
1392 M_FMOV(REG_FTMP3, d);
1398 emit_store(jd, iptr, iptr->dst, d);
1401 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1403 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1404 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1405 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1409 if (d == s1 || d == s2) {
1410 M_DSUBS(s1, s2, REG_FTMP3);
1412 M_FMOV(REG_FTMP3, d);
1418 emit_store(jd, iptr, iptr->dst, d);
1421 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1423 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1424 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1425 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1429 if (d == s1 || d == s2) {
1430 M_FMULS(s1, s2, REG_FTMP3);
1432 M_FMOV(REG_FTMP3, d);
1438 emit_store(jd, iptr, iptr->dst, d);
1441 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1443 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1444 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1445 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1449 if (d == s1 || d == s2) {
1450 M_DMULS(s1, s2, REG_FTMP3);
1452 M_FMOV(REG_FTMP3, d);
1458 emit_store(jd, iptr, iptr->dst, d);
1461 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1463 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1464 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1465 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1469 if (d == s1 || d == s2) {
1470 M_FDIVS(s1, s2, REG_FTMP3);
1472 M_FMOV(REG_FTMP3, d);
1478 emit_store(jd, iptr, iptr->dst, d);
1481 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1483 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1484 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1485 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1489 if (d == s1 || d == s2) {
1490 M_DDIVS(s1, s2, REG_FTMP3);
1492 M_FMOV(REG_FTMP3, d);
1498 emit_store(jd, iptr, iptr->dst, d);
1501 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1503 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1504 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1505 disp = dseg_adddouble(cd, 0.0);
1506 M_LST(s1, REG_PV, disp);
1507 M_DLD(d, REG_PV, disp);
1509 emit_store(jd, iptr, iptr->dst, d);
1512 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1514 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1515 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1516 disp = dseg_adddouble(cd, 0.0);
1517 M_LST(s1, REG_PV, disp);
1518 M_DLD(d, REG_PV, disp);
1520 emit_store(jd, iptr, iptr->dst, d);
1523 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1525 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1526 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP3);
1527 disp = dseg_adddouble(cd, 0.0);
1528 M_CVTDL_C(s1, REG_FTMP2);
1529 M_CVTLI(REG_FTMP2, REG_FTMP3);
1530 M_DST(REG_FTMP3, REG_PV, disp);
1531 M_ILD(d, REG_PV, disp);
1532 emit_store(jd, iptr, iptr->dst, d);
1535 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1537 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1538 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP3);
1539 disp = dseg_adddouble(cd, 0.0);
1540 M_CVTDL_C(s1, REG_FTMP2);
1541 M_DST(REG_FTMP2, REG_PV, disp);
1542 M_LLD(d, REG_PV, disp);
1543 emit_store(jd, iptr, iptr->dst, d);
1546 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1548 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1549 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1552 emit_store(jd, iptr, iptr->dst, d);
1555 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1557 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1558 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1565 emit_store(jd, iptr, iptr->dst, d);
1568 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1570 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1571 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1572 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP3);
1574 M_LSUB_IMM(REG_ZERO, 1, d);
1575 M_FCMPEQ(s1, s2, REG_FTMP3);
1576 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1578 M_FCMPLT(s2, s1, REG_FTMP3);
1579 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1580 M_LADD_IMM(REG_ZERO, 1, d);
1582 M_LSUB_IMM(REG_ZERO, 1, d);
1583 M_FCMPEQS(s1, s2, REG_FTMP3);
1585 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1587 M_FCMPLTS(s2, s1, REG_FTMP3);
1589 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1590 M_LADD_IMM(REG_ZERO, 1, d);
1592 emit_store(jd, iptr, iptr->dst, d);
1595 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1597 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1598 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1599 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP3);
1601 M_LADD_IMM(REG_ZERO, 1, d);
1602 M_FCMPEQ(s1, s2, REG_FTMP3);
1603 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1605 M_FCMPLT(s1, s2, REG_FTMP3);
1606 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1607 M_LSUB_IMM(REG_ZERO, 1, d);
1609 M_LADD_IMM(REG_ZERO, 1, d);
1610 M_FCMPEQS(s1, s2, REG_FTMP3);
1612 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1614 M_FCMPLTS(s1, s2, REG_FTMP3);
1616 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1617 M_LSUB_IMM(REG_ZERO, 1, d);
1619 emit_store(jd, iptr, iptr->dst, d);
1623 /* memory operations **************************************************/
1625 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1627 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1628 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1629 gen_nullptr_check(s1);
1630 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1631 emit_store(jd, iptr, iptr->dst, d);
1634 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1636 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1637 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1638 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1639 if (iptr->op1 == 0) {
1640 gen_nullptr_check(s1);
1643 if (has_ext_instr_set) {
1644 M_LADD (s2, s1, REG_ITMP1);
1645 M_BLDU (d, REG_ITMP1, OFFSET (java_bytearray, data[0]));
1648 M_LADD(s2, s1, REG_ITMP1);
1649 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1650 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
1651 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1652 M_SRA_IMM(d, 56, d);
1654 emit_store(jd, iptr, iptr->dst, d);
1657 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1659 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1660 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1661 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1662 if (iptr->op1 == 0) {
1663 gen_nullptr_check(s1);
1666 if (has_ext_instr_set) {
1667 M_LADD(s2, s1, REG_ITMP1);
1668 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1669 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1671 M_LADD (s2, s1, REG_ITMP1);
1672 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1673 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1674 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1675 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
1677 emit_store(jd, iptr, iptr->dst, d);
1680 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1682 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1683 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1684 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1685 if (iptr->op1 == 0) {
1686 gen_nullptr_check(s1);
1689 if (has_ext_instr_set) {
1690 M_LADD(s2, s1, REG_ITMP1);
1691 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1692 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1695 M_LADD(s2, s1, REG_ITMP1);
1696 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1697 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1698 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1699 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1700 M_SRA_IMM(d, 48, d);
1702 emit_store(jd, iptr, iptr->dst, d);
1705 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1707 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1708 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1709 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1710 if (iptr->op1 == 0) {
1711 gen_nullptr_check(s1);
1714 M_S4ADDQ(s2, s1, REG_ITMP1);
1715 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1716 emit_store(jd, iptr, iptr->dst, d);
1719 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1721 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1722 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1723 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1724 if (iptr->op1 == 0) {
1725 gen_nullptr_check(s1);
1728 M_S8ADDQ(s2, s1, REG_ITMP1);
1729 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1730 emit_store(jd, iptr, iptr->dst, d);
1733 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1735 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1736 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1737 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1738 if (iptr->op1 == 0) {
1739 gen_nullptr_check(s1);
1742 M_S4ADDQ(s2, s1, REG_ITMP1);
1743 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1744 emit_store(jd, iptr, iptr->dst, d);
1747 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1749 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1750 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1751 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1752 if (iptr->op1 == 0) {
1753 gen_nullptr_check(s1);
1756 M_S8ADDQ(s2, s1, REG_ITMP1);
1757 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1758 emit_store(jd, iptr, iptr->dst, d);
1761 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1763 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1764 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1765 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1766 if (iptr->op1 == 0) {
1767 gen_nullptr_check(s1);
1770 M_SAADDQ(s2, s1, REG_ITMP1);
1771 M_ALD(d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1772 emit_store(jd, iptr, iptr->dst, d);
1776 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1778 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1779 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1780 if (iptr->op1 == 0) {
1781 gen_nullptr_check(s1);
1784 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1785 if (has_ext_instr_set) {
1786 M_LADD(s2, s1, REG_ITMP1);
1787 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1789 M_LADD(s2, s1, REG_ITMP1);
1790 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1791 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1792 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
1793 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1794 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1795 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1799 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1801 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1802 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1803 if (iptr->op1 == 0) {
1804 gen_nullptr_check(s1);
1807 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1808 if (has_ext_instr_set) {
1809 M_LADD(s2, s1, REG_ITMP1);
1810 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1811 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1813 M_LADD(s2, s1, REG_ITMP1);
1814 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1815 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1816 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1817 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1818 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1819 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1820 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1824 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1826 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1827 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1828 if (iptr->op1 == 0) {
1829 gen_nullptr_check(s1);
1832 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1833 if (has_ext_instr_set) {
1834 M_LADD(s2, s1, REG_ITMP1);
1835 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1836 M_SST(s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1838 M_LADD(s2, s1, REG_ITMP1);
1839 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1840 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1841 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1842 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1843 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1844 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1845 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1849 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1851 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1852 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1853 if (iptr->op1 == 0) {
1854 gen_nullptr_check(s1);
1857 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1858 M_S4ADDQ(s2, s1, REG_ITMP1);
1859 M_IST(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1862 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1864 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1865 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1866 if (iptr->op1 == 0) {
1867 gen_nullptr_check(s1);
1870 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1871 M_S8ADDQ(s2, s1, REG_ITMP1);
1872 M_LST(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1875 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1877 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1878 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1879 if (iptr->op1 == 0) {
1880 gen_nullptr_check(s1);
1883 s3 = emit_load_s3(jd, iptr, src, REG_FTMP3);
1884 M_S4ADDQ(s2, s1, REG_ITMP1);
1885 M_FST(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1888 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1890 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1891 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1892 if (iptr->op1 == 0) {
1893 gen_nullptr_check(s1);
1896 s3 = emit_load_s3(jd, iptr, src, REG_FTMP3);
1897 M_S8ADDQ(s2, s1, REG_ITMP1);
1898 M_DST(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1901 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1903 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1904 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1905 if (iptr->op1 == 0) {
1906 gen_nullptr_check(s1);
1909 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1911 M_MOV(s1, rd->argintregs[0]);
1912 M_MOV(s3, rd->argintregs[1]);
1913 disp = dseg_addaddress(cd, BUILTIN_canstore);
1914 M_ALD(REG_PV, REG_PV, disp);
1915 M_JSR(REG_RA, REG_PV);
1916 disp = (s4) (cd->mcodeptr - cd->mcodebase);
1917 M_LDA(REG_PV, REG_RA, -disp);
1919 M_BEQZ(REG_RESULT, 0);
1920 codegen_add_arraystoreexception_ref(cd);
1922 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1923 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1924 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1925 M_SAADDQ(s2, s1, REG_ITMP1);
1926 M_AST(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1930 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1932 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1933 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1934 if (iptr->op1 == 0) {
1935 gen_nullptr_check(s1);
1938 M_S4ADDQ(s2, s1, REG_ITMP1);
1939 M_IST(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1942 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1944 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1945 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1946 if (iptr->op1 == 0) {
1947 gen_nullptr_check(s1);
1950 M_S8ADDQ(s2, s1, REG_ITMP1);
1951 M_LST(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1954 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1956 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1957 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1958 if (iptr->op1 == 0) {
1959 gen_nullptr_check(s1);
1962 M_SAADDQ(s2, s1, REG_ITMP1);
1963 M_AST(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1966 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1968 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1969 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1970 if (iptr->op1 == 0) {
1971 gen_nullptr_check(s1);
1974 if (has_ext_instr_set) {
1975 M_LADD(s2, s1, REG_ITMP1);
1976 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1979 M_LADD(s2, s1, REG_ITMP1);
1980 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1981 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1982 M_INSBL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1983 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1984 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1985 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1989 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1991 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1992 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1993 if (iptr->op1 == 0) {
1994 gen_nullptr_check(s1);
1997 if (has_ext_instr_set) {
1998 M_LADD(s2, s1, REG_ITMP1);
1999 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2000 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
2003 M_LADD(s2, s1, REG_ITMP1);
2004 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2005 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2006 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2007 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2008 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2009 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2010 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2014 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
2016 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2017 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2018 if (iptr->op1 == 0) {
2019 gen_nullptr_check(s1);
2022 if (has_ext_instr_set) {
2023 M_LADD(s2, s1, REG_ITMP1);
2024 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2025 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2028 M_LADD(s2, s1, REG_ITMP1);
2029 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2030 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2031 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2032 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2033 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2034 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2035 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2040 case ICMD_GETSTATIC: /* ... ==> ..., value */
2041 /* op1 = type, val.a = field address */
2043 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2044 disp = dseg_addaddress(cd, 0);
2046 codegen_addpatchref(cd, PATCHER_get_putstatic,
2047 INSTRUCTION_UNRESOLVED_FIELD(iptr), disp);
2049 if (opt_showdisassemble)
2054 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
2056 disp = dseg_addaddress(cd, &(fi->value));
2058 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2059 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2061 if (opt_showdisassemble)
2066 M_ALD(REG_ITMP1, REG_PV, disp);
2067 switch (iptr->op1) {
2069 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2070 M_ILD(d, REG_ITMP1, 0);
2073 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2074 M_LLD(d, REG_ITMP1, 0);
2077 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2078 M_ALD(d, REG_ITMP1, 0);
2081 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2082 M_FLD(d, REG_ITMP1, 0);
2085 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2086 M_DLD(d, REG_ITMP1, 0);
2089 emit_store(jd, iptr, iptr->dst, d);
2092 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2093 /* op1 = type, val.a = field address */
2095 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2096 disp = dseg_addaddress(cd, 0);
2098 codegen_addpatchref(cd, PATCHER_get_putstatic,
2099 INSTRUCTION_UNRESOLVED_FIELD(iptr), disp);
2101 if (opt_showdisassemble)
2105 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
2107 disp = dseg_addaddress(cd, &(fi->value));
2109 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2110 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2112 if (opt_showdisassemble)
2117 M_ALD(REG_ITMP1, REG_PV, disp);
2118 switch (iptr->op1) {
2120 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2121 M_IST(s2, REG_ITMP1, 0);
2124 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2125 M_LST(s2, REG_ITMP1, 0);
2128 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2129 M_AST(s2, REG_ITMP1, 0);
2132 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
2133 M_FST(s2, REG_ITMP1, 0);
2136 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
2137 M_DST(s2, REG_ITMP1, 0);
2142 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2143 /* val = value (in current instruction) */
2144 /* op1 = type, val.a = field address (in */
2145 /* following NOP) */
2147 if (INSTRUCTION_IS_UNRESOLVED(iptr + 1)) {
2148 disp = dseg_addaddress(cd, 0);
2150 codegen_addpatchref(cd, PATCHER_get_putstatic,
2151 INSTRUCTION_UNRESOLVED_FIELD(iptr + 1), disp);
2153 if (opt_showdisassemble)
2157 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr + 1);
2159 disp = dseg_addaddress(cd, &(fi->value));
2161 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2162 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2164 if (opt_showdisassemble)
2169 M_ALD(REG_ITMP1, REG_PV, disp);
2170 switch (iptr->op1) {
2172 M_IST(REG_ZERO, REG_ITMP1, 0);
2175 M_LST(REG_ZERO, REG_ITMP1, 0);
2178 M_AST(REG_ZERO, REG_ITMP1, 0);
2181 M_FST(REG_ZERO, REG_ITMP1, 0);
2184 M_DST(REG_ZERO, REG_ITMP1, 0);
2190 case ICMD_GETFIELD: /* ... ==> ..., value */
2191 /* op1 = type, val.i = field offset */
2193 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2194 gen_nullptr_check(s1);
2196 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2197 codegen_addpatchref(cd, PATCHER_get_putfield,
2198 INSTRUCTION_UNRESOLVED_FIELD(iptr), 0);
2200 if (opt_showdisassemble)
2206 disp = INSTRUCTION_RESOLVED_FIELDINFO(iptr)->offset;
2209 switch (iptr->op1) {
2211 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2215 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2219 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2223 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2227 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2231 emit_store(jd, iptr, iptr->dst, d);
2234 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2235 /* op1 = type, val.a = field address */
2237 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2238 gen_nullptr_check(s1);
2240 if (!IS_FLT_DBL_TYPE(iptr->op1)) {
2241 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2243 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
2246 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2247 codegen_addpatchref(cd, PATCHER_get_putfield,
2248 INSTRUCTION_UNRESOLVED_FIELD(iptr), 0);
2250 if (opt_showdisassemble)
2256 disp = INSTRUCTION_RESOLVED_FIELDINFO(iptr)->offset;
2259 switch (iptr->op1) {
2261 M_IST(s2, s1, disp);
2264 M_LST(s2, s1, disp);
2267 M_AST(s2, s1, disp);
2270 M_FST(s2, s1, disp);
2273 M_DST(s2, s1, disp);
2278 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2279 /* val = value (in current instruction) */
2280 /* op1 = type, val.a = field address (in */
2281 /* following NOP) */
2283 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2284 gen_nullptr_check(s1);
2286 if (INSTRUCTION_IS_UNRESOLVED(iptr + 1)) {
2287 codegen_addpatchref(cd, PATCHER_get_putfield,
2288 INSTRUCTION_UNRESOLVED_FIELD(iptr + 1), 0);
2290 if (opt_showdisassemble)
2296 disp = INSTRUCTION_RESOLVED_FIELDINFO(iptr + 1)->offset;
2299 switch (iptr[1].op1) {
2301 M_IST(REG_ZERO, s1, disp);
2304 M_LST(REG_ZERO, s1, disp);
2307 M_AST(REG_ZERO, s1, disp);
2310 M_FST(REG_ZERO, s1, disp);
2313 M_DST(REG_ZERO, s1, disp);
2319 /* branch operations **************************************************/
2321 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2323 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2324 M_INTMOVE(s1, REG_ITMP1_XPTR);
2326 #ifdef ENABLE_VERIFIER
2328 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2329 (unresolved_class *) iptr->val.a, 0);
2331 if (opt_showdisassemble)
2334 #endif /* ENABLE_VERIFIER */
2336 disp = dseg_addaddress(cd, asm_handle_exception);
2337 M_ALD(REG_ITMP2, REG_PV, disp);
2338 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2339 M_NOP; /* nop ensures that XPC is less than the end */
2340 /* of basic block */
2344 case ICMD_GOTO: /* ... ==> ... */
2345 /* op1 = target JavaVM pc */
2347 codegen_addreference(cd, (basicblock *) iptr->target);
2351 case ICMD_JSR: /* ... ==> ... */
2352 /* op1 = target JavaVM pc */
2354 M_BSR(REG_ITMP1, 0);
2355 codegen_addreference(cd, (basicblock *) iptr->target);
2358 case ICMD_RET: /* ... ==> ... */
2359 /* op1 = local variable */
2361 var = &(rd->locals[iptr->op1][TYPE_ADR]);
2362 if (var->flags & INMEMORY) {
2363 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2364 M_RET(REG_ZERO, REG_ITMP1);
2367 M_RET(REG_ZERO, var->regoff);
2371 case ICMD_IFNULL: /* ..., value ==> ... */
2372 /* op1 = target JavaVM pc */
2374 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2376 codegen_addreference(cd, (basicblock *) iptr->target);
2379 case ICMD_IFNONNULL: /* ..., value ==> ... */
2380 /* op1 = target JavaVM pc */
2382 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2384 codegen_addreference(cd, (basicblock *) iptr->target);
2387 case ICMD_IFEQ: /* ..., value ==> ... */
2388 /* op1 = target JavaVM pc, val.i = constant */
2390 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2391 if (iptr->val.i == 0) {
2395 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2396 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2399 ICONST(REG_ITMP2, iptr->val.i);
2400 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2402 M_BNEZ(REG_ITMP1, 0);
2404 codegen_addreference(cd, (basicblock *) iptr->target);
2407 case ICMD_IFLT: /* ..., value ==> ... */
2408 /* op1 = target JavaVM pc, val.i = constant */
2410 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2411 if (iptr->val.i == 0) {
2415 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2416 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2419 ICONST(REG_ITMP2, iptr->val.i);
2420 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2422 M_BNEZ(REG_ITMP1, 0);
2424 codegen_addreference(cd, (basicblock *) iptr->target);
2427 case ICMD_IFLE: /* ..., value ==> ... */
2428 /* op1 = target JavaVM pc, val.i = constant */
2430 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2431 if (iptr->val.i == 0) {
2435 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2436 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2439 ICONST(REG_ITMP2, iptr->val.i);
2440 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2442 M_BNEZ(REG_ITMP1, 0);
2444 codegen_addreference(cd, (basicblock *) iptr->target);
2447 case ICMD_IFNE: /* ..., value ==> ... */
2448 /* op1 = target JavaVM pc, val.i = constant */
2450 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2451 if (iptr->val.i == 0) {
2455 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2456 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2459 ICONST(REG_ITMP2, iptr->val.i);
2460 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2462 M_BEQZ(REG_ITMP1, 0);
2464 codegen_addreference(cd, (basicblock *) iptr->target);
2467 case ICMD_IFGT: /* ..., value ==> ... */
2468 /* op1 = target JavaVM pc, val.i = constant */
2470 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2471 if (iptr->val.i == 0) {
2475 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2476 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2479 ICONST(REG_ITMP2, iptr->val.i);
2480 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2482 M_BEQZ(REG_ITMP1, 0);
2484 codegen_addreference(cd, (basicblock *) iptr->target);
2487 case ICMD_IFGE: /* ..., value ==> ... */
2488 /* op1 = target JavaVM pc, val.i = constant */
2490 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2491 if (iptr->val.i == 0) {
2495 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2496 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2499 ICONST(REG_ITMP2, iptr->val.i);
2500 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2502 M_BEQZ(REG_ITMP1, 0);
2504 codegen_addreference(cd, (basicblock *) iptr->target);
2507 case ICMD_IF_LEQ: /* ..., value ==> ... */
2508 /* op1 = target JavaVM pc, val.l = constant */
2510 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2511 if (iptr->val.l == 0) {
2515 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2516 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2519 LCONST(REG_ITMP2, iptr->val.l);
2520 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2522 M_BNEZ(REG_ITMP1, 0);
2524 codegen_addreference(cd, (basicblock *) iptr->target);
2527 case ICMD_IF_LLT: /* ..., value ==> ... */
2528 /* op1 = target JavaVM pc, val.l = constant */
2530 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2531 if (iptr->val.l == 0) {
2535 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2536 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2539 LCONST(REG_ITMP2, iptr->val.l);
2540 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2542 M_BNEZ(REG_ITMP1, 0);
2544 codegen_addreference(cd, (basicblock *) iptr->target);
2547 case ICMD_IF_LLE: /* ..., value ==> ... */
2548 /* op1 = target JavaVM pc, val.l = constant */
2550 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2551 if (iptr->val.l == 0) {
2555 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2556 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2559 LCONST(REG_ITMP2, iptr->val.l);
2560 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2562 M_BNEZ(REG_ITMP1, 0);
2564 codegen_addreference(cd, (basicblock *) iptr->target);
2567 case ICMD_IF_LNE: /* ..., value ==> ... */
2568 /* op1 = target JavaVM pc, val.l = constant */
2570 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2571 if (iptr->val.l == 0) {
2575 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2576 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2579 LCONST(REG_ITMP2, iptr->val.l);
2580 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2582 M_BEQZ(REG_ITMP1, 0);
2584 codegen_addreference(cd, (basicblock *) iptr->target);
2587 case ICMD_IF_LGT: /* ..., value ==> ... */
2588 /* op1 = target JavaVM pc, val.l = constant */
2590 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2591 if (iptr->val.l == 0) {
2595 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2596 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2599 LCONST(REG_ITMP2, iptr->val.l);
2600 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2602 M_BEQZ(REG_ITMP1, 0);
2604 codegen_addreference(cd, (basicblock *) iptr->target);
2607 case ICMD_IF_LGE: /* ..., value ==> ... */
2608 /* op1 = target JavaVM pc, val.l = constant */
2610 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2611 if (iptr->val.l == 0) {
2615 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2616 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2619 LCONST(REG_ITMP2, iptr->val.l);
2620 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2622 M_BEQZ(REG_ITMP1, 0);
2624 codegen_addreference(cd, (basicblock *) iptr->target);
2627 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2628 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2629 case ICMD_IF_ACMPEQ:
2631 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2632 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2633 M_CMPEQ(s1, s2, REG_ITMP1);
2634 M_BNEZ(REG_ITMP1, 0);
2635 codegen_addreference(cd, (basicblock *) iptr->target);
2638 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2639 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2640 case ICMD_IF_ACMPNE:
2642 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2643 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2644 M_CMPEQ(s1, s2, REG_ITMP1);
2645 M_BEQZ(REG_ITMP1, 0);
2646 codegen_addreference(cd, (basicblock *) iptr->target);
2649 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2650 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2652 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2653 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2654 M_CMPLT(s1, s2, REG_ITMP1);
2655 M_BNEZ(REG_ITMP1, 0);
2656 codegen_addreference(cd, (basicblock *) iptr->target);
2659 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2660 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2662 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2663 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2664 M_CMPLE(s1, s2, REG_ITMP1);
2665 M_BEQZ(REG_ITMP1, 0);
2666 codegen_addreference(cd, (basicblock *) iptr->target);
2669 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2670 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2672 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2673 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2674 M_CMPLE(s1, s2, REG_ITMP1);
2675 M_BNEZ(REG_ITMP1, 0);
2676 codegen_addreference(cd, (basicblock *) iptr->target);
2679 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2680 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2682 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2683 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2684 M_CMPLT(s1, s2, REG_ITMP1);
2685 M_BEQZ(REG_ITMP1, 0);
2686 codegen_addreference(cd, (basicblock *) iptr->target);
2689 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2691 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2694 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2695 /* val.i = constant */
2697 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2698 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2700 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2701 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2702 M_CMPEQ(s1, REG_ZERO, d);
2703 emit_store(jd, iptr, iptr->dst, d);
2706 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2707 M_CMPEQ(s1, REG_ZERO, d);
2709 emit_store(jd, iptr, iptr->dst, d);
2713 M_MOV(s1, REG_ITMP1);
2716 ICONST(d, iptr[1].val.i);
2718 if ((s3 >= 0) && (s3 <= 255)) {
2719 M_CMOVEQ_IMM(s1, s3, d);
2721 ICONST(REG_ITMP3, s3);
2722 M_CMOVEQ(s1, REG_ITMP3, d);
2724 emit_store(jd, iptr, iptr->dst, d);
2727 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2728 /* val.i = constant */
2730 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2731 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2733 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2734 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2735 M_CMPEQ(s1, REG_ZERO, d);
2736 emit_store(jd, iptr, iptr->dst, d);
2739 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2740 M_CMPEQ(s1, REG_ZERO, d);
2742 emit_store(jd, iptr, iptr->dst, d);
2746 M_MOV(s1, REG_ITMP1);
2749 ICONST(d, iptr[1].val.i);
2751 if ((s3 >= 0) && (s3 <= 255)) {
2752 M_CMOVNE_IMM(s1, s3, d);
2754 ICONST(REG_ITMP3, s3);
2755 M_CMOVNE(s1, REG_ITMP3, d);
2757 emit_store(jd, iptr, iptr->dst, d);
2760 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2761 /* val.i = constant */
2763 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2764 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2766 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2767 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2768 M_CMPLT(s1, REG_ZERO, d);
2769 emit_store(jd, iptr, iptr->dst, d);
2772 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2773 M_CMPLE(REG_ZERO, s1, d);
2774 emit_store(jd, iptr, iptr->dst, d);
2778 M_MOV(s1, REG_ITMP1);
2781 ICONST(d, iptr[1].val.i);
2783 if ((s3 >= 0) && (s3 <= 255)) {
2784 M_CMOVLT_IMM(s1, s3, d);
2786 ICONST(REG_ITMP3, s3);
2787 M_CMOVLT(s1, REG_ITMP3, d);
2789 emit_store(jd, iptr, iptr->dst, d);
2792 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2793 /* val.i = constant */
2795 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2796 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2798 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2799 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2800 M_CMPLE(REG_ZERO, s1, d);
2801 emit_store(jd, iptr, iptr->dst, d);
2804 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2805 M_CMPLT(s1, REG_ZERO, d);
2806 emit_store(jd, iptr, iptr->dst, d);
2810 M_MOV(s1, REG_ITMP1);
2813 ICONST(d, iptr[1].val.i);
2815 if ((s3 >= 0) && (s3 <= 255)) {
2816 M_CMOVGE_IMM(s1, s3, d);
2818 ICONST(REG_ITMP3, s3);
2819 M_CMOVGE(s1, REG_ITMP3, d);
2821 emit_store(jd, iptr, iptr->dst, d);
2824 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2825 /* val.i = constant */
2827 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2828 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2830 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2831 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2832 M_CMPLT(REG_ZERO, s1, d);
2833 emit_store(jd, iptr, iptr->dst, d);
2836 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2837 M_CMPLE(s1, REG_ZERO, d);
2838 emit_store(jd, iptr, iptr->dst, d);
2842 M_MOV(s1, REG_ITMP1);
2845 ICONST(d, iptr[1].val.i);
2847 if ((s3 >= 0) && (s3 <= 255)) {
2848 M_CMOVGT_IMM(s1, s3, d);
2850 ICONST(REG_ITMP3, s3);
2851 M_CMOVGT(s1, REG_ITMP3, d);
2853 emit_store(jd, iptr, iptr->dst, d);
2856 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2857 /* val.i = constant */
2859 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2860 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2862 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2863 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2864 M_CMPLE(s1, REG_ZERO, d);
2865 emit_store(jd, iptr, iptr->dst, d);
2868 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2869 M_CMPLT(REG_ZERO, s1, d);
2870 emit_store(jd, iptr, iptr->dst, d);
2874 M_MOV(s1, REG_ITMP1);
2877 ICONST(d, iptr[1].val.i);
2879 if ((s3 >= 0) && (s3 <= 255)) {
2880 M_CMOVLE_IMM(s1, s3, d);
2882 ICONST(REG_ITMP3, s3);
2883 M_CMOVLE(s1, REG_ITMP3, d);
2885 emit_store(jd, iptr, iptr->dst, d);
2889 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2892 s1 = emit_load_s1(jd, iptr, src, REG_RESULT);
2893 M_INTMOVE(s1, REG_RESULT);
2894 goto nowperformreturn;
2896 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2898 s1 = emit_load_s1(jd, iptr, src, REG_RESULT);
2899 M_INTMOVE(s1, REG_RESULT);
2901 #ifdef ENABLE_VERIFIER
2903 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2904 (unresolved_class *) iptr->val.a, 0);
2906 if (opt_showdisassemble)
2909 #endif /* ENABLE_VERIFIER */
2910 goto nowperformreturn;
2912 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2915 s1 = emit_load_s1(jd, iptr, src, REG_FRESULT);
2916 M_FLTMOVE(s1, REG_FRESULT);
2917 goto nowperformreturn;
2919 case ICMD_RETURN: /* ... ==> ... */
2927 /* call trace function */
2929 #if !defined(NDEBUG)
2930 if (opt_verbosecall) {
2931 M_LDA(REG_SP, REG_SP, -3 * 8);
2932 M_AST(REG_RA, REG_SP, 0 * 8);
2933 M_LST(REG_RESULT, REG_SP, 1 * 8);
2934 M_DST(REG_FRESULT, REG_SP, 2 * 8);
2936 disp = dseg_addaddress(cd, m);
2937 M_ALD(rd->argintregs[0], REG_PV, disp);
2938 M_MOV(REG_RESULT, rd->argintregs[1]);
2939 M_FLTMOVE(REG_FRESULT, rd->argfltregs[2]);
2940 M_FLTMOVE(REG_FRESULT, rd->argfltregs[3]);
2942 disp = dseg_addaddress(cd, (void *) builtin_displaymethodstop);
2943 M_ALD(REG_PV, REG_PV, disp);
2944 M_JSR(REG_RA, REG_PV);
2945 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2946 M_LDA(REG_PV, REG_RA, -disp);
2948 M_DLD(REG_FRESULT, REG_SP, 2 * 8);
2949 M_LLD(REG_RESULT, REG_SP, 1 * 8);
2950 M_ALD(REG_RA, REG_SP, 0 * 8);
2951 M_LDA(REG_SP, REG_SP, 3 * 8);
2955 #if defined(USE_THREADS)
2956 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2957 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8);
2959 switch (iptr->opc) {
2963 M_LST(REG_RESULT, REG_SP, rd->memuse * 8);
2967 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2971 disp = dseg_addaddress(cd, BUILTIN_monitorexit);
2972 M_ALD(REG_PV, REG_PV, disp);
2973 M_JSR(REG_RA, REG_PV);
2974 disp = -(s4) (cd->mcodeptr - cd->mcodebase);
2975 M_LDA(REG_PV, REG_RA, disp);
2977 switch (iptr->opc) {
2981 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2985 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2991 /* restore return address */
2993 if (!m->isleafmethod) {
2994 p--; M_LLD(REG_RA, REG_SP, p * 8);
2997 /* restore saved registers */
2999 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
3000 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
3002 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
3003 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
3006 /* deallocate stack */
3009 M_LDA(REG_SP, REG_SP, stackframesize * 8);
3011 M_RET(REG_ZERO, REG_RA);
3017 case ICMD_TABLESWITCH: /* ..., index ==> ... */
3022 tptr = (void **) iptr->target;
3024 s4ptr = iptr->val.a;
3025 l = s4ptr[1]; /* low */
3026 i = s4ptr[2]; /* high */
3028 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3030 M_INTMOVE(s1, REG_ITMP1);
3031 } else if (l <= 32768) {
3032 M_LDA(REG_ITMP1, s1, -l);
3034 ICONST(REG_ITMP2, l);
3035 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
3042 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
3044 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
3045 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3047 M_BEQZ(REG_ITMP2, 0);
3048 codegen_addreference(cd, (basicblock *) tptr[0]);
3050 /* build jump table top down and use address of lowest entry */
3052 /* s4ptr += 3 + i; */
3056 dseg_addtarget(cd, (basicblock *) tptr[0]);
3061 /* length of dataseg after last dseg_addtarget is used by load */
3063 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
3064 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
3065 M_JMP(REG_ZERO, REG_ITMP2);
3070 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3072 s4 i, l, val, *s4ptr;
3075 tptr = (void **) iptr->target;
3077 s4ptr = iptr->val.a;
3078 l = s4ptr[0]; /* default */
3079 i = s4ptr[1]; /* count */
3081 MCODECHECK((i<<2)+8);
3082 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3088 if ((val >= 0) && (val <= 255)) {
3089 M_CMPEQ_IMM(s1, val, REG_ITMP2);
3091 if ((val >= -32768) && (val <= 32767)) {
3092 M_LDA(REG_ITMP2, REG_ZERO, val);
3094 disp = dseg_adds4(cd, val);
3095 M_ILD(REG_ITMP2, REG_PV, disp);
3097 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
3099 M_BNEZ(REG_ITMP2, 0);
3100 codegen_addreference(cd, (basicblock *) tptr[0]);
3105 tptr = (void **) iptr->target;
3106 codegen_addreference(cd, (basicblock *) tptr[0]);
3113 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
3114 /* op1 = arg count val.a = builtintable entry */
3120 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3121 /* op1 = arg count, val.a = method pointer */
3123 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3124 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
3125 case ICMD_INVOKEINTERFACE:
3127 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3128 md = INSTRUCTION_UNRESOLVED_METHOD(iptr)->methodref->parseddesc.md;
3132 lm = INSTRUCTION_RESOLVED_METHODINFO(iptr);
3133 md = lm->parseddesc;
3137 s3 = md->paramcount;
3139 MCODECHECK((s3 << 1) + 64);
3141 /* copy arguments to registers or stack location */
3143 for (s3 = s3 - 1; s3 >= 0; s3--, src = src->prev) {
3144 if (src->varkind == ARGVAR)
3146 if (IS_INT_LNG_TYPE(src->type)) {
3147 if (!md->params[s3].inmemory) {
3148 s1 = rd->argintregs[md->params[s3].regoff];
3149 d = emit_load_s1(jd, iptr, src, s1);
3152 d = emit_load_s1(jd, iptr, src, REG_ITMP1);
3153 M_LST(d, REG_SP, md->params[s3].regoff * 8);
3157 if (!md->params[s3].inmemory) {
3158 s1 = rd->argfltregs[md->params[s3].regoff];
3159 d = emit_load_s1(jd, iptr, src, s1);
3162 d = emit_load_s1(jd, iptr, src, REG_FTMP1);
3163 M_DST(d, REG_SP, md->params[s3].regoff * 8);
3168 switch (iptr->opc) {
3170 disp = dseg_addaddress(cd, bte->fp);
3171 d = md->returntype.type;
3173 M_ALD(REG_PV, REG_PV, disp); /* Pointer to built-in-function */
3174 M_JSR(REG_RA, REG_PV);
3175 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3176 M_LDA(REG_PV, REG_RA, -disp);
3178 /* if op1 == true, we need to check for an exception */
3180 if (iptr->op1 == true) {
3181 M_BEQZ(REG_RESULT, 0);
3182 codegen_add_fillinstacktrace_ref(cd);
3186 case ICMD_INVOKESPECIAL:
3187 M_BEQZ(rd->argintregs[0], 0);
3188 codegen_add_nullpointerexception_ref(cd);
3191 case ICMD_INVOKESTATIC:
3193 unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
3195 disp = dseg_addaddress(cd, NULL);
3197 codegen_addpatchref(cd, PATCHER_invokestatic_special,
3200 if (opt_showdisassemble)
3203 d = um->methodref->parseddesc.md->returntype.type;
3206 disp = dseg_addaddress(cd, lm->stubroutine);
3207 d = lm->parseddesc->returntype.type;
3210 M_ALD(REG_PV, REG_PV, disp); /* method pointer in r27 */
3211 M_JSR(REG_RA, REG_PV);
3212 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3213 M_LDA(REG_PV, REG_RA, -disp);
3216 case ICMD_INVOKEVIRTUAL:
3217 gen_nullptr_check(rd->argintregs[0]);
3220 unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
3222 codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
3224 if (opt_showdisassemble)
3228 d = um->methodref->parseddesc.md->returntype.type;
3231 s1 = OFFSET(vftbl_t, table[0]) +
3232 sizeof(methodptr) * lm->vftblindex;
3233 d = lm->parseddesc->returntype.type;
3236 M_ALD(REG_METHODPTR, rd->argintregs[0],
3237 OFFSET(java_objectheader, vftbl));
3238 M_ALD(REG_PV, REG_METHODPTR, s1);
3239 M_JSR(REG_RA, REG_PV);
3240 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3241 M_LDA(REG_PV, REG_RA, -disp);
3244 case ICMD_INVOKEINTERFACE:
3245 gen_nullptr_check(rd->argintregs[0]);
3248 unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
3250 codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
3252 if (opt_showdisassemble)
3257 d = um->methodref->parseddesc.md->returntype.type;
3260 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3261 sizeof(methodptr*) * lm->class->index;
3263 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3265 d = lm->parseddesc->returntype.type;
3268 M_ALD(REG_METHODPTR, rd->argintregs[0],
3269 OFFSET(java_objectheader, vftbl));
3270 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3271 M_ALD(REG_PV, REG_METHODPTR, s2);
3272 M_JSR(REG_RA, REG_PV);
3273 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3274 M_LDA(REG_PV, REG_RA, -disp);
3278 /* d contains return type */
3280 if (d != TYPE_VOID) {
3281 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3282 s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT);
3283 M_INTMOVE(REG_RESULT, s1);
3284 /* emit_store(jd, iptr, iptr->dst, s1); */
3286 s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FRESULT);
3287 M_FLTMOVE(REG_FRESULT, s1);
3288 /* emit_store(jd, iptr, iptr->dst, s1); */
3290 emit_store(jd, iptr, iptr->dst, s1);
3295 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3297 /* op1: 0 == array, 1 == class */
3298 /* val.a: (classinfo*) superclass */
3300 /* superclass is an interface:
3302 * OK if ((sub == NULL) ||
3303 * (sub->vftbl->interfacetablelength > super->index) &&
3304 * (sub->vftbl->interfacetable[-super->index] != NULL));
3306 * superclass is a class:
3308 * OK if ((sub == NULL) || (0
3309 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3310 * super->vftbl->diffval));
3313 if (iptr->op1 == 1) {
3314 /* object type cast-check */
3317 vftbl_t *supervftbl;
3320 super = (classinfo *) iptr->val.a;
3327 superindex = super->index;
3328 supervftbl = super->vftbl;
3331 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3332 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3334 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3336 /* calculate interface checkcast code size */
3340 s2 += opt_showdisassemble ? 1 : 0;
3342 /* calculate class checkcast code size */
3344 s3 = 9 /* 8 + (s1 == REG_ITMP1) */;
3346 s3 += opt_showdisassemble ? 1 : 0;
3348 /* if class is not resolved, check which code to call */
3351 M_BEQZ(s1, 4 + (opt_showdisassemble ? 1 : 0) + s2 + 1 + s3);
3353 disp = dseg_adds4(cd, 0); /* super->flags */
3355 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3356 (constant_classref *) iptr->target,
3359 if (opt_showdisassemble)
3362 M_ILD(REG_ITMP2, REG_PV, disp);
3363 disp = dseg_adds4(cd, ACC_INTERFACE);
3364 M_ILD(REG_ITMP3, REG_PV, disp);
3365 M_AND(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3366 M_BEQZ(REG_ITMP2, s2 + 1);
3369 /* interface checkcast code */
3371 if (!super || (super->flags & ACC_INTERFACE)) {
3376 codegen_addpatchref(cd,
3377 PATCHER_checkcast_instanceof_interface,
3378 (constant_classref *) iptr->target,
3381 if (opt_showdisassemble)
3385 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3386 M_ILD(REG_ITMP3, REG_ITMP2,
3387 OFFSET(vftbl_t, interfacetablelength));
3388 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
3389 M_BLEZ(REG_ITMP3, 0);
3390 codegen_add_classcastexception_ref(cd);
3391 M_ALD(REG_ITMP3, REG_ITMP2,
3392 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
3393 superindex * sizeof(methodptr*)));
3394 M_BEQZ(REG_ITMP3, 0);
3395 codegen_add_classcastexception_ref(cd);
3401 /* class checkcast code */
3403 if (!super || !(super->flags & ACC_INTERFACE)) {
3404 disp = dseg_addaddress(cd, supervftbl);
3410 codegen_addpatchref(cd,
3411 PATCHER_checkcast_instanceof_class,
3412 (constant_classref *) iptr->target,
3415 if (opt_showdisassemble)
3419 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3420 M_ALD(REG_ITMP3, REG_PV, disp);
3421 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3422 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3424 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3425 /* if (s1 != REG_ITMP1) { */
3426 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3427 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3428 /* #if defined(USE_THREADS) && defined(NATIVE_THREADS) */
3429 /* codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase); */
3431 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3434 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3435 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3436 M_ALD(REG_ITMP3, REG_PV, disp);
3437 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3438 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3439 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3442 M_CMPULE(REG_ITMP2, REG_ITMP3, REG_ITMP3);
3443 M_BEQZ(REG_ITMP3, 0);
3444 codegen_add_classcastexception_ref(cd);
3446 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, s1);
3449 /* array type cast-check */
3451 s1 = emit_load_s1(jd, iptr, src, rd->argintregs[0]);
3452 M_INTMOVE(s1, rd->argintregs[0]);
3454 disp = dseg_addaddress(cd, iptr->val.a);
3456 if (iptr->val.a == NULL) {
3457 codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast,
3458 (constant_classref *) iptr->target,
3461 if (opt_showdisassemble)
3465 M_ALD(rd->argintregs[1], REG_PV, disp);
3466 disp = dseg_addaddress(cd, BUILTIN_arraycheckcast);
3467 M_ALD(REG_PV, REG_PV, disp);
3468 M_JSR(REG_RA, REG_PV);
3469 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3470 M_LDA(REG_PV, REG_RA, -disp);
3472 M_BEQZ(REG_RESULT, 0);
3473 codegen_add_classcastexception_ref(cd);
3475 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3476 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, s1);
3479 emit_store(jd, iptr, iptr->dst, d);
3482 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3484 /* op1: 0 == array, 1 == class */
3485 /* val.a: (classinfo*) superclass */
3487 /* superclass is an interface:
3489 * return (sub != NULL) &&
3490 * (sub->vftbl->interfacetablelength > super->index) &&
3491 * (sub->vftbl->interfacetable[-super->index] != NULL);
3493 * superclass is a class:
3495 * return ((sub != NULL) && (0
3496 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3497 * super->vftbl->diffvall));
3502 vftbl_t *supervftbl;
3505 super = (classinfo *) iptr->val.a;
3512 superindex = super->index;
3513 supervftbl = super->vftbl;
3516 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3517 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3519 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3520 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
3522 M_MOV(s1, REG_ITMP1);
3526 /* calculate interface instanceof code size */
3530 s2 += (d == REG_ITMP2 ? 1 : 0) + (opt_showdisassemble ? 1 : 0);
3532 /* calculate class instanceof code size */
3536 s3 += (opt_showdisassemble ? 1 : 0);
3538 /* if class is not resolved, check which code to call */
3542 M_BEQZ(s1, 4 + (opt_showdisassemble ? 1 : 0) + s2 + 1 + s3);
3544 disp = dseg_adds4(cd, 0); /* super->flags */
3546 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3547 (constant_classref *) iptr->target, disp);
3549 if (opt_showdisassemble)
3552 M_ILD(REG_ITMP3, REG_PV, disp);
3554 disp = dseg_adds4(cd, ACC_INTERFACE);
3555 M_ILD(REG_ITMP2, REG_PV, disp);
3556 M_AND(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3557 M_BEQZ(REG_ITMP3, s2 + 1);
3560 /* interface instanceof code */
3562 if (!super || (super->flags & ACC_INTERFACE)) {
3568 /* If d == REG_ITMP2, then it's destroyed in check code */
3573 codegen_addpatchref(cd,
3574 PATCHER_checkcast_instanceof_interface,
3575 (constant_classref *) iptr->target, 0);
3577 if (opt_showdisassemble)
3581 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3582 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3583 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
3584 M_BLEZ(REG_ITMP3, 2);
3585 M_ALD(REG_ITMP1, REG_ITMP1,
3586 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
3587 superindex * sizeof(methodptr*)));
3588 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3594 /* class instanceof code */
3596 if (!super || !(super->flags & ACC_INTERFACE)) {
3597 disp = dseg_addaddress(cd, supervftbl);
3604 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_class,
3605 (constant_classref *) iptr->target,
3608 if (opt_showdisassemble)
3612 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3613 M_ALD(REG_ITMP2, REG_PV, disp);
3614 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3615 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3617 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3618 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3619 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3620 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3621 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3623 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3624 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3626 emit_store(jd, iptr, iptr->dst, d);
3630 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3631 /* op1 = dimension, val.a = class */
3633 /* check for negative sizes and copy sizes to stack if necessary */
3635 MCODECHECK((iptr->op1 << 1) + 64);
3637 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3638 /* copy SAVEDVAR sizes to stack */
3640 if (src->varkind != ARGVAR) {
3641 s2 = emit_load_s2(jd, iptr, src, REG_ITMP1);
3642 M_LST(s2, REG_SP, s1 * 8);
3646 /* a0 = dimension count */
3648 ICONST(rd->argintregs[0], iptr->op1);
3650 /* is patcher function set? */
3652 if (iptr->val.a == NULL) {
3653 disp = dseg_addaddress(cd, 0);
3655 codegen_addpatchref(cd, PATCHER_builtin_multianewarray,
3656 (constant_classref *) iptr->target,
3659 if (opt_showdisassemble)
3663 disp = dseg_addaddress(cd, iptr->val.a);
3666 /* a1 = arraydescriptor */
3668 M_ALD(rd->argintregs[1], REG_PV, disp);
3670 /* a2 = pointer to dimensions = stack pointer */
3672 M_INTMOVE(REG_SP, rd->argintregs[2]);
3674 disp = dseg_addaddress(cd, BUILTIN_multianewarray);
3675 M_ALD(REG_PV, REG_PV, disp);
3676 M_JSR(REG_RA, REG_PV);
3677 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3678 M_LDA(REG_PV, REG_RA, -disp);
3680 /* check for exception before result assignment */
3682 M_BEQZ(REG_RESULT, 0);
3683 codegen_add_fillinstacktrace_ref(cd);
3685 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT);
3686 M_INTMOVE(REG_RESULT, d);
3687 emit_store(jd, iptr, iptr->dst, d);
3692 new_internalerror("Unknown ICMD %d", iptr->opc);
3696 } /* for instruction */
3698 /* copy values to interface registers */
3700 src = bptr->outstack;
3701 len = bptr->outdepth;
3703 #if defined(ENABLE_LSRA)
3708 if ((src->varkind != STACKVAR)) {
3710 if (IS_FLT_DBL_TYPE(s2)) {
3711 /* XXX can be one call */
3712 s1 = emit_load_s1(jd, NULL, src, REG_FTMP1);
3713 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3714 M_FLTMOVE(s1,rd->interfaces[len][s2].regoff);
3717 M_DST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3721 /* XXX can be one call */
3722 s1 = emit_load_s1(jd, NULL, src, REG_ITMP1);
3723 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3724 M_INTMOVE(s1,rd->interfaces[len][s2].regoff);
3727 M_LST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3733 } /* if (bptr -> flags >= BBREACHED) */
3734 } /* for basic block */
3736 dseg_createlinenumbertable(cd);
3739 /* generate exception and patcher stubs */
3748 savedmcodeptr = NULL;
3750 /* generate exception stubs */
3752 for (eref = cd->exceptionrefs; eref != NULL; eref = eref->next) {
3753 gen_resolvebranch(cd->mcodebase + eref->branchpos,
3754 eref->branchpos, cd->mcodeptr - cd->mcodebase);
3758 /* move index register into REG_ITMP1 */
3760 /* Check if the exception is an
3761 ArrayIndexOutOfBoundsException. If so, move index register
3764 if (eref->reg != -1)
3765 M_MOV(eref->reg, rd->argintregs[4]);
3767 /* calcuate exception address */
3769 M_LDA(rd->argintregs[3], REG_PV, eref->branchpos - 4);
3771 /* move function to call into REG_ITMP3 */
3773 disp = dseg_addaddress(cd, eref->function);
3774 M_ALD(REG_ITMP3, REG_PV, disp);
3776 if (savedmcodeptr != NULL) {
3777 disp = ((u4 *) savedmcodeptr) - (((u4 *) cd->mcodeptr) + 1);
3781 savedmcodeptr = cd->mcodeptr;
3783 M_MOV(REG_PV, rd->argintregs[0]);
3784 M_MOV(REG_SP, rd->argintregs[1]);
3786 if (m->isleafmethod)
3787 M_MOV(REG_RA, rd->argintregs[2]);
3789 M_ALD(rd->argintregs[2],
3790 REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
3792 M_LDA(REG_SP, REG_SP, -2 * 8);
3793 M_AST(rd->argintregs[3], REG_SP, 0 * 8); /* store XPC */
3795 if (m->isleafmethod)
3796 M_AST(REG_RA, REG_SP, 1 * 8);
3798 M_MOV(REG_ITMP3, REG_PV);
3799 M_JSR(REG_RA, REG_PV);
3800 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3801 M_LDA(REG_PV, REG_RA, -disp);
3803 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3805 if (m->isleafmethod)
3806 M_ALD(REG_RA, REG_SP, 1 * 8);
3808 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3809 M_LDA(REG_SP, REG_SP, 2 * 8);
3811 disp = dseg_addaddress(cd, asm_handle_exception);
3812 M_ALD(REG_ITMP3, REG_PV, disp);
3813 M_JMP(REG_ZERO, REG_ITMP3);
3818 /* generate code patching stub call code */
3820 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
3821 /* check code segment size */
3825 /* Get machine code which is patched back in later. The
3826 call is 1 instruction word long. */
3828 tmpmcodeptr = (u1 *) (cd->mcodebase + pref->branchpos);
3830 mcode = *((u4 *) tmpmcodeptr);
3832 /* Patch in the call to call the following code (done at
3835 savedmcodeptr = cd->mcodeptr; /* save current mcodeptr */
3836 cd->mcodeptr = tmpmcodeptr; /* set mcodeptr to patch position */
3838 disp = ((u4 *) savedmcodeptr) - (((u4 *) tmpmcodeptr) + 1);
3839 M_BSR(REG_ITMP3, disp);
3841 cd->mcodeptr = savedmcodeptr; /* restore the current mcodeptr */
3843 /* create stack frame */
3845 M_LSUB_IMM(REG_SP, 6 * 8, REG_SP);
3847 /* move return address onto stack */
3849 M_AST(REG_ITMP3, REG_SP, 5 * 8);
3851 /* move pointer to java_objectheader onto stack */
3853 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3854 /* create a virtual java_objectheader */
3856 (void) dseg_addaddress(cd, lock_get_initial_lock_word()); /* monitorPtr */
3857 disp = dseg_addaddress(cd, NULL); /* vftbl */
3859 M_LDA(REG_ITMP3, REG_PV, disp);
3860 M_AST(REG_ITMP3, REG_SP, 4 * 8);
3865 /* move machine code onto stack */
3867 disp = dseg_adds4(cd, mcode);
3868 M_ILD(REG_ITMP3, REG_PV, disp);
3869 M_IST(REG_ITMP3, REG_SP, 3 * 8);
3871 /* move class/method/field reference onto stack */
3873 disp = dseg_addaddress(cd, pref->ref);
3874 M_ALD(REG_ITMP3, REG_PV, disp);
3875 M_AST(REG_ITMP3, REG_SP, 2 * 8);
3877 /* move data segment displacement onto stack */
3879 disp = dseg_adds4(cd, pref->disp);
3880 M_ILD(REG_ITMP3, REG_PV, disp);
3881 M_IST(REG_ITMP3, REG_SP, 1 * 8);
3883 /* move patcher function pointer onto stack */
3885 disp = dseg_addaddress(cd, pref->patcher);
3886 M_ALD(REG_ITMP3, REG_PV, disp);
3887 M_AST(REG_ITMP3, REG_SP, 0 * 8);
3889 disp = dseg_addaddress(cd, asm_wrapper_patcher);
3890 M_ALD(REG_ITMP3, REG_PV, disp);
3891 M_JMP(REG_ZERO, REG_ITMP3);
3894 /* generate replacement-out stubs */
3899 replacementpoint = jd->code->rplpoints;
3901 for (i = 0; i < jd->code->rplpointcount; ++i, ++replacementpoint) {
3902 /* check code segment size */
3906 /* note start of stub code */
3908 replacementpoint->outcode = (u1 *) (ptrint) (cd->mcodeptr - cd->mcodebase);
3910 /* make machine code for patching */
3912 savedmcodeptr = cd->mcodeptr;
3913 cd->mcodeptr = (u1 *) &(replacementpoint->mcode);
3915 disp = (ptrint)((s4*)replacementpoint->outcode - (s4*)replacementpoint->pc) - 1;
3918 cd->mcodeptr = savedmcodeptr;
3920 /* create stack frame - 16-byte aligned */
3922 M_LSUB_IMM(REG_SP, 2 * 8, REG_SP);
3924 /* push address of `rplpoint` struct */
3926 disp = dseg_addaddress(cd, replacementpoint);
3927 M_ALD(REG_ITMP3, REG_PV, disp);
3928 M_AST(REG_ITMP3, REG_SP, 0 * 8);
3930 /* jump to replacement function */
3932 disp = dseg_addaddress(cd, asm_replacement_out);
3933 M_ALD(REG_ITMP3, REG_PV, disp);
3934 M_JMP(REG_ZERO, REG_ITMP3);
3941 /* everything's ok */
3947 /* createcompilerstub **********************************************************
3949 Creates a stub routine which calls the compiler.
3951 *******************************************************************************/
3953 #define COMPILERSTUB_DATASIZE 2 * SIZEOF_VOID_P
3954 #define COMPILERSTUB_CODESIZE 3 * 4
3956 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
3959 u1 *createcompilerstub(methodinfo *m)
3961 u1 *s; /* memory to hold the stub */
3964 s4 dumpsize; /* code generation pointer */
3966 s = CNEW(u1, COMPILERSTUB_SIZE);
3968 /* set data pointer and code pointer */
3971 s = s + COMPILERSTUB_DATASIZE;
3973 /* mark start of dump memory area */
3975 dumpsize = dump_size();
3977 cd = DNEW(codegendata);
3980 /* Store the methodinfo* in the same place as in the methodheader
3981 for compiled methods. */
3983 d[0] = (ptrint) asm_call_jit_compiler;
3986 /* code for the stub */
3988 M_ALD(REG_ITMP1, REG_PV, -1 * 8); /* load methodinfo pointer */
3989 M_ALD(REG_PV, REG_PV, -2 * 8); /* load pointer to the compiler */
3990 M_JMP(REG_ZERO, REG_PV); /* jump to the compiler */
3992 #if defined(ENABLE_STATISTICS)
3994 count_cstub_len += COMPILERSTUB_SIZE;
3997 /* release dump area */
3999 dump_release(dumpsize);
4005 /* createnativestub ************************************************************
4007 Creates a stub routine which calls a native method.
4009 *******************************************************************************/
4011 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
4016 s4 stackframesize; /* size of stackframe if needed */
4019 s4 i, j; /* count variables */
4022 s4 funcdisp; /* displacement of the function */
4024 /* get required compiler data */
4030 /* initialize variables */
4033 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
4035 /* calculate stack frame size */
4038 1 + /* return address */
4039 sizeof(stackframeinfo) / SIZEOF_VOID_P +
4040 sizeof(localref_table) / SIZEOF_VOID_P +
4041 1 + /* methodinfo for call trace */
4042 (md->paramcount > INT_ARG_CNT ? INT_ARG_CNT : md->paramcount) +
4045 /* create method header */
4047 (void) dseg_addaddress(cd, m); /* MethodPointer */
4048 (void) dseg_adds4(cd, stackframesize * 8); /* FrameSize */
4049 (void) dseg_adds4(cd, 0); /* IsSync */
4050 (void) dseg_adds4(cd, 0); /* IsLeaf */
4051 (void) dseg_adds4(cd, 0); /* IntSave */
4052 (void) dseg_adds4(cd, 0); /* FltSave */
4053 (void) dseg_addlinenumbertablesize(cd);
4054 (void) dseg_adds4(cd, 0); /* ExTableSize */
4056 /* generate stub code */
4058 M_LDA(REG_SP, REG_SP, -stackframesize * 8);
4059 M_AST(REG_RA, REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
4061 /* call trace function */
4063 #if !defined(NDEBUG)
4064 if (opt_verbosecall) {
4065 /* save integer argument registers */
4067 for (i = 0, j = 1; i < md->paramcount && i < INT_ARG_CNT; i++) {
4068 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4069 M_LST(rd->argintregs[i], REG_SP, j * 8);
4074 /* save and copy float arguments into integer registers */
4076 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4077 t = md->paramtypes[i].type;
4079 if (IS_FLT_DBL_TYPE(t)) {
4080 if (IS_2_WORD_TYPE(t)) {
4081 M_DST(rd->argfltregs[i], REG_SP, j * 8);
4082 M_LLD(rd->argintregs[i], REG_SP, j * 8);
4084 M_FST(rd->argfltregs[i], REG_SP, j * 8);
4085 M_ILD(rd->argintregs[i], REG_SP, j * 8);
4091 disp = dseg_addaddress(cd, m);
4092 M_ALD(REG_ITMP1, REG_PV, disp);
4093 M_AST(REG_ITMP1, REG_SP, 0 * 8);
4094 disp = dseg_addaddress(cd, builtin_trace_args);
4095 M_ALD(REG_PV, REG_PV, disp);
4096 M_JSR(REG_RA, REG_PV);
4097 disp = (s4) (cd->mcodeptr - cd->mcodebase);
4098 M_LDA(REG_PV, REG_RA, -disp);
4100 for (i = 0, j = 1; i < md->paramcount && i < INT_ARG_CNT; i++) {
4101 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4102 M_LLD(rd->argintregs[i], REG_SP, j * 8);
4107 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4108 t = md->paramtypes[i].type;
4110 if (IS_FLT_DBL_TYPE(t)) {
4111 if (IS_2_WORD_TYPE(t)) {
4112 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
4114 M_FLD(rd->argfltregs[i], REG_SP, j * 8);
4120 #endif /* !defined(NDEBUG) */
4122 /* get function address (this must happen before the stackframeinfo) */
4124 funcdisp = dseg_addaddress(cd, f);
4126 #if !defined(WITH_STATIC_CLASSPATH)
4128 codegen_addpatchref(cd, PATCHER_resolve_native, m, funcdisp);
4130 if (opt_showdisassemble)
4135 /* save integer and float argument registers */
4137 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
4138 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4139 M_LST(rd->argintregs[i], REG_SP, j * 8);
4144 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4145 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
4146 M_DST(rd->argfltregs[i], REG_SP, j * 8);
4151 /* prepare data structures for native function call */
4153 M_LDA(rd->argintregs[0], REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
4154 M_MOV(REG_PV, rd->argintregs[1]);
4155 M_LDA(rd->argintregs[2], REG_SP, stackframesize * 8);
4156 M_ALD(rd->argintregs[3], REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
4157 disp = dseg_addaddress(cd, codegen_start_native_call);
4158 M_ALD(REG_PV, REG_PV, disp);
4159 M_JSR(REG_RA, REG_PV);
4160 disp = (s4) (cd->mcodeptr - cd->mcodebase);
4161 M_LDA(REG_PV, REG_RA, -disp);
4163 /* restore integer and float argument registers */
4165 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
4166 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4167 M_LLD(rd->argintregs[i], REG_SP, j * 8);
4172 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4173 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
4174 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
4179 /* copy or spill arguments to new locations */
4181 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
4182 t = md->paramtypes[i].type;
4184 if (IS_INT_LNG_TYPE(t)) {
4185 if (!md->params[i].inmemory) {
4186 s1 = rd->argintregs[md->params[i].regoff];
4188 if (!nmd->params[j].inmemory) {
4189 s2 = rd->argintregs[nmd->params[j].regoff];
4193 s2 = nmd->params[j].regoff;
4194 M_LST(s1, REG_SP, s2 * 8);
4198 s1 = md->params[i].regoff + stackframesize;
4199 s2 = nmd->params[j].regoff;
4200 M_LLD(REG_ITMP1, REG_SP, s1 * 8);
4201 M_LST(REG_ITMP1, REG_SP, s2 * 8);
4205 if (!md->params[i].inmemory) {
4206 s1 = rd->argfltregs[md->params[i].regoff];
4208 if (!nmd->params[j].inmemory) {
4209 s2 = rd->argfltregs[nmd->params[j].regoff];
4213 s2 = nmd->params[j].regoff;
4214 if (IS_2_WORD_TYPE(t))
4215 M_DST(s1, REG_SP, s2 * 8);
4217 M_FST(s1, REG_SP, s2 * 8);
4221 s1 = md->params[i].regoff + stackframesize;
4222 s2 = nmd->params[j].regoff;
4223 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
4224 if (IS_2_WORD_TYPE(t))
4225 M_DST(REG_FTMP1, REG_SP, s2 * 8);
4227 M_FST(REG_FTMP1, REG_SP, s2 * 8);
4232 /* put class into second argument register */
4234 if (m->flags & ACC_STATIC) {
4235 disp = dseg_addaddress(cd, m->class);
4236 M_ALD(rd->argintregs[1], REG_PV, disp);
4239 /* put env into first argument register */
4241 disp = dseg_addaddress(cd, _Jv_env);
4242 M_ALD(rd->argintregs[0], REG_PV, disp);
4244 /* do the native function call */
4246 M_ALD(REG_PV, REG_PV, funcdisp);
4247 M_JSR(REG_RA, REG_PV); /* call native method */
4248 disp = (s4) (cd->mcodeptr - cd->mcodebase);
4249 M_LDA(REG_PV, REG_RA, -disp); /* recompute pv from ra */
4251 /* save return value */
4253 if (IS_INT_LNG_TYPE(md->returntype.type))
4254 M_LST(REG_RESULT, REG_SP, 0 * 8);
4256 M_DST(REG_FRESULT, REG_SP, 0 * 8);
4258 /* remove native stackframe info */
4260 M_LDA(rd->argintregs[0], REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
4261 disp = dseg_addaddress(cd, codegen_finish_native_call);
4262 M_ALD(REG_PV, REG_PV, disp);
4263 M_JSR(REG_RA, REG_PV);
4264 disp = (s4) (cd->mcodeptr - cd->mcodebase);
4265 M_LDA(REG_PV, REG_RA, -disp);
4267 /* call finished trace */
4269 #if !defined(NDEBUG)
4270 if (opt_verbosecall) {
4271 /* just restore the value we need, don't care about the other */
4273 if (IS_INT_LNG_TYPE(md->returntype.type))
4274 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4276 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4278 disp = dseg_addaddress(cd, m);
4279 M_ALD(rd->argintregs[0], REG_PV, disp);
4281 M_MOV(REG_RESULT, rd->argintregs[1]);
4282 M_FMOV(REG_FRESULT, rd->argfltregs[2]);
4283 M_FMOV(REG_FRESULT, rd->argfltregs[3]);
4285 disp = dseg_addaddress(cd, builtin_displaymethodstop);
4286 M_ALD(REG_PV, REG_PV, disp);
4287 M_JSR(REG_RA, REG_PV);
4288 disp = (s4) (cd->mcodeptr - cd->mcodebase);
4289 M_LDA(REG_PV, REG_RA, -disp);
4291 #endif /* !defined(NDEBUG) */
4293 /* check for exception */
4295 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4296 disp = dseg_addaddress(cd, builtin_get_exceptionptrptr);
4297 M_ALD(REG_PV, REG_PV, disp);
4298 M_JSR(REG_RA, REG_PV);
4299 disp = (s4) (cd->mcodeptr - cd->mcodebase);
4300 M_LDA(REG_PV, REG_RA, -disp);
4301 M_MOV(REG_RESULT, REG_ITMP3);
4303 disp = dseg_addaddress(cd, &_exceptionptr);
4304 M_ALD(REG_RESULT, REG_PV, disp); /* get address of exceptionptr */
4306 M_ALD(REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
4308 /* restore return value */
4310 if (IS_INT_LNG_TYPE(md->returntype.type))
4311 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4313 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4315 M_BNEZ(REG_ITMP1, 3); /* if no exception then return */
4317 M_ALD(REG_RA, REG_SP, (stackframesize - 1) * 8); /* load return address */
4318 M_LDA(REG_SP, REG_SP, stackframesize * 8);
4319 M_RET(REG_ZERO, REG_RA); /* return to caller */
4321 /* handle exception */
4323 M_AST(REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
4325 M_ALD(REG_RA, REG_SP, (stackframesize - 1) * 8); /* load return address */
4326 M_LDA(REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
4328 M_LDA(REG_SP, REG_SP, stackframesize * 8);
4330 disp = dseg_addaddress(cd, asm_handle_nat_exception);
4331 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
4332 M_JMP(REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
4335 /* process patcher calls **************************************************/
4343 /* there can only be one <clinit> ref entry */
4345 pref = cd->patchrefs;
4347 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
4348 /* Get machine code which is patched back in later. The
4349 call is 1 instruction word long. */
4351 tmpmcodeptr = (u1 *) (cd->mcodebase + pref->branchpos);
4353 mcode = *((u4 *) tmpmcodeptr);
4355 /* Patch in the call to call the following code (done at
4358 savedmcodeptr = cd->mcodeptr; /* save current mcodeptr */
4359 cd->mcodeptr = tmpmcodeptr; /* set mcodeptr to patch position */
4361 disp = ((u4 *) savedmcodeptr) - (((u4 *) tmpmcodeptr) + 1);
4362 M_BSR(REG_ITMP3, disp);
4364 cd->mcodeptr = savedmcodeptr; /* restore the current mcodeptr */
4366 /* create stack frame */
4368 M_LSUB_IMM(REG_SP, 6 * 8, REG_SP);
4370 /* move return address onto stack */
4372 M_AST(REG_ITMP3, REG_SP, 5 * 8);
4374 /* move pointer to java_objectheader onto stack */
4376 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4377 /* create a virtual java_objectheader */
4379 (void) dseg_addaddress(cd, lock_get_initial_lock_word()); /* monitorPtr */
4380 disp = dseg_addaddress(cd, NULL); /* vftbl */
4382 M_LDA(REG_ITMP3, REG_PV, disp);
4383 M_AST(REG_ITMP3, REG_SP, 4 * 8);
4385 M_AST(REG_ZERO, REG_SP, 4 * 8);
4388 /* move machine code onto stack */
4390 disp = dseg_adds4(cd, mcode);
4391 M_ILD(REG_ITMP3, REG_PV, disp);
4392 M_IST(REG_ITMP3, REG_SP, 3 * 8);
4394 /* move class/method/field reference onto stack */
4396 disp = dseg_addaddress(cd, pref->ref);
4397 M_ALD(REG_ITMP3, REG_PV, disp);
4398 M_AST(REG_ITMP3, REG_SP, 2 * 8);
4400 /* move data segment displacement onto stack */
4402 disp = dseg_adds4(cd, pref->disp);
4403 M_ILD(REG_ITMP3, REG_PV, disp);
4404 M_IST(REG_ITMP3, REG_SP, 1 * 8);
4406 /* move patcher function pointer onto stack */
4408 disp = dseg_addaddress(cd, pref->patcher);
4409 M_ALD(REG_ITMP3, REG_PV, disp);
4410 M_AST(REG_ITMP3, REG_SP, 0 * 8);
4412 disp = dseg_addaddress(cd, asm_wrapper_patcher);
4413 M_ALD(REG_ITMP3, REG_PV, disp);
4414 M_JMP(REG_ZERO, REG_ITMP3);
4420 return jd->code->entrypoint;
4425 * These are local overrides for various environment variables in Emacs.
4426 * Please do not remove this and leave it at the end of the file, where
4427 * Emacs will automagically detect them.
4428 * ---------------------------------------------------------------------
4431 * indent-tabs-mode: t
4435 * vim:noexpandtab:sw=4:ts=4: