1 /* jit/alpha/codegen.c - machine code generator for alpha
3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4 Institut f. Computersprachen, TU Wien
5 R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser, M. Probst,
6 S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich,
9 This file is part of CACAO.
11 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License as
13 published by the Free Software Foundation; either version 2, or (at
14 your option) any later version.
16 This program is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
26 Contact: cacao@complang.tuwien.ac.at
28 Authors: Andreas Krall
31 $Id: codegen.c 899 2004-01-22 13:24:36Z twisti $
52 /* include independent code generation stuff */
53 #include "codegen.inc"
57 /* *****************************************************************************
59 Datatypes and Register Allocations:
60 -----------------------------------
62 On 64-bit-machines (like the Alpha) all operands are stored in the
63 registers in a 64-bit form, even when the correspondig JavaVM operands
64 only need 32 bits. This is done by a canonical representation:
66 32-bit integers are allways stored as sign-extended 64-bit values (this
67 approach is directly supported by the Alpha architecture and is very easy
70 32-bit-floats are stored in a 64-bit doubleprecision register by simply
71 expanding the exponent and mantissa with zeroes. (also supported by the
77 The calling conventions and the layout of the stack is explained in detail
78 in the documention file: calling.doc
80 *******************************************************************************/
83 /* register descripton - array ************************************************/
85 /* #define REG_RES 0 reserved register for OS or code generator */
86 /* #define REG_RET 1 return value register */
87 /* #define REG_EXC 2 exception value register (only old jit) */
88 /* #define REG_SAV 3 (callee) saved register */
89 /* #define REG_TMP 4 scratch temporary register (caller saved) */
90 /* #define REG_ARG 5 argument register (caller saved) */
92 /* #define REG_END -1 last entry in tables */
95 REG_RET, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
96 REG_TMP, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
97 REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_TMP, REG_TMP,
98 REG_TMP, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES,
101 /* for use of reserved registers, see comment above */
103 int nregdescfloat[] = {
104 REG_RET, REG_TMP, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
105 REG_SAV, REG_SAV, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
106 REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_TMP, REG_TMP,
107 REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_RES, REG_RES, REG_RES, REG_RES,
110 /* for use of reserved registers, see comment above */
113 /* parameter allocation mode */
115 int nreg_parammode = PARAMMODE_NUMBERED;
117 /* parameter-registers will be allocated by assigning the
118 1. parameter: int/float-reg 16
119 2. parameter: int/float-reg 17
120 3. parameter: int/float-reg 18 ....
124 /* stackframe-infos ***********************************************************/
126 int parentargs_base; /* offset in stackframe for the parameter from the caller*/
128 /* -> see file 'calling.doc' */
131 /* additional functions and macros to generate code ***************************/
133 /* #define BlockPtrOfPC(pc) block+block_index[pc] */
134 #define BlockPtrOfPC(pc) ((basicblock *) iptr->target)
138 #define COUNT_SPILLS count_spills++
144 /* gen_nullptr_check(objreg) */
146 #ifdef SOFTNULLPTRCHECK
147 #define gen_nullptr_check(objreg) \
149 M_BEQZ((objreg), 0);\
150 codegen_addxnullrefs(mcodeptr);\
153 #define gen_nullptr_check(objreg)
157 /* MCODECHECK(icnt) */
159 #define MCODECHECK(icnt) \
160 if((mcodeptr + (icnt)) > mcodeend) mcodeptr = codegen_increase((u1*) mcodeptr)
163 generates an integer-move from register a to b.
164 if a and b are the same int-register, no code will be generated.
167 #define M_INTMOVE(a,b) if(a!=b){M_MOV(a,b);}
171 generates a floating-point-move from register a to b.
172 if a and b are the same float-register, no code will be generated
175 #define M_FLTMOVE(a,b) if(a!=b){M_FMOV(a,b);}
179 this function generates code to fetch data from a pseudo-register
180 into a real register.
181 If the pseudo-register has actually been assigned to a real
182 register, no code will be emitted, since following operations
183 can use this register directly.
185 v: pseudoregister to be fetched from
186 tempregnum: temporary register to be used if v is actually spilled to ram
188 return: the register number, where the operand can be found after
189 fetching (this wil be either tempregnum or the register
190 number allready given to v)
193 #define var_to_reg_int(regnr,v,tempnr) { \
194 if ((v)->flags & INMEMORY) \
195 {COUNT_SPILLS;M_LLD(tempnr,REG_SP,8*(v)->regoff);regnr=tempnr;} \
196 else regnr=(v)->regoff; \
200 #define var_to_reg_flt(regnr,v,tempnr) { \
201 if ((v)->flags & INMEMORY) \
202 {COUNT_SPILLS;M_DLD(tempnr,REG_SP,8*(v)->regoff);regnr=tempnr;} \
203 else regnr=(v)->regoff; \
208 This function determines a register, to which the result of an operation
209 should go, when it is ultimatively intended to store the result in
211 If v is assigned to an actual register, this register will be returned.
212 Otherwise (when v is spilled) this function returns tempregnum.
213 If not already done, regoff and flags are set in the stack location.
216 static int reg_of_var(stackptr v, int tempregnum)
220 switch (v->varkind) {
222 if (!(v->flags & INMEMORY))
226 var = &(interfaces[v->varnum][v->type]);
227 v->regoff = var->regoff;
228 if (!(var->flags & INMEMORY))
232 var = &(locals[v->varnum][v->type]);
233 v->regoff = var->regoff;
234 if (!(var->flags & INMEMORY))
238 v->regoff = v->varnum;
239 if (IS_FLT_DBL_TYPE(v->type)) {
240 if (v->varnum < fltreg_argnum) {
241 v->regoff = argfltregs[v->varnum];
242 return(argfltregs[v->varnum]);
246 if (v->varnum < intreg_argnum) {
247 v->regoff = argintregs[v->varnum];
248 return(argintregs[v->varnum]);
250 v->regoff -= intreg_argnum;
253 v->flags |= INMEMORY;
258 /* store_reg_to_var_xxx:
259 This function generates the code to store the result of an operation
260 back into a spilled pseudo-variable.
261 If the pseudo-variable has not been spilled in the first place, this
262 function will generate nothing.
264 v ............ Pseudovariable
265 tempregnum ... Number of the temporary registers as returned by
269 #define store_reg_to_var_int(sptr, tempregnum) { \
270 if ((sptr)->flags & INMEMORY) { \
272 M_LST(tempregnum, REG_SP, 8 * (sptr)->regoff); \
276 #define store_reg_to_var_flt(sptr, tempregnum) { \
277 if ((sptr)->flags & INMEMORY) { \
279 M_DST(tempregnum, REG_SP, 8 * (sptr)->regoff); \
284 /* NullPointerException handlers and exception handling initialisation */
286 typedef struct sigctx_struct {
288 long sc_onstack; /* sigstack state to restore */
289 long sc_mask; /* signal mask to restore */
290 long sc_pc; /* pc at time of signal */
291 long sc_ps; /* psl to retore */
292 long sc_regs[32]; /* processor regs 0 to 31 */
293 long sc_ownedfp; /* fp has been used */
294 long sc_fpregs[32]; /* fp regs 0 to 31 */
295 unsigned long sc_fpcr; /* floating point control register */
296 unsigned long sc_fp_control; /* software fpcr */
298 unsigned long sc_reserved1, sc_reserved2;
299 unsigned long sc_ssize;
301 unsigned long sc_traparg_a0;
302 unsigned long sc_traparg_a1;
303 unsigned long sc_traparg_a2;
304 unsigned long sc_fp_trap_pc;
305 unsigned long sc_fp_trigger_sum;
306 unsigned long sc_fp_trigger_inst;
307 unsigned long sc_retcode[2];
311 /* NullPointerException signal handler for hardware null pointer check */
313 void catch_NullPointerException(int sig, int code, sigctx_struct *sigctx)
319 /* Reset signal handler - necessary for SysV, does no harm for BSD */
321 instr = *((int*)(sigctx->sc_pc));
322 faultaddr = sigctx->sc_regs[(instr >> 16) & 0x1f];
324 if (faultaddr == 0) {
325 signal(sig, (void*) catch_NullPointerException); /* reinstall handler */
327 sigaddset(&nsig, sig);
328 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
329 sigctx->sc_regs[REG_ITMP1_XPTR] =
330 (long) proto_java_lang_NullPointerException;
331 sigctx->sc_regs[REG_ITMP2_XPC] = sigctx->sc_pc;
332 sigctx->sc_pc = (long) asm_handle_exception;
336 faultaddr += (long) ((instr << 16) >> 16);
337 fprintf(stderr, "faulting address: 0x%16lx\n", faultaddr);
338 panic("Stack overflow");
345 void init_exceptions(void)
350 /* Linux on Digital Alpha needs an initialisation of the ieee floating point
351 control for IEEE compliant arithmetic (option -mieee of GCC). Under
352 Digital Unix this is done automatically.
357 extern unsigned long ieee_get_fp_control();
358 extern void ieee_set_fp_control(unsigned long fp_control);
360 void init_exceptions(void)
362 /* initialize floating point control */
364 ieee_set_fp_control(ieee_get_fp_control()
365 & ~IEEE_TRAP_ENABLE_INV
366 & ~IEEE_TRAP_ENABLE_DZE
367 /* & ~IEEE_TRAP_ENABLE_UNF we dont want underflow */
368 & ~IEEE_TRAP_ENABLE_OVF);
371 /* install signal handlers we need to convert to exceptions */
376 signal(SIGSEGV, (void*) catch_NullPointerException);
380 signal(SIGBUS, (void*) catch_NullPointerException);
386 /* function gen_mcode **********************************************************
388 generates machine code
390 *******************************************************************************/
392 #define MethodPointer -8
393 #define FrameSize -12
398 #define ExTableSize -32
399 #define ExTableStart -32
401 #define ExEntrySize -32
404 #define ExHandlerPC -24
405 #define ExCatchType -32
409 int len, s1, s2, s3, d;
421 savedregs_num = (isleafmethod) ? 0 : 1; /* space to save the RA */
423 /* space to save used callee saved registers */
425 savedregs_num += (savintregcnt - maxsavintreguse);
426 savedregs_num += (savfltregcnt - maxsavfltreguse);
428 parentargs_base = maxmemuse + savedregs_num;
430 #ifdef USE_THREADS /* space to save argument of monitor_enter */
432 if (checksync && (method->flags & ACC_SYNCHRONIZED))
437 /* create method header */
439 (void) dseg_addaddress(method); /* MethodPointer */
440 (void) dseg_adds4(parentargs_base * 8); /* FrameSize */
444 /* IsSync contains the offset relative to the stack pointer for the
445 argument of monitor_exit used in the exception handler. Since the
446 offset could be zero and give a wrong meaning of the flag it is
450 if (checksync && (method->flags & ACC_SYNCHRONIZED))
451 (void) dseg_adds4((maxmemuse + 1) * 8); /* IsSync */
456 (void) dseg_adds4(0); /* IsSync */
458 (void) dseg_adds4(isleafmethod); /* IsLeaf */
459 (void) dseg_adds4(savintregcnt - maxsavintreguse); /* IntSave */
460 (void) dseg_adds4(savfltregcnt - maxsavfltreguse); /* FltSave */
461 (void) dseg_adds4(exceptiontablelength); /* ExTableSize */
463 /* create exception table */
465 for (ex = extable; ex != NULL; ex = ex->down) {
468 if (ex->start != NULL)
469 printf("adding start - %d - ", ex->start->debug_nr);
471 printf("PANIC - start is NULL");
476 dseg_addtarget(ex->start);
480 printf("adding end - %d - ", ex->end->debug_nr);
482 printf("PANIC - end is NULL");
487 dseg_addtarget(ex->end);
490 if (ex->handler != NULL)
491 printf("adding handler - %d\n", ex->handler->debug_nr);
493 printf("PANIC - handler is NULL");
498 dseg_addtarget(ex->handler);
500 (void) dseg_addaddress(ex->catchtype);
503 /* initialize mcode variables */
505 mcodeptr = (s4*) mcodebase;
506 mcodeend = (s4*) (mcodebase + mcodesize);
507 MCODECHECK(128 + mparamcount);
509 /* create stack frame (if necessary) */
512 {M_LDA (REG_SP, REG_SP, -parentargs_base * 8);}
514 /* save return address and used callee saved registers */
518 {p--; M_AST (REG_RA, REG_SP, 8*p);}
519 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
520 {p--; M_LST (savintregs[r], REG_SP, 8 * p);}
521 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
522 {p--; M_DST (savfltregs[r], REG_SP, 8 * p);}
524 /* save monitorenter argument */
527 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
528 if (method->flags & ACC_STATIC) {
529 p = dseg_addaddress (class);
530 M_ALD(REG_ITMP1, REG_PV, p);
531 M_AST(REG_ITMP1, REG_SP, 8 * maxmemuse);
534 M_AST (argintregs[0], REG_SP, 8 * maxmemuse);
539 /* copy argument registers to stack and call trace function with pointer
540 to arguments on stack.
545 M_LDA(REG_SP, REG_SP, -(14 * 8));
546 M_AST(REG_RA, REG_SP, 1 * 8);
548 /* save integer argument registers */
549 for (p = 0; p < mparamcount && p < INT_ARG_CNT; p++) {
550 M_LST(argintregs[p], REG_SP, (2 + p) * 8);
553 /* save and copy float arguments into integer registers */
554 for (p = 0; p < mparamcount && p < FLT_ARG_CNT; p++) {
557 if (IS_FLT_DBL_TYPE(t)) {
558 if (IS_2_WORD_TYPE(t)) {
559 M_DST(argfltregs[p], REG_SP, (8 + p) * 8);
561 M_FST(argfltregs[p], REG_SP, (8 + p) * 8);
564 M_LLD(argintregs[p], REG_SP, (8 + p) * 8);
567 M_DST(argfltregs[p], REG_SP, (8 + p) * 8);
571 p = dseg_addaddress(method);
572 M_ALD(REG_ITMP1, REG_PV, p);
573 M_AST(REG_ITMP1, REG_SP, 0);
574 p = dseg_addaddress((void *) builtin_trace_args);
575 M_ALD(REG_PV, REG_PV, p);
576 M_JSR(REG_RA, REG_PV);
577 disp = -(int)((u1 *) mcodeptr - mcodebase);
578 M_LDA(REG_PV, REG_RA, disp);
579 M_ALD(REG_RA, REG_SP, 1 * 8);
581 for (p = 0; p < mparamcount && p < INT_ARG_CNT; p++) {
582 M_LLD(argintregs[p], REG_SP, (2 + p) * 8);
585 for (p = 0; p < mparamcount && p < FLT_ARG_CNT; p++) {
588 if (IS_FLT_DBL_TYPE(t)) {
589 if (IS_2_WORD_TYPE(t)) {
590 M_DLD(argfltregs[p], REG_SP, (8 + p) * 8);
592 M_FLD(argfltregs[p], REG_SP, (8 + p) * 8);
595 M_DLD(argfltregs[p], REG_SP, (8 + p) * 8);
599 M_LDA (REG_SP, REG_SP, 14 * 8);
602 /* take arguments out of register or stack frame */
604 for (p = 0, l = 0; p < mparamcount; p++) {
606 var = &(locals[l][t]);
608 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
613 if (IS_INT_LNG_TYPE(t)) { /* integer args */
614 if (p < INT_ARG_CNT) { /* register arguments */
615 if (!(var->flags & INMEMORY)) /* reg arg -> register */
616 {M_INTMOVE (argintregs[p], r);}
617 else /* reg arg -> spilled */
618 M_LST (argintregs[p], REG_SP, 8 * r);
620 else { /* stack arguments */
621 pa = p - INT_ARG_CNT;
622 if (!(var->flags & INMEMORY)) /* stack arg -> register */
623 M_LLD (r, REG_SP, 8 * (parentargs_base + pa));
624 else { /* stack arg -> spilled */
625 M_LLD (REG_ITMP1, REG_SP, 8 * (parentargs_base + pa));
626 M_LST (REG_ITMP1, REG_SP, 8 * r);
630 else { /* floating args */
631 if (p < FLT_ARG_CNT) { /* register arguments */
632 if (!(var->flags & INMEMORY)) /* reg arg -> register */
633 {M_FLTMOVE (argfltregs[p], r);}
634 else /* reg arg -> spilled */
635 M_DST (argfltregs[p], REG_SP, 8 * r);
637 else { /* stack arguments */
638 pa = p - FLT_ARG_CNT;
639 if (!(var->flags & INMEMORY)) /* stack-arg -> register */
640 M_DLD (r, REG_SP, 8 * (parentargs_base + pa) );
641 else { /* stack-arg -> spilled */
642 M_DLD (REG_FTMP1, REG_SP, 8 * (parentargs_base + pa));
643 M_DST (REG_FTMP1, REG_SP, 8 * r);
649 /* call trace function */
652 if (runverbose && !isleafmethod) {
653 M_LDA (REG_SP, REG_SP, -8);
654 p = dseg_addaddress (method);
655 M_ALD(REG_ITMP1, REG_PV, p);
656 M_AST(REG_ITMP1, REG_SP, 0);
657 p = dseg_addaddress ((void*) (builtin_trace_args));
658 M_ALD(REG_PV, REG_PV, p);
659 M_JSR(REG_RA, REG_PV);
660 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
661 M_LDA(REG_SP, REG_SP, 8);
665 /* call monitorenter function */
668 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
670 p = dseg_addaddress ((void*) (builtin_monitorenter));
671 M_ALD(REG_PV, REG_PV, p);
672 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
673 M_JSR(REG_RA, REG_PV);
674 disp = -(int)((u1*) mcodeptr - mcodebase);
675 M_LDA(REG_PV, REG_RA, disp);
680 /* end of header generation */
682 /* walk through all basic blocks */
683 for (bptr = block; bptr != NULL; bptr = bptr->next) {
685 bptr->mpc = (int)((u1*) mcodeptr - mcodebase);
687 if (bptr->flags >= BBREACHED) {
689 /* branch resolving */
693 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
694 gen_resolvebranch((u1*) mcodebase + brefs->branchpos,
695 brefs->branchpos, bptr->mpc);
699 /* copy interface registers to their destination */
704 while (src != NULL) {
706 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
707 d = reg_of_var(src, REG_ITMP1);
708 M_INTMOVE(REG_ITMP1, d);
709 store_reg_to_var_int(src, d);
712 d = reg_of_var(src, REG_IFTMP);
713 if ((src->varkind != STACKVAR)) {
715 if (IS_FLT_DBL_TYPE(s2)) {
716 if (!(interfaces[len][s2].flags & INMEMORY)) {
717 s1 = interfaces[len][s2].regoff;
721 M_DLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
723 store_reg_to_var_flt(src, d);
726 if (!(interfaces[len][s2].flags & INMEMORY)) {
727 s1 = interfaces[len][s2].regoff;
731 M_LLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
733 store_reg_to_var_int(src, d);
740 /* walk through all instructions */
744 for (iptr = bptr->iinstr;
746 src = iptr->dst, len--, iptr++) {
748 MCODECHECK(64); /* an instruction usually needs < 64 words */
751 case ICMD_NOP: /* ... ==> ... */
754 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
756 var_to_reg_int(s1, src, REG_ITMP1);
758 codegen_addxnullrefs(mcodeptr);
761 /* constant operations ************************************************/
763 #define ICONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
764 else{a=dseg_adds4(c);M_ILD(r,REG_PV,a);}
766 #define LCONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
767 else{a=dseg_adds8(c);M_LLD(r,REG_PV,a);}
769 case ICMD_ICONST: /* ... ==> ..., constant */
770 /* op1 = 0, val.i = constant */
772 d = reg_of_var(iptr->dst, REG_ITMP1);
773 ICONST(d, iptr->val.i);
774 store_reg_to_var_int(iptr->dst, d);
777 case ICMD_LCONST: /* ... ==> ..., constant */
778 /* op1 = 0, val.l = constant */
780 d = reg_of_var(iptr->dst, REG_ITMP1);
781 LCONST(d, iptr->val.l);
782 store_reg_to_var_int(iptr->dst, d);
785 case ICMD_FCONST: /* ... ==> ..., constant */
786 /* op1 = 0, val.f = constant */
788 d = reg_of_var(iptr->dst, REG_FTMP1);
789 a = dseg_addfloat(iptr->val.f);
791 store_reg_to_var_flt(iptr->dst, d);
794 case ICMD_DCONST: /* ... ==> ..., constant */
795 /* op1 = 0, val.d = constant */
797 d = reg_of_var(iptr->dst, REG_FTMP1);
798 a = dseg_adddouble(iptr->val.d);
800 store_reg_to_var_flt(iptr->dst, d);
803 case ICMD_ACONST: /* ... ==> ..., constant */
804 /* op1 = 0, val.a = constant */
806 d = reg_of_var(iptr->dst, REG_ITMP1);
808 a = dseg_addaddress (iptr->val.a);
812 M_INTMOVE(REG_ZERO, d);
814 store_reg_to_var_int(iptr->dst, d);
818 /* load/store operations **********************************************/
820 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
821 case ICMD_LLOAD: /* op1 = local variable */
824 d = reg_of_var(iptr->dst, REG_ITMP1);
825 if ((iptr->dst->varkind == LOCALVAR) &&
826 (iptr->dst->varnum == iptr->op1))
828 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
829 if (var->flags & INMEMORY)
830 M_LLD(d, REG_SP, 8 * var->regoff);
832 {M_INTMOVE(var->regoff,d);}
833 store_reg_to_var_int(iptr->dst, d);
836 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
837 case ICMD_DLOAD: /* op1 = local variable */
839 d = reg_of_var(iptr->dst, REG_FTMP1);
840 if ((iptr->dst->varkind == LOCALVAR) &&
841 (iptr->dst->varnum == iptr->op1))
843 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
844 if (var->flags & INMEMORY)
845 M_DLD(d, REG_SP, 8 * var->regoff);
847 {M_FLTMOVE(var->regoff,d);}
848 store_reg_to_var_flt(iptr->dst, d);
852 case ICMD_ISTORE: /* ..., value ==> ... */
853 case ICMD_LSTORE: /* op1 = local variable */
856 if ((src->varkind == LOCALVAR) &&
857 (src->varnum == iptr->op1))
859 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
860 if (var->flags & INMEMORY) {
861 var_to_reg_int(s1, src, REG_ITMP1);
862 M_LST(s1, REG_SP, 8 * var->regoff);
865 var_to_reg_int(s1, src, var->regoff);
866 M_INTMOVE(s1, var->regoff);
870 case ICMD_FSTORE: /* ..., value ==> ... */
871 case ICMD_DSTORE: /* op1 = local variable */
873 if ((src->varkind == LOCALVAR) &&
874 (src->varnum == iptr->op1))
876 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
877 if (var->flags & INMEMORY) {
878 var_to_reg_flt(s1, src, REG_FTMP1);
879 M_DST(s1, REG_SP, 8 * var->regoff);
882 var_to_reg_flt(s1, src, var->regoff);
883 M_FLTMOVE(s1, var->regoff);
888 /* pop/dup/swap operations ********************************************/
890 /* attention: double and longs are only one entry in CACAO ICMDs */
892 case ICMD_POP: /* ..., value ==> ... */
893 case ICMD_POP2: /* ..., value, value ==> ... */
896 #define M_COPY(from,to) \
897 d = reg_of_var(to, REG_IFTMP); \
898 if ((from->regoff != to->regoff) || \
899 ((from->flags ^ to->flags) & INMEMORY)) { \
900 if (IS_FLT_DBL_TYPE(from->type)) { \
901 var_to_reg_flt(s1, from, d); \
903 store_reg_to_var_flt(to, d); \
906 var_to_reg_int(s1, from, d); \
908 store_reg_to_var_int(to, d); \
912 case ICMD_DUP: /* ..., a ==> ..., a, a */
913 M_COPY(src, iptr->dst);
916 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
918 M_COPY(src, iptr->dst->prev->prev);
920 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
922 M_COPY(src, iptr->dst);
923 M_COPY(src->prev, iptr->dst->prev);
926 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
928 M_COPY(src->prev, iptr->dst->prev->prev->prev);
930 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
932 M_COPY(src, iptr->dst);
933 M_COPY(src->prev, iptr->dst->prev);
934 M_COPY(src->prev->prev, iptr->dst->prev->prev);
935 M_COPY(src, iptr->dst->prev->prev->prev);
938 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
940 M_COPY(src, iptr->dst);
941 M_COPY(src->prev, iptr->dst->prev);
942 M_COPY(src->prev->prev, iptr->dst->prev->prev);
943 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
944 M_COPY(src, iptr->dst->prev->prev->prev->prev);
945 M_COPY(src->prev, iptr->dst->prev->prev->prev->prev->prev);
948 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
950 M_COPY(src, iptr->dst->prev);
951 M_COPY(src->prev, iptr->dst);
955 /* integer operations *************************************************/
957 case ICMD_INEG: /* ..., value ==> ..., - value */
959 var_to_reg_int(s1, src, REG_ITMP1);
960 d = reg_of_var(iptr->dst, REG_ITMP3);
961 M_ISUB(REG_ZERO, s1, d);
962 store_reg_to_var_int(iptr->dst, d);
965 case ICMD_LNEG: /* ..., value ==> ..., - value */
967 var_to_reg_int(s1, src, REG_ITMP1);
968 d = reg_of_var(iptr->dst, REG_ITMP3);
969 M_LSUB(REG_ZERO, s1, d);
970 store_reg_to_var_int(iptr->dst, d);
973 case ICMD_I2L: /* ..., value ==> ..., value */
975 var_to_reg_int(s1, src, REG_ITMP1);
976 d = reg_of_var(iptr->dst, REG_ITMP3);
978 store_reg_to_var_int(iptr->dst, d);
981 case ICMD_L2I: /* ..., value ==> ..., value */
983 var_to_reg_int(s1, src, REG_ITMP1);
984 d = reg_of_var(iptr->dst, REG_ITMP3);
985 M_IADD(s1, REG_ZERO, d );
986 store_reg_to_var_int(iptr->dst, d);
989 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
991 var_to_reg_int(s1, src, REG_ITMP1);
992 d = reg_of_var(iptr->dst, REG_ITMP3);
993 if (has_ext_instr_set) {
997 M_SLL_IMM(s1, 56, d);
998 M_SRA_IMM( d, 56, d);
1000 store_reg_to_var_int(iptr->dst, d);
1003 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
1005 var_to_reg_int(s1, src, REG_ITMP1);
1006 d = reg_of_var(iptr->dst, REG_ITMP3);
1008 store_reg_to_var_int(iptr->dst, d);
1011 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
1013 var_to_reg_int(s1, src, REG_ITMP1);
1014 d = reg_of_var(iptr->dst, REG_ITMP3);
1015 if (has_ext_instr_set) {
1019 M_SLL_IMM(s1, 48, d);
1020 M_SRA_IMM( d, 48, d);
1022 store_reg_to_var_int(iptr->dst, d);
1026 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1028 var_to_reg_int(s1, src->prev, REG_ITMP1);
1029 var_to_reg_int(s2, src, REG_ITMP2);
1030 d = reg_of_var(iptr->dst, REG_ITMP3);
1032 store_reg_to_var_int(iptr->dst, d);
1035 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
1036 /* val.i = constant */
1038 var_to_reg_int(s1, src, REG_ITMP1);
1039 d = reg_of_var(iptr->dst, REG_ITMP3);
1040 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1041 M_IADD_IMM(s1, iptr->val.i, d);
1044 ICONST(REG_ITMP2, iptr->val.i);
1045 M_IADD(s1, REG_ITMP2, d);
1047 store_reg_to_var_int(iptr->dst, d);
1050 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1052 var_to_reg_int(s1, src->prev, REG_ITMP1);
1053 var_to_reg_int(s2, src, REG_ITMP2);
1054 d = reg_of_var(iptr->dst, REG_ITMP3);
1056 store_reg_to_var_int(iptr->dst, d);
1059 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
1060 /* val.l = constant */
1062 var_to_reg_int(s1, src, REG_ITMP1);
1063 d = reg_of_var(iptr->dst, REG_ITMP3);
1064 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1065 M_LADD_IMM(s1, iptr->val.l, d);
1068 LCONST(REG_ITMP2, iptr->val.l);
1069 M_LADD(s1, REG_ITMP2, d);
1071 store_reg_to_var_int(iptr->dst, d);
1074 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1076 var_to_reg_int(s1, src->prev, REG_ITMP1);
1077 var_to_reg_int(s2, src, REG_ITMP2);
1078 d = reg_of_var(iptr->dst, REG_ITMP3);
1080 store_reg_to_var_int(iptr->dst, d);
1083 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
1084 /* val.i = constant */
1086 var_to_reg_int(s1, src, REG_ITMP1);
1087 d = reg_of_var(iptr->dst, REG_ITMP3);
1088 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1089 M_ISUB_IMM(s1, iptr->val.i, d);
1092 ICONST(REG_ITMP2, iptr->val.i);
1093 M_ISUB(s1, REG_ITMP2, d);
1095 store_reg_to_var_int(iptr->dst, d);
1098 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1100 var_to_reg_int(s1, src->prev, REG_ITMP1);
1101 var_to_reg_int(s2, src, REG_ITMP2);
1102 d = reg_of_var(iptr->dst, REG_ITMP3);
1104 store_reg_to_var_int(iptr->dst, d);
1107 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
1108 /* val.l = constant */
1110 var_to_reg_int(s1, src, REG_ITMP1);
1111 d = reg_of_var(iptr->dst, REG_ITMP3);
1112 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1113 M_LSUB_IMM(s1, iptr->val.l, d);
1116 LCONST(REG_ITMP2, iptr->val.l);
1117 M_LSUB(s1, REG_ITMP2, d);
1119 store_reg_to_var_int(iptr->dst, d);
1122 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1124 var_to_reg_int(s1, src->prev, REG_ITMP1);
1125 var_to_reg_int(s2, src, REG_ITMP2);
1126 d = reg_of_var(iptr->dst, REG_ITMP3);
1128 store_reg_to_var_int(iptr->dst, d);
1131 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
1132 /* val.i = constant */
1134 var_to_reg_int(s1, src, REG_ITMP1);
1135 d = reg_of_var(iptr->dst, REG_ITMP3);
1136 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1137 M_IMUL_IMM(s1, iptr->val.i, d);
1140 ICONST(REG_ITMP2, iptr->val.i);
1141 M_IMUL(s1, REG_ITMP2, d);
1143 store_reg_to_var_int(iptr->dst, d);
1146 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1148 var_to_reg_int(s1, src->prev, REG_ITMP1);
1149 var_to_reg_int(s2, src, REG_ITMP2);
1150 d = reg_of_var(iptr->dst, REG_ITMP3);
1152 store_reg_to_var_int(iptr->dst, d);
1155 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
1156 /* val.l = constant */
1158 var_to_reg_int(s1, src, REG_ITMP1);
1159 d = reg_of_var(iptr->dst, REG_ITMP3);
1160 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1161 M_LMUL_IMM(s1, iptr->val.l, d);
1164 LCONST(REG_ITMP2, iptr->val.l);
1165 M_LMUL(s1, REG_ITMP2, d);
1167 store_reg_to_var_int(iptr->dst, d);
1170 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
1171 case ICMD_LDIVPOW2: /* val.i = constant */
1173 var_to_reg_int(s1, src, REG_ITMP1);
1174 d = reg_of_var(iptr->dst, REG_ITMP3);
1175 if (iptr->val.i <= 15) {
1176 M_LDA(REG_ITMP2, s1, (1 << iptr->val.i) -1);
1177 M_CMOVGE(s1, s1, REG_ITMP2);
1180 M_SRA_IMM(s1, 63, REG_ITMP2);
1181 M_SRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
1182 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1184 M_SRA_IMM(REG_ITMP2, iptr->val.i, d);
1185 store_reg_to_var_int(iptr->dst, d);
1188 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1190 var_to_reg_int(s1, src->prev, REG_ITMP1);
1191 var_to_reg_int(s2, src, REG_ITMP2);
1192 d = reg_of_var(iptr->dst, REG_ITMP3);
1193 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1194 M_SLL(s1, REG_ITMP3, d);
1195 M_IADD(d, REG_ZERO, d);
1196 store_reg_to_var_int(iptr->dst, d);
1199 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1200 /* val.i = constant */
1202 var_to_reg_int(s1, src, REG_ITMP1);
1203 d = reg_of_var(iptr->dst, REG_ITMP3);
1204 M_SLL_IMM(s1, iptr->val.i & 0x1f, d);
1205 M_IADD(d, REG_ZERO, d);
1206 store_reg_to_var_int(iptr->dst, d);
1209 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1211 var_to_reg_int(s1, src->prev, REG_ITMP1);
1212 var_to_reg_int(s2, src, REG_ITMP2);
1213 d = reg_of_var(iptr->dst, REG_ITMP3);
1214 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1215 M_SRA(s1, REG_ITMP3, d);
1216 store_reg_to_var_int(iptr->dst, d);
1219 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1220 /* val.i = constant */
1222 var_to_reg_int(s1, src, REG_ITMP1);
1223 d = reg_of_var(iptr->dst, REG_ITMP3);
1224 M_SRA_IMM(s1, iptr->val.i & 0x1f, d);
1225 store_reg_to_var_int(iptr->dst, d);
1228 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1230 var_to_reg_int(s1, src->prev, REG_ITMP1);
1231 var_to_reg_int(s2, src, REG_ITMP2);
1232 d = reg_of_var(iptr->dst, REG_ITMP3);
1233 M_AND_IMM(s2, 0x1f, REG_ITMP2);
1235 M_SRL(d, REG_ITMP2, d);
1236 M_IADD(d, REG_ZERO, d);
1237 store_reg_to_var_int(iptr->dst, d);
1240 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1241 /* val.i = constant */
1243 var_to_reg_int(s1, src, REG_ITMP1);
1244 d = reg_of_var(iptr->dst, REG_ITMP3);
1246 M_SRL_IMM(d, iptr->val.i & 0x1f, d);
1247 M_IADD(d, REG_ZERO, d);
1248 store_reg_to_var_int(iptr->dst, d);
1251 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1253 var_to_reg_int(s1, src->prev, REG_ITMP1);
1254 var_to_reg_int(s2, src, REG_ITMP2);
1255 d = reg_of_var(iptr->dst, REG_ITMP3);
1257 store_reg_to_var_int(iptr->dst, d);
1260 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1261 /* val.i = constant */
1263 var_to_reg_int(s1, src, REG_ITMP1);
1264 d = reg_of_var(iptr->dst, REG_ITMP3);
1265 M_SLL_IMM(s1, iptr->val.i & 0x3f, d);
1266 store_reg_to_var_int(iptr->dst, d);
1269 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1271 var_to_reg_int(s1, src->prev, REG_ITMP1);
1272 var_to_reg_int(s2, src, REG_ITMP2);
1273 d = reg_of_var(iptr->dst, REG_ITMP3);
1275 store_reg_to_var_int(iptr->dst, d);
1278 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1279 /* val.i = constant */
1281 var_to_reg_int(s1, src, REG_ITMP1);
1282 d = reg_of_var(iptr->dst, REG_ITMP3);
1283 M_SRA_IMM(s1, iptr->val.i & 0x3f, d);
1284 store_reg_to_var_int(iptr->dst, d);
1287 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1289 var_to_reg_int(s1, src->prev, REG_ITMP1);
1290 var_to_reg_int(s2, src, REG_ITMP2);
1291 d = reg_of_var(iptr->dst, REG_ITMP3);
1293 store_reg_to_var_int(iptr->dst, d);
1296 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1297 /* val.i = constant */
1299 var_to_reg_int(s1, src, REG_ITMP1);
1300 d = reg_of_var(iptr->dst, REG_ITMP3);
1301 M_SRL_IMM(s1, iptr->val.i & 0x3f, d);
1302 store_reg_to_var_int(iptr->dst, d);
1305 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1308 var_to_reg_int(s1, src->prev, REG_ITMP1);
1309 var_to_reg_int(s2, src, REG_ITMP2);
1310 d = reg_of_var(iptr->dst, REG_ITMP3);
1312 store_reg_to_var_int(iptr->dst, d);
1315 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1316 /* val.i = constant */
1318 var_to_reg_int(s1, src, REG_ITMP1);
1319 d = reg_of_var(iptr->dst, REG_ITMP3);
1320 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1321 M_AND_IMM(s1, iptr->val.i, d);
1323 else if (iptr->val.i == 0xffff) {
1326 else if (iptr->val.i == 0xffffff) {
1327 M_ZAPNOT_IMM(s1, 0x07, d);
1330 ICONST(REG_ITMP2, iptr->val.i);
1331 M_AND(s1, REG_ITMP2, d);
1333 store_reg_to_var_int(iptr->dst, d);
1336 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1337 /* val.i = constant */
1339 var_to_reg_int(s1, src, REG_ITMP1);
1340 d = reg_of_var(iptr->dst, REG_ITMP3);
1342 M_MOV(s1, REG_ITMP1);
1345 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1346 M_AND_IMM(s1, iptr->val.i, d);
1348 M_ISUB(REG_ZERO, s1, d);
1349 M_AND_IMM(d, iptr->val.i, d);
1351 else if (iptr->val.i == 0xffff) {
1354 M_ISUB(REG_ZERO, s1, d);
1357 else if (iptr->val.i == 0xffffff) {
1358 M_ZAPNOT_IMM(s1, 0x07, d);
1360 M_ISUB(REG_ZERO, s1, d);
1361 M_ZAPNOT_IMM(d, 0x07, d);
1364 ICONST(REG_ITMP2, iptr->val.i);
1365 M_AND(s1, REG_ITMP2, d);
1367 M_ISUB(REG_ZERO, s1, d);
1368 M_AND(d, REG_ITMP2, d);
1370 M_ISUB(REG_ZERO, d, d);
1371 store_reg_to_var_int(iptr->dst, d);
1374 case ICMD_IREM0X10001: /* ..., value ==> ..., value % 0x100001 */
1376 /* b = value & 0xffff;
1378 a = ((b - a) & 0xffff) + (b < a);
1380 var_to_reg_int(s1, src, REG_ITMP1);
1381 d = reg_of_var(iptr->dst, REG_ITMP3);
1383 M_MOV(s1, REG_ITMP3);
1387 M_CZEXT(s1, REG_ITMP2);
1388 M_SRA_IMM(s1, 16, d);
1389 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1390 M_ISUB(REG_ITMP2, d, d);
1392 M_IADD(d, REG_ITMP1, d);
1393 M_BR(11 + (s1 == REG_ITMP1));
1394 M_ISUB(REG_ZERO, s1, REG_ITMP1);
1395 M_CZEXT(REG_ITMP1, REG_ITMP2);
1396 M_SRA_IMM(REG_ITMP1, 16, d);
1397 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1398 M_ISUB(REG_ITMP2, d, d);
1400 M_IADD(d, REG_ITMP1, d);
1401 M_ISUB(REG_ZERO, d, d);
1402 if (s1 == REG_ITMP1) {
1403 var_to_reg_int(s1, src, REG_ITMP1);
1405 M_SLL_IMM(s1, 33, REG_ITMP2);
1406 M_CMPEQ(REG_ITMP2, REG_ZERO, REG_ITMP2);
1407 M_ISUB(d, REG_ITMP2, d);
1408 store_reg_to_var_int(iptr->dst, d);
1411 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1412 /* val.l = constant */
1414 var_to_reg_int(s1, src, REG_ITMP1);
1415 d = reg_of_var(iptr->dst, REG_ITMP3);
1416 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1417 M_AND_IMM(s1, iptr->val.l, d);
1419 else if (iptr->val.l == 0xffffL) {
1422 else if (iptr->val.l == 0xffffffL) {
1423 M_ZAPNOT_IMM(s1, 0x07, d);
1425 else if (iptr->val.l == 0xffffffffL) {
1428 else if (iptr->val.l == 0xffffffffffL) {
1429 M_ZAPNOT_IMM(s1, 0x1f, d);
1431 else if (iptr->val.l == 0xffffffffffffL) {
1432 M_ZAPNOT_IMM(s1, 0x3f, d);
1434 else if (iptr->val.l == 0xffffffffffffffL) {
1435 M_ZAPNOT_IMM(s1, 0x7f, d);
1438 LCONST(REG_ITMP2, iptr->val.l);
1439 M_AND(s1, REG_ITMP2, d);
1441 store_reg_to_var_int(iptr->dst, d);
1444 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1445 /* val.l = constant */
1447 var_to_reg_int(s1, src, REG_ITMP1);
1448 d = reg_of_var(iptr->dst, REG_ITMP3);
1450 M_MOV(s1, REG_ITMP1);
1453 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1454 M_AND_IMM(s1, iptr->val.l, d);
1456 M_LSUB(REG_ZERO, s1, d);
1457 M_AND_IMM(d, iptr->val.l, d);
1459 else if (iptr->val.l == 0xffffL) {
1462 M_LSUB(REG_ZERO, s1, d);
1465 else if (iptr->val.l == 0xffffffL) {
1466 M_ZAPNOT_IMM(s1, 0x07, d);
1468 M_LSUB(REG_ZERO, s1, d);
1469 M_ZAPNOT_IMM(d, 0x07, d);
1471 else if (iptr->val.l == 0xffffffffL) {
1474 M_LSUB(REG_ZERO, s1, d);
1477 else if (iptr->val.l == 0xffffffffffL) {
1478 M_ZAPNOT_IMM(s1, 0x1f, d);
1480 M_LSUB(REG_ZERO, s1, d);
1481 M_ZAPNOT_IMM(d, 0x1f, d);
1483 else if (iptr->val.l == 0xffffffffffffL) {
1484 M_ZAPNOT_IMM(s1, 0x3f, d);
1486 M_LSUB(REG_ZERO, s1, d);
1487 M_ZAPNOT_IMM(d, 0x3f, d);
1489 else if (iptr->val.l == 0xffffffffffffffL) {
1490 M_ZAPNOT_IMM(s1, 0x7f, d);
1492 M_LSUB(REG_ZERO, s1, d);
1493 M_ZAPNOT_IMM(d, 0x7f, d);
1496 LCONST(REG_ITMP2, iptr->val.l);
1497 M_AND(s1, REG_ITMP2, d);
1499 M_LSUB(REG_ZERO, s1, d);
1500 M_AND(d, REG_ITMP2, d);
1502 M_LSUB(REG_ZERO, d, d);
1503 store_reg_to_var_int(iptr->dst, d);
1506 case ICMD_LREM0X10001:/* ..., value ==> ..., value % 0x10001 */
1508 var_to_reg_int(s1, src, REG_ITMP1);
1509 d = reg_of_var(iptr->dst, REG_ITMP3);
1511 M_MOV(s1, REG_ITMP3);
1514 M_CZEXT(s1, REG_ITMP2);
1515 M_SRA_IMM(s1, 16, d);
1516 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1517 M_LSUB(REG_ITMP2, d, d);
1519 M_LADD(d, REG_ITMP1, d);
1520 M_LDA(REG_ITMP2, REG_ZERO, -1);
1521 M_SRL_IMM(REG_ITMP2, 33, REG_ITMP2);
1522 if (s1 == REG_ITMP1) {
1523 var_to_reg_int(s1, src, REG_ITMP1);
1525 M_CMPULT(s1, REG_ITMP2, REG_ITMP2);
1526 M_BNEZ(REG_ITMP2, 11);
1527 M_LDA(d, REG_ZERO, -257);
1528 M_ZAPNOT_IMM(d, 0xcd, d);
1529 M_LSUB(REG_ZERO, s1, REG_ITMP2);
1530 M_CMOVGE(s1, s1, REG_ITMP2);
1531 M_UMULH(REG_ITMP2, d, REG_ITMP2);
1532 M_SRL_IMM(REG_ITMP2, 16, REG_ITMP2);
1533 M_LSUB(REG_ZERO, REG_ITMP2, d);
1534 M_CMOVGE(s1, REG_ITMP2, d);
1535 M_SLL_IMM(d, 16, REG_ITMP2);
1536 M_LADD(d, REG_ITMP2, d);
1538 store_reg_to_var_int(iptr->dst, d);
1541 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1544 var_to_reg_int(s1, src->prev, REG_ITMP1);
1545 var_to_reg_int(s2, src, REG_ITMP2);
1546 d = reg_of_var(iptr->dst, REG_ITMP3);
1548 store_reg_to_var_int(iptr->dst, d);
1551 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1552 /* val.i = constant */
1554 var_to_reg_int(s1, src, REG_ITMP1);
1555 d = reg_of_var(iptr->dst, REG_ITMP3);
1556 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1557 M_OR_IMM(s1, iptr->val.i, d);
1560 ICONST(REG_ITMP2, iptr->val.i);
1561 M_OR(s1, REG_ITMP2, d);
1563 store_reg_to_var_int(iptr->dst, d);
1566 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1567 /* val.l = constant */
1569 var_to_reg_int(s1, src, REG_ITMP1);
1570 d = reg_of_var(iptr->dst, REG_ITMP3);
1571 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1572 M_OR_IMM(s1, iptr->val.l, d);
1575 LCONST(REG_ITMP2, iptr->val.l);
1576 M_OR(s1, REG_ITMP2, d);
1578 store_reg_to_var_int(iptr->dst, d);
1581 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1584 var_to_reg_int(s1, src->prev, REG_ITMP1);
1585 var_to_reg_int(s2, src, REG_ITMP2);
1586 d = reg_of_var(iptr->dst, REG_ITMP3);
1588 store_reg_to_var_int(iptr->dst, d);
1591 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1592 /* val.i = constant */
1594 var_to_reg_int(s1, src, REG_ITMP1);
1595 d = reg_of_var(iptr->dst, REG_ITMP3);
1596 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1597 M_XOR_IMM(s1, iptr->val.i, d);
1600 ICONST(REG_ITMP2, iptr->val.i);
1601 M_XOR(s1, REG_ITMP2, d);
1603 store_reg_to_var_int(iptr->dst, d);
1606 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1607 /* val.l = constant */
1609 var_to_reg_int(s1, src, REG_ITMP1);
1610 d = reg_of_var(iptr->dst, REG_ITMP3);
1611 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1612 M_XOR_IMM(s1, iptr->val.l, d);
1615 LCONST(REG_ITMP2, iptr->val.l);
1616 M_XOR(s1, REG_ITMP2, d);
1618 store_reg_to_var_int(iptr->dst, d);
1622 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1624 var_to_reg_int(s1, src->prev, REG_ITMP1);
1625 var_to_reg_int(s2, src, REG_ITMP2);
1626 d = reg_of_var(iptr->dst, REG_ITMP3);
1627 M_CMPLT(s1, s2, REG_ITMP3);
1628 M_CMPLT(s2, s1, REG_ITMP1);
1629 M_LSUB (REG_ITMP1, REG_ITMP3, d);
1630 store_reg_to_var_int(iptr->dst, d);
1634 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1635 /* op1 = variable, val.i = constant */
1637 var = &(locals[iptr->op1][TYPE_INT]);
1638 if (var->flags & INMEMORY) {
1640 M_LLD(s1, REG_SP, 8 * var->regoff);
1644 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1645 M_IADD_IMM(s1, iptr->val.i, s1);
1647 else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1648 M_ISUB_IMM(s1, (-iptr->val.i), s1);
1651 M_LDA (s1, s1, iptr->val.i);
1652 M_IADD(s1, REG_ZERO, s1);
1654 if (var->flags & INMEMORY)
1655 M_LST(s1, REG_SP, 8 * var->regoff);
1659 /* floating operations ************************************************/
1661 case ICMD_FNEG: /* ..., value ==> ..., - value */
1663 var_to_reg_flt(s1, src, REG_FTMP1);
1664 d = reg_of_var(iptr->dst, REG_FTMP3);
1666 store_reg_to_var_flt(iptr->dst, d);
1669 case ICMD_DNEG: /* ..., value ==> ..., - value */
1671 var_to_reg_flt(s1, src, REG_FTMP1);
1672 d = reg_of_var(iptr->dst, REG_FTMP3);
1674 store_reg_to_var_flt(iptr->dst, d);
1677 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1679 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1680 var_to_reg_flt(s2, src, REG_FTMP2);
1681 d = reg_of_var(iptr->dst, REG_FTMP3);
1686 if (d == s1 || d == s2) {
1687 M_FADDS(s1, s2, REG_FTMP3);
1689 M_FMOV(REG_FTMP3, d);
1696 store_reg_to_var_flt(iptr->dst, d);
1699 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1701 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1702 var_to_reg_flt(s2, src, REG_FTMP2);
1703 d = reg_of_var(iptr->dst, REG_FTMP3);
1708 if (d == s1 || d == s2) {
1709 M_DADDS(s1, s2, REG_FTMP3);
1711 M_FMOV(REG_FTMP3, d);
1718 store_reg_to_var_flt(iptr->dst, d);
1721 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1723 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1724 var_to_reg_flt(s2, src, REG_FTMP2);
1725 d = reg_of_var(iptr->dst, REG_FTMP3);
1730 if (d == s1 || d == s2) {
1731 M_FSUBS(s1, s2, REG_FTMP3);
1733 M_FMOV(REG_FTMP3, d);
1740 store_reg_to_var_flt(iptr->dst, d);
1743 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1745 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1746 var_to_reg_flt(s2, src, REG_FTMP2);
1747 d = reg_of_var(iptr->dst, REG_FTMP3);
1752 if (d == s1 || d == s2) {
1753 M_DSUBS(s1, s2, REG_FTMP3);
1755 M_FMOV(REG_FTMP3, d);
1762 store_reg_to_var_flt(iptr->dst, d);
1765 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1767 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1768 var_to_reg_flt(s2, src, REG_FTMP2);
1769 d = reg_of_var(iptr->dst, REG_FTMP3);
1774 if (d == s1 || d == s2) {
1775 M_FMULS(s1, s2, REG_FTMP3);
1777 M_FMOV(REG_FTMP3, d);
1784 store_reg_to_var_flt(iptr->dst, d);
1787 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1789 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1790 var_to_reg_flt(s2, src, REG_FTMP2);
1791 d = reg_of_var(iptr->dst, REG_FTMP3);
1796 if (d == s1 || d == s2) {
1797 M_DMULS(s1, s2, REG_FTMP3);
1799 M_FMOV(REG_FTMP3, d);
1806 store_reg_to_var_flt(iptr->dst, d);
1809 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1811 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1812 var_to_reg_flt(s2, src, REG_FTMP2);
1813 d = reg_of_var(iptr->dst, REG_FTMP3);
1818 if (d == s1 || d == s2) {
1819 M_FDIVS(s1, s2, REG_FTMP3);
1821 M_FMOV(REG_FTMP3, d);
1828 store_reg_to_var_flt(iptr->dst, d);
1831 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1833 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1834 var_to_reg_flt(s2, src, REG_FTMP2);
1835 d = reg_of_var(iptr->dst, REG_FTMP3);
1840 if (d == s1 || d == s2) {
1841 M_DDIVS(s1, s2, REG_FTMP3);
1843 M_FMOV(REG_FTMP3, d);
1850 store_reg_to_var_flt(iptr->dst, d);
1853 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1855 var_to_reg_int(s1, src, REG_ITMP1);
1856 d = reg_of_var(iptr->dst, REG_FTMP3);
1857 a = dseg_adddouble(0.0);
1858 M_LST (s1, REG_PV, a);
1859 M_DLD (d, REG_PV, a);
1861 store_reg_to_var_flt(iptr->dst, d);
1864 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1866 var_to_reg_int(s1, src, REG_ITMP1);
1867 d = reg_of_var(iptr->dst, REG_FTMP3);
1868 a = dseg_adddouble(0.0);
1869 M_LST (s1, REG_PV, a);
1870 M_DLD (d, REG_PV, a);
1872 store_reg_to_var_flt(iptr->dst, d);
1875 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1877 var_to_reg_flt(s1, src, REG_FTMP1);
1878 d = reg_of_var(iptr->dst, REG_ITMP3);
1879 a = dseg_adddouble(0.0);
1880 M_CVTDL_C(s1, REG_FTMP2);
1881 M_CVTLI(REG_FTMP2, REG_FTMP3);
1882 M_DST (REG_FTMP3, REG_PV, a);
1883 M_ILD (d, REG_PV, a);
1884 store_reg_to_var_int(iptr->dst, d);
1887 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1889 var_to_reg_flt(s1, src, REG_FTMP1);
1890 d = reg_of_var(iptr->dst, REG_ITMP3);
1891 a = dseg_adddouble(0.0);
1892 M_CVTDL_C(s1, REG_FTMP2);
1893 M_DST (REG_FTMP2, REG_PV, a);
1894 M_LLD (d, REG_PV, a);
1895 store_reg_to_var_int(iptr->dst, d);
1898 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1900 var_to_reg_flt(s1, src, REG_FTMP1);
1901 d = reg_of_var(iptr->dst, REG_FTMP3);
1904 store_reg_to_var_flt(iptr->dst, d);
1907 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1909 var_to_reg_flt(s1, src, REG_FTMP1);
1910 d = reg_of_var(iptr->dst, REG_FTMP3);
1918 store_reg_to_var_flt(iptr->dst, d);
1921 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1923 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1924 var_to_reg_flt(s2, src, REG_FTMP2);
1925 d = reg_of_var(iptr->dst, REG_ITMP3);
1927 M_LSUB_IMM(REG_ZERO, 1, d);
1928 M_FCMPEQ(s1, s2, REG_FTMP3);
1929 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1931 M_FCMPLT(s2, s1, REG_FTMP3);
1932 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1933 M_LADD_IMM(REG_ZERO, 1, d);
1936 M_LSUB_IMM(REG_ZERO, 1, d);
1937 M_FCMPEQS(s1, s2, REG_FTMP3);
1939 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1941 M_FCMPLTS(s2, s1, REG_FTMP3);
1943 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1944 M_LADD_IMM(REG_ZERO, 1, d);
1946 store_reg_to_var_int(iptr->dst, d);
1949 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1951 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1952 var_to_reg_flt(s2, src, REG_FTMP2);
1953 d = reg_of_var(iptr->dst, REG_ITMP3);
1955 M_LADD_IMM(REG_ZERO, 1, d);
1956 M_FCMPEQ(s1, s2, REG_FTMP3);
1957 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1959 M_FCMPLT(s1, s2, REG_FTMP3);
1960 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1961 M_LSUB_IMM(REG_ZERO, 1, d);
1964 M_LADD_IMM(REG_ZERO, 1, d);
1965 M_FCMPEQS(s1, s2, REG_FTMP3);
1967 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1969 M_FCMPLTS(s1, s2, REG_FTMP3);
1971 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1972 M_LSUB_IMM(REG_ZERO, 1, d);
1974 store_reg_to_var_int(iptr->dst, d);
1978 /* memory operations **************************************************/
1980 /* #define gen_bound_check \
1982 M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\
1983 M_CMPULT(s2, REG_ITMP3, REG_ITMP3);\
1984 M_BEQZ(REG_ITMP3, 0);\
1985 codegen_addxboundrefs(mcodeptr);\
1989 #define gen_bound_check \
1990 if (checkbounds) { \
1991 M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\
1992 M_CMPULT(s2, REG_ITMP3, REG_ITMP3);\
1993 M_BEQZ(REG_ITMP3, 0);\
1994 codegen_addxboundrefs(mcodeptr); \
1997 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1999 var_to_reg_int(s1, src, REG_ITMP1);
2000 d = reg_of_var(iptr->dst, REG_ITMP3);
2001 gen_nullptr_check(s1);
2002 M_ILD(d, s1, OFFSET(java_arrayheader, size));
2003 store_reg_to_var_int(iptr->dst, d);
2006 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
2008 var_to_reg_int(s1, src->prev, REG_ITMP1);
2009 var_to_reg_int(s2, src, REG_ITMP2);
2010 d = reg_of_var(iptr->dst, REG_ITMP3);
2011 if (iptr->op1 == 0) {
2012 gen_nullptr_check(s1);
2015 M_SAADDQ(s2, s1, REG_ITMP1);
2016 M_ALD( d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
2017 store_reg_to_var_int(iptr->dst, d);
2020 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
2022 var_to_reg_int(s1, src->prev, REG_ITMP1);
2023 var_to_reg_int(s2, src, REG_ITMP2);
2024 d = reg_of_var(iptr->dst, REG_ITMP3);
2025 if (iptr->op1 == 0) {
2026 gen_nullptr_check(s1);
2029 M_S8ADDQ(s2, s1, REG_ITMP1);
2030 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
2031 store_reg_to_var_int(iptr->dst, d);
2034 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
2036 var_to_reg_int(s1, src->prev, REG_ITMP1);
2037 var_to_reg_int(s2, src, REG_ITMP2);
2038 d = reg_of_var(iptr->dst, REG_ITMP3);
2039 if (iptr->op1 == 0) {
2040 gen_nullptr_check(s1);
2044 M_S4ADDQ(s2, s1, REG_ITMP1);
2045 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
2046 store_reg_to_var_int(iptr->dst, d);
2049 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
2051 var_to_reg_int(s1, src->prev, REG_ITMP1);
2052 var_to_reg_int(s2, src, REG_ITMP2);
2053 d = reg_of_var(iptr->dst, REG_FTMP3);
2054 if (iptr->op1 == 0) {
2055 gen_nullptr_check(s1);
2058 M_S4ADDQ(s2, s1, REG_ITMP1);
2059 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
2060 store_reg_to_var_flt(iptr->dst, d);
2063 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
2065 var_to_reg_int(s1, src->prev, REG_ITMP1);
2066 var_to_reg_int(s2, src, REG_ITMP2);
2067 d = reg_of_var(iptr->dst, REG_FTMP3);
2068 if (iptr->op1 == 0) {
2069 gen_nullptr_check(s1);
2072 M_S8ADDQ(s2, s1, REG_ITMP1);
2073 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
2074 store_reg_to_var_flt(iptr->dst, d);
2077 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
2079 var_to_reg_int(s1, src->prev, REG_ITMP1);
2080 var_to_reg_int(s2, src, REG_ITMP2);
2081 d = reg_of_var(iptr->dst, REG_ITMP3);
2082 if (iptr->op1 == 0) {
2083 gen_nullptr_check(s1);
2086 if (has_ext_instr_set) {
2087 M_LADD(s2, s1, REG_ITMP1);
2088 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2089 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
2092 M_LADD (s2, s1, REG_ITMP1);
2093 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2094 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2095 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2096 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
2098 store_reg_to_var_int(iptr->dst, d);
2101 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
2103 var_to_reg_int(s1, src->prev, REG_ITMP1);
2104 var_to_reg_int(s2, src, REG_ITMP2);
2105 d = reg_of_var(iptr->dst, REG_ITMP3);
2106 if (iptr->op1 == 0) {
2107 gen_nullptr_check(s1);
2110 if (has_ext_instr_set) {
2111 M_LADD(s2, s1, REG_ITMP1);
2112 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2113 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
2117 M_LADD(s2, s1, REG_ITMP1);
2118 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2119 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2120 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
2121 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
2122 M_SRA_IMM(d, 48, d);
2124 store_reg_to_var_int(iptr->dst, d);
2127 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
2129 var_to_reg_int(s1, src->prev, REG_ITMP1);
2130 var_to_reg_int(s2, src, REG_ITMP2);
2131 d = reg_of_var(iptr->dst, REG_ITMP3);
2132 if (iptr->op1 == 0) {
2133 gen_nullptr_check(s1);
2136 if (has_ext_instr_set) {
2137 M_LADD (s2, s1, REG_ITMP1);
2138 M_BLDU (d, REG_ITMP1, OFFSET (java_bytearray, data[0]));
2142 M_LADD(s2, s1, REG_ITMP1);
2143 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2144 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
2145 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
2146 M_SRA_IMM(d, 56, d);
2148 store_reg_to_var_int(iptr->dst, d);
2152 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
2154 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2155 var_to_reg_int(s2, src->prev, REG_ITMP2);
2156 if (iptr->op1 == 0) {
2157 gen_nullptr_check(s1);
2160 var_to_reg_int(s3, src, REG_ITMP3);
2161 M_SAADDQ(s2, s1, REG_ITMP1);
2162 M_AST (s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
2165 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
2167 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2168 var_to_reg_int(s2, src->prev, REG_ITMP2);
2169 if (iptr->op1 == 0) {
2170 gen_nullptr_check(s1);
2173 var_to_reg_int(s3, src, REG_ITMP3);
2174 M_S8ADDQ(s2, s1, REG_ITMP1);
2175 M_LST (s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
2178 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
2180 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2181 var_to_reg_int(s2, src->prev, REG_ITMP2);
2182 if (iptr->op1 == 0) {
2183 gen_nullptr_check(s1);
2187 var_to_reg_int(s3, src, REG_ITMP3);
2188 M_S4ADDQ(s2, s1, REG_ITMP1);
2189 M_IST (s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
2192 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
2194 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2195 var_to_reg_int(s2, src->prev, REG_ITMP2);
2196 if (iptr->op1 == 0) {
2197 gen_nullptr_check(s1);
2200 var_to_reg_flt(s3, src, REG_FTMP3);
2201 M_S4ADDQ(s2, s1, REG_ITMP1);
2202 M_FST (s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
2205 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
2207 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2208 var_to_reg_int(s2, src->prev, REG_ITMP2);
2209 if (iptr->op1 == 0) {
2210 gen_nullptr_check(s1);
2213 var_to_reg_flt(s3, src, REG_FTMP3);
2214 M_S8ADDQ(s2, s1, REG_ITMP1);
2215 M_DST (s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
2218 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
2220 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2221 var_to_reg_int(s2, src->prev, REG_ITMP2);
2222 if (iptr->op1 == 0) {
2223 gen_nullptr_check(s1);
2226 var_to_reg_int(s3, src, REG_ITMP3);
2227 if (has_ext_instr_set) {
2228 M_LADD(s2, s1, REG_ITMP1);
2229 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2230 M_SST (s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
2233 M_LADD (s2, s1, REG_ITMP1);
2234 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2235 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2236 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2237 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
2238 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2239 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2240 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2244 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
2246 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2247 var_to_reg_int(s2, src->prev, REG_ITMP2);
2248 if (iptr->op1 == 0) {
2249 gen_nullptr_check(s1);
2252 var_to_reg_int(s3, src, REG_ITMP3);
2253 if (has_ext_instr_set) {
2254 M_LADD(s2, s1, REG_ITMP1);
2255 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2256 M_SST (s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2259 M_LADD (s2, s1, REG_ITMP1);
2260 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2261 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2262 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2263 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
2264 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2265 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2266 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2270 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
2272 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2273 var_to_reg_int(s2, src->prev, REG_ITMP2);
2274 if (iptr->op1 == 0) {
2275 gen_nullptr_check(s1);
2278 var_to_reg_int(s3, src, REG_ITMP3);
2279 if (has_ext_instr_set) {
2280 M_LADD(s2, s1, REG_ITMP1);
2281 M_BST (s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2284 M_LADD (s2, s1, REG_ITMP1);
2285 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2286 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2287 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
2288 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2289 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2290 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2295 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2296 /* op1 = type, val.a = field address */
2298 /* if class isn't yet initialized, do it */
2299 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
2300 /* call helper function which patches this code */
2301 a = dseg_addaddress(((fieldinfo *) iptr->val.a)->class);
2302 M_ALD(REG_ITMP1, REG_PV, a);
2303 a = dseg_addaddress(asm_check_clinit);
2304 M_ALD(REG_PV, REG_PV, a);
2305 M_JSR(REG_RA, REG_PV);
2308 s1 = (int) ((u1*) mcodeptr - mcodebase);
2309 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
2311 s4 ml = -s1, mh = 0;
2312 while (ml < -32768) { ml += 65536; mh--; }
2313 M_LDA(REG_PV, REG_RA, ml);
2314 M_LDAH(REG_PV, REG_PV, mh);
2318 a = dseg_addaddress(&(((fieldinfo *)(iptr->val.a))->value));
2319 M_ALD(REG_ITMP1, REG_PV, a);
2320 switch (iptr->op1) {
2322 var_to_reg_int(s2, src, REG_ITMP2);
2323 M_IST(s2, REG_ITMP1, 0);
2326 var_to_reg_int(s2, src, REG_ITMP2);
2327 M_LST(s2, REG_ITMP1, 0);
2330 var_to_reg_int(s2, src, REG_ITMP2);
2331 M_AST(s2, REG_ITMP1, 0);
2334 var_to_reg_flt(s2, src, REG_FTMP2);
2335 M_FST(s2, REG_ITMP1, 0);
2338 var_to_reg_flt(s2, src, REG_FTMP2);
2339 M_DST(s2, REG_ITMP1, 0);
2341 default: panic ("internal error");
2345 case ICMD_GETSTATIC: /* ... ==> ..., value */
2346 /* op1 = type, val.a = field address */
2348 /* if class isn't yet initialized, do it */
2349 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
2350 /* call helper function which patches this code */
2351 a = dseg_addaddress(((fieldinfo *) iptr->val.a)->class);
2352 M_ALD(REG_ITMP1, REG_PV, a);
2353 a = dseg_addaddress(asm_check_clinit);
2354 M_ALD(REG_PV, REG_PV, a);
2355 M_JSR(REG_RA, REG_PV);
2358 s1 = (int) ((u1*) mcodeptr - mcodebase);
2359 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
2361 s4 ml = -s1, mh = 0;
2362 while (ml < -32768) { ml += 65536; mh--; }
2363 M_LDA(REG_PV, REG_RA, ml);
2364 M_LDAH(REG_PV, REG_PV, mh);
2368 a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value));
2369 M_ALD(REG_ITMP1, REG_PV, a);
2370 switch (iptr->op1) {
2372 d = reg_of_var(iptr->dst, REG_ITMP3);
2373 M_ILD(d, REG_ITMP1, 0);
2374 store_reg_to_var_int(iptr->dst, d);
2377 d = reg_of_var(iptr->dst, REG_ITMP3);
2378 M_LLD(d, REG_ITMP1, 0);
2379 store_reg_to_var_int(iptr->dst, d);
2382 d = reg_of_var(iptr->dst, REG_ITMP3);
2383 M_ALD(d, REG_ITMP1, 0);
2384 store_reg_to_var_int(iptr->dst, d);
2387 d = reg_of_var(iptr->dst, REG_FTMP1);
2388 M_FLD(d, REG_ITMP1, 0);
2389 store_reg_to_var_flt(iptr->dst, d);
2392 d = reg_of_var(iptr->dst, REG_FTMP1);
2393 M_DLD(d, REG_ITMP1, 0);
2394 store_reg_to_var_flt(iptr->dst, d);
2396 default: panic ("internal error");
2401 case ICMD_PUTFIELD: /* ..., value ==> ... */
2402 /* op1 = type, val.i = field offset */
2404 a = ((fieldinfo *)(iptr->val.a))->offset;
2405 switch (iptr->op1) {
2407 var_to_reg_int(s1, src->prev, REG_ITMP1);
2408 var_to_reg_int(s2, src, REG_ITMP2);
2409 gen_nullptr_check(s1);
2413 var_to_reg_int(s1, src->prev, REG_ITMP1);
2414 var_to_reg_int(s2, src, REG_ITMP2);
2415 gen_nullptr_check(s1);
2419 var_to_reg_int(s1, src->prev, REG_ITMP1);
2420 var_to_reg_int(s2, src, REG_ITMP2);
2421 gen_nullptr_check(s1);
2425 var_to_reg_int(s1, src->prev, REG_ITMP1);
2426 var_to_reg_flt(s2, src, REG_FTMP2);
2427 gen_nullptr_check(s1);
2431 var_to_reg_int(s1, src->prev, REG_ITMP1);
2432 var_to_reg_flt(s2, src, REG_FTMP2);
2433 gen_nullptr_check(s1);
2436 default: panic ("internal error");
2440 case ICMD_GETFIELD: /* ... ==> ..., value */
2441 /* op1 = type, val.i = field offset */
2443 a = ((fieldinfo *)(iptr->val.a))->offset;
2444 switch (iptr->op1) {
2446 var_to_reg_int(s1, src, REG_ITMP1);
2447 d = reg_of_var(iptr->dst, REG_ITMP3);
2448 gen_nullptr_check(s1);
2450 store_reg_to_var_int(iptr->dst, d);
2453 var_to_reg_int(s1, src, REG_ITMP1);
2454 d = reg_of_var(iptr->dst, REG_ITMP3);
2455 gen_nullptr_check(s1);
2457 store_reg_to_var_int(iptr->dst, d);
2460 var_to_reg_int(s1, src, REG_ITMP1);
2461 d = reg_of_var(iptr->dst, REG_ITMP3);
2462 gen_nullptr_check(s1);
2464 store_reg_to_var_int(iptr->dst, d);
2467 var_to_reg_int(s1, src, REG_ITMP1);
2468 d = reg_of_var(iptr->dst, REG_FTMP1);
2469 gen_nullptr_check(s1);
2471 store_reg_to_var_flt(iptr->dst, d);
2474 var_to_reg_int(s1, src, REG_ITMP1);
2475 d = reg_of_var(iptr->dst, REG_FTMP1);
2476 gen_nullptr_check(s1);
2478 store_reg_to_var_flt(iptr->dst, d);
2480 default: panic ("internal error");
2485 /* branch operations **************************************************/
2487 #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}}
2489 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2491 var_to_reg_int(s1, src, REG_ITMP1);
2492 M_INTMOVE(s1, REG_ITMP1_XPTR);
2493 a = dseg_addaddress(asm_handle_exception);
2494 M_ALD(REG_ITMP2, REG_PV, a);
2495 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2496 M_NOP; /* nop ensures that XPC is less than the end */
2497 /* of basic block */
2501 case ICMD_GOTO: /* ... ==> ... */
2502 /* op1 = target JavaVM pc */
2504 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2508 case ICMD_JSR: /* ... ==> ... */
2509 /* op1 = target JavaVM pc */
2511 M_BSR(REG_ITMP1, 0);
2512 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2515 case ICMD_RET: /* ... ==> ... */
2516 /* op1 = local variable */
2518 var = &(locals[iptr->op1][TYPE_ADR]);
2519 if (var->flags & INMEMORY) {
2520 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2521 M_RET(REG_ZERO, REG_ITMP1);
2524 M_RET(REG_ZERO, var->regoff);
2528 case ICMD_IFNULL: /* ..., value ==> ... */
2529 /* op1 = target JavaVM pc */
2531 var_to_reg_int(s1, src, REG_ITMP1);
2533 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2536 case ICMD_IFNONNULL: /* ..., value ==> ... */
2537 /* op1 = target JavaVM pc */
2539 var_to_reg_int(s1, src, REG_ITMP1);
2541 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2544 case ICMD_IFEQ: /* ..., value ==> ... */
2545 /* op1 = target JavaVM pc, val.i = constant */
2547 var_to_reg_int(s1, src, REG_ITMP1);
2548 if (iptr->val.i == 0) {
2552 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2553 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2556 ICONST(REG_ITMP2, iptr->val.i);
2557 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2559 M_BNEZ(REG_ITMP1, 0);
2561 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2564 case ICMD_IFLT: /* ..., value ==> ... */
2565 /* op1 = target JavaVM pc, val.i = constant */
2567 var_to_reg_int(s1, src, REG_ITMP1);
2568 if (iptr->val.i == 0) {
2572 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2573 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2576 ICONST(REG_ITMP2, iptr->val.i);
2577 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2579 M_BNEZ(REG_ITMP1, 0);
2581 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2584 case ICMD_IFLE: /* ..., value ==> ... */
2585 /* op1 = target JavaVM pc, val.i = constant */
2587 var_to_reg_int(s1, src, REG_ITMP1);
2588 if (iptr->val.i == 0) {
2592 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2593 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2596 ICONST(REG_ITMP2, iptr->val.i);
2597 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2599 M_BNEZ(REG_ITMP1, 0);
2601 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2604 case ICMD_IFNE: /* ..., value ==> ... */
2605 /* op1 = target JavaVM pc, val.i = constant */
2607 var_to_reg_int(s1, src, REG_ITMP1);
2608 if (iptr->val.i == 0) {
2612 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2613 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2616 ICONST(REG_ITMP2, iptr->val.i);
2617 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2619 M_BEQZ(REG_ITMP1, 0);
2621 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2624 case ICMD_IFGT: /* ..., value ==> ... */
2625 /* op1 = target JavaVM pc, val.i = constant */
2627 var_to_reg_int(s1, src, REG_ITMP1);
2628 if (iptr->val.i == 0) {
2632 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2633 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2636 ICONST(REG_ITMP2, iptr->val.i);
2637 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2639 M_BEQZ(REG_ITMP1, 0);
2641 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2644 case ICMD_IFGE: /* ..., value ==> ... */
2645 /* op1 = target JavaVM pc, val.i = constant */
2647 var_to_reg_int(s1, src, REG_ITMP1);
2648 if (iptr->val.i == 0) {
2652 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2653 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2656 ICONST(REG_ITMP2, iptr->val.i);
2657 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2659 M_BEQZ(REG_ITMP1, 0);
2661 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2664 case ICMD_IF_LEQ: /* ..., value ==> ... */
2665 /* op1 = target JavaVM pc, val.l = constant */
2667 var_to_reg_int(s1, src, REG_ITMP1);
2668 if (iptr->val.l == 0) {
2672 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2673 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2676 LCONST(REG_ITMP2, iptr->val.l);
2677 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2679 M_BNEZ(REG_ITMP1, 0);
2681 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2684 case ICMD_IF_LLT: /* ..., value ==> ... */
2685 /* op1 = target JavaVM pc, val.l = constant */
2687 var_to_reg_int(s1, src, REG_ITMP1);
2688 if (iptr->val.l == 0) {
2692 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2693 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2696 LCONST(REG_ITMP2, iptr->val.l);
2697 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2699 M_BNEZ(REG_ITMP1, 0);
2701 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2704 case ICMD_IF_LLE: /* ..., value ==> ... */
2705 /* op1 = target JavaVM pc, val.l = constant */
2707 var_to_reg_int(s1, src, REG_ITMP1);
2708 if (iptr->val.l == 0) {
2712 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2713 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2716 LCONST(REG_ITMP2, iptr->val.l);
2717 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2719 M_BNEZ(REG_ITMP1, 0);
2721 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2724 case ICMD_IF_LNE: /* ..., value ==> ... */
2725 /* op1 = target JavaVM pc, val.l = constant */
2727 var_to_reg_int(s1, src, REG_ITMP1);
2728 if (iptr->val.l == 0) {
2732 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2733 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2736 LCONST(REG_ITMP2, iptr->val.l);
2737 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2739 M_BEQZ(REG_ITMP1, 0);
2741 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2744 case ICMD_IF_LGT: /* ..., value ==> ... */
2745 /* op1 = target JavaVM pc, val.l = constant */
2747 var_to_reg_int(s1, src, REG_ITMP1);
2748 if (iptr->val.l == 0) {
2752 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2753 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2756 LCONST(REG_ITMP2, iptr->val.l);
2757 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2759 M_BEQZ(REG_ITMP1, 0);
2761 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2764 case ICMD_IF_LGE: /* ..., value ==> ... */
2765 /* op1 = target JavaVM pc, val.l = constant */
2767 var_to_reg_int(s1, src, REG_ITMP1);
2768 if (iptr->val.l == 0) {
2772 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2773 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2776 LCONST(REG_ITMP2, iptr->val.l);
2777 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2779 M_BEQZ(REG_ITMP1, 0);
2781 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2784 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2785 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2786 case ICMD_IF_ACMPEQ:
2788 var_to_reg_int(s1, src->prev, REG_ITMP1);
2789 var_to_reg_int(s2, src, REG_ITMP2);
2790 M_CMPEQ(s1, s2, REG_ITMP1);
2791 M_BNEZ(REG_ITMP1, 0);
2792 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2795 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2796 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2797 case ICMD_IF_ACMPNE:
2799 var_to_reg_int(s1, src->prev, REG_ITMP1);
2800 var_to_reg_int(s2, src, REG_ITMP2);
2801 M_CMPEQ(s1, s2, REG_ITMP1);
2802 M_BEQZ(REG_ITMP1, 0);
2803 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2806 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2807 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2809 var_to_reg_int(s1, src->prev, REG_ITMP1);
2810 var_to_reg_int(s2, src, REG_ITMP2);
2811 M_CMPLT(s1, s2, REG_ITMP1);
2812 M_BNEZ(REG_ITMP1, 0);
2813 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2816 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2817 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2819 var_to_reg_int(s1, src->prev, REG_ITMP1);
2820 var_to_reg_int(s2, src, REG_ITMP2);
2821 M_CMPLE(s1, s2, REG_ITMP1);
2822 M_BEQZ(REG_ITMP1, 0);
2823 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2826 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2827 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2829 var_to_reg_int(s1, src->prev, REG_ITMP1);
2830 var_to_reg_int(s2, src, REG_ITMP2);
2831 M_CMPLE(s1, s2, REG_ITMP1);
2832 M_BNEZ(REG_ITMP1, 0);
2833 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2836 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2837 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2839 var_to_reg_int(s1, src->prev, REG_ITMP1);
2840 var_to_reg_int(s2, src, REG_ITMP2);
2841 M_CMPLT(s1, s2, REG_ITMP1);
2842 M_BEQZ(REG_ITMP1, 0);
2843 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2846 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2848 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2851 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2852 /* val.i = constant */
2854 var_to_reg_int(s1, src, REG_ITMP1);
2855 d = reg_of_var(iptr->dst, REG_ITMP3);
2857 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2858 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2859 M_CMPEQ(s1, REG_ZERO, d);
2860 store_reg_to_var_int(iptr->dst, d);
2863 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2864 M_CMPEQ(s1, REG_ZERO, d);
2866 store_reg_to_var_int(iptr->dst, d);
2870 M_MOV(s1, REG_ITMP1);
2873 ICONST(d, iptr[1].val.i);
2875 if ((s3 >= 0) && (s3 <= 255)) {
2876 M_CMOVEQ_IMM(s1, s3, d);
2879 ICONST(REG_ITMP2, s3);
2880 M_CMOVEQ(s1, REG_ITMP2, d);
2882 store_reg_to_var_int(iptr->dst, d);
2885 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2886 /* val.i = constant */
2888 var_to_reg_int(s1, src, REG_ITMP1);
2889 d = reg_of_var(iptr->dst, REG_ITMP3);
2891 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2892 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2893 M_CMPEQ(s1, REG_ZERO, d);
2894 store_reg_to_var_int(iptr->dst, d);
2897 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2898 M_CMPEQ(s1, REG_ZERO, d);
2900 store_reg_to_var_int(iptr->dst, d);
2904 M_MOV(s1, REG_ITMP1);
2907 ICONST(d, iptr[1].val.i);
2909 if ((s3 >= 0) && (s3 <= 255)) {
2910 M_CMOVNE_IMM(s1, s3, d);
2913 ICONST(REG_ITMP2, s3);
2914 M_CMOVNE(s1, REG_ITMP2, d);
2916 store_reg_to_var_int(iptr->dst, d);
2919 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2920 /* val.i = constant */
2922 var_to_reg_int(s1, src, REG_ITMP1);
2923 d = reg_of_var(iptr->dst, REG_ITMP3);
2925 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2926 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2927 M_CMPLT(s1, REG_ZERO, d);
2928 store_reg_to_var_int(iptr->dst, d);
2931 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2932 M_CMPLE(REG_ZERO, s1, d);
2933 store_reg_to_var_int(iptr->dst, d);
2937 M_MOV(s1, REG_ITMP1);
2940 ICONST(d, iptr[1].val.i);
2942 if ((s3 >= 0) && (s3 <= 255)) {
2943 M_CMOVLT_IMM(s1, s3, d);
2946 ICONST(REG_ITMP2, s3);
2947 M_CMOVLT(s1, REG_ITMP2, d);
2949 store_reg_to_var_int(iptr->dst, d);
2952 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2953 /* val.i = constant */
2955 var_to_reg_int(s1, src, REG_ITMP1);
2956 d = reg_of_var(iptr->dst, REG_ITMP3);
2958 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2959 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2960 M_CMPLE(REG_ZERO, s1, d);
2961 store_reg_to_var_int(iptr->dst, d);
2964 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2965 M_CMPLT(s1, REG_ZERO, d);
2966 store_reg_to_var_int(iptr->dst, d);
2970 M_MOV(s1, REG_ITMP1);
2973 ICONST(d, iptr[1].val.i);
2975 if ((s3 >= 0) && (s3 <= 255)) {
2976 M_CMOVGE_IMM(s1, s3, d);
2979 ICONST(REG_ITMP2, s3);
2980 M_CMOVGE(s1, REG_ITMP2, d);
2982 store_reg_to_var_int(iptr->dst, d);
2985 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2986 /* val.i = constant */
2988 var_to_reg_int(s1, src, REG_ITMP1);
2989 d = reg_of_var(iptr->dst, REG_ITMP3);
2991 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2992 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2993 M_CMPLT(REG_ZERO, s1, d);
2994 store_reg_to_var_int(iptr->dst, d);
2997 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2998 M_CMPLE(s1, REG_ZERO, d);
2999 store_reg_to_var_int(iptr->dst, d);
3003 M_MOV(s1, REG_ITMP1);
3006 ICONST(d, iptr[1].val.i);
3008 if ((s3 >= 0) && (s3 <= 255)) {
3009 M_CMOVGT_IMM(s1, s3, d);
3012 ICONST(REG_ITMP2, s3);
3013 M_CMOVGT(s1, REG_ITMP2, d);
3015 store_reg_to_var_int(iptr->dst, d);
3018 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
3019 /* val.i = constant */
3021 var_to_reg_int(s1, src, REG_ITMP1);
3022 d = reg_of_var(iptr->dst, REG_ITMP3);
3024 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
3025 if ((s3 == 1) && (iptr[1].val.i == 0)) {
3026 M_CMPLE(s1, REG_ZERO, d);
3027 store_reg_to_var_int(iptr->dst, d);
3030 if ((s3 == 0) && (iptr[1].val.i == 1)) {
3031 M_CMPLT(REG_ZERO, s1, d);
3032 store_reg_to_var_int(iptr->dst, d);
3036 M_MOV(s1, REG_ITMP1);
3039 ICONST(d, iptr[1].val.i);
3041 if ((s3 >= 0) && (s3 <= 255)) {
3042 M_CMOVLE_IMM(s1, s3, d);
3045 ICONST(REG_ITMP2, s3);
3046 M_CMOVLE(s1, REG_ITMP2, d);
3048 store_reg_to_var_int(iptr->dst, d);
3052 case ICMD_IRETURN: /* ..., retvalue ==> ... */
3057 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3059 a = dseg_addaddress ((void*) (builtin_monitorexit));
3060 M_ALD(REG_PV, REG_PV, a);
3061 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
3062 M_JSR(REG_RA, REG_PV);
3063 disp = -(int)((u1*) mcodeptr - mcodebase);
3064 M_LDA(REG_PV, REG_RA, disp);
3067 var_to_reg_int(s1, src, REG_RESULT);
3068 M_INTMOVE(s1, REG_RESULT);
3069 goto nowperformreturn;
3071 case ICMD_FRETURN: /* ..., retvalue ==> ... */
3075 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3077 a = dseg_addaddress ((void*) (builtin_monitorexit));
3078 M_ALD(REG_PV, REG_PV, a);
3079 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
3080 M_JSR(REG_RA, REG_PV);
3081 disp = -(int)((u1*) mcodeptr - mcodebase);
3082 M_LDA(REG_PV, REG_RA, disp);
3085 var_to_reg_flt(s1, src, REG_FRESULT);
3086 M_FLTMOVE(s1, REG_FRESULT);
3087 goto nowperformreturn;
3089 case ICMD_RETURN: /* ... ==> ... */
3092 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3094 a = dseg_addaddress ((void*) (builtin_monitorexit));
3095 M_ALD(REG_PV, REG_PV, a);
3096 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
3097 M_JSR(REG_RA, REG_PV);
3098 disp = -(int)((u1*) mcodeptr - mcodebase);
3099 M_LDA(REG_PV, REG_RA, disp);
3107 p = parentargs_base;
3109 /* restore return address */
3112 {p--; M_LLD (REG_RA, REG_SP, 8 * p);}
3114 /* restore saved registers */
3116 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
3117 {p--; M_LLD(savintregs[r], REG_SP, 8 * p);}
3118 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
3119 {p--; M_DLD(savfltregs[r], REG_SP, 8 * p);}
3121 /* deallocate stack */
3123 if (parentargs_base)
3124 {M_LDA(REG_SP, REG_SP, parentargs_base*8);}
3126 /* call trace function */
3129 M_LDA (REG_SP, REG_SP, -24);
3130 M_AST(REG_RA, REG_SP, 0);
3131 M_LST(REG_RESULT, REG_SP, 8);
3132 M_DST(REG_FRESULT, REG_SP,16);
3133 a = dseg_addaddress(method);
3134 M_ALD(argintregs[0], REG_PV, a);
3135 M_MOV(REG_RESULT, argintregs[1]);
3136 M_FLTMOVE(REG_FRESULT, argfltregs[2]);
3137 M_FLTMOVE(REG_FRESULT, argfltregs[3]);
3138 a = dseg_addaddress((void *) builtin_displaymethodstop);
3139 M_ALD(REG_PV, REG_PV, a);
3140 M_JSR (REG_RA, REG_PV);
3141 s1 = (int)((u1*) mcodeptr - mcodebase);
3142 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
3145 while (ml<-32768) { ml+=65536; mh--; }
3146 M_LDA (REG_PV, REG_RA, ml );
3147 M_LDAH (REG_PV, REG_PV, mh );
3149 M_DLD(REG_FRESULT, REG_SP,16);
3150 M_LLD(REG_RESULT, REG_SP, 8);
3151 M_ALD(REG_RA, REG_SP, 0);
3152 M_LDA (REG_SP, REG_SP, 24);
3155 M_RET(REG_ZERO, REG_RA);
3161 case ICMD_TABLESWITCH: /* ..., index ==> ... */
3166 tptr = (void **) iptr->target;
3168 s4ptr = iptr->val.a;
3169 l = s4ptr[1]; /* low */
3170 i = s4ptr[2]; /* high */
3172 var_to_reg_int(s1, src, REG_ITMP1);
3174 {M_INTMOVE(s1, REG_ITMP1);}
3175 else if (l <= 32768) {
3176 M_LDA(REG_ITMP1, s1, -l);
3179 ICONST(REG_ITMP2, l);
3180 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
3187 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
3189 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
3190 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3192 M_BEQZ(REG_ITMP2, 0);
3195 /* codegen_addreference(BlockPtrOfPC(s4ptr[0]), mcodeptr); */
3196 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3198 /* build jump table top down and use address of lowest entry */
3200 /* s4ptr += 3 + i; */
3204 /* dseg_addtarget(BlockPtrOfPC(*--s4ptr)); */
3205 dseg_addtarget((basicblock *) tptr[0]);
3210 /* length of dataseg after last dseg_addtarget is used by load */
3212 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
3213 M_ALD(REG_ITMP2, REG_ITMP2, -dseglen);
3214 M_JMP(REG_ZERO, REG_ITMP2);
3219 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3221 s4 i, l, val, *s4ptr;
3224 tptr = (void **) iptr->target;
3226 s4ptr = iptr->val.a;
3227 l = s4ptr[0]; /* default */
3228 i = s4ptr[1]; /* count */
3230 MCODECHECK((i<<2)+8);
3231 var_to_reg_int(s1, src, REG_ITMP1);
3237 if ((val >= 0) && (val <= 255)) {
3238 M_CMPEQ_IMM(s1, val, REG_ITMP2);
3241 if ((val >= -32768) && (val <= 32767)) {
3242 M_LDA(REG_ITMP2, REG_ZERO, val);
3245 a = dseg_adds4 (val);
3246 M_ILD(REG_ITMP2, REG_PV, a);
3248 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
3250 M_BNEZ(REG_ITMP2, 0);
3251 /* codegen_addreference(BlockPtrOfPC(s4ptr[1]), mcodeptr); */
3252 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3256 /* codegen_addreference(BlockPtrOfPC(l), mcodeptr); */
3258 tptr = (void **) iptr->target;
3259 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3266 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
3267 /* op1 = return type, val.a = function pointer*/
3271 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
3272 /* op1 = return type, val.a = function pointer*/
3276 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
3277 /* op1 = return type, val.a = function pointer*/
3281 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3282 /* op1 = arg count, val.a = method pointer */
3284 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3285 /* op1 = arg count, val.a = method pointer */
3287 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3288 /* op1 = arg count, val.a = method pointer */
3290 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
3291 /* op1 = arg count, val.a = method pointer */
3299 MCODECHECK((s3 << 1) + 64);
3301 /* copy arguments to registers or stack location */
3303 for (; --s3 >= 0; src = src->prev) {
3304 if (src->varkind == ARGVAR)
3306 if (IS_INT_LNG_TYPE(src->type)) {
3307 if (s3 < INT_ARG_CNT) {
3308 s1 = argintregs[s3];
3309 var_to_reg_int(d, src, s1);
3313 var_to_reg_int(d, src, REG_ITMP1);
3314 M_LST(d, REG_SP, 8 * (s3 - INT_ARG_CNT));
3318 if (s3 < FLT_ARG_CNT) {
3319 s1 = argfltregs[s3];
3320 var_to_reg_flt(d, src, s1);
3324 var_to_reg_flt(d, src, REG_FTMP1);
3325 M_DST(d, REG_SP, 8 * (s3 - FLT_ARG_CNT));
3330 switch (iptr->opc) {
3334 a = dseg_addaddress ((void*) (m));
3336 M_ALD(REG_PV, REG_PV, a); /* Pointer to built-in-function */
3338 goto makeactualcall;
3340 case ICMD_INVOKESTATIC:
3341 case ICMD_INVOKESPECIAL:
3342 a = dseg_addaddress (m->stubroutine);
3344 M_ALD(REG_PV, REG_PV, a ); /* method pointer in r27 */
3347 goto makeactualcall;
3349 case ICMD_INVOKEVIRTUAL:
3351 gen_nullptr_check(argintregs[0]);
3352 M_ALD(REG_METHODPTR, argintregs[0],
3353 OFFSET(java_objectheader, vftbl));
3354 M_ALD(REG_PV, REG_METHODPTR, OFFSET(vftbl, table[0]) +
3355 sizeof(methodptr) * m->vftblindex);
3358 goto makeactualcall;
3360 case ICMD_INVOKEINTERFACE:
3363 gen_nullptr_check(argintregs[0]);
3364 M_ALD(REG_METHODPTR, argintregs[0],
3365 OFFSET(java_objectheader, vftbl));
3366 M_ALD(REG_METHODPTR, REG_METHODPTR,
3367 OFFSET(vftbl, interfacetable[0]) -
3368 sizeof(methodptr*) * ci->index);
3369 M_ALD(REG_PV, REG_METHODPTR,
3370 sizeof(methodptr) * (m - ci->methods));
3373 goto makeactualcall;
3377 error ("Unkown ICMD-Command: %d", iptr->opc);
3382 M_JSR (REG_RA, REG_PV);
3386 s1 = (int)((u1*) mcodeptr - mcodebase);
3387 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
3390 while (ml<-32768) { ml+=65536; mh--; }
3391 M_LDA (REG_PV, REG_RA, ml );
3392 M_LDAH (REG_PV, REG_PV, mh );
3395 /* d contains return type */
3397 if (d != TYPE_VOID) {
3398 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3399 s1 = reg_of_var(iptr->dst, REG_RESULT);
3400 M_INTMOVE(REG_RESULT, s1);
3401 store_reg_to_var_int(iptr->dst, s1);
3404 s1 = reg_of_var(iptr->dst, REG_FRESULT);
3405 M_FLTMOVE(REG_FRESULT, s1);
3406 store_reg_to_var_flt(iptr->dst, s1);
3413 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3415 /* op1: 0 == array, 1 == class */
3416 /* val.a: (classinfo*) superclass */
3418 /* superclass is an interface:
3420 * return (sub != NULL) &&
3421 * (sub->vftbl->interfacetablelength > super->index) &&
3422 * (sub->vftbl->interfacetable[-super->index] != NULL);
3424 * superclass is a class:
3426 * return ((sub != NULL) && (0
3427 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3428 * super->vftbl->diffvall));
3432 classinfo *super = (classinfo*) iptr->val.a;
3434 var_to_reg_int(s1, src, REG_ITMP1);
3435 d = reg_of_var(iptr->dst, REG_ITMP3);
3437 M_MOV(s1, REG_ITMP1);
3441 if (iptr->op1) { /* class/interface */
3442 if (super->flags & ACC_INTERFACE) { /* interface */
3444 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3445 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3446 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3447 M_BLEZ(REG_ITMP2, 2);
3448 M_ALD(REG_ITMP1, REG_ITMP1,
3449 OFFSET(vftbl, interfacetable[0]) -
3450 super->index * sizeof(methodptr*));
3451 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3455 s2 = super->vftbl->diffval;
3456 M_BEQZ(s1, 4 + (s2 > 255));
3457 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3458 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3459 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3461 M_CMPULE_IMM(REG_ITMP1, s2, d);
3463 M_LDA(REG_ITMP2, REG_ZERO, s2);
3464 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3468 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3469 a = dseg_addaddress ((void*) super->vftbl);
3470 M_ALD(REG_ITMP2, REG_PV, a);
3471 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3472 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl, baseval));
3473 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, diffval));
3474 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3475 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3479 panic ("internal error: no inlined array instanceof");
3481 store_reg_to_var_int(iptr->dst, d);
3484 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3486 /* op1: 0 == array, 1 == class */
3487 /* val.a: (classinfo*) superclass */
3489 /* superclass is an interface:
3491 * OK if ((sub == NULL) ||
3492 * (sub->vftbl->interfacetablelength > super->index) &&
3493 * (sub->vftbl->interfacetable[-super->index] != NULL));
3495 * superclass is a class:
3497 * OK if ((sub == NULL) || (0
3498 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3499 * super->vftbl->diffvall));
3503 classinfo *super = (classinfo*) iptr->val.a;
3505 d = reg_of_var(iptr->dst, REG_ITMP3);
3506 var_to_reg_int(s1, src, d);
3507 if (iptr->op1) { /* class/interface */
3508 if (super->flags & ACC_INTERFACE) { /* interface */
3510 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3511 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3512 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3513 M_BLEZ(REG_ITMP2, 0);
3514 codegen_addxcastrefs(mcodeptr);
3515 M_ALD(REG_ITMP2, REG_ITMP1,
3516 OFFSET(vftbl, interfacetable[0]) -
3517 super->index * sizeof(methodptr*));
3518 M_BEQZ(REG_ITMP2, 0);
3519 codegen_addxcastrefs(mcodeptr);
3523 s2 = super->vftbl->diffval;
3524 M_BEQZ(s1, 4 + (s2 != 0) + (s2 > 255));
3525 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3526 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3527 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3529 M_BNEZ(REG_ITMP1, 0);
3531 else if (s2 <= 255) {
3532 M_CMPULE_IMM(REG_ITMP1, s2, REG_ITMP2);
3533 M_BEQZ(REG_ITMP2, 0);
3536 M_LDA(REG_ITMP2, REG_ZERO, s2);
3537 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3538 M_BEQZ(REG_ITMP2, 0);
3541 M_BEQZ(s1, 8 + (d == REG_ITMP3));
3542 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3543 a = dseg_addaddress ((void*) super->vftbl);
3544 M_ALD(REG_ITMP2, REG_PV, a);
3545 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3546 if (d != REG_ITMP3) {
3547 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl, baseval));
3548 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, diffval));
3549 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3552 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, baseval));
3553 M_ISUB(REG_ITMP1, REG_ITMP2, REG_ITMP1);
3554 M_ALD(REG_ITMP2, REG_PV, a);
3555 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, diffval));
3557 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3558 M_BEQZ(REG_ITMP2, 0);
3559 codegen_addxcastrefs(mcodeptr);
3563 panic ("internal error: no inlined array checkcast");
3566 store_reg_to_var_int(iptr->dst, d);
3569 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
3571 var_to_reg_int(s1, src, REG_ITMP1);
3573 codegen_addxcheckarefs(mcodeptr);
3576 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3577 /* op1 = dimension, val.a = array descriptor */
3579 /* check for negative sizes and copy sizes to stack if necessary */
3581 MCODECHECK((iptr->op1 << 1) + 64);
3583 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3584 var_to_reg_int(s2, src, REG_ITMP1);
3586 codegen_addxcheckarefs(mcodeptr);
3588 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
3590 if (src->varkind != ARGVAR) {
3591 M_LST(s2, REG_SP, 8 * (s1 + INT_ARG_CNT));
3595 /* a0 = dimension count */
3597 ICONST(argintregs[0], iptr->op1);
3599 /* a1 = arraydescriptor */
3601 a = dseg_addaddress(iptr->val.a);
3602 M_ALD(argintregs[1], REG_PV, a);
3604 /* a2 = pointer to dimensions = stack pointer */
3606 M_INTMOVE(REG_SP, argintregs[2]);
3608 a = dseg_addaddress((void*) (builtin_nmultianewarray));
3609 M_ALD(REG_PV, REG_PV, a);
3610 M_JSR(REG_RA, REG_PV);
3611 s1 = (int)((u1*) mcodeptr - mcodebase);
3613 M_LDA (REG_PV, REG_RA, -s1);
3615 s4 ml = -s1, mh = 0;
3616 while (ml < -32768) {ml += 65536; mh--;}
3617 M_LDA(REG_PV, REG_RA, ml);
3618 M_LDAH(REG_PV, REG_PV, mh);
3620 s1 = reg_of_var(iptr->dst, REG_RESULT);
3621 M_INTMOVE(REG_RESULT, s1);
3622 store_reg_to_var_int(iptr->dst, s1);
3626 default: error ("Unknown pseudo command: %d", iptr->opc);
3632 } /* for instruction */
3634 /* copy values to interface registers */
3636 src = bptr->outstack;
3637 len = bptr->outdepth;
3641 if ((src->varkind != STACKVAR)) {
3643 if (IS_FLT_DBL_TYPE(s2)) {
3644 var_to_reg_flt(s1, src, REG_FTMP1);
3645 if (!(interfaces[len][s2].flags & INMEMORY)) {
3646 M_FLTMOVE(s1,interfaces[len][s2].regoff);
3649 M_DST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3653 var_to_reg_int(s1, src, REG_ITMP1);
3654 if (!(interfaces[len][s2].flags & INMEMORY)) {
3655 M_INTMOVE(s1,interfaces[len][s2].regoff);
3658 M_LST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3664 } /* if (bptr -> flags >= BBREACHED) */
3665 } /* for basic block */
3667 /* bptr -> mpc = (int)((u1*) mcodeptr - mcodebase); */
3670 /* generate bound check stubs */
3672 s4 *xcodeptr = NULL;
3674 for (; xboundrefs != NULL; xboundrefs = xboundrefs->next) {
3675 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3676 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
3677 xboundrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3682 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
3683 xboundrefs->branchpos, (u1*) mcodeptr - mcodebase);
3687 M_LDA(REG_ITMP2_XPC, REG_PV, xboundrefs->branchpos - 4);
3689 if (xcodeptr != NULL) {
3690 int disp = (xcodeptr-mcodeptr)-1;
3694 xcodeptr = mcodeptr;
3696 a = dseg_addaddress(proto_java_lang_ArrayIndexOutOfBoundsException);
3697 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3699 a = dseg_addaddress(asm_handle_exception);
3700 M_ALD(REG_ITMP3, REG_PV, a);
3702 M_JMP(REG_ZERO, REG_ITMP3);
3706 /* generate negative array size check stubs */
3710 for (; xcheckarefs != NULL; xcheckarefs = xcheckarefs->next) {
3711 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3712 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3713 xcheckarefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3717 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3718 xcheckarefs->branchpos, (u1*) mcodeptr - mcodebase);
3722 M_LDA(REG_ITMP2_XPC, REG_PV, xcheckarefs->branchpos - 4);
3724 if (xcodeptr != NULL) {
3725 int disp = (xcodeptr-mcodeptr)-1;
3729 xcodeptr = mcodeptr;
3731 a = dseg_addaddress(proto_java_lang_NegativeArraySizeException);
3732 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3734 a = dseg_addaddress(asm_handle_exception);
3735 M_ALD(REG_ITMP3, REG_PV, a);
3737 M_JMP(REG_ZERO, REG_ITMP3);
3741 /* generate cast check stubs */
3745 for (; xcastrefs != NULL; xcastrefs = xcastrefs->next) {
3746 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3747 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3748 xcastrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3752 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3753 xcastrefs->branchpos, (u1*) mcodeptr - mcodebase);
3757 M_LDA(REG_ITMP2_XPC, REG_PV, xcastrefs->branchpos - 4);
3759 if (xcodeptr != NULL) {
3760 int disp = (xcodeptr-mcodeptr)-1;
3764 xcodeptr = mcodeptr;
3766 a = dseg_addaddress(proto_java_lang_ClassCastException);
3767 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3769 a = dseg_addaddress(asm_handle_exception);
3770 M_ALD(REG_ITMP3, REG_PV, a);
3772 M_JMP(REG_ZERO, REG_ITMP3);
3777 #ifdef SOFTNULLPTRCHECK
3779 /* generate null pointer check stubs */
3783 for (; xnullrefs != NULL; xnullrefs = xnullrefs->next) {
3784 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3785 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3786 xnullrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3790 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3791 xnullrefs->branchpos, (u1*) mcodeptr - mcodebase);
3795 M_LDA(REG_ITMP2_XPC, REG_PV, xnullrefs->branchpos - 4);
3797 if (xcodeptr != NULL) {
3798 int disp = (xcodeptr-mcodeptr)-1;
3802 xcodeptr = mcodeptr;
3804 a = dseg_addaddress(proto_java_lang_NullPointerException);
3805 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3807 a = dseg_addaddress(asm_handle_exception);
3808 M_ALD(REG_ITMP3, REG_PV, a);
3810 M_JMP(REG_ZERO, REG_ITMP3);
3817 codegen_finish((int)((u1*) mcodeptr - mcodebase));
3821 /* function createcompilerstub *************************************************
3823 creates a stub routine which calls the compiler
3825 *******************************************************************************/
3827 #define COMPSTUBSIZE 3
3829 u1 *createcompilerstub(methodinfo *m)
3831 u8 *s = CNEW(u8, COMPSTUBSIZE); /* memory to hold the stub */
3832 s4 *mcodeptr = (s4 *) s; /* code generation pointer */
3834 /* code for the stub */
3835 M_ALD(REG_PV, REG_PV, 16); /* load pointer to the compiler */
3836 M_JMP(0, REG_PV); /* jump to the compiler, return address
3837 in reg 0 is used as method pointer */
3838 s[1] = (u8) m; /* literals to be adressed */
3839 s[2] = (u8) asm_call_jit_compiler; /* jump directly via PV from above */
3842 count_cstub_len += COMPSTUBSIZE * 8;
3849 /* function removecompilerstub *************************************************
3851 deletes a compilerstub from memory (simply by freeing it)
3853 *******************************************************************************/
3855 void removecompilerstub(u1 *stub)
3857 CFREE(stub, COMPSTUBSIZE * 8);
3861 /* function: createnativestub **************************************************
3863 creates a stub routine which calls a native method
3865 *******************************************************************************/
3867 #define NATIVESTUBSIZE 44
3868 #define NATIVEVERBOSESIZE 38 + 13
3869 #define NATIVESTUBOFFSET 8
3871 u1 *createnativestub(functionptr f, methodinfo *m)
3873 u8 *s; /* memory pointer to hold the stub */
3875 s4 *mcodeptr; /* code generation pointer */
3876 int stackframesize = 0; /* size of stackframe if needed */
3881 descriptor2types(m); /* set paramcount and paramtypes */
3883 stubsize = runverbose ? NATIVESTUBSIZE + NATIVEVERBOSESIZE : NATIVESTUBSIZE;
3884 s = CNEW(u8, stubsize); /* memory to hold the stub */
3885 cs = s + NATIVESTUBOFFSET;
3886 mcodeptr = (s4 *) (cs); /* code generation pointer */
3888 *(cs-1) = (u8) f; /* address of native method */
3889 *(cs-2) = (u8) (&_exceptionptr); /* address of exceptionptr */
3890 *(cs-3) = (u8) asm_handle_nat_exception; /* addr of asm exception handler */
3891 *(cs-4) = (u8) (&env); /* addr of jni_environement */
3892 *(cs-5) = (u8) builtin_trace_args;
3894 *(cs-7) = (u8) builtin_displaymethodstop;
3895 *(cs-8) = (u8) m->class;
3897 M_LDA(REG_SP, REG_SP, -8); /* build up stackframe */
3898 M_AST(REG_RA, REG_SP, 0); /* store return address */
3900 /* max. 38 instructions */
3904 M_LDA(REG_SP, REG_SP, -(14 * 8));
3905 M_AST(REG_RA, REG_SP, 1 * 8);
3907 /* save integer argument registers */
3908 for (p = 0; p < mparamcount && p < INT_ARG_CNT; p++) {
3909 M_LST(argintregs[p], REG_SP, (2 + p) * 8);
3912 /* save and copy float arguments into integer registers */
3913 for (p = 0; p < m->paramcount && p < FLT_ARG_CNT; p++) {
3914 t = m->paramtypes[p];
3916 if (IS_FLT_DBL_TYPE(t)) {
3917 if (IS_2_WORD_TYPE(t)) {
3918 M_DST(argfltregs[p], REG_SP, (8 + p) * 8);
3919 M_LLD(argintregs[p], REG_SP, (8 + p) * 8);
3922 M_FST(argfltregs[p], REG_SP, (8 + p) * 8);
3923 M_ILD(argintregs[p], REG_SP, (8 + p) * 8);
3927 M_DST(argfltregs[p], REG_SP, (8 + p) * 8);
3931 M_ALD(REG_ITMP1, REG_PV, -6 * 8);
3932 M_AST(REG_ITMP1, REG_SP, 0);
3933 M_ALD(REG_PV, REG_PV, -5 * 8);
3934 M_JSR(REG_RA, REG_PV);
3935 disp = -(int) (mcodeptr - (s4*) cs) * 4;
3936 M_LDA(REG_PV, REG_RA, disp);
3938 for (p = 0; p < mparamcount && p < INT_ARG_CNT; p++) {
3939 M_LLD(argintregs[p], REG_SP, (2 + p) * 8);
3942 for (p = 0; p < mparamcount && p < FLT_ARG_CNT; p++) {
3945 if (IS_FLT_DBL_TYPE(t)) {
3946 if (IS_2_WORD_TYPE(t)) {
3947 M_DLD(argfltregs[p], REG_SP, (8 + p) * 8);
3950 M_FLD(argfltregs[p], REG_SP, (8 + p) * 8);
3954 M_DLD(argfltregs[p], REG_SP, (8 + p) * 8);
3958 M_LDA (REG_SP, REG_SP, 14 * 8);
3961 /* save argument registers on stack -- if we have to */
3962 if ((m->flags & ACC_STATIC && m->paramcount > (INT_ARG_CNT - 2)) || m->paramcount > (INT_ARG_CNT - 1)) {
3964 int paramshiftcnt = (m->flags & ACC_STATIC) ? 2 : 1;
3965 int stackparamcnt = (m->paramcount > INT_ARG_CNT) ? m->paramcount - INT_ARG_CNT : 0;
3967 stackframesize = stackparamcnt + paramshiftcnt;
3969 M_LDA(REG_SP, REG_SP, -stackframesize * 8);
3971 /* copy stack arguments into new stack frame -- if any */
3972 for (i = 0; i < stackparamcnt; i++) {
3973 M_LLD(REG_ITMP1, REG_SP, (stackparamcnt + 1 + i) * 8);
3974 M_LST(REG_ITMP1, REG_SP, (paramshiftcnt + i) * 8);
3977 if (m->flags & ACC_STATIC) {
3978 if (IS_FLT_DBL_TYPE(m->paramtypes[5])) {
3979 M_DST(argfltregs[5], REG_SP, 1 * 8);
3981 M_LST(argintregs[5], REG_SP, 1 * 8);
3984 if (IS_FLT_DBL_TYPE(m->paramtypes[4])) {
3985 M_DST(argfltregs[4], REG_SP, 0 * 8);
3987 M_LST(argintregs[4], REG_SP, 0 * 8);
3991 if (IS_FLT_DBL_TYPE(m->paramtypes[5])) {
3992 M_DST(argfltregs[5], REG_SP, 0 * 8);
3994 M_LST(argintregs[5], REG_SP, 0 * 8);
3999 if (m->flags & ACC_STATIC) {
4000 M_MOV(argintregs[3], argintregs[5]);
4001 M_MOV(argintregs[2], argintregs[4]);
4002 M_MOV(argintregs[1], argintregs[3]);
4003 M_MOV(argintregs[0], argintregs[2]);
4004 M_FMOV(argfltregs[3], argfltregs[5]);
4005 M_FMOV(argfltregs[2], argfltregs[4]);
4006 M_FMOV(argfltregs[1], argfltregs[3]);
4007 M_FMOV(argfltregs[0], argfltregs[2]);
4009 /* put class into second argument register */
4010 M_ALD(argintregs[1], REG_PV, -8 * 8);
4013 M_MOV(argintregs[4], argintregs[5]);
4014 M_MOV(argintregs[3], argintregs[4]);
4015 M_MOV(argintregs[2], argintregs[3]);
4016 M_MOV(argintregs[1], argintregs[2]);
4017 M_MOV(argintregs[0], argintregs[1]);
4018 M_FMOV(argfltregs[4], argfltregs[5]);
4019 M_FMOV(argfltregs[3], argfltregs[4]);
4020 M_FMOV(argfltregs[2], argfltregs[3]);
4021 M_FMOV(argfltregs[1], argfltregs[2]);
4022 M_FMOV(argfltregs[0], argfltregs[1]);
4025 /* put env into first argument register */
4026 M_ALD(argintregs[0], REG_PV, -4 * 8);
4028 M_ALD(REG_PV, REG_PV, -1 * 8); /* load adress of native method */
4029 M_JSR(REG_RA, REG_PV); /* call native method */
4030 disp = -(int) (mcodeptr - (s4*) cs) * 4;
4031 M_LDA(REG_PV, REG_RA, disp); /* recompute pv from ra */
4033 /* remove stackframe if there is one */
4034 if (stackframesize) {
4035 M_LDA(REG_SP, REG_SP, stackframesize * 8);
4038 /* 13 instructions */
4040 M_LDA(REG_SP, REG_SP, -(2 * 8));
4041 M_ALD(argintregs[0], REG_PV, -6 * 8); /* load method adress */
4042 M_LST(REG_RESULT, REG_SP, 0 * 8);
4043 M_DST(REG_FRESULT, REG_SP, 1 * 8);
4044 M_MOV(REG_RESULT, argintregs[1]);
4045 M_FMOV(REG_FRESULT, argfltregs[2]);
4046 M_FMOV(REG_FRESULT, argfltregs[3]);
4047 M_ALD(REG_PV, REG_PV, -7 * 8); /* builtin_displaymethodstop */
4048 M_JSR(REG_RA, REG_PV);
4049 disp = -(int) (mcodeptr - (s4*) cs) * 4;
4050 M_LDA(REG_PV, REG_RA, disp);
4051 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4052 M_DLD(REG_FRESULT, REG_SP, 1 * 8);
4053 M_LDA(REG_SP, REG_SP, 2 * 8);
4056 M_ALD(REG_ITMP3, REG_PV, -2 * 8); /* get address of exceptionptr */
4057 M_ALD(REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
4058 M_BNEZ(REG_ITMP1, 3); /* if no exception then return */
4060 M_ALD(REG_RA, REG_SP, 0); /* load return address */
4061 M_LDA(REG_SP, REG_SP, 8); /* remove stackframe */
4062 M_RET(REG_ZERO, REG_RA); /* return to caller */
4064 M_AST(REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
4066 M_ALD(REG_RA, REG_SP, 0); /* load return address */
4067 M_LDA(REG_SP, REG_SP, 8); /* remove stackframe */
4068 M_LDA(REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
4069 M_ALD(REG_ITMP3, REG_PV, -3 * 8); /* load asm exception handler address */
4070 M_JMP(REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
4073 dolog_plain("stubsize: %d (for %d params)\n", (int) (mcodeptr - (s4*) s), m->paramcount);
4077 count_nstub_len += NATIVESTUBSIZE * 8;
4080 return (u1*) (s + NATIVESTUBOFFSET);
4084 /* function: removenativestub **************************************************
4086 removes a previously created native-stub from memory
4088 *******************************************************************************/
4090 void removenativestub(u1 *stub)
4092 CFREE((u8*) stub - NATIVESTUBOFFSET, NATIVESTUBSIZE * 8);
4097 * These are local overrides for various environment variables in Emacs.
4098 * Please do not remove this and leave it at the end of the file, where
4099 * Emacs will automagically detect them.
4100 * ---------------------------------------------------------------------
4103 * indent-tabs-mode: t