1 /* alpha/ngen.c ****************************************************************
3 Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
5 See file COPYRIGHT for information on usage and disclaimer of warranties
7 Contains the codegenerator for an Alpha processor.
8 This module generates Alpha machine code for a sequence of
9 pseudo commands (ICMDs).
11 Authors: Andreas Krall EMAIL: cacao@complang.tuwien.ac.at
12 Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at
14 Last Change: $Id: ngen.c 115 1999-01-20 01:52:45Z phil $
16 *******************************************************************************/
18 #include "jitdef.h" /* phil */
20 /* *****************************************************************************
22 Datatypes and Register Allocations:
23 -----------------------------------
25 On 64-bit-machines (like the Alpha) all operands are stored in the
26 registers in a 64-bit form, even when the correspondig JavaVM operands
27 only need 32 bits. This is done by a canonical representation:
29 32-bit integers are allways stored as sign-extended 64-bit values (this
30 approach is directly supported by the Alpha architecture and is very easy
33 32-bit-floats are stored in a 64-bit doubleprecision register by simply
34 expanding the exponent and mantissa with zeroes. (also supported by the
40 The calling conventions and the layout of the stack is explained in detail
41 in the documention file: calling.doc
43 *******************************************************************************/
46 /* additional functions and macros to generate code ***************************/
48 #define BlockPtrOfPC(pc) block+block_index[pc]
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 if (iptr->op1 == 0) {
1874 gen_nullptr_check(s1);
1877 M_SAADDQ(s2, s1, REG_ITMP1);
1878 M_ALD( d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1879 store_reg_to_var_int(iptr->dst, d);
1882 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1884 var_to_reg_int(s1, src->prev, REG_ITMP1);
1885 var_to_reg_int(s2, src, REG_ITMP2);
1886 d = reg_of_var(iptr->dst, REG_ITMP3);
1887 if (iptr->op1 == 0) {
1888 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 if (iptr->op1 == 0) {
1902 gen_nullptr_check(s1);
1905 M_S4ADDQ(s2, s1, REG_ITMP1);
1906 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1907 store_reg_to_var_int(iptr->dst, d);
1910 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1912 var_to_reg_int(s1, src->prev, REG_ITMP1);
1913 var_to_reg_int(s2, src, REG_ITMP2);
1914 d = reg_of_var(iptr->dst, REG_FTMP3);
1915 if (iptr->op1 == 0) {
1916 gen_nullptr_check(s1);
1919 M_S4ADDQ(s2, s1, REG_ITMP1);
1920 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1921 store_reg_to_var_flt(iptr->dst, d);
1924 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1926 var_to_reg_int(s1, src->prev, REG_ITMP1);
1927 var_to_reg_int(s2, src, REG_ITMP2);
1928 d = reg_of_var(iptr->dst, REG_FTMP3);
1929 if (iptr->op1 == 0) {
1930 gen_nullptr_check(s1);
1933 M_S8ADDQ(s2, s1, REG_ITMP1);
1934 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1935 store_reg_to_var_flt(iptr->dst, d);
1938 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1940 var_to_reg_int(s1, src->prev, REG_ITMP1);
1941 var_to_reg_int(s2, src, REG_ITMP2);
1942 d = reg_of_var(iptr->dst, REG_ITMP3);
1943 if (iptr->op1 == 0) {
1944 gen_nullptr_check(s1);
1947 if (has_ext_instr_set) {
1948 M_LADD(s2, s1, REG_ITMP1);
1949 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1950 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1953 M_LADD (s2, s1, REG_ITMP1);
1954 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1955 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1956 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1957 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
1959 store_reg_to_var_int(iptr->dst, d);
1962 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1964 var_to_reg_int(s1, src->prev, REG_ITMP1);
1965 var_to_reg_int(s2, src, REG_ITMP2);
1966 d = reg_of_var(iptr->dst, REG_ITMP3);
1967 if (iptr->op1 == 0) {
1968 gen_nullptr_check(s1);
1971 if (has_ext_instr_set) {
1972 M_LADD(s2, s1, REG_ITMP1);
1973 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1974 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1978 M_LADD(s2, s1, REG_ITMP1);
1979 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1980 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1981 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1982 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1983 M_SRA_IMM(d, 48, d);
1985 store_reg_to_var_int(iptr->dst, d);
1988 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1990 var_to_reg_int(s1, src->prev, REG_ITMP1);
1991 var_to_reg_int(s2, src, REG_ITMP2);
1992 d = reg_of_var(iptr->dst, REG_ITMP3);
1993 if (iptr->op1 == 0) {
1994 gen_nullptr_check(s1);
1997 if (has_ext_instr_set) {
1998 M_LADD (s2, s1, REG_ITMP1);
1999 M_BLDU (d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
2003 M_LADD(s2, s1, REG_ITMP1);
2004 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2005 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
2006 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
2007 M_SRA_IMM(d, 56, d);
2009 store_reg_to_var_int(iptr->dst, d);
2013 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
2015 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2016 var_to_reg_int(s2, src->prev, REG_ITMP2);
2017 if (iptr->op1 == 0) {
2018 gen_nullptr_check(s1);
2021 var_to_reg_int(s3, src, REG_ITMP3);
2022 M_SAADDQ(s2, s1, REG_ITMP1);
2023 M_AST (s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
2026 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
2028 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2029 var_to_reg_int(s2, src->prev, REG_ITMP2);
2030 if (iptr->op1 == 0) {
2031 gen_nullptr_check(s1);
2034 var_to_reg_int(s3, src, REG_ITMP3);
2035 M_S8ADDQ(s2, s1, REG_ITMP1);
2036 M_LST (s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
2039 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
2041 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2042 var_to_reg_int(s2, src->prev, REG_ITMP2);
2043 if (iptr->op1 == 0) {
2044 gen_nullptr_check(s1);
2047 var_to_reg_int(s3, src, REG_ITMP3);
2048 M_S4ADDQ(s2, s1, REG_ITMP1);
2049 M_IST (s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
2052 case ICMD_FASTORE: /* ..., 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 if (iptr->op1 == 0) {
2057 gen_nullptr_check(s1);
2060 var_to_reg_flt(s3, src, REG_FTMP3);
2061 M_S4ADDQ(s2, s1, REG_ITMP1);
2062 M_FST (s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
2065 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
2067 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2068 var_to_reg_int(s2, src->prev, REG_ITMP2);
2069 if (iptr->op1 == 0) {
2070 gen_nullptr_check(s1);
2073 var_to_reg_flt(s3, src, REG_FTMP3);
2074 M_S8ADDQ(s2, s1, REG_ITMP1);
2075 M_DST (s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
2078 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
2080 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2081 var_to_reg_int(s2, src->prev, REG_ITMP2);
2082 if (iptr->op1 == 0) {
2083 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_chararray, 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_chararray, data[0]));
2096 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, 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_SASTORE: /* ..., 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 if (iptr->op1 == 0) {
2109 gen_nullptr_check(s1);
2112 var_to_reg_int(s3, src, REG_ITMP3);
2113 if (has_ext_instr_set) {
2114 M_LADD(s2, s1, REG_ITMP1);
2115 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2116 M_SST (s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2119 M_LADD (s2, s1, REG_ITMP1);
2120 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2121 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2122 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2123 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
2124 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2125 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2126 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2130 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
2132 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2133 var_to_reg_int(s2, src->prev, REG_ITMP2);
2134 if (iptr->op1 == 0) {
2135 gen_nullptr_check(s1);
2138 var_to_reg_int(s3, src, REG_ITMP3);
2139 if (has_ext_instr_set) {
2140 M_LADD(s2, s1, REG_ITMP1);
2141 M_BST (s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2144 M_LADD (s2, s1, REG_ITMP1);
2145 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2146 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2147 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
2148 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2149 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2150 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2155 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2156 /* op1 = type, val.a = field address */
2158 a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value));
2159 M_ALD(REG_ITMP1, REG_PV, a);
2160 switch (iptr->op1) {
2162 var_to_reg_int(s2, src, REG_ITMP2);
2163 M_IST(s2, REG_ITMP1, 0);
2166 var_to_reg_int(s2, src, REG_ITMP2);
2167 M_LST(s2, REG_ITMP1, 0);
2170 var_to_reg_int(s2, src, REG_ITMP2);
2171 M_AST(s2, REG_ITMP1, 0);
2174 var_to_reg_flt(s2, src, REG_FTMP2);
2175 M_FST(s2, REG_ITMP1, 0);
2178 var_to_reg_flt(s2, src, REG_FTMP2);
2179 M_DST(s2, REG_ITMP1, 0);
2181 default: panic ("internal error");
2185 case ICMD_GETSTATIC: /* ... ==> ..., value */
2186 /* op1 = type, val.a = field address */
2188 a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value));
2189 M_ALD(REG_ITMP1, REG_PV, a);
2190 switch (iptr->op1) {
2192 d = reg_of_var(iptr->dst, REG_ITMP3);
2193 M_ILD(d, REG_ITMP1, 0);
2194 store_reg_to_var_int(iptr->dst, d);
2197 d = reg_of_var(iptr->dst, REG_ITMP3);
2198 M_LLD(d, REG_ITMP1, 0);
2199 store_reg_to_var_int(iptr->dst, d);
2202 d = reg_of_var(iptr->dst, REG_ITMP3);
2203 M_ALD(d, REG_ITMP1, 0);
2204 store_reg_to_var_int(iptr->dst, d);
2207 d = reg_of_var(iptr->dst, REG_FTMP1);
2208 M_FLD(d, REG_ITMP1, 0);
2209 store_reg_to_var_flt(iptr->dst, d);
2212 d = reg_of_var(iptr->dst, REG_FTMP1);
2213 M_DLD(d, REG_ITMP1, 0);
2214 store_reg_to_var_flt(iptr->dst, d);
2216 default: panic ("internal error");
2221 case ICMD_PUTFIELD: /* ..., value ==> ... */
2222 /* op1 = type, val.i = field offset */
2224 a = ((fieldinfo *)(iptr->val.a))->offset;
2225 switch (iptr->op1) {
2227 var_to_reg_int(s1, src->prev, REG_ITMP1);
2228 var_to_reg_int(s2, src, REG_ITMP2);
2229 gen_nullptr_check(s1);
2233 var_to_reg_int(s1, src->prev, REG_ITMP1);
2234 var_to_reg_int(s2, src, REG_ITMP2);
2235 gen_nullptr_check(s1);
2239 var_to_reg_int(s1, src->prev, REG_ITMP1);
2240 var_to_reg_int(s2, src, REG_ITMP2);
2241 gen_nullptr_check(s1);
2245 var_to_reg_int(s1, src->prev, REG_ITMP1);
2246 var_to_reg_flt(s2, src, REG_FTMP2);
2247 gen_nullptr_check(s1);
2251 var_to_reg_int(s1, src->prev, REG_ITMP1);
2252 var_to_reg_flt(s2, src, REG_FTMP2);
2253 gen_nullptr_check(s1);
2256 default: panic ("internal error");
2260 case ICMD_GETFIELD: /* ... ==> ..., value */
2261 /* op1 = type, val.i = field offset */
2263 a = ((fieldinfo *)(iptr->val.a))->offset;
2264 switch (iptr->op1) {
2266 var_to_reg_int(s1, src, REG_ITMP1);
2267 d = reg_of_var(iptr->dst, REG_ITMP3);
2268 gen_nullptr_check(s1);
2270 store_reg_to_var_int(iptr->dst, d);
2273 var_to_reg_int(s1, src, REG_ITMP1);
2274 d = reg_of_var(iptr->dst, REG_ITMP3);
2275 gen_nullptr_check(s1);
2277 store_reg_to_var_int(iptr->dst, d);
2280 var_to_reg_int(s1, src, REG_ITMP1);
2281 d = reg_of_var(iptr->dst, REG_ITMP3);
2282 gen_nullptr_check(s1);
2284 store_reg_to_var_int(iptr->dst, d);
2287 var_to_reg_int(s1, src, REG_ITMP1);
2288 d = reg_of_var(iptr->dst, REG_FTMP1);
2289 gen_nullptr_check(s1);
2291 store_reg_to_var_flt(iptr->dst, d);
2294 var_to_reg_int(s1, src, REG_ITMP1);
2295 d = reg_of_var(iptr->dst, REG_FTMP1);
2296 gen_nullptr_check(s1);
2298 store_reg_to_var_flt(iptr->dst, d);
2300 default: panic ("internal error");
2305 /* branch operations **************************************************/
2307 #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}}
2309 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2311 var_to_reg_int(s1, src, REG_ITMP1);
2312 M_INTMOVE(s1, REG_ITMP1_XPTR);
2313 a = dseg_addaddress(asm_handle_exception);
2314 M_ALD(REG_ITMP2, REG_PV, a);
2315 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2319 case ICMD_GOTO: /* ... ==> ... */
2320 /* op1 = target JavaVM pc */
2322 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2326 case ICMD_JSR: /* ... ==> ... */
2327 /* op1 = target JavaVM pc */
2329 M_BSR(REG_ITMP1, 0);
2330 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2333 case ICMD_RET: /* ... ==> ... */
2334 /* op1 = local variable */
2336 var = &(locals[iptr->op1][TYPE_ADR]);
2337 if (var->flags & INMEMORY) {
2338 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2339 M_RET(REG_ZERO, REG_ITMP1);
2342 M_RET(REG_ZERO, var->regoff);
2346 case ICMD_IFNULL: /* ..., value ==> ... */
2347 /* op1 = target JavaVM pc */
2349 var_to_reg_int(s1, src, REG_ITMP1);
2351 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2354 case ICMD_IFNONNULL: /* ..., value ==> ... */
2355 /* op1 = target JavaVM pc */
2357 var_to_reg_int(s1, src, REG_ITMP1);
2359 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2362 case ICMD_IFEQ: /* ..., value ==> ... */
2363 /* op1 = target JavaVM pc, val.i = constant */
2365 var_to_reg_int(s1, src, REG_ITMP1);
2366 if (iptr->val.i == 0) {
2370 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2371 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2374 ICONST(REG_ITMP2, iptr->val.i);
2375 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2377 M_BNEZ(REG_ITMP1, 0);
2379 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2382 case ICMD_IFLT: /* ..., value ==> ... */
2383 /* op1 = target JavaVM pc, val.i = constant */
2385 var_to_reg_int(s1, src, REG_ITMP1);
2386 if (iptr->val.i == 0) {
2390 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2391 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2394 ICONST(REG_ITMP2, iptr->val.i);
2395 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2397 M_BNEZ(REG_ITMP1, 0);
2399 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2402 case ICMD_IFLE: /* ..., value ==> ... */
2403 /* op1 = target JavaVM pc, val.i = constant */
2405 var_to_reg_int(s1, src, REG_ITMP1);
2406 if (iptr->val.i == 0) {
2410 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2411 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2414 ICONST(REG_ITMP2, iptr->val.i);
2415 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2417 M_BNEZ(REG_ITMP1, 0);
2419 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2422 case ICMD_IFNE: /* ..., value ==> ... */
2423 /* op1 = target JavaVM pc, val.i = constant */
2425 var_to_reg_int(s1, src, REG_ITMP1);
2426 if (iptr->val.i == 0) {
2430 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2431 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2434 ICONST(REG_ITMP2, iptr->val.i);
2435 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2437 M_BEQZ(REG_ITMP1, 0);
2439 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2442 case ICMD_IFGT: /* ..., value ==> ... */
2443 /* op1 = target JavaVM pc, val.i = constant */
2445 var_to_reg_int(s1, src, REG_ITMP1);
2446 if (iptr->val.i == 0) {
2450 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2451 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2454 ICONST(REG_ITMP2, iptr->val.i);
2455 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2457 M_BEQZ(REG_ITMP1, 0);
2459 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2462 case ICMD_IFGE: /* ..., value ==> ... */
2463 /* op1 = target JavaVM pc, val.i = constant */
2465 var_to_reg_int(s1, src, REG_ITMP1);
2466 if (iptr->val.i == 0) {
2470 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2471 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2474 ICONST(REG_ITMP2, iptr->val.i);
2475 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2477 M_BEQZ(REG_ITMP1, 0);
2479 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2482 case ICMD_IF_LEQ: /* ..., value ==> ... */
2483 /* op1 = target JavaVM pc, val.l = constant */
2485 var_to_reg_int(s1, src, REG_ITMP1);
2486 if (iptr->val.l == 0) {
2490 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2491 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2494 LCONST(REG_ITMP2, iptr->val.l);
2495 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2497 M_BNEZ(REG_ITMP1, 0);
2499 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2502 case ICMD_IF_LLT: /* ..., value ==> ... */
2503 /* op1 = target JavaVM pc, val.l = constant */
2505 var_to_reg_int(s1, src, REG_ITMP1);
2506 if (iptr->val.l == 0) {
2510 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2511 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2514 LCONST(REG_ITMP2, iptr->val.l);
2515 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2517 M_BNEZ(REG_ITMP1, 0);
2519 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2522 case ICMD_IF_LLE: /* ..., value ==> ... */
2523 /* op1 = target JavaVM pc, val.l = constant */
2525 var_to_reg_int(s1, src, REG_ITMP1);
2526 if (iptr->val.l == 0) {
2530 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2531 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2534 LCONST(REG_ITMP2, iptr->val.l);
2535 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2537 M_BNEZ(REG_ITMP1, 0);
2539 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2542 case ICMD_IF_LNE: /* ..., value ==> ... */
2543 /* op1 = target JavaVM pc, val.l = constant */
2545 var_to_reg_int(s1, src, REG_ITMP1);
2546 if (iptr->val.l == 0) {
2550 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2551 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2554 LCONST(REG_ITMP2, iptr->val.l);
2555 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2557 M_BEQZ(REG_ITMP1, 0);
2559 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2562 case ICMD_IF_LGT: /* ..., value ==> ... */
2563 /* op1 = target JavaVM pc, val.l = constant */
2565 var_to_reg_int(s1, src, REG_ITMP1);
2566 if (iptr->val.l == 0) {
2570 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2571 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2574 LCONST(REG_ITMP2, iptr->val.l);
2575 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2577 M_BEQZ(REG_ITMP1, 0);
2579 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2582 case ICMD_IF_LGE: /* ..., value ==> ... */
2583 /* op1 = target JavaVM pc, val.l = constant */
2585 var_to_reg_int(s1, src, REG_ITMP1);
2586 if (iptr->val.l == 0) {
2590 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2591 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2594 LCONST(REG_ITMP2, iptr->val.l);
2595 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2597 M_BEQZ(REG_ITMP1, 0);
2599 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2602 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2603 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2604 case ICMD_IF_ACMPEQ:
2606 var_to_reg_int(s1, src->prev, REG_ITMP1);
2607 var_to_reg_int(s2, src, REG_ITMP2);
2608 M_CMPEQ(s1, s2, REG_ITMP1);
2609 M_BNEZ(REG_ITMP1, 0);
2610 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2613 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2614 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2615 case ICMD_IF_ACMPNE:
2617 var_to_reg_int(s1, src->prev, REG_ITMP1);
2618 var_to_reg_int(s2, src, REG_ITMP2);
2619 M_CMPEQ(s1, s2, REG_ITMP1);
2620 M_BEQZ(REG_ITMP1, 0);
2621 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2624 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2625 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2627 var_to_reg_int(s1, src->prev, REG_ITMP1);
2628 var_to_reg_int(s2, src, REG_ITMP2);
2629 M_CMPLT(s1, s2, REG_ITMP1);
2630 M_BNEZ(REG_ITMP1, 0);
2631 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2634 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2635 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2637 var_to_reg_int(s1, src->prev, REG_ITMP1);
2638 var_to_reg_int(s2, src, REG_ITMP2);
2639 M_CMPLE(s1, s2, REG_ITMP1);
2640 M_BEQZ(REG_ITMP1, 0);
2641 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2644 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2645 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2647 var_to_reg_int(s1, src->prev, REG_ITMP1);
2648 var_to_reg_int(s2, src, REG_ITMP2);
2649 M_CMPLE(s1, s2, REG_ITMP1);
2650 M_BNEZ(REG_ITMP1, 0);
2651 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2654 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2655 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2657 var_to_reg_int(s1, src->prev, REG_ITMP1);
2658 var_to_reg_int(s2, src, REG_ITMP2);
2659 M_CMPLT(s1, s2, REG_ITMP1);
2660 M_BEQZ(REG_ITMP1, 0);
2661 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2664 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2666 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2669 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2670 /* val.i = constant */
2672 var_to_reg_int(s1, src, REG_ITMP1);
2673 d = reg_of_var(iptr->dst, REG_ITMP3);
2675 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2676 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2677 M_CMPEQ(s1, REG_ZERO, d);
2678 store_reg_to_var_int(iptr->dst, d);
2681 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2682 M_CMPEQ(s1, REG_ZERO, d);
2684 store_reg_to_var_int(iptr->dst, d);
2688 M_MOV(s1, REG_ITMP1);
2691 ICONST(d, iptr[1].val.i);
2693 if ((s3 >= 0) && (s3 <= 255)) {
2694 M_CMOVEQ_IMM(s1, s3, d);
2697 ICONST(REG_ITMP2, s3);
2698 M_CMOVEQ(s1, REG_ITMP2, d);
2700 store_reg_to_var_int(iptr->dst, d);
2703 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2704 /* val.i = constant */
2706 var_to_reg_int(s1, src, REG_ITMP1);
2707 d = reg_of_var(iptr->dst, REG_ITMP3);
2709 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2710 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2711 M_CMPEQ(s1, REG_ZERO, d);
2712 store_reg_to_var_int(iptr->dst, d);
2715 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2716 M_CMPEQ(s1, REG_ZERO, d);
2718 store_reg_to_var_int(iptr->dst, d);
2722 M_MOV(s1, REG_ITMP1);
2725 ICONST(d, iptr[1].val.i);
2727 if ((s3 >= 0) && (s3 <= 255)) {
2728 M_CMOVNE_IMM(s1, s3, d);
2731 ICONST(REG_ITMP2, s3);
2732 M_CMOVNE(s1, REG_ITMP2, d);
2734 store_reg_to_var_int(iptr->dst, d);
2737 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2738 /* val.i = constant */
2740 var_to_reg_int(s1, src, REG_ITMP1);
2741 d = reg_of_var(iptr->dst, REG_ITMP3);
2743 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2744 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2745 M_CMPLT(s1, REG_ZERO, d);
2746 store_reg_to_var_int(iptr->dst, d);
2749 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2750 M_CMPLE(REG_ZERO, s1, d);
2751 store_reg_to_var_int(iptr->dst, d);
2755 M_MOV(s1, REG_ITMP1);
2758 ICONST(d, iptr[1].val.i);
2760 if ((s3 >= 0) && (s3 <= 255)) {
2761 M_CMOVLT_IMM(s1, s3, d);
2764 ICONST(REG_ITMP2, s3);
2765 M_CMOVLT(s1, REG_ITMP2, d);
2767 store_reg_to_var_int(iptr->dst, d);
2770 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2771 /* val.i = constant */
2773 var_to_reg_int(s1, src, REG_ITMP1);
2774 d = reg_of_var(iptr->dst, REG_ITMP3);
2776 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2777 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2778 M_CMPLE(REG_ZERO, s1, d);
2779 store_reg_to_var_int(iptr->dst, d);
2782 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2783 M_CMPLT(s1, REG_ZERO, d);
2784 store_reg_to_var_int(iptr->dst, d);
2788 M_MOV(s1, REG_ITMP1);
2791 ICONST(d, iptr[1].val.i);
2793 if ((s3 >= 0) && (s3 <= 255)) {
2794 M_CMOVGE_IMM(s1, s3, d);
2797 ICONST(REG_ITMP2, s3);
2798 M_CMOVGE(s1, REG_ITMP2, d);
2800 store_reg_to_var_int(iptr->dst, d);
2803 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2804 /* val.i = constant */
2806 var_to_reg_int(s1, src, REG_ITMP1);
2807 d = reg_of_var(iptr->dst, REG_ITMP3);
2809 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2810 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2811 M_CMPLT(REG_ZERO, s1, d);
2812 store_reg_to_var_int(iptr->dst, d);
2815 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2816 M_CMPLE(s1, REG_ZERO, d);
2817 store_reg_to_var_int(iptr->dst, d);
2821 M_MOV(s1, REG_ITMP1);
2824 ICONST(d, iptr[1].val.i);
2826 if ((s3 >= 0) && (s3 <= 255)) {
2827 M_CMOVGT_IMM(s1, s3, d);
2830 ICONST(REG_ITMP2, s3);
2831 M_CMOVGT(s1, REG_ITMP2, d);
2833 store_reg_to_var_int(iptr->dst, d);
2836 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2837 /* val.i = constant */
2839 var_to_reg_int(s1, src, REG_ITMP1);
2840 d = reg_of_var(iptr->dst, REG_ITMP3);
2842 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2843 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2844 M_CMPLE(s1, REG_ZERO, d);
2845 store_reg_to_var_int(iptr->dst, d);
2848 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2849 M_CMPLT(REG_ZERO, s1, d);
2850 store_reg_to_var_int(iptr->dst, d);
2854 M_MOV(s1, REG_ITMP1);
2857 ICONST(d, iptr[1].val.i);
2859 if ((s3 >= 0) && (s3 <= 255)) {
2860 M_CMOVLE_IMM(s1, s3, d);
2863 ICONST(REG_ITMP2, s3);
2864 M_CMOVLE(s1, REG_ITMP2, d);
2866 store_reg_to_var_int(iptr->dst, d);
2870 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2875 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2876 a = dseg_addaddress ((void*) (builtin_monitorexit));
2877 M_ALD(REG_PV, REG_PV, a);
2878 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
2879 M_JSR(REG_RA, REG_PV);
2880 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2883 var_to_reg_int(s1, src, REG_RESULT);
2884 M_INTMOVE(s1, REG_RESULT);
2885 goto nowperformreturn;
2887 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2891 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2892 a = dseg_addaddress ((void*) (builtin_monitorexit));
2893 M_ALD(REG_PV, REG_PV, a);
2894 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
2895 M_JSR(REG_RA, REG_PV);
2896 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2899 var_to_reg_flt(s1, src, REG_FRESULT);
2900 M_FLTMOVE(s1, REG_FRESULT);
2901 goto nowperformreturn;
2903 case ICMD_RETURN: /* ... ==> ... */
2906 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2907 a = dseg_addaddress ((void*) (builtin_monitorexit));
2908 M_ALD(REG_PV, REG_PV, a);
2909 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
2910 M_JSR(REG_RA, REG_PV);
2911 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2919 p = parentargs_base;
2921 /* restore return address */
2924 {p--; M_LLD (REG_RA, REG_SP, 8 * p);}
2926 /* restore saved registers */
2928 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
2929 {p--; M_LLD(savintregs[r], REG_SP, 8 * p);}
2930 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
2931 {p--; M_DLD(savfltregs[r], REG_SP, 8 * p);}
2933 /* deallocate stack */
2935 if (parentargs_base)
2936 {M_LDA(REG_SP, REG_SP, parentargs_base*8);}
2938 /* call trace function */
2941 M_LDA (REG_SP, REG_SP, -24);
2942 M_AST(REG_RA, REG_SP, 0);
2943 M_LST(REG_RESULT, REG_SP, 8);
2944 M_DST(REG_FRESULT, REG_SP,16);
2945 a = dseg_addaddress (method);
2946 M_ALD(argintregs[0], REG_PV, a);
2947 M_MOV(REG_RESULT, argintregs[1]);
2948 M_FLTMOVE(REG_FRESULT, argfltregs[2]);
2949 a = dseg_addaddress ((void*) (builtin_displaymethodstop));
2950 M_ALD(REG_PV, REG_PV, a);
2951 M_JSR (REG_RA, REG_PV);
2952 s1 = (int)((u1*) mcodeptr - mcodebase);
2953 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
2956 while (ml<-32768) { ml+=65536; mh--; }
2957 M_LDA (REG_PV, REG_RA, ml );
2958 M_LDAH (REG_PV, REG_PV, mh );
2960 M_DLD(REG_FRESULT, REG_SP,16);
2961 M_LLD(REG_RESULT, REG_SP, 8);
2962 M_ALD(REG_RA, REG_SP, 0);
2963 M_LDA (REG_SP, REG_SP, 24);
2966 M_RET(REG_ZERO, REG_RA);
2972 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2976 s4ptr = iptr->val.a;
2977 l = s4ptr[1]; /* low */
2978 i = s4ptr[2]; /* high */
2980 var_to_reg_int(s1, src, REG_ITMP1);
2982 {M_INTMOVE(s1, REG_ITMP1);}
2983 else if (l <= 32768) {
2984 M_LDA(REG_ITMP1, s1, -l);
2987 ICONST(REG_ITMP2, l);
2988 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2995 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
2997 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
2998 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3000 M_BEQZ(REG_ITMP2, 0);
3001 mcode_addreference(BlockPtrOfPC(s4ptr[0]), mcodeptr);
3003 /* build jump table top down and use address of lowest entry */
3007 dseg_addtarget(BlockPtrOfPC(*--s4ptr));
3011 /* length of dataseg after last dseg_addtarget is used by load */
3013 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
3014 M_ALD(REG_ITMP2, REG_ITMP2, -dseglen);
3015 M_JMP(REG_ZERO, REG_ITMP2);
3020 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3022 s4 i, l, val, *s4ptr;
3024 s4ptr = iptr->val.a;
3025 l = s4ptr[0]; /* default */
3026 i = s4ptr[1]; /* count */
3028 MCODECHECK((i<<2)+8);
3029 var_to_reg_int(s1, src, REG_ITMP1);
3033 if ((val >= 0) && (val <= 255)) {
3034 M_CMPEQ_IMM(s1, val, REG_ITMP2);
3037 if ((val >= -32768) && (val <= 32767)) {
3038 M_LDA(REG_ITMP2, REG_ZERO, val);
3041 a = dseg_adds4 (val);
3042 M_ILD(REG_ITMP2, REG_PV, a);
3044 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
3046 M_BNEZ(REG_ITMP2, 0);
3047 mcode_addreference(BlockPtrOfPC(s4ptr[1]), mcodeptr);
3051 mcode_addreference(BlockPtrOfPC(l), mcodeptr);
3057 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
3058 /* op1 = return type, val.a = function pointer*/
3062 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
3063 /* op1 = return type, val.a = function pointer*/
3067 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
3068 /* op1 = return type, val.a = function pointer*/
3072 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3073 /* op1 = arg count, val.a = method pointer */
3075 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3076 /* op1 = arg count, val.a = method pointer */
3078 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3079 /* op1 = arg count, val.a = method pointer */
3081 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
3082 /* op1 = arg count, val.a = method pointer */
3090 MCODECHECK((s3 << 1) + 64);
3092 /* copy arguments to registers or stack location */
3094 for (; --s3 >= 0; src = src->prev) {
3095 if (src->varkind == ARGVAR)
3097 if (IS_INT_LNG_TYPE(src->type)) {
3098 if (s3 < INT_ARG_CNT) {
3099 s1 = argintregs[s3];
3100 var_to_reg_int(d, src, s1);
3104 var_to_reg_int(d, src, REG_ITMP1);
3105 M_LST(d, REG_SP, 8 * (s3 - INT_ARG_CNT));
3109 if (s3 < FLT_ARG_CNT) {
3110 s1 = argfltregs[s3];
3111 var_to_reg_flt(d, src, s1);
3115 var_to_reg_flt(d, src, REG_FTMP1);
3116 M_DST(d, REG_SP, 8 * (s3 - FLT_ARG_CNT));
3121 switch (iptr->opc) {
3125 a = dseg_addaddress ((void*) (m));
3127 M_ALD(REG_PV, REG_PV, a); /* Pointer to built-in-function */
3129 goto makeactualcall;
3131 case ICMD_INVOKESTATIC:
3132 case ICMD_INVOKESPECIAL:
3133 a = dseg_addaddress (m->stubroutine);
3135 M_ALD(REG_PV, REG_PV, a ); /* method pointer in r27 */
3138 goto makeactualcall;
3140 case ICMD_INVOKEVIRTUAL:
3142 gen_nullptr_check(argintregs[0]);
3143 M_ALD(REG_METHODPTR, argintregs[0],
3144 OFFSET(java_objectheader, vftbl));
3145 M_ALD(REG_PV, REG_METHODPTR, OFFSET(vftbl, table[0]) +
3146 sizeof(methodptr) * m->vftblindex);
3149 goto makeactualcall;
3151 case ICMD_INVOKEINTERFACE:
3154 gen_nullptr_check(argintregs[0]);
3155 M_ALD(REG_METHODPTR, argintregs[0],
3156 OFFSET(java_objectheader, vftbl));
3157 M_ALD(REG_METHODPTR, REG_METHODPTR,
3158 OFFSET(vftbl, interfacetable[0]) -
3159 sizeof(methodptr*) * ci->index);
3160 M_ALD(REG_PV, REG_METHODPTR,
3161 sizeof(methodptr) * (m - ci->methods));
3164 goto makeactualcall;
3168 sprintf (logtext, "Unkown ICMD-Command: %d", iptr->opc);
3174 M_JSR (REG_RA, REG_PV);
3178 s1 = (int)((u1*) mcodeptr - mcodebase);
3179 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
3182 while (ml<-32768) { ml+=65536; mh--; }
3183 M_LDA (REG_PV, REG_RA, ml );
3184 M_LDAH (REG_PV, REG_PV, mh );
3187 /* d contains return type */
3189 if (d != TYPE_VOID) {
3190 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3191 s1 = reg_of_var(iptr->dst, REG_RESULT);
3192 M_INTMOVE(REG_RESULT, s1);
3193 store_reg_to_var_int(iptr->dst, s1);
3196 s1 = reg_of_var(iptr->dst, REG_FRESULT);
3197 M_FLTMOVE(REG_FRESULT, s1);
3198 store_reg_to_var_flt(iptr->dst, s1);
3205 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3207 /* op1: 0 == array, 1 == class */
3208 /* val.a: (classinfo*) superclass */
3210 /* superclass is an interface:
3212 * return (sub != NULL) &&
3213 * (sub->vftbl->interfacetablelength > super->index) &&
3214 * (sub->vftbl->interfacetable[-super->index] != NULL);
3216 * superclass is a class:
3218 * return ((sub != NULL) && (0
3219 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3220 * super->vftbl->diffvall));
3224 classinfo *super = (classinfo*) iptr->val.a;
3226 var_to_reg_int(s1, src, REG_ITMP1);
3227 d = reg_of_var(iptr->dst, REG_ITMP3);
3229 M_MOV(s1, REG_ITMP1);
3233 if (iptr->op1) { /* class/interface */
3234 if (super->flags & ACC_INTERFACE) { /* interface */
3236 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3237 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3238 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3239 M_BLEZ(REG_ITMP2, 2);
3240 M_ALD(REG_ITMP1, REG_ITMP1,
3241 OFFSET(vftbl, interfacetable[0]) -
3242 super->index * sizeof(methodptr*));
3243 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3246 s2 = super->vftbl->diffval;
3247 M_BEQZ(s1, 4 + (s2 > 255));
3248 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3249 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3250 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3252 M_CMPULE_IMM(REG_ITMP1, s2, d);
3254 M_LDA(REG_ITMP2, REG_ZERO, s2);
3255 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3260 panic ("internal error: no inlined array instanceof");
3262 store_reg_to_var_int(iptr->dst, d);
3265 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3267 /* op1: 0 == array, 1 == class */
3268 /* val.a: (classinfo*) superclass */
3270 /* superclass is an interface:
3272 * OK if ((sub == NULL) ||
3273 * (sub->vftbl->interfacetablelength > super->index) &&
3274 * (sub->vftbl->interfacetable[-super->index] != NULL));
3276 * superclass is a class:
3278 * OK if ((sub == NULL) || (0
3279 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3280 * super->vftbl->diffvall));
3284 classinfo *super = (classinfo*) iptr->val.a;
3286 d = reg_of_var(iptr->dst, REG_ITMP3);
3287 var_to_reg_int(s1, src, d);
3288 if (iptr->op1) { /* class/interface */
3289 if (super->flags & ACC_INTERFACE) { /* interface */
3291 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3292 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3293 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3294 M_BLEZ(REG_ITMP2, 0);
3295 mcode_addxcastrefs(mcodeptr);
3296 M_ALD(REG_ITMP2, REG_ITMP1,
3297 OFFSET(vftbl, interfacetable[0]) -
3298 super->index * sizeof(methodptr*));
3299 M_BEQZ(REG_ITMP2, 0);
3300 mcode_addxcastrefs(mcodeptr);
3303 s2 = super->vftbl->diffval;
3304 M_BEQZ(s1, 4 + (s2 != 0) + (s2 > 255));
3305 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3306 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3307 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3309 M_BNEZ(REG_ITMP1, 0);
3311 else if (s2 <= 255) {
3312 M_CMPULE_IMM(REG_ITMP1, s2, REG_ITMP2);
3313 M_BEQZ(REG_ITMP2, 0);
3316 M_LDA(REG_ITMP2, REG_ZERO, s2);
3317 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3318 M_BEQZ(REG_ITMP2, 0);
3320 mcode_addxcastrefs(mcodeptr);
3324 panic ("internal error: no inlined array checkcast");
3327 store_reg_to_var_int(iptr->dst, d);
3330 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
3332 var_to_reg_int(s1, src, REG_ITMP1);
3334 mcode_addxcheckarefs(mcodeptr);
3337 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3338 /* op1 = dimension, val.a = array descriptor */
3340 /* check for negative sizes and copy sizes to stack if necessary */
3342 MCODECHECK((iptr->op1 << 1) + 64);
3344 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3345 var_to_reg_int(s2, src, REG_ITMP1);
3347 mcode_addxcheckarefs(mcodeptr);
3349 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
3351 if (src->varkind != ARGVAR) {
3352 M_LST(s2, REG_SP, 8 * (s1 + INT_ARG_CNT));
3356 /* a0 = dimension count */
3358 ICONST(argintregs[0], iptr->op1);
3360 /* a1 = arraydescriptor */
3362 a = dseg_addaddress(iptr->val.a);
3363 M_ALD(argintregs[1], REG_PV, a);
3365 /* a2 = pointer to dimensions = stack pointer */
3367 M_INTMOVE(REG_SP, argintregs[2]);
3369 a = dseg_addaddress((void*) (builtin_nmultianewarray));
3370 M_ALD(REG_PV, REG_PV, a);
3371 M_JSR(REG_RA, REG_PV);
3372 s1 = (int)((u1*) mcodeptr - mcodebase);
3374 M_LDA (REG_PV, REG_RA, -s1);
3376 s4 ml = -s1, mh = 0;
3377 while (ml < -32768) {ml += 65536; mh--;}
3378 M_LDA(REG_PV, REG_RA, ml);
3379 M_LDAH(REG_PV, REG_PV, mh);
3381 s1 = reg_of_var(iptr->dst, REG_RESULT);
3382 M_INTMOVE(REG_RESULT, s1);
3383 store_reg_to_var_int(iptr->dst, s1);
3387 default: sprintf (logtext, "Unknown pseudo command: %d", iptr->opc);
3390 } /* for instruction */
3392 /* copy values to interface registers */
3394 src = bptr->outstack;
3395 len = bptr->outdepth;
3399 if ((src->varkind != STACKVAR)) {
3401 if (IS_FLT_DBL_TYPE(s2)) {
3402 var_to_reg_flt(s1, src, REG_FTMP1);
3403 if (!(interfaces[len][s2].flags & INMEMORY)) {
3404 M_FLTMOVE(s1,interfaces[len][s2].regoff);
3407 M_DST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3411 var_to_reg_int(s1, src, REG_ITMP1);
3412 if (!(interfaces[len][s2].flags & INMEMORY)) {
3413 M_INTMOVE(s1,interfaces[len][s2].regoff);
3416 M_LST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3422 } /* if (bptr -> flags >= BBREACHED) */
3423 } /* for basic block */
3425 bptr -> mpc = (int)((u1*) mcodeptr - mcodebase);
3428 /* generate bound check stubs */
3430 s4 *xcodeptr = NULL;
3432 for (; xboundrefs != NULL; xboundrefs = xboundrefs->next) {
3433 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3434 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
3435 xboundrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3439 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
3440 xboundrefs->branchpos, (u1*) mcodeptr - mcodebase);
3444 M_LDA(REG_ITMP2_XPC, REG_PV, xboundrefs->branchpos - 4);
3446 if (xcodeptr != NULL) {
3447 M_BR((xcodeptr-mcodeptr)-1);
3450 xcodeptr = mcodeptr;
3452 a = dseg_addaddress(proto_java_lang_ArrayIndexOutOfBoundsException);
3453 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3455 a = dseg_addaddress(asm_handle_exception);
3456 M_ALD(REG_ITMP3, REG_PV, a);
3458 M_JMP(REG_ZERO, REG_ITMP3);
3462 /* generate negative array size check stubs */
3466 for (; xcheckarefs != NULL; xcheckarefs = xcheckarefs->next) {
3467 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3468 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3469 xcheckarefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3473 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3474 xcheckarefs->branchpos, (u1*) mcodeptr - mcodebase);
3478 M_LDA(REG_ITMP2_XPC, REG_PV, xcheckarefs->branchpos - 4);
3480 if (xcodeptr != NULL) {
3481 M_BR((xcodeptr-mcodeptr)-1);
3484 xcodeptr = mcodeptr;
3486 a = dseg_addaddress(proto_java_lang_NegativeArraySizeException);
3487 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3489 a = dseg_addaddress(asm_handle_exception);
3490 M_ALD(REG_ITMP3, REG_PV, a);
3492 M_JMP(REG_ZERO, REG_ITMP3);
3496 /* generate cast check stubs */
3500 for (; xcastrefs != NULL; xcastrefs = xcastrefs->next) {
3501 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3502 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3503 xcastrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3507 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3508 xcastrefs->branchpos, (u1*) mcodeptr - mcodebase);
3512 M_LDA(REG_ITMP2_XPC, REG_PV, xcastrefs->branchpos - 4);
3514 if (xcodeptr != NULL) {
3515 M_BR((xcodeptr-mcodeptr)-1);
3518 xcodeptr = mcodeptr;
3520 a = dseg_addaddress(proto_java_lang_ClassCastException);
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);
3531 #ifdef SOFTNULLPTRCHECK
3533 /* generate null pointer check stubs */
3537 for (; xnullrefs != NULL; xnullrefs = xnullrefs->next) {
3538 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3539 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3540 xnullrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3544 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3545 xnullrefs->branchpos, (u1*) mcodeptr - mcodebase);
3549 M_LDA(REG_ITMP2_XPC, REG_PV, xnullrefs->branchpos - 4);
3551 if (xcodeptr != NULL) {
3552 M_BR((xcodeptr-mcodeptr)-1);
3555 xcodeptr = mcodeptr;
3557 a = dseg_addaddress(proto_java_lang_NullPointerException);
3558 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3560 a = dseg_addaddress(asm_handle_exception);
3561 M_ALD(REG_ITMP3, REG_PV, a);
3563 M_JMP(REG_ZERO, REG_ITMP3);
3570 mcode_finish((int)((u1*) mcodeptr - mcodebase));
3574 /* redefinition of code generation macros (compiling into array) **************/
3577 These macros are newly defined to allow code generation into an array.
3578 This is necessary, because the original M_.. macros generate code by
3579 calling 'mcode_adds4' that uses an additional data structure to
3582 For a faster (but less flexible) version to generate code, these
3583 macros directly use the (s4* p) - pointer to put the code directly
3584 in a locally defined array.
3585 This makes sense only for the stub-generation-routines below.
3589 #define M_OP3(op,fu,a,b,c,const) \
3590 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<(16-3*(const)))| \
3591 ((const)<<12)|((fu)<<5)|((c)) )
3593 #define M_FOP3(op,fu,a,b,c) \
3594 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<16)|((fu)<<5)|(c) )
3596 #define M_BRA(op,a,disp) \
3597 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((disp)&0x1fffff) )
3599 #define M_MEM(op,a,b,disp) \
3600 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<16)|((disp)&0xffff) )
3603 /* function createcompilerstub *************************************************
3605 creates a stub routine which calls the compiler
3607 *******************************************************************************/
3609 #define COMPSTUBSIZE 3
3611 u1 *createcompilerstub (methodinfo *m)
3613 u8 *s = CNEW (u8, COMPSTUBSIZE); /* memory to hold the stub */
3614 s4 *p = (s4*) s; /* code generation pointer */
3616 /* code for the stub */
3617 M_ALD (REG_PV, REG_PV, 16); /* load pointer to the compiler */
3618 M_JMP (0, REG_PV); /* jump to the compiler, return address
3619 in reg 0 is used as method pointer */
3620 s[1] = (u8) m; /* literals to be adressed */
3621 s[2] = (u8) asm_call_jit_compiler; /* jump directly via PV from above */
3624 count_cstub_len += COMPSTUBSIZE * 8;
3631 /* function removecompilerstub *************************************************
3633 deletes a compilerstub from memory (simply by freeing it)
3635 *******************************************************************************/
3637 void removecompilerstub (u1 *stub)
3639 CFREE (stub, COMPSTUBSIZE * 8);
3643 /* function: createnativestub **************************************************
3645 creates a stub routine which calls a native method
3647 *******************************************************************************/
3649 #define NATIVESTUBSIZE 11
3651 u1 *createnativestub (functionptr f, methodinfo *m)
3653 u8 *s = CNEW (u8, NATIVESTUBSIZE); /* memory to hold the stub */
3654 s4 *p = (s4*) s; /* code generation pointer */
3656 M_LDA (REG_SP, REG_SP, -8); /* build up stackframe */
3657 M_AST (REG_RA, REG_SP, 0); /* store return address */
3659 M_ALD (REG_PV, REG_PV, 8*8); /* load adress of native method */
3660 M_JSR (REG_RA, REG_PV); /* call native method */
3662 M_LDA (REG_PV, REG_RA, -4*4); /* recompute pv from ra */
3663 M_ALD (REG_ITMP3, REG_PV, 9*8); /* get address of exceptionptr */
3665 M_ALD (REG_RA, REG_SP, 0); /* load return address */
3666 M_ALD (REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
3668 M_LDA (REG_SP, REG_SP, 8); /* remove stackframe */
3669 M_BNEZ (REG_ITMP1, 1); /* if no exception then return */
3671 M_RET (REG_ZERO, REG_RA); /* return to caller */
3673 M_AST (REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
3674 M_LDA (REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
3676 M_ALD (REG_ITMP3, REG_PV,10*8); /* load asm exception handler address */
3677 M_JMP (REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
3680 s[8] = (u8) f; /* address of native method */
3681 s[9] = (u8) (&exceptionptr); /* address of exceptionptr */
3682 s[10]= (u8) (asm_handle_nat_exception); /* addr of asm exception handler */
3685 count_nstub_len += NATIVESTUBSIZE * 8;
3692 /* function: removenativestub **************************************************
3694 removes a previously created native-stub from memory
3696 *******************************************************************************/
3698 void removenativestub (u1 *stub)
3700 CFREE (stub, NATIVESTUBSIZE * 8);
3705 * These are local overrides for various environment variables in Emacs.
3706 * Please do not remove this and leave it at the end of the file, where
3707 * Emacs will automagically detect them.
3708 * ---------------------------------------------------------------------
3711 * indent-tabs-mode: t