1 /* src/vm/jit/mips/codegen.c - machine code generator for MIPS
3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 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., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Andreas Krall
30 Changes: Christian Thalinger
33 Contains the codegenerator for an MIPS (R4000 or higher) processor.
34 This module generates MIPS machine code for a sequence of
35 intermediate code commands (ICMDs).
37 $Id: codegen.c 3002 2005-07-12 16:02:45Z twisti $
51 #include "vm/jit/mips/arch.h"
52 #include "vm/jit/mips/codegen.h"
53 #include "vm/jit/mips/types.h"
55 #include "cacao/cacao.h"
56 #include "native/native.h"
57 #include "vm/builtin.h"
58 #include "vm/stringlocal.h"
59 #include "vm/jit/asmpart.h"
60 #include "vm/jit/codegen.inc"
61 #include "vm/jit/jit.h"
64 # include "vm/jit/lsra.h"
65 # include "vm/jit/lsra.inc"
68 #include "vm/jit/patcher.h"
69 #include "vm/jit/reg.h"
70 #include "vm/jit/reg.inc"
73 /* codegen *********************************************************************
75 Generates machine code.
77 *******************************************************************************/
79 void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
81 s4 len, s1, s2, s3, d, disp;
90 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
91 builtintable_entry *bte;
98 savedregs_num = (m->isleafmethod) ? 0 : 1; /* space to save the RA */
100 /* space to save used callee saved registers */
102 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
103 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
105 parentargs_base = rd->memuse + savedregs_num;
107 #if defined(USE_THREADS) /* space to save argument of monitor_enter */
109 if (checksync && (m->flags & ACC_SYNCHRONIZED))
114 /* adjust frame size for 16 byte alignment */
116 if (parentargs_base & 1)
119 /* create method header */
121 #if SIZEOF_VOID_P == 4
122 (void) dseg_addaddress(cd, m); /* Filler */
124 (void) dseg_addaddress(cd, m); /* MethodPointer */
125 (void) dseg_adds4(cd, parentargs_base * 8); /* FrameSize */
127 #if defined(USE_THREADS)
129 /* IsSync contains the offset relative to the stack pointer for the
130 argument of monitor_exit used in the exception handler. Since the
131 offset could be zero and give a wrong meaning of the flag it is
135 if (checksync && (m->flags & ACC_SYNCHRONIZED))
136 (void) dseg_adds4(cd, (rd->memuse + 1) * 8); /* IsSync */
141 (void) dseg_adds4(cd, 0); /* IsSync */
143 (void) dseg_adds4(cd, m->isleafmethod); /* IsLeaf */
144 (void) dseg_adds4(cd, INT_SAV_CNT - rd->savintreguse);/* IntSave */
145 (void) dseg_adds4(cd, FLT_SAV_CNT - rd->savfltreguse);/* FltSave */
146 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
148 /* create exception table */
150 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
151 dseg_addtarget(cd, ex->start);
152 dseg_addtarget(cd, ex->end);
153 dseg_addtarget(cd, ex->handler);
154 (void) dseg_addaddress(cd, ex->catchtype.cls);
157 /* initialize mcode variables */
159 mcodeptr = (s4 *) cd->mcodebase;
160 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
161 MCODECHECK(128 + m->paramcount);
163 /* create stack frame (if necessary) */
166 M_LDA(REG_SP, REG_SP, -parentargs_base * 8);
168 /* save return address and used callee saved registers */
171 if (!m->isleafmethod) {
172 p--; M_AST(REG_RA, REG_SP, p * 8);
174 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
175 p--; M_AST(rd->savintregs[i], REG_SP, p * 8);
177 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
178 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
181 /* take arguments out of register or stack frame */
185 for (p = 0, l = 0; p < md->paramcount; p++) {
186 t = md->paramtypes[p].type;
187 var = &(rd->locals[l][t]);
189 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
193 s1 = md->params[p].regoff;
194 if (IS_INT_LNG_TYPE(t)) { /* integer args */
195 if (!md->params[p].inmemory) { /* register arguments */
196 s2 = rd->argintregs[s1];
197 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
198 M_INTMOVE(s2, var->regoff);
199 } else { /* reg arg -> spilled */
200 M_LST(s2, REG_SP, var->regoff * 8);
203 } else { /* stack arguments */
204 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
205 M_LLD(var->regoff, REG_SP, (parentargs_base + s1) * 8);
206 } else { /* stack arg -> spilled */
207 var->regoff = parentargs_base + s1;
211 } else { /* floating args */
212 if (!md->params[p].inmemory) { /* register arguments */
213 s2 = rd->argfltregs[s1];
214 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
215 M_TFLTMOVE(var->type, s2, var->regoff);
216 } else { /* reg arg -> spilled */
217 M_DST(s2, REG_SP, var->regoff * 8);
220 } else { /* stack arguments */
221 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
222 M_DLD(var->regoff, REG_SP, (parentargs_base + s1) * 8);
223 } else { /* stack-arg -> spilled */
224 var->regoff = parentargs_base + s1;
230 /* call monitorenter function */
232 #if defined(USE_THREADS)
233 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
234 /* stack offset for monitor argument */
239 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
241 for (p = 0; p < INT_ARG_CNT; p++)
242 M_LST(rd->argintregs[p], REG_SP, p * 8);
244 for (p = 0; p < FLT_ARG_CNT; p++)
245 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
247 s1 += INT_ARG_CNT + FLT_ARG_CNT;
250 /* decide which monitor enter function to call */
252 if (m->flags & ACC_STATIC) {
253 p = dseg_addaddress(cd, m->class);
254 M_ALD(REG_ITMP1, REG_PV, p);
255 M_AST(REG_ITMP1, REG_SP, s1 * 8);
256 p = dseg_addaddress(cd, BUILTIN_staticmonitorenter);
257 M_ALD(REG_ITMP3, REG_PV, p);
258 M_JSR(REG_RA, REG_ITMP3);
259 M_INTMOVE(REG_ITMP1, rd->argintregs[0]); /* branch delay */
260 d = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
261 M_LDA(REG_PV, REG_RA, d);
264 M_BEQZ(rd->argintregs[0], 0);
265 codegen_addxnullrefs(cd, mcodeptr);
266 p = dseg_addaddress(cd, BUILTIN_monitorenter);
267 M_ALD(REG_ITMP3, REG_PV, p);
268 M_JSR(REG_RA, REG_ITMP3);
269 M_AST(rd->argintregs[0], REG_SP, s1 * 8); /* br delay */
270 d = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
271 M_LDA(REG_PV, REG_RA, d);
275 for (p = 0; p < INT_ARG_CNT; p++)
276 M_LLD(rd->argintregs[p], REG_SP, p * 8);
278 for (p = 0; p < FLT_ARG_CNT; p++)
279 M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
282 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
287 /* copy argument registers to stack and call trace function */
290 M_LDA(REG_SP, REG_SP, -(2 + INT_ARG_CNT + FLT_ARG_CNT + INT_TMP_CNT + FLT_TMP_CNT) * 8);
291 M_LST(REG_RA, REG_SP, 1 * 8);
293 /* save integer argument registers */
295 for (p = 0; p < md->paramcount && p < INT_ARG_CNT; p++)
296 M_LST(rd->argintregs[p], REG_SP, (2 + p) * 8);
298 /* save and copy float arguments into integer registers */
300 for (p = 0; p < md->paramcount && p < FLT_ARG_CNT; p++) {
301 t = md->paramtypes[p].type;
303 if (IS_FLT_DBL_TYPE(t)) {
304 if (IS_2_WORD_TYPE(t)) {
305 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
306 M_LLD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
309 M_FST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
310 M_ILD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
314 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
318 /* save temporary registers for leaf methods */
320 if (m->isleafmethod) {
321 for (p = 0; p < INT_TMP_CNT; p++)
322 M_LST(rd->tmpintregs[p], REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + p) * 8);
324 for (p = 0; p < FLT_TMP_CNT; p++)
325 M_DST(rd->tmpfltregs[p], REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + INT_TMP_CNT + p) * 8);
328 p = dseg_addaddress(cd, m);
329 M_ALD(REG_ITMP1, REG_PV, p);
330 M_LST(REG_ITMP1, REG_SP, 0);
331 p = dseg_addaddress(cd, (void *) builtin_trace_args);
332 M_ALD(REG_ITMP3, REG_PV, p);
333 M_JSR(REG_RA, REG_ITMP3);
336 M_LLD(REG_RA, REG_SP, 1 * 8);
338 /* restore integer argument registers */
340 for (p = 0; p < md->paramcount && p < INT_ARG_CNT; p++)
341 M_LLD(rd->argintregs[p], REG_SP, (2 + p) * 8);
343 /* restore float argument registers */
345 for (p = 0; p < md->paramcount && p < FLT_ARG_CNT; p++) {
346 t = md->paramtypes[p].type;
348 if (IS_FLT_DBL_TYPE(t)) {
349 if (IS_2_WORD_TYPE(t)) {
350 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
353 M_FLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
357 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
361 /* restore temporary registers for leaf methods */
363 if (m->isleafmethod) {
364 for (p = 0; p < INT_TMP_CNT; p++)
365 M_LLD(rd->tmpintregs[p], REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + p) * 8);
367 for (p = 0; p < FLT_TMP_CNT; p++)
368 M_DLD(rd->tmpfltregs[p], REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + INT_TMP_CNT + p) * 8);
371 M_LDA(REG_SP, REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + INT_TMP_CNT + FLT_TMP_CNT) * 8);
376 /* end of header generation */
378 /* walk through all basic blocks */
380 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
382 bptr->mpc = (s4) ((u1 *) mcodeptr - cd->mcodebase);
384 if (bptr->flags >= BBREACHED) {
386 /* branch resolving */
389 for (bref = bptr->branchrefs; bref != NULL; bref = bref->next) {
390 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
396 /* copy interface registers to their destination */
403 while (src != NULL) {
405 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
406 /* d = reg_of_var(m, src, REG_ITMP1); */
407 if (!(src->flags & INMEMORY))
411 M_INTMOVE(REG_ITMP1, d);
412 store_reg_to_var_int(src, d);
418 while (src != NULL) {
420 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
421 d = reg_of_var(rd, src, REG_ITMP1);
422 M_INTMOVE(REG_ITMP1, d);
423 store_reg_to_var_int(src, d);
426 d = reg_of_var(rd, src, REG_IFTMP);
427 if ((src->varkind != STACKVAR)) {
429 if (IS_FLT_DBL_TYPE(s2)) {
430 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
431 s1 = rd->interfaces[len][s2].regoff;
432 M_TFLTMOVE(s2, s1, d);
435 M_DLD(d, REG_SP, 8 * rd->interfaces[len][s2].regoff);
437 store_reg_to_var_flt(src, d);
440 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
441 s1 = rd->interfaces[len][s2].regoff;
445 M_LLD(d, REG_SP, 8 * rd->interfaces[len][s2].regoff);
447 store_reg_to_var_int(src, d);
456 /* walk through all instructions */
461 for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
463 MCODECHECK(64); /* an instruction usually needs < 64 words */
467 case ICMD_NOP: /* ... ==> ... */
470 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
472 var_to_reg_int(s1, src, REG_ITMP1);
474 codegen_addxnullrefs(cd, mcodeptr);
478 /* constant operations ************************************************/
480 case ICMD_ICONST: /* ... ==> ..., constant */
481 /* op1 = 0, val.i = constant */
483 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
484 ICONST(d, iptr->val.i);
485 store_reg_to_var_int(iptr->dst, d);
488 case ICMD_LCONST: /* ... ==> ..., constant */
489 /* op1 = 0, val.l = constant */
491 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
492 LCONST(d, iptr->val.l);
493 store_reg_to_var_int(iptr->dst, d);
496 case ICMD_FCONST: /* ... ==> ..., constant */
497 /* op1 = 0, val.f = constant */
499 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
500 a = dseg_addfloat(cd, iptr->val.f);
502 store_reg_to_var_flt(iptr->dst, d);
505 case ICMD_DCONST: /* ... ==> ..., constant */
506 /* op1 = 0, val.d = constant */
508 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
509 a = dseg_adddouble(cd, iptr->val.d);
511 store_reg_to_var_flt (iptr->dst, d);
514 case ICMD_ACONST: /* ... ==> ..., constant */
515 /* op1 = 0, val.a = constant */
517 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
519 a = dseg_addaddress(cd, iptr->val.a);
522 M_INTMOVE(REG_ZERO, d);
524 store_reg_to_var_int(iptr->dst, d);
528 /* load/store operations **********************************************/
530 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
531 case ICMD_LLOAD: /* op1 = local variable */
534 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
535 if ((iptr->dst->varkind == LOCALVAR) &&
536 (iptr->dst->varnum == iptr->op1))
538 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
539 if (var->flags & INMEMORY) {
540 M_LLD(d, REG_SP, 8 * var->regoff);
542 M_INTMOVE(var->regoff,d);
544 store_reg_to_var_int(iptr->dst, d);
547 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
548 case ICMD_DLOAD: /* op1 = local variable */
550 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
551 if ((iptr->dst->varkind == LOCALVAR) &&
552 (iptr->dst->varnum == iptr->op1))
554 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
556 int t2 = ((iptr->opc == ICMD_FLOAD) ? TYPE_FLT : TYPE_DBL);
557 if (var->flags & INMEMORY) {
558 M_CCFLD(var->type, t2, d, REG_SP, 8 * var->regoff);
560 M_CCFLTMOVE(var->type, t2, var->regoff, d);
563 store_reg_to_var_flt(iptr->dst, d);
567 case ICMD_ISTORE: /* ..., value ==> ... */
568 case ICMD_LSTORE: /* op1 = local variable */
571 if ((src->varkind == LOCALVAR) &&
572 (src->varnum == iptr->op1))
574 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
575 if (var->flags & INMEMORY) {
576 var_to_reg_int(s1, src, REG_ITMP1);
577 M_LST(s1, REG_SP, 8 * var->regoff);
580 var_to_reg_int(s1, src, var->regoff);
581 M_INTMOVE(s1, var->regoff);
585 case ICMD_FSTORE: /* ..., value ==> ... */
586 case ICMD_DSTORE: /* op1 = local variable */
588 if ((src->varkind == LOCALVAR) &&
589 (src->varnum == iptr->op1))
591 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
593 int t1 = ((iptr->opc == ICMD_FSTORE) ? TYPE_FLT : TYPE_DBL);
594 if (var->flags & INMEMORY) {
595 var_to_reg_flt(s1, src, REG_FTMP1);
596 M_CCFST(t1, var->type, s1, REG_SP, 8 * var->regoff);
599 var_to_reg_flt(s1, src, var->regoff);
600 M_CCFLTMOVE(t1, var->type, s1, var->regoff);
606 /* pop/dup/swap operations ********************************************/
608 /* attention: double and longs are only one entry in CACAO ICMDs */
610 case ICMD_POP: /* ..., value ==> ... */
611 case ICMD_POP2: /* ..., value, value ==> ... */
614 case ICMD_DUP: /* ..., a ==> ..., a, a */
615 M_COPY(src, iptr->dst);
618 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
620 M_COPY(src, iptr->dst);
621 M_COPY(src->prev, iptr->dst->prev);
622 M_COPY(iptr->dst, iptr->dst->prev->prev);
625 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
627 M_COPY(src, iptr->dst);
628 M_COPY(src->prev, iptr->dst->prev);
629 M_COPY(src->prev->prev, iptr->dst->prev->prev);
630 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
633 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
635 M_COPY(src, iptr->dst);
636 M_COPY(src->prev, iptr->dst->prev);
639 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
641 M_COPY(src, iptr->dst);
642 M_COPY(src->prev, iptr->dst->prev);
643 M_COPY(src->prev->prev, iptr->dst->prev->prev);
644 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
645 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev);
648 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
650 M_COPY(src, iptr->dst);
651 M_COPY(src->prev, iptr->dst->prev);
652 M_COPY(src->prev->prev, iptr->dst->prev->prev);
653 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
654 M_COPY(iptr->dst, iptr->dst->prev->prev->prev->prev);
655 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev->prev);
658 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
660 M_COPY(src, iptr->dst->prev);
661 M_COPY(src->prev, iptr->dst);
665 /* integer operations *************************************************/
667 case ICMD_INEG: /* ..., value ==> ..., - value */
669 var_to_reg_int(s1, src, REG_ITMP1);
670 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
671 M_ISUB(REG_ZERO, s1, d);
672 store_reg_to_var_int(iptr->dst, d);
675 case ICMD_LNEG: /* ..., value ==> ..., - value */
677 var_to_reg_int(s1, src, REG_ITMP1);
678 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
679 M_LSUB(REG_ZERO, s1, d);
680 store_reg_to_var_int(iptr->dst, d);
683 case ICMD_I2L: /* ..., value ==> ..., value */
685 var_to_reg_int(s1, src, REG_ITMP1);
686 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
688 store_reg_to_var_int(iptr->dst, d);
691 case ICMD_L2I: /* ..., value ==> ..., value */
693 var_to_reg_int(s1, src, REG_ITMP1);
694 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
695 M_ISLL_IMM(s1, 0, d );
696 store_reg_to_var_int(iptr->dst, d);
699 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
701 var_to_reg_int(s1, src, REG_ITMP1);
702 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
703 M_LSLL_IMM(s1, 56, d);
704 M_LSRA_IMM( d, 56, d);
705 store_reg_to_var_int(iptr->dst, d);
708 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
710 var_to_reg_int(s1, src, REG_ITMP1);
711 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
713 store_reg_to_var_int(iptr->dst, d);
716 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
718 var_to_reg_int(s1, src, REG_ITMP1);
719 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
720 M_LSLL_IMM(s1, 48, d);
721 M_LSRA_IMM( d, 48, d);
722 store_reg_to_var_int(iptr->dst, d);
726 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
728 var_to_reg_int(s1, src->prev, REG_ITMP1);
729 var_to_reg_int(s2, src, REG_ITMP2);
730 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
732 store_reg_to_var_int(iptr->dst, d);
735 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
736 /* val.i = constant */
738 var_to_reg_int(s1, src, REG_ITMP1);
739 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
740 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
741 M_IADD_IMM(s1, iptr->val.i, d);
744 ICONST(REG_ITMP2, iptr->val.i);
745 M_IADD(s1, REG_ITMP2, d);
747 store_reg_to_var_int(iptr->dst, d);
750 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
752 var_to_reg_int(s1, src->prev, REG_ITMP1);
753 var_to_reg_int(s2, src, REG_ITMP2);
754 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
756 store_reg_to_var_int(iptr->dst, d);
759 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
760 /* val.l = constant */
762 var_to_reg_int(s1, src, REG_ITMP1);
763 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
764 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
765 M_LADD_IMM(s1, iptr->val.l, d);
768 LCONST(REG_ITMP2, iptr->val.l);
769 M_LADD(s1, REG_ITMP2, d);
771 store_reg_to_var_int(iptr->dst, d);
774 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
776 var_to_reg_int(s1, src->prev, REG_ITMP1);
777 var_to_reg_int(s2, src, REG_ITMP2);
778 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
780 store_reg_to_var_int(iptr->dst, d);
783 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
784 /* val.i = constant */
786 var_to_reg_int(s1, src, REG_ITMP1);
787 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
788 if ((iptr->val.i >= -32767) && (iptr->val.i <= 32768)) {
789 M_IADD_IMM(s1, -iptr->val.i, d);
792 ICONST(REG_ITMP2, iptr->val.i);
793 M_ISUB(s1, REG_ITMP2, d);
795 store_reg_to_var_int(iptr->dst, d);
798 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
800 var_to_reg_int(s1, src->prev, REG_ITMP1);
801 var_to_reg_int(s2, src, REG_ITMP2);
802 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
804 store_reg_to_var_int(iptr->dst, d);
807 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
808 /* val.l = constant */
810 var_to_reg_int(s1, src, REG_ITMP1);
811 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
812 if ((iptr->val.l >= -32767) && (iptr->val.l <= 32768)) {
813 M_LADD_IMM(s1, -iptr->val.l, d);
816 LCONST(REG_ITMP2, iptr->val.l);
817 M_LSUB(s1, REG_ITMP2, d);
819 store_reg_to_var_int(iptr->dst, d);
822 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
824 var_to_reg_int(s1, src->prev, REG_ITMP1);
825 var_to_reg_int(s2, src, REG_ITMP2);
826 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
831 store_reg_to_var_int(iptr->dst, d);
834 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
835 /* val.i = constant */
837 var_to_reg_int(s1, src, REG_ITMP1);
838 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
839 ICONST(REG_ITMP2, iptr->val.i);
840 M_IMUL(s1, REG_ITMP2);
844 store_reg_to_var_int(iptr->dst, d);
847 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
849 var_to_reg_int(s1, src->prev, REG_ITMP1);
850 var_to_reg_int(s2, src, REG_ITMP2);
851 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
856 store_reg_to_var_int(iptr->dst, d);
859 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
860 /* val.l = constant */
862 var_to_reg_int(s1, src, REG_ITMP1);
863 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
864 LCONST(REG_ITMP2, iptr->val.l);
865 M_LMUL(s1, REG_ITMP2);
869 store_reg_to_var_int(iptr->dst, d);
872 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
874 var_to_reg_int(s1, src->prev, REG_ITMP1);
875 var_to_reg_int(s2, src, REG_ITMP2);
876 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
882 store_reg_to_var_int(iptr->dst, d);
885 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
887 var_to_reg_int(s1, src->prev, REG_ITMP1);
888 var_to_reg_int(s2, src, REG_ITMP2);
889 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
895 store_reg_to_var_int(iptr->dst, d);
898 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
900 var_to_reg_int(s1, src->prev, REG_ITMP1);
901 var_to_reg_int(s2, src, REG_ITMP2);
902 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
908 store_reg_to_var_int(iptr->dst, d);
911 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
913 var_to_reg_int(s1, src->prev, REG_ITMP1);
914 var_to_reg_int(s2, src, REG_ITMP2);
915 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
921 store_reg_to_var_int(iptr->dst, d);
924 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
925 case ICMD_LDIVPOW2: /* val.i = constant */
927 var_to_reg_int(s1, src, REG_ITMP1);
928 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
929 M_LSRA_IMM(s1, 63, REG_ITMP2);
930 M_LSRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
931 M_LADD(s1, REG_ITMP2, REG_ITMP2);
932 M_LSRA_IMM(REG_ITMP2, iptr->val.i, d);
933 store_reg_to_var_int(iptr->dst, d);
936 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
938 var_to_reg_int(s1, src->prev, REG_ITMP1);
939 var_to_reg_int(s2, src, REG_ITMP2);
940 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
942 store_reg_to_var_int(iptr->dst, d);
945 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
946 /* val.i = constant */
948 var_to_reg_int(s1, src, REG_ITMP1);
949 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
950 M_ISLL_IMM(s1, iptr->val.i, d);
951 store_reg_to_var_int(iptr->dst, d);
954 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
956 var_to_reg_int(s1, src->prev, REG_ITMP1);
957 var_to_reg_int(s2, src, REG_ITMP2);
958 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
960 store_reg_to_var_int(iptr->dst, d);
963 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
964 /* val.i = constant */
966 var_to_reg_int(s1, src, REG_ITMP1);
967 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
968 M_ISRA_IMM(s1, iptr->val.i, d);
969 store_reg_to_var_int(iptr->dst, d);
972 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
974 var_to_reg_int(s1, src->prev, REG_ITMP1);
975 var_to_reg_int(s2, src, REG_ITMP2);
976 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
978 store_reg_to_var_int(iptr->dst, d);
981 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
982 /* val.i = constant */
984 var_to_reg_int(s1, src, REG_ITMP1);
985 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
986 M_ISRL_IMM(s1, iptr->val.i, d);
987 store_reg_to_var_int(iptr->dst, d);
990 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
992 var_to_reg_int(s1, src->prev, REG_ITMP1);
993 var_to_reg_int(s2, src, REG_ITMP2);
994 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
996 store_reg_to_var_int(iptr->dst, d);
999 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1000 /* val.i = constant */
1002 var_to_reg_int(s1, src, REG_ITMP1);
1003 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1004 M_LSLL_IMM(s1, iptr->val.i, d);
1005 store_reg_to_var_int(iptr->dst, d);
1008 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1010 var_to_reg_int(s1, src->prev, REG_ITMP1);
1011 var_to_reg_int(s2, src, REG_ITMP2);
1012 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1014 store_reg_to_var_int(iptr->dst, d);
1017 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1018 /* val.i = constant */
1020 var_to_reg_int(s1, src, REG_ITMP1);
1021 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1022 M_LSRA_IMM(s1, iptr->val.i, d);
1023 store_reg_to_var_int(iptr->dst, d);
1026 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1028 var_to_reg_int(s1, src->prev, REG_ITMP1);
1029 var_to_reg_int(s2, src, REG_ITMP2);
1030 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1032 store_reg_to_var_int(iptr->dst, d);
1035 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1036 /* val.i = constant */
1038 var_to_reg_int(s1, src, REG_ITMP1);
1039 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1040 M_LSRL_IMM(s1, iptr->val.i, d);
1041 store_reg_to_var_int(iptr->dst, d);
1044 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1047 var_to_reg_int(s1, src->prev, REG_ITMP1);
1048 var_to_reg_int(s2, src, REG_ITMP2);
1049 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1051 store_reg_to_var_int(iptr->dst, d);
1054 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1055 /* val.i = constant */
1057 var_to_reg_int(s1, src, REG_ITMP1);
1058 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1059 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1060 M_AND_IMM(s1, iptr->val.i, d);
1063 ICONST(REG_ITMP2, iptr->val.i);
1064 M_AND(s1, REG_ITMP2, d);
1066 store_reg_to_var_int(iptr->dst, d);
1069 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1070 /* val.i = constant */
1072 var_to_reg_int(s1, src, REG_ITMP1);
1073 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1075 M_MOV(s1, REG_ITMP1);
1078 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1079 M_AND_IMM(s1, iptr->val.i, d);
1082 M_ISUB(REG_ZERO, s1, d);
1083 M_AND_IMM(d, iptr->val.i, d);
1086 ICONST(REG_ITMP2, iptr->val.i);
1087 M_AND(s1, REG_ITMP2, d);
1090 M_ISUB(REG_ZERO, s1, d);
1091 M_AND(d, REG_ITMP2, d);
1093 M_ISUB(REG_ZERO, d, d);
1094 store_reg_to_var_int(iptr->dst, d);
1097 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1098 /* val.l = constant */
1100 var_to_reg_int(s1, src, REG_ITMP1);
1101 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1102 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1103 M_AND_IMM(s1, iptr->val.l, d);
1106 LCONST(REG_ITMP2, iptr->val.l);
1107 M_AND(s1, REG_ITMP2, d);
1109 store_reg_to_var_int(iptr->dst, d);
1112 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1113 /* val.l = constant */
1115 var_to_reg_int(s1, src, REG_ITMP1);
1116 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1118 M_MOV(s1, REG_ITMP1);
1121 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1122 M_AND_IMM(s1, iptr->val.l, d);
1125 M_LSUB(REG_ZERO, s1, d);
1126 M_AND_IMM(d, iptr->val.l, d);
1129 LCONST(REG_ITMP2, iptr->val.l);
1130 M_AND(s1, REG_ITMP2, d);
1133 M_LSUB(REG_ZERO, s1, d);
1134 M_AND(d, REG_ITMP2, d);
1136 M_LSUB(REG_ZERO, d, d);
1137 store_reg_to_var_int(iptr->dst, d);
1140 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1143 var_to_reg_int(s1, src->prev, REG_ITMP1);
1144 var_to_reg_int(s2, src, REG_ITMP2);
1145 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1147 store_reg_to_var_int(iptr->dst, d);
1150 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1151 /* val.i = constant */
1153 var_to_reg_int(s1, src, REG_ITMP1);
1154 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1155 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1156 M_OR_IMM(s1, iptr->val.i, d);
1159 ICONST(REG_ITMP2, iptr->val.i);
1160 M_OR(s1, REG_ITMP2, d);
1162 store_reg_to_var_int(iptr->dst, d);
1165 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1166 /* val.l = constant */
1168 var_to_reg_int(s1, src, REG_ITMP1);
1169 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1170 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1171 M_OR_IMM(s1, iptr->val.l, d);
1174 LCONST(REG_ITMP2, iptr->val.l);
1175 M_OR(s1, REG_ITMP2, d);
1177 store_reg_to_var_int(iptr->dst, d);
1180 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1183 var_to_reg_int(s1, src->prev, REG_ITMP1);
1184 var_to_reg_int(s2, src, REG_ITMP2);
1185 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1187 store_reg_to_var_int(iptr->dst, d);
1190 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1191 /* val.i = constant */
1193 var_to_reg_int(s1, src, REG_ITMP1);
1194 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1195 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1196 M_XOR_IMM(s1, iptr->val.i, d);
1199 ICONST(REG_ITMP2, iptr->val.i);
1200 M_XOR(s1, REG_ITMP2, d);
1202 store_reg_to_var_int(iptr->dst, d);
1205 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1206 /* val.l = constant */
1208 var_to_reg_int(s1, src, REG_ITMP1);
1209 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1210 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1211 M_XOR_IMM(s1, iptr->val.l, d);
1214 LCONST(REG_ITMP2, iptr->val.l);
1215 M_XOR(s1, REG_ITMP2, d);
1217 store_reg_to_var_int(iptr->dst, d);
1221 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1223 var_to_reg_int(s1, src->prev, REG_ITMP1);
1224 var_to_reg_int(s2, src, REG_ITMP2);
1225 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1226 M_CMPLT(s1, s2, REG_ITMP3);
1227 M_CMPLT(s2, s1, REG_ITMP1);
1228 M_LSUB (REG_ITMP1, REG_ITMP3, d);
1229 store_reg_to_var_int(iptr->dst, d);
1233 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1234 /* op1 = variable, val.i = constant */
1236 var = &(rd->locals[iptr->op1][TYPE_INT]);
1237 if (var->flags & INMEMORY) {
1239 M_LLD(s1, REG_SP, 8 * var->regoff);
1243 M_IADD_IMM(s1, iptr->val.i, s1);
1244 if (var->flags & INMEMORY)
1245 M_LST(s1, REG_SP, 8 * var->regoff);
1249 /* floating operations ************************************************/
1251 case ICMD_FNEG: /* ..., value ==> ..., - value */
1253 var_to_reg_flt(s1, src, REG_FTMP1);
1254 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1256 store_reg_to_var_flt(iptr->dst, d);
1259 case ICMD_DNEG: /* ..., value ==> ..., - value */
1261 var_to_reg_flt(s1, src, REG_FTMP1);
1262 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1264 store_reg_to_var_flt(iptr->dst, d);
1267 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1269 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1270 var_to_reg_flt(s2, src, REG_FTMP2);
1271 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1273 store_reg_to_var_flt(iptr->dst, d);
1276 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1278 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1279 var_to_reg_flt(s2, src, REG_FTMP2);
1280 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1282 store_reg_to_var_flt(iptr->dst, d);
1285 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1287 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1288 var_to_reg_flt(s2, src, REG_FTMP2);
1289 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1291 store_reg_to_var_flt(iptr->dst, d);
1294 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1296 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1297 var_to_reg_flt(s2, src, REG_FTMP2);
1298 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1300 store_reg_to_var_flt(iptr->dst, d);
1303 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1305 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1306 var_to_reg_flt(s2, src, REG_FTMP2);
1307 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1309 store_reg_to_var_flt(iptr->dst, d);
1312 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1314 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1315 var_to_reg_flt(s2, src, REG_FTMP2);
1316 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1318 store_reg_to_var_flt(iptr->dst, d);
1321 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1323 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1324 var_to_reg_flt(s2, src, REG_FTMP2);
1325 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1327 store_reg_to_var_flt(iptr->dst, d);
1330 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1332 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1333 var_to_reg_flt(s2, src, REG_FTMP2);
1334 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1336 store_reg_to_var_flt(iptr->dst, d);
1340 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1342 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1343 var_to_reg_flt(s2, src, REG_FTMP2);
1344 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1345 M_FDIV(s1,s2, REG_FTMP3);
1346 M_FLOORFL(REG_FTMP3, REG_FTMP3);
1347 M_CVTLF(REG_FTMP3, REG_FTMP3);
1348 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1349 M_FSUB(s1, REG_FTMP3, d);
1350 store_reg_to_var_flt(iptr->dst, d);
1353 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1355 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1356 var_to_reg_flt(s2, src, REG_FTMP2);
1357 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1358 M_DDIV(s1,s2, REG_FTMP3);
1359 M_FLOORDL(REG_FTMP3, REG_FTMP3);
1360 M_CVTLD(REG_FTMP3, REG_FTMP3);
1361 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1362 M_DSUB(s1, REG_FTMP3, d);
1363 store_reg_to_var_flt(iptr->dst, d);
1367 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1369 var_to_reg_int(s1, src, REG_ITMP1);
1370 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1373 store_reg_to_var_flt(iptr->dst, d);
1376 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1378 var_to_reg_int(s1, src, REG_ITMP1);
1379 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1382 store_reg_to_var_flt(iptr->dst, d);
1385 case ICMD_F2I: /* ..., (float) value ==> ..., (int) value */
1387 var_to_reg_flt(s1, src, REG_FTMP1);
1388 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1389 M_TRUNCFI(s1, REG_FTMP1);
1390 M_MOVDI(REG_FTMP1, d);
1392 store_reg_to_var_int(iptr->dst, d);
1395 case ICMD_D2I: /* ..., (double) value ==> ..., (int) value */
1397 var_to_reg_flt(s1, src, REG_FTMP1);
1398 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1399 M_TRUNCDI(s1, REG_FTMP1);
1400 M_MOVDI(REG_FTMP1, d);
1402 store_reg_to_var_int(iptr->dst, d);
1405 case ICMD_F2L: /* ..., (float) value ==> ..., (long) value */
1407 var_to_reg_flt(s1, src, REG_FTMP1);
1408 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1409 M_TRUNCFL(s1, REG_FTMP1);
1410 M_MOVDL(REG_FTMP1, d);
1412 store_reg_to_var_int(iptr->dst, d);
1415 case ICMD_D2L: /* ..., (double) value ==> ..., (long) value */
1417 var_to_reg_flt(s1, src, REG_FTMP1);
1418 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1419 M_TRUNCDL(s1, REG_FTMP1);
1420 M_MOVDL(REG_FTMP1, d);
1422 store_reg_to_var_int(iptr->dst, d);
1425 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1427 var_to_reg_flt(s1, src, REG_FTMP1);
1428 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1430 store_reg_to_var_flt(iptr->dst, d);
1433 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1435 var_to_reg_flt(s1, src, REG_FTMP1);
1436 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1438 store_reg_to_var_flt(iptr->dst, d);
1441 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1443 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1444 var_to_reg_flt(s2, src, REG_FTMP2);
1445 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1448 M_LADD_IMM(REG_ZERO, 1, d);
1452 M_LSUB_IMM(REG_ZERO, 1, d);
1453 M_CMOVT(REG_ZERO, d);
1454 store_reg_to_var_int(iptr->dst, d);
1457 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1459 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1460 var_to_reg_flt(s2, src, REG_FTMP2);
1461 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1464 M_LADD_IMM(REG_ZERO, 1, d);
1468 M_LSUB_IMM(REG_ZERO, 1, d);
1469 M_CMOVT(REG_ZERO, d);
1470 store_reg_to_var_int(iptr->dst, d);
1473 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1475 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1476 var_to_reg_flt(s2, src, REG_FTMP2);
1477 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1480 M_LSUB_IMM(REG_ZERO, 1, d);
1484 M_LADD_IMM(REG_ZERO, 1, d);
1485 M_CMOVT(REG_ZERO, d);
1486 store_reg_to_var_int(iptr->dst, d);
1489 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1491 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1492 var_to_reg_flt(s2, src, REG_FTMP2);
1493 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1496 M_LSUB_IMM(REG_ZERO, 1, d);
1500 M_LADD_IMM(REG_ZERO, 1, d);
1501 M_CMOVT(REG_ZERO, d);
1502 store_reg_to_var_int(iptr->dst, d);
1506 /* memory operations **************************************************/
1508 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1510 var_to_reg_int(s1, src, REG_ITMP1);
1511 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1512 gen_nullptr_check(s1);
1513 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1514 store_reg_to_var_int(iptr->dst, d);
1517 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1519 var_to_reg_int(s1, src->prev, REG_ITMP1);
1520 var_to_reg_int(s2, src, REG_ITMP2);
1521 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1522 if (iptr->op1 == 0) {
1523 gen_nullptr_check(s1);
1526 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1527 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1528 M_ALD(d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1529 store_reg_to_var_int(iptr->dst, d);
1532 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1534 var_to_reg_int(s1, src->prev, REG_ITMP1);
1535 var_to_reg_int(s2, src, REG_ITMP2);
1536 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1537 if (iptr->op1 == 0) {
1538 gen_nullptr_check(s1);
1541 M_ASLL_IMM(s2, 2, REG_ITMP2);
1542 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1543 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1544 store_reg_to_var_int(iptr->dst, d);
1547 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1549 var_to_reg_int(s1, src->prev, REG_ITMP1);
1550 var_to_reg_int(s2, src, REG_ITMP2);
1551 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1552 if (iptr->op1 == 0) {
1553 gen_nullptr_check(s1);
1556 M_ASLL_IMM(s2, 3, REG_ITMP2);
1557 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1558 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1559 store_reg_to_var_int(iptr->dst, d);
1562 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1564 var_to_reg_int(s1, src->prev, REG_ITMP1);
1565 var_to_reg_int(s2, src, REG_ITMP2);
1566 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1567 if (iptr->op1 == 0) {
1568 gen_nullptr_check(s1);
1571 M_ASLL_IMM(s2, 2, REG_ITMP2);
1572 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1573 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1574 store_reg_to_var_flt(iptr->dst, d);
1577 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1579 var_to_reg_int(s1, src->prev, REG_ITMP1);
1580 var_to_reg_int(s2, src, REG_ITMP2);
1581 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1582 if (iptr->op1 == 0) {
1583 gen_nullptr_check(s1);
1586 M_ASLL_IMM(s2, 3, REG_ITMP2);
1587 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1588 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1589 store_reg_to_var_flt(iptr->dst, d);
1592 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1594 var_to_reg_int(s1, src->prev, REG_ITMP1);
1595 var_to_reg_int(s2, src, REG_ITMP2);
1596 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1597 if (iptr->op1 == 0) {
1598 gen_nullptr_check(s1);
1601 M_AADD(s2, s1, REG_ITMP1);
1602 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1603 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1604 store_reg_to_var_int(iptr->dst, d);
1607 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1609 var_to_reg_int(s1, src->prev, REG_ITMP1);
1610 var_to_reg_int(s2, src, REG_ITMP2);
1611 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1612 if (iptr->op1 == 0) {
1613 gen_nullptr_check(s1);
1616 M_AADD(s2, s1, REG_ITMP1);
1617 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1618 M_SLDS(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1619 store_reg_to_var_int(iptr->dst, d);
1622 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1624 var_to_reg_int(s1, src->prev, REG_ITMP1);
1625 var_to_reg_int(s2, src, REG_ITMP2);
1626 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1627 if (iptr->op1 == 0) {
1628 gen_nullptr_check(s1);
1631 M_AADD(s2, s1, REG_ITMP1);
1632 M_BLDS(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1633 store_reg_to_var_int(iptr->dst, d);
1637 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1639 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1640 var_to_reg_int(s2, src->prev, REG_ITMP2);
1641 if (iptr->op1 == 0) {
1642 gen_nullptr_check(s1);
1645 var_to_reg_int(s3, src, REG_ITMP3);
1646 M_ASLL_IMM(s2, 2, REG_ITMP2);
1647 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1648 M_IST(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1651 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1653 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1654 var_to_reg_int(s2, src->prev, REG_ITMP2);
1655 if (iptr->op1 == 0) {
1656 gen_nullptr_check(s1);
1659 var_to_reg_int(s3, src, REG_ITMP3);
1660 M_ASLL_IMM(s2, 3, REG_ITMP2);
1661 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1662 M_LST(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1665 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1667 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1668 var_to_reg_int(s2, src->prev, REG_ITMP2);
1669 if (iptr->op1 == 0) {
1670 gen_nullptr_check(s1);
1673 var_to_reg_flt(s3, src, REG_FTMP3);
1674 M_ASLL_IMM(s2, 2, REG_ITMP2);
1675 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1676 M_FST(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1679 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1681 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1682 var_to_reg_int(s2, src->prev, REG_ITMP2);
1683 if (iptr->op1 == 0) {
1684 gen_nullptr_check(s1);
1687 var_to_reg_flt(s3, src, REG_FTMP3);
1688 M_ASLL_IMM(s2, 3, REG_ITMP2);
1689 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1690 M_DST(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1693 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1694 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1696 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1697 var_to_reg_int(s2, src->prev, REG_ITMP2);
1698 if (iptr->op1 == 0) {
1699 gen_nullptr_check(s1);
1702 var_to_reg_int(s3, src, REG_ITMP3);
1703 M_AADD(s2, s1, REG_ITMP1);
1704 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1705 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1708 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1710 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1711 var_to_reg_int(s2, src->prev, REG_ITMP2);
1712 if (iptr->op1 == 0) {
1713 gen_nullptr_check(s1);
1716 var_to_reg_int(s3, src, REG_ITMP3);
1717 M_AADD(s2, s1, REG_ITMP1);
1718 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1722 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1724 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1725 var_to_reg_int(s2, src->prev, REG_ITMP2);
1726 /* if (iptr->op1 == 0) { */
1727 gen_nullptr_check(s1);
1730 var_to_reg_int(s3, src, REG_ITMP3);
1732 M_MOV(s1, rd->argintregs[0]);
1733 M_MOV(s3, rd->argintregs[1]);
1735 disp = dseg_addaddress(cd, bte->fp);
1736 M_ALD(REG_ITMP3, REG_PV, disp);
1737 M_JSR(REG_RA, REG_ITMP3);
1740 M_BEQZ(REG_RESULT, 0);
1741 codegen_addxstorerefs(cd, mcodeptr);
1744 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1745 var_to_reg_int(s2, src->prev, REG_ITMP2);
1746 var_to_reg_int(s3, src, REG_ITMP3);
1747 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1748 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1749 M_AST(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1753 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1755 var_to_reg_int(s1, src->prev, REG_ITMP1);
1756 var_to_reg_int(s2, src, REG_ITMP2);
1757 if (iptr->op1 == 0) {
1758 gen_nullptr_check(s1);
1761 M_ASLL_IMM(s2, 2, REG_ITMP2);
1762 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1763 M_IST(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1766 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1768 var_to_reg_int(s1, src->prev, REG_ITMP1);
1769 var_to_reg_int(s2, src, REG_ITMP2);
1770 if (iptr->op1 == 0) {
1771 gen_nullptr_check(s1);
1774 M_ASLL_IMM(s2, 3, REG_ITMP2);
1775 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1776 M_LST(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1779 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1781 var_to_reg_int(s1, src->prev, REG_ITMP1);
1782 var_to_reg_int(s2, src, REG_ITMP2);
1783 if (iptr->op1 == 0) {
1784 gen_nullptr_check(s1);
1787 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1788 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1789 M_AST(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1792 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1794 var_to_reg_int(s1, src->prev, REG_ITMP1);
1795 var_to_reg_int(s2, src, REG_ITMP2);
1796 if (iptr->op1 == 0) {
1797 gen_nullptr_check(s1);
1800 M_AADD(s2, s1, REG_ITMP1);
1801 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1804 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1805 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1807 var_to_reg_int(s1, src->prev, REG_ITMP1);
1808 var_to_reg_int(s2, src, REG_ITMP2);
1809 if (iptr->op1 == 0) {
1810 gen_nullptr_check(s1);
1813 M_AADD(s2, s1, REG_ITMP1);
1814 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1815 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1819 case ICMD_GETSTATIC: /* ... ==> ..., value */
1820 /* op1 = type, val.a = field address */
1823 codegen_addpatchref(cd, mcodeptr,
1824 PATCHER_get_putstatic,
1825 (unresolved_field *) iptr->target);
1827 if (opt_showdisassemble) {
1834 fieldinfo *fi = iptr->val.a;
1836 if (!fi->class->initialized) {
1837 codegen_addpatchref(cd, mcodeptr,
1838 PATCHER_clinit, fi->class);
1840 if (opt_showdisassemble) {
1845 a = (ptrint) &(fi->value);
1848 a = dseg_addaddress(cd, a);
1849 M_ALD(REG_ITMP1, REG_PV, a);
1850 switch (iptr->op1) {
1852 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1853 M_ILD(d, REG_ITMP1, 0);
1854 store_reg_to_var_int(iptr->dst, d);
1857 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1858 M_LLD(d, REG_ITMP1, 0);
1859 store_reg_to_var_int(iptr->dst, d);
1862 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1863 M_ALD(d, REG_ITMP1, 0);
1864 store_reg_to_var_int(iptr->dst, d);
1867 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
1868 M_FLD(d, REG_ITMP1, 0);
1869 store_reg_to_var_flt(iptr->dst, d);
1872 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
1873 M_DLD(d, REG_ITMP1, 0);
1874 store_reg_to_var_flt(iptr->dst, d);
1879 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1880 /* op1 = type, val.a = field address */
1883 codegen_addpatchref(cd, mcodeptr,
1884 PATCHER_get_putstatic,
1885 (unresolved_field *) iptr->target);
1887 if (opt_showdisassemble) {
1894 fieldinfo *fi = iptr->val.a;
1896 if (!fi->class->initialized) {
1897 codegen_addpatchref(cd, mcodeptr,
1898 PATCHER_clinit, fi->class);
1900 if (opt_showdisassemble) {
1905 a = (ptrint) &(fi->value);
1908 a = dseg_addaddress(cd, a);
1909 M_ALD(REG_ITMP1, REG_PV, a);
1910 switch (iptr->op1) {
1912 var_to_reg_int(s2, src, REG_ITMP2);
1913 M_IST(s2, REG_ITMP1, 0);
1916 var_to_reg_int(s2, src, REG_ITMP2);
1917 M_LST(s2, REG_ITMP1, 0);
1920 var_to_reg_int(s2, src, REG_ITMP2);
1921 M_AST(s2, REG_ITMP1, 0);
1924 var_to_reg_flt(s2, src, REG_FTMP2);
1925 M_FST(s2, REG_ITMP1, 0);
1928 var_to_reg_flt(s2, src, REG_FTMP2);
1929 M_DST(s2, REG_ITMP1, 0);
1934 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1935 /* val = value (in current instruction) */
1936 /* op1 = type, val.a = field address (in */
1937 /* following NOP) */
1939 if (!iptr[1].val.a) {
1940 codegen_addpatchref(cd, mcodeptr,
1941 PATCHER_get_putstatic,
1942 (unresolved_field *) iptr[1].target);
1944 if (opt_showdisassemble) {
1951 fieldinfo *fi = iptr[1].val.a;
1953 if (!fi->class->initialized) {
1954 codegen_addpatchref(cd, mcodeptr,
1955 PATCHER_clinit, fi->class);
1957 if (opt_showdisassemble) {
1962 a = (ptrint) &(fi->value);
1965 a = dseg_addaddress(cd, a);
1966 M_ALD(REG_ITMP1, REG_PV, a);
1967 switch (iptr->op1) {
1969 M_IST(REG_ZERO, REG_ITMP1, 0);
1972 M_LST(REG_ZERO, REG_ITMP1, 0);
1975 M_AST(REG_ZERO, REG_ITMP1, 0);
1978 M_FST(REG_ZERO, REG_ITMP1, 0);
1981 M_DST(REG_ZERO, REG_ITMP1, 0);
1987 case ICMD_GETFIELD: /* ... ==> ..., value */
1988 /* op1 = type, val.i = field offset */
1990 var_to_reg_int(s1, src, REG_ITMP1);
1991 gen_nullptr_check(s1);
1994 codegen_addpatchref(cd, mcodeptr,
1995 PATCHER_get_putfield,
1996 (unresolved_field *) iptr->target);
1998 if (opt_showdisassemble) {
2005 a = ((fieldinfo *) (iptr->val.a))->offset;
2008 switch (iptr->op1) {
2010 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2012 store_reg_to_var_int(iptr->dst, d);
2015 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2017 store_reg_to_var_int(iptr->dst, d);
2020 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2022 store_reg_to_var_int(iptr->dst, d);
2025 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2027 store_reg_to_var_flt(iptr->dst, d);
2030 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2032 store_reg_to_var_flt(iptr->dst, d);
2035 /* XXX quick hack */
2039 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2040 /* op1 = type, val.a = field address */
2042 var_to_reg_int(s1, src->prev, REG_ITMP1);
2043 gen_nullptr_check(s1);
2045 if (!IS_FLT_DBL_TYPE(iptr->op1)) {
2046 var_to_reg_int(s2, src, REG_ITMP2);
2048 var_to_reg_flt(s2, src, REG_FTMP2);
2052 codegen_addpatchref(cd, mcodeptr,
2053 PATCHER_get_putfield,
2054 (unresolved_field *) iptr->target);
2056 if (opt_showdisassemble) {
2063 a = ((fieldinfo *) (iptr->val.a))->offset;
2066 switch (iptr->op1) {
2083 /* XXX quick hack */
2087 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2088 /* val = value (in current instruction) */
2089 /* op1 = type, val.a = field address (in */
2090 /* following NOP) */
2092 var_to_reg_int(s1, src, REG_ITMP1);
2093 gen_nullptr_check(s1);
2095 if (!iptr[1].val.a) {
2096 codegen_addpatchref(cd, mcodeptr,
2097 PATCHER_get_putfield,
2098 (unresolved_field *) iptr[1].target);
2100 if (opt_showdisassemble) {
2107 a = ((fieldinfo *) (iptr[1].val.a))->offset;
2110 switch (iptr[1].op1) {
2112 M_IST(REG_ZERO, s1, a);
2115 M_LST(REG_ZERO, s1, a);
2118 M_AST(REG_ZERO, s1, a);
2121 M_FST(REG_ZERO, s1, a);
2124 M_DST(REG_ZERO, s1, a);
2127 /* XXX quick hack */
2132 /* branch operations **************************************************/
2134 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2136 var_to_reg_int(s1, src, REG_ITMP1);
2137 M_INTMOVE(s1, REG_ITMP1_XPTR);
2138 a = dseg_addaddress(cd, asm_handle_exception);
2139 M_ALD(REG_ITMP2, REG_PV, a);
2140 M_JSR(REG_ITMP2_XPC, REG_ITMP2);
2142 M_NOP; /* nop ensures that XPC is less than the end */
2143 /* of basic block */
2147 case ICMD_GOTO: /* ... ==> ... */
2148 /* op1 = target JavaVM pc */
2150 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2155 case ICMD_JSR: /* ... ==> ... */
2156 /* op1 = target JavaVM pc */
2158 dseg_addtarget(cd, BlockPtrOfPC(iptr->op1));
2159 M_ALD(REG_ITMP1, REG_PV, -(cd->dseglen));
2160 M_JSR(REG_ITMP1, REG_ITMP1); /* REG_ITMP1 = return address */
2164 case ICMD_RET: /* ... ==> ... */
2165 /* op1 = local variable */
2166 var = &(rd->locals[iptr->op1][TYPE_ADR]);
2167 if (var->flags & INMEMORY) {
2168 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2177 case ICMD_IFNULL: /* ..., value ==> ... */
2178 /* op1 = target JavaVM pc */
2180 var_to_reg_int(s1, src, REG_ITMP1);
2182 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2186 case ICMD_IFNONNULL: /* ..., value ==> ... */
2187 /* op1 = target JavaVM pc */
2189 var_to_reg_int(s1, src, REG_ITMP1);
2191 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2195 case ICMD_IFEQ: /* ..., value ==> ... */
2196 /* op1 = target JavaVM pc, val.i = constant */
2198 var_to_reg_int(s1, src, REG_ITMP1);
2199 if (iptr->val.i == 0) {
2203 ICONST(REG_ITMP2, iptr->val.i);
2204 M_BEQ(s1, REG_ITMP2, 0);
2206 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2210 case ICMD_IFLT: /* ..., value ==> ... */
2211 /* op1 = target JavaVM pc, val.i = constant */
2213 var_to_reg_int(s1, src, REG_ITMP1);
2214 if (iptr->val.i == 0) {
2218 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
2219 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2222 ICONST(REG_ITMP2, iptr->val.i);
2223 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2225 M_BNEZ(REG_ITMP1, 0);
2227 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2231 case ICMD_IFLE: /* ..., value ==> ... */
2232 /* op1 = target JavaVM pc, val.i = constant */
2234 var_to_reg_int(s1, src, REG_ITMP1);
2235 if (iptr->val.i == 0) {
2239 if ((iptr->val.i >= -32769) && (iptr->val.i <= 32766)) {
2240 M_CMPLT_IMM(s1, iptr->val.i + 1, REG_ITMP1);
2241 M_BNEZ(REG_ITMP1, 0);
2244 ICONST(REG_ITMP2, iptr->val.i);
2245 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2246 M_BEQZ(REG_ITMP1, 0);
2249 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2253 case ICMD_IFNE: /* ..., value ==> ... */
2254 /* op1 = target JavaVM pc, val.i = constant */
2256 var_to_reg_int(s1, src, REG_ITMP1);
2257 if (iptr->val.i == 0) {
2261 ICONST(REG_ITMP2, iptr->val.i);
2262 M_BNE(s1, REG_ITMP2, 0);
2264 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2268 case ICMD_IFGT: /* ..., value ==> ... */
2269 /* op1 = target JavaVM pc, val.i = constant */
2271 var_to_reg_int(s1, src, REG_ITMP1);
2272 if (iptr->val.i == 0) {
2276 if ((iptr->val.i >= -32769) && (iptr->val.i <= 32766)) {
2277 M_CMPLT_IMM(s1, iptr->val.i + 1, REG_ITMP1);
2278 M_BEQZ(REG_ITMP1, 0);
2281 ICONST(REG_ITMP2, iptr->val.i);
2282 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2283 M_BNEZ(REG_ITMP1, 0);
2286 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2290 case ICMD_IFGE: /* ..., value ==> ... */
2291 /* op1 = target JavaVM pc, val.i = constant */
2293 var_to_reg_int(s1, src, REG_ITMP1);
2294 if (iptr->val.i == 0) {
2298 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
2299 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2302 ICONST(REG_ITMP2, iptr->val.i);
2303 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2305 M_BEQZ(REG_ITMP1, 0);
2307 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2311 case ICMD_IF_LEQ: /* ..., value ==> ... */
2312 /* op1 = target JavaVM pc, val.l = constant */
2314 var_to_reg_int(s1, src, REG_ITMP1);
2315 if (iptr->val.l == 0) {
2319 LCONST(REG_ITMP2, iptr->val.l);
2320 M_BEQ(s1, REG_ITMP2, 0);
2322 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2326 case ICMD_IF_LLT: /* ..., value ==> ... */
2327 /* op1 = target JavaVM pc, val.l = constant */
2329 var_to_reg_int(s1, src, REG_ITMP1);
2330 if (iptr->val.l == 0) {
2334 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2335 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2338 LCONST(REG_ITMP2, iptr->val.l);
2339 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2341 M_BNEZ(REG_ITMP1, 0);
2343 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2347 case ICMD_IF_LLE: /* ..., value ==> ... */
2348 /* op1 = target JavaVM pc, val.l = constant */
2350 var_to_reg_int(s1, src, REG_ITMP1);
2351 if (iptr->val.l == 0) {
2355 if ((iptr->val.l >= -32769) && (iptr->val.l <= 32766)) {
2356 M_CMPLT_IMM(s1, iptr->val.l + 1, REG_ITMP1);
2357 M_BNEZ(REG_ITMP1, 0);
2360 LCONST(REG_ITMP2, iptr->val.l);
2361 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2362 M_BEQZ(REG_ITMP1, 0);
2365 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2369 case ICMD_IF_LNE: /* ..., value ==> ... */
2370 /* op1 = target JavaVM pc, val.l = constant */
2372 var_to_reg_int(s1, src, REG_ITMP1);
2373 if (iptr->val.l == 0) {
2377 LCONST(REG_ITMP2, iptr->val.l);
2378 M_BNE(s1, REG_ITMP2, 0);
2380 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2384 case ICMD_IF_LGT: /* ..., value ==> ... */
2385 /* op1 = target JavaVM pc, val.l = constant */
2387 var_to_reg_int(s1, src, REG_ITMP1);
2388 if (iptr->val.l == 0) {
2392 if ((iptr->val.l >= -32769) && (iptr->val.l <= 32766)) {
2393 M_CMPLT_IMM(s1, iptr->val.l + 1, REG_ITMP1);
2394 M_BEQZ(REG_ITMP1, 0);
2397 LCONST(REG_ITMP2, iptr->val.l);
2398 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2399 M_BNEZ(REG_ITMP1, 0);
2402 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2406 case ICMD_IF_LGE: /* ..., value ==> ... */
2407 /* op1 = target JavaVM pc, val.l = constant */
2409 var_to_reg_int(s1, src, REG_ITMP1);
2410 if (iptr->val.l == 0) {
2414 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2415 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2418 LCONST(REG_ITMP2, iptr->val.l);
2419 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2421 M_BEQZ(REG_ITMP1, 0);
2423 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2427 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2428 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2429 case ICMD_IF_ACMPEQ:
2431 var_to_reg_int(s1, src->prev, REG_ITMP1);
2432 var_to_reg_int(s2, src, REG_ITMP2);
2434 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2438 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2439 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2440 case ICMD_IF_ACMPNE:
2442 var_to_reg_int(s1, src->prev, REG_ITMP1);
2443 var_to_reg_int(s2, src, REG_ITMP2);
2445 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2449 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2450 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2452 var_to_reg_int(s1, src->prev, REG_ITMP1);
2453 var_to_reg_int(s2, src, REG_ITMP2);
2454 M_CMPLT(s1, s2, REG_ITMP1);
2455 M_BNEZ(REG_ITMP1, 0);
2456 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2460 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2461 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2463 var_to_reg_int(s1, src->prev, REG_ITMP1);
2464 var_to_reg_int(s2, src, REG_ITMP2);
2465 M_CMPGT(s1, s2, REG_ITMP1);
2466 M_BNEZ(REG_ITMP1, 0);
2467 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2471 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2472 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2474 var_to_reg_int(s1, src->prev, REG_ITMP1);
2475 var_to_reg_int(s2, src, REG_ITMP2);
2476 M_CMPGT(s1, s2, REG_ITMP1);
2477 M_BEQZ(REG_ITMP1, 0);
2478 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2482 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2483 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2485 var_to_reg_int(s1, src->prev, REG_ITMP1);
2486 var_to_reg_int(s2, src, REG_ITMP2);
2487 M_CMPLT(s1, s2, REG_ITMP1);
2488 M_BEQZ(REG_ITMP1, 0);
2489 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2493 #ifdef CONDITIONAL_LOADCONST
2494 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2496 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2499 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2500 /* val.i = constant */
2502 var_to_reg_int(s1, src, REG_ITMP1);
2503 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2505 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2506 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2507 M_CMPEQ(s1, REG_ZERO, d);
2508 store_reg_to_var_int(iptr->dst, d);
2511 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2512 M_CMPEQ(s1, REG_ZERO, d);
2514 store_reg_to_var_int(iptr->dst, d);
2518 M_MOV(s1, REG_ITMP1);
2521 ICONST(d, iptr[1].val.i);
2523 if ((s3 >= 0) && (s3 <= 255)) {
2524 M_CMOVEQ_IMM(s1, s3, d);
2527 ICONST(REG_ITMP2, s3);
2528 M_CMOVEQ(s1, REG_ITMP2, d);
2530 store_reg_to_var_int(iptr->dst, d);
2533 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2534 /* val.i = constant */
2536 var_to_reg_int(s1, src, REG_ITMP1);
2537 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2539 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2540 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2541 M_CMPEQ(s1, REG_ZERO, d);
2542 store_reg_to_var_int(iptr->dst, d);
2545 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2546 M_CMPEQ(s1, REG_ZERO, d);
2548 store_reg_to_var_int(iptr->dst, d);
2552 M_MOV(s1, REG_ITMP1);
2555 ICONST(d, iptr[1].val.i);
2557 if ((s3 >= 0) && (s3 <= 255)) {
2558 M_CMOVNE_IMM(s1, s3, d);
2561 ICONST(REG_ITMP2, s3);
2562 M_CMOVNE(s1, REG_ITMP2, d);
2564 store_reg_to_var_int(iptr->dst, d);
2567 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2568 /* val.i = constant */
2570 var_to_reg_int(s1, src, REG_ITMP1);
2571 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2573 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2574 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2575 M_CMPLT(s1, REG_ZERO, d);
2576 store_reg_to_var_int(iptr->dst, d);
2579 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2580 M_CMPLE(REG_ZERO, s1, d);
2581 store_reg_to_var_int(iptr->dst, d);
2585 M_MOV(s1, REG_ITMP1);
2588 ICONST(d, iptr[1].val.i);
2590 if ((s3 >= 0) && (s3 <= 255)) {
2591 M_CMOVLT_IMM(s1, s3, d);
2594 ICONST(REG_ITMP2, s3);
2595 M_CMOVLT(s1, REG_ITMP2, d);
2597 store_reg_to_var_int(iptr->dst, d);
2600 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2601 /* val.i = constant */
2603 var_to_reg_int(s1, src, REG_ITMP1);
2604 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2606 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2607 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2608 M_CMPLE(REG_ZERO, s1, d);
2609 store_reg_to_var_int(iptr->dst, d);
2612 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2613 M_CMPLT(s1, REG_ZERO, d);
2614 store_reg_to_var_int(iptr->dst, d);
2618 M_MOV(s1, REG_ITMP1);
2621 ICONST(d, iptr[1].val.i);
2623 if ((s3 >= 0) && (s3 <= 255)) {
2624 M_CMOVGE_IMM(s1, s3, d);
2627 ICONST(REG_ITMP2, s3);
2628 M_CMOVGE(s1, REG_ITMP2, d);
2630 store_reg_to_var_int(iptr->dst, d);
2633 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2634 /* val.i = constant */
2636 var_to_reg_int(s1, src, REG_ITMP1);
2637 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2639 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2640 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2641 M_CMPLT(REG_ZERO, s1, d);
2642 store_reg_to_var_int(iptr->dst, d);
2645 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2646 M_CMPLE(s1, REG_ZERO, d);
2647 store_reg_to_var_int(iptr->dst, d);
2651 M_MOV(s1, REG_ITMP1);
2654 ICONST(d, iptr[1].val.i);
2656 if ((s3 >= 0) && (s3 <= 255)) {
2657 M_CMOVGT_IMM(s1, s3, d);
2660 ICONST(REG_ITMP2, s3);
2661 M_CMOVGT(s1, REG_ITMP2, d);
2663 store_reg_to_var_int(iptr->dst, d);
2666 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2667 /* val.i = constant */
2669 var_to_reg_int(s1, src, REG_ITMP1);
2670 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2672 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2673 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2674 M_CMPLE(s1, REG_ZERO, d);
2675 store_reg_to_var_int(iptr->dst, d);
2678 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2679 M_CMPLT(REG_ZERO, s1, d);
2680 store_reg_to_var_int(iptr->dst, d);
2684 M_MOV(s1, REG_ITMP1);
2687 ICONST(d, iptr[1].val.i);
2689 if ((s3 >= 0) && (s3 <= 255)) {
2690 M_CMOVLE_IMM(s1, s3, d);
2693 ICONST(REG_ITMP2, s3);
2694 M_CMOVLE(s1, REG_ITMP2, d);
2696 store_reg_to_var_int(iptr->dst, d);
2701 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2704 var_to_reg_int(s1, src, REG_RESULT);
2705 M_INTMOVE(s1, REG_RESULT);
2707 #if defined(USE_THREADS)
2708 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2710 a = dseg_addaddress(cd, (void *) builtin_monitorexit);
2711 M_ALD(REG_ITMP3, REG_PV, a);
2712 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8);
2713 M_JSR(REG_RA, REG_ITMP3);
2714 M_LST(REG_RESULT, REG_SP, rd->memuse * 8); /* delay slot */
2716 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
2717 M_LDA(REG_PV, REG_RA, disp);
2718 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2721 goto nowperformreturn;
2723 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2725 var_to_reg_flt(s1, src, REG_FRESULT);
2727 int t = ((iptr->opc == ICMD_FRETURN) ? TYPE_FLT : TYPE_DBL);
2728 M_TFLTMOVE(t, s1, REG_FRESULT);
2731 #if defined(USE_THREADS)
2732 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2734 a = dseg_addaddress(cd, (void *) builtin_monitorexit);
2735 M_ALD(REG_ITMP3, REG_PV, a);
2736 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8);
2737 M_JSR(REG_RA, REG_ITMP3);
2738 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8); /* delay slot */
2740 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
2741 M_LDA(REG_PV, REG_RA, disp);
2742 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2745 goto nowperformreturn;
2747 case ICMD_RETURN: /* ... ==> ... */
2749 #if defined(USE_THREADS)
2750 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2752 a = dseg_addaddress(cd, (void *) builtin_monitorexit);
2753 M_ALD(REG_ITMP3, REG_PV, a);
2754 M_JSR(REG_RA, REG_ITMP3);
2755 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8); /* delay slot */
2756 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
2757 M_LDA(REG_PV, REG_RA, disp);
2765 p = parentargs_base;
2767 /* restore return address */
2769 if (!m->isleafmethod) {
2770 p--; M_LLD(REG_RA, REG_SP, 8 * p);
2773 /* restore saved registers */
2775 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2776 p--; M_LLD(rd->savintregs[i], REG_SP, 8 * p);
2778 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2779 p--; M_DLD(rd->savfltregs[i], REG_SP, 8 * p);
2782 /* call trace function */
2785 M_LDA (REG_SP, REG_SP, -24);
2786 M_LST(REG_RA, REG_SP, 0);
2787 M_LST(REG_RESULT, REG_SP, 8);
2788 M_DST(REG_FRESULT, REG_SP,16);
2789 a = dseg_addaddress(cd, m);
2790 M_ALD(rd->argintregs[0], REG_PV, a);
2791 M_MOV(REG_RESULT, rd->argintregs[1]);
2792 M_FLTMOVE(REG_FRESULT, rd->argfltregs[2]);
2793 M_FMOV(REG_FRESULT, rd->argfltregs[3]);
2794 a = dseg_addaddress(cd, (void *) builtin_displaymethodstop);
2795 M_ALD(REG_ITMP3, REG_PV, a);
2796 M_JSR (REG_RA, REG_ITMP3);
2798 M_DLD(REG_FRESULT, REG_SP,16);
2799 M_LLD(REG_RESULT, REG_SP, 8);
2800 M_LLD(REG_RA, REG_SP, 0);
2801 M_LDA (REG_SP, REG_SP, 24);
2806 /* deallocate stack */
2808 if (parentargs_base) {
2809 M_LDA(REG_SP, REG_SP, parentargs_base * 8);
2820 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2825 tptr = (void **) iptr->target;
2827 s4ptr = iptr->val.a;
2828 l = s4ptr[1]; /* low */
2829 i = s4ptr[2]; /* high */
2831 var_to_reg_int(s1, src, REG_ITMP1);
2833 {M_INTMOVE(s1, REG_ITMP1);}
2834 else if (l <= 32768) {
2835 M_IADD_IMM(s1, -l, REG_ITMP1);
2838 ICONST(REG_ITMP2, l);
2839 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2845 M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
2846 M_BEQZ(REG_ITMP2, 0);
2847 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
2848 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1); /* delay slot*/
2850 /* build jump table top down and use address of lowest entry */
2852 /* s4ptr += 3 + i; */
2856 /* dseg_addtarget(cd, BlockPtrOfPC(*--s4ptr)); */
2857 dseg_addtarget(cd, (basicblock *) tptr[0]);
2862 /* length of dataseg after last dseg_addtarget is used by load */
2864 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2865 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2872 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2874 s4 i, /*l, */val, *s4ptr;
2877 tptr = (void **) iptr->target;
2879 s4ptr = iptr->val.a;
2880 /*l = s4ptr[0];*/ /* default */
2881 i = s4ptr[1]; /* count */
2883 MCODECHECK((i<<2)+8);
2884 var_to_reg_int(s1, src, REG_ITMP1);
2890 ICONST(REG_ITMP2, val);
2891 M_BEQ(s1, REG_ITMP2, 0);
2892 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
2897 tptr = (void **) iptr->target;
2898 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
2905 case ICMD_BUILTIN: /* ..., arg1 ==> ... */
2906 /* op1 = arg count val.a = builtintable entry */
2912 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2913 /* op1 = arg count, val.a = method pointer */
2915 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2916 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2917 case ICMD_INVOKEINTERFACE:
2922 md = lm->parseddesc;
2924 unresolved_method *um = iptr->target;
2925 md = um->methodref->parseddesc.md;
2931 MCODECHECK((s3 << 1) + 64);
2933 /* copy arguments to registers or stack location */
2935 for (s3 = s3 - 1; s3 >= 0; s3--, src = src->prev) {
2936 if (src->varkind == ARGVAR)
2938 if (IS_INT_LNG_TYPE(src->type)) {
2939 if (!md->params[s3].inmemory) {
2940 s1 = rd->argintregs[md->params[s3].regoff];
2941 var_to_reg_int(d, src, s1);
2944 var_to_reg_int(d, src, REG_ITMP1);
2945 M_LST(d, REG_SP, md->params[s3].regoff * 8);
2949 if (!md->params[s3].inmemory) {
2950 s1 = rd->argfltregs[md->params[s3].regoff];
2951 var_to_reg_flt(d, src, s1);
2952 M_TFLTMOVE(src->type, d, s1);
2954 var_to_reg_flt(d, src, REG_FTMP1);
2955 M_DST(d, REG_SP, md->params[s3].regoff * 8);
2960 switch (iptr->opc) {
2963 codegen_addpatchref(cd, mcodeptr, bte->fp, iptr->target);
2965 if (opt_showdisassemble) {
2972 a = (ptrint) bte->fp;
2975 a = dseg_addaddress(cd, a);
2976 d = md->returntype.type;
2978 M_ALD(REG_ITMP3, REG_PV, a); /* built-in-function pointer */
2979 M_JSR(REG_RA, REG_ITMP3);
2981 goto afteractualcall;
2983 case ICMD_INVOKESPECIAL:
2984 gen_nullptr_check(rd->argintregs[0]);
2985 M_ILD(REG_ITMP1, rd->argintregs[0], 0); /* hardware nullptr */
2988 case ICMD_INVOKESTATIC:
2990 unresolved_method *um = iptr->target;
2992 codegen_addpatchref(cd, mcodeptr,
2993 PATCHER_invokestatic_special, um);
2995 if (opt_showdisassemble) {
3000 d = um->methodref->parseddesc.md->returntype.type;
3003 a = (ptrint) lm->stubroutine;
3004 d = lm->parseddesc->returntype.type;
3007 a = dseg_addaddress(cd, a);
3008 M_ALD(REG_PV, REG_PV, a); /* method pointer in pv */
3011 case ICMD_INVOKEVIRTUAL:
3012 gen_nullptr_check(rd->argintregs[0]);
3015 unresolved_method *um = iptr->target;
3017 codegen_addpatchref(cd, mcodeptr,
3018 PATCHER_invokevirtual, um);
3020 if (opt_showdisassemble) {
3025 d = um->methodref->parseddesc.md->returntype.type;
3028 s1 = OFFSET(vftbl_t, table[0]) +
3029 sizeof(methodptr) * lm->vftblindex;
3030 d = lm->parseddesc->returntype.type;
3033 M_ALD(REG_METHODPTR, rd->argintregs[0],
3034 OFFSET(java_objectheader, vftbl));
3035 M_ALD(REG_PV, REG_METHODPTR, s1);
3038 case ICMD_INVOKEINTERFACE:
3039 gen_nullptr_check(rd->argintregs[0]);
3042 unresolved_method *um = iptr->target;
3044 codegen_addpatchref(cd, mcodeptr,
3045 PATCHER_invokeinterface, um);
3047 if (opt_showdisassemble) {
3053 d = um->methodref->parseddesc.md->returntype.type;
3056 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3057 sizeof(methodptr*) * lm->class->index;
3059 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3061 d = lm->parseddesc->returntype.type;
3064 M_ALD(REG_METHODPTR, rd->argintregs[0],
3065 OFFSET(java_objectheader, vftbl));
3066 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3067 M_ALD(REG_PV, REG_METHODPTR, s2);
3071 M_JSR(REG_RA, REG_PV);
3078 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3079 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3081 s4 ml = -s1, mh = 0;
3082 while (ml < -32768) { ml += 65536; mh--; }
3084 M_IADD_IMM(REG_PV, ml, REG_PV);
3085 M_LADD(REG_PV, REG_RA, REG_PV);
3088 /* d contains return type */
3090 if (d != TYPE_VOID) {
3091 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3092 s1 = reg_of_var(rd, iptr->dst, REG_RESULT);
3093 M_INTMOVE(REG_RESULT, s1);
3094 store_reg_to_var_int(iptr->dst, s1);
3096 s1 = reg_of_var(rd, iptr->dst, REG_FRESULT);
3097 M_TFLTMOVE(iptr->dst->type, REG_FRESULT, s1);
3098 store_reg_to_var_flt(iptr->dst, s1);
3104 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3105 /* op1: 0 == array, 1 == class */
3106 /* val.a: (classinfo*) superclass */
3108 /* superclass is an interface:
3110 * OK if ((sub == NULL) ||
3111 * (sub->vftbl->interfacetablelength > super->index) &&
3112 * (sub->vftbl->interfacetable[-super->index] != NULL));
3114 * superclass is a class:
3116 * OK if ((sub == NULL) || (0
3117 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3118 * super->vftbl->diffvall));
3123 vftbl_t *supervftbl;
3126 super = (classinfo *) iptr->val.a;
3133 superindex = super->index;
3134 supervftbl = super->vftbl;
3137 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3138 codegen_threadcritrestart(cd, (u1 *) mcodeptr - cd->mcodebase);
3141 var_to_reg_int(s1, src, REG_ITMP1);
3143 /* calculate interface checkcast code size */
3147 s2 += (opt_showdisassemble ? 2 : 0);
3149 /* calculate class checkcast code size */
3151 s3 = 10 /* 10 + (s1 == REG_ITMP1) */;
3153 s3 += (opt_showdisassemble ? 2 : 0);
3155 /* if class is not resolved, check which code to call */
3158 M_BEQZ(s1, 5 + (opt_showdisassemble ? 2 : 0) + s2 + 2 + s3);
3161 codegen_addpatchref(cd, mcodeptr,
3162 PATCHER_checkcast_instanceof_flags,
3163 (constant_classref *) iptr->target);
3165 if (opt_showdisassemble) {
3169 a = dseg_adds4(cd, 0); /* super->flags */
3170 M_ILD(REG_ITMP2, REG_PV, a);
3171 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
3172 M_BEQZ(REG_ITMP2, 1 + s2 + 2);
3176 /* interface checkcast code */
3178 if (!super || super->flags & ACC_INTERFACE) {
3184 codegen_addpatchref(cd, mcodeptr,
3185 PATCHER_checkcast_instanceof_interface,
3186 (constant_classref *) iptr->target);
3188 if (opt_showdisassemble) {
3193 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3194 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
3195 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3196 M_BLEZ(REG_ITMP3, 0);
3197 codegen_addxcastrefs(cd, mcodeptr);
3199 M_ALD(REG_ITMP3, REG_ITMP2,
3200 OFFSET(vftbl_t, interfacetable[0]) -
3201 superindex * sizeof(methodptr*));
3202 M_BEQZ(REG_ITMP3, 0);
3203 codegen_addxcastrefs(cd, mcodeptr);
3212 /* class checkcast code */
3214 if (!super || !(super->flags & ACC_INTERFACE)) {
3220 codegen_addpatchref(cd, mcodeptr,
3221 PATCHER_checkcast_instanceof_class,
3222 (constant_classref *) iptr->target);
3224 if (opt_showdisassemble) {
3229 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3230 a = dseg_addaddress(cd, (void *) supervftbl);
3231 M_ALD(REG_ITMP3, REG_PV, a);
3232 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3233 codegen_threadcritstart(cd, (u1 *) mcodeptr - cd->mcodebase);
3235 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3236 /* if (s1 != REG_ITMP1) { */
3237 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3238 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3239 /* #if defined(USE_THREADS) && defined(NATIVE_THREADS) */
3240 /* codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase); */
3242 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3244 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3245 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3246 M_ALD(REG_ITMP3, REG_PV, a);
3247 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3248 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3249 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3252 M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3253 M_BNEZ(REG_ITMP3, 0);
3254 codegen_addxcastrefs(cd, mcodeptr);
3257 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
3259 store_reg_to_var_int(iptr->dst, d);
3263 case ICMD_ARRAYCHECKCAST: /* ..., objectref ==> ..., objectref */
3264 /* op1: 1... resolved, 0... not resolved */
3266 var_to_reg_int(s1, src, rd->argintregs[0]);
3267 M_INTMOVE(s1, rd->argintregs[0]);
3272 codegen_addpatchref(cd, mcodeptr, bte->fp, iptr->target);
3274 if (opt_showdisassemble) {
3281 a = (ptrint) bte->fp;
3284 disp = dseg_addaddress(cd, iptr->target);
3285 M_ALD(rd->argintregs[1], REG_PV, disp);
3286 disp = dseg_addaddress(cd, a);
3287 M_ALD(REG_ITMP3, REG_PV, disp);
3288 M_JSR(REG_RA, REG_ITMP3);
3291 M_BEQZ(REG_RESULT, 0);
3292 codegen_addxcastrefs(cd, mcodeptr);
3295 var_to_reg_int(s1, src, REG_ITMP1);
3296 d = reg_of_var(rd, iptr->dst, s1);
3298 store_reg_to_var_int(iptr->dst, d);
3301 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3302 /* op1: 0 == array, 1 == class */
3303 /* val.a: (classinfo*) superclass */
3305 /* superclass is an interface:
3307 * return (sub != NULL) &&
3308 * (sub->vftbl->interfacetablelength > super->index) &&
3309 * (sub->vftbl->interfacetable[-super->index] != NULL);
3311 * superclass is a class:
3313 * return ((sub != NULL) && (0
3314 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3315 * super->vftbl->diffvall));
3320 vftbl_t *supervftbl;
3323 super = (classinfo *) iptr->val.a;
3330 superindex = super->index;
3331 supervftbl = super->vftbl;
3334 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3335 codegen_threadcritrestart(cd, (u1 *) mcodeptr - cd->mcodebase);
3338 var_to_reg_int(s1, src, REG_ITMP1);
3339 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
3341 M_MOV(s1, REG_ITMP1);
3345 /* calculate interface instanceof code size */
3349 s2 += (opt_showdisassemble ? 2 : 0);
3351 /* calculate class instanceof code size */
3355 s3 += (opt_showdisassemble ? 2 : 0);
3359 /* if class is not resolved, check which code to call */
3362 M_BEQZ(s1, 5 + (opt_showdisassemble ? 2 : 0) + s2 + 2 + s3);
3365 codegen_addpatchref(cd, mcodeptr,
3366 PATCHER_checkcast_instanceof_flags,
3367 (constant_classref *) iptr->target);
3369 if (opt_showdisassemble) {
3373 a = dseg_adds4(cd, 0); /* super->flags */
3374 M_ILD(REG_ITMP3, REG_PV, a);
3375 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
3376 M_BEQZ(REG_ITMP3, 1 + s2 + 2);
3380 /* interface instanceof code */
3382 if (!super || (super->flags & ACC_INTERFACE)) {
3388 codegen_addpatchref(cd, mcodeptr,
3389 PATCHER_checkcast_instanceof_interface,
3390 (constant_classref *) iptr->target);
3392 if (opt_showdisassemble) {
3397 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3398 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3399 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3400 M_BLEZ(REG_ITMP3, 3);
3402 M_ALD(REG_ITMP1, REG_ITMP1,
3403 OFFSET(vftbl_t, interfacetable[0]) -
3404 superindex * sizeof(methodptr*));
3405 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3413 /* class instanceof code */
3415 if (!super || !(super->flags & ACC_INTERFACE)) {
3421 codegen_addpatchref(cd, mcodeptr,
3422 PATCHER_checkcast_instanceof_class,
3423 (constant_classref *) iptr->target);
3425 if (opt_showdisassemble) {
3430 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3431 a = dseg_addaddress(cd, supervftbl);
3432 M_ALD(REG_ITMP2, REG_PV, a);
3433 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3434 codegen_threadcritstart(cd, (u1 *) mcodeptr - cd->mcodebase);
3436 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3437 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3438 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3439 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3440 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3442 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3443 M_CMPULT(REG_ITMP2, REG_ITMP1, d);
3446 store_reg_to_var_int(iptr->dst, d);
3450 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
3452 var_to_reg_int(s1, src, REG_ITMP1);
3454 codegen_addxcheckarefs(cd, mcodeptr);
3458 case ICMD_CHECKEXCEPTION: /* ... ==> ... */
3460 M_BEQZ(REG_RESULT, 0);
3461 codegen_addxexceptionrefs(cd, mcodeptr);
3465 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3466 /* op1 = dimension, val.a = array descriptor */
3468 /* check for negative sizes and copy sizes to stack if necessary */
3470 MCODECHECK((iptr->op1 << 1) + 64);
3472 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3473 var_to_reg_int(s2, src, REG_ITMP1);
3475 codegen_addxcheckarefs(cd, mcodeptr);
3478 /* copy SAVEDVAR sizes to stack */
3480 if (src->varkind != ARGVAR) {
3481 M_LST(s2, REG_SP, s1 * 8);
3485 /* is patcher function set? */
3488 codegen_addpatchref(cd, mcodeptr,
3489 (functionptr) iptr->target, iptr->val.a);
3491 if (opt_showdisassemble) {
3498 a = (ptrint) iptr->val.a;
3501 /* a0 = dimension count */
3503 ICONST(rd->argintregs[0], iptr->op1);
3505 /* a1 = arraydescriptor */
3507 a = dseg_addaddress(cd, a);
3508 M_ALD(rd->argintregs[1], REG_PV, a);
3510 /* a2 = pointer to dimensions = stack pointer */
3512 M_INTMOVE(REG_SP, rd->argintregs[2]);
3514 a = dseg_addaddress(cd, BUILTIN_multianewarray);
3515 M_ALD(REG_ITMP3, REG_PV, a);
3516 M_JSR(REG_RA, REG_ITMP3);
3518 s1 = (s4)((u1 *) mcodeptr - cd->mcodebase);
3520 M_LDA(REG_PV, REG_RA, -s1);
3524 s1 = reg_of_var(rd, iptr->dst, REG_RESULT);
3525 M_INTMOVE(REG_RESULT, s1);
3526 store_reg_to_var_int(iptr->dst, s1);
3530 throw_cacao_exception_exit(string_java_lang_InternalError,
3531 "Unknown ICMD %d", iptr->opc);
3534 } /* for instruction */
3536 /* copy values to interface registers */
3538 src = bptr->outstack;
3539 len = bptr->outdepth;
3546 if ((src->varkind != STACKVAR)) {
3548 if (IS_FLT_DBL_TYPE(s2)) {
3549 var_to_reg_flt(s1, src, REG_FTMP1);
3550 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3551 M_TFLTMOVE(s2, s1, rd->interfaces[len][s2].regoff);
3554 M_DST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3558 var_to_reg_int(s1, src, REG_ITMP1);
3559 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3560 M_INTMOVE(s1, rd->interfaces[len][s2].regoff);
3563 M_LST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3569 } /* if (bptr -> flags >= BBREACHED) */
3570 } /* for basic block */
3576 /* generate ArithmeticException stubs */
3580 for (bref = cd->xdivrefs; bref != NULL; bref = bref->next) {
3581 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3582 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3584 (u1 *) xcodeptr - cd->mcodebase - 4);
3588 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3590 (u1 *) mcodeptr - cd->mcodebase);
3594 M_AADD_IMM(REG_PV, bref->branchpos - 4, REG_ITMP2_XPC);
3596 if (xcodeptr != NULL) {
3597 M_BR(xcodeptr - mcodeptr);
3601 xcodeptr = mcodeptr;
3603 M_ASUB_IMM(REG_SP, 1 * 8, REG_SP);
3604 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3606 a = dseg_addaddress(cd, new_arithmeticexception);
3607 M_ALD(REG_ITMP3, REG_PV, a);
3608 M_JSR(REG_RA, REG_ITMP3);
3610 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3612 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3613 M_AADD_IMM(REG_SP, 1 * 8, REG_SP);
3615 a = dseg_addaddress(cd, asm_handle_exception);
3616 M_ALD(REG_ITMP3, REG_PV, a);
3622 /* generate bound check stubs */
3626 for (bref = cd->xboundrefs; bref != NULL; bref = bref->next) {
3627 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3629 (u1 *) mcodeptr - cd->mcodebase);
3633 M_MOV(bref->reg, REG_ITMP1);
3634 M_AADD_IMM(REG_PV, bref->branchpos - 4, REG_ITMP2_XPC);
3636 if (xcodeptr != NULL) {
3637 M_BR(xcodeptr - mcodeptr);
3641 xcodeptr = mcodeptr;
3643 M_ASUB_IMM(REG_SP, 1 * 8, REG_SP);
3644 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3646 M_MOV(REG_ITMP1, rd->argintregs[0]);
3647 a = dseg_addaddress(cd, new_arrayindexoutofboundsexception);
3648 M_ALD(REG_ITMP3, REG_PV, a);
3649 M_JSR(REG_RA, REG_ITMP3);
3651 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3653 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3654 M_AADD_IMM(REG_SP, 1 * 8, REG_SP);
3656 a = dseg_addaddress(cd, asm_handle_exception);
3657 M_ALD(REG_ITMP3, REG_PV, a);
3663 /* generate ArithmeticException stubs */
3667 for (bref = cd->xstorerefs; bref != NULL; bref = bref->next) {
3668 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3669 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3671 (u1 *) xcodeptr - cd->mcodebase - 4);
3675 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3677 (u1 *) mcodeptr - cd->mcodebase);
3681 M_AADD_IMM(REG_PV, bref->branchpos - 4, REG_ITMP2_XPC);
3683 if (xcodeptr != NULL) {
3684 M_BR(xcodeptr - mcodeptr);
3688 xcodeptr = mcodeptr;
3690 M_ASUB_IMM(REG_SP, 1 * 8, REG_SP);
3691 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3693 a = dseg_addaddress(cd, new_arraystoreexception);
3694 M_ALD(REG_ITMP3, REG_PV, a);
3695 M_JSR(REG_RA, REG_ITMP3);
3697 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3699 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3700 M_AADD_IMM(REG_SP, 1 * 8, REG_SP);
3702 a = dseg_addaddress(cd, asm_handle_exception);
3703 M_ALD(REG_ITMP3, REG_PV, a);
3709 /* generate negative array size check stubs */
3713 for (bref = cd->xcheckarefs; bref != NULL; bref = bref->next) {
3714 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3715 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3717 (u1 *) xcodeptr - cd->mcodebase - 4);
3721 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3723 (u1 *) mcodeptr - cd->mcodebase);
3727 M_AADD_IMM(REG_PV, bref->branchpos - 4, REG_ITMP2_XPC);
3729 if (xcodeptr != NULL) {
3730 M_BR(xcodeptr - mcodeptr);
3734 xcodeptr = mcodeptr;
3736 M_ASUB_IMM(REG_SP, 1 * 8, REG_SP);
3737 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3739 a = dseg_addaddress(cd, new_negativearraysizeexception);
3740 M_ALD(REG_ITMP3, REG_PV, a);
3741 M_JSR(REG_RA, REG_ITMP3);
3743 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3745 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3746 M_AADD_IMM(REG_SP, 1 * 8, REG_SP);
3748 a = dseg_addaddress(cd, asm_handle_exception);
3749 M_ALD(REG_ITMP3, REG_PV, a);
3755 /* generate cast check stubs */
3759 for (bref = cd->xcastrefs; bref != NULL; bref = bref->next) {
3760 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3761 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3763 (u1 *) xcodeptr - cd->mcodebase - 4);
3767 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3769 (u1 *) mcodeptr - cd->mcodebase);
3773 M_AADD_IMM(REG_PV, bref->branchpos - 4, REG_ITMP2_XPC);
3775 if (xcodeptr != NULL) {
3776 M_BR(xcodeptr - mcodeptr);
3780 xcodeptr = mcodeptr;
3782 M_ASUB_IMM(REG_SP, 1 * 8, REG_SP);
3783 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3785 a = dseg_addaddress(cd, new_classcastexception);
3786 M_ALD(REG_ITMP3, REG_PV, a);
3787 M_JSR(REG_RA, REG_ITMP3);
3789 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3791 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3792 M_AADD_IMM(REG_SP, 1 * 8, REG_SP);
3794 a = dseg_addaddress(cd, asm_handle_exception);
3795 M_ALD(REG_ITMP3, REG_PV, a);
3801 /* generate exception check stubs */
3805 for (bref = cd->xexceptionrefs; bref != NULL; bref = bref->next) {
3806 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3807 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3809 (u1 *) xcodeptr - cd->mcodebase - 4);
3813 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3815 (u1 *) mcodeptr - cd->mcodebase);
3819 M_AADD_IMM(REG_PV, bref->branchpos - 4, REG_ITMP2_XPC);
3821 if (xcodeptr != NULL) {
3822 M_BR(xcodeptr - mcodeptr);
3826 xcodeptr = mcodeptr;
3828 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3829 M_ASUB_IMM(REG_SP, 1 * 8, REG_SP);
3830 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3832 a = dseg_addaddress(cd, builtin_get_exceptionptrptr);
3833 M_ALD(REG_ITMP3, REG_PV, a);
3834 M_JSR(REG_RA, REG_ITMP3);
3837 /* get the exceptionptr from the ptrprt and clear it */
3838 M_ALD(REG_ITMP1_XPTR, REG_RESULT, 0);
3839 M_AST(REG_ZERO, REG_RESULT, 0);
3841 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3842 M_AADD_IMM(REG_SP, 1 * 8, REG_SP);
3844 a = dseg_addaddress(cd, &_exceptionptr);
3845 M_ALD(REG_ITMP3, REG_PV, a);
3846 M_ALD(REG_ITMP1_XPTR, REG_ITMP3, 0);
3847 M_AST(REG_ZERO, REG_ITMP3, 0);
3850 a = dseg_addaddress(cd, asm_handle_exception);
3851 M_ALD(REG_ITMP3, REG_PV, a);
3857 /* generate null pointer check stubs */
3861 for (bref = cd->xnullrefs; bref != NULL; bref = bref->next) {
3862 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3863 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3865 (u1 *) xcodeptr - cd->mcodebase - 4);
3869 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3871 (u1 *) mcodeptr - cd->mcodebase);
3875 M_AADD_IMM(REG_PV, bref->branchpos - 4, REG_ITMP2_XPC);
3877 if (xcodeptr != NULL) {
3878 M_BR(xcodeptr - mcodeptr);
3882 xcodeptr = mcodeptr;
3884 M_ASUB_IMM(REG_SP, 1 * 8, REG_SP);
3885 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3887 a = dseg_addaddress(cd, new_nullpointerexception);
3888 M_ALD(REG_ITMP3, REG_PV, a);
3889 M_JSR(REG_RA, REG_ITMP3);
3891 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3893 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3894 M_AADD_IMM(REG_SP, 1 * 8, REG_SP);
3896 a = dseg_addaddress(cd, asm_handle_exception);
3897 M_ALD(REG_ITMP3, REG_PV, a);
3904 /* generate put/getstatic stub call code */
3911 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
3912 /* check code segment size */
3916 /* Get machine code which is patched back in later. The call is */
3917 /* 2 instruction words long. */
3919 xcodeptr = (s4 *) (cd->mcodebase + pref->branchpos);
3921 /* We need to split this, because an unaligned 8 byte read causes */
3924 mcode = ((u8) xcodeptr[1] << 32) + (u4) xcodeptr[0];
3926 /* patch in the call to call the following code (done at compile */
3929 tmpmcodeptr = mcodeptr; /* save current mcodeptr */
3930 mcodeptr = xcodeptr; /* set mcodeptr to patch position */
3932 M_BRS(tmpmcodeptr - (xcodeptr + 1));
3933 M_MOV(REG_RA, REG_ITMP3); /* branch delay slot */
3935 mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
3937 /* create stack frame */
3939 M_ASUB_IMM(REG_SP, 5 * 8, REG_SP);
3941 /* move return address onto stack */
3943 M_AST(REG_RA, REG_SP, 4 * 8);
3944 M_MOV(REG_ITMP3, REG_RA); /* restore return address */
3946 /* move pointer to java_objectheader onto stack */
3948 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3949 /* create a virtual java_objectheader */
3951 (void) dseg_addaddress(cd, get_dummyLR()); /* monitorPtr */
3952 a = dseg_addaddress(cd, NULL); /* vftbl */
3955 M_LDA(REG_ITMP3, REG_PV, a);
3957 M_LUI(REG_ITMP3, (a >> 16) & 0x0000ffff);
3958 M_OR_IMM(REG_ITMP3, a & 0x0000ffff, REG_ITMP3);
3959 M_AADD(REG_PV, REG_ITMP3, REG_ITMP3);
3961 M_AST(REG_ITMP3, REG_SP, 3 * 8);
3963 M_AST(REG_ZERO, REG_SP, 3 * 8);
3966 /* move machine code onto stack */
3968 a = dseg_adds8(cd, mcode);
3970 M_LLD(REG_ITMP3, REG_PV, a);
3972 M_LUI(REG_ITMP3, (a >> 16) & 0x0000ffff);
3973 M_AADD(REG_PV, REG_ITMP3, REG_ITMP3);
3974 M_LLD(REG_ITMP3, REG_ITMP3, a & 0x0000ffff);
3976 M_LST(REG_ITMP3, REG_SP, 2 * 8);
3978 /* move class/method/field reference onto stack */
3980 a = dseg_addaddress(cd, pref->ref);
3982 M_ALD(REG_ITMP3, REG_PV, a);
3984 M_LUI(REG_ITMP3, (a >> 16) & 0x0000ffff);
3985 M_AADD(REG_PV, REG_ITMP3, REG_ITMP3);
3986 M_ALD(REG_ITMP3, REG_ITMP3, a & 0x0000ffff);
3988 M_AST(REG_ITMP3, REG_SP, 1 * 8);
3990 /* move patcher function pointer onto stack */
3992 a = dseg_addaddress(cd, pref->patcher);
3994 M_ALD(REG_ITMP3, REG_PV, a);
3996 M_LUI(REG_ITMP3, (a >> 16) & 0x0000ffff);
3997 M_AADD(REG_PV, REG_ITMP3, REG_ITMP3);
3998 M_ALD(REG_ITMP3, REG_ITMP3, a & 0x0000ffff);
4000 M_AST(REG_ITMP3, REG_SP, 0 * 8);
4002 a = dseg_addaddress(cd, asm_wrapper_patcher);
4004 M_ALD(REG_ITMP3, REG_PV, a);
4006 M_LUI(REG_ITMP3, (a >> 16) & 0x0000ffff);
4007 M_AADD(REG_PV, REG_ITMP3, REG_ITMP3);
4008 M_ALD(REG_ITMP3, REG_ITMP3, a & 0x0000ffff);
4016 codegen_finish(m, cd, (s4) ((u1 *) mcodeptr - cd->mcodebase));
4018 docacheflush((void *) m->entrypoint, ((u1 *) mcodeptr - cd->mcodebase));
4022 /* createcompilerstub **********************************************************
4024 Creates a stub routine which calls the compiler.
4026 *******************************************************************************/
4028 #define COMPILERSTUB_DATASIZE 2 * SIZEOF_VOID_P
4029 #define COMPILERSTUB_CODESIZE 4 * 4
4031 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
4034 functionptr createcompilerstub(methodinfo *m)
4036 ptrint *s; /* memory to hold the stub */
4037 s4 *mcodeptr; /* code generation pointer */
4039 s = (ptrint *) CNEW(u1, COMPILERSTUB_SIZE);
4042 s[1] = (ptrint) asm_call_jit_compiler;
4044 mcodeptr = (s4 *) (s + 2);
4046 M_ALD(REG_ITMP1, REG_PV, -2 * SIZEOF_VOID_P); /* method pointer */
4047 M_ALD(REG_PV, REG_PV, -1 * SIZEOF_VOID_P); /* pointer to compiler */
4051 (void) docacheflush((void *) s, (char *) mcodeptr - (char *) s);
4053 #if defined(STATISTICS)
4055 count_cstub_len += COMPILERSTUB_SIZE;
4058 return (functionptr) (((u1 *) s) + COMPILERSTUB_DATASIZE);
4062 /* createnativestub ************************************************************
4064 Creates a stub routine which calls a native method.
4066 *******************************************************************************/
4068 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4069 #define NATIVESTUB_STACK 2
4071 #define NATIVESTUB_STACK 1
4075 functionptr createnativestub(functionptr f, methodinfo *m, codegendata *cd,
4076 registerdata *rd, methoddesc *nmd)
4078 s4 *mcodeptr; /* code generation pointer */
4079 s4 stackframesize; /* size of stackframe if needed */
4083 s4 i, j; /* count variables */
4087 /* initialize variables */
4090 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
4094 /* calculate stack frame size */
4096 stackframesize = nmd->memuse + NATIVESTUB_STACK;
4099 /* create method header */
4101 #if SIZEOF_VOID_P == 4
4102 (void) dseg_addaddress(cd, m); /* MethodPointer */
4104 (void) dseg_addaddress(cd, m); /* MethodPointer */
4105 (void) dseg_adds4(cd, stackframesize * 8); /* FrameSize */
4106 (void) dseg_adds4(cd, 0); /* IsSync */
4107 (void) dseg_adds4(cd, 0); /* IsLeaf */
4108 (void) dseg_adds4(cd, 0); /* IntSave */
4109 (void) dseg_adds4(cd, 0); /* FltSave */
4110 (void) dseg_addlinenumbertablesize(cd);
4111 (void) dseg_adds4(cd, 0); /* ExTableSize */
4114 /* initialize mcode variables */
4116 mcodeptr = (s4 *) cd->mcodebase;
4117 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
4120 /* generate stub code */
4122 M_LDA(REG_SP, REG_SP, -stackframesize * 8); /* build up stackframe */
4123 M_AST(REG_RA, REG_SP, 0); /* store return address */
4125 /* if function is static, check for initialized */
4127 if ((m->flags & ACC_STATIC) && !m->class->initialized) {
4128 codegen_addpatchref(cd, mcodeptr, PATCHER_clinit, m->class);
4130 if (opt_showdisassemble) {
4135 /* call trace function */
4138 M_LDA(REG_SP, REG_SP, -(1 + INT_ARG_CNT + FLT_ARG_CNT) * 8);
4140 /* save integer argument registers */
4142 for (i = 0; i < md->paramcount && i < INT_ARG_CNT; i++)
4143 if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
4144 M_LST(rd->argintregs[i], REG_SP, (1 + i) * 8);
4146 /* save and copy float arguments into integer registers */
4148 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4149 t = md->paramtypes[i].type;
4151 if (IS_FLT_DBL_TYPE(t)) {
4152 if (IS_2_WORD_TYPE(t)) {
4153 M_DST(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4154 M_LLD(rd->argintregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4156 M_FST(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4157 M_ILD(rd->argintregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4162 off = dseg_addaddress(cd, m);
4163 M_ALD(REG_ITMP1, REG_PV, off);
4164 M_AST(REG_ITMP1, REG_SP, 0 * 8);
4165 off = dseg_addaddress(cd, builtin_trace_args);
4166 M_ALD(REG_ITMP3, REG_PV, off);
4167 M_JSR(REG_RA, REG_ITMP3);
4169 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4170 M_LDA(REG_PV, REG_RA, -disp);
4172 for (i = 0; i < md->paramcount && i < INT_ARG_CNT; i++)
4173 if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
4174 M_LLD(rd->argintregs[i], REG_SP, (1 + i) * 8);
4176 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4177 t = md->paramtypes[i].type;
4179 if (IS_FLT_DBL_TYPE(t)) {
4180 if (IS_2_WORD_TYPE(t)) {
4181 M_DLD(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4183 M_FLD(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4188 M_LDA(REG_SP, REG_SP, (1 + INT_ARG_CNT + FLT_ARG_CNT) * 8);
4192 /* copy or spill arguments to new locations */
4194 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
4195 t = md->paramtypes[i].type;
4197 if (IS_INT_LNG_TYPE(t)) {
4198 if (!md->params[i].inmemory) {
4199 s1 = rd->argintregs[md->params[i].regoff];
4201 if (!nmd->params[j].inmemory) {
4202 s2 = rd->argintregs[nmd->params[j].regoff];
4205 s2 = nmd->params[j].regoff;
4206 M_AST(s1, REG_SP, s2 * 8);
4210 s1 = md->params[i].regoff + stackframesize;
4211 s2 = nmd->params[j].regoff;
4212 M_ALD(REG_ITMP1, REG_SP, s1 * 8);
4213 M_AST(REG_ITMP1, REG_SP, s2 * 8);
4217 if (!md->params[i].inmemory) {
4218 s1 = rd->argfltregs[md->params[i].regoff];
4220 if (!nmd->params[j].inmemory) {
4221 s2 = rd->argfltregs[nmd->params[j].regoff];
4222 M_TFLTMOVE(t, s1, s2);
4224 s2 = nmd->params[j].regoff;
4225 if (IS_2_WORD_TYPE(t))
4226 M_DST(s1, REG_SP, s2 * 8);
4228 M_FST(s1, REG_SP, s2 * 8);
4232 s1 = md->params[i].regoff + stackframesize;
4233 s2 = nmd->params[j].regoff;
4234 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
4235 if (IS_2_WORD_TYPE(t))
4236 M_DST(REG_FTMP1, REG_SP, s2 * 8);
4238 M_FST(REG_FTMP1, REG_SP, s2 * 8);
4243 /* put class into second argument register */
4245 if (m->flags & ACC_STATIC) {
4246 off = dseg_addaddress(cd, m->class);
4247 M_ALD(rd->argintregs[1], REG_PV, off);
4250 /* put env into first argument register */
4252 off = dseg_addaddress(cd, &env);
4253 M_ALD(rd->argintregs[0], REG_PV, off);
4255 /* do the native function call */
4257 #if !defined(ENABLE_STATICVM)
4259 codegen_addpatchref(cd, mcodeptr, PATCHER_resolve_native, m);
4261 if (opt_showdisassemble) {
4267 off = dseg_addaddress(cd, f);
4268 M_ALD(REG_ITMP3, REG_PV, off); /* load adress of native method */
4269 M_JSR(REG_RA, REG_ITMP3); /* call native method */
4270 M_NOP; /* delay slot */
4271 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4272 M_LDA(REG_PV, REG_RA, -disp);
4275 /* call finished trace function */
4278 M_LDA(REG_SP, REG_SP, -(2 * 8));
4280 M_AST(REG_RESULT, REG_SP, 0 * 8);
4281 M_DST(REG_FRESULT, REG_SP, 1 * 8);
4283 off = dseg_addaddress(cd, m);
4284 M_ALD(rd->argintregs[0], REG_PV, off);
4286 M_MOV(REG_RESULT, rd->argintregs[1]);
4287 M_DMFC1(REG_ITMP1, REG_FRESULT);
4288 M_DMTC1(REG_ITMP1, rd->argfltregs[2]);
4289 M_DMTC1(REG_ITMP1, rd->argfltregs[3]);
4291 off = dseg_addaddress(cd, builtin_displaymethodstop);
4292 M_ALD(REG_ITMP3, REG_PV, off);
4293 M_JSR(REG_RA, REG_ITMP3);
4295 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4296 M_LDA(REG_PV, REG_RA, -disp);
4298 M_ALD(REG_RESULT, REG_SP, 0 * 8);
4299 M_DLD(REG_FRESULT, REG_SP, 1 * 8);
4301 M_LDA(REG_SP, REG_SP, 2 * 8);
4304 /* check for exception */
4306 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4307 off = dseg_addaddress(cd, builtin_get_exceptionptrptr);
4308 M_ALD(REG_ITMP3, REG_PV, off);
4309 M_JSR(REG_RA, REG_ITMP3);
4312 if (IS_FLT_DBL_TYPE(md->returntype.type)) {
4313 M_DST(REG_FRESULT, REG_SP, 1 * 8);
4315 M_AST(REG_RESULT, REG_SP, 1 * 8);
4318 M_MOV(REG_RESULT, REG_ITMP3);
4320 if (IS_FLT_DBL_TYPE(md->returntype.type)) {
4321 M_DLD(REG_FRESULT, REG_SP, 1 * 8);
4323 M_ALD(REG_RESULT, REG_SP, 1 * 8);
4326 off = dseg_addaddress(cd, &_exceptionptr);
4327 M_ALD(REG_ITMP3, REG_PV, off); /* get address of exceptionptr */
4330 M_LLD(REG_RA, REG_SP, 0); /* load return address */
4331 M_ALD(REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
4333 M_BNEZ(REG_ITMP1, 2); /* if no exception then return */
4334 M_LDA(REG_SP, REG_SP, stackframesize * 8);/* remove stackframe, delay slot*/
4336 M_RET(REG_RA); /* return to caller */
4337 M_NOP; /* delay slot */
4339 /* handle exception */
4341 M_AST(REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
4343 off = dseg_addaddress(cd, asm_handle_nat_exception);
4344 M_ALD(REG_ITMP3, REG_PV, off); /* load asm exception handler address */
4345 M_JMP(REG_ITMP3); /* jump to asm exception handler */
4346 M_LDA(REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
4349 /* generate static stub call code */
4357 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
4358 /* Get machine code which is patched back in later. The call is */
4359 /* 2 instruction words long. */
4361 xcodeptr = (s4 *) (cd->mcodebase + pref->branchpos);
4363 /* We need to split this, because an unaligned 8 byte read causes */
4366 mcode = ((u8) xcodeptr[1] << 32) + (u4) xcodeptr[0];
4368 /* patch in the call to call the following code (done at compile */
4371 tmpmcodeptr = mcodeptr; /* save current mcodeptr */
4372 mcodeptr = xcodeptr; /* set mcodeptr to patch position */
4374 M_BRS(tmpmcodeptr - (xcodeptr + 1));
4375 M_NOP; /* branch delay slot */
4377 mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
4379 /* create stack frame */
4381 M_LSUB_IMM(REG_SP, 5 * 8, REG_SP);
4383 /* move return address onto stack */
4385 M_AST(REG_RA, REG_SP, 4 * 8);
4387 /* move pointer to java_objectheader onto stack */
4389 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4390 /* order reversed because of data segment layout */
4392 (void) dseg_addaddress(cd, get_dummyLR()); /* monitorPtr */
4393 off = dseg_addaddress(cd, NULL); /* vftbl */
4395 M_LDA(REG_ITMP3, REG_PV, off);
4396 M_AST(REG_ITMP3, REG_SP, 3 * 8);
4398 M_AST(REG_ZERO, REG_SP, 3 * 8);
4401 /* move machine code onto stack */
4403 off = dseg_adds8(cd, mcode);
4404 M_LLD(REG_ITMP3, REG_PV, off);
4405 M_LST(REG_ITMP3, REG_SP, 2 * 8);
4407 /* move class/method/field reference onto stack */
4409 off = dseg_addaddress(cd, pref->ref);
4410 M_ALD(REG_ITMP3, REG_PV, off);
4411 M_AST(REG_ITMP3, REG_SP, 1 * 8);
4413 /* move patcher function pointer onto stack */
4415 off = dseg_addaddress(cd, pref->patcher);
4416 M_ALD(REG_ITMP3, REG_PV, off);
4417 M_AST(REG_ITMP3, REG_SP, 0 * 8);
4419 off = dseg_addaddress(cd, asm_wrapper_patcher);
4420 M_ALD(REG_ITMP3, REG_PV, off);
4426 codegen_finish(m, cd, (s4) ((u1 *) mcodeptr - cd->mcodebase));
4428 docacheflush((void *) m->entrypoint, ((u1 *) mcodeptr - cd->mcodebase));
4430 return m->entrypoint;
4435 * These are local overrides for various environment variables in Emacs.
4436 * Please do not remove this and leave it at the end of the file, where
4437 * Emacs will automagically detect them.
4438 * ---------------------------------------------------------------------
4441 * indent-tabs-mode: t