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
33 $Id: codegen.c 2755 2005-06-20 18:26:03Z twisti $
46 #include "vm/jit/alpha/arch.h"
47 #include "vm/jit/alpha/codegen.h"
48 #include "vm/jit/alpha/types.h"
49 #include "vm/jit/alpha/asmoffsets.h"
51 #include "cacao/cacao.h"
52 #include "native/native.h"
53 #include "vm/builtin.h"
54 #include "vm/global.h"
55 #include "vm/loader.h"
56 #include "vm/stringlocal.h"
57 #include "vm/tables.h"
58 #include "vm/jit/asmpart.h"
59 #include "vm/jit/codegen.inc"
60 #include "vm/jit/jit.h"
63 # include "vm/jit/lsra.h"
64 # include "vm/jit/lsra.inc"
67 #include "vm/jit/parse.h"
68 #include "vm/jit/patcher.h"
69 #include "vm/jit/reg.h"
70 #include "vm/jit/reg.inc"
73 /* codegen *********************************************************************
75 Generates machine code.
77 *******************************************************************************/
79 void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
81 s4 len, s1, s2, s3, d;
91 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
92 builtintable_entry *bte;
99 savedregs_num = (m->isleafmethod) ? 0 : 1; /* space to save the RA */
101 /* space to save used callee saved registers */
103 savedregs_num += (rd->savintregcnt - rd->maxsavintreguse);
104 savedregs_num += (rd->savfltregcnt - rd->maxsavfltreguse);
106 parentargs_base = rd->maxmemuse + savedregs_num;
108 #if defined(USE_THREADS) /* space to save argument of monitor_enter */
110 if (checksync && (m->flags & ACC_SYNCHRONIZED))
115 /* create method header */
117 (void) dseg_addaddress(cd, m); /* MethodPointer */
118 (void) dseg_adds4(cd, parentargs_base * 8); /* FrameSize */
120 #if defined(USE_THREADS)
122 /* IsSync contains the offset relative to the stack pointer for the
123 argument of monitor_exit used in the exception handler. Since the
124 offset could be zero and give a wrong meaning of the flag it is
128 if (checksync && (m->flags & ACC_SYNCHRONIZED))
129 (void) dseg_adds4(cd, (rd->maxmemuse + 1) * 8); /* IsSync */
134 (void) dseg_adds4(cd, 0); /* IsSync */
136 (void) dseg_adds4(cd, m->isleafmethod); /* IsLeaf */
137 (void) dseg_adds4(cd, rd->savintregcnt - rd->maxsavintreguse);/* IntSave */
138 (void) dseg_adds4(cd, rd->savfltregcnt - rd->maxsavfltreguse);/* FltSave */
140 dseg_addlinenumbertablesize(cd);
142 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
144 /* create exception table */
146 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
147 dseg_addtarget(cd, ex->start);
148 dseg_addtarget(cd, ex->end);
149 dseg_addtarget(cd, ex->handler);
150 (void) dseg_addaddress(cd, ex->catchtype.cls);
153 /* initialize mcode variables */
155 mcodeptr = (s4 *) cd->mcodebase;
156 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
157 MCODECHECK(128 + m->paramcount);
159 /* create stack frame (if necessary) */
161 if (parentargs_base) {
162 M_LDA(REG_SP, REG_SP, -parentargs_base * 8);
165 /* save return address and used callee saved registers */
168 if (!m->isleafmethod) {
169 p--; M_AST(REG_RA, REG_SP, p * 8);
171 for (i = rd->savintregcnt - 1; i >= rd->maxsavintreguse; i--) {
172 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
174 for (i = rd->savfltregcnt - 1; i >= rd->maxsavfltreguse; i--) {
175 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
178 /* take arguments out of register or stack frame */
182 for (p = 0, l = 0; p < md->paramcount; p++) {
183 t = md->paramtypes[p].type;
184 var = &(rd->locals[l][t]);
186 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
190 s1 = md->params[p].regoff;
191 if (IS_INT_LNG_TYPE(t)) { /* integer args */
192 if (!md->params[p].inmemory) { /* register arguments */
193 s2 = rd->argintregs[s1];
194 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
195 M_INTMOVE(s2, var->regoff);
197 } else { /* reg arg -> spilled */
198 M_LST(s2, REG_SP, var->regoff * 8);
201 } else { /* stack arguments */
202 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
203 M_LLD(var->regoff, REG_SP, (parentargs_base + s1) * 8);
205 } else { /* stack arg -> spilled */
206 var->regoff = parentargs_base + s1;
210 } else { /* floating args */
211 if (!md->params[p].inmemory) { /* register arguments */
212 s2 = rd->argfltregs[s1];
213 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
214 M_FLTMOVE(s2, var->regoff);
216 } else { /* reg arg -> spilled */
217 M_DST(s2, REG_SP, var->regoff * 8);
220 } else { /* stack arguments */
221 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
222 M_DLD(var->regoff, REG_SP, (parentargs_base + s1) * 8);
224 } else { /* stack-arg -> spilled */
225 var->regoff = parentargs_base + s1;
231 /* call monitorenter function */
233 #if defined(USE_THREADS)
234 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
235 /* stack offset for monitor argument */
240 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
242 for (p = 0; p < INT_ARG_CNT; p++)
243 M_LST(rd->argintregs[p], REG_SP, p * 8);
245 for (p = 0; p < FLT_ARG_CNT; p++)
246 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
248 s1 += INT_ARG_CNT + FLT_ARG_CNT;
251 /* decide which monitor enter function to call */
253 if (m->flags & ACC_STATIC) {
254 p = dseg_addaddress(cd, m->class);
255 M_ALD(REG_ITMP1, REG_PV, p);
256 M_AST(REG_ITMP1, REG_SP, s1 * 8);
257 M_INTMOVE(REG_ITMP1, rd->argintregs[0]);
258 p = dseg_addaddress(cd, BUILTIN_staticmonitorenter);
259 M_ALD(REG_PV, REG_PV, p);
260 M_JSR(REG_RA, REG_PV);
261 d = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
262 M_LDA(REG_PV, REG_RA, d);
265 M_BEQZ(rd->argintregs[0], 0);
266 codegen_addxnullrefs(cd, mcodeptr);
267 M_AST(rd->argintregs[0], REG_SP, s1 * 8);
268 p = dseg_addaddress(cd, BUILTIN_monitorenter);
269 M_ALD(REG_PV, REG_PV, p);
270 M_JSR(REG_RA, REG_PV);
271 d = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
272 M_LDA(REG_PV, REG_RA, d);
276 for (p = 0; p < INT_ARG_CNT; p++)
277 M_LLD(rd->argintregs[p], REG_SP, p * 8);
279 for (p = 0; p < FLT_ARG_CNT; p++)
280 M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
282 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
287 /* call trace function */
290 M_LDA(REG_SP, REG_SP, -((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
291 M_AST(REG_RA, REG_SP, 1 * 8);
293 /* save integer argument registers */
295 for (p = 0; p < md->paramcount && p < INT_ARG_CNT; p++)
296 M_LST(rd->argintregs[p], REG_SP, (2 + p) * 8);
298 /* save and copy float arguments into integer registers */
300 for (p = 0; p < md->paramcount && p < FLT_ARG_CNT; p++) {
301 t = md->paramtypes[p].type;
303 if (IS_FLT_DBL_TYPE(t)) {
304 if (IS_2_WORD_TYPE(t)) {
305 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
308 M_FST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
311 M_LLD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
314 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
318 p = dseg_addaddress(cd, m);
319 M_ALD(REG_ITMP1, REG_PV, p);
320 M_AST(REG_ITMP1, REG_SP, 0 * 8);
321 p = dseg_addaddress(cd, (void *) builtin_trace_args);
322 M_ALD(REG_PV, REG_PV, p);
323 M_JSR(REG_RA, REG_PV);
324 d = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
325 M_LDA(REG_PV, REG_RA, d);
326 M_ALD(REG_RA, REG_SP, 1 * 8);
328 /* restore integer argument registers */
330 for (p = 0; p < md->paramcount && p < INT_ARG_CNT; p++)
331 M_LLD(rd->argintregs[p], REG_SP, (2 + p) * 8);
333 /* restore float argument registers */
335 for (p = 0; p < md->paramcount && p < FLT_ARG_CNT; p++) {
336 t = md->paramtypes[p].type;
338 if (IS_FLT_DBL_TYPE(t)) {
339 if (IS_2_WORD_TYPE(t)) {
340 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
343 M_FLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
347 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
351 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT + 2) * 8);
356 /* end of header generation */
358 /* walk through all basic blocks */
360 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
362 bptr->mpc = (s4) ((u1 *) mcodeptr - cd->mcodebase);
364 if (bptr->flags >= BBREACHED) {
366 /* branch resolving */
370 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
371 gen_resolvebranch((u1*) cd->mcodebase + brefs->branchpos,
372 brefs->branchpos, bptr->mpc);
376 /* copy interface registers to their destination */
383 while (src != NULL) {
385 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
386 /* d = reg_of_var(m, src, REG_ITMP1); */
387 if (!(src->flags & INMEMORY))
391 M_INTMOVE(REG_ITMP1, d);
392 store_reg_to_var_int(src, d);
398 while (src != NULL) {
400 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
401 d = reg_of_var(rd, src, REG_ITMP1);
402 M_INTMOVE(REG_ITMP1, d);
403 store_reg_to_var_int(src, d);
406 d = reg_of_var(rd, src, REG_IFTMP);
407 if ((src->varkind != STACKVAR)) {
409 if (IS_FLT_DBL_TYPE(s2)) {
410 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
411 s1 = rd->interfaces[len][s2].regoff;
415 M_DLD(d, REG_SP, 8 * rd->interfaces[len][s2].regoff);
417 store_reg_to_var_flt(src, d);
420 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
421 s1 = rd->interfaces[len][s2].regoff;
425 M_LLD(d, REG_SP, 8 * rd->interfaces[len][s2].regoff);
427 store_reg_to_var_int(src, d);
437 /* walk through all instructions */
442 for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
443 if (iptr->line != currentline) {
444 dseg_addlinenumber(cd, iptr->line, mcodeptr);
445 currentline = iptr->line;
448 MCODECHECK(64); /* an instruction usually needs < 64 words */
451 case ICMD_INLINE_START:
452 case ICMD_INLINE_END:
455 case ICMD_NOP: /* ... ==> ... */
458 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
460 var_to_reg_int(s1, src, REG_ITMP1);
462 codegen_addxnullrefs(cd, mcodeptr);
465 /* constant operations ************************************************/
467 case ICMD_ICONST: /* ... ==> ..., constant */
468 /* op1 = 0, val.i = constant */
470 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
471 ICONST(d, iptr->val.i);
472 store_reg_to_var_int(iptr->dst, d);
475 case ICMD_LCONST: /* ... ==> ..., constant */
476 /* op1 = 0, val.l = constant */
478 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
479 LCONST(d, iptr->val.l);
480 store_reg_to_var_int(iptr->dst, d);
483 case ICMD_FCONST: /* ... ==> ..., constant */
484 /* op1 = 0, val.f = constant */
486 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
487 a = dseg_addfloat(cd, iptr->val.f);
489 store_reg_to_var_flt(iptr->dst, d);
492 case ICMD_DCONST: /* ... ==> ..., constant */
493 /* op1 = 0, val.d = constant */
495 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
496 a = dseg_adddouble(cd, iptr->val.d);
498 store_reg_to_var_flt(iptr->dst, d);
501 case ICMD_ACONST: /* ... ==> ..., constant */
502 /* op1 = 0, val.a = constant */
504 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
506 a = dseg_addaddress(cd, iptr->val.a);
509 M_INTMOVE(REG_ZERO, d);
511 store_reg_to_var_int(iptr->dst, d);
515 /* load/store operations **********************************************/
517 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
518 case ICMD_LLOAD: /* op1 = local variable */
521 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
522 if ((iptr->dst->varkind == LOCALVAR) &&
523 (iptr->dst->varnum == iptr->op1))
525 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
526 if (var->flags & INMEMORY)
527 M_LLD(d, REG_SP, 8 * var->regoff);
529 {M_INTMOVE(var->regoff,d);}
530 store_reg_to_var_int(iptr->dst, d);
533 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
534 case ICMD_DLOAD: /* op1 = local variable */
536 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
537 if ((iptr->dst->varkind == LOCALVAR) &&
538 (iptr->dst->varnum == iptr->op1))
540 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
541 if (var->flags & INMEMORY)
542 M_DLD(d, REG_SP, 8 * var->regoff);
544 {M_FLTMOVE(var->regoff,d);}
545 store_reg_to_var_flt(iptr->dst, d);
549 case ICMD_ISTORE: /* ..., value ==> ... */
550 case ICMD_LSTORE: /* op1 = local variable */
553 if ((src->varkind == LOCALVAR) &&
554 (src->varnum == iptr->op1))
556 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
557 if (var->flags & INMEMORY) {
558 var_to_reg_int(s1, src, REG_ITMP1);
559 M_LST(s1, REG_SP, 8 * var->regoff);
562 var_to_reg_int(s1, src, var->regoff);
563 M_INTMOVE(s1, var->regoff);
567 case ICMD_FSTORE: /* ..., value ==> ... */
568 case ICMD_DSTORE: /* op1 = local variable */
570 if ((src->varkind == LOCALVAR) &&
571 (src->varnum == iptr->op1))
573 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
574 if (var->flags & INMEMORY) {
575 var_to_reg_flt(s1, src, REG_FTMP1);
576 M_DST(s1, REG_SP, 8 * var->regoff);
579 var_to_reg_flt(s1, src, var->regoff);
580 M_FLTMOVE(s1, var->regoff);
585 /* pop/dup/swap operations ********************************************/
587 /* attention: double and longs are only one entry in CACAO ICMDs */
589 case ICMD_POP: /* ..., value ==> ... */
590 case ICMD_POP2: /* ..., value, value ==> ... */
593 case ICMD_DUP: /* ..., a ==> ..., a, a */
594 M_COPY(src, iptr->dst);
597 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
599 M_COPY(src, iptr->dst);
600 M_COPY(src->prev, iptr->dst->prev);
601 M_COPY(iptr->dst, iptr->dst->prev->prev);
604 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
606 M_COPY(src, iptr->dst);
607 M_COPY(src->prev, iptr->dst->prev);
608 M_COPY(src->prev->prev, iptr->dst->prev->prev);
609 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
612 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
614 M_COPY(src, iptr->dst);
615 M_COPY(src->prev, iptr->dst->prev);
618 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
620 M_COPY(src, iptr->dst);
621 M_COPY(src->prev, iptr->dst->prev);
622 M_COPY(src->prev->prev, iptr->dst->prev->prev);
623 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
624 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev);
627 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
629 M_COPY(src, iptr->dst);
630 M_COPY(src->prev, iptr->dst->prev);
631 M_COPY(src->prev->prev, iptr->dst->prev->prev);
632 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
633 M_COPY(iptr->dst, iptr->dst->prev->prev->prev->prev);
634 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev->prev);
637 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
639 M_COPY(src, iptr->dst->prev);
640 M_COPY(src->prev, iptr->dst);
644 /* integer operations *************************************************/
646 case ICMD_INEG: /* ..., value ==> ..., - value */
648 var_to_reg_int(s1, src, REG_ITMP1);
649 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
650 M_ISUB(REG_ZERO, s1, d);
651 store_reg_to_var_int(iptr->dst, d);
654 case ICMD_LNEG: /* ..., value ==> ..., - value */
656 var_to_reg_int(s1, src, REG_ITMP1);
657 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
658 M_LSUB(REG_ZERO, s1, d);
659 store_reg_to_var_int(iptr->dst, d);
662 case ICMD_I2L: /* ..., value ==> ..., value */
664 var_to_reg_int(s1, src, REG_ITMP1);
665 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
667 store_reg_to_var_int(iptr->dst, d);
670 case ICMD_L2I: /* ..., value ==> ..., value */
672 var_to_reg_int(s1, src, REG_ITMP1);
673 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
674 M_IADD(s1, REG_ZERO, d );
675 store_reg_to_var_int(iptr->dst, d);
678 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
680 var_to_reg_int(s1, src, REG_ITMP1);
681 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
682 if (has_ext_instr_set) {
686 M_SLL_IMM(s1, 56, d);
687 M_SRA_IMM( d, 56, d);
689 store_reg_to_var_int(iptr->dst, d);
692 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
694 var_to_reg_int(s1, src, REG_ITMP1);
695 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
697 store_reg_to_var_int(iptr->dst, d);
700 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
702 var_to_reg_int(s1, src, REG_ITMP1);
703 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
704 if (has_ext_instr_set) {
708 M_SLL_IMM(s1, 48, d);
709 M_SRA_IMM( d, 48, d);
711 store_reg_to_var_int(iptr->dst, d);
715 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
717 var_to_reg_int(s1, src->prev, REG_ITMP1);
718 var_to_reg_int(s2, src, REG_ITMP2);
719 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
721 store_reg_to_var_int(iptr->dst, d);
724 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
725 /* val.i = constant */
727 var_to_reg_int(s1, src, REG_ITMP1);
728 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
729 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
730 M_IADD_IMM(s1, iptr->val.i, d);
733 ICONST(REG_ITMP2, iptr->val.i);
734 M_IADD(s1, REG_ITMP2, d);
736 store_reg_to_var_int(iptr->dst, d);
739 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
741 var_to_reg_int(s1, src->prev, REG_ITMP1);
742 var_to_reg_int(s2, src, REG_ITMP2);
743 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
745 store_reg_to_var_int(iptr->dst, d);
748 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
749 /* val.l = constant */
751 var_to_reg_int(s1, src, REG_ITMP1);
752 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
753 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
754 M_LADD_IMM(s1, iptr->val.l, d);
757 LCONST(REG_ITMP2, iptr->val.l);
758 M_LADD(s1, REG_ITMP2, d);
760 store_reg_to_var_int(iptr->dst, d);
763 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
765 var_to_reg_int(s1, src->prev, REG_ITMP1);
766 var_to_reg_int(s2, src, REG_ITMP2);
767 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
769 store_reg_to_var_int(iptr->dst, d);
772 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
773 /* val.i = constant */
775 var_to_reg_int(s1, src, REG_ITMP1);
776 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
777 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
778 M_ISUB_IMM(s1, iptr->val.i, d);
781 ICONST(REG_ITMP2, iptr->val.i);
782 M_ISUB(s1, REG_ITMP2, d);
784 store_reg_to_var_int(iptr->dst, d);
787 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
789 var_to_reg_int(s1, src->prev, REG_ITMP1);
790 var_to_reg_int(s2, src, REG_ITMP2);
791 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
793 store_reg_to_var_int(iptr->dst, d);
796 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
797 /* val.l = constant */
799 var_to_reg_int(s1, src, REG_ITMP1);
800 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
801 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
802 M_LSUB_IMM(s1, iptr->val.l, d);
805 LCONST(REG_ITMP2, iptr->val.l);
806 M_LSUB(s1, REG_ITMP2, d);
808 store_reg_to_var_int(iptr->dst, d);
811 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
813 var_to_reg_int(s1, src->prev, REG_ITMP1);
814 var_to_reg_int(s2, src, REG_ITMP2);
815 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
817 store_reg_to_var_int(iptr->dst, d);
820 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
821 /* val.i = constant */
823 var_to_reg_int(s1, src, REG_ITMP1);
824 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
825 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
826 M_IMUL_IMM(s1, iptr->val.i, d);
829 ICONST(REG_ITMP2, iptr->val.i);
830 M_IMUL(s1, REG_ITMP2, d);
832 store_reg_to_var_int(iptr->dst, d);
835 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
837 var_to_reg_int(s1, src->prev, REG_ITMP1);
838 var_to_reg_int(s2, src, REG_ITMP2);
839 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
841 store_reg_to_var_int(iptr->dst, d);
844 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
845 /* val.l = constant */
847 var_to_reg_int(s1, src, REG_ITMP1);
848 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
849 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
850 M_LMUL_IMM(s1, iptr->val.l, d);
853 LCONST(REG_ITMP2, iptr->val.l);
854 M_LMUL(s1, REG_ITMP2, d);
856 store_reg_to_var_int(iptr->dst, d);
859 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
860 case ICMD_LDIVPOW2: /* val.i = constant */
862 var_to_reg_int(s1, src, REG_ITMP1);
863 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
864 if (iptr->val.i <= 15) {
865 M_LDA(REG_ITMP2, s1, (1 << iptr->val.i) -1);
866 M_CMOVGE(s1, s1, REG_ITMP2);
869 M_SRA_IMM(s1, 63, REG_ITMP2);
870 M_SRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
871 M_LADD(s1, REG_ITMP2, REG_ITMP2);
873 M_SRA_IMM(REG_ITMP2, iptr->val.i, d);
874 store_reg_to_var_int(iptr->dst, d);
877 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
879 var_to_reg_int(s1, src->prev, REG_ITMP1);
880 var_to_reg_int(s2, src, REG_ITMP2);
881 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
882 M_AND_IMM(s2, 0x1f, REG_ITMP3);
883 M_SLL(s1, REG_ITMP3, d);
884 M_IADD(d, REG_ZERO, d);
885 store_reg_to_var_int(iptr->dst, d);
888 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
889 /* val.i = constant */
891 var_to_reg_int(s1, src, REG_ITMP1);
892 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
893 M_SLL_IMM(s1, iptr->val.i & 0x1f, d);
894 M_IADD(d, REG_ZERO, d);
895 store_reg_to_var_int(iptr->dst, d);
898 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
900 var_to_reg_int(s1, src->prev, REG_ITMP1);
901 var_to_reg_int(s2, src, REG_ITMP2);
902 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
903 M_AND_IMM(s2, 0x1f, REG_ITMP3);
904 M_SRA(s1, REG_ITMP3, d);
905 store_reg_to_var_int(iptr->dst, d);
908 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
909 /* val.i = constant */
911 var_to_reg_int(s1, src, REG_ITMP1);
912 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
913 M_SRA_IMM(s1, iptr->val.i & 0x1f, d);
914 store_reg_to_var_int(iptr->dst, d);
917 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
919 var_to_reg_int(s1, src->prev, REG_ITMP1);
920 var_to_reg_int(s2, src, REG_ITMP2);
921 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
922 M_AND_IMM(s2, 0x1f, REG_ITMP2);
924 M_SRL(d, REG_ITMP2, d);
925 M_IADD(d, REG_ZERO, d);
926 store_reg_to_var_int(iptr->dst, d);
929 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
930 /* val.i = constant */
932 var_to_reg_int(s1, src, REG_ITMP1);
933 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
935 M_SRL_IMM(d, iptr->val.i & 0x1f, d);
936 M_IADD(d, REG_ZERO, d);
937 store_reg_to_var_int(iptr->dst, d);
940 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
942 var_to_reg_int(s1, src->prev, REG_ITMP1);
943 var_to_reg_int(s2, src, REG_ITMP2);
944 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
946 store_reg_to_var_int(iptr->dst, d);
949 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
950 /* val.i = constant */
952 var_to_reg_int(s1, src, REG_ITMP1);
953 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
954 M_SLL_IMM(s1, iptr->val.i & 0x3f, d);
955 store_reg_to_var_int(iptr->dst, d);
958 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
960 var_to_reg_int(s1, src->prev, REG_ITMP1);
961 var_to_reg_int(s2, src, REG_ITMP2);
962 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
964 store_reg_to_var_int(iptr->dst, d);
967 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
968 /* val.i = constant */
970 var_to_reg_int(s1, src, REG_ITMP1);
971 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
972 M_SRA_IMM(s1, iptr->val.i & 0x3f, d);
973 store_reg_to_var_int(iptr->dst, d);
976 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
978 var_to_reg_int(s1, src->prev, REG_ITMP1);
979 var_to_reg_int(s2, src, REG_ITMP2);
980 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
982 store_reg_to_var_int(iptr->dst, d);
985 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
986 /* val.i = constant */
988 var_to_reg_int(s1, src, REG_ITMP1);
989 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
990 M_SRL_IMM(s1, iptr->val.i & 0x3f, d);
991 store_reg_to_var_int(iptr->dst, d);
994 case ICMD_IAND: /* ..., 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_ITMP3);
1001 store_reg_to_var_int(iptr->dst, d);
1004 case ICMD_IANDCONST: /* ..., 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_ITMP3);
1009 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1010 M_AND_IMM(s1, iptr->val.i, d);
1012 else if (iptr->val.i == 0xffff) {
1015 else if (iptr->val.i == 0xffffff) {
1016 M_ZAPNOT_IMM(s1, 0x07, d);
1019 ICONST(REG_ITMP2, iptr->val.i);
1020 M_AND(s1, REG_ITMP2, d);
1022 store_reg_to_var_int(iptr->dst, d);
1025 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1026 /* val.i = constant */
1028 var_to_reg_int(s1, src, REG_ITMP1);
1029 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1031 M_MOV(s1, REG_ITMP1);
1034 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1035 M_AND_IMM(s1, iptr->val.i, d);
1037 M_ISUB(REG_ZERO, s1, d);
1038 M_AND_IMM(d, iptr->val.i, d);
1040 else if (iptr->val.i == 0xffff) {
1043 M_ISUB(REG_ZERO, s1, d);
1046 else if (iptr->val.i == 0xffffff) {
1047 M_ZAPNOT_IMM(s1, 0x07, d);
1049 M_ISUB(REG_ZERO, s1, d);
1050 M_ZAPNOT_IMM(d, 0x07, d);
1053 ICONST(REG_ITMP2, iptr->val.i);
1054 M_AND(s1, REG_ITMP2, d);
1056 M_ISUB(REG_ZERO, s1, d);
1057 M_AND(d, REG_ITMP2, d);
1059 M_ISUB(REG_ZERO, d, d);
1060 store_reg_to_var_int(iptr->dst, d);
1063 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1064 /* val.l = constant */
1066 var_to_reg_int(s1, src, REG_ITMP1);
1067 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1068 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1069 M_AND_IMM(s1, iptr->val.l, d);
1071 else if (iptr->val.l == 0xffffL) {
1074 else if (iptr->val.l == 0xffffffL) {
1075 M_ZAPNOT_IMM(s1, 0x07, d);
1077 else if (iptr->val.l == 0xffffffffL) {
1080 else if (iptr->val.l == 0xffffffffffL) {
1081 M_ZAPNOT_IMM(s1, 0x1f, d);
1083 else if (iptr->val.l == 0xffffffffffffL) {
1084 M_ZAPNOT_IMM(s1, 0x3f, d);
1086 else if (iptr->val.l == 0xffffffffffffffL) {
1087 M_ZAPNOT_IMM(s1, 0x7f, d);
1090 LCONST(REG_ITMP2, iptr->val.l);
1091 M_AND(s1, REG_ITMP2, d);
1093 store_reg_to_var_int(iptr->dst, d);
1096 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1097 /* val.l = constant */
1099 var_to_reg_int(s1, src, REG_ITMP1);
1100 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1102 M_MOV(s1, REG_ITMP1);
1105 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1106 M_AND_IMM(s1, iptr->val.l, d);
1108 M_LSUB(REG_ZERO, s1, d);
1109 M_AND_IMM(d, iptr->val.l, d);
1111 else if (iptr->val.l == 0xffffL) {
1114 M_LSUB(REG_ZERO, s1, d);
1117 else if (iptr->val.l == 0xffffffL) {
1118 M_ZAPNOT_IMM(s1, 0x07, d);
1120 M_LSUB(REG_ZERO, s1, d);
1121 M_ZAPNOT_IMM(d, 0x07, d);
1123 else if (iptr->val.l == 0xffffffffL) {
1126 M_LSUB(REG_ZERO, s1, d);
1129 else if (iptr->val.l == 0xffffffffffL) {
1130 M_ZAPNOT_IMM(s1, 0x1f, d);
1132 M_LSUB(REG_ZERO, s1, d);
1133 M_ZAPNOT_IMM(d, 0x1f, d);
1135 else if (iptr->val.l == 0xffffffffffffL) {
1136 M_ZAPNOT_IMM(s1, 0x3f, d);
1138 M_LSUB(REG_ZERO, s1, d);
1139 M_ZAPNOT_IMM(d, 0x3f, d);
1141 else if (iptr->val.l == 0xffffffffffffffL) {
1142 M_ZAPNOT_IMM(s1, 0x7f, d);
1144 M_LSUB(REG_ZERO, s1, d);
1145 M_ZAPNOT_IMM(d, 0x7f, d);
1148 LCONST(REG_ITMP2, iptr->val.l);
1149 M_AND(s1, REG_ITMP2, d);
1151 M_LSUB(REG_ZERO, s1, d);
1152 M_AND(d, REG_ITMP2, d);
1154 M_LSUB(REG_ZERO, d, d);
1155 store_reg_to_var_int(iptr->dst, d);
1158 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1161 var_to_reg_int(s1, src->prev, REG_ITMP1);
1162 var_to_reg_int(s2, src, REG_ITMP2);
1163 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1165 store_reg_to_var_int(iptr->dst, d);
1168 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1169 /* val.i = constant */
1171 var_to_reg_int(s1, src, REG_ITMP1);
1172 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1173 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1174 M_OR_IMM(s1, iptr->val.i, d);
1177 ICONST(REG_ITMP2, iptr->val.i);
1178 M_OR(s1, REG_ITMP2, d);
1180 store_reg_to_var_int(iptr->dst, d);
1183 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1184 /* val.l = constant */
1186 var_to_reg_int(s1, src, REG_ITMP1);
1187 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1188 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1189 M_OR_IMM(s1, iptr->val.l, d);
1192 LCONST(REG_ITMP2, iptr->val.l);
1193 M_OR(s1, REG_ITMP2, d);
1195 store_reg_to_var_int(iptr->dst, d);
1198 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1201 var_to_reg_int(s1, src->prev, REG_ITMP1);
1202 var_to_reg_int(s2, src, REG_ITMP2);
1203 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1205 store_reg_to_var_int(iptr->dst, d);
1208 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1209 /* val.i = constant */
1211 var_to_reg_int(s1, src, REG_ITMP1);
1212 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1213 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1214 M_XOR_IMM(s1, iptr->val.i, d);
1217 ICONST(REG_ITMP2, iptr->val.i);
1218 M_XOR(s1, REG_ITMP2, d);
1220 store_reg_to_var_int(iptr->dst, d);
1223 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1224 /* val.l = constant */
1226 var_to_reg_int(s1, src, REG_ITMP1);
1227 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1228 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1229 M_XOR_IMM(s1, iptr->val.l, d);
1232 LCONST(REG_ITMP2, iptr->val.l);
1233 M_XOR(s1, REG_ITMP2, d);
1235 store_reg_to_var_int(iptr->dst, d);
1239 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1241 var_to_reg_int(s1, src->prev, REG_ITMP1);
1242 var_to_reg_int(s2, src, REG_ITMP2);
1243 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1244 M_CMPLT(s1, s2, REG_ITMP3);
1245 M_CMPLT(s2, s1, REG_ITMP1);
1246 M_LSUB (REG_ITMP1, REG_ITMP3, d);
1247 store_reg_to_var_int(iptr->dst, d);
1251 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1252 /* op1 = variable, val.i = constant */
1254 var = &(rd->locals[iptr->op1][TYPE_INT]);
1255 if (var->flags & INMEMORY) {
1257 M_LLD(s1, REG_SP, 8 * var->regoff);
1261 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1262 M_IADD_IMM(s1, iptr->val.i, s1);
1264 else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1265 M_ISUB_IMM(s1, (-iptr->val.i), s1);
1268 M_LDA (s1, s1, iptr->val.i);
1269 M_IADD(s1, REG_ZERO, s1);
1271 if (var->flags & INMEMORY)
1272 M_LST(s1, REG_SP, 8 * var->regoff);
1276 /* floating operations ************************************************/
1278 case ICMD_FNEG: /* ..., value ==> ..., - value */
1280 var_to_reg_flt(s1, src, REG_FTMP1);
1281 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1283 store_reg_to_var_flt(iptr->dst, d);
1286 case ICMD_DNEG: /* ..., value ==> ..., - value */
1288 var_to_reg_flt(s1, src, REG_FTMP1);
1289 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1291 store_reg_to_var_flt(iptr->dst, d);
1294 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1296 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1297 var_to_reg_flt(s2, src, REG_FTMP2);
1298 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1303 if (d == s1 || d == s2) {
1304 M_FADDS(s1, s2, REG_FTMP3);
1306 M_FMOV(REG_FTMP3, d);
1313 store_reg_to_var_flt(iptr->dst, d);
1316 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1318 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1319 var_to_reg_flt(s2, src, REG_FTMP2);
1320 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1325 if (d == s1 || d == s2) {
1326 M_DADDS(s1, s2, REG_FTMP3);
1328 M_FMOV(REG_FTMP3, d);
1335 store_reg_to_var_flt(iptr->dst, d);
1338 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1340 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1341 var_to_reg_flt(s2, src, REG_FTMP2);
1342 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1347 if (d == s1 || d == s2) {
1348 M_FSUBS(s1, s2, REG_FTMP3);
1350 M_FMOV(REG_FTMP3, d);
1357 store_reg_to_var_flt(iptr->dst, d);
1360 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1362 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1363 var_to_reg_flt(s2, src, REG_FTMP2);
1364 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1369 if (d == s1 || d == s2) {
1370 M_DSUBS(s1, s2, REG_FTMP3);
1372 M_FMOV(REG_FTMP3, d);
1379 store_reg_to_var_flt(iptr->dst, d);
1382 case ICMD_FMUL: /* ..., 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);
1391 if (d == s1 || d == s2) {
1392 M_FMULS(s1, s2, REG_FTMP3);
1394 M_FMOV(REG_FTMP3, d);
1401 store_reg_to_var_flt(iptr->dst, d);
1404 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1406 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1407 var_to_reg_flt(s2, src, REG_FTMP2);
1408 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1413 if (d == s1 || d == s2) {
1414 M_DMULS(s1, s2, REG_FTMP3);
1416 M_FMOV(REG_FTMP3, d);
1423 store_reg_to_var_flt(iptr->dst, d);
1426 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1428 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1429 var_to_reg_flt(s2, src, REG_FTMP2);
1430 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1435 if (d == s1 || d == s2) {
1436 M_FDIVS(s1, s2, REG_FTMP3);
1438 M_FMOV(REG_FTMP3, d);
1445 store_reg_to_var_flt(iptr->dst, d);
1448 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1450 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1451 var_to_reg_flt(s2, src, REG_FTMP2);
1452 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1457 if (d == s1 || d == s2) {
1458 M_DDIVS(s1, s2, REG_FTMP3);
1460 M_FMOV(REG_FTMP3, d);
1467 store_reg_to_var_flt(iptr->dst, d);
1470 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1472 var_to_reg_int(s1, src, REG_ITMP1);
1473 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1474 a = dseg_adddouble(cd, 0.0);
1475 M_LST (s1, REG_PV, a);
1476 M_DLD (d, REG_PV, a);
1478 store_reg_to_var_flt(iptr->dst, d);
1481 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1483 var_to_reg_int(s1, src, REG_ITMP1);
1484 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1485 a = dseg_adddouble(cd, 0.0);
1486 M_LST (s1, REG_PV, a);
1487 M_DLD (d, REG_PV, a);
1489 store_reg_to_var_flt(iptr->dst, d);
1492 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1494 var_to_reg_flt(s1, src, REG_FTMP1);
1495 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1496 a = dseg_adddouble(cd, 0.0);
1497 M_CVTDL_C(s1, REG_FTMP2);
1498 M_CVTLI(REG_FTMP2, REG_FTMP3);
1499 M_DST (REG_FTMP3, REG_PV, a);
1500 M_ILD (d, REG_PV, a);
1501 store_reg_to_var_int(iptr->dst, d);
1504 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1506 var_to_reg_flt(s1, src, REG_FTMP1);
1507 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1508 a = dseg_adddouble(cd, 0.0);
1509 M_CVTDL_C(s1, REG_FTMP2);
1510 M_DST (REG_FTMP2, REG_PV, a);
1511 M_LLD (d, REG_PV, a);
1512 store_reg_to_var_int(iptr->dst, d);
1515 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1517 var_to_reg_flt(s1, src, REG_FTMP1);
1518 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1521 store_reg_to_var_flt(iptr->dst, d);
1524 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1526 var_to_reg_flt(s1, src, REG_FTMP1);
1527 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1535 store_reg_to_var_flt(iptr->dst, d);
1538 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1540 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1541 var_to_reg_flt(s2, src, REG_FTMP2);
1542 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1544 M_LSUB_IMM(REG_ZERO, 1, d);
1545 M_FCMPEQ(s1, s2, REG_FTMP3);
1546 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1548 M_FCMPLT(s2, s1, REG_FTMP3);
1549 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1550 M_LADD_IMM(REG_ZERO, 1, d);
1553 M_LSUB_IMM(REG_ZERO, 1, d);
1554 M_FCMPEQS(s1, s2, REG_FTMP3);
1556 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1558 M_FCMPLTS(s2, s1, REG_FTMP3);
1560 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1561 M_LADD_IMM(REG_ZERO, 1, d);
1563 store_reg_to_var_int(iptr->dst, d);
1566 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1568 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1569 var_to_reg_flt(s2, src, REG_FTMP2);
1570 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1572 M_LADD_IMM(REG_ZERO, 1, d);
1573 M_FCMPEQ(s1, s2, REG_FTMP3);
1574 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1576 M_FCMPLT(s1, s2, REG_FTMP3);
1577 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1578 M_LSUB_IMM(REG_ZERO, 1, d);
1581 M_LADD_IMM(REG_ZERO, 1, d);
1582 M_FCMPEQS(s1, s2, REG_FTMP3);
1584 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1586 M_FCMPLTS(s1, s2, REG_FTMP3);
1588 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1589 M_LSUB_IMM(REG_ZERO, 1, d);
1591 store_reg_to_var_int(iptr->dst, d);
1595 /* memory operations **************************************************/
1597 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1599 var_to_reg_int(s1, src, REG_ITMP1);
1600 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1601 gen_nullptr_check(s1);
1602 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1603 store_reg_to_var_int(iptr->dst, d);
1606 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1608 var_to_reg_int(s1, src->prev, REG_ITMP1);
1609 var_to_reg_int(s2, src, REG_ITMP2);
1610 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1611 if (iptr->op1 == 0) {
1612 gen_nullptr_check(s1);
1615 M_SAADDQ(s2, s1, REG_ITMP1);
1616 M_ALD( d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1617 store_reg_to_var_int(iptr->dst, d);
1620 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1622 var_to_reg_int(s1, src->prev, REG_ITMP1);
1623 var_to_reg_int(s2, src, REG_ITMP2);
1624 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1625 if (iptr->op1 == 0) {
1626 gen_nullptr_check(s1);
1629 M_S8ADDQ(s2, s1, REG_ITMP1);
1630 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1631 store_reg_to_var_int(iptr->dst, d);
1634 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1636 var_to_reg_int(s1, src->prev, REG_ITMP1);
1637 var_to_reg_int(s2, src, REG_ITMP2);
1638 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1639 if (iptr->op1 == 0) {
1640 gen_nullptr_check(s1);
1644 M_S4ADDQ(s2, s1, REG_ITMP1);
1645 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1646 store_reg_to_var_int(iptr->dst, d);
1649 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1651 var_to_reg_int(s1, src->prev, REG_ITMP1);
1652 var_to_reg_int(s2, src, REG_ITMP2);
1653 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1654 if (iptr->op1 == 0) {
1655 gen_nullptr_check(s1);
1658 M_S4ADDQ(s2, s1, REG_ITMP1);
1659 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1660 store_reg_to_var_flt(iptr->dst, d);
1663 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1665 var_to_reg_int(s1, src->prev, REG_ITMP1);
1666 var_to_reg_int(s2, src, REG_ITMP2);
1667 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1668 if (iptr->op1 == 0) {
1669 gen_nullptr_check(s1);
1672 M_S8ADDQ(s2, s1, REG_ITMP1);
1673 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1674 store_reg_to_var_flt(iptr->dst, d);
1677 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1679 var_to_reg_int(s1, src->prev, REG_ITMP1);
1680 var_to_reg_int(s2, src, REG_ITMP2);
1681 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1682 if (iptr->op1 == 0) {
1683 gen_nullptr_check(s1);
1686 if (has_ext_instr_set) {
1687 M_LADD(s2, s1, REG_ITMP1);
1688 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1689 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1692 M_LADD (s2, s1, REG_ITMP1);
1693 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1694 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1695 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1696 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
1698 store_reg_to_var_int(iptr->dst, d);
1701 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1703 var_to_reg_int(s1, src->prev, REG_ITMP1);
1704 var_to_reg_int(s2, src, REG_ITMP2);
1705 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1706 if (iptr->op1 == 0) {
1707 gen_nullptr_check(s1);
1710 if (has_ext_instr_set) {
1711 M_LADD(s2, s1, REG_ITMP1);
1712 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1713 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1717 M_LADD(s2, s1, REG_ITMP1);
1718 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1719 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1720 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1721 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1722 M_SRA_IMM(d, 48, d);
1724 store_reg_to_var_int(iptr->dst, d);
1727 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1729 var_to_reg_int(s1, src->prev, REG_ITMP1);
1730 var_to_reg_int(s2, src, REG_ITMP2);
1731 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1732 if (iptr->op1 == 0) {
1733 gen_nullptr_check(s1);
1736 if (has_ext_instr_set) {
1737 M_LADD (s2, s1, REG_ITMP1);
1738 M_BLDU (d, REG_ITMP1, OFFSET (java_bytearray, data[0]));
1742 M_LADD(s2, s1, REG_ITMP1);
1743 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1744 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
1745 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1746 M_SRA_IMM(d, 56, d);
1748 store_reg_to_var_int(iptr->dst, d);
1752 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1754 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1755 var_to_reg_int(s2, src->prev, REG_ITMP2);
1756 if (iptr->op1 == 0) {
1757 gen_nullptr_check(s1);
1760 var_to_reg_int(s3, src, REG_ITMP3);
1761 M_SAADDQ(s2, s1, REG_ITMP1);
1762 M_AST (s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1765 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1767 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1768 var_to_reg_int(s2, src->prev, REG_ITMP2);
1769 if (iptr->op1 == 0) {
1770 gen_nullptr_check(s1);
1773 var_to_reg_int(s3, src, REG_ITMP3);
1774 M_S8ADDQ(s2, s1, REG_ITMP1);
1775 M_LST (s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1778 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1780 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1781 var_to_reg_int(s2, src->prev, REG_ITMP2);
1782 if (iptr->op1 == 0) {
1783 gen_nullptr_check(s1);
1787 var_to_reg_int(s3, src, REG_ITMP3);
1788 M_S4ADDQ(s2, s1, REG_ITMP1);
1789 M_IST (s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1792 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1794 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1795 var_to_reg_int(s2, src->prev, REG_ITMP2);
1796 if (iptr->op1 == 0) {
1797 gen_nullptr_check(s1);
1800 var_to_reg_flt(s3, src, REG_FTMP3);
1801 M_S4ADDQ(s2, s1, REG_ITMP1);
1802 M_FST (s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1805 case ICMD_DASTORE: /* ..., 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_flt(s3, src, REG_FTMP3);
1814 M_S8ADDQ(s2, s1, REG_ITMP1);
1815 M_DST (s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1818 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1820 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1821 var_to_reg_int(s2, src->prev, REG_ITMP2);
1822 if (iptr->op1 == 0) {
1823 gen_nullptr_check(s1);
1826 var_to_reg_int(s3, src, REG_ITMP3);
1827 if (has_ext_instr_set) {
1828 M_LADD(s2, s1, REG_ITMP1);
1829 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1830 M_SST (s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1833 M_LADD (s2, s1, REG_ITMP1);
1834 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1835 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1836 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1837 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1838 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1839 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
1840 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1844 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1846 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1847 var_to_reg_int(s2, src->prev, REG_ITMP2);
1848 if (iptr->op1 == 0) {
1849 gen_nullptr_check(s1);
1852 var_to_reg_int(s3, src, REG_ITMP3);
1853 if (has_ext_instr_set) {
1854 M_LADD(s2, s1, REG_ITMP1);
1855 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1856 M_SST (s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1859 M_LADD (s2, s1, REG_ITMP1);
1860 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1861 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1862 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1863 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1864 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1865 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
1866 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1870 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1872 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1873 var_to_reg_int(s2, src->prev, REG_ITMP2);
1874 if (iptr->op1 == 0) {
1875 gen_nullptr_check(s1);
1878 var_to_reg_int(s3, src, REG_ITMP3);
1879 if (has_ext_instr_set) {
1880 M_LADD(s2, s1, REG_ITMP1);
1881 M_BST (s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1884 M_LADD (s2, s1, REG_ITMP1);
1885 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1886 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1887 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
1888 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1889 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
1890 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1895 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1897 var_to_reg_int(s1, src->prev, REG_ITMP1);
1898 var_to_reg_int(s2, src, REG_ITMP2);
1899 if (iptr->op1 == 0) {
1900 gen_nullptr_check(s1);
1903 M_S4ADDQ(s2, s1, REG_ITMP1);
1904 M_IST(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1907 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1909 var_to_reg_int(s1, src->prev, REG_ITMP1);
1910 var_to_reg_int(s2, src, REG_ITMP2);
1911 if (iptr->op1 == 0) {
1912 gen_nullptr_check(s1);
1915 M_S8ADDQ(s2, s1, REG_ITMP1);
1916 M_LST(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1919 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1921 var_to_reg_int(s1, src->prev, REG_ITMP1);
1922 var_to_reg_int(s2, src, REG_ITMP2);
1923 if (iptr->op1 == 0) {
1924 gen_nullptr_check(s1);
1927 M_SAADDQ(s2, s1, REG_ITMP1);
1928 M_AST(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1931 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1933 var_to_reg_int(s1, src->prev, REG_ITMP1);
1934 var_to_reg_int(s2, src, REG_ITMP2);
1935 if (iptr->op1 == 0) {
1936 gen_nullptr_check(s1);
1939 if (has_ext_instr_set) {
1940 M_LADD(s2, s1, REG_ITMP1);
1941 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1944 M_LADD(s2, s1, REG_ITMP1);
1945 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1946 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1947 M_INSBL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1948 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1949 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1950 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1954 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1956 var_to_reg_int(s1, src->prev, REG_ITMP1);
1957 var_to_reg_int(s2, src, REG_ITMP2);
1958 if (iptr->op1 == 0) {
1959 gen_nullptr_check(s1);
1962 if (has_ext_instr_set) {
1963 M_LADD(s2, s1, REG_ITMP1);
1964 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1965 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1968 M_LADD(s2, s1, REG_ITMP1);
1969 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1970 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1971 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1972 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1973 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1974 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1975 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1979 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1981 var_to_reg_int(s1, src->prev, REG_ITMP1);
1982 var_to_reg_int(s2, src, REG_ITMP2);
1983 if (iptr->op1 == 0) {
1984 gen_nullptr_check(s1);
1987 if (has_ext_instr_set) {
1988 M_LADD(s2, s1, REG_ITMP1);
1989 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1990 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1993 M_LADD(s2, s1, REG_ITMP1);
1994 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1995 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1996 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1997 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1998 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1999 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2000 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2005 case ICMD_GETSTATIC: /* ... ==> ..., value */
2006 /* op1 = type, val.a = field address */
2009 codegen_addpatchref(cd, mcodeptr,
2010 PATCHER_get_putstatic,
2011 (unresolved_field *) iptr->target);
2013 if (showdisassemble)
2019 fieldinfo *fi = iptr->val.a;
2021 if (!fi->class->initialized) {
2022 codegen_addpatchref(cd, mcodeptr,
2023 PATCHER_clinit, fi->class);
2025 if (showdisassemble)
2029 a = (ptrint) &(fi->value);
2032 a = dseg_addaddress(cd, a);
2033 M_ALD(REG_ITMP1, REG_PV, a);
2034 switch (iptr->op1) {
2036 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2037 M_ILD(d, REG_ITMP1, 0);
2038 store_reg_to_var_int(iptr->dst, d);
2041 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2042 M_LLD(d, REG_ITMP1, 0);
2043 store_reg_to_var_int(iptr->dst, d);
2046 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2047 M_ALD(d, REG_ITMP1, 0);
2048 store_reg_to_var_int(iptr->dst, d);
2051 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2052 M_FLD(d, REG_ITMP1, 0);
2053 store_reg_to_var_flt(iptr->dst, d);
2056 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2057 M_DLD(d, REG_ITMP1, 0);
2058 store_reg_to_var_flt(iptr->dst, d);
2063 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2064 /* op1 = type, val.a = field address */
2067 codegen_addpatchref(cd, mcodeptr,
2068 PATCHER_get_putstatic,
2069 (unresolved_field *) iptr->target);
2071 if (showdisassemble)
2077 fieldinfo *fi = iptr->val.a;
2079 if (!fi->class->initialized) {
2080 codegen_addpatchref(cd, mcodeptr,
2081 PATCHER_clinit, fi->class);
2083 if (showdisassemble)
2087 a = (ptrint) &(fi->value);
2090 a = dseg_addaddress(cd, a);
2091 M_ALD(REG_ITMP1, REG_PV, a);
2092 switch (iptr->op1) {
2094 var_to_reg_int(s2, src, REG_ITMP2);
2095 M_IST(s2, REG_ITMP1, 0);
2098 var_to_reg_int(s2, src, REG_ITMP2);
2099 M_LST(s2, REG_ITMP1, 0);
2102 var_to_reg_int(s2, src, REG_ITMP2);
2103 M_AST(s2, REG_ITMP1, 0);
2106 var_to_reg_flt(s2, src, REG_FTMP2);
2107 M_FST(s2, REG_ITMP1, 0);
2110 var_to_reg_flt(s2, src, REG_FTMP2);
2111 M_DST(s2, REG_ITMP1, 0);
2116 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2117 /* val = value (in current instruction) */
2118 /* op1 = type, val.a = field address (in */
2119 /* following NOP) */
2121 if (!iptr[1].val.a) {
2122 codegen_addpatchref(cd, mcodeptr,
2123 PATCHER_get_putstatic,
2124 (unresolved_field *) iptr[1].target);
2126 if (showdisassemble)
2132 fieldinfo *fi = iptr[1].val.a;
2134 if (!fi->class->initialized) {
2135 codegen_addpatchref(cd, mcodeptr,
2136 PATCHER_clinit, fi->class);
2138 if (showdisassemble)
2142 a = (ptrint) &(fi->value);
2145 a = dseg_addaddress(cd, a);
2146 M_ALD(REG_ITMP1, REG_PV, a);
2147 switch (iptr->op1) {
2149 M_IST(REG_ZERO, REG_ITMP1, 0);
2152 M_LST(REG_ZERO, REG_ITMP1, 0);
2155 M_AST(REG_ZERO, REG_ITMP1, 0);
2158 M_FST(REG_ZERO, REG_ITMP1, 0);
2161 M_DST(REG_ZERO, REG_ITMP1, 0);
2167 case ICMD_GETFIELD: /* ... ==> ..., value */
2168 /* op1 = type, val.i = field offset */
2170 var_to_reg_int(s1, src, REG_ITMP1);
2171 gen_nullptr_check(s1);
2174 codegen_addpatchref(cd, mcodeptr,
2175 PATCHER_get_putfield,
2176 (unresolved_field *) iptr->target);
2178 if (showdisassemble)
2184 a = ((fieldinfo *) (iptr->val.a))->offset;
2187 switch (iptr->op1) {
2189 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2191 store_reg_to_var_int(iptr->dst, d);
2194 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2196 store_reg_to_var_int(iptr->dst, d);
2199 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2201 store_reg_to_var_int(iptr->dst, d);
2204 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2206 store_reg_to_var_flt(iptr->dst, d);
2209 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2211 store_reg_to_var_flt(iptr->dst, d);
2216 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2217 /* op1 = type, val.a = field address */
2219 var_to_reg_int(s1, src->prev, REG_ITMP1);
2220 gen_nullptr_check(s1);
2222 if (!IS_FLT_DBL_TYPE(iptr->op1)) {
2223 var_to_reg_int(s2, src, REG_ITMP2);
2225 var_to_reg_flt(s2, src, REG_FTMP2);
2229 codegen_addpatchref(cd, mcodeptr,
2230 PATCHER_get_putfield,
2231 (unresolved_field *) iptr->target);
2233 if (showdisassemble)
2239 a = ((fieldinfo *) (iptr->val.a))->offset;
2242 switch (iptr->op1) {
2261 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2262 /* val = value (in current instruction) */
2263 /* op1 = type, val.a = field address (in */
2264 /* following NOP) */
2266 var_to_reg_int(s1, src, REG_ITMP1);
2267 gen_nullptr_check(s1);
2269 if (!iptr[1].val.a) {
2270 codegen_addpatchref(cd, mcodeptr,
2271 PATCHER_get_putfield,
2272 (unresolved_field *) iptr[1].target);
2274 if (showdisassemble)
2280 a = ((fieldinfo *) (iptr[1].val.a))->offset;
2283 switch (iptr[1].op1) {
2285 M_IST(REG_ZERO, s1, a);
2288 M_LST(REG_ZERO, s1, a);
2291 M_AST(REG_ZERO, s1, a);
2294 M_FST(REG_ZERO, s1, a);
2297 M_DST(REG_ZERO, s1, a);
2303 /* branch operations **************************************************/
2305 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2307 var_to_reg_int(s1, src, REG_ITMP1);
2308 M_INTMOVE(s1, REG_ITMP1_XPTR);
2309 a = dseg_addaddress(cd, asm_handle_exception);
2310 M_ALD(REG_ITMP2, REG_PV, a);
2311 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2312 M_NOP; /* nop ensures that XPC is less than the end */
2313 /* of basic block */
2317 case ICMD_GOTO: /* ... ==> ... */
2318 /* op1 = target JavaVM pc */
2320 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2324 case ICMD_JSR: /* ... ==> ... */
2325 /* op1 = target JavaVM pc */
2327 M_BSR(REG_ITMP1, 0);
2328 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2331 case ICMD_RET: /* ... ==> ... */
2332 /* op1 = local variable */
2334 var = &(rd->locals[iptr->op1][TYPE_ADR]);
2335 if (var->flags & INMEMORY) {
2336 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2337 M_RET(REG_ZERO, REG_ITMP1);
2340 M_RET(REG_ZERO, var->regoff);
2344 case ICMD_IFNULL: /* ..., value ==> ... */
2345 /* op1 = target JavaVM pc */
2347 var_to_reg_int(s1, src, REG_ITMP1);
2349 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2352 case ICMD_IFNONNULL: /* ..., value ==> ... */
2353 /* op1 = target JavaVM pc */
2355 var_to_reg_int(s1, src, REG_ITMP1);
2357 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2360 case ICMD_IFEQ: /* ..., value ==> ... */
2361 /* op1 = target JavaVM pc, val.i = constant */
2363 var_to_reg_int(s1, src, REG_ITMP1);
2364 if (iptr->val.i == 0) {
2368 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2369 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2372 ICONST(REG_ITMP2, iptr->val.i);
2373 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2375 M_BNEZ(REG_ITMP1, 0);
2377 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2380 case ICMD_IFLT: /* ..., value ==> ... */
2381 /* op1 = target JavaVM pc, val.i = constant */
2383 var_to_reg_int(s1, src, REG_ITMP1);
2384 if (iptr->val.i == 0) {
2388 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2389 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2392 ICONST(REG_ITMP2, iptr->val.i);
2393 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2395 M_BNEZ(REG_ITMP1, 0);
2397 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2400 case ICMD_IFLE: /* ..., value ==> ... */
2401 /* op1 = target JavaVM pc, val.i = constant */
2403 var_to_reg_int(s1, src, REG_ITMP1);
2404 if (iptr->val.i == 0) {
2408 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2409 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2412 ICONST(REG_ITMP2, iptr->val.i);
2413 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2415 M_BNEZ(REG_ITMP1, 0);
2417 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2420 case ICMD_IFNE: /* ..., value ==> ... */
2421 /* op1 = target JavaVM pc, val.i = constant */
2423 var_to_reg_int(s1, src, REG_ITMP1);
2424 if (iptr->val.i == 0) {
2428 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2429 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2432 ICONST(REG_ITMP2, iptr->val.i);
2433 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2435 M_BEQZ(REG_ITMP1, 0);
2437 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2440 case ICMD_IFGT: /* ..., value ==> ... */
2441 /* op1 = target JavaVM pc, val.i = constant */
2443 var_to_reg_int(s1, src, REG_ITMP1);
2444 if (iptr->val.i == 0) {
2448 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2449 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2452 ICONST(REG_ITMP2, iptr->val.i);
2453 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2455 M_BEQZ(REG_ITMP1, 0);
2457 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2460 case ICMD_IFGE: /* ..., value ==> ... */
2461 /* op1 = target JavaVM pc, val.i = constant */
2463 var_to_reg_int(s1, src, REG_ITMP1);
2464 if (iptr->val.i == 0) {
2468 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2469 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2472 ICONST(REG_ITMP2, iptr->val.i);
2473 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2475 M_BEQZ(REG_ITMP1, 0);
2477 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2480 case ICMD_IF_LEQ: /* ..., value ==> ... */
2481 /* op1 = target JavaVM pc, val.l = constant */
2483 var_to_reg_int(s1, src, REG_ITMP1);
2484 if (iptr->val.l == 0) {
2488 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2489 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2492 LCONST(REG_ITMP2, iptr->val.l);
2493 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2495 M_BNEZ(REG_ITMP1, 0);
2497 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2500 case ICMD_IF_LLT: /* ..., value ==> ... */
2501 /* op1 = target JavaVM pc, val.l = constant */
2503 var_to_reg_int(s1, src, REG_ITMP1);
2504 if (iptr->val.l == 0) {
2508 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2509 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2512 LCONST(REG_ITMP2, iptr->val.l);
2513 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2515 M_BNEZ(REG_ITMP1, 0);
2517 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2520 case ICMD_IF_LLE: /* ..., value ==> ... */
2521 /* op1 = target JavaVM pc, val.l = constant */
2523 var_to_reg_int(s1, src, REG_ITMP1);
2524 if (iptr->val.l == 0) {
2528 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2529 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2532 LCONST(REG_ITMP2, iptr->val.l);
2533 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2535 M_BNEZ(REG_ITMP1, 0);
2537 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2540 case ICMD_IF_LNE: /* ..., value ==> ... */
2541 /* op1 = target JavaVM pc, val.l = constant */
2543 var_to_reg_int(s1, src, REG_ITMP1);
2544 if (iptr->val.l == 0) {
2548 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2549 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2552 LCONST(REG_ITMP2, iptr->val.l);
2553 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2555 M_BEQZ(REG_ITMP1, 0);
2557 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2560 case ICMD_IF_LGT: /* ..., value ==> ... */
2561 /* op1 = target JavaVM pc, val.l = constant */
2563 var_to_reg_int(s1, src, REG_ITMP1);
2564 if (iptr->val.l == 0) {
2568 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2569 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2572 LCONST(REG_ITMP2, iptr->val.l);
2573 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2575 M_BEQZ(REG_ITMP1, 0);
2577 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2580 case ICMD_IF_LGE: /* ..., value ==> ... */
2581 /* op1 = target JavaVM pc, val.l = constant */
2583 var_to_reg_int(s1, src, REG_ITMP1);
2584 if (iptr->val.l == 0) {
2588 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2589 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2592 LCONST(REG_ITMP2, iptr->val.l);
2593 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2595 M_BEQZ(REG_ITMP1, 0);
2597 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2600 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2601 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2602 case ICMD_IF_ACMPEQ:
2604 var_to_reg_int(s1, src->prev, REG_ITMP1);
2605 var_to_reg_int(s2, src, REG_ITMP2);
2606 M_CMPEQ(s1, s2, REG_ITMP1);
2607 M_BNEZ(REG_ITMP1, 0);
2608 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2611 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2612 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2613 case ICMD_IF_ACMPNE:
2615 var_to_reg_int(s1, src->prev, REG_ITMP1);
2616 var_to_reg_int(s2, src, REG_ITMP2);
2617 M_CMPEQ(s1, s2, REG_ITMP1);
2618 M_BEQZ(REG_ITMP1, 0);
2619 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2622 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2623 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2625 var_to_reg_int(s1, src->prev, REG_ITMP1);
2626 var_to_reg_int(s2, src, REG_ITMP2);
2627 M_CMPLT(s1, s2, REG_ITMP1);
2628 M_BNEZ(REG_ITMP1, 0);
2629 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2632 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2633 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2635 var_to_reg_int(s1, src->prev, REG_ITMP1);
2636 var_to_reg_int(s2, src, REG_ITMP2);
2637 M_CMPLE(s1, s2, REG_ITMP1);
2638 M_BEQZ(REG_ITMP1, 0);
2639 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2642 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2643 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2645 var_to_reg_int(s1, src->prev, REG_ITMP1);
2646 var_to_reg_int(s2, src, REG_ITMP2);
2647 M_CMPLE(s1, s2, REG_ITMP1);
2648 M_BNEZ(REG_ITMP1, 0);
2649 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2652 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2653 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2655 var_to_reg_int(s1, src->prev, REG_ITMP1);
2656 var_to_reg_int(s2, src, REG_ITMP2);
2657 M_CMPLT(s1, s2, REG_ITMP1);
2658 M_BEQZ(REG_ITMP1, 0);
2659 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2662 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2664 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2667 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2668 /* val.i = constant */
2670 var_to_reg_int(s1, src, REG_ITMP1);
2671 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2673 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2674 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2675 M_CMPEQ(s1, REG_ZERO, d);
2676 store_reg_to_var_int(iptr->dst, d);
2679 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2680 M_CMPEQ(s1, REG_ZERO, d);
2682 store_reg_to_var_int(iptr->dst, d);
2686 M_MOV(s1, REG_ITMP1);
2689 ICONST(d, iptr[1].val.i);
2691 if ((s3 >= 0) && (s3 <= 255)) {
2692 M_CMOVEQ_IMM(s1, s3, d);
2695 ICONST(REG_ITMP2, s3);
2696 M_CMOVEQ(s1, REG_ITMP2, d);
2698 store_reg_to_var_int(iptr->dst, d);
2701 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2702 /* val.i = constant */
2704 var_to_reg_int(s1, src, REG_ITMP1);
2705 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2707 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2708 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2709 M_CMPEQ(s1, REG_ZERO, d);
2710 store_reg_to_var_int(iptr->dst, d);
2713 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2714 M_CMPEQ(s1, REG_ZERO, d);
2716 store_reg_to_var_int(iptr->dst, d);
2720 M_MOV(s1, REG_ITMP1);
2723 ICONST(d, iptr[1].val.i);
2725 if ((s3 >= 0) && (s3 <= 255)) {
2726 M_CMOVNE_IMM(s1, s3, d);
2729 ICONST(REG_ITMP2, s3);
2730 M_CMOVNE(s1, REG_ITMP2, d);
2732 store_reg_to_var_int(iptr->dst, d);
2735 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2736 /* val.i = constant */
2738 var_to_reg_int(s1, src, REG_ITMP1);
2739 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2741 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2742 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2743 M_CMPLT(s1, REG_ZERO, d);
2744 store_reg_to_var_int(iptr->dst, d);
2747 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2748 M_CMPLE(REG_ZERO, s1, d);
2749 store_reg_to_var_int(iptr->dst, d);
2753 M_MOV(s1, REG_ITMP1);
2756 ICONST(d, iptr[1].val.i);
2758 if ((s3 >= 0) && (s3 <= 255)) {
2759 M_CMOVLT_IMM(s1, s3, d);
2762 ICONST(REG_ITMP2, s3);
2763 M_CMOVLT(s1, REG_ITMP2, d);
2765 store_reg_to_var_int(iptr->dst, d);
2768 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2769 /* val.i = constant */
2771 var_to_reg_int(s1, src, REG_ITMP1);
2772 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2774 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2775 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2776 M_CMPLE(REG_ZERO, s1, d);
2777 store_reg_to_var_int(iptr->dst, d);
2780 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2781 M_CMPLT(s1, REG_ZERO, d);
2782 store_reg_to_var_int(iptr->dst, d);
2786 M_MOV(s1, REG_ITMP1);
2789 ICONST(d, iptr[1].val.i);
2791 if ((s3 >= 0) && (s3 <= 255)) {
2792 M_CMOVGE_IMM(s1, s3, d);
2795 ICONST(REG_ITMP2, s3);
2796 M_CMOVGE(s1, REG_ITMP2, d);
2798 store_reg_to_var_int(iptr->dst, d);
2801 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2802 /* val.i = constant */
2804 var_to_reg_int(s1, src, REG_ITMP1);
2805 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2807 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2808 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2809 M_CMPLT(REG_ZERO, s1, d);
2810 store_reg_to_var_int(iptr->dst, d);
2813 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2814 M_CMPLE(s1, REG_ZERO, d);
2815 store_reg_to_var_int(iptr->dst, d);
2819 M_MOV(s1, REG_ITMP1);
2822 ICONST(d, iptr[1].val.i);
2824 if ((s3 >= 0) && (s3 <= 255)) {
2825 M_CMOVGT_IMM(s1, s3, d);
2828 ICONST(REG_ITMP2, s3);
2829 M_CMOVGT(s1, REG_ITMP2, d);
2831 store_reg_to_var_int(iptr->dst, d);
2834 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2835 /* val.i = constant */
2837 var_to_reg_int(s1, src, REG_ITMP1);
2838 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2840 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2841 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2842 M_CMPLE(s1, REG_ZERO, d);
2843 store_reg_to_var_int(iptr->dst, d);
2846 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2847 M_CMPLT(REG_ZERO, s1, d);
2848 store_reg_to_var_int(iptr->dst, d);
2852 M_MOV(s1, REG_ITMP1);
2855 ICONST(d, iptr[1].val.i);
2857 if ((s3 >= 0) && (s3 <= 255)) {
2858 M_CMOVLE_IMM(s1, s3, d);
2861 ICONST(REG_ITMP2, s3);
2862 M_CMOVLE(s1, REG_ITMP2, d);
2864 store_reg_to_var_int(iptr->dst, d);
2868 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2872 var_to_reg_int(s1, src, REG_RESULT);
2873 M_INTMOVE(s1, REG_RESULT);
2875 goto nowperformreturn;
2877 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2880 var_to_reg_flt(s1, src, REG_FRESULT);
2881 M_FLTMOVE(s1, REG_FRESULT);
2883 goto nowperformreturn;
2885 case ICMD_RETURN: /* ... ==> ... */
2891 p = parentargs_base;
2893 /* call trace function */
2896 M_LDA(REG_SP, REG_SP, -3 * 8);
2897 M_AST(REG_RA, REG_SP, 0 * 8);
2898 M_LST(REG_RESULT, REG_SP, 1 * 8);
2899 M_DST(REG_FRESULT, REG_SP, 2 * 8);
2900 a = dseg_addaddress(cd, m);
2901 M_ALD(rd->argintregs[0], REG_PV, a);
2902 M_MOV(REG_RESULT, rd->argintregs[1]);
2903 M_FLTMOVE(REG_FRESULT, rd->argfltregs[2]);
2904 M_FLTMOVE(REG_FRESULT, rd->argfltregs[3]);
2905 a = dseg_addaddress(cd, (void *) builtin_displaymethodstop);
2906 M_ALD(REG_PV, REG_PV, a);
2907 M_JSR(REG_RA, REG_PV);
2908 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
2909 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
2911 s4 ml = -s1, mh = 0;
2912 while (ml < -32768) { ml += 65536; mh--; }
2913 M_LDA(REG_PV, REG_RA, ml);
2914 M_LDAH(REG_PV, REG_PV, mh);
2916 M_DLD(REG_FRESULT, REG_SP, 2 * 8);
2917 M_LLD(REG_RESULT, REG_SP, 1 * 8);
2918 M_ALD(REG_RA, REG_SP, 0 * 8);
2919 M_LDA(REG_SP, REG_SP, 3 * 8);
2922 #if defined(USE_THREADS)
2923 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2926 M_ALD(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
2928 switch (iptr->opc) {
2932 M_LST(REG_RESULT, REG_SP, rd->maxmemuse * 8);
2936 M_DST(REG_FRESULT, REG_SP, rd->maxmemuse * 8);
2940 a = dseg_addaddress(cd, BUILTIN_monitorexit);
2941 M_ALD(REG_PV, REG_PV, a);
2942 M_JSR(REG_RA, REG_PV);
2943 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
2944 M_LDA(REG_PV, REG_RA, disp);
2946 switch (iptr->opc) {
2950 M_LLD(REG_RESULT, REG_SP, rd->maxmemuse * 8);
2954 M_DLD(REG_FRESULT, REG_SP, rd->maxmemuse * 8);
2960 /* restore return address */
2962 if (!m->isleafmethod) {
2963 p--; M_LLD(REG_RA, REG_SP, p * 8);
2966 /* restore saved registers */
2968 for (i = rd->savintregcnt - 1; i >= rd->maxsavintreguse; i--) {
2969 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2971 for (i = rd->savfltregcnt - 1; i >= rd->maxsavfltreguse; i--) {
2972 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2975 /* deallocate stack */
2977 if (parentargs_base) {
2978 M_LDA(REG_SP, REG_SP, parentargs_base * 8);
2981 M_RET(REG_ZERO, REG_RA);
2987 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2992 tptr = (void **) iptr->target;
2994 s4ptr = iptr->val.a;
2995 l = s4ptr[1]; /* low */
2996 i = s4ptr[2]; /* high */
2998 var_to_reg_int(s1, src, REG_ITMP1);
3000 {M_INTMOVE(s1, REG_ITMP1);}
3001 else if (l <= 32768) {
3002 M_LDA(REG_ITMP1, s1, -l);
3005 ICONST(REG_ITMP2, l);
3006 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
3013 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
3015 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
3016 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3018 M_BEQZ(REG_ITMP2, 0);
3021 /* codegen_addreference(cd, BlockPtrOfPC(s4ptr[0]), mcodeptr); */
3022 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3024 /* build jump table top down and use address of lowest entry */
3026 /* s4ptr += 3 + i; */
3030 /* dseg_addtarget(cd, BlockPtrOfPC(*--s4ptr)); */
3031 dseg_addtarget(cd, (basicblock *) tptr[0]);
3036 /* length of dataseg after last dseg_addtarget is used by load */
3038 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
3039 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
3040 M_JMP(REG_ZERO, REG_ITMP2);
3045 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3047 s4 i, l, val, *s4ptr;
3050 tptr = (void **) iptr->target;
3052 s4ptr = iptr->val.a;
3053 l = s4ptr[0]; /* default */
3054 i = s4ptr[1]; /* count */
3056 MCODECHECK((i<<2)+8);
3057 var_to_reg_int(s1, src, REG_ITMP1);
3063 if ((val >= 0) && (val <= 255)) {
3064 M_CMPEQ_IMM(s1, val, REG_ITMP2);
3067 if ((val >= -32768) && (val <= 32767)) {
3068 M_LDA(REG_ITMP2, REG_ZERO, val);
3071 a = dseg_adds4(cd, val);
3072 M_ILD(REG_ITMP2, REG_PV, a);
3074 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
3076 M_BNEZ(REG_ITMP2, 0);
3077 /* codegen_addreference(cd, BlockPtrOfPC(s4ptr[1]), mcodeptr); */
3078 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3082 /* codegen_addreference(cd, BlockPtrOfPC(l), mcodeptr); */
3084 tptr = (void **) iptr->target;
3085 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3092 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
3093 /* op1 = arg count val.a = builtintable entry */
3099 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3100 /* op1 = arg count, val.a = method pointer */
3102 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3103 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
3104 case ICMD_INVOKEINTERFACE:
3109 md = lm->parseddesc;
3111 unresolved_method *um = iptr->target;
3112 md = um->methodref->parseddesc.md;
3118 MCODECHECK((s3 << 1) + 64);
3120 /* copy arguments to registers or stack location */
3122 for (s3 = s3 - 1; s3 >= 0; s3--, src = src->prev) {
3123 if (src->varkind == ARGVAR)
3125 if (IS_INT_LNG_TYPE(src->type)) {
3126 if (!md->params[s3].inmemory) {
3127 s1 = rd->argintregs[md->params[s3].regoff];
3128 var_to_reg_int(d, src, s1);
3131 var_to_reg_int(d, src, REG_ITMP1);
3132 M_LST(d, REG_SP, md->params[s3].regoff * 8);
3136 if (!md->params[s3].inmemory) {
3137 s1 = rd->argfltregs[md->params[s3].regoff];
3138 var_to_reg_flt(d, src, s1);
3141 var_to_reg_flt(d, src, REG_FTMP1);
3142 M_DST(d, REG_SP, md->params[s3].regoff * 8);
3147 switch (iptr->opc) {
3150 codegen_addpatchref(cd, mcodeptr, bte->fp, iptr->target);
3152 if (showdisassemble)
3158 a = (ptrint) bte->fp;
3161 a = dseg_addaddress(cd, a);
3162 d = md->returntype.type;
3164 M_ALD(REG_PV, REG_PV, a); /* Pointer to built-in-function */
3167 case ICMD_INVOKESPECIAL:
3168 gen_nullptr_check(rd->argintregs[0]);
3169 M_ILD(REG_ITMP1, rd->argintregs[0], 0); /* hardware nullptr */
3172 case ICMD_INVOKESTATIC:
3174 unresolved_method *um = iptr->target;
3176 codegen_addpatchref(cd, mcodeptr,
3177 PATCHER_invokestatic_special, um);
3179 if (showdisassemble)
3183 d = um->methodref->parseddesc.md->returntype.type;
3186 a = (ptrint) lm->stubroutine;
3187 d = lm->parseddesc->returntype.type;
3190 a = dseg_addaddress(cd, a);
3191 M_ALD(REG_PV, REG_PV, a); /* method pointer in r27 */
3194 case ICMD_INVOKEVIRTUAL:
3195 gen_nullptr_check(rd->argintregs[0]);
3198 unresolved_method *um = iptr->target;
3200 codegen_addpatchref(cd, mcodeptr,
3201 PATCHER_invokevirtual, um);
3203 if (showdisassemble)
3207 d = um->methodref->parseddesc.md->returntype.type;
3210 s1 = OFFSET(vftbl_t, table[0]) +
3211 sizeof(methodptr) * lm->vftblindex;
3212 d = lm->parseddesc->returntype.type;
3215 M_ALD(REG_METHODPTR, rd->argintregs[0],
3216 OFFSET(java_objectheader, vftbl));
3217 M_ALD(REG_PV, REG_METHODPTR, s1);
3220 case ICMD_INVOKEINTERFACE:
3221 gen_nullptr_check(rd->argintregs[0]);
3224 unresolved_method *um = iptr->target;
3226 codegen_addpatchref(cd, mcodeptr,
3227 PATCHER_invokeinterface, um);
3229 if (showdisassemble)
3234 d = um->methodref->parseddesc.md->returntype.type;
3237 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3238 sizeof(methodptr*) * lm->class->index;
3240 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3242 d = lm->parseddesc->returntype.type;
3245 M_ALD(REG_METHODPTR, rd->argintregs[0],
3246 OFFSET(java_objectheader, vftbl));
3247 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3248 M_ALD(REG_PV, REG_METHODPTR, s2);
3252 M_JSR(REG_RA, REG_PV);
3256 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3257 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3259 s4 ml = -s1, mh = 0;
3260 while (ml < -32768) { ml += 65536; mh--; }
3261 M_LDA(REG_PV, REG_RA, ml);
3262 M_LDAH(REG_PV, REG_PV, mh);
3265 /* d contains return type */
3267 if (d != TYPE_VOID) {
3268 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3269 s1 = reg_of_var(rd, iptr->dst, REG_RESULT);
3270 M_INTMOVE(REG_RESULT, s1);
3271 store_reg_to_var_int(iptr->dst, s1);
3273 s1 = reg_of_var(rd, iptr->dst, REG_FRESULT);
3274 M_FLTMOVE(REG_FRESULT, s1);
3275 store_reg_to_var_flt(iptr->dst, s1);
3281 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3283 /* op1: 0 == array, 1 == class */
3284 /* val.a: (classinfo*) superclass */
3286 /* superclass is an interface:
3288 * OK if ((sub == NULL) ||
3289 * (sub->vftbl->interfacetablelength > super->index) &&
3290 * (sub->vftbl->interfacetable[-super->index] != NULL));
3292 * superclass is a class:
3294 * OK if ((sub == NULL) || (0
3295 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3296 * super->vftbl->diffval));
3301 vftbl_t *supervftbl;
3304 super = (classinfo *) iptr->val.a;
3311 superindex = super->index;
3312 supervftbl = super->vftbl;
3315 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3316 codegen_threadcritrestart(cd, (u1 *) mcodeptr - cd->mcodebase);
3318 var_to_reg_int(s1, src, REG_ITMP1);
3320 /* calculate interface checkcast code size */
3324 s2 += showdisassemble ? 1 : 0;
3326 /* calculate class checkcast code size */
3328 s3 = 9 /* 8 + (s1 == REG_ITMP1) */;
3330 s3 += showdisassemble ? 1 : 0;
3332 /* if class is not resolved, check which code to call */
3335 M_BEQZ(s1, 4 + (showdisassemble ? 1 : 0) + s2 + 1 + s3);
3337 codegen_addpatchref(cd, mcodeptr,
3338 PATCHER_checkcast_instanceof_flags,
3339 (constant_classref *) iptr->target);
3341 if (showdisassemble)
3344 a = dseg_adds4(cd, 0); /* super->flags */
3345 M_ILD(REG_ITMP2, REG_PV, a);
3346 a = dseg_adds4(cd, ACC_INTERFACE);
3347 M_ILD(REG_ITMP3, REG_PV, a);
3348 M_AND(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3349 M_BEQZ(REG_ITMP2, s2 + 1);
3352 /* interface checkcast code */
3354 if (!super || (super->flags & ACC_INTERFACE)) {
3359 codegen_addpatchref(cd, mcodeptr,
3360 PATCHER_checkcast_instanceof_interface,
3361 (constant_classref *) iptr->target);
3363 if (showdisassemble)
3367 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3368 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
3369 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
3370 M_BLEZ(REG_ITMP3, 0);
3371 codegen_addxcastrefs(cd, mcodeptr);
3372 M_ALD(REG_ITMP3, REG_ITMP2,
3373 OFFSET(vftbl_t, interfacetable[0]) -
3374 superindex * sizeof(methodptr*));
3375 M_BEQZ(REG_ITMP3, 0);
3376 codegen_addxcastrefs(cd, mcodeptr);
3382 /* class checkcast code */
3384 if (!super || !(super->flags & ACC_INTERFACE)) {
3389 codegen_addpatchref(cd, mcodeptr,
3390 PATCHER_checkcast_instanceof_class,
3391 (constant_classref *) iptr->target);
3393 if (showdisassemble)
3397 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3398 a = dseg_addaddress(cd, supervftbl);
3399 M_ALD(REG_ITMP3, REG_PV, a);
3400 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3401 codegen_threadcritstart(cd, (u1 *) mcodeptr - cd->mcodebase);
3403 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3404 /* if (s1 != REG_ITMP1) { */
3405 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3406 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3407 /* #if defined(USE_THREADS) && defined(NATIVE_THREADS) */
3408 /* codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase); */
3410 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3413 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3414 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3415 M_ALD(REG_ITMP3, REG_PV, a);
3416 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3417 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3418 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3421 M_CMPULE(REG_ITMP2, REG_ITMP3, REG_ITMP3);
3422 M_BEQZ(REG_ITMP3, 0);
3423 codegen_addxcastrefs(cd, mcodeptr);
3425 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
3427 store_reg_to_var_int(iptr->dst, d);
3431 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3433 /* op1: 0 == array, 1 == class */
3434 /* val.a: (classinfo*) superclass */
3436 /* superclass is an interface:
3438 * return (sub != NULL) &&
3439 * (sub->vftbl->interfacetablelength > super->index) &&
3440 * (sub->vftbl->interfacetable[-super->index] != NULL);
3442 * superclass is a class:
3444 * return ((sub != NULL) && (0
3445 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3446 * super->vftbl->diffvall));
3451 vftbl_t *supervftbl;
3454 super = (classinfo *) iptr->val.a;
3461 superindex = super->index;
3462 supervftbl = super->vftbl;
3465 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3466 codegen_threadcritrestart(cd, (u1 *) mcodeptr - cd->mcodebase);
3468 var_to_reg_int(s1, src, REG_ITMP1);
3469 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
3471 M_MOV(s1, REG_ITMP1);
3475 /* calculate interface instanceof code size */
3479 s2 += (d == REG_ITMP2 ? 1 : 0) + (showdisassemble ? 1 : 0);
3481 /* calculate class instanceof code size */
3485 s3 += (showdisassemble ? 1 : 0);
3487 /* if class is not resolved, check which code to call */
3491 M_BEQZ(s1, 4 + (showdisassemble ? 1 : 0) + s2 + 1 + s3);
3493 codegen_addpatchref(cd, mcodeptr,
3494 PATCHER_checkcast_instanceof_flags,
3495 (constant_classref *) iptr->target);
3497 if (showdisassemble)
3500 a = dseg_adds4(cd, 0); /* super->flags */
3501 M_ILD(REG_ITMP3, REG_PV, a);
3502 a = dseg_adds4(cd, ACC_INTERFACE);
3503 M_ILD(REG_ITMP2, REG_PV, a);
3504 M_AND(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3505 M_BEQZ(REG_ITMP3, s2 + 1);
3508 /* interface instanceof code */
3510 if (!super || (super->flags & ACC_INTERFACE)) {
3516 /* If d == REG_ITMP2, then it's destroyed in check code */
3521 codegen_addpatchref(cd, mcodeptr,
3522 PATCHER_checkcast_instanceof_interface,
3523 (constant_classref *) iptr->target);
3525 if (showdisassemble)
3529 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3530 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3531 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
3532 M_BLEZ(REG_ITMP3, 2);
3533 M_ALD(REG_ITMP1, REG_ITMP1,
3534 OFFSET(vftbl_t, interfacetable[0]) -
3535 superindex * sizeof(methodptr*));
3536 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3542 /* class instanceof code */
3544 if (!super || !(super->flags & ACC_INTERFACE)) {
3550 codegen_addpatchref(cd, mcodeptr,
3551 PATCHER_checkcast_instanceof_class,
3552 (constant_classref *) iptr->target);
3554 if (showdisassemble)
3558 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3559 a = dseg_addaddress(cd, supervftbl);
3560 M_ALD(REG_ITMP2, REG_PV, a);
3561 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3562 codegen_threadcritstart(cd, (u1 *) mcodeptr - cd->mcodebase);
3564 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3565 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3566 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3567 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3568 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3570 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3571 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3573 store_reg_to_var_int(iptr->dst, d);
3578 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
3580 var_to_reg_int(s1, src, REG_ITMP1);
3582 codegen_addxcheckarefs(cd, mcodeptr);
3585 case ICMD_CHECKEXCEPTION: /* ... ==> ... */
3587 M_BEQZ(REG_RESULT, 0);
3588 codegen_addxexceptionrefs(cd, mcodeptr);
3591 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3592 /* op1 = dimension, val.a = array descriptor */
3594 /* check for negative sizes and copy sizes to stack if necessary */
3596 MCODECHECK((iptr->op1 << 1) + 64);
3598 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3599 var_to_reg_int(s2, src, REG_ITMP1);
3601 codegen_addxcheckarefs(cd, mcodeptr);
3603 /* copy SAVEDVAR sizes to stack */
3605 if (src->varkind != ARGVAR) {
3606 M_LST(s2, REG_SP, s1 * 8);
3610 /* is patcher function set? */
3613 codegen_addpatchref(cd, mcodeptr,
3614 (functionptr) iptr->target, iptr->val.a);
3616 if (showdisassemble)
3622 a = (ptrint) iptr->val.a;
3625 /* a0 = dimension count */
3627 ICONST(rd->argintregs[0], iptr->op1);
3629 /* a1 = arraydescriptor */
3631 a = dseg_addaddress(cd, a);
3632 M_ALD(rd->argintregs[1], REG_PV, a);
3634 /* a2 = pointer to dimensions = stack pointer */
3636 M_INTMOVE(REG_SP, rd->argintregs[2]);
3638 a = dseg_addaddress(cd, (void *) BUILTIN_multianewarray);
3639 M_ALD(REG_PV, REG_PV, a);
3640 M_JSR(REG_RA, REG_PV);
3641 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3643 M_LDA(REG_PV, REG_RA, -s1);
3645 s4 ml = -s1, mh = 0;
3646 while (ml < -32768) { ml += 65536; mh--; }
3647 M_LDA(REG_PV, REG_RA, ml);
3648 M_LDAH(REG_PV, REG_PV, mh);
3650 s1 = reg_of_var(rd, iptr->dst, REG_RESULT);
3651 M_INTMOVE(REG_RESULT, s1);
3652 store_reg_to_var_int(iptr->dst, s1);
3656 throw_cacao_exception_exit(string_java_lang_InternalError,
3657 "Unknown ICMD %d", iptr->opc);
3660 } /* for instruction */
3662 /* copy values to interface registers */
3664 src = bptr->outstack;
3665 len = bptr->outdepth;
3672 if ((src->varkind != STACKVAR)) {
3674 if (IS_FLT_DBL_TYPE(s2)) {
3675 var_to_reg_flt(s1, src, REG_FTMP1);
3676 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3677 M_FLTMOVE(s1,rd->interfaces[len][s2].regoff);
3680 M_DST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3684 var_to_reg_int(s1, src, REG_ITMP1);
3685 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3686 M_INTMOVE(s1,rd->interfaces[len][s2].regoff);
3689 M_LST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3695 } /* if (bptr -> flags >= BBREACHED) */
3696 } /* for basic block */
3698 codegen_createlinenumbertable(cd);
3701 /* generate bound check stubs */
3703 s4 *xcodeptr = NULL;
3706 for (bref = cd->xboundrefs; bref != NULL; bref = bref->next) {
3707 gen_resolvebranch((u1*) cd->mcodebase + bref->branchpos,
3709 (u1*) mcodeptr - cd->mcodebase);
3713 /* move index register into REG_ITMP1 */
3714 M_MOV(bref->reg, REG_ITMP1);
3715 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3717 if (xcodeptr != NULL) {
3718 M_BR(xcodeptr - mcodeptr - 1);
3721 xcodeptr = mcodeptr;
3723 a = dseg_addaddress(cd, asm_throw_and_handle_arrayindexoutofbounds_exception);
3724 M_ALD(REG_PV, REG_PV, a);
3726 M_JSR(REG_RA, REG_PV);
3729 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3730 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3732 s4 ml = -s1, mh = 0;
3733 while (ml < -32768) { ml += 65536; mh--; }
3734 M_LDA(REG_PV, REG_RA, ml);
3735 M_LDAH(REG_PV, REG_PV, mh);
3740 /* generate negative array size check stubs */
3744 for (bref = cd->xcheckarefs; bref != NULL; bref = bref->next) {
3745 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3746 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3748 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3752 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3754 (u1 *) mcodeptr - cd->mcodebase);
3758 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3760 if (xcodeptr != NULL) {
3761 M_BR(xcodeptr - mcodeptr - 1);
3764 xcodeptr = mcodeptr;
3766 a = dseg_addaddress(cd, string_java_lang_NegativeArraySizeException);
3767 M_ALD(REG_ITMP1_XPTR,REG_PV,a);
3769 a = dseg_addaddress(cd, asm_throw_and_handle_nat_exception);
3770 M_ALD(REG_PV, REG_PV, a);
3772 M_JSR(REG_RA, REG_PV);
3775 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3776 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3778 s4 ml = -s1, mh = 0;
3779 while (ml < -32768) { ml += 65536; mh--; }
3780 M_LDA(REG_PV, REG_RA, ml);
3781 M_LDAH(REG_PV, REG_PV, mh);
3786 /* generate cast check stubs */
3790 for (bref = cd->xcastrefs; bref != NULL; bref = bref->next) {
3791 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3792 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3794 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3798 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3800 (u1 *) mcodeptr - cd->mcodebase);
3804 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3806 if (xcodeptr != NULL) {
3807 M_BR(xcodeptr - mcodeptr - 1);
3810 xcodeptr = mcodeptr;
3812 a = dseg_addaddress(cd, string_java_lang_ClassCastException);
3813 M_ALD(REG_ITMP1_XPTR,REG_PV,a);
3815 a = dseg_addaddress(cd, asm_throw_and_handle_nat_exception);
3816 M_ALD(REG_PV, REG_PV, a);
3818 M_JSR(REG_RA, REG_PV);
3821 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3822 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3824 s4 ml = -s1, mh = 0;
3825 while (ml < -32768) { ml += 65536; mh--; }
3826 M_LDA(REG_PV, REG_RA, ml);
3827 M_LDAH(REG_PV, REG_PV, mh);
3832 /* generate exception check stubs */
3836 for (bref = cd->xexceptionrefs; bref != NULL; bref = bref->next) {
3837 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3838 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3840 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3844 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3846 (u1 *) mcodeptr - cd->mcodebase);
3850 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3852 if (xcodeptr != NULL) {
3853 M_BR(xcodeptr - mcodeptr - 1);
3856 xcodeptr = mcodeptr;
3858 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3859 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3860 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3862 a = dseg_addaddress(cd, &builtin_get_exceptionptrptr);
3863 M_ALD(REG_PV, REG_PV, a);
3864 M_JSR(REG_RA, REG_PV);
3867 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3868 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3870 s4 ml = -s1, mh = 0;
3871 while (ml < -32768) { ml += 65536; mh--; }
3872 M_LDA(REG_PV, REG_RA, ml);
3873 M_LDAH(REG_PV, REG_PV, mh);
3876 M_ALD(REG_ITMP1_XPTR, REG_RESULT, 0);
3877 M_AST(REG_ZERO, REG_RESULT, 0);
3879 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3880 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3882 a = dseg_addaddress(cd, &_exceptionptr);
3883 M_ALD(REG_ITMP3, REG_PV, a);
3884 M_ALD(REG_ITMP1_XPTR, REG_ITMP3, 0);
3885 M_AST(REG_ZERO, REG_ITMP3, 0);
3888 a = dseg_addaddress(cd, asm_refillin_and_handle_exception);
3889 M_ALD(REG_PV, REG_PV, a);
3891 M_JMP(REG_RA, REG_PV);
3894 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3895 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3897 s4 ml = -s1, mh = 0;
3898 while (ml < -32768) { ml += 65536; mh--; }
3899 M_LDA(REG_PV, REG_RA, ml);
3900 M_LDAH(REG_PV, REG_PV, mh);
3906 /* generate null pointer check stubs */
3910 for (bref = cd->xnullrefs; bref != NULL; bref = bref->next) {
3911 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3912 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3914 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3918 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3920 (u1 *) mcodeptr - cd->mcodebase);
3924 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3926 if (xcodeptr != NULL) {
3927 M_BR(xcodeptr - mcodeptr - 1);
3930 xcodeptr = mcodeptr;
3932 a = dseg_addaddress(cd, string_java_lang_NullPointerException);
3933 M_ALD(REG_ITMP1_XPTR,REG_PV,a);
3935 a = dseg_addaddress(cd, asm_throw_and_handle_nat_exception);
3936 M_ALD(REG_PV, REG_PV, a);
3938 M_JSR(REG_RA, REG_PV);
3941 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3942 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3944 s4 ml = -s1, mh = 0;
3945 while (ml < -32768) { ml += 65536; mh--; }
3946 M_LDA(REG_PV, REG_RA, ml);
3947 M_LDAH(REG_PV, REG_PV, mh);
3952 /* generate put/getstatic stub call code */
3959 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
3960 /* check code segment size */
3962 MCODECHECK(13 + 4 + 1);
3964 /* Get machine code which is patched back in later. The call is */
3965 /* 1 instruction word long. */
3967 xcodeptr = (s4 *) (cd->mcodebase + pref->branchpos);
3970 /* patch in the call to call the following code (done at compile */
3973 tmpmcodeptr = mcodeptr; /* save current mcodeptr */
3974 mcodeptr = xcodeptr; /* set mcodeptr to patch position */
3976 M_BSR(REG_ITMP3, tmpmcodeptr - (xcodeptr + 1));
3978 mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
3980 /* create stack frame */
3982 M_LSUB_IMM(REG_SP, 5 * 8, REG_SP);
3984 /* move return address onto stack */
3986 M_AST(REG_ITMP3, REG_SP, 4 * 8);
3988 /* move pointer to java_objectheader onto stack */
3990 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3991 /* create a virtual java_objectheader */
3993 (void) dseg_addaddress(cd, get_dummyLR()); /* monitorPtr */
3994 a = dseg_addaddress(cd, NULL); /* vftbl */
3997 M_LDA(REG_ITMP3, REG_PV, a);
3999 M_LDAH(REG_ITMP3, REG_PV, (a >> 16) & 0x0000ffff);
4000 M_LDA(REG_ITMP3, REG_ITMP3, a & 0x0000ffff);
4002 M_AST(REG_ITMP3, REG_SP, 3 * 8);
4004 M_AST(REG_ZERO, REG_SP, 3 * 8);
4007 /* move machine code onto stack */
4009 a = dseg_adds4(cd, mcode);
4011 M_ILD(REG_ITMP3, REG_PV, a);
4013 M_LDAH(REG_ITMP3, REG_PV, (a >> 16) & 0x0000ffff);
4014 M_ILD(REG_ITMP3, REG_ITMP3, a & 0x0000ffff);
4016 M_IST(REG_ITMP3, REG_SP, 2 * 8);
4018 /* move class/method/field reference onto stack */
4020 a = dseg_addaddress(cd, pref->ref);
4022 M_ALD(REG_ITMP3, REG_PV, a);
4024 M_LDAH(REG_ITMP3, REG_PV, (a >> 16) & 0x0000ffff);
4025 M_ALD(REG_ITMP3, REG_ITMP3, a & 0x0000ffff);
4027 M_AST(REG_ITMP3, REG_SP, 1 * 8);
4029 /* move patcher function pointer onto stack */
4031 a = dseg_addaddress(cd, pref->patcher);
4033 M_ALD(REG_ITMP3, REG_PV, a);
4035 M_LDAH(REG_ITMP3, REG_PV, (a >> 16) & 0x0000ffff);
4036 M_ALD(REG_ITMP3, REG_ITMP3, a & 0x0000ffff);
4038 M_AST(REG_ITMP3, REG_SP, 0 * 8);
4040 a = dseg_addaddress(cd, asm_wrapper_patcher);
4042 M_ALD(REG_ITMP3, REG_PV, a);
4044 M_LDAH(REG_ITMP3, REG_PV, (a >> 16) & 0x0000ffff);
4045 M_ALD(REG_ITMP3, REG_ITMP3, a & 0x0000ffff);
4047 M_JMP(REG_ZERO, REG_ITMP3);
4052 codegen_finish(m, cd, (s4) ((u1 *) mcodeptr - cd->mcodebase));
4056 /* createcompilerstub **********************************************************
4058 Creates a stub routine which calls the compiler.
4060 *******************************************************************************/
4062 #define COMPSTUBSIZE 3
4064 functionptr createcompilerstub(methodinfo *m)
4066 u8 *s = CNEW(u8, COMPSTUBSIZE); /* memory to hold the stub */
4067 s4 *mcodeptr = (s4 *) s; /* code generation pointer */
4069 /* code for the stub */
4070 M_ALD(REG_PV, REG_PV, 16); /* load pointer to the compiler */
4071 M_JMP(0, REG_PV); /* jump to the compiler, return address
4072 in reg 0 is used as method pointer */
4073 s[1] = (ptrint) m; /* literals to be adressed */
4074 s[2] = (ptrint) asm_call_jit_compiler; /* jump directly via PV from above */
4076 #if defined(STATISTICS)
4078 count_cstub_len += COMPSTUBSIZE * 8;
4081 return (functionptr) s;
4085 /* createnativestub ************************************************************
4087 Creates a stub routine which calls a native method.
4089 *******************************************************************************/
4091 functionptr createnativestub(functionptr f, methodinfo *m, codegendata *cd,
4092 registerdata *rd, methoddesc *nmd)
4094 s4 *mcodeptr; /* code generation pointer */
4095 s4 stackframesize; /* size of stackframe if needed */
4099 s4 i, j; /* count variables */
4103 /* initialize variables */
4106 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
4109 /* calculate stack frame size */
4112 1 + /* return address */
4113 6 + /* dynamic stack info */
4114 1 + /* methodinfo for call trace */
4115 (md->paramcount > INT_ARG_CNT ? INT_ARG_CNT : md->paramcount) +
4119 /* create method header */
4121 (void) dseg_addaddress(cd, m); /* MethodPointer */
4122 (void) dseg_adds4(cd, stackframesize * 8); /* FrameSize */
4123 (void) dseg_adds4(cd, 0); /* IsSync */
4124 (void) dseg_adds4(cd, 0); /* IsLeaf */
4125 (void) dseg_adds4(cd, 0); /* IntSave */
4126 (void) dseg_adds4(cd, 0); /* FltSave */
4127 (void) dseg_addlinenumbertablesize(cd);
4128 (void) dseg_adds4(cd, 0); /* ExTableSize */
4131 /* initialize mcode variables */
4133 mcodeptr = (s4 *) cd->mcodebase;
4134 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
4137 /* generate stub code */
4139 M_LDA(REG_SP, REG_SP, -stackframesize * 8);
4140 M_AST(REG_RA, REG_SP, (stackframesize - 1) * 8);
4143 /* if function is static, check for initialized */
4145 if ((m->flags & ACC_STATIC) && !m->class->initialized) {
4146 codegen_addpatchref(cd, mcodeptr, PATCHER_clinit, m->class);
4148 if (showdisassemble)
4152 /* call trace function */
4155 /* save integer argument registers */
4157 for (i = 0, j = 1; i < md->paramcount && i < INT_ARG_CNT; i++)
4158 if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
4159 M_LST(rd->argintregs[i], REG_SP, j++ * 8);
4161 /* save and copy float arguments into integer registers */
4163 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4164 t = md->paramtypes[i].type;
4166 if (IS_FLT_DBL_TYPE(t)) {
4167 if (IS_2_WORD_TYPE(t)) {
4168 M_DST(rd->argfltregs[i], REG_SP, j * 8);
4169 M_LLD(rd->argintregs[i], REG_SP, j * 8);
4171 M_FST(rd->argfltregs[i], REG_SP, j * 8);
4172 M_ILD(rd->argintregs[i], REG_SP, j * 8);
4178 off = dseg_addaddress(cd, m);
4179 M_ALD(REG_ITMP1, REG_PV, off);
4180 M_AST(REG_ITMP1, REG_SP, 0 * 8);
4181 off = dseg_addaddress(cd, builtin_trace_args);
4182 M_ALD(REG_PV, REG_PV, off);
4183 M_JSR(REG_RA, REG_PV);
4184 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4185 M_LDA(REG_PV, REG_RA, -disp);
4187 for (i = 0, j = 1; i < md->paramcount && i < INT_ARG_CNT; i++)
4188 if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
4189 M_LLD(rd->argintregs[i], REG_SP, j++ * 8);
4191 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4192 t = md->paramtypes[i].type;
4194 if (IS_FLT_DBL_TYPE(t)) {
4195 if (IS_2_WORD_TYPE(t)) {
4196 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
4198 M_FLD(rd->argfltregs[i], REG_SP, j * 8);
4206 /* save integer and float argument registers */
4208 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++)
4209 if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
4210 M_LST(rd->argintregs[i], REG_SP, j++ * 8);
4212 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++)
4213 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type))
4214 M_DST(rd->argfltregs[i], REG_SP, j++ * 8);
4216 /* create native stack info */
4218 off = dseg_addaddress(cd, builtin_asm_get_stackframeinfo);
4219 M_ALD(REG_PV, REG_PV, off);
4220 M_JSR(REG_RA, REG_PV);
4221 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4222 M_LDA(REG_PV, REG_RA, -disp);
4224 M_LST(REG_RESULT, REG_SP, (stackframesize - 5) * 8); /* save adress of pointer */
4225 M_LLD(REG_ITMP2, REG_RESULT, 0); /* get pointer */
4226 M_LST(REG_ITMP2, REG_SP, (stackframesize - 6) * 8); /* save old value */
4227 M_LDA(REG_ITMP3, REG_SP, (stackframesize - 6) * 8); /* calculate new value */
4228 M_LST(REG_ITMP3, REG_RESULT, 0); /* store new value */
4229 off = dseg_addaddress(cd, m);
4230 M_LLD(REG_ITMP2, REG_PV, off);
4231 M_LST(REG_ITMP2, REG_SP, (stackframesize - 4) * 8);
4232 M_LST(REG_ZERO, REG_SP, (stackframesize - 3) * 8);
4233 M_LST(REG_ZERO, REG_SP, (stackframesize - 2) * 8);
4235 /* restore integer and float argument registers */
4237 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++)
4238 if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
4239 M_LLD(rd->argintregs[i], REG_SP, j++ * 8);
4241 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++)
4242 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type))
4243 M_DLD(rd->argfltregs[i], REG_SP, j++ * 8);
4246 /* copy or spill arguments to new locations */
4248 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
4249 t = md->paramtypes[i].type;
4251 if (IS_INT_LNG_TYPE(t)) {
4252 if (!md->params[i].inmemory) {
4253 s1 = rd->argintregs[md->params[i].regoff];
4255 if (!nmd->params[j].inmemory) {
4256 s2 = rd->argintregs[nmd->params[j].regoff];
4260 s2 = nmd->params[j].regoff;
4261 M_LST(s1, REG_SP, s2 * 8);
4265 s1 = md->params[i].regoff + stackframesize;
4266 s2 = nmd->params[j].regoff;
4267 M_LLD(REG_ITMP1, REG_SP, s1 * 8);
4268 M_LST(REG_ITMP1, REG_SP, s2 * 8);
4272 if (!md->params[i].inmemory) {
4273 s1 = rd->argfltregs[md->params[i].regoff];
4275 if (!nmd->params[j].inmemory) {
4276 s2 = rd->argfltregs[nmd->params[j].regoff];
4280 s2 = nmd->params[j].regoff;
4281 M_DST(s1, REG_SP, s2 * 8);
4285 s1 = md->params[i].regoff + stackframesize;
4286 s2 = nmd->params[j].regoff;
4287 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
4288 M_DST(REG_FTMP1, REG_SP, s2 * 8);
4293 /* put class into second argument register */
4295 if (m->flags & ACC_STATIC) {
4296 off = dseg_addaddress(cd, m->class);
4297 M_ALD(rd->argintregs[1], REG_PV, off);
4300 /* put env into first argument register */
4302 off = dseg_addaddress(cd, &env);
4303 M_ALD(rd->argintregs[0], REG_PV, off);
4305 /* do the native function call */
4307 #if !defined(STATIC_CLASSPATH)
4309 codegen_addpatchref(cd, mcodeptr, PATCHER_resolve_native, m);
4311 if (showdisassemble)
4316 off = dseg_addaddress(cd, f);
4317 M_ALD(REG_PV, REG_PV, off); /* load adress of native method */
4318 M_JSR(REG_RA, REG_PV); /* call native method */
4319 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4320 M_LDA(REG_PV, REG_RA, -disp); /* recompute pv from ra */
4323 /* remove native stack info */
4325 M_LLD(REG_ITMP3, REG_SP, (stackframesize - 5) * 8); /* get address of stacktrace helper pointer */
4326 M_LLD(REG_ITMP1, REG_SP, (stackframesize - 6) * 8); /* get old value */
4327 M_LST(REG_ITMP1, REG_ITMP3, 0); /* set old value */
4330 /* call finished trace */
4333 M_LST(REG_RESULT, REG_SP, 0 * 8);
4334 M_DST(REG_FRESULT, REG_SP, 1 * 8);
4336 off = dseg_addaddress(cd, m);
4337 M_ALD(rd->argintregs[0], REG_PV, off);
4339 M_MOV(REG_RESULT, rd->argintregs[1]);
4340 M_FMOV(REG_FRESULT, rd->argfltregs[2]);
4341 M_FMOV(REG_FRESULT, rd->argfltregs[3]);
4343 off = dseg_addaddress(cd, builtin_displaymethodstop);
4344 M_ALD(REG_PV, REG_PV, off);
4345 M_JSR(REG_RA, REG_PV);
4346 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4347 M_LDA(REG_PV, REG_RA, -disp);
4349 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4350 M_DLD(REG_FRESULT, REG_SP, 1 * 8);
4354 /* check for exception */
4356 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4357 if (IS_FLT_DBL_TYPE(md->returntype.type))
4358 M_DST(REG_FRESULT, REG_SP, 0 * 8);
4360 M_AST(REG_RESULT, REG_SP, 0 * 8);
4362 off = dseg_addaddress(cd, builtin_get_exceptionptrptr);
4363 M_ALD(REG_PV, REG_PV, off);
4364 M_JSR(REG_RA, REG_PV);
4365 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4366 M_LDA(REG_PV, REG_RA, -disp);
4367 M_MOV(REG_RESULT, REG_ITMP3);
4369 if (IS_FLT_DBL_TYPE(md->returntype.type))
4370 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4372 M_ALD(REG_RESULT, REG_SP, 0 * 8);
4374 off = dseg_addaddress(cd, &_exceptionptr);
4375 M_ALD(REG_ITMP3, REG_PV, off); /* get address of exceptionptr */
4378 M_ALD(REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
4379 M_BNEZ(REG_ITMP1, 3); /* if no exception then return */
4381 M_ALD(REG_RA, REG_SP, (stackframesize - 1) * 8); /* load return address */
4383 M_LDA(REG_SP, REG_SP, stackframesize * 8);
4385 M_RET(REG_ZERO, REG_RA); /* return to caller */
4387 /* handle exception */
4389 M_AST(REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
4391 M_ALD(REG_RA, REG_SP, (stackframesize - 1) * 8); /* load return address */
4392 M_LDA(REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
4394 M_LDA(REG_SP, REG_SP, stackframesize * 8);
4396 off = dseg_addaddress(cd, asm_handle_nat_exception);
4397 M_ALD(REG_ITMP3, REG_PV, off); /* load asm exception handler address */
4398 M_JMP(REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
4401 /* process patcher calls **************************************************/
4409 /* there can only be one <clinit> ref entry */
4410 pref = cd->patchrefs;
4412 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
4413 /* Get machine code which is patched back in later. The call is */
4414 /* 1 instruction word long. */
4416 xcodeptr = (s4 *) (cd->mcodebase + pref->branchpos);
4417 mcode = (u4) *xcodeptr;
4419 /* patch in the call to call the following code (done at compile */
4422 tmpmcodeptr = mcodeptr; /* save current mcodeptr */
4423 mcodeptr = xcodeptr; /* set mcodeptr to patch position */
4425 M_BSR(REG_ITMP3, tmpmcodeptr - (xcodeptr + 1));
4427 mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
4429 /* create stack frame */
4431 M_LSUB_IMM(REG_SP, 5 * 8, REG_SP);
4433 /* move return address onto stack */
4435 M_AST(REG_ITMP3, REG_SP, 4 * 8);
4437 /* move pointer to java_objectheader onto stack */
4439 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4440 /* create a virtual java_objectheader */
4442 (void) dseg_addaddress(cd, get_dummyLR()); /* monitorPtr */
4443 off = dseg_addaddress(cd, NULL); /* vftbl */
4445 M_LDA(REG_ITMP3, REG_PV, off);
4446 M_AST(REG_ITMP3, REG_SP, 3 * 8);
4448 M_AST(REG_ZERO, REG_SP, 3 * 8);
4451 /* move machine code onto stack */
4453 off = dseg_adds4(cd, mcode);
4454 M_ILD(REG_ITMP3, REG_PV, off);
4455 M_IST(REG_ITMP3, REG_SP, 2 * 8);
4457 /* move class/method/field reference onto stack */
4459 off = dseg_addaddress(cd, pref->ref);
4460 M_ALD(REG_ITMP3, REG_PV, off);
4461 M_AST(REG_ITMP3, REG_SP, 1 * 8);
4463 /* move patcher function pointer onto stack */
4465 off = dseg_addaddress(cd, pref->patcher);
4466 M_ALD(REG_ITMP3, REG_PV, off);
4467 M_AST(REG_ITMP3, REG_SP, 0 * 8);
4469 off = dseg_addaddress(cd, asm_wrapper_patcher);
4470 M_ALD(REG_ITMP3, REG_PV, off);
4471 M_JMP(REG_ZERO, REG_ITMP3);
4475 codegen_finish(m, cd, (s4) ((u1 *) mcodeptr - cd->mcodebase));
4477 return m->entrypoint;
4482 * These are local overrides for various environment variables in Emacs.
4483 * Please do not remove this and leave it at the end of the file, where
4484 * Emacs will automagically detect them.
4485 * ---------------------------------------------------------------------
4488 * indent-tabs-mode: t