1 /* src/vm/jit/alpha/codegen.c - machine code generator for Alpha
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: Joseph Wenninger
34 $Id: codegen.c 3109 2005-07-24 23:07:02Z twisti $
47 #include "vm/jit/alpha/arch.h"
48 #include "vm/jit/alpha/codegen.h"
49 #include "vm/jit/alpha/types.h"
50 #include "vm/jit/alpha/asmoffsets.h"
52 #include "cacao/cacao.h"
53 #include "native/native.h"
54 #include "vm/builtin.h"
55 #include "vm/global.h"
56 #include "vm/loader.h"
57 #include "vm/stringlocal.h"
58 #include "vm/tables.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/parse.h"
69 #include "vm/jit/patcher.h"
70 #include "vm/jit/reg.h"
71 #include "vm/jit/reg.inc"
74 /* codegen *********************************************************************
76 Generates machine code.
78 *******************************************************************************/
80 void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
82 s4 len, s1, s2, s3, d, disp;
92 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
93 builtintable_entry *bte;
96 /* prevent compiler warnings */
107 savedregs_num = (m->isleafmethod) ? 0 : 1; /* space to save the RA */
109 /* space to save used callee saved registers */
111 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
112 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
114 parentargs_base = rd->memuse + savedregs_num;
116 #if defined(USE_THREADS) /* space to save argument of monitor_enter */
118 if (checksync && (m->flags & ACC_SYNCHRONIZED))
123 /* create method header */
125 (void) dseg_addaddress(cd, m); /* MethodPointer */
126 (void) dseg_adds4(cd, parentargs_base * 8); /* FrameSize */
128 #if defined(USE_THREADS)
130 /* IsSync contains the offset relative to the stack pointer for the
131 argument of monitor_exit used in the exception handler. Since the
132 offset could be zero and give a wrong meaning of the flag it is
136 if (checksync && (m->flags & ACC_SYNCHRONIZED))
137 (void) dseg_adds4(cd, (rd->memuse + 1) * 8); /* IsSync */
142 (void) dseg_adds4(cd, 0); /* IsSync */
144 (void) dseg_adds4(cd, m->isleafmethod); /* IsLeaf */
145 (void) dseg_adds4(cd, INT_SAV_CNT - rd->savintreguse);/* IntSave */
146 (void) dseg_adds4(cd, FLT_SAV_CNT - rd->savfltreguse);/* FltSave */
148 dseg_addlinenumbertablesize(cd);
150 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
152 /* create exception table */
154 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
155 dseg_addtarget(cd, ex->start);
156 dseg_addtarget(cd, ex->end);
157 dseg_addtarget(cd, ex->handler);
158 (void) dseg_addaddress(cd, ex->catchtype.cls);
161 /* initialize mcode variables */
163 mcodeptr = (s4 *) cd->mcodebase;
164 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
165 MCODECHECK(128 + m->paramcount);
167 /* create stack frame (if necessary) */
169 if (parentargs_base) {
170 M_LDA(REG_SP, REG_SP, -parentargs_base * 8);
173 /* save return address and used callee saved registers */
176 if (!m->isleafmethod) {
177 p--; M_AST(REG_RA, REG_SP, p * 8);
179 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
180 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
182 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
183 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
186 /* take arguments out of register or stack frame */
190 for (p = 0, l = 0; p < md->paramcount; p++) {
191 t = md->paramtypes[p].type;
192 var = &(rd->locals[l][t]);
194 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
198 s1 = md->params[p].regoff;
199 if (IS_INT_LNG_TYPE(t)) { /* integer args */
200 if (!md->params[p].inmemory) { /* register arguments */
201 s2 = rd->argintregs[s1];
202 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
203 M_INTMOVE(s2, var->regoff);
205 } else { /* reg arg -> spilled */
206 M_LST(s2, REG_SP, var->regoff * 8);
209 } else { /* stack arguments */
210 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
211 M_LLD(var->regoff, REG_SP, (parentargs_base + s1) * 8);
213 } else { /* stack arg -> spilled */
214 var->regoff = parentargs_base + s1;
218 } else { /* floating args */
219 if (!md->params[p].inmemory) { /* register arguments */
220 s2 = rd->argfltregs[s1];
221 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
222 M_FLTMOVE(s2, var->regoff);
224 } else { /* reg arg -> spilled */
225 M_DST(s2, REG_SP, var->regoff * 8);
228 } else { /* stack arguments */
229 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
230 M_DLD(var->regoff, REG_SP, (parentargs_base + s1) * 8);
232 } else { /* stack-arg -> spilled */
233 var->regoff = parentargs_base + s1;
239 /* call monitorenter function */
241 #if defined(USE_THREADS)
242 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
243 /* stack offset for monitor argument */
248 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
250 for (p = 0; p < INT_ARG_CNT; p++)
251 M_LST(rd->argintregs[p], REG_SP, p * 8);
253 for (p = 0; p < FLT_ARG_CNT; p++)
254 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
256 s1 += INT_ARG_CNT + FLT_ARG_CNT;
259 /* decide which monitor enter function to call */
261 if (m->flags & ACC_STATIC) {
262 disp = dseg_addaddress(cd, m->class);
263 M_ALD(REG_ITMP1, REG_PV, disp);
264 M_AST(REG_ITMP1, REG_SP, s1 * 8);
265 M_INTMOVE(REG_ITMP1, rd->argintregs[0]);
266 disp = dseg_addaddress(cd, BUILTIN_staticmonitorenter);
267 M_ALD(REG_PV, REG_PV, disp);
268 M_JSR(REG_RA, REG_PV);
269 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
270 M_LDA(REG_PV, REG_RA, disp);
273 M_BEQZ(rd->argintregs[0], 0);
274 codegen_addxnullrefs(cd, mcodeptr);
275 M_AST(rd->argintregs[0], REG_SP, s1 * 8);
276 disp = dseg_addaddress(cd, BUILTIN_monitorenter);
277 M_ALD(REG_PV, REG_PV, disp);
278 M_JSR(REG_RA, REG_PV);
279 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
280 M_LDA(REG_PV, REG_RA, disp);
284 for (p = 0; p < INT_ARG_CNT; p++)
285 M_LLD(rd->argintregs[p], REG_SP, p * 8);
287 for (p = 0; p < FLT_ARG_CNT; p++)
288 M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
290 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
295 /* call trace function */
298 M_LDA(REG_SP, REG_SP, -((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
299 M_AST(REG_RA, REG_SP, 1 * 8);
301 /* save integer argument registers */
303 for (p = 0; p < md->paramcount && p < INT_ARG_CNT; p++)
304 M_LST(rd->argintregs[p], REG_SP, (2 + p) * 8);
306 /* save and copy float arguments into integer registers */
308 for (p = 0; p < md->paramcount && p < FLT_ARG_CNT; p++) {
309 t = md->paramtypes[p].type;
311 if (IS_FLT_DBL_TYPE(t)) {
312 if (IS_2_WORD_TYPE(t)) {
313 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
316 M_FST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
319 M_LLD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
322 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
326 disp = dseg_addaddress(cd, m);
327 M_ALD(REG_ITMP1, REG_PV, disp);
328 M_AST(REG_ITMP1, REG_SP, 0 * 8);
329 disp = dseg_addaddress(cd, (void *) builtin_trace_args);
330 M_ALD(REG_PV, REG_PV, disp);
331 M_JSR(REG_RA, REG_PV);
332 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
333 M_LDA(REG_PV, REG_RA, disp);
334 M_ALD(REG_RA, REG_SP, 1 * 8);
336 /* restore integer argument registers */
338 for (p = 0; p < md->paramcount && p < INT_ARG_CNT; p++)
339 M_LLD(rd->argintregs[p], REG_SP, (2 + p) * 8);
341 /* restore float argument registers */
343 for (p = 0; p < md->paramcount && p < FLT_ARG_CNT; p++) {
344 t = md->paramtypes[p].type;
346 if (IS_FLT_DBL_TYPE(t)) {
347 if (IS_2_WORD_TYPE(t)) {
348 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
351 M_FLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
355 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
359 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT + 2) * 8);
364 /* end of header generation */
366 /* walk through all basic blocks */
368 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
370 bptr->mpc = (s4) ((u1 *) mcodeptr - cd->mcodebase);
372 if (bptr->flags >= BBREACHED) {
374 /* branch resolving */
378 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
379 gen_resolvebranch((u1*) cd->mcodebase + brefs->branchpos,
380 brefs->branchpos, bptr->mpc);
384 /* copy interface registers to their destination */
391 while (src != NULL) {
393 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
394 /* d = reg_of_var(m, src, REG_ITMP1); */
395 if (!(src->flags & INMEMORY))
399 M_INTMOVE(REG_ITMP1, d);
400 store_reg_to_var_int(src, d);
406 while (src != NULL) {
408 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
409 d = reg_of_var(rd, src, REG_ITMP1);
410 M_INTMOVE(REG_ITMP1, d);
411 store_reg_to_var_int(src, d);
413 d = reg_of_var(rd, src, REG_IFTMP);
414 if ((src->varkind != STACKVAR)) {
416 if (IS_FLT_DBL_TYPE(s2)) {
417 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
418 s1 = rd->interfaces[len][s2].regoff;
421 M_DLD(d, REG_SP, rd->interfaces[len][s2].regoff * 8);
423 store_reg_to_var_flt(src, d);
426 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
427 s1 = rd->interfaces[len][s2].regoff;
430 M_LLD(d, REG_SP, rd->interfaces[len][s2].regoff * 8);
432 store_reg_to_var_int(src, d);
442 /* walk through all instructions */
447 for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
448 if (iptr->line != currentline) {
449 dseg_addlinenumber(cd, iptr->line, (u1 *) mcodeptr);
450 currentline = iptr->line;
453 MCODECHECK(64); /* an instruction usually needs < 64 words */
456 case ICMD_INLINE_START:
457 case ICMD_INLINE_END:
460 case ICMD_NOP: /* ... ==> ... */
463 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
465 var_to_reg_int(s1, src, REG_ITMP1);
467 codegen_addxnullrefs(cd, mcodeptr);
470 /* constant operations ************************************************/
472 case ICMD_ICONST: /* ... ==> ..., constant */
473 /* op1 = 0, val.i = constant */
475 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
476 ICONST(d, iptr->val.i);
477 store_reg_to_var_int(iptr->dst, d);
480 case ICMD_LCONST: /* ... ==> ..., constant */
481 /* op1 = 0, val.l = constant */
483 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
484 LCONST(d, iptr->val.l);
485 store_reg_to_var_int(iptr->dst, d);
488 case ICMD_FCONST: /* ... ==> ..., constant */
489 /* op1 = 0, val.f = constant */
491 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
492 disp = dseg_addfloat(cd, iptr->val.f);
493 M_FLD(d, REG_PV, disp);
494 store_reg_to_var_flt(iptr->dst, d);
497 case ICMD_DCONST: /* ... ==> ..., constant */
498 /* op1 = 0, val.d = constant */
500 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
501 disp = dseg_adddouble(cd, iptr->val.d);
502 M_DLD(d, REG_PV, disp);
503 store_reg_to_var_flt(iptr->dst, d);
506 case ICMD_ACONST: /* ... ==> ..., constant */
507 /* op1 = 0, val.a = constant */
509 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
511 disp = dseg_addaddress(cd, iptr->val.a);
512 M_ALD(d, REG_PV, disp);
514 M_INTMOVE(REG_ZERO, d);
516 store_reg_to_var_int(iptr->dst, d);
520 /* load/store operations **********************************************/
522 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
523 case ICMD_LLOAD: /* op1 = local variable */
526 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
527 if ((iptr->dst->varkind == LOCALVAR) &&
528 (iptr->dst->varnum == iptr->op1))
530 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
531 if (var->flags & INMEMORY) {
532 M_LLD(d, REG_SP, var->regoff * 8);
534 M_INTMOVE(var->regoff, d);
536 store_reg_to_var_int(iptr->dst, d);
539 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
540 case ICMD_DLOAD: /* op1 = local variable */
542 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
543 if ((iptr->dst->varkind == LOCALVAR) &&
544 (iptr->dst->varnum == iptr->op1))
546 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
547 if (var->flags & INMEMORY) {
548 M_DLD(d, REG_SP, var->regoff * 8);
550 M_FLTMOVE(var->regoff, d);
552 store_reg_to_var_flt(iptr->dst, d);
556 case ICMD_ISTORE: /* ..., value ==> ... */
557 case ICMD_LSTORE: /* op1 = local variable */
560 if ((src->varkind == LOCALVAR) &&
561 (src->varnum == iptr->op1))
563 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
564 if (var->flags & INMEMORY) {
565 var_to_reg_int(s1, src, REG_ITMP1);
566 M_LST(s1, REG_SP, var->regoff * 8);
568 var_to_reg_int(s1, src, var->regoff);
569 M_INTMOVE(s1, var->regoff);
573 case ICMD_FSTORE: /* ..., value ==> ... */
574 case ICMD_DSTORE: /* op1 = local variable */
576 if ((src->varkind == LOCALVAR) &&
577 (src->varnum == iptr->op1))
579 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
580 if (var->flags & INMEMORY) {
581 var_to_reg_flt(s1, src, REG_FTMP1);
582 M_DST(s1, REG_SP, var->regoff * 8);
584 var_to_reg_flt(s1, src, var->regoff);
585 M_FLTMOVE(s1, var->regoff);
590 /* pop/dup/swap operations ********************************************/
592 /* attention: double and longs are only one entry in CACAO ICMDs */
594 case ICMD_POP: /* ..., value ==> ... */
595 case ICMD_POP2: /* ..., value, value ==> ... */
598 case ICMD_DUP: /* ..., a ==> ..., a, a */
599 M_COPY(src, iptr->dst);
602 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
604 M_COPY(src, iptr->dst);
605 M_COPY(src->prev, iptr->dst->prev);
606 M_COPY(iptr->dst, iptr->dst->prev->prev);
609 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
611 M_COPY(src, iptr->dst);
612 M_COPY(src->prev, iptr->dst->prev);
613 M_COPY(src->prev->prev, iptr->dst->prev->prev);
614 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
617 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
619 M_COPY(src, iptr->dst);
620 M_COPY(src->prev, iptr->dst->prev);
623 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
625 M_COPY(src, iptr->dst);
626 M_COPY(src->prev, iptr->dst->prev);
627 M_COPY(src->prev->prev, iptr->dst->prev->prev);
628 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
629 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev);
632 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
634 M_COPY(src, iptr->dst);
635 M_COPY(src->prev, iptr->dst->prev);
636 M_COPY(src->prev->prev, iptr->dst->prev->prev);
637 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
638 M_COPY(iptr->dst, iptr->dst->prev->prev->prev->prev);
639 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev->prev);
642 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
644 M_COPY(src, iptr->dst->prev);
645 M_COPY(src->prev, iptr->dst);
649 /* integer operations *************************************************/
651 case ICMD_INEG: /* ..., value ==> ..., - value */
653 var_to_reg_int(s1, src, REG_ITMP1);
654 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
655 M_ISUB(REG_ZERO, s1, d);
656 store_reg_to_var_int(iptr->dst, d);
659 case ICMD_LNEG: /* ..., value ==> ..., - value */
661 var_to_reg_int(s1, src, REG_ITMP1);
662 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
663 M_LSUB(REG_ZERO, s1, d);
664 store_reg_to_var_int(iptr->dst, d);
667 case ICMD_I2L: /* ..., value ==> ..., value */
669 var_to_reg_int(s1, src, REG_ITMP1);
670 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
672 store_reg_to_var_int(iptr->dst, d);
675 case ICMD_L2I: /* ..., value ==> ..., value */
677 var_to_reg_int(s1, src, REG_ITMP1);
678 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
679 M_IADD(s1, REG_ZERO, d);
680 store_reg_to_var_int(iptr->dst, d);
683 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
685 var_to_reg_int(s1, src, REG_ITMP1);
686 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
687 if (has_ext_instr_set) {
690 M_SLL_IMM(s1, 56, d);
691 M_SRA_IMM( d, 56, d);
693 store_reg_to_var_int(iptr->dst, d);
696 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
698 var_to_reg_int(s1, src, REG_ITMP1);
699 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
701 store_reg_to_var_int(iptr->dst, d);
704 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
706 var_to_reg_int(s1, src, REG_ITMP1);
707 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
708 if (has_ext_instr_set) {
711 M_SLL_IMM(s1, 48, d);
712 M_SRA_IMM( d, 48, d);
714 store_reg_to_var_int(iptr->dst, d);
718 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
720 var_to_reg_int(s1, src->prev, REG_ITMP1);
721 var_to_reg_int(s2, src, REG_ITMP2);
722 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
724 store_reg_to_var_int(iptr->dst, d);
727 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
728 /* val.i = constant */
730 var_to_reg_int(s1, src, REG_ITMP1);
731 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
732 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
733 M_IADD_IMM(s1, iptr->val.i, d);
735 ICONST(REG_ITMP2, iptr->val.i);
736 M_IADD(s1, REG_ITMP2, d);
738 store_reg_to_var_int(iptr->dst, d);
741 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
743 var_to_reg_int(s1, src->prev, REG_ITMP1);
744 var_to_reg_int(s2, src, REG_ITMP2);
745 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
747 store_reg_to_var_int(iptr->dst, d);
750 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
751 /* val.l = constant */
753 var_to_reg_int(s1, src, REG_ITMP1);
754 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
755 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
756 M_LADD_IMM(s1, iptr->val.l, d);
758 LCONST(REG_ITMP2, iptr->val.l);
759 M_LADD(s1, REG_ITMP2, d);
761 store_reg_to_var_int(iptr->dst, d);
764 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
766 var_to_reg_int(s1, src->prev, REG_ITMP1);
767 var_to_reg_int(s2, src, REG_ITMP2);
768 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
770 store_reg_to_var_int(iptr->dst, d);
773 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
774 /* val.i = constant */
776 var_to_reg_int(s1, src, REG_ITMP1);
777 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
778 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
779 M_ISUB_IMM(s1, iptr->val.i, d);
781 ICONST(REG_ITMP2, iptr->val.i);
782 M_ISUB(s1, REG_ITMP2, d);
784 store_reg_to_var_int(iptr->dst, d);
787 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
789 var_to_reg_int(s1, src->prev, REG_ITMP1);
790 var_to_reg_int(s2, src, REG_ITMP2);
791 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
793 store_reg_to_var_int(iptr->dst, d);
796 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
797 /* val.l = constant */
799 var_to_reg_int(s1, src, REG_ITMP1);
800 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
801 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
802 M_LSUB_IMM(s1, iptr->val.l, d);
804 LCONST(REG_ITMP2, iptr->val.l);
805 M_LSUB(s1, REG_ITMP2, d);
807 store_reg_to_var_int(iptr->dst, d);
810 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
812 var_to_reg_int(s1, src->prev, REG_ITMP1);
813 var_to_reg_int(s2, src, REG_ITMP2);
814 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
816 store_reg_to_var_int(iptr->dst, d);
819 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
820 /* val.i = constant */
822 var_to_reg_int(s1, src, REG_ITMP1);
823 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
824 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
825 M_IMUL_IMM(s1, iptr->val.i, d);
827 ICONST(REG_ITMP2, iptr->val.i);
828 M_IMUL(s1, REG_ITMP2, d);
830 store_reg_to_var_int(iptr->dst, d);
833 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
835 var_to_reg_int(s1, src->prev, REG_ITMP1);
836 var_to_reg_int(s2, src, REG_ITMP2);
837 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
839 store_reg_to_var_int(iptr->dst, d);
842 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
843 /* val.l = constant */
845 var_to_reg_int(s1, src, REG_ITMP1);
846 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
847 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
848 M_LMUL_IMM(s1, iptr->val.l, d);
850 LCONST(REG_ITMP2, iptr->val.l);
851 M_LMUL(s1, REG_ITMP2, d);
853 store_reg_to_var_int(iptr->dst, d);
856 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
857 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
859 var_to_reg_int(s1, src->prev, REG_ITMP1);
860 var_to_reg_int(s2, src, REG_ITMP2);
861 d = reg_of_var(rd, iptr->dst, REG_RESULT);
863 codegen_addxdivrefs(cd, mcodeptr);
865 M_MOV(s1, rd->argintregs[0]);
866 M_MOV(s2, rd->argintregs[1]);
868 disp = dseg_addaddress(cd, bte->fp);
869 M_ALD(REG_PV, REG_PV, disp);
870 M_JSR(REG_RA, REG_PV);
871 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
872 M_LDA(REG_PV, REG_RA, -disp);
874 M_IADD(REG_RESULT, REG_ZERO, d); /* sign extend (bugfix for gcc -O2) */
875 store_reg_to_var_int(iptr->dst, d);
878 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
879 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
881 var_to_reg_int(s1, src->prev, REG_ITMP1);
882 var_to_reg_int(s2, src, REG_ITMP2);
883 d = reg_of_var(rd, iptr->dst, REG_RESULT);
885 codegen_addxdivrefs(cd, mcodeptr);
887 M_MOV(s1, rd->argintregs[0]);
888 M_MOV(s2, rd->argintregs[1]);
890 disp = dseg_addaddress(cd, bte->fp);
891 M_ALD(REG_PV, REG_PV, disp);
892 M_JSR(REG_RA, REG_PV);
893 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
894 M_LDA(REG_PV, REG_RA, -disp);
896 M_INTMOVE(REG_RESULT, d);
897 store_reg_to_var_int(iptr->dst, d);
900 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
901 case ICMD_LDIVPOW2: /* val.i = constant */
903 var_to_reg_int(s1, src, REG_ITMP1);
904 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
905 if (iptr->val.i <= 15) {
906 M_LDA(REG_ITMP2, s1, (1 << iptr->val.i) -1);
907 M_CMOVGE(s1, s1, REG_ITMP2);
909 M_SRA_IMM(s1, 63, REG_ITMP2);
910 M_SRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
911 M_LADD(s1, REG_ITMP2, REG_ITMP2);
913 M_SRA_IMM(REG_ITMP2, iptr->val.i, d);
914 store_reg_to_var_int(iptr->dst, d);
917 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
919 var_to_reg_int(s1, src->prev, REG_ITMP1);
920 var_to_reg_int(s2, src, REG_ITMP2);
921 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
922 M_AND_IMM(s2, 0x1f, REG_ITMP3);
923 M_SLL(s1, REG_ITMP3, d);
924 M_IADD(d, REG_ZERO, d);
925 store_reg_to_var_int(iptr->dst, d);
928 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
929 /* val.i = constant */
931 var_to_reg_int(s1, src, REG_ITMP1);
932 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
933 M_SLL_IMM(s1, iptr->val.i & 0x1f, d);
934 M_IADD(d, REG_ZERO, d);
935 store_reg_to_var_int(iptr->dst, d);
938 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
940 var_to_reg_int(s1, src->prev, REG_ITMP1);
941 var_to_reg_int(s2, src, REG_ITMP2);
942 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
943 M_AND_IMM(s2, 0x1f, REG_ITMP3);
944 M_SRA(s1, REG_ITMP3, d);
945 store_reg_to_var_int(iptr->dst, d);
948 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
949 /* val.i = constant */
951 var_to_reg_int(s1, src, REG_ITMP1);
952 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
953 M_SRA_IMM(s1, iptr->val.i & 0x1f, d);
954 store_reg_to_var_int(iptr->dst, d);
957 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
959 var_to_reg_int(s1, src->prev, REG_ITMP1);
960 var_to_reg_int(s2, src, REG_ITMP2);
961 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
962 M_AND_IMM(s2, 0x1f, REG_ITMP2);
964 M_SRL(d, REG_ITMP2, d);
965 M_IADD(d, REG_ZERO, d);
966 store_reg_to_var_int(iptr->dst, d);
969 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
970 /* val.i = constant */
972 var_to_reg_int(s1, src, REG_ITMP1);
973 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
975 M_SRL_IMM(d, iptr->val.i & 0x1f, d);
976 M_IADD(d, REG_ZERO, d);
977 store_reg_to_var_int(iptr->dst, d);
980 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
982 var_to_reg_int(s1, src->prev, REG_ITMP1);
983 var_to_reg_int(s2, src, REG_ITMP2);
984 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
986 store_reg_to_var_int(iptr->dst, d);
989 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
990 /* val.i = constant */
992 var_to_reg_int(s1, src, REG_ITMP1);
993 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
994 M_SLL_IMM(s1, iptr->val.i & 0x3f, d);
995 store_reg_to_var_int(iptr->dst, d);
998 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1000 var_to_reg_int(s1, src->prev, REG_ITMP1);
1001 var_to_reg_int(s2, src, REG_ITMP2);
1002 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1004 store_reg_to_var_int(iptr->dst, d);
1007 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1008 /* val.i = constant */
1010 var_to_reg_int(s1, src, REG_ITMP1);
1011 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1012 M_SRA_IMM(s1, iptr->val.i & 0x3f, d);
1013 store_reg_to_var_int(iptr->dst, d);
1016 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1018 var_to_reg_int(s1, src->prev, REG_ITMP1);
1019 var_to_reg_int(s2, src, REG_ITMP2);
1020 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1022 store_reg_to_var_int(iptr->dst, d);
1025 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1026 /* val.i = constant */
1028 var_to_reg_int(s1, src, REG_ITMP1);
1029 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1030 M_SRL_IMM(s1, iptr->val.i & 0x3f, d);
1031 store_reg_to_var_int(iptr->dst, d);
1034 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1037 var_to_reg_int(s1, src->prev, REG_ITMP1);
1038 var_to_reg_int(s2, src, REG_ITMP2);
1039 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1041 store_reg_to_var_int(iptr->dst, d);
1044 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1045 /* val.i = constant */
1047 var_to_reg_int(s1, src, REG_ITMP1);
1048 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1049 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1050 M_AND_IMM(s1, iptr->val.i, d);
1051 } else if (iptr->val.i == 0xffff) {
1053 } else if (iptr->val.i == 0xffffff) {
1054 M_ZAPNOT_IMM(s1, 0x07, d);
1056 ICONST(REG_ITMP2, iptr->val.i);
1057 M_AND(s1, REG_ITMP2, d);
1059 store_reg_to_var_int(iptr->dst, d);
1062 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1063 /* val.i = constant */
1065 var_to_reg_int(s1, src, REG_ITMP1);
1066 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1068 M_MOV(s1, REG_ITMP1);
1071 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1072 M_AND_IMM(s1, iptr->val.i, d);
1074 M_ISUB(REG_ZERO, s1, d);
1075 M_AND_IMM(d, iptr->val.i, d);
1076 } else if (iptr->val.i == 0xffff) {
1079 M_ISUB(REG_ZERO, s1, d);
1081 } else if (iptr->val.i == 0xffffff) {
1082 M_ZAPNOT_IMM(s1, 0x07, d);
1084 M_ISUB(REG_ZERO, s1, d);
1085 M_ZAPNOT_IMM(d, 0x07, d);
1087 ICONST(REG_ITMP2, iptr->val.i);
1088 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_ITMP2);
1102 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1103 M_AND_IMM(s1, iptr->val.l, d);
1104 } else if (iptr->val.l == 0xffffL) {
1106 } else if (iptr->val.l == 0xffffffL) {
1107 M_ZAPNOT_IMM(s1, 0x07, d);
1108 } else if (iptr->val.l == 0xffffffffL) {
1110 } else if (iptr->val.l == 0xffffffffffL) {
1111 M_ZAPNOT_IMM(s1, 0x1f, d);
1112 } else if (iptr->val.l == 0xffffffffffffL) {
1113 M_ZAPNOT_IMM(s1, 0x3f, d);
1114 } else if (iptr->val.l == 0xffffffffffffffL) {
1115 M_ZAPNOT_IMM(s1, 0x7f, d);
1117 LCONST(REG_ITMP2, iptr->val.l);
1118 M_AND(s1, REG_ITMP2, d);
1120 store_reg_to_var_int(iptr->dst, d);
1123 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1124 /* val.l = constant */
1126 var_to_reg_int(s1, src, REG_ITMP1);
1127 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1129 M_MOV(s1, REG_ITMP1);
1132 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1133 M_AND_IMM(s1, iptr->val.l, d);
1135 M_LSUB(REG_ZERO, s1, d);
1136 M_AND_IMM(d, iptr->val.l, d);
1137 } else if (iptr->val.l == 0xffffL) {
1140 M_LSUB(REG_ZERO, s1, d);
1142 } else if (iptr->val.l == 0xffffffL) {
1143 M_ZAPNOT_IMM(s1, 0x07, d);
1145 M_LSUB(REG_ZERO, s1, d);
1146 M_ZAPNOT_IMM(d, 0x07, d);
1147 } else if (iptr->val.l == 0xffffffffL) {
1150 M_LSUB(REG_ZERO, s1, d);
1152 } else if (iptr->val.l == 0xffffffffffL) {
1153 M_ZAPNOT_IMM(s1, 0x1f, d);
1155 M_LSUB(REG_ZERO, s1, d);
1156 M_ZAPNOT_IMM(d, 0x1f, d);
1157 } else if (iptr->val.l == 0xffffffffffffL) {
1158 M_ZAPNOT_IMM(s1, 0x3f, d);
1160 M_LSUB(REG_ZERO, s1, d);
1161 M_ZAPNOT_IMM(d, 0x3f, d);
1162 } else if (iptr->val.l == 0xffffffffffffffL) {
1163 M_ZAPNOT_IMM(s1, 0x7f, d);
1165 M_LSUB(REG_ZERO, s1, d);
1166 M_ZAPNOT_IMM(d, 0x7f, d);
1168 LCONST(REG_ITMP2, iptr->val.l);
1169 M_AND(s1, REG_ITMP2, d);
1171 M_LSUB(REG_ZERO, s1, d);
1172 M_AND(d, REG_ITMP2, d);
1174 M_LSUB(REG_ZERO, d, d);
1175 store_reg_to_var_int(iptr->dst, d);
1178 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1181 var_to_reg_int(s1, src->prev, REG_ITMP1);
1182 var_to_reg_int(s2, src, REG_ITMP2);
1183 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1185 store_reg_to_var_int(iptr->dst, d);
1188 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1189 /* val.i = constant */
1191 var_to_reg_int(s1, src, REG_ITMP1);
1192 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1193 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1194 M_OR_IMM(s1, iptr->val.i, d);
1196 ICONST(REG_ITMP2, iptr->val.i);
1197 M_OR(s1, REG_ITMP2, d);
1199 store_reg_to_var_int(iptr->dst, d);
1202 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1203 /* val.l = constant */
1205 var_to_reg_int(s1, src, REG_ITMP1);
1206 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1207 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1208 M_OR_IMM(s1, iptr->val.l, d);
1210 LCONST(REG_ITMP2, iptr->val.l);
1211 M_OR(s1, REG_ITMP2, d);
1213 store_reg_to_var_int(iptr->dst, d);
1216 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1219 var_to_reg_int(s1, src->prev, REG_ITMP1);
1220 var_to_reg_int(s2, src, REG_ITMP2);
1221 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1223 store_reg_to_var_int(iptr->dst, d);
1226 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1227 /* val.i = constant */
1229 var_to_reg_int(s1, src, REG_ITMP1);
1230 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1231 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1232 M_XOR_IMM(s1, iptr->val.i, d);
1234 ICONST(REG_ITMP2, iptr->val.i);
1235 M_XOR(s1, REG_ITMP2, d);
1237 store_reg_to_var_int(iptr->dst, d);
1240 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1241 /* val.l = constant */
1243 var_to_reg_int(s1, src, REG_ITMP1);
1244 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1245 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1246 M_XOR_IMM(s1, iptr->val.l, d);
1248 LCONST(REG_ITMP2, iptr->val.l);
1249 M_XOR(s1, REG_ITMP2, d);
1251 store_reg_to_var_int(iptr->dst, d);
1255 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1257 var_to_reg_int(s1, src->prev, REG_ITMP1);
1258 var_to_reg_int(s2, src, REG_ITMP2);
1259 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1260 M_CMPLT(s1, s2, REG_ITMP3);
1261 M_CMPLT(s2, s1, REG_ITMP1);
1262 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1263 store_reg_to_var_int(iptr->dst, d);
1267 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1268 /* op1 = variable, val.i = constant */
1270 var = &(rd->locals[iptr->op1][TYPE_INT]);
1271 if (var->flags & INMEMORY) {
1273 M_LLD(s1, REG_SP, var->regoff * 8);
1276 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1277 M_IADD_IMM(s1, iptr->val.i, s1);
1278 } else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1279 M_ISUB_IMM(s1, (-iptr->val.i), s1);
1281 M_LDA (s1, s1, iptr->val.i);
1282 M_IADD(s1, REG_ZERO, s1);
1284 if (var->flags & INMEMORY)
1285 M_LST(s1, REG_SP, var->regoff * 8);
1289 /* floating operations ************************************************/
1291 case ICMD_FNEG: /* ..., value ==> ..., - value */
1293 var_to_reg_flt(s1, src, REG_FTMP1);
1294 d = reg_of_var(rd, iptr->dst, REG_FTMP2);
1296 store_reg_to_var_flt(iptr->dst, d);
1299 case ICMD_DNEG: /* ..., value ==> ..., - value */
1301 var_to_reg_flt(s1, src, REG_FTMP1);
1302 d = reg_of_var(rd, iptr->dst, REG_FTMP2);
1304 store_reg_to_var_flt(iptr->dst, d);
1307 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1309 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1310 var_to_reg_flt(s2, src, REG_FTMP2);
1311 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1315 if (d == s1 || d == s2) {
1316 M_FADDS(s1, s2, REG_FTMP3);
1318 M_FMOV(REG_FTMP3, d);
1324 store_reg_to_var_flt(iptr->dst, d);
1327 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1329 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1330 var_to_reg_flt(s2, src, REG_FTMP2);
1331 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1335 if (d == s1 || d == s2) {
1336 M_DADDS(s1, s2, REG_FTMP3);
1338 M_FMOV(REG_FTMP3, d);
1344 store_reg_to_var_flt(iptr->dst, d);
1347 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1349 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1350 var_to_reg_flt(s2, src, REG_FTMP2);
1351 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1355 if (d == s1 || d == s2) {
1356 M_FSUBS(s1, s2, REG_FTMP3);
1358 M_FMOV(REG_FTMP3, d);
1364 store_reg_to_var_flt(iptr->dst, d);
1367 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1369 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1370 var_to_reg_flt(s2, src, REG_FTMP2);
1371 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1375 if (d == s1 || d == s2) {
1376 M_DSUBS(s1, s2, REG_FTMP3);
1378 M_FMOV(REG_FTMP3, d);
1384 store_reg_to_var_flt(iptr->dst, d);
1387 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1389 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1390 var_to_reg_flt(s2, src, REG_FTMP2);
1391 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1395 if (d == s1 || d == s2) {
1396 M_FMULS(s1, s2, REG_FTMP3);
1398 M_FMOV(REG_FTMP3, d);
1404 store_reg_to_var_flt(iptr->dst, d);
1407 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1409 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1410 var_to_reg_flt(s2, src, REG_FTMP2);
1411 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1415 if (d == s1 || d == s2) {
1416 M_DMULS(s1, s2, REG_FTMP3);
1418 M_FMOV(REG_FTMP3, d);
1424 store_reg_to_var_flt(iptr->dst, d);
1427 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1429 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1430 var_to_reg_flt(s2, src, REG_FTMP2);
1431 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1435 if (d == s1 || d == s2) {
1436 M_FDIVS(s1, s2, REG_FTMP3);
1438 M_FMOV(REG_FTMP3, d);
1444 store_reg_to_var_flt(iptr->dst, d);
1447 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1449 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1450 var_to_reg_flt(s2, src, REG_FTMP2);
1451 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1455 if (d == s1 || d == s2) {
1456 M_DDIVS(s1, s2, REG_FTMP3);
1458 M_FMOV(REG_FTMP3, d);
1464 store_reg_to_var_flt(iptr->dst, d);
1467 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1469 var_to_reg_int(s1, src, REG_ITMP1);
1470 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1471 disp = dseg_adddouble(cd, 0.0);
1472 M_LST(s1, REG_PV, disp);
1473 M_DLD(d, REG_PV, disp);
1475 store_reg_to_var_flt(iptr->dst, d);
1478 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1480 var_to_reg_int(s1, src, REG_ITMP1);
1481 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1482 disp = dseg_adddouble(cd, 0.0);
1483 M_LST(s1, REG_PV, disp);
1484 M_DLD(d, REG_PV, disp);
1486 store_reg_to_var_flt(iptr->dst, d);
1489 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1491 var_to_reg_flt(s1, src, REG_FTMP1);
1492 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1493 disp = dseg_adddouble(cd, 0.0);
1494 M_CVTDL_C(s1, REG_FTMP2);
1495 M_CVTLI(REG_FTMP2, REG_FTMP3);
1496 M_DST(REG_FTMP3, REG_PV, disp);
1497 M_ILD(d, REG_PV, disp);
1498 store_reg_to_var_int(iptr->dst, d);
1501 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1503 var_to_reg_flt(s1, src, REG_FTMP1);
1504 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1505 disp = dseg_adddouble(cd, 0.0);
1506 M_CVTDL_C(s1, REG_FTMP2);
1507 M_DST(REG_FTMP2, REG_PV, disp);
1508 M_LLD(d, REG_PV, disp);
1509 store_reg_to_var_int(iptr->dst, d);
1512 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1514 var_to_reg_flt(s1, src, REG_FTMP1);
1515 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1518 store_reg_to_var_flt(iptr->dst, d);
1521 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1523 var_to_reg_flt(s1, src, REG_FTMP1);
1524 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1531 store_reg_to_var_flt(iptr->dst, d);
1534 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1536 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1537 var_to_reg_flt(s2, src, REG_FTMP2);
1538 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1540 M_LSUB_IMM(REG_ZERO, 1, d);
1541 M_FCMPEQ(s1, s2, REG_FTMP3);
1542 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1544 M_FCMPLT(s2, s1, REG_FTMP3);
1545 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1546 M_LADD_IMM(REG_ZERO, 1, d);
1548 M_LSUB_IMM(REG_ZERO, 1, d);
1549 M_FCMPEQS(s1, s2, REG_FTMP3);
1551 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1553 M_FCMPLTS(s2, s1, REG_FTMP3);
1555 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1556 M_LADD_IMM(REG_ZERO, 1, d);
1558 store_reg_to_var_int(iptr->dst, d);
1561 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1563 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1564 var_to_reg_flt(s2, src, REG_FTMP2);
1565 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1567 M_LADD_IMM(REG_ZERO, 1, d);
1568 M_FCMPEQ(s1, s2, REG_FTMP3);
1569 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1571 M_FCMPLT(s1, s2, REG_FTMP3);
1572 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1573 M_LSUB_IMM(REG_ZERO, 1, d);
1575 M_LADD_IMM(REG_ZERO, 1, d);
1576 M_FCMPEQS(s1, s2, REG_FTMP3);
1578 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1580 M_FCMPLTS(s1, s2, REG_FTMP3);
1582 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1583 M_LSUB_IMM(REG_ZERO, 1, d);
1585 store_reg_to_var_int(iptr->dst, d);
1589 /* memory operations **************************************************/
1591 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1593 var_to_reg_int(s1, src, REG_ITMP1);
1594 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1595 gen_nullptr_check(s1);
1596 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1597 store_reg_to_var_int(iptr->dst, d);
1600 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1602 var_to_reg_int(s1, src->prev, REG_ITMP1);
1603 var_to_reg_int(s2, src, REG_ITMP2);
1604 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1605 if (iptr->op1 == 0) {
1606 gen_nullptr_check(s1);
1609 if (has_ext_instr_set) {
1610 M_LADD (s2, s1, REG_ITMP1);
1611 M_BLDU (d, REG_ITMP1, OFFSET (java_bytearray, data[0]));
1614 M_LADD(s2, s1, REG_ITMP1);
1615 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1616 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
1617 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1618 M_SRA_IMM(d, 56, d);
1620 store_reg_to_var_int(iptr->dst, d);
1623 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1625 var_to_reg_int(s1, src->prev, REG_ITMP1);
1626 var_to_reg_int(s2, src, REG_ITMP2);
1627 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1628 if (iptr->op1 == 0) {
1629 gen_nullptr_check(s1);
1632 if (has_ext_instr_set) {
1633 M_LADD(s2, s1, REG_ITMP1);
1634 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1635 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1637 M_LADD (s2, s1, REG_ITMP1);
1638 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1639 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1640 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1641 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
1643 store_reg_to_var_int(iptr->dst, d);
1646 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1648 var_to_reg_int(s1, src->prev, REG_ITMP1);
1649 var_to_reg_int(s2, src, REG_ITMP2);
1650 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1651 if (iptr->op1 == 0) {
1652 gen_nullptr_check(s1);
1655 if (has_ext_instr_set) {
1656 M_LADD(s2, s1, REG_ITMP1);
1657 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1658 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1661 M_LADD(s2, s1, REG_ITMP1);
1662 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1663 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1664 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1665 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1666 M_SRA_IMM(d, 48, d);
1668 store_reg_to_var_int(iptr->dst, d);
1671 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1673 var_to_reg_int(s1, src->prev, REG_ITMP1);
1674 var_to_reg_int(s2, src, REG_ITMP2);
1675 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1676 if (iptr->op1 == 0) {
1677 gen_nullptr_check(s1);
1680 M_S4ADDQ(s2, s1, REG_ITMP1);
1681 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1682 store_reg_to_var_int(iptr->dst, d);
1685 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1687 var_to_reg_int(s1, src->prev, REG_ITMP1);
1688 var_to_reg_int(s2, src, REG_ITMP2);
1689 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1690 if (iptr->op1 == 0) {
1691 gen_nullptr_check(s1);
1694 M_S8ADDQ(s2, s1, REG_ITMP1);
1695 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1696 store_reg_to_var_int(iptr->dst, d);
1699 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1701 var_to_reg_int(s1, src->prev, REG_ITMP1);
1702 var_to_reg_int(s2, src, REG_ITMP2);
1703 d = reg_of_var(rd, iptr->dst, REG_FTMP2);
1704 if (iptr->op1 == 0) {
1705 gen_nullptr_check(s1);
1708 M_S4ADDQ(s2, s1, REG_ITMP1);
1709 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1710 store_reg_to_var_flt(iptr->dst, d);
1713 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1715 var_to_reg_int(s1, src->prev, REG_ITMP1);
1716 var_to_reg_int(s2, src, REG_ITMP2);
1717 d = reg_of_var(rd, iptr->dst, REG_FTMP2);
1718 if (iptr->op1 == 0) {
1719 gen_nullptr_check(s1);
1722 M_S8ADDQ(s2, s1, REG_ITMP1);
1723 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1724 store_reg_to_var_flt(iptr->dst, d);
1727 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1729 var_to_reg_int(s1, src->prev, REG_ITMP1);
1730 var_to_reg_int(s2, src, REG_ITMP2);
1731 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1732 if (iptr->op1 == 0) {
1733 gen_nullptr_check(s1);
1736 M_SAADDQ(s2, s1, REG_ITMP1);
1737 M_ALD(d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1738 store_reg_to_var_int(iptr->dst, d);
1742 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1744 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1745 var_to_reg_int(s2, src->prev, REG_ITMP2);
1746 if (iptr->op1 == 0) {
1747 gen_nullptr_check(s1);
1750 var_to_reg_int(s3, src, REG_ITMP3);
1751 if (has_ext_instr_set) {
1752 M_LADD(s2, s1, REG_ITMP1);
1753 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1755 M_LADD(s2, s1, REG_ITMP1);
1756 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1757 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1758 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
1759 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1760 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1761 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1765 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1767 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1768 var_to_reg_int(s2, src->prev, REG_ITMP2);
1769 if (iptr->op1 == 0) {
1770 gen_nullptr_check(s1);
1773 var_to_reg_int(s3, src, REG_ITMP3);
1774 if (has_ext_instr_set) {
1775 M_LADD(s2, s1, REG_ITMP1);
1776 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1777 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1779 M_LADD(s2, s1, REG_ITMP1);
1780 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1781 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1782 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1783 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1784 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1785 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1786 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1790 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1792 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1793 var_to_reg_int(s2, src->prev, REG_ITMP2);
1794 if (iptr->op1 == 0) {
1795 gen_nullptr_check(s1);
1798 var_to_reg_int(s3, src, REG_ITMP3);
1799 if (has_ext_instr_set) {
1800 M_LADD(s2, s1, REG_ITMP1);
1801 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1802 M_SST(s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1804 M_LADD(s2, s1, REG_ITMP1);
1805 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1806 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1807 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1808 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1809 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1810 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1811 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1815 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1817 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1818 var_to_reg_int(s2, src->prev, REG_ITMP2);
1819 if (iptr->op1 == 0) {
1820 gen_nullptr_check(s1);
1823 var_to_reg_int(s3, src, REG_ITMP3);
1824 M_S4ADDQ(s2, s1, REG_ITMP1);
1825 M_IST(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1828 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1830 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1831 var_to_reg_int(s2, src->prev, REG_ITMP2);
1832 if (iptr->op1 == 0) {
1833 gen_nullptr_check(s1);
1836 var_to_reg_int(s3, src, REG_ITMP3);
1837 M_S8ADDQ(s2, s1, REG_ITMP1);
1838 M_LST(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1841 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1843 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1844 var_to_reg_int(s2, src->prev, REG_ITMP2);
1845 if (iptr->op1 == 0) {
1846 gen_nullptr_check(s1);
1849 var_to_reg_flt(s3, src, REG_FTMP3);
1850 M_S4ADDQ(s2, s1, REG_ITMP1);
1851 M_FST(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1854 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1856 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1857 var_to_reg_int(s2, src->prev, REG_ITMP2);
1858 if (iptr->op1 == 0) {
1859 gen_nullptr_check(s1);
1862 var_to_reg_flt(s3, src, REG_FTMP3);
1863 M_S8ADDQ(s2, s1, REG_ITMP1);
1864 M_DST(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1867 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1869 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1870 var_to_reg_int(s2, src->prev, REG_ITMP2);
1871 /* if (iptr->op1 == 0) { */
1872 gen_nullptr_check(s1);
1875 var_to_reg_int(s3, src, REG_ITMP3);
1877 M_MOV(s1, rd->argintregs[0]);
1878 M_MOV(s3, rd->argintregs[1]);
1880 disp = dseg_addaddress(cd, bte->fp);
1881 M_ALD(REG_PV, REG_PV, disp);
1882 M_JSR(REG_RA, REG_PV);
1883 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
1884 M_LDA(REG_PV, REG_RA, -disp);
1886 M_BEQZ(REG_RESULT, 0);
1887 codegen_addxstorerefs(cd, mcodeptr);
1889 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1890 var_to_reg_int(s2, src->prev, REG_ITMP2);
1891 var_to_reg_int(s3, src, REG_ITMP3);
1892 M_SAADDQ(s2, s1, REG_ITMP1);
1893 M_AST(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1897 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1899 var_to_reg_int(s1, src->prev, REG_ITMP1);
1900 var_to_reg_int(s2, src, REG_ITMP2);
1901 if (iptr->op1 == 0) {
1902 gen_nullptr_check(s1);
1905 M_S4ADDQ(s2, s1, REG_ITMP1);
1906 M_IST(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1909 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1911 var_to_reg_int(s1, src->prev, REG_ITMP1);
1912 var_to_reg_int(s2, src, REG_ITMP2);
1913 if (iptr->op1 == 0) {
1914 gen_nullptr_check(s1);
1917 M_S8ADDQ(s2, s1, REG_ITMP1);
1918 M_LST(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1921 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1923 var_to_reg_int(s1, src->prev, REG_ITMP1);
1924 var_to_reg_int(s2, src, REG_ITMP2);
1925 if (iptr->op1 == 0) {
1926 gen_nullptr_check(s1);
1929 M_SAADDQ(s2, s1, REG_ITMP1);
1930 M_AST(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1933 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1935 var_to_reg_int(s1, src->prev, REG_ITMP1);
1936 var_to_reg_int(s2, src, REG_ITMP2);
1937 if (iptr->op1 == 0) {
1938 gen_nullptr_check(s1);
1941 if (has_ext_instr_set) {
1942 M_LADD(s2, s1, REG_ITMP1);
1943 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1946 M_LADD(s2, s1, REG_ITMP1);
1947 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1948 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1949 M_INSBL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1950 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1951 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1952 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1956 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1958 var_to_reg_int(s1, src->prev, REG_ITMP1);
1959 var_to_reg_int(s2, src, REG_ITMP2);
1960 if (iptr->op1 == 0) {
1961 gen_nullptr_check(s1);
1964 if (has_ext_instr_set) {
1965 M_LADD(s2, s1, REG_ITMP1);
1966 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1967 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1970 M_LADD(s2, s1, REG_ITMP1);
1971 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1972 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1973 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1974 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1975 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1976 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1977 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1981 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1983 var_to_reg_int(s1, src->prev, REG_ITMP1);
1984 var_to_reg_int(s2, src, REG_ITMP2);
1985 if (iptr->op1 == 0) {
1986 gen_nullptr_check(s1);
1989 if (has_ext_instr_set) {
1990 M_LADD(s2, s1, REG_ITMP1);
1991 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1992 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1995 M_LADD(s2, s1, REG_ITMP1);
1996 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1997 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1998 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1999 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2000 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2001 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2002 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2007 case ICMD_GETSTATIC: /* ... ==> ..., value */
2008 /* op1 = type, val.a = field address */
2011 disp = dseg_addaddress(cd, 0);
2013 codegen_addpatchref(cd, mcodeptr,
2014 PATCHER_get_putstatic,
2015 (unresolved_field *) iptr->target, disp);
2017 if (opt_showdisassemble)
2022 fieldinfo *fi = iptr->val.a;
2024 disp = dseg_addaddress(cd, &(fi->value));
2026 if (!fi->class->initialized) {
2027 codegen_addpatchref(cd, mcodeptr,
2028 PATCHER_clinit, fi->class, 0);
2030 if (opt_showdisassemble)
2035 M_ALD(REG_ITMP1, REG_PV, disp);
2036 switch (iptr->op1) {
2038 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2039 M_ILD(d, REG_ITMP1, 0);
2040 store_reg_to_var_int(iptr->dst, d);
2043 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2044 M_LLD(d, REG_ITMP1, 0);
2045 store_reg_to_var_int(iptr->dst, d);
2048 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2049 M_ALD(d, REG_ITMP1, 0);
2050 store_reg_to_var_int(iptr->dst, d);
2053 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2054 M_FLD(d, REG_ITMP1, 0);
2055 store_reg_to_var_flt(iptr->dst, d);
2058 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2059 M_DLD(d, REG_ITMP1, 0);
2060 store_reg_to_var_flt(iptr->dst, d);
2065 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2066 /* op1 = type, val.a = field address */
2069 disp = dseg_addaddress(cd, 0);
2071 codegen_addpatchref(cd, mcodeptr,
2072 PATCHER_get_putstatic,
2073 (unresolved_field *) iptr->target, disp);
2075 if (opt_showdisassemble)
2079 fieldinfo *fi = iptr->val.a;
2081 disp = dseg_addaddress(cd, &(fi->value));
2083 if (!fi->class->initialized) {
2084 codegen_addpatchref(cd, mcodeptr,
2085 PATCHER_clinit, fi->class, 0);
2087 if (opt_showdisassemble)
2092 M_ALD(REG_ITMP1, REG_PV, disp);
2093 switch (iptr->op1) {
2095 var_to_reg_int(s2, src, REG_ITMP2);
2096 M_IST(s2, REG_ITMP1, 0);
2099 var_to_reg_int(s2, src, REG_ITMP2);
2100 M_LST(s2, REG_ITMP1, 0);
2103 var_to_reg_int(s2, src, REG_ITMP2);
2104 M_AST(s2, REG_ITMP1, 0);
2107 var_to_reg_flt(s2, src, REG_FTMP2);
2108 M_FST(s2, REG_ITMP1, 0);
2111 var_to_reg_flt(s2, src, REG_FTMP2);
2112 M_DST(s2, REG_ITMP1, 0);
2117 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2118 /* val = value (in current instruction) */
2119 /* op1 = type, val.a = field address (in */
2120 /* following NOP) */
2122 if (!iptr[1].val.a) {
2123 disp = dseg_addaddress(cd, 0);
2125 codegen_addpatchref(cd, mcodeptr,
2126 PATCHER_get_putstatic,
2127 (unresolved_field *) iptr[1].target, disp);
2129 if (opt_showdisassemble)
2133 fieldinfo *fi = iptr[1].val.a;
2135 disp = dseg_addaddress(cd, &(fi->value));
2137 if (!fi->class->initialized) {
2138 codegen_addpatchref(cd, mcodeptr,
2139 PATCHER_clinit, fi->class, 0);
2141 if (opt_showdisassemble)
2146 M_ALD(REG_ITMP1, REG_PV, disp);
2147 switch (iptr->op1) {
2149 M_IST(REG_ZERO, REG_ITMP1, 0);
2152 M_LST(REG_ZERO, REG_ITMP1, 0);
2155 M_AST(REG_ZERO, REG_ITMP1, 0);
2158 M_FST(REG_ZERO, REG_ITMP1, 0);
2161 M_DST(REG_ZERO, REG_ITMP1, 0);
2167 case ICMD_GETFIELD: /* ... ==> ..., value */
2168 /* op1 = type, val.i = field offset */
2170 var_to_reg_int(s1, src, REG_ITMP1);
2171 gen_nullptr_check(s1);
2174 codegen_addpatchref(cd, mcodeptr,
2175 PATCHER_get_putfield,
2176 (unresolved_field *) iptr->target, 0);
2178 if (opt_showdisassemble)
2184 disp = ((fieldinfo *) (iptr->val.a))->offset;
2187 switch (iptr->op1) {
2189 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2191 store_reg_to_var_int(iptr->dst, d);
2194 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2196 store_reg_to_var_int(iptr->dst, d);
2199 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2201 store_reg_to_var_int(iptr->dst, d);
2204 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2206 store_reg_to_var_flt(iptr->dst, d);
2209 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2211 store_reg_to_var_flt(iptr->dst, d);
2216 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2217 /* op1 = type, val.a = field address */
2219 var_to_reg_int(s1, src->prev, REG_ITMP1);
2220 gen_nullptr_check(s1);
2222 if (!IS_FLT_DBL_TYPE(iptr->op1)) {
2223 var_to_reg_int(s2, src, REG_ITMP2);
2225 var_to_reg_flt(s2, src, REG_FTMP2);
2229 codegen_addpatchref(cd, mcodeptr,
2230 PATCHER_get_putfield,
2231 (unresolved_field *) iptr->target, 0);
2233 if (opt_showdisassemble)
2239 disp = ((fieldinfo *) (iptr->val.a))->offset;
2242 switch (iptr->op1) {
2244 M_IST(s2, s1, disp);
2247 M_LST(s2, s1, disp);
2250 M_AST(s2, s1, disp);
2253 M_FST(s2, s1, disp);
2256 M_DST(s2, s1, disp);
2261 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2262 /* val = value (in current instruction) */
2263 /* op1 = type, val.a = field address (in */
2264 /* following NOP) */
2266 var_to_reg_int(s1, src, REG_ITMP1);
2267 gen_nullptr_check(s1);
2269 if (!iptr[1].val.a) {
2270 codegen_addpatchref(cd, mcodeptr,
2271 PATCHER_get_putfield,
2272 (unresolved_field *) iptr[1].target, 0);
2274 if (opt_showdisassemble)
2280 disp = ((fieldinfo *) (iptr[1].val.a))->offset;
2283 switch (iptr[1].op1) {
2285 M_IST(REG_ZERO, s1, disp);
2288 M_LST(REG_ZERO, s1, disp);
2291 M_AST(REG_ZERO, s1, disp);
2294 M_FST(REG_ZERO, s1, disp);
2297 M_DST(REG_ZERO, s1, disp);
2303 /* branch operations **************************************************/
2305 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2307 var_to_reg_int(s1, src, REG_ITMP1);
2308 M_INTMOVE(s1, REG_ITMP1_XPTR);
2309 disp = dseg_addaddress(cd, asm_handle_exception);
2310 M_ALD(REG_ITMP2, REG_PV, disp);
2311 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2312 M_NOP; /* nop ensures that XPC is less than the end */
2313 /* of basic block */
2317 case ICMD_GOTO: /* ... ==> ... */
2318 /* op1 = target JavaVM pc */
2320 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2324 case ICMD_JSR: /* ... ==> ... */
2325 /* op1 = target JavaVM pc */
2327 M_BSR(REG_ITMP1, 0);
2328 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2331 case ICMD_RET: /* ... ==> ... */
2332 /* op1 = local variable */
2334 var = &(rd->locals[iptr->op1][TYPE_ADR]);
2335 if (var->flags & INMEMORY) {
2336 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2337 M_RET(REG_ZERO, REG_ITMP1);
2340 M_RET(REG_ZERO, var->regoff);
2344 case ICMD_IFNULL: /* ..., value ==> ... */
2345 /* op1 = target JavaVM pc */
2347 var_to_reg_int(s1, src, REG_ITMP1);
2349 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2352 case ICMD_IFNONNULL: /* ..., value ==> ... */
2353 /* op1 = target JavaVM pc */
2355 var_to_reg_int(s1, src, REG_ITMP1);
2357 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2360 case ICMD_IFEQ: /* ..., value ==> ... */
2361 /* op1 = target JavaVM pc, val.i = constant */
2363 var_to_reg_int(s1, src, REG_ITMP1);
2364 if (iptr->val.i == 0) {
2368 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2369 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2372 ICONST(REG_ITMP2, iptr->val.i);
2373 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2375 M_BNEZ(REG_ITMP1, 0);
2377 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2380 case ICMD_IFLT: /* ..., value ==> ... */
2381 /* op1 = target JavaVM pc, val.i = constant */
2383 var_to_reg_int(s1, src, REG_ITMP1);
2384 if (iptr->val.i == 0) {
2388 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2389 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2392 ICONST(REG_ITMP2, iptr->val.i);
2393 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2395 M_BNEZ(REG_ITMP1, 0);
2397 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2400 case ICMD_IFLE: /* ..., value ==> ... */
2401 /* op1 = target JavaVM pc, val.i = constant */
2403 var_to_reg_int(s1, src, REG_ITMP1);
2404 if (iptr->val.i == 0) {
2408 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2409 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2412 ICONST(REG_ITMP2, iptr->val.i);
2413 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2415 M_BNEZ(REG_ITMP1, 0);
2417 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2420 case ICMD_IFNE: /* ..., value ==> ... */
2421 /* op1 = target JavaVM pc, val.i = constant */
2423 var_to_reg_int(s1, src, REG_ITMP1);
2424 if (iptr->val.i == 0) {
2428 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2429 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2432 ICONST(REG_ITMP2, iptr->val.i);
2433 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2435 M_BEQZ(REG_ITMP1, 0);
2437 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2440 case ICMD_IFGT: /* ..., value ==> ... */
2441 /* op1 = target JavaVM pc, val.i = constant */
2443 var_to_reg_int(s1, src, REG_ITMP1);
2444 if (iptr->val.i == 0) {
2448 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2449 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2452 ICONST(REG_ITMP2, iptr->val.i);
2453 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2455 M_BEQZ(REG_ITMP1, 0);
2457 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2460 case ICMD_IFGE: /* ..., value ==> ... */
2461 /* op1 = target JavaVM pc, val.i = constant */
2463 var_to_reg_int(s1, src, REG_ITMP1);
2464 if (iptr->val.i == 0) {
2468 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2469 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2472 ICONST(REG_ITMP2, iptr->val.i);
2473 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2475 M_BEQZ(REG_ITMP1, 0);
2477 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2480 case ICMD_IF_LEQ: /* ..., value ==> ... */
2481 /* op1 = target JavaVM pc, val.l = constant */
2483 var_to_reg_int(s1, src, REG_ITMP1);
2484 if (iptr->val.l == 0) {
2488 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2489 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2492 LCONST(REG_ITMP2, iptr->val.l);
2493 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2495 M_BNEZ(REG_ITMP1, 0);
2497 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2500 case ICMD_IF_LLT: /* ..., value ==> ... */
2501 /* op1 = target JavaVM pc, val.l = constant */
2503 var_to_reg_int(s1, src, REG_ITMP1);
2504 if (iptr->val.l == 0) {
2508 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2509 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2512 LCONST(REG_ITMP2, iptr->val.l);
2513 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2515 M_BNEZ(REG_ITMP1, 0);
2517 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2520 case ICMD_IF_LLE: /* ..., value ==> ... */
2521 /* op1 = target JavaVM pc, val.l = constant */
2523 var_to_reg_int(s1, src, REG_ITMP1);
2524 if (iptr->val.l == 0) {
2528 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2529 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2532 LCONST(REG_ITMP2, iptr->val.l);
2533 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2535 M_BNEZ(REG_ITMP1, 0);
2537 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2540 case ICMD_IF_LNE: /* ..., value ==> ... */
2541 /* op1 = target JavaVM pc, val.l = constant */
2543 var_to_reg_int(s1, src, REG_ITMP1);
2544 if (iptr->val.l == 0) {
2548 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2549 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2552 LCONST(REG_ITMP2, iptr->val.l);
2553 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2555 M_BEQZ(REG_ITMP1, 0);
2557 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2560 case ICMD_IF_LGT: /* ..., value ==> ... */
2561 /* op1 = target JavaVM pc, val.l = constant */
2563 var_to_reg_int(s1, src, REG_ITMP1);
2564 if (iptr->val.l == 0) {
2568 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2569 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2572 LCONST(REG_ITMP2, iptr->val.l);
2573 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2575 M_BEQZ(REG_ITMP1, 0);
2577 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2580 case ICMD_IF_LGE: /* ..., value ==> ... */
2581 /* op1 = target JavaVM pc, val.l = constant */
2583 var_to_reg_int(s1, src, REG_ITMP1);
2584 if (iptr->val.l == 0) {
2588 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2589 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2592 LCONST(REG_ITMP2, iptr->val.l);
2593 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2595 M_BEQZ(REG_ITMP1, 0);
2597 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2600 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2601 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2602 case ICMD_IF_ACMPEQ:
2604 var_to_reg_int(s1, src->prev, REG_ITMP1);
2605 var_to_reg_int(s2, src, REG_ITMP2);
2606 M_CMPEQ(s1, s2, REG_ITMP1);
2607 M_BNEZ(REG_ITMP1, 0);
2608 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2611 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2612 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2613 case ICMD_IF_ACMPNE:
2615 var_to_reg_int(s1, src->prev, REG_ITMP1);
2616 var_to_reg_int(s2, src, REG_ITMP2);
2617 M_CMPEQ(s1, s2, REG_ITMP1);
2618 M_BEQZ(REG_ITMP1, 0);
2619 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2622 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2623 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2625 var_to_reg_int(s1, src->prev, REG_ITMP1);
2626 var_to_reg_int(s2, src, REG_ITMP2);
2627 M_CMPLT(s1, s2, REG_ITMP1);
2628 M_BNEZ(REG_ITMP1, 0);
2629 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2632 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2633 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2635 var_to_reg_int(s1, src->prev, REG_ITMP1);
2636 var_to_reg_int(s2, src, REG_ITMP2);
2637 M_CMPLE(s1, s2, REG_ITMP1);
2638 M_BEQZ(REG_ITMP1, 0);
2639 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2642 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2643 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2645 var_to_reg_int(s1, src->prev, REG_ITMP1);
2646 var_to_reg_int(s2, src, REG_ITMP2);
2647 M_CMPLE(s1, s2, REG_ITMP1);
2648 M_BNEZ(REG_ITMP1, 0);
2649 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2652 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2653 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2655 var_to_reg_int(s1, src->prev, REG_ITMP1);
2656 var_to_reg_int(s2, src, REG_ITMP2);
2657 M_CMPLT(s1, s2, REG_ITMP1);
2658 M_BEQZ(REG_ITMP1, 0);
2659 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2662 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2664 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2667 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2668 /* val.i = constant */
2670 var_to_reg_int(s1, src, REG_ITMP1);
2671 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2673 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2674 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2675 M_CMPEQ(s1, REG_ZERO, d);
2676 store_reg_to_var_int(iptr->dst, d);
2679 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2680 M_CMPEQ(s1, REG_ZERO, d);
2682 store_reg_to_var_int(iptr->dst, d);
2686 M_MOV(s1, REG_ITMP1);
2689 ICONST(d, iptr[1].val.i);
2691 if ((s3 >= 0) && (s3 <= 255)) {
2692 M_CMOVEQ_IMM(s1, s3, d);
2694 ICONST(REG_ITMP2, s3);
2695 M_CMOVEQ(s1, REG_ITMP2, d);
2697 store_reg_to_var_int(iptr->dst, d);
2700 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2701 /* val.i = constant */
2703 var_to_reg_int(s1, src, REG_ITMP1);
2704 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2706 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2707 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2708 M_CMPEQ(s1, REG_ZERO, d);
2709 store_reg_to_var_int(iptr->dst, d);
2712 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2713 M_CMPEQ(s1, REG_ZERO, d);
2715 store_reg_to_var_int(iptr->dst, d);
2719 M_MOV(s1, REG_ITMP1);
2722 ICONST(d, iptr[1].val.i);
2724 if ((s3 >= 0) && (s3 <= 255)) {
2725 M_CMOVNE_IMM(s1, s3, d);
2727 ICONST(REG_ITMP2, s3);
2728 M_CMOVNE(s1, REG_ITMP2, d);
2730 store_reg_to_var_int(iptr->dst, d);
2733 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2734 /* val.i = constant */
2736 var_to_reg_int(s1, src, REG_ITMP1);
2737 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2739 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2740 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2741 M_CMPLT(s1, REG_ZERO, d);
2742 store_reg_to_var_int(iptr->dst, d);
2745 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2746 M_CMPLE(REG_ZERO, s1, d);
2747 store_reg_to_var_int(iptr->dst, d);
2751 M_MOV(s1, REG_ITMP1);
2754 ICONST(d, iptr[1].val.i);
2756 if ((s3 >= 0) && (s3 <= 255)) {
2757 M_CMOVLT_IMM(s1, s3, d);
2759 ICONST(REG_ITMP2, s3);
2760 M_CMOVLT(s1, REG_ITMP2, d);
2762 store_reg_to_var_int(iptr->dst, d);
2765 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2766 /* val.i = constant */
2768 var_to_reg_int(s1, src, REG_ITMP1);
2769 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2771 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2772 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2773 M_CMPLE(REG_ZERO, s1, d);
2774 store_reg_to_var_int(iptr->dst, d);
2777 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2778 M_CMPLT(s1, REG_ZERO, d);
2779 store_reg_to_var_int(iptr->dst, d);
2783 M_MOV(s1, REG_ITMP1);
2786 ICONST(d, iptr[1].val.i);
2788 if ((s3 >= 0) && (s3 <= 255)) {
2789 M_CMOVGE_IMM(s1, s3, d);
2791 ICONST(REG_ITMP2, s3);
2792 M_CMOVGE(s1, REG_ITMP2, d);
2794 store_reg_to_var_int(iptr->dst, d);
2797 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2798 /* val.i = constant */
2800 var_to_reg_int(s1, src, REG_ITMP1);
2801 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2803 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2804 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2805 M_CMPLT(REG_ZERO, s1, d);
2806 store_reg_to_var_int(iptr->dst, d);
2809 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2810 M_CMPLE(s1, REG_ZERO, d);
2811 store_reg_to_var_int(iptr->dst, d);
2815 M_MOV(s1, REG_ITMP1);
2818 ICONST(d, iptr[1].val.i);
2820 if ((s3 >= 0) && (s3 <= 255)) {
2821 M_CMOVGT_IMM(s1, s3, d);
2823 ICONST(REG_ITMP2, s3);
2824 M_CMOVGT(s1, REG_ITMP2, d);
2826 store_reg_to_var_int(iptr->dst, d);
2829 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2830 /* val.i = constant */
2832 var_to_reg_int(s1, src, REG_ITMP1);
2833 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2835 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2836 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2837 M_CMPLE(s1, REG_ZERO, d);
2838 store_reg_to_var_int(iptr->dst, d);
2841 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2842 M_CMPLT(REG_ZERO, s1, d);
2843 store_reg_to_var_int(iptr->dst, d);
2847 M_MOV(s1, REG_ITMP1);
2850 ICONST(d, iptr[1].val.i);
2852 if ((s3 >= 0) && (s3 <= 255)) {
2853 M_CMOVLE_IMM(s1, s3, d);
2855 ICONST(REG_ITMP2, s3);
2856 M_CMOVLE(s1, REG_ITMP2, d);
2858 store_reg_to_var_int(iptr->dst, d);
2862 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2866 var_to_reg_int(s1, src, REG_RESULT);
2867 M_INTMOVE(s1, REG_RESULT);
2869 goto nowperformreturn;
2871 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2874 var_to_reg_flt(s1, src, REG_FRESULT);
2875 M_FLTMOVE(s1, REG_FRESULT);
2877 goto nowperformreturn;
2879 case ICMD_RETURN: /* ... ==> ... */
2885 p = parentargs_base;
2887 /* call trace function */
2890 M_LDA(REG_SP, REG_SP, -3 * 8);
2891 M_AST(REG_RA, REG_SP, 0 * 8);
2892 M_LST(REG_RESULT, REG_SP, 1 * 8);
2893 M_DST(REG_FRESULT, REG_SP, 2 * 8);
2895 disp = dseg_addaddress(cd, m);
2896 M_ALD(rd->argintregs[0], REG_PV, disp);
2897 M_MOV(REG_RESULT, rd->argintregs[1]);
2898 M_FLTMOVE(REG_FRESULT, rd->argfltregs[2]);
2899 M_FLTMOVE(REG_FRESULT, rd->argfltregs[3]);
2901 disp = dseg_addaddress(cd, (void *) builtin_displaymethodstop);
2902 M_ALD(REG_PV, REG_PV, disp);
2903 M_JSR(REG_RA, REG_PV);
2904 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
2905 M_LDA(REG_PV, REG_RA, -disp);
2907 M_DLD(REG_FRESULT, REG_SP, 2 * 8);
2908 M_LLD(REG_RESULT, REG_SP, 1 * 8);
2909 M_ALD(REG_RA, REG_SP, 0 * 8);
2910 M_LDA(REG_SP, REG_SP, 3 * 8);
2913 #if defined(USE_THREADS)
2914 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2917 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8);
2919 switch (iptr->opc) {
2923 M_LST(REG_RESULT, REG_SP, rd->memuse * 8);
2927 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2931 disp = dseg_addaddress(cd, BUILTIN_monitorexit);
2932 M_ALD(REG_PV, REG_PV, disp);
2933 M_JSR(REG_RA, REG_PV);
2934 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
2935 M_LDA(REG_PV, REG_RA, disp);
2937 switch (iptr->opc) {
2941 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2945 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2951 /* restore return address */
2953 if (!m->isleafmethod) {
2954 p--; M_LLD(REG_RA, REG_SP, p * 8);
2957 /* restore saved registers */
2959 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2960 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2962 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2963 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2966 /* deallocate stack */
2968 if (parentargs_base) {
2969 M_LDA(REG_SP, REG_SP, parentargs_base * 8);
2972 M_RET(REG_ZERO, REG_RA);
2978 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2983 tptr = (void **) iptr->target;
2985 s4ptr = iptr->val.a;
2986 l = s4ptr[1]; /* low */
2987 i = s4ptr[2]; /* high */
2989 var_to_reg_int(s1, src, REG_ITMP1);
2991 M_INTMOVE(s1, REG_ITMP1);
2992 } else if (l <= 32768) {
2993 M_LDA(REG_ITMP1, s1, -l);
2995 ICONST(REG_ITMP2, l);
2996 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
3003 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
3005 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
3006 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3008 M_BEQZ(REG_ITMP2, 0);
3009 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3011 /* build jump table top down and use address of lowest entry */
3013 /* s4ptr += 3 + i; */
3017 dseg_addtarget(cd, (basicblock *) tptr[0]);
3022 /* length of dataseg after last dseg_addtarget is used by load */
3024 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
3025 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
3026 M_JMP(REG_ZERO, REG_ITMP2);
3031 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3033 s4 i, l, val, *s4ptr;
3036 tptr = (void **) iptr->target;
3038 s4ptr = iptr->val.a;
3039 l = s4ptr[0]; /* default */
3040 i = s4ptr[1]; /* count */
3042 MCODECHECK((i<<2)+8);
3043 var_to_reg_int(s1, src, REG_ITMP1);
3049 if ((val >= 0) && (val <= 255)) {
3050 M_CMPEQ_IMM(s1, val, REG_ITMP2);
3052 if ((val >= -32768) && (val <= 32767)) {
3053 M_LDA(REG_ITMP2, REG_ZERO, val);
3055 disp = dseg_adds4(cd, val);
3056 M_ILD(REG_ITMP2, REG_PV, disp);
3058 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
3060 M_BNEZ(REG_ITMP2, 0);
3061 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3066 tptr = (void **) iptr->target;
3067 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3074 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
3075 /* op1 = arg count val.a = builtintable entry */
3081 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3082 /* op1 = arg count, val.a = method pointer */
3084 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3085 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
3086 case ICMD_INVOKEINTERFACE:
3091 md = lm->parseddesc;
3093 unresolved_method *um = iptr->target;
3094 md = um->methodref->parseddesc.md;
3100 MCODECHECK((s3 << 1) + 64);
3102 /* copy arguments to registers or stack location */
3104 for (s3 = s3 - 1; s3 >= 0; s3--, src = src->prev) {
3105 if (src->varkind == ARGVAR)
3107 if (IS_INT_LNG_TYPE(src->type)) {
3108 if (!md->params[s3].inmemory) {
3109 s1 = rd->argintregs[md->params[s3].regoff];
3110 var_to_reg_int(d, src, s1);
3113 var_to_reg_int(d, src, REG_ITMP1);
3114 M_LST(d, REG_SP, md->params[s3].regoff * 8);
3118 if (!md->params[s3].inmemory) {
3119 s1 = rd->argfltregs[md->params[s3].regoff];
3120 var_to_reg_flt(d, src, s1);
3123 var_to_reg_flt(d, src, REG_FTMP1);
3124 M_DST(d, REG_SP, md->params[s3].regoff * 8);
3129 switch (iptr->opc) {
3132 disp = dseg_addaddress(cd, NULL);
3134 codegen_addpatchref(cd, mcodeptr, bte->fp, iptr->target,
3137 if (opt_showdisassemble)
3141 disp = dseg_addaddress(cd, bte->fp);
3144 d = md->returntype.type;
3146 M_ALD(REG_PV, REG_PV, disp); /* Pointer to built-in-function */
3149 case ICMD_INVOKESPECIAL:
3150 M_BEQZ(rd->argintregs[0], 0);
3151 codegen_addxnullrefs(cd, mcodeptr);
3154 case ICMD_INVOKESTATIC:
3156 unresolved_method *um = iptr->target;
3158 disp = dseg_addaddress(cd, NULL);
3160 codegen_addpatchref(cd, mcodeptr,
3161 PATCHER_invokestatic_special, um, disp);
3163 if (opt_showdisassemble)
3166 d = um->methodref->parseddesc.md->returntype.type;
3169 disp = dseg_addaddress(cd, lm->stubroutine);
3170 d = lm->parseddesc->returntype.type;
3173 M_ALD(REG_PV, REG_PV, disp); /* method pointer in r27 */
3176 case ICMD_INVOKEVIRTUAL:
3177 gen_nullptr_check(rd->argintregs[0]);
3180 unresolved_method *um = iptr->target;
3182 codegen_addpatchref(cd, mcodeptr,
3183 PATCHER_invokevirtual, um, 0);
3185 if (opt_showdisassemble)
3189 d = um->methodref->parseddesc.md->returntype.type;
3192 s1 = OFFSET(vftbl_t, table[0]) +
3193 sizeof(methodptr) * lm->vftblindex;
3194 d = lm->parseddesc->returntype.type;
3197 M_ALD(REG_METHODPTR, rd->argintregs[0],
3198 OFFSET(java_objectheader, vftbl));
3199 M_ALD(REG_PV, REG_METHODPTR, s1);
3202 case ICMD_INVOKEINTERFACE:
3203 gen_nullptr_check(rd->argintregs[0]);
3206 unresolved_method *um = iptr->target;
3208 codegen_addpatchref(cd, mcodeptr,
3209 PATCHER_invokeinterface, um, 0);
3211 if (opt_showdisassemble)
3216 d = um->methodref->parseddesc.md->returntype.type;
3219 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3220 sizeof(methodptr*) * lm->class->index;
3222 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3224 d = lm->parseddesc->returntype.type;
3227 M_ALD(REG_METHODPTR, rd->argintregs[0],
3228 OFFSET(java_objectheader, vftbl));
3229 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3230 M_ALD(REG_PV, REG_METHODPTR, s2);
3234 M_JSR(REG_RA, REG_PV);
3235 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3236 M_LDA(REG_PV, REG_RA, -disp);
3238 /* d contains return type */
3240 if (d != TYPE_VOID) {
3241 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3242 s1 = reg_of_var(rd, iptr->dst, REG_RESULT);
3243 M_INTMOVE(REG_RESULT, s1);
3244 store_reg_to_var_int(iptr->dst, s1);
3246 s1 = reg_of_var(rd, iptr->dst, REG_FRESULT);
3247 M_FLTMOVE(REG_FRESULT, s1);
3248 store_reg_to_var_flt(iptr->dst, s1);
3254 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3256 /* op1: 0 == array, 1 == class */
3257 /* val.a: (classinfo*) superclass */
3259 /* superclass is an interface:
3261 * OK if ((sub == NULL) ||
3262 * (sub->vftbl->interfacetablelength > super->index) &&
3263 * (sub->vftbl->interfacetable[-super->index] != NULL));
3265 * superclass is a class:
3267 * OK if ((sub == NULL) || (0
3268 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3269 * super->vftbl->diffval));
3274 vftbl_t *supervftbl;
3277 super = (classinfo *) iptr->val.a;
3284 superindex = super->index;
3285 supervftbl = super->vftbl;
3288 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3289 codegen_threadcritrestart(cd, (u1 *) mcodeptr - cd->mcodebase);
3291 var_to_reg_int(s1, src, REG_ITMP1);
3293 /* calculate interface checkcast code size */
3297 s2 += opt_showdisassemble ? 1 : 0;
3299 /* calculate class checkcast code size */
3301 s3 = 9 /* 8 + (s1 == REG_ITMP1) */;
3303 s3 += opt_showdisassemble ? 1 : 0;
3305 /* if class is not resolved, check which code to call */
3308 M_BEQZ(s1, 4 + (opt_showdisassemble ? 1 : 0) + s2 + 1 + s3);
3310 disp = dseg_adds4(cd, 0); /* super->flags */
3312 codegen_addpatchref(cd, mcodeptr,
3313 PATCHER_checkcast_instanceof_flags,
3314 (constant_classref *) iptr->target, disp);
3316 if (opt_showdisassemble)
3319 M_ILD(REG_ITMP2, REG_PV, disp);
3320 disp = dseg_adds4(cd, ACC_INTERFACE);
3321 M_ILD(REG_ITMP3, REG_PV, disp);
3322 M_AND(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3323 M_BEQZ(REG_ITMP2, s2 + 1);
3326 /* interface checkcast code */
3328 if (!super || (super->flags & ACC_INTERFACE)) {
3333 codegen_addpatchref(cd, mcodeptr,
3334 PATCHER_checkcast_instanceof_interface,
3335 (constant_classref *) iptr->target, 0);
3337 if (opt_showdisassemble)
3341 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3342 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
3343 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
3344 M_BLEZ(REG_ITMP3, 0);
3345 codegen_addxcastrefs(cd, mcodeptr);
3346 M_ALD(REG_ITMP3, REG_ITMP2,
3347 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
3348 superindex * sizeof(methodptr*)));
3349 M_BEQZ(REG_ITMP3, 0);
3350 codegen_addxcastrefs(cd, mcodeptr);
3356 /* class checkcast code */
3358 if (!super || !(super->flags & ACC_INTERFACE)) {
3359 disp = dseg_addaddress(cd, supervftbl);
3365 codegen_addpatchref(cd, mcodeptr,
3366 PATCHER_checkcast_instanceof_class,
3367 (constant_classref *) iptr->target,
3370 if (opt_showdisassemble)
3374 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3375 M_ALD(REG_ITMP3, REG_PV, disp);
3376 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3377 codegen_threadcritstart(cd, (u1 *) mcodeptr - cd->mcodebase);
3379 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3380 /* if (s1 != REG_ITMP1) { */
3381 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3382 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3383 /* #if defined(USE_THREADS) && defined(NATIVE_THREADS) */
3384 /* codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase); */
3386 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3389 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3390 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3391 M_ALD(REG_ITMP3, REG_PV, disp);
3392 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3393 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3394 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3397 M_CMPULE(REG_ITMP2, REG_ITMP3, REG_ITMP3);
3398 M_BEQZ(REG_ITMP3, 0);
3399 codegen_addxcastrefs(cd, mcodeptr);
3401 d = reg_of_var(rd, iptr->dst, s1);
3403 store_reg_to_var_int(iptr->dst, d);
3407 case ICMD_ARRAYCHECKCAST: /* ..., objectref ==> ..., objectref */
3408 /* op1: 1... resolved, 0... not resolved */
3410 var_to_reg_int(s1, src, rd->argintregs[0]);
3411 M_INTMOVE(s1, rd->argintregs[0]);
3415 disp = dseg_addaddress(cd, iptr->target);
3418 codegen_addpatchref(cd, mcodeptr, bte->fp, iptr->target, disp);
3420 if (opt_showdisassemble)
3426 a = (ptrint) bte->fp;
3429 M_ALD(rd->argintregs[1], REG_PV, disp);
3431 disp = dseg_addaddress(cd, a);
3432 M_ALD(REG_PV, REG_PV, disp);
3433 M_JSR(REG_RA, REG_PV);
3434 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3435 M_LDA(REG_PV, REG_RA, -disp);
3437 M_BEQZ(REG_RESULT, 0);
3438 codegen_addxcastrefs(cd, mcodeptr);
3440 var_to_reg_int(s1, src, REG_ITMP1);
3441 d = reg_of_var(rd, iptr->dst, s1);
3443 store_reg_to_var_int(iptr->dst, d);
3446 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3448 /* op1: 0 == array, 1 == class */
3449 /* val.a: (classinfo*) superclass */
3451 /* superclass is an interface:
3453 * return (sub != NULL) &&
3454 * (sub->vftbl->interfacetablelength > super->index) &&
3455 * (sub->vftbl->interfacetable[-super->index] != NULL);
3457 * superclass is a class:
3459 * return ((sub != NULL) && (0
3460 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3461 * super->vftbl->diffvall));
3466 vftbl_t *supervftbl;
3469 super = (classinfo *) iptr->val.a;
3476 superindex = super->index;
3477 supervftbl = super->vftbl;
3480 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3481 codegen_threadcritrestart(cd, (u1 *) mcodeptr - cd->mcodebase);
3483 var_to_reg_int(s1, src, REG_ITMP1);
3484 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
3486 M_MOV(s1, REG_ITMP1);
3490 /* calculate interface instanceof code size */
3494 s2 += (d == REG_ITMP2 ? 1 : 0) + (opt_showdisassemble ? 1 : 0);
3496 /* calculate class instanceof code size */
3500 s3 += (opt_showdisassemble ? 1 : 0);
3502 /* if class is not resolved, check which code to call */
3506 M_BEQZ(s1, 4 + (opt_showdisassemble ? 1 : 0) + s2 + 1 + s3);
3508 disp = dseg_adds4(cd, 0); /* super->flags */
3510 codegen_addpatchref(cd, mcodeptr,
3511 PATCHER_checkcast_instanceof_flags,
3512 (constant_classref *) iptr->target, disp);
3514 if (opt_showdisassemble)
3517 M_ILD(REG_ITMP3, REG_PV, disp);
3519 disp = dseg_adds4(cd, ACC_INTERFACE);
3520 M_ILD(REG_ITMP2, REG_PV, disp);
3521 M_AND(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3522 M_BEQZ(REG_ITMP3, s2 + 1);
3525 /* interface instanceof code */
3527 if (!super || (super->flags & ACC_INTERFACE)) {
3533 /* If d == REG_ITMP2, then it's destroyed in check code */
3538 codegen_addpatchref(cd, mcodeptr,
3539 PATCHER_checkcast_instanceof_interface,
3540 (constant_classref *) iptr->target, 0);
3542 if (opt_showdisassemble)
3546 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3547 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3548 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
3549 M_BLEZ(REG_ITMP3, 2);
3550 M_ALD(REG_ITMP1, REG_ITMP1,
3551 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
3552 superindex * sizeof(methodptr*)));
3553 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3559 /* class instanceof code */
3561 if (!super || !(super->flags & ACC_INTERFACE)) {
3562 disp = dseg_addaddress(cd, supervftbl);
3569 codegen_addpatchref(cd, mcodeptr,
3570 PATCHER_checkcast_instanceof_class,
3571 (constant_classref *) iptr->target,
3574 if (opt_showdisassemble)
3578 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3579 M_ALD(REG_ITMP2, REG_PV, disp);
3580 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3581 codegen_threadcritstart(cd, (u1 *) mcodeptr - cd->mcodebase);
3583 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3584 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3585 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3586 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3587 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3589 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3590 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3592 store_reg_to_var_int(iptr->dst, d);
3597 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
3599 var_to_reg_int(s1, src, REG_ITMP1);
3601 codegen_addxcheckarefs(cd, mcodeptr);
3604 case ICMD_CHECKEXCEPTION: /* ... ==> ... */
3606 M_BEQZ(REG_RESULT, 0);
3607 codegen_addxexceptionrefs(cd, mcodeptr);
3610 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3611 /* op1 = dimension, val.a = array descriptor */
3613 /* check for negative sizes and copy sizes to stack if necessary */
3615 MCODECHECK((iptr->op1 << 1) + 64);
3617 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3618 var_to_reg_int(s2, src, REG_ITMP1);
3620 codegen_addxcheckarefs(cd, mcodeptr);
3622 /* copy SAVEDVAR sizes to stack */
3624 if (src->varkind != ARGVAR) {
3625 M_LST(s2, REG_SP, s1 * 8);
3629 /* a0 = dimension count */
3631 ICONST(rd->argintregs[0], iptr->op1);
3633 /* is patcher function set? */
3636 disp = dseg_addaddress(cd, 0);
3638 codegen_addpatchref(cd, mcodeptr,
3639 (functionptr) iptr->target, iptr->val.a,
3642 if (opt_showdisassemble)
3646 disp = dseg_addaddress(cd, iptr->val.a);
3649 /* a1 = arraydescriptor */
3651 M_ALD(rd->argintregs[1], REG_PV, disp);
3653 /* a2 = pointer to dimensions = stack pointer */
3655 M_INTMOVE(REG_SP, rd->argintregs[2]);
3657 disp = dseg_addaddress(cd, (void *) BUILTIN_multianewarray);
3658 M_ALD(REG_PV, REG_PV, disp);
3659 M_JSR(REG_RA, REG_PV);
3660 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3661 M_LDA(REG_PV, REG_RA, -disp);
3663 d = reg_of_var(rd, iptr->dst, REG_RESULT);
3664 M_INTMOVE(REG_RESULT, d);
3665 store_reg_to_var_int(iptr->dst, d);
3669 throw_cacao_exception_exit(string_java_lang_InternalError,
3670 "Unknown ICMD %d", iptr->opc);
3673 } /* for instruction */
3675 /* copy values to interface registers */
3677 src = bptr->outstack;
3678 len = bptr->outdepth;
3685 if ((src->varkind != STACKVAR)) {
3687 if (IS_FLT_DBL_TYPE(s2)) {
3688 var_to_reg_flt(s1, src, REG_FTMP1);
3689 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3690 M_FLTMOVE(s1,rd->interfaces[len][s2].regoff);
3693 M_DST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3697 var_to_reg_int(s1, src, REG_ITMP1);
3698 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3699 M_INTMOVE(s1,rd->interfaces[len][s2].regoff);
3702 M_LST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3708 } /* if (bptr -> flags >= BBREACHED) */
3709 } /* for basic block */
3711 codegen_createlinenumbertable(cd);
3715 s4 *xcodeptr = NULL;
3718 /* generate ArithmeticException stubs */
3720 for (bref = cd->xdivrefs; bref != NULL; bref = bref->next) {
3721 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3722 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3724 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3728 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3730 (u1 *) mcodeptr - cd->mcodebase);
3734 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3736 if (xcodeptr != NULL) {
3737 M_BR(xcodeptr - mcodeptr - 1);
3740 xcodeptr = mcodeptr;
3742 M_MOV(REG_PV, rd->argintregs[0]);
3743 M_MOV(REG_SP, rd->argintregs[1]);
3744 M_ALD(rd->argintregs[2],
3745 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3746 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3748 M_LDA(REG_SP, REG_SP, -1 * 8);
3749 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3751 disp = dseg_addaddress(cd, stacktrace_inline_arithmeticexception);
3752 M_ALD(REG_PV, REG_PV, disp);
3753 M_JSR(REG_RA, REG_PV);
3754 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3755 M_LDA(REG_PV, REG_RA, -disp);
3757 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3759 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3760 M_LDA(REG_SP, REG_SP, 1 * 8);
3762 disp = dseg_addaddress(cd, asm_handle_exception);
3763 M_ALD(REG_ITMP3, REG_PV, disp);
3764 M_JMP(REG_ZERO, REG_ITMP3);
3768 /* generate ArrayIndexOutOfBoundsException stubs */
3772 for (bref = cd->xboundrefs; bref != NULL; bref = bref->next) {
3773 gen_resolvebranch((u1*) cd->mcodebase + bref->branchpos,
3775 (u1*) mcodeptr - cd->mcodebase);
3779 /* move index register into REG_ITMP1 */
3781 M_MOV(bref->reg, REG_ITMP1);
3782 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3784 if (xcodeptr != NULL) {
3785 M_BR(xcodeptr - mcodeptr - 1);
3788 xcodeptr = mcodeptr;
3790 M_MOV(REG_PV, rd->argintregs[0]);
3791 M_MOV(REG_SP, rd->argintregs[1]);
3793 if (m->isleafmethod)
3794 M_MOV(REG_RA, rd->argintregs[2]);
3796 M_ALD(rd->argintregs[2],
3797 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3799 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3800 M_MOV(REG_ITMP1, rd->argintregs[4]);
3802 M_LDA(REG_SP, REG_SP, -2 * 8);
3803 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3805 if (m->isleafmethod)
3806 M_AST(REG_RA, REG_SP, 1 * 8);
3808 disp = dseg_addaddress(cd, stacktrace_inline_arrayindexoutofboundsexception);
3809 M_ALD(REG_PV, REG_PV, disp);
3810 M_JSR(REG_RA, REG_PV);
3811 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3812 M_LDA(REG_PV, REG_RA, -disp);
3814 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3816 if (m->isleafmethod)
3817 M_ALD(REG_RA, REG_SP, 1 * 8);
3819 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3820 M_LDA(REG_SP, REG_SP, 2 * 8);
3822 disp = dseg_addaddress(cd, asm_handle_exception);
3823 M_ALD(REG_ITMP3, REG_PV, disp);
3824 M_JMP(REG_ZERO, REG_ITMP3);
3828 /* generate ArrayStoreException stubs */
3832 for (bref = cd->xstorerefs; bref != NULL; bref = bref->next) {
3833 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3834 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3836 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3840 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3842 (u1 *) mcodeptr - cd->mcodebase);
3846 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3848 if (xcodeptr != NULL) {
3849 M_BR(xcodeptr - mcodeptr - 1);
3852 xcodeptr = mcodeptr;
3854 M_MOV(REG_PV, rd->argintregs[0]);
3855 M_MOV(REG_SP, rd->argintregs[1]);
3856 M_ALD(rd->argintregs[2],
3857 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3858 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3860 M_LDA(REG_SP, REG_SP, -1 * 8);
3861 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3863 disp = dseg_addaddress(cd, stacktrace_inline_arraystoreexception);
3864 M_ALD(REG_PV, REG_PV, disp);
3865 M_JSR(REG_RA, REG_PV);
3866 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3867 M_LDA(REG_PV, REG_RA, -disp);
3869 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3871 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3872 M_LDA(REG_SP, REG_SP, 1 * 8);
3874 disp = dseg_addaddress(cd, asm_handle_exception);
3875 M_ALD(REG_ITMP3, REG_PV, disp);
3876 M_JMP(REG_ZERO, REG_ITMP3);
3880 /* generate ClassCastException stubs */
3884 for (bref = cd->xcastrefs; bref != NULL; bref = bref->next) {
3885 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3886 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3888 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3892 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3894 (u1 *) mcodeptr - cd->mcodebase);
3898 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3900 if (xcodeptr != NULL) {
3901 M_BR(xcodeptr - mcodeptr - 1);
3904 xcodeptr = mcodeptr;
3906 M_MOV(REG_PV, rd->argintregs[0]);
3907 M_MOV(REG_SP, rd->argintregs[1]);
3909 if (m->isleafmethod)
3910 M_MOV(REG_RA, rd->argintregs[2]);
3912 M_ALD(rd->argintregs[2],
3913 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3915 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3917 M_LDA(REG_SP, REG_SP, -2 * 8);
3918 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3920 if (m->isleafmethod)
3921 M_AST(REG_RA, REG_SP, 1 * 8);
3923 disp = dseg_addaddress(cd, stacktrace_inline_classcastexception);
3924 M_ALD(REG_PV, REG_PV, disp);
3925 M_JSR(REG_RA, REG_PV);
3926 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3927 M_LDA(REG_PV, REG_RA, -disp);
3929 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3931 if (m->isleafmethod)
3932 M_ALD(REG_RA, REG_SP, 1 * 8);
3934 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3935 M_LDA(REG_SP, REG_SP, 2 * 8);
3937 disp = dseg_addaddress(cd, asm_handle_exception);
3938 M_ALD(REG_ITMP3, REG_PV, disp);
3939 M_JMP(REG_ZERO, REG_ITMP3);
3943 /* generate NegativeArraySizeException stubs */
3947 for (bref = cd->xcheckarefs; bref != NULL; bref = bref->next) {
3948 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3949 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3951 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3955 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3957 (u1 *) mcodeptr - cd->mcodebase);
3961 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3963 if (xcodeptr != NULL) {
3964 M_BR(xcodeptr - mcodeptr - 1);
3967 xcodeptr = mcodeptr;
3969 M_MOV(REG_PV, rd->argintregs[0]);
3970 M_MOV(REG_SP, rd->argintregs[1]);
3971 M_ALD(rd->argintregs[2],
3972 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3973 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3975 M_LDA(REG_SP, REG_SP, -2 * 8);
3976 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3978 disp = dseg_addaddress(cd, stacktrace_inline_negativearraysizeexception);
3979 M_ALD(REG_PV, REG_PV, disp);
3980 M_JSR(REG_RA, REG_PV);
3981 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3982 M_LDA(REG_PV, REG_RA, -disp);
3984 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3986 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3987 M_LDA(REG_SP, REG_SP, 2 * 8);
3989 disp = dseg_addaddress(cd, asm_handle_exception);
3990 M_ALD(REG_ITMP3, REG_PV, disp);
3991 M_JMP(REG_ZERO, REG_ITMP3);
3995 /* generate NullPointerException stubs */
3999 for (bref = cd->xnullrefs; bref != NULL; bref = bref->next) {
4000 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
4001 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
4003 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
4007 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
4009 (u1 *) mcodeptr - cd->mcodebase);
4013 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
4015 if (xcodeptr != NULL) {
4016 M_BR(xcodeptr - mcodeptr - 1);
4019 xcodeptr = mcodeptr;
4021 M_MOV(REG_PV, rd->argintregs[0]);
4022 M_MOV(REG_SP, rd->argintregs[1]);
4024 if (m->isleafmethod)
4025 M_MOV(REG_RA, rd->argintregs[2]);
4027 M_ALD(rd->argintregs[2],
4028 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
4030 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
4032 M_LDA(REG_SP, REG_SP, -2 * 8);
4033 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
4035 if (m->isleafmethod)
4036 M_AST(REG_RA, REG_SP, 1 * 8);
4038 disp = dseg_addaddress(cd, stacktrace_inline_nullpointerexception);
4039 M_ALD(REG_PV, REG_PV, disp);
4040 M_JSR(REG_RA, REG_PV);
4041 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4042 M_LDA(REG_PV, REG_RA, -disp);
4044 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
4046 if (m->isleafmethod)
4047 M_ALD(REG_RA, REG_SP, 1 * 8);
4049 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
4050 M_LDA(REG_SP, REG_SP, 2 * 8);
4052 disp = dseg_addaddress(cd, asm_handle_exception);
4053 M_ALD(REG_ITMP3, REG_PV, disp);
4054 M_JMP(REG_ZERO, REG_ITMP3);
4058 /* generate ICMD_CHECKEXCEPTION stubs */
4062 for (bref = cd->xexceptionrefs; bref != NULL; bref = bref->next) {
4063 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
4064 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
4066 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
4070 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
4072 (u1 *) mcodeptr - cd->mcodebase);
4076 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
4078 if (xcodeptr != NULL) {
4079 M_BR(xcodeptr - mcodeptr - 1);
4082 xcodeptr = mcodeptr;
4084 M_MOV(REG_PV, rd->argintregs[0]);
4085 M_MOV(REG_SP, rd->argintregs[1]);
4086 M_ALD(rd->argintregs[2],
4087 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
4088 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
4090 M_LDA(REG_SP, REG_SP, -1 * 8);
4091 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
4093 disp = dseg_addaddress(cd, stacktrace_inline_fillInStackTrace);
4094 M_ALD(REG_PV, REG_PV, disp);
4095 M_JSR(REG_RA, REG_PV);
4096 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4097 M_LDA(REG_PV, REG_RA, -disp);
4099 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
4101 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
4102 M_LDA(REG_SP, REG_SP, 1 * 8);
4104 disp = dseg_addaddress(cd, asm_handle_exception);
4105 M_ALD(REG_ITMP3, REG_PV, disp);
4106 M_JMP(REG_ZERO, REG_ITMP3);
4110 /* generate patcher stub call code */
4117 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
4118 /* check code segment size */
4122 /* Get machine code which is patched back in later. The call is */
4123 /* 1 instruction word long. */
4125 xcodeptr = (s4 *) (cd->mcodebase + pref->branchpos);
4128 /* patch in the call to call the following code (done at compile */
4131 tmpmcodeptr = mcodeptr; /* save current mcodeptr */
4132 mcodeptr = xcodeptr; /* set mcodeptr to patch position */
4134 M_BSR(REG_ITMP3, tmpmcodeptr - (xcodeptr + 1));
4136 mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
4138 /* create stack frame */
4140 M_LSUB_IMM(REG_SP, 6 * 8, REG_SP);
4142 /* move return address onto stack */
4144 M_AST(REG_ITMP3, REG_SP, 5 * 8);
4146 /* move pointer to java_objectheader onto stack */
4148 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4149 /* create a virtual java_objectheader */
4151 (void) dseg_addaddress(cd, get_dummyLR()); /* monitorPtr */
4152 disp = dseg_addaddress(cd, NULL); /* vftbl */
4154 M_LDA(REG_ITMP3, REG_PV, disp);
4155 M_AST(REG_ITMP3, REG_SP, 4 * 8);
4157 M_AST(REG_ZERO, REG_SP, 4 * 8);
4160 /* move machine code onto stack */
4162 disp = dseg_adds4(cd, mcode);
4163 M_ILD(REG_ITMP3, REG_PV, disp);
4164 M_IST(REG_ITMP3, REG_SP, 3 * 8);
4166 /* move class/method/field reference onto stack */
4168 disp = dseg_addaddress(cd, pref->ref);
4169 M_ALD(REG_ITMP3, REG_PV, disp);
4170 M_AST(REG_ITMP3, REG_SP, 2 * 8);
4172 /* move data segment displacement onto stack */
4174 disp = dseg_adds4(cd, pref->disp);
4175 M_ILD(REG_ITMP3, REG_PV, disp);
4176 M_IST(REG_ITMP3, REG_SP, 1 * 8);
4178 /* move patcher function pointer onto stack */
4180 disp = dseg_addaddress(cd, pref->patcher);
4181 M_ALD(REG_ITMP3, REG_PV, disp);
4182 M_AST(REG_ITMP3, REG_SP, 0 * 8);
4184 disp = dseg_addaddress(cd, asm_wrapper_patcher);
4185 M_ALD(REG_ITMP3, REG_PV, disp);
4186 M_JMP(REG_ZERO, REG_ITMP3);
4191 codegen_finish(m, cd, (s4) ((u1 *) mcodeptr - cd->mcodebase));
4195 /* createcompilerstub **********************************************************
4197 Creates a stub routine which calls the compiler.
4199 *******************************************************************************/
4201 #define COMPSTUBSIZE 3
4203 functionptr createcompilerstub(methodinfo *m)
4205 u8 *s = CNEW(u8, COMPSTUBSIZE); /* memory to hold the stub */
4206 s4 *mcodeptr = (s4 *) s; /* code generation pointer */
4208 /* code for the stub */
4209 M_ALD(REG_PV, REG_PV, 16); /* load pointer to the compiler */
4210 M_JMP(0, REG_PV); /* jump to the compiler, return address
4211 in reg 0 is used as method pointer */
4212 s[1] = (ptrint) m; /* literals to be adressed */
4213 s[2] = (ptrint) asm_call_jit_compiler; /* jump directly via PV from above */
4215 #if defined(STATISTICS)
4217 count_cstub_len += COMPSTUBSIZE * 8;
4220 return (functionptr) s;
4224 /* createnativestub ************************************************************
4226 Creates a stub routine which calls a native method.
4228 *******************************************************************************/
4230 functionptr createnativestub(functionptr f, methodinfo *m, codegendata *cd,
4231 registerdata *rd, methoddesc *nmd)
4233 s4 *mcodeptr; /* code generation pointer */
4234 s4 stackframesize; /* size of stackframe if needed */
4237 s4 i, j; /* count variables */
4240 s4 funcdisp; /* displacement of the function */
4242 /* initialize variables */
4245 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
4248 /* calculate stack frame size */
4251 1 + /* return address */
4252 sizeof(stackframeinfo) / SIZEOF_VOID_P +
4253 1 + /* methodinfo for call trace */
4254 (md->paramcount > INT_ARG_CNT ? INT_ARG_CNT : md->paramcount) +
4258 /* create method header */
4260 (void) dseg_addaddress(cd, m); /* MethodPointer */
4261 (void) dseg_adds4(cd, stackframesize * 8); /* FrameSize */
4262 (void) dseg_adds4(cd, 0); /* IsSync */
4263 (void) dseg_adds4(cd, 0); /* IsLeaf */
4264 (void) dseg_adds4(cd, 0); /* IntSave */
4265 (void) dseg_adds4(cd, 0); /* FltSave */
4266 (void) dseg_addlinenumbertablesize(cd);
4267 (void) dseg_adds4(cd, 0); /* ExTableSize */
4270 /* initialize mcode variables */
4272 mcodeptr = (s4 *) cd->mcodebase;
4273 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
4276 /* generate stub code */
4278 M_LDA(REG_SP, REG_SP, -stackframesize * 8);
4279 M_AST(REG_RA, REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
4282 /* call trace function */
4285 /* save integer argument registers */
4287 for (i = 0, j = 1; i < md->paramcount && i < INT_ARG_CNT; i++) {
4288 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4289 M_LST(rd->argintregs[i], REG_SP, j * 8);
4294 /* save and copy float arguments into integer registers */
4296 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4297 t = md->paramtypes[i].type;
4299 if (IS_FLT_DBL_TYPE(t)) {
4300 if (IS_2_WORD_TYPE(t)) {
4301 M_DST(rd->argfltregs[i], REG_SP, j * 8);
4302 M_LLD(rd->argintregs[i], REG_SP, j * 8);
4304 M_FST(rd->argfltregs[i], REG_SP, j * 8);
4305 M_ILD(rd->argintregs[i], REG_SP, j * 8);
4311 disp = dseg_addaddress(cd, m);
4312 M_ALD(REG_ITMP1, REG_PV, disp);
4313 M_AST(REG_ITMP1, REG_SP, 0 * 8);
4314 disp = dseg_addaddress(cd, builtin_trace_args);
4315 M_ALD(REG_PV, REG_PV, disp);
4316 M_JSR(REG_RA, REG_PV);
4317 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4318 M_LDA(REG_PV, REG_RA, -disp);
4320 for (i = 0, j = 1; i < md->paramcount && i < INT_ARG_CNT; i++) {
4321 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4322 M_LLD(rd->argintregs[i], REG_SP, j * 8);
4327 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4328 t = md->paramtypes[i].type;
4330 if (IS_FLT_DBL_TYPE(t)) {
4331 if (IS_2_WORD_TYPE(t)) {
4332 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
4334 M_FLD(rd->argfltregs[i], REG_SP, j * 8);
4341 /* get function address (this must happen before the stackframeinfo) */
4343 funcdisp = dseg_addaddress(cd, f);
4345 #if !defined(ENABLE_STATICVM)
4347 codegen_addpatchref(cd, mcodeptr, PATCHER_resolve_native, m, funcdisp);
4349 if (opt_showdisassemble)
4355 /* save integer and float argument registers */
4357 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
4358 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4359 M_LST(rd->argintregs[i], REG_SP, j * 8);
4364 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4365 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
4366 M_DST(rd->argfltregs[i], REG_SP, j * 8);
4371 /* create native stackframe info */
4373 M_AADD_IMM(REG_SP, stackframesize * 8 - sizeof(stackframeinfo),
4375 M_MOV(REG_PV, rd->argintregs[1]);
4376 M_AADD_IMM(REG_SP, stackframesize * 8, rd->argintregs[2]);
4377 M_ALD(rd->argintregs[3], REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
4378 disp = dseg_addaddress(cd, stacktrace_create_native_stackframeinfo);
4379 M_ALD(REG_PV, REG_PV, disp);
4380 M_JSR(REG_RA, REG_PV);
4381 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4382 M_LDA(REG_PV, REG_RA, -disp);
4384 /* restore integer and float argument registers */
4386 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
4387 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4388 M_LLD(rd->argintregs[i], REG_SP, j * 8);
4393 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4394 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
4395 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
4401 /* copy or spill arguments to new locations */
4403 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
4404 t = md->paramtypes[i].type;
4406 if (IS_INT_LNG_TYPE(t)) {
4407 if (!md->params[i].inmemory) {
4408 s1 = rd->argintregs[md->params[i].regoff];
4410 if (!nmd->params[j].inmemory) {
4411 s2 = rd->argintregs[nmd->params[j].regoff];
4415 s2 = nmd->params[j].regoff;
4416 M_LST(s1, REG_SP, s2 * 8);
4420 s1 = md->params[i].regoff + stackframesize;
4421 s2 = nmd->params[j].regoff;
4422 M_LLD(REG_ITMP1, REG_SP, s1 * 8);
4423 M_LST(REG_ITMP1, REG_SP, s2 * 8);
4427 if (!md->params[i].inmemory) {
4428 s1 = rd->argfltregs[md->params[i].regoff];
4430 if (!nmd->params[j].inmemory) {
4431 s2 = rd->argfltregs[nmd->params[j].regoff];
4435 s2 = nmd->params[j].regoff;
4436 if (IS_2_WORD_TYPE(t))
4437 M_DST(s1, REG_SP, s2 * 8);
4439 M_FST(s1, REG_SP, s2 * 8);
4443 s1 = md->params[i].regoff + stackframesize;
4444 s2 = nmd->params[j].regoff;
4445 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
4446 if (IS_2_WORD_TYPE(t))
4447 M_DST(REG_FTMP1, REG_SP, s2 * 8);
4449 M_FST(REG_FTMP1, REG_SP, s2 * 8);
4454 /* put class into second argument register */
4456 if (m->flags & ACC_STATIC) {
4457 disp = dseg_addaddress(cd, m->class);
4458 M_ALD(rd->argintregs[1], REG_PV, disp);
4461 /* put env into first argument register */
4463 disp = dseg_addaddress(cd, &env);
4464 M_ALD(rd->argintregs[0], REG_PV, disp);
4466 /* do the native function call */
4468 M_ALD(REG_PV, REG_PV, funcdisp);
4469 M_JSR(REG_RA, REG_PV); /* call native method */
4470 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4471 M_LDA(REG_PV, REG_RA, -disp); /* recompute pv from ra */
4474 /* remove native stackframe info */
4476 if (IS_INT_LNG_TYPE(md->returntype.type))
4477 M_LST(REG_RESULT, REG_SP, 0 * 8);
4479 M_DST(REG_FRESULT, REG_SP, 0 * 8);
4481 M_AADD_IMM(REG_SP, stackframesize * 8 - sizeof(stackframeinfo),
4483 disp = dseg_addaddress(cd, stacktrace_remove_stackframeinfo);
4484 M_ALD(REG_PV, REG_PV, disp);
4485 M_JSR(REG_RA, REG_PV);
4486 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4487 M_LDA(REG_PV, REG_RA, -disp);
4489 if (IS_INT_LNG_TYPE(md->returntype.type))
4490 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4492 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4495 /* call finished trace */
4498 M_LST(REG_RESULT, REG_SP, 0 * 8);
4499 M_DST(REG_FRESULT, REG_SP, 1 * 8);
4501 disp = dseg_addaddress(cd, m);
4502 M_ALD(rd->argintregs[0], REG_PV, disp);
4504 M_MOV(REG_RESULT, rd->argintregs[1]);
4505 M_FMOV(REG_FRESULT, rd->argfltregs[2]);
4506 M_FMOV(REG_FRESULT, rd->argfltregs[3]);
4508 disp = dseg_addaddress(cd, builtin_displaymethodstop);
4509 M_ALD(REG_PV, REG_PV, disp);
4510 M_JSR(REG_RA, REG_PV);
4511 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4512 M_LDA(REG_PV, REG_RA, -disp);
4514 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4515 M_DLD(REG_FRESULT, REG_SP, 1 * 8);
4519 /* check for exception */
4521 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4522 if (IS_FLT_DBL_TYPE(md->returntype.type))
4523 M_DST(REG_FRESULT, REG_SP, 0 * 8);
4525 M_AST(REG_RESULT, REG_SP, 0 * 8);
4527 disp = dseg_addaddress(cd, builtin_get_exceptionptrptr);
4528 M_ALD(REG_PV, REG_PV, disp);
4529 M_JSR(REG_RA, REG_PV);
4530 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4531 M_LDA(REG_PV, REG_RA, -disp);
4532 M_MOV(REG_RESULT, REG_ITMP3);
4534 if (IS_FLT_DBL_TYPE(md->returntype.type))
4535 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4537 M_ALD(REG_RESULT, REG_SP, 0 * 8);
4539 disp = dseg_addaddress(cd, &_exceptionptr);
4540 M_ALD(REG_ITMP3, REG_PV, disp); /* get address of exceptionptr */
4543 M_ALD(REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
4544 M_BNEZ(REG_ITMP1, 3); /* if no exception then return */
4546 M_ALD(REG_RA, REG_SP, (stackframesize - 1) * 8); /* load return address */
4548 M_LDA(REG_SP, REG_SP, stackframesize * 8);
4550 M_RET(REG_ZERO, REG_RA); /* return to caller */
4552 /* handle exception */
4554 M_AST(REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
4556 M_ALD(REG_RA, REG_SP, (stackframesize - 1) * 8); /* load return address */
4557 M_LDA(REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
4559 M_LDA(REG_SP, REG_SP, stackframesize * 8);
4561 disp = dseg_addaddress(cd, asm_handle_nat_exception);
4562 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
4563 M_JMP(REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
4566 /* process patcher calls **************************************************/
4574 /* there can only be one <clinit> ref entry */
4575 pref = cd->patchrefs;
4577 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
4578 /* Get machine code which is patched back in later. The call is */
4579 /* 1 instruction word long. */
4581 xcodeptr = (s4 *) (cd->mcodebase + pref->branchpos);
4582 mcode = (u4) *xcodeptr;
4584 /* patch in the call to call the following code (done at compile */
4587 tmpmcodeptr = mcodeptr; /* save current mcodeptr */
4588 mcodeptr = xcodeptr; /* set mcodeptr to patch position */
4590 M_BSR(REG_ITMP3, tmpmcodeptr - (xcodeptr + 1));
4592 mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
4594 /* create stack frame */
4596 M_LSUB_IMM(REG_SP, 6 * 8, REG_SP);
4598 /* move return address onto stack */
4600 M_AST(REG_ITMP3, REG_SP, 5 * 8);
4602 /* move pointer to java_objectheader onto stack */
4604 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4605 /* create a virtual java_objectheader */
4607 (void) dseg_addaddress(cd, get_dummyLR()); /* monitorPtr */
4608 disp = dseg_addaddress(cd, NULL); /* vftbl */
4610 M_LDA(REG_ITMP3, REG_PV, disp);
4611 M_AST(REG_ITMP3, REG_SP, 4 * 8);
4613 M_AST(REG_ZERO, REG_SP, 4 * 8);
4616 /* move machine code onto stack */
4618 disp = dseg_adds4(cd, mcode);
4619 M_ILD(REG_ITMP3, REG_PV, disp);
4620 M_IST(REG_ITMP3, REG_SP, 3 * 8);
4622 /* move class/method/field reference onto stack */
4624 disp = dseg_addaddress(cd, pref->ref);
4625 M_ALD(REG_ITMP3, REG_PV, disp);
4626 M_AST(REG_ITMP3, REG_SP, 2 * 8);
4628 /* move data segment displacement onto stack */
4630 disp = dseg_adds4(cd, pref->disp);
4631 M_ILD(REG_ITMP3, REG_PV, disp);
4632 M_IST(REG_ITMP3, REG_SP, 1 * 8);
4634 /* move patcher function pointer onto stack */
4636 disp = dseg_addaddress(cd, pref->patcher);
4637 M_ALD(REG_ITMP3, REG_PV, disp);
4638 M_AST(REG_ITMP3, REG_SP, 0 * 8);
4640 disp = dseg_addaddress(cd, asm_wrapper_patcher);
4641 M_ALD(REG_ITMP3, REG_PV, disp);
4642 M_JMP(REG_ZERO, REG_ITMP3);
4646 codegen_finish(m, cd, (s4) ((u1 *) mcodeptr - cd->mcodebase));
4648 return m->entrypoint;
4653 * These are local overrides for various environment variables in Emacs.
4654 * Please do not remove this and leave it at the end of the file, where
4655 * Emacs will automagically detect them.
4656 * ---------------------------------------------------------------------
4659 * indent-tabs-mode: t