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) \
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 /* NullPointerException signal handler for hardware null pointer check */
226 void catch_NullPointerException(int sig, int code, sigctx_struct *sigctx)
232 /* Reset signal handler - necessary for SysV, does no harm for BSD */
234 instr = *((int*)(sigctx->sc_pc));
235 faultaddr = sigctx->sc_regs[(instr >> 16) & 0x1f];
237 if (faultaddr == 0) {
238 signal(sig, (void*) catch_NullPointerException); /* reinstall handler */
240 sigaddset(&nsig, sig);
241 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
242 sigctx->sc_regs[REG_ITMP1_XPTR] =
243 (long) proto_java_lang_NullPointerException;
244 sigctx->sc_regs[REG_ITMP2_XPC] = sigctx->sc_pc;
245 sigctx->sc_pc = (long) asm_handle_nat_exception;
249 faultaddr += (long) ((instr << 16) >> 16);
250 fprintf(stderr, "faulting address: 0x%16lx\n", faultaddr);
251 panic("Stack overflow");
258 void init_exceptions(void)
263 /* Linux on Digital Alpha needs an initialisation of the ieee floating point
264 control for IEEE compliant arithmetic (option -mieee of GCC). Under
265 Digital Unix this is done automatically.
270 extern unsigned long ieee_get_fp_control();
271 extern void ieee_set_fp_control(unsigned long fp_control);
273 void init_exceptions(void)
275 /* initialize floating point control */
277 ieee_set_fp_control(ieee_get_fp_control()
278 & ~IEEE_TRAP_ENABLE_INV
279 & ~IEEE_TRAP_ENABLE_DZE
280 /* & ~IEEE_TRAP_ENABLE_UNF we dont want underflow */
281 & ~IEEE_TRAP_ENABLE_OVF);
284 /* install signal handlers we need to convert to exceptions */
289 signal(SIGSEGV, (void*) catch_NullPointerException);
293 signal(SIGBUS, (void*) catch_NullPointerException);
299 /* function gen_mcode **********************************************************
301 generates machine code
303 *******************************************************************************/
305 #define MethodPointer -8
306 #define FrameSize -12
311 #define ExTableSize -32
312 #define ExTableStart -32
314 #define ExEntrySize -32
317 #define ExHandlerPC -24
318 #define ExCatchType -32
320 static void gen_mcode()
322 int len, s1, s2, s3, d, bbs;
333 savedregs_num = (isleafmethod) ? 0 : 1; /* space to save the RA */
335 /* space to save used callee saved registers */
337 savedregs_num += (savintregcnt - maxsavintreguse);
338 savedregs_num += (savfltregcnt - maxsavfltreguse);
340 parentargs_base = maxmemuse + savedregs_num;
342 #ifdef USE_THREADS /* space to save argument of monitor_enter */
344 if (checksync && (method->flags & ACC_SYNCHRONIZED))
349 /* create method header */
351 (void) dseg_addaddress(method); /* MethodPointer */
352 (void) dseg_adds4(parentargs_base * 8); /* FrameSize */
356 /* IsSync contains the offset relative to the stack pointer for the
357 argument of monitor_exit used in the exception handler. Since the
358 offset could be zero and give a wrong meaning of the flag it is
362 if (checksync && (method->flags & ACC_SYNCHRONIZED))
363 (void) dseg_adds4((maxmemuse + 1) * 8); /* IsSync */
368 (void) dseg_adds4(0); /* IsSync */
370 (void) dseg_adds4(isleafmethod); /* IsLeaf */
371 (void) dseg_adds4(savintregcnt - maxsavintreguse); /* IntSave */
372 (void) dseg_adds4(savfltregcnt - maxsavfltreguse); /* FltSave */
373 (void) dseg_adds4(exceptiontablelength); /* ExTableSize */
375 /* create exception table */
377 for (len = 0; len < exceptiontablelength; len++) {
378 dseg_addtarget(BlockPtrOfPC(extable[len].startpc));
379 dseg_addtarget(BlockPtrOfPC(extable[len].endpc));
380 dseg_addtarget(BlockPtrOfPC(extable[len].handlerpc));
381 (void) dseg_addaddress(extable[len].catchtype);
384 /* initialize mcode variables */
386 mcodeptr = (s4*) mcodebase;
387 mcodeend = (s4*) (mcodebase + mcodesize);
388 MCODECHECK(128 + mparamcount);
390 /* create stack frame (if necessary) */
393 {M_LDA (REG_SP, REG_SP, -parentargs_base * 8);}
395 /* save return address and used callee saved registers */
399 {p--; M_AST (REG_RA, REG_SP, 8*p);}
400 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
401 {p--; M_LST (savintregs[r], REG_SP, 8 * p);}
402 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
403 {p--; M_DST (savfltregs[r], REG_SP, 8 * p);}
405 /* save monitorenter argument */
408 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
409 if (method->flags & ACC_STATIC) {
410 p = dseg_addaddress (class);
411 M_ALD(REG_ITMP1, REG_PV, p);
412 M_AST(REG_ITMP1, REG_SP, 8 * maxmemuse);
415 M_AST (argintregs[0], REG_SP, 8 * maxmemuse);
420 /* copy argument registers to stack and call trace function with pointer
421 to arguments on stack. ToDo: save floating point registers !!!!!!!!!
424 if (runverbose && isleafmethod) {
425 M_LDA (REG_SP, REG_SP, -(14*8));
426 M_AST(REG_RA, REG_SP, 1*8);
428 M_LST(argintregs[0], REG_SP, 2*8);
429 M_LST(argintregs[1], REG_SP, 3*8);
430 M_LST(argintregs[2], REG_SP, 4*8);
431 M_LST(argintregs[3], REG_SP, 5*8);
432 M_LST(argintregs[4], REG_SP, 6*8);
433 M_LST(argintregs[5], REG_SP, 7*8);
435 M_DST(argfltregs[0], REG_SP, 8*8);
436 M_DST(argfltregs[1], REG_SP, 9*8);
437 M_DST(argfltregs[2], REG_SP, 10*8);
438 M_DST(argfltregs[3], REG_SP, 11*8);
439 M_DST(argfltregs[4], REG_SP, 12*8);
440 M_DST(argfltregs[5], REG_SP, 13*8);
442 p = dseg_addaddress (method);
443 M_ALD(REG_ITMP1, REG_PV, p);
444 M_AST(REG_ITMP1, REG_SP, 0);
445 p = dseg_addaddress ((void*) (builtin_trace_args));
446 M_ALD(REG_PV, REG_PV, p);
447 M_JSR(REG_RA, REG_PV);
448 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
449 M_ALD(REG_RA, REG_SP, 1*8);
451 M_LLD(argintregs[0], REG_SP, 2*8);
452 M_LLD(argintregs[1], REG_SP, 3*8);
453 M_LLD(argintregs[2], REG_SP, 4*8);
454 M_LLD(argintregs[3], REG_SP, 5*8);
455 M_LLD(argintregs[4], REG_SP, 6*8);
456 M_LLD(argintregs[5], REG_SP, 7*8);
458 M_DLD(argfltregs[0], REG_SP, 8*8);
459 M_DLD(argfltregs[1], REG_SP, 9*8);
460 M_DLD(argfltregs[2], REG_SP, 10*8);
461 M_DLD(argfltregs[3], REG_SP, 11*8);
462 M_DLD(argfltregs[4], REG_SP, 12*8);
463 M_DLD(argfltregs[5], REG_SP, 13*8);
465 M_LDA (REG_SP, REG_SP, 14*8);
468 /* take arguments out of register or stack frame */
470 for (p = 0, l = 0; p < mparamcount; p++) {
472 var = &(locals[l][t]);
474 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
479 if (IS_INT_LNG_TYPE(t)) { /* integer args */
480 if (p < INT_ARG_CNT) { /* register arguments */
481 if (!(var->flags & INMEMORY)) /* reg arg -> register */
482 {M_INTMOVE (argintregs[p], r);}
483 else /* reg arg -> spilled */
484 M_LST (argintregs[p], REG_SP, 8 * r);
486 else { /* stack arguments */
487 pa = p - INT_ARG_CNT;
488 if (!(var->flags & INMEMORY)) /* stack arg -> register */
489 M_LLD (r, REG_SP, 8 * (parentargs_base + pa));
490 else { /* stack arg -> spilled */
491 M_LLD (REG_ITMP1, REG_SP, 8 * (parentargs_base + pa));
492 M_LST (REG_ITMP1, REG_SP, 8 * r);
496 else { /* floating args */
497 if (p < FLT_ARG_CNT) { /* register arguments */
498 if (!(var->flags & INMEMORY)) /* reg arg -> register */
499 {M_FLTMOVE (argfltregs[p], r);}
500 else /* reg arg -> spilled */
501 M_DST (argfltregs[p], REG_SP, 8 * r);
503 else { /* stack arguments */
504 pa = p - FLT_ARG_CNT;
505 if (!(var->flags & INMEMORY)) /* stack-arg -> register */
506 M_DLD (r, REG_SP, 8 * (parentargs_base + pa) );
507 else { /* stack-arg -> spilled */
508 M_DLD (REG_FTMP1, REG_SP, 8 * (parentargs_base + pa));
509 M_DST (REG_FTMP1, REG_SP, 8 * r);
515 /* call trace function */
517 if (runverbose && !isleafmethod) {
518 M_LDA (REG_SP, REG_SP, -8);
519 p = dseg_addaddress (method);
520 M_ALD(REG_ITMP1, REG_PV, p);
521 M_AST(REG_ITMP1, REG_SP, 0);
522 p = dseg_addaddress ((void*) (builtin_trace_args));
523 M_ALD(REG_PV, REG_PV, p);
524 M_JSR(REG_RA, REG_PV);
525 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
526 M_LDA(REG_SP, REG_SP, 8);
529 /* call monitorenter function */
532 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
533 p = dseg_addaddress ((void*) (builtin_monitorenter));
534 M_ALD(REG_PV, REG_PV, p);
535 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
536 M_JSR(REG_RA, REG_PV);
537 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
542 /* end of header generation */
544 /* walk through all basic blocks */
546 for (bbs = block_count, bptr = block; --bbs >= 0; bptr++) {
547 bptr -> mpc = (int)((u1*) mcodeptr - mcodebase);
549 if (bptr->flags >= BBREACHED) {
551 /* branch resolving */
555 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
556 gen_resolvebranch((u1*) mcodebase + brefs->branchpos,
557 brefs->branchpos, bptr->mpc);
561 /* copy interface registers to their destination */
566 while (src != NULL) {
568 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
569 d = reg_of_var(src, REG_ITMP1);
570 M_INTMOVE(REG_ITMP1, d);
571 store_reg_to_var_int(src, d);
574 d = reg_of_var(src, REG_IFTMP);
575 if ((src->varkind != STACKVAR)) {
577 if (IS_FLT_DBL_TYPE(s2)) {
578 if (!(interfaces[len][s2].flags & INMEMORY)) {
579 s1 = interfaces[len][s2].regoff;
583 M_DLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
585 store_reg_to_var_flt(src, d);
588 if (!(interfaces[len][s2].flags & INMEMORY)) {
589 s1 = interfaces[len][s2].regoff;
593 M_LLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
595 store_reg_to_var_int(src, d);
602 /* walk through all instructions */
606 for (iptr = bptr->iinstr;
608 src = iptr->dst, len--, iptr++) {
610 MCODECHECK(64); /* an instruction usually needs < 64 words */
613 case ICMD_NOP: /* ... ==> ... */
616 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
618 var_to_reg_int(s1, src, REG_ITMP1);
620 mcode_addxnullrefs(mcodeptr);
623 /* constant operations ************************************************/
625 #define ICONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
626 else{a=dseg_adds4(c);M_ILD(r,REG_PV,a);}
628 #define LCONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
629 else{a=dseg_adds8(c);M_LLD(r,REG_PV,a);}
631 case ICMD_ICONST: /* ... ==> ..., constant */
632 /* op1 = 0, val.i = constant */
634 d = reg_of_var(iptr->dst, REG_ITMP1);
635 ICONST(d, iptr->val.i);
636 store_reg_to_var_int(iptr->dst, d);
639 case ICMD_LCONST: /* ... ==> ..., constant */
640 /* op1 = 0, val.l = constant */
642 d = reg_of_var(iptr->dst, REG_ITMP1);
643 LCONST(d, iptr->val.l);
644 store_reg_to_var_int(iptr->dst, d);
647 case ICMD_FCONST: /* ... ==> ..., constant */
648 /* op1 = 0, val.f = constant */
650 d = reg_of_var (iptr->dst, REG_FTMP1);
651 a = dseg_addfloat (iptr->val.f);
653 store_reg_to_var_flt (iptr->dst, d);
656 case ICMD_DCONST: /* ... ==> ..., constant */
657 /* op1 = 0, val.d = constant */
659 d = reg_of_var (iptr->dst, REG_FTMP1);
660 a = dseg_adddouble (iptr->val.d);
662 store_reg_to_var_flt (iptr->dst, d);
665 case ICMD_ACONST: /* ... ==> ..., constant */
666 /* op1 = 0, val.a = constant */
668 d = reg_of_var(iptr->dst, REG_ITMP1);
670 a = dseg_addaddress (iptr->val.a);
674 M_INTMOVE(REG_ZERO, d);
676 store_reg_to_var_int(iptr->dst, d);
680 /* load/store operations **********************************************/
682 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
683 case ICMD_LLOAD: /* op1 = local variable */
686 d = reg_of_var(iptr->dst, REG_ITMP1);
687 if ((iptr->dst->varkind == LOCALVAR) &&
688 (iptr->dst->varnum == iptr->op1))
690 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
691 if (var->flags & INMEMORY)
692 M_LLD(d, REG_SP, 8 * var->regoff);
694 {M_INTMOVE(var->regoff,d);}
695 store_reg_to_var_int(iptr->dst, d);
698 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
699 case ICMD_DLOAD: /* op1 = local variable */
701 d = reg_of_var(iptr->dst, REG_FTMP1);
702 if ((iptr->dst->varkind == LOCALVAR) &&
703 (iptr->dst->varnum == iptr->op1))
705 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
706 if (var->flags & INMEMORY)
707 M_DLD(d, REG_SP, 8 * var->regoff);
709 {M_FLTMOVE(var->regoff,d);}
710 store_reg_to_var_flt(iptr->dst, d);
714 case ICMD_ISTORE: /* ..., value ==> ... */
715 case ICMD_LSTORE: /* op1 = local variable */
718 if ((src->varkind == LOCALVAR) &&
719 (src->varnum == iptr->op1))
721 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
722 if (var->flags & INMEMORY) {
723 var_to_reg_int(s1, src, REG_ITMP1);
724 M_LST(s1, REG_SP, 8 * var->regoff);
727 var_to_reg_int(s1, src, var->regoff);
728 M_INTMOVE(s1, var->regoff);
732 case ICMD_FSTORE: /* ..., value ==> ... */
733 case ICMD_DSTORE: /* op1 = local variable */
735 if ((src->varkind == LOCALVAR) &&
736 (src->varnum == iptr->op1))
738 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
739 if (var->flags & INMEMORY) {
740 var_to_reg_flt(s1, src, REG_FTMP1);
741 M_DST(s1, REG_SP, 8 * var->regoff);
744 var_to_reg_flt(s1, src, var->regoff);
745 M_FLTMOVE(s1, var->regoff);
750 /* pop/dup/swap operations ********************************************/
752 /* attention: double and longs are only one entry in CACAO ICMDs */
754 case ICMD_POP: /* ..., value ==> ... */
755 case ICMD_POP2: /* ..., value, value ==> ... */
758 #define M_COPY(from,to) \
759 d = reg_of_var(to, REG_IFTMP); \
760 if ((from->regoff != to->regoff) || \
761 ((from->flags ^ to->flags) & INMEMORY)) { \
762 if (IS_FLT_DBL_TYPE(from->type)) { \
763 var_to_reg_flt(s1, from, d); \
765 store_reg_to_var_flt(to, d); \
768 var_to_reg_int(s1, from, d); \
770 store_reg_to_var_int(to, d); \
774 case ICMD_DUP: /* ..., a ==> ..., a, a */
775 M_COPY(src, iptr->dst);
778 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
780 M_COPY(src, iptr->dst->prev->prev);
782 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
784 M_COPY(src, iptr->dst);
785 M_COPY(src->prev, iptr->dst->prev);
788 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
790 M_COPY(src->prev, iptr->dst->prev->prev->prev);
792 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
794 M_COPY(src, iptr->dst);
795 M_COPY(src->prev, iptr->dst->prev);
796 M_COPY(src->prev->prev, iptr->dst->prev->prev);
797 M_COPY(src, iptr->dst->prev->prev->prev);
800 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
802 M_COPY(src, iptr->dst);
803 M_COPY(src->prev, iptr->dst->prev);
804 M_COPY(src->prev->prev, iptr->dst->prev->prev);
805 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
806 M_COPY(src, iptr->dst->prev->prev->prev->prev);
807 M_COPY(src->prev, iptr->dst->prev->prev->prev->prev->prev);
810 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
812 M_COPY(src, iptr->dst->prev);
813 M_COPY(src->prev, iptr->dst);
817 /* integer operations *************************************************/
819 case ICMD_INEG: /* ..., value ==> ..., - value */
821 var_to_reg_int(s1, src, REG_ITMP1);
822 d = reg_of_var(iptr->dst, REG_ITMP3);
823 M_ISUB(REG_ZERO, s1, d);
824 store_reg_to_var_int(iptr->dst, d);
827 case ICMD_LNEG: /* ..., value ==> ..., - value */
829 var_to_reg_int(s1, src, REG_ITMP1);
830 d = reg_of_var(iptr->dst, REG_ITMP3);
831 M_LSUB(REG_ZERO, s1, d);
832 store_reg_to_var_int(iptr->dst, d);
835 case ICMD_I2L: /* ..., value ==> ..., value */
837 var_to_reg_int(s1, src, REG_ITMP1);
838 d = reg_of_var(iptr->dst, REG_ITMP3);
840 store_reg_to_var_int(iptr->dst, d);
843 case ICMD_L2I: /* ..., value ==> ..., value */
845 var_to_reg_int(s1, src, REG_ITMP1);
846 d = reg_of_var(iptr->dst, REG_ITMP3);
847 M_IADD(s1, REG_ZERO, d );
848 store_reg_to_var_int(iptr->dst, d);
851 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
853 var_to_reg_int(s1, src, REG_ITMP1);
854 d = reg_of_var(iptr->dst, REG_ITMP3);
855 if (has_ext_instr_set) {
859 M_SLL_IMM(s1, 56, d);
860 M_SRA_IMM( d, 56, d);
862 store_reg_to_var_int(iptr->dst, d);
865 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
867 var_to_reg_int(s1, src, REG_ITMP1);
868 d = reg_of_var(iptr->dst, REG_ITMP3);
870 store_reg_to_var_int(iptr->dst, d);
873 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
875 var_to_reg_int(s1, src, REG_ITMP1);
876 d = reg_of_var(iptr->dst, REG_ITMP3);
877 if (has_ext_instr_set) {
881 M_SLL_IMM(s1, 48, d);
882 M_SRA_IMM( d, 48, d);
884 store_reg_to_var_int(iptr->dst, d);
888 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
890 var_to_reg_int(s1, src->prev, REG_ITMP1);
891 var_to_reg_int(s2, src, REG_ITMP2);
892 d = reg_of_var(iptr->dst, REG_ITMP3);
894 store_reg_to_var_int(iptr->dst, d);
897 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
898 /* val.i = constant */
900 var_to_reg_int(s1, src, REG_ITMP1);
901 d = reg_of_var(iptr->dst, REG_ITMP3);
902 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
903 M_IADD_IMM(s1, iptr->val.i, d);
906 ICONST(REG_ITMP2, iptr->val.i);
907 M_IADD(s1, REG_ITMP2, d);
909 store_reg_to_var_int(iptr->dst, d);
912 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
914 var_to_reg_int(s1, src->prev, REG_ITMP1);
915 var_to_reg_int(s2, src, REG_ITMP2);
916 d = reg_of_var(iptr->dst, REG_ITMP3);
918 store_reg_to_var_int(iptr->dst, d);
921 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
922 /* val.l = constant */
924 var_to_reg_int(s1, src, REG_ITMP1);
925 d = reg_of_var(iptr->dst, REG_ITMP3);
926 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
927 M_LADD_IMM(s1, iptr->val.l, d);
930 LCONST(REG_ITMP2, iptr->val.l);
931 M_LADD(s1, REG_ITMP2, d);
933 store_reg_to_var_int(iptr->dst, d);
936 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
938 var_to_reg_int(s1, src->prev, REG_ITMP1);
939 var_to_reg_int(s2, src, REG_ITMP2);
940 d = reg_of_var(iptr->dst, REG_ITMP3);
942 store_reg_to_var_int(iptr->dst, d);
945 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
946 /* val.i = constant */
948 var_to_reg_int(s1, src, REG_ITMP1);
949 d = reg_of_var(iptr->dst, REG_ITMP3);
950 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
951 M_ISUB_IMM(s1, iptr->val.i, d);
954 ICONST(REG_ITMP2, iptr->val.i);
955 M_ISUB(s1, REG_ITMP2, d);
957 store_reg_to_var_int(iptr->dst, d);
960 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
962 var_to_reg_int(s1, src->prev, REG_ITMP1);
963 var_to_reg_int(s2, src, REG_ITMP2);
964 d = reg_of_var(iptr->dst, REG_ITMP3);
966 store_reg_to_var_int(iptr->dst, d);
969 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
970 /* val.l = constant */
972 var_to_reg_int(s1, src, REG_ITMP1);
973 d = reg_of_var(iptr->dst, REG_ITMP3);
974 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
975 M_LSUB_IMM(s1, iptr->val.l, d);
978 LCONST(REG_ITMP2, iptr->val.l);
979 M_LSUB(s1, REG_ITMP2, d);
981 store_reg_to_var_int(iptr->dst, d);
984 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
986 var_to_reg_int(s1, src->prev, REG_ITMP1);
987 var_to_reg_int(s2, src, REG_ITMP2);
988 d = reg_of_var(iptr->dst, REG_ITMP3);
990 store_reg_to_var_int(iptr->dst, d);
993 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
994 /* val.i = constant */
996 var_to_reg_int(s1, src, REG_ITMP1);
997 d = reg_of_var(iptr->dst, REG_ITMP3);
998 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
999 M_IMUL_IMM(s1, iptr->val.i, d);
1002 ICONST(REG_ITMP2, iptr->val.i);
1003 M_IMUL(s1, REG_ITMP2, d);
1005 store_reg_to_var_int(iptr->dst, d);
1008 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1010 var_to_reg_int(s1, src->prev, REG_ITMP1);
1011 var_to_reg_int(s2, src, REG_ITMP2);
1012 d = reg_of_var(iptr->dst, REG_ITMP3);
1014 store_reg_to_var_int(iptr->dst, d);
1017 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
1018 /* val.l = constant */
1020 var_to_reg_int(s1, src, REG_ITMP1);
1021 d = reg_of_var(iptr->dst, REG_ITMP3);
1022 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1023 M_LMUL_IMM(s1, iptr->val.l, d);
1026 LCONST(REG_ITMP2, iptr->val.l);
1027 M_LMUL(s1, REG_ITMP2, d);
1029 store_reg_to_var_int(iptr->dst, d);
1032 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
1033 case ICMD_LDIVPOW2: /* val.i = constant */
1035 var_to_reg_int(s1, src, REG_ITMP1);
1036 d = reg_of_var(iptr->dst, REG_ITMP3);
1037 if (iptr->val.i <= 15) {
1038 M_LDA(REG_ITMP2, s1, (1 << iptr->val.i) -1);
1039 M_CMOVGE(s1, s1, REG_ITMP2);
1042 M_SRA_IMM(s1, 63, REG_ITMP2);
1043 M_SRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
1044 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1046 M_SRA_IMM(REG_ITMP2, iptr->val.i, d);
1047 store_reg_to_var_int(iptr->dst, d);
1050 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1052 var_to_reg_int(s1, src->prev, REG_ITMP1);
1053 var_to_reg_int(s2, src, REG_ITMP2);
1054 d = reg_of_var(iptr->dst, REG_ITMP3);
1055 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1056 M_SLL(s1, REG_ITMP3, d);
1057 M_IADD(d, REG_ZERO, d);
1058 store_reg_to_var_int(iptr->dst, d);
1061 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1062 /* val.i = constant */
1064 var_to_reg_int(s1, src, REG_ITMP1);
1065 d = reg_of_var(iptr->dst, REG_ITMP3);
1066 M_SLL_IMM(s1, iptr->val.i & 0x1f, d);
1067 M_IADD(d, REG_ZERO, d);
1068 store_reg_to_var_int(iptr->dst, d);
1071 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1073 var_to_reg_int(s1, src->prev, REG_ITMP1);
1074 var_to_reg_int(s2, src, REG_ITMP2);
1075 d = reg_of_var(iptr->dst, REG_ITMP3);
1076 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1077 M_SRA(s1, REG_ITMP3, d);
1078 store_reg_to_var_int(iptr->dst, d);
1081 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1082 /* val.i = constant */
1084 var_to_reg_int(s1, src, REG_ITMP1);
1085 d = reg_of_var(iptr->dst, REG_ITMP3);
1086 M_SRA_IMM(s1, iptr->val.i & 0x1f, d);
1087 store_reg_to_var_int(iptr->dst, d);
1090 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1092 var_to_reg_int(s1, src->prev, REG_ITMP1);
1093 var_to_reg_int(s2, src, REG_ITMP2);
1094 d = reg_of_var(iptr->dst, REG_ITMP3);
1095 M_AND_IMM(s2, 0x1f, REG_ITMP2);
1097 M_SRL(d, REG_ITMP2, d);
1098 M_IADD(d, REG_ZERO, d);
1099 store_reg_to_var_int(iptr->dst, d);
1102 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1103 /* val.i = constant */
1105 var_to_reg_int(s1, src, REG_ITMP1);
1106 d = reg_of_var(iptr->dst, REG_ITMP3);
1108 M_SRL_IMM(d, iptr->val.i & 0x1f, d);
1109 M_IADD(d, REG_ZERO, d);
1110 store_reg_to_var_int(iptr->dst, d);
1113 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1115 var_to_reg_int(s1, src->prev, REG_ITMP1);
1116 var_to_reg_int(s2, src, REG_ITMP2);
1117 d = reg_of_var(iptr->dst, REG_ITMP3);
1119 store_reg_to_var_int(iptr->dst, d);
1122 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1123 /* val.l = constant */
1125 var_to_reg_int(s1, src, REG_ITMP1);
1126 d = reg_of_var(iptr->dst, REG_ITMP3);
1127 M_SLL_IMM(s1, iptr->val.l & 0x3f, d);
1128 store_reg_to_var_int(iptr->dst, d);
1131 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1133 var_to_reg_int(s1, src->prev, REG_ITMP1);
1134 var_to_reg_int(s2, src, REG_ITMP2);
1135 d = reg_of_var(iptr->dst, REG_ITMP3);
1137 store_reg_to_var_int(iptr->dst, d);
1140 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1141 /* val.l = constant */
1143 var_to_reg_int(s1, src, REG_ITMP1);
1144 d = reg_of_var(iptr->dst, REG_ITMP3);
1145 M_SRA_IMM(s1, iptr->val.l & 0x3f, d);
1146 store_reg_to_var_int(iptr->dst, d);
1149 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1151 var_to_reg_int(s1, src->prev, REG_ITMP1);
1152 var_to_reg_int(s2, src, REG_ITMP2);
1153 d = reg_of_var(iptr->dst, REG_ITMP3);
1155 store_reg_to_var_int(iptr->dst, d);
1158 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1159 /* val.l = constant */
1161 var_to_reg_int(s1, src, REG_ITMP1);
1162 d = reg_of_var(iptr->dst, REG_ITMP3);
1163 M_SRL_IMM(s1, iptr->val.l & 0x3f, d);
1164 store_reg_to_var_int(iptr->dst, d);
1167 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1170 var_to_reg_int(s1, src->prev, REG_ITMP1);
1171 var_to_reg_int(s2, src, REG_ITMP2);
1172 d = reg_of_var(iptr->dst, REG_ITMP3);
1174 store_reg_to_var_int(iptr->dst, d);
1177 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1178 /* val.i = constant */
1180 var_to_reg_int(s1, src, REG_ITMP1);
1181 d = reg_of_var(iptr->dst, REG_ITMP3);
1182 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1183 M_AND_IMM(s1, iptr->val.i, d);
1185 else if (iptr->val.i == 0xffff) {
1188 else if (iptr->val.i == 0xffffff) {
1189 M_ZAPNOT_IMM(s1, 0x07, d);
1192 ICONST(REG_ITMP2, iptr->val.i);
1193 M_AND(s1, REG_ITMP2, d);
1195 store_reg_to_var_int(iptr->dst, d);
1198 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1199 /* val.i = constant */
1201 var_to_reg_int(s1, src, REG_ITMP1);
1202 d = reg_of_var(iptr->dst, REG_ITMP3);
1204 M_MOV(s1, REG_ITMP1);
1207 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1208 M_AND_IMM(s1, iptr->val.i, d);
1210 M_ISUB(REG_ZERO, s1, d);
1211 M_AND_IMM(d, iptr->val.i, d);
1213 else if (iptr->val.i == 0xffff) {
1216 M_ISUB(REG_ZERO, s1, d);
1219 else if (iptr->val.i == 0xffffff) {
1220 M_ZAPNOT_IMM(s1, 0x07, d);
1222 M_ISUB(REG_ZERO, s1, d);
1223 M_ZAPNOT_IMM(d, 0x07, d);
1226 ICONST(REG_ITMP2, iptr->val.i);
1227 M_AND(s1, REG_ITMP2, d);
1229 M_ISUB(REG_ZERO, s1, d);
1230 M_AND(d, REG_ITMP2, d);
1232 M_ISUB(REG_ZERO, d, d);
1233 store_reg_to_var_int(iptr->dst, d);
1236 case ICMD_IREM0X10001: /* ..., value ==> ..., value % 0x100001 */
1238 /* b = value & 0xffff;
1240 a = ((b - a) & 0xffff) + (b < a);
1242 var_to_reg_int(s1, src, REG_ITMP1);
1243 d = reg_of_var(iptr->dst, REG_ITMP3);
1245 M_MOV(s1, REG_ITMP3);
1249 M_CZEXT(s1, REG_ITMP2);
1250 M_SRA_IMM(s1, 16, d);
1251 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1252 M_ISUB(REG_ITMP2, d, d);
1254 M_IADD(d, REG_ITMP1, d);
1255 M_BR(11 + (s1 == REG_ITMP1));
1256 M_ISUB(REG_ZERO, s1, REG_ITMP1);
1257 M_CZEXT(REG_ITMP1, REG_ITMP2);
1258 M_SRA_IMM(REG_ITMP1, 16, d);
1259 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1260 M_ISUB(REG_ITMP2, d, d);
1262 M_IADD(d, REG_ITMP1, d);
1263 M_ISUB(REG_ZERO, d, d);
1264 if (s1 == REG_ITMP1) {
1265 var_to_reg_int(s1, src, REG_ITMP1);
1267 M_SLL_IMM(s1, 33, REG_ITMP2);
1268 M_CMPEQ(REG_ITMP2, REG_ZERO, REG_ITMP2);
1269 M_ISUB(d, REG_ITMP2, d);
1270 store_reg_to_var_int(iptr->dst, d);
1273 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1274 /* val.l = constant */
1276 var_to_reg_int(s1, src, REG_ITMP1);
1277 d = reg_of_var(iptr->dst, REG_ITMP3);
1278 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1279 M_AND_IMM(s1, iptr->val.l, d);
1281 else if (iptr->val.l == 0xffffL) {
1284 else if (iptr->val.l == 0xffffffL) {
1285 M_ZAPNOT_IMM(s1, 0x07, d);
1287 else if (iptr->val.l == 0xffffffffL) {
1290 else if (iptr->val.l == 0xffffffffffL) {
1291 M_ZAPNOT_IMM(s1, 0x1f, d);
1293 else if (iptr->val.l == 0xffffffffffffL) {
1294 M_ZAPNOT_IMM(s1, 0x3f, d);
1296 else if (iptr->val.l == 0xffffffffffffffL) {
1297 M_ZAPNOT_IMM(s1, 0x7f, d);
1300 LCONST(REG_ITMP2, iptr->val.l);
1301 M_AND(s1, REG_ITMP2, d);
1303 store_reg_to_var_int(iptr->dst, d);
1306 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1307 /* val.l = constant */
1309 var_to_reg_int(s1, src, REG_ITMP1);
1310 d = reg_of_var(iptr->dst, REG_ITMP3);
1312 M_MOV(s1, REG_ITMP1);
1315 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1316 M_AND_IMM(s1, iptr->val.l, d);
1318 M_LSUB(REG_ZERO, s1, d);
1319 M_AND_IMM(d, iptr->val.l, d);
1321 else if (iptr->val.l == 0xffffL) {
1324 M_LSUB(REG_ZERO, s1, d);
1327 else if (iptr->val.l == 0xffffffL) {
1328 M_ZAPNOT_IMM(s1, 0x07, d);
1330 M_LSUB(REG_ZERO, s1, d);
1331 M_ZAPNOT_IMM(d, 0x07, d);
1333 else if (iptr->val.l == 0xffffffffL) {
1336 M_LSUB(REG_ZERO, s1, d);
1339 else if (iptr->val.l == 0xffffffffffL) {
1340 M_ZAPNOT_IMM(s1, 0x1f, d);
1342 M_LSUB(REG_ZERO, s1, d);
1343 M_ZAPNOT_IMM(d, 0x1f, d);
1345 else if (iptr->val.l == 0xffffffffffffL) {
1346 M_ZAPNOT_IMM(s1, 0x3f, d);
1348 M_LSUB(REG_ZERO, s1, d);
1349 M_ZAPNOT_IMM(d, 0x3f, d);
1351 else if (iptr->val.l == 0xffffffffffffffL) {
1352 M_ZAPNOT_IMM(s1, 0x7f, d);
1354 M_LSUB(REG_ZERO, s1, d);
1355 M_ZAPNOT_IMM(d, 0x7f, d);
1358 LCONST(REG_ITMP2, iptr->val.l);
1359 M_AND(s1, REG_ITMP2, d);
1361 M_LSUB(REG_ZERO, s1, d);
1362 M_AND(d, REG_ITMP2, d);
1364 M_LSUB(REG_ZERO, d, d);
1365 store_reg_to_var_int(iptr->dst, d);
1368 case ICMD_LREM0X10001:/* ..., value ==> ..., value % 0x10001 */
1370 var_to_reg_int(s1, src, REG_ITMP1);
1371 d = reg_of_var(iptr->dst, REG_ITMP3);
1373 M_MOV(s1, REG_ITMP3);
1376 M_CZEXT(s1, REG_ITMP2);
1377 M_SRA_IMM(s1, 16, d);
1378 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1379 M_LSUB(REG_ITMP2, d, d);
1381 M_LADD(d, REG_ITMP1, d);
1382 M_LDA(REG_ITMP2, REG_ZERO, -1);
1383 M_SRL_IMM(REG_ITMP2, 33, REG_ITMP2);
1384 if (s1 == REG_ITMP1) {
1385 var_to_reg_int(s1, src, REG_ITMP1);
1387 M_CMPULT(s1, REG_ITMP2, REG_ITMP2);
1388 M_BNEZ(REG_ITMP2, 11);
1389 M_LDA(d, REG_ZERO, -257);
1390 M_ZAPNOT_IMM(d, 0xcd, d);
1391 M_LSUB(REG_ZERO, s1, REG_ITMP2);
1392 M_CMOVGE(s1, s1, REG_ITMP2);
1393 M_UMULH(REG_ITMP2, d, REG_ITMP2);
1394 M_SRL_IMM(REG_ITMP2, 16, REG_ITMP2);
1395 M_LSUB(REG_ZERO, REG_ITMP2, d);
1396 M_CMOVGE(s1, REG_ITMP2, d);
1397 M_SLL_IMM(d, 16, REG_ITMP2);
1398 M_LADD(d, REG_ITMP2, d);
1400 store_reg_to_var_int(iptr->dst, d);
1403 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1406 var_to_reg_int(s1, src->prev, REG_ITMP1);
1407 var_to_reg_int(s2, src, REG_ITMP2);
1408 d = reg_of_var(iptr->dst, REG_ITMP3);
1410 store_reg_to_var_int(iptr->dst, d);
1413 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1414 /* val.i = constant */
1416 var_to_reg_int(s1, src, REG_ITMP1);
1417 d = reg_of_var(iptr->dst, REG_ITMP3);
1418 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1419 M_OR_IMM(s1, iptr->val.i, d);
1422 ICONST(REG_ITMP2, iptr->val.i);
1423 M_OR(s1, REG_ITMP2, d);
1425 store_reg_to_var_int(iptr->dst, d);
1428 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1429 /* val.l = constant */
1431 var_to_reg_int(s1, src, REG_ITMP1);
1432 d = reg_of_var(iptr->dst, REG_ITMP3);
1433 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1434 M_OR_IMM(s1, iptr->val.l, d);
1437 LCONST(REG_ITMP2, iptr->val.l);
1438 M_OR(s1, REG_ITMP2, d);
1440 store_reg_to_var_int(iptr->dst, d);
1443 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1446 var_to_reg_int(s1, src->prev, REG_ITMP1);
1447 var_to_reg_int(s2, src, REG_ITMP2);
1448 d = reg_of_var(iptr->dst, REG_ITMP3);
1450 store_reg_to_var_int(iptr->dst, d);
1453 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1454 /* val.i = constant */
1456 var_to_reg_int(s1, src, REG_ITMP1);
1457 d = reg_of_var(iptr->dst, REG_ITMP3);
1458 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1459 M_XOR_IMM(s1, iptr->val.i, d);
1462 ICONST(REG_ITMP2, iptr->val.i);
1463 M_XOR(s1, REG_ITMP2, d);
1465 store_reg_to_var_int(iptr->dst, d);
1468 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1469 /* val.l = constant */
1471 var_to_reg_int(s1, src, REG_ITMP1);
1472 d = reg_of_var(iptr->dst, REG_ITMP3);
1473 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1474 M_XOR_IMM(s1, iptr->val.l, d);
1477 LCONST(REG_ITMP2, iptr->val.l);
1478 M_XOR(s1, REG_ITMP2, d);
1480 store_reg_to_var_int(iptr->dst, d);
1484 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1486 var_to_reg_int(s1, src->prev, REG_ITMP1);
1487 var_to_reg_int(s2, src, REG_ITMP2);
1488 d = reg_of_var(iptr->dst, REG_ITMP3);
1489 M_CMPLT(s1, s2, REG_ITMP3);
1490 M_CMPLT(s2, s1, REG_ITMP1);
1491 M_LSUB (REG_ITMP1, REG_ITMP3, d);
1492 store_reg_to_var_int(iptr->dst, d);
1496 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1497 /* op1 = variable, val.i = constant */
1499 var = &(locals[iptr->op1][TYPE_INT]);
1500 if (var->flags & INMEMORY) {
1502 M_LLD(s1, REG_SP, 8 * var->regoff);
1506 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1507 M_IADD_IMM(s1, iptr->val.i, s1);
1509 else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1510 M_ISUB_IMM(s1, (-iptr->val.i), s1);
1513 M_LDA (s1, s1, iptr->val.i);
1514 M_IADD(s1, REG_ZERO, s1);
1516 if (var->flags & INMEMORY)
1517 M_LST(s1, REG_SP, 8 * var->regoff);
1521 /* floating operations ************************************************/
1523 case ICMD_FNEG: /* ..., value ==> ..., - value */
1525 var_to_reg_flt(s1, src, REG_FTMP1);
1526 d = reg_of_var(iptr->dst, REG_FTMP3);
1528 store_reg_to_var_flt(iptr->dst, d);
1531 case ICMD_DNEG: /* ..., value ==> ..., - value */
1533 var_to_reg_flt(s1, src, REG_FTMP1);
1534 d = reg_of_var(iptr->dst, REG_FTMP3);
1536 store_reg_to_var_flt(iptr->dst, d);
1539 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1541 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1542 var_to_reg_flt(s2, src, REG_FTMP2);
1543 d = reg_of_var(iptr->dst, REG_FTMP3);
1551 store_reg_to_var_flt(iptr->dst, d);
1554 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1556 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1557 var_to_reg_flt(s2, src, REG_FTMP2);
1558 d = reg_of_var(iptr->dst, REG_FTMP3);
1566 store_reg_to_var_flt(iptr->dst, d);
1569 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1571 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1572 var_to_reg_flt(s2, src, REG_FTMP2);
1573 d = reg_of_var(iptr->dst, REG_FTMP3);
1581 store_reg_to_var_flt(iptr->dst, d);
1584 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1586 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1587 var_to_reg_flt(s2, src, REG_FTMP2);
1588 d = reg_of_var(iptr->dst, REG_FTMP3);
1596 store_reg_to_var_flt(iptr->dst, d);
1599 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1601 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1602 var_to_reg_flt(s2, src, REG_FTMP2);
1603 d = reg_of_var(iptr->dst, REG_FTMP3);
1611 store_reg_to_var_flt(iptr->dst, d);
1614 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1616 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1617 var_to_reg_flt(s2, src, REG_FTMP2);
1618 d = reg_of_var(iptr->dst, REG_FTMP3);
1626 store_reg_to_var_flt(iptr->dst, d);
1629 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1631 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1632 var_to_reg_flt(s2, src, REG_FTMP2);
1633 d = reg_of_var(iptr->dst, REG_FTMP3);
1641 store_reg_to_var_flt(iptr->dst, d);
1644 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1646 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1647 var_to_reg_flt(s2, src, REG_FTMP2);
1648 d = reg_of_var(iptr->dst, REG_FTMP3);
1656 store_reg_to_var_flt(iptr->dst, d);
1659 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1661 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1662 var_to_reg_flt(s2, src, REG_FTMP2);
1663 d = reg_of_var(iptr->dst, REG_FTMP3);
1665 M_FDIVS(s1,s2, REG_FTMP3);
1667 M_CVTDL_CS(REG_FTMP3, REG_FTMP3); /* round to integer */
1669 M_CVTLF(REG_FTMP3, REG_FTMP3);
1670 M_FMULS(REG_FTMP3, s2, REG_FTMP3);
1672 M_FSUBS(s1, REG_FTMP3, d);
1676 M_FDIV(s1,s2, REG_FTMP3);
1677 M_CVTDL_C(REG_FTMP3, REG_FTMP3); /* round to integer */
1678 M_CVTLF(REG_FTMP3, REG_FTMP3);
1679 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1680 M_FSUB(s1, REG_FTMP3, d);
1682 store_reg_to_var_flt(iptr->dst, d);
1685 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1687 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1688 var_to_reg_flt(s2, src, REG_FTMP2);
1689 d = reg_of_var(iptr->dst, REG_FTMP3);
1691 M_DDIVS(s1,s2, REG_FTMP3);
1693 M_CVTDL_CS(REG_FTMP3, REG_FTMP3); /* round to integer */
1695 M_CVTLD(REG_FTMP3, REG_FTMP3);
1696 M_DMULS(REG_FTMP3, s2, REG_FTMP3);
1698 M_DSUBS(s1, REG_FTMP3, d);
1702 M_DDIV(s1,s2, REG_FTMP3);
1703 M_CVTDL_C(REG_FTMP3, REG_FTMP3); /* round to integer */
1704 M_CVTLD(REG_FTMP3, REG_FTMP3);
1705 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1706 M_DSUB(s1, REG_FTMP3, d);
1708 store_reg_to_var_flt(iptr->dst, d);
1711 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1713 var_to_reg_int(s1, src, REG_ITMP1);
1714 d = reg_of_var(iptr->dst, REG_FTMP3);
1715 a = dseg_adddouble(0.0);
1716 M_LST (s1, REG_PV, a);
1717 M_DLD (d, REG_PV, a);
1719 store_reg_to_var_flt(iptr->dst, d);
1722 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1724 var_to_reg_int(s1, src, REG_ITMP1);
1725 d = reg_of_var(iptr->dst, REG_FTMP3);
1726 a = dseg_adddouble(0.0);
1727 M_LST (s1, REG_PV, a);
1728 M_DLD (d, REG_PV, a);
1730 store_reg_to_var_flt(iptr->dst, d);
1733 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1735 var_to_reg_flt(s1, src, REG_FTMP1);
1736 d = reg_of_var(iptr->dst, REG_ITMP3);
1737 a = dseg_adddouble(0.0);
1739 M_CVTDL_CS(s1, REG_FTMP1);
1741 M_CVTLIS(REG_FTMP1, REG_FTMP2);
1745 M_CVTDL_C(s1, REG_FTMP1);
1746 M_CVTLI(REG_FTMP1, REG_FTMP2);
1748 M_DST (REG_FTMP1, REG_PV, a);
1749 M_ILD (d, REG_PV, a);
1750 store_reg_to_var_int(iptr->dst, d);
1753 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1755 var_to_reg_flt(s1, src, REG_FTMP1);
1756 d = reg_of_var(iptr->dst, REG_ITMP3);
1757 a = dseg_adddouble(0.0);
1759 M_CVTDL_CS(s1, REG_FTMP1);
1763 M_CVTDL_C(s1, REG_FTMP1);
1765 M_DST (REG_FTMP1, REG_PV, a);
1766 M_LLD (d, REG_PV, a);
1767 store_reg_to_var_int(iptr->dst, d);
1770 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1772 var_to_reg_flt(s1, src, REG_FTMP1);
1773 d = reg_of_var(iptr->dst, REG_FTMP3);
1775 store_reg_to_var_flt(iptr->dst, d);
1778 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1780 var_to_reg_flt(s1, src, REG_FTMP1);
1781 d = reg_of_var(iptr->dst, REG_FTMP3);
1789 store_reg_to_var_flt(iptr->dst, d);
1792 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1794 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1795 var_to_reg_flt(s2, src, REG_FTMP2);
1796 d = reg_of_var(iptr->dst, REG_ITMP3);
1798 M_LSUB_IMM(REG_ZERO, 1, d);
1799 M_FCMPEQS(s1, s2, REG_FTMP3);
1801 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1803 M_FCMPLTS(s2, s1, REG_FTMP3);
1805 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1806 M_LADD_IMM(REG_ZERO, 1, d);
1809 M_LSUB_IMM(REG_ZERO, 1, d);
1810 M_FCMPEQ(s1, s2, REG_FTMP3);
1811 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1813 M_FCMPLT(s2, s1, REG_FTMP3);
1814 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1815 M_LADD_IMM(REG_ZERO, 1, d);
1817 store_reg_to_var_int(iptr->dst, d);
1820 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1822 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1823 var_to_reg_flt(s2, src, REG_FTMP2);
1824 d = reg_of_var(iptr->dst, REG_ITMP3);
1826 M_LADD_IMM(REG_ZERO, 1, d);
1827 M_FCMPEQS(s1, s2, REG_FTMP3);
1829 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1831 M_FCMPLTS(s1, s2, REG_FTMP3);
1833 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1834 M_LSUB_IMM(REG_ZERO, 1, d);
1837 M_LADD_IMM(REG_ZERO, 1, d);
1838 M_FCMPEQ(s1, s2, REG_FTMP3);
1839 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1841 M_FCMPLT(s1, s2, REG_FTMP3);
1842 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1843 M_LSUB_IMM(REG_ZERO, 1, d);
1845 store_reg_to_var_int(iptr->dst, d);
1849 /* memory operations **************************************************/
1851 #define gen_bound_check \
1853 M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\
1854 M_CMPULT(s2, REG_ITMP3, REG_ITMP3);\
1855 M_BEQZ(REG_ITMP3, 0);\
1856 mcode_addxboundrefs(mcodeptr);\
1859 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1861 var_to_reg_int(s1, src, REG_ITMP1);
1862 d = reg_of_var(iptr->dst, REG_ITMP3);
1863 gen_nullptr_check(s1);
1864 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1865 store_reg_to_var_int(iptr->dst, d);
1868 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1870 var_to_reg_int(s1, src->prev, REG_ITMP1);
1871 var_to_reg_int(s2, src, REG_ITMP2);
1872 d = reg_of_var(iptr->dst, REG_ITMP3);
1873 gen_nullptr_check(s1);
1875 M_SAADDQ(s2, s1, REG_ITMP1);
1876 M_ALD( d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1877 store_reg_to_var_int(iptr->dst, d);
1880 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1882 var_to_reg_int(s1, src->prev, REG_ITMP1);
1883 var_to_reg_int(s2, src, REG_ITMP2);
1884 d = reg_of_var(iptr->dst, REG_ITMP3);
1885 gen_nullptr_check(s1);
1887 M_S8ADDQ(s2, s1, REG_ITMP1);
1888 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1889 store_reg_to_var_int(iptr->dst, d);
1892 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1894 var_to_reg_int(s1, src->prev, REG_ITMP1);
1895 var_to_reg_int(s2, src, REG_ITMP2);
1896 d = reg_of_var(iptr->dst, REG_ITMP3);
1897 gen_nullptr_check(s1);
1899 M_S4ADDQ(s2, s1, REG_ITMP1);
1900 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1901 store_reg_to_var_int(iptr->dst, d);
1904 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1906 var_to_reg_int(s1, src->prev, REG_ITMP1);
1907 var_to_reg_int(s2, src, REG_ITMP2);
1908 d = reg_of_var(iptr->dst, REG_FTMP3);
1909 gen_nullptr_check(s1);
1911 M_S4ADDQ(s2, s1, REG_ITMP1);
1912 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1913 store_reg_to_var_flt(iptr->dst, d);
1916 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1918 var_to_reg_int(s1, src->prev, REG_ITMP1);
1919 var_to_reg_int(s2, src, REG_ITMP2);
1920 d = reg_of_var(iptr->dst, REG_FTMP3);
1921 gen_nullptr_check(s1);
1923 M_S8ADDQ(s2, s1, REG_ITMP1);
1924 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1925 store_reg_to_var_flt(iptr->dst, d);
1928 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1930 var_to_reg_int(s1, src->prev, REG_ITMP1);
1931 var_to_reg_int(s2, src, REG_ITMP2);
1932 d = reg_of_var(iptr->dst, REG_ITMP3);
1933 gen_nullptr_check(s1);
1935 if (has_ext_instr_set) {
1936 M_LADD(s2, s1, REG_ITMP1);
1937 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1938 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1941 M_LADD (s2, s1, REG_ITMP1);
1942 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1943 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1944 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1945 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
1947 store_reg_to_var_int(iptr->dst, d);
1950 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1952 var_to_reg_int(s1, src->prev, REG_ITMP1);
1953 var_to_reg_int(s2, src, REG_ITMP2);
1954 d = reg_of_var(iptr->dst, REG_ITMP3);
1955 gen_nullptr_check(s1);
1957 if (has_ext_instr_set) {
1958 M_LADD(s2, s1, REG_ITMP1);
1959 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1960 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1964 M_LADD(s2, s1, REG_ITMP1);
1965 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1966 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1967 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1968 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1969 M_SRA_IMM(d, 48, d);
1971 store_reg_to_var_int(iptr->dst, d);
1974 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1976 var_to_reg_int(s1, src->prev, REG_ITMP1);
1977 var_to_reg_int(s2, src, REG_ITMP2);
1978 d = reg_of_var(iptr->dst, REG_ITMP3);
1979 gen_nullptr_check(s1);
1981 if (has_ext_instr_set) {
1982 M_LADD (s2, s1, REG_ITMP1);
1983 M_BLDU (d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1987 M_LADD(s2, s1, REG_ITMP1);
1988 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1989 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
1990 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1991 M_SRA_IMM(d, 56, d);
1993 store_reg_to_var_int(iptr->dst, d);
1997 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1999 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2000 var_to_reg_int(s2, src->prev, REG_ITMP2);
2001 gen_nullptr_check(s1);
2003 var_to_reg_int(s3, src, REG_ITMP3);
2004 M_SAADDQ(s2, s1, REG_ITMP1);
2005 M_AST (s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
2008 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
2010 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2011 var_to_reg_int(s2, src->prev, REG_ITMP2);
2012 gen_nullptr_check(s1);
2014 var_to_reg_int(s3, src, REG_ITMP3);
2015 M_S8ADDQ(s2, s1, REG_ITMP1);
2016 M_LST (s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
2019 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
2021 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2022 var_to_reg_int(s2, src->prev, REG_ITMP2);
2023 gen_nullptr_check(s1);
2025 var_to_reg_int(s3, src, REG_ITMP3);
2026 M_S4ADDQ(s2, s1, REG_ITMP1);
2027 M_IST (s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
2030 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
2032 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2033 var_to_reg_int(s2, src->prev, REG_ITMP2);
2034 gen_nullptr_check(s1);
2036 var_to_reg_flt(s3, src, REG_FTMP3);
2037 M_S4ADDQ(s2, s1, REG_ITMP1);
2038 M_FST (s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
2041 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
2043 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2044 var_to_reg_int(s2, src->prev, REG_ITMP2);
2045 gen_nullptr_check(s1);
2047 var_to_reg_flt(s3, src, REG_FTMP3);
2048 M_S8ADDQ(s2, s1, REG_ITMP1);
2049 M_DST (s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
2052 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
2054 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2055 var_to_reg_int(s2, src->prev, REG_ITMP2);
2056 gen_nullptr_check(s1);
2058 var_to_reg_int(s3, src, REG_ITMP3);
2059 if (has_ext_instr_set) {
2060 M_LADD(s2, s1, REG_ITMP1);
2061 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2062 M_SST (s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
2065 M_LADD (s2, s1, REG_ITMP1);
2066 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2067 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2068 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2069 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
2070 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2071 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2072 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2076 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
2078 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2079 var_to_reg_int(s2, src->prev, REG_ITMP2);
2080 gen_nullptr_check(s1);
2082 var_to_reg_int(s3, src, REG_ITMP3);
2083 if (has_ext_instr_set) {
2084 M_LADD(s2, s1, REG_ITMP1);
2085 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2086 M_SST (s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2089 M_LADD (s2, s1, REG_ITMP1);
2090 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2091 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2092 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2093 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
2094 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2095 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2096 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2100 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
2102 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2103 var_to_reg_int(s2, src->prev, REG_ITMP2);
2104 gen_nullptr_check(s1);
2106 var_to_reg_int(s3, src, REG_ITMP3);
2107 if (has_ext_instr_set) {
2108 M_LADD(s2, s1, REG_ITMP1);
2109 M_BST (s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2112 M_LADD (s2, s1, REG_ITMP1);
2113 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2114 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2115 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
2116 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2117 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2118 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2123 /* optimized memory operations ****************************************/
2125 case ICMD_OPT_AALOAD: /* ..., arrayref, index ==> ..., value */
2127 var_to_reg_int(s1, src->prev, REG_ITMP1);
2128 var_to_reg_int(s2, src, REG_ITMP2);
2129 d = reg_of_var(iptr->dst, REG_ITMP3);
2130 M_SAADDQ(s2, s1, REG_ITMP1);
2131 M_ALD( d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
2132 store_reg_to_var_int(iptr->dst, d);
2135 case ICMD_OPT_LALOAD: /* ..., arrayref, index ==> ..., value */
2137 var_to_reg_int(s1, src->prev, REG_ITMP1);
2138 var_to_reg_int(s2, src, REG_ITMP2);
2139 d = reg_of_var(iptr->dst, REG_ITMP3);
2140 M_S8ADDQ(s2, s1, REG_ITMP1);
2141 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
2142 store_reg_to_var_int(iptr->dst, d);
2145 case ICMD_OPT_IALOAD: /* ..., arrayref, index ==> ..., value */
2147 var_to_reg_int(s1, src->prev, REG_ITMP1);
2148 var_to_reg_int(s2, src, REG_ITMP2);
2149 d = reg_of_var(iptr->dst, REG_ITMP3);
2150 M_S4ADDQ(s2, s1, REG_ITMP1);
2151 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
2152 store_reg_to_var_int(iptr->dst, d);
2155 case ICMD_OPT_FALOAD: /* ..., arrayref, index ==> ..., value */
2157 var_to_reg_int(s1, src->prev, REG_ITMP1);
2158 var_to_reg_int(s2, src, REG_ITMP2);
2159 d = reg_of_var(iptr->dst, REG_FTMP3);
2160 M_S4ADDQ(s2, s1, REG_ITMP1);
2161 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
2162 store_reg_to_var_flt(iptr->dst, d);
2165 case ICMD_OPT_DALOAD: /* ..., arrayref, index ==> ..., value */
2167 var_to_reg_int(s1, src->prev, REG_ITMP1);
2168 var_to_reg_int(s2, src, REG_ITMP2);
2169 d = reg_of_var(iptr->dst, REG_FTMP3);
2170 M_S8ADDQ(s2, s1, REG_ITMP1);
2171 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
2172 store_reg_to_var_flt(iptr->dst, d);
2175 case ICMD_OPT_CALOAD: /* ..., arrayref, index ==> ..., value */
2177 var_to_reg_int(s1, src->prev, REG_ITMP1);
2178 var_to_reg_int(s2, src, REG_ITMP2);
2179 d = reg_of_var(iptr->dst, REG_ITMP3);
2180 if (has_ext_instr_set) {
2181 M_LADD(s2, s1, REG_ITMP1);
2182 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2183 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
2186 M_LADD (s2, s1, REG_ITMP1);
2187 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2188 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2189 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2190 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
2192 store_reg_to_var_int(iptr->dst, d);
2195 case ICMD_OPT_SALOAD: /* ..., arrayref, index ==> ..., value */
2197 var_to_reg_int(s1, src->prev, REG_ITMP1);
2198 var_to_reg_int(s2, src, REG_ITMP2);
2199 d = reg_of_var(iptr->dst, REG_ITMP3);
2200 if (has_ext_instr_set) {
2201 M_LADD(s2, s1, REG_ITMP1);
2202 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2203 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
2207 M_LADD(s2, s1, REG_ITMP1);
2208 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2209 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2210 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
2211 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
2212 M_SRA_IMM(d, 48, d);
2214 store_reg_to_var_int(iptr->dst, d);
2217 case ICMD_OPT_BALOAD: /* ..., arrayref, index ==> ..., value */
2219 var_to_reg_int(s1, src->prev, REG_ITMP1);
2220 var_to_reg_int(s2, src, REG_ITMP2);
2221 d = reg_of_var(iptr->dst, REG_ITMP3);
2222 if (has_ext_instr_set) {
2223 M_LADD (s2, s1, REG_ITMP1);
2224 M_BLDU (d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
2228 M_LADD(s2, s1, REG_ITMP1);
2229 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2230 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
2231 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
2232 M_SRA_IMM(d, 56, d);
2234 store_reg_to_var_int(iptr->dst, d);
2238 case ICMD_OPT_AASTORE: /* ..., arrayref, index, value ==> ... */
2240 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2241 var_to_reg_int(s2, src->prev, REG_ITMP2);
2242 var_to_reg_int(s3, src, REG_ITMP3);
2243 M_SAADDQ(s2, s1, REG_ITMP1);
2244 M_AST (s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
2247 case ICMD_OPT_LASTORE: /* ..., arrayref, index, value ==> ... */
2249 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2250 var_to_reg_int(s2, src->prev, REG_ITMP2);
2251 var_to_reg_int(s3, src, REG_ITMP3);
2252 M_S8ADDQ(s2, s1, REG_ITMP1);
2253 M_LST (s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
2256 case ICMD_OPT_IASTORE: /* ..., arrayref, index, value ==> ... */
2258 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2259 var_to_reg_int(s2, src->prev, REG_ITMP2);
2260 var_to_reg_int(s3, src, REG_ITMP3);
2261 M_S4ADDQ(s2, s1, REG_ITMP1);
2262 M_IST (s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
2265 case ICMD_OPT_FASTORE: /* ..., arrayref, index, value ==> ... */
2267 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2268 var_to_reg_int(s2, src->prev, REG_ITMP2);
2269 var_to_reg_flt(s3, src, REG_FTMP3);
2270 M_S4ADDQ(s2, s1, REG_ITMP1);
2271 M_FST (s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
2274 case ICMD_OPT_DASTORE: /* ..., arrayref, index, value ==> ... */
2276 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2277 var_to_reg_int(s2, src->prev, REG_ITMP2);
2278 var_to_reg_flt(s3, src, REG_FTMP3);
2279 M_S8ADDQ(s2, s1, REG_ITMP1);
2280 M_DST (s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
2283 case ICMD_OPT_CASTORE: /* ..., arrayref, index, value ==> ... */
2285 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2286 var_to_reg_int(s2, src->prev, REG_ITMP2);
2287 var_to_reg_int(s3, src, REG_ITMP3);
2288 if (has_ext_instr_set) {
2289 M_LADD(s2, s1, REG_ITMP1);
2290 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2291 M_SST (s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
2294 M_LADD (s2, s1, REG_ITMP1);
2295 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2296 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2297 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2298 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
2299 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2300 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2301 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2305 case ICMD_OPT_SASTORE: /* ..., arrayref, index, value ==> ... */
2307 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2308 var_to_reg_int(s2, src->prev, REG_ITMP2);
2309 var_to_reg_int(s3, src, REG_ITMP3);
2310 if (has_ext_instr_set) {
2311 M_LADD(s2, s1, REG_ITMP1);
2312 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2313 M_SST (s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2316 M_LADD (s2, s1, REG_ITMP1);
2317 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2318 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2319 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2320 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
2321 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2322 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2323 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2327 case ICMD_OPT_BASTORE: /* ..., arrayref, index, value ==> ... */
2329 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2330 var_to_reg_int(s2, src->prev, REG_ITMP2);
2331 var_to_reg_int(s3, src, REG_ITMP3);
2332 if (has_ext_instr_set) {
2333 M_LADD(s2, s1, REG_ITMP1);
2334 M_BST (s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2337 M_LADD (s2, s1, REG_ITMP1);
2338 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2339 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2340 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
2341 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2342 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2343 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2347 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2348 /* op1 = type, val.a = field address */
2350 a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value));
2351 M_ALD(REG_ITMP1, REG_PV, a);
2352 switch (iptr->op1) {
2354 var_to_reg_int(s2, src, REG_ITMP2);
2355 M_IST(s2, REG_ITMP1, 0);
2358 var_to_reg_int(s2, src, REG_ITMP2);
2359 M_LST(s2, REG_ITMP1, 0);
2362 var_to_reg_int(s2, src, REG_ITMP2);
2363 M_AST(s2, REG_ITMP1, 0);
2366 var_to_reg_flt(s2, src, REG_FTMP2);
2367 M_FST(s2, REG_ITMP1, 0);
2370 var_to_reg_flt(s2, src, REG_FTMP2);
2371 M_DST(s2, REG_ITMP1, 0);
2373 default: panic ("internal error");
2377 case ICMD_GETSTATIC: /* ... ==> ..., value */
2378 /* op1 = type, val.a = field address */
2380 a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value));
2381 M_ALD(REG_ITMP1, REG_PV, a);
2382 switch (iptr->op1) {
2384 d = reg_of_var(iptr->dst, REG_ITMP3);
2385 M_ILD(d, REG_ITMP1, 0);
2386 store_reg_to_var_int(iptr->dst, d);
2389 d = reg_of_var(iptr->dst, REG_ITMP3);
2390 M_LLD(d, REG_ITMP1, 0);
2391 store_reg_to_var_int(iptr->dst, d);
2394 d = reg_of_var(iptr->dst, REG_ITMP3);
2395 M_ALD(d, REG_ITMP1, 0);
2396 store_reg_to_var_int(iptr->dst, d);
2399 d = reg_of_var(iptr->dst, REG_FTMP1);
2400 M_FLD(d, REG_ITMP1, 0);
2401 store_reg_to_var_flt(iptr->dst, d);
2404 d = reg_of_var(iptr->dst, REG_FTMP1);
2405 M_DLD(d, REG_ITMP1, 0);
2406 store_reg_to_var_flt(iptr->dst, d);
2408 default: panic ("internal error");
2413 case ICMD_PUTFIELD: /* ..., value ==> ... */
2414 /* op1 = type, val.i = field offset */
2416 a = ((fieldinfo *)(iptr->val.a))->offset;
2417 switch (iptr->op1) {
2419 var_to_reg_int(s1, src->prev, REG_ITMP1);
2420 var_to_reg_int(s2, src, REG_ITMP2);
2421 gen_nullptr_check(s1);
2425 var_to_reg_int(s1, src->prev, REG_ITMP1);
2426 var_to_reg_int(s2, src, REG_ITMP2);
2427 gen_nullptr_check(s1);
2431 var_to_reg_int(s1, src->prev, REG_ITMP1);
2432 var_to_reg_int(s2, src, REG_ITMP2);
2433 gen_nullptr_check(s1);
2437 var_to_reg_int(s1, src->prev, REG_ITMP1);
2438 var_to_reg_flt(s2, src, REG_FTMP2);
2439 gen_nullptr_check(s1);
2443 var_to_reg_int(s1, src->prev, REG_ITMP1);
2444 var_to_reg_flt(s2, src, REG_FTMP2);
2445 gen_nullptr_check(s1);
2448 default: panic ("internal error");
2452 case ICMD_GETFIELD: /* ... ==> ..., value */
2453 /* op1 = type, val.i = field offset */
2455 a = ((fieldinfo *)(iptr->val.a))->offset;
2456 switch (iptr->op1) {
2458 var_to_reg_int(s1, src, REG_ITMP1);
2459 d = reg_of_var(iptr->dst, REG_ITMP3);
2460 gen_nullptr_check(s1);
2462 store_reg_to_var_int(iptr->dst, d);
2465 var_to_reg_int(s1, src, REG_ITMP1);
2466 d = reg_of_var(iptr->dst, REG_ITMP3);
2467 gen_nullptr_check(s1);
2469 store_reg_to_var_int(iptr->dst, d);
2472 var_to_reg_int(s1, src, REG_ITMP1);
2473 d = reg_of_var(iptr->dst, REG_ITMP3);
2474 gen_nullptr_check(s1);
2476 store_reg_to_var_int(iptr->dst, d);
2479 var_to_reg_int(s1, src, REG_ITMP1);
2480 d = reg_of_var(iptr->dst, REG_FTMP1);
2481 gen_nullptr_check(s1);
2483 store_reg_to_var_flt(iptr->dst, d);
2486 var_to_reg_int(s1, src, REG_ITMP1);
2487 d = reg_of_var(iptr->dst, REG_FTMP1);
2488 gen_nullptr_check(s1);
2490 store_reg_to_var_flt(iptr->dst, d);
2492 default: panic ("internal error");
2497 /* branch operations **************************************************/
2499 #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}}
2501 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2503 var_to_reg_int(s1, src, REG_ITMP1);
2504 M_INTMOVE(s1, REG_ITMP1_XPTR);
2505 a = dseg_addaddress(asm_handle_exception);
2506 M_ALD(REG_ITMP2, REG_PV, a);
2507 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2511 case ICMD_GOTO: /* ... ==> ... */
2512 /* op1 = target JavaVM pc */
2514 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2518 case ICMD_JSR: /* ... ==> ... */
2519 /* op1 = target JavaVM pc */
2521 M_BSR(REG_ITMP1, 0);
2522 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2525 case ICMD_RET: /* ... ==> ... */
2526 /* op1 = local variable */
2528 var = &(locals[iptr->op1][TYPE_ADR]);
2529 if (var->flags & INMEMORY) {
2530 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2531 M_RET(REG_ZERO, REG_ITMP1);
2534 M_RET(REG_ZERO, var->regoff);
2538 case ICMD_IFNULL: /* ..., value ==> ... */
2539 /* op1 = target JavaVM pc */
2541 var_to_reg_int(s1, src, REG_ITMP1);
2543 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2546 case ICMD_IFNONNULL: /* ..., value ==> ... */
2547 /* op1 = target JavaVM pc */
2549 var_to_reg_int(s1, src, REG_ITMP1);
2551 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2554 case ICMD_IFEQ: /* ..., value ==> ... */
2555 /* op1 = target JavaVM pc, val.i = constant */
2557 var_to_reg_int(s1, src, REG_ITMP1);
2558 if (iptr->val.i == 0) {
2562 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2563 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2566 ICONST(REG_ITMP2, iptr->val.i);
2567 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2569 M_BNEZ(REG_ITMP1, 0);
2571 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2574 case ICMD_IFLT: /* ..., value ==> ... */
2575 /* op1 = target JavaVM pc, val.i = constant */
2577 var_to_reg_int(s1, src, REG_ITMP1);
2578 if (iptr->val.i == 0) {
2582 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2583 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2586 ICONST(REG_ITMP2, iptr->val.i);
2587 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2589 M_BNEZ(REG_ITMP1, 0);
2591 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2594 case ICMD_IFLE: /* ..., value ==> ... */
2595 /* op1 = target JavaVM pc, val.i = constant */
2597 var_to_reg_int(s1, src, REG_ITMP1);
2598 if (iptr->val.i == 0) {
2602 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2603 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2606 ICONST(REG_ITMP2, iptr->val.i);
2607 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2609 M_BNEZ(REG_ITMP1, 0);
2611 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2614 case ICMD_IFNE: /* ..., value ==> ... */
2615 /* op1 = target JavaVM pc, val.i = constant */
2617 var_to_reg_int(s1, src, REG_ITMP1);
2618 if (iptr->val.i == 0) {
2622 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2623 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2626 ICONST(REG_ITMP2, iptr->val.i);
2627 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2629 M_BEQZ(REG_ITMP1, 0);
2631 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2634 case ICMD_IFGT: /* ..., value ==> ... */
2635 /* op1 = target JavaVM pc, val.i = constant */
2637 var_to_reg_int(s1, src, REG_ITMP1);
2638 if (iptr->val.i == 0) {
2642 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2643 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2646 ICONST(REG_ITMP2, iptr->val.i);
2647 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2649 M_BEQZ(REG_ITMP1, 0);
2651 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2654 case ICMD_IFGE: /* ..., value ==> ... */
2655 /* op1 = target JavaVM pc, val.i = constant */
2657 var_to_reg_int(s1, src, REG_ITMP1);
2658 if (iptr->val.i == 0) {
2662 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2663 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2666 ICONST(REG_ITMP2, iptr->val.i);
2667 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2669 M_BEQZ(REG_ITMP1, 0);
2671 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2674 case ICMD_IF_LEQ: /* ..., value ==> ... */
2675 /* op1 = target JavaVM pc, val.l = constant */
2677 var_to_reg_int(s1, src, REG_ITMP1);
2678 if (iptr->val.l == 0) {
2682 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2683 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2686 LCONST(REG_ITMP2, iptr->val.l);
2687 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2689 M_BNEZ(REG_ITMP1, 0);
2691 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2694 case ICMD_IF_LLT: /* ..., value ==> ... */
2695 /* op1 = target JavaVM pc, val.l = constant */
2697 var_to_reg_int(s1, src, REG_ITMP1);
2698 if (iptr->val.l == 0) {
2702 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2703 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2706 LCONST(REG_ITMP2, iptr->val.l);
2707 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2709 M_BNEZ(REG_ITMP1, 0);
2711 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2714 case ICMD_IF_LLE: /* ..., value ==> ... */
2715 /* op1 = target JavaVM pc, val.l = constant */
2717 var_to_reg_int(s1, src, REG_ITMP1);
2718 if (iptr->val.l == 0) {
2722 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2723 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2726 LCONST(REG_ITMP2, iptr->val.l);
2727 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2729 M_BNEZ(REG_ITMP1, 0);
2731 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2734 case ICMD_IF_LNE: /* ..., value ==> ... */
2735 /* op1 = target JavaVM pc, val.l = constant */
2737 var_to_reg_int(s1, src, REG_ITMP1);
2738 if (iptr->val.l == 0) {
2742 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2743 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2746 LCONST(REG_ITMP2, iptr->val.l);
2747 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2749 M_BEQZ(REG_ITMP1, 0);
2751 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2754 case ICMD_IF_LGT: /* ..., value ==> ... */
2755 /* op1 = target JavaVM pc, val.l = constant */
2757 var_to_reg_int(s1, src, REG_ITMP1);
2758 if (iptr->val.l == 0) {
2762 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2763 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2766 LCONST(REG_ITMP2, iptr->val.l);
2767 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2769 M_BEQZ(REG_ITMP1, 0);
2771 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2774 case ICMD_IF_LGE: /* ..., value ==> ... */
2775 /* op1 = target JavaVM pc, val.l = constant */
2777 var_to_reg_int(s1, src, REG_ITMP1);
2778 if (iptr->val.l == 0) {
2782 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2783 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2786 LCONST(REG_ITMP2, iptr->val.l);
2787 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2789 M_BEQZ(REG_ITMP1, 0);
2791 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2794 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2795 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2796 case ICMD_IF_ACMPEQ:
2798 var_to_reg_int(s1, src->prev, REG_ITMP1);
2799 var_to_reg_int(s2, src, REG_ITMP2);
2800 M_CMPEQ(s1, s2, REG_ITMP1);
2801 M_BNEZ(REG_ITMP1, 0);
2802 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2805 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2806 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2807 case ICMD_IF_ACMPNE:
2809 var_to_reg_int(s1, src->prev, REG_ITMP1);
2810 var_to_reg_int(s2, src, REG_ITMP2);
2811 M_CMPEQ(s1, s2, REG_ITMP1);
2812 M_BEQZ(REG_ITMP1, 0);
2813 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2816 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2817 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2819 var_to_reg_int(s1, src->prev, REG_ITMP1);
2820 var_to_reg_int(s2, src, REG_ITMP2);
2821 M_CMPLT(s1, s2, REG_ITMP1);
2822 M_BNEZ(REG_ITMP1, 0);
2823 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2826 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2827 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2829 var_to_reg_int(s1, src->prev, REG_ITMP1);
2830 var_to_reg_int(s2, src, REG_ITMP2);
2831 M_CMPLE(s1, s2, REG_ITMP1);
2832 M_BEQZ(REG_ITMP1, 0);
2833 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2836 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2837 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2839 var_to_reg_int(s1, src->prev, REG_ITMP1);
2840 var_to_reg_int(s2, src, REG_ITMP2);
2841 M_CMPLE(s1, s2, REG_ITMP1);
2842 M_BNEZ(REG_ITMP1, 0);
2843 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2846 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2847 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2849 var_to_reg_int(s1, src->prev, REG_ITMP1);
2850 var_to_reg_int(s2, src, REG_ITMP2);
2851 M_CMPLT(s1, s2, REG_ITMP1);
2852 M_BEQZ(REG_ITMP1, 0);
2853 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2856 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2858 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2861 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2862 /* val.i = constant */
2864 var_to_reg_int(s1, src, REG_ITMP1);
2865 d = reg_of_var(iptr->dst, REG_ITMP3);
2867 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2868 if ((a == 1) && (iptr[1].val.i == 0)) {
2869 M_CMPEQ(s1, REG_ZERO, d);
2870 store_reg_to_var_int(iptr->dst, d);
2873 if ((a == 0) && (iptr[1].val.i == 1)) {
2874 M_CMPEQ(s1, REG_ZERO, d);
2876 store_reg_to_var_int(iptr->dst, d);
2880 M_MOV(s1, REG_ITMP1);
2883 ICONST(d, iptr[1].val.i);
2885 if ((a >= 0) && (a <= 255)) {
2886 M_CMOVEQ_IMM(s1, a, d);
2889 ICONST(REG_ITMP2, a);
2890 M_CMOVEQ(s1, REG_ITMP2, d);
2892 store_reg_to_var_int(iptr->dst, d);
2895 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2896 /* val.i = constant */
2898 var_to_reg_int(s1, src, REG_ITMP1);
2899 d = reg_of_var(iptr->dst, REG_ITMP3);
2901 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2902 if ((a == 0) && (iptr[1].val.i == 1)) {
2903 M_CMPEQ(s1, REG_ZERO, d);
2904 store_reg_to_var_int(iptr->dst, d);
2907 if ((a == 1) && (iptr[1].val.i == 0)) {
2908 M_CMPEQ(s1, REG_ZERO, d);
2910 store_reg_to_var_int(iptr->dst, d);
2914 M_MOV(s1, REG_ITMP1);
2917 ICONST(d, iptr[1].val.i);
2919 if ((a >= 0) && (a <= 255)) {
2920 M_CMOVNE_IMM(s1, a, d);
2923 ICONST(REG_ITMP2, a);
2924 M_CMOVNE(s1, REG_ITMP2, d);
2926 store_reg_to_var_int(iptr->dst, d);
2929 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2930 /* val.i = constant */
2932 var_to_reg_int(s1, src, REG_ITMP1);
2933 d = reg_of_var(iptr->dst, REG_ITMP3);
2935 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2936 if ((a == 1) && (iptr[1].val.i == 0)) {
2937 M_CMPLT(s1, REG_ZERO, d);
2938 store_reg_to_var_int(iptr->dst, d);
2941 if ((a == 0) && (iptr[1].val.i == 1)) {
2942 M_CMPLE(REG_ZERO, s1, d);
2943 store_reg_to_var_int(iptr->dst, d);
2947 M_MOV(s1, REG_ITMP1);
2950 ICONST(d, iptr[1].val.i);
2952 if ((a >= 0) && (a <= 255)) {
2953 M_CMOVLT_IMM(s1, a, d);
2956 ICONST(REG_ITMP2, a);
2957 M_CMOVLT(s1, REG_ITMP2, d);
2959 store_reg_to_var_int(iptr->dst, d);
2962 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2963 /* val.i = constant */
2965 var_to_reg_int(s1, src, REG_ITMP1);
2966 d = reg_of_var(iptr->dst, REG_ITMP3);
2968 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2969 if ((a == 1) && (iptr[1].val.i == 0)) {
2970 M_CMPLE(REG_ZERO, s1, d);
2971 store_reg_to_var_int(iptr->dst, d);
2974 if ((a == 0) && (iptr[1].val.i == 1)) {
2975 M_CMPLT(s1, REG_ZERO, d);
2976 store_reg_to_var_int(iptr->dst, d);
2980 M_MOV(s1, REG_ITMP1);
2983 ICONST(d, iptr[1].val.i);
2985 if ((a >= 0) && (a <= 255)) {
2986 M_CMOVGE_IMM(s1, a, d);
2989 ICONST(REG_ITMP2, a);
2990 M_CMOVGE(s1, REG_ITMP2, d);
2992 store_reg_to_var_int(iptr->dst, d);
2995 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2996 /* val.i = constant */
2998 var_to_reg_int(s1, src, REG_ITMP1);
2999 d = reg_of_var(iptr->dst, REG_ITMP3);
3001 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
3002 if ((a == 1) && (iptr[1].val.i == 0)) {
3003 M_CMPLT(REG_ZERO, s1, d);
3004 store_reg_to_var_int(iptr->dst, d);
3007 if ((a == 0) && (iptr[1].val.i == 1)) {
3008 M_CMPLE(s1, REG_ZERO, d);
3009 store_reg_to_var_int(iptr->dst, d);
3013 M_MOV(s1, REG_ITMP1);
3016 ICONST(d, iptr[1].val.i);
3018 if ((a >= 0) && (a <= 255)) {
3019 M_CMOVGT_IMM(s1, a, d);
3022 ICONST(REG_ITMP2, a);
3023 M_CMOVGT(s1, REG_ITMP2, d);
3025 store_reg_to_var_int(iptr->dst, d);
3028 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
3029 /* val.i = constant */
3031 var_to_reg_int(s1, src, REG_ITMP1);
3032 d = reg_of_var(iptr->dst, REG_ITMP3);
3034 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
3035 if ((a == 1) && (iptr[1].val.i == 0)) {
3036 M_CMPLE(s1, REG_ZERO, d);
3037 store_reg_to_var_int(iptr->dst, d);
3040 if ((a == 0) && (iptr[1].val.i == 1)) {
3041 M_CMPLT(REG_ZERO, s1, d);
3042 store_reg_to_var_int(iptr->dst, d);
3046 M_MOV(s1, REG_ITMP1);
3049 ICONST(d, iptr[1].val.i);
3051 if ((a >= 0) && (a <= 255)) {
3052 M_CMOVLE_IMM(s1, a, d);
3055 ICONST(REG_ITMP2, a);
3056 M_CMOVLE(s1, REG_ITMP2, d);
3058 store_reg_to_var_int(iptr->dst, d);
3062 case ICMD_IRETURN: /* ..., retvalue ==> ... */
3067 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3068 a = dseg_addaddress ((void*) (builtin_monitorexit));
3069 M_ALD(REG_PV, REG_PV, a);
3070 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
3071 M_JSR(REG_RA, REG_PV);
3072 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
3075 var_to_reg_int(s1, src, REG_RESULT);
3076 M_INTMOVE(s1, REG_RESULT);
3077 goto nowperformreturn;
3079 case ICMD_FRETURN: /* ..., retvalue ==> ... */
3083 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3084 a = dseg_addaddress ((void*) (builtin_monitorexit));
3085 M_ALD(REG_PV, REG_PV, a);
3086 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
3087 M_JSR(REG_RA, REG_PV);
3088 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
3091 var_to_reg_flt(s1, src, REG_FRESULT);
3092 M_FLTMOVE(s1, REG_FRESULT);
3093 goto nowperformreturn;
3095 case ICMD_RETURN: /* ... ==> ... */
3098 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3099 a = dseg_addaddress ((void*) (builtin_monitorexit));
3100 M_ALD(REG_PV, REG_PV, a);
3101 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
3102 M_JSR(REG_RA, REG_PV);
3103 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
3111 p = parentargs_base;
3113 /* restore return address */
3116 {p--; M_LLD (REG_RA, REG_SP, 8 * p);}
3118 /* restore saved registers */
3120 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
3121 {p--; M_LLD(savintregs[r], REG_SP, 8 * p);}
3122 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
3123 {p--; M_DLD(savfltregs[r], REG_SP, 8 * p);}
3125 /* deallocate stack */
3127 if (parentargs_base)
3128 {M_LDA(REG_SP, REG_SP, parentargs_base*8);}
3130 /* call trace function */
3133 M_LDA (REG_SP, REG_SP, -24);
3134 M_AST(REG_RA, REG_SP, 0);
3135 M_LST(REG_RESULT, REG_SP, 8);
3136 M_DST(REG_FRESULT, REG_SP,16);
3137 a = dseg_addaddress (method);
3138 M_ALD(argintregs[0], REG_PV, a);
3139 M_MOV(REG_RESULT, argintregs[1]);
3140 M_FLTMOVE(REG_FRESULT, argfltregs[2]);
3141 a = dseg_addaddress ((void*) (builtin_displaymethodstop));
3142 M_ALD(REG_PV, REG_PV, a);
3143 M_JSR (REG_RA, REG_PV);
3144 s1 = (int)((u1*) mcodeptr - mcodebase);
3145 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
3148 while (ml<-32768) { ml+=65536; mh--; }
3149 M_LDA (REG_PV, REG_RA, ml );
3150 M_LDAH (REG_PV, REG_PV, mh );
3152 M_DLD(REG_FRESULT, REG_SP,16);
3153 M_LLD(REG_RESULT, REG_SP, 8);
3154 M_ALD(REG_RA, REG_SP, 0);
3155 M_LDA (REG_SP, REG_SP, 24);
3158 M_RET(REG_ZERO, REG_RA);
3164 case ICMD_TABLESWITCH: /* ..., index ==> ... */
3168 s4ptr = iptr->val.a;
3169 l = s4ptr[1]; /* low */
3170 i = s4ptr[2]; /* high */
3172 var_to_reg_int(s1, src, REG_ITMP1);
3174 {M_INTMOVE(s1, REG_ITMP1);}
3175 else if (l <= 32768) {
3176 M_LDA(REG_ITMP1, s1, -l);
3179 ICONST(REG_ITMP2, l);
3180 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
3187 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
3189 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
3190 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3192 M_BEQZ(REG_ITMP2, 0);
3193 mcode_addreference(BlockPtrOfPC(s4ptr[0]), mcodeptr);
3195 /* build jump table top down and use address of lowest entry */
3199 dseg_addtarget(BlockPtrOfPC(*--s4ptr));
3203 /* length of dataseg after last dseg_addtarget is used by load */
3205 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
3206 M_ALD(REG_ITMP2, REG_ITMP2, -dseglen);
3207 M_JMP(REG_ZERO, REG_ITMP2);
3212 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3214 s4 i, l, val, *s4ptr;
3216 s4ptr = iptr->val.a;
3217 l = s4ptr[0]; /* default */
3218 i = s4ptr[1]; /* count */
3220 MCODECHECK((i<<2)+8);
3221 var_to_reg_int(s1, src, REG_ITMP1);
3225 if ((val >= 0) && (val <= 255)) {
3226 M_CMPEQ_IMM(s1, val, REG_ITMP2);
3229 if ((val >= -32768) && (val <= 32767)) {
3230 M_LDA(REG_ITMP2, REG_ZERO, val);
3233 a = dseg_adds4 (val);
3234 M_ILD(REG_ITMP2, REG_PV, a);
3236 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
3238 M_BNEZ(REG_ITMP2, 0);
3239 mcode_addreference(BlockPtrOfPC(s4ptr[1]), mcodeptr);
3243 mcode_addreference(BlockPtrOfPC(l), mcodeptr);
3249 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
3250 /* op1 = return type, val.a = function pointer*/
3254 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
3255 /* op1 = return type, val.a = function pointer*/
3259 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
3260 /* op1 = return type, val.a = function pointer*/
3264 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3265 /* op1 = arg count, val.a = method pointer */
3267 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3268 /* op1 = arg count, val.a = method pointer */
3270 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3271 /* op1 = arg count, val.a = method pointer */
3273 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
3274 /* op1 = arg count, val.a = method pointer */
3282 MCODECHECK((s3 << 1) + 64);
3284 /* copy arguments to registers or stack location */
3286 for (; --s3 >= 0; src = src->prev) {
3287 if (src->varkind == ARGVAR)
3289 if (IS_INT_LNG_TYPE(src->type)) {
3290 if (s3 < INT_ARG_CNT) {
3291 s1 = argintregs[s3];
3292 var_to_reg_int(d, src, s1);
3296 var_to_reg_int(d, src, REG_ITMP1);
3297 M_LST(d, REG_SP, 8 * (s3 - INT_ARG_CNT));
3301 if (s3 < FLT_ARG_CNT) {
3302 s1 = argfltregs[s3];
3303 var_to_reg_flt(d, src, s1);
3307 var_to_reg_flt(d, src, REG_FTMP1);
3308 M_DST(d, REG_SP, 8 * (s3 - FLT_ARG_CNT));
3313 switch (iptr->opc) {
3317 a = dseg_addaddress ((void*) (m));
3319 M_ALD(REG_PV, REG_PV, a); /* Pointer to built-in-function */
3321 goto makeactualcall;
3323 case ICMD_INVOKESTATIC:
3324 case ICMD_INVOKESPECIAL:
3325 a = dseg_addaddress (m->stubroutine);
3327 M_ALD(REG_PV, REG_PV, a ); /* method pointer in r27 */
3330 goto makeactualcall;
3332 case ICMD_INVOKEVIRTUAL:
3334 gen_nullptr_check(argintregs[0]);
3335 M_ALD(REG_METHODPTR, argintregs[0],
3336 OFFSET(java_objectheader, vftbl));
3337 M_ALD(REG_PV, REG_METHODPTR, OFFSET(vftbl, table[0]) +
3338 sizeof(methodptr) * m->vftblindex);
3341 goto makeactualcall;
3343 case ICMD_INVOKEINTERFACE:
3346 gen_nullptr_check(argintregs[0]);
3347 M_ALD(REG_METHODPTR, argintregs[0],
3348 OFFSET(java_objectheader, vftbl));
3349 M_ALD(REG_METHODPTR, REG_METHODPTR,
3350 OFFSET(vftbl, interfacetable[0]) -
3351 sizeof(methodptr*) * ci->index);
3352 M_ALD(REG_PV, REG_METHODPTR,
3353 sizeof(methodptr) * (m - ci->methods));
3356 goto makeactualcall;
3360 sprintf (logtext, "Unkown ICMD-Command: %d", iptr->opc);
3366 M_JSR (REG_RA, REG_PV);
3370 s1 = (int)((u1*) mcodeptr - mcodebase);
3371 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
3374 while (ml<-32768) { ml+=65536; mh--; }
3375 M_LDA (REG_PV, REG_RA, ml );
3376 M_LDAH (REG_PV, REG_PV, mh );
3379 /* d contains return type */
3381 if (d != TYPE_VOID) {
3382 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3383 s1 = reg_of_var(iptr->dst, REG_RESULT);
3384 M_INTMOVE(REG_RESULT, s1);
3385 store_reg_to_var_int(iptr->dst, s1);
3388 s1 = reg_of_var(iptr->dst, REG_FRESULT);
3389 M_FLTMOVE(REG_FRESULT, s1);
3390 store_reg_to_var_flt(iptr->dst, s1);
3397 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3399 /* op1: 0 == array, 1 == class */
3400 /* val.a: (classinfo*) superclass */
3402 /* superclass is an interface:
3404 * return (sub != NULL) &&
3405 * (sub->vftbl->interfacetablelength > super->index) &&
3406 * (sub->vftbl->interfacetable[-super->index] != NULL);
3408 * superclass is a class:
3410 * return ((sub != NULL) && (0
3411 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3412 * super->vftbl->diffvall));
3416 classinfo *super = (classinfo*) iptr->val.a;
3418 var_to_reg_int(s1, src, REG_ITMP1);
3419 d = reg_of_var(iptr->dst, REG_ITMP3);
3421 M_MOV(s1, REG_ITMP1);
3425 if (iptr->op1) { /* class/interface */
3426 if (super->flags & ACC_INTERFACE) { /* interface */
3428 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3429 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3430 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3431 M_BLEZ(REG_ITMP2, 2);
3432 M_ALD(REG_ITMP1, REG_ITMP1,
3433 OFFSET(vftbl, interfacetable[0]) -
3434 super->index * sizeof(methodptr*));
3435 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3438 s2 = super->vftbl->diffval;
3439 M_BEQZ(s1, 4 + (s2 > 255));
3440 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3441 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3442 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3444 M_CMPULE_IMM(REG_ITMP1, s2, d);
3446 M_LDA(REG_ITMP2, REG_ZERO, s2);
3447 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3452 panic ("internal error: no inlined array instanceof");
3454 store_reg_to_var_int(iptr->dst, d);
3457 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3459 /* op1: 0 == array, 1 == class */
3460 /* val.a: (classinfo*) superclass */
3462 /* superclass is an interface:
3464 * OK if ((sub == NULL) ||
3465 * (sub->vftbl->interfacetablelength > super->index) &&
3466 * (sub->vftbl->interfacetable[-super->index] != NULL));
3468 * superclass is a class:
3470 * OK if ((sub == NULL) || (0
3471 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3472 * super->vftbl->diffvall));
3476 classinfo *super = (classinfo*) iptr->val.a;
3478 d = reg_of_var(iptr->dst, REG_ITMP3);
3479 var_to_reg_int(s1, src, d);
3480 if (iptr->op1) { /* class/interface */
3481 if (super->flags & ACC_INTERFACE) { /* interface */
3483 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3484 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3485 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3486 M_BLEZ(REG_ITMP2, 0);
3487 mcode_addxcastrefs(mcodeptr);
3488 M_ALD(REG_ITMP2, REG_ITMP1,
3489 OFFSET(vftbl, interfacetable[0]) -
3490 super->index * sizeof(methodptr*));
3491 M_BEQZ(REG_ITMP2, 0);
3492 mcode_addxcastrefs(mcodeptr);
3495 s2 = super->vftbl->diffval;
3496 M_BEQZ(s1, 4 + (s2 != 0) + (s2 > 255));
3497 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3498 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3499 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3501 M_BNEZ(REG_ITMP1, 0);
3503 else if (s2 <= 255) {
3504 M_CMPULE_IMM(REG_ITMP1, s2, REG_ITMP2);
3505 M_BEQZ(REG_ITMP2, 0);
3508 M_LDA(REG_ITMP2, REG_ZERO, s2);
3509 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3510 M_BEQZ(REG_ITMP2, 0);
3512 mcode_addxcastrefs(mcodeptr);
3516 panic ("internal error: no inlined array checkcast");
3519 store_reg_to_var_int(iptr->dst, d);
3522 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
3524 var_to_reg_int(s1, src, REG_ITMP1);
3526 mcode_addxcheckarefs(mcodeptr);
3529 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3530 /* op1 = dimension, val.a = array descriptor */
3532 /* check for negative sizes and copy sizes to stack if necessary */
3534 MCODECHECK((iptr->op1 << 1) + 64);
3536 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3537 var_to_reg_int(s2, src, REG_ITMP1);
3539 mcode_addxcheckarefs(mcodeptr);
3541 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
3543 if (src->varkind != ARGVAR) {
3544 M_LST(s2, REG_SP, 8 * (s1 + INT_ARG_CNT));
3548 /* a0 = dimension count */
3550 ICONST(argintregs[0], iptr->op1);
3552 /* a1 = arraydescriptor */
3554 a = dseg_addaddress(iptr->val.a);
3555 M_ALD(argintregs[1], REG_PV, a);
3557 /* a2 = pointer to dimensions = stack pointer */
3559 M_INTMOVE(REG_SP, argintregs[2]);
3561 a = dseg_addaddress((void*) (builtin_nmultianewarray));
3562 M_ALD(REG_PV, REG_PV, a);
3563 M_JSR(REG_RA, REG_PV);
3564 s1 = (int)((u1*) mcodeptr - mcodebase);
3566 M_LDA (REG_PV, REG_RA, -s1);
3568 s4 ml = -s1, mh = 0;
3569 while (ml < -32768) {ml += 65536; mh--;}
3570 M_LDA(REG_PV, REG_RA, ml);
3571 M_LDAH(REG_PV, REG_PV, mh);
3573 s1 = reg_of_var(iptr->dst, REG_RESULT);
3574 M_INTMOVE(REG_RESULT, s1);
3575 store_reg_to_var_int(iptr->dst, s1);
3579 default: sprintf (logtext, "Unknown pseudo command: %d", iptr->opc);
3582 } /* for instruction */
3584 /* copy values to interface registers */
3586 src = bptr->outstack;
3587 len = bptr->outdepth;
3591 if ((src->varkind != STACKVAR)) {
3593 if (IS_FLT_DBL_TYPE(s2)) {
3594 var_to_reg_flt(s1, src, REG_FTMP1);
3595 if (!(interfaces[len][s2].flags & INMEMORY)) {
3596 M_FLTMOVE(s1,interfaces[len][s2].regoff);
3599 M_DST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3603 var_to_reg_int(s1, src, REG_ITMP1);
3604 if (!(interfaces[len][s2].flags & INMEMORY)) {
3605 M_INTMOVE(s1,interfaces[len][s2].regoff);
3608 M_LST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3614 } /* if (bptr -> flags >= BBREACHED) */
3615 } /* for basic block */
3617 bptr -> mpc = (int)((u1*) mcodeptr - mcodebase);
3620 /* generate bound check stubs */
3622 s4 *xcodeptr = NULL;
3624 for (; xboundrefs != NULL; xboundrefs = xboundrefs->next) {
3625 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3626 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
3627 xboundrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3631 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
3632 xboundrefs->branchpos, (u1*) mcodeptr - mcodebase);
3636 M_LDA(REG_ITMP2_XPC, REG_PV, xboundrefs->branchpos);
3638 if (xcodeptr != NULL) {
3639 M_BR((xcodeptr-mcodeptr)-1);
3642 xcodeptr = mcodeptr;
3644 a = dseg_addaddress(proto_java_lang_ArrayIndexOutOfBoundsException);
3645 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3647 a = dseg_addaddress(asm_handle_exception);
3648 M_ALD(REG_ITMP3, REG_PV, a);
3650 M_JMP(REG_ZERO, REG_ITMP3);
3654 /* generate negative array size check stubs */
3658 for (; xcheckarefs != NULL; xcheckarefs = xcheckarefs->next) {
3659 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3660 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3661 xcheckarefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3665 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3666 xcheckarefs->branchpos, (u1*) mcodeptr - mcodebase);
3670 M_LDA(REG_ITMP2_XPC, REG_PV, xcheckarefs->branchpos);
3672 if (xcodeptr != NULL) {
3673 M_BR((xcodeptr-mcodeptr)-1);
3676 xcodeptr = mcodeptr;
3678 a = dseg_addaddress(proto_java_lang_NegativeArraySizeException);
3679 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3681 a = dseg_addaddress(asm_handle_exception);
3682 M_ALD(REG_ITMP3, REG_PV, a);
3684 M_JMP(REG_ZERO, REG_ITMP3);
3688 /* generate cast check stubs */
3692 for (; xcastrefs != NULL; xcastrefs = xcastrefs->next) {
3693 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3694 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3695 xcastrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3699 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3700 xcastrefs->branchpos, (u1*) mcodeptr - mcodebase);
3704 M_LDA(REG_ITMP2_XPC, REG_PV, xcastrefs->branchpos);
3706 if (xcodeptr != NULL) {
3707 M_BR((xcodeptr-mcodeptr)-1);
3710 xcodeptr = mcodeptr;
3712 a = dseg_addaddress(proto_java_lang_ClassCastException);
3713 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3715 a = dseg_addaddress(asm_handle_exception);
3716 M_ALD(REG_ITMP3, REG_PV, a);
3718 M_JMP(REG_ZERO, REG_ITMP3);
3723 #ifdef SOFTNULLPTRCHECK
3725 /* generate null pointer check stubs */
3729 for (; xnullrefs != NULL; xnullrefs = xnullrefs->next) {
3730 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3731 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3732 xnullrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3736 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3737 xnullrefs->branchpos, (u1*) mcodeptr - mcodebase);
3741 M_LDA(REG_ITMP2_XPC, REG_PV, xnullrefs->branchpos - 4);
3743 if (xcodeptr != NULL) {
3744 M_BR((xcodeptr-mcodeptr)-1);
3747 xcodeptr = mcodeptr;
3749 a = dseg_addaddress(proto_java_lang_NullPointerException);
3750 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3752 a = dseg_addaddress(asm_handle_exception);
3753 M_ALD(REG_ITMP3, REG_PV, a);
3755 M_JMP(REG_ZERO, REG_ITMP3);
3762 mcode_finish((int)((u1*) mcodeptr - mcodebase));
3766 /* redefinition of code generation macros (compiling into array) **************/
3769 These macros are newly defined to allow code generation into an array.
3770 This is necessary, because the original M_.. macros generate code by
3771 calling 'mcode_adds4' that uses an additional data structure to
3774 For a faster (but less flexible) version to generate code, these
3775 macros directly use the (s4* p) - pointer to put the code directly
3776 in a locally defined array.
3777 This makes sense only for the stub-generation-routines below.
3781 #define M_OP3(op,fu,a,b,c,const) \
3782 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<(16-3*(const)))| \
3783 ((const)<<12)|((fu)<<5)|((c)) )
3785 #define M_FOP3(op,fu,a,b,c) \
3786 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<16)|((fu)<<5)|(c) )
3788 #define M_BRA(op,a,disp) \
3789 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((disp)&0x1fffff) )
3791 #define M_MEM(op,a,b,disp) \
3792 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<16)|((disp)&0xffff) )
3795 /* function createcompilerstub *************************************************
3797 creates a stub routine which calls the compiler
3799 *******************************************************************************/
3801 #define COMPSTUBSIZE 3
3803 u1 *createcompilerstub (methodinfo *m)
3805 u8 *s = CNEW (u8, COMPSTUBSIZE); /* memory to hold the stub */
3806 s4 *p = (s4*) s; /* code generation pointer */
3808 /* code for the stub */
3809 M_ALD (REG_PV, REG_PV, 16); /* load pointer to the compiler */
3810 M_JMP (0, REG_PV); /* jump to the compiler, return address
3811 in reg 0 is used as method pointer */
3812 s[1] = (u8) m; /* literals to be adressed */
3813 s[2] = (u8) asm_call_jit_compiler; /* jump directly via PV from above */
3816 count_cstub_len += COMPSTUBSIZE * 8;
3823 /* function removecompilerstub *************************************************
3825 deletes a compilerstub from memory (simply by freeing it)
3827 *******************************************************************************/
3829 void removecompilerstub (u1 *stub)
3831 CFREE (stub, COMPSTUBSIZE * 8);
3835 /* function: createnativestub **************************************************
3837 creates a stub routine which calls a native method
3839 *******************************************************************************/
3841 #define NATIVESTUBSIZE 11
3843 u1 *createnativestub (functionptr f, methodinfo *m)
3845 u8 *s = CNEW (u8, NATIVESTUBSIZE); /* memory to hold the stub */
3846 s4 *p = (s4*) s; /* code generation pointer */
3848 M_LDA (REG_SP, REG_SP, -8); /* build up stackframe */
3849 M_AST (REG_RA, REG_SP, 0); /* store return address */
3851 M_ALD (REG_PV, REG_PV, 8*8); /* load adress of native method */
3852 M_JSR (REG_RA, REG_PV); /* call native method */
3854 M_LDA (REG_PV, REG_RA, -4*4); /* recompute pv from ra */
3855 M_ALD (REG_ITMP3, REG_PV, 9*8); /* get address of exceptionptr */
3857 M_ALD (REG_RA, REG_SP, 0); /* load return address */
3858 M_ALD (REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
3860 M_LDA (REG_SP, REG_SP, 8); /* remove stackframe */
3861 M_BNEZ (REG_ITMP1, 1); /* if no exception then return */
3863 M_RET (REG_ZERO, REG_RA); /* return to caller */
3865 M_AST (REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
3866 M_LDA (REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
3868 M_ALD (REG_ITMP3, REG_PV,10*8); /* load asm exception handler address */
3869 M_JMP (REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
3872 s[8] = (u8) f; /* address of native method */
3873 s[9] = (u8) (&exceptionptr); /* address of exceptionptr */
3874 s[10]= (u8) (asm_handle_nat_exception); /* addr of asm exception handler */
3877 count_nstub_len += NATIVESTUBSIZE * 8;
3884 /* function: removenativestub **************************************************
3886 removes a previously created native-stub from memory
3888 *******************************************************************************/
3890 void removenativestub (u1 *stub)
3892 CFREE (stub, NATIVESTUBSIZE * 8);
3897 * These are local overrides for various environment variables in Emacs.
3898 * Please do not remove this and leave it at the end of the file, where
3899 * Emacs will automagically detect them.
3900 * ---------------------------------------------------------------------
3903 * indent-tabs-mode: t