1 /* 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
32 $Id: codegen.c 1817 2004-12-22 14:50:00Z twisti $
40 #include "vm/jit/alpha/arch.h"
41 #include "native/native.h"
42 #include "vm/builtin.h"
43 #include "vm/global.h"
44 #include "vm/loader.h"
45 #include "vm/tables.h"
46 #include "vm/jit/asmpart.h"
47 #include "vm/jit/jit.h"
49 #include "vm/jit/lsra.h"
51 #include "vm/jit/parse.h"
52 #include "vm/jit/reg.h"
53 #include "vm/jit/alpha/codegen.h"
54 #include "vm/jit/alpha/types.h"
55 #include "vm/jit/alpha/asmoffsets.h"
58 /* *****************************************************************************
60 Datatypes and Register Allocations:
61 -----------------------------------
63 On 64-bit-machines (like the Alpha) all operands are stored in the
64 registers in a 64-bit form, even when the correspondig JavaVM operands
65 only need 32 bits. This is done by a canonical representation:
67 32-bit integers are allways stored as sign-extended 64-bit values (this
68 approach is directly supported by the Alpha architecture and is very easy
71 32-bit-floats are stored in a 64-bit doubleprecision register by simply
72 expanding the exponent and mantissa with zeroes. (also supported by the
78 The calling conventions and the layout of the stack is explained in detail
79 in the documention file: calling.doc
81 *******************************************************************************/
84 /* register descripton - array ************************************************/
86 /* #define REG_RES 0 reserved register for OS or code generator */
87 /* #define REG_RET 1 return value register */
88 /* #define REG_EXC 2 exception value register (only old jit) */
89 /* #define REG_SAV 3 (callee) saved register */
90 /* #define REG_TMP 4 scratch temporary register (caller saved) */
91 /* #define REG_ARG 5 argument register (caller saved) */
93 /* #define REG_END -1 last entry in tables */
96 REG_RET, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
97 REG_TMP, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
98 REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_TMP, REG_TMP,
99 REG_TMP, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES,
102 /* for use of reserved registers, see comment above */
104 int nregdescfloat[] = {
105 REG_RET, REG_TMP, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
106 REG_SAV, REG_SAV, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
107 REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_TMP, REG_TMP,
108 REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_RES, REG_RES, REG_RES, REG_RES,
112 /* Include independent code generation stuff -- include after register */
113 /* descriptions to avoid extern definitions. */
115 #include "vm/jit/codegen.inc"
116 #include "vm/jit/reg.inc"
118 #include "vm/jit/lsra.inc"
122 /* NullPointerException handlers and exception handling initialisation */
124 typedef struct sigctx_struct {
125 long sc_onstack; /* sigstack state to restore */
126 long sc_mask; /* signal mask to restore */
127 long sc_pc; /* pc at time of signal */
128 long sc_ps; /* psl to retore */
129 long sc_regs[32]; /* processor regs 0 to 31 */
130 long sc_ownedfp; /* fp has been used */
131 long sc_fpregs[32]; /* fp regs 0 to 31 */
132 unsigned long sc_fpcr; /* floating point control register */
133 unsigned long sc_fp_control; /* software fpcr */
135 unsigned long sc_reserved1, sc_reserved2;
136 unsigned long sc_ssize;
138 unsigned long sc_traparg_a0;
139 unsigned long sc_traparg_a1;
140 unsigned long sc_traparg_a2;
141 unsigned long sc_fp_trap_pc;
142 unsigned long sc_fp_trigger_sum;
143 unsigned long sc_fp_trigger_inst;
144 unsigned long sc_retcode[2];
148 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
149 void thread_restartcriticalsection(ucontext_t *uc)
152 if ((critical = thread_checkcritical((void*) uc->uc_mcontext.sc_pc)) != NULL)
153 uc->uc_mcontext.sc_pc = (u8) critical;
157 /* NullPointerException signal handler for hardware null pointer check */
159 void catch_NullPointerException(int sig, int code, sigctx_struct *sigctx)
164 java_objectheader *xptr;
166 /* Reset signal handler - necessary for SysV, does no harm for BSD */
168 instr = *((int*)(sigctx->sc_pc));
169 faultaddr = sigctx->sc_regs[(instr >> 16) & 0x1f];
171 if (faultaddr == 0) {
172 /* reinstall handler */
173 signal(sig, catch_NullPointerException);
175 sigaddset(&nsig, sig);
176 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
178 /*xptr = new_nullpointerexception();
179 sigctx->sc_regs[REG_ITMP1_XPTR] = (u8) xptr;*/
181 sigctx->sc_regs[REG_ITMP1_XPTR] = (u8) string_java_lang_NullPointerException;
182 sigctx->sc_regs[REG_ITMP2_XPC] = sigctx->sc_pc;
183 /*sigctx->sc_pc = (u8) asm_handle_exception;*/
184 sigctx->sc_pc = (u8) asm_throw_and_handle_exception;
188 faultaddr += (long) ((instr << 16) >> 16);
189 fprintf(stderr, "faulting address: 0x%016lx\n", faultaddr);
190 panic("Stack overflow");
197 void init_exceptions(void)
202 /* Linux on Digital Alpha needs an initialisation of the ieee floating point
203 control for IEEE compliant arithmetic (option -mieee of GCC). Under
204 Digital Unix this is done automatically.
209 extern unsigned long ieee_get_fp_control();
210 extern void ieee_set_fp_control(unsigned long fp_control);
212 void init_exceptions(void)
214 /* initialize floating point control */
216 ieee_set_fp_control(ieee_get_fp_control()
217 & ~IEEE_TRAP_ENABLE_INV
218 & ~IEEE_TRAP_ENABLE_DZE
219 /* & ~IEEE_TRAP_ENABLE_UNF we dont want underflow */
220 & ~IEEE_TRAP_ENABLE_OVF);
223 /* install signal handlers we need to convert to exceptions */
227 signal(SIGSEGV, (functionptr) catch_NullPointerException);
231 signal(SIGBUS, (functionptr) catch_NullPointerException);
237 /* function gen_mcode **********************************************************
239 generates machine code
241 *******************************************************************************/
243 void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
245 s4 len, s1, s2, s3, d;
259 savedregs_num = (m->isleafmethod) ? 0 : 1; /* space to save the RA */
261 /* space to save used callee saved registers */
263 savedregs_num += (rd->savintregcnt - rd->maxsavintreguse);
264 savedregs_num += (rd->savfltregcnt - rd->maxsavfltreguse);
266 parentargs_base = rd->maxmemuse + savedregs_num;
268 #if defined(USE_THREADS) /* space to save argument of monitor_enter */
270 if (checksync && (m->flags & ACC_SYNCHRONIZED))
275 /* create method header */
277 (void) dseg_addaddress(cd, m); /* MethodPointer */
278 (void) dseg_adds4(cd, parentargs_base * 8); /* FrameSize */
280 #if defined(USE_THREADS)
282 /* IsSync contains the offset relative to the stack pointer for the
283 argument of monitor_exit used in the exception handler. Since the
284 offset could be zero and give a wrong meaning of the flag it is
288 if (checksync && (m->flags & ACC_SYNCHRONIZED))
289 (void) dseg_adds4(cd, (rd->maxmemuse + 1) * 8); /* IsSync */
294 (void) dseg_adds4(cd, 0); /* IsSync */
296 (void) dseg_adds4(cd, m->isleafmethod); /* IsLeaf */
297 (void) dseg_adds4(cd, rd->savintregcnt - rd->maxsavintreguse);/* IntSave */
298 (void) dseg_adds4(cd, rd->savfltregcnt - rd->maxsavfltreguse);/* FltSave */
300 dseg_addlinenumbertablesize(cd);
302 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
304 /* create exception table */
306 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
307 dseg_addtarget(cd, ex->start);
308 dseg_addtarget(cd, ex->end);
309 dseg_addtarget(cd, ex->handler);
310 (void) dseg_addaddress(cd, ex->catchtype);
313 /* initialize mcode variables */
315 mcodeptr = (s4 *) cd->mcodebase;
316 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
317 MCODECHECK(128 + m->paramcount);
319 /* create stack frame (if necessary) */
321 if (parentargs_base) {
322 M_LDA(REG_SP, REG_SP, -parentargs_base * 8);
325 /* save return address and used callee saved registers */
328 if (!m->isleafmethod) {
329 p--; M_AST(REG_RA, REG_SP, p * 8);
331 for (i = rd->savintregcnt - 1; i >= rd->maxsavintreguse; i--) {
332 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
334 for (i = rd->savfltregcnt - 1; i >= rd->maxsavfltreguse; i--) {
335 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
338 /* save monitorenter argument */
340 #if defined(USE_THREADS)
341 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
342 if (m->flags & ACC_STATIC) {
343 p = dseg_addaddress(cd, m->class);
344 M_ALD(REG_ITMP1, REG_PV, p);
345 M_AST(REG_ITMP1, REG_SP, rd->maxmemuse * 8);
348 M_AST(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
353 /* copy argument registers to stack and call trace function with pointer
354 to arguments on stack.
359 M_LDA(REG_SP, REG_SP, -((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
360 M_AST(REG_RA, REG_SP, 1 * 8);
362 /* save integer argument registers */
363 for (p = 0; /* p < m->paramcount && */ p < INT_ARG_CNT; p++) {
364 M_LST(rd->argintregs[p], REG_SP, (2 + p) * 8);
367 /* save and copy float arguments into integer registers */
368 for (p = 0; /* p < m->paramcount && */ p < FLT_ARG_CNT; p++) {
369 t = m->paramtypes[p];
371 if (IS_FLT_DBL_TYPE(t)) {
372 if (IS_2_WORD_TYPE(t)) {
373 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
376 M_FST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
379 M_LLD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
382 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
386 p = dseg_addaddress(cd, m);
387 M_ALD(REG_ITMP1, REG_PV, p);
388 M_AST(REG_ITMP1, REG_SP, 0 * 8);
389 p = dseg_addaddress(cd, (void *) builtin_trace_args);
390 M_ALD(REG_PV, REG_PV, p);
391 M_JSR(REG_RA, REG_PV);
392 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
393 M_LDA(REG_PV, REG_RA, disp);
394 M_ALD(REG_RA, REG_SP, 1 * 8);
396 for (p = 0; /* p < mparamcount && */ p < INT_ARG_CNT; p++) {
397 M_LLD(rd->argintregs[p], REG_SP, (2 + p) * 8);
400 for (p = 0; /* p < mparamcount && */ p < FLT_ARG_CNT; p++) {
401 t = m->paramtypes[p];
403 if (IS_FLT_DBL_TYPE(t)) {
404 if (IS_2_WORD_TYPE(t)) {
405 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
408 M_FLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
412 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
416 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT + 2) * 8);
419 /* take arguments out of register or stack frame */
421 for (p = 0, l = 0; p < m->paramcount; p++) {
422 t = m->paramtypes[p];
423 var = &(rd->locals[l][t]);
425 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
429 if (IS_INT_LNG_TYPE(t)) { /* integer args */
430 if (p < INT_ARG_CNT) { /* register arguments */
431 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
432 M_INTMOVE(rd->argintregs[p], var->regoff);
433 } else { /* reg arg -> spilled */
434 M_LST(rd->argintregs[p], REG_SP, 8 * var->regoff);
437 } else { /* stack arguments */
438 pa = p - INT_ARG_CNT;
439 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
440 M_LLD(var->regoff, REG_SP, 8 * (parentargs_base + pa));
442 } else { /* stack arg -> spilled */
443 M_LLD(REG_ITMP1, REG_SP, 8 * (parentargs_base + pa));
444 M_LST(REG_ITMP1, REG_SP, 8 * var->regoff);
448 } else { /* floating args */
449 if (p < FLT_ARG_CNT) { /* register arguments */
450 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
451 M_FLTMOVE(rd->argfltregs[p], var->regoff);
453 } else { /* reg arg -> spilled */
454 M_DST(rd->argfltregs[p], REG_SP, 8 * var->regoff);
457 } else { /* stack arguments */
458 pa = p - FLT_ARG_CNT;
459 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
460 M_DLD(var->regoff, REG_SP, 8 * (parentargs_base + pa) );
462 } else { /* stack-arg -> spilled */
463 M_DLD(REG_FTMP1, REG_SP, 8 * (parentargs_base + pa));
464 M_DST(REG_FTMP1, REG_SP, 8 * var->regoff);
470 /* call monitorenter function */
472 #if defined(USE_THREADS)
473 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
475 s8 func_enter = (m->flags & ACC_STATIC) ?
476 (s8) builtin_staticmonitorenter : (s8) builtin_monitorenter;
477 p = dseg_addaddress(cd, (void*) func_enter);
478 M_ALD(REG_PV, REG_PV, p);
479 M_ALD(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
480 M_JSR(REG_RA, REG_PV);
481 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
482 M_LDA(REG_PV, REG_RA, disp);
487 /* end of header generation */
489 /* walk through all basic blocks */
490 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
492 bptr->mpc = (s4) ((u1 *) mcodeptr - cd->mcodebase);
494 if (bptr->flags >= BBREACHED) {
496 /* branch resolving */
500 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
501 gen_resolvebranch((u1*) cd->mcodebase + brefs->branchpos,
502 brefs->branchpos, bptr->mpc);
506 /* copy interface registers to their destination */
513 while (src != NULL) {
515 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
516 /* d = reg_of_var(m, src, REG_ITMP1); */
517 if (!(src->flags & INMEMORY))
521 M_INTMOVE(REG_ITMP1, d);
522 store_reg_to_var_int(src, d);
528 while (src != NULL) {
530 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
531 d = reg_of_var(rd, src, REG_ITMP1);
532 M_INTMOVE(REG_ITMP1, d);
533 store_reg_to_var_int(src, d);
536 d = reg_of_var(rd, src, REG_IFTMP);
537 if ((src->varkind != STACKVAR)) {
539 if (IS_FLT_DBL_TYPE(s2)) {
540 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
541 s1 = rd->interfaces[len][s2].regoff;
545 M_DLD(d, REG_SP, 8 * rd->interfaces[len][s2].regoff);
547 store_reg_to_var_flt(src, d);
550 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
551 s1 = rd->interfaces[len][s2].regoff;
555 M_LLD(d, REG_SP, 8 * rd->interfaces[len][s2].regoff);
557 store_reg_to_var_int(src, d);
567 /* walk through all instructions */
571 for (iptr = bptr->iinstr;
573 src = iptr->dst, len--, iptr++) {
575 if (iptr->line!=currentline) {
576 dseg_addlinenumber(cd,iptr->line,mcodeptr);
577 currentline=iptr->line;
580 MCODECHECK(64); /* an instruction usually needs < 64 words */
583 case ICMD_INLINE_START:
584 case ICMD_INLINE_END:
587 case ICMD_NOP: /* ... ==> ... */
590 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
592 var_to_reg_int(s1, src, REG_ITMP1);
594 codegen_addxnullrefs(cd, mcodeptr);
597 /* constant operations ************************************************/
599 case ICMD_ICONST: /* ... ==> ..., constant */
600 /* op1 = 0, val.i = constant */
602 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
603 ICONST(d, iptr->val.i);
604 store_reg_to_var_int(iptr->dst, d);
607 case ICMD_LCONST: /* ... ==> ..., constant */
608 /* op1 = 0, val.l = constant */
610 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
611 LCONST(d, iptr->val.l);
612 store_reg_to_var_int(iptr->dst, d);
615 case ICMD_FCONST: /* ... ==> ..., constant */
616 /* op1 = 0, val.f = constant */
618 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
619 a = dseg_addfloat(cd, iptr->val.f);
621 store_reg_to_var_flt(iptr->dst, d);
624 case ICMD_DCONST: /* ... ==> ..., constant */
625 /* op1 = 0, val.d = constant */
627 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
628 a = dseg_adddouble(cd, iptr->val.d);
630 store_reg_to_var_flt(iptr->dst, d);
633 case ICMD_ACONST: /* ... ==> ..., constant */
634 /* op1 = 0, val.a = constant */
636 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
638 a = dseg_addaddress(cd, iptr->val.a);
641 M_INTMOVE(REG_ZERO, d);
643 store_reg_to_var_int(iptr->dst, d);
647 /* load/store operations **********************************************/
649 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
650 case ICMD_LLOAD: /* op1 = local variable */
653 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
654 if ((iptr->dst->varkind == LOCALVAR) &&
655 (iptr->dst->varnum == iptr->op1))
657 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
658 if (var->flags & INMEMORY)
659 M_LLD(d, REG_SP, 8 * var->regoff);
661 {M_INTMOVE(var->regoff,d);}
662 store_reg_to_var_int(iptr->dst, d);
665 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
666 case ICMD_DLOAD: /* op1 = local variable */
668 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
669 if ((iptr->dst->varkind == LOCALVAR) &&
670 (iptr->dst->varnum == iptr->op1))
672 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
673 if (var->flags & INMEMORY)
674 M_DLD(d, REG_SP, 8 * var->regoff);
676 {M_FLTMOVE(var->regoff,d);}
677 store_reg_to_var_flt(iptr->dst, d);
681 case ICMD_ISTORE: /* ..., value ==> ... */
682 case ICMD_LSTORE: /* op1 = local variable */
685 if ((src->varkind == LOCALVAR) &&
686 (src->varnum == iptr->op1))
688 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
689 if (var->flags & INMEMORY) {
690 var_to_reg_int(s1, src, REG_ITMP1);
691 M_LST(s1, REG_SP, 8 * var->regoff);
694 var_to_reg_int(s1, src, var->regoff);
695 M_INTMOVE(s1, var->regoff);
699 case ICMD_FSTORE: /* ..., value ==> ... */
700 case ICMD_DSTORE: /* op1 = local variable */
702 if ((src->varkind == LOCALVAR) &&
703 (src->varnum == iptr->op1))
705 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
706 if (var->flags & INMEMORY) {
707 var_to_reg_flt(s1, src, REG_FTMP1);
708 M_DST(s1, REG_SP, 8 * var->regoff);
711 var_to_reg_flt(s1, src, var->regoff);
712 M_FLTMOVE(s1, var->regoff);
717 /* pop/dup/swap operations ********************************************/
719 /* attention: double and longs are only one entry in CACAO ICMDs */
721 case ICMD_POP: /* ..., value ==> ... */
722 case ICMD_POP2: /* ..., value, value ==> ... */
725 case ICMD_DUP: /* ..., a ==> ..., a, a */
726 M_COPY(src, iptr->dst);
729 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
731 M_COPY(src, iptr->dst);
732 M_COPY(src->prev, iptr->dst->prev);
733 M_COPY(iptr->dst, iptr->dst->prev->prev);
736 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
738 M_COPY(src, iptr->dst);
739 M_COPY(src->prev, iptr->dst->prev);
740 M_COPY(src->prev->prev, iptr->dst->prev->prev);
741 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
744 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
746 M_COPY(src, iptr->dst);
747 M_COPY(src->prev, iptr->dst->prev);
750 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
752 M_COPY(src, iptr->dst);
753 M_COPY(src->prev, iptr->dst->prev);
754 M_COPY(src->prev->prev, iptr->dst->prev->prev);
755 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
756 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev);
759 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
761 M_COPY(src, iptr->dst);
762 M_COPY(src->prev, iptr->dst->prev);
763 M_COPY(src->prev->prev, iptr->dst->prev->prev);
764 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
765 M_COPY(iptr->dst, iptr->dst->prev->prev->prev->prev);
766 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev->prev);
769 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
771 M_COPY(src, iptr->dst->prev);
772 M_COPY(src->prev, iptr->dst);
776 /* integer operations *************************************************/
778 case ICMD_INEG: /* ..., value ==> ..., - value */
780 var_to_reg_int(s1, src, REG_ITMP1);
781 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
782 M_ISUB(REG_ZERO, s1, d);
783 store_reg_to_var_int(iptr->dst, d);
786 case ICMD_LNEG: /* ..., value ==> ..., - value */
788 var_to_reg_int(s1, src, REG_ITMP1);
789 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
790 M_LSUB(REG_ZERO, s1, d);
791 store_reg_to_var_int(iptr->dst, d);
794 case ICMD_I2L: /* ..., value ==> ..., value */
796 var_to_reg_int(s1, src, REG_ITMP1);
797 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
799 store_reg_to_var_int(iptr->dst, d);
802 case ICMD_L2I: /* ..., value ==> ..., value */
804 var_to_reg_int(s1, src, REG_ITMP1);
805 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
806 M_IADD(s1, REG_ZERO, d );
807 store_reg_to_var_int(iptr->dst, d);
810 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
812 var_to_reg_int(s1, src, REG_ITMP1);
813 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
814 if (has_ext_instr_set) {
818 M_SLL_IMM(s1, 56, d);
819 M_SRA_IMM( d, 56, d);
821 store_reg_to_var_int(iptr->dst, d);
824 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
826 var_to_reg_int(s1, src, REG_ITMP1);
827 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
829 store_reg_to_var_int(iptr->dst, d);
832 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
834 var_to_reg_int(s1, src, REG_ITMP1);
835 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
836 if (has_ext_instr_set) {
840 M_SLL_IMM(s1, 48, d);
841 M_SRA_IMM( d, 48, d);
843 store_reg_to_var_int(iptr->dst, d);
847 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
849 var_to_reg_int(s1, src->prev, REG_ITMP1);
850 var_to_reg_int(s2, src, REG_ITMP2);
851 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
853 store_reg_to_var_int(iptr->dst, d);
856 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
857 /* val.i = constant */
859 var_to_reg_int(s1, src, REG_ITMP1);
860 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
861 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
862 M_IADD_IMM(s1, iptr->val.i, d);
865 ICONST(REG_ITMP2, iptr->val.i);
866 M_IADD(s1, REG_ITMP2, d);
868 store_reg_to_var_int(iptr->dst, d);
871 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
873 var_to_reg_int(s1, src->prev, REG_ITMP1);
874 var_to_reg_int(s2, src, REG_ITMP2);
875 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
877 store_reg_to_var_int(iptr->dst, d);
880 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
881 /* val.l = constant */
883 var_to_reg_int(s1, src, REG_ITMP1);
884 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
885 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
886 M_LADD_IMM(s1, iptr->val.l, d);
889 LCONST(REG_ITMP2, iptr->val.l);
890 M_LADD(s1, REG_ITMP2, d);
892 store_reg_to_var_int(iptr->dst, d);
895 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
897 var_to_reg_int(s1, src->prev, REG_ITMP1);
898 var_to_reg_int(s2, src, REG_ITMP2);
899 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
901 store_reg_to_var_int(iptr->dst, d);
904 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
905 /* val.i = constant */
907 var_to_reg_int(s1, src, REG_ITMP1);
908 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
909 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
910 M_ISUB_IMM(s1, iptr->val.i, d);
913 ICONST(REG_ITMP2, iptr->val.i);
914 M_ISUB(s1, REG_ITMP2, d);
916 store_reg_to_var_int(iptr->dst, d);
919 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
921 var_to_reg_int(s1, src->prev, REG_ITMP1);
922 var_to_reg_int(s2, src, REG_ITMP2);
923 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
925 store_reg_to_var_int(iptr->dst, d);
928 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
929 /* val.l = constant */
931 var_to_reg_int(s1, src, REG_ITMP1);
932 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
933 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
934 M_LSUB_IMM(s1, iptr->val.l, d);
937 LCONST(REG_ITMP2, iptr->val.l);
938 M_LSUB(s1, REG_ITMP2, d);
940 store_reg_to_var_int(iptr->dst, d);
943 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
945 var_to_reg_int(s1, src->prev, REG_ITMP1);
946 var_to_reg_int(s2, src, REG_ITMP2);
947 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
949 store_reg_to_var_int(iptr->dst, d);
952 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
953 /* val.i = constant */
955 var_to_reg_int(s1, src, REG_ITMP1);
956 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
957 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
958 M_IMUL_IMM(s1, iptr->val.i, d);
961 ICONST(REG_ITMP2, iptr->val.i);
962 M_IMUL(s1, REG_ITMP2, d);
964 store_reg_to_var_int(iptr->dst, d);
967 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
969 var_to_reg_int(s1, src->prev, REG_ITMP1);
970 var_to_reg_int(s2, src, REG_ITMP2);
971 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
973 store_reg_to_var_int(iptr->dst, d);
976 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
977 /* val.l = constant */
979 var_to_reg_int(s1, src, REG_ITMP1);
980 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
981 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
982 M_LMUL_IMM(s1, iptr->val.l, d);
985 LCONST(REG_ITMP2, iptr->val.l);
986 M_LMUL(s1, REG_ITMP2, d);
988 store_reg_to_var_int(iptr->dst, d);
991 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
992 case ICMD_LDIVPOW2: /* val.i = constant */
994 var_to_reg_int(s1, src, REG_ITMP1);
995 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
996 if (iptr->val.i <= 15) {
997 M_LDA(REG_ITMP2, s1, (1 << iptr->val.i) -1);
998 M_CMOVGE(s1, s1, REG_ITMP2);
1001 M_SRA_IMM(s1, 63, REG_ITMP2);
1002 M_SRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
1003 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1005 M_SRA_IMM(REG_ITMP2, iptr->val.i, d);
1006 store_reg_to_var_int(iptr->dst, d);
1009 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1011 var_to_reg_int(s1, src->prev, REG_ITMP1);
1012 var_to_reg_int(s2, src, REG_ITMP2);
1013 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1014 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1015 M_SLL(s1, REG_ITMP3, d);
1016 M_IADD(d, REG_ZERO, d);
1017 store_reg_to_var_int(iptr->dst, d);
1020 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1021 /* val.i = constant */
1023 var_to_reg_int(s1, src, REG_ITMP1);
1024 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1025 M_SLL_IMM(s1, iptr->val.i & 0x1f, d);
1026 M_IADD(d, REG_ZERO, d);
1027 store_reg_to_var_int(iptr->dst, d);
1030 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1032 var_to_reg_int(s1, src->prev, REG_ITMP1);
1033 var_to_reg_int(s2, src, REG_ITMP2);
1034 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1035 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1036 M_SRA(s1, REG_ITMP3, d);
1037 store_reg_to_var_int(iptr->dst, d);
1040 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1041 /* val.i = constant */
1043 var_to_reg_int(s1, src, REG_ITMP1);
1044 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1045 M_SRA_IMM(s1, iptr->val.i & 0x1f, d);
1046 store_reg_to_var_int(iptr->dst, d);
1049 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1051 var_to_reg_int(s1, src->prev, REG_ITMP1);
1052 var_to_reg_int(s2, src, REG_ITMP2);
1053 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1054 M_AND_IMM(s2, 0x1f, REG_ITMP2);
1056 M_SRL(d, REG_ITMP2, d);
1057 M_IADD(d, REG_ZERO, d);
1058 store_reg_to_var_int(iptr->dst, d);
1061 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1062 /* val.i = constant */
1064 var_to_reg_int(s1, src, REG_ITMP1);
1065 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1067 M_SRL_IMM(d, iptr->val.i & 0x1f, d);
1068 M_IADD(d, REG_ZERO, d);
1069 store_reg_to_var_int(iptr->dst, d);
1072 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1074 var_to_reg_int(s1, src->prev, REG_ITMP1);
1075 var_to_reg_int(s2, src, REG_ITMP2);
1076 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1078 store_reg_to_var_int(iptr->dst, d);
1081 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1082 /* val.i = constant */
1084 var_to_reg_int(s1, src, REG_ITMP1);
1085 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1086 M_SLL_IMM(s1, iptr->val.i & 0x3f, d);
1087 store_reg_to_var_int(iptr->dst, d);
1090 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1092 var_to_reg_int(s1, src->prev, REG_ITMP1);
1093 var_to_reg_int(s2, src, REG_ITMP2);
1094 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1096 store_reg_to_var_int(iptr->dst, d);
1099 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1100 /* val.i = constant */
1102 var_to_reg_int(s1, src, REG_ITMP1);
1103 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1104 M_SRA_IMM(s1, iptr->val.i & 0x3f, d);
1105 store_reg_to_var_int(iptr->dst, d);
1108 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1110 var_to_reg_int(s1, src->prev, REG_ITMP1);
1111 var_to_reg_int(s2, src, REG_ITMP2);
1112 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1114 store_reg_to_var_int(iptr->dst, d);
1117 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1118 /* val.i = constant */
1120 var_to_reg_int(s1, src, REG_ITMP1);
1121 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1122 M_SRL_IMM(s1, iptr->val.i & 0x3f, d);
1123 store_reg_to_var_int(iptr->dst, d);
1126 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1129 var_to_reg_int(s1, src->prev, REG_ITMP1);
1130 var_to_reg_int(s2, src, REG_ITMP2);
1131 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1133 store_reg_to_var_int(iptr->dst, d);
1136 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1137 /* val.i = constant */
1139 var_to_reg_int(s1, src, REG_ITMP1);
1140 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1141 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1142 M_AND_IMM(s1, iptr->val.i, d);
1144 else if (iptr->val.i == 0xffff) {
1147 else if (iptr->val.i == 0xffffff) {
1148 M_ZAPNOT_IMM(s1, 0x07, d);
1151 ICONST(REG_ITMP2, iptr->val.i);
1152 M_AND(s1, REG_ITMP2, d);
1154 store_reg_to_var_int(iptr->dst, d);
1157 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1158 /* val.i = constant */
1160 var_to_reg_int(s1, src, REG_ITMP1);
1161 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1163 M_MOV(s1, REG_ITMP1);
1166 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1167 M_AND_IMM(s1, iptr->val.i, d);
1169 M_ISUB(REG_ZERO, s1, d);
1170 M_AND_IMM(d, iptr->val.i, d);
1172 else if (iptr->val.i == 0xffff) {
1175 M_ISUB(REG_ZERO, s1, d);
1178 else if (iptr->val.i == 0xffffff) {
1179 M_ZAPNOT_IMM(s1, 0x07, d);
1181 M_ISUB(REG_ZERO, s1, d);
1182 M_ZAPNOT_IMM(d, 0x07, d);
1185 ICONST(REG_ITMP2, iptr->val.i);
1186 M_AND(s1, REG_ITMP2, d);
1188 M_ISUB(REG_ZERO, s1, d);
1189 M_AND(d, REG_ITMP2, d);
1191 M_ISUB(REG_ZERO, d, d);
1192 store_reg_to_var_int(iptr->dst, d);
1195 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1196 /* val.l = constant */
1198 var_to_reg_int(s1, src, REG_ITMP1);
1199 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1200 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1201 M_AND_IMM(s1, iptr->val.l, d);
1203 else if (iptr->val.l == 0xffffL) {
1206 else if (iptr->val.l == 0xffffffL) {
1207 M_ZAPNOT_IMM(s1, 0x07, d);
1209 else if (iptr->val.l == 0xffffffffL) {
1212 else if (iptr->val.l == 0xffffffffffL) {
1213 M_ZAPNOT_IMM(s1, 0x1f, d);
1215 else if (iptr->val.l == 0xffffffffffffL) {
1216 M_ZAPNOT_IMM(s1, 0x3f, d);
1218 else if (iptr->val.l == 0xffffffffffffffL) {
1219 M_ZAPNOT_IMM(s1, 0x7f, d);
1222 LCONST(REG_ITMP2, iptr->val.l);
1223 M_AND(s1, REG_ITMP2, d);
1225 store_reg_to_var_int(iptr->dst, d);
1228 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1229 /* val.l = constant */
1231 var_to_reg_int(s1, src, REG_ITMP1);
1232 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1234 M_MOV(s1, REG_ITMP1);
1237 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1238 M_AND_IMM(s1, iptr->val.l, d);
1240 M_LSUB(REG_ZERO, s1, d);
1241 M_AND_IMM(d, iptr->val.l, d);
1243 else if (iptr->val.l == 0xffffL) {
1246 M_LSUB(REG_ZERO, s1, d);
1249 else if (iptr->val.l == 0xffffffL) {
1250 M_ZAPNOT_IMM(s1, 0x07, d);
1252 M_LSUB(REG_ZERO, s1, d);
1253 M_ZAPNOT_IMM(d, 0x07, d);
1255 else if (iptr->val.l == 0xffffffffL) {
1258 M_LSUB(REG_ZERO, s1, d);
1261 else if (iptr->val.l == 0xffffffffffL) {
1262 M_ZAPNOT_IMM(s1, 0x1f, d);
1264 M_LSUB(REG_ZERO, s1, d);
1265 M_ZAPNOT_IMM(d, 0x1f, d);
1267 else if (iptr->val.l == 0xffffffffffffL) {
1268 M_ZAPNOT_IMM(s1, 0x3f, d);
1270 M_LSUB(REG_ZERO, s1, d);
1271 M_ZAPNOT_IMM(d, 0x3f, d);
1273 else if (iptr->val.l == 0xffffffffffffffL) {
1274 M_ZAPNOT_IMM(s1, 0x7f, d);
1276 M_LSUB(REG_ZERO, s1, d);
1277 M_ZAPNOT_IMM(d, 0x7f, d);
1280 LCONST(REG_ITMP2, iptr->val.l);
1281 M_AND(s1, REG_ITMP2, d);
1283 M_LSUB(REG_ZERO, s1, d);
1284 M_AND(d, REG_ITMP2, d);
1286 M_LSUB(REG_ZERO, d, d);
1287 store_reg_to_var_int(iptr->dst, d);
1290 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1293 var_to_reg_int(s1, src->prev, REG_ITMP1);
1294 var_to_reg_int(s2, src, REG_ITMP2);
1295 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1297 store_reg_to_var_int(iptr->dst, d);
1300 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1301 /* val.i = constant */
1303 var_to_reg_int(s1, src, REG_ITMP1);
1304 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1305 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1306 M_OR_IMM(s1, iptr->val.i, d);
1309 ICONST(REG_ITMP2, iptr->val.i);
1310 M_OR(s1, REG_ITMP2, d);
1312 store_reg_to_var_int(iptr->dst, d);
1315 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1316 /* val.l = constant */
1318 var_to_reg_int(s1, src, REG_ITMP1);
1319 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1320 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1321 M_OR_IMM(s1, iptr->val.l, d);
1324 LCONST(REG_ITMP2, iptr->val.l);
1325 M_OR(s1, REG_ITMP2, d);
1327 store_reg_to_var_int(iptr->dst, d);
1330 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1333 var_to_reg_int(s1, src->prev, REG_ITMP1);
1334 var_to_reg_int(s2, src, REG_ITMP2);
1335 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1337 store_reg_to_var_int(iptr->dst, d);
1340 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1341 /* val.i = constant */
1343 var_to_reg_int(s1, src, REG_ITMP1);
1344 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1345 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1346 M_XOR_IMM(s1, iptr->val.i, d);
1349 ICONST(REG_ITMP2, iptr->val.i);
1350 M_XOR(s1, REG_ITMP2, d);
1352 store_reg_to_var_int(iptr->dst, d);
1355 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1356 /* val.l = constant */
1358 var_to_reg_int(s1, src, REG_ITMP1);
1359 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1360 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1361 M_XOR_IMM(s1, iptr->val.l, d);
1364 LCONST(REG_ITMP2, iptr->val.l);
1365 M_XOR(s1, REG_ITMP2, d);
1367 store_reg_to_var_int(iptr->dst, d);
1371 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1373 var_to_reg_int(s1, src->prev, REG_ITMP1);
1374 var_to_reg_int(s2, src, REG_ITMP2);
1375 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1376 M_CMPLT(s1, s2, REG_ITMP3);
1377 M_CMPLT(s2, s1, REG_ITMP1);
1378 M_LSUB (REG_ITMP1, REG_ITMP3, d);
1379 store_reg_to_var_int(iptr->dst, d);
1383 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1384 /* op1 = variable, val.i = constant */
1386 var = &(rd->locals[iptr->op1][TYPE_INT]);
1387 if (var->flags & INMEMORY) {
1389 M_LLD(s1, REG_SP, 8 * var->regoff);
1393 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1394 M_IADD_IMM(s1, iptr->val.i, s1);
1396 else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1397 M_ISUB_IMM(s1, (-iptr->val.i), s1);
1400 M_LDA (s1, s1, iptr->val.i);
1401 M_IADD(s1, REG_ZERO, s1);
1403 if (var->flags & INMEMORY)
1404 M_LST(s1, REG_SP, 8 * var->regoff);
1408 /* floating operations ************************************************/
1410 case ICMD_FNEG: /* ..., value ==> ..., - value */
1412 var_to_reg_flt(s1, src, REG_FTMP1);
1413 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1415 store_reg_to_var_flt(iptr->dst, d);
1418 case ICMD_DNEG: /* ..., value ==> ..., - value */
1420 var_to_reg_flt(s1, src, REG_FTMP1);
1421 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1423 store_reg_to_var_flt(iptr->dst, d);
1426 case ICMD_FADD: /* ..., 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_FADDS(s1, s2, REG_FTMP3);
1438 M_FMOV(REG_FTMP3, d);
1445 store_reg_to_var_flt(iptr->dst, d);
1448 case ICMD_DADD: /* ..., 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_DADDS(s1, s2, REG_FTMP3);
1460 M_FMOV(REG_FTMP3, d);
1467 store_reg_to_var_flt(iptr->dst, d);
1470 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1472 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1473 var_to_reg_flt(s2, src, REG_FTMP2);
1474 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1479 if (d == s1 || d == s2) {
1480 M_FSUBS(s1, s2, REG_FTMP3);
1482 M_FMOV(REG_FTMP3, d);
1489 store_reg_to_var_flt(iptr->dst, d);
1492 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1494 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1495 var_to_reg_flt(s2, src, REG_FTMP2);
1496 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1501 if (d == s1 || d == s2) {
1502 M_DSUBS(s1, s2, REG_FTMP3);
1504 M_FMOV(REG_FTMP3, d);
1511 store_reg_to_var_flt(iptr->dst, d);
1514 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1516 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1517 var_to_reg_flt(s2, src, REG_FTMP2);
1518 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1523 if (d == s1 || d == s2) {
1524 M_FMULS(s1, s2, REG_FTMP3);
1526 M_FMOV(REG_FTMP3, d);
1533 store_reg_to_var_flt(iptr->dst, d);
1536 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1538 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1539 var_to_reg_flt(s2, src, REG_FTMP2);
1540 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1545 if (d == s1 || d == s2) {
1546 M_DMULS(s1, s2, REG_FTMP3);
1548 M_FMOV(REG_FTMP3, d);
1555 store_reg_to_var_flt(iptr->dst, d);
1558 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1560 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1561 var_to_reg_flt(s2, src, REG_FTMP2);
1562 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1567 if (d == s1 || d == s2) {
1568 M_FDIVS(s1, s2, REG_FTMP3);
1570 M_FMOV(REG_FTMP3, d);
1577 store_reg_to_var_flt(iptr->dst, d);
1580 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1582 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1583 var_to_reg_flt(s2, src, REG_FTMP2);
1584 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1589 if (d == s1 || d == s2) {
1590 M_DDIVS(s1, s2, REG_FTMP3);
1592 M_FMOV(REG_FTMP3, d);
1599 store_reg_to_var_flt(iptr->dst, d);
1602 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1604 var_to_reg_int(s1, src, REG_ITMP1);
1605 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1606 a = dseg_adddouble(cd, 0.0);
1607 M_LST (s1, REG_PV, a);
1608 M_DLD (d, REG_PV, a);
1610 store_reg_to_var_flt(iptr->dst, d);
1613 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1615 var_to_reg_int(s1, src, REG_ITMP1);
1616 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1617 a = dseg_adddouble(cd, 0.0);
1618 M_LST (s1, REG_PV, a);
1619 M_DLD (d, REG_PV, a);
1621 store_reg_to_var_flt(iptr->dst, d);
1624 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1626 var_to_reg_flt(s1, src, REG_FTMP1);
1627 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1628 a = dseg_adddouble(cd, 0.0);
1629 M_CVTDL_C(s1, REG_FTMP2);
1630 M_CVTLI(REG_FTMP2, REG_FTMP3);
1631 M_DST (REG_FTMP3, REG_PV, a);
1632 M_ILD (d, REG_PV, a);
1633 store_reg_to_var_int(iptr->dst, d);
1636 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1638 var_to_reg_flt(s1, src, REG_FTMP1);
1639 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1640 a = dseg_adddouble(cd, 0.0);
1641 M_CVTDL_C(s1, REG_FTMP2);
1642 M_DST (REG_FTMP2, REG_PV, a);
1643 M_LLD (d, REG_PV, a);
1644 store_reg_to_var_int(iptr->dst, d);
1647 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1649 var_to_reg_flt(s1, src, REG_FTMP1);
1650 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1653 store_reg_to_var_flt(iptr->dst, d);
1656 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1658 var_to_reg_flt(s1, src, REG_FTMP1);
1659 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1667 store_reg_to_var_flt(iptr->dst, d);
1670 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1672 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1673 var_to_reg_flt(s2, src, REG_FTMP2);
1674 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1676 M_LSUB_IMM(REG_ZERO, 1, d);
1677 M_FCMPEQ(s1, s2, REG_FTMP3);
1678 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1680 M_FCMPLT(s2, s1, REG_FTMP3);
1681 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1682 M_LADD_IMM(REG_ZERO, 1, d);
1685 M_LSUB_IMM(REG_ZERO, 1, d);
1686 M_FCMPEQS(s1, s2, REG_FTMP3);
1688 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1690 M_FCMPLTS(s2, s1, REG_FTMP3);
1692 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1693 M_LADD_IMM(REG_ZERO, 1, d);
1695 store_reg_to_var_int(iptr->dst, d);
1698 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1700 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1701 var_to_reg_flt(s2, src, REG_FTMP2);
1702 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1704 M_LADD_IMM(REG_ZERO, 1, d);
1705 M_FCMPEQ(s1, s2, REG_FTMP3);
1706 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1708 M_FCMPLT(s1, s2, REG_FTMP3);
1709 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1710 M_LSUB_IMM(REG_ZERO, 1, d);
1713 M_LADD_IMM(REG_ZERO, 1, d);
1714 M_FCMPEQS(s1, s2, REG_FTMP3);
1716 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1718 M_FCMPLTS(s1, s2, REG_FTMP3);
1720 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1721 M_LSUB_IMM(REG_ZERO, 1, d);
1723 store_reg_to_var_int(iptr->dst, d);
1727 /* memory operations **************************************************/
1729 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1731 var_to_reg_int(s1, src, REG_ITMP1);
1732 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1733 gen_nullptr_check(s1);
1734 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1735 store_reg_to_var_int(iptr->dst, d);
1738 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1740 var_to_reg_int(s1, src->prev, REG_ITMP1);
1741 var_to_reg_int(s2, src, REG_ITMP2);
1742 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1743 if (iptr->op1 == 0) {
1744 gen_nullptr_check(s1);
1747 M_SAADDQ(s2, s1, REG_ITMP1);
1748 M_ALD( d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1749 store_reg_to_var_int(iptr->dst, d);
1752 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1754 var_to_reg_int(s1, src->prev, REG_ITMP1);
1755 var_to_reg_int(s2, src, REG_ITMP2);
1756 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1757 if (iptr->op1 == 0) {
1758 gen_nullptr_check(s1);
1761 M_S8ADDQ(s2, s1, REG_ITMP1);
1762 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1763 store_reg_to_var_int(iptr->dst, d);
1766 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1768 var_to_reg_int(s1, src->prev, REG_ITMP1);
1769 var_to_reg_int(s2, src, REG_ITMP2);
1770 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1771 if (iptr->op1 == 0) {
1772 gen_nullptr_check(s1);
1776 M_S4ADDQ(s2, s1, REG_ITMP1);
1777 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1778 store_reg_to_var_int(iptr->dst, d);
1781 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1783 var_to_reg_int(s1, src->prev, REG_ITMP1);
1784 var_to_reg_int(s2, src, REG_ITMP2);
1785 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1786 if (iptr->op1 == 0) {
1787 gen_nullptr_check(s1);
1790 M_S4ADDQ(s2, s1, REG_ITMP1);
1791 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1792 store_reg_to_var_flt(iptr->dst, d);
1795 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1797 var_to_reg_int(s1, src->prev, REG_ITMP1);
1798 var_to_reg_int(s2, src, REG_ITMP2);
1799 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1800 if (iptr->op1 == 0) {
1801 gen_nullptr_check(s1);
1804 M_S8ADDQ(s2, s1, REG_ITMP1);
1805 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1806 store_reg_to_var_flt(iptr->dst, d);
1809 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1811 var_to_reg_int(s1, src->prev, REG_ITMP1);
1812 var_to_reg_int(s2, src, REG_ITMP2);
1813 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1814 if (iptr->op1 == 0) {
1815 gen_nullptr_check(s1);
1818 if (has_ext_instr_set) {
1819 M_LADD(s2, s1, REG_ITMP1);
1820 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1821 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1824 M_LADD (s2, s1, REG_ITMP1);
1825 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1826 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1827 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1828 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
1830 store_reg_to_var_int(iptr->dst, d);
1833 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1835 var_to_reg_int(s1, src->prev, REG_ITMP1);
1836 var_to_reg_int(s2, src, REG_ITMP2);
1837 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1838 if (iptr->op1 == 0) {
1839 gen_nullptr_check(s1);
1842 if (has_ext_instr_set) {
1843 M_LADD(s2, s1, REG_ITMP1);
1844 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1845 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1849 M_LADD(s2, s1, REG_ITMP1);
1850 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1851 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1852 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1853 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1854 M_SRA_IMM(d, 48, d);
1856 store_reg_to_var_int(iptr->dst, d);
1859 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1861 var_to_reg_int(s1, src->prev, REG_ITMP1);
1862 var_to_reg_int(s2, src, REG_ITMP2);
1863 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1864 if (iptr->op1 == 0) {
1865 gen_nullptr_check(s1);
1868 if (has_ext_instr_set) {
1869 M_LADD (s2, s1, REG_ITMP1);
1870 M_BLDU (d, REG_ITMP1, OFFSET (java_bytearray, data[0]));
1874 M_LADD(s2, s1, REG_ITMP1);
1875 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1876 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
1877 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1878 M_SRA_IMM(d, 56, d);
1880 store_reg_to_var_int(iptr->dst, d);
1884 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1886 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1887 var_to_reg_int(s2, src->prev, REG_ITMP2);
1888 if (iptr->op1 == 0) {
1889 gen_nullptr_check(s1);
1892 var_to_reg_int(s3, src, REG_ITMP3);
1893 M_SAADDQ(s2, s1, REG_ITMP1);
1894 M_AST (s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1897 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1899 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1900 var_to_reg_int(s2, src->prev, REG_ITMP2);
1901 if (iptr->op1 == 0) {
1902 gen_nullptr_check(s1);
1905 var_to_reg_int(s3, src, REG_ITMP3);
1906 M_S8ADDQ(s2, s1, REG_ITMP1);
1907 M_LST (s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1910 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1912 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1913 var_to_reg_int(s2, src->prev, REG_ITMP2);
1914 if (iptr->op1 == 0) {
1915 gen_nullptr_check(s1);
1919 var_to_reg_int(s3, src, REG_ITMP3);
1920 M_S4ADDQ(s2, s1, REG_ITMP1);
1921 M_IST (s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1924 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1926 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1927 var_to_reg_int(s2, src->prev, REG_ITMP2);
1928 if (iptr->op1 == 0) {
1929 gen_nullptr_check(s1);
1932 var_to_reg_flt(s3, src, REG_FTMP3);
1933 M_S4ADDQ(s2, s1, REG_ITMP1);
1934 M_FST (s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1937 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1939 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1940 var_to_reg_int(s2, src->prev, REG_ITMP2);
1941 if (iptr->op1 == 0) {
1942 gen_nullptr_check(s1);
1945 var_to_reg_flt(s3, src, REG_FTMP3);
1946 M_S8ADDQ(s2, s1, REG_ITMP1);
1947 M_DST (s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1950 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1952 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1953 var_to_reg_int(s2, src->prev, REG_ITMP2);
1954 if (iptr->op1 == 0) {
1955 gen_nullptr_check(s1);
1958 var_to_reg_int(s3, src, REG_ITMP3);
1959 if (has_ext_instr_set) {
1960 M_LADD(s2, s1, REG_ITMP1);
1961 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1962 M_SST (s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1965 M_LADD (s2, s1, REG_ITMP1);
1966 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1967 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1968 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1969 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1970 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1971 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
1972 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1976 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1978 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1979 var_to_reg_int(s2, src->prev, REG_ITMP2);
1980 if (iptr->op1 == 0) {
1981 gen_nullptr_check(s1);
1984 var_to_reg_int(s3, src, REG_ITMP3);
1985 if (has_ext_instr_set) {
1986 M_LADD(s2, s1, REG_ITMP1);
1987 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1988 M_SST (s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1991 M_LADD (s2, s1, REG_ITMP1);
1992 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1993 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1994 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1995 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1996 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1997 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
1998 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2002 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
2004 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2005 var_to_reg_int(s2, src->prev, REG_ITMP2);
2006 if (iptr->op1 == 0) {
2007 gen_nullptr_check(s1);
2010 var_to_reg_int(s3, src, REG_ITMP3);
2011 if (has_ext_instr_set) {
2012 M_LADD(s2, s1, REG_ITMP1);
2013 M_BST (s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2016 M_LADD (s2, s1, REG_ITMP1);
2017 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2018 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2019 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
2020 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2021 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2022 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2027 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
2029 var_to_reg_int(s1, src->prev, REG_ITMP1);
2030 var_to_reg_int(s2, src, REG_ITMP2);
2031 if (iptr->op1 == 0) {
2032 gen_nullptr_check(s1);
2035 M_S4ADDQ(s2, s1, REG_ITMP1);
2036 M_IST(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
2039 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
2041 var_to_reg_int(s1, src->prev, REG_ITMP1);
2042 var_to_reg_int(s2, src, REG_ITMP2);
2043 if (iptr->op1 == 0) {
2044 gen_nullptr_check(s1);
2047 M_S8ADDQ(s2, s1, REG_ITMP1);
2048 M_LST(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
2051 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
2053 var_to_reg_int(s1, src->prev, REG_ITMP1);
2054 var_to_reg_int(s2, src, REG_ITMP2);
2055 if (iptr->op1 == 0) {
2056 gen_nullptr_check(s1);
2059 M_SAADDQ(s2, s1, REG_ITMP1);
2060 M_AST(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
2063 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
2065 var_to_reg_int(s1, src->prev, REG_ITMP1);
2066 var_to_reg_int(s2, src, REG_ITMP2);
2067 if (iptr->op1 == 0) {
2068 gen_nullptr_check(s1);
2071 if (has_ext_instr_set) {
2072 M_LADD(s2, s1, REG_ITMP1);
2073 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2076 M_LADD(s2, s1, REG_ITMP1);
2077 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2078 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2079 M_INSBL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2080 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2081 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2082 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2086 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
2088 var_to_reg_int(s1, src->prev, REG_ITMP1);
2089 var_to_reg_int(s2, src, REG_ITMP2);
2090 if (iptr->op1 == 0) {
2091 gen_nullptr_check(s1);
2094 if (has_ext_instr_set) {
2095 M_LADD(s2, s1, REG_ITMP1);
2096 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2097 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
2100 M_LADD(s2, s1, REG_ITMP1);
2101 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2102 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2103 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2104 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2105 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2106 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2107 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2111 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
2113 var_to_reg_int(s1, src->prev, REG_ITMP1);
2114 var_to_reg_int(s2, src, REG_ITMP2);
2115 if (iptr->op1 == 0) {
2116 gen_nullptr_check(s1);
2119 if (has_ext_instr_set) {
2120 M_LADD(s2, s1, REG_ITMP1);
2121 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2122 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2125 M_LADD(s2, s1, REG_ITMP1);
2126 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2127 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2128 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2129 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2130 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2131 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2132 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2137 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2138 /* op1 = type, val.a = field address */
2140 /* If the static fields' class is not yet initialized, we do it */
2141 /* now. The call code is generated later. */
2142 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
2143 codegen_addclinitref(cd, mcodeptr, ((fieldinfo *) iptr->val.a)->class);
2145 /* This is just for debugging purposes. Is very difficult to */
2146 /* read patched code. Here we patch the following 2 nop's */
2147 /* so that the real code keeps untouched. */
2148 if (showdisassemble) {
2153 a = dseg_addaddress(cd, &(((fieldinfo *)(iptr->val.a))->value));
2154 M_ALD(REG_ITMP1, REG_PV, a);
2155 switch (iptr->op1) {
2157 var_to_reg_int(s2, src, REG_ITMP2);
2158 M_IST(s2, REG_ITMP1, 0);
2161 var_to_reg_int(s2, src, REG_ITMP2);
2162 M_LST(s2, REG_ITMP1, 0);
2165 var_to_reg_int(s2, src, REG_ITMP2);
2166 M_AST(s2, REG_ITMP1, 0);
2169 var_to_reg_flt(s2, src, REG_FTMP2);
2170 M_FST(s2, REG_ITMP1, 0);
2173 var_to_reg_flt(s2, src, REG_FTMP2);
2174 M_DST(s2, REG_ITMP1, 0);
2176 default: panic ("internal error");
2180 case ICMD_GETSTATIC: /* ... ==> ..., value */
2181 /* op1 = type, val.a = field address */
2183 /* if class isn't yet initialized, do it */
2184 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
2185 codegen_addclinitref(cd, mcodeptr, ((fieldinfo *) iptr->val.a)->class);
2187 /* This is just for debugging purposes. Is very difficult to */
2188 /* read patched code. Here we patch the following 2 nop's */
2189 /* so that the real code keeps untouched. */
2190 if (showdisassemble) {
2195 a = dseg_addaddress(cd, &(((fieldinfo *) iptr->val.a)->value));
2196 M_ALD(REG_ITMP1, REG_PV, a);
2197 switch (iptr->op1) {
2199 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2200 M_ILD(d, REG_ITMP1, 0);
2201 store_reg_to_var_int(iptr->dst, d);
2204 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2205 M_LLD(d, REG_ITMP1, 0);
2206 store_reg_to_var_int(iptr->dst, d);
2209 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2210 M_ALD(d, REG_ITMP1, 0);
2211 store_reg_to_var_int(iptr->dst, d);
2214 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2215 M_FLD(d, REG_ITMP1, 0);
2216 store_reg_to_var_flt(iptr->dst, d);
2219 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2220 M_DLD(d, REG_ITMP1, 0);
2221 store_reg_to_var_flt(iptr->dst, d);
2223 default: panic ("internal error");
2228 case ICMD_PUTFIELD: /* ..., value ==> ... */
2229 /* op1 = type, val.i = field offset */
2231 a = ((fieldinfo *) iptr->val.a)->offset;
2232 switch (iptr->op1) {
2234 var_to_reg_int(s1, src->prev, REG_ITMP1);
2235 var_to_reg_int(s2, src, REG_ITMP2);
2236 gen_nullptr_check(s1);
2240 var_to_reg_int(s1, src->prev, REG_ITMP1);
2241 var_to_reg_int(s2, src, REG_ITMP2);
2242 gen_nullptr_check(s1);
2246 var_to_reg_int(s1, src->prev, REG_ITMP1);
2247 var_to_reg_int(s2, src, REG_ITMP2);
2248 gen_nullptr_check(s1);
2252 var_to_reg_int(s1, src->prev, REG_ITMP1);
2253 var_to_reg_flt(s2, src, REG_FTMP2);
2254 gen_nullptr_check(s1);
2258 var_to_reg_int(s1, src->prev, REG_ITMP1);
2259 var_to_reg_flt(s2, src, REG_FTMP2);
2260 gen_nullptr_check(s1);
2263 default: panic ("internal error");
2267 case ICMD_GETFIELD: /* ... ==> ..., value */
2268 /* op1 = type, val.i = field offset */
2270 a = ((fieldinfo *)(iptr->val.a))->offset;
2271 switch (iptr->op1) {
2273 var_to_reg_int(s1, src, REG_ITMP1);
2274 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2275 gen_nullptr_check(s1);
2277 store_reg_to_var_int(iptr->dst, d);
2280 var_to_reg_int(s1, src, REG_ITMP1);
2281 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2282 gen_nullptr_check(s1);
2284 store_reg_to_var_int(iptr->dst, d);
2287 var_to_reg_int(s1, src, REG_ITMP1);
2288 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2289 gen_nullptr_check(s1);
2291 store_reg_to_var_int(iptr->dst, d);
2294 var_to_reg_int(s1, src, REG_ITMP1);
2295 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2296 gen_nullptr_check(s1);
2298 store_reg_to_var_flt(iptr->dst, d);
2301 var_to_reg_int(s1, src, REG_ITMP1);
2302 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2303 gen_nullptr_check(s1);
2305 store_reg_to_var_flt(iptr->dst, d);
2307 default: panic ("internal error");
2312 /* branch operations **************************************************/
2314 #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}}
2316 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2318 var_to_reg_int(s1, src, REG_ITMP1);
2319 M_INTMOVE(s1, REG_ITMP1_XPTR);
2320 a = dseg_addaddress(cd, asm_handle_exception);
2321 M_ALD(REG_ITMP2, REG_PV, a);
2322 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2323 M_NOP; /* nop ensures that XPC is less than the end */
2324 /* of basic block */
2328 case ICMD_GOTO: /* ... ==> ... */
2329 /* op1 = target JavaVM pc */
2331 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2335 case ICMD_JSR: /* ... ==> ... */
2336 /* op1 = target JavaVM pc */
2338 M_BSR(REG_ITMP1, 0);
2339 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2342 case ICMD_RET: /* ... ==> ... */
2343 /* op1 = local variable */
2345 var = &(rd->locals[iptr->op1][TYPE_ADR]);
2346 if (var->flags & INMEMORY) {
2347 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2348 M_RET(REG_ZERO, REG_ITMP1);
2351 M_RET(REG_ZERO, var->regoff);
2355 case ICMD_IFNULL: /* ..., value ==> ... */
2356 /* op1 = target JavaVM pc */
2358 var_to_reg_int(s1, src, REG_ITMP1);
2360 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2363 case ICMD_IFNONNULL: /* ..., value ==> ... */
2364 /* op1 = target JavaVM pc */
2366 var_to_reg_int(s1, src, REG_ITMP1);
2368 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2371 case ICMD_IFEQ: /* ..., value ==> ... */
2372 /* op1 = target JavaVM pc, val.i = constant */
2374 var_to_reg_int(s1, src, REG_ITMP1);
2375 if (iptr->val.i == 0) {
2379 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2380 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2383 ICONST(REG_ITMP2, iptr->val.i);
2384 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2386 M_BNEZ(REG_ITMP1, 0);
2388 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2391 case ICMD_IFLT: /* ..., value ==> ... */
2392 /* op1 = target JavaVM pc, val.i = constant */
2394 var_to_reg_int(s1, src, REG_ITMP1);
2395 if (iptr->val.i == 0) {
2399 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2400 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2403 ICONST(REG_ITMP2, iptr->val.i);
2404 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2406 M_BNEZ(REG_ITMP1, 0);
2408 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2411 case ICMD_IFLE: /* ..., value ==> ... */
2412 /* op1 = target JavaVM pc, val.i = constant */
2414 var_to_reg_int(s1, src, REG_ITMP1);
2415 if (iptr->val.i == 0) {
2419 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2420 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2423 ICONST(REG_ITMP2, iptr->val.i);
2424 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2426 M_BNEZ(REG_ITMP1, 0);
2428 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2431 case ICMD_IFNE: /* ..., value ==> ... */
2432 /* op1 = target JavaVM pc, val.i = constant */
2434 var_to_reg_int(s1, src, REG_ITMP1);
2435 if (iptr->val.i == 0) {
2439 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2440 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2443 ICONST(REG_ITMP2, iptr->val.i);
2444 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2446 M_BEQZ(REG_ITMP1, 0);
2448 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2451 case ICMD_IFGT: /* ..., value ==> ... */
2452 /* op1 = target JavaVM pc, val.i = constant */
2454 var_to_reg_int(s1, src, REG_ITMP1);
2455 if (iptr->val.i == 0) {
2459 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2460 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2463 ICONST(REG_ITMP2, iptr->val.i);
2464 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2466 M_BEQZ(REG_ITMP1, 0);
2468 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2471 case ICMD_IFGE: /* ..., value ==> ... */
2472 /* op1 = target JavaVM pc, val.i = constant */
2474 var_to_reg_int(s1, src, REG_ITMP1);
2475 if (iptr->val.i == 0) {
2479 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2480 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2483 ICONST(REG_ITMP2, iptr->val.i);
2484 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2486 M_BEQZ(REG_ITMP1, 0);
2488 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2491 case ICMD_IF_LEQ: /* ..., value ==> ... */
2492 /* op1 = target JavaVM pc, val.l = constant */
2494 var_to_reg_int(s1, src, REG_ITMP1);
2495 if (iptr->val.l == 0) {
2499 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2500 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2503 LCONST(REG_ITMP2, iptr->val.l);
2504 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2506 M_BNEZ(REG_ITMP1, 0);
2508 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2511 case ICMD_IF_LLT: /* ..., value ==> ... */
2512 /* op1 = target JavaVM pc, val.l = constant */
2514 var_to_reg_int(s1, src, REG_ITMP1);
2515 if (iptr->val.l == 0) {
2519 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2520 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2523 LCONST(REG_ITMP2, iptr->val.l);
2524 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2526 M_BNEZ(REG_ITMP1, 0);
2528 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2531 case ICMD_IF_LLE: /* ..., value ==> ... */
2532 /* op1 = target JavaVM pc, val.l = constant */
2534 var_to_reg_int(s1, src, REG_ITMP1);
2535 if (iptr->val.l == 0) {
2539 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2540 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2543 LCONST(REG_ITMP2, iptr->val.l);
2544 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2546 M_BNEZ(REG_ITMP1, 0);
2548 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2551 case ICMD_IF_LNE: /* ..., value ==> ... */
2552 /* op1 = target JavaVM pc, val.l = constant */
2554 var_to_reg_int(s1, src, REG_ITMP1);
2555 if (iptr->val.l == 0) {
2559 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2560 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2563 LCONST(REG_ITMP2, iptr->val.l);
2564 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2566 M_BEQZ(REG_ITMP1, 0);
2568 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2571 case ICMD_IF_LGT: /* ..., value ==> ... */
2572 /* op1 = target JavaVM pc, val.l = constant */
2574 var_to_reg_int(s1, src, REG_ITMP1);
2575 if (iptr->val.l == 0) {
2579 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2580 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2583 LCONST(REG_ITMP2, iptr->val.l);
2584 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2586 M_BEQZ(REG_ITMP1, 0);
2588 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2591 case ICMD_IF_LGE: /* ..., value ==> ... */
2592 /* op1 = target JavaVM pc, val.l = constant */
2594 var_to_reg_int(s1, src, REG_ITMP1);
2595 if (iptr->val.l == 0) {
2599 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2600 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2603 LCONST(REG_ITMP2, iptr->val.l);
2604 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2606 M_BEQZ(REG_ITMP1, 0);
2608 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2611 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2612 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2613 case ICMD_IF_ACMPEQ:
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_BNEZ(REG_ITMP1, 0);
2619 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2622 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2623 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2624 case ICMD_IF_ACMPNE:
2626 var_to_reg_int(s1, src->prev, REG_ITMP1);
2627 var_to_reg_int(s2, src, REG_ITMP2);
2628 M_CMPEQ(s1, s2, REG_ITMP1);
2629 M_BEQZ(REG_ITMP1, 0);
2630 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2633 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2634 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2636 var_to_reg_int(s1, src->prev, REG_ITMP1);
2637 var_to_reg_int(s2, src, REG_ITMP2);
2638 M_CMPLT(s1, s2, REG_ITMP1);
2639 M_BNEZ(REG_ITMP1, 0);
2640 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2643 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2644 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2646 var_to_reg_int(s1, src->prev, REG_ITMP1);
2647 var_to_reg_int(s2, src, REG_ITMP2);
2648 M_CMPLE(s1, s2, REG_ITMP1);
2649 M_BEQZ(REG_ITMP1, 0);
2650 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2653 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2654 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2656 var_to_reg_int(s1, src->prev, REG_ITMP1);
2657 var_to_reg_int(s2, src, REG_ITMP2);
2658 M_CMPLE(s1, s2, REG_ITMP1);
2659 M_BNEZ(REG_ITMP1, 0);
2660 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2663 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2664 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2666 var_to_reg_int(s1, src->prev, REG_ITMP1);
2667 var_to_reg_int(s2, src, REG_ITMP2);
2668 M_CMPLT(s1, s2, REG_ITMP1);
2669 M_BEQZ(REG_ITMP1, 0);
2670 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2673 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2675 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2678 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2679 /* val.i = constant */
2681 var_to_reg_int(s1, src, REG_ITMP1);
2682 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2684 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2685 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2686 M_CMPEQ(s1, REG_ZERO, d);
2687 store_reg_to_var_int(iptr->dst, d);
2690 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2691 M_CMPEQ(s1, REG_ZERO, d);
2693 store_reg_to_var_int(iptr->dst, d);
2697 M_MOV(s1, REG_ITMP1);
2700 ICONST(d, iptr[1].val.i);
2702 if ((s3 >= 0) && (s3 <= 255)) {
2703 M_CMOVEQ_IMM(s1, s3, d);
2706 ICONST(REG_ITMP2, s3);
2707 M_CMOVEQ(s1, REG_ITMP2, d);
2709 store_reg_to_var_int(iptr->dst, d);
2712 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2713 /* val.i = constant */
2715 var_to_reg_int(s1, src, REG_ITMP1);
2716 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2718 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2719 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2720 M_CMPEQ(s1, REG_ZERO, d);
2721 store_reg_to_var_int(iptr->dst, d);
2724 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2725 M_CMPEQ(s1, REG_ZERO, d);
2727 store_reg_to_var_int(iptr->dst, d);
2731 M_MOV(s1, REG_ITMP1);
2734 ICONST(d, iptr[1].val.i);
2736 if ((s3 >= 0) && (s3 <= 255)) {
2737 M_CMOVNE_IMM(s1, s3, d);
2740 ICONST(REG_ITMP2, s3);
2741 M_CMOVNE(s1, REG_ITMP2, d);
2743 store_reg_to_var_int(iptr->dst, d);
2746 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2747 /* val.i = constant */
2749 var_to_reg_int(s1, src, REG_ITMP1);
2750 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2752 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2753 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2754 M_CMPLT(s1, REG_ZERO, d);
2755 store_reg_to_var_int(iptr->dst, d);
2758 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2759 M_CMPLE(REG_ZERO, s1, d);
2760 store_reg_to_var_int(iptr->dst, d);
2764 M_MOV(s1, REG_ITMP1);
2767 ICONST(d, iptr[1].val.i);
2769 if ((s3 >= 0) && (s3 <= 255)) {
2770 M_CMOVLT_IMM(s1, s3, d);
2773 ICONST(REG_ITMP2, s3);
2774 M_CMOVLT(s1, REG_ITMP2, d);
2776 store_reg_to_var_int(iptr->dst, d);
2779 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2780 /* val.i = constant */
2782 var_to_reg_int(s1, src, REG_ITMP1);
2783 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2785 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2786 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2787 M_CMPLE(REG_ZERO, s1, d);
2788 store_reg_to_var_int(iptr->dst, d);
2791 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2792 M_CMPLT(s1, REG_ZERO, d);
2793 store_reg_to_var_int(iptr->dst, d);
2797 M_MOV(s1, REG_ITMP1);
2800 ICONST(d, iptr[1].val.i);
2802 if ((s3 >= 0) && (s3 <= 255)) {
2803 M_CMOVGE_IMM(s1, s3, d);
2806 ICONST(REG_ITMP2, s3);
2807 M_CMOVGE(s1, REG_ITMP2, d);
2809 store_reg_to_var_int(iptr->dst, d);
2812 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2813 /* val.i = constant */
2815 var_to_reg_int(s1, src, REG_ITMP1);
2816 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2818 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2819 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2820 M_CMPLT(REG_ZERO, s1, d);
2821 store_reg_to_var_int(iptr->dst, d);
2824 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2825 M_CMPLE(s1, REG_ZERO, d);
2826 store_reg_to_var_int(iptr->dst, d);
2830 M_MOV(s1, REG_ITMP1);
2833 ICONST(d, iptr[1].val.i);
2835 if ((s3 >= 0) && (s3 <= 255)) {
2836 M_CMOVGT_IMM(s1, s3, d);
2839 ICONST(REG_ITMP2, s3);
2840 M_CMOVGT(s1, REG_ITMP2, d);
2842 store_reg_to_var_int(iptr->dst, d);
2845 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2846 /* val.i = constant */
2848 var_to_reg_int(s1, src, REG_ITMP1);
2849 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2851 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2852 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2853 M_CMPLE(s1, REG_ZERO, d);
2854 store_reg_to_var_int(iptr->dst, d);
2857 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2858 M_CMPLT(REG_ZERO, s1, d);
2859 store_reg_to_var_int(iptr->dst, d);
2863 M_MOV(s1, REG_ITMP1);
2866 ICONST(d, iptr[1].val.i);
2868 if ((s3 >= 0) && (s3 <= 255)) {
2869 M_CMOVLE_IMM(s1, s3, d);
2872 ICONST(REG_ITMP2, s3);
2873 M_CMOVLE(s1, REG_ITMP2, d);
2875 store_reg_to_var_int(iptr->dst, d);
2879 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2883 var_to_reg_int(s1, src, REG_RESULT);
2884 M_INTMOVE(s1, REG_RESULT);
2886 #if defined(USE_THREADS)
2887 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2889 a = dseg_addaddress(cd, (void *) (builtin_monitorexit));
2890 M_ALD(REG_PV, REG_PV, a);
2891 M_ALD(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
2892 M_LST(REG_RESULT, REG_SP, rd->maxmemuse * 8);
2893 M_JSR(REG_RA, REG_PV);
2894 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
2895 M_LDA(REG_PV, REG_RA, disp);
2896 M_LLD(REG_RESULT, REG_SP, rd->maxmemuse * 8);
2900 goto nowperformreturn;
2902 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2905 var_to_reg_flt(s1, src, REG_FRESULT);
2906 M_FLTMOVE(s1, REG_FRESULT);
2908 #if defined(USE_THREADS)
2909 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2911 a = dseg_addaddress(cd, (void *) (builtin_monitorexit));
2912 M_ALD(REG_PV, REG_PV, a);
2913 M_ALD(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
2914 M_DST(REG_FRESULT, REG_SP, rd->maxmemuse * 8);
2915 M_JSR(REG_RA, REG_PV);
2916 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
2917 M_LDA(REG_PV, REG_RA, disp);
2918 M_DLD(REG_FRESULT, REG_SP, rd->maxmemuse * 8);
2922 goto nowperformreturn;
2924 case ICMD_RETURN: /* ... ==> ... */
2926 #if defined(USE_THREADS)
2927 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2929 a = dseg_addaddress(cd, (void *) (builtin_monitorexit));
2930 M_ALD(REG_PV, REG_PV, a);
2931 M_ALD(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
2932 M_JSR(REG_RA, REG_PV);
2933 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
2934 M_LDA(REG_PV, REG_RA, disp);
2942 p = parentargs_base;
2944 /* restore return address */
2946 if (!m->isleafmethod) {
2947 p--; M_LLD(REG_RA, REG_SP, p * 8);
2950 /* restore saved registers */
2952 for (i = rd->savintregcnt - 1; i >= rd->maxsavintreguse; i--) {
2953 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2955 for (i = rd->savfltregcnt - 1; i >= rd->maxsavfltreguse; i--) {
2956 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2959 /* deallocate stack */
2961 if (parentargs_base) {
2962 M_LDA(REG_SP, REG_SP, parentargs_base * 8);
2965 /* call trace function */
2968 M_LDA(REG_SP, REG_SP, -3 * 8);
2969 M_AST(REG_RA, REG_SP, 0 * 8);
2970 M_LST(REG_RESULT, REG_SP, 1 * 8);
2971 M_DST(REG_FRESULT, REG_SP, 2 * 8);
2972 a = dseg_addaddress(cd, m);
2973 M_ALD(rd->argintregs[0], REG_PV, a);
2974 M_MOV(REG_RESULT, rd->argintregs[1]);
2975 M_FLTMOVE(REG_FRESULT, rd->argfltregs[2]);
2976 M_FLTMOVE(REG_FRESULT, rd->argfltregs[3]);
2977 a = dseg_addaddress(cd, (void *) builtin_displaymethodstop);
2978 M_ALD(REG_PV, REG_PV, a);
2979 M_JSR(REG_RA, REG_PV);
2980 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
2981 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
2983 s4 ml = -s1, mh = 0;
2984 while (ml < -32768) { ml += 65536; mh--; }
2985 M_LDA(REG_PV, REG_RA, ml);
2986 M_LDAH(REG_PV, REG_PV, mh);
2988 M_DLD(REG_FRESULT, REG_SP, 2 * 8);
2989 M_LLD(REG_RESULT, REG_SP, 1 * 8);
2990 M_ALD(REG_RA, REG_SP, 0 * 8);
2991 M_LDA(REG_SP, REG_SP, 3 * 8);
2994 M_RET(REG_ZERO, REG_RA);
3000 case ICMD_TABLESWITCH: /* ..., index ==> ... */
3005 tptr = (void **) iptr->target;
3007 s4ptr = iptr->val.a;
3008 l = s4ptr[1]; /* low */
3009 i = s4ptr[2]; /* high */
3011 var_to_reg_int(s1, src, REG_ITMP1);
3013 {M_INTMOVE(s1, REG_ITMP1);}
3014 else if (l <= 32768) {
3015 M_LDA(REG_ITMP1, s1, -l);
3018 ICONST(REG_ITMP2, l);
3019 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
3026 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
3028 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
3029 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3031 M_BEQZ(REG_ITMP2, 0);
3034 /* codegen_addreference(cd, BlockPtrOfPC(s4ptr[0]), mcodeptr); */
3035 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3037 /* build jump table top down and use address of lowest entry */
3039 /* s4ptr += 3 + i; */
3043 /* dseg_addtarget(cd, BlockPtrOfPC(*--s4ptr)); */
3044 dseg_addtarget(cd, (basicblock *) tptr[0]);
3049 /* length of dataseg after last dseg_addtarget is used by load */
3051 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
3052 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
3053 M_JMP(REG_ZERO, REG_ITMP2);
3058 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3060 s4 i, l, val, *s4ptr;
3063 tptr = (void **) iptr->target;
3065 s4ptr = iptr->val.a;
3066 l = s4ptr[0]; /* default */
3067 i = s4ptr[1]; /* count */
3069 MCODECHECK((i<<2)+8);
3070 var_to_reg_int(s1, src, REG_ITMP1);
3076 if ((val >= 0) && (val <= 255)) {
3077 M_CMPEQ_IMM(s1, val, REG_ITMP2);
3080 if ((val >= -32768) && (val <= 32767)) {
3081 M_LDA(REG_ITMP2, REG_ZERO, val);
3084 a = dseg_adds4(cd, val);
3085 M_ILD(REG_ITMP2, REG_PV, a);
3087 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
3089 M_BNEZ(REG_ITMP2, 0);
3090 /* codegen_addreference(cd, BlockPtrOfPC(s4ptr[1]), mcodeptr); */
3091 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3095 /* codegen_addreference(cd, BlockPtrOfPC(l), mcodeptr); */
3097 tptr = (void **) iptr->target;
3098 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3105 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
3106 /* op1 = return type, val.a = function pointer*/
3110 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
3111 /* op1 = return type, val.a = function pointer*/
3115 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
3116 /* op1 = return type, val.a = function pointer*/
3120 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3121 /* op1 = arg count, val.a = method pointer */
3123 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3124 /* op1 = arg count, val.a = method pointer */
3126 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3127 /* op1 = arg count, val.a = method pointer */
3129 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
3130 /* op1 = arg count, val.a = method pointer */
3137 MCODECHECK((s3 << 1) + 64);
3139 /* copy arguments to registers or stack location */
3141 for (; --s3 >= 0; src = src->prev) {
3142 if (src->varkind == ARGVAR)
3144 if (IS_INT_LNG_TYPE(src->type)) {
3145 if (s3 < INT_ARG_CNT) {
3146 s1 = rd->argintregs[s3];
3147 var_to_reg_int(d, src, s1);
3151 var_to_reg_int(d, src, REG_ITMP1);
3152 M_LST(d, REG_SP, 8 * (s3 - INT_ARG_CNT));
3156 if (s3 < FLT_ARG_CNT) {
3157 s1 = rd->argfltregs[s3];
3158 var_to_reg_flt(d, src, s1);
3162 var_to_reg_flt(d, src, REG_FTMP1);
3163 M_DST(d, REG_SP, 8 * (s3 - FLT_ARG_CNT));
3169 switch (iptr->opc) {
3173 a = dseg_addaddress(cd, (void *) lm);
3176 M_ALD(REG_PV, REG_PV, a); /* Pointer to built-in-function */
3179 case ICMD_INVOKESTATIC:
3180 case ICMD_INVOKESPECIAL:
3181 a = dseg_addaddress(cd, lm->stubroutine);
3184 M_ALD(REG_PV, REG_PV, a); /* method pointer in r27 */
3187 case ICMD_INVOKEVIRTUAL:
3190 gen_nullptr_check(rd->argintregs[0]);
3191 M_ALD(REG_METHODPTR, rd->argintregs[0],
3192 OFFSET(java_objectheader, vftbl));
3193 M_ALD(REG_PV, REG_METHODPTR, OFFSET(vftbl_t, table[0]) +
3194 sizeof(methodptr) * lm->vftblindex);
3197 case ICMD_INVOKEINTERFACE:
3200 gen_nullptr_check(rd->argintregs[0]);
3201 M_ALD(REG_METHODPTR, rd->argintregs[0],
3202 OFFSET(java_objectheader, vftbl));
3203 M_ALD(REG_METHODPTR, REG_METHODPTR,
3204 OFFSET(vftbl_t, interfacetable[0]) -
3205 sizeof(methodptr*) * lm->class->index);
3206 M_ALD(REG_PV, REG_METHODPTR,
3207 sizeof(methodptr) * (lm - lm->class->methods));
3211 M_JSR(REG_RA, REG_PV);
3215 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3216 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3218 s4 ml = -s1, mh = 0;
3219 while (ml < -32768) { ml += 65536; mh--; }
3220 M_LDA(REG_PV, REG_RA, ml);
3221 M_LDAH(REG_PV, REG_PV, mh);
3224 /* d contains return type */
3226 if (d != TYPE_VOID) {
3227 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3228 s1 = reg_of_var(rd, iptr->dst, REG_RESULT);
3229 M_INTMOVE(REG_RESULT, s1);
3230 store_reg_to_var_int(iptr->dst, s1);
3233 s1 = reg_of_var(rd, iptr->dst, REG_FRESULT);
3234 M_FLTMOVE(REG_FRESULT, s1);
3235 store_reg_to_var_flt(iptr->dst, s1);
3242 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3244 /* op1: 0 == array, 1 == class */
3245 /* val.a: (classinfo*) superclass */
3247 /* superclass is an interface:
3249 * return (sub != NULL) &&
3250 * (sub->vftbl->interfacetablelength > super->index) &&
3251 * (sub->vftbl->interfacetable[-super->index] != NULL);
3253 * superclass is a class:
3255 * return ((sub != NULL) && (0
3256 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3257 * super->vftbl->diffvall));
3261 classinfo *super = (classinfo*) iptr->val.a;
3263 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3264 codegen_threadcritrestart(cd, (u1 *) mcodeptr - cd->mcodebase);
3266 var_to_reg_int(s1, src, REG_ITMP1);
3267 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
3269 M_MOV(s1, REG_ITMP1);
3273 if (iptr->op1) { /* class/interface */
3274 if (super->flags & ACC_INTERFACE) { /* interface */
3276 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3277 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3278 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3279 M_BLEZ(REG_ITMP2, 2);
3280 M_ALD(REG_ITMP1, REG_ITMP1,
3281 OFFSET(vftbl_t, interfacetable[0]) -
3282 super->index * sizeof(methodptr*));
3283 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3287 s2 = super->vftbl->diffval;
3288 M_BEQZ(s1, 4 + (s2 > 255));
3289 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3290 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3291 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3293 M_CMPULE_IMM(REG_ITMP1, s2, d);
3295 M_LDA(REG_ITMP2, REG_ZERO, s2);
3296 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3300 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3301 a = dseg_addaddress(cd, (void*) super->vftbl);
3302 M_ALD(REG_ITMP2, REG_PV, a);
3303 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3304 codegen_threadcritstart(cd, (u1 *) mcodeptr - cd->mcodebase);
3306 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3307 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3308 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3309 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3310 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3312 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3313 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3317 panic ("internal error: no inlined array instanceof");
3319 store_reg_to_var_int(iptr->dst, d);
3322 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3324 /* op1: 0 == array, 1 == class */
3325 /* val.a: (classinfo*) superclass */
3327 /* superclass is an interface:
3329 * OK if ((sub == NULL) ||
3330 * (sub->vftbl->interfacetablelength > super->index) &&
3331 * (sub->vftbl->interfacetable[-super->index] != NULL));
3333 * superclass is a class:
3335 * OK if ((sub == NULL) || (0
3336 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3337 * super->vftbl->diffvall));
3341 classinfo *super = (classinfo *) iptr->val.a;
3343 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3344 codegen_threadcritrestart(cd, (u1 *) mcodeptr - cd->mcodebase);
3346 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
3347 var_to_reg_int(s1, src, d);
3348 if (iptr->op1) { /* class/interface */
3349 if (super->flags & ACC_INTERFACE) { /* interface */
3351 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3352 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3353 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3354 M_BLEZ(REG_ITMP2, 0);
3355 codegen_addxcastrefs(cd, mcodeptr);
3356 M_ALD(REG_ITMP2, REG_ITMP1,
3357 OFFSET(vftbl_t, interfacetable[0]) -
3358 super->index * sizeof(methodptr*));
3359 M_BEQZ(REG_ITMP2, 0);
3360 codegen_addxcastrefs(cd, mcodeptr);
3364 s2 = super->vftbl->diffval;
3365 M_BEQZ(s1, 4 + (s2 != 0) + (s2 > 255));
3366 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3367 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3368 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3370 M_BNEZ(REG_ITMP1, 0);
3372 else if (s2 <= 255) {
3373 M_CMPULE_IMM(REG_ITMP1, s2, REG_ITMP2);
3374 M_BEQZ(REG_ITMP2, 0);
3377 M_LDA(REG_ITMP2, REG_ZERO, s2);
3378 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3379 M_BEQZ(REG_ITMP2, 0);
3382 M_BEQZ(s1, 8 + (d == REG_ITMP3));
3383 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3384 a = dseg_addaddress(cd, (void *) super->vftbl);
3385 M_ALD(REG_ITMP2, REG_PV, a);
3386 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3387 codegen_threadcritstart(cd, (u1 *) mcodeptr - cd->mcodebase);
3389 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3390 if (d != REG_ITMP3) {
3391 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3392 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3393 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3394 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3396 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3399 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3400 M_ISUB(REG_ITMP1, REG_ITMP2, REG_ITMP1);
3401 M_ALD(REG_ITMP2, REG_PV, a);
3402 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3403 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3404 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3407 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3408 M_BEQZ(REG_ITMP2, 0);
3409 codegen_addxcastrefs(cd, mcodeptr);
3413 panic ("internal error: no inlined array checkcast");
3416 store_reg_to_var_int(iptr->dst, d);
3419 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
3421 var_to_reg_int(s1, src, REG_ITMP1);
3423 codegen_addxcheckarefs(cd, mcodeptr);
3426 case ICMD_CHECKEXCEPTION: /* ... ==> ... */
3428 M_BEQZ(REG_RESULT, 0);
3429 codegen_addxexceptionrefs(cd, mcodeptr);
3432 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3433 /* op1 = dimension, val.a = array descriptor */
3435 /* check for negative sizes and copy sizes to stack if necessary */
3437 MCODECHECK((iptr->op1 << 1) + 64);
3439 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3440 var_to_reg_int(s2, src, REG_ITMP1);
3442 codegen_addxcheckarefs(cd, mcodeptr);
3444 /* copy SAVEDVAR sizes to stack */
3446 if (src->varkind != ARGVAR) {
3447 M_LST(s2, REG_SP, s1 * 8);
3451 /* a0 = dimension count */
3453 ICONST(rd->argintregs[0], iptr->op1);
3455 /* a1 = arraydescriptor */
3457 a = dseg_addaddress(cd, iptr->val.a);
3458 M_ALD(rd->argintregs[1], REG_PV, a);
3460 /* a2 = pointer to dimensions = stack pointer */
3462 M_INTMOVE(REG_SP, rd->argintregs[2]);
3464 a = dseg_addaddress(cd, (void *) builtin_nmultianewarray);
3465 M_ALD(REG_PV, REG_PV, a);
3466 M_JSR(REG_RA, REG_PV);
3467 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3469 M_LDA(REG_PV, REG_RA, -s1);
3471 s4 ml = -s1, mh = 0;
3472 while (ml < -32768) { ml += 65536; mh--; }
3473 M_LDA(REG_PV, REG_RA, ml);
3474 M_LDAH(REG_PV, REG_PV, mh);
3476 s1 = reg_of_var(rd, iptr->dst, REG_RESULT);
3477 M_INTMOVE(REG_RESULT, s1);
3478 store_reg_to_var_int(iptr->dst, s1);
3482 throw_cacao_exception_exit(string_java_lang_InternalError,
3483 "Unknown ICMD %d", iptr->opc);
3486 } /* for instruction */
3488 /* copy values to interface registers */
3490 src = bptr->outstack;
3491 len = bptr->outdepth;
3498 if ((src->varkind != STACKVAR)) {
3500 if (IS_FLT_DBL_TYPE(s2)) {
3501 var_to_reg_flt(s1, src, REG_FTMP1);
3502 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3503 M_FLTMOVE(s1,rd->interfaces[len][s2].regoff);
3506 M_DST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3510 var_to_reg_int(s1, src, REG_ITMP1);
3511 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3512 M_INTMOVE(s1,rd->interfaces[len][s2].regoff);
3515 M_LST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3521 } /* if (bptr -> flags >= BBREACHED) */
3522 } /* for basic block */
3524 codegen_createlinenumbertable(cd);
3527 /* generate bound check stubs */
3529 s4 *xcodeptr = NULL;
3532 for (bref = cd->xboundrefs; bref != NULL; bref = bref->next) {
3533 gen_resolvebranch((u1*) cd->mcodebase + bref->branchpos,
3535 (u1*) mcodeptr - cd->mcodebase);
3539 /* move index register into REG_ITMP1 */
3540 M_MOV(bref->reg, REG_ITMP1);
3541 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3543 if (xcodeptr != NULL) {
3544 M_BR(xcodeptr - mcodeptr - 1);
3547 xcodeptr = mcodeptr;
3549 a = dseg_addaddress(cd, asm_throw_and_handle_arrayindexoutofbounds_exception);
3550 M_ALD(REG_PV, REG_PV, a);
3552 M_JSR(REG_RA, REG_PV);
3555 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3556 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3558 s4 ml = -s1, mh = 0;
3559 while (ml < -32768) { ml += 65536; mh--; }
3560 M_LDA(REG_PV, REG_RA, ml);
3561 M_LDAH(REG_PV, REG_PV, mh);
3566 /* generate negative array size check stubs */
3570 for (bref = cd->xcheckarefs; bref != NULL; bref = bref->next) {
3571 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3572 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3574 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3578 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3580 (u1 *) mcodeptr - cd->mcodebase);
3584 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3586 if (xcodeptr != NULL) {
3587 M_BR(xcodeptr - mcodeptr - 1);
3590 xcodeptr = mcodeptr;
3593 a = dseg_addaddress(cd, string_java_lang_NegativeArraySizeException);
3594 M_ALD(REG_ITMP1_XPTR,REG_PV,a);
3596 a = dseg_addaddress(cd, asm_throw_and_handle_nat_exception);
3597 M_ALD(REG_PV, REG_PV, a);
3599 M_JSR(REG_RA, REG_PV);
3602 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3603 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3605 s4 ml = -s1, mh = 0;
3606 while (ml < -32768) { ml += 65536; mh--; }
3607 M_LDA(REG_PV, REG_RA, ml);
3608 M_LDAH(REG_PV, REG_PV, mh);
3615 /* generate cast check stubs */
3619 for (bref = cd->xcastrefs; bref != NULL; bref = bref->next) {
3620 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3621 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3623 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3627 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3629 (u1 *) mcodeptr - cd->mcodebase);
3633 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3635 if (xcodeptr != NULL) {
3636 M_BR(xcodeptr - mcodeptr - 1);
3639 xcodeptr = mcodeptr;
3641 a = dseg_addaddress(cd, string_java_lang_ClassCastException);
3642 M_ALD(REG_ITMP1_XPTR,REG_PV,a);
3644 a = dseg_addaddress(cd, asm_throw_and_handle_nat_exception);
3645 M_ALD(REG_PV, REG_PV, a);
3647 M_JSR(REG_RA, REG_PV);
3650 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3651 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3653 s4 ml = -s1, mh = 0;
3654 while (ml < -32768) { ml += 65536; mh--; }
3655 M_LDA(REG_PV, REG_RA, ml);
3656 M_LDAH(REG_PV, REG_PV, mh);
3662 /* generate exception check stubs */
3666 for (bref = cd->xexceptionrefs; bref != NULL; bref = bref->next) {
3667 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3668 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3670 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3674 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3676 (u1 *) mcodeptr - cd->mcodebase);
3680 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3682 if (xcodeptr != NULL) {
3683 M_BR(xcodeptr - mcodeptr - 1);
3686 xcodeptr = mcodeptr;
3688 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3689 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3690 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3692 a = dseg_addaddress(cd, &builtin_get_exceptionptrptr);
3693 M_ALD(REG_PV, REG_PV, a);
3694 M_JSR(REG_RA, REG_PV);
3697 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3698 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3700 s4 ml = -s1, mh = 0;
3701 while (ml < -32768) { ml += 65536; mh--; }
3702 M_LDA(REG_PV, REG_RA, ml);
3703 M_LDAH(REG_PV, REG_PV, mh);
3706 M_ALD(REG_ITMP1_XPTR, REG_RESULT, 0);
3707 M_AST(REG_ZERO, REG_RESULT, 0);
3709 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3710 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3712 a = dseg_addaddress(cd, &_exceptionptr);
3713 M_ALD(REG_ITMP3, REG_PV, a);
3714 M_ALD(REG_ITMP1_XPTR, REG_ITMP3, 0);
3715 M_AST(REG_ZERO, REG_ITMP3, 0);
3718 a = dseg_addaddress(cd, asm_refillin_and_handle_exception);
3719 M_ALD(REG_PV, REG_PV, a);
3721 M_JMP(REG_RA, REG_PV);
3724 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3725 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3727 s4 ml = -s1, mh = 0;
3728 while (ml < -32768) { ml += 65536; mh--; }
3729 M_LDA(REG_PV, REG_RA, ml);
3730 M_LDAH(REG_PV, REG_PV, mh);
3736 /* generate null pointer check stubs */
3740 for (bref = cd->xnullrefs; bref != NULL; bref = bref->next) {
3741 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3742 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3744 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3748 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3750 (u1 *) mcodeptr - cd->mcodebase);
3754 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3756 if (xcodeptr != NULL) {
3757 M_BR(xcodeptr - mcodeptr - 1);
3760 xcodeptr = mcodeptr;
3762 a = dseg_addaddress(cd, string_java_lang_NullPointerException);
3763 M_ALD(REG_ITMP1_XPTR,REG_PV,a);
3765 a = dseg_addaddress(cd, asm_throw_and_handle_nat_exception);
3766 M_ALD(REG_PV, REG_PV, a);
3768 M_JSR(REG_RA, REG_PV);
3771 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3772 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3774 s4 ml = -s1, mh = 0;
3775 while (ml < -32768) { ml += 65536; mh--; }
3776 M_LDA(REG_PV, REG_RA, ml);
3777 M_LDAH(REG_PV, REG_PV, mh);
3783 /* generate put/getstatic stub call code */
3790 for (cref = cd->clinitrefs; cref != NULL; cref = cref->next) {
3791 /* Get machine code which is patched back in later. The call is */
3792 /* 1 instruction word long. */
3793 xcodeptr = (s4 *) (cd->mcodebase + cref->branchpos);
3796 /* patch in the call to call the following code (done at compile */
3799 tmpmcodeptr = mcodeptr; /* save current mcodeptr */
3800 mcodeptr = xcodeptr; /* set mcodeptr to patch position */
3802 M_BSR(REG_RA, tmpmcodeptr - (xcodeptr + 1));
3804 mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
3808 /* move class pointer into REG_ITMP2 */
3809 a = dseg_addaddress(cd, cref->class);
3810 M_ALD(REG_ITMP1, REG_PV, a);
3812 /* move machine code onto stack */
3813 a = dseg_adds4(cd, mcode);
3814 M_ILD(REG_ITMP3, REG_PV, a);
3815 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3816 M_IST(REG_ITMP3, REG_SP, 0);
3818 a = dseg_addaddress(cd, asm_check_clinit);
3819 M_ALD(REG_ITMP2, REG_PV, a);
3820 M_JMP(REG_ZERO, REG_ITMP2);
3825 codegen_finish(m, cd, (s4) ((u1 *) mcodeptr - cd->mcodebase));
3829 /* function createcompilerstub *************************************************
3831 creates a stub routine which calls the compiler
3833 *******************************************************************************/
3835 #define COMPSTUBSIZE 3
3837 u1 *createcompilerstub(methodinfo *m)
3839 u8 *s = CNEW(u8, COMPSTUBSIZE); /* memory to hold the stub */
3840 s4 *mcodeptr = (s4 *) s; /* code generation pointer */
3842 /* code for the stub */
3843 M_ALD(REG_PV, REG_PV, 16); /* load pointer to the compiler */
3844 M_JMP(0, REG_PV); /* jump to the compiler, return address
3845 in reg 0 is used as method pointer */
3846 s[1] = (u8) m; /* literals to be adressed */
3847 s[2] = (u8) asm_call_jit_compiler; /* jump directly via PV from above */
3849 #if defined(STATISTICS)
3851 count_cstub_len += COMPSTUBSIZE * 8;
3858 /* function removecompilerstub *************************************************
3860 deletes a compilerstub from memory (simply by freeing it)
3862 *******************************************************************************/
3864 void removecompilerstub(u1 *stub)
3866 CFREE(stub, COMPSTUBSIZE * 8);
3870 /* function: createnativestub **************************************************
3872 creates a stub routine which calls a native method
3874 *******************************************************************************/
3877 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3878 #define NATIVESTUB_STACK 8/*ra,native result, oldThreadspecificHeadValue, addressOfThreadspecificHead, method, 0,0,ra*/
3879 #define NATIVESTUB_THREAD_EXTRA (6 + 20) /*20 for additional frame creation*/
3880 #define NATIVESTUB_STACKTRACE_OFFSET 1
3882 #define NATIVESTUB_STACK 7/*ra,oldThreadspecificHeadValue, addressOfThreadspecificHead, method, 0,0,ra*/
3883 #define NATIVESTUB_THREAD_EXTRA (1 + 20) /*20 for additional frame creation*/
3884 #define NATIVESTUB_STACKTRACE_OFFSET 0
3887 #define NATIVESTUB_SIZE (44 + NATIVESTUB_THREAD_EXTRA - 1)
3888 #define NATIVESTUB_STATIC_SIZE 5
3889 #define NATIVESTUB_VERBOSE_SIZE (39 + 13)
3890 #define NATIVESTUB_OFFSET 11
3893 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3894 #define NATIVESTUB_STACK 2
3895 #define NATIVESTUB_THREAD_EXTRA 6
3897 #define NATIVESTUB_STACK 1
3898 #define NATIVESTUB_THREAD_EXTRA 1
3901 #define NATIVESTUB_SIZE (44 + NATIVESTUB_THREAD_EXTRA - 1)
3902 #define NATIVESTUB_STATIC_SIZE 4
3903 #define NATIVESTUB_VERBOSE_SIZE (39 + 13)
3904 #define NATIVESTUB_OFFSET 10
3907 u1 *createnativestub(functionptr f, methodinfo *m)
3909 u8 *s; /* memory pointer to hold the stub */
3911 s4 *mcodeptr; /* code generation pointer */
3912 s4 stackframesize = 0; /* size of stackframe if needed */
3917 t_inlining_globals *id;
3920 /* mark start of dump memory area */
3922 dumpsize = dump_size();
3924 /* setup registers before using it */
3926 cd = DNEW(codegendata);
3927 rd = DNEW(registerdata);
3928 id = DNEW(t_inlining_globals);
3930 inlining_setup(m, id);
3931 reg_setup(m, rd, id);
3933 descriptor2types(m); /* set paramcount and paramtypes */
3935 stubsize = NATIVESTUB_SIZE; /* calculate nativestub size */
3937 if ((m->flags & ACC_STATIC) && !m->class->initialized)
3938 stubsize += NATIVESTUB_STATIC_SIZE;
3941 stubsize += NATIVESTUB_VERBOSE_SIZE;
3943 s = CNEW(u8, stubsize); /* memory to hold the stub */
3944 cs = s + NATIVESTUB_OFFSET;
3945 mcodeptr = (s4 *) cs; /* code generation pointer */
3947 /* set some required varibles which are normally set by codegen_setup */
3948 cd->mcodebase = (u1 *) mcodeptr;
3949 cd->clinitrefs = NULL;
3951 *(cs-1) = (u8) f; /* address of native method */
3952 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3953 *(cs-2) = (u8) &builtin_get_exceptionptrptr;
3955 *(cs-2) = (u8) (&_exceptionptr); /* address of exceptionptr */
3957 *(cs-3) = (u8) asm_handle_nat_exception; /* addr of asm exception handler*/
3958 *(cs-4) = (u8) (&env); /* addr of jni_environement */
3959 *(cs-5) = (u8) builtin_trace_args;
3961 *(cs-7) = (u8) builtin_displaymethodstop;
3962 *(cs-8) = (u8) m->class;
3963 *(cs-9) = (u8) asm_check_clinit;
3964 *(cs-10) = (u8) &builtin_asm_get_stackframeinfo;
3965 *(cs-11) = (u8) NULL; /* filled with machine code */
3967 M_LDA(REG_SP, REG_SP, -NATIVESTUB_STACK * 8); /* build up stackframe */
3968 M_AST(REG_RA, REG_SP, 0 * 8); /* store return address */
3970 M_AST(REG_RA, REG_SP, (6+NATIVESTUB_STACKTRACE_OFFSET) * 8); /* store return address in stackinfo helper*/
3972 /* if function is static, check for initialized */
3974 if (m->flags & ACC_STATIC) {
3975 /* if class isn't yet initialized, do it */
3976 if (!m->class->initialized) {
3977 codegen_addclinitref(cd, mcodeptr, m->class);
3981 /* max. 39 +9 instructions */
3985 M_LDA(REG_SP, REG_SP, -((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
3986 M_AST(REG_RA, REG_SP, 1 * 8);
3988 /* save integer argument registers */
3989 for (p = 0; p < m->paramcount && p < INT_ARG_CNT; p++) {
3990 M_LST(rd->argintregs[p], REG_SP, (2 + p) * 8);
3993 /* save and copy float arguments into integer registers */
3994 for (p = 0; p < m->paramcount && p < FLT_ARG_CNT; p++) {
3995 t = m->paramtypes[p];
3997 if (IS_FLT_DBL_TYPE(t)) {
3998 if (IS_2_WORD_TYPE(t)) {
3999 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4000 M_LLD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4003 M_FST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4004 M_ILD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4008 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4013 M_ALD(REG_ITMP1, REG_PV, -6 * 8);
4014 M_AST(REG_ITMP1, REG_SP, 0 * 8);
4015 M_ALD(REG_PV, REG_PV, -5 * 8);
4016 M_JSR(REG_RA, REG_PV);
4017 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4018 M_LDA(REG_PV, REG_RA, disp);
4023 M_ALD(REG_PV, REG_PV, -10 * 8); /* builtin_asm_get_stackframeinfo */
4024 M_JSR(REG_RA, REG_PV);
4025 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4026 M_LDA(REG_PV, REG_RA, disp);
4029 M_MOV(REG_RESULT,REG_ITMP3);
4030 M_LST(REG_RESULT,REG_ITMP3,0);
4032 M_LST(REG_RESULT,REG_SP, ((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8)+(2+NATIVESTUB_STACKTRACE_OFFSET)*8);/*save adress of pointer*/
4033 M_LLD(REG_ITMP3,REG_RESULT,0); /* get pointer*/
4034 M_LST(REG_ITMP3,REG_SP,(1+NATIVESTUB_STACKTRACE_OFFSET)*8+((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8)); /*save old value*/
4035 M_LDA(REG_ITMP3,REG_SP,(1+NATIVESTUB_STACKTRACE_OFFSET)*8+((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8)); /*calculate new value*/
4036 M_LLD(REG_ITMP2,REG_ITMP3,8);
4037 M_LST(REG_ITMP3,REG_ITMP2,0); /*store new value*/
4038 M_LLD(REG_ITMP2,REG_PV,-6*8);
4039 M_LST(REG_ITMP2,REG_SP,(3+NATIVESTUB_STACKTRACE_OFFSET)*8+((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
4040 M_LST(REG_ZERO,REG_SP,(4+NATIVESTUB_STACKTRACE_OFFSET)*8+((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
4041 M_LST(REG_ZERO,REG_SP,(5+NATIVESTUB_STACKTRACE_OFFSET)*8+((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
4042 /*stack info -end */
4045 for (p = 0; p < m->paramcount && p < INT_ARG_CNT; p++) {
4046 M_LLD(rd->argintregs[p], REG_SP, (2 + p) * 8);
4049 for (p = 0; p < m->paramcount && p < FLT_ARG_CNT; p++) {
4050 t = m->paramtypes[p];
4052 if (IS_FLT_DBL_TYPE(t)) {
4053 if (IS_2_WORD_TYPE(t)) {
4054 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4057 M_FLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4061 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4065 M_ALD(REG_RA, REG_SP, 1 * 8);
4066 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT + 2) * 8);
4069 /* save argument registers on stack -- if we have to */
4070 if ((m->flags & ACC_STATIC && m->paramcount > (INT_ARG_CNT - 2)) || m->paramcount > (INT_ARG_CNT - 1)) {
4072 s4 paramshiftcnt = (m->flags & ACC_STATIC) ? 2 : 1;
4073 s4 stackparamcnt = (m->paramcount > INT_ARG_CNT) ? m->paramcount - INT_ARG_CNT : 0;
4075 stackframesize = stackparamcnt + paramshiftcnt;
4077 M_LDA(REG_SP, REG_SP, -stackframesize * 8);
4079 /* copy stack arguments into new stack frame -- if any */
4080 for (i = 0; i < stackparamcnt; i++) {
4081 M_LLD(REG_ITMP1, REG_SP, (stackparamcnt + 1 + i) * 8);
4082 M_LST(REG_ITMP1, REG_SP, (paramshiftcnt + i) * 8);
4085 if (m->flags & ACC_STATIC) {
4086 if (IS_FLT_DBL_TYPE(m->paramtypes[5])) {
4087 M_DST(rd->argfltregs[5], REG_SP, 1 * 8);
4089 M_LST(rd->argintregs[5], REG_SP, 1 * 8);
4092 if (IS_FLT_DBL_TYPE(m->paramtypes[4])) {
4093 M_DST(rd->argfltregs[4], REG_SP, 0 * 8);
4095 M_LST(rd->argintregs[4], REG_SP, 0 * 8);
4099 if (IS_FLT_DBL_TYPE(m->paramtypes[5])) {
4100 M_DST(rd->argfltregs[5], REG_SP, 0 * 8);
4102 M_LST(rd->argintregs[5], REG_SP, 0 * 8);
4107 if (m->flags & ACC_STATIC) {
4108 M_MOV(rd->argintregs[3], rd->argintregs[5]);
4109 M_MOV(rd->argintregs[2], rd->argintregs[4]);
4110 M_MOV(rd->argintregs[1], rd->argintregs[3]);
4111 M_MOV(rd->argintregs[0], rd->argintregs[2]);
4112 M_FMOV(rd->argfltregs[3], rd->argfltregs[5]);
4113 M_FMOV(rd->argfltregs[2], rd->argfltregs[4]);
4114 M_FMOV(rd->argfltregs[1], rd->argfltregs[3]);
4115 M_FMOV(rd->argfltregs[0], rd->argfltregs[2]);
4117 /* put class into second argument register */
4118 M_ALD(rd->argintregs[1], REG_PV, -8 * 8);
4121 M_MOV(rd->argintregs[4], rd->argintregs[5]);
4122 M_MOV(rd->argintregs[3], rd->argintregs[4]);
4123 M_MOV(rd->argintregs[2], rd->argintregs[3]);
4124 M_MOV(rd->argintregs[1], rd->argintregs[2]);
4125 M_MOV(rd->argintregs[0], rd->argintregs[1]);
4126 M_FMOV(rd->argfltregs[4], rd->argfltregs[5]);
4127 M_FMOV(rd->argfltregs[3], rd->argfltregs[4]);
4128 M_FMOV(rd->argfltregs[2], rd->argfltregs[3]);
4129 M_FMOV(rd->argfltregs[1], rd->argfltregs[2]);
4130 M_FMOV(rd->argfltregs[0], rd->argfltregs[1]);
4133 /* put env into first argument register */
4134 M_ALD(rd->argintregs[0], REG_PV, -4 * 8);
4136 M_ALD(REG_PV, REG_PV, -1 * 8); /* load adress of native method */
4137 M_JSR(REG_RA, REG_PV); /* call native method */
4138 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4139 M_LDA(REG_PV, REG_RA, disp); /* recompute pv from ra */
4141 /* remove stackframe if there is one */
4142 if (stackframesize) {
4143 M_LDA(REG_SP, REG_SP, stackframesize * 8);
4146 /* 13 instructions */
4148 M_LDA(REG_SP, REG_SP, -2 * 8);
4149 M_ALD(rd->argintregs[0], REG_PV, -6 * 8); /* load method adress */
4150 M_LST(REG_RESULT, REG_SP, 0 * 8);
4151 M_DST(REG_FRESULT, REG_SP, 1 * 8);
4152 M_MOV(REG_RESULT, rd->argintregs[1]);
4153 M_FMOV(REG_FRESULT, rd->argfltregs[2]);
4154 M_FMOV(REG_FRESULT, rd->argfltregs[3]);
4155 M_ALD(REG_PV, REG_PV, -7 * 8); /* builtin_displaymethodstop */
4156 M_JSR(REG_RA, REG_PV);
4157 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4158 M_LDA(REG_PV, REG_RA, disp);
4159 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4160 M_DLD(REG_FRESULT, REG_SP, 1 * 8);
4161 M_LDA(REG_SP, REG_SP, 2 * 8);
4164 M_LLD(REG_ITMP3,REG_SP,(2+NATIVESTUB_STACKTRACE_OFFSET)*8); /*get address of stacktrace helper pointer*/
4165 M_LLD(REG_ITMP1,REG_SP,(1+NATIVESTUB_STACKTRACE_OFFSET)*8); /*get old value*/
4166 M_LST(REG_ITMP1,REG_ITMP3,0); /*set old value*/
4168 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4169 if (IS_FLT_DBL_TYPE(m->returntype))
4170 M_DST(REG_FRESULT, REG_SP, 1 * 8);
4172 M_AST(REG_RESULT, REG_SP, 1 * 8);
4173 M_ALD(REG_PV, REG_PV, -2 * 8); /* builtin_get_exceptionptrptr */
4174 M_JSR(REG_RA, REG_PV);
4175 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4176 M_LDA(REG_PV, REG_RA, disp);
4177 M_MOV(REG_RESULT, REG_ITMP3);
4178 if (IS_FLT_DBL_TYPE(m->returntype))
4179 M_DLD(REG_FRESULT, REG_SP, 1 * 8);
4181 M_ALD(REG_RESULT, REG_SP, 1 * 8);
4183 M_ALD(REG_ITMP3, REG_PV, -2 * 8); /* get address of exceptionptr */
4185 M_ALD(REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
4186 M_BNEZ(REG_ITMP1, 3); /* if no exception then return */
4188 M_ALD(REG_RA, REG_SP, 0 * 8); /* load return address */
4189 M_LDA(REG_SP, REG_SP, NATIVESTUB_STACK * 8); /* remove stackframe */
4190 M_RET(REG_ZERO, REG_RA); /* return to caller */
4192 M_AST(REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
4194 M_ALD(REG_RA, REG_SP, 0 * 8); /* load return address */
4195 M_LDA(REG_SP, REG_SP, NATIVESTUB_STACK * 8); /* remove stackframe */
4196 M_LDA(REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
4197 M_ALD(REG_ITMP3, REG_PV, -3 * 8); /* load asm exception handler address */
4198 M_JMP(REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
4200 /* generate put/getstatic stub call code */
4207 /* there can only be one clinit ref entry */
4208 cref = cd->clinitrefs;
4211 /* Get machine code which is patched back in later. The call is */
4212 /* 1 instruction word long. */
4213 xcodeptr = (s4 *) (cd->mcodebase + cref->branchpos);
4214 *(cs-11) = (u4) *xcodeptr;
4216 /* patch in the call to call the following code (done at compile */
4219 tmpmcodeptr = mcodeptr; /* save current mcodeptr */
4220 mcodeptr = xcodeptr; /* set mcodeptr to patch position */
4222 M_BSR(REG_RA, tmpmcodeptr - (xcodeptr + 1));
4224 mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
4226 /* move class pointer into REG_ITMP2 */
4227 M_ALD(REG_ITMP1, REG_PV, -8 * 8); /* class */
4229 /* move machine code into REG_ITMP3 */
4230 M_ILD(REG_ITMP3, REG_PV, -11 * 8); /* machine code */
4231 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
4232 M_IST(REG_ITMP3, REG_SP, 0);
4234 M_ALD(REG_ITMP2, REG_PV, -9 * 8); /* asm_check_clinit */
4235 M_JMP(REG_ZERO, REG_ITMP2);
4239 /* Check if the stub size is big enough to hold the whole stub generated. */
4240 /* If not, this can lead into unpredictable crashes, because of heap */
4242 if ((s4) ((ptrint) mcodeptr - (ptrint) s) > stubsize * sizeof(u8)) {
4243 throw_cacao_exception_exit(string_java_lang_InternalError,
4244 "Native stub size %d is to small for current stub size %d",
4245 stubsize, (s4) ((ptrint) mcodeptr - (ptrint) s));
4248 #if defined(STATISTICS)
4250 count_nstub_len += NATIVESTUB_SIZE * 8;
4253 /* release dump area */
4255 dump_release(dumpsize);
4257 return (u1 *) (s + NATIVESTUB_OFFSET);
4261 /* function: removenativestub **************************************************
4263 removes a previously created native-stub from memory
4265 *******************************************************************************/
4267 void removenativestub(u1 *stub)
4269 CFREE((u8 *) stub - NATIVESTUBOFFSET, NATIVESTUBSIZE * 8);
4274 * These are local overrides for various environment variables in Emacs.
4275 * Please do not remove this and leave it at the end of the file, where
4276 * Emacs will automagically detect them.
4277 * ---------------------------------------------------------------------
4280 * indent-tabs-mode: t