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/118
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");
230 void init_exceptions(void)
232 /* install signal handlers we need to convert to exceptions */
237 signal(SIGSEGV, (void*) catch_NullPointerException);
241 signal(SIGBUS, (void*) catch_NullPointerException);
247 /* function gen_mcode **********************************************************
249 generates machine code
251 *******************************************************************************/
253 #define MethodPointer -8
254 #define FrameSize -12
259 #define ExTableSize -32
260 #define ExTableStart -32
262 #define ExEntrySize -32
265 #define ExHandlerPC -24
266 #define ExCatchType -32
268 static void gen_mcode()
270 int len, s1, s2, s3, d, bbs;
281 savedregs_num = (isleafmethod) ? 0 : 1; /* space to save the RA */
283 /* space to save used callee saved registers */
285 savedregs_num += (savintregcnt - maxsavintreguse);
286 savedregs_num += (savfltregcnt - maxsavfltreguse);
288 parentargs_base = maxmemuse + savedregs_num;
290 #ifdef USE_THREADS /* space to save argument of monitor_enter */
292 if (checksync && (method->flags & ACC_SYNCHRONIZED))
297 /* create method header */
299 (void) dseg_addaddress(method); /* MethodPointer */
300 (void) dseg_adds4(parentargs_base * 8); /* FrameSize */
304 /* IsSync contains the offset relative to the stack pointer for the
305 argument of monitor_exit used in the exception handler. Since the
306 offset could be zero and give a wrong meaning of the flag it is
310 if (checksync && (method->flags & ACC_SYNCHRONIZED))
311 (void) dseg_adds4((maxmemuse + 1) * 8); /* IsSync */
316 (void) dseg_adds4(0); /* IsSync */
318 (void) dseg_adds4(isleafmethod); /* IsLeaf */
319 (void) dseg_adds4(savintregcnt - maxsavintreguse); /* IntSave */
320 (void) dseg_adds4(savfltregcnt - maxsavfltreguse); /* FltSave */
321 (void) dseg_adds4(exceptiontablelength); /* ExTableSize */
323 /* create exception table */
325 for (len = 0; len < exceptiontablelength; len++) {
326 dseg_addtarget(BlockPtrOfPC(extable[len].startpc));
327 dseg_addtarget(BlockPtrOfPC(extable[len].endpc));
328 dseg_addtarget(BlockPtrOfPC(extable[len].handlerpc));
329 (void) dseg_addaddress(extable[len].catchtype);
332 /* initialize mcode variables */
334 mcodeptr = (s4*) mcodebase;
335 mcodeend = (s4*) (mcodebase + mcodesize);
336 MCODECHECK(128 + mparamcount);
338 /* create stack frame (if necessary) */
341 {M_LDA (REG_SP, REG_SP, -parentargs_base * 8);}
343 /* save return address and used callee saved registers */
347 {p--; M_AST (REG_RA, REG_SP, 8*p);}
348 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
349 {p--; M_LST (savintregs[r], REG_SP, 8 * p);}
350 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
351 {p--; M_DST (savfltregs[r], REG_SP, 8 * p);}
353 /* save monitorenter argument */
356 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
357 if (method->flags & ACC_STATIC) {
358 p = dseg_addaddress (class);
359 M_ALD(REG_ITMP1, REG_PV, p);
360 M_AST(REG_ITMP1, REG_SP, 8 * maxmemuse);
363 M_AST (argintregs[0], REG_SP, 8 * maxmemuse);
368 /* copy argument registers to stack and call trace function with pointer
369 to arguments on stack. ToDo: save floating point registers !!!!!!!!!
372 if (runverbose && isleafmethod) {
373 M_LDA (REG_SP, REG_SP, -(18*8));
375 M_AST(REG_RA, REG_SP, 1*8);
377 M_LST(argintregs[0], REG_SP, 2*8);
378 M_LST(argintregs[1], REG_SP, 3*8);
379 M_LST(argintregs[2], REG_SP, 4*8);
380 M_LST(argintregs[3], REG_SP, 5*8);
381 M_LST(argintregs[4], REG_SP, 6*8);
382 M_LST(argintregs[5], REG_SP, 7*8);
383 M_LST(argintregs[6], REG_SP, 8*8);
384 M_LST(argintregs[7], REG_SP, 9*8);
386 M_DST(argfltregs[0], REG_SP, 10*8);
387 M_DST(argfltregs[1], REG_SP, 11*8);
388 M_DST(argfltregs[2], REG_SP, 12*8);
389 M_DST(argfltregs[3], REG_SP, 13*8);
390 M_DST(argfltregs[4], REG_SP, 14*8);
391 M_DST(argfltregs[5], REG_SP, 15*8);
392 M_DST(argfltregs[6], REG_SP, 16*8);
393 M_DST(argfltregs[7], REG_SP, 17*8);
395 p = dseg_addaddress (method);
396 M_ALD(REG_ITMP1, REG_PV, p);
397 M_LST(REG_ITMP1, REG_SP, 0);
398 p = dseg_addaddress ((void*) (builtin_trace_args));
399 M_ALD(REG_ITMP1, REG_PV, p);
400 M_JSR(REG_RA, REG_ITMP1);
403 M_ALD(REG_RA, REG_SP, 1*8);
405 M_LLD(argintregs[0], REG_SP, 2*8);
406 M_LLD(argintregs[1], REG_SP, 3*8);
407 M_LLD(argintregs[2], REG_SP, 4*8);
408 M_LLD(argintregs[3], REG_SP, 5*8);
409 M_LLD(argintregs[4], REG_SP, 6*8);
410 M_LLD(argintregs[5], REG_SP, 7*8);
411 M_LLD(argintregs[6], REG_SP, 8*8);
412 M_LLD(argintregs[7], REG_SP, 9*8);
414 M_DLD(argfltregs[0], REG_SP, 10*8);
415 M_DLD(argfltregs[1], REG_SP, 11*8);
416 M_DLD(argfltregs[2], REG_SP, 12*8);
417 M_DLD(argfltregs[3], REG_SP, 13*8);
418 M_DLD(argfltregs[4], REG_SP, 14*8);
419 M_DLD(argfltregs[5], REG_SP, 15*8);
420 M_DLD(argfltregs[6], REG_SP, 16*8);
421 M_DLD(argfltregs[7], REG_SP, 17*8);
423 M_LDA (REG_SP, REG_SP, 18*8);
426 /* take arguments out of register or stack frame */
428 for (p = 0, l = 0; p < mparamcount; p++) {
430 var = &(locals[l][t]);
432 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
437 if (IS_INT_LNG_TYPE(t)) { /* integer args */
438 if (p < INT_ARG_CNT) { /* register arguments */
439 if (!(var->flags & INMEMORY)) /* reg arg -> register */
440 {M_INTMOVE (argintregs[p], r);}
441 else /* reg arg -> spilled */
442 M_LST (argintregs[p], REG_SP, 8 * r);
444 else { /* stack arguments */
445 pa = p - INT_ARG_CNT;
446 if (!(var->flags & INMEMORY)) /* stack arg -> register */
447 M_LLD (r, REG_SP, 8 * (parentargs_base + pa));
448 else { /* stack arg -> spilled */
449 M_LLD (REG_ITMP1, REG_SP, 8 * (parentargs_base + pa));
450 M_LST (REG_ITMP1, REG_SP, 8 * r);
454 else { /* floating args */
455 if (p < FLT_ARG_CNT) { /* register arguments */
456 if (!(var->flags & INMEMORY)) /* reg arg -> register */
457 {M_FLTMOVE (argfltregs[p], r);}
458 else /* reg arg -> spilled */
459 M_DST (argfltregs[p], REG_SP, 8 * r);
461 else { /* stack arguments */
462 pa = p - FLT_ARG_CNT;
463 if (!(var->flags & INMEMORY)) /* stack-arg -> register */
464 M_DLD (r, REG_SP, 8 * (parentargs_base + pa) );
465 else { /* stack-arg -> spilled */
466 M_DLD (REG_FTMP1, REG_SP, 8 * (parentargs_base + pa));
467 M_DST (REG_FTMP1, REG_SP, 8 * r);
473 /* call trace function */
475 if (runverbose && !isleafmethod) {
476 M_LDA (REG_SP, REG_SP, -8);
477 p = dseg_addaddress (method);
478 M_ALD(REG_ITMP1, REG_PV, p);
479 M_AST(REG_ITMP1, REG_SP, 0);
480 p = dseg_addaddress ((void*) (builtin_trace_args));
481 M_ALD(REG_ITMP1, REG_PV, p);
482 M_JSR(REG_RA, REG_ITMP1);
484 M_LDA(REG_SP, REG_SP, 8);
487 /* call monitorenter function */
490 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
491 p = dseg_addaddress ((void*) (builtin_monitorenter));
492 M_ALD(REG_ITMP1, REG_PV, p);
493 M_JSR(REG_RA, REG_ITMP1);
494 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
499 /* end of header generation */
501 /* walk through all basic blocks */
503 for (bbs = block_count, bptr = block; --bbs >= 0; bptr++) {
504 bptr -> mpc = (int)((u1*) mcodeptr - mcodebase);
506 if (bptr->flags >= BBREACHED) {
508 /* branch resolving */
512 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
513 gen_resolvebranch((u1*) mcodebase + brefs->branchpos,
514 brefs->branchpos, bptr->mpc);
518 /* copy interface registers to their destination */
523 while (src != NULL) {
525 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
526 d = reg_of_var(src, REG_ITMP1);
527 M_INTMOVE(REG_ITMP1, d);
528 store_reg_to_var_int(src, d);
531 d = reg_of_var(src, REG_IFTMP);
532 if ((src->varkind != STACKVAR)) {
534 if (IS_FLT_DBL_TYPE(s2)) {
535 if (!(interfaces[len][s2].flags & INMEMORY)) {
536 s1 = interfaces[len][s2].regoff;
540 M_DLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
542 store_reg_to_var_flt(src, d);
545 if (!(interfaces[len][s2].flags & INMEMORY)) {
546 s1 = interfaces[len][s2].regoff;
550 M_LLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
552 store_reg_to_var_int(src, d);
559 /* walk through all instructions */
563 for (iptr = bptr->iinstr;
565 src = iptr->dst, len--, iptr++) {
567 MCODECHECK(64); /* an instruction usually needs < 64 words */
570 case ICMD_NOP: /* ... ==> ... */
573 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
575 var_to_reg_int(s1, src, REG_ITMP1);
577 mcode_addxnullrefs(mcodeptr);
581 /* constant operations ************************************************/
583 #define ICONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_IADD_IMM(REG_ZERO,c,r);} \
584 else if(((c)>=0)&&((c)<=0xffff)){M_OR_IMM(REG_ZERO,c,r);} \
585 else{a=dseg_adds4(c);M_ILD(r,REG_PV,a);}
587 #define LCONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LADD_IMM(REG_ZERO,c,r);} \
588 else if(((c)>=0)&&((c)<=0xffff)){M_OR_IMM(REG_ZERO,c,r);} \
589 else{a=dseg_adds8(c);M_LLD(r,REG_PV,a);}
591 case ICMD_ICONST: /* ... ==> ..., constant */
592 /* op1 = 0, val.i = constant */
594 d = reg_of_var(iptr->dst, REG_ITMP1);
595 ICONST(d, iptr->val.i);
596 store_reg_to_var_int(iptr->dst, d);
599 case ICMD_LCONST: /* ... ==> ..., constant */
600 /* op1 = 0, val.l = constant */
602 d = reg_of_var(iptr->dst, REG_ITMP1);
603 LCONST(d, iptr->val.l);
604 store_reg_to_var_int(iptr->dst, d);
607 case ICMD_FCONST: /* ... ==> ..., constant */
608 /* op1 = 0, val.f = constant */
610 d = reg_of_var (iptr->dst, REG_FTMP1);
611 a = dseg_addfloat (iptr->val.f);
613 store_reg_to_var_flt (iptr->dst, d);
616 case ICMD_DCONST: /* ... ==> ..., constant */
617 /* op1 = 0, val.d = constant */
619 d = reg_of_var (iptr->dst, REG_FTMP1);
620 a = dseg_adddouble (iptr->val.d);
622 store_reg_to_var_flt (iptr->dst, d);
625 case ICMD_ACONST: /* ... ==> ..., constant */
626 /* op1 = 0, val.a = constant */
628 d = reg_of_var(iptr->dst, REG_ITMP1);
630 a = dseg_addaddress (iptr->val.a);
634 M_INTMOVE(REG_ZERO, d);
636 store_reg_to_var_int(iptr->dst, d);
640 /* load/store operations **********************************************/
642 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
643 case ICMD_LLOAD: /* op1 = local variable */
646 d = reg_of_var(iptr->dst, REG_ITMP1);
647 if ((iptr->dst->varkind == LOCALVAR) &&
648 (iptr->dst->varnum == iptr->op1))
650 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
651 if (var->flags & INMEMORY)
652 M_LLD(d, REG_SP, 8 * var->regoff);
654 {M_INTMOVE(var->regoff,d);}
655 store_reg_to_var_int(iptr->dst, d);
658 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
659 case ICMD_DLOAD: /* op1 = local variable */
661 d = reg_of_var(iptr->dst, REG_FTMP1);
662 if ((iptr->dst->varkind == LOCALVAR) &&
663 (iptr->dst->varnum == iptr->op1))
665 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
666 if (var->flags & INMEMORY)
667 M_DLD(d, REG_SP, 8 * var->regoff);
669 {M_FLTMOVE(var->regoff,d);}
670 store_reg_to_var_flt(iptr->dst, d);
674 case ICMD_ISTORE: /* ..., value ==> ... */
675 case ICMD_LSTORE: /* op1 = local variable */
678 if ((src->varkind == LOCALVAR) &&
679 (src->varnum == iptr->op1))
681 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
682 if (var->flags & INMEMORY) {
683 var_to_reg_int(s1, src, REG_ITMP1);
684 M_LST(s1, REG_SP, 8 * var->regoff);
687 var_to_reg_int(s1, src, var->regoff);
688 M_INTMOVE(s1, var->regoff);
692 case ICMD_FSTORE: /* ..., value ==> ... */
693 case ICMD_DSTORE: /* op1 = local variable */
695 if ((src->varkind == LOCALVAR) &&
696 (src->varnum == iptr->op1))
698 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
699 if (var->flags & INMEMORY) {
700 var_to_reg_flt(s1, src, REG_FTMP1);
701 M_DST(s1, REG_SP, 8 * var->regoff);
704 var_to_reg_flt(s1, src, var->regoff);
705 M_FLTMOVE(s1, var->regoff);
710 /* pop/dup/swap operations ********************************************/
712 /* attention: double and longs are only one entry in CACAO ICMDs */
714 case ICMD_POP: /* ..., value ==> ... */
715 case ICMD_POP2: /* ..., value, value ==> ... */
718 #define M_COPY(from,to) \
719 d = reg_of_var(to, REG_IFTMP); \
720 if ((from->regoff != to->regoff) || \
721 ((from->flags ^ to->flags) & INMEMORY)) { \
722 if (IS_FLT_DBL_TYPE(from->type)) { \
723 var_to_reg_flt(s1, from, d); \
725 store_reg_to_var_flt(to, d); \
728 var_to_reg_int(s1, from, d); \
730 store_reg_to_var_int(to, d); \
734 case ICMD_DUP: /* ..., a ==> ..., a, a */
735 M_COPY(src, iptr->dst);
738 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
740 M_COPY(src, iptr->dst->prev->prev);
742 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
744 M_COPY(src, iptr->dst);
745 M_COPY(src->prev, iptr->dst->prev);
748 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
750 M_COPY(src->prev, iptr->dst->prev->prev->prev);
752 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
754 M_COPY(src, iptr->dst);
755 M_COPY(src->prev, iptr->dst->prev);
756 M_COPY(src->prev->prev, iptr->dst->prev->prev);
757 M_COPY(src, iptr->dst->prev->prev->prev);
760 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
762 M_COPY(src, iptr->dst);
763 M_COPY(src->prev, iptr->dst->prev);
764 M_COPY(src->prev->prev, iptr->dst->prev->prev);
765 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
766 M_COPY(src, iptr->dst->prev->prev->prev->prev);
767 M_COPY(src->prev, iptr->dst->prev->prev->prev->prev->prev);
770 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
772 M_COPY(src, iptr->dst->prev);
773 M_COPY(src->prev, iptr->dst);
777 /* integer operations *************************************************/
779 case ICMD_INEG: /* ..., value ==> ..., - value */
781 var_to_reg_int(s1, src, REG_ITMP1);
782 d = reg_of_var(iptr->dst, REG_ITMP3);
783 M_ISUB(REG_ZERO, s1, d);
784 store_reg_to_var_int(iptr->dst, d);
787 case ICMD_LNEG: /* ..., value ==> ..., - value */
789 var_to_reg_int(s1, src, REG_ITMP1);
790 d = reg_of_var(iptr->dst, REG_ITMP3);
791 M_LSUB(REG_ZERO, s1, d);
792 store_reg_to_var_int(iptr->dst, d);
795 case ICMD_I2L: /* ..., value ==> ..., value */
797 var_to_reg_int(s1, src, REG_ITMP1);
798 d = reg_of_var(iptr->dst, REG_ITMP3);
800 store_reg_to_var_int(iptr->dst, d);
803 case ICMD_L2I: /* ..., value ==> ..., value */
805 var_to_reg_int(s1, src, REG_ITMP1);
806 d = reg_of_var(iptr->dst, REG_ITMP3);
807 M_IADD(s1, REG_ZERO, d );
808 store_reg_to_var_int(iptr->dst, d);
811 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
813 var_to_reg_int(s1, src, REG_ITMP1);
814 d = reg_of_var(iptr->dst, REG_ITMP3);
815 M_LSLL_IMM(s1, 56, d);
816 M_LSRA_IMM( d, 56, d);
817 store_reg_to_var_int(iptr->dst, d);
820 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
822 var_to_reg_int(s1, src, REG_ITMP1);
823 d = reg_of_var(iptr->dst, REG_ITMP3);
825 store_reg_to_var_int(iptr->dst, d);
828 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
830 var_to_reg_int(s1, src, REG_ITMP1);
831 d = reg_of_var(iptr->dst, REG_ITMP3);
832 M_LSLL_IMM(s1, 48, d);
833 M_LSRA_IMM( d, 48, d);
834 store_reg_to_var_int(iptr->dst, d);
838 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
840 var_to_reg_int(s1, src->prev, REG_ITMP1);
841 var_to_reg_int(s2, src, REG_ITMP2);
842 d = reg_of_var(iptr->dst, REG_ITMP3);
844 store_reg_to_var_int(iptr->dst, d);
847 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
848 /* val.i = constant */
850 var_to_reg_int(s1, src, REG_ITMP1);
851 d = reg_of_var(iptr->dst, REG_ITMP3);
852 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
853 M_IADD_IMM(s1, iptr->val.i, d);
856 ICONST(REG_ITMP2, iptr->val.i);
857 M_IADD(s1, REG_ITMP2, d);
859 store_reg_to_var_int(iptr->dst, d);
862 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
864 var_to_reg_int(s1, src->prev, REG_ITMP1);
865 var_to_reg_int(s2, src, REG_ITMP2);
866 d = reg_of_var(iptr->dst, REG_ITMP3);
868 store_reg_to_var_int(iptr->dst, d);
871 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
872 /* val.l = constant */
874 var_to_reg_int(s1, src, REG_ITMP1);
875 d = reg_of_var(iptr->dst, REG_ITMP3);
876 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
877 M_LADD_IMM(s1, iptr->val.l, d);
880 LCONST(REG_ITMP2, iptr->val.l);
881 M_LADD(s1, REG_ITMP2, d);
883 store_reg_to_var_int(iptr->dst, d);
886 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
888 var_to_reg_int(s1, src->prev, REG_ITMP1);
889 var_to_reg_int(s2, src, REG_ITMP2);
890 d = reg_of_var(iptr->dst, REG_ITMP3);
892 store_reg_to_var_int(iptr->dst, d);
895 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
896 /* val.i = constant */
898 var_to_reg_int(s1, src, REG_ITMP1);
899 d = reg_of_var(iptr->dst, REG_ITMP3);
900 if ((iptr->val.i >= -32767) && (iptr->val.i <= 32768)) {
901 M_IADD_IMM(s1, -iptr->val.i, d);
904 ICONST(REG_ITMP2, iptr->val.i);
905 M_ISUB(s1, REG_ITMP2, d);
907 store_reg_to_var_int(iptr->dst, d);
910 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
912 var_to_reg_int(s1, src->prev, REG_ITMP1);
913 var_to_reg_int(s2, src, REG_ITMP2);
914 d = reg_of_var(iptr->dst, REG_ITMP3);
916 store_reg_to_var_int(iptr->dst, d);
919 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
920 /* val.l = constant */
922 var_to_reg_int(s1, src, REG_ITMP1);
923 d = reg_of_var(iptr->dst, REG_ITMP3);
924 if ((iptr->val.l >= -32767) && (iptr->val.l <= 32768)) {
925 M_LADD_IMM(s1, -iptr->val.l, d);
928 LCONST(REG_ITMP2, iptr->val.l);
929 M_LSUB(s1, REG_ITMP2, d);
931 store_reg_to_var_int(iptr->dst, d);
934 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
936 var_to_reg_int(s1, src->prev, REG_ITMP1);
937 var_to_reg_int(s2, src, REG_ITMP2);
938 d = reg_of_var(iptr->dst, REG_ITMP3);
943 store_reg_to_var_int(iptr->dst, d);
946 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
947 /* val.i = constant */
949 var_to_reg_int(s1, src, REG_ITMP1);
950 d = reg_of_var(iptr->dst, REG_ITMP3);
951 ICONST(REG_ITMP2, iptr->val.i);
952 M_IMUL(s1, REG_ITMP2);
956 store_reg_to_var_int(iptr->dst, d);
959 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
961 var_to_reg_int(s1, src->prev, REG_ITMP1);
962 var_to_reg_int(s2, src, REG_ITMP2);
963 d = reg_of_var(iptr->dst, REG_ITMP3);
968 store_reg_to_var_int(iptr->dst, d);
971 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
972 /* val.l = constant */
974 var_to_reg_int(s1, src, REG_ITMP1);
975 d = reg_of_var(iptr->dst, REG_ITMP3);
976 LCONST(REG_ITMP2, iptr->val.l);
977 M_LMUL(s1, REG_ITMP2);
981 store_reg_to_var_int(iptr->dst, d);
984 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
986 var_to_reg_int(s1, src->prev, REG_ITMP1);
987 var_to_reg_int(s2, src, REG_ITMP2);
988 d = reg_of_var(iptr->dst, REG_ITMP3);
993 store_reg_to_var_int(iptr->dst, d);
996 case ICMD_IDIVCONST: /* ..., value ==> ..., value / constant */
997 /* val.i = constant */
999 var_to_reg_int(s1, src, REG_ITMP1);
1000 d = reg_of_var(iptr->dst, REG_ITMP3);
1001 ICONST(REG_ITMP2, iptr->val.i);
1002 M_IDIV(s1, REG_ITMP2);
1006 store_reg_to_var_int(iptr->dst, d);
1009 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1011 var_to_reg_int(s1, src->prev, REG_ITMP1);
1012 var_to_reg_int(s2, src, REG_ITMP2);
1013 d = reg_of_var(iptr->dst, REG_ITMP3);
1018 store_reg_to_var_int(iptr->dst, d);
1021 case ICMD_LDIVCONST: /* ..., value ==> ..., value / constant */
1022 /* val.l = constant */
1024 var_to_reg_int(s1, src, REG_ITMP1);
1025 d = reg_of_var(iptr->dst, REG_ITMP3);
1026 LCONST(REG_ITMP2, iptr->val.l);
1027 M_LDIV(s1, REG_ITMP2);
1031 store_reg_to_var_int(iptr->dst, d);
1034 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1036 var_to_reg_int(s1, src->prev, REG_ITMP1);
1037 var_to_reg_int(s2, src, REG_ITMP2);
1038 d = reg_of_var(iptr->dst, REG_ITMP3);
1043 store_reg_to_var_int(iptr->dst, d);
1046 case ICMD_IREMCONST: /* ..., value ==> ..., value % constant */
1047 /* val.i = constant */
1049 var_to_reg_int(s1, src, REG_ITMP1);
1050 d = reg_of_var(iptr->dst, REG_ITMP3);
1051 ICONST(REG_ITMP2, iptr->val.i);
1052 M_IDIV(s1, REG_ITMP2);
1056 store_reg_to_var_int(iptr->dst, d);
1059 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1061 var_to_reg_int(s1, src->prev, REG_ITMP1);
1062 var_to_reg_int(s2, src, REG_ITMP2);
1063 d = reg_of_var(iptr->dst, REG_ITMP3);
1068 store_reg_to_var_int(iptr->dst, d);
1071 case ICMD_LREMCONST: /* ..., value ==> ..., value % constant */
1072 /* val.l = constant */
1074 var_to_reg_int(s1, src, REG_ITMP1);
1075 d = reg_of_var(iptr->dst, REG_ITMP3);
1076 LCONST(REG_ITMP2, iptr->val.l);
1077 M_LDIV(s1, REG_ITMP2);
1081 store_reg_to_var_int(iptr->dst, d);
1084 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
1085 case ICMD_LDIVPOW2: /* val.i = constant */
1087 var_to_reg_int(s1, src, REG_ITMP1);
1088 d = reg_of_var(iptr->dst, REG_ITMP3);
1089 M_LSRA_IMM(s1, 63, REG_ITMP2);
1090 M_LSRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
1091 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1092 M_LSRA_IMM(REG_ITMP2, iptr->val.i, d);
1093 store_reg_to_var_int(iptr->dst, d);
1096 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1098 var_to_reg_int(s1, src->prev, REG_ITMP1);
1099 var_to_reg_int(s2, src, REG_ITMP2);
1100 d = reg_of_var(iptr->dst, REG_ITMP3);
1102 store_reg_to_var_int(iptr->dst, d);
1105 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1106 /* val.i = constant */
1108 var_to_reg_int(s1, src, REG_ITMP1);
1109 d = reg_of_var(iptr->dst, REG_ITMP3);
1110 M_ISLL_IMM(s1, iptr->val.i, d);
1111 store_reg_to_var_int(iptr->dst, d);
1114 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1116 var_to_reg_int(s1, src->prev, REG_ITMP1);
1117 var_to_reg_int(s2, src, REG_ITMP2);
1118 d = reg_of_var(iptr->dst, REG_ITMP3);
1120 store_reg_to_var_int(iptr->dst, d);
1123 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1124 /* val.i = constant */
1126 var_to_reg_int(s1, src, REG_ITMP1);
1127 d = reg_of_var(iptr->dst, REG_ITMP3);
1128 M_ISRA_IMM(s1, iptr->val.i, d);
1129 store_reg_to_var_int(iptr->dst, d);
1132 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1134 var_to_reg_int(s1, src->prev, REG_ITMP1);
1135 var_to_reg_int(s2, src, REG_ITMP2);
1136 d = reg_of_var(iptr->dst, REG_ITMP3);
1138 store_reg_to_var_int(iptr->dst, d);
1141 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1142 /* val.i = constant */
1144 var_to_reg_int(s1, src, REG_ITMP1);
1145 d = reg_of_var(iptr->dst, REG_ITMP3);
1146 M_ISRL_IMM(s1, iptr->val.i, d);
1147 store_reg_to_var_int(iptr->dst, d);
1150 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1152 var_to_reg_int(s1, src->prev, REG_ITMP1);
1153 var_to_reg_int(s2, src, REG_ITMP2);
1154 d = reg_of_var(iptr->dst, REG_ITMP3);
1156 store_reg_to_var_int(iptr->dst, d);
1159 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1160 /* val.l = constant */
1162 var_to_reg_int(s1, src, REG_ITMP1);
1163 d = reg_of_var(iptr->dst, REG_ITMP3);
1164 M_LSLL_IMM(s1, iptr->val.l, d);
1165 store_reg_to_var_int(iptr->dst, d);
1168 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1170 var_to_reg_int(s1, src->prev, REG_ITMP1);
1171 var_to_reg_int(s2, src, REG_ITMP2);
1172 d = reg_of_var(iptr->dst, REG_ITMP3);
1174 store_reg_to_var_int(iptr->dst, d);
1177 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1178 /* val.l = constant */
1180 var_to_reg_int(s1, src, REG_ITMP1);
1181 d = reg_of_var(iptr->dst, REG_ITMP3);
1182 M_LSRA_IMM(s1, iptr->val.l, d);
1183 store_reg_to_var_int(iptr->dst, d);
1186 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1188 var_to_reg_int(s1, src->prev, REG_ITMP1);
1189 var_to_reg_int(s2, src, REG_ITMP2);
1190 d = reg_of_var(iptr->dst, REG_ITMP3);
1192 store_reg_to_var_int(iptr->dst, d);
1195 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1196 /* val.l = constant */
1198 var_to_reg_int(s1, src, REG_ITMP1);
1199 d = reg_of_var(iptr->dst, REG_ITMP3);
1200 M_LSRL_IMM(s1, iptr->val.l, d);
1201 store_reg_to_var_int(iptr->dst, d);
1204 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1207 var_to_reg_int(s1, src->prev, REG_ITMP1);
1208 var_to_reg_int(s2, src, REG_ITMP2);
1209 d = reg_of_var(iptr->dst, REG_ITMP3);
1211 store_reg_to_var_int(iptr->dst, d);
1214 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1215 /* val.i = constant */
1217 var_to_reg_int(s1, src, REG_ITMP1);
1218 d = reg_of_var(iptr->dst, REG_ITMP3);
1219 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1220 M_AND_IMM(s1, iptr->val.i, d);
1223 ICONST(REG_ITMP2, iptr->val.i);
1224 M_AND(s1, REG_ITMP2, d);
1226 store_reg_to_var_int(iptr->dst, d);
1229 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1230 /* val.i = constant */
1232 var_to_reg_int(s1, src, REG_ITMP1);
1233 d = reg_of_var(iptr->dst, REG_ITMP3);
1235 M_MOV(s1, REG_ITMP1);
1238 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1239 M_AND_IMM(s1, iptr->val.i, d);
1242 M_ISUB(REG_ZERO, s1, d);
1243 M_AND_IMM(d, iptr->val.i, d);
1246 ICONST(REG_ITMP2, iptr->val.i);
1247 M_AND(s1, REG_ITMP2, d);
1250 M_ISUB(REG_ZERO, s1, d);
1251 M_AND(d, REG_ITMP2, d);
1253 M_ISUB(REG_ZERO, d, d);
1254 store_reg_to_var_int(iptr->dst, d);
1257 case ICMD_IREM0X10001: /* ..., value ==> ..., value % 0x100001 */
1259 /* b = value & 0xffff;
1261 a = ((b - a) & 0xffff) + (b < a);
1263 var_to_reg_int(s1, src, REG_ITMP1);
1264 d = reg_of_var(iptr->dst, REG_ITMP3);
1266 M_MOV(s1, REG_ITMP3);
1270 M_CZEXT(s1, REG_ITMP2); /* delay slot */
1271 M_ISRA_IMM(s1, 16, d);
1272 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1273 M_ISUB(REG_ITMP2, d, d);
1276 M_IADD(d, REG_ITMP1, d); /* delay slot */
1278 M_LUI(REG_ITMP2, 1);
1279 M_IADD_IMM(REG_ITMP2, 1, REG_ITMP2);
1280 M_IDIV(s1, REG_ITMP2);
1284 store_reg_to_var_int(iptr->dst, d);
1287 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1288 /* val.l = constant */
1290 var_to_reg_int(s1, src, REG_ITMP1);
1291 d = reg_of_var(iptr->dst, REG_ITMP3);
1292 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1293 M_AND_IMM(s1, iptr->val.l, d);
1296 LCONST(REG_ITMP2, iptr->val.l);
1297 M_AND(s1, REG_ITMP2, d);
1299 store_reg_to_var_int(iptr->dst, d);
1302 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1303 /* val.l = constant */
1305 var_to_reg_int(s1, src, REG_ITMP1);
1306 d = reg_of_var(iptr->dst, REG_ITMP3);
1308 M_MOV(s1, REG_ITMP1);
1311 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1312 M_AND_IMM(s1, iptr->val.l, d);
1315 M_LSUB(REG_ZERO, s1, d);
1316 M_AND_IMM(d, iptr->val.l, d);
1319 LCONST(REG_ITMP2, iptr->val.l);
1320 M_AND(s1, REG_ITMP2, d);
1323 M_LSUB(REG_ZERO, s1, d);
1324 M_AND(d, REG_ITMP2, d);
1326 M_LSUB(REG_ZERO, d, d);
1327 store_reg_to_var_int(iptr->dst, d);
1330 case ICMD_LREM0X10001:/* ..., value ==> ..., value % 0x10001 */
1332 var_to_reg_int(s1, src, REG_ITMP1);
1333 d = reg_of_var(iptr->dst, REG_ITMP3);
1334 M_LUI(REG_ITMP2, 1);
1335 M_LADD_IMM(REG_ITMP2, 1, REG_ITMP2);
1336 M_LDIV(s1, REG_ITMP2);
1340 store_reg_to_var_int(iptr->dst, d);
1343 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1346 var_to_reg_int(s1, src->prev, REG_ITMP1);
1347 var_to_reg_int(s2, src, REG_ITMP2);
1348 d = reg_of_var(iptr->dst, REG_ITMP3);
1350 store_reg_to_var_int(iptr->dst, d);
1353 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1354 /* val.i = constant */
1356 var_to_reg_int(s1, src, REG_ITMP1);
1357 d = reg_of_var(iptr->dst, REG_ITMP3);
1358 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1359 M_OR_IMM(s1, iptr->val.i, d);
1362 ICONST(REG_ITMP2, iptr->val.i);
1363 M_OR(s1, REG_ITMP2, d);
1365 store_reg_to_var_int(iptr->dst, d);
1368 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1369 /* val.l = constant */
1371 var_to_reg_int(s1, src, REG_ITMP1);
1372 d = reg_of_var(iptr->dst, REG_ITMP3);
1373 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1374 M_OR_IMM(s1, iptr->val.l, d);
1377 LCONST(REG_ITMP2, iptr->val.l);
1378 M_OR(s1, REG_ITMP2, d);
1380 store_reg_to_var_int(iptr->dst, d);
1383 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1386 var_to_reg_int(s1, src->prev, REG_ITMP1);
1387 var_to_reg_int(s2, src, REG_ITMP2);
1388 d = reg_of_var(iptr->dst, REG_ITMP3);
1390 store_reg_to_var_int(iptr->dst, d);
1393 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1394 /* val.i = constant */
1396 var_to_reg_int(s1, src, REG_ITMP1);
1397 d = reg_of_var(iptr->dst, REG_ITMP3);
1398 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1399 M_XOR_IMM(s1, iptr->val.i, d);
1402 ICONST(REG_ITMP2, iptr->val.i);
1403 M_XOR(s1, REG_ITMP2, d);
1405 store_reg_to_var_int(iptr->dst, d);
1408 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1409 /* val.l = constant */
1411 var_to_reg_int(s1, src, REG_ITMP1);
1412 d = reg_of_var(iptr->dst, REG_ITMP3);
1413 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1414 M_XOR_IMM(s1, iptr->val.l, d);
1417 LCONST(REG_ITMP2, iptr->val.l);
1418 M_XOR(s1, REG_ITMP2, d);
1420 store_reg_to_var_int(iptr->dst, d);
1424 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1426 var_to_reg_int(s1, src->prev, REG_ITMP1);
1427 var_to_reg_int(s2, src, REG_ITMP2);
1428 d = reg_of_var(iptr->dst, REG_ITMP3);
1429 M_CMPLT(s1, s2, REG_ITMP3);
1430 M_CMPLT(s2, s1, REG_ITMP1);
1431 M_LSUB (REG_ITMP1, REG_ITMP3, d);
1432 store_reg_to_var_int(iptr->dst, d);
1436 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1437 /* op1 = variable, val.i = constant */
1439 var = &(locals[iptr->op1][TYPE_INT]);
1440 if (var->flags & INMEMORY) {
1442 M_LLD(s1, REG_SP, 8 * var->regoff);
1446 M_IADD_IMM(s1, iptr->val.i, s1);
1447 if (var->flags & INMEMORY)
1448 M_LST(s1, REG_SP, 8 * var->regoff);
1452 /* floating operations ************************************************/
1454 case ICMD_FNEG: /* ..., value ==> ..., - value */
1456 var_to_reg_flt(s1, src, REG_FTMP1);
1457 d = reg_of_var(iptr->dst, REG_FTMP3);
1459 store_reg_to_var_flt(iptr->dst, d);
1462 case ICMD_DNEG: /* ..., value ==> ..., - value */
1464 var_to_reg_flt(s1, src, REG_FTMP1);
1465 d = reg_of_var(iptr->dst, REG_FTMP3);
1467 store_reg_to_var_flt(iptr->dst, d);
1470 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1472 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1473 var_to_reg_flt(s2, src, REG_FTMP2);
1474 d = reg_of_var(iptr->dst, REG_FTMP3);
1476 store_reg_to_var_flt(iptr->dst, d);
1479 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1481 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1482 var_to_reg_flt(s2, src, REG_FTMP2);
1483 d = reg_of_var(iptr->dst, REG_FTMP3);
1485 store_reg_to_var_flt(iptr->dst, d);
1488 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1490 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1491 var_to_reg_flt(s2, src, REG_FTMP2);
1492 d = reg_of_var(iptr->dst, REG_FTMP3);
1494 store_reg_to_var_flt(iptr->dst, d);
1497 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1499 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1500 var_to_reg_flt(s2, src, REG_FTMP2);
1501 d = reg_of_var(iptr->dst, REG_FTMP3);
1503 store_reg_to_var_flt(iptr->dst, d);
1506 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1508 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1509 var_to_reg_flt(s2, src, REG_FTMP2);
1510 d = reg_of_var(iptr->dst, REG_FTMP3);
1512 store_reg_to_var_flt(iptr->dst, d);
1515 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1517 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1518 var_to_reg_flt(s2, src, REG_FTMP2);
1519 d = reg_of_var(iptr->dst, REG_FTMP3);
1521 store_reg_to_var_flt(iptr->dst, d);
1524 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1526 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1527 var_to_reg_flt(s2, src, REG_FTMP2);
1528 d = reg_of_var(iptr->dst, REG_FTMP3);
1530 store_reg_to_var_flt(iptr->dst, d);
1533 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1535 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1536 var_to_reg_flt(s2, src, REG_FTMP2);
1537 d = reg_of_var(iptr->dst, REG_FTMP3);
1539 store_reg_to_var_flt(iptr->dst, d);
1542 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1544 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1545 var_to_reg_flt(s2, src, REG_FTMP2);
1546 d = reg_of_var(iptr->dst, REG_FTMP3);
1547 M_FDIV(s1,s2, REG_FTMP3);
1548 M_FLOORFL(REG_FTMP3, REG_FTMP3);
1549 M_CVTLF(REG_FTMP3, REG_FTMP3);
1550 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1551 M_FSUB(s1, REG_FTMP3, d);
1552 store_reg_to_var_flt(iptr->dst, d);
1555 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1557 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1558 var_to_reg_flt(s2, src, REG_FTMP2);
1559 d = reg_of_var(iptr->dst, REG_FTMP3);
1560 M_DDIV(s1,s2, REG_FTMP3);
1561 M_FLOORDL(REG_FTMP3, REG_FTMP3);
1562 M_CVTLD(REG_FTMP3, REG_FTMP3);
1563 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1564 M_DSUB(s1, REG_FTMP3, d);
1565 store_reg_to_var_flt(iptr->dst, d);
1568 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1570 var_to_reg_int(s1, src, REG_ITMP1);
1571 d = reg_of_var(iptr->dst, REG_FTMP3);
1574 store_reg_to_var_flt(iptr->dst, d);
1577 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1579 var_to_reg_int(s1, src, REG_ITMP1);
1580 d = reg_of_var(iptr->dst, REG_FTMP3);
1583 store_reg_to_var_flt(iptr->dst, d);
1586 case ICMD_F2I: /* ..., (float) value ==> ..., (int) value */
1588 var_to_reg_flt(s1, src, REG_FTMP1);
1589 d = reg_of_var(iptr->dst, REG_ITMP3);
1590 M_CVTFI(s1, REG_FTMP1);
1591 M_MOVDL(REG_FTMP1, d);
1592 store_reg_to_var_int(iptr->dst, d);
1595 case ICMD_D2I: /* ..., (double) value ==> ..., (int) value */
1597 var_to_reg_flt(s1, src, REG_FTMP1);
1598 d = reg_of_var(iptr->dst, REG_ITMP3);
1599 M_CVTDI(s1, REG_FTMP1);
1600 M_MOVDL(REG_FTMP1, d);
1601 store_reg_to_var_int(iptr->dst, d);
1604 case ICMD_F2L: /* ..., (float) value ==> ..., (long) value */
1606 var_to_reg_flt(s1, src, REG_FTMP1);
1607 d = reg_of_var(iptr->dst, REG_ITMP3);
1608 M_CVTFL(s1, REG_FTMP1);
1609 M_MOVDL(REG_FTMP1, d);
1610 store_reg_to_var_int(iptr->dst, d);
1613 case ICMD_D2L: /* ..., (double) value ==> ..., (long) value */
1615 var_to_reg_flt(s1, src, REG_FTMP1);
1616 d = reg_of_var(iptr->dst, REG_ITMP3);
1617 M_CVTDL(s1, REG_FTMP1);
1618 M_MOVDL(REG_FTMP1, d);
1619 store_reg_to_var_int(iptr->dst, d);
1622 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1624 var_to_reg_flt(s1, src, REG_FTMP1);
1625 d = reg_of_var(iptr->dst, REG_FTMP3);
1627 store_reg_to_var_flt(iptr->dst, d);
1630 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1632 var_to_reg_flt(s1, src, REG_FTMP1);
1633 d = reg_of_var(iptr->dst, REG_FTMP3);
1635 store_reg_to_var_flt(iptr->dst, d);
1638 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1640 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1641 var_to_reg_flt(s2, src, REG_FTMP2);
1642 d = reg_of_var(iptr->dst, REG_ITMP3);
1644 M_FBF(2); /* jump over next instructions */
1645 M_LSUB_IMM(REG_ZERO, 1, d);
1648 M_FBF(2); /* jump over next instruction */
1650 M_LADD_IMM(REG_ZERO, 1, d);
1651 store_reg_to_var_int(iptr->dst, d);
1654 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1656 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1657 var_to_reg_flt(s2, src, REG_FTMP2);
1658 d = reg_of_var(iptr->dst, REG_ITMP3);
1660 M_FBF(2); /* jump over next instructions */
1661 M_LSUB_IMM(REG_ZERO, 1, d);
1664 M_FBF(2); /* jump over next instruction */
1666 M_LADD_IMM(REG_ZERO, 1, d);
1667 store_reg_to_var_int(iptr->dst, d);
1670 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1672 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1673 var_to_reg_flt(s2, src, REG_FTMP2);
1674 d = reg_of_var(iptr->dst, REG_ITMP3);
1676 M_FBF(2); /* jump over next instruction */
1677 M_LADD_IMM(REG_ZERO, 1, d);
1680 M_FBF(2); /* jump over next instruction */
1682 M_LSUB_IMM(REG_ZERO, 1, d);
1683 store_reg_to_var_int(iptr->dst, d);
1686 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1688 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1689 var_to_reg_flt(s2, src, REG_FTMP2);
1690 d = reg_of_var(iptr->dst, REG_ITMP3);
1692 M_FBF(2); /* jump over next instruction */
1693 M_LADD_IMM(REG_ZERO, 1, d);
1696 M_FBF(2); /* jump over next instruction */
1698 M_LSUB_IMM(REG_ZERO, 1, d);
1699 store_reg_to_var_int(iptr->dst, d);
1703 /* memory operations **************************************************/
1705 #define gen_bound_check \
1707 M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\
1708 M_CMPULT(s2, REG_ITMP3, REG_ITMP3);\
1709 M_BEQZ(REG_ITMP3, 0);\
1710 mcode_addxboundrefs(mcodeptr);\
1714 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1716 var_to_reg_int(s1, src, REG_ITMP1);
1717 d = reg_of_var(iptr->dst, REG_ITMP3);
1718 gen_nullptr_check(s1);
1719 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1720 store_reg_to_var_int(iptr->dst, d);
1723 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1725 var_to_reg_int(s1, src->prev, REG_ITMP1);
1726 var_to_reg_int(s2, src, REG_ITMP2);
1727 d = reg_of_var(iptr->dst, REG_ITMP3);
1728 gen_nullptr_check(s1);
1730 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1731 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1732 M_ALD(d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1733 store_reg_to_var_int(iptr->dst, d);
1736 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1738 var_to_reg_int(s1, src->prev, REG_ITMP1);
1739 var_to_reg_int(s2, src, REG_ITMP2);
1740 d = reg_of_var(iptr->dst, REG_ITMP3);
1741 gen_nullptr_check(s1);
1743 M_ASLL_IMM(s2, 2, REG_ITMP2);
1744 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1745 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1746 store_reg_to_var_int(iptr->dst, d);
1749 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1751 var_to_reg_int(s1, src->prev, REG_ITMP1);
1752 var_to_reg_int(s2, src, REG_ITMP2);
1753 d = reg_of_var(iptr->dst, REG_ITMP3);
1754 gen_nullptr_check(s1);
1756 M_ASLL_IMM(s2, 3, REG_ITMP2);
1757 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1758 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1759 store_reg_to_var_int(iptr->dst, d);
1762 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1764 var_to_reg_int(s1, src->prev, REG_ITMP1);
1765 var_to_reg_int(s2, src, REG_ITMP2);
1766 d = reg_of_var(iptr->dst, REG_FTMP3);
1767 gen_nullptr_check(s1);
1769 M_ASLL_IMM(s2, 2, REG_ITMP2);
1770 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1771 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1772 store_reg_to_var_flt(iptr->dst, d);
1775 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1777 var_to_reg_int(s1, src->prev, REG_ITMP1);
1778 var_to_reg_int(s2, src, REG_ITMP2);
1779 d = reg_of_var(iptr->dst, REG_FTMP3);
1780 gen_nullptr_check(s1);
1782 M_ASLL_IMM(s2, 3, REG_ITMP2);
1783 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1784 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1785 store_reg_to_var_flt(iptr->dst, d);
1788 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1790 var_to_reg_int(s1, src->prev, REG_ITMP1);
1791 var_to_reg_int(s2, src, REG_ITMP2);
1792 d = reg_of_var(iptr->dst, REG_ITMP3);
1793 gen_nullptr_check(s1);
1795 M_AADD(s2, s1, REG_ITMP1);
1796 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1797 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1798 store_reg_to_var_int(iptr->dst, d);
1801 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1803 var_to_reg_int(s1, src->prev, REG_ITMP1);
1804 var_to_reg_int(s2, src, REG_ITMP2);
1805 d = reg_of_var(iptr->dst, REG_ITMP3);
1806 gen_nullptr_check(s1);
1808 M_AADD(s2, s1, REG_ITMP1);
1809 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1810 M_SLDS(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1811 store_reg_to_var_int(iptr->dst, d);
1814 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1816 var_to_reg_int(s1, src->prev, REG_ITMP1);
1817 var_to_reg_int(s2, src, REG_ITMP2);
1818 d = reg_of_var(iptr->dst, REG_ITMP3);
1819 gen_nullptr_check(s1);
1821 M_AADD(s2, s1, REG_ITMP1);
1822 M_BLDS(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1823 store_reg_to_var_int(iptr->dst, d);
1827 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1829 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1830 var_to_reg_int(s2, src->prev, REG_ITMP2);
1831 gen_nullptr_check(s1);
1833 var_to_reg_int(s3, src, REG_ITMP3);
1834 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1835 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1836 M_AST(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1839 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1841 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1842 var_to_reg_int(s2, src->prev, REG_ITMP2);
1843 gen_nullptr_check(s1);
1845 var_to_reg_int(s3, src, REG_ITMP3);
1846 M_ASLL_IMM(s2, 2, REG_ITMP2);
1847 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1848 M_IST(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1851 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1853 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1854 var_to_reg_int(s2, src->prev, REG_ITMP2);
1855 gen_nullptr_check(s1);
1857 var_to_reg_int(s3, src, REG_ITMP3);
1858 M_ASLL_IMM(s2, 3, REG_ITMP2);
1859 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1860 M_LST(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1863 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1865 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1866 var_to_reg_int(s2, src->prev, REG_ITMP2);
1867 gen_nullptr_check(s1);
1869 var_to_reg_flt(s3, src, REG_FTMP3);
1870 M_ASLL_IMM(s2, 2, REG_ITMP2);
1871 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1872 M_FST(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1875 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1877 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1878 var_to_reg_int(s2, src->prev, REG_ITMP2);
1879 gen_nullptr_check(s1);
1881 var_to_reg_flt(s3, src, REG_FTMP3);
1882 M_ASLL_IMM(s2, 3, REG_ITMP2);
1883 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1884 M_DST(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1887 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1888 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1890 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1891 var_to_reg_int(s2, src->prev, REG_ITMP2);
1892 gen_nullptr_check(s1);
1894 var_to_reg_int(s3, src, REG_ITMP3);
1895 M_AADD(s2, s1, REG_ITMP1);
1896 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1897 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1900 case ICMD_BASTORE: /* ..., 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 gen_nullptr_check(s1);
1906 var_to_reg_int(s3, src, REG_ITMP3);
1907 M_AADD(s2, s1, REG_ITMP1);
1908 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1912 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1913 /* op1 = type, val.a = field address */
1915 a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value));
1916 M_ALD(REG_ITMP1, REG_PV, a);
1917 switch (iptr->op1) {
1919 var_to_reg_int(s2, src, REG_ITMP2);
1920 M_IST(s2, REG_ITMP1, 0);
1923 var_to_reg_int(s2, src, REG_ITMP2);
1924 M_LST(s2, REG_ITMP1, 0);
1927 var_to_reg_int(s2, src, REG_ITMP2);
1928 M_AST(s2, REG_ITMP1, 0);
1931 var_to_reg_flt(s2, src, REG_FTMP2);
1932 M_FST(s2, REG_ITMP1, 0);
1935 var_to_reg_flt(s2, src, REG_FTMP2);
1936 M_DST(s2, REG_ITMP1, 0);
1938 default: panic ("internal error");
1942 case ICMD_GETSTATIC: /* ... ==> ..., value */
1943 /* op1 = type, val.a = field address */
1945 a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value));
1946 M_ALD(REG_ITMP1, REG_PV, a);
1947 switch (iptr->op1) {
1949 d = reg_of_var(iptr->dst, REG_ITMP3);
1950 M_ILD(d, REG_ITMP1, 0);
1951 store_reg_to_var_int(iptr->dst, d);
1954 d = reg_of_var(iptr->dst, REG_ITMP3);
1955 M_LLD(d, REG_ITMP1, 0);
1956 store_reg_to_var_int(iptr->dst, d);
1959 d = reg_of_var(iptr->dst, REG_ITMP3);
1960 M_ALD(d, REG_ITMP1, 0);
1961 store_reg_to_var_int(iptr->dst, d);
1964 d = reg_of_var(iptr->dst, REG_FTMP1);
1965 M_FLD(d, REG_ITMP1, 0);
1966 store_reg_to_var_flt(iptr->dst, d);
1969 d = reg_of_var(iptr->dst, REG_FTMP1);
1970 M_DLD(d, REG_ITMP1, 0);
1971 store_reg_to_var_flt(iptr->dst, d);
1973 default: panic ("internal error");
1978 case ICMD_PUTFIELD: /* ..., value ==> ... */
1979 /* op1 = type, val.i = field offset */
1981 a = ((fieldinfo *)(iptr->val.a))->offset;
1982 switch (iptr->op1) {
1984 var_to_reg_int(s1, src->prev, REG_ITMP1);
1985 var_to_reg_int(s2, src, REG_ITMP2);
1986 gen_nullptr_check(s1);
1990 var_to_reg_int(s1, src->prev, REG_ITMP1);
1991 var_to_reg_int(s2, src, REG_ITMP2);
1992 gen_nullptr_check(s1);
1996 var_to_reg_int(s1, src->prev, REG_ITMP1);
1997 var_to_reg_int(s2, src, REG_ITMP2);
1998 gen_nullptr_check(s1);
2002 var_to_reg_int(s1, src->prev, REG_ITMP1);
2003 var_to_reg_flt(s2, src, REG_FTMP2);
2004 gen_nullptr_check(s1);
2008 var_to_reg_int(s1, src->prev, REG_ITMP1);
2009 var_to_reg_flt(s2, src, REG_FTMP2);
2010 gen_nullptr_check(s1);
2013 default: panic ("internal error");
2017 case ICMD_GETFIELD: /* ... ==> ..., value */
2018 /* op1 = type, val.i = field offset */
2020 a = ((fieldinfo *)(iptr->val.a))->offset;
2021 switch (iptr->op1) {
2023 var_to_reg_int(s1, src, REG_ITMP1);
2024 d = reg_of_var(iptr->dst, REG_ITMP3);
2025 gen_nullptr_check(s1);
2027 store_reg_to_var_int(iptr->dst, d);
2030 var_to_reg_int(s1, src, REG_ITMP1);
2031 d = reg_of_var(iptr->dst, REG_ITMP3);
2032 gen_nullptr_check(s1);
2034 store_reg_to_var_int(iptr->dst, d);
2037 var_to_reg_int(s1, src, REG_ITMP1);
2038 d = reg_of_var(iptr->dst, REG_ITMP3);
2039 gen_nullptr_check(s1);
2041 store_reg_to_var_int(iptr->dst, d);
2044 var_to_reg_int(s1, src, REG_ITMP1);
2045 d = reg_of_var(iptr->dst, REG_FTMP1);
2046 gen_nullptr_check(s1);
2048 store_reg_to_var_flt(iptr->dst, d);
2051 var_to_reg_int(s1, src, REG_ITMP1);
2052 d = reg_of_var(iptr->dst, REG_FTMP1);
2053 gen_nullptr_check(s1);
2055 store_reg_to_var_flt(iptr->dst, d);
2057 default: panic ("internal error");
2062 /* branch operations **************************************************/
2064 #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}}
2066 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2068 var_to_reg_int(s1, src, REG_ITMP1);
2069 M_INTMOVE(s1, REG_ITMP1_XPTR);
2070 a = dseg_addaddress(asm_handle_exception);
2071 M_ALD(REG_ITMP2, REG_PV, a);
2072 M_JSR(REG_ITMP2_XPC, REG_ITMP2);
2077 case ICMD_GOTO: /* ... ==> ... */
2078 /* op1 = target JavaVM pc */
2080 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2085 case ICMD_JSR: /* ... ==> ... */
2086 /* op1 = target JavaVM pc */
2088 dseg_addtarget(BlockPtrOfPC(iptr->op1));
2089 M_ALD(REG_ITMP1, REG_PV, -dseglen);
2090 M_JSR(REG_ITMP1, REG_ITMP1); /* REG_ITMP1 = return address */
2094 case ICMD_RET: /* ... ==> ... */
2095 /* op1 = local variable */
2097 var = &(locals[iptr->op1][TYPE_ADR]);
2098 if (var->flags & INMEMORY) {
2099 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2108 case ICMD_IFNULL: /* ..., value ==> ... */
2109 /* op1 = target JavaVM pc */
2111 var_to_reg_int(s1, src, REG_ITMP1);
2113 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2117 case ICMD_IFNONNULL: /* ..., value ==> ... */
2118 /* op1 = target JavaVM pc */
2120 var_to_reg_int(s1, src, REG_ITMP1);
2122 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2126 case ICMD_IFEQ: /* ..., value ==> ... */
2127 /* op1 = target JavaVM pc, val.i = constant */
2129 var_to_reg_int(s1, src, REG_ITMP1);
2130 if (iptr->val.i == 0) {
2134 ICONST(REG_ITMP2, iptr->val.i);
2135 M_BEQ(s1, REG_ITMP2, 0);
2137 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2141 case ICMD_IFLT: /* ..., value ==> ... */
2142 /* op1 = target JavaVM pc, val.i = constant */
2144 var_to_reg_int(s1, src, REG_ITMP1);
2145 if (iptr->val.i == 0) {
2149 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
2150 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2153 ICONST(REG_ITMP2, iptr->val.i);
2154 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2156 M_BNEZ(REG_ITMP1, 0);
2158 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2162 case ICMD_IFLE: /* ..., value ==> ... */
2163 /* op1 = target JavaVM pc, val.i = constant */
2165 var_to_reg_int(s1, src, REG_ITMP1);
2166 if (iptr->val.i == 0) {
2170 if ((iptr->val.i >= -32769) && (iptr->val.i <= 32766)) {
2171 M_CMPLT_IMM(s1, iptr->val.i + 1, REG_ITMP1);
2172 M_BNEZ(REG_ITMP1, 0);
2175 ICONST(REG_ITMP2, iptr->val.i);
2176 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2177 M_BEQZ(REG_ITMP1, 0);
2180 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2184 case ICMD_IFNE: /* ..., value ==> ... */
2185 /* op1 = target JavaVM pc, val.i = constant */
2187 var_to_reg_int(s1, src, REG_ITMP1);
2188 if (iptr->val.i == 0) {
2192 ICONST(REG_ITMP2, iptr->val.i);
2193 M_BNE(s1, REG_ITMP2, 0);
2195 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2199 case ICMD_IFGT: /* ..., value ==> ... */
2200 /* op1 = target JavaVM pc, val.i = constant */
2202 var_to_reg_int(s1, src, REG_ITMP1);
2203 if (iptr->val.i == 0) {
2207 if ((iptr->val.i >= -32769) && (iptr->val.i <= 32766)) {
2208 M_CMPLT_IMM(s1, iptr->val.i + 1, REG_ITMP1);
2209 M_BEQZ(REG_ITMP1, 0);
2212 ICONST(REG_ITMP2, iptr->val.i);
2213 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2214 M_BNEZ(REG_ITMP1, 0);
2217 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2221 case ICMD_IFGE: /* ..., 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 >= -32768) && (iptr->val.i <= 32767)) {
2230 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2233 ICONST(REG_ITMP2, iptr->val.i);
2234 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2236 M_BEQZ(REG_ITMP1, 0);
2238 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2242 case ICMD_IF_LEQ: /* ..., value ==> ... */
2243 /* op1 = target JavaVM pc, val.l = constant */
2245 var_to_reg_int(s1, src, REG_ITMP1);
2246 if (iptr->val.l == 0) {
2250 LCONST(REG_ITMP2, iptr->val.l);
2251 M_BEQ(s1, REG_ITMP2, 0);
2253 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2257 case ICMD_IF_LLT: /* ..., value ==> ... */
2258 /* op1 = target JavaVM pc, val.l = constant */
2260 var_to_reg_int(s1, src, REG_ITMP1);
2261 if (iptr->val.l == 0) {
2265 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2266 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2269 LCONST(REG_ITMP2, iptr->val.l);
2270 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2272 M_BNEZ(REG_ITMP1, 0);
2274 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2278 case ICMD_IF_LLE: /* ..., value ==> ... */
2279 /* op1 = target JavaVM pc, val.l = constant */
2281 var_to_reg_int(s1, src, REG_ITMP1);
2282 if (iptr->val.l == 0) {
2286 if ((iptr->val.l >= -32769) && (iptr->val.l <= 32766)) {
2287 M_CMPLT_IMM(s1, iptr->val.l + 1, REG_ITMP1);
2288 M_BNEZ(REG_ITMP1, 0);
2291 LCONST(REG_ITMP2, iptr->val.l);
2292 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2293 M_BEQZ(REG_ITMP1, 0);
2296 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2300 case ICMD_IF_LNE: /* ..., value ==> ... */
2301 /* op1 = target JavaVM pc, val.l = constant */
2303 var_to_reg_int(s1, src, REG_ITMP1);
2304 if (iptr->val.l == 0) {
2308 LCONST(REG_ITMP2, iptr->val.l);
2309 M_BNE(s1, REG_ITMP2, 0);
2311 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2315 case ICMD_IF_LGT: /* ..., value ==> ... */
2316 /* op1 = target JavaVM pc, val.l = constant */
2318 var_to_reg_int(s1, src, REG_ITMP1);
2319 if (iptr->val.l == 0) {
2323 if ((iptr->val.l >= -32769) && (iptr->val.l <= 32766)) {
2324 M_CMPLT_IMM(s1, iptr->val.l + 1, REG_ITMP1);
2325 M_BEQZ(REG_ITMP1, 0);
2328 LCONST(REG_ITMP2, iptr->val.l);
2329 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2330 M_BNEZ(REG_ITMP1, 0);
2333 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2337 case ICMD_IF_LGE: /* ..., 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 >= -32768) && (iptr->val.l <= 32767)) {
2346 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2349 LCONST(REG_ITMP2, iptr->val.l);
2350 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2352 M_BEQZ(REG_ITMP1, 0);
2354 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2358 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2359 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2360 case ICMD_IF_ACMPEQ:
2362 var_to_reg_int(s1, src->prev, REG_ITMP1);
2363 var_to_reg_int(s2, src, REG_ITMP2);
2365 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2369 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2370 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2371 case ICMD_IF_ACMPNE:
2373 var_to_reg_int(s1, src->prev, REG_ITMP1);
2374 var_to_reg_int(s2, src, REG_ITMP2);
2376 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2380 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2381 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2383 var_to_reg_int(s1, src->prev, REG_ITMP1);
2384 var_to_reg_int(s2, src, REG_ITMP2);
2385 M_CMPLT(s1, s2, REG_ITMP1);
2386 M_BNEZ(REG_ITMP1, 0);
2387 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2391 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2392 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2394 var_to_reg_int(s1, src->prev, REG_ITMP1);
2395 var_to_reg_int(s2, src, REG_ITMP2);
2396 M_CMPGT(s1, s2, REG_ITMP1);
2397 M_BNEZ(REG_ITMP1, 0);
2398 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2402 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2403 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2405 var_to_reg_int(s1, src->prev, REG_ITMP1);
2406 var_to_reg_int(s2, src, REG_ITMP2);
2407 M_CMPGT(s1, s2, REG_ITMP1);
2408 M_BEQZ(REG_ITMP1, 0);
2409 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2413 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2414 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2416 var_to_reg_int(s1, src->prev, REG_ITMP1);
2417 var_to_reg_int(s2, src, REG_ITMP2);
2418 M_CMPLT(s1, s2, REG_ITMP1);
2419 M_BEQZ(REG_ITMP1, 0);
2420 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2424 #ifdef CONDITIONAL_LOADCONST
2425 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2427 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2430 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2431 /* val.i = constant */
2433 var_to_reg_int(s1, src, REG_ITMP1);
2434 d = reg_of_var(iptr->dst, REG_ITMP3);
2436 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2437 if ((a == 1) && (iptr[1].val.i == 0)) {
2438 M_CMPEQ(s1, REG_ZERO, d);
2439 store_reg_to_var_int(iptr->dst, d);
2442 if ((a == 0) && (iptr[1].val.i == 1)) {
2443 M_CMPEQ(s1, REG_ZERO, d);
2445 store_reg_to_var_int(iptr->dst, d);
2449 M_MOV(s1, REG_ITMP1);
2452 ICONST(d, iptr[1].val.i);
2454 if ((a >= 0) && (a <= 255)) {
2455 M_CMOVEQ_IMM(s1, a, d);
2458 ICONST(REG_ITMP2, a);
2459 M_CMOVEQ(s1, REG_ITMP2, d);
2461 store_reg_to_var_int(iptr->dst, d);
2464 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2465 /* val.i = constant */
2467 var_to_reg_int(s1, src, REG_ITMP1);
2468 d = reg_of_var(iptr->dst, REG_ITMP3);
2470 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2471 if ((a == 0) && (iptr[1].val.i == 1)) {
2472 M_CMPEQ(s1, REG_ZERO, d);
2473 store_reg_to_var_int(iptr->dst, d);
2476 if ((a == 1) && (iptr[1].val.i == 0)) {
2477 M_CMPEQ(s1, REG_ZERO, d);
2479 store_reg_to_var_int(iptr->dst, d);
2483 M_MOV(s1, REG_ITMP1);
2486 ICONST(d, iptr[1].val.i);
2488 if ((a >= 0) && (a <= 255)) {
2489 M_CMOVNE_IMM(s1, a, d);
2492 ICONST(REG_ITMP2, a);
2493 M_CMOVNE(s1, REG_ITMP2, d);
2495 store_reg_to_var_int(iptr->dst, d);
2498 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2499 /* val.i = constant */
2501 var_to_reg_int(s1, src, REG_ITMP1);
2502 d = reg_of_var(iptr->dst, REG_ITMP3);
2504 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2505 if ((a == 1) && (iptr[1].val.i == 0)) {
2506 M_CMPLT(s1, REG_ZERO, d);
2507 store_reg_to_var_int(iptr->dst, d);
2510 if ((a == 0) && (iptr[1].val.i == 1)) {
2511 M_CMPLE(REG_ZERO, s1, d);
2512 store_reg_to_var_int(iptr->dst, d);
2516 M_MOV(s1, REG_ITMP1);
2519 ICONST(d, iptr[1].val.i);
2521 if ((a >= 0) && (a <= 255)) {
2522 M_CMOVLT_IMM(s1, a, d);
2525 ICONST(REG_ITMP2, a);
2526 M_CMOVLT(s1, REG_ITMP2, d);
2528 store_reg_to_var_int(iptr->dst, d);
2531 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2532 /* val.i = constant */
2534 var_to_reg_int(s1, src, REG_ITMP1);
2535 d = reg_of_var(iptr->dst, REG_ITMP3);
2537 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2538 if ((a == 1) && (iptr[1].val.i == 0)) {
2539 M_CMPLE(REG_ZERO, s1, d);
2540 store_reg_to_var_int(iptr->dst, d);
2543 if ((a == 0) && (iptr[1].val.i == 1)) {
2544 M_CMPLT(s1, REG_ZERO, d);
2545 store_reg_to_var_int(iptr->dst, d);
2549 M_MOV(s1, REG_ITMP1);
2552 ICONST(d, iptr[1].val.i);
2554 if ((a >= 0) && (a <= 255)) {
2555 M_CMOVGE_IMM(s1, a, d);
2558 ICONST(REG_ITMP2, a);
2559 M_CMOVGE(s1, REG_ITMP2, d);
2561 store_reg_to_var_int(iptr->dst, d);
2564 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2565 /* val.i = constant */
2567 var_to_reg_int(s1, src, REG_ITMP1);
2568 d = reg_of_var(iptr->dst, REG_ITMP3);
2570 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2571 if ((a == 1) && (iptr[1].val.i == 0)) {
2572 M_CMPLT(REG_ZERO, s1, d);
2573 store_reg_to_var_int(iptr->dst, d);
2576 if ((a == 0) && (iptr[1].val.i == 1)) {
2577 M_CMPLE(s1, REG_ZERO, d);
2578 store_reg_to_var_int(iptr->dst, d);
2582 M_MOV(s1, REG_ITMP1);
2585 ICONST(d, iptr[1].val.i);
2587 if ((a >= 0) && (a <= 255)) {
2588 M_CMOVGT_IMM(s1, a, d);
2591 ICONST(REG_ITMP2, a);
2592 M_CMOVGT(s1, REG_ITMP2, d);
2594 store_reg_to_var_int(iptr->dst, d);
2597 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2598 /* val.i = constant */
2600 var_to_reg_int(s1, src, REG_ITMP1);
2601 d = reg_of_var(iptr->dst, REG_ITMP3);
2603 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2604 if ((a == 1) && (iptr[1].val.i == 0)) {
2605 M_CMPLE(s1, REG_ZERO, d);
2606 store_reg_to_var_int(iptr->dst, d);
2609 if ((a == 0) && (iptr[1].val.i == 1)) {
2610 M_CMPLT(REG_ZERO, s1, d);
2611 store_reg_to_var_int(iptr->dst, d);
2615 M_MOV(s1, REG_ITMP1);
2618 ICONST(d, iptr[1].val.i);
2620 if ((a >= 0) && (a <= 255)) {
2621 M_CMOVLE_IMM(s1, a, d);
2624 ICONST(REG_ITMP2, a);
2625 M_CMOVLE(s1, REG_ITMP2, d);
2627 store_reg_to_var_int(iptr->dst, d);
2632 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2637 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2638 a = dseg_addaddress ((void*) (builtin_monitorexit));
2639 M_ALD(REG_ITMP1, REG_PV, a);
2640 M_JSR(REG_RA, REG_ITMP1);
2641 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse); /* delay slot */
2644 var_to_reg_int(s1, src, REG_RESULT);
2645 M_INTMOVE(s1, REG_RESULT);
2646 goto nowperformreturn;
2648 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2652 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2653 a = dseg_addaddress ((void*) (builtin_monitorexit));
2654 M_ALD(REG_ITMP1, REG_PV, a);
2655 M_JSR(REG_RA, REG_ITMP1);
2656 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse); /* delay slot */
2659 var_to_reg_flt(s1, src, REG_FRESULT);
2660 M_FLTMOVE(s1, REG_FRESULT);
2661 goto nowperformreturn;
2663 case ICMD_RETURN: /* ... ==> ... */
2666 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2667 a = dseg_addaddress ((void*) (builtin_monitorexit));
2668 M_ALD(REG_ITMP1, REG_PV, a);
2669 M_JSR(REG_RA, REG_ITMP1);
2670 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse); /* delay slot */
2678 p = parentargs_base;
2680 /* restore return address */
2683 {p--; M_LLD (REG_RA, REG_SP, 8 * p);}
2685 /* restore saved registers */
2687 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
2688 {p--; M_LLD(savintregs[r], REG_SP, 8 * p);}
2689 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
2690 {p--; M_DLD(savfltregs[r], REG_SP, 8 * p);}
2692 /* call trace function */
2695 M_LDA (REG_SP, REG_SP, -24);
2696 M_AST(REG_RA, REG_SP, 0);
2697 M_LST(REG_RESULT, REG_SP, 8);
2698 M_DST(REG_FRESULT, REG_SP,16);
2699 a = dseg_addaddress (method);
2700 M_ALD(argintregs[0], REG_PV, a);
2701 M_MOV(REG_RESULT, argintregs[1]);
2702 a = dseg_addaddress ((void*) (builtin_displaymethodstop));
2703 M_ALD(REG_ITMP1, REG_PV, a);
2704 M_JSR (REG_RA, REG_ITMP1);
2705 M_FLTMOVE(REG_FRESULT, argfltregs[2]); /* delay slot */
2707 M_ALD(REG_RA, REG_SP, 0);
2708 M_LLD(REG_RESULT, REG_SP, 8);
2709 M_DLD(REG_FRESULT, REG_SP,16);
2710 M_LDA (REG_SP, REG_SP, 24);
2715 /* deallocate stack */
2717 if (parentargs_base)
2718 {M_LDA(REG_SP, REG_SP, parentargs_base*8);}
2726 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2730 s4ptr = iptr->val.a;
2731 l = s4ptr[1]; /* low */
2732 i = s4ptr[2]; /* high */
2734 var_to_reg_int(s1, src, REG_ITMP1);
2736 {M_INTMOVE(s1, REG_ITMP1);}
2737 else if (l <= 32768) {
2738 M_IADD_IMM(s1, -l, REG_ITMP1);
2741 ICONST(REG_ITMP2, l);
2742 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2748 M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
2749 M_BEQZ(REG_ITMP2, 0);
2750 mcode_addreference(BlockPtrOfPC(s4ptr[0]), mcodeptr);
2751 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1); /* delay slot*/
2753 /* build jump table top down and use address of lowest entry */
2757 dseg_addtarget(BlockPtrOfPC(*--s4ptr));
2761 /* length of dataseg after last dseg_addtarget is used by load */
2763 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2764 M_ALD(REG_ITMP2, REG_ITMP2, -dseglen);
2771 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2773 s4 i, l, val, *s4ptr;
2775 s4ptr = iptr->val.a;
2776 l = s4ptr[0]; /* default */
2777 i = s4ptr[1]; /* count */
2779 MCODECHECK((i<<2)+8);
2780 var_to_reg_int(s1, src, REG_ITMP1);
2784 ICONST(REG_ITMP2, val);
2786 M_BEQ(s1, REG_ITMP2, 0);
2787 mcode_addreference(BlockPtrOfPC(s4ptr[1]), mcodeptr);
2790 ICONST(REG_ITMP2, val);
2792 M_BEQ(s1, REG_ITMP2, 0);
2793 mcode_addreference(BlockPtrOfPC(s4ptr[1]), mcodeptr);
2798 mcode_addreference(BlockPtrOfPC(l), mcodeptr);
2805 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
2806 /* op1 = return type, val.a = function pointer*/
2810 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
2811 /* op1 = return type, val.a = function pointer*/
2815 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
2816 /* op1 = return type, val.a = function pointer*/
2820 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2821 /* op1 = arg count, val.a = method pointer */
2823 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2824 /* op1 = arg count, val.a = method pointer */
2826 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2827 /* op1 = arg count, val.a = method pointer */
2829 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
2830 /* op1 = arg count, val.a = method pointer */
2838 MCODECHECK((s3 << 1) + 64);
2840 /* copy arguments to registers or stack location */
2842 for (; --s3 >= 0; src = src->prev) {
2843 if (src->varkind == ARGVAR)
2845 if (IS_INT_LNG_TYPE(src->type)) {
2846 if (s3 < INT_ARG_CNT) {
2847 s1 = argintregs[s3];
2848 var_to_reg_int(d, src, s1);
2852 var_to_reg_int(d, src, REG_ITMP1);
2853 M_LST(d, REG_SP, 8 * (s3 - INT_ARG_CNT));
2857 if (s3 < FLT_ARG_CNT) {
2858 s1 = argfltregs[s3];
2859 var_to_reg_flt(d, src, s1);
2863 var_to_reg_flt(d, src, REG_FTMP1);
2864 M_DST(d, REG_SP, 8 * (s3 - FLT_ARG_CNT));
2869 switch (iptr->opc) {
2873 a = dseg_addaddress ((void*) (m));
2874 M_ALD(REG_ITMP1, REG_PV, a); /* built-in-function pointer */
2875 M_JSR (REG_RA, REG_ITMP1);
2877 d = iptr->op1; /* return type */
2878 goto afteractualcall;
2880 case ICMD_INVOKESTATIC:
2881 case ICMD_INVOKESPECIAL:
2882 a = dseg_addaddress (m->stubroutine);
2884 M_ALD(REG_PV, REG_PV, a ); /* method pointer in pv */
2887 goto makeactualcall;
2889 case ICMD_INVOKEVIRTUAL:
2891 gen_nullptr_check(argintregs[0]);
2892 M_ALD(REG_METHODPTR, argintregs[0],
2893 OFFSET(java_objectheader, vftbl));
2894 M_ALD(REG_PV, REG_METHODPTR, OFFSET(vftbl, table[0]) +
2895 sizeof(methodptr) * m->vftblindex);
2898 goto makeactualcall;
2900 case ICMD_INVOKEINTERFACE:
2903 gen_nullptr_check(argintregs[0]);
2904 M_ALD(REG_METHODPTR, argintregs[0],
2905 OFFSET(java_objectheader, vftbl));
2906 M_ALD(REG_METHODPTR, REG_METHODPTR,
2907 OFFSET(vftbl, interfacetable[0]) -
2908 sizeof(methodptr*) * ci->index);
2909 M_ALD(REG_PV, REG_METHODPTR,
2910 sizeof(methodptr) * (m - ci->methods));
2913 goto makeactualcall;
2917 sprintf (logtext, "Unkown ICMD-Command: %d", iptr->opc);
2923 M_JSR (REG_RA, REG_PV);
2928 s1 = (int)((u1*) mcodeptr - mcodebase);
2929 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
2931 panic("method to big");
2936 /* d contains return type */
2938 if (d != TYPE_VOID) {
2939 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
2940 s1 = reg_of_var(iptr->dst, REG_RESULT);
2941 M_INTMOVE(REG_RESULT, s1);
2942 store_reg_to_var_int(iptr->dst, s1);
2945 s1 = reg_of_var(iptr->dst, REG_FRESULT);
2946 M_FLTMOVE(REG_FRESULT, s1);
2947 store_reg_to_var_flt(iptr->dst, s1);
2954 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2956 /* op1: 0 == array, 1 == class */
2957 /* val.a: (classinfo*) superclass */
2959 /* superclass is an interface:
2961 * return (sub != NULL) &&
2962 * (sub->vftbl->interfacetablelength > super->index) &&
2963 * (sub->vftbl->interfacetable[-super->index] != NULL);
2965 * superclass is a class:
2967 * return ((sub != NULL) && (0
2968 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2969 * super->vftbl->diffvall));
2973 classinfo *super = (classinfo*) iptr->val.a;
2975 var_to_reg_int(s1, src, REG_ITMP1);
2976 d = reg_of_var(iptr->dst, REG_ITMP3);
2978 M_MOV(s1, REG_ITMP1);
2982 if (iptr->op1) { /* class/interface */
2983 if (super->flags & ACC_INTERFACE) { /* interface */
2986 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2987 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
2988 M_IADD_IMM(REG_ITMP2, - super->index, REG_ITMP2);
2989 M_BLEZ(REG_ITMP2, 3);
2991 M_ALD(REG_ITMP1, REG_ITMP1,
2992 OFFSET(vftbl, interfacetable[0]) -
2993 super->index * sizeof(methodptr*));
2994 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
2997 s2 = super->vftbl->diffval;
3000 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3001 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3002 M_IADD_IMM(REG_ITMP1, - super->vftbl->baseval, REG_ITMP1);
3003 M_CMPULT_IMM(REG_ITMP1, s2 + 1, d);
3007 panic ("internal error: no inlined array instanceof");
3009 store_reg_to_var_int(iptr->dst, d);
3012 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3014 /* op1: 0 == array, 1 == class */
3015 /* val.a: (classinfo*) superclass */
3017 /* superclass is an interface:
3019 * OK if ((sub == NULL) ||
3020 * (sub->vftbl->interfacetablelength > super->index) &&
3021 * (sub->vftbl->interfacetable[-super->index] != NULL));
3023 * superclass is a class:
3025 * OK if ((sub == NULL) || (0
3026 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3027 * super->vftbl->diffvall));
3031 classinfo *super = (classinfo*) iptr->val.a;
3033 d = reg_of_var(iptr->dst, REG_ITMP3);
3034 var_to_reg_int(s1, src, d);
3035 if (iptr->op1) { /* class/interface */
3036 if (super->flags & ACC_INTERFACE) { /* interface */
3039 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3040 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3041 M_IADD_IMM(REG_ITMP2, - super->index, REG_ITMP2);
3042 M_BLEZ(REG_ITMP2, 0);
3043 mcode_addxcastrefs(mcodeptr);
3045 M_ALD(REG_ITMP2, REG_ITMP1,
3046 OFFSET(vftbl, interfacetable[0]) -
3047 super->index * sizeof(methodptr*));
3048 M_BEQZ(REG_ITMP2, 0);
3049 mcode_addxcastrefs(mcodeptr);
3053 s2 = super->vftbl->diffval;
3054 M_BEQZ(s1, 6 + (s2 != 0));
3056 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3057 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3058 M_IADD_IMM(REG_ITMP1, - super->vftbl->baseval, REG_ITMP1);
3060 M_BNEZ(REG_ITMP1, 0);
3063 M_CMPULT_IMM(REG_ITMP1, s2 + 1, REG_ITMP2);
3064 M_BEQZ(REG_ITMP2, 0);
3066 mcode_addxcastrefs(mcodeptr);
3071 panic ("internal error: no inlined array checkcast");
3074 store_reg_to_var_int(iptr->dst, d);
3077 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
3079 var_to_reg_int(s1, src, REG_ITMP1);
3081 mcode_addxcheckarefs(mcodeptr);
3085 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3086 /* op1 = dimension, val.a = array descriptor */
3088 /* check for negative sizes and copy sizes to stack if necessary */
3090 MCODECHECK((iptr->op1 << 1) + 64);
3092 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3093 var_to_reg_int(s2, src, REG_ITMP1);
3095 mcode_addxcheckarefs(mcodeptr);
3098 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
3100 if (src->varkind != ARGVAR) {
3101 M_LST(s2, REG_SP, 8 * (s1 + INT_ARG_CNT));
3105 /* a0 = dimension count */
3107 ICONST(argintregs[0], iptr->op1);
3109 /* a1 = arraydescriptor */
3111 a = dseg_addaddress(iptr->val.a);
3112 M_ALD(argintregs[1], REG_PV, a);
3114 /* a2 = pointer to dimensions = stack pointer */
3116 M_INTMOVE(REG_SP, argintregs[2]);
3118 a = dseg_addaddress((void*) (builtin_nmultianewarray));
3119 M_ALD(REG_ITMP1, REG_PV, a);
3120 M_JSR(REG_RA, REG_ITMP1);
3122 s1 = reg_of_var(iptr->dst, REG_RESULT);
3123 M_INTMOVE(REG_RESULT, s1);
3124 store_reg_to_var_int(iptr->dst, s1);
3128 default: sprintf (logtext, "Unknown pseudo command: %d", iptr->opc);
3131 } /* for instruction */
3133 /* copy values to interface registers */
3135 src = bptr->outstack;
3136 len = bptr->outdepth;
3140 if ((src->varkind != STACKVAR)) {
3142 if (IS_FLT_DBL_TYPE(s2)) {
3143 var_to_reg_flt(s1, src, REG_FTMP1);
3144 if (!(interfaces[len][s2].flags & INMEMORY)) {
3145 M_FLTMOVE(s1,interfaces[len][s2].regoff);
3148 M_DST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3152 var_to_reg_int(s1, src, REG_ITMP1);
3153 if (!(interfaces[len][s2].flags & INMEMORY)) {
3154 M_INTMOVE(s1,interfaces[len][s2].regoff);
3157 M_LST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3163 } /* if (bptr -> flags >= BBREACHED) */
3164 } /* for basic block */
3166 bptr -> mpc = (int)((u1*) mcodeptr - mcodebase);
3169 /* generate bound check stubs */
3171 s4 *xcodeptr = NULL;
3173 for (; xboundrefs != NULL; xboundrefs = xboundrefs->next) {
3174 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3175 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
3176 xboundrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3180 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
3181 xboundrefs->branchpos, (u1*) mcodeptr - mcodebase);
3185 M_LDA(REG_ITMP2_XPC, REG_PV, xboundrefs->branchpos);
3187 if (xcodeptr != NULL) {
3188 M_BR((xcodeptr-mcodeptr)-1);
3192 xcodeptr = mcodeptr;
3194 a = dseg_addaddress(proto_java_lang_ArrayIndexOutOfBoundsException);
3195 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3197 a = dseg_addaddress(asm_handle_exception);
3198 M_ALD(REG_ITMP3, REG_PV, a);
3205 /* generate negative array size check stubs */
3209 for (; xcheckarefs != NULL; xcheckarefs = xcheckarefs->next) {
3210 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3211 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3212 xcheckarefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3216 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3217 xcheckarefs->branchpos, (u1*) mcodeptr - mcodebase);
3221 M_LDA(REG_ITMP2_XPC, REG_PV, xcheckarefs->branchpos);
3223 if (xcodeptr != NULL) {
3224 M_BR((xcodeptr-mcodeptr)-1);
3228 xcodeptr = mcodeptr;
3230 a = dseg_addaddress(proto_java_lang_NegativeArraySizeException);
3231 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3233 a = dseg_addaddress(asm_handle_exception);
3234 M_ALD(REG_ITMP3, REG_PV, a);
3241 /* generate cast check stubs */
3245 for (; xcastrefs != NULL; xcastrefs = xcastrefs->next) {
3246 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3247 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3248 xcastrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3252 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3253 xcastrefs->branchpos, (u1*) mcodeptr - mcodebase);
3257 M_LDA(REG_ITMP2_XPC, REG_PV, xcastrefs->branchpos);
3259 if (xcodeptr != NULL) {
3260 M_BR((xcodeptr-mcodeptr)-1);
3264 xcodeptr = mcodeptr;
3266 a = dseg_addaddress(proto_java_lang_ClassCastException);
3267 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3269 a = dseg_addaddress(asm_handle_exception);
3270 M_ALD(REG_ITMP3, REG_PV, a);
3278 #ifdef SOFTNULLPTRCHECK
3280 /* generate null pointer check stubs */
3284 for (; xnullrefs != NULL; xnullrefs = xnullrefs->next) {
3285 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3286 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3287 xnullrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3291 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3292 xnullrefs->branchpos, (u1*) mcodeptr - mcodebase);
3296 M_LDA(REG_ITMP2_XPC, REG_PV, xnullrefs->branchpos - 4);
3298 if (xcodeptr != NULL) {
3299 M_BR((xcodeptr-mcodeptr)-1);
3303 xcodeptr = mcodeptr;
3305 a = dseg_addaddress(proto_java_lang_NullPointerException);
3306 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3308 a = dseg_addaddress(asm_handle_exception);
3309 M_ALD(REG_ITMP3, REG_PV, a);
3319 mcode_finish((int)((u1*) mcodeptr - mcodebase));
3323 /* redefinition of code generation macros (compiling into array) **************/
3326 These macros are newly defined to allow code generation into an array.
3327 This is necessary, because the original M_.. macros generate code by
3328 calling 'mcode_adds4' that uses an additional data structure to
3331 For a faster (but less flexible) version to generate code, these
3332 macros directly use the (s4* p) - pointer to put the code directly
3333 in a locally defined array.
3334 This makes sense only for the stub-generation-routines below.
3338 #define M_ITYPE(op, rs, rt, imm)\
3339 *(p++) = (((op)<<26)|((rs)<<21)|((rt)<<16)|((imm)&0xffff))
3342 #define M_JTYPE(op, imm)\
3343 *(p++) = (((op)<<26)|((off)&0x3ffffff))
3346 #define M_RTYPE(op, rs, rt, rd, sa, fu)\
3347 *(p++) = (((op)<<26)|((rs)<<21)|((rt)<<16)|((rd)<<11)|((sa)<<6)|(fu))
3350 /* function createcompilerstub *************************************************
3352 creates a stub routine which calls the compiler
3354 *******************************************************************************/
3356 #define COMPSTUBSIZE 4
3358 u1 *createcompilerstub (methodinfo *m)
3360 u8 *s = CNEW (u8, COMPSTUBSIZE); /* memory to hold the stub */
3361 s4 *p = (s4*) s; /* code generation pointer */
3363 /* code for the stub */
3364 M_ALD(REG_PV, REG_PV, 16); /* load pointer to the compiler */
3365 M_JSR(REG_ITMP1, REG_PV); /* jump to the compiler, return address
3366 in itmp1 is used as method pointer */
3370 s[2] = (u8) m; /* literals to be adressed */
3371 s[3] = (u8) asm_call_jit_compiler; /* jump directly via PV from above */
3374 count_cstub_len += COMPSTUBSIZE * 8;
3381 /* function removecompilerstub *************************************************
3383 deletes a compilerstub from memory (simply by freeing it)
3385 *******************************************************************************/
3387 void removecompilerstub (u1 *stub)
3389 CFREE (stub, COMPSTUBSIZE * 8);
3393 /* function: createnativestub **************************************************
3395 creates a stub routine which calls a native method
3397 *******************************************************************************/
3399 #define NATIVESTUBSIZE 11
3401 u1 *createnativestub (functionptr f, methodinfo *m)
3403 u8 *s = CNEW (u8, NATIVESTUBSIZE); /* memory to hold the stub */
3404 s4 *p = (s4*) s; /* code generation pointer */
3406 M_ALD (REG_ITMP1, REG_PV, 8*8); /* load adress of native method */
3407 M_LDA (REG_SP, REG_SP, -8); /* build up stackframe */
3409 M_AST (REG_RA, REG_SP, 0); /* store return address */
3410 M_JSR (REG_RA, REG_ITMP1); /* call native method */
3412 M_NOP; /* delay slot */
3413 M_ALD (REG_ITMP3, REG_PV, 9*8); /* get address of exceptionptr */
3415 M_ALD (REG_RA, REG_SP, 0); /* load return address */
3416 M_ALD (REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
3418 M_BNEZ (REG_ITMP1, 2); /* if no exception then return */
3419 M_LDA (REG_SP, REG_SP, 8); /* remove stackframe, delay slot */
3421 M_RET (REG_RA); /* return to caller */
3422 M_NOP; /* delay slot */
3424 M_AST (REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
3425 M_ALD (REG_ITMP3, REG_PV,10*8); /* load asm exception handler address */
3427 M_JMP (REG_ITMP3); /* jump to asm exception handler */
3428 M_LDA (REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
3431 s[8] = (u8) f; /* address of native method */
3432 s[9] = (u8) (&exceptionptr); /* address of exceptionptr */
3433 s[10]= (u8) (asm_handle_nat_exception); /* addr of asm exception handler */
3436 count_nstub_len += NATIVESTUBSIZE * 8;
3443 /* function: removenativestub **************************************************
3445 removes a previously created native-stub from memory
3447 *******************************************************************************/
3449 void removenativestub (u1 *stub)
3451 CFREE (stub, NATIVESTUBSIZE * 8);
3456 * These are local overrides for various environment variables in Emacs.
3457 * Please do not remove this and leave it at the end of the file, where
3458 * Emacs will automagically detect them.
3459 * ---------------------------------------------------------------------
3462 * indent-tabs-mode: t