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: $Id: ngen.c 232 2003-02-13 11:35:40Z stefan $
15 *******************************************************************************/
17 #include "jitdef.h" /* phil */
22 /* *****************************************************************************
24 Datatypes and Register Allocations:
25 -----------------------------------
27 On 64-bit-machines (like the MIPS) all operands are stored in the
28 registers in a 64-bit form, even when the correspondig JavaVM operands
29 only need 32 bits. This is done by a canonical representation:
31 32-bit integers are allways stored as sign-extended 64-bit values (this
32 approach is directly supported by the MIPS architecture and is very easy
35 32-bit-floats are stored in a 64-bit double precision register by simply
36 expanding the exponent and mantissa with zeroes. (also supported by the
42 The calling conventions and the layout of the stack is explained in detail
43 in the documention file: calling.doc
45 *******************************************************************************/
48 /* additional functions and macros to generate code ***************************/
50 /* #define BlockPtrOfPC(pc) block+block_index[pc] */
51 #define BlockPtrOfPC(pc) ((basicblock *) iptr->target)
55 #define COUNT_SPILLS count_spills++
61 /* gen_nullptr_check(objreg) */
63 #ifdef SOFTNULLPTRCHECK
64 #define gen_nullptr_check(objreg) \
67 mcode_addxnullrefs(mcodeptr);\
71 #define gen_nullptr_check(objreg)
75 /* MCODECHECK(icnt) */
77 #define MCODECHECK(icnt) \
78 if((mcodeptr+(icnt))>mcodeend)mcodeptr=mcode_increase((u1*)mcodeptr)
81 generates an integer-move from register a to b.
82 if a and b are the same int-register, no code will be generated.
85 #define M_INTMOVE(a,b) if(a!=b){M_MOV(a,b);}
89 generates a floating-point-move from register a to b.
90 if a and b are the same float-register, no code will be generated
93 #define M_FLTMOVE(a,b) {if(a!=b){M_DMOV(a,b);}}
95 #define M_TFLTMOVE(t,a,b) \
102 #define M_TFLD(t,a,b,disp) \
108 #define M_TFST(t,a,b,disp) \
114 #define M_CCFLTMOVE(t1,t2,a,b) \
116 {M_TFLTMOVE(t1,a,b);} \
118 if ((t1)==TYPE_DBL) \
123 #define M_CCFLD(t1,t2,a,b,disp) \
127 M_DLD(REG_FTMP1,b,disp); \
128 if ((t1)==TYPE_DBL) \
129 {M_CVTDF(REG_FTMP1,a);} \
131 {M_CVTFD(REG_FTMP1,a);} \
134 #define M_CCFST(t1,t2,a,b,disp) \
138 if ((t1)==TYPE_DBL) \
139 {M_CVTDF(a,REG_FTMP1);} \
141 {M_CVTFD(a,REG_FTMP1);} \
142 M_DST(REG_FTMP1,b,disp); \
147 this function generates code to fetch data from a pseudo-register
148 into a real register.
149 If the pseudo-register has actually been assigned to a real
150 register, no code will be emitted, since following operations
151 can use this register directly.
153 v: pseudoregister to be fetched from
154 tempregnum: temporary register to be used if v is actually spilled to ram
156 return: the register number, where the operand can be found after
157 fetching (this wil be either tempregnum or the register
158 number allready given to v)
161 #define var_to_reg_int(regnr,v,tempnr) { \
162 if ((v)->flags & INMEMORY) \
163 {COUNT_SPILLS;M_LLD(tempnr,REG_SP,8*(v)->regoff);regnr=tempnr;} \
164 else regnr=(v)->regoff; \
168 #define var_to_reg_flt(regnr,v,tempnr) { \
169 if ((v)->flags & INMEMORY) \
170 {COUNT_SPILLS;M_DLD(tempnr,REG_SP,8*(v)->regoff);regnr=tempnr;} \
171 else regnr=(v)->regoff; \
176 This function determines a register, to which the result of an operation
177 should go, when it is ultimatively intended to store the result in
179 If v is assigned to an actual register, this register will be returned.
180 Otherwise (when v is spilled) this function returns tempregnum.
181 If not already done, regoff and flags are set in the stack location.
184 static int reg_of_var(stackptr v, int tempregnum)
188 switch (v->varkind) {
190 if (!(v->flags & INMEMORY))
194 var = &(interfaces[v->varnum][v->type]);
195 v->regoff = var->regoff;
196 if (!(var->flags & INMEMORY))
200 var = &(locals[v->varnum][v->type]);
201 v->regoff = var->regoff;
202 if (!(var->flags & INMEMORY))
206 v->regoff = v->varnum;
207 if (IS_FLT_DBL_TYPE(v->type)) {
208 if (v->varnum < fltreg_argnum) {
209 v->regoff = argfltregs[v->varnum];
210 return(argfltregs[v->varnum]);
214 if (v->varnum < intreg_argnum) {
215 v->regoff = argintregs[v->varnum];
216 return(argintregs[v->varnum]);
218 v->regoff -= intreg_argnum;
221 v->flags |= INMEMORY;
226 /* store_reg_to_var_xxx:
227 This function generates the code to store the result of an operation
228 back into a spilled pseudo-variable.
229 If the pseudo-variable has not been spilled in the first place, this
230 function will generate nothing.
232 v ............ Pseudovariable
233 tempregnum ... Number of the temporary registers as returned by
237 #define store_reg_to_var_int(sptr, tempregnum) { \
238 if ((sptr)->flags & INMEMORY) { \
240 M_LST(tempregnum, REG_SP, 8 * (sptr)->regoff); \
244 #define store_reg_to_var_flt(sptr, tempregnum) { \
245 if ((sptr)->flags & INMEMORY) { \
247 M_DST(tempregnum, REG_SP, 8 * (sptr)->regoff); \
252 void docacheflush(u1 *p, long bytelen, int dummy);
254 /* NullPointerException handlers and exception handling initialisation */
256 /* NullPointerException signal handler for hardware null pointer check */
258 void catch_NullPointerException(int sig, int code, struct sigcontext *sigctx)
264 /* Reset signal handler - necessary for SysV, does no harm for BSD */
266 instr = *((int*)(sigctx->sc_pc));
267 faultaddr = sigctx->sc_regs[(instr >> 21) & 0x1f];
269 if (faultaddr == 0) {
270 signal(sig, (void*) catch_NullPointerException); /* reinstall handler */
272 sigaddset(&nsig, sig);
273 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
274 sigctx->sc_regs[REG_ITMP1_XPTR] =
275 (long) proto_java_lang_NullPointerException;
276 sigctx->sc_regs[REG_ITMP2_XPC] = sigctx->sc_pc;
277 sigctx->sc_pc = (long) asm_handle_nat_exception;
280 faultaddr += (long) ((instr << 16) >> 16);
281 fprintf(stderr, "faulting address: 0x%lx at 0x%lx\n", (long) faultaddr, (long) sigctx->sc_pc);
282 panic("Stack overflow");
286 void createcalljava ();
289 void init_exceptions(void)
294 /* install signal handlers we need to convert to exceptions */
299 signal(SIGSEGV, (void*) catch_NullPointerException);
303 signal(SIGBUS, (void*) catch_NullPointerException);
309 /* function gen_mcode **********************************************************
311 generates machine code
313 *******************************************************************************/
315 #define MethodPointer -8
316 #define FrameSize -12
321 #define ExTableSize -32
322 #define ExTableStart -32
325 #define ExEntrySize -32
328 #define ExHandlerPC -24
329 #define ExCatchType -32
331 #define ExEntrySize -16
334 #define ExHandlerPC -12
335 #define ExCatchType -16
338 static void gen_mcode()
340 int len, s1, s2, s3, d, bbs;
352 savedregs_num = (isleafmethod) ? 0 : 1; /* space to save the RA */
354 /* space to save used callee saved registers */
356 savedregs_num += (savintregcnt - maxsavintreguse);
357 savedregs_num += (savfltregcnt - maxsavfltreguse);
359 parentargs_base = maxmemuse + savedregs_num;
361 #ifdef USE_THREADS /* space to save argument of monitor_enter */
363 if (checksync && (method->flags & ACC_SYNCHRONIZED))
368 /* adjust frame size for 16 byte alignment */
370 if (parentargs_base & 1)
373 /* create method header */
376 (void) dseg_addaddress(method); /* Filler */
378 (void) dseg_addaddress(method); /* MethodPointer */
379 (void) dseg_adds4(parentargs_base * 8); /* FrameSize */
383 /* IsSync contains the offset relative to the stack pointer for the
384 argument of monitor_exit used in the exception handler. Since the
385 offset could be zero and give a wrong meaning of the flag it is
389 if (checksync && (method->flags & ACC_SYNCHRONIZED))
390 (void) dseg_adds4((maxmemuse + 1) * 8); /* IsSync */
395 (void) dseg_adds4(0); /* IsSync */
397 (void) dseg_adds4(isleafmethod); /* IsLeaf */
398 (void) dseg_adds4(savintregcnt - maxsavintreguse); /* IntSave */
399 (void) dseg_adds4(savfltregcnt - maxsavfltreguse); /* FltSave */
400 (void) dseg_adds4(exceptiontablelength); /* ExTableSize */
402 /* create exception table */
404 for (ex = extable; ex != NULL; ex = ex->down) {
407 if (ex->start != NULL)
408 printf("adding start - %d - ", ex->start->debug_nr);
410 printf("PANIC - start is NULL");
415 dseg_addtarget(ex->start);
419 printf("adding end - %d - ", ex->end->debug_nr);
421 printf("PANIC - end is NULL");
426 dseg_addtarget(ex->end);
429 if (ex->handler != NULL)
430 printf("adding handler - %d\n", ex->handler->debug_nr);
432 printf("PANIC - handler is NULL");
437 dseg_addtarget(ex->handler);
439 (void) dseg_addaddress(ex->catchtype);
442 /* initialize mcode variables */
444 mcodeptr = (s4*) mcodebase;
445 mcodeend = (s4*) (mcodebase + mcodesize);
446 MCODECHECK(128 + mparamcount);
448 /* create stack frame (if necessary) */
451 {M_LDA (REG_SP, REG_SP, -parentargs_base * 8);}
453 /* save return address and used callee saved registers */
457 {p--; M_LST (REG_RA, REG_SP, 8*p);}
458 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
459 {p--; M_LST (savintregs[r], REG_SP, 8 * p);}
460 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
461 {p--; M_DST (savfltregs[r], REG_SP, 8 * p);}
463 /* save monitorenter argument */
466 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
467 if (method->flags & ACC_STATIC) {
468 p = dseg_addaddress (class);
469 M_ALD(REG_ITMP1, REG_PV, p);
470 M_AST(REG_ITMP1, REG_SP, 8 * maxmemuse);
473 M_AST (argintregs[0], REG_SP, 8 * maxmemuse);
478 /* copy argument registers to stack and call trace function with pointer
479 to arguments on stack. ToDo: save floating point registers !!!!!!!!!
483 M_LDA (REG_SP, REG_SP, -(18*8));
485 M_LST(REG_RA, REG_SP, 1*8);
487 M_LST(argintregs[0], REG_SP, 2*8);
488 M_LST(argintregs[1], REG_SP, 3*8);
489 M_LST(argintregs[2], REG_SP, 4*8);
490 M_LST(argintregs[3], REG_SP, 5*8);
491 M_LST(argintregs[4], REG_SP, 6*8);
492 M_LST(argintregs[5], REG_SP, 7*8);
493 M_LST(argintregs[6], REG_SP, 8*8);
494 M_LST(argintregs[7], REG_SP, 9*8);
496 M_DST(argfltregs[0], REG_SP, 10*8);
497 M_DST(argfltregs[1], REG_SP, 11*8);
498 M_DST(argfltregs[2], REG_SP, 12*8);
499 M_DST(argfltregs[3], REG_SP, 13*8);
500 M_DST(argfltregs[4], REG_SP, 14*8);
501 M_DST(argfltregs[5], REG_SP, 15*8);
502 M_DST(argfltregs[6], REG_SP, 16*8);
503 M_DST(argfltregs[7], REG_SP, 17*8);
505 p = dseg_addaddress (method);
506 M_ALD(REG_ITMP1, REG_PV, p);
507 M_LST(REG_ITMP1, REG_SP, 0);
508 p = dseg_addaddress ((void*) (builtin_trace_args));
509 M_ALD(REG_ITMP3, REG_PV, p);
510 M_JSR(REG_RA, REG_ITMP3);
513 M_LLD(REG_RA, REG_SP, 1*8);
515 M_LLD(argintregs[0], REG_SP, 2*8);
516 M_LLD(argintregs[1], REG_SP, 3*8);
517 M_LLD(argintregs[2], REG_SP, 4*8);
518 M_LLD(argintregs[3], REG_SP, 5*8);
519 M_LLD(argintregs[4], REG_SP, 6*8);
520 M_LLD(argintregs[5], REG_SP, 7*8);
521 M_LLD(argintregs[6], REG_SP, 8*8);
522 M_LLD(argintregs[7], REG_SP, 9*8);
524 M_DLD(argfltregs[0], REG_SP, 10*8);
525 M_DLD(argfltregs[1], REG_SP, 11*8);
526 M_DLD(argfltregs[2], REG_SP, 12*8);
527 M_DLD(argfltregs[3], REG_SP, 13*8);
528 M_DLD(argfltregs[4], REG_SP, 14*8);
529 M_DLD(argfltregs[5], REG_SP, 15*8);
530 M_DLD(argfltregs[6], REG_SP, 16*8);
531 M_DLD(argfltregs[7], REG_SP, 17*8);
533 M_LDA (REG_SP, REG_SP, 18*8);
536 /* take arguments out of register or stack frame */
538 for (p = 0, l = 0; p < mparamcount; p++) {
540 var = &(locals[l][t]);
542 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
547 if (IS_INT_LNG_TYPE(t)) { /* integer args */
548 if (p < INT_ARG_CNT) { /* register arguments */
549 if (!(var->flags & INMEMORY)) /* reg arg -> register */
550 {M_INTMOVE (argintregs[p], r);}
551 else /* reg arg -> spilled */
552 M_LST (argintregs[p], REG_SP, 8 * r);
554 else { /* stack arguments */
555 pa = p - INT_ARG_CNT;
556 if (!(var->flags & INMEMORY)) /* stack arg -> register */
557 M_LLD (r, REG_SP, 8 * (parentargs_base + pa));
558 else { /* stack arg -> spilled */
559 M_LLD (REG_ITMP1, REG_SP, 8 * (parentargs_base + pa));
560 M_LST (REG_ITMP1, REG_SP, 8 * r);
564 else { /* floating args */
565 if (p < FLT_ARG_CNT) { /* register arguments */
566 if (!(var->flags & INMEMORY)) /* reg arg -> register */
567 {M_TFLTMOVE (var->type, argfltregs[p], r);}
568 else /* reg arg -> spilled */
569 M_DST (argfltregs[p], REG_SP, 8 * r);
571 else { /* stack arguments */
572 pa = p - FLT_ARG_CNT;
573 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
574 M_DLD (r, REG_SP, 8 * (parentargs_base + pa) );
575 } else { /* stack-arg -> spilled */
576 M_DLD (REG_FTMP1, REG_SP, 8 * (parentargs_base + pa));
577 M_DST (REG_FTMP1, REG_SP, 8 * r);
583 /* call trace function */
585 if (runverbose && !isleafmethod) {
586 M_LDA (REG_SP, REG_SP, -8);
587 p = dseg_addaddress (method);
588 M_ALD(REG_ITMP1, REG_PV, p);
589 M_AST(REG_ITMP1, REG_SP, 0);
590 p = dseg_addaddress ((void*) (builtin_trace_args));
591 M_ALD(REG_ITMP3, REG_PV, p);
592 M_JSR(REG_RA, REG_ITMP3);
594 M_LDA(REG_SP, REG_SP, 8);
597 /* call monitorenter function */
600 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
602 p = dseg_addaddress ((void*) (builtin_monitorenter));
603 M_ALD(REG_ITMP3, REG_PV, p);
604 M_JSR(REG_RA, REG_ITMP3);
605 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
606 disp = -(int)((u1*) mcodeptr - mcodebase);
607 M_LDA(REG_PV, REG_RA, disp);
612 /* end of header generation */
614 /* walk through all basic blocks */
615 for (/* bbs = block_count, */ bptr = block; /* --bbs >= 0 */ bptr != NULL; bptr = bptr->next) {
617 bptr -> mpc = (int)((u1*) mcodeptr - mcodebase);
619 if (bptr->flags >= BBREACHED) {
621 /* branch resolving */
625 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
626 gen_resolvebranch((u1*) mcodebase + brefs->branchpos,
627 brefs->branchpos, bptr->mpc);
631 /* copy interface registers to their destination */
636 while (src != NULL) {
638 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
639 d = reg_of_var(src, REG_ITMP1);
640 M_INTMOVE(REG_ITMP1, d);
641 store_reg_to_var_int(src, d);
644 d = reg_of_var(src, REG_IFTMP);
645 if ((src->varkind != STACKVAR)) {
647 if (IS_FLT_DBL_TYPE(s2)) {
648 if (!(interfaces[len][s2].flags & INMEMORY)) {
649 s1 = interfaces[len][s2].regoff;
653 M_DLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
655 store_reg_to_var_flt(src, d);
658 if (!(interfaces[len][s2].flags & INMEMORY)) {
659 s1 = interfaces[len][s2].regoff;
663 M_LLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
665 store_reg_to_var_int(src, d);
672 /* walk through all instructions */
676 for (iptr = bptr->iinstr;
678 src = iptr->dst, len--, iptr++) {
680 MCODECHECK(64); /* an instruction usually needs < 64 words */
683 case ICMD_NOP: /* ... ==> ... */
686 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
688 var_to_reg_int(s1, src, REG_ITMP1);
690 mcode_addxnullrefs(mcodeptr);
694 /* constant operations ************************************************/
696 #define ICONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_IADD_IMM(REG_ZERO,c,r);} \
697 else if(((c)>=0)&&((c)<=0xffff)){M_OR_IMM(REG_ZERO,c,r);} \
698 else{a=dseg_adds4(c);M_ILD(r,REG_PV,a);}
700 #define LCONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LADD_IMM(REG_ZERO,c,r);} \
701 else if(((c)>=0)&&((c)<=0xffff)){M_OR_IMM(REG_ZERO,c,r);} \
702 else{a=dseg_adds8(c);M_LLD(r,REG_PV,a);}
704 case ICMD_ICONST: /* ... ==> ..., constant */
705 /* op1 = 0, val.i = constant */
707 d = reg_of_var(iptr->dst, REG_ITMP1);
708 ICONST(d, iptr->val.i);
709 store_reg_to_var_int(iptr->dst, d);
712 case ICMD_LCONST: /* ... ==> ..., constant */
713 /* op1 = 0, val.l = constant */
715 d = reg_of_var(iptr->dst, REG_ITMP1);
716 LCONST(d, iptr->val.l);
717 store_reg_to_var_int(iptr->dst, d);
720 case ICMD_FCONST: /* ... ==> ..., constant */
721 /* op1 = 0, val.f = constant */
723 d = reg_of_var (iptr->dst, REG_FTMP1);
724 a = dseg_addfloat (iptr->val.f);
726 store_reg_to_var_flt (iptr->dst, d);
729 case ICMD_DCONST: /* ... ==> ..., constant */
730 /* op1 = 0, val.d = constant */
732 d = reg_of_var (iptr->dst, REG_FTMP1);
733 a = dseg_adddouble (iptr->val.d);
735 store_reg_to_var_flt (iptr->dst, d);
738 case ICMD_ACONST: /* ... ==> ..., constant */
739 /* op1 = 0, val.a = constant */
741 d = reg_of_var(iptr->dst, REG_ITMP1);
743 a = dseg_addaddress (iptr->val.a);
747 M_INTMOVE(REG_ZERO, d);
749 store_reg_to_var_int(iptr->dst, d);
753 /* load/store operations **********************************************/
755 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
756 case ICMD_LLOAD: /* op1 = local variable */
759 d = reg_of_var(iptr->dst, REG_ITMP1);
760 if ((iptr->dst->varkind == LOCALVAR) &&
761 (iptr->dst->varnum == iptr->op1))
763 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
764 if (var->flags & INMEMORY)
765 M_LLD(d, REG_SP, 8 * var->regoff);
767 {M_INTMOVE(var->regoff,d);}
768 store_reg_to_var_int(iptr->dst, d);
771 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
772 case ICMD_DLOAD: /* op1 = local variable */
774 d = reg_of_var(iptr->dst, REG_FTMP1);
775 if ((iptr->dst->varkind == LOCALVAR) &&
776 (iptr->dst->varnum == iptr->op1))
778 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
780 int t2 = ((iptr->opc == ICMD_FLOAD) ? TYPE_FLT : TYPE_DBL);
781 if (var->flags & INMEMORY)
782 {M_CCFLD(var->type,t2,d, REG_SP, 8 * var->regoff);}
784 {M_CCFLTMOVE(var->type,t2,var->regoff,d);}
786 store_reg_to_var_flt(iptr->dst, d);
790 case ICMD_ISTORE: /* ..., value ==> ... */
791 case ICMD_LSTORE: /* op1 = local variable */
794 if ((src->varkind == LOCALVAR) &&
795 (src->varnum == iptr->op1))
797 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
798 if (var->flags & INMEMORY) {
799 var_to_reg_int(s1, src, REG_ITMP1);
800 M_LST(s1, REG_SP, 8 * var->regoff);
803 var_to_reg_int(s1, src, var->regoff);
804 M_INTMOVE(s1, var->regoff);
808 case ICMD_FSTORE: /* ..., value ==> ... */
809 case ICMD_DSTORE: /* op1 = local variable */
811 if ((src->varkind == LOCALVAR) &&
812 (src->varnum == iptr->op1))
814 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
816 int t1 = ((iptr->opc == ICMD_FSTORE) ? TYPE_FLT : TYPE_DBL);
817 if (var->flags & INMEMORY) {
818 var_to_reg_flt(s1, src, REG_FTMP1);
819 M_CCFST(t1,var->type,s1, REG_SP, 8 * var->regoff);
822 var_to_reg_flt(s1, src, var->regoff);
823 M_CCFLTMOVE(t1,var->type,s1, var->regoff);
829 /* pop/dup/swap operations ********************************************/
831 /* attention: double and longs are only one entry in CACAO ICMDs */
833 case ICMD_POP: /* ..., value ==> ... */
834 case ICMD_POP2: /* ..., value, value ==> ... */
837 #define M_COPY(from,to) \
838 d = reg_of_var(to, REG_IFTMP); \
839 if ((from->regoff != to->regoff) || \
840 ((from->flags ^ to->flags) & INMEMORY)) { \
841 if (IS_FLT_DBL_TYPE(from->type)) { \
842 var_to_reg_flt(s1, from, d); \
843 M_TFLTMOVE(from->type,s1,d); \
844 store_reg_to_var_flt(to, d); \
847 var_to_reg_int(s1, from, d); \
849 store_reg_to_var_int(to, d); \
853 case ICMD_DUP: /* ..., a ==> ..., a, a */
854 M_COPY(src, iptr->dst);
857 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
859 M_COPY(src, iptr->dst->prev->prev);
861 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
863 M_COPY(src, iptr->dst);
864 M_COPY(src->prev, iptr->dst->prev);
867 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
869 M_COPY(src->prev, iptr->dst->prev->prev->prev);
871 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
873 M_COPY(src, iptr->dst);
874 M_COPY(src->prev, iptr->dst->prev);
875 M_COPY(src->prev->prev, iptr->dst->prev->prev);
876 M_COPY(src, iptr->dst->prev->prev->prev);
879 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
881 M_COPY(src, iptr->dst);
882 M_COPY(src->prev, iptr->dst->prev);
883 M_COPY(src->prev->prev, iptr->dst->prev->prev);
884 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
885 M_COPY(src, iptr->dst->prev->prev->prev->prev);
886 M_COPY(src->prev, iptr->dst->prev->prev->prev->prev->prev);
889 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
891 M_COPY(src, iptr->dst->prev);
892 M_COPY(src->prev, iptr->dst);
896 /* integer operations *************************************************/
898 case ICMD_INEG: /* ..., value ==> ..., - value */
900 var_to_reg_int(s1, src, REG_ITMP1);
901 d = reg_of_var(iptr->dst, REG_ITMP3);
902 M_ISUB(REG_ZERO, s1, d);
903 store_reg_to_var_int(iptr->dst, d);
906 case ICMD_LNEG: /* ..., value ==> ..., - value */
908 var_to_reg_int(s1, src, REG_ITMP1);
909 d = reg_of_var(iptr->dst, REG_ITMP3);
910 M_LSUB(REG_ZERO, s1, d);
911 store_reg_to_var_int(iptr->dst, d);
914 case ICMD_I2L: /* ..., value ==> ..., value */
916 var_to_reg_int(s1, src, REG_ITMP1);
917 d = reg_of_var(iptr->dst, REG_ITMP3);
919 store_reg_to_var_int(iptr->dst, d);
922 case ICMD_L2I: /* ..., value ==> ..., value */
924 var_to_reg_int(s1, src, REG_ITMP1);
925 d = reg_of_var(iptr->dst, REG_ITMP3);
926 M_IADD(s1, REG_ZERO, d );
927 store_reg_to_var_int(iptr->dst, d);
930 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
932 var_to_reg_int(s1, src, REG_ITMP1);
933 d = reg_of_var(iptr->dst, REG_ITMP3);
934 M_LSLL_IMM(s1, 56, d);
935 M_LSRA_IMM( d, 56, d);
936 store_reg_to_var_int(iptr->dst, d);
939 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
941 var_to_reg_int(s1, src, REG_ITMP1);
942 d = reg_of_var(iptr->dst, REG_ITMP3);
944 store_reg_to_var_int(iptr->dst, d);
947 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
949 var_to_reg_int(s1, src, REG_ITMP1);
950 d = reg_of_var(iptr->dst, REG_ITMP3);
951 M_LSLL_IMM(s1, 48, d);
952 M_LSRA_IMM( d, 48, d);
953 store_reg_to_var_int(iptr->dst, d);
957 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
959 var_to_reg_int(s1, src->prev, REG_ITMP1);
960 var_to_reg_int(s2, src, REG_ITMP2);
961 d = reg_of_var(iptr->dst, REG_ITMP3);
963 store_reg_to_var_int(iptr->dst, d);
966 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
967 /* val.i = constant */
969 var_to_reg_int(s1, src, REG_ITMP1);
970 d = reg_of_var(iptr->dst, REG_ITMP3);
971 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
972 M_IADD_IMM(s1, iptr->val.i, d);
975 ICONST(REG_ITMP2, iptr->val.i);
976 M_IADD(s1, REG_ITMP2, d);
978 store_reg_to_var_int(iptr->dst, d);
981 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
983 var_to_reg_int(s1, src->prev, REG_ITMP1);
984 var_to_reg_int(s2, src, REG_ITMP2);
985 d = reg_of_var(iptr->dst, REG_ITMP3);
987 store_reg_to_var_int(iptr->dst, d);
990 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
991 /* val.l = constant */
993 var_to_reg_int(s1, src, REG_ITMP1);
994 d = reg_of_var(iptr->dst, REG_ITMP3);
995 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
996 M_LADD_IMM(s1, iptr->val.l, d);
999 LCONST(REG_ITMP2, iptr->val.l);
1000 M_LADD(s1, REG_ITMP2, d);
1002 store_reg_to_var_int(iptr->dst, d);
1005 case ICMD_ISUB: /* ..., 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);
1011 store_reg_to_var_int(iptr->dst, d);
1014 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
1015 /* val.i = constant */
1017 var_to_reg_int(s1, src, REG_ITMP1);
1018 d = reg_of_var(iptr->dst, REG_ITMP3);
1019 if ((iptr->val.i >= -32767) && (iptr->val.i <= 32768)) {
1020 M_IADD_IMM(s1, -iptr->val.i, d);
1023 ICONST(REG_ITMP2, iptr->val.i);
1024 M_ISUB(s1, REG_ITMP2, d);
1026 store_reg_to_var_int(iptr->dst, d);
1029 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1031 var_to_reg_int(s1, src->prev, REG_ITMP1);
1032 var_to_reg_int(s2, src, REG_ITMP2);
1033 d = reg_of_var(iptr->dst, REG_ITMP3);
1035 store_reg_to_var_int(iptr->dst, d);
1038 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
1039 /* val.l = constant */
1041 var_to_reg_int(s1, src, REG_ITMP1);
1042 d = reg_of_var(iptr->dst, REG_ITMP3);
1043 if ((iptr->val.l >= -32767) && (iptr->val.l <= 32768)) {
1044 M_LADD_IMM(s1, -iptr->val.l, d);
1047 LCONST(REG_ITMP2, iptr->val.l);
1048 M_LSUB(s1, REG_ITMP2, d);
1050 store_reg_to_var_int(iptr->dst, d);
1053 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1055 var_to_reg_int(s1, src->prev, REG_ITMP1);
1056 var_to_reg_int(s2, src, REG_ITMP2);
1057 d = reg_of_var(iptr->dst, REG_ITMP3);
1062 store_reg_to_var_int(iptr->dst, d);
1065 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
1066 /* val.i = constant */
1068 var_to_reg_int(s1, src, REG_ITMP1);
1069 d = reg_of_var(iptr->dst, REG_ITMP3);
1070 ICONST(REG_ITMP2, iptr->val.i);
1071 M_IMUL(s1, REG_ITMP2);
1075 store_reg_to_var_int(iptr->dst, d);
1078 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1080 var_to_reg_int(s1, src->prev, REG_ITMP1);
1081 var_to_reg_int(s2, src, REG_ITMP2);
1082 d = reg_of_var(iptr->dst, REG_ITMP3);
1087 store_reg_to_var_int(iptr->dst, d);
1090 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
1091 /* val.l = constant */
1093 var_to_reg_int(s1, src, REG_ITMP1);
1094 d = reg_of_var(iptr->dst, REG_ITMP3);
1095 LCONST(REG_ITMP2, iptr->val.l);
1096 M_LMUL(s1, REG_ITMP2);
1100 store_reg_to_var_int(iptr->dst, d);
1103 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1105 var_to_reg_int(s1, src->prev, REG_ITMP1);
1106 var_to_reg_int(s2, src, REG_ITMP2);
1107 d = reg_of_var(iptr->dst, REG_ITMP3);
1112 store_reg_to_var_int(iptr->dst, d);
1115 case ICMD_IDIVCONST: /* ..., value ==> ..., value / constant */
1116 /* val.i = constant */
1118 var_to_reg_int(s1, src, REG_ITMP1);
1119 d = reg_of_var(iptr->dst, REG_ITMP3);
1120 ICONST(REG_ITMP2, iptr->val.i);
1121 M_IDIV(s1, REG_ITMP2);
1125 store_reg_to_var_int(iptr->dst, d);
1128 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1130 var_to_reg_int(s1, src->prev, REG_ITMP1);
1131 var_to_reg_int(s2, src, REG_ITMP2);
1132 d = reg_of_var(iptr->dst, REG_ITMP3);
1137 store_reg_to_var_int(iptr->dst, d);
1140 case ICMD_LDIVCONST: /* ..., 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 LCONST(REG_ITMP2, iptr->val.l);
1146 M_LDIV(s1, REG_ITMP2);
1150 store_reg_to_var_int(iptr->dst, d);
1153 case ICMD_IREM: /* ..., 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);
1162 store_reg_to_var_int(iptr->dst, d);
1165 case ICMD_IREMCONST: /* ..., value ==> ..., value % constant */
1166 /* val.i = constant */
1168 var_to_reg_int(s1, src, REG_ITMP1);
1169 d = reg_of_var(iptr->dst, REG_ITMP3);
1170 ICONST(REG_ITMP2, iptr->val.i);
1171 M_IDIV(s1, REG_ITMP2);
1175 store_reg_to_var_int(iptr->dst, d);
1178 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1180 var_to_reg_int(s1, src->prev, REG_ITMP1);
1181 var_to_reg_int(s2, src, REG_ITMP2);
1182 d = reg_of_var(iptr->dst, REG_ITMP3);
1187 store_reg_to_var_int(iptr->dst, d);
1190 case ICMD_LREMCONST: /* ..., value ==> ..., value % constant */
1191 /* val.l = constant */
1193 var_to_reg_int(s1, src, REG_ITMP1);
1194 d = reg_of_var(iptr->dst, REG_ITMP3);
1195 LCONST(REG_ITMP2, iptr->val.l);
1196 M_LDIV(s1, REG_ITMP2);
1200 store_reg_to_var_int(iptr->dst, d);
1203 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
1204 case ICMD_LDIVPOW2: /* val.i = constant */
1206 var_to_reg_int(s1, src, REG_ITMP1);
1207 d = reg_of_var(iptr->dst, REG_ITMP3);
1208 M_LSRA_IMM(s1, 63, REG_ITMP2);
1209 M_LSRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
1210 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1211 M_LSRA_IMM(REG_ITMP2, iptr->val.i, d);
1212 store_reg_to_var_int(iptr->dst, d);
1215 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1217 var_to_reg_int(s1, src->prev, REG_ITMP1);
1218 var_to_reg_int(s2, src, REG_ITMP2);
1219 d = reg_of_var(iptr->dst, REG_ITMP3);
1221 store_reg_to_var_int(iptr->dst, d);
1224 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1225 /* val.i = constant */
1227 var_to_reg_int(s1, src, REG_ITMP1);
1228 d = reg_of_var(iptr->dst, REG_ITMP3);
1229 M_ISLL_IMM(s1, iptr->val.i, d);
1230 store_reg_to_var_int(iptr->dst, d);
1233 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1235 var_to_reg_int(s1, src->prev, REG_ITMP1);
1236 var_to_reg_int(s2, src, REG_ITMP2);
1237 d = reg_of_var(iptr->dst, REG_ITMP3);
1239 store_reg_to_var_int(iptr->dst, d);
1242 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1243 /* val.i = constant */
1245 var_to_reg_int(s1, src, REG_ITMP1);
1246 d = reg_of_var(iptr->dst, REG_ITMP3);
1247 M_ISRA_IMM(s1, iptr->val.i, d);
1248 store_reg_to_var_int(iptr->dst, d);
1251 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1253 var_to_reg_int(s1, src->prev, REG_ITMP1);
1254 var_to_reg_int(s2, src, REG_ITMP2);
1255 d = reg_of_var(iptr->dst, REG_ITMP3);
1257 store_reg_to_var_int(iptr->dst, d);
1260 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1261 /* val.i = constant */
1263 var_to_reg_int(s1, src, REG_ITMP1);
1264 d = reg_of_var(iptr->dst, REG_ITMP3);
1265 M_ISRL_IMM(s1, iptr->val.i, d);
1266 store_reg_to_var_int(iptr->dst, d);
1269 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1271 var_to_reg_int(s1, src->prev, REG_ITMP1);
1272 var_to_reg_int(s2, src, REG_ITMP2);
1273 d = reg_of_var(iptr->dst, REG_ITMP3);
1275 store_reg_to_var_int(iptr->dst, d);
1278 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1279 /* val.l = constant */
1281 var_to_reg_int(s1, src, REG_ITMP1);
1282 d = reg_of_var(iptr->dst, REG_ITMP3);
1283 M_LSLL_IMM(s1, iptr->val.l, d);
1284 store_reg_to_var_int(iptr->dst, d);
1287 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1289 var_to_reg_int(s1, src->prev, REG_ITMP1);
1290 var_to_reg_int(s2, src, REG_ITMP2);
1291 d = reg_of_var(iptr->dst, REG_ITMP3);
1293 store_reg_to_var_int(iptr->dst, d);
1296 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1297 /* val.l = constant */
1299 var_to_reg_int(s1, src, REG_ITMP1);
1300 d = reg_of_var(iptr->dst, REG_ITMP3);
1301 M_LSRA_IMM(s1, iptr->val.l, d);
1302 store_reg_to_var_int(iptr->dst, d);
1305 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1307 var_to_reg_int(s1, src->prev, REG_ITMP1);
1308 var_to_reg_int(s2, src, REG_ITMP2);
1309 d = reg_of_var(iptr->dst, REG_ITMP3);
1311 store_reg_to_var_int(iptr->dst, d);
1314 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1315 /* val.l = constant */
1317 var_to_reg_int(s1, src, REG_ITMP1);
1318 d = reg_of_var(iptr->dst, REG_ITMP3);
1319 M_LSRL_IMM(s1, iptr->val.l, d);
1320 store_reg_to_var_int(iptr->dst, d);
1323 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1326 var_to_reg_int(s1, src->prev, REG_ITMP1);
1327 var_to_reg_int(s2, src, REG_ITMP2);
1328 d = reg_of_var(iptr->dst, REG_ITMP3);
1330 store_reg_to_var_int(iptr->dst, d);
1333 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1334 /* val.i = constant */
1336 var_to_reg_int(s1, src, REG_ITMP1);
1337 d = reg_of_var(iptr->dst, REG_ITMP3);
1338 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1339 M_AND_IMM(s1, iptr->val.i, d);
1342 ICONST(REG_ITMP2, iptr->val.i);
1343 M_AND(s1, REG_ITMP2, d);
1345 store_reg_to_var_int(iptr->dst, d);
1348 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1349 /* val.i = constant */
1351 var_to_reg_int(s1, src, REG_ITMP1);
1352 d = reg_of_var(iptr->dst, REG_ITMP3);
1354 M_MOV(s1, REG_ITMP1);
1357 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1358 M_AND_IMM(s1, iptr->val.i, d);
1361 M_ISUB(REG_ZERO, s1, d);
1362 M_AND_IMM(d, iptr->val.i, d);
1365 ICONST(REG_ITMP2, iptr->val.i);
1366 M_AND(s1, REG_ITMP2, d);
1369 M_ISUB(REG_ZERO, s1, d);
1370 M_AND(d, REG_ITMP2, d);
1372 M_ISUB(REG_ZERO, d, d);
1373 store_reg_to_var_int(iptr->dst, d);
1376 case ICMD_IREM0X10001: /* ..., value ==> ..., value % 0x100001 */
1378 /* b = value & 0xffff;
1380 a = ((b - a) & 0xffff) + (b < a);
1382 var_to_reg_int(s1, src, REG_ITMP1);
1383 d = reg_of_var(iptr->dst, REG_ITMP3);
1385 M_MOV(s1, REG_ITMP3);
1389 M_CZEXT(s1, REG_ITMP2); /* delay slot */
1390 M_ISRA_IMM(s1, 16, d);
1391 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1392 M_ISUB(REG_ITMP2, d, d);
1395 M_IADD(d, REG_ITMP1, d); /* delay slot */
1397 M_LUI(REG_ITMP2, 1);
1398 M_IADD_IMM(REG_ITMP2, 1, REG_ITMP2);
1399 M_IDIV(s1, REG_ITMP2);
1403 store_reg_to_var_int(iptr->dst, d);
1406 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1407 /* val.l = constant */
1409 var_to_reg_int(s1, src, REG_ITMP1);
1410 d = reg_of_var(iptr->dst, REG_ITMP3);
1411 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1412 M_AND_IMM(s1, iptr->val.l, d);
1415 LCONST(REG_ITMP2, iptr->val.l);
1416 M_AND(s1, REG_ITMP2, d);
1418 store_reg_to_var_int(iptr->dst, d);
1421 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1422 /* val.l = constant */
1424 var_to_reg_int(s1, src, REG_ITMP1);
1425 d = reg_of_var(iptr->dst, REG_ITMP3);
1427 M_MOV(s1, REG_ITMP1);
1430 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1431 M_AND_IMM(s1, iptr->val.l, d);
1434 M_LSUB(REG_ZERO, s1, d);
1435 M_AND_IMM(d, iptr->val.l, d);
1438 LCONST(REG_ITMP2, iptr->val.l);
1439 M_AND(s1, REG_ITMP2, d);
1442 M_LSUB(REG_ZERO, s1, d);
1443 M_AND(d, REG_ITMP2, d);
1445 M_LSUB(REG_ZERO, d, d);
1446 store_reg_to_var_int(iptr->dst, d);
1449 case ICMD_LREM0X10001:/* ..., value ==> ..., value % 0x10001 */
1451 var_to_reg_int(s1, src, REG_ITMP1);
1452 d = reg_of_var(iptr->dst, REG_ITMP3);
1453 M_LUI(REG_ITMP2, 1);
1454 M_LADD_IMM(REG_ITMP2, 1, REG_ITMP2);
1455 M_LDIV(s1, REG_ITMP2);
1459 store_reg_to_var_int(iptr->dst, d);
1462 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1465 var_to_reg_int(s1, src->prev, REG_ITMP1);
1466 var_to_reg_int(s2, src, REG_ITMP2);
1467 d = reg_of_var(iptr->dst, REG_ITMP3);
1469 store_reg_to_var_int(iptr->dst, d);
1472 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1473 /* val.i = constant */
1475 var_to_reg_int(s1, src, REG_ITMP1);
1476 d = reg_of_var(iptr->dst, REG_ITMP3);
1477 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1478 M_OR_IMM(s1, iptr->val.i, d);
1481 ICONST(REG_ITMP2, iptr->val.i);
1482 M_OR(s1, REG_ITMP2, d);
1484 store_reg_to_var_int(iptr->dst, d);
1487 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1488 /* val.l = constant */
1490 var_to_reg_int(s1, src, REG_ITMP1);
1491 d = reg_of_var(iptr->dst, REG_ITMP3);
1492 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1493 M_OR_IMM(s1, iptr->val.l, d);
1496 LCONST(REG_ITMP2, iptr->val.l);
1497 M_OR(s1, REG_ITMP2, d);
1499 store_reg_to_var_int(iptr->dst, d);
1502 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1505 var_to_reg_int(s1, src->prev, REG_ITMP1);
1506 var_to_reg_int(s2, src, REG_ITMP2);
1507 d = reg_of_var(iptr->dst, REG_ITMP3);
1509 store_reg_to_var_int(iptr->dst, d);
1512 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1513 /* val.i = constant */
1515 var_to_reg_int(s1, src, REG_ITMP1);
1516 d = reg_of_var(iptr->dst, REG_ITMP3);
1517 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1518 M_XOR_IMM(s1, iptr->val.i, d);
1521 ICONST(REG_ITMP2, iptr->val.i);
1522 M_XOR(s1, REG_ITMP2, d);
1524 store_reg_to_var_int(iptr->dst, d);
1527 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1528 /* val.l = constant */
1530 var_to_reg_int(s1, src, REG_ITMP1);
1531 d = reg_of_var(iptr->dst, REG_ITMP3);
1532 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1533 M_XOR_IMM(s1, iptr->val.l, d);
1536 LCONST(REG_ITMP2, iptr->val.l);
1537 M_XOR(s1, REG_ITMP2, d);
1539 store_reg_to_var_int(iptr->dst, d);
1543 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1545 var_to_reg_int(s1, src->prev, REG_ITMP1);
1546 var_to_reg_int(s2, src, REG_ITMP2);
1547 d = reg_of_var(iptr->dst, REG_ITMP3);
1548 M_CMPLT(s1, s2, REG_ITMP3);
1549 M_CMPLT(s2, s1, REG_ITMP1);
1550 M_LSUB (REG_ITMP1, REG_ITMP3, d);
1551 store_reg_to_var_int(iptr->dst, d);
1555 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1556 /* op1 = variable, val.i = constant */
1558 var = &(locals[iptr->op1][TYPE_INT]);
1559 if (var->flags & INMEMORY) {
1561 M_LLD(s1, REG_SP, 8 * var->regoff);
1565 M_IADD_IMM(s1, iptr->val.i, s1);
1566 if (var->flags & INMEMORY)
1567 M_LST(s1, REG_SP, 8 * var->regoff);
1571 /* floating operations ************************************************/
1573 case ICMD_FNEG: /* ..., value ==> ..., - value */
1575 var_to_reg_flt(s1, src, REG_FTMP1);
1576 d = reg_of_var(iptr->dst, REG_FTMP3);
1578 store_reg_to_var_flt(iptr->dst, d);
1581 case ICMD_DNEG: /* ..., value ==> ..., - value */
1583 var_to_reg_flt(s1, src, REG_FTMP1);
1584 d = reg_of_var(iptr->dst, REG_FTMP3);
1586 store_reg_to_var_flt(iptr->dst, d);
1589 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1591 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1592 var_to_reg_flt(s2, src, REG_FTMP2);
1593 d = reg_of_var(iptr->dst, REG_FTMP3);
1595 store_reg_to_var_flt(iptr->dst, d);
1598 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1600 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1601 var_to_reg_flt(s2, src, REG_FTMP2);
1602 d = reg_of_var(iptr->dst, REG_FTMP3);
1604 store_reg_to_var_flt(iptr->dst, d);
1607 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1609 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1610 var_to_reg_flt(s2, src, REG_FTMP2);
1611 d = reg_of_var(iptr->dst, REG_FTMP3);
1613 store_reg_to_var_flt(iptr->dst, d);
1616 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1618 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1619 var_to_reg_flt(s2, src, REG_FTMP2);
1620 d = reg_of_var(iptr->dst, REG_FTMP3);
1622 store_reg_to_var_flt(iptr->dst, d);
1625 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1627 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1628 var_to_reg_flt(s2, src, REG_FTMP2);
1629 d = reg_of_var(iptr->dst, REG_FTMP3);
1631 store_reg_to_var_flt(iptr->dst, d);
1634 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1636 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1637 var_to_reg_flt(s2, src, REG_FTMP2);
1638 d = reg_of_var(iptr->dst, REG_FTMP3);
1640 store_reg_to_var_flt(iptr->dst, d);
1643 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1645 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1646 var_to_reg_flt(s2, src, REG_FTMP2);
1647 d = reg_of_var(iptr->dst, REG_FTMP3);
1649 store_reg_to_var_flt(iptr->dst, d);
1652 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1654 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1655 var_to_reg_flt(s2, src, REG_FTMP2);
1656 d = reg_of_var(iptr->dst, REG_FTMP3);
1658 store_reg_to_var_flt(iptr->dst, d);
1661 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1664 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1665 var_to_reg_flt(s2, src, REG_FTMP2);
1666 d = reg_of_var(iptr->dst, REG_FTMP3);
1667 M_FDIV(s1,s2, REG_FTMP3);
1668 M_FLOORFL(REG_FTMP3, REG_FTMP3);
1669 M_CVTLF(REG_FTMP3, REG_FTMP3);
1670 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1671 M_FSUB(s1, REG_FTMP3, d);
1672 store_reg_to_var_flt(iptr->dst, d);
1675 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1677 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1678 var_to_reg_flt(s2, src, REG_FTMP2);
1679 d = reg_of_var(iptr->dst, REG_FTMP3);
1680 M_DDIV(s1,s2, REG_FTMP3);
1681 M_FLOORDL(REG_FTMP3, REG_FTMP3);
1682 M_CVTLD(REG_FTMP3, REG_FTMP3);
1683 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1684 M_DSUB(s1, REG_FTMP3, d);
1685 store_reg_to_var_flt(iptr->dst, d);
1688 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1690 var_to_reg_int(s1, src, REG_ITMP1);
1691 d = reg_of_var(iptr->dst, REG_FTMP3);
1694 store_reg_to_var_flt(iptr->dst, d);
1697 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1699 var_to_reg_int(s1, src, REG_ITMP1);
1700 d = reg_of_var(iptr->dst, REG_FTMP3);
1703 store_reg_to_var_flt(iptr->dst, d);
1706 case ICMD_F2I: /* ..., (float) value ==> ..., (int) value */
1708 var_to_reg_flt(s1, src, REG_FTMP1);
1709 d = reg_of_var(iptr->dst, REG_ITMP3);
1710 M_TRUNCFI(s1, REG_FTMP1);
1711 M_MOVDI(REG_FTMP1, d);
1713 store_reg_to_var_int(iptr->dst, d);
1716 case ICMD_D2I: /* ..., (double) value ==> ..., (int) value */
1718 var_to_reg_flt(s1, src, REG_FTMP1);
1719 d = reg_of_var(iptr->dst, REG_ITMP3);
1720 M_TRUNCDI(s1, REG_FTMP1);
1721 M_MOVDI(REG_FTMP1, d);
1723 store_reg_to_var_int(iptr->dst, d);
1726 case ICMD_F2L: /* ..., (float) value ==> ..., (long) value */
1728 var_to_reg_flt(s1, src, REG_FTMP1);
1729 d = reg_of_var(iptr->dst, REG_ITMP3);
1730 M_TRUNCFL(s1, REG_FTMP1);
1731 M_MOVDL(REG_FTMP1, d);
1733 store_reg_to_var_int(iptr->dst, d);
1736 case ICMD_D2L: /* ..., (double) value ==> ..., (long) value */
1738 var_to_reg_flt(s1, src, REG_FTMP1);
1739 d = reg_of_var(iptr->dst, REG_ITMP3);
1740 M_TRUNCDL(s1, REG_FTMP1);
1741 M_MOVDL(REG_FTMP1, d);
1743 store_reg_to_var_int(iptr->dst, d);
1746 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1748 var_to_reg_flt(s1, src, REG_FTMP1);
1749 d = reg_of_var(iptr->dst, REG_FTMP3);
1751 store_reg_to_var_flt(iptr->dst, d);
1754 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1756 var_to_reg_flt(s1, src, REG_FTMP1);
1757 d = reg_of_var(iptr->dst, REG_FTMP3);
1759 store_reg_to_var_flt(iptr->dst, d);
1762 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1764 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1765 var_to_reg_flt(s2, src, REG_FTMP2);
1766 d = reg_of_var(iptr->dst, REG_ITMP3);
1768 M_NOP; /* compare delay */
1769 M_FBF(2); /* jump over next instructions */
1770 M_LSUB_IMM(REG_ZERO, 1, d); /* delay slot */
1773 M_NOP; /* compare delay */
1774 M_FBF(2); /* jump over next instruction */
1776 M_LADD_IMM(REG_ZERO, 1, d);
1777 store_reg_to_var_int(iptr->dst, d);
1780 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1782 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1783 var_to_reg_flt(s2, src, REG_FTMP2);
1784 d = reg_of_var(iptr->dst, REG_ITMP3);
1786 M_NOP; /* compare delay */
1787 M_FBF(2); /* jump over next instructions */
1788 M_LSUB_IMM(REG_ZERO, 1, d); /* delay slot */
1791 M_NOP; /* compare delay */
1792 M_FBF(2); /* jump over next instruction */
1794 M_LADD_IMM(REG_ZERO, 1, d);
1795 store_reg_to_var_int(iptr->dst, d);
1798 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1800 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1801 var_to_reg_flt(s2, src, REG_FTMP2);
1802 d = reg_of_var(iptr->dst, REG_ITMP3);
1804 M_NOP; /* compare delay */
1805 M_FBF(2); /* jump over next instruction */
1806 M_LADD_IMM(REG_ZERO, 1, d); /* delay slot */
1809 M_NOP; /* compare delay */
1810 M_FBF(2); /* jump over next instruction */
1812 M_LSUB_IMM(REG_ZERO, 1, d);
1813 store_reg_to_var_int(iptr->dst, d);
1816 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1818 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1819 var_to_reg_flt(s2, src, REG_FTMP2);
1820 d = reg_of_var(iptr->dst, REG_ITMP3);
1822 M_NOP; /* compare delay */
1823 M_FBF(2); /* jump over next instruction */
1824 M_LADD_IMM(REG_ZERO, 1, d); /* delay slot */
1827 M_NOP; /* compare delay */
1828 M_FBF(2); /* jump over next instruction */
1830 M_LSUB_IMM(REG_ZERO, 1, d);
1831 store_reg_to_var_int(iptr->dst, d);
1835 /* memory operations **************************************************/
1837 #define gen_bound_check \
1839 M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\
1840 M_CMPULT(s2, REG_ITMP3, REG_ITMP3);\
1841 M_BEQZ(REG_ITMP3, 0);\
1842 mcode_addxboundrefs(mcodeptr);\
1846 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1848 var_to_reg_int(s1, src, REG_ITMP1);
1849 d = reg_of_var(iptr->dst, REG_ITMP3);
1850 gen_nullptr_check(s1);
1851 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1852 store_reg_to_var_int(iptr->dst, d);
1855 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1857 var_to_reg_int(s1, src->prev, REG_ITMP1);
1858 var_to_reg_int(s2, src, REG_ITMP2);
1859 d = reg_of_var(iptr->dst, REG_ITMP3);
1860 if (iptr->op1 == 0) {
1861 gen_nullptr_check(s1);
1864 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1865 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1866 M_ALD(d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1867 store_reg_to_var_int(iptr->dst, d);
1870 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1872 var_to_reg_int(s1, src->prev, REG_ITMP1);
1873 var_to_reg_int(s2, src, REG_ITMP2);
1874 d = reg_of_var(iptr->dst, REG_ITMP3);
1875 if (iptr->op1 == 0) {
1876 gen_nullptr_check(s1);
1879 M_ASLL_IMM(s2, 2, REG_ITMP2);
1880 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1881 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1882 store_reg_to_var_int(iptr->dst, d);
1885 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1887 var_to_reg_int(s1, src->prev, REG_ITMP1);
1888 var_to_reg_int(s2, src, REG_ITMP2);
1889 d = reg_of_var(iptr->dst, REG_ITMP3);
1890 if (iptr->op1 == 0) {
1891 gen_nullptr_check(s1);
1894 M_ASLL_IMM(s2, 3, REG_ITMP2);
1895 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1896 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1897 store_reg_to_var_int(iptr->dst, d);
1900 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1902 var_to_reg_int(s1, src->prev, REG_ITMP1);
1903 var_to_reg_int(s2, src, REG_ITMP2);
1904 d = reg_of_var(iptr->dst, REG_FTMP3);
1905 if (iptr->op1 == 0) {
1906 gen_nullptr_check(s1);
1909 M_ASLL_IMM(s2, 2, REG_ITMP2);
1910 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1911 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1912 store_reg_to_var_flt(iptr->dst, d);
1915 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1917 var_to_reg_int(s1, src->prev, REG_ITMP1);
1918 var_to_reg_int(s2, src, REG_ITMP2);
1919 d = reg_of_var(iptr->dst, REG_FTMP3);
1920 if (iptr->op1 == 0) {
1921 gen_nullptr_check(s1);
1924 M_ASLL_IMM(s2, 3, REG_ITMP2);
1925 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1926 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1927 store_reg_to_var_flt(iptr->dst, d);
1930 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1932 var_to_reg_int(s1, src->prev, REG_ITMP1);
1933 var_to_reg_int(s2, src, REG_ITMP2);
1934 d = reg_of_var(iptr->dst, REG_ITMP3);
1935 if (iptr->op1 == 0) {
1936 gen_nullptr_check(s1);
1939 M_AADD(s2, s1, REG_ITMP1);
1940 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1941 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1942 store_reg_to_var_int(iptr->dst, d);
1945 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1947 var_to_reg_int(s1, src->prev, REG_ITMP1);
1948 var_to_reg_int(s2, src, REG_ITMP2);
1949 d = reg_of_var(iptr->dst, REG_ITMP3);
1950 if (iptr->op1 == 0) {
1951 gen_nullptr_check(s1);
1954 M_AADD(s2, s1, REG_ITMP1);
1955 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1956 M_SLDS(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1957 store_reg_to_var_int(iptr->dst, d);
1960 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1962 var_to_reg_int(s1, src->prev, REG_ITMP1);
1963 var_to_reg_int(s2, src, REG_ITMP2);
1964 d = reg_of_var(iptr->dst, REG_ITMP3);
1965 if (iptr->op1 == 0) {
1966 gen_nullptr_check(s1);
1969 M_AADD(s2, s1, REG_ITMP1);
1970 M_BLDS(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1971 store_reg_to_var_int(iptr->dst, d);
1975 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1977 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1978 var_to_reg_int(s2, src->prev, REG_ITMP2);
1979 if (iptr->op1 == 0) {
1980 gen_nullptr_check(s1);
1983 var_to_reg_int(s3, src, REG_ITMP3);
1984 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1985 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1986 M_AST(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1989 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1991 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1992 var_to_reg_int(s2, src->prev, REG_ITMP2);
1993 if (iptr->op1 == 0) {
1994 gen_nullptr_check(s1);
1997 var_to_reg_int(s3, src, REG_ITMP3);
1998 M_ASLL_IMM(s2, 2, REG_ITMP2);
1999 M_AADD(REG_ITMP2, s1, REG_ITMP1);
2000 M_IST(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
2003 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
2005 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2006 var_to_reg_int(s2, src->prev, REG_ITMP2);
2007 if (iptr->op1 == 0) {
2008 gen_nullptr_check(s1);
2011 var_to_reg_int(s3, src, REG_ITMP3);
2012 M_ASLL_IMM(s2, 3, REG_ITMP2);
2013 M_AADD(REG_ITMP2, s1, REG_ITMP1);
2014 M_LST(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
2017 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
2019 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2020 var_to_reg_int(s2, src->prev, REG_ITMP2);
2021 if (iptr->op1 == 0) {
2022 gen_nullptr_check(s1);
2025 var_to_reg_flt(s3, src, REG_FTMP3);
2026 M_ASLL_IMM(s2, 2, REG_ITMP2);
2027 M_AADD(REG_ITMP2, s1, REG_ITMP1);
2028 M_FST(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
2031 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
2033 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2034 var_to_reg_int(s2, src->prev, REG_ITMP2);
2035 if (iptr->op1 == 0) {
2036 gen_nullptr_check(s1);
2039 var_to_reg_flt(s3, src, REG_FTMP3);
2040 M_ASLL_IMM(s2, 3, REG_ITMP2);
2041 M_AADD(REG_ITMP2, s1, REG_ITMP1);
2042 M_DST(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
2045 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
2046 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
2048 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2049 var_to_reg_int(s2, src->prev, REG_ITMP2);
2050 if (iptr->op1 == 0) {
2051 gen_nullptr_check(s1);
2054 var_to_reg_int(s3, src, REG_ITMP3);
2055 M_AADD(s2, s1, REG_ITMP1);
2056 M_AADD(s2, REG_ITMP1, REG_ITMP1);
2057 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
2060 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
2062 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2063 var_to_reg_int(s2, src->prev, REG_ITMP2);
2064 if (iptr->op1 == 0) {
2065 gen_nullptr_check(s1);
2068 var_to_reg_int(s3, src, REG_ITMP3);
2069 M_AADD(s2, s1, REG_ITMP1);
2070 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2074 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2075 /* op1 = type, val.a = field address */
2077 a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value));
2078 M_ALD(REG_ITMP1, REG_PV, a);
2079 switch (iptr->op1) {
2081 var_to_reg_int(s2, src, REG_ITMP2);
2082 M_IST(s2, REG_ITMP1, 0);
2085 var_to_reg_int(s2, src, REG_ITMP2);
2086 M_LST(s2, REG_ITMP1, 0);
2089 var_to_reg_int(s2, src, REG_ITMP2);
2090 M_AST(s2, REG_ITMP1, 0);
2093 var_to_reg_flt(s2, src, REG_FTMP2);
2094 M_FST(s2, REG_ITMP1, 0);
2097 var_to_reg_flt(s2, src, REG_FTMP2);
2098 M_DST(s2, REG_ITMP1, 0);
2100 default: panic ("internal error");
2104 case ICMD_GETSTATIC: /* ... ==> ..., value */
2105 /* op1 = type, val.a = field address */
2107 a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value));
2108 M_ALD(REG_ITMP1, REG_PV, a);
2109 switch (iptr->op1) {
2111 d = reg_of_var(iptr->dst, REG_ITMP3);
2112 M_ILD(d, REG_ITMP1, 0);
2113 store_reg_to_var_int(iptr->dst, d);
2116 d = reg_of_var(iptr->dst, REG_ITMP3);
2117 M_LLD(d, REG_ITMP1, 0);
2118 store_reg_to_var_int(iptr->dst, d);
2121 d = reg_of_var(iptr->dst, REG_ITMP3);
2122 M_ALD(d, REG_ITMP1, 0);
2123 store_reg_to_var_int(iptr->dst, d);
2126 d = reg_of_var(iptr->dst, REG_FTMP1);
2127 M_FLD(d, REG_ITMP1, 0);
2128 store_reg_to_var_flt(iptr->dst, d);
2131 d = reg_of_var(iptr->dst, REG_FTMP1);
2132 M_DLD(d, REG_ITMP1, 0);
2133 store_reg_to_var_flt(iptr->dst, d);
2135 default: panic ("internal error");
2140 case ICMD_PUTFIELD: /* ..., value ==> ... */
2141 /* op1 = type, val.i = field offset */
2143 a = ((fieldinfo *)(iptr->val.a))->offset;
2144 switch (iptr->op1) {
2146 var_to_reg_int(s1, src->prev, REG_ITMP1);
2147 var_to_reg_int(s2, src, REG_ITMP2);
2148 gen_nullptr_check(s1);
2152 var_to_reg_int(s1, src->prev, REG_ITMP1);
2153 var_to_reg_int(s2, src, REG_ITMP2);
2154 gen_nullptr_check(s1);
2158 var_to_reg_int(s1, src->prev, REG_ITMP1);
2159 var_to_reg_int(s2, src, REG_ITMP2);
2160 gen_nullptr_check(s1);
2164 var_to_reg_int(s1, src->prev, REG_ITMP1);
2165 var_to_reg_flt(s2, src, REG_FTMP2);
2166 gen_nullptr_check(s1);
2170 var_to_reg_int(s1, src->prev, REG_ITMP1);
2171 var_to_reg_flt(s2, src, REG_FTMP2);
2172 gen_nullptr_check(s1);
2175 default: panic ("internal error");
2179 case ICMD_GETFIELD: /* ... ==> ..., value */
2180 /* op1 = type, val.i = field offset */
2182 a = ((fieldinfo *)(iptr->val.a))->offset;
2183 switch (iptr->op1) {
2185 var_to_reg_int(s1, src, REG_ITMP1);
2186 d = reg_of_var(iptr->dst, REG_ITMP3);
2187 gen_nullptr_check(s1);
2189 store_reg_to_var_int(iptr->dst, d);
2192 var_to_reg_int(s1, src, REG_ITMP1);
2193 d = reg_of_var(iptr->dst, REG_ITMP3);
2194 gen_nullptr_check(s1);
2196 store_reg_to_var_int(iptr->dst, d);
2199 var_to_reg_int(s1, src, REG_ITMP1);
2200 d = reg_of_var(iptr->dst, REG_ITMP3);
2201 gen_nullptr_check(s1);
2203 store_reg_to_var_int(iptr->dst, d);
2206 var_to_reg_int(s1, src, REG_ITMP1);
2207 d = reg_of_var(iptr->dst, REG_FTMP1);
2208 gen_nullptr_check(s1);
2210 store_reg_to_var_flt(iptr->dst, d);
2213 var_to_reg_int(s1, src, REG_ITMP1);
2214 d = reg_of_var(iptr->dst, REG_FTMP1);
2215 gen_nullptr_check(s1);
2217 store_reg_to_var_flt(iptr->dst, d);
2219 default: panic ("internal error");
2224 /* branch operations **************************************************/
2226 #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}}
2228 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2230 var_to_reg_int(s1, src, REG_ITMP1);
2231 M_INTMOVE(s1, REG_ITMP1_XPTR);
2232 a = dseg_addaddress(asm_handle_exception);
2233 M_ALD(REG_ITMP2, REG_PV, a);
2234 M_JSR(REG_ITMP2_XPC, REG_ITMP2);
2239 case ICMD_GOTO: /* ... ==> ... */
2240 /* op1 = target JavaVM pc */
2242 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2247 case ICMD_JSR: /* ... ==> ... */
2248 /* op1 = target JavaVM pc */
2250 dseg_addtarget(BlockPtrOfPC(iptr->op1));
2251 M_ALD(REG_ITMP1, REG_PV, -dseglen);
2252 M_JSR(REG_ITMP1, REG_ITMP1); /* REG_ITMP1 = return address */
2256 case ICMD_RET: /* ... ==> ... */
2257 /* op1 = local variable */
2258 var = &(locals[iptr->op1][TYPE_ADR]);
2259 if (var->flags & INMEMORY) {
2260 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2269 case ICMD_IFNULL: /* ..., value ==> ... */
2270 /* op1 = target JavaVM pc */
2272 var_to_reg_int(s1, src, REG_ITMP1);
2274 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2278 case ICMD_IFNONNULL: /* ..., value ==> ... */
2279 /* op1 = target JavaVM pc */
2281 var_to_reg_int(s1, src, REG_ITMP1);
2283 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2287 case ICMD_IFEQ: /* ..., value ==> ... */
2288 /* op1 = target JavaVM pc, val.i = constant */
2290 var_to_reg_int(s1, src, REG_ITMP1);
2291 if (iptr->val.i == 0) {
2295 ICONST(REG_ITMP2, iptr->val.i);
2296 M_BEQ(s1, REG_ITMP2, 0);
2298 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2302 case ICMD_IFLT: /* ..., value ==> ... */
2303 /* op1 = target JavaVM pc, val.i = constant */
2305 var_to_reg_int(s1, src, REG_ITMP1);
2306 if (iptr->val.i == 0) {
2310 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
2311 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2314 ICONST(REG_ITMP2, iptr->val.i);
2315 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2317 M_BNEZ(REG_ITMP1, 0);
2319 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2323 case ICMD_IFLE: /* ..., value ==> ... */
2324 /* op1 = target JavaVM pc, val.i = constant */
2326 var_to_reg_int(s1, src, REG_ITMP1);
2327 if (iptr->val.i == 0) {
2331 if ((iptr->val.i >= -32769) && (iptr->val.i <= 32766)) {
2332 M_CMPLT_IMM(s1, iptr->val.i + 1, REG_ITMP1);
2333 M_BNEZ(REG_ITMP1, 0);
2336 ICONST(REG_ITMP2, iptr->val.i);
2337 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2338 M_BEQZ(REG_ITMP1, 0);
2341 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2345 case ICMD_IFNE: /* ..., value ==> ... */
2346 /* op1 = target JavaVM pc, val.i = constant */
2348 var_to_reg_int(s1, src, REG_ITMP1);
2349 if (iptr->val.i == 0) {
2353 ICONST(REG_ITMP2, iptr->val.i);
2354 M_BNE(s1, REG_ITMP2, 0);
2356 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2360 case ICMD_IFGT: /* ..., value ==> ... */
2361 /* op1 = target JavaVM pc, val.i = constant */
2363 var_to_reg_int(s1, src, REG_ITMP1);
2364 if (iptr->val.i == 0) {
2368 if ((iptr->val.i >= -32769) && (iptr->val.i <= 32766)) {
2369 M_CMPLT_IMM(s1, iptr->val.i + 1, REG_ITMP1);
2370 M_BEQZ(REG_ITMP1, 0);
2373 ICONST(REG_ITMP2, iptr->val.i);
2374 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2375 M_BNEZ(REG_ITMP1, 0);
2378 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2382 case ICMD_IFGE: /* ..., 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 >= -32768) && (iptr->val.i <= 32767)) {
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_BEQZ(REG_ITMP1, 0);
2399 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2403 case ICMD_IF_LEQ: /* ..., value ==> ... */
2404 /* op1 = target JavaVM pc, val.l = constant */
2406 var_to_reg_int(s1, src, REG_ITMP1);
2407 if (iptr->val.l == 0) {
2411 LCONST(REG_ITMP2, iptr->val.l);
2412 M_BEQ(s1, REG_ITMP2, 0);
2414 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2418 case ICMD_IF_LLT: /* ..., value ==> ... */
2419 /* op1 = target JavaVM pc, val.l = constant */
2421 var_to_reg_int(s1, src, REG_ITMP1);
2422 if (iptr->val.l == 0) {
2426 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2427 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2430 LCONST(REG_ITMP2, iptr->val.l);
2431 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2433 M_BNEZ(REG_ITMP1, 0);
2435 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2439 case ICMD_IF_LLE: /* ..., value ==> ... */
2440 /* op1 = target JavaVM pc, val.l = constant */
2442 var_to_reg_int(s1, src, REG_ITMP1);
2443 if (iptr->val.l == 0) {
2447 if ((iptr->val.l >= -32769) && (iptr->val.l <= 32766)) {
2448 M_CMPLT_IMM(s1, iptr->val.l + 1, REG_ITMP1);
2449 M_BNEZ(REG_ITMP1, 0);
2452 LCONST(REG_ITMP2, iptr->val.l);
2453 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2454 M_BEQZ(REG_ITMP1, 0);
2457 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2461 case ICMD_IF_LNE: /* ..., value ==> ... */
2462 /* op1 = target JavaVM pc, val.l = constant */
2464 var_to_reg_int(s1, src, REG_ITMP1);
2465 if (iptr->val.l == 0) {
2469 LCONST(REG_ITMP2, iptr->val.l);
2470 M_BNE(s1, REG_ITMP2, 0);
2472 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2476 case ICMD_IF_LGT: /* ..., value ==> ... */
2477 /* op1 = target JavaVM pc, val.l = constant */
2479 var_to_reg_int(s1, src, REG_ITMP1);
2480 if (iptr->val.l == 0) {
2484 if ((iptr->val.l >= -32769) && (iptr->val.l <= 32766)) {
2485 M_CMPLT_IMM(s1, iptr->val.l + 1, REG_ITMP1);
2486 M_BEQZ(REG_ITMP1, 0);
2489 LCONST(REG_ITMP2, iptr->val.l);
2490 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2491 M_BNEZ(REG_ITMP1, 0);
2494 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2498 case ICMD_IF_LGE: /* ..., value ==> ... */
2499 /* op1 = target JavaVM pc, val.l = constant */
2501 var_to_reg_int(s1, src, REG_ITMP1);
2502 if (iptr->val.l == 0) {
2506 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2507 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2510 LCONST(REG_ITMP2, iptr->val.l);
2511 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2513 M_BEQZ(REG_ITMP1, 0);
2515 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2519 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2520 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2521 case ICMD_IF_ACMPEQ:
2523 var_to_reg_int(s1, src->prev, REG_ITMP1);
2524 var_to_reg_int(s2, src, REG_ITMP2);
2526 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2530 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2531 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2532 case ICMD_IF_ACMPNE:
2534 var_to_reg_int(s1, src->prev, REG_ITMP1);
2535 var_to_reg_int(s2, src, REG_ITMP2);
2537 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2541 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2542 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2544 var_to_reg_int(s1, src->prev, REG_ITMP1);
2545 var_to_reg_int(s2, src, REG_ITMP2);
2546 M_CMPLT(s1, s2, REG_ITMP1);
2547 M_BNEZ(REG_ITMP1, 0);
2548 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2552 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2553 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2555 var_to_reg_int(s1, src->prev, REG_ITMP1);
2556 var_to_reg_int(s2, src, REG_ITMP2);
2557 M_CMPGT(s1, s2, REG_ITMP1);
2558 M_BNEZ(REG_ITMP1, 0);
2559 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2563 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2564 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2566 var_to_reg_int(s1, src->prev, REG_ITMP1);
2567 var_to_reg_int(s2, src, REG_ITMP2);
2568 M_CMPGT(s1, s2, REG_ITMP1);
2569 M_BEQZ(REG_ITMP1, 0);
2570 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2574 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2575 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2577 var_to_reg_int(s1, src->prev, REG_ITMP1);
2578 var_to_reg_int(s2, src, REG_ITMP2);
2579 M_CMPLT(s1, s2, REG_ITMP1);
2580 M_BEQZ(REG_ITMP1, 0);
2581 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2585 #ifdef CONDITIONAL_LOADCONST
2586 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2588 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2591 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2592 /* val.i = constant */
2594 var_to_reg_int(s1, src, REG_ITMP1);
2595 d = reg_of_var(iptr->dst, REG_ITMP3);
2597 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2598 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2599 M_CMPEQ(s1, REG_ZERO, d);
2600 store_reg_to_var_int(iptr->dst, d);
2603 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2604 M_CMPEQ(s1, REG_ZERO, d);
2606 store_reg_to_var_int(iptr->dst, d);
2610 M_MOV(s1, REG_ITMP1);
2613 ICONST(d, iptr[1].val.i);
2615 if ((s3 >= 0) && (s3 <= 255)) {
2616 M_CMOVEQ_IMM(s1, s3, d);
2619 ICONST(REG_ITMP2, s3);
2620 M_CMOVEQ(s1, REG_ITMP2, d);
2622 store_reg_to_var_int(iptr->dst, d);
2625 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2626 /* val.i = constant */
2628 var_to_reg_int(s1, src, REG_ITMP1);
2629 d = reg_of_var(iptr->dst, REG_ITMP3);
2631 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2632 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2633 M_CMPEQ(s1, REG_ZERO, d);
2634 store_reg_to_var_int(iptr->dst, d);
2637 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2638 M_CMPEQ(s1, REG_ZERO, d);
2640 store_reg_to_var_int(iptr->dst, d);
2644 M_MOV(s1, REG_ITMP1);
2647 ICONST(d, iptr[1].val.i);
2649 if ((s3 >= 0) && (s3 <= 255)) {
2650 M_CMOVNE_IMM(s1, s3, d);
2653 ICONST(REG_ITMP2, s3);
2654 M_CMOVNE(s1, REG_ITMP2, d);
2656 store_reg_to_var_int(iptr->dst, d);
2659 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2660 /* val.i = constant */
2662 var_to_reg_int(s1, src, REG_ITMP1);
2663 d = reg_of_var(iptr->dst, REG_ITMP3);
2665 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2666 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2667 M_CMPLT(s1, REG_ZERO, d);
2668 store_reg_to_var_int(iptr->dst, d);
2671 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2672 M_CMPLE(REG_ZERO, s1, d);
2673 store_reg_to_var_int(iptr->dst, d);
2677 M_MOV(s1, REG_ITMP1);
2680 ICONST(d, iptr[1].val.i);
2682 if ((s3 >= 0) && (s3 <= 255)) {
2683 M_CMOVLT_IMM(s1, s3, d);
2686 ICONST(REG_ITMP2, s3);
2687 M_CMOVLT(s1, REG_ITMP2, d);
2689 store_reg_to_var_int(iptr->dst, d);
2692 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2693 /* val.i = constant */
2695 var_to_reg_int(s1, src, REG_ITMP1);
2696 d = reg_of_var(iptr->dst, REG_ITMP3);
2698 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2699 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2700 M_CMPLE(REG_ZERO, s1, d);
2701 store_reg_to_var_int(iptr->dst, d);
2704 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2705 M_CMPLT(s1, REG_ZERO, d);
2706 store_reg_to_var_int(iptr->dst, d);
2710 M_MOV(s1, REG_ITMP1);
2713 ICONST(d, iptr[1].val.i);
2715 if ((s3 >= 0) && (s3 <= 255)) {
2716 M_CMOVGE_IMM(s1, s3, d);
2719 ICONST(REG_ITMP2, s3);
2720 M_CMOVGE(s1, REG_ITMP2, d);
2722 store_reg_to_var_int(iptr->dst, d);
2725 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2726 /* val.i = constant */
2728 var_to_reg_int(s1, src, REG_ITMP1);
2729 d = reg_of_var(iptr->dst, REG_ITMP3);
2731 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2732 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2733 M_CMPLT(REG_ZERO, s1, d);
2734 store_reg_to_var_int(iptr->dst, d);
2737 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2738 M_CMPLE(s1, REG_ZERO, d);
2739 store_reg_to_var_int(iptr->dst, d);
2743 M_MOV(s1, REG_ITMP1);
2746 ICONST(d, iptr[1].val.i);
2748 if ((s3 >= 0) && (s3 <= 255)) {
2749 M_CMOVGT_IMM(s1, s3, d);
2752 ICONST(REG_ITMP2, s3);
2753 M_CMOVGT(s1, REG_ITMP2, d);
2755 store_reg_to_var_int(iptr->dst, d);
2758 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2759 /* val.i = constant */
2761 var_to_reg_int(s1, src, REG_ITMP1);
2762 d = reg_of_var(iptr->dst, REG_ITMP3);
2764 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2765 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2766 M_CMPLE(s1, REG_ZERO, d);
2767 store_reg_to_var_int(iptr->dst, d);
2770 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2771 M_CMPLT(REG_ZERO, s1, d);
2772 store_reg_to_var_int(iptr->dst, d);
2776 M_MOV(s1, REG_ITMP1);
2779 ICONST(d, iptr[1].val.i);
2781 if ((s3 >= 0) && (s3 <= 255)) {
2782 M_CMOVLE_IMM(s1, s3, d);
2785 ICONST(REG_ITMP2, s3);
2786 M_CMOVLE(s1, REG_ITMP2, d);
2788 store_reg_to_var_int(iptr->dst, d);
2793 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2798 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2800 a = dseg_addaddress ((void*) (builtin_monitorexit));
2801 M_ALD(REG_ITMP3, REG_PV, a);
2802 M_JSR(REG_RA, REG_ITMP3);
2803 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse); /* delay slot */
2804 disp = -(int)((u1*) mcodeptr - mcodebase);
2805 M_LDA(REG_PV, REG_RA, disp);
2808 var_to_reg_int(s1, src, REG_RESULT);
2809 M_INTMOVE(s1, REG_RESULT);
2810 goto nowperformreturn;
2812 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2816 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2818 a = dseg_addaddress ((void*) (builtin_monitorexit));
2819 M_ALD(REG_ITMP3, REG_PV, a);
2820 M_JSR(REG_RA, REG_ITMP3);
2821 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse); /* delay slot */
2822 disp = -(int)((u1*) mcodeptr - mcodebase);
2823 M_LDA(REG_PV, REG_RA, disp);
2826 var_to_reg_flt(s1, src, REG_FRESULT);
2828 int t = ((iptr->opc == ICMD_FRETURN) ? TYPE_FLT : TYPE_DBL);
2829 M_TFLTMOVE(t, s1, REG_FRESULT);
2831 goto nowperformreturn;
2833 case ICMD_RETURN: /* ... ==> ... */
2836 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2838 a = dseg_addaddress ((void*) (builtin_monitorexit));
2839 M_ALD(REG_ITMP3, REG_PV, a);
2840 M_JSR(REG_RA, REG_ITMP3);
2841 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse); /* delay slot */
2842 disp = -(int)((u1*) mcodeptr - mcodebase);
2843 M_LDA(REG_PV, REG_RA, disp);
2851 p = parentargs_base;
2853 /* restore return address */
2856 {p--; M_LLD (REG_RA, REG_SP, 8 * p);}
2858 /* restore saved registers */
2860 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
2861 {p--; M_LLD(savintregs[r], REG_SP, 8 * p);}
2862 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
2863 {p--; M_DLD(savfltregs[r], REG_SP, 8 * p);}
2865 /* call trace function */
2868 M_LDA (REG_SP, REG_SP, -24);
2869 M_LST(REG_RA, REG_SP, 0);
2870 M_LST(REG_RESULT, REG_SP, 8);
2871 M_DST(REG_FRESULT, REG_SP,16);
2872 a = dseg_addaddress (method);
2873 M_ALD(argintregs[0], REG_PV, a);
2874 M_MOV(REG_RESULT, argintregs[1]);
2875 M_FLTMOVE(REG_FRESULT, argfltregs[2]);
2876 M_FMOV(REG_FRESULT, argfltregs[3]);
2877 a = dseg_addaddress ((void*) (builtin_displaymethodstop));
2878 M_ALD(REG_ITMP3, REG_PV, a);
2879 M_JSR (REG_RA, REG_ITMP3);
2881 M_DLD(REG_FRESULT, REG_SP,16);
2882 M_LLD(REG_RESULT, REG_SP, 8);
2883 M_LLD(REG_RA, REG_SP, 0);
2884 M_LDA (REG_SP, REG_SP, 24);
2889 /* deallocate stack */
2891 if (parentargs_base)
2892 {M_LDA(REG_SP, REG_SP, parentargs_base*8);}
2900 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2905 tptr = (void **) iptr->target;
2907 s4ptr = iptr->val.a;
2908 l = s4ptr[1]; /* low */
2909 i = s4ptr[2]; /* high */
2911 var_to_reg_int(s1, src, REG_ITMP1);
2913 {M_INTMOVE(s1, REG_ITMP1);}
2914 else if (l <= 32768) {
2915 M_IADD_IMM(s1, -l, REG_ITMP1);
2918 ICONST(REG_ITMP2, l);
2919 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2925 M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
2926 M_BEQZ(REG_ITMP2, 0);
2927 mcode_addreference((basicblock *) tptr[0], mcodeptr);
2928 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1); /* delay slot*/
2930 /* build jump table top down and use address of lowest entry */
2932 /* s4ptr += 3 + i; */
2936 /* dseg_addtarget(BlockPtrOfPC(*--s4ptr)); */
2937 dseg_addtarget((basicblock *) tptr[0]);
2942 /* length of dataseg after last dseg_addtarget is used by load */
2944 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2945 M_ALD(REG_ITMP2, REG_ITMP2, -dseglen);
2952 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2954 s4 i, l, val, *s4ptr;
2957 tptr = (void **) iptr->target;
2959 s4ptr = iptr->val.a;
2960 l = s4ptr[0]; /* default */
2961 i = s4ptr[1]; /* count */
2963 MCODECHECK((i<<2)+8);
2964 var_to_reg_int(s1, src, REG_ITMP1);
2970 ICONST(REG_ITMP2, val);
2971 M_BEQ(s1, REG_ITMP2, 0);
2972 mcode_addreference((basicblock *) tptr[0], mcodeptr);
2977 tptr = (void **) iptr->target;
2978 mcode_addreference((basicblock *) tptr[0], mcodeptr);
2985 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
2986 /* op1 = return type, val.a = function pointer*/
2990 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
2991 /* op1 = return type, val.a = function pointer*/
2995 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
2996 /* op1 = return type, val.a = function pointer*/
3000 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3001 /* op1 = arg count, val.a = method pointer */
3003 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3004 /* op1 = arg count, val.a = method pointer */
3006 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3007 /* op1 = arg count, val.a = method pointer */
3009 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
3010 /* op1 = arg count, val.a = method pointer */
3018 MCODECHECK((s3 << 1) + 64);
3020 /* copy arguments to registers or stack location */
3022 for (; --s3 >= 0; src = src->prev) {
3023 if (src->varkind == ARGVAR)
3025 if (IS_INT_LNG_TYPE(src->type)) {
3026 if (s3 < INT_ARG_CNT) {
3027 s1 = argintregs[s3];
3028 var_to_reg_int(d, src, s1);
3032 var_to_reg_int(d, src, REG_ITMP1);
3033 M_LST(d, REG_SP, 8 * (s3 - INT_ARG_CNT));
3037 if (s3 < FLT_ARG_CNT) {
3038 s1 = argfltregs[s3];
3039 var_to_reg_flt(d, src, s1);
3040 M_TFLTMOVE(src->type,d, s1);
3043 var_to_reg_flt(d, src, REG_FTMP1);
3044 M_DST(d, REG_SP, 8 * (s3 - FLT_ARG_CNT));
3049 switch (iptr->opc) {
3053 a = dseg_addaddress ((void*) (m));
3054 M_ALD(REG_ITMP3, REG_PV, a); /* built-in-function pointer */
3055 M_JSR (REG_RA, REG_ITMP3);
3057 d = iptr->op1; /* return type */
3058 goto afteractualcall;
3060 case ICMD_INVOKESTATIC:
3061 case ICMD_INVOKESPECIAL:
3062 a = dseg_addaddress (m->stubroutine);
3064 M_ALD(REG_PV, REG_PV, a ); /* method pointer in pv */
3067 goto makeactualcall;
3069 case ICMD_INVOKEVIRTUAL:
3071 gen_nullptr_check(argintregs[0]);
3072 M_ALD(REG_METHODPTR, argintregs[0],
3073 OFFSET(java_objectheader, vftbl));
3074 M_ALD(REG_PV, REG_METHODPTR, OFFSET(vftbl, table[0]) +
3075 sizeof(methodptr) * m->vftblindex);
3078 goto makeactualcall;
3080 case ICMD_INVOKEINTERFACE:
3083 gen_nullptr_check(argintregs[0]);
3084 M_ALD(REG_METHODPTR, argintregs[0],
3085 OFFSET(java_objectheader, vftbl));
3086 M_ALD(REG_METHODPTR, REG_METHODPTR,
3087 OFFSET(vftbl, interfacetable[0]) -
3088 sizeof(methodptr*) * ci->index);
3089 M_ALD(REG_PV, REG_METHODPTR,
3090 sizeof(methodptr) * (m - ci->methods));
3093 goto makeactualcall;
3097 sprintf (logtext, "Unkown ICMD-Command: %d", iptr->opc);
3103 M_JSR (REG_RA, REG_PV);
3110 s1 = (int)((u1*) mcodeptr - mcodebase);
3111 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
3114 while (ml<-32768) { ml+=65536; mh--; }
3116 M_IADD_IMM(REG_PV, ml, REG_PV);
3117 M_LADD(REG_PV, REG_RA, REG_PV);
3120 /* d contains return type */
3122 if (d != TYPE_VOID) {
3123 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3124 s1 = reg_of_var(iptr->dst, REG_RESULT);
3125 M_INTMOVE(REG_RESULT, s1);
3126 store_reg_to_var_int(iptr->dst, s1);
3129 s1 = reg_of_var(iptr->dst, REG_FRESULT);
3130 M_TFLTMOVE(iptr->dst->type, REG_FRESULT, s1);
3131 store_reg_to_var_flt(iptr->dst, s1);
3138 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3140 /* op1: 0 == array, 1 == class */
3141 /* val.a: (classinfo*) superclass */
3143 /* superclass is an interface:
3145 * return (sub != NULL) &&
3146 * (sub->vftbl->interfacetablelength > super->index) &&
3147 * (sub->vftbl->interfacetable[-super->index] != NULL);
3149 * superclass is a class:
3151 * return ((sub != NULL) && (0
3152 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3153 * super->vftbl->diffvall));
3157 classinfo *super = (classinfo*) iptr->val.a;
3159 var_to_reg_int(s1, src, REG_ITMP1);
3160 d = reg_of_var(iptr->dst, REG_ITMP3);
3162 M_MOV(s1, REG_ITMP1);
3166 if (iptr->op1) { /* class/interface */
3167 if (super->flags & ACC_INTERFACE) { /* interface */
3170 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3171 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3172 M_IADD_IMM(REG_ITMP2, - super->index, REG_ITMP2);
3173 M_BLEZ(REG_ITMP2, 3);
3175 M_ALD(REG_ITMP1, REG_ITMP1,
3176 OFFSET(vftbl, interfacetable[0]) -
3177 super->index * sizeof(methodptr*));
3178 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3182 s2 = super->vftbl->diffval;
3185 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3186 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3187 M_IADD_IMM(REG_ITMP1, - super->vftbl->baseval, REG_ITMP1);
3188 M_CMPULT_IMM(REG_ITMP1, s2 + 1, d);
3193 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3194 a = dseg_addaddress ((void*) super->vftbl);
3195 M_ALD(REG_ITMP2, REG_PV, a);
3196 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3197 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl, baseval));
3198 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, diffval));
3199 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3200 M_CMPULT(REG_ITMP2, REG_ITMP1, d);
3206 panic ("internal error: no inlined array instanceof");
3208 store_reg_to_var_int(iptr->dst, d);
3211 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3213 /* op1: 0 == array, 1 == class */
3214 /* val.a: (classinfo*) superclass */
3216 /* superclass is an interface:
3218 * OK if ((sub == NULL) ||
3219 * (sub->vftbl->interfacetablelength > super->index) &&
3220 * (sub->vftbl->interfacetable[-super->index] != NULL));
3222 * superclass is a class:
3224 * OK if ((sub == NULL) || (0
3225 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3226 * super->vftbl->diffvall));
3230 classinfo *super = (classinfo*) iptr->val.a;
3232 d = reg_of_var(iptr->dst, REG_ITMP3);
3233 var_to_reg_int(s1, src, d);
3234 if (iptr->op1) { /* class/interface */
3235 if (super->flags & ACC_INTERFACE) { /* interface */
3238 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3239 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3240 M_IADD_IMM(REG_ITMP2, - super->index, REG_ITMP2);
3241 M_BLEZ(REG_ITMP2, 0);
3242 mcode_addxcastrefs(mcodeptr);
3244 M_ALD(REG_ITMP2, REG_ITMP1,
3245 OFFSET(vftbl, interfacetable[0]) -
3246 super->index * sizeof(methodptr*));
3247 M_BEQZ(REG_ITMP2, 0);
3248 mcode_addxcastrefs(mcodeptr);
3254 s2 = super->vftbl->diffval;
3255 M_BEQZ(s1, 6 + (s2 != 0));
3257 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3258 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3259 M_IADD_IMM(REG_ITMP1, - super->vftbl->baseval, REG_ITMP1);
3261 M_BNEZ(REG_ITMP1, 0);
3264 M_CMPULT_IMM(REG_ITMP1, s2 + 1, REG_ITMP2);
3265 M_BEQZ(REG_ITMP2, 0);
3269 M_BEQZ(s1, 10 + (d == REG_ITMP3));
3271 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3272 a = dseg_addaddress ((void*) super->vftbl);
3273 M_ALD(REG_ITMP2, REG_PV, a);
3274 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3275 if (d != REG_ITMP3) {
3276 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl, baseval));
3277 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, diffval));
3278 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3280 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, baseval));
3281 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3282 M_ALD(REG_ITMP2, REG_PV, a);
3283 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, diffval));
3285 M_CMPULT(REG_ITMP2, REG_ITMP1, REG_ITMP2);
3286 M_BNEZ(REG_ITMP2, 0);
3288 mcode_addxcastrefs(mcodeptr);
3293 panic ("internal error: no inlined array checkcast");
3296 store_reg_to_var_int(iptr->dst, d);
3299 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
3301 var_to_reg_int(s1, src, REG_ITMP1);
3303 mcode_addxcheckarefs(mcodeptr);
3307 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3308 /* op1 = dimension, val.a = array descriptor */
3310 /* check for negative sizes and copy sizes to stack if necessary */
3312 MCODECHECK((iptr->op1 << 1) + 64);
3314 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3315 var_to_reg_int(s2, src, REG_ITMP1);
3317 mcode_addxcheckarefs(mcodeptr);
3320 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
3322 if (src->varkind != ARGVAR) {
3323 M_LST(s2, REG_SP, 8 * (s1 + INT_ARG_CNT));
3327 /* a0 = dimension count */
3329 ICONST(argintregs[0], iptr->op1);
3331 /* a1 = arraydescriptor */
3333 a = dseg_addaddress(iptr->val.a);
3334 M_ALD(argintregs[1], REG_PV, a);
3336 /* a2 = pointer to dimensions = stack pointer */
3338 M_INTMOVE(REG_SP, argintregs[2]);
3340 a = dseg_addaddress((void*) (builtin_nmultianewarray));
3341 M_ALD(REG_ITMP3, REG_PV, a);
3342 M_JSR(REG_RA, REG_ITMP3);
3344 s1 = (int)((u1*) mcodeptr - mcodebase);
3346 M_LDA (REG_PV, REG_RA, -s1);
3350 s1 = reg_of_var(iptr->dst, REG_RESULT);
3351 M_INTMOVE(REG_RESULT, s1);
3352 store_reg_to_var_int(iptr->dst, s1);
3356 default: sprintf (logtext, "Unknown pseudo command: %d", iptr->opc);
3363 } /* for instruction */
3365 /* copy values to interface registers */
3367 src = bptr->outstack;
3368 len = bptr->outdepth;
3372 if ((src->varkind != STACKVAR)) {
3374 if (IS_FLT_DBL_TYPE(s2)) {
3375 var_to_reg_flt(s1, src, REG_FTMP1);
3376 if (!(interfaces[len][s2].flags & INMEMORY)) {
3377 M_TFLTMOVE(s2,s1,interfaces[len][s2].regoff);
3380 M_DST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3384 var_to_reg_int(s1, src, REG_ITMP1);
3385 if (!(interfaces[len][s2].flags & INMEMORY)) {
3386 M_INTMOVE(s1,interfaces[len][s2].regoff);
3389 M_LST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3395 } /* if (bptr -> flags >= BBREACHED) */
3396 } /* for basic block */
3398 /* bptr -> mpc = (int)((u1*) mcodeptr - mcodebase); */
3401 /* generate bound check stubs */
3403 s4 *xcodeptr = NULL;
3405 for (; xboundrefs != NULL; xboundrefs = xboundrefs->next) {
3406 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3407 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
3408 xboundrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3413 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
3414 xboundrefs->branchpos, (u1*) mcodeptr - mcodebase);
3418 M_LDA(REG_ITMP2_XPC, REG_PV, xboundrefs->branchpos - 4);
3420 if (xcodeptr != NULL) {
3421 int disp = xcodeptr-mcodeptr;
3426 xcodeptr = mcodeptr;
3428 a = dseg_addaddress(asm_handle_exception);
3429 M_ALD(REG_ITMP3, REG_PV, a);
3432 a = dseg_addaddress(proto_java_lang_ArrayIndexOutOfBoundsException);
3433 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3437 /* generate negative array size check stubs */
3441 for (; xcheckarefs != NULL; xcheckarefs = xcheckarefs->next) {
3442 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3443 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3444 xcheckarefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3448 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3449 xcheckarefs->branchpos, (u1*) mcodeptr - mcodebase);
3453 M_LDA(REG_ITMP2_XPC, REG_PV, xcheckarefs->branchpos - 4);
3455 if (xcodeptr != NULL) {
3456 int disp = xcodeptr-mcodeptr;
3461 xcodeptr = mcodeptr;
3463 a = dseg_addaddress(asm_handle_exception);
3464 M_ALD(REG_ITMP3, REG_PV, a);
3467 a = dseg_addaddress(proto_java_lang_NegativeArraySizeException);
3468 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3472 /* generate cast check stubs */
3476 for (; xcastrefs != NULL; xcastrefs = xcastrefs->next) {
3477 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3478 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3479 xcastrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3483 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3484 xcastrefs->branchpos, (u1*) mcodeptr - mcodebase);
3488 M_LDA(REG_ITMP2_XPC, REG_PV, xcastrefs->branchpos - 4);
3490 if (xcodeptr != NULL) {
3491 int disp = xcodeptr-mcodeptr;
3496 xcodeptr = mcodeptr;
3498 a = dseg_addaddress(asm_handle_exception);
3499 M_ALD(REG_ITMP3, REG_PV, a);
3502 a = dseg_addaddress(proto_java_lang_ClassCastException);
3503 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3508 #ifdef SOFTNULLPTRCHECK
3510 /* generate null pointer check stubs */
3514 for (; xnullrefs != NULL; xnullrefs = xnullrefs->next) {
3515 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3516 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3517 xnullrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3521 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3522 xnullrefs->branchpos, (u1*) mcodeptr - mcodebase);
3526 M_LDA(REG_ITMP2_XPC, REG_PV, xnullrefs->branchpos - 4);
3528 if (xcodeptr != NULL) {
3529 int disp = xcodeptr-mcodeptr;
3534 xcodeptr = mcodeptr;
3536 a = dseg_addaddress(asm_handle_exception);
3537 M_ALD(REG_ITMP3, REG_PV, a);
3540 a = dseg_addaddress(proto_java_lang_NullPointerException);
3541 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3548 mcode_finish((int)((u1*) mcodeptr - mcodebase));
3550 docacheflush((void*) method->entrypoint,
3551 ((u1*) mcodeptr - mcodebase), ICACHE);
3555 /* redefinition of code generation macros (compiling into array) **************/
3558 These macros are newly defined to allow code generation into an array.
3559 This is necessary, because the original M_.. macros generate code by
3560 calling 'mcode_adds4' that uses an additional data structure to
3563 For a faster (but less flexible) version to generate code, these
3564 macros directly use the (s4* p) - pointer to put the code directly
3565 in a locally defined array.
3566 This makes sense only for the stub-generation-routines below.
3570 #define M_ITYPE(op, rs, rt, imm)\
3571 *(p++) = (((op)<<26)|((rs)<<21)|((rt)<<16)|((imm)&0xffff))
3574 #define M_JTYPE(op, imm)\
3575 *(p++) = (((op)<<26)|((off)&0x3ffffff))
3578 #define M_RTYPE(op, rs, rt, rd, sa, fu)\
3579 *(p++) = (((op)<<26)|((rs)<<21)|((rt)<<16)|((rd)<<11)|((sa)<<6)|(fu))
3582 /* function createcompilerstub *************************************************
3584 creates a stub routine which calls the compiler
3586 *******************************************************************************/
3588 #define COMPSTUBSIZE 4
3590 u1 *createcompilerstub (methodinfo *m)
3592 u8 *s = CNEW (u8, COMPSTUBSIZE); /* memory to hold the stub */
3593 s4 *p = (s4*) s; /* code generation pointer */
3595 /* code for the stub */
3596 M_ALD(REG_PV, REG_PV, 24); /* load pointer to the compiler */
3598 M_JSR(REG_ITMP1, REG_PV); /* jump to the compiler, return address
3599 in itmp1 is used as method pointer */
3602 s[2] = (u8) m; /* literals to be adressed */
3603 s[3] = (u8) asm_call_jit_compiler; /* jump directly via PV from above */
3605 (void) docacheflush((void*) s, (char*) p - (char*) s, ICACHE);
3608 count_cstub_len += COMPSTUBSIZE * 8;
3615 /* function removecompilerstub *************************************************
3617 deletes a compilerstub from memory (simply by freeing it)
3619 *******************************************************************************/
3621 void removecompilerstub (u1 *stub)
3623 CFREE (stub, COMPSTUBSIZE * 8);
3626 /* function: createnativestub **************************************************
3628 creates a stub routine which calls a native method
3630 *******************************************************************************/
3632 #define NATIVESTUBSIZE 18
3634 u1 *createnativestub (functionptr f, methodinfo *m)
3636 u8 *s = CNEW (u8, NATIVESTUBSIZE); /* memory to hold the stub */
3637 s4 *p = (s4*) s; /* code generation pointer */
3641 M_MOV (argintregs[4], argintregs[5]);
3642 M_DMOV (argfltregs[4], argfltregs[5]);
3644 M_MOV (argintregs[3], argintregs[4]);
3645 M_DMOV (argfltregs[3], argfltregs[4]);
3647 M_MOV (argintregs[2], argintregs[3]);
3648 M_DMOV (argfltregs[2], argfltregs[3]);
3650 M_MOV (argintregs[1], argintregs[2]);
3651 M_DMOV (argfltregs[1], argfltregs[2]);
3653 M_MOV (argintregs[0], argintregs[1]);
3654 M_DMOV (argfltregs[0], argfltregs[1]);
3656 M_ALD (argintregs[0], REG_PV, 17*8); /* load adress of jni_environement */
3658 M_ALD (REG_ITMP3, REG_PV, 14*8); /* load adress of native method */
3659 M_LDA (REG_SP, REG_SP, -8); /* build up stackframe */
3661 M_LST (REG_RA, REG_SP, 0); /* store return address */
3662 M_JSR (REG_RA, REG_ITMP3); /* call native method */
3664 M_NOP; /* delay slot */
3665 M_ALD (REG_ITMP3, REG_PV, 15*8); /* get address of exceptionptr */
3667 M_LLD (REG_RA, REG_SP, 0); /* load return address */
3668 M_ALD (REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
3670 M_BNEZ (REG_ITMP1, 2); /* if no exception then return */
3671 M_LDA (REG_SP, REG_SP, 8); /* remove stackframe, delay slot */
3673 M_RET (REG_RA); /* return to caller */
3674 M_NOP; /* delay slot */
3676 M_AST (REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
3677 M_ALD (REG_ITMP3, REG_PV,16*8); /* load asm exception handler address */
3679 M_JMP (REG_ITMP3); /* jump to asm exception handler */
3680 M_LDA (REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
3683 s[14] = (u8) f; /* address of native method */
3684 s[15] = (u8) (&exceptionptr); /* address of exceptionptr */
3685 s[16]= (u8) (asm_handle_nat_exception); /* addr of asm exception handler */
3686 s[17] = (u8) (&env); /* addr of jni_environement */
3688 (void) docacheflush((void*) s, (char*) p - (char*) s, ICACHE);
3691 count_nstub_len += NATIVESTUBSIZE * 8;
3697 /* function: removenativestub **************************************************
3699 removes a previously created native-stub from memory
3701 *******************************************************************************/
3703 void removenativestub (u1 *stub)
3705 CFREE (stub, NATIVESTUBSIZE * 8);
3709 /* function: createcalljava ****************************************************
3711 creates the asm_calljavamethod (MIPS assembler does not like data in the
3712 text segment). Documentation can be found in asmpart.c.
3714 *******************************************************************************/
3723 #define CALL_JAVA_MEM_SIZE 60
3724 #define CALL_JAVA_ENTRY 20
3725 #define CALL_JAVA_XHANDLER 55
3727 static s4 calljavamem[CALL_JAVA_MEM_SIZE];
3729 void createcalljava ()
3733 *((void**)(calljavamem + 0)) = (void*) asm_call_jit_compiler;
3734 *((void**)(calljavamem + 2)) = (void*) builtin_throw_exception;
3736 *((void**)(calljavamem + 4)) = NULL;
3737 *((void**)(calljavamem + 6)) = (void*) (calljavamem + CALL_JAVA_XHANDLER);
3738 *((void**)(calljavamem + 8)) = (void*) (calljavamem + CALL_JAVA_XHANDLER);
3739 *((void**)(calljavamem +10)) = (void*) (calljavamem + CALL_JAVA_ENTRY);
3741 *((void**)(calljavamem + 8)) = NULL;
3742 *((void**)(calljavamem + 9)) = (void*) (calljavamem + CALL_JAVA_XHANDLER);
3743 *((void**)(calljavamem +10)) = (void*) (calljavamem + CALL_JAVA_XHANDLER);
3744 *((void**)(calljavamem +11)) = (void*) (calljavamem + CALL_JAVA_ENTRY);
3747 calljavamem[12] = 1; /* extable size */
3748 calljavamem[13] = 0; /* fltsave */
3749 calljavamem[14] = 0; /* intsave */
3750 calljavamem[15] = 0; /* isleaf */
3751 calljavamem[16] = 0; /* IsSync */
3752 calljavamem[17] = 80; /* frame size */
3753 calljavamem[18] = 0; /* method pointer (NULL) */
3754 calljavamem[19] = 0; /* method pointer (NULL) */
3756 p = calljavamem + CALL_JAVA_ENTRY; /* code generation pointer */
3759 M_LDA (REG_SP, REG_SP, -10*8); /* allocate stackframe */
3760 M_LST (REG_RA, REG_SP, 0); /* save return address */
3762 M_BRS(1); /* compute current program counter */
3763 M_LST (REG_PV, REG_SP, 3*8); /* save procedure vector */
3765 M_LDA (REG_PV, REG_RA, -4*4); /* compute procedure vector */
3766 M_DST (REG_FSS0, REG_SP, 4*8); /* save non JavaABI saved flt regs */
3768 M_DST (REG_FSS1, REG_SP, 5*8);
3769 M_DST (REG_FSS2, REG_SP, 6*8);
3771 M_DST (REG_FSS3, REG_SP, 7*8);
3772 M_DST (REG_FSS4, REG_SP, 8*8);
3774 M_DST (REG_FSS5, REG_SP, 9*8);
3775 M_LST (REG_ARG_0, REG_SP, 2*8); /* save method pointer for compiler */
3777 M_LDA (REG_ITMP1, REG_SP, 2*8); /* pass pointer to methodptr via itmp1*/
3778 M_MOV (REG_ARG_1, REG_ARG_0); /* pass the remaining parameters */
3780 M_MOV (REG_ARG_2, REG_ARG_1);
3781 M_MOV (REG_ARG_3, REG_ARG_2);
3783 M_MOV (REG_ARG_4, REG_ARG_3);
3784 M_ALD (REG_METHODPTR, REG_PV, -80); /* address of asm_call_jit_compiler */
3786 M_AST (REG_METHODPTR, REG_SP, 8); /* store function address */
3787 M_MOV (REG_SP, REG_METHODPTR); /* set method pointer */
3789 M_ALD (REG_PV, REG_METHODPTR, 8); /* method call as in Java */
3790 M_JSR (REG_RA, REG_PV); /* call JIT compiler */
3792 M_NOP; /* delay slot */
3793 M_LDA (REG_PV, REG_RA, -23*4); /* recompute procedure vector */
3797 M_CLR (REG_RESULT); /* clear return value (exception ptr) */
3801 /* calljava_return: */
3802 M_LLD (REG_RA, REG_SP, 0); /* restore return address */
3804 M_LLD (REG_PV, REG_SP, 3*8); /* restore procedure vector */
3805 M_DLD (REG_FSS0, REG_SP, 4*8); /* restore non JavaABI saved flt regs */
3807 M_DLD (REG_FSS1, REG_SP, 5*8);
3808 M_DLD (REG_FSS2, REG_SP, 6*8);
3810 M_DLD (REG_FSS3, REG_SP, 7*8);
3811 M_DLD (REG_FSS4, REG_SP, 8*8);
3813 M_DLD (REG_FSS5, REG_SP, 9*8);
3814 M_RET(REG_RA); /* return */
3816 M_LDA (REG_SP, REG_SP, 10*8); /* deallocate stackframe (delay slot) */
3819 /* calljava_xhandler: */
3821 M_ALD (REG_ITMP3, REG_PV, -72); /* address of builtin_throw_exception */
3823 M_JSR (REG_RA, REG_ITMP3); /* call builtin */
3824 M_MOV (REG_ITMP1, REG_ARG_0); /* pass parameter (delay slot) */
3826 M_BR(-14); /* branch calljava_return */
3827 M_NOP; /* delay slot */
3829 (void) cacheflush((void*)(calljavamem + CALL_JAVA_ENTRY),
3830 (CALL_JAVA_MEM_SIZE - CALL_JAVA_ENTRY) * (int) sizeof(s4), ICACHE);
3834 typedef java_objectheader* (*asm_fptr)(methodinfo*, void*, void*, void*, void*);
3836 java_objectheader *asm_calljavamethod (methodinfo *m, void *arg1, void *arg2,
3837 void *arg3, void *arg4)
3839 ((asm_fptr)(calljavamem + 20))(m, arg1, arg2, arg3, arg4);
3843 java_objectheader *asm_calljavafunction (methodinfo *m, void *arg1, void *arg2,
3844 void *arg3, void *arg4)
3846 return ((asm_fptr)(calljavamem + 20))(m, arg1, arg2, arg3, arg4);
3854 void docacheflush(u1 *p, long bytelen, int dummy)
3856 u1 *e = p + bytelen;
3857 long psize = sysconf(_SC_PAGESIZE);
3858 p -= (long) p & (psize-1);
3859 e += psize - ((((long) e - 1) & (psize-1)) + 1);
3861 mprotect(p, bytelen, PROT_READ|PROT_WRITE|PROT_EXEC);
3865 * These are local overrides for various environment variables in Emacs.
3866 * Please do not remove this and leave it at the end of the file, where
3867 * Emacs will automagically detect them.
3868 * ---------------------------------------------------------------------
3871 * indent-tabs-mode: t