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: $Id: ngen.c 474 2003-10-04 18:55:10Z stefan $
16 *******************************************************************************/
18 #include "jitdef.h" /* phil */
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] */
49 #define BlockPtrOfPC(pc) ((basicblock *) iptr->target)
53 #define COUNT_SPILLS count_spills++
59 /* gen_nullptr_check(objreg) */
61 #ifdef SOFTNULLPTRCHECK
62 #define gen_nullptr_check(objreg) \
65 mcode_addxnullrefs(mcodeptr);\
68 #define gen_nullptr_check(objreg)
72 /* MCODECHECK(icnt) */
74 #define MCODECHECK(icnt) \
75 if((mcodeptr+(icnt))>mcodeend)mcodeptr=mcode_increase((u1*)mcodeptr)
78 generates an integer-move from register a to b.
79 if a and b are the same int-register, no code will be generated.
82 #define M_INTMOVE(a,b) if(a!=b){M_MOV(a,b);}
86 generates a floating-point-move from register a to b.
87 if a and b are the same float-register, no code will be generated
90 #define M_FLTMOVE(a,b) if(a!=b){M_FMOV(a,b);}
94 this function generates code to fetch data from a pseudo-register
96 If the pseudo-register has actually been assigned to a real
97 register, no code will be emitted, since following operations
98 can use this register directly.
100 v: pseudoregister to be fetched from
101 tempregnum: temporary register to be used if v is actually spilled to ram
103 return: the register number, where the operand can be found after
104 fetching (this wil be either tempregnum or the register
105 number allready given to v)
108 #define var_to_reg_int(regnr,v,tempnr) { \
109 if ((v)->flags & INMEMORY) \
110 {COUNT_SPILLS;M_LLD(tempnr,REG_SP,8*(v)->regoff);regnr=tempnr;} \
111 else regnr=(v)->regoff; \
115 #define var_to_reg_flt(regnr,v,tempnr) { \
116 if ((v)->flags & INMEMORY) \
117 {COUNT_SPILLS;M_DLD(tempnr,REG_SP,8*(v)->regoff);regnr=tempnr;} \
118 else regnr=(v)->regoff; \
123 This function determines a register, to which the result of an operation
124 should go, when it is ultimatively intended to store the result in
126 If v is assigned to an actual register, this register will be returned.
127 Otherwise (when v is spilled) this function returns tempregnum.
128 If not already done, regoff and flags are set in the stack location.
131 static int reg_of_var(stackptr v, int tempregnum)
135 switch (v->varkind) {
137 if (!(v->flags & INMEMORY))
141 var = &(interfaces[v->varnum][v->type]);
142 v->regoff = var->regoff;
143 if (!(var->flags & INMEMORY))
147 var = &(locals[v->varnum][v->type]);
148 v->regoff = var->regoff;
149 if (!(var->flags & INMEMORY))
153 v->regoff = v->varnum;
154 if (IS_FLT_DBL_TYPE(v->type)) {
155 if (v->varnum < fltreg_argnum) {
156 v->regoff = argfltregs[v->varnum];
157 return(argfltregs[v->varnum]);
161 if (v->varnum < intreg_argnum) {
162 v->regoff = argintregs[v->varnum];
163 return(argintregs[v->varnum]);
165 v->regoff -= intreg_argnum;
168 v->flags |= INMEMORY;
173 /* store_reg_to_var_xxx:
174 This function generates the code to store the result of an operation
175 back into a spilled pseudo-variable.
176 If the pseudo-variable has not been spilled in the first place, this
177 function will generate nothing.
179 v ............ Pseudovariable
180 tempregnum ... Number of the temporary registers as returned by
184 #define store_reg_to_var_int(sptr, tempregnum) { \
185 if ((sptr)->flags & INMEMORY) { \
187 M_LST(tempregnum, REG_SP, 8 * (sptr)->regoff); \
191 #define store_reg_to_var_flt(sptr, tempregnum) { \
192 if ((sptr)->flags & INMEMORY) { \
194 M_DST(tempregnum, REG_SP, 8 * (sptr)->regoff); \
199 /* NullPointerException handlers and exception handling initialisation */
201 typedef struct sigctx_struct {
203 long sc_onstack; /* sigstack state to restore */
204 long sc_mask; /* signal mask to restore */
205 long sc_pc; /* pc at time of signal */
206 long sc_ps; /* psl to retore */
207 long sc_regs[32]; /* processor regs 0 to 31 */
208 long sc_ownedfp; /* fp has been used */
209 long sc_fpregs[32]; /* fp regs 0 to 31 */
210 unsigned long sc_fpcr; /* floating point control register */
211 unsigned long sc_fp_control; /* software fpcr */
213 unsigned long sc_reserved1, sc_reserved2;
214 unsigned long sc_ssize;
216 unsigned long sc_traparg_a0;
217 unsigned long sc_traparg_a1;
218 unsigned long sc_traparg_a2;
219 unsigned long sc_fp_trap_pc;
220 unsigned long sc_fp_trigger_sum;
221 unsigned long sc_fp_trigger_inst;
222 unsigned long sc_retcode[2];
226 /* NullPointerException signal handler for hardware null pointer check */
228 void catch_NullPointerException(int sig, int code, sigctx_struct *sigctx)
234 /* Reset signal handler - necessary for SysV, does no harm for BSD */
236 instr = *((int*)(sigctx->sc_pc));
237 faultaddr = sigctx->sc_regs[(instr >> 16) & 0x1f];
239 if (faultaddr == 0) {
240 signal(sig, (void*) catch_NullPointerException); /* reinstall handler */
242 sigaddset(&nsig, sig);
243 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
244 sigctx->sc_regs[REG_ITMP1_XPTR] =
245 (long) proto_java_lang_NullPointerException;
246 sigctx->sc_regs[REG_ITMP2_XPC] = sigctx->sc_pc;
247 sigctx->sc_pc = (long) asm_handle_exception;
251 faultaddr += (long) ((instr << 16) >> 16);
252 fprintf(stderr, "faulting address: 0x%16lx\n", faultaddr);
253 panic("Stack overflow");
260 void init_exceptions(void)
265 /* Linux on Digital Alpha needs an initialisation of the ieee floating point
266 control for IEEE compliant arithmetic (option -mieee of GCC). Under
267 Digital Unix this is done automatically.
272 extern unsigned long ieee_get_fp_control();
273 extern void ieee_set_fp_control(unsigned long fp_control);
275 void init_exceptions(void)
277 /* initialize floating point control */
280 ieee_set_fp_control(ieee_get_fp_control()
281 & ~IEEE_TRAP_ENABLE_INV
282 & ~IEEE_TRAP_ENABLE_DZE
283 /* & ~IEEE_TRAP_ENABLE_UNF we dont want underflow */
284 & ~IEEE_TRAP_ENABLE_INE
285 & ~IEEE_TRAP_ENABLE_DNO
286 & ~IEEE_TRAP_ENABLE_OVF);
290 /* install signal handlers we need to convert to exceptions */
295 signal(SIGSEGV, (void*) catch_NullPointerException);
299 signal(SIGBUS, (void*) catch_NullPointerException);
305 void print_float(double d)
309 // printf("%d %08x %08x\n", ++count, i1[1], i1[0]);
311 sprintf(buf, "%g", d);
312 printf("%d %s\n", ++count, buf+1);
315 /* function gen_mcode **********************************************************
317 generates machine code
319 *******************************************************************************/
321 #define MethodPointer -8
322 #define FrameSize -12
327 #define ExTableSize -32
328 #define ExTableStart -32
330 #define ExEntrySize -32
333 #define ExHandlerPC -24
334 #define ExCatchType -32
338 static void gen_mcode()
340 int len, s1, s2, s3, d, bbs;
353 if (++mcount == 99) {
356 savedregs_num = (isleafmethod) ? 0 : 1; /* space to save the RA */
358 /* space to save used callee saved registers */
360 savedregs_num += (savintregcnt - maxsavintreguse);
361 savedregs_num += (savfltregcnt - maxsavfltreguse);
363 parentargs_base = maxmemuse + savedregs_num;
365 #ifdef USE_THREADS /* space to save argument of monitor_enter */
367 if (checksync && (method->flags & ACC_SYNCHRONIZED))
372 /* create method header */
374 (void) dseg_addaddress(method); /* MethodPointer */
375 (void) dseg_adds4(parentargs_base * 8); /* FrameSize */
379 /* IsSync contains the offset relative to the stack pointer for the
380 argument of monitor_exit used in the exception handler. Since the
381 offset could be zero and give a wrong meaning of the flag it is
385 if (checksync && (method->flags & ACC_SYNCHRONIZED))
386 (void) dseg_adds4((maxmemuse + 1) * 8); /* IsSync */
391 (void) dseg_adds4(0); /* IsSync */
393 (void) dseg_adds4(isleafmethod); /* IsLeaf */
394 (void) dseg_adds4(savintregcnt - maxsavintreguse); /* IntSave */
395 (void) dseg_adds4(savfltregcnt - maxsavfltreguse); /* FltSave */
396 (void) dseg_adds4(exceptiontablelength); /* ExTableSize */
398 /* create exception table */
400 for (ex = extable; ex != NULL; ex = ex->down) {
403 if (ex->start != NULL)
404 printf("adding start - %d - ", ex->start->debug_nr);
406 printf("PANIC - start is NULL");
411 dseg_addtarget(ex->start);
415 printf("adding end - %d - ", ex->end->debug_nr);
417 printf("PANIC - end is NULL");
422 dseg_addtarget(ex->end);
425 if (ex->handler != NULL)
426 printf("adding handler - %d\n", ex->handler->debug_nr);
428 printf("PANIC - handler is NULL");
433 dseg_addtarget(ex->handler);
435 (void) dseg_addaddress(ex->catchtype);
438 /* initialize mcode variables */
440 mcodeptr = (s4*) mcodebase;
441 mcodeend = (s4*) (mcodebase + mcodesize);
442 MCODECHECK(128 + mparamcount);
444 /* create stack frame (if necessary) */
447 {M_LDA (REG_SP, REG_SP, -parentargs_base * 8);}
449 /* save return address and used callee saved registers */
453 {p--; M_AST (REG_RA, REG_SP, 8*p);}
454 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
455 {p--; M_LST (savintregs[r], REG_SP, 8 * p);}
456 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
457 {p--; M_DST (savfltregs[r], REG_SP, 8 * p);}
459 /* save monitorenter argument */
462 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
463 if (method->flags & ACC_STATIC) {
464 p = dseg_addaddress (class);
465 M_ALD(REG_ITMP1, REG_PV, p);
466 M_AST(REG_ITMP1, REG_SP, 8 * maxmemuse);
469 M_AST (argintregs[0], REG_SP, 8 * maxmemuse);
474 /* copy argument registers to stack and call trace function with pointer
475 to arguments on stack. ToDo: save floating point registers !!!!!!!!!
479 M_LDA (REG_SP, REG_SP, -(14*8));
480 M_AST(REG_RA, REG_SP, 1*8);
482 M_LST(argintregs[0], REG_SP, 2*8);
483 M_LST(argintregs[1], REG_SP, 3*8);
484 M_LST(argintregs[2], REG_SP, 4*8);
485 M_LST(argintregs[3], REG_SP, 5*8);
486 M_LST(argintregs[4], REG_SP, 6*8);
487 M_LST(argintregs[5], REG_SP, 7*8);
489 M_DST(argfltregs[0], REG_SP, 8*8);
490 M_DST(argfltregs[1], REG_SP, 9*8);
491 M_DST(argfltregs[2], REG_SP, 10*8);
492 M_DST(argfltregs[3], REG_SP, 11*8);
493 M_DST(argfltregs[4], REG_SP, 12*8);
494 M_DST(argfltregs[5], REG_SP, 13*8);
496 p = dseg_addaddress (method);
497 M_ALD(REG_ITMP1, REG_PV, p);
498 M_AST(REG_ITMP1, REG_SP, 0);
499 p = dseg_addaddress ((void*) (builtin_trace_args));
500 M_ALD(REG_PV, REG_PV, p);
501 M_JSR(REG_RA, REG_PV);
502 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
503 M_ALD(REG_RA, REG_SP, 1*8);
505 M_LLD(argintregs[0], REG_SP, 2*8);
506 M_LLD(argintregs[1], REG_SP, 3*8);
507 M_LLD(argintregs[2], REG_SP, 4*8);
508 M_LLD(argintregs[3], REG_SP, 5*8);
509 M_LLD(argintregs[4], REG_SP, 6*8);
510 M_LLD(argintregs[5], REG_SP, 7*8);
512 M_DLD(argfltregs[0], REG_SP, 8*8);
513 M_DLD(argfltregs[1], REG_SP, 9*8);
514 M_DLD(argfltregs[2], REG_SP, 10*8);
515 M_DLD(argfltregs[3], REG_SP, 11*8);
516 M_DLD(argfltregs[4], REG_SP, 12*8);
517 M_DLD(argfltregs[5], REG_SP, 13*8);
519 M_LDA (REG_SP, REG_SP, 14*8);
522 /* take arguments out of register or stack frame */
524 for (p = 0, l = 0; p < mparamcount; p++) {
526 var = &(locals[l][t]);
528 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
533 if (IS_INT_LNG_TYPE(t)) { /* integer args */
534 if (p < INT_ARG_CNT) { /* register arguments */
535 if (!(var->flags & INMEMORY)) /* reg arg -> register */
536 {M_INTMOVE (argintregs[p], r);}
537 else /* reg arg -> spilled */
538 M_LST (argintregs[p], REG_SP, 8 * r);
540 else { /* stack arguments */
541 pa = p - INT_ARG_CNT;
542 if (!(var->flags & INMEMORY)) /* stack arg -> register */
543 M_LLD (r, REG_SP, 8 * (parentargs_base + pa));
544 else { /* stack arg -> spilled */
545 M_LLD (REG_ITMP1, REG_SP, 8 * (parentargs_base + pa));
546 M_LST (REG_ITMP1, REG_SP, 8 * r);
550 else { /* floating args */
551 if (p < FLT_ARG_CNT) { /* register arguments */
552 if (!(var->flags & INMEMORY)) /* reg arg -> register */
553 {M_FLTMOVE (argfltregs[p], r);}
554 else /* reg arg -> spilled */
555 M_DST (argfltregs[p], REG_SP, 8 * r);
557 else { /* stack arguments */
558 pa = p - FLT_ARG_CNT;
559 if (!(var->flags & INMEMORY)) /* stack-arg -> register */
560 M_DLD (r, REG_SP, 8 * (parentargs_base + pa) );
561 else { /* stack-arg -> spilled */
562 M_DLD (REG_FTMP1, REG_SP, 8 * (parentargs_base + pa));
563 M_DST (REG_FTMP1, REG_SP, 8 * r);
569 /* call trace function */
572 if (runverbose && !isleafmethod) {
573 M_LDA (REG_SP, REG_SP, -8);
574 p = dseg_addaddress (method);
575 M_ALD(REG_ITMP1, REG_PV, p);
576 M_AST(REG_ITMP1, REG_SP, 0);
577 p = dseg_addaddress ((void*) (builtin_trace_args));
578 M_ALD(REG_PV, REG_PV, p);
579 M_JSR(REG_RA, REG_PV);
580 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
581 M_LDA(REG_SP, REG_SP, 8);
585 /* call monitorenter function */
588 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
589 p = dseg_addaddress ((void*) (builtin_monitorenter));
590 M_ALD(REG_PV, REG_PV, p);
591 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
592 M_JSR(REG_RA, REG_PV);
593 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
598 /* end of header generation */
600 /* walk through all basic blocks */
601 for (/* bbs = block_count, */ bptr = block; /* --bbs >= 0 */ bptr != NULL; bptr = bptr->next) {
603 bptr -> mpc = (int)((u1*) mcodeptr - mcodebase);
605 if (bptr->flags >= BBREACHED) {
607 /* branch resolving */
611 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
612 gen_resolvebranch((u1*) mcodebase + brefs->branchpos,
613 brefs->branchpos, bptr->mpc);
617 /* copy interface registers to their destination */
622 while (src != NULL) {
624 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
625 d = reg_of_var(src, REG_ITMP1);
626 M_INTMOVE(REG_ITMP1, d);
627 store_reg_to_var_int(src, d);
630 d = reg_of_var(src, REG_IFTMP);
631 if ((src->varkind != STACKVAR)) {
633 if (IS_FLT_DBL_TYPE(s2)) {
634 if (!(interfaces[len][s2].flags & INMEMORY)) {
635 s1 = interfaces[len][s2].regoff;
639 M_DLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
641 store_reg_to_var_flt(src, d);
644 if (!(interfaces[len][s2].flags & INMEMORY)) {
645 s1 = interfaces[len][s2].regoff;
649 M_LLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
651 store_reg_to_var_int(src, d);
658 /* walk through all instructions */
662 for (iptr = bptr->iinstr;
664 src = iptr->dst, len--, iptr++) {
666 MCODECHECK(64); /* an instruction usually needs < 64 words */
669 case ICMD_NOP: /* ... ==> ... */
672 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
674 var_to_reg_int(s1, src, REG_ITMP1);
676 mcode_addxnullrefs(mcodeptr);
679 /* constant operations ************************************************/
681 #define ICONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
682 else{a=dseg_adds4(c);M_ILD(r,REG_PV,a);}
684 #define LCONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
685 else{a=dseg_adds8(c);M_LLD(r,REG_PV,a);}
687 case ICMD_ICONST: /* ... ==> ..., constant */
688 /* op1 = 0, val.i = constant */
690 d = reg_of_var(iptr->dst, REG_ITMP1);
691 ICONST(d, iptr->val.i);
692 store_reg_to_var_int(iptr->dst, d);
695 case ICMD_LCONST: /* ... ==> ..., constant */
696 /* op1 = 0, val.l = constant */
698 d = reg_of_var(iptr->dst, REG_ITMP1);
699 LCONST(d, iptr->val.l);
700 store_reg_to_var_int(iptr->dst, d);
703 case ICMD_FCONST: /* ... ==> ..., constant */
704 /* op1 = 0, val.f = constant */
706 d = reg_of_var (iptr->dst, REG_FTMP1);
707 a = dseg_addfloat (iptr->val.f);
709 store_reg_to_var_flt (iptr->dst, d);
712 case ICMD_DCONST: /* ... ==> ..., constant */
713 /* op1 = 0, val.d = constant */
715 d = reg_of_var (iptr->dst, REG_FTMP1);
716 a = dseg_adddouble (iptr->val.d);
718 store_reg_to_var_flt (iptr->dst, d);
721 case ICMD_ACONST: /* ... ==> ..., constant */
722 /* op1 = 0, val.a = constant */
724 d = reg_of_var(iptr->dst, REG_ITMP1);
726 a = dseg_addaddress (iptr->val.a);
730 M_INTMOVE(REG_ZERO, d);
732 store_reg_to_var_int(iptr->dst, d);
736 /* load/store operations **********************************************/
738 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
739 case ICMD_LLOAD: /* op1 = local variable */
742 d = reg_of_var(iptr->dst, REG_ITMP1);
743 if ((iptr->dst->varkind == LOCALVAR) &&
744 (iptr->dst->varnum == iptr->op1))
746 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
747 if (var->flags & INMEMORY)
748 M_LLD(d, REG_SP, 8 * var->regoff);
750 {M_INTMOVE(var->regoff,d);}
751 store_reg_to_var_int(iptr->dst, d);
754 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
755 case ICMD_DLOAD: /* op1 = local variable */
757 d = reg_of_var(iptr->dst, REG_FTMP1);
759 if ((iptr->dst->varkind == LOCALVAR) &&
760 (iptr->dst->varnum == iptr->op1))
763 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
764 if (var->flags & INMEMORY)
765 M_DLD(d, REG_SP, 8 * var->regoff);
767 {M_FLTMOVE(var->regoff,d);}
768 store_reg_to_var_flt(iptr->dst, d);
771 M_LDA(REG_SP, REG_SP, -8 * 38);
772 M_LST(REG_RA, REG_SP, 0);
773 M_LST(1, REG_SP, 8 * 1);
774 M_LST(2, REG_SP, 8 * 2);
775 M_LST(3, REG_SP, 8 * 3);
776 M_LST(4, REG_SP, 8 * 4);
777 M_LST(5, REG_SP, 8 * 5);
778 M_LST(6, REG_SP, 8 * 6);
779 M_LST(7, REG_SP, 8 * 7);
780 M_LST(8, REG_SP, 8 * 8);
781 M_LST(16, REG_SP, 8 * 9);
782 M_LST(17, REG_SP, 8 * 10);
783 M_LST(18, REG_SP, 8 * 11);
784 M_LST(19, REG_SP, 8 * 12);
785 M_LST(20, REG_SP, 8 * 13);
786 M_LST(21, REG_SP, 8 * 14);
787 M_LST(22, REG_SP, 8 * 15);
788 M_LST(23, REG_SP, 8 * 16);
789 M_LST(24, REG_SP, 8 * 17);
790 M_LST(REG_PV, REG_SP, 8 * 18);
792 M_DST(1, REG_SP, 8 * 19);
793 M_DST(10, REG_SP, 8 * 20);
794 M_DST(11, REG_SP, 8 * 21);
795 M_DST(12, REG_SP, 8 * 22);
796 M_DST(13, REG_SP, 8 * 23);
797 M_DST(14, REG_SP, 8 * 24);
798 M_DST(15, REG_SP, 8 * 25);
799 M_DST(16, REG_SP, 8 * 26);
800 M_DST(17, REG_SP, 8 * 27);
801 M_DST(18, REG_SP, 8 * 28);
802 M_DST(19, REG_SP, 8 * 29);
803 M_DST(20, REG_SP, 8 * 30);
804 M_DST(21, REG_SP, 8 * 31);
805 M_DST(22, REG_SP, 8 * 32);
806 M_DST(23, REG_SP, 8 * 33);
807 M_DST(24, REG_SP, 8 * 34);
808 M_DST(25, REG_SP, 8 * 35);
809 M_DST(26, REG_SP, 8 * 36);
810 M_DST(27, REG_SP, 8 * 37);
813 a = dseg_addaddress (print_float);
814 M_ALD(REG_PV, REG_PV, a);
815 M_JSR(REG_RA, REG_PV);
817 M_LLD(REG_RA, REG_SP, 0);
818 M_LLD(1, REG_SP, 8 * 1);
819 M_LLD(2, REG_SP, 8 * 2);
820 M_LLD(3, REG_SP, 8 * 3);
821 M_LLD(4, REG_SP, 8 * 4);
822 M_LLD(5, REG_SP, 8 * 5);
823 M_LLD(6, REG_SP, 8 * 6);
824 M_LLD(7, REG_SP, 8 * 7);
825 M_LLD(8, REG_SP, 8 * 8);
826 M_LLD(16, REG_SP, 8 * 9);
827 M_LLD(17, REG_SP, 8 * 10);
828 M_LLD(18, REG_SP, 8 * 11);
829 M_LLD(19, REG_SP, 8 * 12);
830 M_LLD(20, REG_SP, 8 * 13);
831 M_LLD(21, REG_SP, 8 * 14);
832 M_LLD(22, REG_SP, 8 * 15);
833 M_LLD(23, REG_SP, 8 * 16);
834 M_LLD(24, REG_SP, 8 * 17);
835 M_LLD(REG_PV, REG_SP, 8 * 18);
837 M_DLD(1, REG_SP, 8 * 19);
838 M_DLD(10, REG_SP, 8 * 20);
839 M_DLD(11, REG_SP, 8 * 21);
840 M_DLD(12, REG_SP, 8 * 22);
841 M_DLD(13, REG_SP, 8 * 23);
842 M_DLD(14, REG_SP, 8 * 24);
843 M_DLD(15, REG_SP, 8 * 25);
844 M_DLD(16, REG_SP, 8 * 26);
845 M_DLD(17, REG_SP, 8 * 27);
846 M_DLD(18, REG_SP, 8 * 28);
847 M_DLD(19, REG_SP, 8 * 29);
848 M_DLD(20, REG_SP, 8 * 30);
849 M_DLD(21, REG_SP, 8 * 31);
850 M_DLD(22, REG_SP, 8 * 32);
851 M_DLD(23, REG_SP, 8 * 33);
852 M_DLD(24, REG_SP, 8 * 34);
853 M_DLD(25, REG_SP, 8 * 35);
854 M_DLD(26, REG_SP, 8 * 36);
855 M_DLD(27, REG_SP, 8 * 37);
856 M_LDA(REG_SP, REG_SP, 8 * 38);
862 case ICMD_ISTORE: /* ..., value ==> ... */
863 case ICMD_LSTORE: /* op1 = local variable */
866 if ((src->varkind == LOCALVAR) &&
867 (src->varnum == iptr->op1))
869 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
870 if (var->flags & INMEMORY) {
871 var_to_reg_int(s1, src, REG_ITMP1);
872 M_LST(s1, REG_SP, 8 * var->regoff);
875 var_to_reg_int(s1, src, var->regoff);
876 M_INTMOVE(s1, var->regoff);
880 case ICMD_FSTORE: /* ..., value ==> ... */
881 case ICMD_DSTORE: /* op1 = local variable */
883 if ((src->varkind == LOCALVAR) &&
884 (src->varnum == iptr->op1))
886 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
887 if (var->flags & INMEMORY) {
888 var_to_reg_flt(s1, src, REG_FTMP1);
889 M_DST(s1, REG_SP, 8 * var->regoff);
892 var_to_reg_flt(s1, src, var->regoff);
893 M_FLTMOVE(s1, var->regoff);
898 /* pop/dup/swap operations ********************************************/
900 /* attention: double and longs are only one entry in CACAO ICMDs */
902 case ICMD_POP: /* ..., value ==> ... */
903 case ICMD_POP2: /* ..., value, value ==> ... */
906 #define M_COPY(from,to) \
907 d = reg_of_var(to, REG_IFTMP); \
908 if ((from->regoff != to->regoff) || \
909 ((from->flags ^ to->flags) & INMEMORY)) { \
910 if (IS_FLT_DBL_TYPE(from->type)) { \
911 var_to_reg_flt(s1, from, d); \
913 store_reg_to_var_flt(to, d); \
916 var_to_reg_int(s1, from, d); \
918 store_reg_to_var_int(to, d); \
922 case ICMD_DUP: /* ..., a ==> ..., a, a */
923 M_COPY(src, iptr->dst);
926 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
928 M_COPY(src, iptr->dst->prev->prev);
930 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
932 M_COPY(src, iptr->dst);
933 M_COPY(src->prev, iptr->dst->prev);
936 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
938 M_COPY(src->prev, iptr->dst->prev->prev->prev);
940 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
942 M_COPY(src, iptr->dst);
943 M_COPY(src->prev, iptr->dst->prev);
944 M_COPY(src->prev->prev, iptr->dst->prev->prev);
945 M_COPY(src, iptr->dst->prev->prev->prev);
948 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
950 M_COPY(src, iptr->dst);
951 M_COPY(src->prev, iptr->dst->prev);
952 M_COPY(src->prev->prev, iptr->dst->prev->prev);
953 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
954 M_COPY(src, iptr->dst->prev->prev->prev->prev);
955 M_COPY(src->prev, iptr->dst->prev->prev->prev->prev->prev);
958 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
960 M_COPY(src, iptr->dst->prev);
961 M_COPY(src->prev, iptr->dst);
965 /* integer operations *************************************************/
967 case ICMD_INEG: /* ..., value ==> ..., - value */
969 var_to_reg_int(s1, src, REG_ITMP1);
970 d = reg_of_var(iptr->dst, REG_ITMP3);
971 M_ISUB(REG_ZERO, s1, d);
972 store_reg_to_var_int(iptr->dst, d);
975 case ICMD_LNEG: /* ..., value ==> ..., - value */
977 var_to_reg_int(s1, src, REG_ITMP1);
978 d = reg_of_var(iptr->dst, REG_ITMP3);
979 M_LSUB(REG_ZERO, s1, d);
980 store_reg_to_var_int(iptr->dst, d);
983 case ICMD_I2L: /* ..., value ==> ..., value */
985 var_to_reg_int(s1, src, REG_ITMP1);
986 d = reg_of_var(iptr->dst, REG_ITMP3);
988 store_reg_to_var_int(iptr->dst, d);
991 case ICMD_L2I: /* ..., value ==> ..., value */
993 var_to_reg_int(s1, src, REG_ITMP1);
994 d = reg_of_var(iptr->dst, REG_ITMP3);
995 M_IADD(s1, REG_ZERO, d );
996 store_reg_to_var_int(iptr->dst, d);
999 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
1001 var_to_reg_int(s1, src, REG_ITMP1);
1002 d = reg_of_var(iptr->dst, REG_ITMP3);
1003 if (has_ext_instr_set) {
1007 M_SLL_IMM(s1, 56, d);
1008 M_SRA_IMM( d, 56, d);
1010 store_reg_to_var_int(iptr->dst, d);
1013 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
1015 var_to_reg_int(s1, src, REG_ITMP1);
1016 d = reg_of_var(iptr->dst, REG_ITMP3);
1018 store_reg_to_var_int(iptr->dst, d);
1021 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
1023 var_to_reg_int(s1, src, REG_ITMP1);
1024 d = reg_of_var(iptr->dst, REG_ITMP3);
1025 if (has_ext_instr_set) {
1029 M_SLL_IMM(s1, 48, d);
1030 M_SRA_IMM( d, 48, d);
1032 store_reg_to_var_int(iptr->dst, d);
1036 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1038 var_to_reg_int(s1, src->prev, REG_ITMP1);
1039 var_to_reg_int(s2, src, REG_ITMP2);
1040 d = reg_of_var(iptr->dst, REG_ITMP3);
1042 store_reg_to_var_int(iptr->dst, d);
1045 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
1046 /* val.i = constant */
1048 var_to_reg_int(s1, src, REG_ITMP1);
1049 d = reg_of_var(iptr->dst, REG_ITMP3);
1050 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1051 M_IADD_IMM(s1, iptr->val.i, d);
1054 ICONST(REG_ITMP2, iptr->val.i);
1055 M_IADD(s1, REG_ITMP2, d);
1057 store_reg_to_var_int(iptr->dst, d);
1060 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1062 var_to_reg_int(s1, src->prev, REG_ITMP1);
1063 var_to_reg_int(s2, src, REG_ITMP2);
1064 d = reg_of_var(iptr->dst, REG_ITMP3);
1066 store_reg_to_var_int(iptr->dst, d);
1069 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
1070 /* val.l = constant */
1072 var_to_reg_int(s1, src, REG_ITMP1);
1073 d = reg_of_var(iptr->dst, REG_ITMP3);
1074 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1075 M_LADD_IMM(s1, iptr->val.l, d);
1078 LCONST(REG_ITMP2, iptr->val.l);
1079 M_LADD(s1, REG_ITMP2, d);
1081 store_reg_to_var_int(iptr->dst, d);
1084 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1086 var_to_reg_int(s1, src->prev, REG_ITMP1);
1087 var_to_reg_int(s2, src, REG_ITMP2);
1088 d = reg_of_var(iptr->dst, REG_ITMP3);
1090 store_reg_to_var_int(iptr->dst, d);
1093 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
1094 /* val.i = constant */
1096 var_to_reg_int(s1, src, REG_ITMP1);
1097 d = reg_of_var(iptr->dst, REG_ITMP3);
1098 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1099 M_ISUB_IMM(s1, iptr->val.i, d);
1102 ICONST(REG_ITMP2, iptr->val.i);
1103 M_ISUB(s1, REG_ITMP2, d);
1105 store_reg_to_var_int(iptr->dst, d);
1108 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1110 var_to_reg_int(s1, src->prev, REG_ITMP1);
1111 var_to_reg_int(s2, src, REG_ITMP2);
1112 d = reg_of_var(iptr->dst, REG_ITMP3);
1114 store_reg_to_var_int(iptr->dst, d);
1117 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
1118 /* val.l = constant */
1120 var_to_reg_int(s1, src, REG_ITMP1);
1121 d = reg_of_var(iptr->dst, REG_ITMP3);
1122 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1123 M_LSUB_IMM(s1, iptr->val.l, d);
1126 LCONST(REG_ITMP2, iptr->val.l);
1127 M_LSUB(s1, REG_ITMP2, d);
1129 store_reg_to_var_int(iptr->dst, d);
1132 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1134 var_to_reg_int(s1, src->prev, REG_ITMP1);
1135 var_to_reg_int(s2, src, REG_ITMP2);
1136 d = reg_of_var(iptr->dst, REG_ITMP3);
1138 store_reg_to_var_int(iptr->dst, d);
1141 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
1142 /* val.i = constant */
1144 var_to_reg_int(s1, src, REG_ITMP1);
1145 d = reg_of_var(iptr->dst, REG_ITMP3);
1146 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1147 M_IMUL_IMM(s1, iptr->val.i, d);
1150 ICONST(REG_ITMP2, iptr->val.i);
1151 M_IMUL(s1, REG_ITMP2, d);
1153 store_reg_to_var_int(iptr->dst, d);
1156 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1158 var_to_reg_int(s1, src->prev, REG_ITMP1);
1159 var_to_reg_int(s2, src, REG_ITMP2);
1160 d = reg_of_var(iptr->dst, REG_ITMP3);
1162 store_reg_to_var_int(iptr->dst, d);
1165 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
1166 /* val.l = constant */
1168 var_to_reg_int(s1, src, REG_ITMP1);
1169 d = reg_of_var(iptr->dst, REG_ITMP3);
1170 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1171 M_LMUL_IMM(s1, iptr->val.l, d);
1174 LCONST(REG_ITMP2, iptr->val.l);
1175 M_LMUL(s1, REG_ITMP2, d);
1177 store_reg_to_var_int(iptr->dst, d);
1180 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
1181 case ICMD_LDIVPOW2: /* val.i = constant */
1183 var_to_reg_int(s1, src, REG_ITMP1);
1184 d = reg_of_var(iptr->dst, REG_ITMP3);
1185 if (iptr->val.i <= 15) {
1186 M_LDA(REG_ITMP2, s1, (1 << iptr->val.i) -1);
1187 M_CMOVGE(s1, s1, REG_ITMP2);
1190 M_SRA_IMM(s1, 63, REG_ITMP2);
1191 M_SRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
1192 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1194 M_SRA_IMM(REG_ITMP2, iptr->val.i, d);
1195 store_reg_to_var_int(iptr->dst, d);
1198 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1200 var_to_reg_int(s1, src->prev, REG_ITMP1);
1201 var_to_reg_int(s2, src, REG_ITMP2);
1202 d = reg_of_var(iptr->dst, REG_ITMP3);
1203 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1204 M_SLL(s1, REG_ITMP3, d);
1205 M_IADD(d, REG_ZERO, d);
1206 store_reg_to_var_int(iptr->dst, d);
1209 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1210 /* val.i = constant */
1212 var_to_reg_int(s1, src, REG_ITMP1);
1213 d = reg_of_var(iptr->dst, REG_ITMP3);
1214 M_SLL_IMM(s1, iptr->val.i & 0x1f, d);
1215 M_IADD(d, REG_ZERO, d);
1216 store_reg_to_var_int(iptr->dst, d);
1219 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1221 var_to_reg_int(s1, src->prev, REG_ITMP1);
1222 var_to_reg_int(s2, src, REG_ITMP2);
1223 d = reg_of_var(iptr->dst, REG_ITMP3);
1224 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1225 M_SRA(s1, REG_ITMP3, d);
1226 store_reg_to_var_int(iptr->dst, d);
1229 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1230 /* val.i = constant */
1232 var_to_reg_int(s1, src, REG_ITMP1);
1233 d = reg_of_var(iptr->dst, REG_ITMP3);
1234 M_SRA_IMM(s1, iptr->val.i & 0x1f, d);
1235 store_reg_to_var_int(iptr->dst, d);
1238 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1240 var_to_reg_int(s1, src->prev, REG_ITMP1);
1241 var_to_reg_int(s2, src, REG_ITMP2);
1242 d = reg_of_var(iptr->dst, REG_ITMP3);
1243 M_AND_IMM(s2, 0x1f, REG_ITMP2);
1245 M_SRL(d, REG_ITMP2, d);
1246 M_IADD(d, REG_ZERO, d);
1247 store_reg_to_var_int(iptr->dst, d);
1250 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1251 /* val.i = constant */
1253 var_to_reg_int(s1, src, REG_ITMP1);
1254 d = reg_of_var(iptr->dst, REG_ITMP3);
1256 M_SRL_IMM(d, iptr->val.i & 0x1f, d);
1257 M_IADD(d, REG_ZERO, d);
1258 store_reg_to_var_int(iptr->dst, d);
1261 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1263 var_to_reg_int(s1, src->prev, REG_ITMP1);
1264 var_to_reg_int(s2, src, REG_ITMP2);
1265 d = reg_of_var(iptr->dst, REG_ITMP3);
1267 store_reg_to_var_int(iptr->dst, d);
1270 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1271 /* val.i = constant */
1273 var_to_reg_int(s1, src, REG_ITMP1);
1274 d = reg_of_var(iptr->dst, REG_ITMP3);
1275 M_SLL_IMM(s1, iptr->val.i & 0x3f, d);
1276 store_reg_to_var_int(iptr->dst, d);
1279 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1281 var_to_reg_int(s1, src->prev, REG_ITMP1);
1282 var_to_reg_int(s2, src, REG_ITMP2);
1283 d = reg_of_var(iptr->dst, REG_ITMP3);
1285 store_reg_to_var_int(iptr->dst, d);
1288 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1289 /* val.i = constant */
1291 var_to_reg_int(s1, src, REG_ITMP1);
1292 d = reg_of_var(iptr->dst, REG_ITMP3);
1293 M_SRA_IMM(s1, iptr->val.i & 0x3f, d);
1294 store_reg_to_var_int(iptr->dst, d);
1297 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1299 var_to_reg_int(s1, src->prev, REG_ITMP1);
1300 var_to_reg_int(s2, src, REG_ITMP2);
1301 d = reg_of_var(iptr->dst, REG_ITMP3);
1303 store_reg_to_var_int(iptr->dst, d);
1306 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1307 /* val.i = constant */
1309 var_to_reg_int(s1, src, REG_ITMP1);
1310 d = reg_of_var(iptr->dst, REG_ITMP3);
1311 M_SRL_IMM(s1, iptr->val.i & 0x3f, d);
1312 store_reg_to_var_int(iptr->dst, d);
1315 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1318 var_to_reg_int(s1, src->prev, REG_ITMP1);
1319 var_to_reg_int(s2, src, REG_ITMP2);
1320 d = reg_of_var(iptr->dst, REG_ITMP3);
1322 store_reg_to_var_int(iptr->dst, d);
1325 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1326 /* val.i = constant */
1328 var_to_reg_int(s1, src, REG_ITMP1);
1329 d = reg_of_var(iptr->dst, REG_ITMP3);
1330 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1331 M_AND_IMM(s1, iptr->val.i, d);
1333 else if (iptr->val.i == 0xffff) {
1336 else if (iptr->val.i == 0xffffff) {
1337 M_ZAPNOT_IMM(s1, 0x07, d);
1340 ICONST(REG_ITMP2, iptr->val.i);
1341 M_AND(s1, REG_ITMP2, d);
1343 store_reg_to_var_int(iptr->dst, d);
1346 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1347 /* val.i = constant */
1349 var_to_reg_int(s1, src, REG_ITMP1);
1350 d = reg_of_var(iptr->dst, REG_ITMP3);
1352 M_MOV(s1, REG_ITMP1);
1355 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1356 M_AND_IMM(s1, iptr->val.i, d);
1358 M_ISUB(REG_ZERO, s1, d);
1359 M_AND_IMM(d, iptr->val.i, d);
1361 else if (iptr->val.i == 0xffff) {
1364 M_ISUB(REG_ZERO, s1, d);
1367 else if (iptr->val.i == 0xffffff) {
1368 M_ZAPNOT_IMM(s1, 0x07, d);
1370 M_ISUB(REG_ZERO, s1, d);
1371 M_ZAPNOT_IMM(d, 0x07, d);
1374 ICONST(REG_ITMP2, iptr->val.i);
1375 M_AND(s1, REG_ITMP2, d);
1377 M_ISUB(REG_ZERO, s1, d);
1378 M_AND(d, REG_ITMP2, d);
1380 M_ISUB(REG_ZERO, d, d);
1381 store_reg_to_var_int(iptr->dst, d);
1384 case ICMD_IREM0X10001: /* ..., value ==> ..., value % 0x100001 */
1386 /* b = value & 0xffff;
1388 a = ((b - a) & 0xffff) + (b < a);
1390 var_to_reg_int(s1, src, REG_ITMP1);
1391 d = reg_of_var(iptr->dst, REG_ITMP3);
1393 M_MOV(s1, REG_ITMP3);
1397 M_CZEXT(s1, REG_ITMP2);
1398 M_SRA_IMM(s1, 16, d);
1399 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1400 M_ISUB(REG_ITMP2, d, d);
1402 M_IADD(d, REG_ITMP1, d);
1403 M_BR(11 + (s1 == REG_ITMP1));
1404 M_ISUB(REG_ZERO, s1, REG_ITMP1);
1405 M_CZEXT(REG_ITMP1, REG_ITMP2);
1406 M_SRA_IMM(REG_ITMP1, 16, d);
1407 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1408 M_ISUB(REG_ITMP2, d, d);
1410 M_IADD(d, REG_ITMP1, d);
1411 M_ISUB(REG_ZERO, d, d);
1412 if (s1 == REG_ITMP1) {
1413 var_to_reg_int(s1, src, REG_ITMP1);
1415 M_SLL_IMM(s1, 33, REG_ITMP2);
1416 M_CMPEQ(REG_ITMP2, REG_ZERO, REG_ITMP2);
1417 M_ISUB(d, REG_ITMP2, d);
1418 store_reg_to_var_int(iptr->dst, d);
1421 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1422 /* val.l = constant */
1424 var_to_reg_int(s1, src, REG_ITMP1);
1425 d = reg_of_var(iptr->dst, REG_ITMP3);
1426 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1427 M_AND_IMM(s1, iptr->val.l, d);
1429 else if (iptr->val.l == 0xffffL) {
1432 else if (iptr->val.l == 0xffffffL) {
1433 M_ZAPNOT_IMM(s1, 0x07, d);
1435 else if (iptr->val.l == 0xffffffffL) {
1438 else if (iptr->val.l == 0xffffffffffL) {
1439 M_ZAPNOT_IMM(s1, 0x1f, d);
1441 else if (iptr->val.l == 0xffffffffffffL) {
1442 M_ZAPNOT_IMM(s1, 0x3f, d);
1444 else if (iptr->val.l == 0xffffffffffffffL) {
1445 M_ZAPNOT_IMM(s1, 0x7f, d);
1448 LCONST(REG_ITMP2, iptr->val.l);
1449 M_AND(s1, REG_ITMP2, d);
1451 store_reg_to_var_int(iptr->dst, d);
1454 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1455 /* val.l = constant */
1457 var_to_reg_int(s1, src, REG_ITMP1);
1458 d = reg_of_var(iptr->dst, REG_ITMP3);
1460 M_MOV(s1, REG_ITMP1);
1463 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1464 M_AND_IMM(s1, iptr->val.l, d);
1466 M_LSUB(REG_ZERO, s1, d);
1467 M_AND_IMM(d, iptr->val.l, d);
1469 else if (iptr->val.l == 0xffffL) {
1472 M_LSUB(REG_ZERO, s1, d);
1475 else if (iptr->val.l == 0xffffffL) {
1476 M_ZAPNOT_IMM(s1, 0x07, d);
1478 M_LSUB(REG_ZERO, s1, d);
1479 M_ZAPNOT_IMM(d, 0x07, d);
1481 else if (iptr->val.l == 0xffffffffL) {
1484 M_LSUB(REG_ZERO, s1, d);
1487 else if (iptr->val.l == 0xffffffffffL) {
1488 M_ZAPNOT_IMM(s1, 0x1f, d);
1490 M_LSUB(REG_ZERO, s1, d);
1491 M_ZAPNOT_IMM(d, 0x1f, d);
1493 else if (iptr->val.l == 0xffffffffffffL) {
1494 M_ZAPNOT_IMM(s1, 0x3f, d);
1496 M_LSUB(REG_ZERO, s1, d);
1497 M_ZAPNOT_IMM(d, 0x3f, d);
1499 else if (iptr->val.l == 0xffffffffffffffL) {
1500 M_ZAPNOT_IMM(s1, 0x7f, d);
1502 M_LSUB(REG_ZERO, s1, d);
1503 M_ZAPNOT_IMM(d, 0x7f, d);
1506 LCONST(REG_ITMP2, iptr->val.l);
1507 M_AND(s1, REG_ITMP2, d);
1509 M_LSUB(REG_ZERO, s1, d);
1510 M_AND(d, REG_ITMP2, d);
1512 M_LSUB(REG_ZERO, d, d);
1513 store_reg_to_var_int(iptr->dst, d);
1516 case ICMD_LREM0X10001:/* ..., value ==> ..., value % 0x10001 */
1518 var_to_reg_int(s1, src, REG_ITMP1);
1519 d = reg_of_var(iptr->dst, REG_ITMP3);
1521 M_MOV(s1, REG_ITMP3);
1524 M_CZEXT(s1, REG_ITMP2);
1525 M_SRA_IMM(s1, 16, d);
1526 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1527 M_LSUB(REG_ITMP2, d, d);
1529 M_LADD(d, REG_ITMP1, d);
1530 M_LDA(REG_ITMP2, REG_ZERO, -1);
1531 M_SRL_IMM(REG_ITMP2, 33, REG_ITMP2);
1532 if (s1 == REG_ITMP1) {
1533 var_to_reg_int(s1, src, REG_ITMP1);
1535 M_CMPULT(s1, REG_ITMP2, REG_ITMP2);
1536 M_BNEZ(REG_ITMP2, 11);
1537 M_LDA(d, REG_ZERO, -257);
1538 M_ZAPNOT_IMM(d, 0xcd, d);
1539 M_LSUB(REG_ZERO, s1, REG_ITMP2);
1540 M_CMOVGE(s1, s1, REG_ITMP2);
1541 M_UMULH(REG_ITMP2, d, REG_ITMP2);
1542 M_SRL_IMM(REG_ITMP2, 16, REG_ITMP2);
1543 M_LSUB(REG_ZERO, REG_ITMP2, d);
1544 M_CMOVGE(s1, REG_ITMP2, d);
1545 M_SLL_IMM(d, 16, REG_ITMP2);
1546 M_LADD(d, REG_ITMP2, d);
1548 store_reg_to_var_int(iptr->dst, d);
1551 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1554 var_to_reg_int(s1, src->prev, REG_ITMP1);
1555 var_to_reg_int(s2, src, REG_ITMP2);
1556 d = reg_of_var(iptr->dst, REG_ITMP3);
1558 store_reg_to_var_int(iptr->dst, d);
1561 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1562 /* val.i = constant */
1564 var_to_reg_int(s1, src, REG_ITMP1);
1565 d = reg_of_var(iptr->dst, REG_ITMP3);
1566 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1567 M_OR_IMM(s1, iptr->val.i, d);
1570 ICONST(REG_ITMP2, iptr->val.i);
1571 M_OR(s1, REG_ITMP2, d);
1573 store_reg_to_var_int(iptr->dst, d);
1576 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1577 /* val.l = constant */
1579 var_to_reg_int(s1, src, REG_ITMP1);
1580 d = reg_of_var(iptr->dst, REG_ITMP3);
1581 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1582 M_OR_IMM(s1, iptr->val.l, d);
1585 LCONST(REG_ITMP2, iptr->val.l);
1586 M_OR(s1, REG_ITMP2, d);
1588 store_reg_to_var_int(iptr->dst, d);
1591 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1594 var_to_reg_int(s1, src->prev, REG_ITMP1);
1595 var_to_reg_int(s2, src, REG_ITMP2);
1596 d = reg_of_var(iptr->dst, REG_ITMP3);
1598 store_reg_to_var_int(iptr->dst, d);
1601 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1602 /* val.i = constant */
1604 var_to_reg_int(s1, src, REG_ITMP1);
1605 d = reg_of_var(iptr->dst, REG_ITMP3);
1606 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1607 M_XOR_IMM(s1, iptr->val.i, d);
1610 ICONST(REG_ITMP2, iptr->val.i);
1611 M_XOR(s1, REG_ITMP2, d);
1613 store_reg_to_var_int(iptr->dst, d);
1616 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1617 /* val.l = constant */
1619 var_to_reg_int(s1, src, REG_ITMP1);
1620 d = reg_of_var(iptr->dst, REG_ITMP3);
1621 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1622 M_XOR_IMM(s1, iptr->val.l, d);
1625 LCONST(REG_ITMP2, iptr->val.l);
1626 M_XOR(s1, REG_ITMP2, d);
1628 store_reg_to_var_int(iptr->dst, d);
1632 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1634 var_to_reg_int(s1, src->prev, REG_ITMP1);
1635 var_to_reg_int(s2, src, REG_ITMP2);
1636 d = reg_of_var(iptr->dst, REG_ITMP3);
1637 M_CMPLT(s1, s2, REG_ITMP3);
1638 M_CMPLT(s2, s1, REG_ITMP1);
1639 M_LSUB (REG_ITMP1, REG_ITMP3, d);
1640 store_reg_to_var_int(iptr->dst, d);
1644 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1645 /* op1 = variable, val.i = constant */
1647 var = &(locals[iptr->op1][TYPE_INT]);
1648 if (var->flags & INMEMORY) {
1650 M_LLD(s1, REG_SP, 8 * var->regoff);
1654 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1655 M_IADD_IMM(s1, iptr->val.i, s1);
1657 else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1658 M_ISUB_IMM(s1, (-iptr->val.i), s1);
1661 M_LDA (s1, s1, iptr->val.i);
1662 M_IADD(s1, REG_ZERO, s1);
1664 if (var->flags & INMEMORY)
1665 M_LST(s1, REG_SP, 8 * var->regoff);
1669 /* floating operations ************************************************/
1671 case ICMD_FNEG: /* ..., value ==> ..., - value */
1673 var_to_reg_flt(s1, src, REG_FTMP1);
1674 d = reg_of_var(iptr->dst, REG_FTMP3);
1676 store_reg_to_var_flt(iptr->dst, d);
1679 case ICMD_DNEG: /* ..., value ==> ..., - value */
1681 var_to_reg_flt(s1, src, REG_FTMP1);
1682 d = reg_of_var(iptr->dst, REG_FTMP3);
1684 store_reg_to_var_flt(iptr->dst, d);
1687 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1689 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1690 var_to_reg_flt(s2, src, REG_FTMP2);
1691 d = reg_of_var(iptr->dst, REG_FTMP3);
1699 store_reg_to_var_flt(iptr->dst, d);
1702 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1704 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1705 var_to_reg_flt(s2, src, REG_FTMP2);
1706 d = reg_of_var(iptr->dst, REG_FTMP3);
1714 store_reg_to_var_flt(iptr->dst, d);
1717 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1719 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1720 var_to_reg_flt(s2, src, REG_FTMP2);
1721 d = reg_of_var(iptr->dst, REG_FTMP3);
1729 store_reg_to_var_flt(iptr->dst, d);
1732 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1734 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1735 var_to_reg_flt(s2, src, REG_FTMP2);
1736 d = reg_of_var(iptr->dst, REG_FTMP3);
1744 store_reg_to_var_flt(iptr->dst, d);
1747 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1749 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1750 var_to_reg_flt(s2, src, REG_FTMP2);
1751 d = reg_of_var(iptr->dst, REG_FTMP3);
1759 store_reg_to_var_flt(iptr->dst, d);
1762 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1764 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1765 var_to_reg_flt(s2, src, REG_FTMP2);
1766 d = reg_of_var(iptr->dst, REG_FTMP3);
1774 store_reg_to_var_flt(iptr->dst, d);
1777 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1779 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1780 var_to_reg_flt(s2, src, REG_FTMP2);
1781 d = reg_of_var(iptr->dst, REG_FTMP3);
1789 store_reg_to_var_flt(iptr->dst, d);
1792 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / 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_FTMP3);
1804 store_reg_to_var_flt(iptr->dst, d);
1807 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1809 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1810 var_to_reg_flt(s2, src, REG_FTMP2);
1811 d = reg_of_var(iptr->dst, REG_FTMP3);
1813 M_FDIVS(s1,s2, REG_FTMP3);
1815 M_CVTDL_CS(REG_FTMP3, REG_FTMP3); /* round to integer */
1817 M_CVTLF(REG_FTMP3, REG_FTMP3);
1818 M_FMULS(REG_FTMP3, s2, REG_FTMP3);
1820 M_FSUBS(s1, REG_FTMP3, d);
1824 M_FDIV(s1,s2, REG_FTMP3);
1825 M_CVTDL_C(REG_FTMP3, REG_FTMP3); /* round to integer */
1826 M_CVTLF(REG_FTMP3, REG_FTMP3);
1827 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1828 M_FSUB(s1, REG_FTMP3, d);
1830 store_reg_to_var_flt(iptr->dst, d);
1833 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1835 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1836 var_to_reg_flt(s2, src, REG_FTMP2);
1837 d = reg_of_var(iptr->dst, REG_FTMP3);
1839 M_DDIVS(s1,s2, REG_FTMP3);
1841 M_CVTDL_CS(REG_FTMP3, REG_FTMP3); /* round to integer */
1843 M_CVTLD(REG_FTMP3, REG_FTMP3);
1844 M_DMULS(REG_FTMP3, s2, REG_FTMP3);
1846 M_DSUBS(s1, REG_FTMP3, d);
1850 M_DDIV(s1,s2, REG_FTMP3);
1851 M_CVTDL_C(REG_FTMP3, REG_FTMP3); /* round to integer */
1852 M_CVTLD(REG_FTMP3, REG_FTMP3);
1853 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1854 M_DSUB(s1, REG_FTMP3, d);
1856 store_reg_to_var_flt(iptr->dst, d);
1859 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1861 var_to_reg_int(s1, src, REG_ITMP1);
1862 d = reg_of_var(iptr->dst, REG_FTMP3);
1863 a = dseg_adddouble(0.0);
1864 M_LST (s1, REG_PV, a);
1865 M_DLD (d, REG_PV, a);
1867 store_reg_to_var_flt(iptr->dst, d);
1870 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1872 var_to_reg_int(s1, src, REG_ITMP1);
1873 d = reg_of_var(iptr->dst, REG_FTMP3);
1874 a = dseg_adddouble(0.0);
1875 M_LST (s1, REG_PV, a);
1876 M_DLD (d, REG_PV, a);
1878 store_reg_to_var_flt(iptr->dst, d);
1881 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1883 var_to_reg_flt(s1, src, REG_FTMP1);
1884 d = reg_of_var(iptr->dst, REG_ITMP3);
1885 a = dseg_adddouble(0.0);
1887 M_CVTDL_CS(s1, REG_FTMP1);
1889 M_CVTLIS(REG_FTMP1, REG_FTMP2);
1893 M_CVTDL_C(s1, REG_FTMP1);
1894 M_CVTLI(REG_FTMP1, REG_FTMP2);
1896 M_DST (REG_FTMP1, REG_PV, a);
1897 M_ILD (d, REG_PV, a);
1898 store_reg_to_var_int(iptr->dst, d);
1901 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1903 var_to_reg_flt(s1, src, REG_FTMP1);
1904 d = reg_of_var(iptr->dst, REG_ITMP3);
1905 a = dseg_adddouble(0.0);
1907 M_CVTDL_CS(s1, REG_FTMP1);
1911 M_CVTDL_C(s1, REG_FTMP1);
1913 M_DST (REG_FTMP1, REG_PV, a);
1914 M_LLD (d, REG_PV, a);
1915 store_reg_to_var_int(iptr->dst, d);
1918 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1920 var_to_reg_flt(s1, src, REG_FTMP1);
1921 d = reg_of_var(iptr->dst, REG_FTMP3);
1923 store_reg_to_var_flt(iptr->dst, d);
1926 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1928 var_to_reg_flt(s1, src, REG_FTMP1);
1929 d = reg_of_var(iptr->dst, REG_FTMP3);
1937 store_reg_to_var_flt(iptr->dst, d);
1940 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1942 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1943 var_to_reg_flt(s2, src, REG_FTMP2);
1944 d = reg_of_var(iptr->dst, REG_ITMP3);
1946 M_LSUB_IMM(REG_ZERO, 1, d);
1947 M_FCMPEQS(s1, s2, REG_FTMP3);
1949 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1951 M_FCMPLTS(s2, s1, REG_FTMP3);
1953 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1954 M_LADD_IMM(REG_ZERO, 1, d);
1957 M_LSUB_IMM(REG_ZERO, 1, d);
1958 M_FCMPEQ(s1, s2, REG_FTMP3);
1959 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1961 M_FCMPLT(s2, s1, REG_FTMP3);
1962 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1963 M_LADD_IMM(REG_ZERO, 1, d);
1965 store_reg_to_var_int(iptr->dst, d);
1968 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1970 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1971 var_to_reg_flt(s2, src, REG_FTMP2);
1972 d = reg_of_var(iptr->dst, REG_ITMP3);
1974 M_LADD_IMM(REG_ZERO, 1, d);
1975 M_FCMPEQS(s1, s2, REG_FTMP3);
1977 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1979 M_FCMPLTS(s1, s2, REG_FTMP3);
1981 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1982 M_LSUB_IMM(REG_ZERO, 1, d);
1985 M_LADD_IMM(REG_ZERO, 1, d);
1986 M_FCMPEQ(s1, s2, REG_FTMP3);
1987 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1989 M_FCMPLT(s1, s2, REG_FTMP3);
1990 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1991 M_LSUB_IMM(REG_ZERO, 1, d);
1993 store_reg_to_var_int(iptr->dst, d);
1997 /* memory operations **************************************************/
1999 /* #define gen_bound_check \
2001 M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\
2002 M_CMPULT(s2, REG_ITMP3, REG_ITMP3);\
2003 M_BEQZ(REG_ITMP3, 0);\
2004 mcode_addxboundrefs(mcodeptr);\
2008 #define gen_bound_check \
2009 if (checkbounds) { \
2010 M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\
2011 M_CMPULT(s2, REG_ITMP3, REG_ITMP3);\
2012 M_BEQZ(REG_ITMP3, 0);\
2013 mcode_addxboundrefs(mcodeptr); \
2016 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
2018 var_to_reg_int(s1, src, REG_ITMP1);
2019 d = reg_of_var(iptr->dst, REG_ITMP3);
2020 gen_nullptr_check(s1);
2021 M_ILD(d, s1, OFFSET(java_arrayheader, size));
2022 store_reg_to_var_int(iptr->dst, d);
2025 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
2027 var_to_reg_int(s1, src->prev, REG_ITMP1);
2028 var_to_reg_int(s2, src, REG_ITMP2);
2029 d = reg_of_var(iptr->dst, REG_ITMP3);
2030 if (iptr->op1 == 0) {
2031 gen_nullptr_check(s1);
2034 M_SAADDQ(s2, s1, REG_ITMP1);
2035 M_ALD( d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
2036 store_reg_to_var_int(iptr->dst, d);
2039 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
2041 var_to_reg_int(s1, src->prev, REG_ITMP1);
2042 var_to_reg_int(s2, src, REG_ITMP2);
2043 d = reg_of_var(iptr->dst, REG_ITMP3);
2044 if (iptr->op1 == 0) {
2045 gen_nullptr_check(s1);
2048 M_S8ADDQ(s2, s1, REG_ITMP1);
2049 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
2050 store_reg_to_var_int(iptr->dst, d);
2053 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
2055 var_to_reg_int(s1, src->prev, REG_ITMP1);
2056 var_to_reg_int(s2, src, REG_ITMP2);
2057 d = reg_of_var(iptr->dst, REG_ITMP3);
2058 if (iptr->op1 == 0) {
2059 gen_nullptr_check(s1);
2063 M_S4ADDQ(s2, s1, REG_ITMP1);
2064 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
2065 store_reg_to_var_int(iptr->dst, d);
2068 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
2070 var_to_reg_int(s1, src->prev, REG_ITMP1);
2071 var_to_reg_int(s2, src, REG_ITMP2);
2072 d = reg_of_var(iptr->dst, REG_FTMP3);
2073 if (iptr->op1 == 0) {
2074 gen_nullptr_check(s1);
2077 M_S4ADDQ(s2, s1, REG_ITMP1);
2078 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
2079 store_reg_to_var_flt(iptr->dst, d);
2082 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
2084 var_to_reg_int(s1, src->prev, REG_ITMP1);
2085 var_to_reg_int(s2, src, REG_ITMP2);
2086 d = reg_of_var(iptr->dst, REG_FTMP3);
2087 if (iptr->op1 == 0) {
2088 gen_nullptr_check(s1);
2091 M_S8ADDQ(s2, s1, REG_ITMP1);
2092 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
2093 store_reg_to_var_flt(iptr->dst, d);
2096 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
2098 var_to_reg_int(s1, src->prev, REG_ITMP1);
2099 var_to_reg_int(s2, src, REG_ITMP2);
2100 d = reg_of_var(iptr->dst, REG_ITMP3);
2101 if (iptr->op1 == 0) {
2102 gen_nullptr_check(s1);
2105 if (has_ext_instr_set) {
2106 M_LADD(s2, s1, REG_ITMP1);
2107 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2108 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
2111 M_LADD (s2, s1, REG_ITMP1);
2112 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2113 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2114 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2115 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
2117 store_reg_to_var_int(iptr->dst, d);
2120 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
2122 var_to_reg_int(s1, src->prev, REG_ITMP1);
2123 var_to_reg_int(s2, src, REG_ITMP2);
2124 d = reg_of_var(iptr->dst, REG_ITMP3);
2125 if (iptr->op1 == 0) {
2126 gen_nullptr_check(s1);
2129 if (has_ext_instr_set) {
2130 M_LADD(s2, s1, REG_ITMP1);
2131 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2132 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
2136 M_LADD(s2, s1, REG_ITMP1);
2137 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2138 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2139 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
2140 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
2141 M_SRA_IMM(d, 48, d);
2143 store_reg_to_var_int(iptr->dst, d);
2146 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
2148 var_to_reg_int(s1, src->prev, REG_ITMP1);
2149 var_to_reg_int(s2, src, REG_ITMP2);
2150 d = reg_of_var(iptr->dst, REG_ITMP3);
2151 if (iptr->op1 == 0) {
2152 gen_nullptr_check(s1);
2155 if (has_ext_instr_set) {
2156 M_LADD (s2, s1, REG_ITMP1);
2157 M_BLDU (d, REG_ITMP1, OFFSET (java_bytearray, data[0]));
2161 M_LADD(s2, s1, REG_ITMP1);
2162 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2163 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
2164 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
2165 M_SRA_IMM(d, 56, d);
2167 store_reg_to_var_int(iptr->dst, d);
2171 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
2173 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2174 var_to_reg_int(s2, src->prev, REG_ITMP2);
2175 if (iptr->op1 == 0) {
2176 gen_nullptr_check(s1);
2179 var_to_reg_int(s3, src, REG_ITMP3);
2180 M_SAADDQ(s2, s1, REG_ITMP1);
2181 M_AST (s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
2184 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
2186 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2187 var_to_reg_int(s2, src->prev, REG_ITMP2);
2188 if (iptr->op1 == 0) {
2189 gen_nullptr_check(s1);
2192 var_to_reg_int(s3, src, REG_ITMP3);
2193 M_S8ADDQ(s2, s1, REG_ITMP1);
2194 M_LST (s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
2197 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
2199 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2200 var_to_reg_int(s2, src->prev, REG_ITMP2);
2201 if (iptr->op1 == 0) {
2202 gen_nullptr_check(s1);
2206 var_to_reg_int(s3, src, REG_ITMP3);
2207 M_S4ADDQ(s2, s1, REG_ITMP1);
2208 M_IST (s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
2211 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
2213 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2214 var_to_reg_int(s2, src->prev, REG_ITMP2);
2215 if (iptr->op1 == 0) {
2216 gen_nullptr_check(s1);
2219 var_to_reg_flt(s3, src, REG_FTMP3);
2220 M_S4ADDQ(s2, s1, REG_ITMP1);
2221 M_FST (s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
2224 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
2226 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2227 var_to_reg_int(s2, src->prev, REG_ITMP2);
2228 if (iptr->op1 == 0) {
2229 gen_nullptr_check(s1);
2232 var_to_reg_flt(s3, src, REG_FTMP3);
2233 M_S8ADDQ(s2, s1, REG_ITMP1);
2234 M_DST (s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
2237 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
2239 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2240 var_to_reg_int(s2, src->prev, REG_ITMP2);
2241 if (iptr->op1 == 0) {
2242 gen_nullptr_check(s1);
2245 var_to_reg_int(s3, src, REG_ITMP3);
2246 if (has_ext_instr_set) {
2247 M_LADD(s2, s1, REG_ITMP1);
2248 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2249 M_SST (s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
2252 M_LADD (s2, s1, REG_ITMP1);
2253 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2254 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2255 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2256 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
2257 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2258 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2259 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2263 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
2265 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2266 var_to_reg_int(s2, src->prev, REG_ITMP2);
2267 if (iptr->op1 == 0) {
2268 gen_nullptr_check(s1);
2271 var_to_reg_int(s3, src, REG_ITMP3);
2272 if (has_ext_instr_set) {
2273 M_LADD(s2, s1, REG_ITMP1);
2274 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2275 M_SST (s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2278 M_LADD (s2, s1, REG_ITMP1);
2279 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2280 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2281 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2282 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
2283 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2284 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2285 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2289 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
2291 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2292 var_to_reg_int(s2, src->prev, REG_ITMP2);
2293 if (iptr->op1 == 0) {
2294 gen_nullptr_check(s1);
2297 var_to_reg_int(s3, src, REG_ITMP3);
2298 if (has_ext_instr_set) {
2299 M_LADD(s2, s1, REG_ITMP1);
2300 M_BST (s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2303 M_LADD (s2, s1, REG_ITMP1);
2304 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2305 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2306 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
2307 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2308 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2309 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2314 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2315 /* op1 = type, val.a = field address */
2317 a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value));
2318 M_ALD(REG_ITMP1, REG_PV, a);
2319 switch (iptr->op1) {
2321 var_to_reg_int(s2, src, REG_ITMP2);
2322 M_IST(s2, REG_ITMP1, 0);
2325 var_to_reg_int(s2, src, REG_ITMP2);
2326 M_LST(s2, REG_ITMP1, 0);
2329 var_to_reg_int(s2, src, REG_ITMP2);
2330 M_AST(s2, REG_ITMP1, 0);
2333 var_to_reg_flt(s2, src, REG_FTMP2);
2334 M_FST(s2, REG_ITMP1, 0);
2337 var_to_reg_flt(s2, src, REG_FTMP2);
2338 M_DST(s2, REG_ITMP1, 0);
2340 default: panic ("internal error");
2344 case ICMD_GETSTATIC: /* ... ==> ..., value */
2345 /* op1 = type, val.a = field address */
2347 a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value));
2348 M_ALD(REG_ITMP1, REG_PV, a);
2349 switch (iptr->op1) {
2351 d = reg_of_var(iptr->dst, REG_ITMP3);
2352 M_ILD(d, REG_ITMP1, 0);
2353 store_reg_to_var_int(iptr->dst, d);
2356 d = reg_of_var(iptr->dst, REG_ITMP3);
2357 M_LLD(d, REG_ITMP1, 0);
2358 store_reg_to_var_int(iptr->dst, d);
2361 d = reg_of_var(iptr->dst, REG_ITMP3);
2362 M_ALD(d, REG_ITMP1, 0);
2363 store_reg_to_var_int(iptr->dst, d);
2366 d = reg_of_var(iptr->dst, REG_FTMP1);
2367 M_FLD(d, REG_ITMP1, 0);
2368 store_reg_to_var_flt(iptr->dst, d);
2371 d = reg_of_var(iptr->dst, REG_FTMP1);
2372 M_DLD(d, REG_ITMP1, 0);
2373 store_reg_to_var_flt(iptr->dst, d);
2375 default: panic ("internal error");
2380 case ICMD_PUTFIELD: /* ..., value ==> ... */
2381 /* op1 = type, val.i = field offset */
2383 a = ((fieldinfo *)(iptr->val.a))->offset;
2384 switch (iptr->op1) {
2386 var_to_reg_int(s1, src->prev, REG_ITMP1);
2387 var_to_reg_int(s2, src, REG_ITMP2);
2388 gen_nullptr_check(s1);
2392 var_to_reg_int(s1, src->prev, REG_ITMP1);
2393 var_to_reg_int(s2, src, REG_ITMP2);
2394 gen_nullptr_check(s1);
2398 var_to_reg_int(s1, src->prev, REG_ITMP1);
2399 var_to_reg_int(s2, src, REG_ITMP2);
2400 gen_nullptr_check(s1);
2404 var_to_reg_int(s1, src->prev, REG_ITMP1);
2405 var_to_reg_flt(s2, src, REG_FTMP2);
2406 gen_nullptr_check(s1);
2410 var_to_reg_int(s1, src->prev, REG_ITMP1);
2411 var_to_reg_flt(s2, src, REG_FTMP2);
2412 gen_nullptr_check(s1);
2415 default: panic ("internal error");
2419 case ICMD_GETFIELD: /* ... ==> ..., value */
2420 /* op1 = type, val.i = field offset */
2422 a = ((fieldinfo *)(iptr->val.a))->offset;
2423 switch (iptr->op1) {
2425 var_to_reg_int(s1, src, REG_ITMP1);
2426 d = reg_of_var(iptr->dst, REG_ITMP3);
2427 gen_nullptr_check(s1);
2429 store_reg_to_var_int(iptr->dst, d);
2432 var_to_reg_int(s1, src, REG_ITMP1);
2433 d = reg_of_var(iptr->dst, REG_ITMP3);
2434 gen_nullptr_check(s1);
2436 store_reg_to_var_int(iptr->dst, d);
2439 var_to_reg_int(s1, src, REG_ITMP1);
2440 d = reg_of_var(iptr->dst, REG_ITMP3);
2441 gen_nullptr_check(s1);
2443 store_reg_to_var_int(iptr->dst, d);
2446 var_to_reg_int(s1, src, REG_ITMP1);
2447 d = reg_of_var(iptr->dst, REG_FTMP1);
2448 gen_nullptr_check(s1);
2450 store_reg_to_var_flt(iptr->dst, d);
2453 var_to_reg_int(s1, src, REG_ITMP1);
2454 d = reg_of_var(iptr->dst, REG_FTMP1);
2455 gen_nullptr_check(s1);
2457 store_reg_to_var_flt(iptr->dst, d);
2459 default: panic ("internal error");
2464 /* branch operations **************************************************/
2466 #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}}
2468 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2470 var_to_reg_int(s1, src, REG_ITMP1);
2471 M_INTMOVE(s1, REG_ITMP1_XPTR);
2472 a = dseg_addaddress(asm_handle_exception);
2473 M_ALD(REG_ITMP2, REG_PV, a);
2474 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2475 M_NOP; /* nop ensures that XPC is less than the end */
2476 /* of basic block */
2480 case ICMD_GOTO: /* ... ==> ... */
2481 /* op1 = target JavaVM pc */
2483 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2487 case ICMD_JSR: /* ... ==> ... */
2488 /* op1 = target JavaVM pc */
2490 M_BSR(REG_ITMP1, 0);
2491 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2494 case ICMD_RET: /* ... ==> ... */
2495 /* op1 = local variable */
2497 var = &(locals[iptr->op1][TYPE_ADR]);
2498 if (var->flags & INMEMORY) {
2499 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2500 M_RET(REG_ZERO, REG_ITMP1);
2503 M_RET(REG_ZERO, var->regoff);
2507 case ICMD_IFNULL: /* ..., value ==> ... */
2508 /* op1 = target JavaVM pc */
2510 var_to_reg_int(s1, src, REG_ITMP1);
2512 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2515 case ICMD_IFNONNULL: /* ..., value ==> ... */
2516 /* op1 = target JavaVM pc */
2518 var_to_reg_int(s1, src, REG_ITMP1);
2520 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2523 case ICMD_IFEQ: /* ..., value ==> ... */
2524 /* op1 = target JavaVM pc, val.i = constant */
2526 var_to_reg_int(s1, src, REG_ITMP1);
2527 if (iptr->val.i == 0) {
2531 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2532 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2535 ICONST(REG_ITMP2, iptr->val.i);
2536 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2538 M_BNEZ(REG_ITMP1, 0);
2540 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2543 case ICMD_IFLT: /* ..., value ==> ... */
2544 /* op1 = target JavaVM pc, val.i = constant */
2546 var_to_reg_int(s1, src, REG_ITMP1);
2547 if (iptr->val.i == 0) {
2551 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2552 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2555 ICONST(REG_ITMP2, iptr->val.i);
2556 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2558 M_BNEZ(REG_ITMP1, 0);
2560 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2563 case ICMD_IFLE: /* ..., value ==> ... */
2564 /* op1 = target JavaVM pc, val.i = constant */
2566 var_to_reg_int(s1, src, REG_ITMP1);
2567 if (iptr->val.i == 0) {
2571 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2572 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2575 ICONST(REG_ITMP2, iptr->val.i);
2576 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2578 M_BNEZ(REG_ITMP1, 0);
2580 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2583 case ICMD_IFNE: /* ..., value ==> ... */
2584 /* op1 = target JavaVM pc, val.i = constant */
2586 var_to_reg_int(s1, src, REG_ITMP1);
2587 if (iptr->val.i == 0) {
2591 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2592 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2595 ICONST(REG_ITMP2, iptr->val.i);
2596 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2598 M_BEQZ(REG_ITMP1, 0);
2600 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2603 case ICMD_IFGT: /* ..., value ==> ... */
2604 /* op1 = target JavaVM pc, val.i = constant */
2606 var_to_reg_int(s1, src, REG_ITMP1);
2607 if (iptr->val.i == 0) {
2611 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2612 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2615 ICONST(REG_ITMP2, iptr->val.i);
2616 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2618 M_BEQZ(REG_ITMP1, 0);
2620 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2623 case ICMD_IFGE: /* ..., value ==> ... */
2624 /* op1 = target JavaVM pc, val.i = constant */
2626 var_to_reg_int(s1, src, REG_ITMP1);
2627 if (iptr->val.i == 0) {
2631 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2632 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2635 ICONST(REG_ITMP2, iptr->val.i);
2636 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2638 M_BEQZ(REG_ITMP1, 0);
2640 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2643 case ICMD_IF_LEQ: /* ..., value ==> ... */
2644 /* op1 = target JavaVM pc, val.l = constant */
2646 var_to_reg_int(s1, src, REG_ITMP1);
2647 if (iptr->val.l == 0) {
2651 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2652 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2655 LCONST(REG_ITMP2, iptr->val.l);
2656 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2658 M_BNEZ(REG_ITMP1, 0);
2660 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2663 case ICMD_IF_LLT: /* ..., value ==> ... */
2664 /* op1 = target JavaVM pc, val.l = constant */
2666 var_to_reg_int(s1, src, REG_ITMP1);
2667 if (iptr->val.l == 0) {
2671 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2672 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2675 LCONST(REG_ITMP2, iptr->val.l);
2676 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2678 M_BNEZ(REG_ITMP1, 0);
2680 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2683 case ICMD_IF_LLE: /* ..., value ==> ... */
2684 /* op1 = target JavaVM pc, val.l = constant */
2686 var_to_reg_int(s1, src, REG_ITMP1);
2687 if (iptr->val.l == 0) {
2691 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2692 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2695 LCONST(REG_ITMP2, iptr->val.l);
2696 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2698 M_BNEZ(REG_ITMP1, 0);
2700 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2703 case ICMD_IF_LNE: /* ..., value ==> ... */
2704 /* op1 = target JavaVM pc, val.l = constant */
2706 var_to_reg_int(s1, src, REG_ITMP1);
2707 if (iptr->val.l == 0) {
2711 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2712 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2715 LCONST(REG_ITMP2, iptr->val.l);
2716 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2718 M_BEQZ(REG_ITMP1, 0);
2720 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2723 case ICMD_IF_LGT: /* ..., value ==> ... */
2724 /* op1 = target JavaVM pc, val.l = constant */
2726 var_to_reg_int(s1, src, REG_ITMP1);
2727 if (iptr->val.l == 0) {
2731 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2732 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2735 LCONST(REG_ITMP2, iptr->val.l);
2736 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2738 M_BEQZ(REG_ITMP1, 0);
2740 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2743 case ICMD_IF_LGE: /* ..., value ==> ... */
2744 /* op1 = target JavaVM pc, val.l = constant */
2746 var_to_reg_int(s1, src, REG_ITMP1);
2747 if (iptr->val.l == 0) {
2751 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2752 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2755 LCONST(REG_ITMP2, iptr->val.l);
2756 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2758 M_BEQZ(REG_ITMP1, 0);
2760 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2763 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2764 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2765 case ICMD_IF_ACMPEQ:
2767 var_to_reg_int(s1, src->prev, REG_ITMP1);
2768 var_to_reg_int(s2, src, REG_ITMP2);
2769 M_CMPEQ(s1, s2, REG_ITMP1);
2770 M_BNEZ(REG_ITMP1, 0);
2771 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2774 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2775 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2776 case ICMD_IF_ACMPNE:
2778 var_to_reg_int(s1, src->prev, REG_ITMP1);
2779 var_to_reg_int(s2, src, REG_ITMP2);
2780 M_CMPEQ(s1, s2, REG_ITMP1);
2781 M_BEQZ(REG_ITMP1, 0);
2782 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2785 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2786 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2788 var_to_reg_int(s1, src->prev, REG_ITMP1);
2789 var_to_reg_int(s2, src, REG_ITMP2);
2790 M_CMPLT(s1, s2, REG_ITMP1);
2791 M_BNEZ(REG_ITMP1, 0);
2792 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2795 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2796 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2798 var_to_reg_int(s1, src->prev, REG_ITMP1);
2799 var_to_reg_int(s2, src, REG_ITMP2);
2800 M_CMPLE(s1, s2, REG_ITMP1);
2801 M_BEQZ(REG_ITMP1, 0);
2802 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2805 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2806 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2808 var_to_reg_int(s1, src->prev, REG_ITMP1);
2809 var_to_reg_int(s2, src, REG_ITMP2);
2810 M_CMPLE(s1, s2, REG_ITMP1);
2811 M_BNEZ(REG_ITMP1, 0);
2812 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2815 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2816 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2818 var_to_reg_int(s1, src->prev, REG_ITMP1);
2819 var_to_reg_int(s2, src, REG_ITMP2);
2820 M_CMPLT(s1, s2, REG_ITMP1);
2821 M_BEQZ(REG_ITMP1, 0);
2822 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2825 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2827 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2830 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2831 /* val.i = constant */
2833 var_to_reg_int(s1, src, REG_ITMP1);
2834 d = reg_of_var(iptr->dst, REG_ITMP3);
2836 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2837 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2838 M_CMPEQ(s1, REG_ZERO, d);
2839 store_reg_to_var_int(iptr->dst, d);
2842 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2843 M_CMPEQ(s1, REG_ZERO, d);
2845 store_reg_to_var_int(iptr->dst, d);
2849 M_MOV(s1, REG_ITMP1);
2852 ICONST(d, iptr[1].val.i);
2854 if ((s3 >= 0) && (s3 <= 255)) {
2855 M_CMOVEQ_IMM(s1, s3, d);
2858 ICONST(REG_ITMP2, s3);
2859 M_CMOVEQ(s1, REG_ITMP2, d);
2861 store_reg_to_var_int(iptr->dst, d);
2864 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2865 /* val.i = constant */
2867 var_to_reg_int(s1, src, REG_ITMP1);
2868 d = reg_of_var(iptr->dst, REG_ITMP3);
2870 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2871 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2872 M_CMPEQ(s1, REG_ZERO, d);
2873 store_reg_to_var_int(iptr->dst, d);
2876 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2877 M_CMPEQ(s1, REG_ZERO, d);
2879 store_reg_to_var_int(iptr->dst, d);
2883 M_MOV(s1, REG_ITMP1);
2886 ICONST(d, iptr[1].val.i);
2888 if ((s3 >= 0) && (s3 <= 255)) {
2889 M_CMOVNE_IMM(s1, s3, d);
2892 ICONST(REG_ITMP2, s3);
2893 M_CMOVNE(s1, REG_ITMP2, d);
2895 store_reg_to_var_int(iptr->dst, d);
2898 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2899 /* val.i = constant */
2901 var_to_reg_int(s1, src, REG_ITMP1);
2902 d = reg_of_var(iptr->dst, REG_ITMP3);
2904 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2905 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2906 M_CMPLT(s1, REG_ZERO, d);
2907 store_reg_to_var_int(iptr->dst, d);
2910 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2911 M_CMPLE(REG_ZERO, s1, d);
2912 store_reg_to_var_int(iptr->dst, d);
2916 M_MOV(s1, REG_ITMP1);
2919 ICONST(d, iptr[1].val.i);
2921 if ((s3 >= 0) && (s3 <= 255)) {
2922 M_CMOVLT_IMM(s1, s3, d);
2925 ICONST(REG_ITMP2, s3);
2926 M_CMOVLT(s1, REG_ITMP2, d);
2928 store_reg_to_var_int(iptr->dst, d);
2931 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2932 /* val.i = constant */
2934 var_to_reg_int(s1, src, REG_ITMP1);
2935 d = reg_of_var(iptr->dst, REG_ITMP3);
2937 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2938 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2939 M_CMPLE(REG_ZERO, s1, d);
2940 store_reg_to_var_int(iptr->dst, d);
2943 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2944 M_CMPLT(s1, REG_ZERO, d);
2945 store_reg_to_var_int(iptr->dst, d);
2949 M_MOV(s1, REG_ITMP1);
2952 ICONST(d, iptr[1].val.i);
2954 if ((s3 >= 0) && (s3 <= 255)) {
2955 M_CMOVGE_IMM(s1, s3, d);
2958 ICONST(REG_ITMP2, s3);
2959 M_CMOVGE(s1, REG_ITMP2, d);
2961 store_reg_to_var_int(iptr->dst, d);
2964 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2965 /* val.i = constant */
2967 var_to_reg_int(s1, src, REG_ITMP1);
2968 d = reg_of_var(iptr->dst, REG_ITMP3);
2970 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2971 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2972 M_CMPLT(REG_ZERO, s1, d);
2973 store_reg_to_var_int(iptr->dst, d);
2976 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2977 M_CMPLE(s1, REG_ZERO, d);
2978 store_reg_to_var_int(iptr->dst, d);
2982 M_MOV(s1, REG_ITMP1);
2985 ICONST(d, iptr[1].val.i);
2987 if ((s3 >= 0) && (s3 <= 255)) {
2988 M_CMOVGT_IMM(s1, s3, d);
2991 ICONST(REG_ITMP2, s3);
2992 M_CMOVGT(s1, REG_ITMP2, d);
2994 store_reg_to_var_int(iptr->dst, d);
2997 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2998 /* val.i = constant */
3000 var_to_reg_int(s1, src, REG_ITMP1);
3001 d = reg_of_var(iptr->dst, REG_ITMP3);
3003 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
3004 if ((s3 == 1) && (iptr[1].val.i == 0)) {
3005 M_CMPLE(s1, REG_ZERO, d);
3006 store_reg_to_var_int(iptr->dst, d);
3009 if ((s3 == 0) && (iptr[1].val.i == 1)) {
3010 M_CMPLT(REG_ZERO, s1, d);
3011 store_reg_to_var_int(iptr->dst, d);
3015 M_MOV(s1, REG_ITMP1);
3018 ICONST(d, iptr[1].val.i);
3020 if ((s3 >= 0) && (s3 <= 255)) {
3021 M_CMOVLE_IMM(s1, s3, d);
3024 ICONST(REG_ITMP2, s3);
3025 M_CMOVLE(s1, REG_ITMP2, d);
3027 store_reg_to_var_int(iptr->dst, d);
3031 case ICMD_IRETURN: /* ..., retvalue ==> ... */
3036 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3037 a = dseg_addaddress ((void*) (builtin_monitorexit));
3038 M_ALD(REG_PV, REG_PV, a);
3039 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
3040 M_JSR(REG_RA, REG_PV);
3041 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
3044 var_to_reg_int(s1, src, REG_RESULT);
3045 M_INTMOVE(s1, REG_RESULT);
3046 goto nowperformreturn;
3048 case ICMD_FRETURN: /* ..., retvalue ==> ... */
3052 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3053 a = dseg_addaddress ((void*) (builtin_monitorexit));
3054 M_ALD(REG_PV, REG_PV, a);
3055 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
3056 M_JSR(REG_RA, REG_PV);
3057 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
3060 var_to_reg_flt(s1, src, REG_FRESULT);
3061 M_FLTMOVE(s1, REG_FRESULT);
3062 goto nowperformreturn;
3064 case ICMD_RETURN: /* ... ==> ... */
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));
3080 p = parentargs_base;
3082 /* restore return address */
3085 {p--; M_LLD (REG_RA, REG_SP, 8 * p);}
3087 /* restore saved registers */
3089 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
3090 {p--; M_LLD(savintregs[r], REG_SP, 8 * p);}
3091 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
3092 {p--; M_DLD(savfltregs[r], REG_SP, 8 * p);}
3094 /* deallocate stack */
3096 if (parentargs_base)
3097 {M_LDA(REG_SP, REG_SP, parentargs_base*8);}
3099 /* call trace function */
3102 M_LDA (REG_SP, REG_SP, -24);
3103 M_AST(REG_RA, REG_SP, 0);
3104 M_LST(REG_RESULT, REG_SP, 8);
3105 M_DST(REG_FRESULT, REG_SP,16);
3106 a = dseg_addaddress (method);
3107 M_ALD(argintregs[0], REG_PV, a);
3108 M_MOV(REG_RESULT, argintregs[1]);
3109 M_FLTMOVE(REG_FRESULT, argfltregs[2]);
3110 M_FLTMOVE(REG_FRESULT, argfltregs[3]);
3111 a = dseg_addaddress ((void*) (builtin_displaymethodstop));
3112 M_ALD(REG_PV, REG_PV, a);
3113 M_JSR (REG_RA, REG_PV);
3114 s1 = (int)((u1*) mcodeptr - mcodebase);
3115 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
3118 while (ml<-32768) { ml+=65536; mh--; }
3119 M_LDA (REG_PV, REG_RA, ml );
3120 M_LDAH (REG_PV, REG_PV, mh );
3122 M_DLD(REG_FRESULT, REG_SP,16);
3123 M_LLD(REG_RESULT, REG_SP, 8);
3124 M_ALD(REG_RA, REG_SP, 0);
3125 M_LDA (REG_SP, REG_SP, 24);
3128 M_RET(REG_ZERO, REG_RA);
3134 case ICMD_TABLESWITCH: /* ..., index ==> ... */
3139 tptr = (void **) iptr->target;
3141 s4ptr = iptr->val.a;
3142 l = s4ptr[1]; /* low */
3143 i = s4ptr[2]; /* high */
3145 var_to_reg_int(s1, src, REG_ITMP1);
3147 {M_INTMOVE(s1, REG_ITMP1);}
3148 else if (l <= 32768) {
3149 M_LDA(REG_ITMP1, s1, -l);
3152 ICONST(REG_ITMP2, l);
3153 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
3160 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
3162 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
3163 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3165 M_BEQZ(REG_ITMP2, 0);
3168 /* mcode_addreference(BlockPtrOfPC(s4ptr[0]), mcodeptr); */
3169 mcode_addreference((basicblock *) tptr[0], mcodeptr);
3171 /* build jump table top down and use address of lowest entry */
3173 /* s4ptr += 3 + i; */
3177 /* dseg_addtarget(BlockPtrOfPC(*--s4ptr)); */
3178 dseg_addtarget((basicblock *) tptr[0]);
3183 /* length of dataseg after last dseg_addtarget is used by load */
3185 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
3186 M_ALD(REG_ITMP2, REG_ITMP2, -dseglen);
3187 M_JMP(REG_ZERO, REG_ITMP2);
3192 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3194 s4 i, l, val, *s4ptr;
3197 tptr = (void **) iptr->target;
3199 s4ptr = iptr->val.a;
3200 l = s4ptr[0]; /* default */
3201 i = s4ptr[1]; /* count */
3203 MCODECHECK((i<<2)+8);
3204 var_to_reg_int(s1, src, REG_ITMP1);
3210 if ((val >= 0) && (val <= 255)) {
3211 M_CMPEQ_IMM(s1, val, REG_ITMP2);
3214 if ((val >= -32768) && (val <= 32767)) {
3215 M_LDA(REG_ITMP2, REG_ZERO, val);
3218 a = dseg_adds4 (val);
3219 M_ILD(REG_ITMP2, REG_PV, a);
3221 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
3223 M_BNEZ(REG_ITMP2, 0);
3224 /* mcode_addreference(BlockPtrOfPC(s4ptr[1]), mcodeptr); */
3225 mcode_addreference((basicblock *) tptr[0], mcodeptr);
3229 /* mcode_addreference(BlockPtrOfPC(l), mcodeptr); */
3231 tptr = (void **) iptr->target;
3232 mcode_addreference((basicblock *) tptr[0], mcodeptr);
3239 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
3240 /* op1 = return type, val.a = function pointer*/
3244 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
3245 /* op1 = return type, val.a = function pointer*/
3249 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
3250 /* op1 = return type, val.a = function pointer*/
3254 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3255 /* op1 = arg count, val.a = method pointer */
3257 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3258 /* op1 = arg count, val.a = method pointer */
3260 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3261 /* op1 = arg count, val.a = method pointer */
3263 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
3264 /* op1 = arg count, val.a = method pointer */
3272 MCODECHECK((s3 << 1) + 64);
3274 /* copy arguments to registers or stack location */
3276 for (; --s3 >= 0; src = src->prev) {
3277 if (src->varkind == ARGVAR)
3279 if (IS_INT_LNG_TYPE(src->type)) {
3280 if (s3 < INT_ARG_CNT) {
3281 s1 = argintregs[s3];
3282 var_to_reg_int(d, src, s1);
3286 var_to_reg_int(d, src, REG_ITMP1);
3287 M_LST(d, REG_SP, 8 * (s3 - INT_ARG_CNT));
3291 if (s3 < FLT_ARG_CNT) {
3292 s1 = argfltregs[s3];
3293 var_to_reg_flt(d, src, s1);
3297 var_to_reg_flt(d, src, REG_FTMP1);
3298 M_DST(d, REG_SP, 8 * (s3 - FLT_ARG_CNT));
3303 switch (iptr->opc) {
3307 a = dseg_addaddress ((void*) (m));
3309 M_ALD(REG_PV, REG_PV, a); /* Pointer to built-in-function */
3311 goto makeactualcall;
3313 case ICMD_INVOKESTATIC:
3314 case ICMD_INVOKESPECIAL:
3315 a = dseg_addaddress (m->stubroutine);
3317 M_ALD(REG_PV, REG_PV, a ); /* method pointer in r27 */
3320 goto makeactualcall;
3322 case ICMD_INVOKEVIRTUAL:
3324 gen_nullptr_check(argintregs[0]);
3325 M_ALD(REG_METHODPTR, argintregs[0],
3326 OFFSET(java_objectheader, vftbl));
3327 M_ALD(REG_PV, REG_METHODPTR, OFFSET(vftbl, table[0]) +
3328 sizeof(methodptr) * m->vftblindex);
3331 goto makeactualcall;
3333 case ICMD_INVOKEINTERFACE:
3336 gen_nullptr_check(argintregs[0]);
3337 M_ALD(REG_METHODPTR, argintregs[0],
3338 OFFSET(java_objectheader, vftbl));
3339 M_ALD(REG_METHODPTR, REG_METHODPTR,
3340 OFFSET(vftbl, interfacetable[0]) -
3341 sizeof(methodptr*) * ci->index);
3342 M_ALD(REG_PV, REG_METHODPTR,
3343 sizeof(methodptr) * (m - ci->methods));
3346 goto makeactualcall;
3350 sprintf (logtext, "Unkown ICMD-Command: %d", iptr->opc);
3356 M_JSR (REG_RA, REG_PV);
3360 s1 = (int)((u1*) mcodeptr - mcodebase);
3361 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
3364 while (ml<-32768) { ml+=65536; mh--; }
3365 M_LDA (REG_PV, REG_RA, ml );
3366 M_LDAH (REG_PV, REG_PV, mh );
3369 /* d contains return type */
3371 if (d != TYPE_VOID) {
3372 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3373 s1 = reg_of_var(iptr->dst, REG_RESULT);
3374 M_INTMOVE(REG_RESULT, s1);
3375 store_reg_to_var_int(iptr->dst, s1);
3378 s1 = reg_of_var(iptr->dst, REG_FRESULT);
3379 M_FLTMOVE(REG_FRESULT, s1);
3380 store_reg_to_var_flt(iptr->dst, s1);
3387 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3389 /* op1: 0 == array, 1 == class */
3390 /* val.a: (classinfo*) superclass */
3392 /* superclass is an interface:
3394 * return (sub != NULL) &&
3395 * (sub->vftbl->interfacetablelength > super->index) &&
3396 * (sub->vftbl->interfacetable[-super->index] != NULL);
3398 * superclass is a class:
3400 * return ((sub != NULL) && (0
3401 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3402 * super->vftbl->diffvall));
3406 classinfo *super = (classinfo*) iptr->val.a;
3408 var_to_reg_int(s1, src, REG_ITMP1);
3409 d = reg_of_var(iptr->dst, REG_ITMP3);
3411 M_MOV(s1, REG_ITMP1);
3415 if (iptr->op1) { /* class/interface */
3416 if (super->flags & ACC_INTERFACE) { /* interface */
3418 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3419 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3420 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3421 M_BLEZ(REG_ITMP2, 2);
3422 M_ALD(REG_ITMP1, REG_ITMP1,
3423 OFFSET(vftbl, interfacetable[0]) -
3424 super->index * sizeof(methodptr*));
3425 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3429 s2 = super->vftbl->diffval;
3430 M_BEQZ(s1, 4 + (s2 > 255));
3431 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3432 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3433 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3435 M_CMPULE_IMM(REG_ITMP1, s2, d);
3437 M_LDA(REG_ITMP2, REG_ZERO, s2);
3438 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3442 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3443 a = dseg_addaddress ((void*) super->vftbl);
3444 M_ALD(REG_ITMP2, REG_PV, a);
3445 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3446 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl, baseval));
3447 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, diffval));
3448 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3449 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3453 panic ("internal error: no inlined array instanceof");
3455 store_reg_to_var_int(iptr->dst, d);
3458 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3460 /* op1: 0 == array, 1 == class */
3461 /* val.a: (classinfo*) superclass */
3463 /* superclass is an interface:
3465 * OK if ((sub == NULL) ||
3466 * (sub->vftbl->interfacetablelength > super->index) &&
3467 * (sub->vftbl->interfacetable[-super->index] != NULL));
3469 * superclass is a class:
3471 * OK if ((sub == NULL) || (0
3472 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3473 * super->vftbl->diffvall));
3477 classinfo *super = (classinfo*) iptr->val.a;
3479 d = reg_of_var(iptr->dst, REG_ITMP3);
3480 var_to_reg_int(s1, src, d);
3481 if (iptr->op1) { /* class/interface */
3482 if (super->flags & ACC_INTERFACE) { /* interface */
3484 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3485 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3486 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3487 M_BLEZ(REG_ITMP2, 0);
3488 mcode_addxcastrefs(mcodeptr);
3489 M_ALD(REG_ITMP2, REG_ITMP1,
3490 OFFSET(vftbl, interfacetable[0]) -
3491 super->index * sizeof(methodptr*));
3492 M_BEQZ(REG_ITMP2, 0);
3493 mcode_addxcastrefs(mcodeptr);
3497 s2 = super->vftbl->diffval;
3498 M_BEQZ(s1, 4 + (s2 != 0) + (s2 > 255));
3499 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3500 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3501 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3503 M_BNEZ(REG_ITMP1, 0);
3505 else if (s2 <= 255) {
3506 M_CMPULE_IMM(REG_ITMP1, s2, REG_ITMP2);
3507 M_BEQZ(REG_ITMP2, 0);
3510 M_LDA(REG_ITMP2, REG_ZERO, s2);
3511 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3512 M_BEQZ(REG_ITMP2, 0);
3515 M_BEQZ(s1, 8 + (d == REG_ITMP3));
3516 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3517 a = dseg_addaddress ((void*) super->vftbl);
3518 M_ALD(REG_ITMP2, REG_PV, a);
3519 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3520 if (d != REG_ITMP3) {
3521 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl, baseval));
3522 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, diffval));
3523 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3526 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, baseval));
3527 M_ISUB(REG_ITMP1, REG_ITMP2, REG_ITMP1);
3528 M_ALD(REG_ITMP2, REG_PV, a);
3529 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, diffval));
3531 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3532 M_BEQZ(REG_ITMP2, 0);
3533 mcode_addxcastrefs(mcodeptr);
3537 panic ("internal error: no inlined array checkcast");
3540 store_reg_to_var_int(iptr->dst, d);
3543 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
3545 var_to_reg_int(s1, src, REG_ITMP1);
3547 mcode_addxcheckarefs(mcodeptr);
3550 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3551 /* op1 = dimension, val.a = array descriptor */
3553 /* check for negative sizes and copy sizes to stack if necessary */
3555 MCODECHECK((iptr->op1 << 1) + 64);
3557 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3558 var_to_reg_int(s2, src, REG_ITMP1);
3560 mcode_addxcheckarefs(mcodeptr);
3562 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
3564 if (src->varkind != ARGVAR) {
3565 M_LST(s2, REG_SP, 8 * (s1 + INT_ARG_CNT));
3569 /* a0 = dimension count */
3571 ICONST(argintregs[0], iptr->op1);
3573 /* a1 = arraydescriptor */
3575 a = dseg_addaddress(iptr->val.a);
3576 M_ALD(argintregs[1], REG_PV, a);
3578 /* a2 = pointer to dimensions = stack pointer */
3580 M_INTMOVE(REG_SP, argintregs[2]);
3582 a = dseg_addaddress((void*) (builtin_nmultianewarray));
3583 M_ALD(REG_PV, REG_PV, a);
3584 M_JSR(REG_RA, REG_PV);
3585 s1 = (int)((u1*) mcodeptr - mcodebase);
3587 M_LDA (REG_PV, REG_RA, -s1);
3589 s4 ml = -s1, mh = 0;
3590 while (ml < -32768) {ml += 65536; mh--;}
3591 M_LDA(REG_PV, REG_RA, ml);
3592 M_LDAH(REG_PV, REG_PV, mh);
3594 s1 = reg_of_var(iptr->dst, REG_RESULT);
3595 M_INTMOVE(REG_RESULT, s1);
3596 store_reg_to_var_int(iptr->dst, s1);
3600 default: sprintf (logtext, "Unknown pseudo command: %d", iptr->opc);
3607 } /* for instruction */
3609 /* copy values to interface registers */
3611 src = bptr->outstack;
3612 len = bptr->outdepth;
3616 if ((src->varkind != STACKVAR)) {
3618 if (IS_FLT_DBL_TYPE(s2)) {
3619 var_to_reg_flt(s1, src, REG_FTMP1);
3620 if (!(interfaces[len][s2].flags & INMEMORY)) {
3621 M_FLTMOVE(s1,interfaces[len][s2].regoff);
3624 M_DST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3628 var_to_reg_int(s1, src, REG_ITMP1);
3629 if (!(interfaces[len][s2].flags & INMEMORY)) {
3630 M_INTMOVE(s1,interfaces[len][s2].regoff);
3633 M_LST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3639 } /* if (bptr -> flags >= BBREACHED) */
3640 } /* for basic block */
3642 /* bptr -> mpc = (int)((u1*) mcodeptr - mcodebase); */
3645 /* generate bound check stubs */
3647 s4 *xcodeptr = NULL;
3649 for (; xboundrefs != NULL; xboundrefs = xboundrefs->next) {
3650 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3651 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
3652 xboundrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3657 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
3658 xboundrefs->branchpos, (u1*) mcodeptr - mcodebase);
3662 M_LDA(REG_ITMP2_XPC, REG_PV, xboundrefs->branchpos - 4);
3664 if (xcodeptr != NULL) {
3665 M_BR((xcodeptr-mcodeptr)-1);
3668 xcodeptr = mcodeptr;
3670 a = dseg_addaddress(proto_java_lang_ArrayIndexOutOfBoundsException);
3671 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3673 a = dseg_addaddress(asm_handle_exception);
3674 M_ALD(REG_ITMP3, REG_PV, a);
3676 M_JMP(REG_ZERO, REG_ITMP3);
3680 /* generate negative array size check stubs */
3684 for (; xcheckarefs != NULL; xcheckarefs = xcheckarefs->next) {
3685 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3686 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3687 xcheckarefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3691 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3692 xcheckarefs->branchpos, (u1*) mcodeptr - mcodebase);
3696 M_LDA(REG_ITMP2_XPC, REG_PV, xcheckarefs->branchpos - 4);
3698 if (xcodeptr != NULL) {
3699 M_BR((xcodeptr-mcodeptr)-1);
3702 xcodeptr = mcodeptr;
3704 a = dseg_addaddress(proto_java_lang_NegativeArraySizeException);
3705 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3707 a = dseg_addaddress(asm_handle_exception);
3708 M_ALD(REG_ITMP3, REG_PV, a);
3710 M_JMP(REG_ZERO, REG_ITMP3);
3714 /* generate cast check stubs */
3718 for (; xcastrefs != NULL; xcastrefs = xcastrefs->next) {
3719 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3720 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3721 xcastrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3725 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3726 xcastrefs->branchpos, (u1*) mcodeptr - mcodebase);
3730 M_LDA(REG_ITMP2_XPC, REG_PV, xcastrefs->branchpos - 4);
3732 if (xcodeptr != NULL) {
3733 M_BR((xcodeptr-mcodeptr)-1);
3736 xcodeptr = mcodeptr;
3738 a = dseg_addaddress(proto_java_lang_ClassCastException);
3739 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3741 a = dseg_addaddress(asm_handle_exception);
3742 M_ALD(REG_ITMP3, REG_PV, a);
3744 M_JMP(REG_ZERO, REG_ITMP3);
3749 #ifdef SOFTNULLPTRCHECK
3751 /* generate null pointer check stubs */
3755 for (; xnullrefs != NULL; xnullrefs = xnullrefs->next) {
3756 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3757 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3758 xnullrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3762 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3763 xnullrefs->branchpos, (u1*) mcodeptr - mcodebase);
3767 M_LDA(REG_ITMP2_XPC, REG_PV, xnullrefs->branchpos - 4);
3769 if (xcodeptr != NULL) {
3770 M_BR((xcodeptr-mcodeptr)-1);
3773 xcodeptr = mcodeptr;
3775 a = dseg_addaddress(proto_java_lang_NullPointerException);
3776 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3778 a = dseg_addaddress(asm_handle_exception);
3779 M_ALD(REG_ITMP3, REG_PV, a);
3781 M_JMP(REG_ZERO, REG_ITMP3);
3788 mcode_finish((int)((u1*) mcodeptr - mcodebase));
3792 /* redefinition of code generation macros (compiling into array) **************/
3795 These macros are newly defined to allow code generation into an array.
3796 This is necessary, because the original M_.. macros generate code by
3797 calling 'mcode_adds4' that uses an additional data structure to
3800 For a faster (but less flexible) version to generate code, these
3801 macros directly use the (s4* p) - pointer to put the code directly
3802 in a locally defined array.
3803 This makes sense only for the stub-generation-routines below.
3807 #define M_OP3(op,fu,a,b,c,const) \
3808 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<(16-3*(const)))| \
3809 ((const)<<12)|((fu)<<5)|((c)) )
3811 #define M_FOP3(op,fu,a,b,c) \
3812 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<16)|((fu)<<5)|(c) )
3814 #define M_BRA(op,a,disp) \
3815 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((disp)&0x1fffff) )
3817 #define M_MEM(op,a,b,disp) \
3818 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<16)|((disp)&0xffff) )
3821 /* function createcompilerstub *************************************************
3823 creates a stub routine which calls the compiler
3825 *******************************************************************************/
3827 #define COMPSTUBSIZE 3
3829 u1 *createcompilerstub (methodinfo *m)
3831 u8 *s = CNEW (u8, COMPSTUBSIZE); /* memory to hold the stub */
3832 s4 *p = (s4*) s; /* code generation pointer */
3834 /* code for the stub */
3835 M_ALD (REG_PV, REG_PV, 16); /* load pointer to the compiler */
3836 M_JMP (0, REG_PV); /* jump to the compiler, return address
3837 in reg 0 is used as method pointer */
3838 s[1] = (u8) m; /* literals to be adressed */
3839 s[2] = (u8) asm_call_jit_compiler; /* jump directly via PV from above */
3842 count_cstub_len += COMPSTUBSIZE * 8;
3849 /* function removecompilerstub *************************************************
3851 deletes a compilerstub from memory (simply by freeing it)
3853 *******************************************************************************/
3855 void removecompilerstub (u1 *stub)
3857 CFREE (stub, COMPSTUBSIZE * 8);
3860 /* function: createnativestub **************************************************
3862 creates a stub routine which calls a native method
3864 *******************************************************************************/
3866 #define NATIVESTUBSIZE 34
3867 #define NATIVESTUBOFFSET 8
3869 int runverbosenat = 0;
3871 u1 *createnativestub (functionptr f, methodinfo *m)
3874 u8 *s = CNEW (u8, NATIVESTUBSIZE); /* memory to hold the stub */
3875 u8 *cs = s + NATIVESTUBOFFSET;
3876 s4 *p = (s4*) (cs); /* code generation pointer */
3878 *(cs-1) = (u8) f; /* address of native method */
3879 *(cs-2) = (u8) (&exceptionptr); /* address of exceptionptr */
3880 *(cs-3) = (u8) asm_handle_nat_exception; /* addr of asm exception handler */
3881 *(cs-4) = (u8) (&env); /* addr of jni_environement */
3882 *(cs-5) = (u8) asm_builtin_trace;
3884 *(cs-7) = (u8) asm_builtin_exittrace;
3885 *(cs-8) = (u8) builtin_trace_exception;
3889 utf_display(m->class->name);
3891 utf_display(m->name);
3892 printf(" 0x%p\n", cs);
3895 M_LDA (REG_SP, REG_SP, -8); /* build up stackframe */
3896 M_AST (REG_RA, REG_SP, 0); /* store return address */
3899 if (runverbosenat) {
3900 M_ALD(REG_ITMP1, REG_PV, -6*8);
3901 M_ALD(REG_PV, REG_PV, -5*8);
3903 M_JSR(REG_RA, REG_PV);
3904 disp = -(int) (p - (s4*) cs)*4;
3905 M_LDA(REG_PV, REG_RA, disp);
3911 M_MOV (argintregs[4],argintregs[5]);
3912 M_FMOV (argfltregs[4],argfltregs[5]);
3914 M_MOV (argintregs[3],argintregs[4]);
3915 M_FMOV (argfltregs[3],argfltregs[4]);
3917 M_MOV (argintregs[2],argintregs[3]);
3918 M_FMOV (argfltregs[2],argfltregs[3]);
3920 M_MOV (argintregs[1],argintregs[2]);
3921 M_FMOV (argfltregs[1],argfltregs[2]);
3923 M_MOV (argintregs[0],argintregs[1]);
3924 M_FMOV (argfltregs[0],argfltregs[1]);
3926 M_ALD (argintregs[0], REG_PV, -4*8);/* load adress of jni_environement */
3928 M_ALD (REG_PV, REG_PV, -1*8); /* load adress of native method */
3929 M_JSR (REG_RA, REG_PV); /* call native method */
3931 disp = -(int) (p - (s4*) cs)*4;
3932 M_LDA (REG_PV, REG_RA, disp); /* recompute pv from ra */
3933 M_ALD (REG_ITMP3, REG_PV, -2*8); /* get address of exceptionptr */
3935 M_ALD (REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
3937 3 + (runverbosenat ? 6 : 0)); /* if no exception then return */
3940 if (runverbosenat) {
3941 M_ALD(argintregs[0], REG_PV, -6*8);
3942 M_MOV(REG_RESULT, argintregs[1]);
3943 M_FMOV(REG_FRESULT, argfltregs[2]);
3944 M_FMOV(REG_FRESULT, argfltregs[3]);
3945 M_ALD(REG_PV, REG_PV, -7*8);
3946 M_JSR(REG_RA, REG_PV);
3950 M_ALD (REG_RA, REG_SP, 0); /* load return address */
3951 M_LDA (REG_SP, REG_SP, 8); /* remove stackframe */
3953 M_RET (REG_ZERO, REG_RA); /* return to caller */
3955 M_AST (REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
3958 if (runverbosenat) {
3959 M_LDA(REG_SP, REG_SP, -8);
3960 M_AST(REG_ITMP1, REG_SP, 0);
3961 M_MOV(REG_ITMP1, argintregs[0]);
3962 M_ALD(argintregs[1], REG_PV, -6*8);
3963 M_ALD(argintregs[2], REG_SP, 0);
3964 M_CLR(argintregs[3]);
3965 M_ALD(REG_PV, REG_PV, -8*8);
3966 M_JSR(REG_RA, REG_PV);
3967 disp = -(int) (p - (s4*) cs)*4;
3968 M_LDA (REG_PV, REG_RA, disp);
3969 M_ALD(REG_ITMP1, REG_SP, 0);
3970 M_LDA(REG_SP, REG_SP, 8);
3974 M_ALD (REG_RA, REG_SP, 0); /* load return address */
3975 M_LDA (REG_SP, REG_SP, 8); /* remove stackframe */
3977 M_LDA (REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
3979 M_ALD (REG_ITMP3, REG_PV, -3*8); /* load asm exception handler address */
3980 M_JMP (REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
3984 static int stubprinted;
3986 printf("stubsize: %d/2\n", (int) (p - (s4*) s));
3992 count_nstub_len += NATIVESTUBSIZE * 8;
3995 return (u1*) (s + NATIVESTUBOFFSET);
3998 /* function: removenativestub **************************************************
4000 removes a previously created native-stub from memory
4002 *******************************************************************************/
4004 void removenativestub (u1 *stub)
4006 CFREE ((u8*) stub - NATIVESTUBOFFSET, NATIVESTUBSIZE * 8);
4011 * These are local overrides for various environment variables in Emacs.
4012 * Please do not remove this and leave it at the end of the file, where
4013 * Emacs will automagically detect them.
4014 * ---------------------------------------------------------------------
4017 * indent-tabs-mode: t