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 /* asm_signal_exception passes exception pointer and the signal context
225 structure (contains the saved registers) to the assembler handler which
226 restores registers and walks through the Java exception tables.
229 void asm_signal_exception(void *xptr, void *sigctx);
232 /* NullPointerException signal handler for hardware null pointer check */
234 void catch_NullPointerException(int sig, int code, sigctx_struct *sigctx)
240 /* Reset signal handler - necessary for SysV, does no harm for BSD */
242 instr = *((int*)(sigctx->sc_pc));
243 faultaddr = sigctx->sc_regs[(instr >> 16) & 0x1f];
245 if (faultaddr == 0) {
246 signal(sig, (void*) catch_NullPointerException); /* reinstall handler */
248 sigaddset(&nsig, sig);
249 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
250 asm_signal_exception(proto_java_lang_NullPointerException, sigctx);
253 faultaddr += (long) ((instr << 16) >> 16);
254 fprintf(stderr, "faulting address: 0x%16lx\n", faultaddr);
255 panic("Stack overflow");
262 void init_exceptions(void)
267 /* Linux on Digital Alpha needs an initialisation of the ieee floating point
268 control for IEEE compliant arithmetic (option -mieee of GCC). Under
269 Digital Unix this is done automatically.
274 extern unsigned long ieee_get_fp_control();
275 extern void ieee_set_fp_control(unsigned long fp_control);
277 void init_exceptions(void)
279 /* initialize floating point control */
281 ieee_set_fp_control(ieee_get_fp_control()
282 & ~IEEE_TRAP_ENABLE_INV
283 & ~IEEE_TRAP_ENABLE_DZE
284 /* & ~IEEE_TRAP_ENABLE_UNF we dont want underflow */
285 & ~IEEE_TRAP_ENABLE_OVF);
288 /* install signal handlers we need to convert to exceptions */
293 signal(SIGSEGV, (void*) catch_NullPointerException);
297 signal(SIGBUS, (void*) catch_NullPointerException);
303 /* function gen_mcode **********************************************************
305 generates machine code
307 *******************************************************************************/
309 #define MethodPointer -8
310 #define FrameSize -12
315 #define ExTableSize -32
316 #define ExTableStart -32
318 #define ExEntrySize -32
321 #define ExHandlerPC -24
322 #define ExCatchType -32
324 static void gen_mcode()
326 int len, s1, s2, s3, d, bbs;
337 savedregs_num = (isleafmethod) ? 0 : 1; /* space to save the RA */
339 /* space to save used callee saved registers */
341 savedregs_num += (savintregcnt - maxsavintreguse);
342 savedregs_num += (savfltregcnt - maxsavfltreguse);
344 parentargs_base = maxmemuse + savedregs_num;
346 #ifdef USE_THREADS /* space to save argument of monitor_enter */
348 if (checksync && (method->flags & ACC_SYNCHRONIZED))
353 /* create method header */
355 (void) dseg_addaddress(method); /* MethodPointer */
356 (void) dseg_adds4(parentargs_base * 8); /* FrameSize */
360 /* IsSync contains the offset relative to the stack pointer for the
361 argument of monitor_exit used in the exception handler. Since the
362 offset could be zero and give a wrong meaning of the flag it is
366 if (checksync && (method->flags & ACC_SYNCHRONIZED))
367 (void) dseg_adds4((maxmemuse + 1) * 8); /* IsSync */
372 (void) dseg_adds4(0); /* IsSync */
374 (void) dseg_adds4(isleafmethod); /* IsLeaf */
375 (void) dseg_adds4(savintregcnt - maxsavintreguse); /* IntSave */
376 (void) dseg_adds4(savfltregcnt - maxsavfltreguse); /* FltSave */
377 (void) dseg_adds4(exceptiontablelength); /* ExTableSize */
379 /* create exception table */
381 for (len = 0; len < exceptiontablelength; len++) {
382 dseg_addtarget(BlockPtrOfPC(extable[len].startpc));
383 dseg_addtarget(BlockPtrOfPC(extable[len].endpc));
384 dseg_addtarget(BlockPtrOfPC(extable[len].handlerpc));
385 (void) dseg_addaddress(extable[len].catchtype);
388 /* initialize mcode variables */
390 mcodeptr = (s4*) mcodebase;
391 mcodeend = (s4*) (mcodebase + mcodesize);
392 MCODECHECK(128 + mparamcount);
394 /* create stack frame (if necessary) */
397 {M_LDA (REG_SP, REG_SP, -parentargs_base * 8);}
399 /* save return address and used callee saved registers */
403 {p--; M_AST (REG_RA, REG_SP, 8*p);}
404 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
405 {p--; M_LST (savintregs[r], REG_SP, 8 * p);}
406 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
407 {p--; M_DST (savfltregs[r], REG_SP, 8 * p);}
409 /* save monitorenter argument */
412 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
413 if (method->flags & ACC_STATIC) {
414 p = dseg_addaddress (class);
415 M_ALD(REG_ITMP1, REG_PV, p);
416 M_AST(REG_ITMP1, REG_SP, 8 * maxmemuse);
419 M_AST (argintregs[0], REG_SP, 8 * maxmemuse);
424 /* copy argument registers to stack and call trace function with pointer
425 to arguments on stack. ToDo: save floating point registers !!!!!!!!!
428 if (runverbose && isleafmethod) {
429 M_LDA (REG_SP, REG_SP, -(14*8));
430 M_AST(REG_RA, REG_SP, 1*8);
432 M_LST(argintregs[0], REG_SP, 2*8);
433 M_LST(argintregs[1], REG_SP, 3*8);
434 M_LST(argintregs[2], REG_SP, 4*8);
435 M_LST(argintregs[3], REG_SP, 5*8);
436 M_LST(argintregs[4], REG_SP, 6*8);
437 M_LST(argintregs[5], REG_SP, 7*8);
439 M_DST(argfltregs[0], REG_SP, 8*8);
440 M_DST(argfltregs[1], REG_SP, 9*8);
441 M_DST(argfltregs[2], REG_SP, 10*8);
442 M_DST(argfltregs[3], REG_SP, 11*8);
443 M_DST(argfltregs[4], REG_SP, 12*8);
444 M_DST(argfltregs[5], REG_SP, 13*8);
446 p = dseg_addaddress (method);
447 M_ALD(REG_ITMP1, REG_PV, p);
448 M_AST(REG_ITMP1, REG_SP, 0);
449 p = dseg_addaddress ((void*) (builtin_trace_args));
450 M_ALD(REG_PV, REG_PV, p);
451 M_JSR(REG_RA, REG_PV);
452 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
453 M_ALD(REG_RA, REG_SP, 1*8);
455 M_LLD(argintregs[0], REG_SP, 2*8);
456 M_LLD(argintregs[1], REG_SP, 3*8);
457 M_LLD(argintregs[2], REG_SP, 4*8);
458 M_LLD(argintregs[3], REG_SP, 5*8);
459 M_LLD(argintregs[4], REG_SP, 6*8);
460 M_LLD(argintregs[5], REG_SP, 7*8);
462 M_DLD(argfltregs[0], REG_SP, 8*8);
463 M_DLD(argfltregs[1], REG_SP, 9*8);
464 M_DLD(argfltregs[2], REG_SP, 10*8);
465 M_DLD(argfltregs[3], REG_SP, 11*8);
466 M_DLD(argfltregs[4], REG_SP, 12*8);
467 M_DLD(argfltregs[5], REG_SP, 13*8);
469 M_LDA (REG_SP, REG_SP, 14*8);
472 /* take arguments out of register or stack frame */
474 for (p = 0, l = 0; p < mparamcount; p++) {
476 var = &(locals[l][t]);
478 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
483 if (IS_INT_LNG_TYPE(t)) { /* integer args */
484 if (p < INT_ARG_CNT) { /* register arguments */
485 if (!(var->flags & INMEMORY)) /* reg arg -> register */
486 {M_INTMOVE (argintregs[p], r);}
487 else /* reg arg -> spilled */
488 M_LST (argintregs[p], REG_SP, 8 * r);
490 else { /* stack arguments */
491 pa = p - INT_ARG_CNT;
492 if (!(var->flags & INMEMORY)) /* stack arg -> register */
493 M_LLD (r, REG_SP, 8 * (parentargs_base + pa));
494 else { /* stack arg -> spilled */
495 M_LLD (REG_ITMP1, REG_SP, 8 * (parentargs_base + pa));
496 M_LST (REG_ITMP1, REG_SP, 8 * r);
500 else { /* floating args */
501 if (p < FLT_ARG_CNT) { /* register arguments */
502 if (!(var->flags & INMEMORY)) /* reg arg -> register */
503 {M_FLTMOVE (argfltregs[p], r);}
504 else /* reg arg -> spilled */
505 M_DST (argfltregs[p], REG_SP, 8 * r);
507 else { /* stack arguments */
508 pa = p - FLT_ARG_CNT;
509 if (!(var->flags & INMEMORY)) /* stack-arg -> register */
510 M_DLD (r, REG_SP, 8 * (parentargs_base + pa) );
511 else { /* stack-arg -> spilled */
512 M_DLD (REG_FTMP1, REG_SP, 8 * (parentargs_base + pa));
513 M_DST (REG_FTMP1, REG_SP, 8 * r);
519 /* call trace function */
521 if (runverbose && !isleafmethod) {
522 M_LDA (REG_SP, REG_SP, -8);
523 p = dseg_addaddress (method);
524 M_ALD(REG_ITMP1, REG_PV, p);
525 M_AST(REG_ITMP1, REG_SP, 0);
526 p = dseg_addaddress ((void*) (builtin_trace_args));
527 M_ALD(REG_PV, REG_PV, p);
528 M_JSR(REG_RA, REG_PV);
529 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
530 M_LDA(REG_SP, REG_SP, 8);
533 /* call monitorenter function */
536 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
537 p = dseg_addaddress ((void*) (builtin_monitorenter));
538 M_ALD(REG_PV, REG_PV, p);
539 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
540 M_JSR(REG_RA, REG_PV);
541 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
546 /* end of header generation */
548 /* walk through all basic blocks */
550 for (bbs = block_count, bptr = block; --bbs >= 0; bptr++) {
551 bptr -> mpc = (int)((u1*) mcodeptr - mcodebase);
553 if (bptr->flags >= BBREACHED) {
555 /* branch resolving */
559 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
560 gen_resolvebranch((u1*) mcodebase + brefs->branchpos,
561 brefs->branchpos, bptr->mpc);
565 /* copy interface registers to their destination */
570 while (src != NULL) {
572 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
573 d = reg_of_var(src, REG_ITMP1);
574 M_INTMOVE(REG_ITMP1, d);
575 store_reg_to_var_int(src, d);
578 d = reg_of_var(src, REG_IFTMP);
579 if ((src->varkind != STACKVAR)) {
581 if (IS_FLT_DBL_TYPE(s2)) {
582 if (!(interfaces[len][s2].flags & INMEMORY)) {
583 s1 = interfaces[len][s2].regoff;
587 M_DLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
589 store_reg_to_var_flt(src, d);
592 if (!(interfaces[len][s2].flags & INMEMORY)) {
593 s1 = interfaces[len][s2].regoff;
597 M_LLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
599 store_reg_to_var_int(src, d);
606 /* walk through all instructions */
610 for (iptr = bptr->iinstr;
612 src = iptr->dst, len--, iptr++) {
614 MCODECHECK(64); /* an instruction usually needs < 64 words */
617 case ICMD_NOP: /* ... ==> ... */
620 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
622 var_to_reg_int(s1, src, REG_ITMP1);
624 mcode_addxnullrefs(mcodeptr);
627 /* constant operations ************************************************/
629 #define ICONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
630 else{a=dseg_adds4(c);M_ILD(r,REG_PV,a);}
632 #define LCONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
633 else{a=dseg_adds8(c);M_LLD(r,REG_PV,a);}
635 case ICMD_ICONST: /* ... ==> ..., constant */
636 /* op1 = 0, val.i = constant */
638 d = reg_of_var(iptr->dst, REG_ITMP1);
639 ICONST(d, iptr->val.i);
640 store_reg_to_var_int(iptr->dst, d);
643 case ICMD_LCONST: /* ... ==> ..., constant */
644 /* op1 = 0, val.l = constant */
646 d = reg_of_var(iptr->dst, REG_ITMP1);
647 LCONST(d, iptr->val.l);
648 store_reg_to_var_int(iptr->dst, d);
651 case ICMD_FCONST: /* ... ==> ..., constant */
652 /* op1 = 0, val.f = constant */
654 d = reg_of_var (iptr->dst, REG_FTMP1);
655 a = dseg_addfloat (iptr->val.f);
657 store_reg_to_var_flt (iptr->dst, d);
660 case ICMD_DCONST: /* ... ==> ..., constant */
661 /* op1 = 0, val.d = constant */
663 d = reg_of_var (iptr->dst, REG_FTMP1);
664 a = dseg_adddouble (iptr->val.d);
666 store_reg_to_var_flt (iptr->dst, d);
669 case ICMD_ACONST: /* ... ==> ..., constant */
670 /* op1 = 0, val.a = constant */
672 d = reg_of_var(iptr->dst, REG_ITMP1);
674 a = dseg_addaddress (iptr->val.a);
678 M_INTMOVE(REG_ZERO, d);
680 store_reg_to_var_int(iptr->dst, d);
684 /* load/store operations **********************************************/
686 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
687 case ICMD_LLOAD: /* op1 = local variable */
690 d = reg_of_var(iptr->dst, REG_ITMP1);
691 if ((iptr->dst->varkind == LOCALVAR) &&
692 (iptr->dst->varnum == iptr->op1))
694 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
695 if (var->flags & INMEMORY)
696 M_LLD(d, REG_SP, 8 * var->regoff);
698 {M_INTMOVE(var->regoff,d);}
699 store_reg_to_var_int(iptr->dst, d);
702 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
703 case ICMD_DLOAD: /* op1 = local variable */
705 d = reg_of_var(iptr->dst, REG_FTMP1);
706 if ((iptr->dst->varkind == LOCALVAR) &&
707 (iptr->dst->varnum == iptr->op1))
709 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
710 if (var->flags & INMEMORY)
711 M_DLD(d, REG_SP, 8 * var->regoff);
713 {M_FLTMOVE(var->regoff,d);}
714 store_reg_to_var_flt(iptr->dst, d);
718 case ICMD_ISTORE: /* ..., value ==> ... */
719 case ICMD_LSTORE: /* op1 = local variable */
722 if ((src->varkind == LOCALVAR) &&
723 (src->varnum == iptr->op1))
725 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
726 if (var->flags & INMEMORY) {
727 var_to_reg_int(s1, src, REG_ITMP1);
728 M_LST(s1, REG_SP, 8 * var->regoff);
731 var_to_reg_int(s1, src, var->regoff);
732 M_INTMOVE(s1, var->regoff);
736 case ICMD_FSTORE: /* ..., value ==> ... */
737 case ICMD_DSTORE: /* op1 = local variable */
739 if ((src->varkind == LOCALVAR) &&
740 (src->varnum == iptr->op1))
742 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
743 if (var->flags & INMEMORY) {
744 var_to_reg_flt(s1, src, REG_FTMP1);
745 M_DST(s1, REG_SP, 8 * var->regoff);
748 var_to_reg_flt(s1, src, var->regoff);
749 M_FLTMOVE(s1, var->regoff);
754 /* pop/dup/swap operations ********************************************/
756 /* attention: double and longs are only one entry in CACAO ICMDs */
758 case ICMD_POP: /* ..., value ==> ... */
759 case ICMD_POP2: /* ..., value, value ==> ... */
762 #define M_COPY(from,to) \
763 d = reg_of_var(to, REG_IFTMP); \
764 if ((from->regoff != to->regoff) || \
765 ((from->flags ^ to->flags) & INMEMORY)) { \
766 if (IS_FLT_DBL_TYPE(from->type)) { \
767 var_to_reg_flt(s1, from, d); \
769 store_reg_to_var_flt(to, d); \
772 var_to_reg_int(s1, from, d); \
774 store_reg_to_var_int(to, d); \
778 case ICMD_DUP: /* ..., a ==> ..., a, a */
779 M_COPY(src, iptr->dst);
782 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
784 M_COPY(src, iptr->dst->prev->prev);
786 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
788 M_COPY(src, iptr->dst);
789 M_COPY(src->prev, iptr->dst->prev);
792 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
794 M_COPY(src->prev, iptr->dst->prev->prev->prev);
796 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
798 M_COPY(src, iptr->dst);
799 M_COPY(src->prev, iptr->dst->prev);
800 M_COPY(src->prev->prev, iptr->dst->prev->prev);
801 M_COPY(src, iptr->dst->prev->prev->prev);
804 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
806 M_COPY(src, iptr->dst);
807 M_COPY(src->prev, iptr->dst->prev);
808 M_COPY(src->prev->prev, iptr->dst->prev->prev);
809 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
810 M_COPY(src, iptr->dst->prev->prev->prev->prev);
811 M_COPY(src->prev, iptr->dst->prev->prev->prev->prev->prev);
814 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
816 M_COPY(src, iptr->dst->prev);
817 M_COPY(src->prev, iptr->dst);
821 /* integer operations *************************************************/
823 case ICMD_INEG: /* ..., value ==> ..., - value */
825 var_to_reg_int(s1, src, REG_ITMP1);
826 d = reg_of_var(iptr->dst, REG_ITMP3);
827 M_ISUB(REG_ZERO, s1, d);
828 store_reg_to_var_int(iptr->dst, d);
831 case ICMD_LNEG: /* ..., value ==> ..., - value */
833 var_to_reg_int(s1, src, REG_ITMP1);
834 d = reg_of_var(iptr->dst, REG_ITMP3);
835 M_LSUB(REG_ZERO, s1, d);
836 store_reg_to_var_int(iptr->dst, d);
839 case ICMD_I2L: /* ..., value ==> ..., value */
841 var_to_reg_int(s1, src, REG_ITMP1);
842 d = reg_of_var(iptr->dst, REG_ITMP3);
844 store_reg_to_var_int(iptr->dst, d);
847 case ICMD_L2I: /* ..., value ==> ..., value */
849 var_to_reg_int(s1, src, REG_ITMP1);
850 d = reg_of_var(iptr->dst, REG_ITMP3);
851 M_IADD(s1, REG_ZERO, d );
852 store_reg_to_var_int(iptr->dst, d);
855 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
857 var_to_reg_int(s1, src, REG_ITMP1);
858 d = reg_of_var(iptr->dst, REG_ITMP3);
859 if (has_ext_instr_set) {
863 M_SLL_IMM(s1, 56, d);
864 M_SRA_IMM( d, 56, d);
866 store_reg_to_var_int(iptr->dst, d);
869 case ICMD_INT2CHAR: /* ..., 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_INT2SHORT: /* ..., value ==> ..., value */
879 var_to_reg_int(s1, src, REG_ITMP1);
880 d = reg_of_var(iptr->dst, REG_ITMP3);
881 if (has_ext_instr_set) {
885 M_SLL_IMM(s1, 48, d);
886 M_SRA_IMM( d, 48, d);
888 store_reg_to_var_int(iptr->dst, d);
892 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
894 var_to_reg_int(s1, src->prev, REG_ITMP1);
895 var_to_reg_int(s2, src, REG_ITMP2);
896 d = reg_of_var(iptr->dst, REG_ITMP3);
898 store_reg_to_var_int(iptr->dst, d);
901 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
902 /* val.i = constant */
904 var_to_reg_int(s1, src, REG_ITMP1);
905 d = reg_of_var(iptr->dst, REG_ITMP3);
906 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
907 M_IADD_IMM(s1, iptr->val.i, d);
910 ICONST(REG_ITMP2, iptr->val.i);
911 M_IADD(s1, REG_ITMP2, d);
913 store_reg_to_var_int(iptr->dst, d);
916 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
918 var_to_reg_int(s1, src->prev, REG_ITMP1);
919 var_to_reg_int(s2, src, REG_ITMP2);
920 d = reg_of_var(iptr->dst, REG_ITMP3);
922 store_reg_to_var_int(iptr->dst, d);
925 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
926 /* val.l = constant */
928 var_to_reg_int(s1, src, REG_ITMP1);
929 d = reg_of_var(iptr->dst, REG_ITMP3);
930 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
931 M_LADD_IMM(s1, iptr->val.l, d);
934 LCONST(REG_ITMP2, iptr->val.l);
935 M_LADD(s1, REG_ITMP2, d);
937 store_reg_to_var_int(iptr->dst, d);
940 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
942 var_to_reg_int(s1, src->prev, REG_ITMP1);
943 var_to_reg_int(s2, src, REG_ITMP2);
944 d = reg_of_var(iptr->dst, REG_ITMP3);
946 store_reg_to_var_int(iptr->dst, d);
949 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
950 /* val.i = constant */
952 var_to_reg_int(s1, src, REG_ITMP1);
953 d = reg_of_var(iptr->dst, REG_ITMP3);
954 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
955 M_ISUB_IMM(s1, iptr->val.i, d);
958 ICONST(REG_ITMP2, iptr->val.i);
959 M_ISUB(s1, REG_ITMP2, d);
961 store_reg_to_var_int(iptr->dst, d);
964 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
966 var_to_reg_int(s1, src->prev, REG_ITMP1);
967 var_to_reg_int(s2, src, REG_ITMP2);
968 d = reg_of_var(iptr->dst, REG_ITMP3);
970 store_reg_to_var_int(iptr->dst, d);
973 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
974 /* val.l = constant */
976 var_to_reg_int(s1, src, REG_ITMP1);
977 d = reg_of_var(iptr->dst, REG_ITMP3);
978 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
979 M_LSUB_IMM(s1, iptr->val.l, d);
982 LCONST(REG_ITMP2, iptr->val.l);
983 M_LSUB(s1, REG_ITMP2, d);
985 store_reg_to_var_int(iptr->dst, d);
988 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
990 var_to_reg_int(s1, src->prev, REG_ITMP1);
991 var_to_reg_int(s2, src, REG_ITMP2);
992 d = reg_of_var(iptr->dst, REG_ITMP3);
994 store_reg_to_var_int(iptr->dst, d);
997 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
998 /* val.i = constant */
1000 var_to_reg_int(s1, src, REG_ITMP1);
1001 d = reg_of_var(iptr->dst, REG_ITMP3);
1002 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1003 M_IMUL_IMM(s1, iptr->val.i, d);
1006 ICONST(REG_ITMP2, iptr->val.i);
1007 M_IMUL(s1, REG_ITMP2, d);
1009 store_reg_to_var_int(iptr->dst, d);
1012 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1014 var_to_reg_int(s1, src->prev, REG_ITMP1);
1015 var_to_reg_int(s2, src, REG_ITMP2);
1016 d = reg_of_var(iptr->dst, REG_ITMP3);
1018 store_reg_to_var_int(iptr->dst, d);
1021 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
1022 /* val.l = constant */
1024 var_to_reg_int(s1, src, REG_ITMP1);
1025 d = reg_of_var(iptr->dst, REG_ITMP3);
1026 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1027 M_LMUL_IMM(s1, iptr->val.l, d);
1030 LCONST(REG_ITMP2, iptr->val.l);
1031 M_LMUL(s1, REG_ITMP2, d);
1033 store_reg_to_var_int(iptr->dst, d);
1036 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
1037 case ICMD_LDIVPOW2: /* val.i = constant */
1039 var_to_reg_int(s1, src, REG_ITMP1);
1040 d = reg_of_var(iptr->dst, REG_ITMP3);
1041 if (iptr->val.i <= 15) {
1042 M_LDA(REG_ITMP2, s1, (1 << iptr->val.i) -1);
1043 M_CMOVGE(s1, s1, REG_ITMP2);
1046 M_SRA_IMM(s1, 63, REG_ITMP2);
1047 M_SRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
1048 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1050 M_SRA_IMM(REG_ITMP2, iptr->val.i, d);
1051 store_reg_to_var_int(iptr->dst, d);
1054 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1056 var_to_reg_int(s1, src->prev, REG_ITMP1);
1057 var_to_reg_int(s2, src, REG_ITMP2);
1058 d = reg_of_var(iptr->dst, REG_ITMP3);
1059 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1060 M_SLL(s1, REG_ITMP3, d);
1061 M_IADD(d, REG_ZERO, d);
1062 store_reg_to_var_int(iptr->dst, d);
1065 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1066 /* val.i = constant */
1068 var_to_reg_int(s1, src, REG_ITMP1);
1069 d = reg_of_var(iptr->dst, REG_ITMP3);
1070 M_SLL_IMM(s1, iptr->val.i & 0x1f, d);
1071 M_IADD(d, REG_ZERO, d);
1072 store_reg_to_var_int(iptr->dst, d);
1075 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1077 var_to_reg_int(s1, src->prev, REG_ITMP1);
1078 var_to_reg_int(s2, src, REG_ITMP2);
1079 d = reg_of_var(iptr->dst, REG_ITMP3);
1080 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1081 M_SRA(s1, REG_ITMP3, d);
1082 store_reg_to_var_int(iptr->dst, d);
1085 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1086 /* val.i = constant */
1088 var_to_reg_int(s1, src, REG_ITMP1);
1089 d = reg_of_var(iptr->dst, REG_ITMP3);
1090 M_SRA_IMM(s1, iptr->val.i & 0x1f, d);
1091 store_reg_to_var_int(iptr->dst, d);
1094 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1096 var_to_reg_int(s1, src->prev, REG_ITMP1);
1097 var_to_reg_int(s2, src, REG_ITMP2);
1098 d = reg_of_var(iptr->dst, REG_ITMP3);
1099 M_AND_IMM(s2, 0x1f, REG_ITMP2);
1101 M_SRL(d, REG_ITMP2, d);
1102 M_IADD(d, REG_ZERO, d);
1103 store_reg_to_var_int(iptr->dst, d);
1106 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1107 /* val.i = constant */
1109 var_to_reg_int(s1, src, REG_ITMP1);
1110 d = reg_of_var(iptr->dst, REG_ITMP3);
1112 M_SRL_IMM(d, iptr->val.i & 0x1f, d);
1113 M_IADD(d, REG_ZERO, d);
1114 store_reg_to_var_int(iptr->dst, d);
1117 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1119 var_to_reg_int(s1, src->prev, REG_ITMP1);
1120 var_to_reg_int(s2, src, REG_ITMP2);
1121 d = reg_of_var(iptr->dst, REG_ITMP3);
1123 store_reg_to_var_int(iptr->dst, d);
1126 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1127 /* val.l = constant */
1129 var_to_reg_int(s1, src, REG_ITMP1);
1130 d = reg_of_var(iptr->dst, REG_ITMP3);
1131 M_SLL_IMM(s1, iptr->val.l & 0x3f, d);
1132 store_reg_to_var_int(iptr->dst, d);
1135 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1137 var_to_reg_int(s1, src->prev, REG_ITMP1);
1138 var_to_reg_int(s2, src, REG_ITMP2);
1139 d = reg_of_var(iptr->dst, REG_ITMP3);
1141 store_reg_to_var_int(iptr->dst, d);
1144 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1145 /* val.l = constant */
1147 var_to_reg_int(s1, src, REG_ITMP1);
1148 d = reg_of_var(iptr->dst, REG_ITMP3);
1149 M_SRA_IMM(s1, iptr->val.l & 0x3f, d);
1150 store_reg_to_var_int(iptr->dst, d);
1153 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1155 var_to_reg_int(s1, src->prev, REG_ITMP1);
1156 var_to_reg_int(s2, src, REG_ITMP2);
1157 d = reg_of_var(iptr->dst, REG_ITMP3);
1159 store_reg_to_var_int(iptr->dst, d);
1162 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1163 /* val.l = constant */
1165 var_to_reg_int(s1, src, REG_ITMP1);
1166 d = reg_of_var(iptr->dst, REG_ITMP3);
1167 M_SRL_IMM(s1, iptr->val.l & 0x3f, d);
1168 store_reg_to_var_int(iptr->dst, d);
1171 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1174 var_to_reg_int(s1, src->prev, REG_ITMP1);
1175 var_to_reg_int(s2, src, REG_ITMP2);
1176 d = reg_of_var(iptr->dst, REG_ITMP3);
1178 store_reg_to_var_int(iptr->dst, d);
1181 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1182 /* val.i = constant */
1184 var_to_reg_int(s1, src, REG_ITMP1);
1185 d = reg_of_var(iptr->dst, REG_ITMP3);
1186 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1187 M_AND_IMM(s1, iptr->val.i, d);
1189 else if (iptr->val.i == 0xffff) {
1192 else if (iptr->val.i == 0xffffff) {
1193 M_ZAPNOT_IMM(s1, 0x07, d);
1196 ICONST(REG_ITMP2, iptr->val.i);
1197 M_AND(s1, REG_ITMP2, d);
1199 store_reg_to_var_int(iptr->dst, d);
1202 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1203 /* val.i = constant */
1205 var_to_reg_int(s1, src, REG_ITMP1);
1206 d = reg_of_var(iptr->dst, REG_ITMP3);
1208 M_MOV(s1, REG_ITMP1);
1211 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1212 M_AND_IMM(s1, iptr->val.i, d);
1214 M_ISUB(REG_ZERO, s1, d);
1215 M_AND_IMM(d, iptr->val.i, d);
1217 else if (iptr->val.i == 0xffff) {
1220 M_ISUB(REG_ZERO, s1, d);
1223 else if (iptr->val.i == 0xffffff) {
1224 M_ZAPNOT_IMM(s1, 0x07, d);
1226 M_ISUB(REG_ZERO, s1, d);
1227 M_ZAPNOT_IMM(d, 0x07, d);
1230 ICONST(REG_ITMP2, iptr->val.i);
1231 M_AND(s1, REG_ITMP2, d);
1233 M_ISUB(REG_ZERO, s1, d);
1234 M_AND(d, REG_ITMP2, d);
1236 M_ISUB(REG_ZERO, d, d);
1237 store_reg_to_var_int(iptr->dst, d);
1240 case ICMD_IREM0X10001: /* ..., value ==> ..., value % 0x100001 */
1242 /* b = value & 0xffff;
1244 a = ((b - a) & 0xffff) + (b < a);
1246 var_to_reg_int(s1, src, REG_ITMP1);
1247 d = reg_of_var(iptr->dst, REG_ITMP3);
1249 M_MOV(s1, REG_ITMP3);
1253 M_CZEXT(s1, REG_ITMP2);
1254 M_SRA_IMM(s1, 16, d);
1255 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1256 M_ISUB(REG_ITMP2, d, d);
1258 M_IADD(d, REG_ITMP1, d);
1259 M_BR(11 + (s1 == REG_ITMP1));
1260 M_ISUB(REG_ZERO, s1, REG_ITMP1);
1261 M_CZEXT(REG_ITMP1, REG_ITMP2);
1262 M_SRA_IMM(REG_ITMP1, 16, d);
1263 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1264 M_ISUB(REG_ITMP2, d, d);
1266 M_IADD(d, REG_ITMP1, d);
1267 M_ISUB(REG_ZERO, d, d);
1268 if (s1 == REG_ITMP1) {
1269 var_to_reg_int(s1, src, REG_ITMP1);
1271 M_SLL_IMM(s1, 33, REG_ITMP2);
1272 M_CMPEQ(REG_ITMP2, REG_ZERO, REG_ITMP2);
1273 M_ISUB(d, REG_ITMP2, d);
1274 store_reg_to_var_int(iptr->dst, d);
1277 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1278 /* val.l = constant */
1280 var_to_reg_int(s1, src, REG_ITMP1);
1281 d = reg_of_var(iptr->dst, REG_ITMP3);
1282 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1283 M_AND_IMM(s1, iptr->val.l, d);
1285 else if (iptr->val.l == 0xffffL) {
1288 else if (iptr->val.l == 0xffffffL) {
1289 M_ZAPNOT_IMM(s1, 0x07, d);
1291 else if (iptr->val.l == 0xffffffffL) {
1294 else if (iptr->val.l == 0xffffffffffL) {
1295 M_ZAPNOT_IMM(s1, 0x1f, d);
1297 else if (iptr->val.l == 0xffffffffffffL) {
1298 M_ZAPNOT_IMM(s1, 0x3f, d);
1300 else if (iptr->val.l == 0xffffffffffffffL) {
1301 M_ZAPNOT_IMM(s1, 0x7f, d);
1304 LCONST(REG_ITMP2, iptr->val.l);
1305 M_AND(s1, REG_ITMP2, d);
1307 store_reg_to_var_int(iptr->dst, d);
1310 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1311 /* val.l = constant */
1313 var_to_reg_int(s1, src, REG_ITMP1);
1314 d = reg_of_var(iptr->dst, REG_ITMP3);
1316 M_MOV(s1, REG_ITMP1);
1319 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1320 M_AND_IMM(s1, iptr->val.l, d);
1322 M_LSUB(REG_ZERO, s1, d);
1323 M_AND_IMM(d, iptr->val.l, d);
1325 else if (iptr->val.l == 0xffffL) {
1328 M_LSUB(REG_ZERO, s1, d);
1331 else if (iptr->val.l == 0xffffffL) {
1332 M_ZAPNOT_IMM(s1, 0x07, d);
1334 M_LSUB(REG_ZERO, s1, d);
1335 M_ZAPNOT_IMM(d, 0x07, d);
1337 else if (iptr->val.l == 0xffffffffL) {
1340 M_LSUB(REG_ZERO, s1, d);
1343 else if (iptr->val.l == 0xffffffffffL) {
1344 M_ZAPNOT_IMM(s1, 0x1f, d);
1346 M_LSUB(REG_ZERO, s1, d);
1347 M_ZAPNOT_IMM(d, 0x1f, d);
1349 else if (iptr->val.l == 0xffffffffffffL) {
1350 M_ZAPNOT_IMM(s1, 0x3f, d);
1352 M_LSUB(REG_ZERO, s1, d);
1353 M_ZAPNOT_IMM(d, 0x3f, d);
1355 else if (iptr->val.l == 0xffffffffffffffL) {
1356 M_ZAPNOT_IMM(s1, 0x7f, d);
1358 M_LSUB(REG_ZERO, s1, d);
1359 M_ZAPNOT_IMM(d, 0x7f, d);
1362 LCONST(REG_ITMP2, iptr->val.l);
1363 M_AND(s1, REG_ITMP2, d);
1365 M_LSUB(REG_ZERO, s1, d);
1366 M_AND(d, REG_ITMP2, d);
1368 M_LSUB(REG_ZERO, d, d);
1369 store_reg_to_var_int(iptr->dst, d);
1372 case ICMD_LREM0X10001:/* ..., value ==> ..., value % 0x10001 */
1374 var_to_reg_int(s1, src, REG_ITMP1);
1375 d = reg_of_var(iptr->dst, REG_ITMP3);
1377 M_MOV(s1, REG_ITMP3);
1380 M_CZEXT(s1, REG_ITMP2);
1381 M_SRA_IMM(s1, 16, d);
1382 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1383 M_LSUB(REG_ITMP2, d, d);
1385 M_LADD(d, REG_ITMP1, d);
1386 M_LDA(REG_ITMP2, REG_ZERO, -1);
1387 M_SRL_IMM(REG_ITMP2, 33, REG_ITMP2);
1388 if (s1 == REG_ITMP1) {
1389 var_to_reg_int(s1, src, REG_ITMP1);
1391 M_CMPULT(s1, REG_ITMP2, REG_ITMP2);
1392 M_BNEZ(REG_ITMP2, 11);
1393 M_LDA(d, REG_ZERO, -257);
1394 M_ZAPNOT_IMM(d, 0xcd, d);
1395 M_LSUB(REG_ZERO, s1, REG_ITMP2);
1396 M_CMOVGE(s1, s1, REG_ITMP2);
1397 M_UMULH(REG_ITMP2, d, REG_ITMP2);
1398 M_SRL_IMM(REG_ITMP2, 16, REG_ITMP2);
1399 M_LSUB(REG_ZERO, REG_ITMP2, d);
1400 M_CMOVGE(s1, REG_ITMP2, d);
1401 M_SLL_IMM(d, 16, REG_ITMP2);
1402 M_LADD(d, REG_ITMP2, d);
1404 store_reg_to_var_int(iptr->dst, d);
1407 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1410 var_to_reg_int(s1, src->prev, REG_ITMP1);
1411 var_to_reg_int(s2, src, REG_ITMP2);
1412 d = reg_of_var(iptr->dst, REG_ITMP3);
1414 store_reg_to_var_int(iptr->dst, d);
1417 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1418 /* val.i = constant */
1420 var_to_reg_int(s1, src, REG_ITMP1);
1421 d = reg_of_var(iptr->dst, REG_ITMP3);
1422 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1423 M_OR_IMM(s1, iptr->val.i, d);
1426 ICONST(REG_ITMP2, iptr->val.i);
1427 M_OR(s1, REG_ITMP2, d);
1429 store_reg_to_var_int(iptr->dst, d);
1432 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1433 /* val.l = constant */
1435 var_to_reg_int(s1, src, REG_ITMP1);
1436 d = reg_of_var(iptr->dst, REG_ITMP3);
1437 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1438 M_OR_IMM(s1, iptr->val.l, d);
1441 LCONST(REG_ITMP2, iptr->val.l);
1442 M_OR(s1, REG_ITMP2, d);
1444 store_reg_to_var_int(iptr->dst, d);
1447 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1450 var_to_reg_int(s1, src->prev, REG_ITMP1);
1451 var_to_reg_int(s2, src, REG_ITMP2);
1452 d = reg_of_var(iptr->dst, REG_ITMP3);
1454 store_reg_to_var_int(iptr->dst, d);
1457 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1458 /* val.i = constant */
1460 var_to_reg_int(s1, src, REG_ITMP1);
1461 d = reg_of_var(iptr->dst, REG_ITMP3);
1462 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1463 M_XOR_IMM(s1, iptr->val.i, d);
1466 ICONST(REG_ITMP2, iptr->val.i);
1467 M_XOR(s1, REG_ITMP2, d);
1469 store_reg_to_var_int(iptr->dst, d);
1472 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1473 /* val.l = constant */
1475 var_to_reg_int(s1, src, REG_ITMP1);
1476 d = reg_of_var(iptr->dst, REG_ITMP3);
1477 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1478 M_XOR_IMM(s1, iptr->val.l, d);
1481 LCONST(REG_ITMP2, iptr->val.l);
1482 M_XOR(s1, REG_ITMP2, d);
1484 store_reg_to_var_int(iptr->dst, d);
1488 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1490 var_to_reg_int(s1, src->prev, REG_ITMP1);
1491 var_to_reg_int(s2, src, REG_ITMP2);
1492 d = reg_of_var(iptr->dst, REG_ITMP3);
1493 M_CMPLT(s1, s2, REG_ITMP3);
1494 M_CMPLT(s2, s1, REG_ITMP1);
1495 M_LSUB (REG_ITMP1, REG_ITMP3, d);
1496 store_reg_to_var_int(iptr->dst, d);
1500 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1501 /* op1 = variable, val.i = constant */
1503 var = &(locals[iptr->op1][TYPE_INT]);
1504 if (var->flags & INMEMORY) {
1506 M_LLD(s1, REG_SP, 8 * var->regoff);
1510 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1511 M_IADD_IMM(s1, iptr->val.i, s1);
1513 else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1514 M_ISUB_IMM(s1, (-iptr->val.i), s1);
1517 M_LDA (s1, s1, iptr->val.i);
1518 M_IADD(s1, REG_ZERO, s1);
1520 if (var->flags & INMEMORY)
1521 M_LST(s1, REG_SP, 8 * var->regoff);
1525 /* floating operations ************************************************/
1527 case ICMD_FNEG: /* ..., value ==> ..., - value */
1529 var_to_reg_flt(s1, src, REG_FTMP1);
1530 d = reg_of_var(iptr->dst, REG_FTMP3);
1532 store_reg_to_var_flt(iptr->dst, d);
1535 case ICMD_DNEG: /* ..., value ==> ..., - value */
1537 var_to_reg_flt(s1, src, REG_FTMP1);
1538 d = reg_of_var(iptr->dst, REG_FTMP3);
1540 store_reg_to_var_flt(iptr->dst, d);
1543 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1545 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1546 var_to_reg_flt(s2, src, REG_FTMP2);
1547 d = reg_of_var(iptr->dst, REG_FTMP3);
1555 store_reg_to_var_flt(iptr->dst, d);
1558 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1560 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1561 var_to_reg_flt(s2, src, REG_FTMP2);
1562 d = reg_of_var(iptr->dst, REG_FTMP3);
1570 store_reg_to_var_flt(iptr->dst, d);
1573 case ICMD_FSUB: /* ..., 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_DSUB: /* ..., 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_FMUL: /* ..., 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_DMUL: /* ..., 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_FDIV: /* ..., 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_DDIV: /* ..., 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_FREM: /* ..., 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);
1669 M_FDIVS(s1,s2, REG_FTMP3);
1671 M_CVTDL_CS(REG_FTMP3, REG_FTMP3); /* round to integer */
1673 M_CVTLF(REG_FTMP3, REG_FTMP3);
1674 M_FMULS(REG_FTMP3, s2, REG_FTMP3);
1676 M_FSUBS(s1, REG_FTMP3, d);
1680 M_FDIV(s1,s2, REG_FTMP3);
1681 M_CVTDL_C(REG_FTMP3, REG_FTMP3); /* round to integer */
1682 M_CVTLF(REG_FTMP3, REG_FTMP3);
1683 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1684 M_FSUB(s1, REG_FTMP3, d);
1686 store_reg_to_var_flt(iptr->dst, d);
1689 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1691 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1692 var_to_reg_flt(s2, src, REG_FTMP2);
1693 d = reg_of_var(iptr->dst, REG_FTMP3);
1695 M_DDIVS(s1,s2, REG_FTMP3);
1697 M_CVTDL_CS(REG_FTMP3, REG_FTMP3); /* round to integer */
1699 M_CVTLD(REG_FTMP3, REG_FTMP3);
1700 M_DMULS(REG_FTMP3, s2, REG_FTMP3);
1702 M_DSUBS(s1, REG_FTMP3, d);
1706 M_DDIV(s1,s2, REG_FTMP3);
1707 M_CVTDL_C(REG_FTMP3, REG_FTMP3); /* round to integer */
1708 M_CVTLD(REG_FTMP3, REG_FTMP3);
1709 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1710 M_DSUB(s1, REG_FTMP3, d);
1712 store_reg_to_var_flt(iptr->dst, d);
1715 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1717 var_to_reg_int(s1, src, REG_ITMP1);
1718 d = reg_of_var(iptr->dst, REG_FTMP3);
1719 a = dseg_adddouble(0.0);
1720 M_LST (s1, REG_PV, a);
1721 M_DLD (d, REG_PV, a);
1723 store_reg_to_var_flt(iptr->dst, d);
1726 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1728 var_to_reg_int(s1, src, REG_ITMP1);
1729 d = reg_of_var(iptr->dst, REG_FTMP3);
1730 a = dseg_adddouble(0.0);
1731 M_LST (s1, REG_PV, a);
1732 M_DLD (d, REG_PV, a);
1734 store_reg_to_var_flt(iptr->dst, d);
1737 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1739 var_to_reg_flt(s1, src, REG_FTMP1);
1740 d = reg_of_var(iptr->dst, REG_ITMP3);
1741 a = dseg_adddouble(0.0);
1743 M_CVTDL_CS(s1, REG_FTMP1);
1745 M_CVTLIS(REG_FTMP1, REG_FTMP2);
1749 M_CVTDL_C(s1, REG_FTMP1);
1750 M_CVTLI(REG_FTMP1, REG_FTMP2);
1752 M_DST (REG_FTMP1, REG_PV, a);
1753 M_ILD (d, REG_PV, a);
1754 store_reg_to_var_int(iptr->dst, d);
1757 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1759 var_to_reg_flt(s1, src, REG_FTMP1);
1760 d = reg_of_var(iptr->dst, REG_ITMP3);
1761 a = dseg_adddouble(0.0);
1763 M_CVTDL_CS(s1, REG_FTMP1);
1767 M_CVTDL_C(s1, REG_FTMP1);
1769 M_DST (REG_FTMP1, REG_PV, a);
1770 M_LLD (d, REG_PV, a);
1771 store_reg_to_var_int(iptr->dst, d);
1774 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1776 var_to_reg_flt(s1, src, REG_FTMP1);
1777 d = reg_of_var(iptr->dst, REG_FTMP3);
1779 store_reg_to_var_flt(iptr->dst, d);
1782 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1784 var_to_reg_flt(s1, src, REG_FTMP1);
1785 d = reg_of_var(iptr->dst, REG_FTMP3);
1793 store_reg_to_var_flt(iptr->dst, d);
1796 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1798 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1799 var_to_reg_flt(s2, src, REG_FTMP2);
1800 d = reg_of_var(iptr->dst, REG_ITMP3);
1802 M_LSUB_IMM(REG_ZERO, 1, d);
1803 M_FCMPEQS(s1, s2, REG_FTMP3);
1805 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1807 M_FCMPLTS(s2, s1, REG_FTMP3);
1809 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1810 M_LADD_IMM(REG_ZERO, 1, d);
1813 M_LSUB_IMM(REG_ZERO, 1, d);
1814 M_FCMPEQ(s1, s2, REG_FTMP3);
1815 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1817 M_FCMPLT(s2, s1, REG_FTMP3);
1818 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1819 M_LADD_IMM(REG_ZERO, 1, d);
1821 store_reg_to_var_int(iptr->dst, d);
1824 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1826 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1827 var_to_reg_flt(s2, src, REG_FTMP2);
1828 d = reg_of_var(iptr->dst, REG_ITMP3);
1830 M_LADD_IMM(REG_ZERO, 1, d);
1831 M_FCMPEQS(s1, s2, REG_FTMP3);
1833 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1835 M_FCMPLTS(s1, s2, REG_FTMP3);
1837 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1838 M_LSUB_IMM(REG_ZERO, 1, d);
1841 M_LADD_IMM(REG_ZERO, 1, d);
1842 M_FCMPEQ(s1, s2, REG_FTMP3);
1843 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1845 M_FCMPLT(s1, s2, REG_FTMP3);
1846 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1847 M_LSUB_IMM(REG_ZERO, 1, d);
1849 store_reg_to_var_int(iptr->dst, d);
1853 /* memory operations **************************************************/
1855 #define gen_bound_check \
1857 M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\
1858 M_CMPULT(s2, REG_ITMP3, REG_ITMP3);\
1859 M_BEQZ(REG_ITMP3, 0);\
1860 mcode_addxboundrefs(mcodeptr);\
1863 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1865 var_to_reg_int(s1, src, REG_ITMP1);
1866 d = reg_of_var(iptr->dst, REG_ITMP3);
1867 gen_nullptr_check(s1);
1868 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1869 store_reg_to_var_int(iptr->dst, d);
1872 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1874 var_to_reg_int(s1, src->prev, REG_ITMP1);
1875 var_to_reg_int(s2, src, REG_ITMP2);
1876 d = reg_of_var(iptr->dst, REG_ITMP3);
1877 gen_nullptr_check(s1);
1879 M_SAADDQ(s2, s1, REG_ITMP1);
1880 M_ALD( d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1881 store_reg_to_var_int(iptr->dst, d);
1884 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1886 var_to_reg_int(s1, src->prev, REG_ITMP1);
1887 var_to_reg_int(s2, src, REG_ITMP2);
1888 d = reg_of_var(iptr->dst, REG_ITMP3);
1889 gen_nullptr_check(s1);
1891 M_S8ADDQ(s2, s1, REG_ITMP1);
1892 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1893 store_reg_to_var_int(iptr->dst, d);
1896 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1898 var_to_reg_int(s1, src->prev, REG_ITMP1);
1899 var_to_reg_int(s2, src, REG_ITMP2);
1900 d = reg_of_var(iptr->dst, REG_ITMP3);
1901 gen_nullptr_check(s1);
1903 M_S4ADDQ(s2, s1, REG_ITMP1);
1904 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1905 store_reg_to_var_int(iptr->dst, d);
1908 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1910 var_to_reg_int(s1, src->prev, REG_ITMP1);
1911 var_to_reg_int(s2, src, REG_ITMP2);
1912 d = reg_of_var(iptr->dst, REG_FTMP3);
1913 gen_nullptr_check(s1);
1915 M_S4ADDQ(s2, s1, REG_ITMP1);
1916 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1917 store_reg_to_var_flt(iptr->dst, d);
1920 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1922 var_to_reg_int(s1, src->prev, REG_ITMP1);
1923 var_to_reg_int(s2, src, REG_ITMP2);
1924 d = reg_of_var(iptr->dst, REG_FTMP3);
1925 gen_nullptr_check(s1);
1927 M_S8ADDQ(s2, s1, REG_ITMP1);
1928 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1929 store_reg_to_var_flt(iptr->dst, d);
1932 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1934 var_to_reg_int(s1, src->prev, REG_ITMP1);
1935 var_to_reg_int(s2, src, REG_ITMP2);
1936 d = reg_of_var(iptr->dst, REG_ITMP3);
1937 gen_nullptr_check(s1);
1939 if (has_ext_instr_set) {
1940 M_LADD(s2, s1, REG_ITMP1);
1941 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1942 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1945 M_LADD (s2, s1, REG_ITMP1);
1946 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1947 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1948 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1949 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
1951 store_reg_to_var_int(iptr->dst, d);
1954 case ICMD_SALOAD: /* ..., 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_ITMP3);
1959 gen_nullptr_check(s1);
1961 if (has_ext_instr_set) {
1962 M_LADD(s2, s1, REG_ITMP1);
1963 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1964 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1968 M_LADD(s2, s1, REG_ITMP1);
1969 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1970 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1971 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1972 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1973 M_SRA_IMM(d, 48, d);
1975 store_reg_to_var_int(iptr->dst, d);
1978 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1980 var_to_reg_int(s1, src->prev, REG_ITMP1);
1981 var_to_reg_int(s2, src, REG_ITMP2);
1982 d = reg_of_var(iptr->dst, REG_ITMP3);
1983 gen_nullptr_check(s1);
1985 if (has_ext_instr_set) {
1986 M_LADD (s2, s1, REG_ITMP1);
1987 M_BLDU (d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1991 M_LADD(s2, s1, REG_ITMP1);
1992 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1993 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
1994 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1995 M_SRA_IMM(d, 56, d);
1997 store_reg_to_var_int(iptr->dst, d);
2001 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
2003 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2004 var_to_reg_int(s2, src->prev, REG_ITMP2);
2005 gen_nullptr_check(s1);
2007 var_to_reg_int(s3, src, REG_ITMP3);
2008 M_SAADDQ(s2, s1, REG_ITMP1);
2009 M_AST (s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
2012 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
2014 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2015 var_to_reg_int(s2, src->prev, REG_ITMP2);
2016 gen_nullptr_check(s1);
2018 var_to_reg_int(s3, src, REG_ITMP3);
2019 M_S8ADDQ(s2, s1, REG_ITMP1);
2020 M_LST (s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
2023 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
2025 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2026 var_to_reg_int(s2, src->prev, REG_ITMP2);
2027 gen_nullptr_check(s1);
2029 var_to_reg_int(s3, src, REG_ITMP3);
2030 M_S4ADDQ(s2, s1, REG_ITMP1);
2031 M_IST (s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
2034 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
2036 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2037 var_to_reg_int(s2, src->prev, REG_ITMP2);
2038 gen_nullptr_check(s1);
2040 var_to_reg_flt(s3, src, REG_FTMP3);
2041 M_S4ADDQ(s2, s1, REG_ITMP1);
2042 M_FST (s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
2045 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
2047 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2048 var_to_reg_int(s2, src->prev, REG_ITMP2);
2049 gen_nullptr_check(s1);
2051 var_to_reg_flt(s3, src, REG_FTMP3);
2052 M_S8ADDQ(s2, s1, REG_ITMP1);
2053 M_DST (s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
2056 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
2058 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2059 var_to_reg_int(s2, src->prev, REG_ITMP2);
2060 gen_nullptr_check(s1);
2062 var_to_reg_int(s3, src, REG_ITMP3);
2063 if (has_ext_instr_set) {
2064 M_LADD(s2, s1, REG_ITMP1);
2065 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2066 M_SST (s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
2069 M_LADD (s2, s1, REG_ITMP1);
2070 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2071 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2072 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2073 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
2074 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2075 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2076 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2080 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
2082 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2083 var_to_reg_int(s2, src->prev, REG_ITMP2);
2084 gen_nullptr_check(s1);
2086 var_to_reg_int(s3, src, REG_ITMP3);
2087 if (has_ext_instr_set) {
2088 M_LADD(s2, s1, REG_ITMP1);
2089 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2090 M_SST (s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2093 M_LADD (s2, s1, REG_ITMP1);
2094 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2095 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2096 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2097 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
2098 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2099 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2100 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2104 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
2106 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2107 var_to_reg_int(s2, src->prev, REG_ITMP2);
2108 gen_nullptr_check(s1);
2110 var_to_reg_int(s3, src, REG_ITMP3);
2111 if (has_ext_instr_set) {
2112 M_LADD(s2, s1, REG_ITMP1);
2113 M_BST (s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2116 M_LADD (s2, s1, REG_ITMP1);
2117 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2118 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2119 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
2120 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2121 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2122 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2127 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2128 /* op1 = type, val.a = field address */
2130 a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value));
2131 M_ALD(REG_ITMP1, REG_PV, a);
2132 switch (iptr->op1) {
2134 var_to_reg_int(s2, src, REG_ITMP2);
2135 M_IST(s2, REG_ITMP1, 0);
2138 var_to_reg_int(s2, src, REG_ITMP2);
2139 M_LST(s2, REG_ITMP1, 0);
2142 var_to_reg_int(s2, src, REG_ITMP2);
2143 M_AST(s2, REG_ITMP1, 0);
2146 var_to_reg_flt(s2, src, REG_FTMP2);
2147 M_FST(s2, REG_ITMP1, 0);
2150 var_to_reg_flt(s2, src, REG_FTMP2);
2151 M_DST(s2, REG_ITMP1, 0);
2153 default: panic ("internal error");
2157 case ICMD_GETSTATIC: /* ... ==> ..., value */
2158 /* op1 = type, val.a = field address */
2160 a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value));
2161 M_ALD(REG_ITMP1, REG_PV, a);
2162 switch (iptr->op1) {
2164 d = reg_of_var(iptr->dst, REG_ITMP3);
2165 M_ILD(d, REG_ITMP1, 0);
2166 store_reg_to_var_int(iptr->dst, d);
2169 d = reg_of_var(iptr->dst, REG_ITMP3);
2170 M_LLD(d, REG_ITMP1, 0);
2171 store_reg_to_var_int(iptr->dst, d);
2174 d = reg_of_var(iptr->dst, REG_ITMP3);
2175 M_ALD(d, REG_ITMP1, 0);
2176 store_reg_to_var_int(iptr->dst, d);
2179 d = reg_of_var(iptr->dst, REG_FTMP1);
2180 M_FLD(d, REG_ITMP1, 0);
2181 store_reg_to_var_flt(iptr->dst, d);
2184 d = reg_of_var(iptr->dst, REG_FTMP1);
2185 M_DLD(d, REG_ITMP1, 0);
2186 store_reg_to_var_flt(iptr->dst, d);
2188 default: panic ("internal error");
2193 case ICMD_PUTFIELD: /* ..., value ==> ... */
2194 /* op1 = type, val.i = field offset */
2196 a = ((fieldinfo *)(iptr->val.a))->offset;
2197 switch (iptr->op1) {
2199 var_to_reg_int(s1, src->prev, REG_ITMP1);
2200 var_to_reg_int(s2, src, REG_ITMP2);
2201 gen_nullptr_check(s1);
2205 var_to_reg_int(s1, src->prev, REG_ITMP1);
2206 var_to_reg_int(s2, src, REG_ITMP2);
2207 gen_nullptr_check(s1);
2211 var_to_reg_int(s1, src->prev, REG_ITMP1);
2212 var_to_reg_int(s2, src, REG_ITMP2);
2213 gen_nullptr_check(s1);
2217 var_to_reg_int(s1, src->prev, REG_ITMP1);
2218 var_to_reg_flt(s2, src, REG_FTMP2);
2219 gen_nullptr_check(s1);
2223 var_to_reg_int(s1, src->prev, REG_ITMP1);
2224 var_to_reg_flt(s2, src, REG_FTMP2);
2225 gen_nullptr_check(s1);
2228 default: panic ("internal error");
2232 case ICMD_GETFIELD: /* ... ==> ..., value */
2233 /* op1 = type, val.i = field offset */
2235 a = ((fieldinfo *)(iptr->val.a))->offset;
2236 switch (iptr->op1) {
2238 var_to_reg_int(s1, src, REG_ITMP1);
2239 d = reg_of_var(iptr->dst, REG_ITMP3);
2240 gen_nullptr_check(s1);
2242 store_reg_to_var_int(iptr->dst, d);
2245 var_to_reg_int(s1, src, REG_ITMP1);
2246 d = reg_of_var(iptr->dst, REG_ITMP3);
2247 gen_nullptr_check(s1);
2249 store_reg_to_var_int(iptr->dst, d);
2252 var_to_reg_int(s1, src, REG_ITMP1);
2253 d = reg_of_var(iptr->dst, REG_ITMP3);
2254 gen_nullptr_check(s1);
2256 store_reg_to_var_int(iptr->dst, d);
2259 var_to_reg_int(s1, src, REG_ITMP1);
2260 d = reg_of_var(iptr->dst, REG_FTMP1);
2261 gen_nullptr_check(s1);
2263 store_reg_to_var_flt(iptr->dst, d);
2266 var_to_reg_int(s1, src, REG_ITMP1);
2267 d = reg_of_var(iptr->dst, REG_FTMP1);
2268 gen_nullptr_check(s1);
2270 store_reg_to_var_flt(iptr->dst, d);
2272 default: panic ("internal error");
2277 /* branch operations **************************************************/
2279 #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}}
2281 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2283 var_to_reg_int(s1, src, REG_ITMP1);
2284 M_INTMOVE(s1, REG_ITMP1_XPTR);
2285 a = dseg_addaddress(asm_handle_exception);
2286 M_ALD(REG_ITMP2, REG_PV, a);
2287 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2291 case ICMD_GOTO: /* ... ==> ... */
2292 /* op1 = target JavaVM pc */
2294 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2298 case ICMD_JSR: /* ... ==> ... */
2299 /* op1 = target JavaVM pc */
2301 M_BSR(REG_ITMP1, 0);
2302 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2305 case ICMD_RET: /* ... ==> ... */
2306 /* op1 = local variable */
2308 var = &(locals[iptr->op1][TYPE_ADR]);
2309 if (var->flags & INMEMORY) {
2310 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2311 M_RET(REG_ZERO, REG_ITMP1);
2314 M_RET(REG_ZERO, var->regoff);
2318 case ICMD_IFNULL: /* ..., value ==> ... */
2319 /* op1 = target JavaVM pc */
2321 var_to_reg_int(s1, src, REG_ITMP1);
2323 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2326 case ICMD_IFNONNULL: /* ..., value ==> ... */
2327 /* op1 = target JavaVM pc */
2329 var_to_reg_int(s1, src, REG_ITMP1);
2331 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2334 case ICMD_IFEQ: /* ..., value ==> ... */
2335 /* op1 = target JavaVM pc, val.i = constant */
2337 var_to_reg_int(s1, src, REG_ITMP1);
2338 if (iptr->val.i == 0) {
2342 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2343 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2346 ICONST(REG_ITMP2, iptr->val.i);
2347 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2349 M_BNEZ(REG_ITMP1, 0);
2351 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2354 case ICMD_IFLT: /* ..., value ==> ... */
2355 /* op1 = target JavaVM pc, val.i = constant */
2357 var_to_reg_int(s1, src, REG_ITMP1);
2358 if (iptr->val.i == 0) {
2362 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2363 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2366 ICONST(REG_ITMP2, iptr->val.i);
2367 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2369 M_BNEZ(REG_ITMP1, 0);
2371 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2374 case ICMD_IFLE: /* ..., value ==> ... */
2375 /* op1 = target JavaVM pc, val.i = constant */
2377 var_to_reg_int(s1, src, REG_ITMP1);
2378 if (iptr->val.i == 0) {
2382 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2383 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2386 ICONST(REG_ITMP2, iptr->val.i);
2387 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2389 M_BNEZ(REG_ITMP1, 0);
2391 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2394 case ICMD_IFNE: /* ..., value ==> ... */
2395 /* op1 = target JavaVM pc, val.i = constant */
2397 var_to_reg_int(s1, src, REG_ITMP1);
2398 if (iptr->val.i == 0) {
2402 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2403 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2406 ICONST(REG_ITMP2, iptr->val.i);
2407 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2409 M_BEQZ(REG_ITMP1, 0);
2411 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2414 case ICMD_IFGT: /* ..., value ==> ... */
2415 /* op1 = target JavaVM pc, val.i = constant */
2417 var_to_reg_int(s1, src, REG_ITMP1);
2418 if (iptr->val.i == 0) {
2422 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2423 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2426 ICONST(REG_ITMP2, iptr->val.i);
2427 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2429 M_BEQZ(REG_ITMP1, 0);
2431 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2434 case ICMD_IFGE: /* ..., value ==> ... */
2435 /* op1 = target JavaVM pc, val.i = constant */
2437 var_to_reg_int(s1, src, REG_ITMP1);
2438 if (iptr->val.i == 0) {
2442 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2443 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2446 ICONST(REG_ITMP2, iptr->val.i);
2447 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2449 M_BEQZ(REG_ITMP1, 0);
2451 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2454 case ICMD_IF_LEQ: /* ..., value ==> ... */
2455 /* op1 = target JavaVM pc, val.l = constant */
2457 var_to_reg_int(s1, src, REG_ITMP1);
2458 if (iptr->val.l == 0) {
2462 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2463 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2466 LCONST(REG_ITMP2, iptr->val.l);
2467 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2469 M_BNEZ(REG_ITMP1, 0);
2471 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2474 case ICMD_IF_LLT: /* ..., value ==> ... */
2475 /* op1 = target JavaVM pc, val.l = constant */
2477 var_to_reg_int(s1, src, REG_ITMP1);
2478 if (iptr->val.l == 0) {
2482 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2483 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2486 LCONST(REG_ITMP2, iptr->val.l);
2487 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2489 M_BNEZ(REG_ITMP1, 0);
2491 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2494 case ICMD_IF_LLE: /* ..., value ==> ... */
2495 /* op1 = target JavaVM pc, val.l = constant */
2497 var_to_reg_int(s1, src, REG_ITMP1);
2498 if (iptr->val.l == 0) {
2502 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2503 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2506 LCONST(REG_ITMP2, iptr->val.l);
2507 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2509 M_BNEZ(REG_ITMP1, 0);
2511 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2514 case ICMD_IF_LNE: /* ..., value ==> ... */
2515 /* op1 = target JavaVM pc, val.l = constant */
2517 var_to_reg_int(s1, src, REG_ITMP1);
2518 if (iptr->val.l == 0) {
2522 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2523 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2526 LCONST(REG_ITMP2, iptr->val.l);
2527 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2529 M_BEQZ(REG_ITMP1, 0);
2531 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2534 case ICMD_IF_LGT: /* ..., value ==> ... */
2535 /* op1 = target JavaVM pc, val.l = constant */
2537 var_to_reg_int(s1, src, REG_ITMP1);
2538 if (iptr->val.l == 0) {
2542 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2543 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2546 LCONST(REG_ITMP2, iptr->val.l);
2547 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2549 M_BEQZ(REG_ITMP1, 0);
2551 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2554 case ICMD_IF_LGE: /* ..., value ==> ... */
2555 /* op1 = target JavaVM pc, val.l = constant */
2557 var_to_reg_int(s1, src, REG_ITMP1);
2558 if (iptr->val.l == 0) {
2562 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2563 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2566 LCONST(REG_ITMP2, iptr->val.l);
2567 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2569 M_BEQZ(REG_ITMP1, 0);
2571 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2574 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2575 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2576 case ICMD_IF_ACMPEQ:
2578 var_to_reg_int(s1, src->prev, REG_ITMP1);
2579 var_to_reg_int(s2, src, REG_ITMP2);
2580 M_CMPEQ(s1, s2, REG_ITMP1);
2581 M_BNEZ(REG_ITMP1, 0);
2582 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2585 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2586 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2587 case ICMD_IF_ACMPNE:
2589 var_to_reg_int(s1, src->prev, REG_ITMP1);
2590 var_to_reg_int(s2, src, REG_ITMP2);
2591 M_CMPEQ(s1, s2, REG_ITMP1);
2592 M_BEQZ(REG_ITMP1, 0);
2593 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2596 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2597 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2599 var_to_reg_int(s1, src->prev, REG_ITMP1);
2600 var_to_reg_int(s2, src, REG_ITMP2);
2601 M_CMPLT(s1, s2, REG_ITMP1);
2602 M_BNEZ(REG_ITMP1, 0);
2603 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2606 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2607 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2609 var_to_reg_int(s1, src->prev, REG_ITMP1);
2610 var_to_reg_int(s2, src, REG_ITMP2);
2611 M_CMPLE(s1, s2, REG_ITMP1);
2612 M_BEQZ(REG_ITMP1, 0);
2613 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2616 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2617 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2619 var_to_reg_int(s1, src->prev, REG_ITMP1);
2620 var_to_reg_int(s2, src, REG_ITMP2);
2621 M_CMPLE(s1, s2, REG_ITMP1);
2622 M_BNEZ(REG_ITMP1, 0);
2623 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2626 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2627 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2629 var_to_reg_int(s1, src->prev, REG_ITMP1);
2630 var_to_reg_int(s2, src, REG_ITMP2);
2631 M_CMPLT(s1, s2, REG_ITMP1);
2632 M_BEQZ(REG_ITMP1, 0);
2633 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2636 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2638 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2641 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2642 /* val.i = constant */
2644 var_to_reg_int(s1, src, REG_ITMP1);
2645 d = reg_of_var(iptr->dst, REG_ITMP3);
2647 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2648 if ((a == 1) && (iptr[1].val.i == 0)) {
2649 M_CMPEQ(s1, REG_ZERO, d);
2650 store_reg_to_var_int(iptr->dst, d);
2653 if ((a == 0) && (iptr[1].val.i == 1)) {
2654 M_CMPEQ(s1, REG_ZERO, d);
2656 store_reg_to_var_int(iptr->dst, d);
2660 M_MOV(s1, REG_ITMP1);
2663 ICONST(d, iptr[1].val.i);
2665 if ((a >= 0) && (a <= 255)) {
2666 M_CMOVEQ_IMM(s1, a, d);
2669 ICONST(REG_ITMP2, a);
2670 M_CMOVEQ(s1, REG_ITMP2, d);
2672 store_reg_to_var_int(iptr->dst, d);
2675 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2676 /* val.i = constant */
2678 var_to_reg_int(s1, src, REG_ITMP1);
2679 d = reg_of_var(iptr->dst, REG_ITMP3);
2681 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2682 if ((a == 0) && (iptr[1].val.i == 1)) {
2683 M_CMPEQ(s1, REG_ZERO, d);
2684 store_reg_to_var_int(iptr->dst, d);
2687 if ((a == 1) && (iptr[1].val.i == 0)) {
2688 M_CMPEQ(s1, REG_ZERO, d);
2690 store_reg_to_var_int(iptr->dst, d);
2694 M_MOV(s1, REG_ITMP1);
2697 ICONST(d, iptr[1].val.i);
2699 if ((a >= 0) && (a <= 255)) {
2700 M_CMOVNE_IMM(s1, a, d);
2703 ICONST(REG_ITMP2, a);
2704 M_CMOVNE(s1, REG_ITMP2, d);
2706 store_reg_to_var_int(iptr->dst, d);
2709 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2710 /* val.i = constant */
2712 var_to_reg_int(s1, src, REG_ITMP1);
2713 d = reg_of_var(iptr->dst, REG_ITMP3);
2715 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2716 if ((a == 1) && (iptr[1].val.i == 0)) {
2717 M_CMPLT(s1, REG_ZERO, d);
2718 store_reg_to_var_int(iptr->dst, d);
2721 if ((a == 0) && (iptr[1].val.i == 1)) {
2722 M_CMPLE(REG_ZERO, s1, d);
2723 store_reg_to_var_int(iptr->dst, d);
2727 M_MOV(s1, REG_ITMP1);
2730 ICONST(d, iptr[1].val.i);
2732 if ((a >= 0) && (a <= 255)) {
2733 M_CMOVLT_IMM(s1, a, d);
2736 ICONST(REG_ITMP2, a);
2737 M_CMOVLT(s1, REG_ITMP2, d);
2739 store_reg_to_var_int(iptr->dst, d);
2742 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2743 /* val.i = constant */
2745 var_to_reg_int(s1, src, REG_ITMP1);
2746 d = reg_of_var(iptr->dst, REG_ITMP3);
2748 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2749 if ((a == 1) && (iptr[1].val.i == 0)) {
2750 M_CMPLE(REG_ZERO, s1, d);
2751 store_reg_to_var_int(iptr->dst, d);
2754 if ((a == 0) && (iptr[1].val.i == 1)) {
2755 M_CMPLT(s1, REG_ZERO, d);
2756 store_reg_to_var_int(iptr->dst, d);
2760 M_MOV(s1, REG_ITMP1);
2763 ICONST(d, iptr[1].val.i);
2765 if ((a >= 0) && (a <= 255)) {
2766 M_CMOVGE_IMM(s1, a, d);
2769 ICONST(REG_ITMP2, a);
2770 M_CMOVGE(s1, REG_ITMP2, d);
2772 store_reg_to_var_int(iptr->dst, d);
2775 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2776 /* val.i = constant */
2778 var_to_reg_int(s1, src, REG_ITMP1);
2779 d = reg_of_var(iptr->dst, REG_ITMP3);
2781 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2782 if ((a == 1) && (iptr[1].val.i == 0)) {
2783 M_CMPLT(REG_ZERO, s1, d);
2784 store_reg_to_var_int(iptr->dst, d);
2787 if ((a == 0) && (iptr[1].val.i == 1)) {
2788 M_CMPLE(s1, REG_ZERO, d);
2789 store_reg_to_var_int(iptr->dst, d);
2793 M_MOV(s1, REG_ITMP1);
2796 ICONST(d, iptr[1].val.i);
2798 if ((a >= 0) && (a <= 255)) {
2799 M_CMOVGT_IMM(s1, a, d);
2802 ICONST(REG_ITMP2, a);
2803 M_CMOVGT(s1, REG_ITMP2, d);
2805 store_reg_to_var_int(iptr->dst, d);
2808 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2809 /* val.i = constant */
2811 var_to_reg_int(s1, src, REG_ITMP1);
2812 d = reg_of_var(iptr->dst, REG_ITMP3);
2814 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2815 if ((a == 1) && (iptr[1].val.i == 0)) {
2816 M_CMPLE(s1, REG_ZERO, d);
2817 store_reg_to_var_int(iptr->dst, d);
2820 if ((a == 0) && (iptr[1].val.i == 1)) {
2821 M_CMPLT(REG_ZERO, s1, d);
2822 store_reg_to_var_int(iptr->dst, d);
2826 M_MOV(s1, REG_ITMP1);
2829 ICONST(d, iptr[1].val.i);
2831 if ((a >= 0) && (a <= 255)) {
2832 M_CMOVLE_IMM(s1, a, d);
2835 ICONST(REG_ITMP2, a);
2836 M_CMOVLE(s1, REG_ITMP2, d);
2838 store_reg_to_var_int(iptr->dst, d);
2842 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2847 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2848 a = dseg_addaddress ((void*) (builtin_monitorexit));
2849 M_ALD(REG_PV, REG_PV, a);
2850 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
2851 M_JSR(REG_RA, REG_PV);
2852 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2855 var_to_reg_int(s1, src, REG_RESULT);
2856 M_INTMOVE(s1, REG_RESULT);
2857 goto nowperformreturn;
2859 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2863 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2864 a = dseg_addaddress ((void*) (builtin_monitorexit));
2865 M_ALD(REG_PV, REG_PV, a);
2866 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
2867 M_JSR(REG_RA, REG_PV);
2868 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2871 var_to_reg_flt(s1, src, REG_FRESULT);
2872 M_FLTMOVE(s1, REG_FRESULT);
2873 goto nowperformreturn;
2875 case ICMD_RETURN: /* ... ==> ... */
2878 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2879 a = dseg_addaddress ((void*) (builtin_monitorexit));
2880 M_ALD(REG_PV, REG_PV, a);
2881 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
2882 M_JSR(REG_RA, REG_PV);
2883 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2891 p = parentargs_base;
2893 /* restore return address */
2896 {p--; M_LLD (REG_RA, REG_SP, 8 * p);}
2898 /* restore saved registers */
2900 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
2901 {p--; M_LLD(savintregs[r], REG_SP, 8 * p);}
2902 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
2903 {p--; M_DLD(savfltregs[r], REG_SP, 8 * p);}
2905 /* deallocate stack */
2907 if (parentargs_base)
2908 {M_LDA(REG_SP, REG_SP, parentargs_base*8);}
2910 /* call trace function */
2913 M_LDA (REG_SP, REG_SP, -24);
2914 M_AST(REG_RA, REG_SP, 0);
2915 M_LST(REG_RESULT, REG_SP, 8);
2916 M_DST(REG_FRESULT, REG_SP,16);
2917 a = dseg_addaddress (method);
2918 M_ALD(argintregs[0], REG_PV, a);
2919 M_MOV(REG_RESULT, argintregs[1]);
2920 M_FLTMOVE(REG_FRESULT, argfltregs[2]);
2921 a = dseg_addaddress ((void*) (builtin_displaymethodstop));
2922 M_ALD(REG_PV, REG_PV, a);
2923 M_JSR (REG_RA, REG_PV);
2924 s1 = (int)((u1*) mcodeptr - mcodebase);
2925 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
2928 while (ml<-32768) { ml+=65536; mh--; }
2929 M_LDA (REG_PV, REG_RA, ml );
2930 M_LDAH (REG_PV, REG_PV, mh );
2932 M_DLD(REG_FRESULT, REG_SP,16);
2933 M_LLD(REG_RESULT, REG_SP, 8);
2934 M_ALD(REG_RA, REG_SP, 0);
2935 M_LDA (REG_SP, REG_SP, 24);
2938 M_RET(REG_ZERO, REG_RA);
2944 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2948 s4ptr = iptr->val.a;
2949 l = s4ptr[1]; /* low */
2950 i = s4ptr[2]; /* high */
2952 var_to_reg_int(s1, src, REG_ITMP1);
2954 {M_INTMOVE(s1, REG_ITMP1);}
2956 M_LDA(REG_ITMP1, s1, -l);
2962 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
2964 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
2965 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
2967 M_BEQZ(REG_ITMP2, 0);
2968 mcode_addreference(BlockPtrOfPC(s4ptr[0]), mcodeptr);
2970 /* build jump table top down and use address of lowest entry */
2974 dseg_addtarget(BlockPtrOfPC(*--s4ptr));
2978 /* length of dataseg after last dseg_addtarget is used by load */
2980 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
2981 M_ALD(REG_ITMP2, REG_ITMP2, -dseglen);
2982 M_JMP(REG_ZERO, REG_ITMP2);
2987 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2989 s4 i, l, val, *s4ptr;
2991 s4ptr = iptr->val.a;
2992 l = s4ptr[0]; /* default */
2993 i = s4ptr[1]; /* count */
2995 MCODECHECK((i<<2)+8);
2996 var_to_reg_int(s1, src, REG_ITMP1);
3000 if ((val >= 0) && (val <= 255)) {
3001 M_CMPEQ_IMM(s1, val, REG_ITMP2);
3004 if ((val >= -32768) && (val <= 32767)) {
3005 M_LDA(REG_ITMP2, REG_ZERO, val);
3008 a = dseg_adds4 (val);
3009 M_ILD(REG_ITMP2, REG_PV, a);
3011 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
3013 M_BNEZ(REG_ITMP2, 0);
3014 mcode_addreference(BlockPtrOfPC(s4ptr[1]), mcodeptr);
3018 mcode_addreference(BlockPtrOfPC(l), mcodeptr);
3024 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
3025 /* op1 = return type, val.a = function pointer*/
3029 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
3030 /* op1 = return type, val.a = function pointer*/
3034 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
3035 /* op1 = return type, val.a = function pointer*/
3039 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3040 /* op1 = arg count, val.a = method pointer */
3042 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3043 /* op1 = arg count, val.a = method pointer */
3045 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3046 /* op1 = arg count, val.a = method pointer */
3048 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
3049 /* op1 = arg count, val.a = method pointer */
3057 MCODECHECK((s3 << 1) + 64);
3059 /* copy arguments to registers or stack location */
3061 for (; --s3 >= 0; src = src->prev) {
3062 if (src->varkind == ARGVAR)
3064 if (IS_INT_LNG_TYPE(src->type)) {
3065 if (s3 < INT_ARG_CNT) {
3066 s1 = argintregs[s3];
3067 var_to_reg_int(d, src, s1);
3071 var_to_reg_int(d, src, REG_ITMP1);
3072 M_LST(d, REG_SP, 8 * (s3 - INT_ARG_CNT));
3076 if (s3 < FLT_ARG_CNT) {
3077 s1 = argfltregs[s3];
3078 var_to_reg_flt(d, src, s1);
3082 var_to_reg_flt(d, src, REG_FTMP1);
3083 M_DST(d, REG_SP, 8 * (s3 - FLT_ARG_CNT));
3088 switch (iptr->opc) {
3092 a = dseg_addaddress ((void*) (m));
3094 M_ALD(REG_PV, REG_PV, a); /* Pointer to built-in-function */
3096 goto makeactualcall;
3098 case ICMD_INVOKESTATIC:
3099 case ICMD_INVOKESPECIAL:
3100 a = dseg_addaddress (m->stubroutine);
3102 M_ALD(REG_PV, REG_PV, a ); /* method pointer in r27 */
3105 goto makeactualcall;
3107 case ICMD_INVOKEVIRTUAL:
3109 gen_nullptr_check(argintregs[0]);
3110 M_ALD(REG_METHODPTR, argintregs[0],
3111 OFFSET(java_objectheader, vftbl));
3112 M_ALD(REG_PV, REG_METHODPTR, OFFSET(vftbl, table[0]) +
3113 sizeof(methodptr) * m->vftblindex);
3116 goto makeactualcall;
3118 case ICMD_INVOKEINTERFACE:
3121 gen_nullptr_check(argintregs[0]);
3122 M_ALD(REG_METHODPTR, argintregs[0],
3123 OFFSET(java_objectheader, vftbl));
3124 M_ALD(REG_METHODPTR, REG_METHODPTR,
3125 OFFSET(vftbl, interfacetable[0]) -
3126 sizeof(methodptr*) * ci->index);
3127 M_ALD(REG_PV, REG_METHODPTR,
3128 sizeof(methodptr) * (m - ci->methods));
3131 goto makeactualcall;
3135 sprintf (logtext, "Unkown ICMD-Command: %d", iptr->opc);
3141 M_JSR (REG_RA, REG_PV);
3145 s1 = (int)((u1*) mcodeptr - mcodebase);
3146 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
3149 while (ml<-32768) { ml+=65536; mh--; }
3150 M_LDA (REG_PV, REG_RA, ml );
3151 M_LDAH (REG_PV, REG_PV, mh );
3154 /* d contains return type */
3156 if (d != TYPE_VOID) {
3157 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3158 s1 = reg_of_var(iptr->dst, REG_RESULT);
3159 M_INTMOVE(REG_RESULT, s1);
3160 store_reg_to_var_int(iptr->dst, s1);
3163 s1 = reg_of_var(iptr->dst, REG_FRESULT);
3164 M_FLTMOVE(REG_FRESULT, s1);
3165 store_reg_to_var_flt(iptr->dst, s1);
3172 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3174 /* op1: 0 == array, 1 == class */
3175 /* val.a: (classinfo*) superclass */
3177 /* superclass is an interface:
3179 * return (sub != NULL) &&
3180 * (sub->vftbl->interfacetablelength > super->index) &&
3181 * (sub->vftbl->interfacetable[-super->index] != NULL);
3183 * superclass is a class:
3185 * return ((sub != NULL) && (0
3186 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3187 * super->vftbl->diffvall));
3191 classinfo *super = (classinfo*) iptr->val.a;
3193 var_to_reg_int(s1, src, REG_ITMP1);
3194 d = reg_of_var(iptr->dst, REG_ITMP3);
3196 M_MOV(s1, REG_ITMP1);
3200 if (iptr->op1) { /* class/interface */
3201 if (super->flags & ACC_INTERFACE) { /* interface */
3203 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3204 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3205 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3206 M_BLEZ(REG_ITMP2, 2);
3207 M_ALD(REG_ITMP1, REG_ITMP1,
3208 OFFSET(vftbl, interfacetable[0]) -
3209 super->index * sizeof(methodptr*));
3210 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3213 s2 = super->vftbl->diffval;
3214 M_BEQZ(s1, 4 + (s2 > 255));
3215 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3216 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3217 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3219 M_CMPULE_IMM(REG_ITMP1, s2, d);
3221 M_LDA(REG_ITMP2, REG_ZERO, s2);
3222 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3227 panic ("internal error: no inlined array instanceof");
3229 store_reg_to_var_int(iptr->dst, d);
3232 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3234 /* op1: 0 == array, 1 == class */
3235 /* val.a: (classinfo*) superclass */
3237 /* superclass is an interface:
3239 * OK if ((sub == NULL) ||
3240 * (sub->vftbl->interfacetablelength > super->index) &&
3241 * (sub->vftbl->interfacetable[-super->index] != NULL));
3243 * superclass is a class:
3245 * OK if ((sub == NULL) || (0
3246 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3247 * super->vftbl->diffvall));
3251 classinfo *super = (classinfo*) iptr->val.a;
3253 d = reg_of_var(iptr->dst, REG_ITMP3);
3254 var_to_reg_int(s1, src, d);
3255 if (iptr->op1) { /* class/interface */
3256 if (super->flags & ACC_INTERFACE) { /* interface */
3258 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3259 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3260 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3261 M_BLEZ(REG_ITMP2, 0);
3262 mcode_addxcastrefs(mcodeptr);
3263 M_ALD(REG_ITMP2, REG_ITMP1,
3264 OFFSET(vftbl, interfacetable[0]) -
3265 super->index * sizeof(methodptr*));
3266 M_BEQZ(REG_ITMP2, 0);
3267 mcode_addxcastrefs(mcodeptr);
3270 s2 = super->vftbl->diffval;
3271 M_BEQZ(s1, 4 + (s2 != 0) + (s2 > 255));
3272 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3273 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3274 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3276 M_BNEZ(REG_ITMP1, 0);
3278 else if (s2 <= 255) {
3279 M_CMPULE_IMM(REG_ITMP1, s2, REG_ITMP2);
3280 M_BEQZ(REG_ITMP2, 0);
3283 M_LDA(REG_ITMP2, REG_ZERO, s2);
3284 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3285 M_BEQZ(REG_ITMP2, 0);
3287 mcode_addxcastrefs(mcodeptr);
3291 panic ("internal error: no inlined array checkcast");
3294 store_reg_to_var_int(iptr->dst, d);
3297 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
3299 var_to_reg_int(s1, src, REG_ITMP1);
3301 mcode_addxcheckarefs(mcodeptr);
3304 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3305 /* op1 = dimension, val.a = array descriptor */
3307 /* check for negative sizes and copy sizes to stack if necessary */
3309 MCODECHECK((iptr->op1 << 1) + 64);
3311 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3312 var_to_reg_int(s2, src, REG_ITMP1);
3314 mcode_addxcheckarefs(mcodeptr);
3316 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
3318 if (src->varkind != ARGVAR) {
3319 M_LST(s2, REG_SP, 8 * (s1 + INT_ARG_CNT));
3323 /* a0 = dimension count */
3325 M_LDA(argintregs[0], REG_ZERO, iptr->op1);
3327 /* a1 = arraydescriptor */
3329 a = dseg_addaddress(iptr->val.a);
3330 M_ALD(argintregs[1], REG_PV, a);
3332 /* a2 = pointer to dimensions = stack pointer */
3334 M_INTMOVE(REG_SP, argintregs[2]);
3336 a = dseg_addaddress((void*) (builtin_nmultianewarray));
3337 M_ALD(REG_PV, REG_PV, a);
3338 M_JSR(REG_RA, REG_PV);
3339 s1 = (int)((u1*) mcodeptr - mcodebase);
3341 M_LDA (REG_PV, REG_RA, -s1);
3343 s4 ml = -s1, mh = 0;
3344 while (ml < -32768) {ml += 65536; mh--;}
3345 M_LDA(REG_PV, REG_RA, ml);
3346 M_LDAH(REG_PV, REG_PV, mh);
3348 s1 = reg_of_var(iptr->dst, REG_RESULT);
3349 M_INTMOVE(REG_RESULT, s1);
3350 store_reg_to_var_int(iptr->dst, s1);
3354 default: sprintf (logtext, "Unknown pseudo command: %d", iptr->opc);
3357 } /* for instruction */
3359 /* copy values to interface registers */
3361 src = bptr->outstack;
3362 len = bptr->outdepth;
3366 if ((src->varkind != STACKVAR)) {
3368 if (IS_FLT_DBL_TYPE(s2)) {
3369 var_to_reg_flt(s1, src, REG_FTMP1);
3370 if (!(interfaces[len][s2].flags & INMEMORY)) {
3371 M_FLTMOVE(s1,interfaces[len][s2].regoff);
3374 M_DST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3378 var_to_reg_int(s1, src, REG_ITMP1);
3379 if (!(interfaces[len][s2].flags & INMEMORY)) {
3380 M_INTMOVE(s1,interfaces[len][s2].regoff);
3383 M_LST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3389 } /* if (bptr -> flags >= BBREACHED) */
3390 } /* for basic block */
3392 bptr -> mpc = (int)((u1*) mcodeptr - mcodebase);
3395 /* generate bound check stubs */
3397 s4 *xcodeptr = NULL;
3399 for (; xboundrefs != NULL; xboundrefs = xboundrefs->next) {
3400 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3401 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
3402 xboundrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3406 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
3407 xboundrefs->branchpos, (u1*) mcodeptr - mcodebase);
3411 M_LDA(REG_ITMP2_XPC, REG_PV, xboundrefs->branchpos);
3413 if (xcodeptr != NULL) {
3414 M_BR((xcodeptr-mcodeptr)-1);
3417 xcodeptr = mcodeptr;
3419 a = dseg_addaddress(proto_java_lang_ArrayIndexOutOfBoundsException);
3420 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3422 a = dseg_addaddress(asm_handle_exception);
3423 M_ALD(REG_ITMP3, REG_PV, a);
3425 M_JMP(REG_ZERO, REG_ITMP3);
3429 /* generate negative array size check stubs */
3433 for (; xcheckarefs != NULL; xcheckarefs = xcheckarefs->next) {
3434 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3435 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3436 xcheckarefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3440 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3441 xcheckarefs->branchpos, (u1*) mcodeptr - mcodebase);
3445 M_LDA(REG_ITMP2_XPC, REG_PV, xcheckarefs->branchpos);
3447 if (xcodeptr != NULL) {
3448 M_BR((xcodeptr-mcodeptr)-1);
3451 xcodeptr = mcodeptr;
3453 a = dseg_addaddress(proto_java_lang_NegativeArraySizeException);
3454 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3456 a = dseg_addaddress(asm_handle_exception);
3457 M_ALD(REG_ITMP3, REG_PV, a);
3459 M_JMP(REG_ZERO, REG_ITMP3);
3463 /* generate cast check stubs */
3467 for (; xcastrefs != NULL; xcastrefs = xcastrefs->next) {
3468 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3469 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3470 xcastrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3474 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3475 xcastrefs->branchpos, (u1*) mcodeptr - mcodebase);
3479 M_LDA(REG_ITMP2_XPC, REG_PV, xcastrefs->branchpos);
3481 if (xcodeptr != NULL) {
3482 M_BR((xcodeptr-mcodeptr)-1);
3485 xcodeptr = mcodeptr;
3487 a = dseg_addaddress(proto_java_lang_ClassCastException);
3488 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3490 a = dseg_addaddress(asm_handle_exception);
3491 M_ALD(REG_ITMP3, REG_PV, a);
3493 M_JMP(REG_ZERO, REG_ITMP3);
3498 #ifdef SOFTNULLPTRCHECK
3500 /* generate null pointer check stubs */
3504 for (; xnullrefs != NULL; xnullrefs = xnullrefs->next) {
3505 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3506 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3507 xnullrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3511 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3512 xnullrefs->branchpos, (u1*) mcodeptr - mcodebase);
3516 M_LDA(REG_ITMP2_XPC, REG_PV, xnullrefs->branchpos - 4);
3518 if (xcodeptr != NULL) {
3519 M_BR((xcodeptr-mcodeptr)-1);
3522 xcodeptr = mcodeptr;
3524 a = dseg_addaddress(proto_java_lang_NullPointerException);
3525 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3527 a = dseg_addaddress(asm_handle_exception);
3528 M_ALD(REG_ITMP3, REG_PV, a);
3530 M_JMP(REG_ZERO, REG_ITMP3);
3537 mcode_finish((int)((u1*) mcodeptr - mcodebase));
3541 /* redefinition of code generation macros (compiling into array) **************/
3544 These macros are newly defined to allow code generation into an array.
3545 This is necessary, because the original M_.. macros generate code by
3546 calling 'mcode_adds4' that uses an additional data structure to
3549 For a faster (but less flexible) version to generate code, these
3550 macros directly use the (s4* p) - pointer to put the code directly
3551 in a locally defined array.
3552 This makes sense only for the stub-generation-routines below.
3556 #define M_OP3(op,fu,a,b,c,const) \
3557 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<(16-3*(const)))| \
3558 ((const)<<12)|((fu)<<5)|((c)) )
3560 #define M_FOP3(op,fu,a,b,c) \
3561 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<16)|((fu)<<5)|(c) )
3563 #define M_BRA(op,a,disp) \
3564 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((disp)&0x1fffff) )
3566 #define M_MEM(op,a,b,disp) \
3567 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<16)|((disp)&0xffff) )
3570 /* function createcompilerstub *************************************************
3572 creates a stub routine which calls the compiler
3574 *******************************************************************************/
3576 #define COMPSTUBSIZE 3
3578 u1 *createcompilerstub (methodinfo *m)
3580 u8 *s = CNEW (u8, COMPSTUBSIZE); /* memory to hold the stub */
3581 s4 *p = (s4*) s; /* code generation pointer */
3583 /* code for the stub */
3584 M_ALD (REG_PV, REG_PV, 16); /* load pointer to the compiler */
3585 M_JMP (0, REG_PV); /* jump to the compiler, return address
3586 in reg 0 is used as method pointer */
3587 s[1] = (u8) m; /* literals to be adressed */
3588 s[2] = (u8) asm_call_jit_compiler; /* jump directly via PV from above */
3591 count_cstub_len += COMPSTUBSIZE * 8;
3598 /* function removecompilerstub *************************************************
3600 deletes a compilerstub from memory (simply by freeing it)
3602 *******************************************************************************/
3604 void removecompilerstub (u1 *stub)
3606 CFREE (stub, COMPSTUBSIZE * 8);
3610 /* function: createnativestub **************************************************
3612 creates a stub routine which calls a native method
3614 *******************************************************************************/
3616 #define NATIVESTUBSIZE 11
3618 u1 *createnativestub (functionptr f, methodinfo *m)
3620 u8 *s = CNEW (u8, NATIVESTUBSIZE); /* memory to hold the stub */
3621 s4 *p = (s4*) s; /* code generation pointer */
3623 M_LDA (REG_SP, REG_SP, -8); /* build up stackframe */
3624 M_AST (REG_RA, REG_SP, 0); /* store return address */
3626 M_ALD (REG_PV, REG_PV, 8*8); /* load adress of native method */
3627 M_JSR (REG_RA, REG_PV); /* call native method */
3629 M_LDA (REG_PV, REG_RA, -4*4); /* recompute pv from ra */
3630 M_ALD (REG_ITMP3, REG_PV, 9*8); /* get address of exceptionptr */
3632 M_ALD (REG_RA, REG_SP, 0); /* load return address */
3633 M_ALD (REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
3635 M_LDA (REG_SP, REG_SP, 8); /* remove stackframe */
3636 M_BNEZ (REG_ITMP1, 1); /* if no exception then return */
3638 M_RET (REG_ZERO, REG_RA); /* return to caller */
3640 M_AST (REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
3641 M_LDA (REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
3643 M_ALD (REG_ITMP3, REG_PV,10*8); /* load asm exception handler address */
3644 M_JMP (REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
3647 s[8] = (u8) f; /* address of native method */
3648 s[9] = (u8) (&exceptionptr); /* address of exceptionptr */
3649 s[10]= (u8) (asm_handle_nat_exception); /* addr of asm exception handler */
3652 count_nstub_len += NATIVESTUBSIZE * 8;
3659 /* function: removenativestub **************************************************
3661 removes a previously created native-stub from memory
3663 *******************************************************************************/
3665 void removenativestub (u1 *stub)
3667 CFREE (stub, NATIVESTUBSIZE * 8);
3672 * These are local overrides for various environment variables in Emacs.
3673 * Please do not remove this and leave it at the end of the file, where
3674 * Emacs will automagically detect them.
3675 * ---------------------------------------------------------------------
3678 * indent-tabs-mode: t