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 132 1999-09-27 15:54:42Z chris $
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_nat_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 */
279 ieee_set_fp_control(ieee_get_fp_control()
280 & ~IEEE_TRAP_ENABLE_INV
281 & ~IEEE_TRAP_ENABLE_DZE
282 /* & ~IEEE_TRAP_ENABLE_UNF we dont want underflow */
283 & ~IEEE_TRAP_ENABLE_OVF);
286 /* install signal handlers we need to convert to exceptions */
291 signal(SIGSEGV, (void*) catch_NullPointerException);
295 signal(SIGBUS, (void*) catch_NullPointerException);
301 /* function gen_mcode **********************************************************
303 generates machine code
305 *******************************************************************************/
307 #define MethodPointer -8
308 #define FrameSize -12
313 #define ExTableSize -32
314 #define ExTableStart -32
316 #define ExEntrySize -32
319 #define ExHandlerPC -24
320 #define ExCatchType -32
322 static void gen_mcode()
324 int len, s1, s2, s3, d, bbs;
336 savedregs_num = (isleafmethod) ? 0 : 1; /* space to save the RA */
338 /* space to save used callee saved registers */
340 savedregs_num += (savintregcnt - maxsavintreguse);
341 savedregs_num += (savfltregcnt - maxsavfltreguse);
343 parentargs_base = maxmemuse + savedregs_num;
345 #ifdef USE_THREADS /* space to save argument of monitor_enter */
347 if (checksync && (method->flags & ACC_SYNCHRONIZED))
352 /* create method header */
354 (void) dseg_addaddress(method); /* MethodPointer */
355 (void) dseg_adds4(parentargs_base * 8); /* FrameSize */
359 /* IsSync contains the offset relative to the stack pointer for the
360 argument of monitor_exit used in the exception handler. Since the
361 offset could be zero and give a wrong meaning of the flag it is
365 if (checksync && (method->flags & ACC_SYNCHRONIZED))
366 (void) dseg_adds4((maxmemuse + 1) * 8); /* IsSync */
371 (void) dseg_adds4(0); /* IsSync */
373 (void) dseg_adds4(isleafmethod); /* IsLeaf */
374 (void) dseg_adds4(savintregcnt - maxsavintreguse); /* IntSave */
375 (void) dseg_adds4(savfltregcnt - maxsavfltreguse); /* FltSave */
376 (void) dseg_adds4(exceptiontablelength); /* ExTableSize */
378 /* create exception table */
380 for (ex = extable; ex != NULL; ex = ex->down) {
383 if (ex->start != NULL)
384 printf("adding start - %d - ", ex->start->debug_nr);
386 printf("PANIC - start is NULL");
391 dseg_addtarget(ex->start);
395 printf("adding end - %d - ", ex->end->debug_nr);
397 printf("PANIC - end is NULL");
402 dseg_addtarget(ex->end);
405 if (ex->handler != NULL)
406 printf("adding handler - %d\n", ex->handler->debug_nr);
408 printf("PANIC - handler is NULL");
413 dseg_addtarget(ex->handler);
415 (void) dseg_addaddress(ex->catchtype);
418 /* initialize mcode variables */
420 mcodeptr = (s4*) mcodebase;
421 mcodeend = (s4*) (mcodebase + mcodesize);
422 MCODECHECK(128 + mparamcount);
424 /* create stack frame (if necessary) */
427 {M_LDA (REG_SP, REG_SP, -parentargs_base * 8);}
429 /* save return address and used callee saved registers */
433 {p--; M_AST (REG_RA, REG_SP, 8*p);}
434 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
435 {p--; M_LST (savintregs[r], REG_SP, 8 * p);}
436 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
437 {p--; M_DST (savfltregs[r], REG_SP, 8 * p);}
439 /* save monitorenter argument */
442 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
443 if (method->flags & ACC_STATIC) {
444 p = dseg_addaddress (class);
445 M_ALD(REG_ITMP1, REG_PV, p);
446 M_AST(REG_ITMP1, REG_SP, 8 * maxmemuse);
449 M_AST (argintregs[0], REG_SP, 8 * maxmemuse);
454 /* copy argument registers to stack and call trace function with pointer
455 to arguments on stack. ToDo: save floating point registers !!!!!!!!!
458 if (runverbose && isleafmethod) {
459 M_LDA (REG_SP, REG_SP, -(14*8));
460 M_AST(REG_RA, REG_SP, 1*8);
462 M_LST(argintregs[0], REG_SP, 2*8);
463 M_LST(argintregs[1], REG_SP, 3*8);
464 M_LST(argintregs[2], REG_SP, 4*8);
465 M_LST(argintregs[3], REG_SP, 5*8);
466 M_LST(argintregs[4], REG_SP, 6*8);
467 M_LST(argintregs[5], REG_SP, 7*8);
469 M_DST(argfltregs[0], REG_SP, 8*8);
470 M_DST(argfltregs[1], REG_SP, 9*8);
471 M_DST(argfltregs[2], REG_SP, 10*8);
472 M_DST(argfltregs[3], REG_SP, 11*8);
473 M_DST(argfltregs[4], REG_SP, 12*8);
474 M_DST(argfltregs[5], REG_SP, 13*8);
476 p = dseg_addaddress (method);
477 M_ALD(REG_ITMP1, REG_PV, p);
478 M_AST(REG_ITMP1, REG_SP, 0);
479 p = dseg_addaddress ((void*) (builtin_trace_args));
480 M_ALD(REG_PV, REG_PV, p);
481 M_JSR(REG_RA, REG_PV);
482 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
483 M_ALD(REG_RA, REG_SP, 1*8);
485 M_LLD(argintregs[0], REG_SP, 2*8);
486 M_LLD(argintregs[1], REG_SP, 3*8);
487 M_LLD(argintregs[2], REG_SP, 4*8);
488 M_LLD(argintregs[3], REG_SP, 5*8);
489 M_LLD(argintregs[4], REG_SP, 6*8);
490 M_LLD(argintregs[5], REG_SP, 7*8);
492 M_DLD(argfltregs[0], REG_SP, 8*8);
493 M_DLD(argfltregs[1], REG_SP, 9*8);
494 M_DLD(argfltregs[2], REG_SP, 10*8);
495 M_DLD(argfltregs[3], REG_SP, 11*8);
496 M_DLD(argfltregs[4], REG_SP, 12*8);
497 M_DLD(argfltregs[5], REG_SP, 13*8);
499 M_LDA (REG_SP, REG_SP, 14*8);
502 /* take arguments out of register or stack frame */
504 for (p = 0, l = 0; p < mparamcount; p++) {
506 var = &(locals[l][t]);
508 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
513 if (IS_INT_LNG_TYPE(t)) { /* integer args */
514 if (p < INT_ARG_CNT) { /* register arguments */
515 if (!(var->flags & INMEMORY)) /* reg arg -> register */
516 {M_INTMOVE (argintregs[p], r);}
517 else /* reg arg -> spilled */
518 M_LST (argintregs[p], REG_SP, 8 * r);
520 else { /* stack arguments */
521 pa = p - INT_ARG_CNT;
522 if (!(var->flags & INMEMORY)) /* stack arg -> register */
523 M_LLD (r, REG_SP, 8 * (parentargs_base + pa));
524 else { /* stack arg -> spilled */
525 M_LLD (REG_ITMP1, REG_SP, 8 * (parentargs_base + pa));
526 M_LST (REG_ITMP1, REG_SP, 8 * r);
530 else { /* floating args */
531 if (p < FLT_ARG_CNT) { /* register arguments */
532 if (!(var->flags & INMEMORY)) /* reg arg -> register */
533 {M_FLTMOVE (argfltregs[p], r);}
534 else /* reg arg -> spilled */
535 M_DST (argfltregs[p], REG_SP, 8 * r);
537 else { /* stack arguments */
538 pa = p - FLT_ARG_CNT;
539 if (!(var->flags & INMEMORY)) /* stack-arg -> register */
540 M_DLD (r, REG_SP, 8 * (parentargs_base + pa) );
541 else { /* stack-arg -> spilled */
542 M_DLD (REG_FTMP1, REG_SP, 8 * (parentargs_base + pa));
543 M_DST (REG_FTMP1, REG_SP, 8 * r);
549 /* call trace function */
551 if (runverbose && !isleafmethod) {
552 M_LDA (REG_SP, REG_SP, -8);
553 p = dseg_addaddress (method);
554 M_ALD(REG_ITMP1, REG_PV, p);
555 M_AST(REG_ITMP1, REG_SP, 0);
556 p = dseg_addaddress ((void*) (builtin_trace_args));
557 M_ALD(REG_PV, REG_PV, p);
558 M_JSR(REG_RA, REG_PV);
559 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
560 M_LDA(REG_SP, REG_SP, 8);
563 /* call monitorenter function */
566 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
567 p = dseg_addaddress ((void*) (builtin_monitorenter));
568 M_ALD(REG_PV, REG_PV, p);
569 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
570 M_JSR(REG_RA, REG_PV);
571 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
576 /* end of header generation */
578 /* walk through all basic blocks */
579 for (/* bbs = block_count, */ bptr = block; /* --bbs >= 0 */ bptr != NULL; bptr = bptr->next) {
581 bptr -> mpc = (int)((u1*) mcodeptr - mcodebase);
583 if (bptr->flags >= BBREACHED) {
585 /* branch resolving */
589 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
590 gen_resolvebranch((u1*) mcodebase + brefs->branchpos,
591 brefs->branchpos, bptr->mpc);
595 /* copy interface registers to their destination */
600 while (src != NULL) {
602 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
603 d = reg_of_var(src, REG_ITMP1);
604 M_INTMOVE(REG_ITMP1, d);
605 store_reg_to_var_int(src, d);
608 d = reg_of_var(src, REG_IFTMP);
609 if ((src->varkind != STACKVAR)) {
611 if (IS_FLT_DBL_TYPE(s2)) {
612 if (!(interfaces[len][s2].flags & INMEMORY)) {
613 s1 = interfaces[len][s2].regoff;
617 M_DLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
619 store_reg_to_var_flt(src, d);
622 if (!(interfaces[len][s2].flags & INMEMORY)) {
623 s1 = interfaces[len][s2].regoff;
627 M_LLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
629 store_reg_to_var_int(src, d);
636 /* walk through all instructions */
640 for (iptr = bptr->iinstr;
642 src = iptr->dst, len--, iptr++) {
644 MCODECHECK(64); /* an instruction usually needs < 64 words */
647 case ICMD_NOP: /* ... ==> ... */
650 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
652 var_to_reg_int(s1, src, REG_ITMP1);
654 mcode_addxnullrefs(mcodeptr);
657 /* constant operations ************************************************/
659 #define ICONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
660 else{a=dseg_adds4(c);M_ILD(r,REG_PV,a);}
662 #define LCONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
663 else{a=dseg_adds8(c);M_LLD(r,REG_PV,a);}
665 case ICMD_ICONST: /* ... ==> ..., constant */
666 /* op1 = 0, val.i = constant */
668 d = reg_of_var(iptr->dst, REG_ITMP1);
669 ICONST(d, iptr->val.i);
670 store_reg_to_var_int(iptr->dst, d);
673 case ICMD_LCONST: /* ... ==> ..., constant */
674 /* op1 = 0, val.l = constant */
676 d = reg_of_var(iptr->dst, REG_ITMP1);
677 LCONST(d, iptr->val.l);
678 store_reg_to_var_int(iptr->dst, d);
681 case ICMD_FCONST: /* ... ==> ..., constant */
682 /* op1 = 0, val.f = constant */
684 d = reg_of_var (iptr->dst, REG_FTMP1);
685 a = dseg_addfloat (iptr->val.f);
687 store_reg_to_var_flt (iptr->dst, d);
690 case ICMD_DCONST: /* ... ==> ..., constant */
691 /* op1 = 0, val.d = constant */
693 d = reg_of_var (iptr->dst, REG_FTMP1);
694 a = dseg_adddouble (iptr->val.d);
696 store_reg_to_var_flt (iptr->dst, d);
699 case ICMD_ACONST: /* ... ==> ..., constant */
700 /* op1 = 0, val.a = constant */
702 d = reg_of_var(iptr->dst, REG_ITMP1);
704 a = dseg_addaddress (iptr->val.a);
708 M_INTMOVE(REG_ZERO, d);
710 store_reg_to_var_int(iptr->dst, d);
714 /* load/store operations **********************************************/
716 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
717 case ICMD_LLOAD: /* op1 = local variable */
720 d = reg_of_var(iptr->dst, REG_ITMP1);
721 if ((iptr->dst->varkind == LOCALVAR) &&
722 (iptr->dst->varnum == iptr->op1))
724 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
725 if (var->flags & INMEMORY)
726 M_LLD(d, REG_SP, 8 * var->regoff);
728 {M_INTMOVE(var->regoff,d);}
729 store_reg_to_var_int(iptr->dst, d);
732 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
733 case ICMD_DLOAD: /* op1 = local variable */
735 d = reg_of_var(iptr->dst, REG_FTMP1);
736 if ((iptr->dst->varkind == LOCALVAR) &&
737 (iptr->dst->varnum == iptr->op1))
739 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
740 if (var->flags & INMEMORY)
741 M_DLD(d, REG_SP, 8 * var->regoff);
743 {M_FLTMOVE(var->regoff,d);}
744 store_reg_to_var_flt(iptr->dst, d);
748 case ICMD_ISTORE: /* ..., value ==> ... */
749 case ICMD_LSTORE: /* op1 = local variable */
752 if ((src->varkind == LOCALVAR) &&
753 (src->varnum == iptr->op1))
755 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
756 if (var->flags & INMEMORY) {
757 var_to_reg_int(s1, src, REG_ITMP1);
758 M_LST(s1, REG_SP, 8 * var->regoff);
761 var_to_reg_int(s1, src, var->regoff);
762 M_INTMOVE(s1, var->regoff);
766 case ICMD_FSTORE: /* ..., value ==> ... */
767 case ICMD_DSTORE: /* op1 = local variable */
769 if ((src->varkind == LOCALVAR) &&
770 (src->varnum == iptr->op1))
772 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
773 if (var->flags & INMEMORY) {
774 var_to_reg_flt(s1, src, REG_FTMP1);
775 M_DST(s1, REG_SP, 8 * var->regoff);
778 var_to_reg_flt(s1, src, var->regoff);
779 M_FLTMOVE(s1, var->regoff);
784 /* pop/dup/swap operations ********************************************/
786 /* attention: double and longs are only one entry in CACAO ICMDs */
788 case ICMD_POP: /* ..., value ==> ... */
789 case ICMD_POP2: /* ..., value, value ==> ... */
792 #define M_COPY(from,to) \
793 d = reg_of_var(to, REG_IFTMP); \
794 if ((from->regoff != to->regoff) || \
795 ((from->flags ^ to->flags) & INMEMORY)) { \
796 if (IS_FLT_DBL_TYPE(from->type)) { \
797 var_to_reg_flt(s1, from, d); \
799 store_reg_to_var_flt(to, d); \
802 var_to_reg_int(s1, from, d); \
804 store_reg_to_var_int(to, d); \
808 case ICMD_DUP: /* ..., a ==> ..., a, a */
809 M_COPY(src, iptr->dst);
812 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
814 M_COPY(src, iptr->dst->prev->prev);
816 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
818 M_COPY(src, iptr->dst);
819 M_COPY(src->prev, iptr->dst->prev);
822 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
824 M_COPY(src->prev, iptr->dst->prev->prev->prev);
826 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
828 M_COPY(src, iptr->dst);
829 M_COPY(src->prev, iptr->dst->prev);
830 M_COPY(src->prev->prev, iptr->dst->prev->prev);
831 M_COPY(src, iptr->dst->prev->prev->prev);
834 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
836 M_COPY(src, iptr->dst);
837 M_COPY(src->prev, iptr->dst->prev);
838 M_COPY(src->prev->prev, iptr->dst->prev->prev);
839 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
840 M_COPY(src, iptr->dst->prev->prev->prev->prev);
841 M_COPY(src->prev, iptr->dst->prev->prev->prev->prev->prev);
844 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
846 M_COPY(src, iptr->dst->prev);
847 M_COPY(src->prev, iptr->dst);
851 /* integer operations *************************************************/
853 case ICMD_INEG: /* ..., value ==> ..., - value */
855 var_to_reg_int(s1, src, REG_ITMP1);
856 d = reg_of_var(iptr->dst, REG_ITMP3);
857 M_ISUB(REG_ZERO, s1, d);
858 store_reg_to_var_int(iptr->dst, d);
861 case ICMD_LNEG: /* ..., value ==> ..., - value */
863 var_to_reg_int(s1, src, REG_ITMP1);
864 d = reg_of_var(iptr->dst, REG_ITMP3);
865 M_LSUB(REG_ZERO, s1, d);
866 store_reg_to_var_int(iptr->dst, d);
869 case ICMD_I2L: /* ..., value ==> ..., value */
871 var_to_reg_int(s1, src, REG_ITMP1);
872 d = reg_of_var(iptr->dst, REG_ITMP3);
874 store_reg_to_var_int(iptr->dst, d);
877 case ICMD_L2I: /* ..., value ==> ..., value */
879 var_to_reg_int(s1, src, REG_ITMP1);
880 d = reg_of_var(iptr->dst, REG_ITMP3);
881 M_IADD(s1, REG_ZERO, d );
882 store_reg_to_var_int(iptr->dst, d);
885 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
887 var_to_reg_int(s1, src, REG_ITMP1);
888 d = reg_of_var(iptr->dst, REG_ITMP3);
889 if (has_ext_instr_set) {
893 M_SLL_IMM(s1, 56, d);
894 M_SRA_IMM( d, 56, d);
896 store_reg_to_var_int(iptr->dst, d);
899 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
901 var_to_reg_int(s1, src, REG_ITMP1);
902 d = reg_of_var(iptr->dst, REG_ITMP3);
904 store_reg_to_var_int(iptr->dst, d);
907 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
909 var_to_reg_int(s1, src, REG_ITMP1);
910 d = reg_of_var(iptr->dst, REG_ITMP3);
911 if (has_ext_instr_set) {
915 M_SLL_IMM(s1, 48, d);
916 M_SRA_IMM( d, 48, d);
918 store_reg_to_var_int(iptr->dst, d);
922 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
924 var_to_reg_int(s1, src->prev, REG_ITMP1);
925 var_to_reg_int(s2, src, REG_ITMP2);
926 d = reg_of_var(iptr->dst, REG_ITMP3);
928 store_reg_to_var_int(iptr->dst, d);
931 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
932 /* val.i = constant */
934 var_to_reg_int(s1, src, REG_ITMP1);
935 d = reg_of_var(iptr->dst, REG_ITMP3);
936 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
937 M_IADD_IMM(s1, iptr->val.i, d);
940 ICONST(REG_ITMP2, iptr->val.i);
941 M_IADD(s1, REG_ITMP2, d);
943 store_reg_to_var_int(iptr->dst, d);
946 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
948 var_to_reg_int(s1, src->prev, REG_ITMP1);
949 var_to_reg_int(s2, src, REG_ITMP2);
950 d = reg_of_var(iptr->dst, REG_ITMP3);
952 store_reg_to_var_int(iptr->dst, d);
955 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
956 /* val.l = constant */
958 var_to_reg_int(s1, src, REG_ITMP1);
959 d = reg_of_var(iptr->dst, REG_ITMP3);
960 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
961 M_LADD_IMM(s1, iptr->val.l, d);
964 LCONST(REG_ITMP2, iptr->val.l);
965 M_LADD(s1, REG_ITMP2, d);
967 store_reg_to_var_int(iptr->dst, d);
970 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
972 var_to_reg_int(s1, src->prev, REG_ITMP1);
973 var_to_reg_int(s2, src, REG_ITMP2);
974 d = reg_of_var(iptr->dst, REG_ITMP3);
976 store_reg_to_var_int(iptr->dst, d);
979 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
980 /* val.i = constant */
982 var_to_reg_int(s1, src, REG_ITMP1);
983 d = reg_of_var(iptr->dst, REG_ITMP3);
984 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
985 M_ISUB_IMM(s1, iptr->val.i, d);
988 ICONST(REG_ITMP2, iptr->val.i);
989 M_ISUB(s1, REG_ITMP2, d);
991 store_reg_to_var_int(iptr->dst, d);
994 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
996 var_to_reg_int(s1, src->prev, REG_ITMP1);
997 var_to_reg_int(s2, src, REG_ITMP2);
998 d = reg_of_var(iptr->dst, REG_ITMP3);
1000 store_reg_to_var_int(iptr->dst, d);
1003 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
1004 /* val.l = constant */
1006 var_to_reg_int(s1, src, REG_ITMP1);
1007 d = reg_of_var(iptr->dst, REG_ITMP3);
1008 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1009 M_LSUB_IMM(s1, iptr->val.l, d);
1012 LCONST(REG_ITMP2, iptr->val.l);
1013 M_LSUB(s1, REG_ITMP2, d);
1015 store_reg_to_var_int(iptr->dst, d);
1018 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1020 var_to_reg_int(s1, src->prev, REG_ITMP1);
1021 var_to_reg_int(s2, src, REG_ITMP2);
1022 d = reg_of_var(iptr->dst, REG_ITMP3);
1024 store_reg_to_var_int(iptr->dst, d);
1027 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
1028 /* val.i = constant */
1030 var_to_reg_int(s1, src, REG_ITMP1);
1031 d = reg_of_var(iptr->dst, REG_ITMP3);
1032 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1033 M_IMUL_IMM(s1, iptr->val.i, d);
1036 ICONST(REG_ITMP2, iptr->val.i);
1037 M_IMUL(s1, REG_ITMP2, d);
1039 store_reg_to_var_int(iptr->dst, d);
1042 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1044 var_to_reg_int(s1, src->prev, REG_ITMP1);
1045 var_to_reg_int(s2, src, REG_ITMP2);
1046 d = reg_of_var(iptr->dst, REG_ITMP3);
1048 store_reg_to_var_int(iptr->dst, d);
1051 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
1052 /* val.l = constant */
1054 var_to_reg_int(s1, src, REG_ITMP1);
1055 d = reg_of_var(iptr->dst, REG_ITMP3);
1056 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1057 M_LMUL_IMM(s1, iptr->val.l, d);
1060 LCONST(REG_ITMP2, iptr->val.l);
1061 M_LMUL(s1, REG_ITMP2, d);
1063 store_reg_to_var_int(iptr->dst, d);
1066 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
1067 case ICMD_LDIVPOW2: /* val.i = constant */
1069 var_to_reg_int(s1, src, REG_ITMP1);
1070 d = reg_of_var(iptr->dst, REG_ITMP3);
1071 if (iptr->val.i <= 15) {
1072 M_LDA(REG_ITMP2, s1, (1 << iptr->val.i) -1);
1073 M_CMOVGE(s1, s1, REG_ITMP2);
1076 M_SRA_IMM(s1, 63, REG_ITMP2);
1077 M_SRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
1078 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1080 M_SRA_IMM(REG_ITMP2, iptr->val.i, d);
1081 store_reg_to_var_int(iptr->dst, d);
1084 case ICMD_ISHL: /* ..., 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);
1089 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1090 M_SLL(s1, REG_ITMP3, d);
1091 M_IADD(d, REG_ZERO, d);
1092 store_reg_to_var_int(iptr->dst, d);
1095 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1096 /* val.i = constant */
1098 var_to_reg_int(s1, src, REG_ITMP1);
1099 d = reg_of_var(iptr->dst, REG_ITMP3);
1100 M_SLL_IMM(s1, iptr->val.i & 0x1f, d);
1101 M_IADD(d, REG_ZERO, d);
1102 store_reg_to_var_int(iptr->dst, d);
1105 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1107 var_to_reg_int(s1, src->prev, REG_ITMP1);
1108 var_to_reg_int(s2, src, REG_ITMP2);
1109 d = reg_of_var(iptr->dst, REG_ITMP3);
1110 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1111 M_SRA(s1, REG_ITMP3, d);
1112 store_reg_to_var_int(iptr->dst, d);
1115 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1116 /* val.i = constant */
1118 var_to_reg_int(s1, src, REG_ITMP1);
1119 d = reg_of_var(iptr->dst, REG_ITMP3);
1120 M_SRA_IMM(s1, iptr->val.i & 0x1f, d);
1121 store_reg_to_var_int(iptr->dst, d);
1124 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1126 var_to_reg_int(s1, src->prev, REG_ITMP1);
1127 var_to_reg_int(s2, src, REG_ITMP2);
1128 d = reg_of_var(iptr->dst, REG_ITMP3);
1129 M_AND_IMM(s2, 0x1f, REG_ITMP2);
1131 M_SRL(d, REG_ITMP2, d);
1132 M_IADD(d, REG_ZERO, d);
1133 store_reg_to_var_int(iptr->dst, d);
1136 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1137 /* val.i = constant */
1139 var_to_reg_int(s1, src, REG_ITMP1);
1140 d = reg_of_var(iptr->dst, REG_ITMP3);
1142 M_SRL_IMM(d, iptr->val.i & 0x1f, d);
1143 M_IADD(d, REG_ZERO, d);
1144 store_reg_to_var_int(iptr->dst, d);
1147 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1149 var_to_reg_int(s1, src->prev, REG_ITMP1);
1150 var_to_reg_int(s2, src, REG_ITMP2);
1151 d = reg_of_var(iptr->dst, REG_ITMP3);
1153 store_reg_to_var_int(iptr->dst, d);
1156 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1157 /* val.l = constant */
1159 var_to_reg_int(s1, src, REG_ITMP1);
1160 d = reg_of_var(iptr->dst, REG_ITMP3);
1161 M_SLL_IMM(s1, iptr->val.l & 0x3f, d);
1162 store_reg_to_var_int(iptr->dst, d);
1165 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1167 var_to_reg_int(s1, src->prev, REG_ITMP1);
1168 var_to_reg_int(s2, src, REG_ITMP2);
1169 d = reg_of_var(iptr->dst, REG_ITMP3);
1171 store_reg_to_var_int(iptr->dst, d);
1174 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1175 /* val.l = constant */
1177 var_to_reg_int(s1, src, REG_ITMP1);
1178 d = reg_of_var(iptr->dst, REG_ITMP3);
1179 M_SRA_IMM(s1, iptr->val.l & 0x3f, d);
1180 store_reg_to_var_int(iptr->dst, d);
1183 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1185 var_to_reg_int(s1, src->prev, REG_ITMP1);
1186 var_to_reg_int(s2, src, REG_ITMP2);
1187 d = reg_of_var(iptr->dst, REG_ITMP3);
1189 store_reg_to_var_int(iptr->dst, d);
1192 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1193 /* val.l = constant */
1195 var_to_reg_int(s1, src, REG_ITMP1);
1196 d = reg_of_var(iptr->dst, REG_ITMP3);
1197 M_SRL_IMM(s1, iptr->val.l & 0x3f, d);
1198 store_reg_to_var_int(iptr->dst, d);
1201 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1204 var_to_reg_int(s1, src->prev, REG_ITMP1);
1205 var_to_reg_int(s2, src, REG_ITMP2);
1206 d = reg_of_var(iptr->dst, REG_ITMP3);
1208 store_reg_to_var_int(iptr->dst, d);
1211 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1212 /* val.i = constant */
1214 var_to_reg_int(s1, src, REG_ITMP1);
1215 d = reg_of_var(iptr->dst, REG_ITMP3);
1216 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1217 M_AND_IMM(s1, iptr->val.i, d);
1219 else if (iptr->val.i == 0xffff) {
1222 else if (iptr->val.i == 0xffffff) {
1223 M_ZAPNOT_IMM(s1, 0x07, d);
1226 ICONST(REG_ITMP2, iptr->val.i);
1227 M_AND(s1, REG_ITMP2, d);
1229 store_reg_to_var_int(iptr->dst, d);
1232 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1233 /* val.i = constant */
1235 var_to_reg_int(s1, src, REG_ITMP1);
1236 d = reg_of_var(iptr->dst, REG_ITMP3);
1238 M_MOV(s1, REG_ITMP1);
1241 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1242 M_AND_IMM(s1, iptr->val.i, d);
1244 M_ISUB(REG_ZERO, s1, d);
1245 M_AND_IMM(d, iptr->val.i, d);
1247 else if (iptr->val.i == 0xffff) {
1250 M_ISUB(REG_ZERO, s1, d);
1253 else if (iptr->val.i == 0xffffff) {
1254 M_ZAPNOT_IMM(s1, 0x07, d);
1256 M_ISUB(REG_ZERO, s1, d);
1257 M_ZAPNOT_IMM(d, 0x07, d);
1260 ICONST(REG_ITMP2, iptr->val.i);
1261 M_AND(s1, REG_ITMP2, d);
1263 M_ISUB(REG_ZERO, s1, d);
1264 M_AND(d, REG_ITMP2, d);
1266 M_ISUB(REG_ZERO, d, d);
1267 store_reg_to_var_int(iptr->dst, d);
1270 case ICMD_IREM0X10001: /* ..., value ==> ..., value % 0x100001 */
1272 /* b = value & 0xffff;
1274 a = ((b - a) & 0xffff) + (b < a);
1276 var_to_reg_int(s1, src, REG_ITMP1);
1277 d = reg_of_var(iptr->dst, REG_ITMP3);
1279 M_MOV(s1, REG_ITMP3);
1283 M_CZEXT(s1, REG_ITMP2);
1284 M_SRA_IMM(s1, 16, d);
1285 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1286 M_ISUB(REG_ITMP2, d, d);
1288 M_IADD(d, REG_ITMP1, d);
1289 M_BR(11 + (s1 == REG_ITMP1));
1290 M_ISUB(REG_ZERO, s1, REG_ITMP1);
1291 M_CZEXT(REG_ITMP1, REG_ITMP2);
1292 M_SRA_IMM(REG_ITMP1, 16, d);
1293 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1294 M_ISUB(REG_ITMP2, d, d);
1296 M_IADD(d, REG_ITMP1, d);
1297 M_ISUB(REG_ZERO, d, d);
1298 if (s1 == REG_ITMP1) {
1299 var_to_reg_int(s1, src, REG_ITMP1);
1301 M_SLL_IMM(s1, 33, REG_ITMP2);
1302 M_CMPEQ(REG_ITMP2, REG_ZERO, REG_ITMP2);
1303 M_ISUB(d, REG_ITMP2, d);
1304 store_reg_to_var_int(iptr->dst, d);
1307 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1308 /* val.l = constant */
1310 var_to_reg_int(s1, src, REG_ITMP1);
1311 d = reg_of_var(iptr->dst, REG_ITMP3);
1312 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1313 M_AND_IMM(s1, iptr->val.l, d);
1315 else if (iptr->val.l == 0xffffL) {
1318 else if (iptr->val.l == 0xffffffL) {
1319 M_ZAPNOT_IMM(s1, 0x07, d);
1321 else if (iptr->val.l == 0xffffffffL) {
1324 else if (iptr->val.l == 0xffffffffffL) {
1325 M_ZAPNOT_IMM(s1, 0x1f, d);
1327 else if (iptr->val.l == 0xffffffffffffL) {
1328 M_ZAPNOT_IMM(s1, 0x3f, d);
1330 else if (iptr->val.l == 0xffffffffffffffL) {
1331 M_ZAPNOT_IMM(s1, 0x7f, d);
1334 LCONST(REG_ITMP2, iptr->val.l);
1335 M_AND(s1, REG_ITMP2, d);
1337 store_reg_to_var_int(iptr->dst, d);
1340 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1341 /* val.l = constant */
1343 var_to_reg_int(s1, src, REG_ITMP1);
1344 d = reg_of_var(iptr->dst, REG_ITMP3);
1346 M_MOV(s1, REG_ITMP1);
1349 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1350 M_AND_IMM(s1, iptr->val.l, d);
1352 M_LSUB(REG_ZERO, s1, d);
1353 M_AND_IMM(d, iptr->val.l, d);
1355 else if (iptr->val.l == 0xffffL) {
1358 M_LSUB(REG_ZERO, s1, d);
1361 else if (iptr->val.l == 0xffffffL) {
1362 M_ZAPNOT_IMM(s1, 0x07, d);
1364 M_LSUB(REG_ZERO, s1, d);
1365 M_ZAPNOT_IMM(d, 0x07, d);
1367 else if (iptr->val.l == 0xffffffffL) {
1370 M_LSUB(REG_ZERO, s1, d);
1373 else if (iptr->val.l == 0xffffffffffL) {
1374 M_ZAPNOT_IMM(s1, 0x1f, d);
1376 M_LSUB(REG_ZERO, s1, d);
1377 M_ZAPNOT_IMM(d, 0x1f, d);
1379 else if (iptr->val.l == 0xffffffffffffL) {
1380 M_ZAPNOT_IMM(s1, 0x3f, d);
1382 M_LSUB(REG_ZERO, s1, d);
1383 M_ZAPNOT_IMM(d, 0x3f, d);
1385 else if (iptr->val.l == 0xffffffffffffffL) {
1386 M_ZAPNOT_IMM(s1, 0x7f, d);
1388 M_LSUB(REG_ZERO, s1, d);
1389 M_ZAPNOT_IMM(d, 0x7f, d);
1392 LCONST(REG_ITMP2, iptr->val.l);
1393 M_AND(s1, REG_ITMP2, d);
1395 M_LSUB(REG_ZERO, s1, d);
1396 M_AND(d, REG_ITMP2, d);
1398 M_LSUB(REG_ZERO, d, d);
1399 store_reg_to_var_int(iptr->dst, d);
1402 case ICMD_LREM0X10001:/* ..., value ==> ..., value % 0x10001 */
1404 var_to_reg_int(s1, src, REG_ITMP1);
1405 d = reg_of_var(iptr->dst, REG_ITMP3);
1407 M_MOV(s1, REG_ITMP3);
1410 M_CZEXT(s1, REG_ITMP2);
1411 M_SRA_IMM(s1, 16, d);
1412 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1413 M_LSUB(REG_ITMP2, d, d);
1415 M_LADD(d, REG_ITMP1, d);
1416 M_LDA(REG_ITMP2, REG_ZERO, -1);
1417 M_SRL_IMM(REG_ITMP2, 33, REG_ITMP2);
1418 if (s1 == REG_ITMP1) {
1419 var_to_reg_int(s1, src, REG_ITMP1);
1421 M_CMPULT(s1, REG_ITMP2, REG_ITMP2);
1422 M_BNEZ(REG_ITMP2, 11);
1423 M_LDA(d, REG_ZERO, -257);
1424 M_ZAPNOT_IMM(d, 0xcd, d);
1425 M_LSUB(REG_ZERO, s1, REG_ITMP2);
1426 M_CMOVGE(s1, s1, REG_ITMP2);
1427 M_UMULH(REG_ITMP2, d, REG_ITMP2);
1428 M_SRL_IMM(REG_ITMP2, 16, REG_ITMP2);
1429 M_LSUB(REG_ZERO, REG_ITMP2, d);
1430 M_CMOVGE(s1, REG_ITMP2, d);
1431 M_SLL_IMM(d, 16, REG_ITMP2);
1432 M_LADD(d, REG_ITMP2, d);
1434 store_reg_to_var_int(iptr->dst, d);
1437 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1440 var_to_reg_int(s1, src->prev, REG_ITMP1);
1441 var_to_reg_int(s2, src, REG_ITMP2);
1442 d = reg_of_var(iptr->dst, REG_ITMP3);
1444 store_reg_to_var_int(iptr->dst, d);
1447 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1448 /* val.i = constant */
1450 var_to_reg_int(s1, src, REG_ITMP1);
1451 d = reg_of_var(iptr->dst, REG_ITMP3);
1452 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1453 M_OR_IMM(s1, iptr->val.i, d);
1456 ICONST(REG_ITMP2, iptr->val.i);
1457 M_OR(s1, REG_ITMP2, d);
1459 store_reg_to_var_int(iptr->dst, d);
1462 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1463 /* val.l = constant */
1465 var_to_reg_int(s1, src, REG_ITMP1);
1466 d = reg_of_var(iptr->dst, REG_ITMP3);
1467 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1468 M_OR_IMM(s1, iptr->val.l, d);
1471 LCONST(REG_ITMP2, iptr->val.l);
1472 M_OR(s1, REG_ITMP2, d);
1474 store_reg_to_var_int(iptr->dst, d);
1477 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1480 var_to_reg_int(s1, src->prev, REG_ITMP1);
1481 var_to_reg_int(s2, src, REG_ITMP2);
1482 d = reg_of_var(iptr->dst, REG_ITMP3);
1484 store_reg_to_var_int(iptr->dst, d);
1487 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1488 /* val.i = constant */
1490 var_to_reg_int(s1, src, REG_ITMP1);
1491 d = reg_of_var(iptr->dst, REG_ITMP3);
1492 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1493 M_XOR_IMM(s1, iptr->val.i, d);
1496 ICONST(REG_ITMP2, iptr->val.i);
1497 M_XOR(s1, REG_ITMP2, d);
1499 store_reg_to_var_int(iptr->dst, d);
1502 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1503 /* val.l = constant */
1505 var_to_reg_int(s1, src, REG_ITMP1);
1506 d = reg_of_var(iptr->dst, REG_ITMP3);
1507 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1508 M_XOR_IMM(s1, iptr->val.l, d);
1511 LCONST(REG_ITMP2, iptr->val.l);
1512 M_XOR(s1, REG_ITMP2, d);
1514 store_reg_to_var_int(iptr->dst, d);
1518 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1520 var_to_reg_int(s1, src->prev, REG_ITMP1);
1521 var_to_reg_int(s2, src, REG_ITMP2);
1522 d = reg_of_var(iptr->dst, REG_ITMP3);
1523 M_CMPLT(s1, s2, REG_ITMP3);
1524 M_CMPLT(s2, s1, REG_ITMP1);
1525 M_LSUB (REG_ITMP1, REG_ITMP3, d);
1526 store_reg_to_var_int(iptr->dst, d);
1530 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1531 /* op1 = variable, val.i = constant */
1533 var = &(locals[iptr->op1][TYPE_INT]);
1534 if (var->flags & INMEMORY) {
1536 M_LLD(s1, REG_SP, 8 * var->regoff);
1540 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1541 M_IADD_IMM(s1, iptr->val.i, s1);
1543 else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1544 M_ISUB_IMM(s1, (-iptr->val.i), s1);
1547 M_LDA (s1, s1, iptr->val.i);
1548 M_IADD(s1, REG_ZERO, s1);
1550 if (var->flags & INMEMORY)
1551 M_LST(s1, REG_SP, 8 * var->regoff);
1555 /* floating operations ************************************************/
1557 case ICMD_FNEG: /* ..., value ==> ..., - value */
1559 var_to_reg_flt(s1, src, REG_FTMP1);
1560 d = reg_of_var(iptr->dst, REG_FTMP3);
1562 store_reg_to_var_flt(iptr->dst, d);
1565 case ICMD_DNEG: /* ..., value ==> ..., - value */
1567 var_to_reg_flt(s1, src, REG_FTMP1);
1568 d = reg_of_var(iptr->dst, REG_FTMP3);
1570 store_reg_to_var_flt(iptr->dst, d);
1573 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1575 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1576 var_to_reg_flt(s2, src, REG_FTMP2);
1577 d = reg_of_var(iptr->dst, REG_FTMP3);
1585 store_reg_to_var_flt(iptr->dst, d);
1588 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1590 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1591 var_to_reg_flt(s2, src, REG_FTMP2);
1592 d = reg_of_var(iptr->dst, REG_FTMP3);
1600 store_reg_to_var_flt(iptr->dst, d);
1603 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1605 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1606 var_to_reg_flt(s2, src, REG_FTMP2);
1607 d = reg_of_var(iptr->dst, REG_FTMP3);
1615 store_reg_to_var_flt(iptr->dst, d);
1618 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1620 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1621 var_to_reg_flt(s2, src, REG_FTMP2);
1622 d = reg_of_var(iptr->dst, REG_FTMP3);
1630 store_reg_to_var_flt(iptr->dst, d);
1633 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1635 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1636 var_to_reg_flt(s2, src, REG_FTMP2);
1637 d = reg_of_var(iptr->dst, REG_FTMP3);
1645 store_reg_to_var_flt(iptr->dst, d);
1648 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1650 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1651 var_to_reg_flt(s2, src, REG_FTMP2);
1652 d = reg_of_var(iptr->dst, REG_FTMP3);
1660 store_reg_to_var_flt(iptr->dst, d);
1663 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1665 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1666 var_to_reg_flt(s2, src, REG_FTMP2);
1667 d = reg_of_var(iptr->dst, REG_FTMP3);
1675 store_reg_to_var_flt(iptr->dst, d);
1678 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1680 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1681 var_to_reg_flt(s2, src, REG_FTMP2);
1682 d = reg_of_var(iptr->dst, REG_FTMP3);
1690 store_reg_to_var_flt(iptr->dst, d);
1693 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1695 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1696 var_to_reg_flt(s2, src, REG_FTMP2);
1697 d = reg_of_var(iptr->dst, REG_FTMP3);
1699 M_FDIVS(s1,s2, REG_FTMP3);
1701 M_CVTDL_CS(REG_FTMP3, REG_FTMP3); /* round to integer */
1703 M_CVTLF(REG_FTMP3, REG_FTMP3);
1704 M_FMULS(REG_FTMP3, s2, REG_FTMP3);
1706 M_FSUBS(s1, REG_FTMP3, d);
1710 M_FDIV(s1,s2, REG_FTMP3);
1711 M_CVTDL_C(REG_FTMP3, REG_FTMP3); /* round to integer */
1712 M_CVTLF(REG_FTMP3, REG_FTMP3);
1713 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1714 M_FSUB(s1, REG_FTMP3, d);
1716 store_reg_to_var_flt(iptr->dst, d);
1719 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1721 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1722 var_to_reg_flt(s2, src, REG_FTMP2);
1723 d = reg_of_var(iptr->dst, REG_FTMP3);
1725 M_DDIVS(s1,s2, REG_FTMP3);
1727 M_CVTDL_CS(REG_FTMP3, REG_FTMP3); /* round to integer */
1729 M_CVTLD(REG_FTMP3, REG_FTMP3);
1730 M_DMULS(REG_FTMP3, s2, REG_FTMP3);
1732 M_DSUBS(s1, REG_FTMP3, d);
1736 M_DDIV(s1,s2, REG_FTMP3);
1737 M_CVTDL_C(REG_FTMP3, REG_FTMP3); /* round to integer */
1738 M_CVTLD(REG_FTMP3, REG_FTMP3);
1739 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1740 M_DSUB(s1, REG_FTMP3, d);
1742 store_reg_to_var_flt(iptr->dst, d);
1745 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1747 var_to_reg_int(s1, src, REG_ITMP1);
1748 d = reg_of_var(iptr->dst, REG_FTMP3);
1749 a = dseg_adddouble(0.0);
1750 M_LST (s1, REG_PV, a);
1751 M_DLD (d, REG_PV, a);
1753 store_reg_to_var_flt(iptr->dst, d);
1756 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1758 var_to_reg_int(s1, src, REG_ITMP1);
1759 d = reg_of_var(iptr->dst, REG_FTMP3);
1760 a = dseg_adddouble(0.0);
1761 M_LST (s1, REG_PV, a);
1762 M_DLD (d, REG_PV, a);
1764 store_reg_to_var_flt(iptr->dst, d);
1767 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1769 var_to_reg_flt(s1, src, REG_FTMP1);
1770 d = reg_of_var(iptr->dst, REG_ITMP3);
1771 a = dseg_adddouble(0.0);
1773 M_CVTDL_CS(s1, REG_FTMP1);
1775 M_CVTLIS(REG_FTMP1, REG_FTMP2);
1779 M_CVTDL_C(s1, REG_FTMP1);
1780 M_CVTLI(REG_FTMP1, REG_FTMP2);
1782 M_DST (REG_FTMP1, REG_PV, a);
1783 M_ILD (d, REG_PV, a);
1784 store_reg_to_var_int(iptr->dst, d);
1787 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1789 var_to_reg_flt(s1, src, REG_FTMP1);
1790 d = reg_of_var(iptr->dst, REG_ITMP3);
1791 a = dseg_adddouble(0.0);
1793 M_CVTDL_CS(s1, REG_FTMP1);
1797 M_CVTDL_C(s1, REG_FTMP1);
1799 M_DST (REG_FTMP1, REG_PV, a);
1800 M_LLD (d, REG_PV, a);
1801 store_reg_to_var_int(iptr->dst, d);
1804 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1806 var_to_reg_flt(s1, src, REG_FTMP1);
1807 d = reg_of_var(iptr->dst, REG_FTMP3);
1809 store_reg_to_var_flt(iptr->dst, d);
1812 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1814 var_to_reg_flt(s1, src, REG_FTMP1);
1815 d = reg_of_var(iptr->dst, REG_FTMP3);
1823 store_reg_to_var_flt(iptr->dst, d);
1826 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1828 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1829 var_to_reg_flt(s2, src, REG_FTMP2);
1830 d = reg_of_var(iptr->dst, REG_ITMP3);
1832 M_LSUB_IMM(REG_ZERO, 1, d);
1833 M_FCMPEQS(s1, s2, REG_FTMP3);
1835 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1837 M_FCMPLTS(s2, s1, REG_FTMP3);
1839 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1840 M_LADD_IMM(REG_ZERO, 1, d);
1843 M_LSUB_IMM(REG_ZERO, 1, d);
1844 M_FCMPEQ(s1, s2, REG_FTMP3);
1845 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1847 M_FCMPLT(s2, s1, REG_FTMP3);
1848 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1849 M_LADD_IMM(REG_ZERO, 1, d);
1851 store_reg_to_var_int(iptr->dst, d);
1854 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1856 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1857 var_to_reg_flt(s2, src, REG_FTMP2);
1858 d = reg_of_var(iptr->dst, REG_ITMP3);
1860 M_LADD_IMM(REG_ZERO, 1, d);
1861 M_FCMPEQS(s1, s2, REG_FTMP3);
1863 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1865 M_FCMPLTS(s1, s2, REG_FTMP3);
1867 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1868 M_LSUB_IMM(REG_ZERO, 1, d);
1871 M_LADD_IMM(REG_ZERO, 1, d);
1872 M_FCMPEQ(s1, s2, REG_FTMP3);
1873 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1875 M_FCMPLT(s1, s2, REG_FTMP3);
1876 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1877 M_LSUB_IMM(REG_ZERO, 1, d);
1879 store_reg_to_var_int(iptr->dst, d);
1883 /* memory operations **************************************************/
1885 /* #define gen_bound_check \
1887 M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\
1888 M_CMPULT(s2, REG_ITMP3, REG_ITMP3);\
1889 M_BEQZ(REG_ITMP3, 0);\
1890 mcode_addxboundrefs(mcodeptr);\
1894 #define gen_bound_check \
1895 if (checkbounds) { \
1896 M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\
1897 M_CMPULT(s2, REG_ITMP3, REG_ITMP3);\
1898 M_BEQZ(REG_ITMP3, 0);\
1899 mcode_addxboundrefs(mcodeptr); \
1902 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1904 var_to_reg_int(s1, src, REG_ITMP1);
1905 d = reg_of_var(iptr->dst, REG_ITMP3);
1906 gen_nullptr_check(s1);
1907 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1908 store_reg_to_var_int(iptr->dst, d);
1911 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1913 var_to_reg_int(s1, src->prev, REG_ITMP1);
1914 var_to_reg_int(s2, src, REG_ITMP2);
1915 d = reg_of_var(iptr->dst, REG_ITMP3);
1916 if (iptr->op1 == 0) {
1917 gen_nullptr_check(s1);
1920 M_SAADDQ(s2, s1, REG_ITMP1);
1921 M_ALD( d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1922 store_reg_to_var_int(iptr->dst, d);
1925 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1927 var_to_reg_int(s1, src->prev, REG_ITMP1);
1928 var_to_reg_int(s2, src, REG_ITMP2);
1929 d = reg_of_var(iptr->dst, REG_ITMP3);
1930 if (iptr->op1 == 0) {
1931 gen_nullptr_check(s1);
1934 M_S8ADDQ(s2, s1, REG_ITMP1);
1935 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1936 store_reg_to_var_int(iptr->dst, d);
1939 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1941 var_to_reg_int(s1, src->prev, REG_ITMP1);
1942 var_to_reg_int(s2, src, REG_ITMP2);
1943 d = reg_of_var(iptr->dst, REG_ITMP3);
1944 if (iptr->op1 == 0) {
1945 gen_nullptr_check(s1);
1949 M_S4ADDQ(s2, s1, REG_ITMP1);
1950 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1951 store_reg_to_var_int(iptr->dst, d);
1954 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1956 var_to_reg_int(s1, src->prev, REG_ITMP1);
1957 var_to_reg_int(s2, src, REG_ITMP2);
1958 d = reg_of_var(iptr->dst, REG_FTMP3);
1959 if (iptr->op1 == 0) {
1960 gen_nullptr_check(s1);
1963 M_S4ADDQ(s2, s1, REG_ITMP1);
1964 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1965 store_reg_to_var_flt(iptr->dst, d);
1968 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1970 var_to_reg_int(s1, src->prev, REG_ITMP1);
1971 var_to_reg_int(s2, src, REG_ITMP2);
1972 d = reg_of_var(iptr->dst, REG_FTMP3);
1973 if (iptr->op1 == 0) {
1974 gen_nullptr_check(s1);
1977 M_S8ADDQ(s2, s1, REG_ITMP1);
1978 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1979 store_reg_to_var_flt(iptr->dst, d);
1982 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1984 var_to_reg_int(s1, src->prev, REG_ITMP1);
1985 var_to_reg_int(s2, src, REG_ITMP2);
1986 d = reg_of_var(iptr->dst, REG_ITMP3);
1987 if (iptr->op1 == 0) {
1988 gen_nullptr_check(s1);
1991 if (has_ext_instr_set) {
1992 M_LADD(s2, s1, REG_ITMP1);
1993 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1994 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1997 M_LADD (s2, s1, REG_ITMP1);
1998 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1999 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2000 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2001 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
2003 store_reg_to_var_int(iptr->dst, d);
2006 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
2008 var_to_reg_int(s1, src->prev, REG_ITMP1);
2009 var_to_reg_int(s2, src, REG_ITMP2);
2010 d = reg_of_var(iptr->dst, REG_ITMP3);
2011 if (iptr->op1 == 0) {
2012 gen_nullptr_check(s1);
2015 if (has_ext_instr_set) {
2016 M_LADD(s2, s1, REG_ITMP1);
2017 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2018 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
2022 M_LADD(s2, s1, REG_ITMP1);
2023 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2024 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2025 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
2026 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
2027 M_SRA_IMM(d, 48, d);
2029 store_reg_to_var_int(iptr->dst, d);
2032 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
2034 var_to_reg_int(s1, src->prev, REG_ITMP1);
2035 var_to_reg_int(s2, src, REG_ITMP2);
2036 d = reg_of_var(iptr->dst, REG_ITMP3);
2037 if (iptr->op1 == 0) {
2038 gen_nullptr_check(s1);
2041 if (has_ext_instr_set) {
2042 M_LADD (s2, s1, REG_ITMP1);
2043 M_BLDU (d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
2047 M_LADD(s2, s1, REG_ITMP1);
2048 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2049 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
2050 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
2051 M_SRA_IMM(d, 56, d);
2053 store_reg_to_var_int(iptr->dst, d);
2057 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
2059 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2060 var_to_reg_int(s2, src->prev, REG_ITMP2);
2061 if (iptr->op1 == 0) {
2062 gen_nullptr_check(s1);
2065 var_to_reg_int(s3, src, REG_ITMP3);
2066 M_SAADDQ(s2, s1, REG_ITMP1);
2067 M_AST (s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
2070 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
2072 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2073 var_to_reg_int(s2, src->prev, REG_ITMP2);
2074 if (iptr->op1 == 0) {
2075 gen_nullptr_check(s1);
2078 var_to_reg_int(s3, src, REG_ITMP3);
2079 M_S8ADDQ(s2, s1, REG_ITMP1);
2080 M_LST (s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
2083 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
2085 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2086 var_to_reg_int(s2, src->prev, REG_ITMP2);
2087 if (iptr->op1 == 0) {
2088 gen_nullptr_check(s1);
2092 var_to_reg_int(s3, src, REG_ITMP3);
2093 M_S4ADDQ(s2, s1, REG_ITMP1);
2094 M_IST (s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
2097 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
2099 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2100 var_to_reg_int(s2, src->prev, REG_ITMP2);
2101 if (iptr->op1 == 0) {
2102 gen_nullptr_check(s1);
2105 var_to_reg_flt(s3, src, REG_FTMP3);
2106 M_S4ADDQ(s2, s1, REG_ITMP1);
2107 M_FST (s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
2110 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
2112 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2113 var_to_reg_int(s2, src->prev, REG_ITMP2);
2114 if (iptr->op1 == 0) {
2115 gen_nullptr_check(s1);
2118 var_to_reg_flt(s3, src, REG_FTMP3);
2119 M_S8ADDQ(s2, s1, REG_ITMP1);
2120 M_DST (s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
2123 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
2125 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2126 var_to_reg_int(s2, src->prev, REG_ITMP2);
2127 if (iptr->op1 == 0) {
2128 gen_nullptr_check(s1);
2131 var_to_reg_int(s3, src, REG_ITMP3);
2132 if (has_ext_instr_set) {
2133 M_LADD(s2, s1, REG_ITMP1);
2134 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2135 M_SST (s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
2138 M_LADD (s2, s1, REG_ITMP1);
2139 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2140 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2141 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2142 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
2143 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2144 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2145 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2149 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
2151 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2152 var_to_reg_int(s2, src->prev, REG_ITMP2);
2153 if (iptr->op1 == 0) {
2154 gen_nullptr_check(s1);
2157 var_to_reg_int(s3, src, REG_ITMP3);
2158 if (has_ext_instr_set) {
2159 M_LADD(s2, s1, REG_ITMP1);
2160 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2161 M_SST (s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2164 M_LADD (s2, s1, REG_ITMP1);
2165 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2166 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2167 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2168 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
2169 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2170 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2171 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2175 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
2177 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2178 var_to_reg_int(s2, src->prev, REG_ITMP2);
2179 if (iptr->op1 == 0) {
2180 gen_nullptr_check(s1);
2183 var_to_reg_int(s3, src, REG_ITMP3);
2184 if (has_ext_instr_set) {
2185 M_LADD(s2, s1, REG_ITMP1);
2186 M_BST (s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2189 M_LADD (s2, s1, REG_ITMP1);
2190 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2191 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2192 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
2193 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2194 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2195 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2200 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2201 /* op1 = type, val.a = field address */
2203 a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value));
2204 M_ALD(REG_ITMP1, REG_PV, a);
2205 switch (iptr->op1) {
2207 var_to_reg_int(s2, src, REG_ITMP2);
2208 M_IST(s2, REG_ITMP1, 0);
2211 var_to_reg_int(s2, src, REG_ITMP2);
2212 M_LST(s2, REG_ITMP1, 0);
2215 var_to_reg_int(s2, src, REG_ITMP2);
2216 M_AST(s2, REG_ITMP1, 0);
2219 var_to_reg_flt(s2, src, REG_FTMP2);
2220 M_FST(s2, REG_ITMP1, 0);
2223 var_to_reg_flt(s2, src, REG_FTMP2);
2224 M_DST(s2, REG_ITMP1, 0);
2226 default: panic ("internal error");
2230 case ICMD_GETSTATIC: /* ... ==> ..., value */
2231 /* op1 = type, val.a = field address */
2233 a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value));
2234 M_ALD(REG_ITMP1, REG_PV, a);
2235 switch (iptr->op1) {
2237 d = reg_of_var(iptr->dst, REG_ITMP3);
2238 M_ILD(d, REG_ITMP1, 0);
2239 store_reg_to_var_int(iptr->dst, d);
2242 d = reg_of_var(iptr->dst, REG_ITMP3);
2243 M_LLD(d, REG_ITMP1, 0);
2244 store_reg_to_var_int(iptr->dst, d);
2247 d = reg_of_var(iptr->dst, REG_ITMP3);
2248 M_ALD(d, REG_ITMP1, 0);
2249 store_reg_to_var_int(iptr->dst, d);
2252 d = reg_of_var(iptr->dst, REG_FTMP1);
2253 M_FLD(d, REG_ITMP1, 0);
2254 store_reg_to_var_flt(iptr->dst, d);
2257 d = reg_of_var(iptr->dst, REG_FTMP1);
2258 M_DLD(d, REG_ITMP1, 0);
2259 store_reg_to_var_flt(iptr->dst, d);
2261 default: panic ("internal error");
2266 case ICMD_PUTFIELD: /* ..., value ==> ... */
2267 /* op1 = type, val.i = field offset */
2269 a = ((fieldinfo *)(iptr->val.a))->offset;
2270 switch (iptr->op1) {
2272 var_to_reg_int(s1, src->prev, REG_ITMP1);
2273 var_to_reg_int(s2, src, REG_ITMP2);
2274 gen_nullptr_check(s1);
2278 var_to_reg_int(s1, src->prev, REG_ITMP1);
2279 var_to_reg_int(s2, src, REG_ITMP2);
2280 gen_nullptr_check(s1);
2284 var_to_reg_int(s1, src->prev, REG_ITMP1);
2285 var_to_reg_int(s2, src, REG_ITMP2);
2286 gen_nullptr_check(s1);
2290 var_to_reg_int(s1, src->prev, REG_ITMP1);
2291 var_to_reg_flt(s2, src, REG_FTMP2);
2292 gen_nullptr_check(s1);
2296 var_to_reg_int(s1, src->prev, REG_ITMP1);
2297 var_to_reg_flt(s2, src, REG_FTMP2);
2298 gen_nullptr_check(s1);
2301 default: panic ("internal error");
2305 case ICMD_GETFIELD: /* ... ==> ..., value */
2306 /* op1 = type, val.i = field offset */
2308 a = ((fieldinfo *)(iptr->val.a))->offset;
2309 switch (iptr->op1) {
2311 var_to_reg_int(s1, src, REG_ITMP1);
2312 d = reg_of_var(iptr->dst, REG_ITMP3);
2313 gen_nullptr_check(s1);
2315 store_reg_to_var_int(iptr->dst, d);
2318 var_to_reg_int(s1, src, REG_ITMP1);
2319 d = reg_of_var(iptr->dst, REG_ITMP3);
2320 gen_nullptr_check(s1);
2322 store_reg_to_var_int(iptr->dst, d);
2325 var_to_reg_int(s1, src, REG_ITMP1);
2326 d = reg_of_var(iptr->dst, REG_ITMP3);
2327 gen_nullptr_check(s1);
2329 store_reg_to_var_int(iptr->dst, d);
2332 var_to_reg_int(s1, src, REG_ITMP1);
2333 d = reg_of_var(iptr->dst, REG_FTMP1);
2334 gen_nullptr_check(s1);
2336 store_reg_to_var_flt(iptr->dst, d);
2339 var_to_reg_int(s1, src, REG_ITMP1);
2340 d = reg_of_var(iptr->dst, REG_FTMP1);
2341 gen_nullptr_check(s1);
2343 store_reg_to_var_flt(iptr->dst, d);
2345 default: panic ("internal error");
2350 /* branch operations **************************************************/
2352 #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}}
2354 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2356 var_to_reg_int(s1, src, REG_ITMP1);
2357 M_INTMOVE(s1, REG_ITMP1_XPTR);
2358 a = dseg_addaddress(asm_handle_exception);
2359 M_ALD(REG_ITMP2, REG_PV, a);
2360 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2364 case ICMD_GOTO: /* ... ==> ... */
2365 /* op1 = target JavaVM pc */
2367 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2371 case ICMD_JSR: /* ... ==> ... */
2372 /* op1 = target JavaVM pc */
2374 M_BSR(REG_ITMP1, 0);
2375 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2378 case ICMD_RET: /* ... ==> ... */
2379 /* op1 = local variable */
2381 var = &(locals[iptr->op1][TYPE_ADR]);
2382 if (var->flags & INMEMORY) {
2383 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2384 M_RET(REG_ZERO, REG_ITMP1);
2387 M_RET(REG_ZERO, var->regoff);
2391 case ICMD_IFNULL: /* ..., value ==> ... */
2392 /* op1 = target JavaVM pc */
2394 var_to_reg_int(s1, src, REG_ITMP1);
2396 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2399 case ICMD_IFNONNULL: /* ..., value ==> ... */
2400 /* op1 = target JavaVM pc */
2402 var_to_reg_int(s1, src, REG_ITMP1);
2404 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2407 case ICMD_IFEQ: /* ..., value ==> ... */
2408 /* op1 = target JavaVM pc, val.i = constant */
2410 var_to_reg_int(s1, src, REG_ITMP1);
2411 if (iptr->val.i == 0) {
2415 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2416 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2419 ICONST(REG_ITMP2, iptr->val.i);
2420 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2422 M_BNEZ(REG_ITMP1, 0);
2424 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2427 case ICMD_IFLT: /* ..., value ==> ... */
2428 /* op1 = target JavaVM pc, val.i = constant */
2430 var_to_reg_int(s1, src, REG_ITMP1);
2431 if (iptr->val.i == 0) {
2435 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2436 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2439 ICONST(REG_ITMP2, iptr->val.i);
2440 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2442 M_BNEZ(REG_ITMP1, 0);
2444 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2447 case ICMD_IFLE: /* ..., value ==> ... */
2448 /* op1 = target JavaVM pc, val.i = constant */
2450 var_to_reg_int(s1, src, REG_ITMP1);
2451 if (iptr->val.i == 0) {
2455 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2456 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2459 ICONST(REG_ITMP2, iptr->val.i);
2460 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2462 M_BNEZ(REG_ITMP1, 0);
2464 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2467 case ICMD_IFNE: /* ..., value ==> ... */
2468 /* op1 = target JavaVM pc, val.i = constant */
2470 var_to_reg_int(s1, src, REG_ITMP1);
2471 if (iptr->val.i == 0) {
2475 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2476 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2479 ICONST(REG_ITMP2, iptr->val.i);
2480 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2482 M_BEQZ(REG_ITMP1, 0);
2484 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2487 case ICMD_IFGT: /* ..., value ==> ... */
2488 /* op1 = target JavaVM pc, val.i = constant */
2490 var_to_reg_int(s1, src, REG_ITMP1);
2491 if (iptr->val.i == 0) {
2495 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2496 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2499 ICONST(REG_ITMP2, iptr->val.i);
2500 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2502 M_BEQZ(REG_ITMP1, 0);
2504 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2507 case ICMD_IFGE: /* ..., value ==> ... */
2508 /* op1 = target JavaVM pc, val.i = constant */
2510 var_to_reg_int(s1, src, REG_ITMP1);
2511 if (iptr->val.i == 0) {
2515 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2516 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2519 ICONST(REG_ITMP2, iptr->val.i);
2520 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2522 M_BEQZ(REG_ITMP1, 0);
2524 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2527 case ICMD_IF_LEQ: /* ..., value ==> ... */
2528 /* op1 = target JavaVM pc, val.l = constant */
2530 var_to_reg_int(s1, src, REG_ITMP1);
2531 if (iptr->val.l == 0) {
2535 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2536 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2539 LCONST(REG_ITMP2, iptr->val.l);
2540 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2542 M_BNEZ(REG_ITMP1, 0);
2544 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2547 case ICMD_IF_LLT: /* ..., value ==> ... */
2548 /* op1 = target JavaVM pc, val.l = constant */
2550 var_to_reg_int(s1, src, REG_ITMP1);
2551 if (iptr->val.l == 0) {
2555 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2556 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2559 LCONST(REG_ITMP2, iptr->val.l);
2560 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2562 M_BNEZ(REG_ITMP1, 0);
2564 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2567 case ICMD_IF_LLE: /* ..., value ==> ... */
2568 /* op1 = target JavaVM pc, val.l = constant */
2570 var_to_reg_int(s1, src, REG_ITMP1);
2571 if (iptr->val.l == 0) {
2575 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2576 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2579 LCONST(REG_ITMP2, iptr->val.l);
2580 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2582 M_BNEZ(REG_ITMP1, 0);
2584 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2587 case ICMD_IF_LNE: /* ..., value ==> ... */
2588 /* op1 = target JavaVM pc, val.l = constant */
2590 var_to_reg_int(s1, src, REG_ITMP1);
2591 if (iptr->val.l == 0) {
2595 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2596 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2599 LCONST(REG_ITMP2, iptr->val.l);
2600 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2602 M_BEQZ(REG_ITMP1, 0);
2604 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2607 case ICMD_IF_LGT: /* ..., value ==> ... */
2608 /* op1 = target JavaVM pc, val.l = constant */
2610 var_to_reg_int(s1, src, REG_ITMP1);
2611 if (iptr->val.l == 0) {
2615 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2616 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2619 LCONST(REG_ITMP2, iptr->val.l);
2620 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2622 M_BEQZ(REG_ITMP1, 0);
2624 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2627 case ICMD_IF_LGE: /* ..., value ==> ... */
2628 /* op1 = target JavaVM pc, val.l = constant */
2630 var_to_reg_int(s1, src, REG_ITMP1);
2631 if (iptr->val.l == 0) {
2635 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2636 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2639 LCONST(REG_ITMP2, iptr->val.l);
2640 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2642 M_BEQZ(REG_ITMP1, 0);
2644 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2647 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2648 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2649 case ICMD_IF_ACMPEQ:
2651 var_to_reg_int(s1, src->prev, REG_ITMP1);
2652 var_to_reg_int(s2, src, REG_ITMP2);
2653 M_CMPEQ(s1, s2, REG_ITMP1);
2654 M_BNEZ(REG_ITMP1, 0);
2655 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2658 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2659 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2660 case ICMD_IF_ACMPNE:
2662 var_to_reg_int(s1, src->prev, REG_ITMP1);
2663 var_to_reg_int(s2, src, REG_ITMP2);
2664 M_CMPEQ(s1, s2, REG_ITMP1);
2665 M_BEQZ(REG_ITMP1, 0);
2666 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2669 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2670 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2672 var_to_reg_int(s1, src->prev, REG_ITMP1);
2673 var_to_reg_int(s2, src, REG_ITMP2);
2674 M_CMPLT(s1, s2, REG_ITMP1);
2675 M_BNEZ(REG_ITMP1, 0);
2676 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2679 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2680 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2682 var_to_reg_int(s1, src->prev, REG_ITMP1);
2683 var_to_reg_int(s2, src, REG_ITMP2);
2684 M_CMPLE(s1, s2, REG_ITMP1);
2685 M_BEQZ(REG_ITMP1, 0);
2686 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2689 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2690 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2692 var_to_reg_int(s1, src->prev, REG_ITMP1);
2693 var_to_reg_int(s2, src, REG_ITMP2);
2694 M_CMPLE(s1, s2, REG_ITMP1);
2695 M_BNEZ(REG_ITMP1, 0);
2696 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2699 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2700 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2702 var_to_reg_int(s1, src->prev, REG_ITMP1);
2703 var_to_reg_int(s2, src, REG_ITMP2);
2704 M_CMPLT(s1, s2, REG_ITMP1);
2705 M_BEQZ(REG_ITMP1, 0);
2706 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2709 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2711 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2714 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2715 /* val.i = constant */
2717 var_to_reg_int(s1, src, REG_ITMP1);
2718 d = reg_of_var(iptr->dst, REG_ITMP3);
2720 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2721 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2722 M_CMPEQ(s1, REG_ZERO, d);
2723 store_reg_to_var_int(iptr->dst, d);
2726 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2727 M_CMPEQ(s1, REG_ZERO, d);
2729 store_reg_to_var_int(iptr->dst, d);
2733 M_MOV(s1, REG_ITMP1);
2736 ICONST(d, iptr[1].val.i);
2738 if ((s3 >= 0) && (s3 <= 255)) {
2739 M_CMOVEQ_IMM(s1, s3, d);
2742 ICONST(REG_ITMP2, s3);
2743 M_CMOVEQ(s1, REG_ITMP2, d);
2745 store_reg_to_var_int(iptr->dst, d);
2748 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2749 /* val.i = constant */
2751 var_to_reg_int(s1, src, REG_ITMP1);
2752 d = reg_of_var(iptr->dst, REG_ITMP3);
2754 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2755 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2756 M_CMPEQ(s1, REG_ZERO, d);
2757 store_reg_to_var_int(iptr->dst, d);
2760 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2761 M_CMPEQ(s1, REG_ZERO, d);
2763 store_reg_to_var_int(iptr->dst, d);
2767 M_MOV(s1, REG_ITMP1);
2770 ICONST(d, iptr[1].val.i);
2772 if ((s3 >= 0) && (s3 <= 255)) {
2773 M_CMOVNE_IMM(s1, s3, d);
2776 ICONST(REG_ITMP2, s3);
2777 M_CMOVNE(s1, REG_ITMP2, d);
2779 store_reg_to_var_int(iptr->dst, d);
2782 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2783 /* val.i = constant */
2785 var_to_reg_int(s1, src, REG_ITMP1);
2786 d = reg_of_var(iptr->dst, REG_ITMP3);
2788 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2789 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2790 M_CMPLT(s1, REG_ZERO, d);
2791 store_reg_to_var_int(iptr->dst, d);
2794 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2795 M_CMPLE(REG_ZERO, s1, d);
2796 store_reg_to_var_int(iptr->dst, d);
2800 M_MOV(s1, REG_ITMP1);
2803 ICONST(d, iptr[1].val.i);
2805 if ((s3 >= 0) && (s3 <= 255)) {
2806 M_CMOVLT_IMM(s1, s3, d);
2809 ICONST(REG_ITMP2, s3);
2810 M_CMOVLT(s1, REG_ITMP2, d);
2812 store_reg_to_var_int(iptr->dst, d);
2815 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2816 /* val.i = constant */
2818 var_to_reg_int(s1, src, REG_ITMP1);
2819 d = reg_of_var(iptr->dst, REG_ITMP3);
2821 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2822 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2823 M_CMPLE(REG_ZERO, s1, d);
2824 store_reg_to_var_int(iptr->dst, d);
2827 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2828 M_CMPLT(s1, REG_ZERO, d);
2829 store_reg_to_var_int(iptr->dst, d);
2833 M_MOV(s1, REG_ITMP1);
2836 ICONST(d, iptr[1].val.i);
2838 if ((s3 >= 0) && (s3 <= 255)) {
2839 M_CMOVGE_IMM(s1, s3, d);
2842 ICONST(REG_ITMP2, s3);
2843 M_CMOVGE(s1, REG_ITMP2, d);
2845 store_reg_to_var_int(iptr->dst, d);
2848 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2849 /* val.i = constant */
2851 var_to_reg_int(s1, src, REG_ITMP1);
2852 d = reg_of_var(iptr->dst, REG_ITMP3);
2854 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2855 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2856 M_CMPLT(REG_ZERO, s1, d);
2857 store_reg_to_var_int(iptr->dst, d);
2860 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2861 M_CMPLE(s1, REG_ZERO, d);
2862 store_reg_to_var_int(iptr->dst, d);
2866 M_MOV(s1, REG_ITMP1);
2869 ICONST(d, iptr[1].val.i);
2871 if ((s3 >= 0) && (s3 <= 255)) {
2872 M_CMOVGT_IMM(s1, s3, d);
2875 ICONST(REG_ITMP2, s3);
2876 M_CMOVGT(s1, REG_ITMP2, d);
2878 store_reg_to_var_int(iptr->dst, d);
2881 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2882 /* val.i = constant */
2884 var_to_reg_int(s1, src, REG_ITMP1);
2885 d = reg_of_var(iptr->dst, REG_ITMP3);
2887 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2888 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2889 M_CMPLE(s1, REG_ZERO, d);
2890 store_reg_to_var_int(iptr->dst, d);
2893 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2894 M_CMPLT(REG_ZERO, s1, d);
2895 store_reg_to_var_int(iptr->dst, d);
2899 M_MOV(s1, REG_ITMP1);
2902 ICONST(d, iptr[1].val.i);
2904 if ((s3 >= 0) && (s3 <= 255)) {
2905 M_CMOVLE_IMM(s1, s3, d);
2908 ICONST(REG_ITMP2, s3);
2909 M_CMOVLE(s1, REG_ITMP2, d);
2911 store_reg_to_var_int(iptr->dst, d);
2915 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2920 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2921 a = dseg_addaddress ((void*) (builtin_monitorexit));
2922 M_ALD(REG_PV, REG_PV, a);
2923 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
2924 M_JSR(REG_RA, REG_PV);
2925 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2928 var_to_reg_int(s1, src, REG_RESULT);
2929 M_INTMOVE(s1, REG_RESULT);
2930 goto nowperformreturn;
2932 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2936 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2937 a = dseg_addaddress ((void*) (builtin_monitorexit));
2938 M_ALD(REG_PV, REG_PV, a);
2939 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
2940 M_JSR(REG_RA, REG_PV);
2941 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2944 var_to_reg_flt(s1, src, REG_FRESULT);
2945 M_FLTMOVE(s1, REG_FRESULT);
2946 goto nowperformreturn;
2948 case ICMD_RETURN: /* ... ==> ... */
2951 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2952 a = dseg_addaddress ((void*) (builtin_monitorexit));
2953 M_ALD(REG_PV, REG_PV, a);
2954 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
2955 M_JSR(REG_RA, REG_PV);
2956 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2964 p = parentargs_base;
2966 /* restore return address */
2969 {p--; M_LLD (REG_RA, REG_SP, 8 * p);}
2971 /* restore saved registers */
2973 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
2974 {p--; M_LLD(savintregs[r], REG_SP, 8 * p);}
2975 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
2976 {p--; M_DLD(savfltregs[r], REG_SP, 8 * p);}
2978 /* deallocate stack */
2980 if (parentargs_base)
2981 {M_LDA(REG_SP, REG_SP, parentargs_base*8);}
2983 /* call trace function */
2986 M_LDA (REG_SP, REG_SP, -24);
2987 M_AST(REG_RA, REG_SP, 0);
2988 M_LST(REG_RESULT, REG_SP, 8);
2989 M_DST(REG_FRESULT, REG_SP,16);
2990 a = dseg_addaddress (method);
2991 M_ALD(argintregs[0], REG_PV, a);
2992 M_MOV(REG_RESULT, argintregs[1]);
2993 M_FLTMOVE(REG_FRESULT, argfltregs[2]);
2994 a = dseg_addaddress ((void*) (builtin_displaymethodstop));
2995 M_ALD(REG_PV, REG_PV, a);
2996 M_JSR (REG_RA, REG_PV);
2997 s1 = (int)((u1*) mcodeptr - mcodebase);
2998 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
3001 while (ml<-32768) { ml+=65536; mh--; }
3002 M_LDA (REG_PV, REG_RA, ml );
3003 M_LDAH (REG_PV, REG_PV, mh );
3005 M_DLD(REG_FRESULT, REG_SP,16);
3006 M_LLD(REG_RESULT, REG_SP, 8);
3007 M_ALD(REG_RA, REG_SP, 0);
3008 M_LDA (REG_SP, REG_SP, 24);
3011 M_RET(REG_ZERO, REG_RA);
3017 case ICMD_TABLESWITCH: /* ..., index ==> ... */
3022 tptr = (void **) iptr->target;
3024 s4ptr = iptr->val.a;
3025 l = s4ptr[1]; /* low */
3026 i = s4ptr[2]; /* high */
3028 var_to_reg_int(s1, src, REG_ITMP1);
3030 {M_INTMOVE(s1, REG_ITMP1);}
3031 else if (l <= 32768) {
3032 M_LDA(REG_ITMP1, s1, -l);
3035 ICONST(REG_ITMP2, l);
3036 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
3043 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
3045 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
3046 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3048 M_BEQZ(REG_ITMP2, 0);
3051 /* mcode_addreference(BlockPtrOfPC(s4ptr[0]), mcodeptr); */
3052 mcode_addreference((basicblock *) tptr[0], mcodeptr);
3054 /* build jump table top down and use address of lowest entry */
3056 /* s4ptr += 3 + i; */
3060 /* dseg_addtarget(BlockPtrOfPC(*--s4ptr)); */
3061 dseg_addtarget((basicblock *) tptr[0]);
3066 /* length of dataseg after last dseg_addtarget is used by load */
3068 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
3069 M_ALD(REG_ITMP2, REG_ITMP2, -dseglen);
3070 M_JMP(REG_ZERO, REG_ITMP2);
3075 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3077 s4 i, l, val, *s4ptr;
3080 tptr = (void **) iptr->target;
3082 s4ptr = iptr->val.a;
3083 l = s4ptr[0]; /* default */
3084 i = s4ptr[1]; /* count */
3086 MCODECHECK((i<<2)+8);
3087 var_to_reg_int(s1, src, REG_ITMP1);
3093 if ((val >= 0) && (val <= 255)) {
3094 M_CMPEQ_IMM(s1, val, REG_ITMP2);
3097 if ((val >= -32768) && (val <= 32767)) {
3098 M_LDA(REG_ITMP2, REG_ZERO, val);
3101 a = dseg_adds4 (val);
3102 M_ILD(REG_ITMP2, REG_PV, a);
3104 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
3106 M_BNEZ(REG_ITMP2, 0);
3107 /* mcode_addreference(BlockPtrOfPC(s4ptr[1]), mcodeptr); */
3108 mcode_addreference((basicblock *) tptr[0], mcodeptr);
3112 /* mcode_addreference(BlockPtrOfPC(l), mcodeptr); */
3114 tptr = (void **) iptr->target;
3115 mcode_addreference((basicblock *) tptr[0], mcodeptr);
3122 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
3123 /* op1 = return type, val.a = function pointer*/
3127 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
3128 /* op1 = return type, val.a = function pointer*/
3132 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
3133 /* op1 = return type, val.a = function pointer*/
3137 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3138 /* op1 = arg count, val.a = method pointer */
3140 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3141 /* op1 = arg count, val.a = method pointer */
3143 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3144 /* op1 = arg count, val.a = method pointer */
3146 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
3147 /* op1 = arg count, val.a = method pointer */
3155 MCODECHECK((s3 << 1) + 64);
3157 /* copy arguments to registers or stack location */
3159 for (; --s3 >= 0; src = src->prev) {
3160 if (src->varkind == ARGVAR)
3162 if (IS_INT_LNG_TYPE(src->type)) {
3163 if (s3 < INT_ARG_CNT) {
3164 s1 = argintregs[s3];
3165 var_to_reg_int(d, src, s1);
3169 var_to_reg_int(d, src, REG_ITMP1);
3170 M_LST(d, REG_SP, 8 * (s3 - INT_ARG_CNT));
3174 if (s3 < FLT_ARG_CNT) {
3175 s1 = argfltregs[s3];
3176 var_to_reg_flt(d, src, s1);
3180 var_to_reg_flt(d, src, REG_FTMP1);
3181 M_DST(d, REG_SP, 8 * (s3 - FLT_ARG_CNT));
3186 switch (iptr->opc) {
3190 a = dseg_addaddress ((void*) (m));
3192 M_ALD(REG_PV, REG_PV, a); /* Pointer to built-in-function */
3194 goto makeactualcall;
3196 case ICMD_INVOKESTATIC:
3197 case ICMD_INVOKESPECIAL:
3198 a = dseg_addaddress (m->stubroutine);
3200 M_ALD(REG_PV, REG_PV, a ); /* method pointer in r27 */
3203 goto makeactualcall;
3205 case ICMD_INVOKEVIRTUAL:
3207 gen_nullptr_check(argintregs[0]);
3208 M_ALD(REG_METHODPTR, argintregs[0],
3209 OFFSET(java_objectheader, vftbl));
3210 M_ALD(REG_PV, REG_METHODPTR, OFFSET(vftbl, table[0]) +
3211 sizeof(methodptr) * m->vftblindex);
3214 goto makeactualcall;
3216 case ICMD_INVOKEINTERFACE:
3219 gen_nullptr_check(argintregs[0]);
3220 M_ALD(REG_METHODPTR, argintregs[0],
3221 OFFSET(java_objectheader, vftbl));
3222 M_ALD(REG_METHODPTR, REG_METHODPTR,
3223 OFFSET(vftbl, interfacetable[0]) -
3224 sizeof(methodptr*) * ci->index);
3225 M_ALD(REG_PV, REG_METHODPTR,
3226 sizeof(methodptr) * (m - ci->methods));
3229 goto makeactualcall;
3233 sprintf (logtext, "Unkown ICMD-Command: %d", iptr->opc);
3239 M_JSR (REG_RA, REG_PV);
3243 s1 = (int)((u1*) mcodeptr - mcodebase);
3244 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
3247 while (ml<-32768) { ml+=65536; mh--; }
3248 M_LDA (REG_PV, REG_RA, ml );
3249 M_LDAH (REG_PV, REG_PV, mh );
3252 /* d contains return type */
3254 if (d != TYPE_VOID) {
3255 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3256 s1 = reg_of_var(iptr->dst, REG_RESULT);
3257 M_INTMOVE(REG_RESULT, s1);
3258 store_reg_to_var_int(iptr->dst, s1);
3261 s1 = reg_of_var(iptr->dst, REG_FRESULT);
3262 M_FLTMOVE(REG_FRESULT, s1);
3263 store_reg_to_var_flt(iptr->dst, s1);
3270 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3272 /* op1: 0 == array, 1 == class */
3273 /* val.a: (classinfo*) superclass */
3275 /* superclass is an interface:
3277 * return (sub != NULL) &&
3278 * (sub->vftbl->interfacetablelength > super->index) &&
3279 * (sub->vftbl->interfacetable[-super->index] != NULL);
3281 * superclass is a class:
3283 * return ((sub != NULL) && (0
3284 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3285 * super->vftbl->diffvall));
3289 classinfo *super = (classinfo*) iptr->val.a;
3291 var_to_reg_int(s1, src, REG_ITMP1);
3292 d = reg_of_var(iptr->dst, REG_ITMP3);
3294 M_MOV(s1, REG_ITMP1);
3298 if (iptr->op1) { /* class/interface */
3299 if (super->flags & ACC_INTERFACE) { /* interface */
3301 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3302 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3303 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3304 M_BLEZ(REG_ITMP2, 2);
3305 M_ALD(REG_ITMP1, REG_ITMP1,
3306 OFFSET(vftbl, interfacetable[0]) -
3307 super->index * sizeof(methodptr*));
3308 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3311 s2 = super->vftbl->diffval;
3312 M_BEQZ(s1, 4 + (s2 > 255));
3313 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3314 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3315 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3317 M_CMPULE_IMM(REG_ITMP1, s2, d);
3319 M_LDA(REG_ITMP2, REG_ZERO, s2);
3320 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3325 panic ("internal error: no inlined array instanceof");
3327 store_reg_to_var_int(iptr->dst, d);
3330 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3332 /* op1: 0 == array, 1 == class */
3333 /* val.a: (classinfo*) superclass */
3335 /* superclass is an interface:
3337 * OK if ((sub == NULL) ||
3338 * (sub->vftbl->interfacetablelength > super->index) &&
3339 * (sub->vftbl->interfacetable[-super->index] != NULL));
3341 * superclass is a class:
3343 * OK if ((sub == NULL) || (0
3344 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3345 * super->vftbl->diffvall));
3349 classinfo *super = (classinfo*) iptr->val.a;
3351 d = reg_of_var(iptr->dst, REG_ITMP3);
3352 var_to_reg_int(s1, src, d);
3353 if (iptr->op1) { /* class/interface */
3354 if (super->flags & ACC_INTERFACE) { /* interface */
3356 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3357 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3358 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3359 M_BLEZ(REG_ITMP2, 0);
3360 mcode_addxcastrefs(mcodeptr);
3361 M_ALD(REG_ITMP2, REG_ITMP1,
3362 OFFSET(vftbl, interfacetable[0]) -
3363 super->index * sizeof(methodptr*));
3364 M_BEQZ(REG_ITMP2, 0);
3365 mcode_addxcastrefs(mcodeptr);
3368 s2 = super->vftbl->diffval;
3369 M_BEQZ(s1, 4 + (s2 != 0) + (s2 > 255));
3370 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3371 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3372 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3374 M_BNEZ(REG_ITMP1, 0);
3376 else if (s2 <= 255) {
3377 M_CMPULE_IMM(REG_ITMP1, s2, REG_ITMP2);
3378 M_BEQZ(REG_ITMP2, 0);
3381 M_LDA(REG_ITMP2, REG_ZERO, s2);
3382 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3383 M_BEQZ(REG_ITMP2, 0);
3385 mcode_addxcastrefs(mcodeptr);
3389 panic ("internal error: no inlined array checkcast");
3392 store_reg_to_var_int(iptr->dst, d);
3395 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
3397 var_to_reg_int(s1, src, REG_ITMP1);
3399 mcode_addxcheckarefs(mcodeptr);
3402 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3403 /* op1 = dimension, val.a = array descriptor */
3405 /* check for negative sizes and copy sizes to stack if necessary */
3407 MCODECHECK((iptr->op1 << 1) + 64);
3409 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3410 var_to_reg_int(s2, src, REG_ITMP1);
3412 mcode_addxcheckarefs(mcodeptr);
3414 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
3416 if (src->varkind != ARGVAR) {
3417 M_LST(s2, REG_SP, 8 * (s1 + INT_ARG_CNT));
3421 /* a0 = dimension count */
3423 ICONST(argintregs[0], iptr->op1);
3425 /* a1 = arraydescriptor */
3427 a = dseg_addaddress(iptr->val.a);
3428 M_ALD(argintregs[1], REG_PV, a);
3430 /* a2 = pointer to dimensions = stack pointer */
3432 M_INTMOVE(REG_SP, argintregs[2]);
3434 a = dseg_addaddress((void*) (builtin_nmultianewarray));
3435 M_ALD(REG_PV, REG_PV, a);
3436 M_JSR(REG_RA, REG_PV);
3437 s1 = (int)((u1*) mcodeptr - mcodebase);
3439 M_LDA (REG_PV, REG_RA, -s1);
3441 s4 ml = -s1, mh = 0;
3442 while (ml < -32768) {ml += 65536; mh--;}
3443 M_LDA(REG_PV, REG_RA, ml);
3444 M_LDAH(REG_PV, REG_PV, mh);
3446 s1 = reg_of_var(iptr->dst, REG_RESULT);
3447 M_INTMOVE(REG_RESULT, s1);
3448 store_reg_to_var_int(iptr->dst, s1);
3452 default: sprintf (logtext, "Unknown pseudo command: %d", iptr->opc);
3459 } /* for instruction */
3461 /* copy values to interface registers */
3463 src = bptr->outstack;
3464 len = bptr->outdepth;
3468 if ((src->varkind != STACKVAR)) {
3470 if (IS_FLT_DBL_TYPE(s2)) {
3471 var_to_reg_flt(s1, src, REG_FTMP1);
3472 if (!(interfaces[len][s2].flags & INMEMORY)) {
3473 M_FLTMOVE(s1,interfaces[len][s2].regoff);
3476 M_DST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3480 var_to_reg_int(s1, src, REG_ITMP1);
3481 if (!(interfaces[len][s2].flags & INMEMORY)) {
3482 M_INTMOVE(s1,interfaces[len][s2].regoff);
3485 M_LST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3491 } /* if (bptr -> flags >= BBREACHED) */
3492 } /* for basic block */
3494 /* bptr -> mpc = (int)((u1*) mcodeptr - mcodebase); */
3497 /* generate bound check stubs */
3499 s4 *xcodeptr = NULL;
3501 for (; xboundrefs != NULL; xboundrefs = xboundrefs->next) {
3502 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3503 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
3504 xboundrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3509 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
3510 xboundrefs->branchpos, (u1*) mcodeptr - mcodebase);
3514 M_LDA(REG_ITMP2_XPC, REG_PV, xboundrefs->branchpos - 4);
3516 if (xcodeptr != NULL) {
3517 M_BR((xcodeptr-mcodeptr)-1);
3520 xcodeptr = mcodeptr;
3522 a = dseg_addaddress(proto_java_lang_ArrayIndexOutOfBoundsException);
3523 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3525 a = dseg_addaddress(asm_handle_exception);
3526 M_ALD(REG_ITMP3, REG_PV, a);
3528 M_JMP(REG_ZERO, REG_ITMP3);
3532 /* generate negative array size check stubs */
3536 for (; xcheckarefs != NULL; xcheckarefs = xcheckarefs->next) {
3537 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3538 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3539 xcheckarefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3543 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3544 xcheckarefs->branchpos, (u1*) mcodeptr - mcodebase);
3548 M_LDA(REG_ITMP2_XPC, REG_PV, xcheckarefs->branchpos - 4);
3550 if (xcodeptr != NULL) {
3551 M_BR((xcodeptr-mcodeptr)-1);
3554 xcodeptr = mcodeptr;
3556 a = dseg_addaddress(proto_java_lang_NegativeArraySizeException);
3557 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3559 a = dseg_addaddress(asm_handle_exception);
3560 M_ALD(REG_ITMP3, REG_PV, a);
3562 M_JMP(REG_ZERO, REG_ITMP3);
3566 /* generate cast check stubs */
3570 for (; xcastrefs != NULL; xcastrefs = xcastrefs->next) {
3571 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3572 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3573 xcastrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3577 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3578 xcastrefs->branchpos, (u1*) mcodeptr - mcodebase);
3582 M_LDA(REG_ITMP2_XPC, REG_PV, xcastrefs->branchpos - 4);
3584 if (xcodeptr != NULL) {
3585 M_BR((xcodeptr-mcodeptr)-1);
3588 xcodeptr = mcodeptr;
3590 a = dseg_addaddress(proto_java_lang_ClassCastException);
3591 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3593 a = dseg_addaddress(asm_handle_exception);
3594 M_ALD(REG_ITMP3, REG_PV, a);
3596 M_JMP(REG_ZERO, REG_ITMP3);
3601 #ifdef SOFTNULLPTRCHECK
3603 /* generate null pointer check stubs */
3607 for (; xnullrefs != NULL; xnullrefs = xnullrefs->next) {
3608 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3609 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3610 xnullrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3614 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3615 xnullrefs->branchpos, (u1*) mcodeptr - mcodebase);
3619 M_LDA(REG_ITMP2_XPC, REG_PV, xnullrefs->branchpos - 4);
3621 if (xcodeptr != NULL) {
3622 M_BR((xcodeptr-mcodeptr)-1);
3625 xcodeptr = mcodeptr;
3627 a = dseg_addaddress(proto_java_lang_NullPointerException);
3628 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3630 a = dseg_addaddress(asm_handle_exception);
3631 M_ALD(REG_ITMP3, REG_PV, a);
3633 M_JMP(REG_ZERO, REG_ITMP3);
3640 mcode_finish((int)((u1*) mcodeptr - mcodebase));
3644 /* redefinition of code generation macros (compiling into array) **************/
3647 These macros are newly defined to allow code generation into an array.
3648 This is necessary, because the original M_.. macros generate code by
3649 calling 'mcode_adds4' that uses an additional data structure to
3652 For a faster (but less flexible) version to generate code, these
3653 macros directly use the (s4* p) - pointer to put the code directly
3654 in a locally defined array.
3655 This makes sense only for the stub-generation-routines below.
3659 #define M_OP3(op,fu,a,b,c,const) \
3660 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<(16-3*(const)))| \
3661 ((const)<<12)|((fu)<<5)|((c)) )
3663 #define M_FOP3(op,fu,a,b,c) \
3664 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<16)|((fu)<<5)|(c) )
3666 #define M_BRA(op,a,disp) \
3667 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((disp)&0x1fffff) )
3669 #define M_MEM(op,a,b,disp) \
3670 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<16)|((disp)&0xffff) )
3673 /* function createcompilerstub *************************************************
3675 creates a stub routine which calls the compiler
3677 *******************************************************************************/
3679 #define COMPSTUBSIZE 3
3681 u1 *createcompilerstub (methodinfo *m)
3683 u8 *s = CNEW (u8, COMPSTUBSIZE); /* memory to hold the stub */
3684 s4 *p = (s4*) s; /* code generation pointer */
3686 /* code for the stub */
3687 M_ALD (REG_PV, REG_PV, 16); /* load pointer to the compiler */
3688 M_JMP (0, REG_PV); /* jump to the compiler, return address
3689 in reg 0 is used as method pointer */
3690 s[1] = (u8) m; /* literals to be adressed */
3691 s[2] = (u8) asm_call_jit_compiler; /* jump directly via PV from above */
3694 count_cstub_len += COMPSTUBSIZE * 8;
3701 /* function removecompilerstub *************************************************
3703 deletes a compilerstub from memory (simply by freeing it)
3705 *******************************************************************************/
3707 void removecompilerstub (u1 *stub)
3709 CFREE (stub, COMPSTUBSIZE * 8);
3713 /* function: createnativestub **************************************************
3715 creates a stub routine which calls a native method
3717 *******************************************************************************/
3719 #define NATIVESTUBSIZE 11
3721 u1 *createnativestub (functionptr f, methodinfo *m)
3723 u8 *s = CNEW (u8, NATIVESTUBSIZE); /* memory to hold the stub */
3724 s4 *p = (s4*) s; /* code generation pointer */
3726 M_LDA (REG_SP, REG_SP, -8); /* build up stackframe */
3727 M_AST (REG_RA, REG_SP, 0); /* store return address */
3729 M_ALD (REG_PV, REG_PV, 8*8); /* load adress of native method */
3730 M_JSR (REG_RA, REG_PV); /* call native method */
3732 M_LDA (REG_PV, REG_RA, -4*4); /* recompute pv from ra */
3733 M_ALD (REG_ITMP3, REG_PV, 9*8); /* get address of exceptionptr */
3735 M_ALD (REG_RA, REG_SP, 0); /* load return address */
3736 M_ALD (REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
3738 M_LDA (REG_SP, REG_SP, 8); /* remove stackframe */
3739 M_BNEZ (REG_ITMP1, 1); /* if no exception then return */
3741 M_RET (REG_ZERO, REG_RA); /* return to caller */
3743 M_AST (REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
3744 M_LDA (REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
3746 M_ALD (REG_ITMP3, REG_PV,10*8); /* load asm exception handler address */
3747 M_JMP (REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
3750 s[8] = (u8) f; /* address of native method */
3751 s[9] = (u8) (&exceptionptr); /* address of exceptionptr */
3752 s[10]= (u8) (asm_handle_nat_exception); /* addr of asm exception handler */
3755 count_nstub_len += NATIVESTUBSIZE * 8;
3762 /* function: removenativestub **************************************************
3764 removes a previously created native-stub from memory
3766 *******************************************************************************/
3768 void removenativestub (u1 *stub)
3770 CFREE (stub, NATIVESTUBSIZE * 8);
3775 * These are local overrides for various environment variables in Emacs.
3776 * Please do not remove this and leave it at the end of the file, where
3777 * Emacs will automagically detect them.
3778 * ---------------------------------------------------------------------
3781 * indent-tabs-mode: t