1 /* alpha/ngen.c ****************************************************************
3 Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
5 See file COPYRIGHT for information on usage and disclaimer of warranties
7 Contains the codegenerator for an Alpha processor.
8 This module generates Alpha machine code for a sequence of
9 pseudo commands (ICMDs).
11 Authors: Andreas Krall EMAIL: cacao@complang.tuwien.ac.at
12 Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at
14 Last Change: 1998/08/10
16 *******************************************************************************/
20 /* *****************************************************************************
22 Datatypes and Register Allocations:
23 -----------------------------------
25 On 64-bit-machines (like the Alpha) all operands are stored in the
26 registers in a 64-bit form, even when the correspondig JavaVM operands
27 only need 32 bits. This is done by a canonical representation:
29 32-bit integers are allways stored as sign-extended 64-bit values (this
30 approach is directly supported by the Alpha architecture and is very easy
33 32-bit-floats are stored in a 64-bit doubleprecision register by simply
34 expanding the exponent and mantissa with zeroes. (also supported by the
40 The calling conventions and the layout of the stack is explained in detail
41 in the documention file: calling.doc
43 *******************************************************************************/
46 /* additional functions and macros to generate code ***************************/
48 #define BlockPtrOfPC(pc) block+block_index[pc]
51 #define COUNT_SPILLS count_spills++
57 /* gen_nullptr_check(objreg) */
59 #ifdef SOFTNULLPTRCHECK
60 #define gen_nullptr_check(objreg) \
63 mcode_addxnullrefs(mcodeptr);\
66 #define gen_nullptr_check(objreg)
70 /* MCODECHECK(icnt) */
72 #define MCODECHECK(icnt) \
73 if((mcodeptr+(icnt))>mcodeend)mcodeptr=mcode_increase((u1*)mcodeptr)
76 generates an integer-move from register a to b.
77 if a and b are the same int-register, no code will be generated.
80 #define M_INTMOVE(a,b) if(a!=b){M_MOV(a,b);}
84 generates a floating-point-move from register a to b.
85 if a and b are the same float-register, no code will be generated
88 #define M_FLTMOVE(a,b) if(a!=b){M_FMOV(a,b);}
92 this function generates code to fetch data from a pseudo-register
94 If the pseudo-register has actually been assigned to a real
95 register, no code will be emitted, since following operations
96 can use this register directly.
98 v: pseudoregister to be fetched from
99 tempregnum: temporary register to be used if v is actually spilled to ram
101 return: the register number, where the operand can be found after
102 fetching (this wil be either tempregnum or the register
103 number allready given to v)
106 #define var_to_reg_int(regnr,v,tempnr) { \
107 if ((v)->flags & INMEMORY) \
108 {COUNT_SPILLS;M_LLD(tempnr,REG_SP,8*(v)->regoff);regnr=tempnr;} \
109 else regnr=(v)->regoff; \
113 #define var_to_reg_flt(regnr,v,tempnr) { \
114 if ((v)->flags & INMEMORY) \
115 {COUNT_SPILLS;M_DLD(tempnr,REG_SP,8*(v)->regoff);regnr=tempnr;} \
116 else regnr=(v)->regoff; \
121 This function determines a register, to which the result of an operation
122 should go, when it is ultimatively intended to store the result in
124 If v is assigned to an actual register, this register will be returned.
125 Otherwise (when v is spilled) this function returns tempregnum.
126 If not already done, regoff and flags are set in the stack location.
129 static int reg_of_var(stackptr v, int tempregnum)
133 switch (v->varkind) {
135 if (!(v->flags & INMEMORY))
139 var = &(interfaces[v->varnum][v->type]);
140 v->regoff = var->regoff;
141 if (!(var->flags & INMEMORY))
145 var = &(locals[v->varnum][v->type]);
146 v->regoff = var->regoff;
147 if (!(var->flags & INMEMORY))
151 v->regoff = v->varnum;
152 if (IS_FLT_DBL_TYPE(v->type)) {
153 if (v->varnum < fltreg_argnum) {
154 v->regoff = argfltregs[v->varnum];
155 return(argfltregs[v->varnum]);
159 if (v->varnum < intreg_argnum) {
160 v->regoff = argintregs[v->varnum];
161 return(argintregs[v->varnum]);
163 v->regoff -= intreg_argnum;
166 v->flags |= INMEMORY;
171 /* store_reg_to_var_xxx:
172 This function generates the code to store the result of an operation
173 back into a spilled pseudo-variable.
174 If the pseudo-variable has not been spilled in the first place, this
175 function will generate nothing.
177 v ............ Pseudovariable
178 tempregnum ... Number of the temporary registers as returned by
182 #define store_reg_to_var_int(sptr, tempregnum) { \
183 if ((sptr)->flags & INMEMORY) { \
185 M_LST(tempregnum, REG_SP, 8 * (sptr)->regoff); \
189 #define store_reg_to_var_flt(sptr, tempregnum) { \
190 if ((sptr)->flags & INMEMORY) { \
192 M_DST(tempregnum, REG_SP, 8 * (sptr)->regoff); \
197 /* NullPointerException handlers and exception handling initialisation */
199 typedef struct sigctx_struct {
201 long sc_onstack; /* sigstack state to restore */
202 long sc_mask; /* signal mask to restore */
203 long sc_pc; /* pc at time of signal */
204 long sc_ps; /* psl to retore */
205 long sc_regs[32]; /* processor regs 0 to 31 */
206 long sc_ownedfp; /* fp has been used */
207 long sc_fpregs[32]; /* fp regs 0 to 31 */
208 unsigned long sc_fpcr; /* floating point control register */
209 unsigned long sc_fp_control; /* software fpcr */
211 unsigned long sc_reserved1, sc_reserved2;
212 unsigned long sc_ssize;
214 unsigned long sc_traparg_a0;
215 unsigned long sc_traparg_a1;
216 unsigned long sc_traparg_a2;
217 unsigned long sc_fp_trap_pc;
218 unsigned long sc_fp_trigger_sum;
219 unsigned long sc_fp_trigger_inst;
220 unsigned long sc_retcode[2];
224 /* NullPointerException signal handler for hardware null pointer check */
226 void catch_NullPointerException(int sig, int code, sigctx_struct *sigctx)
232 /* Reset signal handler - necessary for SysV, does no harm for BSD */
234 instr = *((int*)(sigctx->sc_pc));
235 faultaddr = sigctx->sc_regs[(instr >> 16) & 0x1f];
237 if (faultaddr == 0) {
238 signal(sig, (void*) catch_NullPointerException); /* reinstall handler */
240 sigaddset(&nsig, sig);
241 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
242 sigctx->sc_regs[REG_ITMP1_XPTR] =
243 (long) proto_java_lang_NullPointerException;
244 sigctx->sc_regs[REG_ITMP2_XPC] = sigctx->sc_pc;
245 sigctx->sc_pc = (long) asm_handle_nat_exception;
249 faultaddr += (long) ((instr << 16) >> 16);
250 fprintf(stderr, "faulting address: 0x%16lx\n", faultaddr);
251 panic("Stack overflow");
258 void init_exceptions(void)
263 /* Linux on Digital Alpha needs an initialisation of the ieee floating point
264 control for IEEE compliant arithmetic (option -mieee of GCC). Under
265 Digital Unix this is done automatically.
270 extern unsigned long ieee_get_fp_control();
271 extern void ieee_set_fp_control(unsigned long fp_control);
273 void init_exceptions(void)
275 /* initialize floating point control */
277 ieee_set_fp_control(ieee_get_fp_control()
278 & ~IEEE_TRAP_ENABLE_INV
279 & ~IEEE_TRAP_ENABLE_DZE
280 /* & ~IEEE_TRAP_ENABLE_UNF we dont want underflow */
281 & ~IEEE_TRAP_ENABLE_OVF);
284 /* install signal handlers we need to convert to exceptions */
289 signal(SIGSEGV, (void*) catch_NullPointerException);
293 signal(SIGBUS, (void*) catch_NullPointerException);
299 /* function gen_mcode **********************************************************
301 generates machine code
303 *******************************************************************************/
305 #define MethodPointer -8
306 #define FrameSize -12
311 #define ExTableSize -32
312 #define ExTableStart -32
314 #define ExEntrySize -32
317 #define ExHandlerPC -24
318 #define ExCatchType -32
320 static void gen_mcode()
322 int len, s1, s2, s3, d, bbs;
333 savedregs_num = (isleafmethod) ? 0 : 1; /* space to save the RA */
335 /* space to save used callee saved registers */
337 savedregs_num += (savintregcnt - maxsavintreguse);
338 savedregs_num += (savfltregcnt - maxsavfltreguse);
340 parentargs_base = maxmemuse + savedregs_num;
342 #ifdef USE_THREADS /* space to save argument of monitor_enter */
344 if (checksync && (method->flags & ACC_SYNCHRONIZED))
349 /* create method header */
351 (void) dseg_addaddress(method); /* MethodPointer */
352 (void) dseg_adds4(parentargs_base * 8); /* FrameSize */
356 /* IsSync contains the offset relative to the stack pointer for the
357 argument of monitor_exit used in the exception handler. Since the
358 offset could be zero and give a wrong meaning of the flag it is
362 if (checksync && (method->flags & ACC_SYNCHRONIZED))
363 (void) dseg_adds4((maxmemuse + 1) * 8); /* IsSync */
368 (void) dseg_adds4(0); /* IsSync */
370 (void) dseg_adds4(isleafmethod); /* IsLeaf */
371 (void) dseg_adds4(savintregcnt - maxsavintreguse); /* IntSave */
372 (void) dseg_adds4(savfltregcnt - maxsavfltreguse); /* FltSave */
373 (void) dseg_adds4(exceptiontablelength); /* ExTableSize */
375 /* create exception table */
377 for (len = 0; len < exceptiontablelength; len++) {
378 dseg_addtarget(BlockPtrOfPC(extable[len].startpc));
379 dseg_addtarget(BlockPtrOfPC(extable[len].endpc));
380 dseg_addtarget(BlockPtrOfPC(extable[len].handlerpc));
381 (void) dseg_addaddress(extable[len].catchtype);
384 /* initialize mcode variables */
386 mcodeptr = (s4*) mcodebase;
387 mcodeend = (s4*) (mcodebase + mcodesize);
388 MCODECHECK(128 + mparamcount);
390 /* create stack frame (if necessary) */
393 {M_LDA (REG_SP, REG_SP, -parentargs_base * 8);}
395 /* save return address and used callee saved registers */
399 {p--; M_AST (REG_RA, REG_SP, 8*p);}
400 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
401 {p--; M_LST (savintregs[r], REG_SP, 8 * p);}
402 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
403 {p--; M_DST (savfltregs[r], REG_SP, 8 * p);}
405 /* save monitorenter argument */
408 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
409 if (method->flags & ACC_STATIC) {
410 p = dseg_addaddress (class);
411 M_ALD(REG_ITMP1, REG_PV, p);
412 M_AST(REG_ITMP1, REG_SP, 8 * maxmemuse);
415 M_AST (argintregs[0], REG_SP, 8 * maxmemuse);
420 /* copy argument registers to stack and call trace function with pointer
421 to arguments on stack. ToDo: save floating point registers !!!!!!!!!
424 if (runverbose && isleafmethod) {
425 M_LDA (REG_SP, REG_SP, -(14*8));
426 M_AST(REG_RA, REG_SP, 1*8);
428 M_LST(argintregs[0], REG_SP, 2*8);
429 M_LST(argintregs[1], REG_SP, 3*8);
430 M_LST(argintregs[2], REG_SP, 4*8);
431 M_LST(argintregs[3], REG_SP, 5*8);
432 M_LST(argintregs[4], REG_SP, 6*8);
433 M_LST(argintregs[5], REG_SP, 7*8);
435 M_DST(argfltregs[0], REG_SP, 8*8);
436 M_DST(argfltregs[1], REG_SP, 9*8);
437 M_DST(argfltregs[2], REG_SP, 10*8);
438 M_DST(argfltregs[3], REG_SP, 11*8);
439 M_DST(argfltregs[4], REG_SP, 12*8);
440 M_DST(argfltregs[5], REG_SP, 13*8);
442 p = dseg_addaddress (method);
443 M_ALD(REG_ITMP1, REG_PV, p);
444 M_AST(REG_ITMP1, REG_SP, 0);
445 p = dseg_addaddress ((void*) (builtin_trace_args));
446 M_ALD(REG_PV, REG_PV, p);
447 M_JSR(REG_RA, REG_PV);
448 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
449 M_ALD(REG_RA, REG_SP, 1*8);
451 M_LLD(argintregs[0], REG_SP, 2*8);
452 M_LLD(argintregs[1], REG_SP, 3*8);
453 M_LLD(argintregs[2], REG_SP, 4*8);
454 M_LLD(argintregs[3], REG_SP, 5*8);
455 M_LLD(argintregs[4], REG_SP, 6*8);
456 M_LLD(argintregs[5], REG_SP, 7*8);
458 M_DLD(argfltregs[0], REG_SP, 8*8);
459 M_DLD(argfltregs[1], REG_SP, 9*8);
460 M_DLD(argfltregs[2], REG_SP, 10*8);
461 M_DLD(argfltregs[3], REG_SP, 11*8);
462 M_DLD(argfltregs[4], REG_SP, 12*8);
463 M_DLD(argfltregs[5], REG_SP, 13*8);
465 M_LDA (REG_SP, REG_SP, 14*8);
468 /* take arguments out of register or stack frame */
470 for (p = 0, l = 0; p < mparamcount; p++) {
472 var = &(locals[l][t]);
474 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
479 if (IS_INT_LNG_TYPE(t)) { /* integer args */
480 if (p < INT_ARG_CNT) { /* register arguments */
481 if (!(var->flags & INMEMORY)) /* reg arg -> register */
482 {M_INTMOVE (argintregs[p], r);}
483 else /* reg arg -> spilled */
484 M_LST (argintregs[p], REG_SP, 8 * r);
486 else { /* stack arguments */
487 pa = p - INT_ARG_CNT;
488 if (!(var->flags & INMEMORY)) /* stack arg -> register */
489 M_LLD (r, REG_SP, 8 * (parentargs_base + pa));
490 else { /* stack arg -> spilled */
491 M_LLD (REG_ITMP1, REG_SP, 8 * (parentargs_base + pa));
492 M_LST (REG_ITMP1, REG_SP, 8 * r);
496 else { /* floating args */
497 if (p < FLT_ARG_CNT) { /* register arguments */
498 if (!(var->flags & INMEMORY)) /* reg arg -> register */
499 {M_FLTMOVE (argfltregs[p], r);}
500 else /* reg arg -> spilled */
501 M_DST (argfltregs[p], REG_SP, 8 * r);
503 else { /* stack arguments */
504 pa = p - FLT_ARG_CNT;
505 if (!(var->flags & INMEMORY)) /* stack-arg -> register */
506 M_DLD (r, REG_SP, 8 * (parentargs_base + pa) );
507 else { /* stack-arg -> spilled */
508 M_DLD (REG_FTMP1, REG_SP, 8 * (parentargs_base + pa));
509 M_DST (REG_FTMP1, REG_SP, 8 * r);
515 /* call trace function */
517 if (runverbose && !isleafmethod) {
518 M_LDA (REG_SP, REG_SP, -8);
519 p = dseg_addaddress (method);
520 M_ALD(REG_ITMP1, REG_PV, p);
521 M_AST(REG_ITMP1, REG_SP, 0);
522 p = dseg_addaddress ((void*) (builtin_trace_args));
523 M_ALD(REG_PV, REG_PV, p);
524 M_JSR(REG_RA, REG_PV);
525 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
526 M_LDA(REG_SP, REG_SP, 8);
529 /* call monitorenter function */
532 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
533 p = dseg_addaddress ((void*) (builtin_monitorenter));
534 M_ALD(REG_PV, REG_PV, p);
535 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
536 M_JSR(REG_RA, REG_PV);
537 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
542 /* end of header generation */
544 /* walk through all basic blocks */
546 for (bbs = block_count, bptr = block; --bbs >= 0; bptr++) {
547 bptr -> mpc = (int)((u1*) mcodeptr - mcodebase);
549 if (bptr->flags >= BBREACHED) {
551 /* branch resolving */
555 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
556 gen_resolvebranch((u1*) mcodebase + brefs->branchpos,
557 brefs->branchpos, bptr->mpc);
561 /* copy interface registers to their destination */
566 while (src != NULL) {
568 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
569 d = reg_of_var(src, REG_ITMP1);
570 M_INTMOVE(REG_ITMP1, d);
571 store_reg_to_var_int(src, d);
574 d = reg_of_var(src, REG_IFTMP);
575 if ((src->varkind != STACKVAR)) {
577 if (IS_FLT_DBL_TYPE(s2)) {
578 if (!(interfaces[len][s2].flags & INMEMORY)) {
579 s1 = interfaces[len][s2].regoff;
583 M_DLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
585 store_reg_to_var_flt(src, d);
588 if (!(interfaces[len][s2].flags & INMEMORY)) {
589 s1 = interfaces[len][s2].regoff;
593 M_LLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
595 store_reg_to_var_int(src, d);
602 /* walk through all instructions */
606 for (iptr = bptr->iinstr;
608 src = iptr->dst, len--, iptr++) {
610 MCODECHECK(64); /* an instruction usually needs < 64 words */
613 case ICMD_NOP: /* ... ==> ... */
616 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
618 var_to_reg_int(s1, src, REG_ITMP1);
620 mcode_addxnullrefs(mcodeptr);
623 /* constant operations ************************************************/
625 #define ICONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
626 else{a=dseg_adds4(c);M_ILD(r,REG_PV,a);}
628 #define LCONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
629 else{a=dseg_adds8(c);M_LLD(r,REG_PV,a);}
631 case ICMD_ICONST: /* ... ==> ..., constant */
632 /* op1 = 0, val.i = constant */
634 d = reg_of_var(iptr->dst, REG_ITMP1);
635 ICONST(d, iptr->val.i);
636 store_reg_to_var_int(iptr->dst, d);
639 case ICMD_LCONST: /* ... ==> ..., constant */
640 /* op1 = 0, val.l = constant */
642 d = reg_of_var(iptr->dst, REG_ITMP1);
643 LCONST(d, iptr->val.l);
644 store_reg_to_var_int(iptr->dst, d);
647 case ICMD_FCONST: /* ... ==> ..., constant */
648 /* op1 = 0, val.f = constant */
650 d = reg_of_var (iptr->dst, REG_FTMP1);
651 a = dseg_addfloat (iptr->val.f);
653 store_reg_to_var_flt (iptr->dst, d);
656 case ICMD_DCONST: /* ... ==> ..., constant */
657 /* op1 = 0, val.d = constant */
659 d = reg_of_var (iptr->dst, REG_FTMP1);
660 a = dseg_adddouble (iptr->val.d);
662 store_reg_to_var_flt (iptr->dst, d);
665 case ICMD_ACONST: /* ... ==> ..., constant */
666 /* op1 = 0, val.a = constant */
668 d = reg_of_var(iptr->dst, REG_ITMP1);
670 a = dseg_addaddress (iptr->val.a);
674 M_INTMOVE(REG_ZERO, d);
676 store_reg_to_var_int(iptr->dst, d);
680 /* load/store operations **********************************************/
682 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
683 case ICMD_LLOAD: /* op1 = local variable */
686 d = reg_of_var(iptr->dst, REG_ITMP1);
687 if ((iptr->dst->varkind == LOCALVAR) &&
688 (iptr->dst->varnum == iptr->op1))
690 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
691 if (var->flags & INMEMORY)
692 M_LLD(d, REG_SP, 8 * var->regoff);
694 {M_INTMOVE(var->regoff,d);}
695 store_reg_to_var_int(iptr->dst, d);
698 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
699 case ICMD_DLOAD: /* op1 = local variable */
701 d = reg_of_var(iptr->dst, REG_FTMP1);
702 if ((iptr->dst->varkind == LOCALVAR) &&
703 (iptr->dst->varnum == iptr->op1))
705 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
706 if (var->flags & INMEMORY)
707 M_DLD(d, REG_SP, 8 * var->regoff);
709 {M_FLTMOVE(var->regoff,d);}
710 store_reg_to_var_flt(iptr->dst, d);
714 case ICMD_ISTORE: /* ..., value ==> ... */
715 case ICMD_LSTORE: /* op1 = local variable */
718 if ((src->varkind == LOCALVAR) &&
719 (src->varnum == iptr->op1))
721 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
722 if (var->flags & INMEMORY) {
723 var_to_reg_int(s1, src, REG_ITMP1);
724 M_LST(s1, REG_SP, 8 * var->regoff);
727 var_to_reg_int(s1, src, var->regoff);
728 M_INTMOVE(s1, var->regoff);
732 case ICMD_FSTORE: /* ..., value ==> ... */
733 case ICMD_DSTORE: /* op1 = local variable */
735 if ((src->varkind == LOCALVAR) &&
736 (src->varnum == iptr->op1))
738 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
739 if (var->flags & INMEMORY) {
740 var_to_reg_flt(s1, src, REG_FTMP1);
741 M_DST(s1, REG_SP, 8 * var->regoff);
744 var_to_reg_flt(s1, src, var->regoff);
745 M_FLTMOVE(s1, var->regoff);
750 /* pop/dup/swap operations ********************************************/
752 /* attention: double and longs are only one entry in CACAO ICMDs */
754 case ICMD_POP: /* ..., value ==> ... */
755 case ICMD_POP2: /* ..., value, value ==> ... */
758 #define M_COPY(from,to) \
759 d = reg_of_var(to, REG_IFTMP); \
760 if ((from->regoff != to->regoff) || \
761 ((from->flags ^ to->flags) & INMEMORY)) { \
762 if (IS_FLT_DBL_TYPE(from->type)) { \
763 var_to_reg_flt(s1, from, d); \
765 store_reg_to_var_flt(to, d); \
768 var_to_reg_int(s1, from, d); \
770 store_reg_to_var_int(to, d); \
774 case ICMD_DUP: /* ..., a ==> ..., a, a */
775 M_COPY(src, iptr->dst);
778 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
780 M_COPY(src, iptr->dst->prev->prev);
782 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
784 M_COPY(src, iptr->dst);
785 M_COPY(src->prev, iptr->dst->prev);
788 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
790 M_COPY(src->prev, iptr->dst->prev->prev->prev);
792 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
794 M_COPY(src, iptr->dst);
795 M_COPY(src->prev, iptr->dst->prev);
796 M_COPY(src->prev->prev, iptr->dst->prev->prev);
797 M_COPY(src, iptr->dst->prev->prev->prev);
800 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
802 M_COPY(src, iptr->dst);
803 M_COPY(src->prev, iptr->dst->prev);
804 M_COPY(src->prev->prev, iptr->dst->prev->prev);
805 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
806 M_COPY(src, iptr->dst->prev->prev->prev->prev);
807 M_COPY(src->prev, iptr->dst->prev->prev->prev->prev->prev);
810 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
812 M_COPY(src, iptr->dst->prev);
813 M_COPY(src->prev, iptr->dst);
817 /* integer operations *************************************************/
819 case ICMD_INEG: /* ..., value ==> ..., - value */
821 var_to_reg_int(s1, src, REG_ITMP1);
822 d = reg_of_var(iptr->dst, REG_ITMP3);
823 M_ISUB(REG_ZERO, s1, d);
824 store_reg_to_var_int(iptr->dst, d);
827 case ICMD_LNEG: /* ..., value ==> ..., - value */
829 var_to_reg_int(s1, src, REG_ITMP1);
830 d = reg_of_var(iptr->dst, REG_ITMP3);
831 M_LSUB(REG_ZERO, s1, d);
832 store_reg_to_var_int(iptr->dst, d);
835 case ICMD_I2L: /* ..., value ==> ..., value */
837 var_to_reg_int(s1, src, REG_ITMP1);
838 d = reg_of_var(iptr->dst, REG_ITMP3);
840 store_reg_to_var_int(iptr->dst, d);
843 case ICMD_L2I: /* ..., value ==> ..., value */
845 var_to_reg_int(s1, src, REG_ITMP1);
846 d = reg_of_var(iptr->dst, REG_ITMP3);
847 M_IADD(s1, REG_ZERO, d );
848 store_reg_to_var_int(iptr->dst, d);
851 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
853 var_to_reg_int(s1, src, REG_ITMP1);
854 d = reg_of_var(iptr->dst, REG_ITMP3);
855 if (has_ext_instr_set) {
859 M_SLL_IMM(s1, 56, d);
860 M_SRA_IMM( d, 56, d);
862 store_reg_to_var_int(iptr->dst, d);
865 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
867 var_to_reg_int(s1, src, REG_ITMP1);
868 d = reg_of_var(iptr->dst, REG_ITMP3);
870 store_reg_to_var_int(iptr->dst, d);
873 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
875 var_to_reg_int(s1, src, REG_ITMP1);
876 d = reg_of_var(iptr->dst, REG_ITMP3);
877 if (has_ext_instr_set) {
881 M_SLL_IMM(s1, 48, d);
882 M_SRA_IMM( d, 48, d);
884 store_reg_to_var_int(iptr->dst, d);
888 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
890 var_to_reg_int(s1, src->prev, REG_ITMP1);
891 var_to_reg_int(s2, src, REG_ITMP2);
892 d = reg_of_var(iptr->dst, REG_ITMP3);
894 store_reg_to_var_int(iptr->dst, d);
897 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
898 /* val.i = constant */
900 var_to_reg_int(s1, src, REG_ITMP1);
901 d = reg_of_var(iptr->dst, REG_ITMP3);
902 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
903 M_IADD_IMM(s1, iptr->val.i, d);
906 ICONST(REG_ITMP2, iptr->val.i);
907 M_IADD(s1, REG_ITMP2, d);
909 store_reg_to_var_int(iptr->dst, d);
912 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
914 var_to_reg_int(s1, src->prev, REG_ITMP1);
915 var_to_reg_int(s2, src, REG_ITMP2);
916 d = reg_of_var(iptr->dst, REG_ITMP3);
918 store_reg_to_var_int(iptr->dst, d);
921 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
922 /* val.l = constant */
924 var_to_reg_int(s1, src, REG_ITMP1);
925 d = reg_of_var(iptr->dst, REG_ITMP3);
926 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
927 M_LADD_IMM(s1, iptr->val.l, d);
930 LCONST(REG_ITMP2, iptr->val.l);
931 M_LADD(s1, REG_ITMP2, d);
933 store_reg_to_var_int(iptr->dst, d);
936 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
938 var_to_reg_int(s1, src->prev, REG_ITMP1);
939 var_to_reg_int(s2, src, REG_ITMP2);
940 d = reg_of_var(iptr->dst, REG_ITMP3);
942 store_reg_to_var_int(iptr->dst, d);
945 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
946 /* val.i = constant */
948 var_to_reg_int(s1, src, REG_ITMP1);
949 d = reg_of_var(iptr->dst, REG_ITMP3);
950 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
951 M_ISUB_IMM(s1, iptr->val.i, d);
954 ICONST(REG_ITMP2, iptr->val.i);
955 M_ISUB(s1, REG_ITMP2, d);
957 store_reg_to_var_int(iptr->dst, d);
960 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
962 var_to_reg_int(s1, src->prev, REG_ITMP1);
963 var_to_reg_int(s2, src, REG_ITMP2);
964 d = reg_of_var(iptr->dst, REG_ITMP3);
966 store_reg_to_var_int(iptr->dst, d);
969 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
970 /* val.l = constant */
972 var_to_reg_int(s1, src, REG_ITMP1);
973 d = reg_of_var(iptr->dst, REG_ITMP3);
974 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
975 M_LSUB_IMM(s1, iptr->val.l, d);
978 LCONST(REG_ITMP2, iptr->val.l);
979 M_LSUB(s1, REG_ITMP2, d);
981 store_reg_to_var_int(iptr->dst, d);
984 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
986 var_to_reg_int(s1, src->prev, REG_ITMP1);
987 var_to_reg_int(s2, src, REG_ITMP2);
988 d = reg_of_var(iptr->dst, REG_ITMP3);
990 store_reg_to_var_int(iptr->dst, d);
993 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
994 /* val.i = constant */
996 var_to_reg_int(s1, src, REG_ITMP1);
997 d = reg_of_var(iptr->dst, REG_ITMP3);
998 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
999 M_IMUL_IMM(s1, iptr->val.i, d);
1002 ICONST(REG_ITMP2, iptr->val.i);
1003 M_IMUL(s1, REG_ITMP2, d);
1005 store_reg_to_var_int(iptr->dst, d);
1008 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1010 var_to_reg_int(s1, src->prev, REG_ITMP1);
1011 var_to_reg_int(s2, src, REG_ITMP2);
1012 d = reg_of_var(iptr->dst, REG_ITMP3);
1014 store_reg_to_var_int(iptr->dst, d);
1017 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
1018 /* val.l = constant */
1020 var_to_reg_int(s1, src, REG_ITMP1);
1021 d = reg_of_var(iptr->dst, REG_ITMP3);
1022 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1023 M_LMUL_IMM(s1, iptr->val.l, d);
1026 LCONST(REG_ITMP2, iptr->val.l);
1027 M_LMUL(s1, REG_ITMP2, d);
1029 store_reg_to_var_int(iptr->dst, d);
1032 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
1033 case ICMD_LDIVPOW2: /* val.i = constant */
1035 var_to_reg_int(s1, src, REG_ITMP1);
1036 d = reg_of_var(iptr->dst, REG_ITMP3);
1037 if (iptr->val.i <= 15) {
1038 M_LDA(REG_ITMP2, s1, (1 << iptr->val.i) -1);
1039 M_CMOVGE(s1, s1, REG_ITMP2);
1042 M_SRA_IMM(s1, 63, REG_ITMP2);
1043 M_SRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
1044 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1046 M_SRA_IMM(REG_ITMP2, iptr->val.i, d);
1047 store_reg_to_var_int(iptr->dst, d);
1050 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1052 var_to_reg_int(s1, src->prev, REG_ITMP1);
1053 var_to_reg_int(s2, src, REG_ITMP2);
1054 d = reg_of_var(iptr->dst, REG_ITMP3);
1055 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1056 M_SLL(s1, REG_ITMP3, d);
1057 M_IADD(d, REG_ZERO, d);
1058 store_reg_to_var_int(iptr->dst, d);
1061 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1062 /* val.i = constant */
1064 var_to_reg_int(s1, src, REG_ITMP1);
1065 d = reg_of_var(iptr->dst, REG_ITMP3);
1066 M_SLL_IMM(s1, iptr->val.i & 0x1f, d);
1067 M_IADD(d, REG_ZERO, d);
1068 store_reg_to_var_int(iptr->dst, d);
1071 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1073 var_to_reg_int(s1, src->prev, REG_ITMP1);
1074 var_to_reg_int(s2, src, REG_ITMP2);
1075 d = reg_of_var(iptr->dst, REG_ITMP3);
1076 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1077 M_SRA(s1, REG_ITMP3, d);
1078 store_reg_to_var_int(iptr->dst, d);
1081 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1082 /* val.i = constant */
1084 var_to_reg_int(s1, src, REG_ITMP1);
1085 d = reg_of_var(iptr->dst, REG_ITMP3);
1086 M_SRA_IMM(s1, iptr->val.i & 0x1f, d);
1087 store_reg_to_var_int(iptr->dst, d);
1090 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1092 var_to_reg_int(s1, src->prev, REG_ITMP1);
1093 var_to_reg_int(s2, src, REG_ITMP2);
1094 d = reg_of_var(iptr->dst, REG_ITMP3);
1095 M_AND_IMM(s2, 0x1f, REG_ITMP2);
1097 M_SRL(d, REG_ITMP2, d);
1098 M_IADD(d, REG_ZERO, d);
1099 store_reg_to_var_int(iptr->dst, d);
1102 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1103 /* val.i = constant */
1105 var_to_reg_int(s1, src, REG_ITMP1);
1106 d = reg_of_var(iptr->dst, REG_ITMP3);
1108 M_SRL_IMM(d, iptr->val.i & 0x1f, d);
1109 M_IADD(d, REG_ZERO, d);
1110 store_reg_to_var_int(iptr->dst, d);
1113 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1115 var_to_reg_int(s1, src->prev, REG_ITMP1);
1116 var_to_reg_int(s2, src, REG_ITMP2);
1117 d = reg_of_var(iptr->dst, REG_ITMP3);
1119 store_reg_to_var_int(iptr->dst, d);
1122 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1123 /* val.l = constant */
1125 var_to_reg_int(s1, src, REG_ITMP1);
1126 d = reg_of_var(iptr->dst, REG_ITMP3);
1127 M_SLL_IMM(s1, iptr->val.l & 0x3f, d);
1128 store_reg_to_var_int(iptr->dst, d);
1131 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1133 var_to_reg_int(s1, src->prev, REG_ITMP1);
1134 var_to_reg_int(s2, src, REG_ITMP2);
1135 d = reg_of_var(iptr->dst, REG_ITMP3);
1137 store_reg_to_var_int(iptr->dst, d);
1140 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1141 /* val.l = constant */
1143 var_to_reg_int(s1, src, REG_ITMP1);
1144 d = reg_of_var(iptr->dst, REG_ITMP3);
1145 M_SRA_IMM(s1, iptr->val.l & 0x3f, d);
1146 store_reg_to_var_int(iptr->dst, d);
1149 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1151 var_to_reg_int(s1, src->prev, REG_ITMP1);
1152 var_to_reg_int(s2, src, REG_ITMP2);
1153 d = reg_of_var(iptr->dst, REG_ITMP3);
1155 store_reg_to_var_int(iptr->dst, d);
1158 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1159 /* val.l = constant */
1161 var_to_reg_int(s1, src, REG_ITMP1);
1162 d = reg_of_var(iptr->dst, REG_ITMP3);
1163 M_SRL_IMM(s1, iptr->val.l & 0x3f, d);
1164 store_reg_to_var_int(iptr->dst, d);
1167 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1170 var_to_reg_int(s1, src->prev, REG_ITMP1);
1171 var_to_reg_int(s2, src, REG_ITMP2);
1172 d = reg_of_var(iptr->dst, REG_ITMP3);
1174 store_reg_to_var_int(iptr->dst, d);
1177 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1178 /* val.i = constant */
1180 var_to_reg_int(s1, src, REG_ITMP1);
1181 d = reg_of_var(iptr->dst, REG_ITMP3);
1182 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1183 M_AND_IMM(s1, iptr->val.i, d);
1185 else if (iptr->val.i == 0xffff) {
1188 else if (iptr->val.i == 0xffffff) {
1189 M_ZAPNOT_IMM(s1, 0x07, d);
1192 ICONST(REG_ITMP2, iptr->val.i);
1193 M_AND(s1, REG_ITMP2, d);
1195 store_reg_to_var_int(iptr->dst, d);
1198 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1199 /* val.i = constant */
1201 var_to_reg_int(s1, src, REG_ITMP1);
1202 d = reg_of_var(iptr->dst, REG_ITMP3);
1204 M_MOV(s1, REG_ITMP1);
1207 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1208 M_AND_IMM(s1, iptr->val.i, d);
1210 M_ISUB(REG_ZERO, s1, d);
1211 M_AND_IMM(d, iptr->val.i, d);
1213 else if (iptr->val.i == 0xffff) {
1216 M_ISUB(REG_ZERO, s1, d);
1219 else if (iptr->val.i == 0xffffff) {
1220 M_ZAPNOT_IMM(s1, 0x07, d);
1222 M_ISUB(REG_ZERO, s1, d);
1223 M_ZAPNOT_IMM(d, 0x07, d);
1226 ICONST(REG_ITMP2, iptr->val.i);
1227 M_AND(s1, REG_ITMP2, d);
1229 M_ISUB(REG_ZERO, s1, d);
1230 M_AND(d, REG_ITMP2, d);
1232 M_ISUB(REG_ZERO, d, d);
1233 store_reg_to_var_int(iptr->dst, d);
1236 case ICMD_IREM0X10001: /* ..., value ==> ..., value % 0x100001 */
1238 /* b = value & 0xffff;
1240 a = ((b - a) & 0xffff) + (b < a);
1242 var_to_reg_int(s1, src, REG_ITMP1);
1243 d = reg_of_var(iptr->dst, REG_ITMP3);
1245 M_MOV(s1, REG_ITMP3);
1249 M_CZEXT(s1, REG_ITMP2);
1250 M_SRA_IMM(s1, 16, d);
1251 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1252 M_ISUB(REG_ITMP2, d, d);
1254 M_IADD(d, REG_ITMP1, d);
1255 M_BR(11 + (s1 == REG_ITMP1));
1256 M_ISUB(REG_ZERO, s1, REG_ITMP1);
1257 M_CZEXT(REG_ITMP1, REG_ITMP2);
1258 M_SRA_IMM(REG_ITMP1, 16, d);
1259 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1260 M_ISUB(REG_ITMP2, d, d);
1262 M_IADD(d, REG_ITMP1, d);
1263 M_ISUB(REG_ZERO, d, d);
1264 if (s1 == REG_ITMP1) {
1265 var_to_reg_int(s1, src, REG_ITMP1);
1267 M_SLL_IMM(s1, 33, REG_ITMP2);
1268 M_CMPEQ(REG_ITMP2, REG_ZERO, REG_ITMP2);
1269 M_ISUB(d, REG_ITMP2, d);
1270 store_reg_to_var_int(iptr->dst, d);
1273 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1274 /* val.l = constant */
1276 var_to_reg_int(s1, src, REG_ITMP1);
1277 d = reg_of_var(iptr->dst, REG_ITMP3);
1278 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1279 M_AND_IMM(s1, iptr->val.l, d);
1281 else if (iptr->val.l == 0xffffL) {
1284 else if (iptr->val.l == 0xffffffL) {
1285 M_ZAPNOT_IMM(s1, 0x07, d);
1287 else if (iptr->val.l == 0xffffffffL) {
1290 else if (iptr->val.l == 0xffffffffffL) {
1291 M_ZAPNOT_IMM(s1, 0x1f, d);
1293 else if (iptr->val.l == 0xffffffffffffL) {
1294 M_ZAPNOT_IMM(s1, 0x3f, d);
1296 else if (iptr->val.l == 0xffffffffffffffL) {
1297 M_ZAPNOT_IMM(s1, 0x7f, d);
1300 LCONST(REG_ITMP2, iptr->val.l);
1301 M_AND(s1, REG_ITMP2, d);
1303 store_reg_to_var_int(iptr->dst, d);
1306 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1307 /* val.l = constant */
1309 var_to_reg_int(s1, src, REG_ITMP1);
1310 d = reg_of_var(iptr->dst, REG_ITMP3);
1312 M_MOV(s1, REG_ITMP1);
1315 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1316 M_AND_IMM(s1, iptr->val.l, d);
1318 M_LSUB(REG_ZERO, s1, d);
1319 M_AND_IMM(d, iptr->val.l, d);
1321 else if (iptr->val.l == 0xffffL) {
1324 M_LSUB(REG_ZERO, s1, d);
1327 else if (iptr->val.l == 0xffffffL) {
1328 M_ZAPNOT_IMM(s1, 0x07, d);
1330 M_LSUB(REG_ZERO, s1, d);
1331 M_ZAPNOT_IMM(d, 0x07, d);
1333 else if (iptr->val.l == 0xffffffffL) {
1336 M_LSUB(REG_ZERO, s1, d);
1339 else if (iptr->val.l == 0xffffffffffL) {
1340 M_ZAPNOT_IMM(s1, 0x1f, d);
1342 M_LSUB(REG_ZERO, s1, d);
1343 M_ZAPNOT_IMM(d, 0x1f, d);
1345 else if (iptr->val.l == 0xffffffffffffL) {
1346 M_ZAPNOT_IMM(s1, 0x3f, d);
1348 M_LSUB(REG_ZERO, s1, d);
1349 M_ZAPNOT_IMM(d, 0x3f, d);
1351 else if (iptr->val.l == 0xffffffffffffffL) {
1352 M_ZAPNOT_IMM(s1, 0x7f, d);
1354 M_LSUB(REG_ZERO, s1, d);
1355 M_ZAPNOT_IMM(d, 0x7f, d);
1358 LCONST(REG_ITMP2, iptr->val.l);
1359 M_AND(s1, REG_ITMP2, d);
1361 M_LSUB(REG_ZERO, s1, d);
1362 M_AND(d, REG_ITMP2, d);
1364 M_LSUB(REG_ZERO, d, d);
1365 store_reg_to_var_int(iptr->dst, d);
1368 case ICMD_LREM0X10001:/* ..., value ==> ..., value % 0x10001 */
1370 var_to_reg_int(s1, src, REG_ITMP1);
1371 d = reg_of_var(iptr->dst, REG_ITMP3);
1373 M_MOV(s1, REG_ITMP3);
1376 M_CZEXT(s1, REG_ITMP2);
1377 M_SRA_IMM(s1, 16, d);
1378 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1379 M_LSUB(REG_ITMP2, d, d);
1381 M_LADD(d, REG_ITMP1, d);
1382 M_LDA(REG_ITMP2, REG_ZERO, -1);
1383 M_SRL_IMM(REG_ITMP2, 33, REG_ITMP2);
1384 if (s1 == REG_ITMP1) {
1385 var_to_reg_int(s1, src, REG_ITMP1);
1387 M_CMPULT(s1, REG_ITMP2, REG_ITMP2);
1388 M_BNEZ(REG_ITMP2, 11);
1389 M_LDA(d, REG_ZERO, -257);
1390 M_ZAPNOT_IMM(d, 0xcd, d);
1391 M_LSUB(REG_ZERO, s1, REG_ITMP2);
1392 M_CMOVGE(s1, s1, REG_ITMP2);
1393 M_UMULH(REG_ITMP2, d, REG_ITMP2);
1394 M_SRL_IMM(REG_ITMP2, 16, REG_ITMP2);
1395 M_LSUB(REG_ZERO, REG_ITMP2, d);
1396 M_CMOVGE(s1, REG_ITMP2, d);
1397 M_SLL_IMM(d, 16, REG_ITMP2);
1398 M_LADD(d, REG_ITMP2, d);
1400 store_reg_to_var_int(iptr->dst, d);
1403 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1406 var_to_reg_int(s1, src->prev, REG_ITMP1);
1407 var_to_reg_int(s2, src, REG_ITMP2);
1408 d = reg_of_var(iptr->dst, REG_ITMP3);
1410 store_reg_to_var_int(iptr->dst, d);
1413 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1414 /* val.i = constant */
1416 var_to_reg_int(s1, src, REG_ITMP1);
1417 d = reg_of_var(iptr->dst, REG_ITMP3);
1418 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1419 M_OR_IMM(s1, iptr->val.i, d);
1422 ICONST(REG_ITMP2, iptr->val.i);
1423 M_OR(s1, REG_ITMP2, d);
1425 store_reg_to_var_int(iptr->dst, d);
1428 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1429 /* val.l = constant */
1431 var_to_reg_int(s1, src, REG_ITMP1);
1432 d = reg_of_var(iptr->dst, REG_ITMP3);
1433 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1434 M_OR_IMM(s1, iptr->val.l, d);
1437 LCONST(REG_ITMP2, iptr->val.l);
1438 M_OR(s1, REG_ITMP2, d);
1440 store_reg_to_var_int(iptr->dst, d);
1443 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1446 var_to_reg_int(s1, src->prev, REG_ITMP1);
1447 var_to_reg_int(s2, src, REG_ITMP2);
1448 d = reg_of_var(iptr->dst, REG_ITMP3);
1450 store_reg_to_var_int(iptr->dst, d);
1453 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1454 /* val.i = constant */
1456 var_to_reg_int(s1, src, REG_ITMP1);
1457 d = reg_of_var(iptr->dst, REG_ITMP3);
1458 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1459 M_XOR_IMM(s1, iptr->val.i, d);
1462 ICONST(REG_ITMP2, iptr->val.i);
1463 M_XOR(s1, REG_ITMP2, d);
1465 store_reg_to_var_int(iptr->dst, d);
1468 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1469 /* val.l = constant */
1471 var_to_reg_int(s1, src, REG_ITMP1);
1472 d = reg_of_var(iptr->dst, REG_ITMP3);
1473 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1474 M_XOR_IMM(s1, iptr->val.l, d);
1477 LCONST(REG_ITMP2, iptr->val.l);
1478 M_XOR(s1, REG_ITMP2, d);
1480 store_reg_to_var_int(iptr->dst, d);
1484 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1486 var_to_reg_int(s1, src->prev, REG_ITMP1);
1487 var_to_reg_int(s2, src, REG_ITMP2);
1488 d = reg_of_var(iptr->dst, REG_ITMP3);
1489 M_CMPLT(s1, s2, REG_ITMP3);
1490 M_CMPLT(s2, s1, REG_ITMP1);
1491 M_LSUB (REG_ITMP1, REG_ITMP3, d);
1492 store_reg_to_var_int(iptr->dst, d);
1496 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1497 /* op1 = variable, val.i = constant */
1499 var = &(locals[iptr->op1][TYPE_INT]);
1500 if (var->flags & INMEMORY) {
1502 M_LLD(s1, REG_SP, 8 * var->regoff);
1506 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1507 M_IADD_IMM(s1, iptr->val.i, s1);
1509 else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1510 M_ISUB_IMM(s1, (-iptr->val.i), s1);
1513 M_LDA (s1, s1, iptr->val.i);
1514 M_IADD(s1, REG_ZERO, s1);
1516 if (var->flags & INMEMORY)
1517 M_LST(s1, REG_SP, 8 * var->regoff);
1521 /* floating operations ************************************************/
1523 case ICMD_FNEG: /* ..., value ==> ..., - value */
1525 var_to_reg_flt(s1, src, REG_FTMP1);
1526 d = reg_of_var(iptr->dst, REG_FTMP3);
1528 store_reg_to_var_flt(iptr->dst, d);
1531 case ICMD_DNEG: /* ..., value ==> ..., - value */
1533 var_to_reg_flt(s1, src, REG_FTMP1);
1534 d = reg_of_var(iptr->dst, REG_FTMP3);
1536 store_reg_to_var_flt(iptr->dst, d);
1539 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1541 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1542 var_to_reg_flt(s2, src, REG_FTMP2);
1543 d = reg_of_var(iptr->dst, REG_FTMP3);
1551 store_reg_to_var_flt(iptr->dst, d);
1554 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1556 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1557 var_to_reg_flt(s2, src, REG_FTMP2);
1558 d = reg_of_var(iptr->dst, REG_FTMP3);
1566 store_reg_to_var_flt(iptr->dst, d);
1569 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1571 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1572 var_to_reg_flt(s2, src, REG_FTMP2);
1573 d = reg_of_var(iptr->dst, REG_FTMP3);
1581 store_reg_to_var_flt(iptr->dst, d);
1584 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1586 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1587 var_to_reg_flt(s2, src, REG_FTMP2);
1588 d = reg_of_var(iptr->dst, REG_FTMP3);
1596 store_reg_to_var_flt(iptr->dst, d);
1599 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1601 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1602 var_to_reg_flt(s2, src, REG_FTMP2);
1603 d = reg_of_var(iptr->dst, REG_FTMP3);
1611 store_reg_to_var_flt(iptr->dst, d);
1614 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1616 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1617 var_to_reg_flt(s2, src, REG_FTMP2);
1618 d = reg_of_var(iptr->dst, REG_FTMP3);
1626 store_reg_to_var_flt(iptr->dst, d);
1629 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1631 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1632 var_to_reg_flt(s2, src, REG_FTMP2);
1633 d = reg_of_var(iptr->dst, REG_FTMP3);
1641 store_reg_to_var_flt(iptr->dst, d);
1644 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1646 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1647 var_to_reg_flt(s2, src, REG_FTMP2);
1648 d = reg_of_var(iptr->dst, REG_FTMP3);
1656 store_reg_to_var_flt(iptr->dst, d);
1659 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1661 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1662 var_to_reg_flt(s2, src, REG_FTMP2);
1663 d = reg_of_var(iptr->dst, REG_FTMP3);
1665 M_FDIVS(s1,s2, REG_FTMP3);
1667 M_CVTDL_CS(REG_FTMP3, REG_FTMP3); /* round to integer */
1669 M_CVTLF(REG_FTMP3, REG_FTMP3);
1670 M_FMULS(REG_FTMP3, s2, REG_FTMP3);
1672 M_FSUBS(s1, REG_FTMP3, d);
1676 M_FDIV(s1,s2, REG_FTMP3);
1677 M_CVTDL_C(REG_FTMP3, REG_FTMP3); /* round to integer */
1678 M_CVTLF(REG_FTMP3, REG_FTMP3);
1679 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1680 M_FSUB(s1, REG_FTMP3, d);
1682 store_reg_to_var_flt(iptr->dst, d);
1685 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1687 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1688 var_to_reg_flt(s2, src, REG_FTMP2);
1689 d = reg_of_var(iptr->dst, REG_FTMP3);
1691 M_DDIVS(s1,s2, REG_FTMP3);
1693 M_CVTDL_CS(REG_FTMP3, REG_FTMP3); /* round to integer */
1695 M_CVTLD(REG_FTMP3, REG_FTMP3);
1696 M_DMULS(REG_FTMP3, s2, REG_FTMP3);
1698 M_DSUBS(s1, REG_FTMP3, d);
1702 M_DDIV(s1,s2, REG_FTMP3);
1703 M_CVTDL_C(REG_FTMP3, REG_FTMP3); /* round to integer */
1704 M_CVTLD(REG_FTMP3, REG_FTMP3);
1705 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1706 M_DSUB(s1, REG_FTMP3, d);
1708 store_reg_to_var_flt(iptr->dst, d);
1711 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1713 var_to_reg_int(s1, src, REG_ITMP1);
1714 d = reg_of_var(iptr->dst, REG_FTMP3);
1715 a = dseg_adddouble(0.0);
1716 M_LST (s1, REG_PV, a);
1717 M_DLD (d, REG_PV, a);
1719 store_reg_to_var_flt(iptr->dst, d);
1722 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1724 var_to_reg_int(s1, src, REG_ITMP1);
1725 d = reg_of_var(iptr->dst, REG_FTMP3);
1726 a = dseg_adddouble(0.0);
1727 M_LST (s1, REG_PV, a);
1728 M_DLD (d, REG_PV, a);
1730 store_reg_to_var_flt(iptr->dst, d);
1733 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1735 var_to_reg_flt(s1, src, REG_FTMP1);
1736 d = reg_of_var(iptr->dst, REG_ITMP3);
1737 a = dseg_adddouble(0.0);
1739 M_CVTDL_CS(s1, REG_FTMP1);
1741 M_CVTLIS(REG_FTMP1, REG_FTMP2);
1745 M_CVTDL_C(s1, REG_FTMP1);
1746 M_CVTLI(REG_FTMP1, REG_FTMP2);
1748 M_DST (REG_FTMP1, REG_PV, a);
1749 M_ILD (d, REG_PV, a);
1750 store_reg_to_var_int(iptr->dst, d);
1753 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1755 var_to_reg_flt(s1, src, REG_FTMP1);
1756 d = reg_of_var(iptr->dst, REG_ITMP3);
1757 a = dseg_adddouble(0.0);
1759 M_CVTDL_CS(s1, REG_FTMP1);
1763 M_CVTDL_C(s1, REG_FTMP1);
1765 M_DST (REG_FTMP1, REG_PV, a);
1766 M_LLD (d, REG_PV, a);
1767 store_reg_to_var_int(iptr->dst, d);
1770 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1772 var_to_reg_flt(s1, src, REG_FTMP1);
1773 d = reg_of_var(iptr->dst, REG_FTMP3);
1775 store_reg_to_var_flt(iptr->dst, d);
1778 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1780 var_to_reg_flt(s1, src, REG_FTMP1);
1781 d = reg_of_var(iptr->dst, REG_FTMP3);
1789 store_reg_to_var_flt(iptr->dst, d);
1792 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1794 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1795 var_to_reg_flt(s2, src, REG_FTMP2);
1796 d = reg_of_var(iptr->dst, REG_ITMP3);
1798 M_LSUB_IMM(REG_ZERO, 1, d);
1799 M_FCMPEQS(s1, s2, REG_FTMP3);
1801 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1803 M_FCMPLTS(s2, s1, REG_FTMP3);
1805 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1806 M_LADD_IMM(REG_ZERO, 1, d);
1809 M_LSUB_IMM(REG_ZERO, 1, d);
1810 M_FCMPEQ(s1, s2, REG_FTMP3);
1811 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1813 M_FCMPLT(s2, s1, REG_FTMP3);
1814 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1815 M_LADD_IMM(REG_ZERO, 1, d);
1817 store_reg_to_var_int(iptr->dst, d);
1820 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1822 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1823 var_to_reg_flt(s2, src, REG_FTMP2);
1824 d = reg_of_var(iptr->dst, REG_ITMP3);
1826 M_LADD_IMM(REG_ZERO, 1, d);
1827 M_FCMPEQS(s1, s2, REG_FTMP3);
1829 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1831 M_FCMPLTS(s1, s2, REG_FTMP3);
1833 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1834 M_LSUB_IMM(REG_ZERO, 1, d);
1837 M_LADD_IMM(REG_ZERO, 1, d);
1838 M_FCMPEQ(s1, s2, REG_FTMP3);
1839 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1841 M_FCMPLT(s1, s2, REG_FTMP3);
1842 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1843 M_LSUB_IMM(REG_ZERO, 1, d);
1845 store_reg_to_var_int(iptr->dst, d);
1849 /* memory operations **************************************************/
1851 #define gen_bound_check \
1853 M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\
1854 M_CMPULT(s2, REG_ITMP3, REG_ITMP3);\
1855 M_BEQZ(REG_ITMP3, 0);\
1856 mcode_addxboundrefs(mcodeptr);\
1859 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1861 var_to_reg_int(s1, src, REG_ITMP1);
1862 d = reg_of_var(iptr->dst, REG_ITMP3);
1863 gen_nullptr_check(s1);
1864 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1865 store_reg_to_var_int(iptr->dst, d);
1868 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1870 var_to_reg_int(s1, src->prev, REG_ITMP1);
1871 var_to_reg_int(s2, src, REG_ITMP2);
1872 d = reg_of_var(iptr->dst, REG_ITMP3);
1873 gen_nullptr_check(s1);
1875 M_SAADDQ(s2, s1, REG_ITMP1);
1876 M_ALD( d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1877 store_reg_to_var_int(iptr->dst, d);
1880 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1882 var_to_reg_int(s1, src->prev, REG_ITMP1);
1883 var_to_reg_int(s2, src, REG_ITMP2);
1884 d = reg_of_var(iptr->dst, REG_ITMP3);
1885 gen_nullptr_check(s1);
1887 M_S8ADDQ(s2, s1, REG_ITMP1);
1888 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1889 store_reg_to_var_int(iptr->dst, d);
1892 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1894 var_to_reg_int(s1, src->prev, REG_ITMP1);
1895 var_to_reg_int(s2, src, REG_ITMP2);
1896 d = reg_of_var(iptr->dst, REG_ITMP3);
1897 gen_nullptr_check(s1);
1899 M_S4ADDQ(s2, s1, REG_ITMP1);
1900 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1901 store_reg_to_var_int(iptr->dst, d);
1904 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1906 var_to_reg_int(s1, src->prev, REG_ITMP1);
1907 var_to_reg_int(s2, src, REG_ITMP2);
1908 d = reg_of_var(iptr->dst, REG_FTMP3);
1909 gen_nullptr_check(s1);
1911 M_S4ADDQ(s2, s1, REG_ITMP1);
1912 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1913 store_reg_to_var_flt(iptr->dst, d);
1916 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1918 var_to_reg_int(s1, src->prev, REG_ITMP1);
1919 var_to_reg_int(s2, src, REG_ITMP2);
1920 d = reg_of_var(iptr->dst, REG_FTMP3);
1921 gen_nullptr_check(s1);
1923 M_S8ADDQ(s2, s1, REG_ITMP1);
1924 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1925 store_reg_to_var_flt(iptr->dst, d);
1928 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1930 var_to_reg_int(s1, src->prev, REG_ITMP1);
1931 var_to_reg_int(s2, src, REG_ITMP2);
1932 d = reg_of_var(iptr->dst, REG_ITMP3);
1933 gen_nullptr_check(s1);
1935 if (has_ext_instr_set) {
1936 M_LADD(s2, s1, REG_ITMP1);
1937 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1938 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1941 M_LADD (s2, s1, REG_ITMP1);
1942 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1943 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1944 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1945 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
1947 store_reg_to_var_int(iptr->dst, d);
1950 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1952 var_to_reg_int(s1, src->prev, REG_ITMP1);
1953 var_to_reg_int(s2, src, REG_ITMP2);
1954 d = reg_of_var(iptr->dst, REG_ITMP3);
1955 gen_nullptr_check(s1);
1957 if (has_ext_instr_set) {
1958 M_LADD(s2, s1, REG_ITMP1);
1959 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1960 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1964 M_LADD(s2, s1, REG_ITMP1);
1965 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1966 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1967 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1968 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1969 M_SRA_IMM(d, 48, d);
1971 store_reg_to_var_int(iptr->dst, d);
1974 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1976 var_to_reg_int(s1, src->prev, REG_ITMP1);
1977 var_to_reg_int(s2, src, REG_ITMP2);
1978 d = reg_of_var(iptr->dst, REG_ITMP3);
1979 gen_nullptr_check(s1);
1981 if (has_ext_instr_set) {
1982 M_LADD (s2, s1, REG_ITMP1);
1983 M_BLDU (d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1987 M_LADD(s2, s1, REG_ITMP1);
1988 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1989 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
1990 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1991 M_SRA_IMM(d, 56, d);
1993 store_reg_to_var_int(iptr->dst, d);
1997 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1999 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2000 var_to_reg_int(s2, src->prev, REG_ITMP2);
2001 gen_nullptr_check(s1);
2003 var_to_reg_int(s3, src, REG_ITMP3);
2004 M_SAADDQ(s2, s1, REG_ITMP1);
2005 M_AST (s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
2008 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
2010 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2011 var_to_reg_int(s2, src->prev, REG_ITMP2);
2012 gen_nullptr_check(s1);
2014 var_to_reg_int(s3, src, REG_ITMP3);
2015 M_S8ADDQ(s2, s1, REG_ITMP1);
2016 M_LST (s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
2019 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
2021 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2022 var_to_reg_int(s2, src->prev, REG_ITMP2);
2023 gen_nullptr_check(s1);
2025 var_to_reg_int(s3, src, REG_ITMP3);
2026 M_S4ADDQ(s2, s1, REG_ITMP1);
2027 M_IST (s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
2030 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
2032 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2033 var_to_reg_int(s2, src->prev, REG_ITMP2);
2034 gen_nullptr_check(s1);
2036 var_to_reg_flt(s3, src, REG_FTMP3);
2037 M_S4ADDQ(s2, s1, REG_ITMP1);
2038 M_FST (s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
2041 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
2043 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2044 var_to_reg_int(s2, src->prev, REG_ITMP2);
2045 gen_nullptr_check(s1);
2047 var_to_reg_flt(s3, src, REG_FTMP3);
2048 M_S8ADDQ(s2, s1, REG_ITMP1);
2049 M_DST (s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
2052 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
2054 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2055 var_to_reg_int(s2, src->prev, REG_ITMP2);
2056 gen_nullptr_check(s1);
2058 var_to_reg_int(s3, src, REG_ITMP3);
2059 if (has_ext_instr_set) {
2060 M_LADD(s2, s1, REG_ITMP1);
2061 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2062 M_SST (s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
2065 M_LADD (s2, s1, REG_ITMP1);
2066 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2067 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2068 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2069 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
2070 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2071 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2072 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2076 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
2078 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2079 var_to_reg_int(s2, src->prev, REG_ITMP2);
2080 gen_nullptr_check(s1);
2082 var_to_reg_int(s3, src, REG_ITMP3);
2083 if (has_ext_instr_set) {
2084 M_LADD(s2, s1, REG_ITMP1);
2085 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2086 M_SST (s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2089 M_LADD (s2, s1, REG_ITMP1);
2090 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2091 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2092 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2093 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
2094 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2095 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2096 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2100 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
2102 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2103 var_to_reg_int(s2, src->prev, REG_ITMP2);
2104 gen_nullptr_check(s1);
2106 var_to_reg_int(s3, src, REG_ITMP3);
2107 if (has_ext_instr_set) {
2108 M_LADD(s2, s1, REG_ITMP1);
2109 M_BST (s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2112 M_LADD (s2, s1, REG_ITMP1);
2113 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2114 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2115 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
2116 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2117 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2118 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2123 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2124 /* op1 = type, val.a = field address */
2126 a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value));
2127 M_ALD(REG_ITMP1, REG_PV, a);
2128 switch (iptr->op1) {
2130 var_to_reg_int(s2, src, REG_ITMP2);
2131 M_IST(s2, REG_ITMP1, 0);
2134 var_to_reg_int(s2, src, REG_ITMP2);
2135 M_LST(s2, REG_ITMP1, 0);
2138 var_to_reg_int(s2, src, REG_ITMP2);
2139 M_AST(s2, REG_ITMP1, 0);
2142 var_to_reg_flt(s2, src, REG_FTMP2);
2143 M_FST(s2, REG_ITMP1, 0);
2146 var_to_reg_flt(s2, src, REG_FTMP2);
2147 M_DST(s2, REG_ITMP1, 0);
2149 default: panic ("internal error");
2153 case ICMD_GETSTATIC: /* ... ==> ..., value */
2154 /* op1 = type, val.a = field address */
2156 a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value));
2157 M_ALD(REG_ITMP1, REG_PV, a);
2158 switch (iptr->op1) {
2160 d = reg_of_var(iptr->dst, REG_ITMP3);
2161 M_ILD(d, REG_ITMP1, 0);
2162 store_reg_to_var_int(iptr->dst, d);
2165 d = reg_of_var(iptr->dst, REG_ITMP3);
2166 M_LLD(d, REG_ITMP1, 0);
2167 store_reg_to_var_int(iptr->dst, d);
2170 d = reg_of_var(iptr->dst, REG_ITMP3);
2171 M_ALD(d, REG_ITMP1, 0);
2172 store_reg_to_var_int(iptr->dst, d);
2175 d = reg_of_var(iptr->dst, REG_FTMP1);
2176 M_FLD(d, REG_ITMP1, 0);
2177 store_reg_to_var_flt(iptr->dst, d);
2180 d = reg_of_var(iptr->dst, REG_FTMP1);
2181 M_DLD(d, REG_ITMP1, 0);
2182 store_reg_to_var_flt(iptr->dst, d);
2184 default: panic ("internal error");
2189 case ICMD_PUTFIELD: /* ..., value ==> ... */
2190 /* op1 = type, val.i = field offset */
2192 a = ((fieldinfo *)(iptr->val.a))->offset;
2193 switch (iptr->op1) {
2195 var_to_reg_int(s1, src->prev, REG_ITMP1);
2196 var_to_reg_int(s2, src, REG_ITMP2);
2197 gen_nullptr_check(s1);
2201 var_to_reg_int(s1, src->prev, REG_ITMP1);
2202 var_to_reg_int(s2, src, REG_ITMP2);
2203 gen_nullptr_check(s1);
2207 var_to_reg_int(s1, src->prev, REG_ITMP1);
2208 var_to_reg_int(s2, src, REG_ITMP2);
2209 gen_nullptr_check(s1);
2213 var_to_reg_int(s1, src->prev, REG_ITMP1);
2214 var_to_reg_flt(s2, src, REG_FTMP2);
2215 gen_nullptr_check(s1);
2219 var_to_reg_int(s1, src->prev, REG_ITMP1);
2220 var_to_reg_flt(s2, src, REG_FTMP2);
2221 gen_nullptr_check(s1);
2224 default: panic ("internal error");
2228 case ICMD_GETFIELD: /* ... ==> ..., value */
2229 /* op1 = type, val.i = field offset */
2231 a = ((fieldinfo *)(iptr->val.a))->offset;
2232 switch (iptr->op1) {
2234 var_to_reg_int(s1, src, REG_ITMP1);
2235 d = reg_of_var(iptr->dst, REG_ITMP3);
2236 gen_nullptr_check(s1);
2238 store_reg_to_var_int(iptr->dst, d);
2241 var_to_reg_int(s1, src, REG_ITMP1);
2242 d = reg_of_var(iptr->dst, REG_ITMP3);
2243 gen_nullptr_check(s1);
2245 store_reg_to_var_int(iptr->dst, d);
2248 var_to_reg_int(s1, src, REG_ITMP1);
2249 d = reg_of_var(iptr->dst, REG_ITMP3);
2250 gen_nullptr_check(s1);
2252 store_reg_to_var_int(iptr->dst, d);
2255 var_to_reg_int(s1, src, REG_ITMP1);
2256 d = reg_of_var(iptr->dst, REG_FTMP1);
2257 gen_nullptr_check(s1);
2259 store_reg_to_var_flt(iptr->dst, d);
2262 var_to_reg_int(s1, src, REG_ITMP1);
2263 d = reg_of_var(iptr->dst, REG_FTMP1);
2264 gen_nullptr_check(s1);
2266 store_reg_to_var_flt(iptr->dst, d);
2268 default: panic ("internal error");
2273 /* branch operations **************************************************/
2275 #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}}
2277 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2279 var_to_reg_int(s1, src, REG_ITMP1);
2280 M_INTMOVE(s1, REG_ITMP1_XPTR);
2281 a = dseg_addaddress(asm_handle_exception);
2282 M_ALD(REG_ITMP2, REG_PV, a);
2283 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2287 case ICMD_GOTO: /* ... ==> ... */
2288 /* op1 = target JavaVM pc */
2290 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2294 case ICMD_JSR: /* ... ==> ... */
2295 /* op1 = target JavaVM pc */
2297 M_BSR(REG_ITMP1, 0);
2298 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2301 case ICMD_RET: /* ... ==> ... */
2302 /* op1 = local variable */
2304 var = &(locals[iptr->op1][TYPE_ADR]);
2305 if (var->flags & INMEMORY) {
2306 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2307 M_RET(REG_ZERO, REG_ITMP1);
2310 M_RET(REG_ZERO, var->regoff);
2314 case ICMD_IFNULL: /* ..., value ==> ... */
2315 /* op1 = target JavaVM pc */
2317 var_to_reg_int(s1, src, REG_ITMP1);
2319 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2322 case ICMD_IFNONNULL: /* ..., value ==> ... */
2323 /* op1 = target JavaVM pc */
2325 var_to_reg_int(s1, src, REG_ITMP1);
2327 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2330 case ICMD_IFEQ: /* ..., value ==> ... */
2331 /* op1 = target JavaVM pc, val.i = constant */
2333 var_to_reg_int(s1, src, REG_ITMP1);
2334 if (iptr->val.i == 0) {
2338 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2339 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2342 ICONST(REG_ITMP2, iptr->val.i);
2343 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2345 M_BNEZ(REG_ITMP1, 0);
2347 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2350 case ICMD_IFLT: /* ..., value ==> ... */
2351 /* op1 = target JavaVM pc, val.i = constant */
2353 var_to_reg_int(s1, src, REG_ITMP1);
2354 if (iptr->val.i == 0) {
2358 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2359 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2362 ICONST(REG_ITMP2, iptr->val.i);
2363 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2365 M_BNEZ(REG_ITMP1, 0);
2367 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2370 case ICMD_IFLE: /* ..., value ==> ... */
2371 /* op1 = target JavaVM pc, val.i = constant */
2373 var_to_reg_int(s1, src, REG_ITMP1);
2374 if (iptr->val.i == 0) {
2378 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2379 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2382 ICONST(REG_ITMP2, iptr->val.i);
2383 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2385 M_BNEZ(REG_ITMP1, 0);
2387 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2390 case ICMD_IFNE: /* ..., value ==> ... */
2391 /* op1 = target JavaVM pc, val.i = constant */
2393 var_to_reg_int(s1, src, REG_ITMP1);
2394 if (iptr->val.i == 0) {
2398 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2399 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2402 ICONST(REG_ITMP2, iptr->val.i);
2403 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2405 M_BEQZ(REG_ITMP1, 0);
2407 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2410 case ICMD_IFGT: /* ..., value ==> ... */
2411 /* op1 = target JavaVM pc, val.i = constant */
2413 var_to_reg_int(s1, src, REG_ITMP1);
2414 if (iptr->val.i == 0) {
2418 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2419 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2422 ICONST(REG_ITMP2, iptr->val.i);
2423 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2425 M_BEQZ(REG_ITMP1, 0);
2427 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2430 case ICMD_IFGE: /* ..., value ==> ... */
2431 /* op1 = target JavaVM pc, val.i = constant */
2433 var_to_reg_int(s1, src, REG_ITMP1);
2434 if (iptr->val.i == 0) {
2438 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2439 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2442 ICONST(REG_ITMP2, iptr->val.i);
2443 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2445 M_BEQZ(REG_ITMP1, 0);
2447 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2450 case ICMD_IF_LEQ: /* ..., value ==> ... */
2451 /* op1 = target JavaVM pc, val.l = constant */
2453 var_to_reg_int(s1, src, REG_ITMP1);
2454 if (iptr->val.l == 0) {
2458 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2459 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2462 LCONST(REG_ITMP2, iptr->val.l);
2463 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2465 M_BNEZ(REG_ITMP1, 0);
2467 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2470 case ICMD_IF_LLT: /* ..., value ==> ... */
2471 /* op1 = target JavaVM pc, val.l = constant */
2473 var_to_reg_int(s1, src, REG_ITMP1);
2474 if (iptr->val.l == 0) {
2478 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2479 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2482 LCONST(REG_ITMP2, iptr->val.l);
2483 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2485 M_BNEZ(REG_ITMP1, 0);
2487 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2490 case ICMD_IF_LLE: /* ..., value ==> ... */
2491 /* op1 = target JavaVM pc, val.l = constant */
2493 var_to_reg_int(s1, src, REG_ITMP1);
2494 if (iptr->val.l == 0) {
2498 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2499 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2502 LCONST(REG_ITMP2, iptr->val.l);
2503 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2505 M_BNEZ(REG_ITMP1, 0);
2507 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2510 case ICMD_IF_LNE: /* ..., value ==> ... */
2511 /* op1 = target JavaVM pc, val.l = constant */
2513 var_to_reg_int(s1, src, REG_ITMP1);
2514 if (iptr->val.l == 0) {
2518 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2519 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2522 LCONST(REG_ITMP2, iptr->val.l);
2523 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2525 M_BEQZ(REG_ITMP1, 0);
2527 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2530 case ICMD_IF_LGT: /* ..., value ==> ... */
2531 /* op1 = target JavaVM pc, val.l = constant */
2533 var_to_reg_int(s1, src, REG_ITMP1);
2534 if (iptr->val.l == 0) {
2538 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2539 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2542 LCONST(REG_ITMP2, iptr->val.l);
2543 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2545 M_BEQZ(REG_ITMP1, 0);
2547 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2550 case ICMD_IF_LGE: /* ..., value ==> ... */
2551 /* op1 = target JavaVM pc, val.l = constant */
2553 var_to_reg_int(s1, src, REG_ITMP1);
2554 if (iptr->val.l == 0) {
2558 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2559 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2562 LCONST(REG_ITMP2, iptr->val.l);
2563 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2565 M_BEQZ(REG_ITMP1, 0);
2567 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2570 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2571 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2572 case ICMD_IF_ACMPEQ:
2574 var_to_reg_int(s1, src->prev, REG_ITMP1);
2575 var_to_reg_int(s2, src, REG_ITMP2);
2576 M_CMPEQ(s1, s2, REG_ITMP1);
2577 M_BNEZ(REG_ITMP1, 0);
2578 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2581 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2582 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2583 case ICMD_IF_ACMPNE:
2585 var_to_reg_int(s1, src->prev, REG_ITMP1);
2586 var_to_reg_int(s2, src, REG_ITMP2);
2587 M_CMPEQ(s1, s2, REG_ITMP1);
2588 M_BEQZ(REG_ITMP1, 0);
2589 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2592 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2593 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2595 var_to_reg_int(s1, src->prev, REG_ITMP1);
2596 var_to_reg_int(s2, src, REG_ITMP2);
2597 M_CMPLT(s1, s2, REG_ITMP1);
2598 M_BNEZ(REG_ITMP1, 0);
2599 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2602 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2603 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2605 var_to_reg_int(s1, src->prev, REG_ITMP1);
2606 var_to_reg_int(s2, src, REG_ITMP2);
2607 M_CMPLE(s1, s2, REG_ITMP1);
2608 M_BEQZ(REG_ITMP1, 0);
2609 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2612 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2613 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2615 var_to_reg_int(s1, src->prev, REG_ITMP1);
2616 var_to_reg_int(s2, src, REG_ITMP2);
2617 M_CMPLE(s1, s2, REG_ITMP1);
2618 M_BNEZ(REG_ITMP1, 0);
2619 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2622 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2623 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2625 var_to_reg_int(s1, src->prev, REG_ITMP1);
2626 var_to_reg_int(s2, src, REG_ITMP2);
2627 M_CMPLT(s1, s2, REG_ITMP1);
2628 M_BEQZ(REG_ITMP1, 0);
2629 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2632 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2634 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2637 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2638 /* val.i = constant */
2640 var_to_reg_int(s1, src, REG_ITMP1);
2641 d = reg_of_var(iptr->dst, REG_ITMP3);
2643 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2644 if ((a == 1) && (iptr[1].val.i == 0)) {
2645 M_CMPEQ(s1, REG_ZERO, d);
2646 store_reg_to_var_int(iptr->dst, d);
2649 if ((a == 0) && (iptr[1].val.i == 1)) {
2650 M_CMPEQ(s1, REG_ZERO, d);
2652 store_reg_to_var_int(iptr->dst, d);
2656 M_MOV(s1, REG_ITMP1);
2659 ICONST(d, iptr[1].val.i);
2661 if ((a >= 0) && (a <= 255)) {
2662 M_CMOVEQ_IMM(s1, a, d);
2665 ICONST(REG_ITMP2, a);
2666 M_CMOVEQ(s1, REG_ITMP2, d);
2668 store_reg_to_var_int(iptr->dst, d);
2671 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2672 /* val.i = constant */
2674 var_to_reg_int(s1, src, REG_ITMP1);
2675 d = reg_of_var(iptr->dst, REG_ITMP3);
2677 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2678 if ((a == 0) && (iptr[1].val.i == 1)) {
2679 M_CMPEQ(s1, REG_ZERO, d);
2680 store_reg_to_var_int(iptr->dst, d);
2683 if ((a == 1) && (iptr[1].val.i == 0)) {
2684 M_CMPEQ(s1, REG_ZERO, d);
2686 store_reg_to_var_int(iptr->dst, d);
2690 M_MOV(s1, REG_ITMP1);
2693 ICONST(d, iptr[1].val.i);
2695 if ((a >= 0) && (a <= 255)) {
2696 M_CMOVNE_IMM(s1, a, d);
2699 ICONST(REG_ITMP2, a);
2700 M_CMOVNE(s1, REG_ITMP2, d);
2702 store_reg_to_var_int(iptr->dst, d);
2705 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2706 /* val.i = constant */
2708 var_to_reg_int(s1, src, REG_ITMP1);
2709 d = reg_of_var(iptr->dst, REG_ITMP3);
2711 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2712 if ((a == 1) && (iptr[1].val.i == 0)) {
2713 M_CMPLT(s1, REG_ZERO, d);
2714 store_reg_to_var_int(iptr->dst, d);
2717 if ((a == 0) && (iptr[1].val.i == 1)) {
2718 M_CMPLE(REG_ZERO, s1, d);
2719 store_reg_to_var_int(iptr->dst, d);
2723 M_MOV(s1, REG_ITMP1);
2726 ICONST(d, iptr[1].val.i);
2728 if ((a >= 0) && (a <= 255)) {
2729 M_CMOVLT_IMM(s1, a, d);
2732 ICONST(REG_ITMP2, a);
2733 M_CMOVLT(s1, REG_ITMP2, d);
2735 store_reg_to_var_int(iptr->dst, d);
2738 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2739 /* val.i = constant */
2741 var_to_reg_int(s1, src, REG_ITMP1);
2742 d = reg_of_var(iptr->dst, REG_ITMP3);
2744 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2745 if ((a == 1) && (iptr[1].val.i == 0)) {
2746 M_CMPLE(REG_ZERO, s1, d);
2747 store_reg_to_var_int(iptr->dst, d);
2750 if ((a == 0) && (iptr[1].val.i == 1)) {
2751 M_CMPLT(s1, REG_ZERO, d);
2752 store_reg_to_var_int(iptr->dst, d);
2756 M_MOV(s1, REG_ITMP1);
2759 ICONST(d, iptr[1].val.i);
2761 if ((a >= 0) && (a <= 255)) {
2762 M_CMOVGE_IMM(s1, a, d);
2765 ICONST(REG_ITMP2, a);
2766 M_CMOVGE(s1, REG_ITMP2, d);
2768 store_reg_to_var_int(iptr->dst, d);
2771 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2772 /* val.i = constant */
2774 var_to_reg_int(s1, src, REG_ITMP1);
2775 d = reg_of_var(iptr->dst, REG_ITMP3);
2777 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2778 if ((a == 1) && (iptr[1].val.i == 0)) {
2779 M_CMPLT(REG_ZERO, s1, d);
2780 store_reg_to_var_int(iptr->dst, d);
2783 if ((a == 0) && (iptr[1].val.i == 1)) {
2784 M_CMPLE(s1, REG_ZERO, d);
2785 store_reg_to_var_int(iptr->dst, d);
2789 M_MOV(s1, REG_ITMP1);
2792 ICONST(d, iptr[1].val.i);
2794 if ((a >= 0) && (a <= 255)) {
2795 M_CMOVGT_IMM(s1, a, d);
2798 ICONST(REG_ITMP2, a);
2799 M_CMOVGT(s1, REG_ITMP2, d);
2801 store_reg_to_var_int(iptr->dst, d);
2804 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2805 /* val.i = constant */
2807 var_to_reg_int(s1, src, REG_ITMP1);
2808 d = reg_of_var(iptr->dst, REG_ITMP3);
2810 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2811 if ((a == 1) && (iptr[1].val.i == 0)) {
2812 M_CMPLE(s1, REG_ZERO, d);
2813 store_reg_to_var_int(iptr->dst, d);
2816 if ((a == 0) && (iptr[1].val.i == 1)) {
2817 M_CMPLT(REG_ZERO, s1, d);
2818 store_reg_to_var_int(iptr->dst, d);
2822 M_MOV(s1, REG_ITMP1);
2825 ICONST(d, iptr[1].val.i);
2827 if ((a >= 0) && (a <= 255)) {
2828 M_CMOVLE_IMM(s1, a, d);
2831 ICONST(REG_ITMP2, a);
2832 M_CMOVLE(s1, REG_ITMP2, d);
2834 store_reg_to_var_int(iptr->dst, d);
2838 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2843 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2844 a = dseg_addaddress ((void*) (builtin_monitorexit));
2845 M_ALD(REG_PV, REG_PV, a);
2846 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
2847 M_JSR(REG_RA, REG_PV);
2848 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2851 var_to_reg_int(s1, src, REG_RESULT);
2852 M_INTMOVE(s1, REG_RESULT);
2853 goto nowperformreturn;
2855 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2859 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2860 a = dseg_addaddress ((void*) (builtin_monitorexit));
2861 M_ALD(REG_PV, REG_PV, a);
2862 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
2863 M_JSR(REG_RA, REG_PV);
2864 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2867 var_to_reg_flt(s1, src, REG_FRESULT);
2868 M_FLTMOVE(s1, REG_FRESULT);
2869 goto nowperformreturn;
2871 case ICMD_RETURN: /* ... ==> ... */
2874 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2875 a = dseg_addaddress ((void*) (builtin_monitorexit));
2876 M_ALD(REG_PV, REG_PV, a);
2877 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
2878 M_JSR(REG_RA, REG_PV);
2879 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2887 p = parentargs_base;
2889 /* restore return address */
2892 {p--; M_LLD (REG_RA, REG_SP, 8 * p);}
2894 /* restore saved registers */
2896 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
2897 {p--; M_LLD(savintregs[r], REG_SP, 8 * p);}
2898 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
2899 {p--; M_DLD(savfltregs[r], REG_SP, 8 * p);}
2901 /* deallocate stack */
2903 if (parentargs_base)
2904 {M_LDA(REG_SP, REG_SP, parentargs_base*8);}
2906 /* call trace function */
2909 M_LDA (REG_SP, REG_SP, -24);
2910 M_AST(REG_RA, REG_SP, 0);
2911 M_LST(REG_RESULT, REG_SP, 8);
2912 M_DST(REG_FRESULT, REG_SP,16);
2913 a = dseg_addaddress (method);
2914 M_ALD(argintregs[0], REG_PV, a);
2915 M_MOV(REG_RESULT, argintregs[1]);
2916 M_FLTMOVE(REG_FRESULT, argfltregs[2]);
2917 a = dseg_addaddress ((void*) (builtin_displaymethodstop));
2918 M_ALD(REG_PV, REG_PV, a);
2919 M_JSR (REG_RA, REG_PV);
2920 s1 = (int)((u1*) mcodeptr - mcodebase);
2921 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
2924 while (ml<-32768) { ml+=65536; mh--; }
2925 M_LDA (REG_PV, REG_RA, ml );
2926 M_LDAH (REG_PV, REG_PV, mh );
2928 M_DLD(REG_FRESULT, REG_SP,16);
2929 M_LLD(REG_RESULT, REG_SP, 8);
2930 M_ALD(REG_RA, REG_SP, 0);
2931 M_LDA (REG_SP, REG_SP, 24);
2934 M_RET(REG_ZERO, REG_RA);
2940 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2944 s4ptr = iptr->val.a;
2945 l = s4ptr[1]; /* low */
2946 i = s4ptr[2]; /* high */
2948 var_to_reg_int(s1, src, REG_ITMP1);
2950 {M_INTMOVE(s1, REG_ITMP1);}
2952 M_LDA(REG_ITMP1, s1, -l);
2958 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
2960 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
2961 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
2963 M_BEQZ(REG_ITMP2, 0);
2964 mcode_addreference(BlockPtrOfPC(s4ptr[0]), mcodeptr);
2966 /* build jump table top down and use address of lowest entry */
2970 dseg_addtarget(BlockPtrOfPC(*--s4ptr));
2974 /* length of dataseg after last dseg_addtarget is used by load */
2976 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
2977 M_ALD(REG_ITMP2, REG_ITMP2, -dseglen);
2978 M_JMP(REG_ZERO, REG_ITMP2);
2983 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2985 s4 i, l, val, *s4ptr;
2987 s4ptr = iptr->val.a;
2988 l = s4ptr[0]; /* default */
2989 i = s4ptr[1]; /* count */
2991 MCODECHECK((i<<2)+8);
2992 var_to_reg_int(s1, src, REG_ITMP1);
2996 if ((val >= 0) && (val <= 255)) {
2997 M_CMPEQ_IMM(s1, val, REG_ITMP2);
3000 if ((val >= -32768) && (val <= 32767)) {
3001 M_LDA(REG_ITMP2, REG_ZERO, val);
3004 a = dseg_adds4 (val);
3005 M_ILD(REG_ITMP2, REG_PV, a);
3007 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
3009 M_BNEZ(REG_ITMP2, 0);
3010 mcode_addreference(BlockPtrOfPC(s4ptr[1]), mcodeptr);
3014 mcode_addreference(BlockPtrOfPC(l), mcodeptr);
3020 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
3021 /* op1 = return type, val.a = function pointer*/
3025 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
3026 /* op1 = return type, val.a = function pointer*/
3030 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
3031 /* op1 = return type, val.a = function pointer*/
3035 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3036 /* op1 = arg count, val.a = method pointer */
3038 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3039 /* op1 = arg count, val.a = method pointer */
3041 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3042 /* op1 = arg count, val.a = method pointer */
3044 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
3045 /* op1 = arg count, val.a = method pointer */
3053 MCODECHECK((s3 << 1) + 64);
3055 /* copy arguments to registers or stack location */
3057 for (; --s3 >= 0; src = src->prev) {
3058 if (src->varkind == ARGVAR)
3060 if (IS_INT_LNG_TYPE(src->type)) {
3061 if (s3 < INT_ARG_CNT) {
3062 s1 = argintregs[s3];
3063 var_to_reg_int(d, src, s1);
3067 var_to_reg_int(d, src, REG_ITMP1);
3068 M_LST(d, REG_SP, 8 * (s3 - INT_ARG_CNT));
3072 if (s3 < FLT_ARG_CNT) {
3073 s1 = argfltregs[s3];
3074 var_to_reg_flt(d, src, s1);
3078 var_to_reg_flt(d, src, REG_FTMP1);
3079 M_DST(d, REG_SP, 8 * (s3 - FLT_ARG_CNT));
3084 switch (iptr->opc) {
3088 a = dseg_addaddress ((void*) (m));
3090 M_ALD(REG_PV, REG_PV, a); /* Pointer to built-in-function */
3092 goto makeactualcall;
3094 case ICMD_INVOKESTATIC:
3095 case ICMD_INVOKESPECIAL:
3096 a = dseg_addaddress (m->stubroutine);
3098 M_ALD(REG_PV, REG_PV, a ); /* method pointer in r27 */
3101 goto makeactualcall;
3103 case ICMD_INVOKEVIRTUAL:
3105 gen_nullptr_check(argintregs[0]);
3106 M_ALD(REG_METHODPTR, argintregs[0],
3107 OFFSET(java_objectheader, vftbl));
3108 M_ALD(REG_PV, REG_METHODPTR, OFFSET(vftbl, table[0]) +
3109 sizeof(methodptr) * m->vftblindex);
3112 goto makeactualcall;
3114 case ICMD_INVOKEINTERFACE:
3117 gen_nullptr_check(argintregs[0]);
3118 M_ALD(REG_METHODPTR, argintregs[0],
3119 OFFSET(java_objectheader, vftbl));
3120 M_ALD(REG_METHODPTR, REG_METHODPTR,
3121 OFFSET(vftbl, interfacetable[0]) -
3122 sizeof(methodptr*) * ci->index);
3123 M_ALD(REG_PV, REG_METHODPTR,
3124 sizeof(methodptr) * (m - ci->methods));
3127 goto makeactualcall;
3131 sprintf (logtext, "Unkown ICMD-Command: %d", iptr->opc);
3137 M_JSR (REG_RA, REG_PV);
3141 s1 = (int)((u1*) mcodeptr - mcodebase);
3142 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
3145 while (ml<-32768) { ml+=65536; mh--; }
3146 M_LDA (REG_PV, REG_RA, ml );
3147 M_LDAH (REG_PV, REG_PV, mh );
3150 /* d contains return type */
3152 if (d != TYPE_VOID) {
3153 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3154 s1 = reg_of_var(iptr->dst, REG_RESULT);
3155 M_INTMOVE(REG_RESULT, s1);
3156 store_reg_to_var_int(iptr->dst, s1);
3159 s1 = reg_of_var(iptr->dst, REG_FRESULT);
3160 M_FLTMOVE(REG_FRESULT, s1);
3161 store_reg_to_var_flt(iptr->dst, s1);
3168 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3170 /* op1: 0 == array, 1 == class */
3171 /* val.a: (classinfo*) superclass */
3173 /* superclass is an interface:
3175 * return (sub != NULL) &&
3176 * (sub->vftbl->interfacetablelength > super->index) &&
3177 * (sub->vftbl->interfacetable[-super->index] != NULL);
3179 * superclass is a class:
3181 * return ((sub != NULL) && (0
3182 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3183 * super->vftbl->diffvall));
3187 classinfo *super = (classinfo*) iptr->val.a;
3189 var_to_reg_int(s1, src, REG_ITMP1);
3190 d = reg_of_var(iptr->dst, REG_ITMP3);
3192 M_MOV(s1, REG_ITMP1);
3196 if (iptr->op1) { /* class/interface */
3197 if (super->flags & ACC_INTERFACE) { /* interface */
3199 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3200 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3201 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3202 M_BLEZ(REG_ITMP2, 2);
3203 M_ALD(REG_ITMP1, REG_ITMP1,
3204 OFFSET(vftbl, interfacetable[0]) -
3205 super->index * sizeof(methodptr*));
3206 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3209 s2 = super->vftbl->diffval;
3210 M_BEQZ(s1, 4 + (s2 > 255));
3211 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3212 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3213 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3215 M_CMPULE_IMM(REG_ITMP1, s2, d);
3217 M_LDA(REG_ITMP2, REG_ZERO, s2);
3218 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3223 panic ("internal error: no inlined array instanceof");
3225 store_reg_to_var_int(iptr->dst, d);
3228 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3230 /* op1: 0 == array, 1 == class */
3231 /* val.a: (classinfo*) superclass */
3233 /* superclass is an interface:
3235 * OK if ((sub == NULL) ||
3236 * (sub->vftbl->interfacetablelength > super->index) &&
3237 * (sub->vftbl->interfacetable[-super->index] != NULL));
3239 * superclass is a class:
3241 * OK if ((sub == NULL) || (0
3242 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3243 * super->vftbl->diffvall));
3247 classinfo *super = (classinfo*) iptr->val.a;
3249 d = reg_of_var(iptr->dst, REG_ITMP3);
3250 var_to_reg_int(s1, src, d);
3251 if (iptr->op1) { /* class/interface */
3252 if (super->flags & ACC_INTERFACE) { /* interface */
3254 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3255 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3256 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3257 M_BLEZ(REG_ITMP2, 0);
3258 mcode_addxcastrefs(mcodeptr);
3259 M_ALD(REG_ITMP2, REG_ITMP1,
3260 OFFSET(vftbl, interfacetable[0]) -
3261 super->index * sizeof(methodptr*));
3262 M_BEQZ(REG_ITMP2, 0);
3263 mcode_addxcastrefs(mcodeptr);
3266 s2 = super->vftbl->diffval;
3267 M_BEQZ(s1, 4 + (s2 != 0) + (s2 > 255));
3268 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3269 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3270 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3272 M_BNEZ(REG_ITMP1, 0);
3274 else if (s2 <= 255) {
3275 M_CMPULE_IMM(REG_ITMP1, s2, REG_ITMP2);
3276 M_BEQZ(REG_ITMP2, 0);
3279 M_LDA(REG_ITMP2, REG_ZERO, s2);
3280 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3281 M_BEQZ(REG_ITMP2, 0);
3283 mcode_addxcastrefs(mcodeptr);
3287 panic ("internal error: no inlined array checkcast");
3290 store_reg_to_var_int(iptr->dst, d);
3293 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
3295 var_to_reg_int(s1, src, REG_ITMP1);
3297 mcode_addxcheckarefs(mcodeptr);
3300 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3301 /* op1 = dimension, val.a = array descriptor */
3303 /* check for negative sizes and copy sizes to stack if necessary */
3305 MCODECHECK((iptr->op1 << 1) + 64);
3307 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3308 var_to_reg_int(s2, src, REG_ITMP1);
3310 mcode_addxcheckarefs(mcodeptr);
3312 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
3314 if (src->varkind != ARGVAR) {
3315 M_LST(s2, REG_SP, 8 * (s1 + INT_ARG_CNT));
3319 /* a0 = dimension count */
3321 M_LDA(argintregs[0], REG_ZERO, iptr->op1);
3323 /* a1 = arraydescriptor */
3325 a = dseg_addaddress(iptr->val.a);
3326 M_ALD(argintregs[1], REG_PV, a);
3328 /* a2 = pointer to dimensions = stack pointer */
3330 M_INTMOVE(REG_SP, argintregs[2]);
3332 a = dseg_addaddress((void*) (builtin_nmultianewarray));
3333 M_ALD(REG_PV, REG_PV, a);
3334 M_JSR(REG_RA, REG_PV);
3335 s1 = (int)((u1*) mcodeptr - mcodebase);
3337 M_LDA (REG_PV, REG_RA, -s1);
3339 s4 ml = -s1, mh = 0;
3340 while (ml < -32768) {ml += 65536; mh--;}
3341 M_LDA(REG_PV, REG_RA, ml);
3342 M_LDAH(REG_PV, REG_PV, mh);
3344 s1 = reg_of_var(iptr->dst, REG_RESULT);
3345 M_INTMOVE(REG_RESULT, s1);
3346 store_reg_to_var_int(iptr->dst, s1);
3350 default: sprintf (logtext, "Unknown pseudo command: %d", iptr->opc);
3353 } /* for instruction */
3355 /* copy values to interface registers */
3357 src = bptr->outstack;
3358 len = bptr->outdepth;
3362 if ((src->varkind != STACKVAR)) {
3364 if (IS_FLT_DBL_TYPE(s2)) {
3365 var_to_reg_flt(s1, src, REG_FTMP1);
3366 if (!(interfaces[len][s2].flags & INMEMORY)) {
3367 M_FLTMOVE(s1,interfaces[len][s2].regoff);
3370 M_DST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3374 var_to_reg_int(s1, src, REG_ITMP1);
3375 if (!(interfaces[len][s2].flags & INMEMORY)) {
3376 M_INTMOVE(s1,interfaces[len][s2].regoff);
3379 M_LST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3385 } /* if (bptr -> flags >= BBREACHED) */
3386 } /* for basic block */
3388 bptr -> mpc = (int)((u1*) mcodeptr - mcodebase);
3391 /* generate bound check stubs */
3393 s4 *xcodeptr = NULL;
3395 for (; xboundrefs != NULL; xboundrefs = xboundrefs->next) {
3396 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3397 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
3398 xboundrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3402 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
3403 xboundrefs->branchpos, (u1*) mcodeptr - mcodebase);
3407 M_LDA(REG_ITMP2_XPC, REG_PV, xboundrefs->branchpos);
3409 if (xcodeptr != NULL) {
3410 M_BR((xcodeptr-mcodeptr)-1);
3413 xcodeptr = mcodeptr;
3415 a = dseg_addaddress(proto_java_lang_ArrayIndexOutOfBoundsException);
3416 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3418 a = dseg_addaddress(asm_handle_exception);
3419 M_ALD(REG_ITMP3, REG_PV, a);
3421 M_JMP(REG_ZERO, REG_ITMP3);
3425 /* generate negative array size check stubs */
3429 for (; xcheckarefs != NULL; xcheckarefs = xcheckarefs->next) {
3430 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3431 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3432 xcheckarefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3436 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3437 xcheckarefs->branchpos, (u1*) mcodeptr - mcodebase);
3441 M_LDA(REG_ITMP2_XPC, REG_PV, xcheckarefs->branchpos);
3443 if (xcodeptr != NULL) {
3444 M_BR((xcodeptr-mcodeptr)-1);
3447 xcodeptr = mcodeptr;
3449 a = dseg_addaddress(proto_java_lang_NegativeArraySizeException);
3450 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3452 a = dseg_addaddress(asm_handle_exception);
3453 M_ALD(REG_ITMP3, REG_PV, a);
3455 M_JMP(REG_ZERO, REG_ITMP3);
3459 /* generate cast check stubs */
3463 for (; xcastrefs != NULL; xcastrefs = xcastrefs->next) {
3464 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3465 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3466 xcastrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3470 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3471 xcastrefs->branchpos, (u1*) mcodeptr - mcodebase);
3475 M_LDA(REG_ITMP2_XPC, REG_PV, xcastrefs->branchpos);
3477 if (xcodeptr != NULL) {
3478 M_BR((xcodeptr-mcodeptr)-1);
3481 xcodeptr = mcodeptr;
3483 a = dseg_addaddress(proto_java_lang_ClassCastException);
3484 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3486 a = dseg_addaddress(asm_handle_exception);
3487 M_ALD(REG_ITMP3, REG_PV, a);
3489 M_JMP(REG_ZERO, REG_ITMP3);
3494 #ifdef SOFTNULLPTRCHECK
3496 /* generate null pointer check stubs */
3500 for (; xnullrefs != NULL; xnullrefs = xnullrefs->next) {
3501 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3502 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3503 xnullrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3507 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3508 xnullrefs->branchpos, (u1*) mcodeptr - mcodebase);
3512 M_LDA(REG_ITMP2_XPC, REG_PV, xnullrefs->branchpos - 4);
3514 if (xcodeptr != NULL) {
3515 M_BR((xcodeptr-mcodeptr)-1);
3518 xcodeptr = mcodeptr;
3520 a = dseg_addaddress(proto_java_lang_NullPointerException);
3521 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3523 a = dseg_addaddress(asm_handle_exception);
3524 M_ALD(REG_ITMP3, REG_PV, a);
3526 M_JMP(REG_ZERO, REG_ITMP3);
3533 mcode_finish((int)((u1*) mcodeptr - mcodebase));
3537 /* redefinition of code generation macros (compiling into array) **************/
3540 These macros are newly defined to allow code generation into an array.
3541 This is necessary, because the original M_.. macros generate code by
3542 calling 'mcode_adds4' that uses an additional data structure to
3545 For a faster (but less flexible) version to generate code, these
3546 macros directly use the (s4* p) - pointer to put the code directly
3547 in a locally defined array.
3548 This makes sense only for the stub-generation-routines below.
3552 #define M_OP3(op,fu,a,b,c,const) \
3553 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<(16-3*(const)))| \
3554 ((const)<<12)|((fu)<<5)|((c)) )
3556 #define M_FOP3(op,fu,a,b,c) \
3557 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<16)|((fu)<<5)|(c) )
3559 #define M_BRA(op,a,disp) \
3560 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((disp)&0x1fffff) )
3562 #define M_MEM(op,a,b,disp) \
3563 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<16)|((disp)&0xffff) )
3566 /* function createcompilerstub *************************************************
3568 creates a stub routine which calls the compiler
3570 *******************************************************************************/
3572 #define COMPSTUBSIZE 3
3574 u1 *createcompilerstub (methodinfo *m)
3576 u8 *s = CNEW (u8, COMPSTUBSIZE); /* memory to hold the stub */
3577 s4 *p = (s4*) s; /* code generation pointer */
3579 /* code for the stub */
3580 M_ALD (REG_PV, REG_PV, 16); /* load pointer to the compiler */
3581 M_JMP (0, REG_PV); /* jump to the compiler, return address
3582 in reg 0 is used as method pointer */
3583 s[1] = (u8) m; /* literals to be adressed */
3584 s[2] = (u8) asm_call_jit_compiler; /* jump directly via PV from above */
3587 count_cstub_len += COMPSTUBSIZE * 8;
3594 /* function removecompilerstub *************************************************
3596 deletes a compilerstub from memory (simply by freeing it)
3598 *******************************************************************************/
3600 void removecompilerstub (u1 *stub)
3602 CFREE (stub, COMPSTUBSIZE * 8);
3606 /* function: createnativestub **************************************************
3608 creates a stub routine which calls a native method
3610 *******************************************************************************/
3612 #define NATIVESTUBSIZE 11
3614 u1 *createnativestub (functionptr f, methodinfo *m)
3616 u8 *s = CNEW (u8, NATIVESTUBSIZE); /* memory to hold the stub */
3617 s4 *p = (s4*) s; /* code generation pointer */
3619 M_LDA (REG_SP, REG_SP, -8); /* build up stackframe */
3620 M_AST (REG_RA, REG_SP, 0); /* store return address */
3622 M_ALD (REG_PV, REG_PV, 8*8); /* load adress of native method */
3623 M_JSR (REG_RA, REG_PV); /* call native method */
3625 M_LDA (REG_PV, REG_RA, -4*4); /* recompute pv from ra */
3626 M_ALD (REG_ITMP3, REG_PV, 9*8); /* get address of exceptionptr */
3628 M_ALD (REG_RA, REG_SP, 0); /* load return address */
3629 M_ALD (REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
3631 M_LDA (REG_SP, REG_SP, 8); /* remove stackframe */
3632 M_BNEZ (REG_ITMP1, 1); /* if no exception then return */
3634 M_RET (REG_ZERO, REG_RA); /* return to caller */
3636 M_AST (REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
3637 M_LDA (REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
3639 M_ALD (REG_ITMP3, REG_PV,10*8); /* load asm exception handler address */
3640 M_JMP (REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
3643 s[8] = (u8) f; /* address of native method */
3644 s[9] = (u8) (&exceptionptr); /* address of exceptionptr */
3645 s[10]= (u8) (asm_handle_nat_exception); /* addr of asm exception handler */
3648 count_nstub_len += NATIVESTUBSIZE * 8;
3655 /* function: removenativestub **************************************************
3657 removes a previously created native-stub from memory
3659 *******************************************************************************/
3661 void removenativestub (u1 *stub)
3663 CFREE (stub, NATIVESTUBSIZE * 8);
3668 * These are local overrides for various environment variables in Emacs.
3669 * Please do not remove this and leave it at the end of the file, where
3670 * Emacs will automagically detect them.
3671 * ---------------------------------------------------------------------
3674 * indent-tabs-mode: t