X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=alpha%2Fngen.c;h=69771a08159665e56a6f9889cef324d7965b679d;hb=4ac5116f91e794bb6d7a85eebcfe75b72af27d19;hp=3e3b430e2edb60d81d4df404cc65cc3fae6d0346;hpb=ff031baabb850aacea256edf02b24bb53a639de5;p=cacao.git diff --git a/alpha/ngen.c b/alpha/ngen.c index 3e3b430e2..69771a081 100644 --- a/alpha/ngen.c +++ b/alpha/ngen.c @@ -11,11 +11,11 @@ Authors: Andreas Krall EMAIL: cacao@complang.tuwien.ac.at Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at - Last Change: 1998/08/10 + Last Change: $Id: ngen.c 132 1999-09-27 15:54:42Z chris $ *******************************************************************************/ - +#include "jitdef.h" /* phil */ /* ***************************************************************************** @@ -23,30 +23,31 @@ Datatypes and Register Allocations: ----------------------------------- On 64-bit-machines (like the Alpha) all operands are stored in the -registers in a 64-bit form, even when the correspondig JavaVM -operands only need 32 bits. -This is done by a canonical representation: +registers in a 64-bit form, even when the correspondig JavaVM operands +only need 32 bits. This is done by a canonical representation: -32-bit integers are allways stored as sign-extended 64-bit values -(this approach is directly supported by the Alpha architecture and -is very easy to implement). +32-bit integers are allways stored as sign-extended 64-bit values (this +approach is directly supported by the Alpha architecture and is very easy +to implement). -32-bit-floats are stored in a 64-bit doubleprecision register by -simply expanding the exponent and mantissa with zeroes. -(also supported by the architecture) +32-bit-floats are stored in a 64-bit doubleprecision register by simply +expanding the exponent and mantissa with zeroes. (also supported by the +architecture) Stackframes: -The calling conventions and the layout of the stack is -explained in detail in the documention file: calling.doc +The calling conventions and the layout of the stack is explained in detail +in the documention file: calling.doc *******************************************************************************/ /* additional functions and macros to generate code ***************************/ -#define BlockPtrOfPC(pc) block+block_index[pc] +/* #define BlockPtrOfPC(pc) block+block_index[pc] */ +#define BlockPtrOfPC(pc) ((basicblock *) iptr->target) + #ifdef STATISTICS #define COUNT_SPILLS count_spills++ @@ -78,7 +79,7 @@ explained in detail in the documention file: calling.doc if a and b are the same int-register, no code will be generated. */ -#define M_INTMOVE(a,b) if(a!=b){M_OR(a,a,b,0);} +#define M_INTMOVE(a,b) if(a!=b){M_MOV(a,b);} /* M_FLTMOVE: @@ -119,13 +120,12 @@ explained in detail in the documention file: calling.doc /* reg_of_var: - This function determines a register, to which the result of an - operation should go, when it is ultimatively intended to store the result - in pseudoregister v. - If v is assigned to an actual register, this register will be - returned. - Otherwise (when v is spilled) this function returns tempregnum. - If not already done, regoff and flags are set in the stack location. + This function determines a register, to which the result of an operation + should go, when it is ultimatively intended to store the result in + pseudoregister v. + If v is assigned to an actual register, this register will be returned. + Otherwise (when v is spilled) this function returns tempregnum. + If not already done, regoff and flags are set in the stack location. */ static int reg_of_var(stackptr v, int tempregnum) @@ -196,27 +196,76 @@ static int reg_of_var(stackptr v, int tempregnum) } -void asm_signal_exception(void *xptr, void *sigctx); - -void catch_NullPointerException(int sig, int code, void *sigctx) +/* NullPointerException handlers and exception handling initialisation */ + +typedef struct sigctx_struct { + + long sc_onstack; /* sigstack state to restore */ + long sc_mask; /* signal mask to restore */ + long sc_pc; /* pc at time of signal */ + long sc_ps; /* psl to retore */ + long sc_regs[32]; /* processor regs 0 to 31 */ + long sc_ownedfp; /* fp has been used */ + long sc_fpregs[32]; /* fp regs 0 to 31 */ + unsigned long sc_fpcr; /* floating point control register */ + unsigned long sc_fp_control; /* software fpcr */ + /* rest is unused */ + unsigned long sc_reserved1, sc_reserved2; + unsigned long sc_ssize; + char *sc_sbase; + unsigned long sc_traparg_a0; + unsigned long sc_traparg_a1; + unsigned long sc_traparg_a2; + unsigned long sc_fp_trap_pc; + unsigned long sc_fp_trigger_sum; + unsigned long sc_fp_trigger_inst; + unsigned long sc_retcode[2]; +} sigctx_struct; + + +/* NullPointerException signal handler for hardware null pointer check */ + +void catch_NullPointerException(int sig, int code, sigctx_struct *sigctx) { sigset_t nsig; + int instr; + long faultaddr; /* Reset signal handler - necessary for SysV, does no harm for BSD */ - signal(sig, (void*) catch_NullPointerException); - sigemptyset(&nsig); - sigaddset(&nsig, sig); - sigprocmask(SIG_UNBLOCK, &nsig, NULL); - asm_signal_exception(proto_java_lang_NullPointerException, sigctx); + instr = *((int*)(sigctx->sc_pc)); + faultaddr = sigctx->sc_regs[(instr >> 16) & 0x1f]; + + if (faultaddr == 0) { + signal(sig, (void*) catch_NullPointerException); /* reinstall handler */ + sigemptyset(&nsig); + sigaddset(&nsig, sig); + sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */ + sigctx->sc_regs[REG_ITMP1_XPTR] = + (long) proto_java_lang_NullPointerException; + sigctx->sc_regs[REG_ITMP2_XPC] = sigctx->sc_pc; + sigctx->sc_pc = (long) asm_handle_nat_exception; + return; + } + else { + faultaddr += (long) ((instr << 16) >> 16); + fprintf(stderr, "faulting address: 0x%16lx\n", faultaddr); + panic("Stack overflow"); + } } + #ifdef __osf__ void init_exceptions(void) { -#else +#else /* Linux */ + +/* Linux on Digital Alpha needs an initialisation of the ieee floating point + control for IEEE compliant arithmetic (option -mieee of GCC). Under + Digital Unix this is done automatically. +*/ #include @@ -225,19 +274,23 @@ extern void ieee_set_fp_control(unsigned long fp_control); void init_exceptions(void) { -/* initialise floating point control */ +/* initialize floating point control */ + ieee_set_fp_control(ieee_get_fp_control() & ~IEEE_TRAP_ENABLE_INV & ~IEEE_TRAP_ENABLE_DZE -/* & ~IEEE_TRAP_ENABLE_UNF */ +/* & ~IEEE_TRAP_ENABLE_UNF we dont want underflow */ & ~IEEE_TRAP_ENABLE_OVF); #endif - /* Catch signal we need to convert to exceptions */ + /* install signal handlers we need to convert to exceptions */ + if (!checknull) { + #if defined(SIGSEGV) signal(SIGSEGV, (void*) catch_NullPointerException); #endif + #if defined(SIGBUS) signal(SIGBUS, (void*) catch_NullPointerException); #endif @@ -275,6 +328,7 @@ static void gen_mcode() varinfo *var; basicblock *bptr; instruction *iptr; + xtable *ex; { int p, pa, t, l, r; @@ -288,9 +342,11 @@ static void gen_mcode() parentargs_base = maxmemuse + savedregs_num; -#ifdef USE_THREADS +#ifdef USE_THREADS /* space to save argument of monitor_enter */ + if (checksync && (method->flags & ACC_SYNCHRONIZED)) parentargs_base++; + #endif /* create method header */ @@ -299,29 +355,71 @@ static void gen_mcode() (void) dseg_adds4(parentargs_base * 8); /* FrameSize */ #ifdef USE_THREADS + + /* IsSync contains the offset relative to the stack pointer for the + argument of monitor_exit used in the exception handler. Since the + offset could be zero and give a wrong meaning of the flag it is + offset by one. + */ + if (checksync && (method->flags & ACC_SYNCHRONIZED)) (void) dseg_adds4((maxmemuse + 1) * 8); /* IsSync */ else + #endif - (void) dseg_adds4(0); /* IsSync */ + + (void) dseg_adds4(0); /* IsSync */ (void) dseg_adds4(isleafmethod); /* IsLeaf */ (void) dseg_adds4(savintregcnt - maxsavintreguse); /* IntSave */ (void) dseg_adds4(savfltregcnt - maxsavfltreguse); /* FltSave */ (void) dseg_adds4(exceptiontablelength); /* ExTableSize */ - for (len = 0; len < exceptiontablelength; len++) { - dseg_addtarget(BlockPtrOfPC(extable[len].startpc)); - dseg_addtarget(BlockPtrOfPC(extable[len].endpc)); - dseg_addtarget(BlockPtrOfPC(extable[len].handlerpc)); - (void) dseg_addaddress(extable[len].catchtype); + /* create exception table */ + + for (ex = extable; ex != NULL; ex = ex->down) { + +#ifdef LOOP_DEBUG + if (ex->start != NULL) + printf("adding start - %d - ", ex->start->debug_nr); + else { + printf("PANIC - start is NULL"); + exit(-1); } +#endif + + dseg_addtarget(ex->start); - /* initialise mcode variables */ +#ifdef LOOP_DEBUG + if (ex->end != NULL) + printf("adding end - %d - ", ex->end->debug_nr); + else { + printf("PANIC - end is NULL"); + exit(-1); + } +#endif + + dseg_addtarget(ex->end); + +#ifdef LOOP_DEBUG + if (ex->handler != NULL) + printf("adding handler - %d\n", ex->handler->debug_nr); + else { + printf("PANIC - handler is NULL"); + exit(-1); + } +#endif + + dseg_addtarget(ex->handler); + + (void) dseg_addaddress(ex->catchtype); + } + + /* initialize mcode variables */ mcodeptr = (s4*) mcodebase; mcodeend = (s4*) (mcodebase + mcodesize); - MCODECHECK(128); + MCODECHECK(128 + mparamcount); /* create stack frame (if necessary) */ @@ -332,7 +430,7 @@ static void gen_mcode() p = parentargs_base; if (!isleafmethod) - {p--; M_LST (REG_RA, REG_SP, 8*p);} + {p--; M_AST (REG_RA, REG_SP, 8*p);} for (r = savintregcnt - 1; r >= maxsavintreguse; r--) {p--; M_LST (savintregs[r], REG_SP, 8 * p);} for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--) @@ -344,39 +442,61 @@ static void gen_mcode() if (checksync && (method->flags & ACC_SYNCHRONIZED)) { if (method->flags & ACC_STATIC) { p = dseg_addaddress (class); - M_LLD(REG_ITMP1, REG_PV, p); - M_LST(REG_ITMP1, REG_SP, 8 * maxmemuse); + M_ALD(REG_ITMP1, REG_PV, p); + M_AST(REG_ITMP1, REG_SP, 8 * maxmemuse); } else { - M_LST (argintregs[0], REG_SP, 8 * maxmemuse); + M_AST (argintregs[0], REG_SP, 8 * maxmemuse); } } #endif + /* copy argument registers to stack and call trace function with pointer + to arguments on stack. ToDo: save floating point registers !!!!!!!!! + */ + if (runverbose && isleafmethod) { - M_LDA (REG_SP, REG_SP, -(8*8)); - M_LST(REG_RA, REG_SP, 1*8); - M_LST(argintregs[0], REG_SP, 2*8); - M_LST(argintregs[1], REG_SP, 3*8); - M_LST(argintregs[2], REG_SP, 4*8); - M_LST(argintregs[3], REG_SP, 5*8); - M_LST(argintregs[4], REG_SP, 6*8); - M_LST(argintregs[5], REG_SP, 7*8); + M_LDA (REG_SP, REG_SP, -(14*8)); + M_AST(REG_RA, REG_SP, 1*8); + + M_LST(argintregs[0], REG_SP, 2*8); + M_LST(argintregs[1], REG_SP, 3*8); + M_LST(argintregs[2], REG_SP, 4*8); + M_LST(argintregs[3], REG_SP, 5*8); + M_LST(argintregs[4], REG_SP, 6*8); + M_LST(argintregs[5], REG_SP, 7*8); + + M_DST(argfltregs[0], REG_SP, 8*8); + M_DST(argfltregs[1], REG_SP, 9*8); + M_DST(argfltregs[2], REG_SP, 10*8); + M_DST(argfltregs[3], REG_SP, 11*8); + M_DST(argfltregs[4], REG_SP, 12*8); + M_DST(argfltregs[5], REG_SP, 13*8); + p = dseg_addaddress (method); - M_LLD(REG_ITMP1, REG_PV, p); - M_LST(REG_ITMP1, REG_SP, 0); + M_ALD(REG_ITMP1, REG_PV, p); + M_AST(REG_ITMP1, REG_SP, 0); p = dseg_addaddress ((void*) (builtin_trace_args)); - M_LLD(REG_PV, REG_PV, p); + M_ALD(REG_PV, REG_PV, p); M_JSR(REG_RA, REG_PV); M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase)); - M_LLD(REG_RA, REG_SP, 1*8); - M_LLD(argintregs[0], REG_SP, 2*8); - M_LLD(argintregs[1], REG_SP, 3*8); - M_LLD(argintregs[2], REG_SP, 4*8); - M_LLD(argintregs[3], REG_SP, 5*8); - M_LLD(argintregs[4], REG_SP, 6*8); - M_LLD(argintregs[5], REG_SP, 7*8); - M_LDA (REG_SP, REG_SP, 8*8); + M_ALD(REG_RA, REG_SP, 1*8); + + M_LLD(argintregs[0], REG_SP, 2*8); + M_LLD(argintregs[1], REG_SP, 3*8); + M_LLD(argintregs[2], REG_SP, 4*8); + M_LLD(argintregs[3], REG_SP, 5*8); + M_LLD(argintregs[4], REG_SP, 6*8); + M_LLD(argintregs[5], REG_SP, 7*8); + + M_DLD(argfltregs[0], REG_SP, 8*8); + M_DLD(argfltregs[1], REG_SP, 9*8); + M_DLD(argfltregs[2], REG_SP, 10*8); + M_DLD(argfltregs[3], REG_SP, 11*8); + M_DLD(argfltregs[4], REG_SP, 12*8); + M_DLD(argfltregs[5], REG_SP, 13*8); + + M_LDA (REG_SP, REG_SP, 14*8); } /* take arguments out of register or stack frame */ @@ -426,23 +546,27 @@ static void gen_mcode() } } /* end for */ + /* call trace function */ + if (runverbose && !isleafmethod) { M_LDA (REG_SP, REG_SP, -8); p = dseg_addaddress (method); - M_LLD(REG_ITMP1, REG_PV, p); - M_LST(REG_ITMP1, REG_SP, 0); + M_ALD(REG_ITMP1, REG_PV, p); + M_AST(REG_ITMP1, REG_SP, 0); p = dseg_addaddress ((void*) (builtin_trace_args)); - M_LLD(REG_PV, REG_PV, p); + M_ALD(REG_PV, REG_PV, p); M_JSR(REG_RA, REG_PV); M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase)); M_LDA(REG_SP, REG_SP, 8); } + /* call monitorenter function */ + #ifdef USE_THREADS if (checksync && (method->flags & ACC_SYNCHRONIZED)) { p = dseg_addaddress ((void*) (builtin_monitorenter)); - M_LLD(REG_PV, REG_PV, p); - M_LLD(argintregs[0], REG_SP, 8 * maxmemuse); + M_ALD(REG_PV, REG_PV, p); + M_ALD(argintregs[0], REG_SP, 8 * maxmemuse); M_JSR(REG_RA, REG_PV); M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase)); } @@ -451,7 +575,9 @@ static void gen_mcode() /* end of header generation */ - for (bbs = block_count, bptr = block; --bbs >= 0; bptr++) { + /* walk through all basic blocks */ + for (/* bbs = block_count, */ bptr = block; /* --bbs >= 0 */ bptr != NULL; bptr = bptr->next) { + bptr -> mpc = (int)((u1*) mcodeptr - mcodebase); if (bptr->flags >= BBREACHED) { @@ -465,6 +591,9 @@ static void gen_mcode() brefs->branchpos, bptr->mpc); } } + + /* copy interface registers to their destination */ + src = bptr->instack; len = bptr->indepth; MCODECHECK(64+len); @@ -503,69 +632,77 @@ static void gen_mcode() } src = src->prev; } + + /* walk through all instructions */ + src = bptr->instack; len = bptr->icount; for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) { - MCODECHECK(64); + MCODECHECK(64); /* an instruction usually needs < 64 words */ switch (iptr->opc) { - case ICMD_NOP: + case ICMD_NOP: /* ... ==> ... */ break; - case ICMD_NULLCHECKPOP: + case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */ + var_to_reg_int(s1, src, REG_ITMP1); - gen_nullptr_check(s1); + M_BEQZ(s1, 0); + mcode_addxnullrefs(mcodeptr); break; /* constant operations ************************************************/ - case ICMD_ICONST: +#define ICONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \ + else{a=dseg_adds4(c);M_ILD(r,REG_PV,a);} + +#define LCONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \ + else{a=dseg_adds8(c);M_LLD(r,REG_PV,a);} + + case ICMD_ICONST: /* ... ==> ..., constant */ + /* op1 = 0, val.i = constant */ + d = reg_of_var(iptr->dst, REG_ITMP1); - if ( (iptr->val.i >= -32768) && (iptr->val.i <= 32767) ) { - M_LDA(d, REG_ZERO, iptr->val.i); - } - else { - a = dseg_adds4 (iptr->val.i); - M_ILD(d, REG_PV, a); - } + ICONST(d, iptr->val.i); store_reg_to_var_int(iptr->dst, d); break; - case ICMD_LCONST: + case ICMD_LCONST: /* ... ==> ..., constant */ + /* op1 = 0, val.l = constant */ + d = reg_of_var(iptr->dst, REG_ITMP1); - if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767) ) { - M_LDA(d, REG_ZERO, iptr->val.l); - } - else { - a = dseg_adds8 (iptr->val.l); - M_LLD(d, REG_PV, a); - } + LCONST(d, iptr->val.l); store_reg_to_var_int(iptr->dst, d); break; - case ICMD_FCONST: + case ICMD_FCONST: /* ... ==> ..., constant */ + /* op1 = 0, val.f = constant */ + d = reg_of_var (iptr->dst, REG_FTMP1); a = dseg_addfloat (iptr->val.f); M_FLD(d, REG_PV, a); store_reg_to_var_flt (iptr->dst, d); break; - case ICMD_DCONST: + case ICMD_DCONST: /* ... ==> ..., constant */ + /* op1 = 0, val.d = constant */ + d = reg_of_var (iptr->dst, REG_FTMP1); a = dseg_adddouble (iptr->val.d); M_DLD(d, REG_PV, a); store_reg_to_var_flt (iptr->dst, d); break; + case ICMD_ACONST: /* ... ==> ..., constant */ + /* op1 = 0, val.a = constant */ - case ICMD_ACONST: d = reg_of_var(iptr->dst, REG_ITMP1); if (iptr->val.a) { a = dseg_addaddress (iptr->val.a); - M_LLD(d, REG_PV, a); + M_ALD(d, REG_PV, a); } else { M_INTMOVE(REG_ZERO, d); @@ -573,11 +710,13 @@ static void gen_mcode() store_reg_to_var_int(iptr->dst, d); break; + /* load/store operations **********************************************/ - case ICMD_ILOAD: - case ICMD_LLOAD: + case ICMD_ILOAD: /* ... ==> ..., content of local variable */ + case ICMD_LLOAD: /* op1 = local variable */ case ICMD_ALOAD: + d = reg_of_var(iptr->dst, REG_ITMP1); if ((iptr->dst->varkind == LOCALVAR) && (iptr->dst->varnum == iptr->op1)) @@ -590,8 +729,9 @@ static void gen_mcode() store_reg_to_var_int(iptr->dst, d); break; - case ICMD_FLOAD: - case ICMD_DLOAD: + case ICMD_FLOAD: /* ... ==> ..., content of local variable */ + case ICMD_DLOAD: /* op1 = local variable */ + d = reg_of_var(iptr->dst, REG_FTMP1); if ((iptr->dst->varkind == LOCALVAR) && (iptr->dst->varnum == iptr->op1)) @@ -605,9 +745,10 @@ static void gen_mcode() break; - case ICMD_ISTORE: - case ICMD_LSTORE: + case ICMD_ISTORE: /* ..., value ==> ... */ + case ICMD_LSTORE: /* op1 = local variable */ case ICMD_ASTORE: + if ((src->varkind == LOCALVAR) && (src->varnum == iptr->op1)) break; @@ -622,8 +763,9 @@ static void gen_mcode() } break; - case ICMD_FSTORE: - case ICMD_DSTORE: + case ICMD_FSTORE: /* ..., value ==> ... */ + case ICMD_DSTORE: /* op1 = local variable */ + if ((src->varkind == LOCALVAR) && (src->varnum == iptr->op1)) break; @@ -641,8 +783,10 @@ static void gen_mcode() /* pop/dup/swap operations ********************************************/ - case ICMD_POP: - case ICMD_POP2: + /* attention: double and longs are only one entry in CACAO ICMDs */ + + case ICMD_POP: /* ..., value ==> ... */ + case ICMD_POP2: /* ..., value, value ==> ... */ break; #define M_COPY(from,to) \ @@ -661,27 +805,34 @@ static void gen_mcode() }\ } - case ICMD_DUP: + case ICMD_DUP: /* ..., a ==> ..., a, a */ M_COPY(src, iptr->dst); break; - case ICMD_DUP_X1: + case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */ + M_COPY(src, iptr->dst->prev->prev); - case ICMD_DUP2: + + case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */ + M_COPY(src, iptr->dst); M_COPY(src->prev, iptr->dst->prev); break; - case ICMD_DUP2_X1: + case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */ + M_COPY(src->prev, iptr->dst->prev->prev->prev); - case ICMD_DUP_X2: + + case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */ + M_COPY(src, iptr->dst); M_COPY(src->prev, iptr->dst->prev); M_COPY(src->prev->prev, iptr->dst->prev->prev); M_COPY(src, iptr->dst->prev->prev->prev); break; - case ICMD_DUP2_X2: + case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */ + M_COPY(src, iptr->dst); M_COPY(src->prev, iptr->dst->prev); M_COPY(src->prev->prev, iptr->dst->prev->prev); @@ -690,7 +841,8 @@ static void gen_mcode() M_COPY(src->prev, iptr->dst->prev->prev->prev->prev->prev); break; - case ICMD_SWAP: + case ICMD_SWAP: /* ..., a, b ==> ..., b, a */ + M_COPY(src, iptr->dst->prev); M_COPY(src->prev, iptr->dst); break; @@ -698,578 +850,686 @@ static void gen_mcode() /* integer operations *************************************************/ - case ICMD_INEG: + case ICMD_INEG: /* ..., value ==> ..., - value */ + var_to_reg_int(s1, src, REG_ITMP1); d = reg_of_var(iptr->dst, REG_ITMP3); - M_ISUB(REG_ZERO, s1, d, 0); + M_ISUB(REG_ZERO, s1, d); store_reg_to_var_int(iptr->dst, d); break; - case ICMD_LNEG: + case ICMD_LNEG: /* ..., value ==> ..., - value */ + var_to_reg_int(s1, src, REG_ITMP1); d = reg_of_var(iptr->dst, REG_ITMP3); - M_LSUB(REG_ZERO, s1, d, 0); + M_LSUB(REG_ZERO, s1, d); store_reg_to_var_int(iptr->dst, d); break; - case ICMD_I2L: + case ICMD_I2L: /* ..., value ==> ..., value */ + var_to_reg_int(s1, src, REG_ITMP1); d = reg_of_var(iptr->dst, REG_ITMP3); M_INTMOVE(s1, d); store_reg_to_var_int(iptr->dst, d); break; - case ICMD_L2I: + case ICMD_L2I: /* ..., value ==> ..., value */ + var_to_reg_int(s1, src, REG_ITMP1); d = reg_of_var(iptr->dst, REG_ITMP3); - M_IADD(s1, REG_ZERO, d , 0); + M_IADD(s1, REG_ZERO, d ); store_reg_to_var_int(iptr->dst, d); break; - case ICMD_INT2BYTE: + case ICMD_INT2BYTE: /* ..., value ==> ..., value */ + var_to_reg_int(s1, src, REG_ITMP1); d = reg_of_var(iptr->dst, REG_ITMP3); if (has_ext_instr_set) { M_BSEXT(s1, d); } else { - M_SLL(s1,56, d, 1); - M_SRA( d,56, d, 1); + M_SLL_IMM(s1, 56, d); + M_SRA_IMM( d, 56, d); } store_reg_to_var_int(iptr->dst, d); break; - case ICMD_INT2CHAR: + case ICMD_INT2CHAR: /* ..., value ==> ..., value */ + var_to_reg_int(s1, src, REG_ITMP1); d = reg_of_var(iptr->dst, REG_ITMP3); - M_ZAPNOT(s1, 0x03, d, 1); + M_CZEXT(s1, d); store_reg_to_var_int(iptr->dst, d); break; - case ICMD_INT2SHORT: + case ICMD_INT2SHORT: /* ..., value ==> ..., value */ + var_to_reg_int(s1, src, REG_ITMP1); d = reg_of_var(iptr->dst, REG_ITMP3); if (has_ext_instr_set) { M_SSEXT(s1, d); } else { - M_SLL( s1, 48, d, 1); - M_SRA( d, 48, d, 1); + M_SLL_IMM(s1, 48, d); + M_SRA_IMM( d, 48, d); } store_reg_to_var_int(iptr->dst, d); break; -#define ICONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \ - else{a=dseg_adds4(c);M_ILD(r,REG_PV,a);} - -#define LCONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \ - else{a=dseg_adds8(c);M_LLD(r,REG_PV,a);} + case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */ - case ICMD_IADD: var_to_reg_int(s1, src->prev, REG_ITMP1); var_to_reg_int(s2, src, REG_ITMP2); d = reg_of_var(iptr->dst, REG_ITMP3); - M_IADD(s1, s2, d, 0); + M_IADD(s1, s2, d); store_reg_to_var_int(iptr->dst, d); break; - case ICMD_IADDCONST: + + case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */ + /* val.i = constant */ + var_to_reg_int(s1, src, REG_ITMP1); d = reg_of_var(iptr->dst, REG_ITMP3); if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) { - M_IADD(s1, iptr->val.i, d, 1); + M_IADD_IMM(s1, iptr->val.i, d); } else { ICONST(REG_ITMP2, iptr->val.i); - M_IADD(s1, REG_ITMP2, d, 0); + M_IADD(s1, REG_ITMP2, d); } store_reg_to_var_int(iptr->dst, d); break; - case ICMD_LADD: + + case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */ + var_to_reg_int(s1, src->prev, REG_ITMP1); var_to_reg_int(s2, src, REG_ITMP2); d = reg_of_var(iptr->dst, REG_ITMP3); - M_LADD(s1, s2, d, 0); + M_LADD(s1, s2, d); store_reg_to_var_int(iptr->dst, d); break; - case ICMD_LADDCONST: + + case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */ + /* val.l = constant */ + var_to_reg_int(s1, src, REG_ITMP1); d = reg_of_var(iptr->dst, REG_ITMP3); if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) { - M_LADD(s1, iptr->val.l, d, 1); + M_LADD_IMM(s1, iptr->val.l, d); } else { LCONST(REG_ITMP2, iptr->val.l); - M_LADD(s1, REG_ITMP2, d, 0); + M_LADD(s1, REG_ITMP2, d); } store_reg_to_var_int(iptr->dst, d); break; - case ICMD_ISUB: + case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */ + var_to_reg_int(s1, src->prev, REG_ITMP1); var_to_reg_int(s2, src, REG_ITMP2); d = reg_of_var(iptr->dst, REG_ITMP3); - M_ISUB(s1, s2, d, 0); + M_ISUB(s1, s2, d); store_reg_to_var_int(iptr->dst, d); break; - case ICMD_ISUBCONST: + + case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */ + /* val.i = constant */ + var_to_reg_int(s1, src, REG_ITMP1); d = reg_of_var(iptr->dst, REG_ITMP3); if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) { - M_ISUB(s1, iptr->val.i, d, 1); + M_ISUB_IMM(s1, iptr->val.i, d); } else { ICONST(REG_ITMP2, iptr->val.i); - M_ISUB(s1, REG_ITMP2, d, 0); + M_ISUB(s1, REG_ITMP2, d); } store_reg_to_var_int(iptr->dst, d); break; - case ICMD_LSUB: + + case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */ + var_to_reg_int(s1, src->prev, REG_ITMP1); var_to_reg_int(s2, src, REG_ITMP2); d = reg_of_var(iptr->dst, REG_ITMP3); - M_LSUB(s1, s2, d, 0); + M_LSUB(s1, s2, d); store_reg_to_var_int(iptr->dst, d); break; - case ICMD_LSUBCONST: + + case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */ + /* val.l = constant */ + var_to_reg_int(s1, src, REG_ITMP1); d = reg_of_var(iptr->dst, REG_ITMP3); if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) { - M_LSUB(s1, iptr->val.l, d, 1); + M_LSUB_IMM(s1, iptr->val.l, d); } else { LCONST(REG_ITMP2, iptr->val.l); - M_LSUB(s1, REG_ITMP2, d, 0); + M_LSUB(s1, REG_ITMP2, d); } store_reg_to_var_int(iptr->dst, d); break; - case ICMD_IMUL: + case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */ + var_to_reg_int(s1, src->prev, REG_ITMP1); var_to_reg_int(s2, src, REG_ITMP2); d = reg_of_var(iptr->dst, REG_ITMP3); - M_IMUL(s1, s2, d, 0); + M_IMUL(s1, s2, d); store_reg_to_var_int(iptr->dst, d); break; - case ICMD_IMULCONST: + + case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */ + /* val.i = constant */ + var_to_reg_int(s1, src, REG_ITMP1); d = reg_of_var(iptr->dst, REG_ITMP3); if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) { - M_IMUL(s1, iptr->val.i, d, 1); + M_IMUL_IMM(s1, iptr->val.i, d); } else { ICONST(REG_ITMP2, iptr->val.i); - M_IMUL(s1, REG_ITMP2, d, 0); + M_IMUL(s1, REG_ITMP2, d); } store_reg_to_var_int(iptr->dst, d); break; - case ICMD_LMUL: + + case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */ + var_to_reg_int(s1, src->prev, REG_ITMP1); var_to_reg_int(s2, src, REG_ITMP2); d = reg_of_var(iptr->dst, REG_ITMP3); - M_LMUL (s1, s2, d, 0); + M_LMUL (s1, s2, d); store_reg_to_var_int(iptr->dst, d); break; - case ICMD_LMULCONST: + + case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */ + /* val.l = constant */ + var_to_reg_int(s1, src, REG_ITMP1); d = reg_of_var(iptr->dst, REG_ITMP3); if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) { - M_LMUL(s1, iptr->val.l, d, 1); + M_LMUL_IMM(s1, iptr->val.l, d); } else { LCONST(REG_ITMP2, iptr->val.l); - M_LMUL(s1, REG_ITMP2, d, 0); + M_LMUL(s1, REG_ITMP2, d); } store_reg_to_var_int(iptr->dst, d); break; - case ICMD_IDIVPOW2: - case ICMD_LDIVPOW2: + + case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */ + case ICMD_LDIVPOW2: /* val.i = constant */ + var_to_reg_int(s1, src, REG_ITMP1); d = reg_of_var(iptr->dst, REG_ITMP3); if (iptr->val.i <= 15) { M_LDA(REG_ITMP2, s1, (1 << iptr->val.i) -1); - M_CMOVGE(s1, s1, REG_ITMP2, 0); + M_CMOVGE(s1, s1, REG_ITMP2); } else { - M_SRA(s1, 63, REG_ITMP2, 1); - M_SRL(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2, 1); - M_LADD(s1, REG_ITMP2, REG_ITMP2, 0); + M_SRA_IMM(s1, 63, REG_ITMP2); + M_SRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2); + M_LADD(s1, REG_ITMP2, REG_ITMP2); } - M_SRA(REG_ITMP2, iptr->val.i, d, 1); + M_SRA_IMM(REG_ITMP2, iptr->val.i, d); store_reg_to_var_int(iptr->dst, d); break; - - case ICMD_ISHL: + case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */ + var_to_reg_int(s1, src->prev, REG_ITMP1); var_to_reg_int(s2, src, REG_ITMP2); d = reg_of_var(iptr->dst, REG_ITMP3); - M_AND(s2, 0x1f, REG_ITMP3, 1); - M_SLL(s1, REG_ITMP3, d, 0); - M_IADD(d, REG_ZERO, d, 0); + M_AND_IMM(s2, 0x1f, REG_ITMP3); + M_SLL(s1, REG_ITMP3, d); + M_IADD(d, REG_ZERO, d); store_reg_to_var_int(iptr->dst, d); break; - case ICMD_ISHLCONST: + + case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */ + /* val.i = constant */ + var_to_reg_int(s1, src, REG_ITMP1); d = reg_of_var(iptr->dst, REG_ITMP3); - M_SLL(s1, iptr->val.i & 0x1f, d, 1); - M_IADD(d, REG_ZERO, d, 0); + M_SLL_IMM(s1, iptr->val.i & 0x1f, d); + M_IADD(d, REG_ZERO, d); store_reg_to_var_int(iptr->dst, d); break; - case ICMD_ISHR: + case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */ + var_to_reg_int(s1, src->prev, REG_ITMP1); var_to_reg_int(s2, src, REG_ITMP2); d = reg_of_var(iptr->dst, REG_ITMP3); - M_AND(s2, 0x1f, REG_ITMP3, 1); - M_SRA(s1, REG_ITMP3, d, 0); + M_AND_IMM(s2, 0x1f, REG_ITMP3); + M_SRA(s1, REG_ITMP3, d); store_reg_to_var_int(iptr->dst, d); break; - case ICMD_ISHRCONST: + + case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */ + /* val.i = constant */ + var_to_reg_int(s1, src, REG_ITMP1); d = reg_of_var(iptr->dst, REG_ITMP3); - M_SRA(s1, iptr->val.i & 0x1f, d, 1); + M_SRA_IMM(s1, iptr->val.i & 0x1f, d); store_reg_to_var_int(iptr->dst, d); break; - case ICMD_IUSHR: + case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */ + var_to_reg_int(s1, src->prev, REG_ITMP1); var_to_reg_int(s2, src, REG_ITMP2); d = reg_of_var(iptr->dst, REG_ITMP3); - M_AND (s2, 0x1f, REG_ITMP2, 1); - M_ZAPNOT(s1, 0x0f, d, 1); - M_SRL ( d, REG_ITMP2, d, 0); - M_IADD ( d, REG_ZERO, d, 0); + M_AND_IMM(s2, 0x1f, REG_ITMP2); + M_IZEXT(s1, d); + M_SRL(d, REG_ITMP2, d); + M_IADD(d, REG_ZERO, d); store_reg_to_var_int(iptr->dst, d); break; - case ICMD_IUSHRCONST: + + case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */ + /* val.i = constant */ + var_to_reg_int(s1, src, REG_ITMP1); d = reg_of_var(iptr->dst, REG_ITMP3); - M_ZAPNOT(s1, 0x0f, d, 1); - M_SRL(d, iptr->val.i & 0x1f, d, 1); - M_IADD(d, REG_ZERO, d, 0); + M_IZEXT(s1, d); + M_SRL_IMM(d, iptr->val.i & 0x1f, d); + M_IADD(d, REG_ZERO, d); store_reg_to_var_int(iptr->dst, d); break; - case ICMD_LSHL: + case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */ + var_to_reg_int(s1, src->prev, REG_ITMP1); var_to_reg_int(s2, src, REG_ITMP2); d = reg_of_var(iptr->dst, REG_ITMP3); - M_SLL(s1, s2, d, 0); + M_SLL(s1, s2, d); store_reg_to_var_int(iptr->dst, d); break; - case ICMD_LSHLCONST: + + case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */ + /* val.l = constant */ + var_to_reg_int(s1, src, REG_ITMP1); d = reg_of_var(iptr->dst, REG_ITMP3); - M_SLL(s1, iptr->val.l & 0x3f, d, 1); + M_SLL_IMM(s1, iptr->val.l & 0x3f, d); store_reg_to_var_int(iptr->dst, d); break; - case ICMD_LSHR: + case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */ + var_to_reg_int(s1, src->prev, REG_ITMP1); var_to_reg_int(s2, src, REG_ITMP2); d = reg_of_var(iptr->dst, REG_ITMP3); - M_SRA(s1, s2, d, 0); + M_SRA(s1, s2, d); store_reg_to_var_int(iptr->dst, d); break; - case ICMD_LSHRCONST: + + case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */ + /* val.l = constant */ + var_to_reg_int(s1, src, REG_ITMP1); d = reg_of_var(iptr->dst, REG_ITMP3); - M_SRA(s1, iptr->val.l & 0x3f, d, 1); + M_SRA_IMM(s1, iptr->val.l & 0x3f, d); store_reg_to_var_int(iptr->dst, d); break; - case ICMD_LUSHR: + case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */ + var_to_reg_int(s1, src->prev, REG_ITMP1); var_to_reg_int(s2, src, REG_ITMP2); d = reg_of_var(iptr->dst, REG_ITMP3); - M_SRL(s1, s2, d, 0); + M_SRL(s1, s2, d); store_reg_to_var_int(iptr->dst, d); break; - case ICMD_LUSHRCONST: + + case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */ + /* val.l = constant */ + var_to_reg_int(s1, src, REG_ITMP1); d = reg_of_var(iptr->dst, REG_ITMP3); - M_SRL(s1, iptr->val.l & 0x3f, d, 1); + M_SRL_IMM(s1, iptr->val.l & 0x3f, d); store_reg_to_var_int(iptr->dst, d); break; - case ICMD_IAND: + case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */ case ICMD_LAND: + var_to_reg_int(s1, src->prev, REG_ITMP1); var_to_reg_int(s2, src, REG_ITMP2); d = reg_of_var(iptr->dst, REG_ITMP3); - M_AND(s1, s2, d, 0); + M_AND(s1, s2, d); store_reg_to_var_int(iptr->dst, d); break; - case ICMD_IANDCONST: + + case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */ + /* val.i = constant */ + var_to_reg_int(s1, src, REG_ITMP1); d = reg_of_var(iptr->dst, REG_ITMP3); if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) { - M_AND(s1, iptr->val.i, d, 1); + M_AND_IMM(s1, iptr->val.i, d); } else if (iptr->val.i == 0xffff) { - M_ZAPNOT(s1, 0x03, d, 1); + M_CZEXT(s1, d); } else if (iptr->val.i == 0xffffff) { - M_ZAPNOT(s1, 0x07, d, 1); + M_ZAPNOT_IMM(s1, 0x07, d); } else { ICONST(REG_ITMP2, iptr->val.i); - M_AND(s1, REG_ITMP2, d, 0); + M_AND(s1, REG_ITMP2, d); } store_reg_to_var_int(iptr->dst, d); break; - case ICMD_IREMPOW2: + + case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */ + /* val.i = constant */ + var_to_reg_int(s1, src, REG_ITMP1); d = reg_of_var(iptr->dst, REG_ITMP3); + if (s1 == d) { + M_MOV(s1, REG_ITMP1); + s1 = REG_ITMP1; + } if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) { - M_AND(s1, iptr->val.i, d, 1); + M_AND_IMM(s1, iptr->val.i, d); M_BGEZ(s1, 3); - M_ISUB(REG_ZERO, s1, d, 0); - M_AND(d, iptr->val.i, d, 1); + M_ISUB(REG_ZERO, s1, d); + M_AND_IMM(d, iptr->val.i, d); } else if (iptr->val.i == 0xffff) { - M_ZAPNOT(s1, 0x03, d, 1); + M_CZEXT(s1, d); M_BGEZ(s1, 3); - M_ISUB(REG_ZERO, s1, d, 0); - M_ZAPNOT(d, 0x03, d, 1); + M_ISUB(REG_ZERO, s1, d); + M_CZEXT(d, d); } else if (iptr->val.i == 0xffffff) { - M_ZAPNOT(s1, 0x07, d, 1); + M_ZAPNOT_IMM(s1, 0x07, d); M_BGEZ(s1, 3); - M_ISUB(REG_ZERO, s1, d, 0); - M_ZAPNOT(d, 0x07, d, 1); + M_ISUB(REG_ZERO, s1, d); + M_ZAPNOT_IMM(d, 0x07, d); } else { ICONST(REG_ITMP2, iptr->val.i); - M_AND(s1, REG_ITMP2, d, 0); + M_AND(s1, REG_ITMP2, d); M_BGEZ(s1, 3); - M_ISUB(REG_ZERO, s1, d, 0); - M_AND(d, REG_ITMP2, d, 0); + M_ISUB(REG_ZERO, s1, d); + M_AND(d, REG_ITMP2, d); } - M_ISUB(REG_ZERO, d, d, 0); + M_ISUB(REG_ZERO, d, d); store_reg_to_var_int(iptr->dst, d); break; - case ICMD_IREM0X10001: + + case ICMD_IREM0X10001: /* ..., value ==> ..., value % 0x100001 */ -/* i % 0x100001 - b = i & 0xffff; - a = i >> 16; +/* b = value & 0xffff; + a = value >> 16; a = ((b - a) & 0xffff) + (b < a); */ var_to_reg_int(s1, src, REG_ITMP1); d = reg_of_var(iptr->dst, REG_ITMP3); - M_ZAPNOT(s1, 0x03, REG_ITMP2, 1); - M_SRA(s1, 16, d, 1); - M_CMPLT(REG_ITMP2, d, REG_ITMP1, 0); - M_ISUB(REG_ITMP2, d, d, 0); - M_ZAPNOT(d, 0x03, d, 1); - M_IADD(d, REG_ITMP1, d, 0); - M_BGEZ(s1, 11); - M_ISUB(REG_ZERO, s1, REG_ITMP1, 0); - M_ZAPNOT(REG_ITMP1, 0x03, REG_ITMP2, 1); - M_SRA(REG_ITMP1, 16, d, 1); - M_CMPLT(REG_ITMP2, d, REG_ITMP1, 0); - M_ISUB(REG_ITMP2, d, d, 0); - M_ZAPNOT(d, 0x03, d, 1); - M_IADD(d, REG_ITMP1, d, 0); - M_ISUB(REG_ZERO, d, d, 0); - M_SLL(s1, 33, REG_ITMP2, 1); - M_CMPEQ(REG_ITMP2, REG_ZERO, REG_ITMP2, 0); - M_ISUB(d, REG_ITMP2, d, 0); - store_reg_to_var_int(iptr->dst, d); - break; - case ICMD_LANDCONST: + if (s1 == d) { + M_MOV(s1, REG_ITMP3); + s1 = REG_ITMP3; + } + M_BLTZ(s1, 7); + M_CZEXT(s1, REG_ITMP2); + M_SRA_IMM(s1, 16, d); + M_CMPLT(REG_ITMP2, d, REG_ITMP1); + M_ISUB(REG_ITMP2, d, d); + M_CZEXT(d, d); + M_IADD(d, REG_ITMP1, d); + M_BR(11 + (s1 == REG_ITMP1)); + M_ISUB(REG_ZERO, s1, REG_ITMP1); + M_CZEXT(REG_ITMP1, REG_ITMP2); + M_SRA_IMM(REG_ITMP1, 16, d); + M_CMPLT(REG_ITMP2, d, REG_ITMP1); + M_ISUB(REG_ITMP2, d, d); + M_CZEXT(d, d); + M_IADD(d, REG_ITMP1, d); + M_ISUB(REG_ZERO, d, d); + if (s1 == REG_ITMP1) { + var_to_reg_int(s1, src, REG_ITMP1); + } + M_SLL_IMM(s1, 33, REG_ITMP2); + M_CMPEQ(REG_ITMP2, REG_ZERO, REG_ITMP2); + M_ISUB(d, REG_ITMP2, d); + store_reg_to_var_int(iptr->dst, d); + break; + + case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */ + /* val.l = constant */ + var_to_reg_int(s1, src, REG_ITMP1); d = reg_of_var(iptr->dst, REG_ITMP3); if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) { - M_AND(s1, iptr->val.l, d, 1); + M_AND_IMM(s1, iptr->val.l, d); } else if (iptr->val.l == 0xffffL) { - M_ZAPNOT(s1, 0x03, d, 1); + M_CZEXT(s1, d); } else if (iptr->val.l == 0xffffffL) { - M_ZAPNOT(s1, 0x07, d, 1); + M_ZAPNOT_IMM(s1, 0x07, d); } else if (iptr->val.l == 0xffffffffL) { - M_ZAPNOT(s1, 0x0f, d, 1); + M_IZEXT(s1, d); } else if (iptr->val.l == 0xffffffffffL) { - M_ZAPNOT(s1, 0x1f, d, 1); + M_ZAPNOT_IMM(s1, 0x1f, d); } else if (iptr->val.l == 0xffffffffffffL) { - M_ZAPNOT(s1, 0x3f, d, 1); + M_ZAPNOT_IMM(s1, 0x3f, d); } else if (iptr->val.l == 0xffffffffffffffL) { - M_ZAPNOT(s1, 0x7f, d, 1); + M_ZAPNOT_IMM(s1, 0x7f, d); } else { LCONST(REG_ITMP2, iptr->val.l); - M_AND(s1, REG_ITMP2, d, 0); + M_AND(s1, REG_ITMP2, d); } store_reg_to_var_int(iptr->dst, d); break; - case ICMD_LREMPOW2: + + case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */ + /* val.l = constant */ + var_to_reg_int(s1, src, REG_ITMP1); d = reg_of_var(iptr->dst, REG_ITMP3); + if (s1 == d) { + M_MOV(s1, REG_ITMP1); + s1 = REG_ITMP1; + } if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) { - M_AND(s1, iptr->val.l, d, 1); + M_AND_IMM(s1, iptr->val.l, d); M_BGEZ(s1, 3); - M_LSUB(REG_ZERO, s1, d, 0); - M_AND(d, iptr->val.l, d, 1); + M_LSUB(REG_ZERO, s1, d); + M_AND_IMM(d, iptr->val.l, d); } else if (iptr->val.l == 0xffffL) { - M_ZAPNOT(s1, 0x03, d, 1); + M_CZEXT(s1, d); M_BGEZ(s1, 3); - M_LSUB(REG_ZERO, s1, d, 0); - M_ZAPNOT(d, 0x03, d, 1); + M_LSUB(REG_ZERO, s1, d); + M_CZEXT(d, d); } else if (iptr->val.l == 0xffffffL) { - M_ZAPNOT(s1, 0x07, d, 1); + M_ZAPNOT_IMM(s1, 0x07, d); M_BGEZ(s1, 3); - M_LSUB(REG_ZERO, s1, d, 0); - M_ZAPNOT(d, 0x07, d, 1); + M_LSUB(REG_ZERO, s1, d); + M_ZAPNOT_IMM(d, 0x07, d); } else if (iptr->val.l == 0xffffffffL) { - M_ZAPNOT(s1, 0x0f, d, 1); + M_IZEXT(s1, d); M_BGEZ(s1, 3); - M_LSUB(REG_ZERO, s1, d, 0); - M_ZAPNOT(d, 0x0f, d, 1); + M_LSUB(REG_ZERO, s1, d); + M_IZEXT(d, d); } else if (iptr->val.l == 0xffffffffffL) { - M_ZAPNOT(s1, 0x1f, d, 1); + M_ZAPNOT_IMM(s1, 0x1f, d); M_BGEZ(s1, 3); - M_LSUB(REG_ZERO, s1, d, 0); - M_ZAPNOT(d, 0x1f, d, 1); + M_LSUB(REG_ZERO, s1, d); + M_ZAPNOT_IMM(d, 0x1f, d); } else if (iptr->val.l == 0xffffffffffffL) { - M_ZAPNOT(s1, 0x3f, d, 1); + M_ZAPNOT_IMM(s1, 0x3f, d); M_BGEZ(s1, 3); - M_LSUB(REG_ZERO, s1, d, 0); - M_ZAPNOT(d, 0x3f, d, 1); + M_LSUB(REG_ZERO, s1, d); + M_ZAPNOT_IMM(d, 0x3f, d); } else if (iptr->val.l == 0xffffffffffffffL) { - M_ZAPNOT(s1, 0x7f, d, 1); + M_ZAPNOT_IMM(s1, 0x7f, d); M_BGEZ(s1, 3); - M_LSUB(REG_ZERO, s1, d, 0); - M_ZAPNOT(d, 0x7f, d, 1); + M_LSUB(REG_ZERO, s1, d); + M_ZAPNOT_IMM(d, 0x7f, d); } else { LCONST(REG_ITMP2, iptr->val.l); - M_AND(s1, REG_ITMP2, d, 0); + M_AND(s1, REG_ITMP2, d); M_BGEZ(s1, 3); - M_LSUB(REG_ZERO, s1, d, 0); - M_AND(d, REG_ITMP2, d, 0); + M_LSUB(REG_ZERO, s1, d); + M_AND(d, REG_ITMP2, d); } - M_LSUB(REG_ZERO, d, d, 0); + M_LSUB(REG_ZERO, d, d); store_reg_to_var_int(iptr->dst, d); break; - case ICMD_LREM0X10001: + + case ICMD_LREM0X10001:/* ..., value ==> ..., value % 0x10001 */ + var_to_reg_int(s1, src, REG_ITMP1); d = reg_of_var(iptr->dst, REG_ITMP3); - M_ZAPNOT(s1, 0x03, REG_ITMP2, 1); - M_SRA(s1, 16, d, 1); - M_CMPLT(REG_ITMP2, d, REG_ITMP1, 0); - M_LSUB(REG_ITMP2, d, d, 0); - M_ZAPNOT(d, 0x03, d, 1); - M_LADD(d, REG_ITMP1, d, 0); + if (s1 == d) { + M_MOV(s1, REG_ITMP3); + s1 = REG_ITMP3; + } + M_CZEXT(s1, REG_ITMP2); + M_SRA_IMM(s1, 16, d); + M_CMPLT(REG_ITMP2, d, REG_ITMP1); + M_LSUB(REG_ITMP2, d, d); + M_CZEXT(d, d); + M_LADD(d, REG_ITMP1, d); M_LDA(REG_ITMP2, REG_ZERO, -1); - M_SRL(REG_ITMP2, 33, REG_ITMP2, 1); - M_CMPULT(s1, REG_ITMP2, REG_ITMP2, 0); + M_SRL_IMM(REG_ITMP2, 33, REG_ITMP2); + if (s1 == REG_ITMP1) { + var_to_reg_int(s1, src, REG_ITMP1); + } + M_CMPULT(s1, REG_ITMP2, REG_ITMP2); M_BNEZ(REG_ITMP2, 11); M_LDA(d, REG_ZERO, -257); - M_ZAPNOT(d, 0xcd, d, 1); - M_LSUB(REG_ZERO, s1, REG_ITMP2, 0); - M_CMOVGE(s1, s1, REG_ITMP2, 0); - M_UMULH(REG_ITMP2, d, REG_ITMP2, 0); - M_SRL(REG_ITMP2, 16, REG_ITMP2, 1); - M_LSUB(REG_ZERO, REG_ITMP2, d, 0); - M_CMOVGE(s1, REG_ITMP2, d, 0); - M_SLL(d, 16, REG_ITMP2, 1); - M_LADD(d, REG_ITMP2, d, 0); - M_LSUB(s1, d, d, 0); + M_ZAPNOT_IMM(d, 0xcd, d); + M_LSUB(REG_ZERO, s1, REG_ITMP2); + M_CMOVGE(s1, s1, REG_ITMP2); + M_UMULH(REG_ITMP2, d, REG_ITMP2); + M_SRL_IMM(REG_ITMP2, 16, REG_ITMP2); + M_LSUB(REG_ZERO, REG_ITMP2, d); + M_CMOVGE(s1, REG_ITMP2, d); + M_SLL_IMM(d, 16, REG_ITMP2); + M_LADD(d, REG_ITMP2, d); + M_LSUB(s1, d, d); store_reg_to_var_int(iptr->dst, d); break; - case ICMD_IOR: + case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */ case ICMD_LOR: + var_to_reg_int(s1, src->prev, REG_ITMP1); var_to_reg_int(s2, src, REG_ITMP2); d = reg_of_var(iptr->dst, REG_ITMP3); - M_OR( s1,s2, d, 0); + M_OR( s1,s2, d); store_reg_to_var_int(iptr->dst, d); break; - case ICMD_IORCONST: + + case ICMD_IORCONST: /* ..., value ==> ..., value | constant */ + /* val.i = constant */ + var_to_reg_int(s1, src, REG_ITMP1); d = reg_of_var(iptr->dst, REG_ITMP3); if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) { - M_OR(s1, iptr->val.i, d, 1); + M_OR_IMM(s1, iptr->val.i, d); } else { ICONST(REG_ITMP2, iptr->val.i); - M_OR(s1, REG_ITMP2, d, 0); + M_OR(s1, REG_ITMP2, d); } store_reg_to_var_int(iptr->dst, d); break; - case ICMD_LORCONST: + + case ICMD_LORCONST: /* ..., value ==> ..., value | constant */ + /* val.l = constant */ + var_to_reg_int(s1, src, REG_ITMP1); d = reg_of_var(iptr->dst, REG_ITMP3); if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) { - M_OR(s1, iptr->val.l, d, 1); + M_OR_IMM(s1, iptr->val.l, d); } else { LCONST(REG_ITMP2, iptr->val.l); - M_OR(s1, REG_ITMP2, d, 0); + M_OR(s1, REG_ITMP2, d); } store_reg_to_var_int(iptr->dst, d); break; - case ICMD_IXOR: + case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */ case ICMD_LXOR: + var_to_reg_int(s1, src->prev, REG_ITMP1); var_to_reg_int(s2, src, REG_ITMP2); d = reg_of_var(iptr->dst, REG_ITMP3); - M_XOR(s1, s2, d, 0); + M_XOR(s1, s2, d); store_reg_to_var_int(iptr->dst, d); break; - case ICMD_IXORCONST: + + case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */ + /* val.i = constant */ + var_to_reg_int(s1, src, REG_ITMP1); d = reg_of_var(iptr->dst, REG_ITMP3); if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) { - M_XOR(s1, iptr->val.i, d, 1); + M_XOR_IMM(s1, iptr->val.i, d); } else { ICONST(REG_ITMP2, iptr->val.i); - M_XOR(s1, REG_ITMP2, d, 0); + M_XOR(s1, REG_ITMP2, d); } store_reg_to_var_int(iptr->dst, d); break; - case ICMD_LXORCONST: + + case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */ + /* val.l = constant */ + var_to_reg_int(s1, src, REG_ITMP1); d = reg_of_var(iptr->dst, REG_ITMP3); if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) { - M_XOR(s1, iptr->val.l, d, 1); + M_XOR_IMM(s1, iptr->val.l, d); } else { LCONST(REG_ITMP2, iptr->val.l); - M_XOR(s1, REG_ITMP2, d, 0); + M_XOR(s1, REG_ITMP2, d); } store_reg_to_var_int(iptr->dst, d); break; - case ICMD_LCMP: + case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */ + var_to_reg_int(s1, src->prev, REG_ITMP1); var_to_reg_int(s2, src, REG_ITMP2); d = reg_of_var(iptr->dst, REG_ITMP3); - M_CMPLT(s1, s2, REG_ITMP3, 0); - M_CMPLT(s2, s1, REG_ITMP1, 0); - M_LSUB (REG_ITMP1, REG_ITMP3, d, 0); + M_CMPLT(s1, s2, REG_ITMP3); + M_CMPLT(s2, s1, REG_ITMP1); + M_LSUB (REG_ITMP1, REG_ITMP3, d); store_reg_to_var_int(iptr->dst, d); break; - case ICMD_IINC: + case ICMD_IINC: /* ..., value ==> ..., value + constant */ + /* op1 = variable, val.i = constant */ + var = &(locals[iptr->op1][TYPE_INT]); if (var->flags & INMEMORY) { s1 = REG_ITMP1; @@ -1278,14 +1538,14 @@ static void gen_mcode() else s1 = var->regoff; if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) { - M_IADD(s1, iptr->val.i, s1, 1); + M_IADD_IMM(s1, iptr->val.i, s1); } else if ((iptr->val.i > -256) && (iptr->val.i < 0)) { - M_ISUB(s1, (-iptr->val.i), s1, 1); + M_ISUB_IMM(s1, (-iptr->val.i), s1); } else { M_LDA (s1, s1, iptr->val.i); - M_IADD(s1, REG_ZERO, s1, 0); + M_IADD(s1, REG_ZERO, s1); } if (var->flags & INMEMORY) M_LST(s1, REG_SP, 8 * var->regoff); @@ -1294,20 +1554,24 @@ static void gen_mcode() /* floating operations ************************************************/ - case ICMD_FNEG: + case ICMD_FNEG: /* ..., value ==> ..., - value */ + var_to_reg_flt(s1, src, REG_FTMP1); d = reg_of_var(iptr->dst, REG_FTMP3); M_FMOVN(s1, d); store_reg_to_var_flt(iptr->dst, d); break; - case ICMD_DNEG: + + case ICMD_DNEG: /* ..., value ==> ..., - value */ + var_to_reg_flt(s1, src, REG_FTMP1); d = reg_of_var(iptr->dst, REG_FTMP3); M_FMOVN(s1, d); store_reg_to_var_flt(iptr->dst, d); break; - case ICMD_FADD: + case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */ + var_to_reg_flt(s1, src->prev, REG_FTMP1); var_to_reg_flt(s2, src, REG_FTMP2); d = reg_of_var(iptr->dst, REG_FTMP3); @@ -1320,7 +1584,9 @@ static void gen_mcode() } store_reg_to_var_flt(iptr->dst, d); break; - case ICMD_DADD: + + case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */ + var_to_reg_flt(s1, src->prev, REG_FTMP1); var_to_reg_flt(s2, src, REG_FTMP2); d = reg_of_var(iptr->dst, REG_FTMP3); @@ -1334,7 +1600,8 @@ static void gen_mcode() store_reg_to_var_flt(iptr->dst, d); break; - case ICMD_FSUB: + case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */ + var_to_reg_flt(s1, src->prev, REG_FTMP1); var_to_reg_flt(s2, src, REG_FTMP2); d = reg_of_var(iptr->dst, REG_FTMP3); @@ -1347,7 +1614,9 @@ static void gen_mcode() } store_reg_to_var_flt(iptr->dst, d); break; - case ICMD_DSUB: + + case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */ + var_to_reg_flt(s1, src->prev, REG_FTMP1); var_to_reg_flt(s2, src, REG_FTMP2); d = reg_of_var(iptr->dst, REG_FTMP3); @@ -1361,7 +1630,8 @@ static void gen_mcode() store_reg_to_var_flt(iptr->dst, d); break; - case ICMD_FMUL: + case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */ + var_to_reg_flt(s1, src->prev, REG_FTMP1); var_to_reg_flt(s2, src, REG_FTMP2); d = reg_of_var(iptr->dst, REG_FTMP3); @@ -1374,7 +1644,9 @@ static void gen_mcode() } store_reg_to_var_flt(iptr->dst, d); break; - case ICMD_DMUL: + + case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */ + var_to_reg_flt(s1, src->prev, REG_FTMP1); var_to_reg_flt(s2, src, REG_FTMP2); d = reg_of_var(iptr->dst, REG_FTMP3); @@ -1388,7 +1660,8 @@ static void gen_mcode() store_reg_to_var_flt(iptr->dst, d); break; - case ICMD_FDIV: + case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */ + var_to_reg_flt(s1, src->prev, REG_FTMP1); var_to_reg_flt(s2, src, REG_FTMP2); d = reg_of_var(iptr->dst, REG_FTMP3); @@ -1401,7 +1674,9 @@ static void gen_mcode() } store_reg_to_var_flt(iptr->dst, d); break; - case ICMD_DDIV: + + case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */ + var_to_reg_flt(s1, src->prev, REG_FTMP1); var_to_reg_flt(s2, src, REG_FTMP2); d = reg_of_var(iptr->dst, REG_FTMP3); @@ -1415,16 +1690,17 @@ static void gen_mcode() store_reg_to_var_flt(iptr->dst, d); break; - case ICMD_FREM: + case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */ + var_to_reg_flt(s1, src->prev, REG_FTMP1); var_to_reg_flt(s2, src, REG_FTMP2); d = reg_of_var(iptr->dst, REG_FTMP3); if (checkfloats) { M_FDIVS(s1,s2, REG_FTMP3); M_TRAPB; - M_CVTDL_CS(REG_ZERO, REG_FTMP3, REG_FTMP3); /* round to integer */ + M_CVTDL_CS(REG_FTMP3, REG_FTMP3); /* round to integer */ M_TRAPB; - M_CVTLF(REG_ZERO, REG_FTMP3, REG_FTMP3); + M_CVTLF(REG_FTMP3, REG_FTMP3); M_FMULS(REG_FTMP3, s2, REG_FTMP3); M_TRAPB; M_FSUBS(s1, REG_FTMP3, d); @@ -1432,23 +1708,25 @@ static void gen_mcode() } else { M_FDIV(s1,s2, REG_FTMP3); - M_CVTDL_C(REG_ZERO, REG_FTMP3, REG_FTMP3); /* round to integer */ - M_CVTLF(REG_ZERO, REG_FTMP3, REG_FTMP3); + M_CVTDL_C(REG_FTMP3, REG_FTMP3); /* round to integer */ + M_CVTLF(REG_FTMP3, REG_FTMP3); M_FMUL(REG_FTMP3, s2, REG_FTMP3); M_FSUB(s1, REG_FTMP3, d); } store_reg_to_var_flt(iptr->dst, d); break; - case ICMD_DREM: + + case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */ + var_to_reg_flt(s1, src->prev, REG_FTMP1); var_to_reg_flt(s2, src, REG_FTMP2); d = reg_of_var(iptr->dst, REG_FTMP3); if (checkfloats) { M_DDIVS(s1,s2, REG_FTMP3); M_TRAPB; - M_CVTDL_CS(REG_ZERO, REG_FTMP3, REG_FTMP3); /* round to integer */ + M_CVTDL_CS(REG_FTMP3, REG_FTMP3); /* round to integer */ M_TRAPB; - M_CVTLD(REG_ZERO, REG_FTMP3, REG_FTMP3); + M_CVTLD(REG_FTMP3, REG_FTMP3); M_DMULS(REG_FTMP3, s2, REG_FTMP3); M_TRAPB; M_DSUBS(s1, REG_FTMP3, d); @@ -1456,49 +1734,49 @@ static void gen_mcode() } else { M_DDIV(s1,s2, REG_FTMP3); - M_CVTDL_C(REG_ZERO, REG_FTMP3, REG_FTMP3); /* round to integer */ - M_CVTLD(REG_ZERO, REG_FTMP3, REG_FTMP3); + M_CVTDL_C(REG_FTMP3, REG_FTMP3); /* round to integer */ + M_CVTLD(REG_FTMP3, REG_FTMP3); M_DMUL(REG_FTMP3, s2, REG_FTMP3); M_DSUB(s1, REG_FTMP3, d); } store_reg_to_var_flt(iptr->dst, d); break; - case ICMD_I2F: + case ICMD_I2F: /* ..., value ==> ..., (float) value */ case ICMD_L2F: var_to_reg_int(s1, src, REG_ITMP1); d = reg_of_var(iptr->dst, REG_FTMP3); a = dseg_adddouble(0.0); M_LST (s1, REG_PV, a); M_DLD (d, REG_PV, a); - M_CVTLF(REG_ZERO, d, d); + M_CVTLF(d, d); store_reg_to_var_flt(iptr->dst, d); break; - case ICMD_I2D: + case ICMD_I2D: /* ..., value ==> ..., (double) value */ case ICMD_L2D: var_to_reg_int(s1, src, REG_ITMP1); d = reg_of_var(iptr->dst, REG_FTMP3); a = dseg_adddouble(0.0); M_LST (s1, REG_PV, a); M_DLD (d, REG_PV, a); - M_CVTLD(REG_ZERO, d, d); + M_CVTLD(d, d); store_reg_to_var_flt(iptr->dst, d); break; - case ICMD_F2I: + case ICMD_F2I: /* ..., value ==> ..., (int) value */ case ICMD_D2I: var_to_reg_flt(s1, src, REG_FTMP1); d = reg_of_var(iptr->dst, REG_ITMP3); a = dseg_adddouble(0.0); if (checkfloats) { - M_CVTDL_CS(REG_ZERO, s1, REG_FTMP1); + M_CVTDL_CS(s1, REG_FTMP1); M_TRAPB; M_CVTLIS(REG_FTMP1, REG_FTMP2); M_TRAPB; } else { - M_CVTDL_C(REG_ZERO, s1, REG_FTMP1); + M_CVTDL_C(s1, REG_FTMP1); M_CVTLI(REG_FTMP1, REG_FTMP2); } M_DST (REG_FTMP1, REG_PV, a); @@ -1506,95 +1784,97 @@ static void gen_mcode() store_reg_to_var_int(iptr->dst, d); break; - case ICMD_F2L: + case ICMD_F2L: /* ..., value ==> ..., (long) value */ case ICMD_D2L: var_to_reg_flt(s1, src, REG_FTMP1); d = reg_of_var(iptr->dst, REG_ITMP3); a = dseg_adddouble(0.0); if (checkfloats) { - M_CVTDL_CS(REG_ZERO, s1, REG_FTMP1); + M_CVTDL_CS(s1, REG_FTMP1); M_TRAPB; } else { - M_CVTDL_C(REG_ZERO, s1, REG_FTMP1); + M_CVTDL_C(s1, REG_FTMP1); } M_DST (REG_FTMP1, REG_PV, a); M_LLD (d, REG_PV, a); store_reg_to_var_int(iptr->dst, d); break; - case ICMD_F2D: + case ICMD_F2D: /* ..., value ==> ..., (double) value */ + var_to_reg_flt(s1, src, REG_FTMP1); d = reg_of_var(iptr->dst, REG_FTMP3); M_FLTMOVE(s1, d); store_reg_to_var_flt(iptr->dst, d); break; - case ICMD_D2F: + case ICMD_D2F: /* ..., value ==> ..., (double) value */ + var_to_reg_flt(s1, src, REG_FTMP1); d = reg_of_var(iptr->dst, REG_FTMP3); if (checkfloats) { - M_CVTDFS(REG_ZERO, s1, d); + M_CVTDFS(s1, d); M_TRAPB; } else { - M_CVTDF(REG_ZERO, s1, d); + M_CVTDF(s1, d); } store_reg_to_var_flt(iptr->dst, d); break; - case ICMD_FCMPL: + case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */ case ICMD_DCMPL: var_to_reg_flt(s1, src->prev, REG_FTMP1); var_to_reg_flt(s2, src, REG_FTMP2); d = reg_of_var(iptr->dst, REG_ITMP3); if (checkfloats) { - M_LSUB (REG_ZERO, 1, d, 1); + M_LSUB_IMM(REG_ZERO, 1, d); M_FCMPEQS(s1, s2, REG_FTMP3); M_TRAPB; - M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */ - M_OR (REG_ZERO, REG_ZERO, d, 0); + M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */ + M_CLR (d); M_FCMPLTS(s2, s1, REG_FTMP3); M_TRAPB; - M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */ - M_LADD (REG_ZERO, 1, d, 1); + M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */ + M_LADD_IMM(REG_ZERO, 1, d); } else { - M_LSUB (REG_ZERO, 1, d, 1); + M_LSUB_IMM(REG_ZERO, 1, d); M_FCMPEQ(s1, s2, REG_FTMP3); - M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */ - M_OR (REG_ZERO, REG_ZERO, d, 0); + M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */ + M_CLR (d); M_FCMPLT(s2, s1, REG_FTMP3); - M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */ - M_LADD (REG_ZERO, 1, d, 1); + M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */ + M_LADD_IMM(REG_ZERO, 1, d); } store_reg_to_var_int(iptr->dst, d); break; - case ICMD_FCMPG: + case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */ case ICMD_DCMPG: var_to_reg_flt(s1, src->prev, REG_FTMP1); var_to_reg_flt(s2, src, REG_FTMP2); d = reg_of_var(iptr->dst, REG_ITMP3); if (checkfloats) { - M_LADD (REG_ZERO, 1, d, 1); + M_LADD_IMM(REG_ZERO, 1, d); M_FCMPEQS(s1, s2, REG_FTMP3); M_TRAPB; - M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */ - M_OR (REG_ZERO, REG_ZERO, d, 0); + M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */ + M_CLR (d); M_FCMPLTS(s1, s2, REG_FTMP3); M_TRAPB; - M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */ - M_LSUB (REG_ZERO, 1, d, 1); + M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */ + M_LSUB_IMM(REG_ZERO, 1, d); } else { - M_LADD (REG_ZERO, 1, d, 1); + M_LADD_IMM(REG_ZERO, 1, d); M_FCMPEQ(s1, s2, REG_FTMP3); - M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */ - M_OR (REG_ZERO, REG_ZERO, d, 0); + M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */ + M_CLR (d); M_FCMPLT(s1, s2, REG_FTMP3); - M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */ - M_LSUB (REG_ZERO, 1, d, 1); + M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */ + M_LSUB_IMM(REG_ZERO, 1, d); } store_reg_to_var_int(iptr->dst, d); break; @@ -1602,15 +1882,25 @@ static void gen_mcode() /* memory operations **************************************************/ -#define gen_bound_check \ + /* #define gen_bound_check \ if (checkbounds) {\ - M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\ - M_CMPULT(s2, REG_ITMP3, REG_ITMP3, 0);\ - M_BEQZ(REG_ITMP3, 0);\ - mcode_addxboundrefs(mcodeptr);\ - } + M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\ + M_CMPULT(s2, REG_ITMP3, REG_ITMP3);\ + M_BEQZ(REG_ITMP3, 0);\ + mcode_addxboundrefs(mcodeptr);\ + } + */ + +#define gen_bound_check \ + if (checkbounds) { \ + M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\ + M_CMPULT(s2, REG_ITMP3, REG_ITMP3);\ + M_BEQZ(REG_ITMP3, 0);\ + mcode_addxboundrefs(mcodeptr); \ + } + + case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */ - case ICMD_ARRAYLENGTH: var_to_reg_int(s1, src, REG_ITMP1); d = reg_of_var(iptr->dst, REG_ITMP3); gen_nullptr_check(s1); @@ -1618,243 +1908,313 @@ static void gen_mcode() store_reg_to_var_int(iptr->dst, d); break; - case ICMD_AALOAD: + case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */ + var_to_reg_int(s1, src->prev, REG_ITMP1); var_to_reg_int(s2, src, REG_ITMP2); d = reg_of_var(iptr->dst, REG_ITMP3); - gen_nullptr_check(s1); - gen_bound_check; - M_S8ADDQ(s2, s1, REG_ITMP1, 0); - M_LLD( d, REG_ITMP1, OFFSET(java_objectarray, data[0])); + if (iptr->op1 == 0) { + gen_nullptr_check(s1); + gen_bound_check; + } + M_SAADDQ(s2, s1, REG_ITMP1); + M_ALD( d, REG_ITMP1, OFFSET(java_objectarray, data[0])); store_reg_to_var_int(iptr->dst, d); break; - case ICMD_LALOAD: + + case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */ + var_to_reg_int(s1, src->prev, REG_ITMP1); var_to_reg_int(s2, src, REG_ITMP2); d = reg_of_var(iptr->dst, REG_ITMP3); - gen_nullptr_check(s1); - gen_bound_check; - M_S8ADDQ(s2, s1, REG_ITMP1, 0); + if (iptr->op1 == 0) { + gen_nullptr_check(s1); + gen_bound_check; + } + M_S8ADDQ(s2, s1, REG_ITMP1); M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0])); store_reg_to_var_int(iptr->dst, d); break; - case ICMD_IALOAD: + + case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */ + var_to_reg_int(s1, src->prev, REG_ITMP1); var_to_reg_int(s2, src, REG_ITMP2); d = reg_of_var(iptr->dst, REG_ITMP3); - gen_nullptr_check(s1); - gen_bound_check; - M_S4ADDQ(s2, s1, REG_ITMP1, 0); + if (iptr->op1 == 0) { + gen_nullptr_check(s1); + gen_bound_check; + } + + M_S4ADDQ(s2, s1, REG_ITMP1); M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0])); store_reg_to_var_int(iptr->dst, d); break; - case ICMD_FALOAD: + + case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */ + var_to_reg_int(s1, src->prev, REG_ITMP1); var_to_reg_int(s2, src, REG_ITMP2); d = reg_of_var(iptr->dst, REG_FTMP3); - gen_nullptr_check(s1); - gen_bound_check; - M_S4ADDQ(s2, s1, REG_ITMP1, 0); + if (iptr->op1 == 0) { + gen_nullptr_check(s1); + gen_bound_check; + } + M_S4ADDQ(s2, s1, REG_ITMP1); M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0])); store_reg_to_var_flt(iptr->dst, d); break; - case ICMD_DALOAD: + + case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */ + var_to_reg_int(s1, src->prev, REG_ITMP1); var_to_reg_int(s2, src, REG_ITMP2); d = reg_of_var(iptr->dst, REG_FTMP3); - gen_nullptr_check(s1); - gen_bound_check; - M_S8ADDQ(s2, s1, REG_ITMP1, 0); + if (iptr->op1 == 0) { + gen_nullptr_check(s1); + gen_bound_check; + } + M_S8ADDQ(s2, s1, REG_ITMP1); M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0])); store_reg_to_var_flt(iptr->dst, d); break; - case ICMD_CALOAD: + + case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */ + var_to_reg_int(s1, src->prev, REG_ITMP1); var_to_reg_int(s2, src, REG_ITMP2); d = reg_of_var(iptr->dst, REG_ITMP3); - gen_nullptr_check(s1); - gen_bound_check; + if (iptr->op1 == 0) { + gen_nullptr_check(s1); + gen_bound_check; + } if (has_ext_instr_set) { - M_LADD(s2, s1, REG_ITMP1, 0); - M_LADD(s2, REG_ITMP1, REG_ITMP1, 0); + M_LADD(s2, s1, REG_ITMP1); + M_LADD(s2, REG_ITMP1, REG_ITMP1); M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0])); } else { - M_LADD (s2, s1, REG_ITMP1, 0); - M_LADD (s2, REG_ITMP1, REG_ITMP1, 0); + M_LADD (s2, s1, REG_ITMP1); + M_LADD (s2, REG_ITMP1, REG_ITMP1); M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0])); M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0])); - M_EXTWL(REG_ITMP2, REG_ITMP1, d, 0); + M_EXTWL(REG_ITMP2, REG_ITMP1, d); } store_reg_to_var_int(iptr->dst, d); break; - case ICMD_SALOAD: + + case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */ + var_to_reg_int(s1, src->prev, REG_ITMP1); var_to_reg_int(s2, src, REG_ITMP2); d = reg_of_var(iptr->dst, REG_ITMP3); - gen_nullptr_check(s1); - gen_bound_check; + if (iptr->op1 == 0) { + gen_nullptr_check(s1); + gen_bound_check; + } if (has_ext_instr_set) { - M_LADD(s2, s1, REG_ITMP1, 0); - M_LADD(s2, REG_ITMP1, REG_ITMP1, 0); + M_LADD(s2, s1, REG_ITMP1); + M_LADD(s2, REG_ITMP1, REG_ITMP1); M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0])); M_SSEXT(d, d); } else { - M_LADD(s2, s1, REG_ITMP1, 0); - M_LADD(s2, REG_ITMP1, REG_ITMP1, 0); + M_LADD(s2, s1, REG_ITMP1); + M_LADD(s2, REG_ITMP1, REG_ITMP1); M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0])); M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2); - M_EXTQH(REG_ITMP2, REG_ITMP1, d, 0); - M_SRA(d, 48, d, 1); + M_EXTQH(REG_ITMP2, REG_ITMP1, d); + M_SRA_IMM(d, 48, d); } store_reg_to_var_int(iptr->dst, d); break; - case ICMD_BALOAD: + + case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */ + var_to_reg_int(s1, src->prev, REG_ITMP1); var_to_reg_int(s2, src, REG_ITMP2); d = reg_of_var(iptr->dst, REG_ITMP3); - gen_nullptr_check(s1); - gen_bound_check; + if (iptr->op1 == 0) { + gen_nullptr_check(s1); + gen_bound_check; + } if (has_ext_instr_set) { - M_LADD (s2, s1, REG_ITMP1, 0); + M_LADD (s2, s1, REG_ITMP1); M_BLDU (d, REG_ITMP1, OFFSET (java_shortarray, data[0])); M_BSEXT (d, d); } else { - M_LADD(s2, s1, REG_ITMP1, 0); + M_LADD(s2, s1, REG_ITMP1); M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0])); M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1); - M_EXTQH(REG_ITMP2, REG_ITMP1, d, 0); - M_SRA(d, 56, d, 1); + M_EXTQH(REG_ITMP2, REG_ITMP1, d); + M_SRA_IMM(d, 56, d); } store_reg_to_var_int(iptr->dst, d); break; - case ICMD_AASTORE: + + case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */ + var_to_reg_int(s1, src->prev->prev, REG_ITMP1); var_to_reg_int(s2, src->prev, REG_ITMP2); - gen_nullptr_check(s1); - gen_bound_check; + if (iptr->op1 == 0) { + gen_nullptr_check(s1); + gen_bound_check; + } var_to_reg_int(s3, src, REG_ITMP3); - M_S8ADDQ(s2, s1, REG_ITMP1, 0); - M_LST (s3, REG_ITMP1, OFFSET(java_objectarray, data[0])); + M_SAADDQ(s2, s1, REG_ITMP1); + M_AST (s3, REG_ITMP1, OFFSET(java_objectarray, data[0])); break; - case ICMD_LASTORE: + + case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */ + var_to_reg_int(s1, src->prev->prev, REG_ITMP1); var_to_reg_int(s2, src->prev, REG_ITMP2); - gen_nullptr_check(s1); - gen_bound_check; + if (iptr->op1 == 0) { + gen_nullptr_check(s1); + gen_bound_check; + } var_to_reg_int(s3, src, REG_ITMP3); - M_S8ADDQ(s2, s1, REG_ITMP1, 0); + M_S8ADDQ(s2, s1, REG_ITMP1); M_LST (s3, REG_ITMP1, OFFSET(java_longarray, data[0])); break; - case ICMD_IASTORE: + + case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */ + var_to_reg_int(s1, src->prev->prev, REG_ITMP1); var_to_reg_int(s2, src->prev, REG_ITMP2); - gen_nullptr_check(s1); - gen_bound_check; + if (iptr->op1 == 0) { + gen_nullptr_check(s1); + gen_bound_check; + } + var_to_reg_int(s3, src, REG_ITMP3); - M_S4ADDQ(s2, s1, REG_ITMP1, 0); + M_S4ADDQ(s2, s1, REG_ITMP1); M_IST (s3, REG_ITMP1, OFFSET(java_intarray, data[0])); break; - case ICMD_FASTORE: + + case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */ + var_to_reg_int(s1, src->prev->prev, REG_ITMP1); var_to_reg_int(s2, src->prev, REG_ITMP2); - gen_nullptr_check(s1); - gen_bound_check; + if (iptr->op1 == 0) { + gen_nullptr_check(s1); + gen_bound_check; + } var_to_reg_flt(s3, src, REG_FTMP3); - M_S4ADDQ(s2, s1, REG_ITMP1, 0); + M_S4ADDQ(s2, s1, REG_ITMP1); M_FST (s3, REG_ITMP1, OFFSET(java_floatarray, data[0])); break; - case ICMD_DASTORE: + + case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */ + var_to_reg_int(s1, src->prev->prev, REG_ITMP1); var_to_reg_int(s2, src->prev, REG_ITMP2); - gen_nullptr_check(s1); - gen_bound_check; + if (iptr->op1 == 0) { + gen_nullptr_check(s1); + gen_bound_check; + } var_to_reg_flt(s3, src, REG_FTMP3); - M_S8ADDQ(s2, s1, REG_ITMP1, 0); + M_S8ADDQ(s2, s1, REG_ITMP1); M_DST (s3, REG_ITMP1, OFFSET(java_doublearray, data[0])); break; - case ICMD_CASTORE: + + case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */ + var_to_reg_int(s1, src->prev->prev, REG_ITMP1); var_to_reg_int(s2, src->prev, REG_ITMP2); - gen_nullptr_check(s1); - gen_bound_check; + if (iptr->op1 == 0) { + gen_nullptr_check(s1); + gen_bound_check; + } var_to_reg_int(s3, src, REG_ITMP3); if (has_ext_instr_set) { - M_LADD(s2, s1, REG_ITMP1, 0); - M_LADD(s2, REG_ITMP1, REG_ITMP1, 0); + M_LADD(s2, s1, REG_ITMP1); + M_LADD(s2, REG_ITMP1, REG_ITMP1); M_SST (s3, REG_ITMP1, OFFSET(java_chararray, data[0])); } else { - M_LADD (s2, s1, REG_ITMP1, 0); - M_LADD (s2, REG_ITMP1, REG_ITMP1, 0); + M_LADD (s2, s1, REG_ITMP1); + M_LADD (s2, REG_ITMP1, REG_ITMP1); M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0])); M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0])); - M_INSWL(s3, REG_ITMP1, REG_ITMP3, 0); - M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2, 0); - M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2, 0); + M_INSWL(s3, REG_ITMP1, REG_ITMP3); + M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2); + M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2); M_LST_U(REG_ITMP2, REG_ITMP1, 0); } break; - case ICMD_SASTORE: + + case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */ + var_to_reg_int(s1, src->prev->prev, REG_ITMP1); var_to_reg_int(s2, src->prev, REG_ITMP2); - gen_nullptr_check(s1); - gen_bound_check; + if (iptr->op1 == 0) { + gen_nullptr_check(s1); + gen_bound_check; + } var_to_reg_int(s3, src, REG_ITMP3); if (has_ext_instr_set) { - M_LADD(s2, s1, REG_ITMP1, 0); - M_LADD(s2, REG_ITMP1, REG_ITMP1, 0); + M_LADD(s2, s1, REG_ITMP1); + M_LADD(s2, REG_ITMP1, REG_ITMP1); M_SST (s3, REG_ITMP1, OFFSET(java_shortarray, data[0])); } else { - M_LADD (s2, s1, REG_ITMP1, 0); - M_LADD (s2, REG_ITMP1, REG_ITMP1, 0); + M_LADD (s2, s1, REG_ITMP1); + M_LADD (s2, REG_ITMP1, REG_ITMP1); M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0])); M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])); - M_INSWL(s3, REG_ITMP1, REG_ITMP3, 0); - M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2, 0); - M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2, 0); + M_INSWL(s3, REG_ITMP1, REG_ITMP3); + M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2); + M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2); M_LST_U(REG_ITMP2, REG_ITMP1, 0); } break; - case ICMD_BASTORE: + + case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */ + var_to_reg_int(s1, src->prev->prev, REG_ITMP1); var_to_reg_int(s2, src->prev, REG_ITMP2); - gen_nullptr_check(s1); - gen_bound_check; + if (iptr->op1 == 0) { + gen_nullptr_check(s1); + gen_bound_check; + } var_to_reg_int(s3, src, REG_ITMP3); if (has_ext_instr_set) { - M_LADD(s2, s1, REG_ITMP1, 0); + M_LADD(s2, s1, REG_ITMP1); M_BST (s3, REG_ITMP1, OFFSET(java_bytearray, data[0])); } else { - M_LADD (s2, s1, REG_ITMP1, 0); + M_LADD (s2, s1, REG_ITMP1); M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0])); M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])); - M_INSBL(s3, REG_ITMP1, REG_ITMP3, 0); - M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2, 0); - M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2, 0); + M_INSBL(s3, REG_ITMP1, REG_ITMP3); + M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2); + M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2); M_LST_U(REG_ITMP2, REG_ITMP1, 0); } break; - case ICMD_PUTSTATIC: + case ICMD_PUTSTATIC: /* ..., value ==> ... */ + /* op1 = type, val.a = field address */ + a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value)); - M_LLD(REG_ITMP1, REG_PV, a); + M_ALD(REG_ITMP1, REG_PV, a); switch (iptr->op1) { case TYPE_INT: var_to_reg_int(s2, src, REG_ITMP2); M_IST(s2, REG_ITMP1, 0); break; case TYPE_LNG: - case TYPE_ADR: var_to_reg_int(s2, src, REG_ITMP2); M_LST(s2, REG_ITMP1, 0); break; + case TYPE_ADR: + var_to_reg_int(s2, src, REG_ITMP2); + M_AST(s2, REG_ITMP1, 0); + break; case TYPE_FLT: var_to_reg_flt(s2, src, REG_FTMP2); M_FST(s2, REG_ITMP1, 0); @@ -1867,9 +2227,11 @@ static void gen_mcode() } break; - case ICMD_GETSTATIC: + case ICMD_GETSTATIC: /* ... ==> ..., value */ + /* op1 = type, val.a = field address */ + a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value)); - M_LLD(REG_ITMP1, REG_PV, a); + M_ALD(REG_ITMP1, REG_PV, a); switch (iptr->op1) { case TYPE_INT: d = reg_of_var(iptr->dst, REG_ITMP3); @@ -1877,11 +2239,15 @@ static void gen_mcode() store_reg_to_var_int(iptr->dst, d); break; case TYPE_LNG: - case TYPE_ADR: d = reg_of_var(iptr->dst, REG_ITMP3); M_LLD(d, REG_ITMP1, 0); store_reg_to_var_int(iptr->dst, d); break; + case TYPE_ADR: + d = reg_of_var(iptr->dst, REG_ITMP3); + M_ALD(d, REG_ITMP1, 0); + store_reg_to_var_int(iptr->dst, d); + break; case TYPE_FLT: d = reg_of_var(iptr->dst, REG_FTMP1); M_FLD(d, REG_ITMP1, 0); @@ -1897,7 +2263,9 @@ static void gen_mcode() break; - case ICMD_PUTFIELD: + case ICMD_PUTFIELD: /* ..., value ==> ... */ + /* op1 = type, val.i = field offset */ + a = ((fieldinfo *)(iptr->val.a))->offset; switch (iptr->op1) { case TYPE_INT: @@ -1907,12 +2275,17 @@ static void gen_mcode() M_IST(s2, s1, a); break; case TYPE_LNG: - case TYPE_ADR: var_to_reg_int(s1, src->prev, REG_ITMP1); var_to_reg_int(s2, src, REG_ITMP2); gen_nullptr_check(s1); M_LST(s2, s1, a); break; + case TYPE_ADR: + var_to_reg_int(s1, src->prev, REG_ITMP1); + var_to_reg_int(s2, src, REG_ITMP2); + gen_nullptr_check(s1); + M_AST(s2, s1, a); + break; case TYPE_FLT: var_to_reg_int(s1, src->prev, REG_ITMP1); var_to_reg_flt(s2, src, REG_FTMP2); @@ -1929,7 +2302,9 @@ static void gen_mcode() } break; - case ICMD_GETFIELD: + case ICMD_GETFIELD: /* ... ==> ..., value */ + /* op1 = type, val.i = field offset */ + a = ((fieldinfo *)(iptr->val.a))->offset; switch (iptr->op1) { case TYPE_INT: @@ -1940,13 +2315,19 @@ static void gen_mcode() store_reg_to_var_int(iptr->dst, d); break; case TYPE_LNG: - case TYPE_ADR: var_to_reg_int(s1, src, REG_ITMP1); d = reg_of_var(iptr->dst, REG_ITMP3); gen_nullptr_check(s1); M_LLD(d, s1, a); store_reg_to_var_int(iptr->dst, d); break; + case TYPE_ADR: + var_to_reg_int(s1, src, REG_ITMP1); + d = reg_of_var(iptr->dst, REG_ITMP3); + gen_nullptr_check(s1); + M_ALD(d, s1, a); + store_reg_to_var_int(iptr->dst, d); + break; case TYPE_FLT: var_to_reg_int(s1, src, REG_ITMP1); d = reg_of_var(iptr->dst, REG_FTMP1); @@ -1970,30 +2351,36 @@ static void gen_mcode() #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}} - case ICMD_ATHROW: + case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */ + var_to_reg_int(s1, src, REG_ITMP1); M_INTMOVE(s1, REG_ITMP1_XPTR); a = dseg_addaddress(asm_handle_exception); - M_LLD(REG_ITMP2, REG_PV, a); + M_ALD(REG_ITMP2, REG_PV, a); M_JMP(REG_ITMP2_XPC, REG_ITMP2); ALIGNCODENOP; break; - case ICMD_GOTO: + case ICMD_GOTO: /* ... ==> ... */ + /* op1 = target JavaVM pc */ M_BR(0); mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr); ALIGNCODENOP; break; - case ICMD_JSR: + case ICMD_JSR: /* ... ==> ... */ + /* op1 = target JavaVM pc */ + M_BSR(REG_ITMP1, 0); mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr); break; - case ICMD_RET: + case ICMD_RET: /* ... ==> ... */ + /* op1 = local variable */ + var = &(locals[iptr->op1][TYPE_ADR]); if (var->flags & INMEMORY) { - M_LLD(REG_ITMP1, REG_SP, 8 * var->regoff); + M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff); M_RET(REG_ZERO, REG_ITMP1); } else @@ -2001,469 +2388,539 @@ static void gen_mcode() ALIGNCODENOP; break; - case ICMD_IFNULL: + case ICMD_IFNULL: /* ..., value ==> ... */ + /* op1 = target JavaVM pc */ + var_to_reg_int(s1, src, REG_ITMP1); M_BEQZ(s1, 0); mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr); break; - case ICMD_IFNONNULL: + + case ICMD_IFNONNULL: /* ..., value ==> ... */ + /* op1 = target JavaVM pc */ + var_to_reg_int(s1, src, REG_ITMP1); M_BNEZ(s1, 0); mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr); break; - case ICMD_IFEQ: + case ICMD_IFEQ: /* ..., value ==> ... */ + /* op1 = target JavaVM pc, val.i = constant */ + var_to_reg_int(s1, src, REG_ITMP1); if (iptr->val.i == 0) { M_BEQZ(s1, 0); } else { if ((iptr->val.i > 0) && (iptr->val.i <= 255)) { - M_CMPEQ(s1, iptr->val.i, REG_ITMP1, 1); + M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1); } else { ICONST(REG_ITMP2, iptr->val.i); - M_CMPEQ(s1, REG_ITMP2, REG_ITMP1, 0); + M_CMPEQ(s1, REG_ITMP2, REG_ITMP1); } M_BNEZ(REG_ITMP1, 0); } mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr); break; - case ICMD_IFLT: + + case ICMD_IFLT: /* ..., value ==> ... */ + /* op1 = target JavaVM pc, val.i = constant */ + var_to_reg_int(s1, src, REG_ITMP1); if (iptr->val.i == 0) { M_BLTZ(s1, 0); } else { if ((iptr->val.i > 0) && (iptr->val.i <= 255)) { - M_CMPLT(s1, iptr->val.i, REG_ITMP1, 1); + M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1); } else { ICONST(REG_ITMP2, iptr->val.i); - M_CMPLT(s1, REG_ITMP2, REG_ITMP1, 0); + M_CMPLT(s1, REG_ITMP2, REG_ITMP1); } M_BNEZ(REG_ITMP1, 0); } mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr); break; - case ICMD_IFLE: + + case ICMD_IFLE: /* ..., value ==> ... */ + /* op1 = target JavaVM pc, val.i = constant */ + var_to_reg_int(s1, src, REG_ITMP1); if (iptr->val.i == 0) { M_BLEZ(s1, 0); } else { if ((iptr->val.i > 0) && (iptr->val.i <= 255)) { - M_CMPLE(s1, iptr->val.i, REG_ITMP1, 1); + M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1); } else { ICONST(REG_ITMP2, iptr->val.i); - M_CMPLE(s1, REG_ITMP2, REG_ITMP1, 0); + M_CMPLE(s1, REG_ITMP2, REG_ITMP1); } M_BNEZ(REG_ITMP1, 0); } mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr); break; - case ICMD_IFNE: + + case ICMD_IFNE: /* ..., value ==> ... */ + /* op1 = target JavaVM pc, val.i = constant */ + var_to_reg_int(s1, src, REG_ITMP1); if (iptr->val.i == 0) { M_BNEZ(s1, 0); } else { if ((iptr->val.i > 0) && (iptr->val.i <= 255)) { - M_CMPEQ(s1, iptr->val.i, REG_ITMP1, 1); + M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1); } else { ICONST(REG_ITMP2, iptr->val.i); - M_CMPEQ(s1, REG_ITMP2, REG_ITMP1, 0); + M_CMPEQ(s1, REG_ITMP2, REG_ITMP1); } M_BEQZ(REG_ITMP1, 0); } mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr); break; - case ICMD_IFGT: + + case ICMD_IFGT: /* ..., value ==> ... */ + /* op1 = target JavaVM pc, val.i = constant */ + var_to_reg_int(s1, src, REG_ITMP1); if (iptr->val.i == 0) { M_BGTZ(s1, 0); } else { if ((iptr->val.i > 0) && (iptr->val.i <= 255)) { - M_CMPLE(s1, iptr->val.i, REG_ITMP1, 1); + M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1); } else { ICONST(REG_ITMP2, iptr->val.i); - M_CMPLE(s1, REG_ITMP2, REG_ITMP1, 0); + M_CMPLE(s1, REG_ITMP2, REG_ITMP1); } M_BEQZ(REG_ITMP1, 0); } mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr); break; - case ICMD_IFGE: + + case ICMD_IFGE: /* ..., value ==> ... */ + /* op1 = target JavaVM pc, val.i = constant */ + var_to_reg_int(s1, src, REG_ITMP1); if (iptr->val.i == 0) { M_BGEZ(s1, 0); } else { if ((iptr->val.i > 0) && (iptr->val.i <= 255)) { - M_CMPLT(s1, iptr->val.i, REG_ITMP1, 1); + M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1); } else { ICONST(REG_ITMP2, iptr->val.i); - M_CMPLT(s1, REG_ITMP2, REG_ITMP1, 0); + M_CMPLT(s1, REG_ITMP2, REG_ITMP1); } M_BEQZ(REG_ITMP1, 0); } mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr); break; - case ICMD_IF_LEQ: + case ICMD_IF_LEQ: /* ..., value ==> ... */ + /* op1 = target JavaVM pc, val.l = constant */ + var_to_reg_int(s1, src, REG_ITMP1); if (iptr->val.l == 0) { M_BEQZ(s1, 0); } else { if ((iptr->val.l > 0) && (iptr->val.l <= 255)) { - M_CMPEQ(s1, iptr->val.l, REG_ITMP1, 1); + M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1); } else { LCONST(REG_ITMP2, iptr->val.l); - M_CMPEQ(s1, REG_ITMP2, REG_ITMP1, 0); + M_CMPEQ(s1, REG_ITMP2, REG_ITMP1); } M_BNEZ(REG_ITMP1, 0); } mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr); break; - case ICMD_IF_LLT: + + case ICMD_IF_LLT: /* ..., value ==> ... */ + /* op1 = target JavaVM pc, val.l = constant */ + var_to_reg_int(s1, src, REG_ITMP1); if (iptr->val.l == 0) { M_BLTZ(s1, 0); } else { if ((iptr->val.l > 0) && (iptr->val.l <= 255)) { - M_CMPLT(s1, iptr->val.l, REG_ITMP1, 1); + M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1); } else { LCONST(REG_ITMP2, iptr->val.l); - M_CMPLT(s1, REG_ITMP2, REG_ITMP1, 0); + M_CMPLT(s1, REG_ITMP2, REG_ITMP1); } M_BNEZ(REG_ITMP1, 0); } mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr); break; - case ICMD_IF_LLE: + + case ICMD_IF_LLE: /* ..., value ==> ... */ + /* op1 = target JavaVM pc, val.l = constant */ + var_to_reg_int(s1, src, REG_ITMP1); if (iptr->val.l == 0) { M_BLEZ(s1, 0); } else { if ((iptr->val.l > 0) && (iptr->val.l <= 255)) { - M_CMPLE(s1, iptr->val.l, REG_ITMP1, 1); + M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1); } else { LCONST(REG_ITMP2, iptr->val.l); - M_CMPLE(s1, REG_ITMP2, REG_ITMP1, 0); + M_CMPLE(s1, REG_ITMP2, REG_ITMP1); } M_BNEZ(REG_ITMP1, 0); } mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr); break; - case ICMD_IF_LNE: + + case ICMD_IF_LNE: /* ..., value ==> ... */ + /* op1 = target JavaVM pc, val.l = constant */ + var_to_reg_int(s1, src, REG_ITMP1); if (iptr->val.l == 0) { M_BNEZ(s1, 0); } else { if ((iptr->val.l > 0) && (iptr->val.l <= 255)) { - M_CMPEQ(s1, iptr->val.l, REG_ITMP1, 1); + M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1); } else { LCONST(REG_ITMP2, iptr->val.l); - M_CMPEQ(s1, REG_ITMP2, REG_ITMP1, 0); + M_CMPEQ(s1, REG_ITMP2, REG_ITMP1); } M_BEQZ(REG_ITMP1, 0); } mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr); break; - case ICMD_IF_LGT: + + case ICMD_IF_LGT: /* ..., value ==> ... */ + /* op1 = target JavaVM pc, val.l = constant */ + var_to_reg_int(s1, src, REG_ITMP1); if (iptr->val.l == 0) { M_BGTZ(s1, 0); } else { if ((iptr->val.l > 0) && (iptr->val.l <= 255)) { - M_CMPLE(s1, iptr->val.l, REG_ITMP1, 1); + M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1); } else { LCONST(REG_ITMP2, iptr->val.l); - M_CMPLE(s1, REG_ITMP2, REG_ITMP1, 0); + M_CMPLE(s1, REG_ITMP2, REG_ITMP1); } M_BEQZ(REG_ITMP1, 0); } mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr); break; - case ICMD_IF_LGE: + + case ICMD_IF_LGE: /* ..., value ==> ... */ + /* op1 = target JavaVM pc, val.l = constant */ + var_to_reg_int(s1, src, REG_ITMP1); if (iptr->val.l == 0) { M_BGEZ(s1, 0); } else { if ((iptr->val.l > 0) && (iptr->val.l <= 255)) { - M_CMPLT(s1, iptr->val.l, REG_ITMP1, 1); + M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1); } else { LCONST(REG_ITMP2, iptr->val.l); - M_CMPLT(s1, REG_ITMP2, REG_ITMP1, 0); + M_CMPLT(s1, REG_ITMP2, REG_ITMP1); } M_BEQZ(REG_ITMP1, 0); } mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr); break; - case ICMD_IF_ICMPEQ: - case ICMD_IF_LCMPEQ: + case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */ + case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */ case ICMD_IF_ACMPEQ: + var_to_reg_int(s1, src->prev, REG_ITMP1); var_to_reg_int(s2, src, REG_ITMP2); - M_CMPEQ(s1, s2, REG_ITMP1, 0); + M_CMPEQ(s1, s2, REG_ITMP1); M_BNEZ(REG_ITMP1, 0); mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr); break; - case ICMD_IF_ICMPNE: - case ICMD_IF_LCMPNE: + + case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */ + case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */ case ICMD_IF_ACMPNE: + var_to_reg_int(s1, src->prev, REG_ITMP1); var_to_reg_int(s2, src, REG_ITMP2); - M_CMPEQ(s1, s2, REG_ITMP1, 0); + M_CMPEQ(s1, s2, REG_ITMP1); M_BEQZ(REG_ITMP1, 0); mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr); break; - case ICMD_IF_ICMPLT: - case ICMD_IF_LCMPLT: + + case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */ + case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */ + var_to_reg_int(s1, src->prev, REG_ITMP1); var_to_reg_int(s2, src, REG_ITMP2); - M_CMPLT(s1, s2, REG_ITMP1, 0); + M_CMPLT(s1, s2, REG_ITMP1); M_BNEZ(REG_ITMP1, 0); mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr); break; - case ICMD_IF_ICMPGT: - case ICMD_IF_LCMPGT: + + case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */ + case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */ + var_to_reg_int(s1, src->prev, REG_ITMP1); var_to_reg_int(s2, src, REG_ITMP2); - M_CMPLE(s1, s2, REG_ITMP1, 0); + M_CMPLE(s1, s2, REG_ITMP1); M_BEQZ(REG_ITMP1, 0); mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr); break; - case ICMD_IF_ICMPLE: - case ICMD_IF_LCMPLE: + + case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */ + case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */ + var_to_reg_int(s1, src->prev, REG_ITMP1); var_to_reg_int(s2, src, REG_ITMP2); - M_CMPLE(s1, s2, REG_ITMP1, 0); + M_CMPLE(s1, s2, REG_ITMP1); M_BNEZ(REG_ITMP1, 0); mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr); break; - case ICMD_IF_ICMPGE: - case ICMD_IF_LCMPGE: + + case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */ + case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */ + var_to_reg_int(s1, src->prev, REG_ITMP1); var_to_reg_int(s2, src, REG_ITMP2); - M_CMPLT(s1, s2, REG_ITMP1, 0); + M_CMPLT(s1, s2, REG_ITMP1); M_BEQZ(REG_ITMP1, 0); mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr); break; - case ICMD_ELSE_ICONST: + /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */ + + case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */ break; - case ICMD_IFEQ_ICONST: + + case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */ + /* val.i = constant */ + var_to_reg_int(s1, src, REG_ITMP1); d = reg_of_var(iptr->dst, REG_ITMP3); - a = iptr->val.i; + s3 = iptr->val.i; if (iptr[1].opc == ICMD_ELSE_ICONST) { - if ((a == 1) && (iptr[1].val.i == 0)) { - M_CMPEQ(s1, REG_ZERO, d, 0); + if ((s3 == 1) && (iptr[1].val.i == 0)) { + M_CMPEQ(s1, REG_ZERO, d); store_reg_to_var_int(iptr->dst, d); break; } - if ((a == 0) && (iptr[1].val.i == 1)) { - M_CMPEQ(s1, REG_ZERO, d, 0); - M_XOR(d, 1, d, 1); + if ((s3 == 0) && (iptr[1].val.i == 1)) { + M_CMPEQ(s1, REG_ZERO, d); + M_XOR_IMM(d, 1, d); store_reg_to_var_int(iptr->dst, d); break; } if (s1 == d) { - M_OR(s1, s1 , REG_ITMP1, 0); + M_MOV(s1, REG_ITMP1); s1 = REG_ITMP1; } ICONST(d, iptr[1].val.i); } - if ((a >= 0) && (a <= 255)) { - M_CMOVEQ(s1, a, d, 1); + if ((s3 >= 0) && (s3 <= 255)) { + M_CMOVEQ_IMM(s1, s3, d); } else { - ICONST(REG_ITMP2, a); - M_CMOVEQ(s1, REG_ITMP2, d, 0); + ICONST(REG_ITMP2, s3); + M_CMOVEQ(s1, REG_ITMP2, d); } store_reg_to_var_int(iptr->dst, d); break; - case ICMD_IFNE_ICONST: + + case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */ + /* val.i = constant */ + var_to_reg_int(s1, src, REG_ITMP1); d = reg_of_var(iptr->dst, REG_ITMP3); - a = iptr->val.i; + s3 = iptr->val.i; if (iptr[1].opc == ICMD_ELSE_ICONST) { - if ((a == 0) && (iptr[1].val.i == 1)) { - M_CMPEQ(s1, REG_ZERO, d, 0); + if ((s3 == 0) && (iptr[1].val.i == 1)) { + M_CMPEQ(s1, REG_ZERO, d); store_reg_to_var_int(iptr->dst, d); break; } - if ((a == 1) && (iptr[1].val.i == 0)) { - M_CMPEQ(s1, REG_ZERO, d, 0); - M_XOR(d, 1, d, 1); + if ((s3 == 1) && (iptr[1].val.i == 0)) { + M_CMPEQ(s1, REG_ZERO, d); + M_XOR_IMM(d, 1, d); store_reg_to_var_int(iptr->dst, d); break; } if (s1 == d) { - M_OR(s1, s1 , REG_ITMP1, 0); + M_MOV(s1, REG_ITMP1); s1 = REG_ITMP1; } ICONST(d, iptr[1].val.i); } - if ((a >= 0) && (a <= 255)) { - M_CMOVNE(s1, a, d, 1); + if ((s3 >= 0) && (s3 <= 255)) { + M_CMOVNE_IMM(s1, s3, d); } else { - ICONST(REG_ITMP2, a); - M_CMOVNE(s1, REG_ITMP2, d, 0); + ICONST(REG_ITMP2, s3); + M_CMOVNE(s1, REG_ITMP2, d); } store_reg_to_var_int(iptr->dst, d); break; - case ICMD_IFLT_ICONST: + + case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */ + /* val.i = constant */ + var_to_reg_int(s1, src, REG_ITMP1); d = reg_of_var(iptr->dst, REG_ITMP3); - a = iptr->val.i; + s3 = iptr->val.i; if ((iptr[1].opc == ICMD_ELSE_ICONST)) { - if ((a == 1) && (iptr[1].val.i == 0)) { - M_CMPLT(s1, REG_ZERO, d, 0); + if ((s3 == 1) && (iptr[1].val.i == 0)) { + M_CMPLT(s1, REG_ZERO, d); store_reg_to_var_int(iptr->dst, d); break; } - if ((a == 0) && (iptr[1].val.i == 1)) { - M_CMPLE(REG_ZERO, s1, d, 0); + if ((s3 == 0) && (iptr[1].val.i == 1)) { + M_CMPLE(REG_ZERO, s1, d); store_reg_to_var_int(iptr->dst, d); break; } if (s1 == d) { - M_OR(s1, s1 , REG_ITMP1, 0); + M_MOV(s1, REG_ITMP1); s1 = REG_ITMP1; } ICONST(d, iptr[1].val.i); } - if ((a >= 0) && (a <= 255)) { - M_CMOVLT(s1, a, d, 1); + if ((s3 >= 0) && (s3 <= 255)) { + M_CMOVLT_IMM(s1, s3, d); } else { - ICONST(REG_ITMP2, a); - M_CMOVLT(s1, REG_ITMP2, d, 0); + ICONST(REG_ITMP2, s3); + M_CMOVLT(s1, REG_ITMP2, d); } store_reg_to_var_int(iptr->dst, d); break; - case ICMD_IFGE_ICONST: + + case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */ + /* val.i = constant */ + var_to_reg_int(s1, src, REG_ITMP1); d = reg_of_var(iptr->dst, REG_ITMP3); - a = iptr->val.i; + s3 = iptr->val.i; if ((iptr[1].opc == ICMD_ELSE_ICONST)) { - if ((a == 1) && (iptr[1].val.i == 0)) { - M_CMPLE(REG_ZERO, s1, d, 0); + if ((s3 == 1) && (iptr[1].val.i == 0)) { + M_CMPLE(REG_ZERO, s1, d); store_reg_to_var_int(iptr->dst, d); break; } - if ((a == 0) && (iptr[1].val.i == 1)) { - M_CMPLT(s1, REG_ZERO, d, 0); + if ((s3 == 0) && (iptr[1].val.i == 1)) { + M_CMPLT(s1, REG_ZERO, d); store_reg_to_var_int(iptr->dst, d); break; } if (s1 == d) { - M_OR(s1, s1 , REG_ITMP1, 0); + M_MOV(s1, REG_ITMP1); s1 = REG_ITMP1; } ICONST(d, iptr[1].val.i); } - if ((a >= 0) && (a <= 255)) { - M_CMOVGE(s1, a, d, 1); + if ((s3 >= 0) && (s3 <= 255)) { + M_CMOVGE_IMM(s1, s3, d); } else { - ICONST(REG_ITMP2, a); - M_CMOVGE(s1, REG_ITMP2, d, 0); + ICONST(REG_ITMP2, s3); + M_CMOVGE(s1, REG_ITMP2, d); } store_reg_to_var_int(iptr->dst, d); break; - case ICMD_IFGT_ICONST: + + case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */ + /* val.i = constant */ + var_to_reg_int(s1, src, REG_ITMP1); d = reg_of_var(iptr->dst, REG_ITMP3); - a = iptr->val.i; + s3 = iptr->val.i; if ((iptr[1].opc == ICMD_ELSE_ICONST)) { - if ((a == 1) && (iptr[1].val.i == 0)) { - M_CMPLT(REG_ZERO, s1, d, 0); + if ((s3 == 1) && (iptr[1].val.i == 0)) { + M_CMPLT(REG_ZERO, s1, d); store_reg_to_var_int(iptr->dst, d); break; } - if ((a == 0) && (iptr[1].val.i == 1)) { - M_CMPLE(s1, REG_ZERO, d, 0); + if ((s3 == 0) && (iptr[1].val.i == 1)) { + M_CMPLE(s1, REG_ZERO, d); store_reg_to_var_int(iptr->dst, d); break; } if (s1 == d) { - M_OR(s1, s1 , REG_ITMP1, 0); + M_MOV(s1, REG_ITMP1); s1 = REG_ITMP1; } ICONST(d, iptr[1].val.i); } - if ((a >= 0) && (a <= 255)) { - M_CMOVGT(s1, a, d, 1); + if ((s3 >= 0) && (s3 <= 255)) { + M_CMOVGT_IMM(s1, s3, d); } else { - ICONST(REG_ITMP2, a); - M_CMOVGT(s1, REG_ITMP2, d, 0); + ICONST(REG_ITMP2, s3); + M_CMOVGT(s1, REG_ITMP2, d); } store_reg_to_var_int(iptr->dst, d); break; - case ICMD_IFLE_ICONST: + + case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */ + /* val.i = constant */ + var_to_reg_int(s1, src, REG_ITMP1); d = reg_of_var(iptr->dst, REG_ITMP3); - a = iptr->val.i; + s3 = iptr->val.i; if ((iptr[1].opc == ICMD_ELSE_ICONST)) { - if ((a == 1) && (iptr[1].val.i == 0)) { - M_CMPLE(s1, REG_ZERO, d, 0); + if ((s3 == 1) && (iptr[1].val.i == 0)) { + M_CMPLE(s1, REG_ZERO, d); store_reg_to_var_int(iptr->dst, d); break; } - if ((a == 0) && (iptr[1].val.i == 1)) { - M_CMPLT(REG_ZERO, s1, d, 0); + if ((s3 == 0) && (iptr[1].val.i == 1)) { + M_CMPLT(REG_ZERO, s1, d); store_reg_to_var_int(iptr->dst, d); break; } if (s1 == d) { - M_OR(s1, s1 , REG_ITMP1, 0); + M_MOV(s1, REG_ITMP1); s1 = REG_ITMP1; } ICONST(d, iptr[1].val.i); } - if ((a >= 0) && (a <= 255)) { - M_CMOVLE(s1, a, d, 1); + if ((s3 >= 0) && (s3 <= 255)) { + M_CMOVLE_IMM(s1, s3, d); } else { - ICONST(REG_ITMP2, a); - M_CMOVLE(s1, REG_ITMP2, d, 0); + ICONST(REG_ITMP2, s3); + M_CMOVLE(s1, REG_ITMP2, d); } store_reg_to_var_int(iptr->dst, d); break; - case ICMD_IRETURN: + case ICMD_IRETURN: /* ..., retvalue ==> ... */ case ICMD_LRETURN: case ICMD_ARETURN: #ifdef USE_THREADS if (checksync && (method->flags & ACC_SYNCHRONIZED)) { a = dseg_addaddress ((void*) (builtin_monitorexit)); - M_LLD(REG_PV, REG_PV, a); - M_LLD(argintregs[0], REG_SP, 8 * maxmemuse); + M_ALD(REG_PV, REG_PV, a); + M_ALD(argintregs[0], REG_SP, 8 * maxmemuse); M_JSR(REG_RA, REG_PV); M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase)); } @@ -2472,14 +2929,14 @@ static void gen_mcode() M_INTMOVE(s1, REG_RESULT); goto nowperformreturn; - case ICMD_FRETURN: + case ICMD_FRETURN: /* ..., retvalue ==> ... */ case ICMD_DRETURN: #ifdef USE_THREADS if (checksync && (method->flags & ACC_SYNCHRONIZED)) { a = dseg_addaddress ((void*) (builtin_monitorexit)); - M_LLD(REG_PV, REG_PV, a); - M_LLD(argintregs[0], REG_SP, 8 * maxmemuse); + M_ALD(REG_PV, REG_PV, a); + M_ALD(argintregs[0], REG_SP, 8 * maxmemuse); M_JSR(REG_RA, REG_PV); M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase)); } @@ -2488,13 +2945,13 @@ static void gen_mcode() M_FLTMOVE(s1, REG_FRESULT); goto nowperformreturn; - case ICMD_RETURN: + case ICMD_RETURN: /* ... ==> ... */ #ifdef USE_THREADS if (checksync && (method->flags & ACC_SYNCHRONIZED)) { a = dseg_addaddress ((void*) (builtin_monitorexit)); - M_LLD(REG_PV, REG_PV, a); - M_LLD(argintregs[0], REG_SP, 8 * maxmemuse); + M_ALD(REG_PV, REG_PV, a); + M_ALD(argintregs[0], REG_SP, 8 * maxmemuse); M_JSR(REG_RA, REG_PV); M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase)); } @@ -2505,26 +2962,37 @@ nowperformreturn: int r, p; p = parentargs_base; + + /* restore return address */ + if (!isleafmethod) {p--; M_LLD (REG_RA, REG_SP, 8 * p);} + + /* restore saved registers */ + for (r = savintregcnt - 1; r >= maxsavintreguse; r--) {p--; M_LLD(savintregs[r], REG_SP, 8 * p);} for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--) {p--; M_DLD(savfltregs[r], REG_SP, 8 * p);} + /* deallocate stack */ + if (parentargs_base) {M_LDA(REG_SP, REG_SP, parentargs_base*8);} + + /* call trace function */ + if (runverbose) { M_LDA (REG_SP, REG_SP, -24); - M_LST(REG_RA, REG_SP, 0); + M_AST(REG_RA, REG_SP, 0); M_LST(REG_RESULT, REG_SP, 8); M_DST(REG_FRESULT, REG_SP,16); a = dseg_addaddress (method); - M_LLD(argintregs[0], REG_PV, a); - M_OR(REG_RESULT, REG_RESULT, argintregs[1], 0); + M_ALD(argintregs[0], REG_PV, a); + M_MOV(REG_RESULT, argintregs[1]); M_FLTMOVE(REG_FRESULT, argfltregs[2]); a = dseg_addaddress ((void*) (builtin_displaymethodstop)); - M_LLD(REG_PV, REG_PV, a); + M_ALD(REG_PV, REG_PV, a); M_JSR (REG_RA, REG_PV); s1 = (int)((u1*) mcodeptr - mcodebase); if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1); @@ -2536,18 +3004,22 @@ nowperformreturn: } M_DLD(REG_FRESULT, REG_SP,16); M_LLD(REG_RESULT, REG_SP, 8); - M_LLD(REG_RA, REG_SP, 0); + M_ALD(REG_RA, REG_SP, 0); M_LDA (REG_SP, REG_SP, 24); } + M_RET(REG_ZERO, REG_RA); ALIGNCODENOP; } break; - case ICMD_TABLESWITCH: + case ICMD_TABLESWITCH: /* ..., index ==> ... */ { s4 i, l, *s4ptr; + void **tptr; + + tptr = (void **) iptr->target; s4ptr = iptr->val.a; l = s4ptr[1]; /* low */ @@ -2556,39 +3028,56 @@ nowperformreturn: var_to_reg_int(s1, src, REG_ITMP1); if (l == 0) {M_INTMOVE(s1, REG_ITMP1);} - else + else if (l <= 32768) { M_LDA(REG_ITMP1, s1, -l); + } + else { + ICONST(REG_ITMP2, l); + M_ISUB(s1, REG_ITMP2, REG_ITMP1); + } i = i - l + 1; + /* range check */ + if (i <= 256) - M_CMPULE(REG_ITMP1, i - 1, REG_ITMP2, 1); + M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2); else { M_LDA(REG_ITMP2, REG_ZERO, i - 1); - M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2, 0); + M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2); } M_BEQZ(REG_ITMP2, 0); - mcode_addreference(BlockPtrOfPC(s4ptr[0]), mcodeptr); + + + /* mcode_addreference(BlockPtrOfPC(s4ptr[0]), mcodeptr); */ + mcode_addreference((basicblock *) tptr[0], mcodeptr); /* build jump table top down and use address of lowest entry */ - s4ptr += 3 + i; + /* s4ptr += 3 + i; */ + tptr += i; + while (--i >= 0) { - dseg_addtarget(BlockPtrOfPC(*--s4ptr)); + /* dseg_addtarget(BlockPtrOfPC(*--s4ptr)); */ + dseg_addtarget((basicblock *) tptr[0]); + --tptr; } } /* length of dataseg after last dseg_addtarget is used by load */ - M_S8ADDQ(REG_ITMP1, REG_PV, REG_ITMP2, 0); - M_LLD(REG_ITMP2, REG_ITMP2, -dseglen); + M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2); + M_ALD(REG_ITMP2, REG_ITMP2, -dseglen); M_JMP(REG_ZERO, REG_ITMP2); ALIGNCODENOP; break; - case ICMD_LOOKUPSWITCH: + case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */ { s4 i, l, val, *s4ptr; + void **tptr; + + tptr = (void **) iptr->target; s4ptr = iptr->val.a; l = s4ptr[0]; /* default */ @@ -2598,9 +3087,11 @@ nowperformreturn: var_to_reg_int(s1, src, REG_ITMP1); while (--i >= 0) { s4ptr += 2; + ++tptr; + val = s4ptr[0]; if ((val >= 0) && (val <= 255)) { - M_CMPEQ(s1, val, REG_ITMP2, 1); + M_CMPEQ_IMM(s1, val, REG_ITMP2); } else { if ((val >= -32768) && (val <= 32767)) { @@ -2610,35 +3101,51 @@ nowperformreturn: a = dseg_adds4 (val); M_ILD(REG_ITMP2, REG_PV, a); } - M_CMPEQ(s1, REG_ITMP2, REG_ITMP2, 0); + M_CMPEQ(s1, REG_ITMP2, REG_ITMP2); } M_BNEZ(REG_ITMP2, 0); - mcode_addreference(BlockPtrOfPC(s4ptr[1]), mcodeptr); + /* mcode_addreference(BlockPtrOfPC(s4ptr[1]), mcodeptr); */ + mcode_addreference((basicblock *) tptr[0], mcodeptr); } M_BR(0); - mcode_addreference(BlockPtrOfPC(l), mcodeptr); + /* mcode_addreference(BlockPtrOfPC(l), mcodeptr); */ + + tptr = (void **) iptr->target; + mcode_addreference((basicblock *) tptr[0], mcodeptr); + ALIGNCODENOP; break; } - case ICMD_BUILTIN3: + case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */ + /* op1 = return type, val.a = function pointer*/ s3 = 3; goto gen_method; - case ICMD_BUILTIN2: + case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */ + /* op1 = return type, val.a = function pointer*/ s3 = 2; goto gen_method; - case ICMD_BUILTIN1: + case ICMD_BUILTIN1: /* ..., arg1 ==> ... */ + /* op1 = return type, val.a = function pointer*/ s3 = 1; goto gen_method; - case ICMD_INVOKESTATIC: - case ICMD_INVOKESPECIAL: - case ICMD_INVOKEVIRTUAL: - case ICMD_INVOKEINTERFACE: + case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */ + /* op1 = arg count, val.a = method pointer */ + + case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */ + /* op1 = arg count, val.a = method pointer */ + + case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */ + /* op1 = arg count, val.a = method pointer */ + + case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */ + /* op1 = arg count, val.a = method pointer */ + s3 = iptr->op1; gen_method: { @@ -2647,6 +3154,8 @@ gen_method: { MCODECHECK((s3 << 1) + 64); + /* copy arguments to registers or stack location */ + for (; --s3 >= 0; src = src->prev) { if (src->varkind == ARGVAR) continue; @@ -2680,7 +3189,7 @@ gen_method: { case ICMD_BUILTIN1: a = dseg_addaddress ((void*) (m)); - M_LLD(REG_PV, REG_PV, a); /* Pointer to built-in-function */ + M_ALD(REG_PV, REG_PV, a); /* Pointer to built-in-function */ d = iptr->op1; goto makeactualcall; @@ -2688,7 +3197,7 @@ gen_method: { case ICMD_INVOKESPECIAL: a = dseg_addaddress (m->stubroutine); - M_LLD(REG_PV, REG_PV, a ); /* Method-Pointer in r27 */ + M_ALD(REG_PV, REG_PV, a ); /* method pointer in r27 */ d = m->returntype; goto makeactualcall; @@ -2696,9 +3205,9 @@ gen_method: { case ICMD_INVOKEVIRTUAL: gen_nullptr_check(argintregs[0]); - M_LLD(REG_METHODPTR, argintregs[0], + M_ALD(REG_METHODPTR, argintregs[0], OFFSET(java_objectheader, vftbl)); - M_LLD(REG_PV, REG_METHODPTR, OFFSET(vftbl, table[0]) + + M_ALD(REG_PV, REG_METHODPTR, OFFSET(vftbl, table[0]) + sizeof(methodptr) * m->vftblindex); d = m->returntype; @@ -2708,12 +3217,12 @@ gen_method: { ci = m->class; gen_nullptr_check(argintregs[0]); - M_LLD(REG_METHODPTR, argintregs[0], + M_ALD(REG_METHODPTR, argintregs[0], OFFSET(java_objectheader, vftbl)); - M_LLD(REG_METHODPTR, REG_METHODPTR, + M_ALD(REG_METHODPTR, REG_METHODPTR, OFFSET(vftbl, interfacetable[0]) - sizeof(methodptr*) * ci->index); - M_LLD(REG_PV, REG_METHODPTR, + M_ALD(REG_PV, REG_METHODPTR, sizeof(methodptr) * (m - ci->methods)); d = m->returntype; @@ -2728,6 +3237,9 @@ gen_method: { makeactualcall: M_JSR (REG_RA, REG_PV); + + /* recompute pv */ + s1 = (int)((u1*) mcodeptr - mcodebase); if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1); else { @@ -2737,6 +3249,8 @@ makeactualcall: M_LDAH (REG_PV, REG_PV, mh ); } + /* d contains return type */ + if (d != TYPE_VOID) { if (IS_INT_LNG_TYPE(iptr->dst->type)) { s1 = reg_of_var(iptr->dst, REG_RESULT); @@ -2791,7 +3305,7 @@ makeactualcall: M_ALD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*)); - M_CMPULT(REG_ZERO, REG_ITMP1, d, 0); /* REG_ITMP1 != 0 */ + M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */ } else { /* class */ s2 = super->vftbl->diffval; @@ -2800,10 +3314,10 @@ makeactualcall: M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval)); M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval); if (s2 <= 255) - M_CMPULE(REG_ITMP1, s2, d, 1); + M_CMPULE_IMM(REG_ITMP1, s2, d); else { M_LDA(REG_ITMP2, REG_ZERO, s2); - M_CMPULE(REG_ITMP1, REG_ITMP2, d, 0); + M_CMPULE(REG_ITMP1, REG_ITMP2, d); } } } @@ -2860,12 +3374,12 @@ makeactualcall: M_BNEZ(REG_ITMP1, 0); } else if (s2 <= 255) { - M_CMPULE(REG_ITMP1, s2, REG_ITMP2, 1); + M_CMPULE_IMM(REG_ITMP1, s2, REG_ITMP2); M_BEQZ(REG_ITMP2, 0); } else { M_LDA(REG_ITMP2, REG_ZERO, s2); - M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2, 0); + M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2); M_BEQZ(REG_ITMP2, 0); } mcode_addxcastrefs(mcodeptr); @@ -2878,13 +3392,15 @@ makeactualcall: store_reg_to_var_int(iptr->dst, d); break; - case ICMD_CHECKASIZE: + case ICMD_CHECKASIZE: /* ..., size ==> ..., size */ + var_to_reg_int(s1, src, REG_ITMP1); M_BLTZ(s1, 0); mcode_addxcheckarefs(mcodeptr); break; - case ICMD_MULTIANEWARRAY: + case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */ + /* op1 = dimension, val.a = array descriptor */ /* check for negative sizes and copy sizes to stack if necessary */ @@ -2904,19 +3420,19 @@ makeactualcall: /* a0 = dimension count */ - M_LDA(argintregs[0], REG_ZERO, iptr->op1); + ICONST(argintregs[0], iptr->op1); /* a1 = arraydescriptor */ a = dseg_addaddress(iptr->val.a); - M_LLD(argintregs[1], REG_PV, a); + M_ALD(argintregs[1], REG_PV, a); /* a2 = pointer to dimensions = stack pointer */ M_INTMOVE(REG_SP, argintregs[2]); a = dseg_addaddress((void*) (builtin_nmultianewarray)); - M_LLD(REG_PV, REG_PV, a); + M_ALD(REG_PV, REG_PV, a); M_JSR(REG_RA, REG_PV); s1 = (int)((u1*) mcodeptr - mcodebase); if (s1 <= 32768) @@ -2926,7 +3442,7 @@ makeactualcall: while (ml < -32768) {ml += 65536; mh--;} M_LDA(REG_PV, REG_RA, ml); M_LDAH(REG_PV, REG_PV, mh); - } + } s1 = reg_of_var(iptr->dst, REG_RESULT); M_INTMOVE(REG_RESULT, s1); store_reg_to_var_int(iptr->dst, s1); @@ -2935,8 +3451,15 @@ makeactualcall: default: sprintf (logtext, "Unknown pseudo command: %d", iptr->opc); error(); + + + } /* switch */ + } /* for instruction */ + + /* copy values to interface registers */ + src = bptr->outstack; len = bptr->outdepth; MCODECHECK(64+len); @@ -2968,9 +3491,11 @@ makeactualcall: } /* if (bptr -> flags >= BBREACHED) */ } /* for basic block */ - bptr -> mpc = (int)((u1*) mcodeptr - mcodebase); + /* bptr -> mpc = (int)((u1*) mcodeptr - mcodebase); */ { + /* generate bound check stubs */ + s4 *xcodeptr = NULL; for (; xboundrefs != NULL; xboundrefs = xboundrefs->next) { @@ -2980,12 +3505,13 @@ makeactualcall: continue; } + gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos, xboundrefs->branchpos, (u1*) mcodeptr - mcodebase); MCODECHECK(8); - M_LDA(REG_ITMP2_XPC, REG_PV, xboundrefs->branchpos); + M_LDA(REG_ITMP2_XPC, REG_PV, xboundrefs->branchpos - 4); if (xcodeptr != NULL) { M_BR((xcodeptr-mcodeptr)-1); @@ -2994,15 +3520,17 @@ makeactualcall: xcodeptr = mcodeptr; a = dseg_addaddress(proto_java_lang_ArrayIndexOutOfBoundsException); - M_LLD(REG_ITMP1_XPTR, REG_PV, a); + M_ALD(REG_ITMP1_XPTR, REG_PV, a); a = dseg_addaddress(asm_handle_exception); - M_LLD(REG_ITMP3, REG_PV, a); + M_ALD(REG_ITMP3, REG_PV, a); M_JMP(REG_ZERO, REG_ITMP3); } } + /* generate negative array size check stubs */ + xcodeptr = NULL; for (; xcheckarefs != NULL; xcheckarefs = xcheckarefs->next) { @@ -3017,7 +3545,7 @@ makeactualcall: MCODECHECK(8); - M_LDA(REG_ITMP2_XPC, REG_PV, xcheckarefs->branchpos); + M_LDA(REG_ITMP2_XPC, REG_PV, xcheckarefs->branchpos - 4); if (xcodeptr != NULL) { M_BR((xcodeptr-mcodeptr)-1); @@ -3026,15 +3554,17 @@ makeactualcall: xcodeptr = mcodeptr; a = dseg_addaddress(proto_java_lang_NegativeArraySizeException); - M_LLD(REG_ITMP1_XPTR, REG_PV, a); + M_ALD(REG_ITMP1_XPTR, REG_PV, a); a = dseg_addaddress(asm_handle_exception); - M_LLD(REG_ITMP3, REG_PV, a); + M_ALD(REG_ITMP3, REG_PV, a); M_JMP(REG_ZERO, REG_ITMP3); } } + /* generate cast check stubs */ + xcodeptr = NULL; for (; xcastrefs != NULL; xcastrefs = xcastrefs->next) { @@ -3049,7 +3579,7 @@ makeactualcall: MCODECHECK(8); - M_LDA(REG_ITMP2_XPC, REG_PV, xcastrefs->branchpos); + M_LDA(REG_ITMP2_XPC, REG_PV, xcastrefs->branchpos - 4); if (xcodeptr != NULL) { M_BR((xcodeptr-mcodeptr)-1); @@ -3058,10 +3588,10 @@ makeactualcall: xcodeptr = mcodeptr; a = dseg_addaddress(proto_java_lang_ClassCastException); - M_LLD(REG_ITMP1_XPTR, REG_PV, a); + M_ALD(REG_ITMP1_XPTR, REG_PV, a); a = dseg_addaddress(asm_handle_exception); - M_LLD(REG_ITMP3, REG_PV, a); + M_ALD(REG_ITMP3, REG_PV, a); M_JMP(REG_ZERO, REG_ITMP3); } @@ -3070,6 +3600,8 @@ makeactualcall: #ifdef SOFTNULLPTRCHECK + /* generate null pointer check stubs */ + xcodeptr = NULL; for (; xnullrefs != NULL; xnullrefs = xnullrefs->next) { @@ -3093,10 +3625,10 @@ makeactualcall: xcodeptr = mcodeptr; a = dseg_addaddress(proto_java_lang_NullPointerException); - M_LLD(REG_ITMP1_XPTR, REG_PV, a); + M_ALD(REG_ITMP1_XPTR, REG_PV, a); a = dseg_addaddress(asm_handle_exception); - M_LLD(REG_ITMP3, REG_PV, a); + M_ALD(REG_ITMP3, REG_PV, a); M_JMP(REG_ZERO, REG_ITMP3); } @@ -3138,8 +3670,6 @@ This makes sense only for the stub-generation-routines below. *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<16)|((disp)&0xffff) ) -#if 0 - /* function createcompilerstub ************************************************* creates a stub routine which calls the compiler @@ -3154,7 +3684,7 @@ u1 *createcompilerstub (methodinfo *m) s4 *p = (s4*) s; /* code generation pointer */ /* code for the stub */ - M_LLD (REG_PV, REG_PV, 16); /* load pointer to the compiler */ + M_ALD (REG_PV, REG_PV, 16); /* load pointer to the compiler */ M_JMP (0, REG_PV); /* jump to the compiler, return address in reg 0 is used as method pointer */ s[1] = (u8) m; /* literals to be adressed */ @@ -3180,21 +3710,7 @@ void removecompilerstub (u1 *stub) } -/* function: removenativestub ************************************************** - - removes a previously created native-stub from memory - -*******************************************************************************/ - -void removenativestub (u1 *stub) -{ - CFREE (stub, NATIVESTUBSIZE * 8); -} - -#endif /* 0 */ - - -/* function: ncreatenativestub ************************************************* +/* function: createnativestub ************************************************** creates a stub routine which calls a native method @@ -3202,32 +3718,32 @@ void removenativestub (u1 *stub) #define NATIVESTUBSIZE 11 -u1 *ncreatenativestub (functionptr f, methodinfo *m) +u1 *createnativestub (functionptr f, methodinfo *m) { u8 *s = CNEW (u8, NATIVESTUBSIZE); /* memory to hold the stub */ s4 *p = (s4*) s; /* code generation pointer */ M_LDA (REG_SP, REG_SP, -8); /* build up stackframe */ - M_LST (REG_RA, REG_SP, 0); /* store return address */ + M_AST (REG_RA, REG_SP, 0); /* store return address */ - M_LLD (REG_PV, REG_PV, 8*8); /* load adress of native method */ + M_ALD (REG_PV, REG_PV, 8*8); /* load adress of native method */ M_JSR (REG_RA, REG_PV); /* call native method */ M_LDA (REG_PV, REG_RA, -4*4); /* recompute pv from ra */ - M_LLD (REG_ITMP3, REG_PV, 9*8); /* get address of exceptionptr */ + M_ALD (REG_ITMP3, REG_PV, 9*8); /* get address of exceptionptr */ - M_LLD (REG_RA, REG_SP, 0); /* load return address */ - M_LLD (REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */ + M_ALD (REG_RA, REG_SP, 0); /* load return address */ + M_ALD (REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */ M_LDA (REG_SP, REG_SP, 8); /* remove stackframe */ M_BNEZ (REG_ITMP1, 1); /* if no exception then return */ M_RET (REG_ZERO, REG_RA); /* return to caller */ - M_LST (REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */ + M_AST (REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */ M_LDA (REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */ - M_LLD (REG_ITMP3, REG_PV,10*8); /* load asm exception handler address */ + M_ALD (REG_ITMP3, REG_PV,10*8); /* load asm exception handler address */ M_JMP (REG_ZERO, REG_ITMP3); /* jump to asm exception handler */ @@ -3243,6 +3759,18 @@ u1 *ncreatenativestub (functionptr f, methodinfo *m) } +/* function: removenativestub ************************************************** + + removes a previously created native-stub from memory + +*******************************************************************************/ + +void removenativestub (u1 *stub) +{ + CFREE (stub, NATIVESTUBSIZE * 8); +} + + /* * These are local overrides for various environment variables in Emacs. * Please do not remove this and leave it at the end of the file, where