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
35 $Id: codegen.c 3720 2005-11-19 03:10:38Z edwin $
49 #include "vm/jit/alpha/arch.h"
50 #include "vm/jit/alpha/codegen.h"
52 #include "cacao/cacao.h"
53 #include "native/jni.h"
54 #include "native/native.h"
55 #include "vm/builtin.h"
56 #include "vm/global.h"
57 #include "vm/loader.h"
58 #include "vm/stringlocal.h"
59 #include "vm/tables.h"
60 #include "vm/jit/asmpart.h"
61 #include "vm/jit/codegen.inc"
62 #include "vm/jit/jit.h"
65 # include "vm/jit/lsra.h"
66 # include "vm/jit/lsra.inc"
69 #include "vm/jit/parse.h"
70 #include "vm/jit/patcher.h"
71 #include "vm/jit/reg.h"
72 #include "vm/jit/reg.inc"
75 /* codegen *********************************************************************
77 Generates machine code.
79 *******************************************************************************/
81 bool codegen(methodinfo *m, codegendata *cd, registerdata *rd)
83 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 if ((iptr->target != NULL) && (iptr->val.a == NULL)) {
512 disp = dseg_addaddress(cd, iptr->val.a);
514 codegen_addpatchref(cd, mcodeptr,
516 (unresolved_class *) iptr->target, disp);
518 if (opt_showdisassemble)
521 M_ALD(d, REG_PV, disp);
524 if (iptr->val.a == NULL) {
525 M_INTMOVE(REG_ZERO, d);
527 disp = dseg_addaddress(cd, iptr->val.a);
528 M_ALD(d, REG_PV, disp);
531 store_reg_to_var_int(iptr->dst, d);
535 /* load/store operations **********************************************/
537 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
538 case ICMD_LLOAD: /* op1 = local variable */
541 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
542 if ((iptr->dst->varkind == LOCALVAR) &&
543 (iptr->dst->varnum == iptr->op1))
545 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
546 if (var->flags & INMEMORY) {
547 M_LLD(d, REG_SP, var->regoff * 8);
549 M_INTMOVE(var->regoff, d);
551 store_reg_to_var_int(iptr->dst, d);
554 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
555 case ICMD_DLOAD: /* op1 = local variable */
557 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
558 if ((iptr->dst->varkind == LOCALVAR) &&
559 (iptr->dst->varnum == iptr->op1))
561 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
562 if (var->flags & INMEMORY) {
563 M_DLD(d, REG_SP, var->regoff * 8);
565 M_FLTMOVE(var->regoff, d);
567 store_reg_to_var_flt(iptr->dst, d);
571 case ICMD_ISTORE: /* ..., value ==> ... */
572 case ICMD_LSTORE: /* op1 = local variable */
575 if ((src->varkind == LOCALVAR) &&
576 (src->varnum == iptr->op1))
578 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
579 if (var->flags & INMEMORY) {
580 var_to_reg_int(s1, src, REG_ITMP1);
581 M_LST(s1, REG_SP, var->regoff * 8);
583 var_to_reg_int(s1, src, var->regoff);
584 M_INTMOVE(s1, var->regoff);
588 case ICMD_FSTORE: /* ..., value ==> ... */
589 case ICMD_DSTORE: /* op1 = local variable */
591 if ((src->varkind == LOCALVAR) &&
592 (src->varnum == iptr->op1))
594 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
595 if (var->flags & INMEMORY) {
596 var_to_reg_flt(s1, src, REG_FTMP1);
597 M_DST(s1, REG_SP, var->regoff * 8);
599 var_to_reg_flt(s1, src, var->regoff);
600 M_FLTMOVE(s1, var->regoff);
605 /* pop/dup/swap operations ********************************************/
607 /* attention: double and longs are only one entry in CACAO ICMDs */
609 case ICMD_POP: /* ..., value ==> ... */
610 case ICMD_POP2: /* ..., value, value ==> ... */
613 case ICMD_DUP: /* ..., a ==> ..., a, a */
614 M_COPY(src, iptr->dst);
617 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
619 M_COPY(src, iptr->dst);
620 M_COPY(src->prev, iptr->dst->prev);
621 M_COPY(iptr->dst, iptr->dst->prev->prev);
624 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
626 M_COPY(src, iptr->dst);
627 M_COPY(src->prev, iptr->dst->prev);
628 M_COPY(src->prev->prev, iptr->dst->prev->prev);
629 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
632 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
634 M_COPY(src, iptr->dst);
635 M_COPY(src->prev, iptr->dst->prev);
638 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
640 M_COPY(src, iptr->dst);
641 M_COPY(src->prev, iptr->dst->prev);
642 M_COPY(src->prev->prev, iptr->dst->prev->prev);
643 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
644 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev);
647 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
649 M_COPY(src, iptr->dst);
650 M_COPY(src->prev, iptr->dst->prev);
651 M_COPY(src->prev->prev, iptr->dst->prev->prev);
652 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
653 M_COPY(iptr->dst, iptr->dst->prev->prev->prev->prev);
654 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev->prev);
657 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
659 M_COPY(src, iptr->dst->prev);
660 M_COPY(src->prev, iptr->dst);
664 /* integer operations *************************************************/
666 case ICMD_INEG: /* ..., value ==> ..., - value */
668 var_to_reg_int(s1, src, REG_ITMP1);
669 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
670 M_ISUB(REG_ZERO, s1, d);
671 store_reg_to_var_int(iptr->dst, d);
674 case ICMD_LNEG: /* ..., value ==> ..., - value */
676 var_to_reg_int(s1, src, REG_ITMP1);
677 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
678 M_LSUB(REG_ZERO, s1, d);
679 store_reg_to_var_int(iptr->dst, d);
682 case ICMD_I2L: /* ..., value ==> ..., value */
684 var_to_reg_int(s1, src, REG_ITMP1);
685 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
687 store_reg_to_var_int(iptr->dst, d);
690 case ICMD_L2I: /* ..., value ==> ..., value */
692 var_to_reg_int(s1, src, REG_ITMP1);
693 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
694 M_IADD(s1, REG_ZERO, d);
695 store_reg_to_var_int(iptr->dst, d);
698 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
700 var_to_reg_int(s1, src, REG_ITMP1);
701 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
702 if (has_ext_instr_set) {
705 M_SLL_IMM(s1, 56, d);
706 M_SRA_IMM( d, 56, d);
708 store_reg_to_var_int(iptr->dst, d);
711 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
713 var_to_reg_int(s1, src, REG_ITMP1);
714 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
716 store_reg_to_var_int(iptr->dst, d);
719 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
721 var_to_reg_int(s1, src, REG_ITMP1);
722 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
723 if (has_ext_instr_set) {
726 M_SLL_IMM(s1, 48, d);
727 M_SRA_IMM( d, 48, d);
729 store_reg_to_var_int(iptr->dst, d);
733 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
735 var_to_reg_int(s1, src->prev, REG_ITMP1);
736 var_to_reg_int(s2, src, REG_ITMP2);
737 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
739 store_reg_to_var_int(iptr->dst, d);
742 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
743 /* val.i = constant */
745 var_to_reg_int(s1, src, REG_ITMP1);
746 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
747 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
748 M_IADD_IMM(s1, iptr->val.i, d);
750 ICONST(REG_ITMP2, iptr->val.i);
751 M_IADD(s1, REG_ITMP2, d);
753 store_reg_to_var_int(iptr->dst, d);
756 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
758 var_to_reg_int(s1, src->prev, REG_ITMP1);
759 var_to_reg_int(s2, src, REG_ITMP2);
760 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
762 store_reg_to_var_int(iptr->dst, d);
765 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
766 /* val.l = constant */
768 var_to_reg_int(s1, src, REG_ITMP1);
769 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
770 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
771 M_LADD_IMM(s1, iptr->val.l, d);
773 LCONST(REG_ITMP2, iptr->val.l);
774 M_LADD(s1, REG_ITMP2, d);
776 store_reg_to_var_int(iptr->dst, d);
779 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
781 var_to_reg_int(s1, src->prev, REG_ITMP1);
782 var_to_reg_int(s2, src, REG_ITMP2);
783 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
785 store_reg_to_var_int(iptr->dst, d);
788 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
789 /* val.i = constant */
791 var_to_reg_int(s1, src, REG_ITMP1);
792 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
793 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
794 M_ISUB_IMM(s1, iptr->val.i, d);
796 ICONST(REG_ITMP2, iptr->val.i);
797 M_ISUB(s1, REG_ITMP2, d);
799 store_reg_to_var_int(iptr->dst, d);
802 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
804 var_to_reg_int(s1, src->prev, REG_ITMP1);
805 var_to_reg_int(s2, src, REG_ITMP2);
806 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
808 store_reg_to_var_int(iptr->dst, d);
811 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
812 /* val.l = constant */
814 var_to_reg_int(s1, src, REG_ITMP1);
815 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
816 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
817 M_LSUB_IMM(s1, iptr->val.l, d);
819 LCONST(REG_ITMP2, iptr->val.l);
820 M_LSUB(s1, REG_ITMP2, d);
822 store_reg_to_var_int(iptr->dst, d);
825 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
827 var_to_reg_int(s1, src->prev, REG_ITMP1);
828 var_to_reg_int(s2, src, REG_ITMP2);
829 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
831 store_reg_to_var_int(iptr->dst, d);
834 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
835 /* val.i = constant */
837 var_to_reg_int(s1, src, REG_ITMP1);
838 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
839 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
840 M_IMUL_IMM(s1, iptr->val.i, d);
842 ICONST(REG_ITMP2, iptr->val.i);
843 M_IMUL(s1, REG_ITMP2, d);
845 store_reg_to_var_int(iptr->dst, d);
848 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
850 var_to_reg_int(s1, src->prev, REG_ITMP1);
851 var_to_reg_int(s2, src, REG_ITMP2);
852 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
854 store_reg_to_var_int(iptr->dst, d);
857 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
858 /* val.l = constant */
860 var_to_reg_int(s1, src, REG_ITMP1);
861 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
862 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
863 M_LMUL_IMM(s1, iptr->val.l, d);
865 LCONST(REG_ITMP2, iptr->val.l);
866 M_LMUL(s1, REG_ITMP2, d);
868 store_reg_to_var_int(iptr->dst, d);
871 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
872 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
874 var_to_reg_int(s1, src->prev, REG_ITMP1);
875 var_to_reg_int(s2, src, REG_ITMP2);
876 d = reg_of_var(rd, iptr->dst, REG_RESULT);
878 codegen_addxdivrefs(cd, mcodeptr);
880 M_MOV(s1, rd->argintregs[0]);
881 M_MOV(s2, rd->argintregs[1]);
883 disp = dseg_addaddress(cd, bte->fp);
884 M_ALD(REG_PV, REG_PV, disp);
885 M_JSR(REG_RA, REG_PV);
886 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
887 M_LDA(REG_PV, REG_RA, -disp);
889 M_IADD(REG_RESULT, REG_ZERO, d); /* sign extend (bugfix for gcc -O2) */
890 store_reg_to_var_int(iptr->dst, d);
893 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
894 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
896 var_to_reg_int(s1, src->prev, REG_ITMP1);
897 var_to_reg_int(s2, src, REG_ITMP2);
898 d = reg_of_var(rd, iptr->dst, REG_RESULT);
900 codegen_addxdivrefs(cd, mcodeptr);
902 M_MOV(s1, rd->argintregs[0]);
903 M_MOV(s2, rd->argintregs[1]);
905 disp = dseg_addaddress(cd, bte->fp);
906 M_ALD(REG_PV, REG_PV, disp);
907 M_JSR(REG_RA, REG_PV);
908 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
909 M_LDA(REG_PV, REG_RA, -disp);
911 M_INTMOVE(REG_RESULT, d);
912 store_reg_to_var_int(iptr->dst, d);
915 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
916 case ICMD_LDIVPOW2: /* val.i = constant */
918 var_to_reg_int(s1, src, REG_ITMP1);
919 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
920 if (iptr->val.i <= 15) {
921 M_LDA(REG_ITMP2, s1, (1 << iptr->val.i) -1);
922 M_CMOVGE(s1, s1, REG_ITMP2);
924 M_SRA_IMM(s1, 63, REG_ITMP2);
925 M_SRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
926 M_LADD(s1, REG_ITMP2, REG_ITMP2);
928 M_SRA_IMM(REG_ITMP2, iptr->val.i, d);
929 store_reg_to_var_int(iptr->dst, d);
932 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
934 var_to_reg_int(s1, src->prev, REG_ITMP1);
935 var_to_reg_int(s2, src, REG_ITMP2);
936 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
937 M_AND_IMM(s2, 0x1f, REG_ITMP3);
938 M_SLL(s1, REG_ITMP3, d);
939 M_IADD(d, REG_ZERO, d);
940 store_reg_to_var_int(iptr->dst, d);
943 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
944 /* val.i = constant */
946 var_to_reg_int(s1, src, REG_ITMP1);
947 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
948 M_SLL_IMM(s1, iptr->val.i & 0x1f, d);
949 M_IADD(d, REG_ZERO, d);
950 store_reg_to_var_int(iptr->dst, d);
953 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
955 var_to_reg_int(s1, src->prev, REG_ITMP1);
956 var_to_reg_int(s2, src, REG_ITMP2);
957 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
958 M_AND_IMM(s2, 0x1f, REG_ITMP3);
959 M_SRA(s1, REG_ITMP3, d);
960 store_reg_to_var_int(iptr->dst, d);
963 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
964 /* val.i = constant */
966 var_to_reg_int(s1, src, REG_ITMP1);
967 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
968 M_SRA_IMM(s1, iptr->val.i & 0x1f, d);
969 store_reg_to_var_int(iptr->dst, d);
972 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
974 var_to_reg_int(s1, src->prev, REG_ITMP1);
975 var_to_reg_int(s2, src, REG_ITMP2);
976 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
977 M_AND_IMM(s2, 0x1f, REG_ITMP2);
979 M_SRL(d, REG_ITMP2, d);
980 M_IADD(d, REG_ZERO, d);
981 store_reg_to_var_int(iptr->dst, d);
984 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
985 /* val.i = constant */
987 var_to_reg_int(s1, src, REG_ITMP1);
988 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
990 M_SRL_IMM(d, iptr->val.i & 0x1f, d);
991 M_IADD(d, REG_ZERO, d);
992 store_reg_to_var_int(iptr->dst, d);
995 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
997 var_to_reg_int(s1, src->prev, REG_ITMP1);
998 var_to_reg_int(s2, src, REG_ITMP2);
999 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1001 store_reg_to_var_int(iptr->dst, d);
1004 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1005 /* val.i = constant */
1007 var_to_reg_int(s1, src, REG_ITMP1);
1008 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1009 M_SLL_IMM(s1, iptr->val.i & 0x3f, d);
1010 store_reg_to_var_int(iptr->dst, d);
1013 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1015 var_to_reg_int(s1, src->prev, REG_ITMP1);
1016 var_to_reg_int(s2, src, REG_ITMP2);
1017 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1019 store_reg_to_var_int(iptr->dst, d);
1022 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1023 /* val.i = constant */
1025 var_to_reg_int(s1, src, REG_ITMP1);
1026 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1027 M_SRA_IMM(s1, iptr->val.i & 0x3f, d);
1028 store_reg_to_var_int(iptr->dst, d);
1031 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1033 var_to_reg_int(s1, src->prev, REG_ITMP1);
1034 var_to_reg_int(s2, src, REG_ITMP2);
1035 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1037 store_reg_to_var_int(iptr->dst, d);
1040 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1041 /* val.i = constant */
1043 var_to_reg_int(s1, src, REG_ITMP1);
1044 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1045 M_SRL_IMM(s1, iptr->val.i & 0x3f, d);
1046 store_reg_to_var_int(iptr->dst, d);
1049 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1052 var_to_reg_int(s1, src->prev, REG_ITMP1);
1053 var_to_reg_int(s2, src, REG_ITMP2);
1054 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1056 store_reg_to_var_int(iptr->dst, d);
1059 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1060 /* val.i = constant */
1062 var_to_reg_int(s1, src, REG_ITMP1);
1063 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1064 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1065 M_AND_IMM(s1, iptr->val.i, d);
1066 } else if (iptr->val.i == 0xffff) {
1068 } else if (iptr->val.i == 0xffffff) {
1069 M_ZAPNOT_IMM(s1, 0x07, d);
1071 ICONST(REG_ITMP2, iptr->val.i);
1072 M_AND(s1, REG_ITMP2, d);
1074 store_reg_to_var_int(iptr->dst, d);
1077 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1078 /* val.i = constant */
1080 var_to_reg_int(s1, src, REG_ITMP1);
1081 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1083 M_MOV(s1, REG_ITMP1);
1086 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1087 M_AND_IMM(s1, iptr->val.i, d);
1089 M_ISUB(REG_ZERO, s1, d);
1090 M_AND_IMM(d, iptr->val.i, d);
1091 } else if (iptr->val.i == 0xffff) {
1094 M_ISUB(REG_ZERO, s1, d);
1096 } else if (iptr->val.i == 0xffffff) {
1097 M_ZAPNOT_IMM(s1, 0x07, d);
1099 M_ISUB(REG_ZERO, s1, d);
1100 M_ZAPNOT_IMM(d, 0x07, d);
1102 ICONST(REG_ITMP2, iptr->val.i);
1103 M_AND(s1, REG_ITMP2, d);
1105 M_ISUB(REG_ZERO, s1, d);
1106 M_AND(d, REG_ITMP2, d);
1108 M_ISUB(REG_ZERO, d, d);
1109 store_reg_to_var_int(iptr->dst, d);
1112 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1113 /* val.l = constant */
1115 var_to_reg_int(s1, src, REG_ITMP1);
1116 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1117 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1118 M_AND_IMM(s1, iptr->val.l, d);
1119 } else if (iptr->val.l == 0xffffL) {
1121 } else if (iptr->val.l == 0xffffffL) {
1122 M_ZAPNOT_IMM(s1, 0x07, d);
1123 } else if (iptr->val.l == 0xffffffffL) {
1125 } else if (iptr->val.l == 0xffffffffffL) {
1126 M_ZAPNOT_IMM(s1, 0x1f, d);
1127 } else if (iptr->val.l == 0xffffffffffffL) {
1128 M_ZAPNOT_IMM(s1, 0x3f, d);
1129 } else if (iptr->val.l == 0xffffffffffffffL) {
1130 M_ZAPNOT_IMM(s1, 0x7f, d);
1132 LCONST(REG_ITMP2, iptr->val.l);
1133 M_AND(s1, REG_ITMP2, d);
1135 store_reg_to_var_int(iptr->dst, d);
1138 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1139 /* val.l = constant */
1141 var_to_reg_int(s1, src, REG_ITMP1);
1142 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1144 M_MOV(s1, REG_ITMP1);
1147 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1148 M_AND_IMM(s1, iptr->val.l, d);
1150 M_LSUB(REG_ZERO, s1, d);
1151 M_AND_IMM(d, iptr->val.l, d);
1152 } else if (iptr->val.l == 0xffffL) {
1155 M_LSUB(REG_ZERO, s1, d);
1157 } else if (iptr->val.l == 0xffffffL) {
1158 M_ZAPNOT_IMM(s1, 0x07, d);
1160 M_LSUB(REG_ZERO, s1, d);
1161 M_ZAPNOT_IMM(d, 0x07, d);
1162 } else if (iptr->val.l == 0xffffffffL) {
1165 M_LSUB(REG_ZERO, s1, d);
1167 } else if (iptr->val.l == 0xffffffffffL) {
1168 M_ZAPNOT_IMM(s1, 0x1f, d);
1170 M_LSUB(REG_ZERO, s1, d);
1171 M_ZAPNOT_IMM(d, 0x1f, d);
1172 } else if (iptr->val.l == 0xffffffffffffL) {
1173 M_ZAPNOT_IMM(s1, 0x3f, d);
1175 M_LSUB(REG_ZERO, s1, d);
1176 M_ZAPNOT_IMM(d, 0x3f, d);
1177 } else if (iptr->val.l == 0xffffffffffffffL) {
1178 M_ZAPNOT_IMM(s1, 0x7f, d);
1180 M_LSUB(REG_ZERO, s1, d);
1181 M_ZAPNOT_IMM(d, 0x7f, d);
1183 LCONST(REG_ITMP2, iptr->val.l);
1184 M_AND(s1, REG_ITMP2, d);
1186 M_LSUB(REG_ZERO, s1, d);
1187 M_AND(d, REG_ITMP2, d);
1189 M_LSUB(REG_ZERO, d, d);
1190 store_reg_to_var_int(iptr->dst, d);
1193 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1196 var_to_reg_int(s1, src->prev, REG_ITMP1);
1197 var_to_reg_int(s2, src, REG_ITMP2);
1198 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1200 store_reg_to_var_int(iptr->dst, d);
1203 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1204 /* val.i = constant */
1206 var_to_reg_int(s1, src, REG_ITMP1);
1207 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1208 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1209 M_OR_IMM(s1, iptr->val.i, d);
1211 ICONST(REG_ITMP2, iptr->val.i);
1212 M_OR(s1, REG_ITMP2, d);
1214 store_reg_to_var_int(iptr->dst, d);
1217 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1218 /* val.l = constant */
1220 var_to_reg_int(s1, src, REG_ITMP1);
1221 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1222 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1223 M_OR_IMM(s1, iptr->val.l, d);
1225 LCONST(REG_ITMP2, iptr->val.l);
1226 M_OR(s1, REG_ITMP2, d);
1228 store_reg_to_var_int(iptr->dst, d);
1231 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1234 var_to_reg_int(s1, src->prev, REG_ITMP1);
1235 var_to_reg_int(s2, src, REG_ITMP2);
1236 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1238 store_reg_to_var_int(iptr->dst, d);
1241 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1242 /* val.i = constant */
1244 var_to_reg_int(s1, src, REG_ITMP1);
1245 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1246 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1247 M_XOR_IMM(s1, iptr->val.i, d);
1249 ICONST(REG_ITMP2, iptr->val.i);
1250 M_XOR(s1, REG_ITMP2, d);
1252 store_reg_to_var_int(iptr->dst, d);
1255 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1256 /* val.l = constant */
1258 var_to_reg_int(s1, src, REG_ITMP1);
1259 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1260 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1261 M_XOR_IMM(s1, iptr->val.l, d);
1263 LCONST(REG_ITMP2, iptr->val.l);
1264 M_XOR(s1, REG_ITMP2, d);
1266 store_reg_to_var_int(iptr->dst, d);
1270 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1272 var_to_reg_int(s1, src->prev, REG_ITMP1);
1273 var_to_reg_int(s2, src, REG_ITMP2);
1274 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1275 M_CMPLT(s1, s2, REG_ITMP3);
1276 M_CMPLT(s2, s1, REG_ITMP1);
1277 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1278 store_reg_to_var_int(iptr->dst, d);
1282 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1283 /* op1 = variable, val.i = constant */
1285 var = &(rd->locals[iptr->op1][TYPE_INT]);
1286 if (var->flags & INMEMORY) {
1288 M_LLD(s1, REG_SP, var->regoff * 8);
1291 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1292 M_IADD_IMM(s1, iptr->val.i, s1);
1293 } else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1294 M_ISUB_IMM(s1, (-iptr->val.i), s1);
1296 M_LDA (s1, s1, iptr->val.i);
1297 M_IADD(s1, REG_ZERO, s1);
1299 if (var->flags & INMEMORY)
1300 M_LST(s1, REG_SP, var->regoff * 8);
1304 /* floating operations ************************************************/
1306 case ICMD_FNEG: /* ..., value ==> ..., - value */
1308 var_to_reg_flt(s1, src, REG_FTMP1);
1309 d = reg_of_var(rd, iptr->dst, REG_FTMP2);
1311 store_reg_to_var_flt(iptr->dst, d);
1314 case ICMD_DNEG: /* ..., value ==> ..., - value */
1316 var_to_reg_flt(s1, src, REG_FTMP1);
1317 d = reg_of_var(rd, iptr->dst, REG_FTMP2);
1319 store_reg_to_var_flt(iptr->dst, d);
1322 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1324 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1325 var_to_reg_flt(s2, src, REG_FTMP2);
1326 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1330 if (d == s1 || d == s2) {
1331 M_FADDS(s1, s2, REG_FTMP3);
1333 M_FMOV(REG_FTMP3, d);
1339 store_reg_to_var_flt(iptr->dst, d);
1342 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1344 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1345 var_to_reg_flt(s2, src, REG_FTMP2);
1346 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1350 if (d == s1 || d == s2) {
1351 M_DADDS(s1, s2, REG_FTMP3);
1353 M_FMOV(REG_FTMP3, d);
1359 store_reg_to_var_flt(iptr->dst, d);
1362 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1364 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1365 var_to_reg_flt(s2, src, REG_FTMP2);
1366 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1370 if (d == s1 || d == s2) {
1371 M_FSUBS(s1, s2, REG_FTMP3);
1373 M_FMOV(REG_FTMP3, d);
1379 store_reg_to_var_flt(iptr->dst, d);
1382 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1384 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1385 var_to_reg_flt(s2, src, REG_FTMP2);
1386 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1390 if (d == s1 || d == s2) {
1391 M_DSUBS(s1, s2, REG_FTMP3);
1393 M_FMOV(REG_FTMP3, d);
1399 store_reg_to_var_flt(iptr->dst, d);
1402 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1404 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1405 var_to_reg_flt(s2, src, REG_FTMP2);
1406 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1410 if (d == s1 || d == s2) {
1411 M_FMULS(s1, s2, REG_FTMP3);
1413 M_FMOV(REG_FTMP3, d);
1419 store_reg_to_var_flt(iptr->dst, d);
1422 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1424 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1425 var_to_reg_flt(s2, src, REG_FTMP2);
1426 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1430 if (d == s1 || d == s2) {
1431 M_DMULS(s1, s2, REG_FTMP3);
1433 M_FMOV(REG_FTMP3, d);
1439 store_reg_to_var_flt(iptr->dst, d);
1442 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1444 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1445 var_to_reg_flt(s2, src, REG_FTMP2);
1446 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1450 if (d == s1 || d == s2) {
1451 M_FDIVS(s1, s2, REG_FTMP3);
1453 M_FMOV(REG_FTMP3, d);
1459 store_reg_to_var_flt(iptr->dst, d);
1462 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1464 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1465 var_to_reg_flt(s2, src, REG_FTMP2);
1466 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1470 if (d == s1 || d == s2) {
1471 M_DDIVS(s1, s2, REG_FTMP3);
1473 M_FMOV(REG_FTMP3, d);
1479 store_reg_to_var_flt(iptr->dst, d);
1482 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1484 var_to_reg_int(s1, src, REG_ITMP1);
1485 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1486 disp = dseg_adddouble(cd, 0.0);
1487 M_LST(s1, REG_PV, disp);
1488 M_DLD(d, REG_PV, disp);
1490 store_reg_to_var_flt(iptr->dst, d);
1493 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1495 var_to_reg_int(s1, src, REG_ITMP1);
1496 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1497 disp = dseg_adddouble(cd, 0.0);
1498 M_LST(s1, REG_PV, disp);
1499 M_DLD(d, REG_PV, disp);
1501 store_reg_to_var_flt(iptr->dst, d);
1504 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1506 var_to_reg_flt(s1, src, REG_FTMP1);
1507 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1508 disp = dseg_adddouble(cd, 0.0);
1509 M_CVTDL_C(s1, REG_FTMP2);
1510 M_CVTLI(REG_FTMP2, REG_FTMP3);
1511 M_DST(REG_FTMP3, REG_PV, disp);
1512 M_ILD(d, REG_PV, disp);
1513 store_reg_to_var_int(iptr->dst, d);
1516 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1518 var_to_reg_flt(s1, src, REG_FTMP1);
1519 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1520 disp = dseg_adddouble(cd, 0.0);
1521 M_CVTDL_C(s1, REG_FTMP2);
1522 M_DST(REG_FTMP2, REG_PV, disp);
1523 M_LLD(d, REG_PV, disp);
1524 store_reg_to_var_int(iptr->dst, d);
1527 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1529 var_to_reg_flt(s1, src, REG_FTMP1);
1530 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1533 store_reg_to_var_flt(iptr->dst, d);
1536 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1538 var_to_reg_flt(s1, src, REG_FTMP1);
1539 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1546 store_reg_to_var_flt(iptr->dst, d);
1549 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1551 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1552 var_to_reg_flt(s2, src, REG_FTMP2);
1553 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1555 M_LSUB_IMM(REG_ZERO, 1, d);
1556 M_FCMPEQ(s1, s2, REG_FTMP3);
1557 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1559 M_FCMPLT(s2, s1, REG_FTMP3);
1560 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1561 M_LADD_IMM(REG_ZERO, 1, d);
1563 M_LSUB_IMM(REG_ZERO, 1, d);
1564 M_FCMPEQS(s1, s2, REG_FTMP3);
1566 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1568 M_FCMPLTS(s2, s1, REG_FTMP3);
1570 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1571 M_LADD_IMM(REG_ZERO, 1, d);
1573 store_reg_to_var_int(iptr->dst, d);
1576 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1578 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1579 var_to_reg_flt(s2, src, REG_FTMP2);
1580 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1582 M_LADD_IMM(REG_ZERO, 1, d);
1583 M_FCMPEQ(s1, s2, REG_FTMP3);
1584 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1586 M_FCMPLT(s1, s2, REG_FTMP3);
1587 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1588 M_LSUB_IMM(REG_ZERO, 1, d);
1590 M_LADD_IMM(REG_ZERO, 1, d);
1591 M_FCMPEQS(s1, s2, REG_FTMP3);
1593 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1595 M_FCMPLTS(s1, s2, REG_FTMP3);
1597 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1598 M_LSUB_IMM(REG_ZERO, 1, d);
1600 store_reg_to_var_int(iptr->dst, d);
1604 /* memory operations **************************************************/
1606 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1608 var_to_reg_int(s1, src, REG_ITMP1);
1609 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1610 gen_nullptr_check(s1);
1611 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1612 store_reg_to_var_int(iptr->dst, d);
1615 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1617 var_to_reg_int(s1, src->prev, REG_ITMP1);
1618 var_to_reg_int(s2, src, REG_ITMP2);
1619 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1620 if (iptr->op1 == 0) {
1621 gen_nullptr_check(s1);
1624 if (has_ext_instr_set) {
1625 M_LADD (s2, s1, REG_ITMP1);
1626 M_BLDU (d, REG_ITMP1, OFFSET (java_bytearray, data[0]));
1629 M_LADD(s2, s1, REG_ITMP1);
1630 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1631 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
1632 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1633 M_SRA_IMM(d, 56, d);
1635 store_reg_to_var_int(iptr->dst, d);
1638 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1640 var_to_reg_int(s1, src->prev, REG_ITMP1);
1641 var_to_reg_int(s2, src, REG_ITMP2);
1642 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1643 if (iptr->op1 == 0) {
1644 gen_nullptr_check(s1);
1647 if (has_ext_instr_set) {
1648 M_LADD(s2, s1, REG_ITMP1);
1649 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1650 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1652 M_LADD (s2, s1, REG_ITMP1);
1653 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1654 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1655 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1656 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
1658 store_reg_to_var_int(iptr->dst, d);
1661 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1663 var_to_reg_int(s1, src->prev, REG_ITMP1);
1664 var_to_reg_int(s2, src, REG_ITMP2);
1665 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1666 if (iptr->op1 == 0) {
1667 gen_nullptr_check(s1);
1670 if (has_ext_instr_set) {
1671 M_LADD(s2, s1, REG_ITMP1);
1672 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1673 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1676 M_LADD(s2, s1, REG_ITMP1);
1677 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1678 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1679 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1680 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1681 M_SRA_IMM(d, 48, d);
1683 store_reg_to_var_int(iptr->dst, d);
1686 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1688 var_to_reg_int(s1, src->prev, REG_ITMP1);
1689 var_to_reg_int(s2, src, REG_ITMP2);
1690 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1691 if (iptr->op1 == 0) {
1692 gen_nullptr_check(s1);
1695 M_S4ADDQ(s2, s1, REG_ITMP1);
1696 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1697 store_reg_to_var_int(iptr->dst, d);
1700 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1702 var_to_reg_int(s1, src->prev, REG_ITMP1);
1703 var_to_reg_int(s2, src, REG_ITMP2);
1704 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1705 if (iptr->op1 == 0) {
1706 gen_nullptr_check(s1);
1709 M_S8ADDQ(s2, s1, REG_ITMP1);
1710 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1711 store_reg_to_var_int(iptr->dst, d);
1714 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1716 var_to_reg_int(s1, src->prev, REG_ITMP1);
1717 var_to_reg_int(s2, src, REG_ITMP2);
1718 d = reg_of_var(rd, iptr->dst, REG_FTMP2);
1719 if (iptr->op1 == 0) {
1720 gen_nullptr_check(s1);
1723 M_S4ADDQ(s2, s1, REG_ITMP1);
1724 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1725 store_reg_to_var_flt(iptr->dst, d);
1728 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1730 var_to_reg_int(s1, src->prev, REG_ITMP1);
1731 var_to_reg_int(s2, src, REG_ITMP2);
1732 d = reg_of_var(rd, iptr->dst, REG_FTMP2);
1733 if (iptr->op1 == 0) {
1734 gen_nullptr_check(s1);
1737 M_S8ADDQ(s2, s1, REG_ITMP1);
1738 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1739 store_reg_to_var_flt(iptr->dst, d);
1742 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1744 var_to_reg_int(s1, src->prev, REG_ITMP1);
1745 var_to_reg_int(s2, src, REG_ITMP2);
1746 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1747 if (iptr->op1 == 0) {
1748 gen_nullptr_check(s1);
1751 M_SAADDQ(s2, s1, REG_ITMP1);
1752 M_ALD(d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1753 store_reg_to_var_int(iptr->dst, d);
1757 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1759 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1760 var_to_reg_int(s2, src->prev, REG_ITMP2);
1761 if (iptr->op1 == 0) {
1762 gen_nullptr_check(s1);
1765 var_to_reg_int(s3, src, REG_ITMP3);
1766 if (has_ext_instr_set) {
1767 M_LADD(s2, s1, REG_ITMP1);
1768 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1770 M_LADD(s2, s1, REG_ITMP1);
1771 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1772 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1773 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
1774 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1775 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1776 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1780 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1782 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1783 var_to_reg_int(s2, src->prev, REG_ITMP2);
1784 if (iptr->op1 == 0) {
1785 gen_nullptr_check(s1);
1788 var_to_reg_int(s3, src, REG_ITMP3);
1789 if (has_ext_instr_set) {
1790 M_LADD(s2, s1, REG_ITMP1);
1791 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1792 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1794 M_LADD(s2, s1, REG_ITMP1);
1795 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1796 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1797 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1798 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1799 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1800 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1801 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1805 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1807 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1808 var_to_reg_int(s2, src->prev, REG_ITMP2);
1809 if (iptr->op1 == 0) {
1810 gen_nullptr_check(s1);
1813 var_to_reg_int(s3, src, REG_ITMP3);
1814 if (has_ext_instr_set) {
1815 M_LADD(s2, s1, REG_ITMP1);
1816 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1817 M_SST(s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1819 M_LADD(s2, s1, REG_ITMP1);
1820 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1821 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1822 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1823 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1824 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1825 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1826 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1830 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1832 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1833 var_to_reg_int(s2, src->prev, REG_ITMP2);
1834 if (iptr->op1 == 0) {
1835 gen_nullptr_check(s1);
1838 var_to_reg_int(s3, src, REG_ITMP3);
1839 M_S4ADDQ(s2, s1, REG_ITMP1);
1840 M_IST(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1843 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1845 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1846 var_to_reg_int(s2, src->prev, REG_ITMP2);
1847 if (iptr->op1 == 0) {
1848 gen_nullptr_check(s1);
1851 var_to_reg_int(s3, src, REG_ITMP3);
1852 M_S8ADDQ(s2, s1, REG_ITMP1);
1853 M_LST(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1856 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1858 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1859 var_to_reg_int(s2, src->prev, REG_ITMP2);
1860 if (iptr->op1 == 0) {
1861 gen_nullptr_check(s1);
1864 var_to_reg_flt(s3, src, REG_FTMP3);
1865 M_S4ADDQ(s2, s1, REG_ITMP1);
1866 M_FST(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1869 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1871 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1872 var_to_reg_int(s2, src->prev, REG_ITMP2);
1873 if (iptr->op1 == 0) {
1874 gen_nullptr_check(s1);
1877 var_to_reg_flt(s3, src, REG_FTMP3);
1878 M_S8ADDQ(s2, s1, REG_ITMP1);
1879 M_DST(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1882 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1884 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1885 var_to_reg_int(s2, src->prev, REG_ITMP2);
1886 if (iptr->op1 == 0) {
1887 gen_nullptr_check(s1);
1890 var_to_reg_int(s3, src, REG_ITMP3);
1892 M_MOV(s1, rd->argintregs[0]);
1893 M_MOV(s3, rd->argintregs[1]);
1894 disp = dseg_addaddress(cd, BUILTIN_canstore);
1895 M_ALD(REG_PV, REG_PV, disp);
1896 M_JSR(REG_RA, REG_PV);
1897 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
1898 M_LDA(REG_PV, REG_RA, -disp);
1900 M_BEQZ(REG_RESULT, 0);
1901 codegen_addxstorerefs(cd, mcodeptr);
1903 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1904 var_to_reg_int(s2, src->prev, REG_ITMP2);
1905 var_to_reg_int(s3, src, REG_ITMP3);
1906 M_SAADDQ(s2, s1, REG_ITMP1);
1907 M_AST(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1911 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1913 var_to_reg_int(s1, src->prev, REG_ITMP1);
1914 var_to_reg_int(s2, src, REG_ITMP2);
1915 if (iptr->op1 == 0) {
1916 gen_nullptr_check(s1);
1919 M_S4ADDQ(s2, s1, REG_ITMP1);
1920 M_IST(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1923 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1925 var_to_reg_int(s1, src->prev, REG_ITMP1);
1926 var_to_reg_int(s2, src, REG_ITMP2);
1927 if (iptr->op1 == 0) {
1928 gen_nullptr_check(s1);
1931 M_S8ADDQ(s2, s1, REG_ITMP1);
1932 M_LST(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1935 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1937 var_to_reg_int(s1, src->prev, REG_ITMP1);
1938 var_to_reg_int(s2, src, REG_ITMP2);
1939 if (iptr->op1 == 0) {
1940 gen_nullptr_check(s1);
1943 M_SAADDQ(s2, s1, REG_ITMP1);
1944 M_AST(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1947 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1949 var_to_reg_int(s1, src->prev, REG_ITMP1);
1950 var_to_reg_int(s2, src, REG_ITMP2);
1951 if (iptr->op1 == 0) {
1952 gen_nullptr_check(s1);
1955 if (has_ext_instr_set) {
1956 M_LADD(s2, s1, REG_ITMP1);
1957 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1960 M_LADD(s2, s1, REG_ITMP1);
1961 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1962 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1963 M_INSBL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1964 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1965 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1966 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1970 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1972 var_to_reg_int(s1, src->prev, REG_ITMP1);
1973 var_to_reg_int(s2, src, REG_ITMP2);
1974 if (iptr->op1 == 0) {
1975 gen_nullptr_check(s1);
1978 if (has_ext_instr_set) {
1979 M_LADD(s2, s1, REG_ITMP1);
1980 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1981 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1984 M_LADD(s2, s1, REG_ITMP1);
1985 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1986 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1987 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1988 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1989 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1990 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1991 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1995 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1997 var_to_reg_int(s1, src->prev, REG_ITMP1);
1998 var_to_reg_int(s2, src, REG_ITMP2);
1999 if (iptr->op1 == 0) {
2000 gen_nullptr_check(s1);
2003 if (has_ext_instr_set) {
2004 M_LADD(s2, s1, REG_ITMP1);
2005 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2006 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2009 M_LADD(s2, s1, REG_ITMP1);
2010 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2011 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2012 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2013 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2014 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2015 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2016 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2021 case ICMD_GETSTATIC: /* ... ==> ..., value */
2022 /* op1 = type, val.a = field address */
2025 disp = dseg_addaddress(cd, 0);
2027 codegen_addpatchref(cd, mcodeptr,
2028 PATCHER_get_putstatic,
2029 (unresolved_field *) iptr->target, disp);
2031 if (opt_showdisassemble)
2036 fieldinfo *fi = iptr->val.a;
2038 disp = dseg_addaddress(cd, &(fi->value));
2040 if (!fi->class->initialized) {
2041 codegen_addpatchref(cd, mcodeptr,
2042 PATCHER_clinit, fi->class, 0);
2044 if (opt_showdisassemble)
2049 M_ALD(REG_ITMP1, REG_PV, disp);
2050 switch (iptr->op1) {
2052 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2053 M_ILD(d, REG_ITMP1, 0);
2054 store_reg_to_var_int(iptr->dst, d);
2057 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2058 M_LLD(d, REG_ITMP1, 0);
2059 store_reg_to_var_int(iptr->dst, d);
2062 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2063 M_ALD(d, REG_ITMP1, 0);
2064 store_reg_to_var_int(iptr->dst, d);
2067 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2068 M_FLD(d, REG_ITMP1, 0);
2069 store_reg_to_var_flt(iptr->dst, d);
2072 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2073 M_DLD(d, REG_ITMP1, 0);
2074 store_reg_to_var_flt(iptr->dst, d);
2079 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2080 /* op1 = type, val.a = field address */
2083 disp = dseg_addaddress(cd, 0);
2085 codegen_addpatchref(cd, mcodeptr,
2086 PATCHER_get_putstatic,
2087 (unresolved_field *) iptr->target, disp);
2089 if (opt_showdisassemble)
2093 fieldinfo *fi = iptr->val.a;
2095 disp = dseg_addaddress(cd, &(fi->value));
2097 if (!fi->class->initialized) {
2098 codegen_addpatchref(cd, mcodeptr,
2099 PATCHER_clinit, fi->class, 0);
2101 if (opt_showdisassemble)
2106 M_ALD(REG_ITMP1, REG_PV, disp);
2107 switch (iptr->op1) {
2109 var_to_reg_int(s2, src, REG_ITMP2);
2110 M_IST(s2, REG_ITMP1, 0);
2113 var_to_reg_int(s2, src, REG_ITMP2);
2114 M_LST(s2, REG_ITMP1, 0);
2117 var_to_reg_int(s2, src, REG_ITMP2);
2118 M_AST(s2, REG_ITMP1, 0);
2121 var_to_reg_flt(s2, src, REG_FTMP2);
2122 M_FST(s2, REG_ITMP1, 0);
2125 var_to_reg_flt(s2, src, REG_FTMP2);
2126 M_DST(s2, REG_ITMP1, 0);
2131 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2132 /* val = value (in current instruction) */
2133 /* op1 = type, val.a = field address (in */
2134 /* following NOP) */
2136 if (!iptr[1].val.a) {
2137 disp = dseg_addaddress(cd, 0);
2139 codegen_addpatchref(cd, mcodeptr,
2140 PATCHER_get_putstatic,
2141 (unresolved_field *) iptr[1].target, disp);
2143 if (opt_showdisassemble)
2147 fieldinfo *fi = iptr[1].val.a;
2149 disp = dseg_addaddress(cd, &(fi->value));
2151 if (!fi->class->initialized) {
2152 codegen_addpatchref(cd, mcodeptr,
2153 PATCHER_clinit, fi->class, 0);
2155 if (opt_showdisassemble)
2160 M_ALD(REG_ITMP1, REG_PV, disp);
2161 switch (iptr->op1) {
2163 M_IST(REG_ZERO, REG_ITMP1, 0);
2166 M_LST(REG_ZERO, REG_ITMP1, 0);
2169 M_AST(REG_ZERO, REG_ITMP1, 0);
2172 M_FST(REG_ZERO, REG_ITMP1, 0);
2175 M_DST(REG_ZERO, REG_ITMP1, 0);
2181 case ICMD_GETFIELD: /* ... ==> ..., value */
2182 /* op1 = type, val.i = field offset */
2184 var_to_reg_int(s1, src, REG_ITMP1);
2185 gen_nullptr_check(s1);
2188 codegen_addpatchref(cd, mcodeptr,
2189 PATCHER_get_putfield,
2190 (unresolved_field *) iptr->target, 0);
2192 if (opt_showdisassemble)
2198 disp = ((fieldinfo *) (iptr->val.a))->offset;
2201 switch (iptr->op1) {
2203 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2205 store_reg_to_var_int(iptr->dst, d);
2208 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2210 store_reg_to_var_int(iptr->dst, d);
2213 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2215 store_reg_to_var_int(iptr->dst, d);
2218 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2220 store_reg_to_var_flt(iptr->dst, d);
2223 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2225 store_reg_to_var_flt(iptr->dst, d);
2230 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2231 /* op1 = type, val.a = field address */
2233 var_to_reg_int(s1, src->prev, REG_ITMP1);
2234 gen_nullptr_check(s1);
2236 if (!IS_FLT_DBL_TYPE(iptr->op1)) {
2237 var_to_reg_int(s2, src, REG_ITMP2);
2239 var_to_reg_flt(s2, src, REG_FTMP2);
2243 codegen_addpatchref(cd, mcodeptr,
2244 PATCHER_get_putfield,
2245 (unresolved_field *) iptr->target, 0);
2247 if (opt_showdisassemble)
2253 disp = ((fieldinfo *) (iptr->val.a))->offset;
2256 switch (iptr->op1) {
2258 M_IST(s2, s1, disp);
2261 M_LST(s2, s1, disp);
2264 M_AST(s2, s1, disp);
2267 M_FST(s2, s1, disp);
2270 M_DST(s2, s1, disp);
2275 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2276 /* val = value (in current instruction) */
2277 /* op1 = type, val.a = field address (in */
2278 /* following NOP) */
2280 var_to_reg_int(s1, src, REG_ITMP1);
2281 gen_nullptr_check(s1);
2283 if (!iptr[1].val.a) {
2284 codegen_addpatchref(cd, mcodeptr,
2285 PATCHER_get_putfield,
2286 (unresolved_field *) iptr[1].target, 0);
2288 if (opt_showdisassemble)
2294 disp = ((fieldinfo *) (iptr[1].val.a))->offset;
2297 switch (iptr[1].op1) {
2299 M_IST(REG_ZERO, s1, disp);
2302 M_LST(REG_ZERO, s1, disp);
2305 M_AST(REG_ZERO, s1, disp);
2308 M_FST(REG_ZERO, s1, disp);
2311 M_DST(REG_ZERO, s1, disp);
2317 /* branch operations **************************************************/
2319 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2321 var_to_reg_int(s1, src, REG_ITMP1);
2322 M_INTMOVE(s1, REG_ITMP1_XPTR);
2325 codegen_addpatchref(cd, mcodeptr,
2326 PATCHER_athrow_areturn,
2327 (unresolved_class *) iptr->val.a, 0);
2329 if (opt_showdisassemble)
2333 disp = dseg_addaddress(cd, asm_handle_exception);
2334 M_ALD(REG_ITMP2, REG_PV, disp);
2335 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2336 M_NOP; /* nop ensures that XPC is less than the end */
2337 /* of basic block */
2341 case ICMD_GOTO: /* ... ==> ... */
2342 /* op1 = target JavaVM pc */
2344 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2348 case ICMD_JSR: /* ... ==> ... */
2349 /* op1 = target JavaVM pc */
2351 M_BSR(REG_ITMP1, 0);
2352 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2355 case ICMD_RET: /* ... ==> ... */
2356 /* op1 = local variable */
2358 var = &(rd->locals[iptr->op1][TYPE_ADR]);
2359 if (var->flags & INMEMORY) {
2360 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2361 M_RET(REG_ZERO, REG_ITMP1);
2364 M_RET(REG_ZERO, var->regoff);
2368 case ICMD_IFNULL: /* ..., value ==> ... */
2369 /* op1 = target JavaVM pc */
2371 var_to_reg_int(s1, src, REG_ITMP1);
2373 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2376 case ICMD_IFNONNULL: /* ..., value ==> ... */
2377 /* op1 = target JavaVM pc */
2379 var_to_reg_int(s1, src, REG_ITMP1);
2381 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2384 case ICMD_IFEQ: /* ..., value ==> ... */
2385 /* op1 = target JavaVM pc, val.i = constant */
2387 var_to_reg_int(s1, src, REG_ITMP1);
2388 if (iptr->val.i == 0) {
2392 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2393 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2396 ICONST(REG_ITMP2, iptr->val.i);
2397 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2399 M_BNEZ(REG_ITMP1, 0);
2401 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2404 case ICMD_IFLT: /* ..., value ==> ... */
2405 /* op1 = target JavaVM pc, val.i = constant */
2407 var_to_reg_int(s1, src, REG_ITMP1);
2408 if (iptr->val.i == 0) {
2412 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2413 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2416 ICONST(REG_ITMP2, iptr->val.i);
2417 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2419 M_BNEZ(REG_ITMP1, 0);
2421 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2424 case ICMD_IFLE: /* ..., value ==> ... */
2425 /* op1 = target JavaVM pc, val.i = constant */
2427 var_to_reg_int(s1, src, REG_ITMP1);
2428 if (iptr->val.i == 0) {
2432 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2433 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2436 ICONST(REG_ITMP2, iptr->val.i);
2437 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2439 M_BNEZ(REG_ITMP1, 0);
2441 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2444 case ICMD_IFNE: /* ..., value ==> ... */
2445 /* op1 = target JavaVM pc, val.i = constant */
2447 var_to_reg_int(s1, src, REG_ITMP1);
2448 if (iptr->val.i == 0) {
2452 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2453 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2456 ICONST(REG_ITMP2, iptr->val.i);
2457 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2459 M_BEQZ(REG_ITMP1, 0);
2461 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2464 case ICMD_IFGT: /* ..., value ==> ... */
2465 /* op1 = target JavaVM pc, val.i = constant */
2467 var_to_reg_int(s1, src, REG_ITMP1);
2468 if (iptr->val.i == 0) {
2472 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2473 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2476 ICONST(REG_ITMP2, iptr->val.i);
2477 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2479 M_BEQZ(REG_ITMP1, 0);
2481 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2484 case ICMD_IFGE: /* ..., value ==> ... */
2485 /* op1 = target JavaVM pc, val.i = constant */
2487 var_to_reg_int(s1, src, REG_ITMP1);
2488 if (iptr->val.i == 0) {
2492 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2493 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2496 ICONST(REG_ITMP2, iptr->val.i);
2497 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2499 M_BEQZ(REG_ITMP1, 0);
2501 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2504 case ICMD_IF_LEQ: /* ..., value ==> ... */
2505 /* op1 = target JavaVM pc, val.l = constant */
2507 var_to_reg_int(s1, src, REG_ITMP1);
2508 if (iptr->val.l == 0) {
2512 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2513 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2516 LCONST(REG_ITMP2, iptr->val.l);
2517 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2519 M_BNEZ(REG_ITMP1, 0);
2521 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2524 case ICMD_IF_LLT: /* ..., value ==> ... */
2525 /* op1 = target JavaVM pc, val.l = constant */
2527 var_to_reg_int(s1, src, REG_ITMP1);
2528 if (iptr->val.l == 0) {
2532 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2533 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2536 LCONST(REG_ITMP2, iptr->val.l);
2537 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2539 M_BNEZ(REG_ITMP1, 0);
2541 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2544 case ICMD_IF_LLE: /* ..., value ==> ... */
2545 /* op1 = target JavaVM pc, val.l = constant */
2547 var_to_reg_int(s1, src, REG_ITMP1);
2548 if (iptr->val.l == 0) {
2552 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2553 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2556 LCONST(REG_ITMP2, iptr->val.l);
2557 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2559 M_BNEZ(REG_ITMP1, 0);
2561 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2564 case ICMD_IF_LNE: /* ..., value ==> ... */
2565 /* op1 = target JavaVM pc, val.l = constant */
2567 var_to_reg_int(s1, src, REG_ITMP1);
2568 if (iptr->val.l == 0) {
2572 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2573 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2576 LCONST(REG_ITMP2, iptr->val.l);
2577 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2579 M_BEQZ(REG_ITMP1, 0);
2581 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2584 case ICMD_IF_LGT: /* ..., value ==> ... */
2585 /* op1 = target JavaVM pc, val.l = constant */
2587 var_to_reg_int(s1, src, REG_ITMP1);
2588 if (iptr->val.l == 0) {
2592 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2593 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2596 LCONST(REG_ITMP2, iptr->val.l);
2597 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2599 M_BEQZ(REG_ITMP1, 0);
2601 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2604 case ICMD_IF_LGE: /* ..., value ==> ... */
2605 /* op1 = target JavaVM pc, val.l = constant */
2607 var_to_reg_int(s1, src, REG_ITMP1);
2608 if (iptr->val.l == 0) {
2612 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2613 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2616 LCONST(REG_ITMP2, iptr->val.l);
2617 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2619 M_BEQZ(REG_ITMP1, 0);
2621 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2624 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2625 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2626 case ICMD_IF_ACMPEQ:
2628 var_to_reg_int(s1, src->prev, REG_ITMP1);
2629 var_to_reg_int(s2, src, REG_ITMP2);
2630 M_CMPEQ(s1, s2, REG_ITMP1);
2631 M_BNEZ(REG_ITMP1, 0);
2632 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2635 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2636 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2637 case ICMD_IF_ACMPNE:
2639 var_to_reg_int(s1, src->prev, REG_ITMP1);
2640 var_to_reg_int(s2, src, REG_ITMP2);
2641 M_CMPEQ(s1, s2, REG_ITMP1);
2642 M_BEQZ(REG_ITMP1, 0);
2643 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2646 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2647 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2649 var_to_reg_int(s1, src->prev, REG_ITMP1);
2650 var_to_reg_int(s2, src, REG_ITMP2);
2651 M_CMPLT(s1, s2, REG_ITMP1);
2652 M_BNEZ(REG_ITMP1, 0);
2653 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2656 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2657 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2659 var_to_reg_int(s1, src->prev, REG_ITMP1);
2660 var_to_reg_int(s2, src, REG_ITMP2);
2661 M_CMPLE(s1, s2, REG_ITMP1);
2662 M_BEQZ(REG_ITMP1, 0);
2663 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2666 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2667 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2669 var_to_reg_int(s1, src->prev, REG_ITMP1);
2670 var_to_reg_int(s2, src, REG_ITMP2);
2671 M_CMPLE(s1, s2, REG_ITMP1);
2672 M_BNEZ(REG_ITMP1, 0);
2673 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2676 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2677 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2679 var_to_reg_int(s1, src->prev, REG_ITMP1);
2680 var_to_reg_int(s2, src, REG_ITMP2);
2681 M_CMPLT(s1, s2, REG_ITMP1);
2682 M_BEQZ(REG_ITMP1, 0);
2683 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2686 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2688 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2691 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2692 /* val.i = constant */
2694 var_to_reg_int(s1, src, REG_ITMP1);
2695 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2697 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2698 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2699 M_CMPEQ(s1, REG_ZERO, d);
2700 store_reg_to_var_int(iptr->dst, d);
2703 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2704 M_CMPEQ(s1, REG_ZERO, d);
2706 store_reg_to_var_int(iptr->dst, d);
2710 M_MOV(s1, REG_ITMP1);
2713 ICONST(d, iptr[1].val.i);
2715 if ((s3 >= 0) && (s3 <= 255)) {
2716 M_CMOVEQ_IMM(s1, s3, d);
2718 ICONST(REG_ITMP3, s3);
2719 M_CMOVEQ(s1, REG_ITMP3, d);
2721 store_reg_to_var_int(iptr->dst, d);
2724 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2725 /* val.i = constant */
2727 var_to_reg_int(s1, src, REG_ITMP1);
2728 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2730 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2731 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2732 M_CMPEQ(s1, REG_ZERO, d);
2733 store_reg_to_var_int(iptr->dst, d);
2736 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2737 M_CMPEQ(s1, REG_ZERO, d);
2739 store_reg_to_var_int(iptr->dst, d);
2743 M_MOV(s1, REG_ITMP1);
2746 ICONST(d, iptr[1].val.i);
2748 if ((s3 >= 0) && (s3 <= 255)) {
2749 M_CMOVNE_IMM(s1, s3, d);
2751 ICONST(REG_ITMP3, s3);
2752 M_CMOVNE(s1, REG_ITMP3, d);
2754 store_reg_to_var_int(iptr->dst, d);
2757 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2758 /* val.i = constant */
2760 var_to_reg_int(s1, src, REG_ITMP1);
2761 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2763 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2764 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2765 M_CMPLT(s1, REG_ZERO, d);
2766 store_reg_to_var_int(iptr->dst, d);
2769 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2770 M_CMPLE(REG_ZERO, s1, d);
2771 store_reg_to_var_int(iptr->dst, d);
2775 M_MOV(s1, REG_ITMP1);
2778 ICONST(d, iptr[1].val.i);
2780 if ((s3 >= 0) && (s3 <= 255)) {
2781 M_CMOVLT_IMM(s1, s3, d);
2783 ICONST(REG_ITMP3, s3);
2784 M_CMOVLT(s1, REG_ITMP3, d);
2786 store_reg_to_var_int(iptr->dst, d);
2789 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2790 /* val.i = constant */
2792 var_to_reg_int(s1, src, REG_ITMP1);
2793 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2795 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2796 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2797 M_CMPLE(REG_ZERO, s1, d);
2798 store_reg_to_var_int(iptr->dst, d);
2801 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2802 M_CMPLT(s1, REG_ZERO, d);
2803 store_reg_to_var_int(iptr->dst, d);
2807 M_MOV(s1, REG_ITMP1);
2810 ICONST(d, iptr[1].val.i);
2812 if ((s3 >= 0) && (s3 <= 255)) {
2813 M_CMOVGE_IMM(s1, s3, d);
2815 ICONST(REG_ITMP3, s3);
2816 M_CMOVGE(s1, REG_ITMP3, d);
2818 store_reg_to_var_int(iptr->dst, d);
2821 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2822 /* val.i = constant */
2824 var_to_reg_int(s1, src, REG_ITMP1);
2825 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2827 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2828 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2829 M_CMPLT(REG_ZERO, s1, d);
2830 store_reg_to_var_int(iptr->dst, d);
2833 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2834 M_CMPLE(s1, REG_ZERO, d);
2835 store_reg_to_var_int(iptr->dst, d);
2839 M_MOV(s1, REG_ITMP1);
2842 ICONST(d, iptr[1].val.i);
2844 if ((s3 >= 0) && (s3 <= 255)) {
2845 M_CMOVGT_IMM(s1, s3, d);
2847 ICONST(REG_ITMP3, s3);
2848 M_CMOVGT(s1, REG_ITMP3, d);
2850 store_reg_to_var_int(iptr->dst, d);
2853 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2854 /* val.i = constant */
2856 var_to_reg_int(s1, src, REG_ITMP1);
2857 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2859 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2860 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2861 M_CMPLE(s1, REG_ZERO, d);
2862 store_reg_to_var_int(iptr->dst, d);
2865 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2866 M_CMPLT(REG_ZERO, s1, d);
2867 store_reg_to_var_int(iptr->dst, d);
2871 M_MOV(s1, REG_ITMP1);
2874 ICONST(d, iptr[1].val.i);
2876 if ((s3 >= 0) && (s3 <= 255)) {
2877 M_CMOVLE_IMM(s1, s3, d);
2879 ICONST(REG_ITMP3, s3);
2880 M_CMOVLE(s1, REG_ITMP3, d);
2882 store_reg_to_var_int(iptr->dst, d);
2886 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2889 var_to_reg_int(s1, src, REG_RESULT);
2890 M_INTMOVE(s1, REG_RESULT);
2891 goto nowperformreturn;
2893 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2895 var_to_reg_int(s1, src, REG_RESULT);
2896 M_INTMOVE(s1, REG_RESULT);
2899 codegen_addpatchref(cd, mcodeptr,
2900 PATCHER_athrow_areturn,
2901 (unresolved_class *) iptr->val.a, 0);
2903 if (opt_showdisassemble)
2906 goto nowperformreturn;
2908 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2911 var_to_reg_flt(s1, src, REG_FRESULT);
2912 M_FLTMOVE(s1, REG_FRESULT);
2913 goto nowperformreturn;
2915 case ICMD_RETURN: /* ... ==> ... */
2921 p = parentargs_base;
2923 /* call trace function */
2926 M_LDA(REG_SP, REG_SP, -3 * 8);
2927 M_AST(REG_RA, REG_SP, 0 * 8);
2928 M_LST(REG_RESULT, REG_SP, 1 * 8);
2929 M_DST(REG_FRESULT, REG_SP, 2 * 8);
2931 disp = dseg_addaddress(cd, m);
2932 M_ALD(rd->argintregs[0], REG_PV, disp);
2933 M_MOV(REG_RESULT, rd->argintregs[1]);
2934 M_FLTMOVE(REG_FRESULT, rd->argfltregs[2]);
2935 M_FLTMOVE(REG_FRESULT, rd->argfltregs[3]);
2937 disp = dseg_addaddress(cd, (void *) builtin_displaymethodstop);
2938 M_ALD(REG_PV, REG_PV, disp);
2939 M_JSR(REG_RA, REG_PV);
2940 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
2941 M_LDA(REG_PV, REG_RA, -disp);
2943 M_DLD(REG_FRESULT, REG_SP, 2 * 8);
2944 M_LLD(REG_RESULT, REG_SP, 1 * 8);
2945 M_ALD(REG_RA, REG_SP, 0 * 8);
2946 M_LDA(REG_SP, REG_SP, 3 * 8);
2949 #if defined(USE_THREADS)
2950 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2951 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8);
2953 switch (iptr->opc) {
2957 M_LST(REG_RESULT, REG_SP, rd->memuse * 8);
2961 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2965 disp = dseg_addaddress(cd, BUILTIN_monitorexit);
2966 M_ALD(REG_PV, REG_PV, disp);
2967 M_JSR(REG_RA, REG_PV);
2968 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
2969 M_LDA(REG_PV, REG_RA, disp);
2971 switch (iptr->opc) {
2975 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2979 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2985 /* restore return address */
2987 if (!m->isleafmethod) {
2988 p--; M_LLD(REG_RA, REG_SP, p * 8);
2991 /* restore saved registers */
2993 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2994 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2996 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2997 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
3000 /* deallocate stack */
3002 if (parentargs_base) {
3003 M_LDA(REG_SP, REG_SP, parentargs_base * 8);
3006 M_RET(REG_ZERO, REG_RA);
3012 case ICMD_TABLESWITCH: /* ..., index ==> ... */
3017 tptr = (void **) iptr->target;
3019 s4ptr = iptr->val.a;
3020 l = s4ptr[1]; /* low */
3021 i = s4ptr[2]; /* high */
3023 var_to_reg_int(s1, src, REG_ITMP1);
3025 M_INTMOVE(s1, REG_ITMP1);
3026 } else if (l <= 32768) {
3027 M_LDA(REG_ITMP1, s1, -l);
3029 ICONST(REG_ITMP2, l);
3030 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
3037 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
3039 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
3040 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3042 M_BEQZ(REG_ITMP2, 0);
3043 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3045 /* build jump table top down and use address of lowest entry */
3047 /* s4ptr += 3 + i; */
3051 dseg_addtarget(cd, (basicblock *) tptr[0]);
3056 /* length of dataseg after last dseg_addtarget is used by load */
3058 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
3059 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
3060 M_JMP(REG_ZERO, REG_ITMP2);
3065 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3067 s4 i, l, val, *s4ptr;
3070 tptr = (void **) iptr->target;
3072 s4ptr = iptr->val.a;
3073 l = s4ptr[0]; /* default */
3074 i = s4ptr[1]; /* count */
3076 MCODECHECK((i<<2)+8);
3077 var_to_reg_int(s1, src, REG_ITMP1);
3083 if ((val >= 0) && (val <= 255)) {
3084 M_CMPEQ_IMM(s1, val, REG_ITMP2);
3086 if ((val >= -32768) && (val <= 32767)) {
3087 M_LDA(REG_ITMP2, REG_ZERO, val);
3089 disp = dseg_adds4(cd, val);
3090 M_ILD(REG_ITMP2, REG_PV, disp);
3092 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
3094 M_BNEZ(REG_ITMP2, 0);
3095 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3100 tptr = (void **) iptr->target;
3101 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3108 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
3109 /* op1 = arg count val.a = builtintable entry */
3115 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3116 /* op1 = arg count, val.a = method pointer */
3118 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3119 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
3120 case ICMD_INVOKEINTERFACE:
3125 unresolved_method *um = iptr->target;
3126 md = um->methodref->parseddesc.md;
3128 md = lm->parseddesc;
3132 s3 = md->paramcount;
3134 MCODECHECK((s3 << 1) + 64);
3136 /* copy arguments to registers or stack location */
3138 for (s3 = s3 - 1; s3 >= 0; s3--, src = src->prev) {
3139 if (src->varkind == ARGVAR)
3141 if (IS_INT_LNG_TYPE(src->type)) {
3142 if (!md->params[s3].inmemory) {
3143 s1 = rd->argintregs[md->params[s3].regoff];
3144 var_to_reg_int(d, src, s1);
3147 var_to_reg_int(d, src, REG_ITMP1);
3148 M_LST(d, REG_SP, md->params[s3].regoff * 8);
3152 if (!md->params[s3].inmemory) {
3153 s1 = rd->argfltregs[md->params[s3].regoff];
3154 var_to_reg_flt(d, src, s1);
3157 var_to_reg_flt(d, src, REG_FTMP1);
3158 M_DST(d, REG_SP, md->params[s3].regoff * 8);
3163 switch (iptr->opc) {
3165 disp = dseg_addaddress(cd, bte->fp);
3166 d = md->returntype.type;
3168 M_ALD(REG_PV, REG_PV, disp); /* Pointer to built-in-function */
3169 M_JSR(REG_RA, REG_PV);
3170 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3171 M_LDA(REG_PV, REG_RA, -disp);
3173 /* if op1 == true, we need to check for an exception */
3175 if (iptr->op1 == true) {
3176 M_BEQZ(REG_RESULT, 0);
3177 codegen_addxexceptionrefs(cd, mcodeptr);
3181 case ICMD_INVOKESPECIAL:
3182 M_BEQZ(rd->argintregs[0], 0);
3183 codegen_addxnullrefs(cd, mcodeptr);
3186 case ICMD_INVOKESTATIC:
3188 unresolved_method *um = iptr->target;
3190 disp = dseg_addaddress(cd, NULL);
3192 codegen_addpatchref(cd, mcodeptr,
3193 PATCHER_invokestatic_special, um, disp);
3195 if (opt_showdisassemble)
3198 d = um->methodref->parseddesc.md->returntype.type;
3201 disp = dseg_addaddress(cd, lm->stubroutine);
3202 d = lm->parseddesc->returntype.type;
3205 M_ALD(REG_PV, REG_PV, disp); /* method pointer in r27 */
3206 M_JSR(REG_RA, REG_PV);
3207 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3208 M_LDA(REG_PV, REG_RA, -disp);
3211 case ICMD_INVOKEVIRTUAL:
3212 gen_nullptr_check(rd->argintregs[0]);
3215 unresolved_method *um = iptr->target;
3217 codegen_addpatchref(cd, mcodeptr,
3218 PATCHER_invokevirtual, um, 0);
3220 if (opt_showdisassemble)
3224 d = um->methodref->parseddesc.md->returntype.type;
3227 s1 = OFFSET(vftbl_t, table[0]) +
3228 sizeof(methodptr) * lm->vftblindex;
3229 d = lm->parseddesc->returntype.type;
3232 M_ALD(REG_METHODPTR, rd->argintregs[0],
3233 OFFSET(java_objectheader, vftbl));
3234 M_ALD(REG_PV, REG_METHODPTR, s1);
3235 M_JSR(REG_RA, REG_PV);
3236 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3237 M_LDA(REG_PV, REG_RA, -disp);
3240 case ICMD_INVOKEINTERFACE:
3241 gen_nullptr_check(rd->argintregs[0]);
3244 unresolved_method *um = iptr->target;
3246 codegen_addpatchref(cd, mcodeptr,
3247 PATCHER_invokeinterface, um, 0);
3249 if (opt_showdisassemble)
3254 d = um->methodref->parseddesc.md->returntype.type;
3257 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3258 sizeof(methodptr*) * lm->class->index;
3260 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3262 d = lm->parseddesc->returntype.type;
3265 M_ALD(REG_METHODPTR, rd->argintregs[0],
3266 OFFSET(java_objectheader, vftbl));
3267 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3268 M_ALD(REG_PV, REG_METHODPTR, s2);
3269 M_JSR(REG_RA, REG_PV);
3270 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3271 M_LDA(REG_PV, REG_RA, -disp);
3275 /* d contains return type */
3277 if (d != TYPE_VOID) {
3278 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3279 s1 = reg_of_var(rd, iptr->dst, REG_RESULT);
3280 M_INTMOVE(REG_RESULT, s1);
3281 store_reg_to_var_int(iptr->dst, s1);
3283 s1 = reg_of_var(rd, iptr->dst, REG_FRESULT);
3284 M_FLTMOVE(REG_FRESULT, s1);
3285 store_reg_to_var_flt(iptr->dst, s1);
3291 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3293 /* op1: 0 == array, 1 == class */
3294 /* val.a: (classinfo*) superclass */
3296 /* superclass is an interface:
3298 * OK if ((sub == NULL) ||
3299 * (sub->vftbl->interfacetablelength > super->index) &&
3300 * (sub->vftbl->interfacetable[-super->index] != NULL));
3302 * superclass is a class:
3304 * OK if ((sub == NULL) || (0
3305 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3306 * super->vftbl->diffval));
3309 if (iptr->op1 == 1) {
3310 /* object type cast-check */
3313 vftbl_t *supervftbl;
3316 super = (classinfo *) iptr->val.a;
3323 superindex = super->index;
3324 supervftbl = super->vftbl;
3327 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3328 codegen_threadcritrestart(cd, (u1 *) mcodeptr - cd->mcodebase);
3330 var_to_reg_int(s1, src, REG_ITMP1);
3332 /* calculate interface checkcast code size */
3336 s2 += opt_showdisassemble ? 1 : 0;
3338 /* calculate class checkcast code size */
3340 s3 = 9 /* 8 + (s1 == REG_ITMP1) */;
3342 s3 += opt_showdisassemble ? 1 : 0;
3344 /* if class is not resolved, check which code to call */
3347 M_BEQZ(s1, 4 + (opt_showdisassemble ? 1 : 0) + s2 + 1 + s3);
3349 disp = dseg_adds4(cd, 0); /* super->flags */
3351 codegen_addpatchref(cd, mcodeptr,
3352 PATCHER_checkcast_instanceof_flags,
3353 (constant_classref *) iptr->target,
3356 if (opt_showdisassemble)
3359 M_ILD(REG_ITMP2, REG_PV, disp);
3360 disp = dseg_adds4(cd, ACC_INTERFACE);
3361 M_ILD(REG_ITMP3, REG_PV, disp);
3362 M_AND(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3363 M_BEQZ(REG_ITMP2, s2 + 1);
3366 /* interface checkcast code */
3368 if (!super || (super->flags & ACC_INTERFACE)) {
3373 codegen_addpatchref(cd, mcodeptr,
3374 PATCHER_checkcast_instanceof_interface,
3375 (constant_classref *) iptr->target,
3378 if (opt_showdisassemble)
3382 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3383 M_ILD(REG_ITMP3, REG_ITMP2,
3384 OFFSET(vftbl_t, interfacetablelength));
3385 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
3386 M_BLEZ(REG_ITMP3, 0);
3387 codegen_addxcastrefs(cd, mcodeptr);
3388 M_ALD(REG_ITMP3, REG_ITMP2,
3389 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
3390 superindex * sizeof(methodptr*)));
3391 M_BEQZ(REG_ITMP3, 0);
3392 codegen_addxcastrefs(cd, mcodeptr);
3398 /* class checkcast code */
3400 if (!super || !(super->flags & ACC_INTERFACE)) {
3401 disp = dseg_addaddress(cd, supervftbl);
3407 codegen_addpatchref(cd, mcodeptr,
3408 PATCHER_checkcast_instanceof_class,
3409 (constant_classref *) iptr->target,
3412 if (opt_showdisassemble)
3416 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3417 M_ALD(REG_ITMP3, REG_PV, disp);
3418 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3419 codegen_threadcritstart(cd, (u1 *) mcodeptr - cd->mcodebase);
3421 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3422 /* if (s1 != REG_ITMP1) { */
3423 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3424 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3425 /* #if defined(USE_THREADS) && defined(NATIVE_THREADS) */
3426 /* codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase); */
3428 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3431 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3432 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3433 M_ALD(REG_ITMP3, REG_PV, disp);
3434 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3435 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3436 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3439 M_CMPULE(REG_ITMP2, REG_ITMP3, REG_ITMP3);
3440 M_BEQZ(REG_ITMP3, 0);
3441 codegen_addxcastrefs(cd, mcodeptr);
3443 d = reg_of_var(rd, iptr->dst, s1);
3446 /* array type cast-check */
3448 var_to_reg_int(s1, src, rd->argintregs[0]);
3449 M_INTMOVE(s1, rd->argintregs[0]);
3451 disp = dseg_addaddress(cd, iptr->val.a);
3453 if (iptr->val.a == NULL) {
3454 codegen_addpatchref(cd, mcodeptr,
3455 PATCHER_builtin_arraycheckcast,
3456 (constant_classref *) iptr->target,
3459 if (opt_showdisassemble)
3463 M_ALD(rd->argintregs[1], REG_PV, disp);
3464 disp = dseg_addaddress(cd, BUILTIN_arraycheckcast);
3465 M_ALD(REG_PV, REG_PV, disp);
3466 M_JSR(REG_RA, REG_PV);
3467 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3468 M_LDA(REG_PV, REG_RA, -disp);
3470 M_BEQZ(REG_RESULT, 0);
3471 codegen_addxcastrefs(cd, mcodeptr);
3473 var_to_reg_int(s1, src, REG_ITMP1);
3474 d = reg_of_var(rd, iptr->dst, s1);
3477 store_reg_to_var_int(iptr->dst, d);
3480 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3482 /* op1: 0 == array, 1 == class */
3483 /* val.a: (classinfo*) superclass */
3485 /* superclass is an interface:
3487 * return (sub != NULL) &&
3488 * (sub->vftbl->interfacetablelength > super->index) &&
3489 * (sub->vftbl->interfacetable[-super->index] != NULL);
3491 * superclass is a class:
3493 * return ((sub != NULL) && (0
3494 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3495 * super->vftbl->diffvall));
3500 vftbl_t *supervftbl;
3503 super = (classinfo *) iptr->val.a;
3510 superindex = super->index;
3511 supervftbl = super->vftbl;
3514 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3515 codegen_threadcritrestart(cd, (u1 *) mcodeptr - cd->mcodebase);
3517 var_to_reg_int(s1, src, REG_ITMP1);
3518 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
3520 M_MOV(s1, REG_ITMP1);
3524 /* calculate interface instanceof code size */
3528 s2 += (d == REG_ITMP2 ? 1 : 0) + (opt_showdisassemble ? 1 : 0);
3530 /* calculate class instanceof code size */
3534 s3 += (opt_showdisassemble ? 1 : 0);
3536 /* if class is not resolved, check which code to call */
3540 M_BEQZ(s1, 4 + (opt_showdisassemble ? 1 : 0) + s2 + 1 + s3);
3542 disp = dseg_adds4(cd, 0); /* super->flags */
3544 codegen_addpatchref(cd, mcodeptr,
3545 PATCHER_checkcast_instanceof_flags,
3546 (constant_classref *) iptr->target, disp);
3548 if (opt_showdisassemble)
3551 M_ILD(REG_ITMP3, REG_PV, disp);
3553 disp = dseg_adds4(cd, ACC_INTERFACE);
3554 M_ILD(REG_ITMP2, REG_PV, disp);
3555 M_AND(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3556 M_BEQZ(REG_ITMP3, s2 + 1);
3559 /* interface instanceof code */
3561 if (!super || (super->flags & ACC_INTERFACE)) {
3567 /* If d == REG_ITMP2, then it's destroyed in check code */
3572 codegen_addpatchref(cd, mcodeptr,
3573 PATCHER_checkcast_instanceof_interface,
3574 (constant_classref *) iptr->target, 0);
3576 if (opt_showdisassemble)
3580 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3581 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3582 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
3583 M_BLEZ(REG_ITMP3, 2);
3584 M_ALD(REG_ITMP1, REG_ITMP1,
3585 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
3586 superindex * sizeof(methodptr*)));
3587 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3593 /* class instanceof code */
3595 if (!super || !(super->flags & ACC_INTERFACE)) {
3596 disp = dseg_addaddress(cd, supervftbl);
3603 codegen_addpatchref(cd, mcodeptr,
3604 PATCHER_checkcast_instanceof_class,
3605 (constant_classref *) iptr->target,
3608 if (opt_showdisassemble)
3612 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3613 M_ALD(REG_ITMP2, REG_PV, disp);
3614 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3615 codegen_threadcritstart(cd, (u1 *) mcodeptr - cd->mcodebase);
3617 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3618 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3619 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3620 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3621 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3623 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3624 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3626 store_reg_to_var_int(iptr->dst, d);
3630 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3631 /* op1 = dimension, val.a = array descriptor */
3633 /* check for negative sizes and copy sizes to stack if necessary */
3635 MCODECHECK((iptr->op1 << 1) + 64);
3637 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3638 /* copy SAVEDVAR sizes to stack */
3640 if (src->varkind != ARGVAR) {
3641 var_to_reg_int(s2, src, REG_ITMP1);
3642 M_LST(s2, REG_SP, s1 * 8);
3646 /* a0 = dimension count */
3648 ICONST(rd->argintregs[0], iptr->op1);
3650 /* is patcher function set? */
3653 disp = dseg_addaddress(cd, 0);
3655 codegen_addpatchref(cd, mcodeptr,
3656 (functionptr) iptr->target, iptr->val.a,
3659 if (opt_showdisassemble)
3663 disp = dseg_addaddress(cd, iptr->val.a);
3666 /* a1 = arraydescriptor */
3668 M_ALD(rd->argintregs[1], REG_PV, disp);
3670 /* a2 = pointer to dimensions = stack pointer */
3672 M_INTMOVE(REG_SP, rd->argintregs[2]);
3674 disp = dseg_addaddress(cd, (void *) BUILTIN_multianewarray);
3675 M_ALD(REG_PV, REG_PV, disp);
3676 M_JSR(REG_RA, REG_PV);
3677 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3678 M_LDA(REG_PV, REG_RA, -disp);
3680 /* check for exception before result assignment */
3682 M_BEQZ(REG_RESULT, 0);
3683 codegen_addxexceptionrefs(cd, mcodeptr);
3685 d = reg_of_var(rd, iptr->dst, REG_RESULT);
3686 M_INTMOVE(REG_RESULT, d);
3687 store_reg_to_var_int(iptr->dst, d);
3692 new_internalerror("Unknown ICMD %d", iptr->opc);
3696 } /* for instruction */
3698 /* copy values to interface registers */
3700 src = bptr->outstack;
3701 len = bptr->outdepth;
3708 if ((src->varkind != STACKVAR)) {
3710 if (IS_FLT_DBL_TYPE(s2)) {
3711 var_to_reg_flt(s1, src, REG_FTMP1);
3712 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3713 M_FLTMOVE(s1,rd->interfaces[len][s2].regoff);
3716 M_DST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3720 var_to_reg_int(s1, src, REG_ITMP1);
3721 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3722 M_INTMOVE(s1,rd->interfaces[len][s2].regoff);
3725 M_LST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3731 } /* if (bptr -> flags >= BBREACHED) */
3732 } /* for basic block */
3734 codegen_createlinenumbertable(cd);
3738 s4 *xcodeptr = NULL;
3741 /* generate ArithmeticException stubs */
3743 for (bref = cd->xdivrefs; bref != NULL; bref = bref->next) {
3744 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3746 (u1 *) mcodeptr - cd->mcodebase);
3750 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3752 if (xcodeptr != NULL) {
3753 disp = xcodeptr - mcodeptr - 1;
3757 xcodeptr = mcodeptr;
3759 M_MOV(REG_PV, rd->argintregs[0]);
3760 M_MOV(REG_SP, rd->argintregs[1]);
3761 M_ALD(rd->argintregs[2],
3762 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3763 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3765 M_LDA(REG_SP, REG_SP, -1 * 8);
3766 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3768 disp = dseg_addaddress(cd, stacktrace_inline_arithmeticexception);
3769 M_ALD(REG_PV, REG_PV, disp);
3770 M_JSR(REG_RA, REG_PV);
3771 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3772 M_LDA(REG_PV, REG_RA, -disp);
3774 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3776 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3777 M_LDA(REG_SP, REG_SP, 1 * 8);
3779 disp = dseg_addaddress(cd, asm_handle_exception);
3780 M_ALD(REG_ITMP3, REG_PV, disp);
3781 M_JMP(REG_ZERO, REG_ITMP3);
3785 /* generate ArrayIndexOutOfBoundsException stubs */
3789 for (bref = cd->xboundrefs; bref != NULL; bref = bref->next) {
3790 gen_resolvebranch((u1*) cd->mcodebase + bref->branchpos,
3792 (u1*) mcodeptr - cd->mcodebase);
3796 /* move index register into REG_ITMP1 */
3798 M_MOV(bref->reg, REG_ITMP1);
3799 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3801 if (xcodeptr != NULL) {
3802 disp = xcodeptr - mcodeptr - 1;
3806 xcodeptr = mcodeptr;
3808 M_MOV(REG_PV, rd->argintregs[0]);
3809 M_MOV(REG_SP, rd->argintregs[1]);
3811 if (m->isleafmethod)
3812 M_MOV(REG_RA, rd->argintregs[2]);
3814 M_ALD(rd->argintregs[2],
3815 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3817 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3818 M_MOV(REG_ITMP1, rd->argintregs[4]);
3820 M_LDA(REG_SP, REG_SP, -2 * 8);
3821 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3823 if (m->isleafmethod)
3824 M_AST(REG_RA, REG_SP, 1 * 8);
3826 disp = dseg_addaddress(cd, stacktrace_inline_arrayindexoutofboundsexception);
3827 M_ALD(REG_PV, REG_PV, disp);
3828 M_JSR(REG_RA, REG_PV);
3829 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3830 M_LDA(REG_PV, REG_RA, -disp);
3832 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3834 if (m->isleafmethod)
3835 M_ALD(REG_RA, REG_SP, 1 * 8);
3837 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3838 M_LDA(REG_SP, REG_SP, 2 * 8);
3840 disp = dseg_addaddress(cd, asm_handle_exception);
3841 M_ALD(REG_ITMP3, REG_PV, disp);
3842 M_JMP(REG_ZERO, REG_ITMP3);
3846 /* generate ArrayStoreException stubs */
3850 for (bref = cd->xstorerefs; bref != NULL; bref = bref->next) {
3851 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3853 (u1 *) mcodeptr - cd->mcodebase);
3857 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3859 if (xcodeptr != NULL) {
3860 disp = xcodeptr - mcodeptr - 1;
3864 xcodeptr = mcodeptr;
3866 M_MOV(REG_PV, rd->argintregs[0]);
3867 M_MOV(REG_SP, rd->argintregs[1]);
3868 M_ALD(rd->argintregs[2],
3869 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3870 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3872 M_LDA(REG_SP, REG_SP, -1 * 8);
3873 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3875 disp = dseg_addaddress(cd, stacktrace_inline_arraystoreexception);
3876 M_ALD(REG_PV, REG_PV, disp);
3877 M_JSR(REG_RA, REG_PV);
3878 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3879 M_LDA(REG_PV, REG_RA, -disp);
3881 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3883 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3884 M_LDA(REG_SP, REG_SP, 1 * 8);
3886 disp = dseg_addaddress(cd, asm_handle_exception);
3887 M_ALD(REG_ITMP3, REG_PV, disp);
3888 M_JMP(REG_ZERO, REG_ITMP3);
3892 /* generate ClassCastException stubs */
3896 for (bref = cd->xcastrefs; bref != NULL; bref = bref->next) {
3897 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3899 (u1 *) mcodeptr - cd->mcodebase);
3903 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3905 if (xcodeptr != NULL) {
3906 disp = xcodeptr - mcodeptr - 1;
3910 xcodeptr = mcodeptr;
3912 M_MOV(REG_PV, rd->argintregs[0]);
3913 M_MOV(REG_SP, rd->argintregs[1]);
3915 if (m->isleafmethod)
3916 M_MOV(REG_RA, rd->argintregs[2]);
3918 M_ALD(rd->argintregs[2],
3919 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3921 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3923 M_LDA(REG_SP, REG_SP, -2 * 8);
3924 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3926 if (m->isleafmethod)
3927 M_AST(REG_RA, REG_SP, 1 * 8);
3929 disp = dseg_addaddress(cd, stacktrace_inline_classcastexception);
3930 M_ALD(REG_PV, REG_PV, disp);
3931 M_JSR(REG_RA, REG_PV);
3932 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3933 M_LDA(REG_PV, REG_RA, -disp);
3935 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3937 if (m->isleafmethod)
3938 M_ALD(REG_RA, REG_SP, 1 * 8);
3940 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3941 M_LDA(REG_SP, REG_SP, 2 * 8);
3943 disp = dseg_addaddress(cd, asm_handle_exception);
3944 M_ALD(REG_ITMP3, REG_PV, disp);
3945 M_JMP(REG_ZERO, REG_ITMP3);
3949 /* generate NullPointerException stubs */
3953 for (bref = cd->xnullrefs; bref != NULL; bref = bref->next) {
3954 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3956 (u1 *) mcodeptr - cd->mcodebase);
3960 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3962 if (xcodeptr != NULL) {
3963 disp = xcodeptr - mcodeptr - 1;
3967 xcodeptr = mcodeptr;
3969 M_MOV(REG_PV, rd->argintregs[0]);
3970 M_MOV(REG_SP, rd->argintregs[1]);
3972 if (m->isleafmethod)
3973 M_MOV(REG_RA, rd->argintregs[2]);
3975 M_ALD(rd->argintregs[2],
3976 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3978 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3980 M_LDA(REG_SP, REG_SP, -2 * 8);
3981 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3983 if (m->isleafmethod)
3984 M_AST(REG_RA, REG_SP, 1 * 8);
3986 disp = dseg_addaddress(cd, stacktrace_inline_nullpointerexception);
3987 M_ALD(REG_PV, REG_PV, disp);
3988 M_JSR(REG_RA, REG_PV);
3989 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3990 M_LDA(REG_PV, REG_RA, -disp);
3992 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3994 if (m->isleafmethod)
3995 M_ALD(REG_RA, REG_SP, 1 * 8);
3997 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3998 M_LDA(REG_SP, REG_SP, 2 * 8);
4000 disp = dseg_addaddress(cd, asm_handle_exception);
4001 M_ALD(REG_ITMP3, REG_PV, disp);
4002 M_JMP(REG_ZERO, REG_ITMP3);
4006 /* generate exception check stubs */
4010 for (bref = cd->xexceptionrefs; bref != NULL; bref = bref->next) {
4011 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
4013 (u1 *) mcodeptr - cd->mcodebase);
4017 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
4019 if (xcodeptr != NULL) {
4020 disp = xcodeptr - mcodeptr - 1;
4024 xcodeptr = mcodeptr;
4026 M_MOV(REG_PV, rd->argintregs[0]);
4027 M_MOV(REG_SP, rd->argintregs[1]);
4028 M_ALD(rd->argintregs[2],
4029 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
4030 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
4032 M_LDA(REG_SP, REG_SP, -1 * 8);
4033 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
4035 disp = dseg_addaddress(cd, stacktrace_inline_fillInStackTrace);
4036 M_ALD(REG_PV, REG_PV, disp);
4037 M_JSR(REG_RA, REG_PV);
4038 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4039 M_LDA(REG_PV, REG_RA, -disp);
4041 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
4043 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
4044 M_LDA(REG_SP, REG_SP, 1 * 8);
4046 disp = dseg_addaddress(cd, asm_handle_exception);
4047 M_ALD(REG_ITMP3, REG_PV, disp);
4048 M_JMP(REG_ZERO, REG_ITMP3);
4052 /* generate patcher stub call code */
4059 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
4060 /* check code segment size */
4064 /* Get machine code which is patched back in later. The call is */
4065 /* 1 instruction word long. */
4067 xcodeptr = (s4 *) (cd->mcodebase + pref->branchpos);
4070 /* patch in the call to call the following code (done at compile */
4073 tmpmcodeptr = mcodeptr; /* save current mcodeptr */
4074 mcodeptr = xcodeptr; /* set mcodeptr to patch position */
4076 M_BSR(REG_ITMP3, tmpmcodeptr - (xcodeptr + 1));
4078 mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
4080 /* create stack frame */
4082 M_LSUB_IMM(REG_SP, 6 * 8, REG_SP);
4084 /* move return address onto stack */
4086 M_AST(REG_ITMP3, REG_SP, 5 * 8);
4088 /* move pointer to java_objectheader onto stack */
4090 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4091 /* create a virtual java_objectheader */
4093 (void) dseg_addaddress(cd, get_dummyLR()); /* monitorPtr */
4094 disp = dseg_addaddress(cd, NULL); /* vftbl */
4096 M_LDA(REG_ITMP3, REG_PV, disp);
4097 M_AST(REG_ITMP3, REG_SP, 4 * 8);
4102 /* move machine code onto stack */
4104 disp = dseg_adds4(cd, mcode);
4105 M_ILD(REG_ITMP3, REG_PV, disp);
4106 M_IST(REG_ITMP3, REG_SP, 3 * 8);
4108 /* move class/method/field reference onto stack */
4110 disp = dseg_addaddress(cd, pref->ref);
4111 M_ALD(REG_ITMP3, REG_PV, disp);
4112 M_AST(REG_ITMP3, REG_SP, 2 * 8);
4114 /* move data segment displacement onto stack */
4116 disp = dseg_adds4(cd, pref->disp);
4117 M_ILD(REG_ITMP3, REG_PV, disp);
4118 M_IST(REG_ITMP3, REG_SP, 1 * 8);
4120 /* move patcher function pointer onto stack */
4122 disp = dseg_addaddress(cd, pref->patcher);
4123 M_ALD(REG_ITMP3, REG_PV, disp);
4124 M_AST(REG_ITMP3, REG_SP, 0 * 8);
4126 disp = dseg_addaddress(cd, asm_wrapper_patcher);
4127 M_ALD(REG_ITMP3, REG_PV, disp);
4128 M_JMP(REG_ZERO, REG_ITMP3);
4133 codegen_finish(m, cd, (s4) ((u1 *) mcodeptr - cd->mcodebase));
4135 /* everything's ok */
4141 /* createcompilerstub **********************************************************
4143 Creates a stub routine which calls the compiler.
4145 *******************************************************************************/
4147 #define COMPSTUBSIZE 3
4149 functionptr createcompilerstub(methodinfo *m)
4151 u8 *s = CNEW(u8, COMPSTUBSIZE); /* memory to hold the stub */
4152 s4 *mcodeptr = (s4 *) s; /* code generation pointer */
4154 /* code for the stub */
4155 M_ALD(REG_PV, REG_PV, 16); /* load pointer to the compiler */
4156 M_JMP(0, REG_PV); /* jump to the compiler, return address
4157 in reg 0 is used as method pointer */
4158 s[1] = (ptrint) m; /* literals to be adressed */
4159 s[2] = (ptrint) asm_call_jit_compiler; /* jump directly via PV from above */
4161 #if defined(STATISTICS)
4163 count_cstub_len += COMPSTUBSIZE * 8;
4166 return (functionptr) s;
4170 /* createnativestub ************************************************************
4172 Creates a stub routine which calls a native method.
4174 *******************************************************************************/
4176 functionptr createnativestub(functionptr f, methodinfo *m, codegendata *cd,
4177 registerdata *rd, methoddesc *nmd)
4179 s4 *mcodeptr; /* code generation pointer */
4180 s4 stackframesize; /* size of stackframe if needed */
4183 s4 i, j; /* count variables */
4186 s4 funcdisp; /* displacement of the function */
4188 /* initialize variables */
4191 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
4194 /* calculate stack frame size */
4197 1 + /* return address */
4198 sizeof(stackframeinfo) / SIZEOF_VOID_P +
4199 sizeof(localref_table) / SIZEOF_VOID_P +
4200 1 + /* methodinfo for call trace */
4201 (md->paramcount > INT_ARG_CNT ? INT_ARG_CNT : md->paramcount) +
4205 /* create method header */
4207 (void) dseg_addaddress(cd, m); /* MethodPointer */
4208 (void) dseg_adds4(cd, stackframesize * 8); /* FrameSize */
4209 (void) dseg_adds4(cd, 0); /* IsSync */
4210 (void) dseg_adds4(cd, 0); /* IsLeaf */
4211 (void) dseg_adds4(cd, 0); /* IntSave */
4212 (void) dseg_adds4(cd, 0); /* FltSave */
4213 (void) dseg_addlinenumbertablesize(cd);
4214 (void) dseg_adds4(cd, 0); /* ExTableSize */
4217 /* initialize mcode variables */
4219 mcodeptr = (s4 *) cd->mcodebase;
4220 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
4223 /* generate stub code */
4225 M_LDA(REG_SP, REG_SP, -stackframesize * 8);
4226 M_AST(REG_RA, REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
4229 /* call trace function */
4232 /* save integer argument registers */
4234 for (i = 0, j = 1; i < md->paramcount && i < INT_ARG_CNT; i++) {
4235 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4236 M_LST(rd->argintregs[i], REG_SP, j * 8);
4241 /* save and copy float arguments into integer registers */
4243 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4244 t = md->paramtypes[i].type;
4246 if (IS_FLT_DBL_TYPE(t)) {
4247 if (IS_2_WORD_TYPE(t)) {
4248 M_DST(rd->argfltregs[i], REG_SP, j * 8);
4249 M_LLD(rd->argintregs[i], REG_SP, j * 8);
4251 M_FST(rd->argfltregs[i], REG_SP, j * 8);
4252 M_ILD(rd->argintregs[i], REG_SP, j * 8);
4258 disp = dseg_addaddress(cd, m);
4259 M_ALD(REG_ITMP1, REG_PV, disp);
4260 M_AST(REG_ITMP1, REG_SP, 0 * 8);
4261 disp = dseg_addaddress(cd, builtin_trace_args);
4262 M_ALD(REG_PV, REG_PV, disp);
4263 M_JSR(REG_RA, REG_PV);
4264 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4265 M_LDA(REG_PV, REG_RA, -disp);
4267 for (i = 0, j = 1; i < md->paramcount && i < INT_ARG_CNT; i++) {
4268 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4269 M_LLD(rd->argintregs[i], REG_SP, j * 8);
4274 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4275 t = md->paramtypes[i].type;
4277 if (IS_FLT_DBL_TYPE(t)) {
4278 if (IS_2_WORD_TYPE(t)) {
4279 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
4281 M_FLD(rd->argfltregs[i], REG_SP, j * 8);
4288 /* get function address (this must happen before the stackframeinfo) */
4290 funcdisp = dseg_addaddress(cd, f);
4292 #if !defined(ENABLE_STATICVM)
4294 codegen_addpatchref(cd, mcodeptr, PATCHER_resolve_native, m, funcdisp);
4296 if (opt_showdisassemble)
4301 /* save integer and float argument registers */
4303 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
4304 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4305 M_LST(rd->argintregs[i], REG_SP, j * 8);
4310 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4311 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
4312 M_DST(rd->argfltregs[i], REG_SP, j * 8);
4317 /* prepare data structures for native function call */
4319 M_LDA(rd->argintregs[0], REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
4320 M_MOV(REG_PV, rd->argintregs[1]);
4321 M_LDA(rd->argintregs[2], REG_SP, stackframesize * 8);
4322 M_ALD(rd->argintregs[3], REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
4323 disp = dseg_addaddress(cd, codegen_start_native_call);
4324 M_ALD(REG_PV, REG_PV, disp);
4325 M_JSR(REG_RA, REG_PV);
4326 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4327 M_LDA(REG_PV, REG_RA, -disp);
4329 /* restore integer and float argument registers */
4331 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
4332 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4333 M_LLD(rd->argintregs[i], REG_SP, j * 8);
4338 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4339 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
4340 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
4345 /* copy or spill arguments to new locations */
4347 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
4348 t = md->paramtypes[i].type;
4350 if (IS_INT_LNG_TYPE(t)) {
4351 if (!md->params[i].inmemory) {
4352 s1 = rd->argintregs[md->params[i].regoff];
4354 if (!nmd->params[j].inmemory) {
4355 s2 = rd->argintregs[nmd->params[j].regoff];
4359 s2 = nmd->params[j].regoff;
4360 M_LST(s1, REG_SP, s2 * 8);
4364 s1 = md->params[i].regoff + stackframesize;
4365 s2 = nmd->params[j].regoff;
4366 M_LLD(REG_ITMP1, REG_SP, s1 * 8);
4367 M_LST(REG_ITMP1, REG_SP, s2 * 8);
4371 if (!md->params[i].inmemory) {
4372 s1 = rd->argfltregs[md->params[i].regoff];
4374 if (!nmd->params[j].inmemory) {
4375 s2 = rd->argfltregs[nmd->params[j].regoff];
4379 s2 = nmd->params[j].regoff;
4380 if (IS_2_WORD_TYPE(t))
4381 M_DST(s1, REG_SP, s2 * 8);
4383 M_FST(s1, REG_SP, s2 * 8);
4387 s1 = md->params[i].regoff + stackframesize;
4388 s2 = nmd->params[j].regoff;
4389 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
4390 if (IS_2_WORD_TYPE(t))
4391 M_DST(REG_FTMP1, REG_SP, s2 * 8);
4393 M_FST(REG_FTMP1, REG_SP, s2 * 8);
4398 /* put class into second argument register */
4400 if (m->flags & ACC_STATIC) {
4401 disp = dseg_addaddress(cd, m->class);
4402 M_ALD(rd->argintregs[1], REG_PV, disp);
4405 /* put env into first argument register */
4407 disp = dseg_addaddress(cd, &env);
4408 M_ALD(rd->argintregs[0], REG_PV, disp);
4410 /* do the native function call */
4412 M_ALD(REG_PV, REG_PV, funcdisp);
4413 M_JSR(REG_RA, REG_PV); /* call native method */
4414 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4415 M_LDA(REG_PV, REG_RA, -disp); /* recompute pv from ra */
4417 /* save return value */
4419 if (IS_INT_LNG_TYPE(md->returntype.type))
4420 M_LST(REG_RESULT, REG_SP, 0 * 8);
4422 M_DST(REG_FRESULT, REG_SP, 0 * 8);
4424 /* remove native stackframe info */
4426 M_LDA(rd->argintregs[0], REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
4427 disp = dseg_addaddress(cd, codegen_finish_native_call);
4428 M_ALD(REG_PV, REG_PV, disp);
4429 M_JSR(REG_RA, REG_PV);
4430 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4431 M_LDA(REG_PV, REG_RA, -disp);
4433 /* call finished trace */
4436 /* just restore the value we need, don't care about the other */
4438 if (IS_INT_LNG_TYPE(md->returntype.type))
4439 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4441 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4443 disp = dseg_addaddress(cd, m);
4444 M_ALD(rd->argintregs[0], REG_PV, disp);
4446 M_MOV(REG_RESULT, rd->argintregs[1]);
4447 M_FMOV(REG_FRESULT, rd->argfltregs[2]);
4448 M_FMOV(REG_FRESULT, rd->argfltregs[3]);
4450 disp = dseg_addaddress(cd, builtin_displaymethodstop);
4451 M_ALD(REG_PV, REG_PV, disp);
4452 M_JSR(REG_RA, REG_PV);
4453 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4454 M_LDA(REG_PV, REG_RA, -disp);
4457 /* check for exception */
4459 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4460 disp = dseg_addaddress(cd, builtin_get_exceptionptrptr);
4461 M_ALD(REG_PV, REG_PV, disp);
4462 M_JSR(REG_RA, REG_PV);
4463 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4464 M_LDA(REG_PV, REG_RA, -disp);
4465 M_MOV(REG_RESULT, REG_ITMP3);
4467 disp = dseg_addaddress(cd, &_exceptionptr);
4468 M_ALD(REG_RESULT, REG_PV, disp); /* get address of exceptionptr */
4470 M_ALD(REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
4472 /* restore return value */
4474 if (IS_INT_LNG_TYPE(md->returntype.type))
4475 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4477 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4479 M_BNEZ(REG_ITMP1, 3); /* if no exception then return */
4481 M_ALD(REG_RA, REG_SP, (stackframesize - 1) * 8); /* load return address */
4482 M_LDA(REG_SP, REG_SP, stackframesize * 8);
4483 M_RET(REG_ZERO, REG_RA); /* return to caller */
4485 /* handle exception */
4487 M_AST(REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
4489 M_ALD(REG_RA, REG_SP, (stackframesize - 1) * 8); /* load return address */
4490 M_LDA(REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
4492 M_LDA(REG_SP, REG_SP, stackframesize * 8);
4494 disp = dseg_addaddress(cd, asm_handle_nat_exception);
4495 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
4496 M_JMP(REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
4499 /* process patcher calls **************************************************/
4507 /* there can only be one <clinit> ref entry */
4508 pref = cd->patchrefs;
4510 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
4511 /* Get machine code which is patched back in later. The call is */
4512 /* 1 instruction word long. */
4514 xcodeptr = (s4 *) (cd->mcodebase + pref->branchpos);
4515 mcode = (u4) *xcodeptr;
4517 /* patch in the call to call the following code (done at compile */
4520 tmpmcodeptr = mcodeptr; /* save current mcodeptr */
4521 mcodeptr = xcodeptr; /* set mcodeptr to patch position */
4523 M_BSR(REG_ITMP3, tmpmcodeptr - (xcodeptr + 1));
4525 mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
4527 /* create stack frame */
4529 M_LSUB_IMM(REG_SP, 6 * 8, REG_SP);
4531 /* move return address onto stack */
4533 M_AST(REG_ITMP3, REG_SP, 5 * 8);
4535 /* move pointer to java_objectheader onto stack */
4537 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4538 /* create a virtual java_objectheader */
4540 (void) dseg_addaddress(cd, get_dummyLR()); /* monitorPtr */
4541 disp = dseg_addaddress(cd, NULL); /* vftbl */
4543 M_LDA(REG_ITMP3, REG_PV, disp);
4544 M_AST(REG_ITMP3, REG_SP, 4 * 8);
4546 M_AST(REG_ZERO, REG_SP, 4 * 8);
4549 /* move machine code onto stack */
4551 disp = dseg_adds4(cd, mcode);
4552 M_ILD(REG_ITMP3, REG_PV, disp);
4553 M_IST(REG_ITMP3, REG_SP, 3 * 8);
4555 /* move class/method/field reference onto stack */
4557 disp = dseg_addaddress(cd, pref->ref);
4558 M_ALD(REG_ITMP3, REG_PV, disp);
4559 M_AST(REG_ITMP3, REG_SP, 2 * 8);
4561 /* move data segment displacement onto stack */
4563 disp = dseg_adds4(cd, pref->disp);
4564 M_ILD(REG_ITMP3, REG_PV, disp);
4565 M_IST(REG_ITMP3, REG_SP, 1 * 8);
4567 /* move patcher function pointer onto stack */
4569 disp = dseg_addaddress(cd, pref->patcher);
4570 M_ALD(REG_ITMP3, REG_PV, disp);
4571 M_AST(REG_ITMP3, REG_SP, 0 * 8);
4573 disp = dseg_addaddress(cd, asm_wrapper_patcher);
4574 M_ALD(REG_ITMP3, REG_PV, disp);
4575 M_JMP(REG_ZERO, REG_ITMP3);
4579 codegen_finish(m, cd, (s4) ((u1 *) mcodeptr - cd->mcodebase));
4581 return m->entrypoint;
4586 * These are local overrides for various environment variables in Emacs.
4587 * Please do not remove this and leave it at the end of the file, where
4588 * Emacs will automagically detect them.
4589 * ---------------------------------------------------------------------
4592 * indent-tabs-mode: t