1 /* mips/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 MIPS (R4000 or higher) processor.
8 This module generates MIPS machine code for a sequence of intermediate
11 Authors: Andreas Krall EMAIL: cacao@complang.tuwien.ac.at
13 Last Change: 1998/11/18
15 *******************************************************************************/
19 /* *****************************************************************************
21 Datatypes and Register Allocations:
22 -----------------------------------
24 On 64-bit-machines (like the MIPS) all operands are stored in the
25 registers in a 64-bit form, even when the correspondig JavaVM operands
26 only need 32 bits. This is done by a canonical representation:
28 32-bit integers are allways stored as sign-extended 64-bit values (this
29 approach is directly supported by the MIPS architecture and is very easy
32 32-bit-floats are stored in a 64-bit double precision register by simply
33 expanding the exponent and mantissa with zeroes. (also supported by the
39 The calling conventions and the layout of the stack is explained in detail
40 in the documention file: calling.doc
42 *******************************************************************************/
45 /* additional functions and macros to generate code ***************************/
47 #define BlockPtrOfPC(pc) block+block_index[pc]
50 #define COUNT_SPILLS count_spills++
56 /* gen_nullptr_check(objreg) */
58 #ifdef SOFTNULLPTRCHECK
59 #define gen_nullptr_check(objreg) \
62 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_DMOV(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 /* NullPointerException signal handler for hardware null pointer check */
201 void catch_NullPointerException(int sig, int code, struct sigcontext *sigctx)
207 /* Reset signal handler - necessary for SysV, does no harm for BSD */
209 instr = *((int*)(sigctx->sc_pc));
210 faultaddr = sigctx->sc_regs[(instr >> 21) & 0x1f];
212 if (faultaddr == 0) {
213 signal(sig, (void*) catch_NullPointerException); /* reinstall handler */
215 sigaddset(&nsig, sig);
216 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
217 sigctx->sc_regs[REG_ITMP1_XPTR] =
218 (long) proto_java_lang_NullPointerException;
219 sigctx->sc_regs[REG_ITMP2_XPC] = sigctx->sc_pc;
220 sigctx->sc_pc = (long) asm_handle_nat_exception;
223 faultaddr += (long) ((instr << 16) >> 16);
224 fprintf(stderr, "faulting address: 0x%16lx\n", faultaddr);
225 panic("Stack overflow");
229 void createcalljava ();
232 void init_exceptions(void)
237 /* install signal handlers we need to convert to exceptions */
242 signal(SIGSEGV, (void*) catch_NullPointerException);
246 signal(SIGBUS, (void*) catch_NullPointerException);
252 /* function gen_mcode **********************************************************
254 generates machine code
256 *******************************************************************************/
258 #define MethodPointer -8
259 #define FrameSize -12
264 #define ExTableSize -32
265 #define ExTableStart -32
268 #define ExEntrySize -32
271 #define ExHandlerPC -24
272 #define ExCatchType -32
274 #define ExEntrySize -16
277 #define ExHandlerPC -12
278 #define ExCatchType -16
281 static void gen_mcode()
283 int len, s1, s2, s3, d, bbs;
294 savedregs_num = (isleafmethod) ? 0 : 1; /* space to save the RA */
296 /* space to save used callee saved registers */
298 savedregs_num += (savintregcnt - maxsavintreguse);
299 savedregs_num += (savfltregcnt - maxsavfltreguse);
301 parentargs_base = maxmemuse + savedregs_num;
303 #ifdef USE_THREADS /* space to save argument of monitor_enter */
305 if (checksync && (method->flags & ACC_SYNCHRONIZED))
310 /* adjust frame size for 16 byte alignment */
312 if (parentargs_base & 1)
315 /* create method header */
318 (void) dseg_addaddress(method); /* Filler */
320 (void) dseg_addaddress(method); /* MethodPointer */
321 (void) dseg_adds4(parentargs_base * 8); /* FrameSize */
325 /* IsSync contains the offset relative to the stack pointer for the
326 argument of monitor_exit used in the exception handler. Since the
327 offset could be zero and give a wrong meaning of the flag it is
331 if (checksync && (method->flags & ACC_SYNCHRONIZED))
332 (void) dseg_adds4((maxmemuse + 1) * 8); /* IsSync */
337 (void) dseg_adds4(0); /* IsSync */
339 (void) dseg_adds4(isleafmethod); /* IsLeaf */
340 (void) dseg_adds4(savintregcnt - maxsavintreguse); /* IntSave */
341 (void) dseg_adds4(savfltregcnt - maxsavfltreguse); /* FltSave */
342 (void) dseg_adds4(exceptiontablelength); /* ExTableSize */
344 /* create exception table */
346 for (len = 0; len < exceptiontablelength; len++) {
347 dseg_addtarget(BlockPtrOfPC(extable[len].startpc));
348 dseg_addtarget(BlockPtrOfPC(extable[len].endpc));
349 dseg_addtarget(BlockPtrOfPC(extable[len].handlerpc));
350 (void) dseg_addaddress(extable[len].catchtype);
353 /* initialize mcode variables */
355 mcodeptr = (s4*) mcodebase;
356 mcodeend = (s4*) (mcodebase + mcodesize);
357 MCODECHECK(128 + mparamcount);
359 /* create stack frame (if necessary) */
362 {M_LDA (REG_SP, REG_SP, -parentargs_base * 8);}
364 /* save return address and used callee saved registers */
368 {p--; M_LST (REG_RA, REG_SP, 8*p);}
369 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
370 {p--; M_LST (savintregs[r], REG_SP, 8 * p);}
371 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
372 {p--; M_DST (savfltregs[r], REG_SP, 8 * p);}
374 /* save monitorenter argument */
377 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
378 if (method->flags & ACC_STATIC) {
379 p = dseg_addaddress (class);
380 M_ALD(REG_ITMP1, REG_PV, p);
381 M_AST(REG_ITMP1, REG_SP, 8 * maxmemuse);
384 M_AST (argintregs[0], REG_SP, 8 * maxmemuse);
389 /* copy argument registers to stack and call trace function with pointer
390 to arguments on stack. ToDo: save floating point registers !!!!!!!!!
393 if (runverbose && isleafmethod) {
394 M_LDA (REG_SP, REG_SP, -(18*8));
396 M_LST(REG_RA, REG_SP, 1*8);
398 M_LST(argintregs[0], REG_SP, 2*8);
399 M_LST(argintregs[1], REG_SP, 3*8);
400 M_LST(argintregs[2], REG_SP, 4*8);
401 M_LST(argintregs[3], REG_SP, 5*8);
402 M_LST(argintregs[4], REG_SP, 6*8);
403 M_LST(argintregs[5], REG_SP, 7*8);
404 M_LST(argintregs[6], REG_SP, 8*8);
405 M_LST(argintregs[7], REG_SP, 9*8);
407 M_DST(argfltregs[0], REG_SP, 10*8);
408 M_DST(argfltregs[1], REG_SP, 11*8);
409 M_DST(argfltregs[2], REG_SP, 12*8);
410 M_DST(argfltregs[3], REG_SP, 13*8);
411 M_DST(argfltregs[4], REG_SP, 14*8);
412 M_DST(argfltregs[5], REG_SP, 15*8);
413 M_DST(argfltregs[6], REG_SP, 16*8);
414 M_DST(argfltregs[7], REG_SP, 17*8);
416 p = dseg_addaddress (method);
417 M_ALD(REG_ITMP1, REG_PV, p);
418 M_LST(REG_ITMP1, REG_SP, 0);
419 p = dseg_addaddress ((void*) (builtin_trace_args));
420 M_ALD(REG_ITMP3, REG_PV, p);
421 M_JSR(REG_RA, REG_ITMP3);
424 M_LLD(REG_RA, REG_SP, 1*8);
426 M_LLD(argintregs[0], REG_SP, 2*8);
427 M_LLD(argintregs[1], REG_SP, 3*8);
428 M_LLD(argintregs[2], REG_SP, 4*8);
429 M_LLD(argintregs[3], REG_SP, 5*8);
430 M_LLD(argintregs[4], REG_SP, 6*8);
431 M_LLD(argintregs[5], REG_SP, 7*8);
432 M_LLD(argintregs[6], REG_SP, 8*8);
433 M_LLD(argintregs[7], REG_SP, 9*8);
435 M_DLD(argfltregs[0], REG_SP, 10*8);
436 M_DLD(argfltregs[1], REG_SP, 11*8);
437 M_DLD(argfltregs[2], REG_SP, 12*8);
438 M_DLD(argfltregs[3], REG_SP, 13*8);
439 M_DLD(argfltregs[4], REG_SP, 14*8);
440 M_DLD(argfltregs[5], REG_SP, 15*8);
441 M_DLD(argfltregs[6], REG_SP, 16*8);
442 M_DLD(argfltregs[7], REG_SP, 17*8);
444 M_LDA (REG_SP, REG_SP, 18*8);
447 /* take arguments out of register or stack frame */
449 for (p = 0, l = 0; p < mparamcount; p++) {
451 var = &(locals[l][t]);
453 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
458 if (IS_INT_LNG_TYPE(t)) { /* integer args */
459 if (p < INT_ARG_CNT) { /* register arguments */
460 if (!(var->flags & INMEMORY)) /* reg arg -> register */
461 {M_INTMOVE (argintregs[p], r);}
462 else /* reg arg -> spilled */
463 M_LST (argintregs[p], REG_SP, 8 * r);
465 else { /* stack arguments */
466 pa = p - INT_ARG_CNT;
467 if (!(var->flags & INMEMORY)) /* stack arg -> register */
468 M_LLD (r, REG_SP, 8 * (parentargs_base + pa));
469 else { /* stack arg -> spilled */
470 M_LLD (REG_ITMP1, REG_SP, 8 * (parentargs_base + pa));
471 M_LST (REG_ITMP1, REG_SP, 8 * r);
475 else { /* floating args */
476 if (p < FLT_ARG_CNT) { /* register arguments */
477 if (!(var->flags & INMEMORY)) /* reg arg -> register */
478 {M_FLTMOVE (argfltregs[p], r);}
479 else /* reg arg -> spilled */
480 M_DST (argfltregs[p], REG_SP, 8 * r);
482 else { /* stack arguments */
483 pa = p - FLT_ARG_CNT;
484 if (!(var->flags & INMEMORY)) /* stack-arg -> register */
485 M_DLD (r, REG_SP, 8 * (parentargs_base + pa) );
486 else { /* stack-arg -> spilled */
487 M_DLD (REG_FTMP1, REG_SP, 8 * (parentargs_base + pa));
488 M_DST (REG_FTMP1, REG_SP, 8 * r);
494 /* call trace function */
496 if (runverbose && !isleafmethod) {
497 M_LDA (REG_SP, REG_SP, -8);
498 p = dseg_addaddress (method);
499 M_ALD(REG_ITMP1, REG_PV, p);
500 M_AST(REG_ITMP1, REG_SP, 0);
501 p = dseg_addaddress ((void*) (builtin_trace_args));
502 M_ALD(REG_ITMP3, REG_PV, p);
503 M_JSR(REG_RA, REG_ITMP3);
505 M_LDA(REG_SP, REG_SP, 8);
508 /* call monitorenter function */
511 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
512 p = dseg_addaddress ((void*) (builtin_monitorenter));
513 M_ALD(REG_ITMP3, REG_PV, p);
514 M_JSR(REG_RA, REG_ITMP3);
515 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
520 /* end of header generation */
522 /* walk through all basic blocks */
524 for (bbs = block_count, bptr = block; --bbs >= 0; bptr++) {
525 bptr -> mpc = (int)((u1*) mcodeptr - mcodebase);
527 if (bptr->flags >= BBREACHED) {
529 /* branch resolving */
533 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
534 gen_resolvebranch((u1*) mcodebase + brefs->branchpos,
535 brefs->branchpos, bptr->mpc);
539 /* copy interface registers to their destination */
544 while (src != NULL) {
546 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
547 d = reg_of_var(src, REG_ITMP1);
548 M_INTMOVE(REG_ITMP1, d);
549 store_reg_to_var_int(src, d);
552 d = reg_of_var(src, REG_IFTMP);
553 if ((src->varkind != STACKVAR)) {
555 if (IS_FLT_DBL_TYPE(s2)) {
556 if (!(interfaces[len][s2].flags & INMEMORY)) {
557 s1 = interfaces[len][s2].regoff;
561 M_DLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
563 store_reg_to_var_flt(src, d);
566 if (!(interfaces[len][s2].flags & INMEMORY)) {
567 s1 = interfaces[len][s2].regoff;
571 M_LLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
573 store_reg_to_var_int(src, d);
580 /* walk through all instructions */
584 for (iptr = bptr->iinstr;
586 src = iptr->dst, len--, iptr++) {
588 MCODECHECK(64); /* an instruction usually needs < 64 words */
591 case ICMD_NOP: /* ... ==> ... */
594 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
596 var_to_reg_int(s1, src, REG_ITMP1);
598 mcode_addxnullrefs(mcodeptr);
602 /* constant operations ************************************************/
604 #define ICONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_IADD_IMM(REG_ZERO,c,r);} \
605 else if(((c)>=0)&&((c)<=0xffff)){M_OR_IMM(REG_ZERO,c,r);} \
606 else{a=dseg_adds4(c);M_ILD(r,REG_PV,a);}
608 #define LCONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LADD_IMM(REG_ZERO,c,r);} \
609 else if(((c)>=0)&&((c)<=0xffff)){M_OR_IMM(REG_ZERO,c,r);} \
610 else{a=dseg_adds8(c);M_LLD(r,REG_PV,a);}
612 case ICMD_ICONST: /* ... ==> ..., constant */
613 /* op1 = 0, val.i = constant */
615 d = reg_of_var(iptr->dst, REG_ITMP1);
616 ICONST(d, iptr->val.i);
617 store_reg_to_var_int(iptr->dst, d);
620 case ICMD_LCONST: /* ... ==> ..., constant */
621 /* op1 = 0, val.l = constant */
623 d = reg_of_var(iptr->dst, REG_ITMP1);
624 LCONST(d, iptr->val.l);
625 store_reg_to_var_int(iptr->dst, d);
628 case ICMD_FCONST: /* ... ==> ..., constant */
629 /* op1 = 0, val.f = constant */
631 d = reg_of_var (iptr->dst, REG_FTMP1);
632 a = dseg_addfloat (iptr->val.f);
634 store_reg_to_var_flt (iptr->dst, d);
637 case ICMD_DCONST: /* ... ==> ..., constant */
638 /* op1 = 0, val.d = constant */
640 d = reg_of_var (iptr->dst, REG_FTMP1);
641 a = dseg_adddouble (iptr->val.d);
643 store_reg_to_var_flt (iptr->dst, d);
646 case ICMD_ACONST: /* ... ==> ..., constant */
647 /* op1 = 0, val.a = constant */
649 d = reg_of_var(iptr->dst, REG_ITMP1);
651 a = dseg_addaddress (iptr->val.a);
655 M_INTMOVE(REG_ZERO, d);
657 store_reg_to_var_int(iptr->dst, d);
661 /* load/store operations **********************************************/
663 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
664 case ICMD_LLOAD: /* op1 = local variable */
667 d = reg_of_var(iptr->dst, REG_ITMP1);
668 if ((iptr->dst->varkind == LOCALVAR) &&
669 (iptr->dst->varnum == iptr->op1))
671 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
672 if (var->flags & INMEMORY)
673 M_LLD(d, REG_SP, 8 * var->regoff);
675 {M_INTMOVE(var->regoff,d);}
676 store_reg_to_var_int(iptr->dst, d);
679 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
680 case ICMD_DLOAD: /* op1 = local variable */
682 d = reg_of_var(iptr->dst, REG_FTMP1);
683 if ((iptr->dst->varkind == LOCALVAR) &&
684 (iptr->dst->varnum == iptr->op1))
686 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
687 if (var->flags & INMEMORY)
688 M_DLD(d, REG_SP, 8 * var->regoff);
690 {M_FLTMOVE(var->regoff,d);}
691 store_reg_to_var_flt(iptr->dst, d);
695 case ICMD_ISTORE: /* ..., value ==> ... */
696 case ICMD_LSTORE: /* op1 = local variable */
699 if ((src->varkind == LOCALVAR) &&
700 (src->varnum == iptr->op1))
702 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
703 if (var->flags & INMEMORY) {
704 var_to_reg_int(s1, src, REG_ITMP1);
705 M_LST(s1, REG_SP, 8 * var->regoff);
708 var_to_reg_int(s1, src, var->regoff);
709 M_INTMOVE(s1, var->regoff);
713 case ICMD_FSTORE: /* ..., value ==> ... */
714 case ICMD_DSTORE: /* op1 = local variable */
716 if ((src->varkind == LOCALVAR) &&
717 (src->varnum == iptr->op1))
719 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
720 if (var->flags & INMEMORY) {
721 var_to_reg_flt(s1, src, REG_FTMP1);
722 M_DST(s1, REG_SP, 8 * var->regoff);
725 var_to_reg_flt(s1, src, var->regoff);
726 M_FLTMOVE(s1, var->regoff);
731 /* pop/dup/swap operations ********************************************/
733 /* attention: double and longs are only one entry in CACAO ICMDs */
735 case ICMD_POP: /* ..., value ==> ... */
736 case ICMD_POP2: /* ..., value, value ==> ... */
739 #define M_COPY(from,to) \
740 d = reg_of_var(to, REG_IFTMP); \
741 if ((from->regoff != to->regoff) || \
742 ((from->flags ^ to->flags) & INMEMORY)) { \
743 if (IS_FLT_DBL_TYPE(from->type)) { \
744 var_to_reg_flt(s1, from, d); \
746 store_reg_to_var_flt(to, d); \
749 var_to_reg_int(s1, from, d); \
751 store_reg_to_var_int(to, d); \
755 case ICMD_DUP: /* ..., a ==> ..., a, a */
756 M_COPY(src, iptr->dst);
759 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
761 M_COPY(src, iptr->dst->prev->prev);
763 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
765 M_COPY(src, iptr->dst);
766 M_COPY(src->prev, iptr->dst->prev);
769 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
771 M_COPY(src->prev, iptr->dst->prev->prev->prev);
773 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
775 M_COPY(src, iptr->dst);
776 M_COPY(src->prev, iptr->dst->prev);
777 M_COPY(src->prev->prev, iptr->dst->prev->prev);
778 M_COPY(src, iptr->dst->prev->prev->prev);
781 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
783 M_COPY(src, iptr->dst);
784 M_COPY(src->prev, iptr->dst->prev);
785 M_COPY(src->prev->prev, iptr->dst->prev->prev);
786 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
787 M_COPY(src, iptr->dst->prev->prev->prev->prev);
788 M_COPY(src->prev, iptr->dst->prev->prev->prev->prev->prev);
791 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
793 M_COPY(src, iptr->dst->prev);
794 M_COPY(src->prev, iptr->dst);
798 /* integer operations *************************************************/
800 case ICMD_INEG: /* ..., value ==> ..., - value */
802 var_to_reg_int(s1, src, REG_ITMP1);
803 d = reg_of_var(iptr->dst, REG_ITMP3);
804 M_ISUB(REG_ZERO, s1, d);
805 store_reg_to_var_int(iptr->dst, d);
808 case ICMD_LNEG: /* ..., value ==> ..., - value */
810 var_to_reg_int(s1, src, REG_ITMP1);
811 d = reg_of_var(iptr->dst, REG_ITMP3);
812 M_LSUB(REG_ZERO, s1, d);
813 store_reg_to_var_int(iptr->dst, d);
816 case ICMD_I2L: /* ..., value ==> ..., value */
818 var_to_reg_int(s1, src, REG_ITMP1);
819 d = reg_of_var(iptr->dst, REG_ITMP3);
821 store_reg_to_var_int(iptr->dst, d);
824 case ICMD_L2I: /* ..., value ==> ..., value */
826 var_to_reg_int(s1, src, REG_ITMP1);
827 d = reg_of_var(iptr->dst, REG_ITMP3);
828 M_IADD(s1, REG_ZERO, d );
829 store_reg_to_var_int(iptr->dst, d);
832 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
834 var_to_reg_int(s1, src, REG_ITMP1);
835 d = reg_of_var(iptr->dst, REG_ITMP3);
836 M_LSLL_IMM(s1, 56, d);
837 M_LSRA_IMM( d, 56, d);
838 store_reg_to_var_int(iptr->dst, d);
841 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
843 var_to_reg_int(s1, src, REG_ITMP1);
844 d = reg_of_var(iptr->dst, REG_ITMP3);
846 store_reg_to_var_int(iptr->dst, d);
849 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
851 var_to_reg_int(s1, src, REG_ITMP1);
852 d = reg_of_var(iptr->dst, REG_ITMP3);
853 M_LSLL_IMM(s1, 48, d);
854 M_LSRA_IMM( d, 48, d);
855 store_reg_to_var_int(iptr->dst, d);
859 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
861 var_to_reg_int(s1, src->prev, REG_ITMP1);
862 var_to_reg_int(s2, src, REG_ITMP2);
863 d = reg_of_var(iptr->dst, REG_ITMP3);
865 store_reg_to_var_int(iptr->dst, d);
868 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
869 /* val.i = constant */
871 var_to_reg_int(s1, src, REG_ITMP1);
872 d = reg_of_var(iptr->dst, REG_ITMP3);
873 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
874 M_IADD_IMM(s1, iptr->val.i, d);
877 ICONST(REG_ITMP2, iptr->val.i);
878 M_IADD(s1, REG_ITMP2, d);
880 store_reg_to_var_int(iptr->dst, d);
883 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
885 var_to_reg_int(s1, src->prev, REG_ITMP1);
886 var_to_reg_int(s2, src, REG_ITMP2);
887 d = reg_of_var(iptr->dst, REG_ITMP3);
889 store_reg_to_var_int(iptr->dst, d);
892 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
893 /* val.l = constant */
895 var_to_reg_int(s1, src, REG_ITMP1);
896 d = reg_of_var(iptr->dst, REG_ITMP3);
897 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
898 M_LADD_IMM(s1, iptr->val.l, d);
901 LCONST(REG_ITMP2, iptr->val.l);
902 M_LADD(s1, REG_ITMP2, d);
904 store_reg_to_var_int(iptr->dst, d);
907 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
909 var_to_reg_int(s1, src->prev, REG_ITMP1);
910 var_to_reg_int(s2, src, REG_ITMP2);
911 d = reg_of_var(iptr->dst, REG_ITMP3);
913 store_reg_to_var_int(iptr->dst, d);
916 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
917 /* val.i = constant */
919 var_to_reg_int(s1, src, REG_ITMP1);
920 d = reg_of_var(iptr->dst, REG_ITMP3);
921 if ((iptr->val.i >= -32767) && (iptr->val.i <= 32768)) {
922 M_IADD_IMM(s1, -iptr->val.i, d);
925 ICONST(REG_ITMP2, iptr->val.i);
926 M_ISUB(s1, REG_ITMP2, d);
928 store_reg_to_var_int(iptr->dst, d);
931 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
933 var_to_reg_int(s1, src->prev, REG_ITMP1);
934 var_to_reg_int(s2, src, REG_ITMP2);
935 d = reg_of_var(iptr->dst, REG_ITMP3);
937 store_reg_to_var_int(iptr->dst, d);
940 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
941 /* val.l = constant */
943 var_to_reg_int(s1, src, REG_ITMP1);
944 d = reg_of_var(iptr->dst, REG_ITMP3);
945 if ((iptr->val.l >= -32767) && (iptr->val.l <= 32768)) {
946 M_LADD_IMM(s1, -iptr->val.l, d);
949 LCONST(REG_ITMP2, iptr->val.l);
950 M_LSUB(s1, REG_ITMP2, d);
952 store_reg_to_var_int(iptr->dst, d);
955 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
957 var_to_reg_int(s1, src->prev, REG_ITMP1);
958 var_to_reg_int(s2, src, REG_ITMP2);
959 d = reg_of_var(iptr->dst, REG_ITMP3);
964 store_reg_to_var_int(iptr->dst, d);
967 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
968 /* val.i = constant */
970 var_to_reg_int(s1, src, REG_ITMP1);
971 d = reg_of_var(iptr->dst, REG_ITMP3);
972 ICONST(REG_ITMP2, iptr->val.i);
973 M_IMUL(s1, REG_ITMP2);
977 store_reg_to_var_int(iptr->dst, d);
980 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
982 var_to_reg_int(s1, src->prev, REG_ITMP1);
983 var_to_reg_int(s2, src, REG_ITMP2);
984 d = reg_of_var(iptr->dst, REG_ITMP3);
989 store_reg_to_var_int(iptr->dst, d);
992 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
993 /* val.l = constant */
995 var_to_reg_int(s1, src, REG_ITMP1);
996 d = reg_of_var(iptr->dst, REG_ITMP3);
997 LCONST(REG_ITMP2, iptr->val.l);
998 M_LMUL(s1, REG_ITMP2);
1002 store_reg_to_var_int(iptr->dst, d);
1005 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1007 var_to_reg_int(s1, src->prev, REG_ITMP1);
1008 var_to_reg_int(s2, src, REG_ITMP2);
1009 d = reg_of_var(iptr->dst, REG_ITMP3);
1014 store_reg_to_var_int(iptr->dst, d);
1017 case ICMD_IDIVCONST: /* ..., value ==> ..., value / constant */
1018 /* val.i = constant */
1020 var_to_reg_int(s1, src, REG_ITMP1);
1021 d = reg_of_var(iptr->dst, REG_ITMP3);
1022 ICONST(REG_ITMP2, iptr->val.i);
1023 M_IDIV(s1, REG_ITMP2);
1027 store_reg_to_var_int(iptr->dst, d);
1030 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1032 var_to_reg_int(s1, src->prev, REG_ITMP1);
1033 var_to_reg_int(s2, src, REG_ITMP2);
1034 d = reg_of_var(iptr->dst, REG_ITMP3);
1039 store_reg_to_var_int(iptr->dst, d);
1042 case ICMD_LDIVCONST: /* ..., value ==> ..., value / constant */
1043 /* val.l = constant */
1045 var_to_reg_int(s1, src, REG_ITMP1);
1046 d = reg_of_var(iptr->dst, REG_ITMP3);
1047 LCONST(REG_ITMP2, iptr->val.l);
1048 M_LDIV(s1, REG_ITMP2);
1052 store_reg_to_var_int(iptr->dst, d);
1055 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1057 var_to_reg_int(s1, src->prev, REG_ITMP1);
1058 var_to_reg_int(s2, src, REG_ITMP2);
1059 d = reg_of_var(iptr->dst, REG_ITMP3);
1064 store_reg_to_var_int(iptr->dst, d);
1067 case ICMD_IREMCONST: /* ..., value ==> ..., value % constant */
1068 /* val.i = constant */
1070 var_to_reg_int(s1, src, REG_ITMP1);
1071 d = reg_of_var(iptr->dst, REG_ITMP3);
1072 ICONST(REG_ITMP2, iptr->val.i);
1073 M_IDIV(s1, REG_ITMP2);
1077 store_reg_to_var_int(iptr->dst, d);
1080 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1082 var_to_reg_int(s1, src->prev, REG_ITMP1);
1083 var_to_reg_int(s2, src, REG_ITMP2);
1084 d = reg_of_var(iptr->dst, REG_ITMP3);
1089 store_reg_to_var_int(iptr->dst, d);
1092 case ICMD_LREMCONST: /* ..., value ==> ..., value % constant */
1093 /* val.l = constant */
1095 var_to_reg_int(s1, src, REG_ITMP1);
1096 d = reg_of_var(iptr->dst, REG_ITMP3);
1097 LCONST(REG_ITMP2, iptr->val.l);
1098 M_LDIV(s1, REG_ITMP2);
1102 store_reg_to_var_int(iptr->dst, d);
1105 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
1106 case ICMD_LDIVPOW2: /* val.i = constant */
1108 var_to_reg_int(s1, src, REG_ITMP1);
1109 d = reg_of_var(iptr->dst, REG_ITMP3);
1110 M_LSRA_IMM(s1, 63, REG_ITMP2);
1111 M_LSRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
1112 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1113 M_LSRA_IMM(REG_ITMP2, iptr->val.i, d);
1114 store_reg_to_var_int(iptr->dst, d);
1117 case ICMD_ISHL: /* ..., 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_ISHLCONST: /* ..., value ==> ..., value << constant */
1127 /* val.i = constant */
1129 var_to_reg_int(s1, src, REG_ITMP1);
1130 d = reg_of_var(iptr->dst, REG_ITMP3);
1131 M_ISLL_IMM(s1, iptr->val.i, d);
1132 store_reg_to_var_int(iptr->dst, d);
1135 case ICMD_ISHR: /* ..., 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_ISHRCONST: /* ..., value ==> ..., value >> constant */
1145 /* val.i = constant */
1147 var_to_reg_int(s1, src, REG_ITMP1);
1148 d = reg_of_var(iptr->dst, REG_ITMP3);
1149 M_ISRA_IMM(s1, iptr->val.i, d);
1150 store_reg_to_var_int(iptr->dst, d);
1153 case ICMD_IUSHR: /* ..., 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_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1163 /* val.i = constant */
1165 var_to_reg_int(s1, src, REG_ITMP1);
1166 d = reg_of_var(iptr->dst, REG_ITMP3);
1167 M_ISRL_IMM(s1, iptr->val.i, d);
1168 store_reg_to_var_int(iptr->dst, d);
1171 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1173 var_to_reg_int(s1, src->prev, REG_ITMP1);
1174 var_to_reg_int(s2, src, REG_ITMP2);
1175 d = reg_of_var(iptr->dst, REG_ITMP3);
1177 store_reg_to_var_int(iptr->dst, d);
1180 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1181 /* val.l = constant */
1183 var_to_reg_int(s1, src, REG_ITMP1);
1184 d = reg_of_var(iptr->dst, REG_ITMP3);
1185 M_LSLL_IMM(s1, iptr->val.l, d);
1186 store_reg_to_var_int(iptr->dst, d);
1189 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1191 var_to_reg_int(s1, src->prev, REG_ITMP1);
1192 var_to_reg_int(s2, src, REG_ITMP2);
1193 d = reg_of_var(iptr->dst, REG_ITMP3);
1195 store_reg_to_var_int(iptr->dst, d);
1198 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1199 /* val.l = constant */
1201 var_to_reg_int(s1, src, REG_ITMP1);
1202 d = reg_of_var(iptr->dst, REG_ITMP3);
1203 M_LSRA_IMM(s1, iptr->val.l, d);
1204 store_reg_to_var_int(iptr->dst, d);
1207 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1209 var_to_reg_int(s1, src->prev, REG_ITMP1);
1210 var_to_reg_int(s2, src, REG_ITMP2);
1211 d = reg_of_var(iptr->dst, REG_ITMP3);
1213 store_reg_to_var_int(iptr->dst, d);
1216 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1217 /* val.l = constant */
1219 var_to_reg_int(s1, src, REG_ITMP1);
1220 d = reg_of_var(iptr->dst, REG_ITMP3);
1221 M_LSRL_IMM(s1, iptr->val.l, d);
1222 store_reg_to_var_int(iptr->dst, d);
1225 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1228 var_to_reg_int(s1, src->prev, REG_ITMP1);
1229 var_to_reg_int(s2, src, REG_ITMP2);
1230 d = reg_of_var(iptr->dst, REG_ITMP3);
1232 store_reg_to_var_int(iptr->dst, d);
1235 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1236 /* val.i = constant */
1238 var_to_reg_int(s1, src, REG_ITMP1);
1239 d = reg_of_var(iptr->dst, REG_ITMP3);
1240 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1241 M_AND_IMM(s1, iptr->val.i, d);
1244 ICONST(REG_ITMP2, iptr->val.i);
1245 M_AND(s1, REG_ITMP2, d);
1247 store_reg_to_var_int(iptr->dst, d);
1250 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1251 /* val.i = constant */
1253 var_to_reg_int(s1, src, REG_ITMP1);
1254 d = reg_of_var(iptr->dst, REG_ITMP3);
1256 M_MOV(s1, REG_ITMP1);
1259 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1260 M_AND_IMM(s1, iptr->val.i, d);
1263 M_ISUB(REG_ZERO, s1, d);
1264 M_AND_IMM(d, iptr->val.i, d);
1267 ICONST(REG_ITMP2, iptr->val.i);
1268 M_AND(s1, REG_ITMP2, d);
1271 M_ISUB(REG_ZERO, s1, d);
1272 M_AND(d, REG_ITMP2, d);
1274 M_ISUB(REG_ZERO, d, d);
1275 store_reg_to_var_int(iptr->dst, d);
1278 case ICMD_IREM0X10001: /* ..., value ==> ..., value % 0x100001 */
1280 /* b = value & 0xffff;
1282 a = ((b - a) & 0xffff) + (b < a);
1284 var_to_reg_int(s1, src, REG_ITMP1);
1285 d = reg_of_var(iptr->dst, REG_ITMP3);
1287 M_MOV(s1, REG_ITMP3);
1291 M_CZEXT(s1, REG_ITMP2); /* delay slot */
1292 M_ISRA_IMM(s1, 16, d);
1293 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1294 M_ISUB(REG_ITMP2, d, d);
1297 M_IADD(d, REG_ITMP1, d); /* delay slot */
1299 M_LUI(REG_ITMP2, 1);
1300 M_IADD_IMM(REG_ITMP2, 1, REG_ITMP2);
1301 M_IDIV(s1, REG_ITMP2);
1305 store_reg_to_var_int(iptr->dst, d);
1308 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1309 /* val.l = constant */
1311 var_to_reg_int(s1, src, REG_ITMP1);
1312 d = reg_of_var(iptr->dst, REG_ITMP3);
1313 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1314 M_AND_IMM(s1, iptr->val.l, d);
1317 LCONST(REG_ITMP2, iptr->val.l);
1318 M_AND(s1, REG_ITMP2, d);
1320 store_reg_to_var_int(iptr->dst, d);
1323 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1324 /* val.l = constant */
1326 var_to_reg_int(s1, src, REG_ITMP1);
1327 d = reg_of_var(iptr->dst, REG_ITMP3);
1329 M_MOV(s1, REG_ITMP1);
1332 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1333 M_AND_IMM(s1, iptr->val.l, d);
1336 M_LSUB(REG_ZERO, s1, d);
1337 M_AND_IMM(d, iptr->val.l, d);
1340 LCONST(REG_ITMP2, iptr->val.l);
1341 M_AND(s1, REG_ITMP2, d);
1344 M_LSUB(REG_ZERO, s1, d);
1345 M_AND(d, REG_ITMP2, d);
1347 M_LSUB(REG_ZERO, d, d);
1348 store_reg_to_var_int(iptr->dst, d);
1351 case ICMD_LREM0X10001:/* ..., value ==> ..., value % 0x10001 */
1353 var_to_reg_int(s1, src, REG_ITMP1);
1354 d = reg_of_var(iptr->dst, REG_ITMP3);
1355 M_LUI(REG_ITMP2, 1);
1356 M_LADD_IMM(REG_ITMP2, 1, REG_ITMP2);
1357 M_LDIV(s1, REG_ITMP2);
1361 store_reg_to_var_int(iptr->dst, d);
1364 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1367 var_to_reg_int(s1, src->prev, REG_ITMP1);
1368 var_to_reg_int(s2, src, REG_ITMP2);
1369 d = reg_of_var(iptr->dst, REG_ITMP3);
1371 store_reg_to_var_int(iptr->dst, d);
1374 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1375 /* val.i = constant */
1377 var_to_reg_int(s1, src, REG_ITMP1);
1378 d = reg_of_var(iptr->dst, REG_ITMP3);
1379 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1380 M_OR_IMM(s1, iptr->val.i, d);
1383 ICONST(REG_ITMP2, iptr->val.i);
1384 M_OR(s1, REG_ITMP2, d);
1386 store_reg_to_var_int(iptr->dst, d);
1389 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1390 /* val.l = constant */
1392 var_to_reg_int(s1, src, REG_ITMP1);
1393 d = reg_of_var(iptr->dst, REG_ITMP3);
1394 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1395 M_OR_IMM(s1, iptr->val.l, d);
1398 LCONST(REG_ITMP2, iptr->val.l);
1399 M_OR(s1, REG_ITMP2, d);
1401 store_reg_to_var_int(iptr->dst, d);
1404 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1407 var_to_reg_int(s1, src->prev, REG_ITMP1);
1408 var_to_reg_int(s2, src, REG_ITMP2);
1409 d = reg_of_var(iptr->dst, REG_ITMP3);
1411 store_reg_to_var_int(iptr->dst, d);
1414 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1415 /* val.i = constant */
1417 var_to_reg_int(s1, src, REG_ITMP1);
1418 d = reg_of_var(iptr->dst, REG_ITMP3);
1419 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1420 M_XOR_IMM(s1, iptr->val.i, d);
1423 ICONST(REG_ITMP2, iptr->val.i);
1424 M_XOR(s1, REG_ITMP2, d);
1426 store_reg_to_var_int(iptr->dst, d);
1429 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1430 /* val.l = constant */
1432 var_to_reg_int(s1, src, REG_ITMP1);
1433 d = reg_of_var(iptr->dst, REG_ITMP3);
1434 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1435 M_XOR_IMM(s1, iptr->val.l, d);
1438 LCONST(REG_ITMP2, iptr->val.l);
1439 M_XOR(s1, REG_ITMP2, d);
1441 store_reg_to_var_int(iptr->dst, d);
1445 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1447 var_to_reg_int(s1, src->prev, REG_ITMP1);
1448 var_to_reg_int(s2, src, REG_ITMP2);
1449 d = reg_of_var(iptr->dst, REG_ITMP3);
1450 M_CMPLT(s1, s2, REG_ITMP3);
1451 M_CMPLT(s2, s1, REG_ITMP1);
1452 M_LSUB (REG_ITMP1, REG_ITMP3, d);
1453 store_reg_to_var_int(iptr->dst, d);
1457 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1458 /* op1 = variable, val.i = constant */
1460 var = &(locals[iptr->op1][TYPE_INT]);
1461 if (var->flags & INMEMORY) {
1463 M_LLD(s1, REG_SP, 8 * var->regoff);
1467 M_IADD_IMM(s1, iptr->val.i, s1);
1468 if (var->flags & INMEMORY)
1469 M_LST(s1, REG_SP, 8 * var->regoff);
1473 /* floating operations ************************************************/
1475 case ICMD_FNEG: /* ..., value ==> ..., - value */
1477 var_to_reg_flt(s1, src, REG_FTMP1);
1478 d = reg_of_var(iptr->dst, REG_FTMP3);
1480 store_reg_to_var_flt(iptr->dst, d);
1483 case ICMD_DNEG: /* ..., value ==> ..., - value */
1485 var_to_reg_flt(s1, src, REG_FTMP1);
1486 d = reg_of_var(iptr->dst, REG_FTMP3);
1488 store_reg_to_var_flt(iptr->dst, d);
1491 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1493 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1494 var_to_reg_flt(s2, src, REG_FTMP2);
1495 d = reg_of_var(iptr->dst, REG_FTMP3);
1497 store_reg_to_var_flt(iptr->dst, d);
1500 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1502 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1503 var_to_reg_flt(s2, src, REG_FTMP2);
1504 d = reg_of_var(iptr->dst, REG_FTMP3);
1506 store_reg_to_var_flt(iptr->dst, d);
1509 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1511 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1512 var_to_reg_flt(s2, src, REG_FTMP2);
1513 d = reg_of_var(iptr->dst, REG_FTMP3);
1515 store_reg_to_var_flt(iptr->dst, d);
1518 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1520 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1521 var_to_reg_flt(s2, src, REG_FTMP2);
1522 d = reg_of_var(iptr->dst, REG_FTMP3);
1524 store_reg_to_var_flt(iptr->dst, d);
1527 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1529 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1530 var_to_reg_flt(s2, src, REG_FTMP2);
1531 d = reg_of_var(iptr->dst, REG_FTMP3);
1533 store_reg_to_var_flt(iptr->dst, d);
1536 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1538 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1539 var_to_reg_flt(s2, src, REG_FTMP2);
1540 d = reg_of_var(iptr->dst, REG_FTMP3);
1542 store_reg_to_var_flt(iptr->dst, d);
1545 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1547 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1548 var_to_reg_flt(s2, src, REG_FTMP2);
1549 d = reg_of_var(iptr->dst, REG_FTMP3);
1551 store_reg_to_var_flt(iptr->dst, d);
1554 case ICMD_DDIV: /* ..., 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);
1560 store_reg_to_var_flt(iptr->dst, d);
1563 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1565 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1566 var_to_reg_flt(s2, src, REG_FTMP2);
1567 d = reg_of_var(iptr->dst, REG_FTMP3);
1568 M_FDIV(s1,s2, REG_FTMP3);
1569 M_FLOORFL(REG_FTMP3, REG_FTMP3);
1570 M_CVTLF(REG_FTMP3, REG_FTMP3);
1571 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1572 M_FSUB(s1, REG_FTMP3, d);
1573 store_reg_to_var_flt(iptr->dst, d);
1576 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1578 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1579 var_to_reg_flt(s2, src, REG_FTMP2);
1580 d = reg_of_var(iptr->dst, REG_FTMP3);
1581 M_DDIV(s1,s2, REG_FTMP3);
1582 M_FLOORDL(REG_FTMP3, REG_FTMP3);
1583 M_CVTLD(REG_FTMP3, REG_FTMP3);
1584 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1585 M_DSUB(s1, REG_FTMP3, d);
1586 store_reg_to_var_flt(iptr->dst, d);
1589 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1591 var_to_reg_int(s1, src, REG_ITMP1);
1592 d = reg_of_var(iptr->dst, REG_FTMP3);
1595 store_reg_to_var_flt(iptr->dst, d);
1598 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1600 var_to_reg_int(s1, src, REG_ITMP1);
1601 d = reg_of_var(iptr->dst, REG_FTMP3);
1604 store_reg_to_var_flt(iptr->dst, d);
1607 case ICMD_F2I: /* ..., (float) value ==> ..., (int) value */
1609 var_to_reg_flt(s1, src, REG_FTMP1);
1610 d = reg_of_var(iptr->dst, REG_ITMP3);
1611 M_CVTFI(s1, REG_FTMP1);
1612 M_MOVDI(REG_FTMP1, d);
1613 store_reg_to_var_int(iptr->dst, d);
1616 case ICMD_D2I: /* ..., (double) value ==> ..., (int) value */
1618 var_to_reg_flt(s1, src, REG_FTMP1);
1619 d = reg_of_var(iptr->dst, REG_ITMP3);
1620 M_CVTDI(s1, REG_FTMP1);
1621 M_MOVDI(REG_FTMP1, d);
1622 store_reg_to_var_int(iptr->dst, d);
1625 case ICMD_F2L: /* ..., (float) value ==> ..., (long) value */
1627 var_to_reg_flt(s1, src, REG_FTMP1);
1628 d = reg_of_var(iptr->dst, REG_ITMP3);
1629 M_CVTFL(s1, REG_FTMP1);
1630 M_MOVDL(REG_FTMP1, d);
1631 store_reg_to_var_int(iptr->dst, d);
1634 case ICMD_D2L: /* ..., (double) value ==> ..., (long) value */
1636 var_to_reg_flt(s1, src, REG_FTMP1);
1637 d = reg_of_var(iptr->dst, REG_ITMP3);
1638 M_CVTDL(s1, REG_FTMP1);
1639 M_MOVDL(REG_FTMP1, d);
1640 store_reg_to_var_int(iptr->dst, d);
1643 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1645 var_to_reg_flt(s1, src, REG_FTMP1);
1646 d = reg_of_var(iptr->dst, REG_FTMP3);
1648 store_reg_to_var_flt(iptr->dst, d);
1651 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1653 var_to_reg_flt(s1, src, REG_FTMP1);
1654 d = reg_of_var(iptr->dst, REG_FTMP3);
1656 store_reg_to_var_flt(iptr->dst, d);
1659 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl 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_ITMP3);
1665 M_NOP; /* compare delay */
1666 M_FBF(2); /* jump over next instructions */
1667 M_LSUB_IMM(REG_ZERO, 1, d); /* delay slot */
1670 M_NOP; /* compare delay */
1671 M_FBF(2); /* jump over next instruction */
1673 M_LADD_IMM(REG_ZERO, 1, d);
1674 store_reg_to_var_int(iptr->dst, d);
1677 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1679 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1680 var_to_reg_flt(s2, src, REG_FTMP2);
1681 d = reg_of_var(iptr->dst, REG_ITMP3);
1683 M_NOP; /* compare delay */
1684 M_FBF(2); /* jump over next instructions */
1685 M_LSUB_IMM(REG_ZERO, 1, d); /* delay slot */
1688 M_NOP; /* compare delay */
1689 M_FBF(2); /* jump over next instruction */
1691 M_LADD_IMM(REG_ZERO, 1, d);
1692 store_reg_to_var_int(iptr->dst, d);
1695 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1697 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1698 var_to_reg_flt(s2, src, REG_FTMP2);
1699 d = reg_of_var(iptr->dst, REG_ITMP3);
1701 M_NOP; /* compare delay */
1702 M_FBF(2); /* jump over next instruction */
1703 M_LADD_IMM(REG_ZERO, 1, d); /* delay slot */
1706 M_NOP; /* compare delay */
1707 M_FBF(2); /* jump over next instruction */
1709 M_LSUB_IMM(REG_ZERO, 1, d);
1710 store_reg_to_var_int(iptr->dst, d);
1713 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1715 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1716 var_to_reg_flt(s2, src, REG_FTMP2);
1717 d = reg_of_var(iptr->dst, REG_ITMP3);
1719 M_NOP; /* compare delay */
1720 M_FBF(2); /* jump over next instruction */
1721 M_LADD_IMM(REG_ZERO, 1, d); /* delay slot */
1724 M_NOP; /* compare delay */
1725 M_FBF(2); /* jump over next instruction */
1727 M_LSUB_IMM(REG_ZERO, 1, d);
1728 store_reg_to_var_int(iptr->dst, d);
1732 /* memory operations **************************************************/
1734 #define gen_bound_check \
1736 M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\
1737 M_CMPULT(s2, REG_ITMP3, REG_ITMP3);\
1738 M_BEQZ(REG_ITMP3, 0);\
1739 mcode_addxboundrefs(mcodeptr);\
1743 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1745 var_to_reg_int(s1, src, REG_ITMP1);
1746 d = reg_of_var(iptr->dst, REG_ITMP3);
1747 gen_nullptr_check(s1);
1748 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1749 store_reg_to_var_int(iptr->dst, d);
1752 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1754 var_to_reg_int(s1, src->prev, REG_ITMP1);
1755 var_to_reg_int(s2, src, REG_ITMP2);
1756 d = reg_of_var(iptr->dst, REG_ITMP3);
1757 if (iptr->op1 == 0) {
1758 gen_nullptr_check(s1);
1761 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1762 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1763 M_ALD(d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1764 store_reg_to_var_int(iptr->dst, d);
1767 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1769 var_to_reg_int(s1, src->prev, REG_ITMP1);
1770 var_to_reg_int(s2, src, REG_ITMP2);
1771 d = reg_of_var(iptr->dst, REG_ITMP3);
1772 if (iptr->op1 == 0) {
1773 gen_nullptr_check(s1);
1776 M_ASLL_IMM(s2, 2, REG_ITMP2);
1777 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1778 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1779 store_reg_to_var_int(iptr->dst, d);
1782 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1784 var_to_reg_int(s1, src->prev, REG_ITMP1);
1785 var_to_reg_int(s2, src, REG_ITMP2);
1786 d = reg_of_var(iptr->dst, REG_ITMP3);
1787 if (iptr->op1 == 0) {
1788 gen_nullptr_check(s1);
1791 M_ASLL_IMM(s2, 3, REG_ITMP2);
1792 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1793 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1794 store_reg_to_var_int(iptr->dst, d);
1797 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1799 var_to_reg_int(s1, src->prev, REG_ITMP1);
1800 var_to_reg_int(s2, src, REG_ITMP2);
1801 d = reg_of_var(iptr->dst, REG_FTMP3);
1802 if (iptr->op1 == 0) {
1803 gen_nullptr_check(s1);
1806 M_ASLL_IMM(s2, 2, REG_ITMP2);
1807 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1808 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1809 store_reg_to_var_flt(iptr->dst, d);
1812 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1814 var_to_reg_int(s1, src->prev, REG_ITMP1);
1815 var_to_reg_int(s2, src, REG_ITMP2);
1816 d = reg_of_var(iptr->dst, REG_FTMP3);
1817 if (iptr->op1 == 0) {
1818 gen_nullptr_check(s1);
1821 M_ASLL_IMM(s2, 3, REG_ITMP2);
1822 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1823 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1824 store_reg_to_var_flt(iptr->dst, d);
1827 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1829 var_to_reg_int(s1, src->prev, REG_ITMP1);
1830 var_to_reg_int(s2, src, REG_ITMP2);
1831 d = reg_of_var(iptr->dst, REG_ITMP3);
1832 if (iptr->op1 == 0) {
1833 gen_nullptr_check(s1);
1836 M_AADD(s2, s1, REG_ITMP1);
1837 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1838 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1839 store_reg_to_var_int(iptr->dst, d);
1842 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1844 var_to_reg_int(s1, src->prev, REG_ITMP1);
1845 var_to_reg_int(s2, src, REG_ITMP2);
1846 d = reg_of_var(iptr->dst, REG_ITMP3);
1847 if (iptr->op1 == 0) {
1848 gen_nullptr_check(s1);
1851 M_AADD(s2, s1, REG_ITMP1);
1852 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1853 M_SLDS(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1854 store_reg_to_var_int(iptr->dst, d);
1857 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1859 var_to_reg_int(s1, src->prev, REG_ITMP1);
1860 var_to_reg_int(s2, src, REG_ITMP2);
1861 d = reg_of_var(iptr->dst, REG_ITMP3);
1862 if (iptr->op1 == 0) {
1863 gen_nullptr_check(s1);
1866 M_AADD(s2, s1, REG_ITMP1);
1867 M_BLDS(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1868 store_reg_to_var_int(iptr->dst, d);
1872 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1874 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1875 var_to_reg_int(s2, src->prev, REG_ITMP2);
1876 if (iptr->op1 == 0) {
1877 gen_nullptr_check(s1);
1880 var_to_reg_int(s3, src, REG_ITMP3);
1881 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1882 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1883 M_AST(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1886 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1888 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1889 var_to_reg_int(s2, src->prev, REG_ITMP2);
1890 if (iptr->op1 == 0) {
1891 gen_nullptr_check(s1);
1894 var_to_reg_int(s3, src, REG_ITMP3);
1895 M_ASLL_IMM(s2, 2, REG_ITMP2);
1896 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1897 M_IST(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1900 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1902 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1903 var_to_reg_int(s2, src->prev, REG_ITMP2);
1904 if (iptr->op1 == 0) {
1905 gen_nullptr_check(s1);
1908 var_to_reg_int(s3, src, REG_ITMP3);
1909 M_ASLL_IMM(s2, 3, REG_ITMP2);
1910 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1911 M_LST(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1914 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1916 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1917 var_to_reg_int(s2, src->prev, REG_ITMP2);
1918 if (iptr->op1 == 0) {
1919 gen_nullptr_check(s1);
1922 var_to_reg_flt(s3, src, REG_FTMP3);
1923 M_ASLL_IMM(s2, 2, REG_ITMP2);
1924 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1925 M_FST(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1928 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1930 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1931 var_to_reg_int(s2, src->prev, REG_ITMP2);
1932 if (iptr->op1 == 0) {
1933 gen_nullptr_check(s1);
1936 var_to_reg_flt(s3, src, REG_FTMP3);
1937 M_ASLL_IMM(s2, 3, REG_ITMP2);
1938 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1939 M_DST(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1942 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1943 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1945 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1946 var_to_reg_int(s2, src->prev, REG_ITMP2);
1947 if (iptr->op1 == 0) {
1948 gen_nullptr_check(s1);
1951 var_to_reg_int(s3, src, REG_ITMP3);
1952 M_AADD(s2, s1, REG_ITMP1);
1953 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1954 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1957 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1959 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1960 var_to_reg_int(s2, src->prev, REG_ITMP2);
1961 if (iptr->op1 == 0) {
1962 gen_nullptr_check(s1);
1965 var_to_reg_int(s3, src, REG_ITMP3);
1966 M_AADD(s2, s1, REG_ITMP1);
1967 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1971 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1972 /* op1 = type, val.a = field address */
1974 a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value));
1975 M_ALD(REG_ITMP1, REG_PV, a);
1976 switch (iptr->op1) {
1978 var_to_reg_int(s2, src, REG_ITMP2);
1979 M_IST(s2, REG_ITMP1, 0);
1982 var_to_reg_int(s2, src, REG_ITMP2);
1983 M_LST(s2, REG_ITMP1, 0);
1986 var_to_reg_int(s2, src, REG_ITMP2);
1987 M_AST(s2, REG_ITMP1, 0);
1990 var_to_reg_flt(s2, src, REG_FTMP2);
1991 M_FST(s2, REG_ITMP1, 0);
1994 var_to_reg_flt(s2, src, REG_FTMP2);
1995 M_DST(s2, REG_ITMP1, 0);
1997 default: panic ("internal error");
2001 case ICMD_GETSTATIC: /* ... ==> ..., value */
2002 /* op1 = type, val.a = field address */
2004 a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value));
2005 M_ALD(REG_ITMP1, REG_PV, a);
2006 switch (iptr->op1) {
2008 d = reg_of_var(iptr->dst, REG_ITMP3);
2009 M_ILD(d, REG_ITMP1, 0);
2010 store_reg_to_var_int(iptr->dst, d);
2013 d = reg_of_var(iptr->dst, REG_ITMP3);
2014 M_LLD(d, REG_ITMP1, 0);
2015 store_reg_to_var_int(iptr->dst, d);
2018 d = reg_of_var(iptr->dst, REG_ITMP3);
2019 M_ALD(d, REG_ITMP1, 0);
2020 store_reg_to_var_int(iptr->dst, d);
2023 d = reg_of_var(iptr->dst, REG_FTMP1);
2024 M_FLD(d, REG_ITMP1, 0);
2025 store_reg_to_var_flt(iptr->dst, d);
2028 d = reg_of_var(iptr->dst, REG_FTMP1);
2029 M_DLD(d, REG_ITMP1, 0);
2030 store_reg_to_var_flt(iptr->dst, d);
2032 default: panic ("internal error");
2037 case ICMD_PUTFIELD: /* ..., value ==> ... */
2038 /* op1 = type, val.i = field offset */
2040 a = ((fieldinfo *)(iptr->val.a))->offset;
2041 switch (iptr->op1) {
2043 var_to_reg_int(s1, src->prev, REG_ITMP1);
2044 var_to_reg_int(s2, src, REG_ITMP2);
2045 gen_nullptr_check(s1);
2049 var_to_reg_int(s1, src->prev, REG_ITMP1);
2050 var_to_reg_int(s2, src, REG_ITMP2);
2051 gen_nullptr_check(s1);
2055 var_to_reg_int(s1, src->prev, REG_ITMP1);
2056 var_to_reg_int(s2, src, REG_ITMP2);
2057 gen_nullptr_check(s1);
2061 var_to_reg_int(s1, src->prev, REG_ITMP1);
2062 var_to_reg_flt(s2, src, REG_FTMP2);
2063 gen_nullptr_check(s1);
2067 var_to_reg_int(s1, src->prev, REG_ITMP1);
2068 var_to_reg_flt(s2, src, REG_FTMP2);
2069 gen_nullptr_check(s1);
2072 default: panic ("internal error");
2076 case ICMD_GETFIELD: /* ... ==> ..., value */
2077 /* op1 = type, val.i = field offset */
2079 a = ((fieldinfo *)(iptr->val.a))->offset;
2080 switch (iptr->op1) {
2082 var_to_reg_int(s1, src, REG_ITMP1);
2083 d = reg_of_var(iptr->dst, REG_ITMP3);
2084 gen_nullptr_check(s1);
2086 store_reg_to_var_int(iptr->dst, d);
2089 var_to_reg_int(s1, src, REG_ITMP1);
2090 d = reg_of_var(iptr->dst, REG_ITMP3);
2091 gen_nullptr_check(s1);
2093 store_reg_to_var_int(iptr->dst, d);
2096 var_to_reg_int(s1, src, REG_ITMP1);
2097 d = reg_of_var(iptr->dst, REG_ITMP3);
2098 gen_nullptr_check(s1);
2100 store_reg_to_var_int(iptr->dst, d);
2103 var_to_reg_int(s1, src, REG_ITMP1);
2104 d = reg_of_var(iptr->dst, REG_FTMP1);
2105 gen_nullptr_check(s1);
2107 store_reg_to_var_flt(iptr->dst, d);
2110 var_to_reg_int(s1, src, REG_ITMP1);
2111 d = reg_of_var(iptr->dst, REG_FTMP1);
2112 gen_nullptr_check(s1);
2114 store_reg_to_var_flt(iptr->dst, d);
2116 default: panic ("internal error");
2121 /* branch operations **************************************************/
2123 #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}}
2125 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2127 var_to_reg_int(s1, src, REG_ITMP1);
2128 M_INTMOVE(s1, REG_ITMP1_XPTR);
2129 a = dseg_addaddress(asm_handle_exception);
2130 M_ALD(REG_ITMP2, REG_PV, a);
2131 M_JSR(REG_ITMP2_XPC, REG_ITMP2);
2136 case ICMD_GOTO: /* ... ==> ... */
2137 /* op1 = target JavaVM pc */
2139 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2144 case ICMD_JSR: /* ... ==> ... */
2145 /* op1 = target JavaVM pc */
2147 dseg_addtarget(BlockPtrOfPC(iptr->op1));
2148 M_ALD(REG_ITMP1, REG_PV, -dseglen);
2149 M_JSR(REG_ITMP1, REG_ITMP1); /* REG_ITMP1 = return address */
2153 case ICMD_RET: /* ... ==> ... */
2154 /* op1 = local variable */
2156 var = &(locals[iptr->op1][TYPE_ADR]);
2157 if (var->flags & INMEMORY) {
2158 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2167 case ICMD_IFNULL: /* ..., value ==> ... */
2168 /* op1 = target JavaVM pc */
2170 var_to_reg_int(s1, src, REG_ITMP1);
2172 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2176 case ICMD_IFNONNULL: /* ..., value ==> ... */
2177 /* op1 = target JavaVM pc */
2179 var_to_reg_int(s1, src, REG_ITMP1);
2181 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2185 case ICMD_IFEQ: /* ..., value ==> ... */
2186 /* op1 = target JavaVM pc, val.i = constant */
2188 var_to_reg_int(s1, src, REG_ITMP1);
2189 if (iptr->val.i == 0) {
2193 ICONST(REG_ITMP2, iptr->val.i);
2194 M_BEQ(s1, REG_ITMP2, 0);
2196 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2200 case ICMD_IFLT: /* ..., value ==> ... */
2201 /* op1 = target JavaVM pc, val.i = constant */
2203 var_to_reg_int(s1, src, REG_ITMP1);
2204 if (iptr->val.i == 0) {
2208 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
2209 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2212 ICONST(REG_ITMP2, iptr->val.i);
2213 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2215 M_BNEZ(REG_ITMP1, 0);
2217 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2221 case ICMD_IFLE: /* ..., value ==> ... */
2222 /* op1 = target JavaVM pc, val.i = constant */
2224 var_to_reg_int(s1, src, REG_ITMP1);
2225 if (iptr->val.i == 0) {
2229 if ((iptr->val.i >= -32769) && (iptr->val.i <= 32766)) {
2230 M_CMPLT_IMM(s1, iptr->val.i + 1, REG_ITMP1);
2231 M_BNEZ(REG_ITMP1, 0);
2234 ICONST(REG_ITMP2, iptr->val.i);
2235 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2236 M_BEQZ(REG_ITMP1, 0);
2239 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2243 case ICMD_IFNE: /* ..., value ==> ... */
2244 /* op1 = target JavaVM pc, val.i = constant */
2246 var_to_reg_int(s1, src, REG_ITMP1);
2247 if (iptr->val.i == 0) {
2251 ICONST(REG_ITMP2, iptr->val.i);
2252 M_BNE(s1, REG_ITMP2, 0);
2254 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2258 case ICMD_IFGT: /* ..., value ==> ... */
2259 /* op1 = target JavaVM pc, val.i = constant */
2261 var_to_reg_int(s1, src, REG_ITMP1);
2262 if (iptr->val.i == 0) {
2266 if ((iptr->val.i >= -32769) && (iptr->val.i <= 32766)) {
2267 M_CMPLT_IMM(s1, iptr->val.i + 1, REG_ITMP1);
2268 M_BEQZ(REG_ITMP1, 0);
2271 ICONST(REG_ITMP2, iptr->val.i);
2272 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2273 M_BNEZ(REG_ITMP1, 0);
2276 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2280 case ICMD_IFGE: /* ..., value ==> ... */
2281 /* op1 = target JavaVM pc, val.i = constant */
2283 var_to_reg_int(s1, src, REG_ITMP1);
2284 if (iptr->val.i == 0) {
2288 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
2289 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2292 ICONST(REG_ITMP2, iptr->val.i);
2293 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2295 M_BEQZ(REG_ITMP1, 0);
2297 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2301 case ICMD_IF_LEQ: /* ..., value ==> ... */
2302 /* op1 = target JavaVM pc, val.l = constant */
2304 var_to_reg_int(s1, src, REG_ITMP1);
2305 if (iptr->val.l == 0) {
2309 LCONST(REG_ITMP2, iptr->val.l);
2310 M_BEQ(s1, REG_ITMP2, 0);
2312 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2316 case ICMD_IF_LLT: /* ..., value ==> ... */
2317 /* op1 = target JavaVM pc, val.l = constant */
2319 var_to_reg_int(s1, src, REG_ITMP1);
2320 if (iptr->val.l == 0) {
2324 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2325 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2328 LCONST(REG_ITMP2, iptr->val.l);
2329 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2331 M_BNEZ(REG_ITMP1, 0);
2333 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2337 case ICMD_IF_LLE: /* ..., value ==> ... */
2338 /* op1 = target JavaVM pc, val.l = constant */
2340 var_to_reg_int(s1, src, REG_ITMP1);
2341 if (iptr->val.l == 0) {
2345 if ((iptr->val.l >= -32769) && (iptr->val.l <= 32766)) {
2346 M_CMPLT_IMM(s1, iptr->val.l + 1, REG_ITMP1);
2347 M_BNEZ(REG_ITMP1, 0);
2350 LCONST(REG_ITMP2, iptr->val.l);
2351 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2352 M_BEQZ(REG_ITMP1, 0);
2355 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2359 case ICMD_IF_LNE: /* ..., value ==> ... */
2360 /* op1 = target JavaVM pc, val.l = constant */
2362 var_to_reg_int(s1, src, REG_ITMP1);
2363 if (iptr->val.l == 0) {
2367 LCONST(REG_ITMP2, iptr->val.l);
2368 M_BNE(s1, REG_ITMP2, 0);
2370 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2374 case ICMD_IF_LGT: /* ..., value ==> ... */
2375 /* op1 = target JavaVM pc, val.l = constant */
2377 var_to_reg_int(s1, src, REG_ITMP1);
2378 if (iptr->val.l == 0) {
2382 if ((iptr->val.l >= -32769) && (iptr->val.l <= 32766)) {
2383 M_CMPLT_IMM(s1, iptr->val.l + 1, REG_ITMP1);
2384 M_BEQZ(REG_ITMP1, 0);
2387 LCONST(REG_ITMP2, iptr->val.l);
2388 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2389 M_BNEZ(REG_ITMP1, 0);
2392 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2396 case ICMD_IF_LGE: /* ..., value ==> ... */
2397 /* op1 = target JavaVM pc, val.l = constant */
2399 var_to_reg_int(s1, src, REG_ITMP1);
2400 if (iptr->val.l == 0) {
2404 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2405 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2408 LCONST(REG_ITMP2, iptr->val.l);
2409 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2411 M_BEQZ(REG_ITMP1, 0);
2413 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2417 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2418 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2419 case ICMD_IF_ACMPEQ:
2421 var_to_reg_int(s1, src->prev, REG_ITMP1);
2422 var_to_reg_int(s2, src, REG_ITMP2);
2424 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2428 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2429 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2430 case ICMD_IF_ACMPNE:
2432 var_to_reg_int(s1, src->prev, REG_ITMP1);
2433 var_to_reg_int(s2, src, REG_ITMP2);
2435 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2439 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2440 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2442 var_to_reg_int(s1, src->prev, REG_ITMP1);
2443 var_to_reg_int(s2, src, REG_ITMP2);
2444 M_CMPLT(s1, s2, REG_ITMP1);
2445 M_BNEZ(REG_ITMP1, 0);
2446 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2450 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2451 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2453 var_to_reg_int(s1, src->prev, REG_ITMP1);
2454 var_to_reg_int(s2, src, REG_ITMP2);
2455 M_CMPGT(s1, s2, REG_ITMP1);
2456 M_BNEZ(REG_ITMP1, 0);
2457 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2461 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2462 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2464 var_to_reg_int(s1, src->prev, REG_ITMP1);
2465 var_to_reg_int(s2, src, REG_ITMP2);
2466 M_CMPGT(s1, s2, REG_ITMP1);
2467 M_BEQZ(REG_ITMP1, 0);
2468 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2472 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2473 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2475 var_to_reg_int(s1, src->prev, REG_ITMP1);
2476 var_to_reg_int(s2, src, REG_ITMP2);
2477 M_CMPLT(s1, s2, REG_ITMP1);
2478 M_BEQZ(REG_ITMP1, 0);
2479 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2483 #ifdef CONDITIONAL_LOADCONST
2484 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2486 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2489 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2490 /* val.i = constant */
2492 var_to_reg_int(s1, src, REG_ITMP1);
2493 d = reg_of_var(iptr->dst, REG_ITMP3);
2495 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2496 if ((a == 1) && (iptr[1].val.i == 0)) {
2497 M_CMPEQ(s1, REG_ZERO, d);
2498 store_reg_to_var_int(iptr->dst, d);
2501 if ((a == 0) && (iptr[1].val.i == 1)) {
2502 M_CMPEQ(s1, REG_ZERO, d);
2504 store_reg_to_var_int(iptr->dst, d);
2508 M_MOV(s1, REG_ITMP1);
2511 ICONST(d, iptr[1].val.i);
2513 if ((a >= 0) && (a <= 255)) {
2514 M_CMOVEQ_IMM(s1, a, d);
2517 ICONST(REG_ITMP2, a);
2518 M_CMOVEQ(s1, REG_ITMP2, d);
2520 store_reg_to_var_int(iptr->dst, d);
2523 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2524 /* val.i = constant */
2526 var_to_reg_int(s1, src, REG_ITMP1);
2527 d = reg_of_var(iptr->dst, REG_ITMP3);
2529 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2530 if ((a == 0) && (iptr[1].val.i == 1)) {
2531 M_CMPEQ(s1, REG_ZERO, d);
2532 store_reg_to_var_int(iptr->dst, d);
2535 if ((a == 1) && (iptr[1].val.i == 0)) {
2536 M_CMPEQ(s1, REG_ZERO, d);
2538 store_reg_to_var_int(iptr->dst, d);
2542 M_MOV(s1, REG_ITMP1);
2545 ICONST(d, iptr[1].val.i);
2547 if ((a >= 0) && (a <= 255)) {
2548 M_CMOVNE_IMM(s1, a, d);
2551 ICONST(REG_ITMP2, a);
2552 M_CMOVNE(s1, REG_ITMP2, d);
2554 store_reg_to_var_int(iptr->dst, d);
2557 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2558 /* val.i = constant */
2560 var_to_reg_int(s1, src, REG_ITMP1);
2561 d = reg_of_var(iptr->dst, REG_ITMP3);
2563 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2564 if ((a == 1) && (iptr[1].val.i == 0)) {
2565 M_CMPLT(s1, REG_ZERO, d);
2566 store_reg_to_var_int(iptr->dst, d);
2569 if ((a == 0) && (iptr[1].val.i == 1)) {
2570 M_CMPLE(REG_ZERO, s1, d);
2571 store_reg_to_var_int(iptr->dst, d);
2575 M_MOV(s1, REG_ITMP1);
2578 ICONST(d, iptr[1].val.i);
2580 if ((a >= 0) && (a <= 255)) {
2581 M_CMOVLT_IMM(s1, a, d);
2584 ICONST(REG_ITMP2, a);
2585 M_CMOVLT(s1, REG_ITMP2, d);
2587 store_reg_to_var_int(iptr->dst, d);
2590 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2591 /* val.i = constant */
2593 var_to_reg_int(s1, src, REG_ITMP1);
2594 d = reg_of_var(iptr->dst, REG_ITMP3);
2596 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2597 if ((a == 1) && (iptr[1].val.i == 0)) {
2598 M_CMPLE(REG_ZERO, s1, d);
2599 store_reg_to_var_int(iptr->dst, d);
2602 if ((a == 0) && (iptr[1].val.i == 1)) {
2603 M_CMPLT(s1, REG_ZERO, d);
2604 store_reg_to_var_int(iptr->dst, d);
2608 M_MOV(s1, REG_ITMP1);
2611 ICONST(d, iptr[1].val.i);
2613 if ((a >= 0) && (a <= 255)) {
2614 M_CMOVGE_IMM(s1, a, d);
2617 ICONST(REG_ITMP2, a);
2618 M_CMOVGE(s1, REG_ITMP2, d);
2620 store_reg_to_var_int(iptr->dst, d);
2623 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2624 /* val.i = constant */
2626 var_to_reg_int(s1, src, REG_ITMP1);
2627 d = reg_of_var(iptr->dst, REG_ITMP3);
2629 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2630 if ((a == 1) && (iptr[1].val.i == 0)) {
2631 M_CMPLT(REG_ZERO, s1, d);
2632 store_reg_to_var_int(iptr->dst, d);
2635 if ((a == 0) && (iptr[1].val.i == 1)) {
2636 M_CMPLE(s1, REG_ZERO, d);
2637 store_reg_to_var_int(iptr->dst, d);
2641 M_MOV(s1, REG_ITMP1);
2644 ICONST(d, iptr[1].val.i);
2646 if ((a >= 0) && (a <= 255)) {
2647 M_CMOVGT_IMM(s1, a, d);
2650 ICONST(REG_ITMP2, a);
2651 M_CMOVGT(s1, REG_ITMP2, d);
2653 store_reg_to_var_int(iptr->dst, d);
2656 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2657 /* val.i = constant */
2659 var_to_reg_int(s1, src, REG_ITMP1);
2660 d = reg_of_var(iptr->dst, REG_ITMP3);
2662 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2663 if ((a == 1) && (iptr[1].val.i == 0)) {
2664 M_CMPLE(s1, REG_ZERO, d);
2665 store_reg_to_var_int(iptr->dst, d);
2668 if ((a == 0) && (iptr[1].val.i == 1)) {
2669 M_CMPLT(REG_ZERO, s1, d);
2670 store_reg_to_var_int(iptr->dst, d);
2674 M_MOV(s1, REG_ITMP1);
2677 ICONST(d, iptr[1].val.i);
2679 if ((a >= 0) && (a <= 255)) {
2680 M_CMOVLE_IMM(s1, a, d);
2683 ICONST(REG_ITMP2, a);
2684 M_CMOVLE(s1, REG_ITMP2, d);
2686 store_reg_to_var_int(iptr->dst, d);
2691 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2696 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2697 a = dseg_addaddress ((void*) (builtin_monitorexit));
2698 M_ALD(REG_ITMP3, REG_PV, a);
2699 M_JSR(REG_RA, REG_ITMP3);
2700 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse); /* delay slot */
2703 var_to_reg_int(s1, src, REG_RESULT);
2704 M_INTMOVE(s1, REG_RESULT);
2705 goto nowperformreturn;
2707 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2711 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2712 a = dseg_addaddress ((void*) (builtin_monitorexit));
2713 M_ALD(REG_ITMP3, REG_PV, a);
2714 M_JSR(REG_RA, REG_ITMP3);
2715 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse); /* delay slot */
2718 var_to_reg_flt(s1, src, REG_FRESULT);
2719 M_FLTMOVE(s1, REG_FRESULT);
2720 goto nowperformreturn;
2722 case ICMD_RETURN: /* ... ==> ... */
2725 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2726 a = dseg_addaddress ((void*) (builtin_monitorexit));
2727 M_ALD(REG_ITMP3, REG_PV, a);
2728 M_JSR(REG_RA, REG_ITMP3);
2729 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse); /* delay slot */
2737 p = parentargs_base;
2739 /* restore return address */
2742 {p--; M_LLD (REG_RA, REG_SP, 8 * p);}
2744 /* restore saved registers */
2746 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
2747 {p--; M_LLD(savintregs[r], REG_SP, 8 * p);}
2748 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
2749 {p--; M_DLD(savfltregs[r], REG_SP, 8 * p);}
2751 /* call trace function */
2754 M_LDA (REG_SP, REG_SP, -24);
2755 M_LST(REG_RA, REG_SP, 0);
2756 M_LST(REG_RESULT, REG_SP, 8);
2757 M_DST(REG_FRESULT, REG_SP,16);
2758 a = dseg_addaddress (method);
2759 M_ALD(argintregs[0], REG_PV, a);
2760 M_MOV(REG_RESULT, argintregs[1]);
2761 a = dseg_addaddress ((void*) (builtin_displaymethodstop));
2762 M_ALD(REG_ITMP3, REG_PV, a);
2763 M_JSR (REG_RA, REG_ITMP3);
2764 M_FLTMOVE(REG_FRESULT, argfltregs[2]); /* delay slot */
2766 M_LLD(REG_RA, REG_SP, 0);
2767 M_LLD(REG_RESULT, REG_SP, 8);
2768 M_DLD(REG_FRESULT, REG_SP,16);
2769 M_LDA (REG_SP, REG_SP, 24);
2774 /* deallocate stack */
2776 if (parentargs_base)
2777 {M_LDA(REG_SP, REG_SP, parentargs_base*8);}
2785 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2789 s4ptr = iptr->val.a;
2790 l = s4ptr[1]; /* low */
2791 i = s4ptr[2]; /* high */
2793 var_to_reg_int(s1, src, REG_ITMP1);
2795 {M_INTMOVE(s1, REG_ITMP1);}
2796 else if (l <= 32768) {
2797 M_IADD_IMM(s1, -l, REG_ITMP1);
2800 ICONST(REG_ITMP2, l);
2801 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2807 M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
2808 M_BEQZ(REG_ITMP2, 0);
2809 mcode_addreference(BlockPtrOfPC(s4ptr[0]), mcodeptr);
2810 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1); /* delay slot*/
2812 /* build jump table top down and use address of lowest entry */
2816 dseg_addtarget(BlockPtrOfPC(*--s4ptr));
2820 /* length of dataseg after last dseg_addtarget is used by load */
2822 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2823 M_ALD(REG_ITMP2, REG_ITMP2, -dseglen);
2830 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2832 s4 i, l, val, *s4ptr;
2834 s4ptr = iptr->val.a;
2835 l = s4ptr[0]; /* default */
2836 i = s4ptr[1]; /* count */
2838 MCODECHECK((i<<2)+8);
2839 var_to_reg_int(s1, src, REG_ITMP1);
2843 ICONST(REG_ITMP2, val);
2845 M_BEQ(s1, REG_ITMP2, 0);
2846 mcode_addreference(BlockPtrOfPC(s4ptr[1]), mcodeptr);
2849 ICONST(REG_ITMP2, val);
2851 M_BEQ(s1, REG_ITMP2, 0);
2852 mcode_addreference(BlockPtrOfPC(s4ptr[1]), mcodeptr);
2857 mcode_addreference(BlockPtrOfPC(l), mcodeptr);
2864 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
2865 /* op1 = return type, val.a = function pointer*/
2869 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
2870 /* op1 = return type, val.a = function pointer*/
2874 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
2875 /* op1 = return type, val.a = function pointer*/
2879 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2880 /* op1 = arg count, val.a = method pointer */
2882 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2883 /* op1 = arg count, val.a = method pointer */
2885 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2886 /* op1 = arg count, val.a = method pointer */
2888 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
2889 /* op1 = arg count, val.a = method pointer */
2897 MCODECHECK((s3 << 1) + 64);
2899 /* copy arguments to registers or stack location */
2901 for (; --s3 >= 0; src = src->prev) {
2902 if (src->varkind == ARGVAR)
2904 if (IS_INT_LNG_TYPE(src->type)) {
2905 if (s3 < INT_ARG_CNT) {
2906 s1 = argintregs[s3];
2907 var_to_reg_int(d, src, s1);
2911 var_to_reg_int(d, src, REG_ITMP1);
2912 M_LST(d, REG_SP, 8 * (s3 - INT_ARG_CNT));
2916 if (s3 < FLT_ARG_CNT) {
2917 s1 = argfltregs[s3];
2918 var_to_reg_flt(d, src, s1);
2922 var_to_reg_flt(d, src, REG_FTMP1);
2923 M_DST(d, REG_SP, 8 * (s3 - FLT_ARG_CNT));
2928 switch (iptr->opc) {
2932 a = dseg_addaddress ((void*) (m));
2933 M_ALD(REG_ITMP3, REG_PV, a); /* built-in-function pointer */
2934 M_JSR (REG_RA, REG_ITMP3);
2936 d = iptr->op1; /* return type */
2937 goto afteractualcall;
2939 case ICMD_INVOKESTATIC:
2940 case ICMD_INVOKESPECIAL:
2941 a = dseg_addaddress (m->stubroutine);
2943 M_ALD(REG_PV, REG_PV, a ); /* method pointer in pv */
2946 goto makeactualcall;
2948 case ICMD_INVOKEVIRTUAL:
2950 gen_nullptr_check(argintregs[0]);
2951 M_ALD(REG_METHODPTR, argintregs[0],
2952 OFFSET(java_objectheader, vftbl));
2953 M_ALD(REG_PV, REG_METHODPTR, OFFSET(vftbl, table[0]) +
2954 sizeof(methodptr) * m->vftblindex);
2957 goto makeactualcall;
2959 case ICMD_INVOKEINTERFACE:
2962 gen_nullptr_check(argintregs[0]);
2963 M_ALD(REG_METHODPTR, argintregs[0],
2964 OFFSET(java_objectheader, vftbl));
2965 M_ALD(REG_METHODPTR, REG_METHODPTR,
2966 OFFSET(vftbl, interfacetable[0]) -
2967 sizeof(methodptr*) * ci->index);
2968 M_ALD(REG_PV, REG_METHODPTR,
2969 sizeof(methodptr) * (m - ci->methods));
2972 goto makeactualcall;
2976 sprintf (logtext, "Unkown ICMD-Command: %d", iptr->opc);
2982 M_JSR (REG_RA, REG_PV);
2989 s1 = (int)((u1*) mcodeptr - mcodebase);
2990 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
2992 panic("method to big");
2995 /* d contains return type */
2997 if (d != TYPE_VOID) {
2998 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
2999 s1 = reg_of_var(iptr->dst, REG_RESULT);
3000 M_INTMOVE(REG_RESULT, s1);
3001 store_reg_to_var_int(iptr->dst, s1);
3004 s1 = reg_of_var(iptr->dst, REG_FRESULT);
3005 M_FLTMOVE(REG_FRESULT, s1);
3006 store_reg_to_var_flt(iptr->dst, s1);
3013 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3015 /* op1: 0 == array, 1 == class */
3016 /* val.a: (classinfo*) superclass */
3018 /* superclass is an interface:
3020 * return (sub != NULL) &&
3021 * (sub->vftbl->interfacetablelength > super->index) &&
3022 * (sub->vftbl->interfacetable[-super->index] != NULL);
3024 * superclass is a class:
3026 * return ((sub != NULL) && (0
3027 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3028 * super->vftbl->diffvall));
3032 classinfo *super = (classinfo*) iptr->val.a;
3034 var_to_reg_int(s1, src, REG_ITMP1);
3035 d = reg_of_var(iptr->dst, REG_ITMP3);
3037 M_MOV(s1, REG_ITMP1);
3041 if (iptr->op1) { /* class/interface */
3042 if (super->flags & ACC_INTERFACE) { /* interface */
3045 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3046 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3047 M_IADD_IMM(REG_ITMP2, - super->index, REG_ITMP2);
3048 M_BLEZ(REG_ITMP2, 3);
3050 M_ALD(REG_ITMP1, REG_ITMP1,
3051 OFFSET(vftbl, interfacetable[0]) -
3052 super->index * sizeof(methodptr*));
3053 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3056 s2 = super->vftbl->diffval;
3059 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3060 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3061 M_IADD_IMM(REG_ITMP1, - super->vftbl->baseval, REG_ITMP1);
3062 M_CMPULT_IMM(REG_ITMP1, s2 + 1, d);
3066 panic ("internal error: no inlined array instanceof");
3068 store_reg_to_var_int(iptr->dst, d);
3071 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3073 /* op1: 0 == array, 1 == class */
3074 /* val.a: (classinfo*) superclass */
3076 /* superclass is an interface:
3078 * OK if ((sub == NULL) ||
3079 * (sub->vftbl->interfacetablelength > super->index) &&
3080 * (sub->vftbl->interfacetable[-super->index] != NULL));
3082 * superclass is a class:
3084 * OK if ((sub == NULL) || (0
3085 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3086 * super->vftbl->diffvall));
3090 classinfo *super = (classinfo*) iptr->val.a;
3092 d = reg_of_var(iptr->dst, REG_ITMP3);
3093 var_to_reg_int(s1, src, d);
3094 if (iptr->op1) { /* class/interface */
3095 if (super->flags & ACC_INTERFACE) { /* interface */
3098 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3099 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3100 M_IADD_IMM(REG_ITMP2, - super->index, REG_ITMP2);
3101 M_BLEZ(REG_ITMP2, 0);
3102 mcode_addxcastrefs(mcodeptr);
3104 M_ALD(REG_ITMP2, REG_ITMP1,
3105 OFFSET(vftbl, interfacetable[0]) -
3106 super->index * sizeof(methodptr*));
3107 M_BEQZ(REG_ITMP2, 0);
3108 mcode_addxcastrefs(mcodeptr);
3112 s2 = super->vftbl->diffval;
3113 M_BEQZ(s1, 6 + (s2 != 0));
3115 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3116 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3117 M_IADD_IMM(REG_ITMP1, - super->vftbl->baseval, REG_ITMP1);
3119 M_BNEZ(REG_ITMP1, 0);
3122 M_CMPULT_IMM(REG_ITMP1, s2 + 1, REG_ITMP2);
3123 M_BEQZ(REG_ITMP2, 0);
3125 mcode_addxcastrefs(mcodeptr);
3130 panic ("internal error: no inlined array checkcast");
3133 store_reg_to_var_int(iptr->dst, d);
3136 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
3138 var_to_reg_int(s1, src, REG_ITMP1);
3140 mcode_addxcheckarefs(mcodeptr);
3144 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3145 /* op1 = dimension, val.a = array descriptor */
3147 /* check for negative sizes and copy sizes to stack if necessary */
3149 MCODECHECK((iptr->op1 << 1) + 64);
3151 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3152 var_to_reg_int(s2, src, REG_ITMP1);
3154 mcode_addxcheckarefs(mcodeptr);
3157 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
3159 if (src->varkind != ARGVAR) {
3160 M_LST(s2, REG_SP, 8 * (s1 + INT_ARG_CNT));
3164 /* a0 = dimension count */
3166 ICONST(argintregs[0], iptr->op1);
3168 /* a1 = arraydescriptor */
3170 a = dseg_addaddress(iptr->val.a);
3171 M_ALD(argintregs[1], REG_PV, a);
3173 /* a2 = pointer to dimensions = stack pointer */
3175 M_INTMOVE(REG_SP, argintregs[2]);
3177 a = dseg_addaddress((void*) (builtin_nmultianewarray));
3178 M_ALD(REG_ITMP3, REG_PV, a);
3179 M_JSR(REG_RA, REG_ITMP3);
3181 s1 = reg_of_var(iptr->dst, REG_RESULT);
3182 M_INTMOVE(REG_RESULT, s1);
3183 store_reg_to_var_int(iptr->dst, s1);
3187 default: sprintf (logtext, "Unknown pseudo command: %d", iptr->opc);
3190 } /* for instruction */
3192 /* copy values to interface registers */
3194 src = bptr->outstack;
3195 len = bptr->outdepth;
3199 if ((src->varkind != STACKVAR)) {
3201 if (IS_FLT_DBL_TYPE(s2)) {
3202 var_to_reg_flt(s1, src, REG_FTMP1);
3203 if (!(interfaces[len][s2].flags & INMEMORY)) {
3204 M_FLTMOVE(s1,interfaces[len][s2].regoff);
3207 M_DST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3211 var_to_reg_int(s1, src, REG_ITMP1);
3212 if (!(interfaces[len][s2].flags & INMEMORY)) {
3213 M_INTMOVE(s1,interfaces[len][s2].regoff);
3216 M_LST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3222 } /* if (bptr -> flags >= BBREACHED) */
3223 } /* for basic block */
3225 bptr -> mpc = (int)((u1*) mcodeptr - mcodebase);
3228 /* generate bound check stubs */
3230 s4 *xcodeptr = NULL;
3232 for (; xboundrefs != NULL; xboundrefs = xboundrefs->next) {
3233 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3234 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
3235 xboundrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3239 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
3240 xboundrefs->branchpos, (u1*) mcodeptr - mcodebase);
3244 M_LDA(REG_ITMP2_XPC, REG_PV, xboundrefs->branchpos - 4);
3246 if (xcodeptr != NULL) {
3247 M_BR((xcodeptr-mcodeptr));
3251 xcodeptr = mcodeptr;
3253 a = dseg_addaddress(asm_handle_exception);
3254 M_ALD(REG_ITMP3, REG_PV, a);
3257 a = dseg_addaddress(proto_java_lang_ArrayIndexOutOfBoundsException);
3258 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3262 /* generate negative array size check stubs */
3266 for (; xcheckarefs != NULL; xcheckarefs = xcheckarefs->next) {
3267 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3268 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3269 xcheckarefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3273 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3274 xcheckarefs->branchpos, (u1*) mcodeptr - mcodebase);
3278 M_LDA(REG_ITMP2_XPC, REG_PV, xcheckarefs->branchpos - 4);
3280 if (xcodeptr != NULL) {
3281 M_BR((xcodeptr-mcodeptr));
3285 xcodeptr = mcodeptr;
3287 a = dseg_addaddress(asm_handle_exception);
3288 M_ALD(REG_ITMP3, REG_PV, a);
3291 a = dseg_addaddress(proto_java_lang_NegativeArraySizeException);
3292 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3296 /* generate cast check stubs */
3300 for (; xcastrefs != NULL; xcastrefs = xcastrefs->next) {
3301 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3302 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3303 xcastrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3307 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3308 xcastrefs->branchpos, (u1*) mcodeptr - mcodebase);
3312 M_LDA(REG_ITMP2_XPC, REG_PV, xcastrefs->branchpos - 4);
3314 if (xcodeptr != NULL) {
3315 M_BR((xcodeptr-mcodeptr));
3319 xcodeptr = mcodeptr;
3321 a = dseg_addaddress(asm_handle_exception);
3322 M_ALD(REG_ITMP3, REG_PV, a);
3325 a = dseg_addaddress(proto_java_lang_ClassCastException);
3326 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3331 #ifdef SOFTNULLPTRCHECK
3333 /* generate null pointer check stubs */
3337 for (; xnullrefs != NULL; xnullrefs = xnullrefs->next) {
3338 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3339 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3340 xnullrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3344 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3345 xnullrefs->branchpos, (u1*) mcodeptr - mcodebase);
3349 M_LDA(REG_ITMP2_XPC, REG_PV, xnullrefs->branchpos - 4);
3351 if (xcodeptr != NULL) {
3352 M_BR((xcodeptr-mcodeptr));
3356 xcodeptr = mcodeptr;
3358 a = dseg_addaddress(asm_handle_exception);
3359 M_ALD(REG_ITMP3, REG_PV, a);
3362 a = dseg_addaddress(proto_java_lang_NullPointerException);
3363 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3370 mcode_finish((int)((u1*) mcodeptr - mcodebase));
3372 (void) cacheflush((void*) method->entrypoint,
3373 (int)((u1*) mcodeptr - mcodebase), ICACHE);
3377 /* redefinition of code generation macros (compiling into array) **************/
3380 These macros are newly defined to allow code generation into an array.
3381 This is necessary, because the original M_.. macros generate code by
3382 calling 'mcode_adds4' that uses an additional data structure to
3385 For a faster (but less flexible) version to generate code, these
3386 macros directly use the (s4* p) - pointer to put the code directly
3387 in a locally defined array.
3388 This makes sense only for the stub-generation-routines below.
3392 #define M_ITYPE(op, rs, rt, imm)\
3393 *(p++) = (((op)<<26)|((rs)<<21)|((rt)<<16)|((imm)&0xffff))
3396 #define M_JTYPE(op, imm)\
3397 *(p++) = (((op)<<26)|((off)&0x3ffffff))
3400 #define M_RTYPE(op, rs, rt, rd, sa, fu)\
3401 *(p++) = (((op)<<26)|((rs)<<21)|((rt)<<16)|((rd)<<11)|((sa)<<6)|(fu))
3404 /* function createcompilerstub *************************************************
3406 creates a stub routine which calls the compiler
3408 *******************************************************************************/
3410 #define COMPSTUBSIZE 4
3412 u1 *createcompilerstub (methodinfo *m)
3414 u8 *s = CNEW (u8, COMPSTUBSIZE); /* memory to hold the stub */
3415 s4 *p = (s4*) s; /* code generation pointer */
3417 /* code for the stub */
3418 M_ALD(REG_PV, REG_PV, 24); /* load pointer to the compiler */
3420 M_JSR(REG_ITMP1, REG_PV); /* jump to the compiler, return address
3421 in itmp1 is used as method pointer */
3424 (void) cacheflush((void*) s, (char*) p - (char*) s, ICACHE);
3426 s[2] = (u8) m; /* literals to be adressed */
3427 s[3] = (u8) asm_call_jit_compiler; /* jump directly via PV from above */
3430 count_cstub_len += COMPSTUBSIZE * 8;
3437 /* function removecompilerstub *************************************************
3439 deletes a compilerstub from memory (simply by freeing it)
3441 *******************************************************************************/
3443 void removecompilerstub (u1 *stub)
3445 CFREE (stub, COMPSTUBSIZE * 8);
3449 /* function: createnativestub **************************************************
3451 creates a stub routine which calls a native method
3453 *******************************************************************************/
3455 #define NATIVESTUBSIZE 11
3457 u1 *createnativestub (functionptr f, methodinfo *m)
3459 u8 *s = CNEW (u8, NATIVESTUBSIZE); /* memory to hold the stub */
3460 s4 *p = (s4*) s; /* code generation pointer */
3462 M_ALD (REG_ITMP3, REG_PV, 8*8); /* load adress of native method */
3463 M_LDA (REG_SP, REG_SP, -8); /* build up stackframe */
3465 M_LST (REG_RA, REG_SP, 0); /* store return address */
3466 M_JSR (REG_RA, REG_ITMP3); /* call native method */
3468 M_NOP; /* delay slot */
3469 M_ALD (REG_ITMP3, REG_PV, 9*8); /* get address of exceptionptr */
3471 M_LLD (REG_RA, REG_SP, 0); /* load return address */
3472 M_ALD (REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
3474 M_BNEZ (REG_ITMP1, 2); /* if no exception then return */
3475 M_LDA (REG_SP, REG_SP, 8); /* remove stackframe, delay slot */
3477 M_RET (REG_RA); /* return to caller */
3478 M_NOP; /* delay slot */
3480 M_AST (REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
3481 M_ALD (REG_ITMP3, REG_PV,10*8); /* load asm exception handler address */
3483 M_JMP (REG_ITMP3); /* jump to asm exception handler */
3484 M_LDA (REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
3487 (void) cacheflush((void*) s, (char*) p - (char*) s, ICACHE);
3489 s[8] = (u8) f; /* address of native method */
3490 s[9] = (u8) (&exceptionptr); /* address of exceptionptr */
3491 s[10]= (u8) (asm_handle_nat_exception); /* addr of asm exception handler */
3494 count_nstub_len += NATIVESTUBSIZE * 8;
3501 /* function: removenativestub **************************************************
3503 removes a previously created native-stub from memory
3505 *******************************************************************************/
3507 void removenativestub (u1 *stub)
3509 CFREE (stub, NATIVESTUBSIZE * 8);
3513 /* function: createcalljava ****************************************************
3515 creates the asm_calljavamethod (MIPS assembler does not like data in the
3516 text segment). Documentation can be found in asmpart.c.
3518 *******************************************************************************/
3527 #define CALL_JAVA_MEM_SIZE 60
3528 #define CALL_JAVA_ENTRY 20
3529 #define CALL_JAVA_XHANDLER 55
3531 static s4 calljavamem[CALL_JAVA_MEM_SIZE];
3533 void createcalljava ()
3537 *((void**)(calljavamem + 0)) = (void*) asm_call_jit_compiler;
3538 *((void**)(calljavamem + 2)) = (void*) builtin_throw_exception;
3540 *((void**)(calljavamem + 4)) = NULL;
3541 *((void**)(calljavamem + 6)) = (void*) (calljavamem + CALL_JAVA_XHANDLER);
3542 *((void**)(calljavamem + 8)) = (void*) (calljavamem + CALL_JAVA_XHANDLER);
3543 *((void**)(calljavamem +10)) = (void*) (calljavamem + CALL_JAVA_ENTRY);
3545 *((void**)(calljavamem + 8)) = NULL;
3546 *((void**)(calljavamem + 9)) = (void*) (calljavamem + CALL_JAVA_XHANDLER);
3547 *((void**)(calljavamem +10)) = (void*) (calljavamem + CALL_JAVA_XHANDLER);
3548 *((void**)(calljavamem +11)) = (void*) (calljavamem + CALL_JAVA_ENTRY);
3551 calljavamem[12] = 1; /* extable size */
3552 calljavamem[13] = 0; /* fltsave */
3553 calljavamem[14] = 0; /* intsave */
3554 calljavamem[15] = 0; /* isleaf */
3555 calljavamem[16] = 0; /* IsSync */
3556 calljavamem[17] = 80; /* frame size */
3557 calljavamem[18] = 0; /* method pointer (NULL) */
3558 calljavamem[19] = 0; /* method pointer (NULL) */
3560 p = calljavamem + CALL_JAVA_ENTRY; /* code generation pointer */
3563 M_LDA (REG_SP, REG_SP, -10*8); /* allocate stackframe */
3564 M_LST (REG_RA, REG_SP, 0); /* save return address */
3566 M_BRS(1); /* compute current program counter */
3567 M_LST (REG_PV, REG_SP, 3*8); /* save procedure vector */
3569 M_LDA (REG_PV, REG_RA, -4*4); /* compute procedure vector */
3570 M_DST (REG_FSS0, REG_SP, 4*8); /* save non JavaABI saved flt regs */
3572 M_DST (REG_FSS1, REG_SP, 5*8);
3573 M_DST (REG_FSS2, REG_SP, 6*8);
3575 M_DST (REG_FSS3, REG_SP, 7*8);
3576 M_DST (REG_FSS4, REG_SP, 8*8);
3578 M_DST (REG_FSS5, REG_SP, 9*8);
3579 M_LST (REG_ARG_0, REG_SP, 2*8); /* save method pointer for compiler */
3581 M_LDA (REG_ITMP1, REG_SP, 2*8); /* pass pointer to methodptr via itmp1*/
3582 M_MOV (REG_ARG_1, REG_ARG_0); /* pass the remaining parameters */
3584 M_MOV (REG_ARG_2, REG_ARG_1);
3585 M_MOV (REG_ARG_3, REG_ARG_2);
3587 M_MOV (REG_ARG_4, REG_ARG_3);
3588 M_ALD (REG_METHODPTR, REG_PV, -80); /* address of asm_call_jit_compiler */
3590 M_AST (REG_METHODPTR, REG_SP, 8); /* store function address */
3591 M_MOV (REG_SP, REG_METHODPTR); /* set method pointer */
3593 M_ALD (REG_PV, REG_METHODPTR, 8); /* method call as in Java */
3594 M_JSR (REG_RA, REG_PV); /* call JIT compiler */
3596 M_NOP; /* delay slot */
3597 M_LDA (REG_PV, REG_RA, -23*4); /* recompute procedure vector */
3600 M_CLR (REG_RESULT); /* clear return value (exception ptr) */
3601 /* calljava_return: */
3602 M_LLD (REG_RA, REG_SP, 0); /* restore return address */
3604 M_LLD (REG_PV, REG_SP, 3*8); /* restore procedure vector */
3605 M_DLD (REG_FSS0, REG_SP, 4*8); /* restore non JavaABI saved flt regs */
3607 M_DLD (REG_FSS1, REG_SP, 5*8);
3608 M_DLD (REG_FSS2, REG_SP, 6*8);
3610 M_DLD (REG_FSS3, REG_SP, 7*8);
3611 M_DLD (REG_FSS4, REG_SP, 8*8);
3613 M_DLD (REG_FSS5, REG_SP, 9*8);
3614 M_RET(REG_RA); /* return */
3616 M_LDA (REG_SP, REG_SP, 10*8); /* deallocate stackframe (delay slot) */
3619 /* calljava_xhandler: */
3621 M_ALD (REG_ITMP3, REG_PV, -72); /* address of builtin_throw_exception */
3623 M_JSR (REG_RA, REG_ITMP3); /* call builtin */
3624 M_MOV (REG_ITMP1, REG_ARG_0); /* pass parameter (delay slot) */
3626 M_BR(-14); /* branch calljava_return */
3627 M_NOP; /* delay slot */
3629 (void) cacheflush((void*)(calljavamem + CALL_JAVA_ENTRY),
3630 (CALL_JAVA_MEM_SIZE - CALL_JAVA_ENTRY) * (int) sizeof(s4), ICACHE);
3634 typedef java_objectheader* (*asm_fptr)(methodinfo*, void*, void*, void*, void*);
3636 java_objectheader *asm_calljavamethod (methodinfo *m, void *arg1, void *arg2,
3637 void *arg3, void *arg4)
3639 return ((asm_fptr)(calljavamem + 20))(m, arg1, arg2, arg3, arg4);
3644 * These are local overrides for various environment variables in Emacs.
3645 * Please do not remove this and leave it at the end of the file, where
3646 * Emacs will automagically detect them.
3647 * ---------------------------------------------------------------------
3650 * indent-tabs-mode: t