1 /* alpha/ngen.c ****************************************************************
3 Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
5 See file COPYRIGHT for information on usage and disclaimer of warranties
7 Contains the codegenerator for an Alpha processor.
8 This module generates Alpha machine code for a sequence of
9 pseudo commands (ICMDs).
11 Authors: Andreas Krall EMAIL: cacao@complang.tuwien.ac.at
12 Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at
14 Last Change: 1998/08/10
16 *******************************************************************************/
20 /* *****************************************************************************
22 Datatypes and Register Allocations:
23 -----------------------------------
25 On 64-bit-machines (like the Alpha) all operands are stored in the
26 registers in a 64-bit form, even when the correspondig JavaVM operands
27 only need 32 bits. This is done by a canonical representation:
29 32-bit integers are allways stored as sign-extended 64-bit values (this
30 approach is directly supported by the Alpha architecture and is very easy
33 32-bit-floats are stored in a 64-bit doubleprecision register by simply
34 expanding the exponent and mantissa with zeroes. (also supported by the
40 The calling conventions and the layout of the stack is explained in detail
41 in the documention file: calling.doc
43 *******************************************************************************/
46 /* additional functions and macros to generate code ***************************/
48 #define BlockPtrOfPC(pc) block+block_index[pc]
51 #define COUNT_SPILLS count_spills++
57 /* gen_nullptr_check(objreg) */
59 #ifdef SOFTNULLPTRCHECK
60 #define gen_nullptr_check(objreg) \
62 M_BEQZ((objreg), REG);\
63 mcode_addxnullrefs(mcodeptr);\
66 #define gen_nullptr_check(objreg)
70 /* MCODECHECK(icnt) */
72 #define MCODECHECK(icnt) \
73 if((mcodeptr+(icnt))>mcodeend)mcodeptr=mcode_increase((u1*)mcodeptr)
76 generates an integer-move from register a to b.
77 if a and b are the same int-register, no code will be generated.
80 #define M_INTMOVE(a,b) if(a!=b){M_MOV(a,b);}
84 generates a floating-point-move from register a to b.
85 if a and b are the same float-register, no code will be generated
88 #define M_FLTMOVE(a,b) if(a!=b){M_FMOV(a,b);}
92 this function generates code to fetch data from a pseudo-register
94 If the pseudo-register has actually been assigned to a real
95 register, no code will be emitted, since following operations
96 can use this register directly.
98 v: pseudoregister to be fetched from
99 tempregnum: temporary register to be used if v is actually spilled to ram
101 return: the register number, where the operand can be found after
102 fetching (this wil be either tempregnum or the register
103 number allready given to v)
106 #define var_to_reg_int(regnr,v,tempnr) { \
107 if ((v)->flags & INMEMORY) \
108 {COUNT_SPILLS;M_LLD(tempnr,REG_SP,8*(v)->regoff);regnr=tempnr;} \
109 else regnr=(v)->regoff; \
113 #define var_to_reg_flt(regnr,v,tempnr) { \
114 if ((v)->flags & INMEMORY) \
115 {COUNT_SPILLS;M_DLD(tempnr,REG_SP,8*(v)->regoff);regnr=tempnr;} \
116 else regnr=(v)->regoff; \
121 This function determines a register, to which the result of an operation
122 should go, when it is ultimatively intended to store the result in
124 If v is assigned to an actual register, this register will be returned.
125 Otherwise (when v is spilled) this function returns tempregnum.
126 If not already done, regoff and flags are set in the stack location.
129 static int reg_of_var(stackptr v, int tempregnum)
133 switch (v->varkind) {
135 if (!(v->flags & INMEMORY))
139 var = &(interfaces[v->varnum][v->type]);
140 v->regoff = var->regoff;
141 if (!(var->flags & INMEMORY))
145 var = &(locals[v->varnum][v->type]);
146 v->regoff = var->regoff;
147 if (!(var->flags & INMEMORY))
151 v->regoff = v->varnum;
152 if (IS_FLT_DBL_TYPE(v->type)) {
153 if (v->varnum < fltreg_argnum) {
154 v->regoff = argfltregs[v->varnum];
155 return(argfltregs[v->varnum]);
159 if (v->varnum < intreg_argnum) {
160 v->regoff = argintregs[v->varnum];
161 return(argintregs[v->varnum]);
163 v->regoff -= intreg_argnum;
166 v->flags |= INMEMORY;
171 /* store_reg_to_var_xxx:
172 This function generates the code to store the result of an operation
173 back into a spilled pseudo-variable.
174 If the pseudo-variable has not been spilled in the first place, this
175 function will generate nothing.
177 v ............ Pseudovariable
178 tempregnum ... Number of the temporary registers as returned by
182 #define store_reg_to_var_int(sptr, tempregnum) { \
183 if ((sptr)->flags & INMEMORY) { \
185 M_LST(tempregnum, REG_SP, 8 * (sptr)->regoff); \
189 #define store_reg_to_var_flt(sptr, tempregnum) { \
190 if ((sptr)->flags & INMEMORY) { \
192 M_DST(tempregnum, REG_SP, 8 * (sptr)->regoff); \
197 /* NullPointerException handlers and exception handling initialisation */
199 typedef struct sigctx_struct {
201 long sc_onstack; /* sigstack state to restore */
202 long sc_mask; /* signal mask to restore */
203 long sc_pc; /* pc at time of signal */
204 long sc_ps; /* psl to retore */
205 long sc_regs[32]; /* processor regs 0 to 31 */
206 long sc_ownedfp; /* fp has been used */
207 long sc_fpregs[32]; /* fp regs 0 to 31 */
208 unsigned long sc_fpcr; /* floating point control register */
209 unsigned long sc_fp_control; /* software fpcr */
211 unsigned long sc_reserved1, sc_reserved2;
212 unsigned long sc_ssize;
214 unsigned long sc_traparg_a0;
215 unsigned long sc_traparg_a1;
216 unsigned long sc_traparg_a2;
217 unsigned long sc_fp_trap_pc;
218 unsigned long sc_fp_trigger_sum;
219 unsigned long sc_fp_trigger_inst;
220 unsigned long sc_retcode[2];
224 /* asm_signal_exception passes exception pointer and the signal context
225 structure (contains the saved registers) to the assembler handler which
226 restores registers and walks through the Java exception tables.
229 void asm_signal_exception(void *xptr, void *sigctx);
232 /* NullPointerException signal handler for hardware null pointer check */
234 void catch_NullPointerException(int sig, int code, sigctx_struct *sigctx)
240 /* Reset signal handler - necessary for SysV, does no harm for BSD */
242 instr = *((int*)(sigctx->sc_pc));
243 faultaddr = sigctx->sc_regs[(instr >> 16) & 0x1f];
245 if (faultaddr == 0) {
246 signal(sig, (void*) catch_NullPointerException); /* reinstall handler */
248 sigaddset(&nsig, sig);
249 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
250 asm_signal_exception(proto_java_lang_NullPointerException, sigctx);
253 faultaddr += (long) ((instr << 16) >> 16);
254 fprintf(stderr, "faulting address: 0x%16lx\n", faultaddr);
255 panic("Stack overflow");
262 void init_exceptions(void)
267 /* Linux on Digital Alpha needs an initialisation of the ieee floating point
268 control for IEEE compliant arithmetic (option -mieee of GCC). Under
269 Digital Unix this is done automatically.
274 extern unsigned long ieee_get_fp_control();
275 extern void ieee_set_fp_control(unsigned long fp_control);
277 void init_exceptions(void)
279 /* initialize floating point control */
281 ieee_set_fp_control(ieee_get_fp_control()
282 & ~IEEE_TRAP_ENABLE_INV
283 & ~IEEE_TRAP_ENABLE_DZE
284 /* & ~IEEE_TRAP_ENABLE_UNF we dont want underflow */
285 & ~IEEE_TRAP_ENABLE_OVF);
288 /* install signal handlers we need to convert to exceptions */
293 signal(SIGSEGV, (void*) catch_NullPointerException);
297 signal(SIGBUS, (void*) catch_NullPointerException);
303 /* function gen_mcode **********************************************************
305 generates machine code
307 *******************************************************************************/
309 #define MethodPointer -8
310 #define FrameSize -12
315 #define ExTableSize -32
316 #define ExTableStart -32
318 #define ExEntrySize -32
321 #define ExHandlerPC -24
322 #define ExCatchType -32
324 static void gen_mcode()
326 int len, s1, s2, s3, d, bbs;
337 savedregs_num = (isleafmethod) ? 0 : 1; /* space to save the RA */
339 /* space to save used callee saved registers */
341 savedregs_num += (savintregcnt - maxsavintreguse);
342 savedregs_num += (savfltregcnt - maxsavfltreguse);
344 parentargs_base = maxmemuse + savedregs_num;
346 #ifdef USE_THREADS /* space to save argument of monitor_enter */
348 if (checksync && (method->flags & ACC_SYNCHRONIZED))
353 /* create method header */
355 (void) dseg_addaddress(method); /* MethodPointer */
356 (void) dseg_adds4(parentargs_base * 8); /* FrameSize */
360 /* IsSync contains the offset relative to the stack pointer for the
361 argument of monitor_exit used in the exception handler. Since the
362 offset could be zero and give a wrong meaning of the flag it is
366 if (checksync && (method->flags & ACC_SYNCHRONIZED))
367 (void) dseg_adds4((maxmemuse + 1) * 8); /* IsSync */
372 (void) dseg_adds4(0); /* IsSync */
374 (void) dseg_adds4(isleafmethod); /* IsLeaf */
375 (void) dseg_adds4(savintregcnt - maxsavintreguse); /* IntSave */
376 (void) dseg_adds4(savfltregcnt - maxsavfltreguse); /* FltSave */
377 (void) dseg_adds4(exceptiontablelength); /* ExTableSize */
379 /* create exception table */
381 for (len = 0; len < exceptiontablelength; len++) {
382 dseg_addtarget(BlockPtrOfPC(extable[len].startpc));
383 dseg_addtarget(BlockPtrOfPC(extable[len].endpc));
384 dseg_addtarget(BlockPtrOfPC(extable[len].handlerpc));
385 (void) dseg_addaddress(extable[len].catchtype);
388 /* initialize mcode variables */
390 mcodeptr = (s4*) mcodebase;
391 mcodeend = (s4*) (mcodebase + mcodesize);
392 MCODECHECK(128 + mparamcount);
394 /* create stack frame (if necessary) */
397 {M_LDA (REG_SP, REG_SP, -parentargs_base * 8);}
399 /* save return address and used callee saved registers */
403 {p--; M_AST (REG_RA, REG_SP, 8*p);}
404 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
405 {p--; M_LST (savintregs[r], REG_SP, 8 * p);}
406 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
407 {p--; M_DST (savfltregs[r], REG_SP, 8 * p);}
409 /* save monitorenter argument */
412 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
413 if (method->flags & ACC_STATIC) {
414 p = dseg_addaddress (class);
415 M_ALD(REG_ITMP1, REG_PV, p);
416 M_AST(REG_ITMP1, REG_SP, 8 * maxmemuse);
419 M_AST (argintregs[0], REG_SP, 8 * maxmemuse);
424 /* copy argument registers to stack and call trace function with pointer
425 to arguments on stack. ToDo: save floating point registers !!!!!!!!!
428 if (runverbose && isleafmethod) {
429 M_LDA (REG_SP, REG_SP, -(8*8));
430 M_AST(REG_RA, REG_SP, 1*8);
431 M_LST(argintregs[0], REG_SP, 2*8);
432 M_LST(argintregs[1], REG_SP, 3*8);
433 M_LST(argintregs[2], REG_SP, 4*8);
434 M_LST(argintregs[3], REG_SP, 5*8);
435 M_LST(argintregs[4], REG_SP, 6*8);
436 M_LST(argintregs[5], REG_SP, 7*8);
437 p = dseg_addaddress (method);
438 M_ALD(REG_ITMP1, REG_PV, p);
439 M_AST(REG_ITMP1, REG_SP, REG);
440 p = dseg_addaddress ((void*) (builtin_trace_args));
441 M_ALD(REG_PV, REG_PV, p);
442 M_JSR(REG_RA, REG_PV);
443 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
444 M_ALD(REG_RA, REG_SP, 1*8);
445 M_LLD(argintregs[0], REG_SP, 2*8);
446 M_LLD(argintregs[1], REG_SP, 3*8);
447 M_LLD(argintregs[2], REG_SP, 4*8);
448 M_LLD(argintregs[3], REG_SP, 5*8);
449 M_LLD(argintregs[4], REG_SP, 6*8);
450 M_LLD(argintregs[5], REG_SP, 7*8);
451 M_LDA (REG_SP, REG_SP, 8*8);
454 /* take arguments out of register or stack frame */
456 for (p = 0, l = 0; p < mparamcount; p++) {
458 var = &(locals[l][t]);
460 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
465 if (IS_INT_LNG_TYPE(t)) { /* integer args */
466 if (p < INT_ARG_CNT) { /* register arguments */
467 if (!(var->flags & INMEMORY)) /* reg arg -> register */
468 {M_INTMOVE (argintregs[p], r);}
469 else /* reg arg -> spilled */
470 M_LST (argintregs[p], REG_SP, 8 * r);
472 else { /* stack arguments */
473 pa = p - INT_ARG_CNT;
474 if (!(var->flags & INMEMORY)) /* stack arg -> register */
475 M_LLD (r, REG_SP, 8 * (parentargs_base + pa));
476 else { /* stack arg -> spilled */
477 M_LLD (REG_ITMP1, REG_SP, 8 * (parentargs_base + pa));
478 M_LST (REG_ITMP1, REG_SP, 8 * r);
482 else { /* floating args */
483 if (p < FLT_ARG_CNT) { /* register arguments */
484 if (!(var->flags & INMEMORY)) /* reg arg -> register */
485 {M_FLTMOVE (argfltregs[p], r);}
486 else /* reg arg -> spilled */
487 M_DST (argfltregs[p], REG_SP, 8 * r);
489 else { /* stack arguments */
490 pa = p - FLT_ARG_CNT;
491 if (!(var->flags & INMEMORY)) /* stack-arg -> register */
492 M_DLD (r, REG_SP, 8 * (parentargs_base + pa) );
493 else { /* stack-arg -> spilled */
494 M_DLD (REG_FTMP1, REG_SP, 8 * (parentargs_base + pa));
495 M_DST (REG_FTMP1, REG_SP, 8 * r);
501 /* call trace function */
503 if (runverbose && !isleafmethod) {
504 M_LDA (REG_SP, REG_SP, -8);
505 p = dseg_addaddress (method);
506 M_ALD(REG_ITMP1, REG_PV, p);
507 M_AST(REG_ITMP1, REG_SP, REG);
508 p = dseg_addaddress ((void*) (builtin_trace_args));
509 M_ALD(REG_PV, REG_PV, p);
510 M_JSR(REG_RA, REG_PV);
511 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
512 M_LDA(REG_SP, REG_SP, 8);
515 /* call monitorenter function */
518 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
519 p = dseg_addaddress ((void*) (builtin_monitorenter));
520 M_ALD(REG_PV, REG_PV, p);
521 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
522 M_JSR(REG_RA, REG_PV);
523 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
528 /* end of header generation */
530 /* walk through all basic blocks */
532 for (bbs = block_count, bptr = block; --bbs >= 0; bptr++) {
533 bptr -> mpc = (int)((u1*) mcodeptr - mcodebase);
535 if (bptr->flags >= BBREACHED) {
537 /* branch resolving */
541 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
542 gen_resolvebranch((u1*) mcodebase + brefs->branchpos,
543 brefs->branchpos, bptr->mpc);
547 /* copy interface registers to their destination */
552 while (src != NULL) {
554 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
555 d = reg_of_var(src, REG_ITMP1);
556 M_INTMOVE(REG_ITMP1, d);
557 store_reg_to_var_int(src, d);
560 d = reg_of_var(src, REG_IFTMP);
561 if ((src->varkind != STACKVAR)) {
563 if (IS_FLT_DBL_TYPE(s2)) {
564 if (!(interfaces[len][s2].flags & INMEMORY)) {
565 s1 = interfaces[len][s2].regoff;
569 M_DLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
571 store_reg_to_var_flt(src, d);
574 if (!(interfaces[len][s2].flags & INMEMORY)) {
575 s1 = interfaces[len][s2].regoff;
579 M_LLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
581 store_reg_to_var_int(src, d);
588 /* walk through all instructions */
592 for (iptr = bptr->iinstr;
594 src = iptr->dst, len--, iptr++) {
596 MCODECHECK(64); /* an instruction usually needs < 64 words */
599 case ICMD_NOP: /* ... ==> ... */
602 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
604 var_to_reg_int(s1, src, REG_ITMP1);
606 mcode_addxnullrefs(mcodeptr);
609 /* constant operations ************************************************/
611 #define ICONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
612 else{a=dseg_adds4(c);M_ILD(r,REG_PV,a);}
614 #define LCONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
615 else{a=dseg_adds8(c);M_LLD(r,REG_PV,a);}
617 case ICMD_ICONST: /* ... ==> ..., constant */
618 /* op1 = 0, val.i = constant */
620 d = reg_of_var(iptr->dst, REG_ITMP1);
621 ICONST(d, iptr->val.i);
622 store_reg_to_var_int(iptr->dst, d);
625 case ICMD_LCONST: /* ... ==> ..., constant */
626 /* op1 = 0, val.l = constant */
628 d = reg_of_var(iptr->dst, REG_ITMP1);
629 LCONST(d, iptr->val.l);
630 store_reg_to_var_int(iptr->dst, d);
633 case ICMD_FCONST: /* ... ==> ..., constant */
634 /* op1 = 0, val.f = constant */
636 d = reg_of_var (iptr->dst, REG_FTMP1);
637 a = dseg_addfloat (iptr->val.f);
639 store_reg_to_var_flt (iptr->dst, d);
642 case ICMD_DCONST: /* ... ==> ..., constant */
643 /* op1 = 0, val.d = constant */
645 d = reg_of_var (iptr->dst, REG_FTMP1);
646 a = dseg_adddouble (iptr->val.d);
648 store_reg_to_var_flt (iptr->dst, d);
651 case ICMD_ACONST: /* ... ==> ..., constant */
652 /* op1 = 0, val.a = constant */
654 d = reg_of_var(iptr->dst, REG_ITMP1);
656 a = dseg_addaddress (iptr->val.a);
660 M_INTMOVE(REG_ZERO, d);
662 store_reg_to_var_int(iptr->dst, d);
666 /* load/store operations **********************************************/
668 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
669 case ICMD_LLOAD: /* op1 = local variable */
672 d = reg_of_var(iptr->dst, REG_ITMP1);
673 if ((iptr->dst->varkind == LOCALVAR) &&
674 (iptr->dst->varnum == iptr->op1))
676 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
677 if (var->flags & INMEMORY)
678 M_LLD(d, REG_SP, 8 * var->regoff);
680 {M_INTMOVE(var->regoff,d);}
681 store_reg_to_var_int(iptr->dst, d);
684 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
685 case ICMD_DLOAD: /* op1 = local variable */
687 d = reg_of_var(iptr->dst, REG_FTMP1);
688 if ((iptr->dst->varkind == LOCALVAR) &&
689 (iptr->dst->varnum == iptr->op1))
691 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
692 if (var->flags & INMEMORY)
693 M_DLD(d, REG_SP, 8 * var->regoff);
695 {M_FLTMOVE(var->regoff,d);}
696 store_reg_to_var_flt(iptr->dst, d);
700 case ICMD_ISTORE: /* ..., value ==> ... */
701 case ICMD_LSTORE: /* op1 = local variable */
704 if ((src->varkind == LOCALVAR) &&
705 (src->varnum == iptr->op1))
707 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
708 if (var->flags & INMEMORY) {
709 var_to_reg_int(s1, src, REG_ITMP1);
710 M_LST(s1, REG_SP, 8 * var->regoff);
713 var_to_reg_int(s1, src, var->regoff);
714 M_INTMOVE(s1, var->regoff);
718 case ICMD_FSTORE: /* ..., value ==> ... */
719 case ICMD_DSTORE: /* op1 = local variable */
721 if ((src->varkind == LOCALVAR) &&
722 (src->varnum == iptr->op1))
724 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
725 if (var->flags & INMEMORY) {
726 var_to_reg_flt(s1, src, REG_FTMP1);
727 M_DST(s1, REG_SP, 8 * var->regoff);
730 var_to_reg_flt(s1, src, var->regoff);
731 M_FLTMOVE(s1, var->regoff);
736 /* pop/dup/swap operations ********************************************/
738 /* attention: double and longs are only one entry in CACAO ICMDs */
740 case ICMD_POP: /* ..., value ==> ... */
741 case ICMD_POP2: /* ..., value, value ==> ... */
744 #define M_COPY(from,to) \
745 d = reg_of_var(to, REG_IFTMP); \
746 if ((from->regoff != to->regoff) || \
747 ((from->flags ^ to->flags) & INMEMORY)) { \
748 if (IS_FLT_DBL_TYPE(from->type)) { \
749 var_to_reg_flt(s1, from, d); \
751 store_reg_to_var_flt(to, d); \
754 var_to_reg_int(s1, from, d); \
756 store_reg_to_var_int(to, d); \
760 case ICMD_DUP: /* ..., a ==> ..., a, a */
761 M_COPY(src, iptr->dst);
764 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
766 M_COPY(src, iptr->dst->prev->prev);
768 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
770 M_COPY(src, iptr->dst);
771 M_COPY(src->prev, iptr->dst->prev);
774 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
776 M_COPY(src->prev, iptr->dst->prev->prev->prev);
778 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
780 M_COPY(src, iptr->dst);
781 M_COPY(src->prev, iptr->dst->prev);
782 M_COPY(src->prev->prev, iptr->dst->prev->prev);
783 M_COPY(src, iptr->dst->prev->prev->prev);
786 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
788 M_COPY(src, iptr->dst);
789 M_COPY(src->prev, iptr->dst->prev);
790 M_COPY(src->prev->prev, iptr->dst->prev->prev);
791 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
792 M_COPY(src, iptr->dst->prev->prev->prev->prev);
793 M_COPY(src->prev, iptr->dst->prev->prev->prev->prev->prev);
796 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
798 M_COPY(src, iptr->dst->prev);
799 M_COPY(src->prev, iptr->dst);
803 /* integer operations *************************************************/
805 case ICMD_INEG: /* ..., value ==> ..., - value */
807 var_to_reg_int(s1, src, REG_ITMP1);
808 d = reg_of_var(iptr->dst, REG_ITMP3);
809 M_ISUB(REG_ZERO, s1, d, REG);
810 store_reg_to_var_int(iptr->dst, d);
813 case ICMD_LNEG: /* ..., value ==> ..., - value */
815 var_to_reg_int(s1, src, REG_ITMP1);
816 d = reg_of_var(iptr->dst, REG_ITMP3);
817 M_LSUB(REG_ZERO, s1, d, REG);
818 store_reg_to_var_int(iptr->dst, d);
821 case ICMD_I2L: /* ..., value ==> ..., value */
823 var_to_reg_int(s1, src, REG_ITMP1);
824 d = reg_of_var(iptr->dst, REG_ITMP3);
826 store_reg_to_var_int(iptr->dst, d);
829 case ICMD_L2I: /* ..., value ==> ..., value */
831 var_to_reg_int(s1, src, REG_ITMP1);
832 d = reg_of_var(iptr->dst, REG_ITMP3);
833 M_IADD(s1, REG_ZERO, d , REG);
834 store_reg_to_var_int(iptr->dst, d);
837 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
839 var_to_reg_int(s1, src, REG_ITMP1);
840 d = reg_of_var(iptr->dst, REG_ITMP3);
841 if (has_ext_instr_set) {
845 M_SLL(s1, 56, d, CONST);
846 M_SRA( d, 56, d, CONST);
848 store_reg_to_var_int(iptr->dst, d);
851 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
853 var_to_reg_int(s1, src, REG_ITMP1);
854 d = reg_of_var(iptr->dst, REG_ITMP3);
856 store_reg_to_var_int(iptr->dst, d);
859 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
861 var_to_reg_int(s1, src, REG_ITMP1);
862 d = reg_of_var(iptr->dst, REG_ITMP3);
863 if (has_ext_instr_set) {
867 M_SLL(s1, 48, d, CONST);
868 M_SRA( d, 48, d, CONST);
870 store_reg_to_var_int(iptr->dst, d);
874 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
876 var_to_reg_int(s1, src->prev, REG_ITMP1);
877 var_to_reg_int(s2, src, REG_ITMP2);
878 d = reg_of_var(iptr->dst, REG_ITMP3);
879 M_IADD(s1, s2, d, 0);
880 store_reg_to_var_int(iptr->dst, d);
883 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
884 /* val.i = constant */
886 var_to_reg_int(s1, src, REG_ITMP1);
887 d = reg_of_var(iptr->dst, REG_ITMP3);
888 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
889 M_IADD(s1, iptr->val.i, d, CONST);
892 ICONST(REG_ITMP2, iptr->val.i);
893 M_IADD(s1, REG_ITMP2, d, REG);
895 store_reg_to_var_int(iptr->dst, d);
898 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
900 var_to_reg_int(s1, src->prev, REG_ITMP1);
901 var_to_reg_int(s2, src, REG_ITMP2);
902 d = reg_of_var(iptr->dst, REG_ITMP3);
903 M_LADD(s1, s2, d, 0);
904 store_reg_to_var_int(iptr->dst, d);
907 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
908 /* val.l = constant */
910 var_to_reg_int(s1, src, REG_ITMP1);
911 d = reg_of_var(iptr->dst, REG_ITMP3);
912 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
913 M_LADD(s1, iptr->val.l, d, CONST);
916 LCONST(REG_ITMP2, iptr->val.l);
917 M_LADD(s1, REG_ITMP2, d, REG);
919 store_reg_to_var_int(iptr->dst, d);
922 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
924 var_to_reg_int(s1, src->prev, REG_ITMP1);
925 var_to_reg_int(s2, src, REG_ITMP2);
926 d = reg_of_var(iptr->dst, REG_ITMP3);
927 M_ISUB(s1, s2, d, REG);
928 store_reg_to_var_int(iptr->dst, d);
931 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
932 /* val.i = constant */
934 var_to_reg_int(s1, src, REG_ITMP1);
935 d = reg_of_var(iptr->dst, REG_ITMP3);
936 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
937 M_ISUB(s1, iptr->val.i, d, CONST);
940 ICONST(REG_ITMP2, iptr->val.i);
941 M_ISUB(s1, REG_ITMP2, d, REG);
943 store_reg_to_var_int(iptr->dst, d);
946 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
948 var_to_reg_int(s1, src->prev, REG_ITMP1);
949 var_to_reg_int(s2, src, REG_ITMP2);
950 d = reg_of_var(iptr->dst, REG_ITMP3);
951 M_LSUB(s1, s2, d, REG);
952 store_reg_to_var_int(iptr->dst, d);
955 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
956 /* val.l = constant */
958 var_to_reg_int(s1, src, REG_ITMP1);
959 d = reg_of_var(iptr->dst, REG_ITMP3);
960 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
961 M_LSUB(s1, iptr->val.l, d, CONST);
964 LCONST(REG_ITMP2, iptr->val.l);
965 M_LSUB(s1, REG_ITMP2, d, REG);
967 store_reg_to_var_int(iptr->dst, d);
970 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
972 var_to_reg_int(s1, src->prev, REG_ITMP1);
973 var_to_reg_int(s2, src, REG_ITMP2);
974 d = reg_of_var(iptr->dst, REG_ITMP3);
975 M_IMUL(s1, s2, d, REG);
976 store_reg_to_var_int(iptr->dst, d);
979 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
980 /* val.i = constant */
982 var_to_reg_int(s1, src, REG_ITMP1);
983 d = reg_of_var(iptr->dst, REG_ITMP3);
984 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
985 M_IMUL(s1, iptr->val.i, d, CONST);
988 ICONST(REG_ITMP2, iptr->val.i);
989 M_IMUL(s1, REG_ITMP2, d, REG);
991 store_reg_to_var_int(iptr->dst, d);
994 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
996 var_to_reg_int(s1, src->prev, REG_ITMP1);
997 var_to_reg_int(s2, src, REG_ITMP2);
998 d = reg_of_var(iptr->dst, REG_ITMP3);
999 M_LMUL (s1, s2, d, REG);
1000 store_reg_to_var_int(iptr->dst, d);
1003 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
1004 /* val.l = constant */
1006 var_to_reg_int(s1, src, REG_ITMP1);
1007 d = reg_of_var(iptr->dst, REG_ITMP3);
1008 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1009 M_LMUL(s1, iptr->val.l, d, CONST);
1012 LCONST(REG_ITMP2, iptr->val.l);
1013 M_LMUL(s1, REG_ITMP2, d, REG);
1015 store_reg_to_var_int(iptr->dst, d);
1018 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
1019 case ICMD_LDIVPOW2: /* val.i = constant */
1021 var_to_reg_int(s1, src, REG_ITMP1);
1022 d = reg_of_var(iptr->dst, REG_ITMP3);
1023 if (iptr->val.i <= 15) {
1024 M_LDA(REG_ITMP2, s1, (1 << iptr->val.i) -1);
1025 M_CMOVGE(s1, s1, REG_ITMP2, REG);
1028 M_SRA(s1, 63, REG_ITMP2, CONST);
1029 M_SRL(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2, CONST);
1030 M_LADD(s1, REG_ITMP2, REG_ITMP2, REG);
1032 M_SRA(REG_ITMP2, iptr->val.i, d, CONST);
1033 store_reg_to_var_int(iptr->dst, d);
1036 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1038 var_to_reg_int(s1, src->prev, REG_ITMP1);
1039 var_to_reg_int(s2, src, REG_ITMP2);
1040 d = reg_of_var(iptr->dst, REG_ITMP3);
1041 M_AND(s2, 0x1f, REG_ITMP3, CONST);
1042 M_SLL(s1, REG_ITMP3, d, REG);
1043 M_IADD(d, REG_ZERO, d, REG);
1044 store_reg_to_var_int(iptr->dst, d);
1047 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1048 /* val.i = constant */
1050 var_to_reg_int(s1, src, REG_ITMP1);
1051 d = reg_of_var(iptr->dst, REG_ITMP3);
1052 M_SLL(s1, iptr->val.i & 0x1f, d, CONST);
1053 M_IADD(d, REG_ZERO, d, REG);
1054 store_reg_to_var_int(iptr->dst, d);
1057 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1059 var_to_reg_int(s1, src->prev, REG_ITMP1);
1060 var_to_reg_int(s2, src, REG_ITMP2);
1061 d = reg_of_var(iptr->dst, REG_ITMP3);
1062 M_AND(s2, 0x1f, REG_ITMP3, 1);
1063 M_SRA(s1, REG_ITMP3, d, 0);
1064 store_reg_to_var_int(iptr->dst, d);
1067 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1068 /* val.i = constant */
1070 var_to_reg_int(s1, src, REG_ITMP1);
1071 d = reg_of_var(iptr->dst, REG_ITMP3);
1072 M_SRA(s1, iptr->val.i & 0x1f, d, CONST);
1073 store_reg_to_var_int(iptr->dst, d);
1076 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1078 var_to_reg_int(s1, src->prev, REG_ITMP1);
1079 var_to_reg_int(s2, src, REG_ITMP2);
1080 d = reg_of_var(iptr->dst, REG_ITMP3);
1081 M_AND (s2, 0x1f, REG_ITMP2, 1);
1083 M_SRL ( d, REG_ITMP2, d, REG);
1084 M_IADD ( d, REG_ZERO, d, REG);
1085 store_reg_to_var_int(iptr->dst, d);
1088 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1089 /* val.i = constant */
1091 var_to_reg_int(s1, src, REG_ITMP1);
1092 d = reg_of_var(iptr->dst, REG_ITMP3);
1094 M_SRL(d, iptr->val.i & 0x1f, d, CONST);
1095 M_IADD(d, REG_ZERO, d, REG);
1096 store_reg_to_var_int(iptr->dst, d);
1099 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1101 var_to_reg_int(s1, src->prev, REG_ITMP1);
1102 var_to_reg_int(s2, src, REG_ITMP2);
1103 d = reg_of_var(iptr->dst, REG_ITMP3);
1104 M_SLL(s1, s2, d, REG);
1105 store_reg_to_var_int(iptr->dst, d);
1108 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1109 /* val.l = constant */
1111 var_to_reg_int(s1, src, REG_ITMP1);
1112 d = reg_of_var(iptr->dst, REG_ITMP3);
1113 M_SLL(s1, iptr->val.l & 0x3f, d, CONST);
1114 store_reg_to_var_int(iptr->dst, d);
1117 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1119 var_to_reg_int(s1, src->prev, REG_ITMP1);
1120 var_to_reg_int(s2, src, REG_ITMP2);
1121 d = reg_of_var(iptr->dst, REG_ITMP3);
1122 M_SRA(s1, s2, d, 0);
1123 store_reg_to_var_int(iptr->dst, d);
1126 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1127 /* val.l = constant */
1129 var_to_reg_int(s1, src, REG_ITMP1);
1130 d = reg_of_var(iptr->dst, REG_ITMP3);
1131 M_SRA(s1, iptr->val.l & 0x3f, d, CONST);
1132 store_reg_to_var_int(iptr->dst, d);
1135 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1137 var_to_reg_int(s1, src->prev, REG_ITMP1);
1138 var_to_reg_int(s2, src, REG_ITMP2);
1139 d = reg_of_var(iptr->dst, REG_ITMP3);
1140 M_SRL(s1, s2, d, 0);
1141 store_reg_to_var_int(iptr->dst, d);
1144 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1145 /* val.l = constant */
1147 var_to_reg_int(s1, src, REG_ITMP1);
1148 d = reg_of_var(iptr->dst, REG_ITMP3);
1149 M_SRL(s1, iptr->val.l & 0x3f, d, CONST);
1150 store_reg_to_var_int(iptr->dst, d);
1153 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1156 var_to_reg_int(s1, src->prev, REG_ITMP1);
1157 var_to_reg_int(s2, src, REG_ITMP2);
1158 d = reg_of_var(iptr->dst, REG_ITMP3);
1159 M_AND(s1, s2, d, REG);
1160 store_reg_to_var_int(iptr->dst, d);
1163 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1164 /* val.i = constant */
1166 var_to_reg_int(s1, src, REG_ITMP1);
1167 d = reg_of_var(iptr->dst, REG_ITMP3);
1168 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1169 M_AND(s1, iptr->val.i, d, CONST);
1171 else if (iptr->val.i == 0xffff) {
1174 else if (iptr->val.i == 0xffffff) {
1175 M_ZAPNOT(s1, 0x07, d, CONST);
1178 ICONST(REG_ITMP2, iptr->val.i);
1179 M_AND(s1, REG_ITMP2, d, REG);
1181 store_reg_to_var_int(iptr->dst, d);
1184 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1185 /* val.i = constant */
1187 var_to_reg_int(s1, src, REG_ITMP1);
1188 d = reg_of_var(iptr->dst, REG_ITMP3);
1190 M_MOV(s1, REG_ITMP1);
1193 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1194 M_AND(s1, iptr->val.i, d, CONST);
1196 M_ISUB(REG_ZERO, s1, d, REG);
1197 M_AND(d, iptr->val.i, d, CONST);
1199 else if (iptr->val.i == 0xffff) {
1202 M_ISUB(REG_ZERO, s1, d, REG);
1205 else if (iptr->val.i == 0xffffff) {
1206 M_ZAPNOT(s1, 0x07, d, CONST);
1208 M_ISUB(REG_ZERO, s1, d, REG);
1209 M_ZAPNOT(d, 0x07, d, CONST);
1212 ICONST(REG_ITMP2, iptr->val.i);
1213 M_AND(s1, REG_ITMP2, d, REG);
1215 M_ISUB(REG_ZERO, s1, d, REG);
1216 M_AND(d, REG_ITMP2, d, REG);
1218 M_ISUB(REG_ZERO, d, d, REG);
1219 store_reg_to_var_int(iptr->dst, d);
1222 case ICMD_IREM0X10001: /* ..., value ==> ..., value % 0x100001 */
1224 /* b = value & 0xffff;
1226 a = ((b - a) & 0xffff) + (b < a);
1228 var_to_reg_int(s1, src, REG_ITMP1);
1229 d = reg_of_var(iptr->dst, REG_ITMP3);
1231 M_MOV(s1, REG_ITMP3);
1235 M_CZEXT(s1, REG_ITMP2);
1236 M_SRA(s1, 16, d, CONST);
1237 M_CMPLT(REG_ITMP2, d, REG_ITMP1, REG);
1238 M_ISUB(REG_ITMP2, d, d, REG);
1240 M_IADD(d, REG_ITMP1, d, REG);
1241 M_BR(11 + (s1 == REG_ITMP1));
1242 M_ISUB(REG_ZERO, s1, REG_ITMP1, REG);
1243 M_CZEXT(REG_ITMP1, REG_ITMP2);
1244 M_SRA(REG_ITMP1, 16, d, CONST);
1245 M_CMPLT(REG_ITMP2, d, REG_ITMP1, REG);
1246 M_ISUB(REG_ITMP2, d, d, REG);
1248 M_IADD(d, REG_ITMP1, d, REG);
1249 M_ISUB(REG_ZERO, d, d, REG);
1250 if (s1 == REG_ITMP1) {
1251 var_to_reg_int(s1, src, REG_ITMP1);
1253 M_SLL(s1, 33, REG_ITMP2, CONST);
1254 M_CMPEQ(REG_ITMP2, REG_ZERO, REG_ITMP2, REG);
1255 M_ISUB(d, REG_ITMP2, d, REG);
1256 store_reg_to_var_int(iptr->dst, d);
1259 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1260 /* val.l = constant */
1262 var_to_reg_int(s1, src, REG_ITMP1);
1263 d = reg_of_var(iptr->dst, REG_ITMP3);
1264 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1265 M_AND(s1, iptr->val.l, d, CONST);
1267 else if (iptr->val.l == 0xffffL) {
1270 else if (iptr->val.l == 0xffffffL) {
1271 M_ZAPNOT(s1, 0x07, d, CONST);
1273 else if (iptr->val.l == 0xffffffffL) {
1276 else if (iptr->val.l == 0xffffffffffL) {
1277 M_ZAPNOT(s1, 0x1f, d, CONST);
1279 else if (iptr->val.l == 0xffffffffffffL) {
1280 M_ZAPNOT(s1, 0x3f, d, CONST);
1282 else if (iptr->val.l == 0xffffffffffffffL) {
1283 M_ZAPNOT(s1, 0x7f, d, CONST);
1286 LCONST(REG_ITMP2, iptr->val.l);
1287 M_AND(s1, REG_ITMP2, d, REG);
1289 store_reg_to_var_int(iptr->dst, d);
1292 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1293 /* val.l = constant */
1295 var_to_reg_int(s1, src, REG_ITMP1);
1296 d = reg_of_var(iptr->dst, REG_ITMP3);
1298 M_MOV(s1, REG_ITMP1);
1301 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1302 M_AND(s1, iptr->val.l, d, CONST);
1304 M_LSUB(REG_ZERO, s1, d, REG);
1305 M_AND(d, iptr->val.l, d, CONST);
1307 else if (iptr->val.l == 0xffffL) {
1310 M_LSUB(REG_ZERO, s1, d, REG);
1313 else if (iptr->val.l == 0xffffffL) {
1314 M_ZAPNOT(s1, 0x07, d, CONST);
1316 M_LSUB(REG_ZERO, s1, d, REG);
1317 M_ZAPNOT(d, 0x07, d, CONST);
1319 else if (iptr->val.l == 0xffffffffL) {
1322 M_LSUB(REG_ZERO, s1, d, REG);
1325 else if (iptr->val.l == 0xffffffffffL) {
1326 M_ZAPNOT(s1, 0x1f, d, CONST);
1328 M_LSUB(REG_ZERO, s1, d, REG);
1329 M_ZAPNOT(d, 0x1f, d, CONST);
1331 else if (iptr->val.l == 0xffffffffffffL) {
1332 M_ZAPNOT(s1, 0x3f, d, CONST);
1334 M_LSUB(REG_ZERO, s1, d, REG);
1335 M_ZAPNOT(d, 0x3f, d, CONST);
1337 else if (iptr->val.l == 0xffffffffffffffL) {
1338 M_ZAPNOT(s1, 0x7f, d, CONST);
1340 M_LSUB(REG_ZERO, s1, d, REG);
1341 M_ZAPNOT(d, 0x7f, d, CONST);
1344 LCONST(REG_ITMP2, iptr->val.l);
1345 M_AND(s1, REG_ITMP2, d, REG);
1347 M_LSUB(REG_ZERO, s1, d, REG);
1348 M_AND(d, REG_ITMP2, d, REG);
1350 M_LSUB(REG_ZERO, d, d, REG);
1351 store_reg_to_var_int(iptr->dst, d);
1354 case ICMD_LREM0X10001:/* ..., value ==> ..., value % 0x10001 */
1356 var_to_reg_int(s1, src, REG_ITMP1);
1357 d = reg_of_var(iptr->dst, REG_ITMP3);
1359 M_MOV(s1, REG_ITMP3);
1362 M_CZEXT(s1, REG_ITMP2);
1363 M_SRA(s1, 16, d, CONST);
1364 M_CMPLT(REG_ITMP2, d, REG_ITMP1, REG);
1365 M_LSUB(REG_ITMP2, d, d, REG);
1367 M_LADD(d, REG_ITMP1, d, REG);
1368 M_LDA(REG_ITMP2, REG_ZERO, -1);
1369 M_SRL(REG_ITMP2, 33, REG_ITMP2, CONST);
1370 if (s1 == REG_ITMP1) {
1371 var_to_reg_int(s1, src, REG_ITMP1);
1373 M_CMPULT(s1, REG_ITMP2, REG_ITMP2, REG);
1374 M_BNEZ(REG_ITMP2, 11);
1375 M_LDA(d, REG_ZERO, -257);
1376 M_ZAPNOT(d, 0xcd, d, CONST);
1377 M_LSUB(REG_ZERO, s1, REG_ITMP2, REG);
1378 M_CMOVGE(s1, s1, REG_ITMP2, REG);
1379 M_UMULH(REG_ITMP2, d, REG_ITMP2, REG);
1380 M_SRL(REG_ITMP2, 16, REG_ITMP2, CONST);
1381 M_LSUB(REG_ZERO, REG_ITMP2, d, REG);
1382 M_CMOVGE(s1, REG_ITMP2, d, REG);
1383 M_SLL(d, 16, REG_ITMP2, CONST);
1384 M_LADD(d, REG_ITMP2, d, REG);
1385 M_LSUB(s1, d, d, REG);
1386 store_reg_to_var_int(iptr->dst, d);
1389 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1392 var_to_reg_int(s1, src->prev, REG_ITMP1);
1393 var_to_reg_int(s2, src, REG_ITMP2);
1394 d = reg_of_var(iptr->dst, REG_ITMP3);
1395 M_OR( s1,s2, d, REG);
1396 store_reg_to_var_int(iptr->dst, d);
1399 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1400 /* val.i = constant */
1402 var_to_reg_int(s1, src, REG_ITMP1);
1403 d = reg_of_var(iptr->dst, REG_ITMP3);
1404 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1405 M_OR(s1, iptr->val.i, d, CONST);
1408 ICONST(REG_ITMP2, iptr->val.i);
1409 M_OR(s1, REG_ITMP2, d, REG);
1411 store_reg_to_var_int(iptr->dst, d);
1414 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1415 /* val.l = constant */
1417 var_to_reg_int(s1, src, REG_ITMP1);
1418 d = reg_of_var(iptr->dst, REG_ITMP3);
1419 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1420 M_OR(s1, iptr->val.l, d, CONST);
1423 LCONST(REG_ITMP2, iptr->val.l);
1424 M_OR(s1, REG_ITMP2, d, REG);
1426 store_reg_to_var_int(iptr->dst, d);
1429 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1432 var_to_reg_int(s1, src->prev, REG_ITMP1);
1433 var_to_reg_int(s2, src, REG_ITMP2);
1434 d = reg_of_var(iptr->dst, REG_ITMP3);
1435 M_XOR(s1, s2, d, REG);
1436 store_reg_to_var_int(iptr->dst, d);
1439 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1440 /* val.i = constant */
1442 var_to_reg_int(s1, src, REG_ITMP1);
1443 d = reg_of_var(iptr->dst, REG_ITMP3);
1444 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1445 M_XOR(s1, iptr->val.i, d, CONST);
1448 ICONST(REG_ITMP2, iptr->val.i);
1449 M_XOR(s1, REG_ITMP2, d, REG);
1451 store_reg_to_var_int(iptr->dst, d);
1454 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1455 /* val.l = constant */
1457 var_to_reg_int(s1, src, REG_ITMP1);
1458 d = reg_of_var(iptr->dst, REG_ITMP3);
1459 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1460 M_XOR(s1, iptr->val.l, d, CONST);
1463 LCONST(REG_ITMP2, iptr->val.l);
1464 M_XOR(s1, REG_ITMP2, d, REG);
1466 store_reg_to_var_int(iptr->dst, d);
1470 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1472 var_to_reg_int(s1, src->prev, REG_ITMP1);
1473 var_to_reg_int(s2, src, REG_ITMP2);
1474 d = reg_of_var(iptr->dst, REG_ITMP3);
1475 M_CMPLT(s1, s2, REG_ITMP3, REG);
1476 M_CMPLT(s2, s1, REG_ITMP1, REG);
1477 M_LSUB (REG_ITMP1, REG_ITMP3, d, REG);
1478 store_reg_to_var_int(iptr->dst, d);
1482 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1483 /* op1 = variable, val.i = constant */
1485 var = &(locals[iptr->op1][TYPE_INT]);
1486 if (var->flags & INMEMORY) {
1488 M_LLD(s1, REG_SP, 8 * var->regoff);
1492 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1493 M_IADD(s1, iptr->val.i, s1, CONST);
1495 else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1496 M_ISUB(s1, (-iptr->val.i), s1, CONST);
1499 M_LDA (s1, s1, iptr->val.i);
1500 M_IADD(s1, REG_ZERO, s1, REG);
1502 if (var->flags & INMEMORY)
1503 M_LST(s1, REG_SP, 8 * var->regoff);
1507 /* floating operations ************************************************/
1509 case ICMD_FNEG: /* ..., value ==> ..., - value */
1511 var_to_reg_flt(s1, src, REG_FTMP1);
1512 d = reg_of_var(iptr->dst, REG_FTMP3);
1514 store_reg_to_var_flt(iptr->dst, d);
1517 case ICMD_DNEG: /* ..., value ==> ..., - value */
1519 var_to_reg_flt(s1, src, REG_FTMP1);
1520 d = reg_of_var(iptr->dst, REG_FTMP3);
1522 store_reg_to_var_flt(iptr->dst, d);
1525 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1527 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1528 var_to_reg_flt(s2, src, REG_FTMP2);
1529 d = reg_of_var(iptr->dst, REG_FTMP3);
1537 store_reg_to_var_flt(iptr->dst, d);
1540 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1542 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1543 var_to_reg_flt(s2, src, REG_FTMP2);
1544 d = reg_of_var(iptr->dst, REG_FTMP3);
1552 store_reg_to_var_flt(iptr->dst, d);
1555 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1557 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1558 var_to_reg_flt(s2, src, REG_FTMP2);
1559 d = reg_of_var(iptr->dst, REG_FTMP3);
1567 store_reg_to_var_flt(iptr->dst, d);
1570 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1572 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1573 var_to_reg_flt(s2, src, REG_FTMP2);
1574 d = reg_of_var(iptr->dst, REG_FTMP3);
1582 store_reg_to_var_flt(iptr->dst, d);
1585 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1587 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1588 var_to_reg_flt(s2, src, REG_FTMP2);
1589 d = reg_of_var(iptr->dst, REG_FTMP3);
1597 store_reg_to_var_flt(iptr->dst, d);
1600 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1602 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1603 var_to_reg_flt(s2, src, REG_FTMP2);
1604 d = reg_of_var(iptr->dst, REG_FTMP3);
1612 store_reg_to_var_flt(iptr->dst, d);
1615 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1617 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1618 var_to_reg_flt(s2, src, REG_FTMP2);
1619 d = reg_of_var(iptr->dst, REG_FTMP3);
1627 store_reg_to_var_flt(iptr->dst, d);
1630 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1632 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1633 var_to_reg_flt(s2, src, REG_FTMP2);
1634 d = reg_of_var(iptr->dst, REG_FTMP3);
1642 store_reg_to_var_flt(iptr->dst, d);
1645 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1647 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1648 var_to_reg_flt(s2, src, REG_FTMP2);
1649 d = reg_of_var(iptr->dst, REG_FTMP3);
1651 M_FDIVS(s1,s2, REG_FTMP3);
1653 M_CVTDL_CS(REG_ZERO, REG_FTMP3, REG_FTMP3); /* round to integer */
1655 M_CVTLF(REG_ZERO, REG_FTMP3, REG_FTMP3);
1656 M_FMULS(REG_FTMP3, s2, REG_FTMP3);
1658 M_FSUBS(s1, REG_FTMP3, d);
1662 M_FDIV(s1,s2, REG_FTMP3);
1663 M_CVTDL_C(REG_ZERO, REG_FTMP3, REG_FTMP3); /* round to integer */
1664 M_CVTLF(REG_ZERO, REG_FTMP3, REG_FTMP3);
1665 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1666 M_FSUB(s1, REG_FTMP3, d);
1668 store_reg_to_var_flt(iptr->dst, d);
1671 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1673 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1674 var_to_reg_flt(s2, src, REG_FTMP2);
1675 d = reg_of_var(iptr->dst, REG_FTMP3);
1677 M_DDIVS(s1,s2, REG_FTMP3);
1679 M_CVTDL_CS(REG_ZERO, REG_FTMP3, REG_FTMP3); /* round to integer */
1681 M_CVTLD(REG_ZERO, REG_FTMP3, REG_FTMP3);
1682 M_DMULS(REG_FTMP3, s2, REG_FTMP3);
1684 M_DSUBS(s1, REG_FTMP3, d);
1688 M_DDIV(s1,s2, REG_FTMP3);
1689 M_CVTDL_C(REG_ZERO, REG_FTMP3, REG_FTMP3); /* round to integer */
1690 M_CVTLD(REG_ZERO, REG_FTMP3, REG_FTMP3);
1691 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1692 M_DSUB(s1, REG_FTMP3, d);
1694 store_reg_to_var_flt(iptr->dst, d);
1697 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1699 var_to_reg_int(s1, src, REG_ITMP1);
1700 d = reg_of_var(iptr->dst, REG_FTMP3);
1701 a = dseg_adddouble(0.0);
1702 M_LST (s1, REG_PV, a);
1703 M_DLD (d, REG_PV, a);
1704 M_CVTLF(REG_ZERO, d, d);
1705 store_reg_to_var_flt(iptr->dst, d);
1708 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1710 var_to_reg_int(s1, src, REG_ITMP1);
1711 d = reg_of_var(iptr->dst, REG_FTMP3);
1712 a = dseg_adddouble(0.0);
1713 M_LST (s1, REG_PV, a);
1714 M_DLD (d, REG_PV, a);
1715 M_CVTLD(REG_ZERO, d, d);
1716 store_reg_to_var_flt(iptr->dst, d);
1719 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1721 var_to_reg_flt(s1, src, REG_FTMP1);
1722 d = reg_of_var(iptr->dst, REG_ITMP3);
1723 a = dseg_adddouble(0.0);
1725 M_CVTDL_CS(REG_ZERO, s1, REG_FTMP1);
1727 M_CVTLIS(REG_FTMP1, REG_FTMP2);
1731 M_CVTDL_C(REG_ZERO, s1, REG_FTMP1);
1732 M_CVTLI(REG_FTMP1, REG_FTMP2);
1734 M_DST (REG_FTMP1, REG_PV, a);
1735 M_ILD (d, REG_PV, a);
1736 store_reg_to_var_int(iptr->dst, d);
1739 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1741 var_to_reg_flt(s1, src, REG_FTMP1);
1742 d = reg_of_var(iptr->dst, REG_ITMP3);
1743 a = dseg_adddouble(0.0);
1745 M_CVTDL_CS(REG_ZERO, s1, REG_FTMP1);
1749 M_CVTDL_C(REG_ZERO, s1, REG_FTMP1);
1751 M_DST (REG_FTMP1, REG_PV, a);
1752 M_LLD (d, REG_PV, a);
1753 store_reg_to_var_int(iptr->dst, d);
1756 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1758 var_to_reg_flt(s1, src, REG_FTMP1);
1759 d = reg_of_var(iptr->dst, REG_FTMP3);
1761 store_reg_to_var_flt(iptr->dst, d);
1764 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1766 var_to_reg_flt(s1, src, REG_FTMP1);
1767 d = reg_of_var(iptr->dst, REG_FTMP3);
1769 M_CVTDFS(REG_ZERO, s1, d);
1773 M_CVTDF(REG_ZERO, s1, d);
1775 store_reg_to_var_flt(iptr->dst, d);
1778 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1780 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1781 var_to_reg_flt(s2, src, REG_FTMP2);
1782 d = reg_of_var(iptr->dst, REG_ITMP3);
1784 M_LSUB (REG_ZERO, 1, d, CONST);
1785 M_FCMPEQS(s1, s2, REG_FTMP3);
1787 M_FBEQZ (REG_FTMP3, CONST); /* jump over next instructions */
1789 M_FCMPLTS(s2, s1, REG_FTMP3);
1791 M_FBEQZ (REG_FTMP3, CONST); /* jump over next instruction */
1792 M_LADD (REG_ZERO, 1, d, CONST);
1795 M_LSUB (REG_ZERO, 1, d, CONST);
1796 M_FCMPEQ(s1, s2, REG_FTMP3);
1797 M_FBEQZ (REG_FTMP3, CONST); /* jump over next instructions */
1799 M_FCMPLT(s2, s1, REG_FTMP3);
1800 M_FBEQZ (REG_FTMP3, CONST); /* jump over next instruction */
1801 M_LADD (REG_ZERO, 1, d, CONST);
1803 store_reg_to_var_int(iptr->dst, d);
1806 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1808 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1809 var_to_reg_flt(s2, src, REG_FTMP2);
1810 d = reg_of_var(iptr->dst, REG_ITMP3);
1812 M_LADD (REG_ZERO, 1, d, CONST);
1813 M_FCMPEQS(s1, s2, REG_FTMP3);
1815 M_FBEQZ (REG_FTMP3, CONST); /* jump over next instruction */
1817 M_FCMPLTS(s1, s2, REG_FTMP3);
1819 M_FBEQZ (REG_FTMP3, CONST); /* jump over next instruction */
1820 M_LSUB (REG_ZERO, 1, d, CONST);
1823 M_LADD (REG_ZERO, 1, d, CONST);
1824 M_FCMPEQ(s1, s2, REG_FTMP3);
1825 M_FBEQZ (REG_FTMP3, CONST); /* jump over next instruction */
1827 M_FCMPLT(s1, s2, REG_FTMP3);
1828 M_FBEQZ (REG_FTMP3, CONST); /* jump over next instruction */
1829 M_LSUB (REG_ZERO, 1, d, CONST);
1831 store_reg_to_var_int(iptr->dst, d);
1835 /* memory operations **************************************************/
1837 #define gen_bound_check \
1839 M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\
1840 M_CMPULT(s2, REG_ITMP3, REG_ITMP3, REG);\
1841 M_BEQZ(REG_ITMP3, REG);\
1842 mcode_addxboundrefs(mcodeptr);\
1845 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1847 var_to_reg_int(s1, src, REG_ITMP1);
1848 d = reg_of_var(iptr->dst, REG_ITMP3);
1849 gen_nullptr_check(s1);
1850 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1851 store_reg_to_var_int(iptr->dst, d);
1854 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1856 var_to_reg_int(s1, src->prev, REG_ITMP1);
1857 var_to_reg_int(s2, src, REG_ITMP2);
1858 d = reg_of_var(iptr->dst, REG_ITMP3);
1859 gen_nullptr_check(s1);
1861 M_SAADDQ(s2, s1, REG_ITMP1, REG);
1862 M_ALD( d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1863 store_reg_to_var_int(iptr->dst, d);
1866 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1868 var_to_reg_int(s1, src->prev, REG_ITMP1);
1869 var_to_reg_int(s2, src, REG_ITMP2);
1870 d = reg_of_var(iptr->dst, REG_ITMP3);
1871 gen_nullptr_check(s1);
1873 M_S8ADDQ(s2, s1, REG_ITMP1, REG);
1874 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1875 store_reg_to_var_int(iptr->dst, d);
1878 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1880 var_to_reg_int(s1, src->prev, REG_ITMP1);
1881 var_to_reg_int(s2, src, REG_ITMP2);
1882 d = reg_of_var(iptr->dst, REG_ITMP3);
1883 gen_nullptr_check(s1);
1885 M_S4ADDQ(s2, s1, REG_ITMP1, REG);
1886 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1887 store_reg_to_var_int(iptr->dst, d);
1890 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1892 var_to_reg_int(s1, src->prev, REG_ITMP1);
1893 var_to_reg_int(s2, src, REG_ITMP2);
1894 d = reg_of_var(iptr->dst, REG_FTMP3);
1895 gen_nullptr_check(s1);
1897 M_S4ADDQ(s2, s1, REG_ITMP1, REG);
1898 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1899 store_reg_to_var_flt(iptr->dst, d);
1902 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1904 var_to_reg_int(s1, src->prev, REG_ITMP1);
1905 var_to_reg_int(s2, src, REG_ITMP2);
1906 d = reg_of_var(iptr->dst, REG_FTMP3);
1907 gen_nullptr_check(s1);
1909 M_S8ADDQ(s2, s1, REG_ITMP1, REG);
1910 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1911 store_reg_to_var_flt(iptr->dst, d);
1914 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1916 var_to_reg_int(s1, src->prev, REG_ITMP1);
1917 var_to_reg_int(s2, src, REG_ITMP2);
1918 d = reg_of_var(iptr->dst, REG_ITMP3);
1919 gen_nullptr_check(s1);
1921 if (has_ext_instr_set) {
1922 M_LADD(s2, s1, REG_ITMP1, REG);
1923 M_LADD(s2, REG_ITMP1, REG_ITMP1, REG);
1924 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1927 M_LADD (s2, s1, REG_ITMP1, 0);
1928 M_LADD (s2, REG_ITMP1, REG_ITMP1, REG);
1929 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1930 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1931 M_EXTWL(REG_ITMP2, REG_ITMP1, d, REG);
1933 store_reg_to_var_int(iptr->dst, d);
1936 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1938 var_to_reg_int(s1, src->prev, REG_ITMP1);
1939 var_to_reg_int(s2, src, REG_ITMP2);
1940 d = reg_of_var(iptr->dst, REG_ITMP3);
1941 gen_nullptr_check(s1);
1943 if (has_ext_instr_set) {
1944 M_LADD(s2, s1, REG_ITMP1, REG);
1945 M_LADD(s2, REG_ITMP1, REG_ITMP1, REG);
1946 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1950 M_LADD(s2, s1, REG_ITMP1, 0);
1951 M_LADD(s2, REG_ITMP1, REG_ITMP1, REG);
1952 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1953 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1954 M_EXTQH(REG_ITMP2, REG_ITMP1, d, REG);
1955 M_SRA(d, 48, d, CONST);
1957 store_reg_to_var_int(iptr->dst, d);
1960 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1962 var_to_reg_int(s1, src->prev, REG_ITMP1);
1963 var_to_reg_int(s2, src, REG_ITMP2);
1964 d = reg_of_var(iptr->dst, REG_ITMP3);
1965 gen_nullptr_check(s1);
1967 if (has_ext_instr_set) {
1968 M_LADD (s2, s1, REG_ITMP1, REG);
1969 M_BLDU (d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1973 M_LADD(s2, s1, REG_ITMP1, REG);
1974 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1975 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
1976 M_EXTQH(REG_ITMP2, REG_ITMP1, d, REG);
1977 M_SRA(d, 56, d, CONST);
1979 store_reg_to_var_int(iptr->dst, d);
1983 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1985 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1986 var_to_reg_int(s2, src->prev, REG_ITMP2);
1987 gen_nullptr_check(s1);
1989 var_to_reg_int(s3, src, REG_ITMP3);
1990 M_SAADDQ(s2, s1, REG_ITMP1, REG);
1991 M_AST (s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1994 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1996 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1997 var_to_reg_int(s2, src->prev, REG_ITMP2);
1998 gen_nullptr_check(s1);
2000 var_to_reg_int(s3, src, REG_ITMP3);
2001 M_S8ADDQ(s2, s1, REG_ITMP1, REG);
2002 M_LST (s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
2005 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
2007 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2008 var_to_reg_int(s2, src->prev, REG_ITMP2);
2009 gen_nullptr_check(s1);
2011 var_to_reg_int(s3, src, REG_ITMP3);
2012 M_S4ADDQ(s2, s1, REG_ITMP1, REG);
2013 M_IST (s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
2016 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
2018 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2019 var_to_reg_int(s2, src->prev, REG_ITMP2);
2020 gen_nullptr_check(s1);
2022 var_to_reg_flt(s3, src, REG_FTMP3);
2023 M_S4ADDQ(s2, s1, REG_ITMP1, REG);
2024 M_FST (s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
2027 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
2029 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2030 var_to_reg_int(s2, src->prev, REG_ITMP2);
2031 gen_nullptr_check(s1);
2033 var_to_reg_flt(s3, src, REG_FTMP3);
2034 M_S8ADDQ(s2, s1, REG_ITMP1, REG);
2035 M_DST (s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
2038 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
2040 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2041 var_to_reg_int(s2, src->prev, REG_ITMP2);
2042 gen_nullptr_check(s1);
2044 var_to_reg_int(s3, src, REG_ITMP3);
2045 if (has_ext_instr_set) {
2046 M_LADD(s2, s1, REG_ITMP1, REG);
2047 M_LADD(s2, REG_ITMP1, REG_ITMP1, REG);
2048 M_SST (s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
2051 M_LADD (s2, s1, REG_ITMP1, REG);
2052 M_LADD (s2, REG_ITMP1, REG_ITMP1, REG);
2053 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2054 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2055 M_INSWL(s3, REG_ITMP1, REG_ITMP3, REG);
2056 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2, REG);
2057 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2, REG);
2058 M_LST_U(REG_ITMP2, REG_ITMP1, REG);
2062 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
2064 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2065 var_to_reg_int(s2, src->prev, REG_ITMP2);
2066 gen_nullptr_check(s1);
2068 var_to_reg_int(s3, src, REG_ITMP3);
2069 if (has_ext_instr_set) {
2070 M_LADD(s2, s1, REG_ITMP1, REG);
2071 M_LADD(s2, REG_ITMP1, REG_ITMP1, REG);
2072 M_SST (s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2075 M_LADD (s2, s1, REG_ITMP1, REG);
2076 M_LADD (s2, REG_ITMP1, REG_ITMP1, REG);
2077 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2078 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2079 M_INSWL(s3, REG_ITMP1, REG_ITMP3, REG);
2080 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2, REG);
2081 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2, REG);
2082 M_LST_U(REG_ITMP2, REG_ITMP1, REG);
2086 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
2088 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2089 var_to_reg_int(s2, src->prev, REG_ITMP2);
2090 gen_nullptr_check(s1);
2092 var_to_reg_int(s3, src, REG_ITMP3);
2093 if (has_ext_instr_set) {
2094 M_LADD(s2, s1, REG_ITMP1, REG);
2095 M_BST (s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2098 M_LADD (s2, s1, REG_ITMP1, 0);
2099 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2100 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2101 M_INSBL(s3, REG_ITMP1, REG_ITMP3, REG);
2102 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2, REG);
2103 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2, REG);
2104 M_LST_U(REG_ITMP2, REG_ITMP1, REG);
2109 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2110 /* op1 = type, val.a = field address */
2112 a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value));
2113 M_ALD(REG_ITMP1, REG_PV, a);
2114 switch (iptr->op1) {
2116 var_to_reg_int(s2, src, REG_ITMP2);
2117 M_IST(s2, REG_ITMP1, REG);
2120 var_to_reg_int(s2, src, REG_ITMP2);
2121 M_LST(s2, REG_ITMP1, REG);
2124 var_to_reg_int(s2, src, REG_ITMP2);
2125 M_AST(s2, REG_ITMP1, REG);
2128 var_to_reg_flt(s2, src, REG_FTMP2);
2129 M_FST(s2, REG_ITMP1, REG);
2132 var_to_reg_flt(s2, src, REG_FTMP2);
2133 M_DST(s2, REG_ITMP1, REG);
2135 default: panic ("internal error");
2139 case ICMD_GETSTATIC: /* ... ==> ..., value */
2140 /* op1 = type, val.a = field address */
2142 a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value));
2143 M_ALD(REG_ITMP1, REG_PV, a);
2144 switch (iptr->op1) {
2146 d = reg_of_var(iptr->dst, REG_ITMP3);
2147 M_ILD(d, REG_ITMP1, REG);
2148 store_reg_to_var_int(iptr->dst, d);
2151 d = reg_of_var(iptr->dst, REG_ITMP3);
2152 M_LLD(d, REG_ITMP1, REG);
2153 store_reg_to_var_int(iptr->dst, d);
2156 d = reg_of_var(iptr->dst, REG_ITMP3);
2157 M_ALD(d, REG_ITMP1, REG);
2158 store_reg_to_var_int(iptr->dst, d);
2161 d = reg_of_var(iptr->dst, REG_FTMP1);
2162 M_FLD(d, REG_ITMP1, REG);
2163 store_reg_to_var_flt(iptr->dst, d);
2166 d = reg_of_var(iptr->dst, REG_FTMP1);
2167 M_DLD(d, REG_ITMP1, REG);
2168 store_reg_to_var_flt(iptr->dst, d);
2170 default: panic ("internal error");
2175 case ICMD_PUTFIELD: /* ..., value ==> ... */
2176 /* op1 = type, val.i = field offset */
2178 a = ((fieldinfo *)(iptr->val.a))->offset;
2179 switch (iptr->op1) {
2181 var_to_reg_int(s1, src->prev, REG_ITMP1);
2182 var_to_reg_int(s2, src, REG_ITMP2);
2183 gen_nullptr_check(s1);
2187 var_to_reg_int(s1, src->prev, REG_ITMP1);
2188 var_to_reg_int(s2, src, REG_ITMP2);
2189 gen_nullptr_check(s1);
2193 var_to_reg_int(s1, src->prev, REG_ITMP1);
2194 var_to_reg_int(s2, src, REG_ITMP2);
2195 gen_nullptr_check(s1);
2199 var_to_reg_int(s1, src->prev, REG_ITMP1);
2200 var_to_reg_flt(s2, src, REG_FTMP2);
2201 gen_nullptr_check(s1);
2205 var_to_reg_int(s1, src->prev, REG_ITMP1);
2206 var_to_reg_flt(s2, src, REG_FTMP2);
2207 gen_nullptr_check(s1);
2210 default: panic ("internal error");
2214 case ICMD_GETFIELD: /* ... ==> ..., value */
2215 /* op1 = type, val.i = field offset */
2217 a = ((fieldinfo *)(iptr->val.a))->offset;
2218 switch (iptr->op1) {
2220 var_to_reg_int(s1, src, REG_ITMP1);
2221 d = reg_of_var(iptr->dst, REG_ITMP3);
2222 gen_nullptr_check(s1);
2224 store_reg_to_var_int(iptr->dst, d);
2227 var_to_reg_int(s1, src, REG_ITMP1);
2228 d = reg_of_var(iptr->dst, REG_ITMP3);
2229 gen_nullptr_check(s1);
2231 store_reg_to_var_int(iptr->dst, d);
2234 var_to_reg_int(s1, src, REG_ITMP1);
2235 d = reg_of_var(iptr->dst, REG_ITMP3);
2236 gen_nullptr_check(s1);
2238 store_reg_to_var_int(iptr->dst, d);
2241 var_to_reg_int(s1, src, REG_ITMP1);
2242 d = reg_of_var(iptr->dst, REG_FTMP1);
2243 gen_nullptr_check(s1);
2245 store_reg_to_var_flt(iptr->dst, d);
2248 var_to_reg_int(s1, src, REG_ITMP1);
2249 d = reg_of_var(iptr->dst, REG_FTMP1);
2250 gen_nullptr_check(s1);
2252 store_reg_to_var_flt(iptr->dst, d);
2254 default: panic ("internal error");
2259 /* branch operations **************************************************/
2261 #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}}
2263 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2265 var_to_reg_int(s1, src, REG_ITMP1);
2266 M_INTMOVE(s1, REG_ITMP1_XPTR);
2267 a = dseg_addaddress(asm_handle_exception);
2268 M_ALD(REG_ITMP2, REG_PV, a);
2269 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2273 case ICMD_GOTO: /* ... ==> ... */
2274 /* op1 = target JavaVM pc */
2276 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2280 case ICMD_JSR: /* ... ==> ... */
2281 /* op1 = target JavaVM pc */
2283 M_BSR(REG_ITMP1, REG);
2284 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2287 case ICMD_RET: /* ... ==> ... */
2288 /* op1 = local variable */
2290 var = &(locals[iptr->op1][TYPE_ADR]);
2291 if (var->flags & INMEMORY) {
2292 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2293 M_RET(REG_ZERO, REG_ITMP1);
2296 M_RET(REG_ZERO, var->regoff);
2300 case ICMD_IFNULL: /* ..., value ==> ... */
2301 /* op1 = target JavaVM pc */
2303 var_to_reg_int(s1, src, REG_ITMP1);
2305 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2308 case ICMD_IFNONNULL: /* ..., value ==> ... */
2309 /* op1 = target JavaVM pc */
2311 var_to_reg_int(s1, src, REG_ITMP1);
2313 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2316 case ICMD_IFEQ: /* ..., value ==> ... */
2317 /* op1 = target JavaVM pc, val.i = constant */
2319 var_to_reg_int(s1, src, REG_ITMP1);
2320 if (iptr->val.i == 0) {
2324 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2325 M_CMPEQ(s1, iptr->val.i, REG_ITMP1, CONST);
2328 ICONST(REG_ITMP2, iptr->val.i);
2329 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1, REG);
2331 M_BNEZ(REG_ITMP1, REG);
2333 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2336 case ICMD_IFLT: /* ..., value ==> ... */
2337 /* op1 = target JavaVM pc, val.i = constant */
2339 var_to_reg_int(s1, src, REG_ITMP1);
2340 if (iptr->val.i == 0) {
2344 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2345 M_CMPLT(s1, iptr->val.i, REG_ITMP1, CONST);
2348 ICONST(REG_ITMP2, iptr->val.i);
2349 M_CMPLT(s1, REG_ITMP2, REG_ITMP1, REG);
2351 M_BNEZ(REG_ITMP1, REG);
2353 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2356 case ICMD_IFLE: /* ..., value ==> ... */
2357 /* op1 = target JavaVM pc, val.i = constant */
2359 var_to_reg_int(s1, src, REG_ITMP1);
2360 if (iptr->val.i == 0) {
2364 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2365 M_CMPLE(s1, iptr->val.i, REG_ITMP1, CONST);
2368 ICONST(REG_ITMP2, iptr->val.i);
2369 M_CMPLE(s1, REG_ITMP2, REG_ITMP1, REG);
2371 M_BNEZ(REG_ITMP1, REG);
2373 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2376 case ICMD_IFNE: /* ..., value ==> ... */
2377 /* op1 = target JavaVM pc, val.i = constant */
2379 var_to_reg_int(s1, src, REG_ITMP1);
2380 if (iptr->val.i == 0) {
2384 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2385 M_CMPEQ(s1, iptr->val.i, REG_ITMP1, CONST);
2388 ICONST(REG_ITMP2, iptr->val.i);
2389 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1, REG);
2391 M_BEQZ(REG_ITMP1, REG);
2393 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2396 case ICMD_IFGT: /* ..., value ==> ... */
2397 /* op1 = target JavaVM pc, val.i = constant */
2399 var_to_reg_int(s1, src, REG_ITMP1);
2400 if (iptr->val.i == 0) {
2404 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2405 M_CMPLE(s1, iptr->val.i, REG_ITMP1, CONST);
2408 ICONST(REG_ITMP2, iptr->val.i);
2409 M_CMPLE(s1, REG_ITMP2, REG_ITMP1, REG);
2411 M_BEQZ(REG_ITMP1, REG);
2413 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2416 case ICMD_IFGE: /* ..., value ==> ... */
2417 /* op1 = target JavaVM pc, val.i = constant */
2419 var_to_reg_int(s1, src, REG_ITMP1);
2420 if (iptr->val.i == 0) {
2424 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2425 M_CMPLT(s1, iptr->val.i, REG_ITMP1, CONST);
2428 ICONST(REG_ITMP2, iptr->val.i);
2429 M_CMPLT(s1, REG_ITMP2, REG_ITMP1, REG);
2431 M_BEQZ(REG_ITMP1, REG);
2433 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2436 case ICMD_IF_LEQ: /* ..., value ==> ... */
2437 /* op1 = target JavaVM pc, val.l = constant */
2439 var_to_reg_int(s1, src, REG_ITMP1);
2440 if (iptr->val.l == 0) {
2444 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2445 M_CMPEQ(s1, iptr->val.l, REG_ITMP1, CONST);
2448 LCONST(REG_ITMP2, iptr->val.l);
2449 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1, REG);
2451 M_BNEZ(REG_ITMP1, REG);
2453 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2456 case ICMD_IF_LLT: /* ..., value ==> ... */
2457 /* op1 = target JavaVM pc, val.l = constant */
2459 var_to_reg_int(s1, src, REG_ITMP1);
2460 if (iptr->val.l == 0) {
2464 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2465 M_CMPLT(s1, iptr->val.l, REG_ITMP1, CONST);
2468 LCONST(REG_ITMP2, iptr->val.l);
2469 M_CMPLT(s1, REG_ITMP2, REG_ITMP1, REG);
2471 M_BNEZ(REG_ITMP1, REG);
2473 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2476 case ICMD_IF_LLE: /* ..., value ==> ... */
2477 /* op1 = target JavaVM pc, val.l = constant */
2479 var_to_reg_int(s1, src, REG_ITMP1);
2480 if (iptr->val.l == 0) {
2484 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2485 M_CMPLE(s1, iptr->val.l, REG_ITMP1, CONST);
2488 LCONST(REG_ITMP2, iptr->val.l);
2489 M_CMPLE(s1, REG_ITMP2, REG_ITMP1, REG);
2491 M_BNEZ(REG_ITMP1, REG);
2493 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2496 case ICMD_IF_LNE: /* ..., value ==> ... */
2497 /* op1 = target JavaVM pc, val.l = constant */
2499 var_to_reg_int(s1, src, REG_ITMP1);
2500 if (iptr->val.l == 0) {
2504 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2505 M_CMPEQ(s1, iptr->val.l, REG_ITMP1, CONST);
2508 LCONST(REG_ITMP2, iptr->val.l);
2509 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1, REG);
2511 M_BEQZ(REG_ITMP1, REG);
2513 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2516 case ICMD_IF_LGT: /* ..., value ==> ... */
2517 /* op1 = target JavaVM pc, val.l = constant */
2519 var_to_reg_int(s1, src, REG_ITMP1);
2520 if (iptr->val.l == 0) {
2524 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2525 M_CMPLE(s1, iptr->val.l, REG_ITMP1, CONST);
2528 LCONST(REG_ITMP2, iptr->val.l);
2529 M_CMPLE(s1, REG_ITMP2, REG_ITMP1, REG);
2531 M_BEQZ(REG_ITMP1, REG);
2533 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2536 case ICMD_IF_LGE: /* ..., value ==> ... */
2537 /* op1 = target JavaVM pc, val.l = constant */
2539 var_to_reg_int(s1, src, REG_ITMP1);
2540 if (iptr->val.l == 0) {
2544 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2545 M_CMPLT(s1, iptr->val.l, REG_ITMP1, CONST);
2548 LCONST(REG_ITMP2, iptr->val.l);
2549 M_CMPLT(s1, REG_ITMP2, REG_ITMP1, REG);
2551 M_BEQZ(REG_ITMP1, REG);
2553 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2556 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2557 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2558 case ICMD_IF_ACMPEQ:
2560 var_to_reg_int(s1, src->prev, REG_ITMP1);
2561 var_to_reg_int(s2, src, REG_ITMP2);
2562 M_CMPEQ(s1, s2, REG_ITMP1, REG);
2563 M_BNEZ(REG_ITMP1, REG);
2564 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2567 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2568 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2569 case ICMD_IF_ACMPNE:
2571 var_to_reg_int(s1, src->prev, REG_ITMP1);
2572 var_to_reg_int(s2, src, REG_ITMP2);
2573 M_CMPEQ(s1, s2, REG_ITMP1, REG);
2574 M_BEQZ(REG_ITMP1, REG);
2575 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2578 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2579 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2581 var_to_reg_int(s1, src->prev, REG_ITMP1);
2582 var_to_reg_int(s2, src, REG_ITMP2);
2583 M_CMPLT(s1, s2, REG_ITMP1, REG);
2584 M_BNEZ(REG_ITMP1, REG);
2585 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2588 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2589 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2591 var_to_reg_int(s1, src->prev, REG_ITMP1);
2592 var_to_reg_int(s2, src, REG_ITMP2);
2593 M_CMPLE(s1, s2, REG_ITMP1, REG);
2594 M_BEQZ(REG_ITMP1, REG);
2595 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2598 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2599 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2601 var_to_reg_int(s1, src->prev, REG_ITMP1);
2602 var_to_reg_int(s2, src, REG_ITMP2);
2603 M_CMPLE(s1, s2, REG_ITMP1, REG);
2604 M_BNEZ(REG_ITMP1, REG);
2605 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2608 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2609 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2611 var_to_reg_int(s1, src->prev, REG_ITMP1);
2612 var_to_reg_int(s2, src, REG_ITMP2);
2613 M_CMPLT(s1, s2, REG_ITMP1, 0);
2614 M_BEQZ(REG_ITMP1, REG);
2615 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2618 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2620 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2623 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2624 /* val.i = constant */
2626 var_to_reg_int(s1, src, REG_ITMP1);
2627 d = reg_of_var(iptr->dst, REG_ITMP3);
2629 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2630 if ((a == 1) && (iptr[1].val.i == 0)) {
2631 M_CMPEQ(s1, REG_ZERO, d, 0);
2632 store_reg_to_var_int(iptr->dst, d);
2635 if ((a == 0) && (iptr[1].val.i == 1)) {
2636 M_CMPEQ(s1, REG_ZERO, d, 0);
2637 M_XOR(d, 1, d, CONST);
2638 store_reg_to_var_int(iptr->dst, d);
2642 M_MOV(s1, REG_ITMP1);
2645 ICONST(d, iptr[1].val.i);
2647 if ((a >= 0) && (a <= 255)) {
2648 M_CMOVEQ(s1, a, d, CONST);
2651 ICONST(REG_ITMP2, a);
2652 M_CMOVEQ(s1, REG_ITMP2, d, REG);
2654 store_reg_to_var_int(iptr->dst, d);
2657 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2658 /* val.i = constant */
2660 var_to_reg_int(s1, src, REG_ITMP1);
2661 d = reg_of_var(iptr->dst, REG_ITMP3);
2663 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2664 if ((a == 0) && (iptr[1].val.i == 1)) {
2665 M_CMPEQ(s1, REG_ZERO, d, 0);
2666 store_reg_to_var_int(iptr->dst, d);
2669 if ((a == 1) && (iptr[1].val.i == 0)) {
2670 M_CMPEQ(s1, REG_ZERO, d, 0);
2671 M_XOR(d, 1, d, CONST);
2672 store_reg_to_var_int(iptr->dst, d);
2676 M_MOV(s1, REG_ITMP1);
2679 ICONST(d, iptr[1].val.i);
2681 if ((a >= 0) && (a <= 255)) {
2682 M_CMOVNE(s1, a, d, CONST);
2685 ICONST(REG_ITMP2, a);
2686 M_CMOVNE(s1, REG_ITMP2, d, REG);
2688 store_reg_to_var_int(iptr->dst, d);
2691 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2692 /* val.i = constant */
2694 var_to_reg_int(s1, src, REG_ITMP1);
2695 d = reg_of_var(iptr->dst, REG_ITMP3);
2697 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2698 if ((a == 1) && (iptr[1].val.i == 0)) {
2699 M_CMPLT(s1, REG_ZERO, d, 0);
2700 store_reg_to_var_int(iptr->dst, d);
2703 if ((a == 0) && (iptr[1].val.i == 1)) {
2704 M_CMPLE(REG_ZERO, s1, d, 0);
2705 store_reg_to_var_int(iptr->dst, d);
2709 M_MOV(s1, REG_ITMP1);
2712 ICONST(d, iptr[1].val.i);
2714 if ((a >= 0) && (a <= 255)) {
2715 M_CMOVLT(s1, a, d, CONST);
2718 ICONST(REG_ITMP2, a);
2719 M_CMOVLT(s1, REG_ITMP2, d, REG);
2721 store_reg_to_var_int(iptr->dst, d);
2724 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2725 /* val.i = constant */
2727 var_to_reg_int(s1, src, REG_ITMP1);
2728 d = reg_of_var(iptr->dst, REG_ITMP3);
2730 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2731 if ((a == 1) && (iptr[1].val.i == 0)) {
2732 M_CMPLE(REG_ZERO, s1, d, 0);
2733 store_reg_to_var_int(iptr->dst, d);
2736 if ((a == 0) && (iptr[1].val.i == 1)) {
2737 M_CMPLT(s1, REG_ZERO, d, 0);
2738 store_reg_to_var_int(iptr->dst, d);
2742 M_MOV(s1, REG_ITMP1);
2745 ICONST(d, iptr[1].val.i);
2747 if ((a >= 0) && (a <= 255)) {
2748 M_CMOVGE(s1, a, d, CONST);
2751 ICONST(REG_ITMP2, a);
2752 M_CMOVGE(s1, REG_ITMP2, d, REG);
2754 store_reg_to_var_int(iptr->dst, d);
2757 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2758 /* val.i = constant */
2760 var_to_reg_int(s1, src, REG_ITMP1);
2761 d = reg_of_var(iptr->dst, REG_ITMP3);
2763 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2764 if ((a == 1) && (iptr[1].val.i == 0)) {
2765 M_CMPLT(REG_ZERO, s1, d, 0);
2766 store_reg_to_var_int(iptr->dst, d);
2769 if ((a == 0) && (iptr[1].val.i == 1)) {
2770 M_CMPLE(s1, REG_ZERO, d, 0);
2771 store_reg_to_var_int(iptr->dst, d);
2775 M_MOV(s1, REG_ITMP1);
2778 ICONST(d, iptr[1].val.i);
2780 if ((a >= 0) && (a <= 255)) {
2781 M_CMOVGT(s1, a, d, CONST);
2784 ICONST(REG_ITMP2, a);
2785 M_CMOVGT(s1, REG_ITMP2, d, REG);
2787 store_reg_to_var_int(iptr->dst, d);
2790 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2791 /* val.i = constant */
2793 var_to_reg_int(s1, src, REG_ITMP1);
2794 d = reg_of_var(iptr->dst, REG_ITMP3);
2796 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2797 if ((a == 1) && (iptr[1].val.i == 0)) {
2798 M_CMPLE(s1, REG_ZERO, d, 0);
2799 store_reg_to_var_int(iptr->dst, d);
2802 if ((a == 0) && (iptr[1].val.i == 1)) {
2803 M_CMPLT(REG_ZERO, s1, d, 0);
2804 store_reg_to_var_int(iptr->dst, d);
2808 M_MOV(s1, REG_ITMP1);
2811 ICONST(d, iptr[1].val.i);
2813 if ((a >= 0) && (a <= 255)) {
2814 M_CMOVLE(s1, a, d, CONST);
2817 ICONST(REG_ITMP2, a);
2818 M_CMOVLE(s1, REG_ITMP2, d, REG);
2820 store_reg_to_var_int(iptr->dst, d);
2824 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2829 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2830 a = dseg_addaddress ((void*) (builtin_monitorexit));
2831 M_ALD(REG_PV, REG_PV, a);
2832 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
2833 M_JSR(REG_RA, REG_PV);
2834 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2837 var_to_reg_int(s1, src, REG_RESULT);
2838 M_INTMOVE(s1, REG_RESULT);
2839 goto nowperformreturn;
2841 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2845 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2846 a = dseg_addaddress ((void*) (builtin_monitorexit));
2847 M_ALD(REG_PV, REG_PV, a);
2848 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
2849 M_JSR(REG_RA, REG_PV);
2850 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2853 var_to_reg_flt(s1, src, REG_FRESULT);
2854 M_FLTMOVE(s1, REG_FRESULT);
2855 goto nowperformreturn;
2857 case ICMD_RETURN: /* ... ==> ... */
2860 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2861 a = dseg_addaddress ((void*) (builtin_monitorexit));
2862 M_ALD(REG_PV, REG_PV, a);
2863 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
2864 M_JSR(REG_RA, REG_PV);
2865 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2873 p = parentargs_base;
2875 /* restore return address */
2878 {p--; M_LLD (REG_RA, REG_SP, 8 * p);}
2880 /* restore saved registers */
2882 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
2883 {p--; M_LLD(savintregs[r], REG_SP, 8 * p);}
2884 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
2885 {p--; M_DLD(savfltregs[r], REG_SP, 8 * p);}
2887 /* deallocate stack */
2889 if (parentargs_base)
2890 {M_LDA(REG_SP, REG_SP, parentargs_base*8);}
2892 /* call trace function */
2895 M_LDA (REG_SP, REG_SP, -24);
2896 M_AST(REG_RA, REG_SP, REG);
2897 M_LST(REG_RESULT, REG_SP, 8);
2898 M_DST(REG_FRESULT, REG_SP,16);
2899 a = dseg_addaddress (method);
2900 M_ALD(argintregs[0], REG_PV, a);
2901 M_MOV(REG_RESULT, argintregs[1]);
2902 M_FLTMOVE(REG_FRESULT, argfltregs[2]);
2903 a = dseg_addaddress ((void*) (builtin_displaymethodstop));
2904 M_ALD(REG_PV, REG_PV, a);
2905 M_JSR (REG_RA, REG_PV);
2906 s1 = (int)((u1*) mcodeptr - mcodebase);
2907 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
2910 while (ml<-32768) { ml+=65536; mh--; }
2911 M_LDA (REG_PV, REG_RA, ml );
2912 M_LDAH (REG_PV, REG_PV, mh );
2914 M_DLD(REG_FRESULT, REG_SP,16);
2915 M_LLD(REG_RESULT, REG_SP, 8);
2916 M_ALD(REG_RA, REG_SP, REG);
2917 M_LDA (REG_SP, REG_SP, 24);
2920 M_RET(REG_ZERO, REG_RA);
2926 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2930 s4ptr = iptr->val.a;
2931 l = s4ptr[1]; /* low */
2932 i = s4ptr[2]; /* high */
2934 var_to_reg_int(s1, src, REG_ITMP1);
2936 {M_INTMOVE(s1, REG_ITMP1);}
2938 M_LDA(REG_ITMP1, s1, -l);
2944 M_CMPULE(REG_ITMP1, i - 1, REG_ITMP2, CONST);
2946 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
2947 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2, REG);
2949 M_BEQZ(REG_ITMP2, REG);
2950 mcode_addreference(BlockPtrOfPC(s4ptr[0]), mcodeptr);
2952 /* build jump table top down and use address of lowest entry */
2956 dseg_addtarget(BlockPtrOfPC(*--s4ptr));
2960 /* length of dataseg after last dseg_addtarget is used by load */
2962 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2, REG);
2963 M_ALD(REG_ITMP2, REG_ITMP2, -dseglen);
2964 M_JMP(REG_ZERO, REG_ITMP2);
2969 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2971 s4 i, l, val, *s4ptr;
2973 s4ptr = iptr->val.a;
2974 l = s4ptr[0]; /* default */
2975 i = s4ptr[1]; /* count */
2977 MCODECHECK((i<<2)+8);
2978 var_to_reg_int(s1, src, REG_ITMP1);
2982 if ((val >= 0) && (val <= 255)) {
2983 M_CMPEQ(s1, val, REG_ITMP2, CONST);
2986 if ((val >= -32768) && (val <= 32767)) {
2987 M_LDA(REG_ITMP2, REG_ZERO, val);
2990 a = dseg_adds4 (val);
2991 M_ILD(REG_ITMP2, REG_PV, a);
2993 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2, REG);
2995 M_BNEZ(REG_ITMP2, REG);
2996 mcode_addreference(BlockPtrOfPC(s4ptr[1]), mcodeptr);
3000 mcode_addreference(BlockPtrOfPC(l), mcodeptr);
3006 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
3007 /* op1 = return type, val.a = function pointer*/
3011 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
3012 /* op1 = return type, val.a = function pointer*/
3016 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
3017 /* op1 = return type, val.a = function pointer*/
3021 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3022 /* op1 = arg count, val.a = method pointer */
3024 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3025 /* op1 = arg count, val.a = method pointer */
3027 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3028 /* op1 = arg count, val.a = method pointer */
3030 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
3031 /* op1 = arg count, val.a = method pointer */
3039 MCODECHECK((s3 << 1) + 64);
3041 /* copy arguments to registers or stack location */
3043 for (; --s3 >= 0; src = src->prev) {
3044 if (src->varkind == ARGVAR)
3046 if (IS_INT_LNG_TYPE(src->type)) {
3047 if (s3 < INT_ARG_CNT) {
3048 s1 = argintregs[s3];
3049 var_to_reg_int(d, src, s1);
3053 var_to_reg_int(d, src, REG_ITMP1);
3054 M_LST(d, REG_SP, 8 * (s3 - INT_ARG_CNT));
3058 if (s3 < FLT_ARG_CNT) {
3059 s1 = argfltregs[s3];
3060 var_to_reg_flt(d, src, s1);
3064 var_to_reg_flt(d, src, REG_FTMP1);
3065 M_DST(d, REG_SP, 8 * (s3 - FLT_ARG_CNT));
3070 switch (iptr->opc) {
3074 a = dseg_addaddress ((void*) (m));
3076 M_ALD(REG_PV, REG_PV, a); /* Pointer to built-in-function */
3078 goto makeactualcall;
3080 case ICMD_INVOKESTATIC:
3081 case ICMD_INVOKESPECIAL:
3082 a = dseg_addaddress (m->stubroutine);
3084 M_ALD(REG_PV, REG_PV, a ); /* method pointer in r27 */
3087 goto makeactualcall;
3089 case ICMD_INVOKEVIRTUAL:
3091 gen_nullptr_check(argintregs[0]);
3092 M_ALD(REG_METHODPTR, argintregs[0],
3093 OFFSET(java_objectheader, vftbl));
3094 M_ALD(REG_PV, REG_METHODPTR, OFFSET(vftbl, table[0]) +
3095 sizeof(methodptr) * m->vftblindex);
3098 goto makeactualcall;
3100 case ICMD_INVOKEINTERFACE:
3103 gen_nullptr_check(argintregs[0]);
3104 M_ALD(REG_METHODPTR, argintregs[0],
3105 OFFSET(java_objectheader, vftbl));
3106 M_ALD(REG_METHODPTR, REG_METHODPTR,
3107 OFFSET(vftbl, interfacetable[0]) -
3108 sizeof(methodptr*) * ci->index);
3109 M_ALD(REG_PV, REG_METHODPTR,
3110 sizeof(methodptr) * (m - ci->methods));
3113 goto makeactualcall;
3117 sprintf (logtext, "Unkown ICMD-Command: %d", iptr->opc);
3123 M_JSR (REG_RA, REG_PV);
3127 s1 = (int)((u1*) mcodeptr - mcodebase);
3128 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
3131 while (ml<-32768) { ml+=65536; mh--; }
3132 M_LDA (REG_PV, REG_RA, ml );
3133 M_LDAH (REG_PV, REG_PV, mh );
3136 /* d contains return type */
3138 if (d != TYPE_VOID) {
3139 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3140 s1 = reg_of_var(iptr->dst, REG_RESULT);
3141 M_INTMOVE(REG_RESULT, s1);
3142 store_reg_to_var_int(iptr->dst, s1);
3145 s1 = reg_of_var(iptr->dst, REG_FRESULT);
3146 M_FLTMOVE(REG_FRESULT, s1);
3147 store_reg_to_var_flt(iptr->dst, s1);
3154 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3156 /* op1: 0 == array, 1 == class */
3157 /* val.a: (classinfo*) superclass */
3159 /* superclass is an interface:
3161 * return (sub != NULL) &&
3162 * (sub->vftbl->interfacetablelength > super->index) &&
3163 * (sub->vftbl->interfacetable[-super->index] != NULL);
3165 * superclass is a class:
3167 * return ((sub != NULL) && (0
3168 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3169 * super->vftbl->diffvall));
3173 classinfo *super = (classinfo*) iptr->val.a;
3175 var_to_reg_int(s1, src, REG_ITMP1);
3176 d = reg_of_var(iptr->dst, REG_ITMP3);
3178 M_MOV(s1, REG_ITMP1);
3182 if (iptr->op1) { /* class/interface */
3183 if (super->flags & ACC_INTERFACE) { /* interface */
3185 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3186 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3187 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3188 M_BLEZ(REG_ITMP2, 2);
3189 M_ALD(REG_ITMP1, REG_ITMP1,
3190 OFFSET(vftbl, interfacetable[0]) -
3191 super->index * sizeof(methodptr*));
3192 M_CMPULT(REG_ZERO, REG_ITMP1, d, REG); /* REG_ITMP1 != 0 */
3195 s2 = super->vftbl->diffval;
3196 M_BEQZ(s1, 4 + (s2 > 255));
3197 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3198 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3199 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3201 M_CMPULE(REG_ITMP1, s2, d, CONST);
3203 M_LDA(REG_ITMP2, REG_ZERO, s2);
3204 M_CMPULE(REG_ITMP1, REG_ITMP2, d, REG);
3209 panic ("internal error: no inlined array instanceof");
3211 store_reg_to_var_int(iptr->dst, d);
3214 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3216 /* op1: 0 == array, 1 == class */
3217 /* val.a: (classinfo*) superclass */
3219 /* superclass is an interface:
3221 * OK if ((sub == NULL) ||
3222 * (sub->vftbl->interfacetablelength > super->index) &&
3223 * (sub->vftbl->interfacetable[-super->index] != NULL));
3225 * superclass is a class:
3227 * OK if ((sub == NULL) || (0
3228 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3229 * super->vftbl->diffvall));
3233 classinfo *super = (classinfo*) iptr->val.a;
3235 d = reg_of_var(iptr->dst, REG_ITMP3);
3236 var_to_reg_int(s1, src, d);
3237 if (iptr->op1) { /* class/interface */
3238 if (super->flags & ACC_INTERFACE) { /* interface */
3240 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3241 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3242 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3243 M_BLEZ(REG_ITMP2, REG);
3244 mcode_addxcastrefs(mcodeptr);
3245 M_ALD(REG_ITMP2, REG_ITMP1,
3246 OFFSET(vftbl, interfacetable[0]) -
3247 super->index * sizeof(methodptr*));
3248 M_BEQZ(REG_ITMP2, REG);
3249 mcode_addxcastrefs(mcodeptr);
3252 s2 = super->vftbl->diffval;
3253 M_BEQZ(s1, 4 + (s2 != 0) + (s2 > 255));
3254 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3255 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3256 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3258 M_BNEZ(REG_ITMP1, REG);
3260 else if (s2 <= 255) {
3261 M_CMPULE(REG_ITMP1, s2, REG_ITMP2, CONST);
3262 M_BEQZ(REG_ITMP2, REG);
3265 M_LDA(REG_ITMP2, REG_ZERO, s2);
3266 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2, REG);
3267 M_BEQZ(REG_ITMP2, REG);
3269 mcode_addxcastrefs(mcodeptr);
3273 panic ("internal error: no inlined array checkcast");
3276 store_reg_to_var_int(iptr->dst, d);
3279 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
3281 var_to_reg_int(s1, src, REG_ITMP1);
3283 mcode_addxcheckarefs(mcodeptr);
3286 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3287 /* op1 = dimension, val.a = array descriptor */
3289 /* check for negative sizes and copy sizes to stack if necessary */
3291 MCODECHECK((iptr->op1 << 1) + 64);
3293 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3294 var_to_reg_int(s2, src, REG_ITMP1);
3296 mcode_addxcheckarefs(mcodeptr);
3298 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
3300 if (src->varkind != ARGVAR) {
3301 M_LST(s2, REG_SP, 8 * (s1 + INT_ARG_CNT));
3305 /* a0 = dimension count */
3307 M_LDA(argintregs[0], REG_ZERO, iptr->op1);
3309 /* a1 = arraydescriptor */
3311 a = dseg_addaddress(iptr->val.a);
3312 M_ALD(argintregs[1], REG_PV, a);
3314 /* a2 = pointer to dimensions = stack pointer */
3316 M_INTMOVE(REG_SP, argintregs[2]);
3318 a = dseg_addaddress((void*) (builtin_nmultianewarray));
3319 M_ALD(REG_PV, REG_PV, a);
3320 M_JSR(REG_RA, REG_PV);
3321 s1 = (int)((u1*) mcodeptr - mcodebase);
3323 M_LDA (REG_PV, REG_RA, -s1);
3325 s4 ml = -s1, mh = 0;
3326 while (ml < -32768) {ml += 65536; mh--;}
3327 M_LDA(REG_PV, REG_RA, ml);
3328 M_LDAH(REG_PV, REG_PV, mh);
3330 s1 = reg_of_var(iptr->dst, REG_RESULT);
3331 M_INTMOVE(REG_RESULT, s1);
3332 store_reg_to_var_int(iptr->dst, s1);
3336 default: sprintf (logtext, "Unknown pseudo command: %d", iptr->opc);
3339 } /* for instruction */
3341 /* copy values to interface registers */
3343 src = bptr->outstack;
3344 len = bptr->outdepth;
3348 if ((src->varkind != STACKVAR)) {
3350 if (IS_FLT_DBL_TYPE(s2)) {
3351 var_to_reg_flt(s1, src, REG_FTMP1);
3352 if (!(interfaces[len][s2].flags & INMEMORY)) {
3353 M_FLTMOVE(s1,interfaces[len][s2].regoff);
3356 M_DST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3360 var_to_reg_int(s1, src, REG_ITMP1);
3361 if (!(interfaces[len][s2].flags & INMEMORY)) {
3362 M_INTMOVE(s1,interfaces[len][s2].regoff);
3365 M_LST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3371 } /* if (bptr -> flags >= BBREACHED) */
3372 } /* for basic block */
3374 bptr -> mpc = (int)((u1*) mcodeptr - mcodebase);
3377 /* generate bound check stubs */
3379 s4 *xcodeptr = NULL;
3381 for (; xboundrefs != NULL; xboundrefs = xboundrefs->next) {
3382 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3383 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
3384 xboundrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3388 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
3389 xboundrefs->branchpos, (u1*) mcodeptr - mcodebase);
3393 M_LDA(REG_ITMP2_XPC, REG_PV, xboundrefs->branchpos);
3395 if (xcodeptr != NULL) {
3396 M_BR((xcodeptr-mcodeptr)-1);
3399 xcodeptr = mcodeptr;
3401 a = dseg_addaddress(proto_java_lang_ArrayIndexOutOfBoundsException);
3402 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3404 a = dseg_addaddress(asm_handle_exception);
3405 M_ALD(REG_ITMP3, REG_PV, a);
3407 M_JMP(REG_ZERO, REG_ITMP3);
3411 /* generate negative array size check stubs */
3415 for (; xcheckarefs != NULL; xcheckarefs = xcheckarefs->next) {
3416 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3417 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3418 xcheckarefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3422 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3423 xcheckarefs->branchpos, (u1*) mcodeptr - mcodebase);
3427 M_LDA(REG_ITMP2_XPC, REG_PV, xcheckarefs->branchpos);
3429 if (xcodeptr != NULL) {
3430 M_BR((xcodeptr-mcodeptr)-1);
3433 xcodeptr = mcodeptr;
3435 a = dseg_addaddress(proto_java_lang_NegativeArraySizeException);
3436 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3438 a = dseg_addaddress(asm_handle_exception);
3439 M_ALD(REG_ITMP3, REG_PV, a);
3441 M_JMP(REG_ZERO, REG_ITMP3);
3445 /* generate cast check stubs */
3449 for (; xcastrefs != NULL; xcastrefs = xcastrefs->next) {
3450 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3451 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3452 xcastrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3456 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3457 xcastrefs->branchpos, (u1*) mcodeptr - mcodebase);
3461 M_LDA(REG_ITMP2_XPC, REG_PV, xcastrefs->branchpos);
3463 if (xcodeptr != NULL) {
3464 M_BR((xcodeptr-mcodeptr)-1);
3467 xcodeptr = mcodeptr;
3469 a = dseg_addaddress(proto_java_lang_ClassCastException);
3470 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3472 a = dseg_addaddress(asm_handle_exception);
3473 M_ALD(REG_ITMP3, REG_PV, a);
3475 M_JMP(REG_ZERO, REG_ITMP3);
3480 #ifdef SOFTNULLPTRCHECK
3482 /* generate null pointer check stubs */
3486 for (; xnullrefs != NULL; xnullrefs = xnullrefs->next) {
3487 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3488 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3489 xnullrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3493 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3494 xnullrefs->branchpos, (u1*) mcodeptr - mcodebase);
3498 M_LDA(REG_ITMP2_XPC, REG_PV, xnullrefs->branchpos - 4);
3500 if (xcodeptr != NULL) {
3501 M_BR((xcodeptr-mcodeptr)-1);
3504 xcodeptr = mcodeptr;
3506 a = dseg_addaddress(proto_java_lang_NullPointerException);
3507 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3509 a = dseg_addaddress(asm_handle_exception);
3510 M_ALD(REG_ITMP3, REG_PV, a);
3512 M_JMP(REG_ZERO, REG_ITMP3);
3519 mcode_finish((int)((u1*) mcodeptr - mcodebase));
3523 /* redefinition of code generation macros (compiling into array) **************/
3526 These macros are newly defined to allow code generation into an array.
3527 This is necessary, because the original M_.. macros generate code by
3528 calling 'mcode_adds4' that uses an additional data structure to
3531 For a faster (but less flexible) version to generate code, these
3532 macros directly use the (s4* p) - pointer to put the code directly
3533 in a locally defined array.
3534 This makes sense only for the stub-generation-routines below.
3538 #define M_OP3(op,fu,a,b,c,const) \
3539 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<(16-3*(const)))| \
3540 ((const)<<12)|((fu)<<5)|((c)) )
3542 #define M_FOP3(op,fu,a,b,c) \
3543 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<16)|((fu)<<5)|(c) )
3545 #define M_BRA(op,a,disp) \
3546 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((disp)&0x1fffff) )
3548 #define M_MEM(op,a,b,disp) \
3549 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<16)|((disp)&0xffff) )
3552 /* function createcompilerstub *************************************************
3554 creates a stub routine which calls the compiler
3556 *******************************************************************************/
3558 #define COMPSTUBSIZE 3
3560 u1 *createcompilerstub (methodinfo *m)
3562 u8 *s = CNEW (u8, COMPSTUBSIZE); /* memory to hold the stub */
3563 s4 *p = (s4*) s; /* code generation pointer */
3565 /* code for the stub */
3566 M_ALD (REG_PV, REG_PV, 16); /* load pointer to the compiler */
3567 M_JMP (0, REG_PV); /* jump to the compiler, return address
3568 in reg 0 is used as method pointer */
3569 s[1] = (u8) m; /* literals to be adressed */
3570 s[2] = (u8) asm_call_jit_compiler; /* jump directly via PV from above */
3573 count_cstub_len += COMPSTUBSIZE * 8;
3580 /* function removecompilerstub *************************************************
3582 deletes a compilerstub from memory (simply by freeing it)
3584 *******************************************************************************/
3586 void removecompilerstub (u1 *stub)
3588 CFREE (stub, COMPSTUBSIZE * 8);
3592 /* function: ncreatenativestub *************************************************
3594 creates a stub routine which calls a native method
3596 *******************************************************************************/
3598 #define NATIVESTUBSIZE 11
3600 u1 *ncreatenativestub (functionptr f, methodinfo *m)
3602 u8 *s = CNEW (u8, NATIVESTUBSIZE); /* memory to hold the stub */
3603 s4 *p = (s4*) s; /* code generation pointer */
3605 M_LDA (REG_SP, REG_SP, -8); /* build up stackframe */
3606 M_AST (REG_RA, REG_SP, REG); /* store return address */
3608 M_ALD (REG_PV, REG_PV, 8*8); /* load adress of native method */
3609 M_JSR (REG_RA, REG_PV); /* call native method */
3611 M_LDA (REG_PV, REG_RA, -4*4); /* recompute pv from ra */
3612 M_ALD (REG_ITMP3, REG_PV, 9*8); /* get address of exceptionptr */
3614 M_ALD (REG_RA, REG_SP, REG); /* load return address */
3615 M_ALD (REG_ITMP1, REG_ITMP3, REG); /* load exception into reg. itmp1 */
3617 M_LDA (REG_SP, REG_SP, 8); /* remove stackframe */
3618 M_BNEZ (REG_ITMP1, CONST); /* if no exception then return */
3620 M_RET (REG_ZERO, REG_RA); /* return to caller */
3622 M_AST (REG_ZERO, REG_ITMP3, REG); /* store NULL into exceptionptr */
3623 M_LDA (REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
3625 M_ALD (REG_ITMP3, REG_PV,10*8); /* load asm exception handler address */
3626 M_JMP (REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
3629 s[8] = (u8) f; /* address of native method */
3630 s[9] = (u8) (&exceptionptr); /* address of exceptionptr */
3631 s[10]= (u8) (asm_handle_nat_exception); /* addr of asm exception handler */
3634 count_nstub_len += NATIVESTUBSIZE * 8;
3641 /* function: removenativestub **************************************************
3643 removes a previously created native-stub from memory
3645 *******************************************************************************/
3647 void removenativestub (u1 *stub)
3649 CFREE (stub, NATIVESTUBSIZE * 8);
3654 * These are local overrides for various environment variables in Emacs.
3655 * Please do not remove this and leave it at the end of the file, where
3656 * Emacs will automagically detect them.
3657 * ---------------------------------------------------------------------
3660 * indent-tabs-mode: t