1 /* alpha/ngen.c ****************************************************************
3 Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
5 See file COPYRIGHT for information on usage and disclaimer of warranties
7 Contains the codegenerator for an Alpha processor.
8 This module generates Alpha machine code for a sequence of
9 pseudo commands (ICMDs).
11 Authors: Andreas Krall EMAIL: cacao@complang.tuwien.ac.at
12 Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at
14 Last Change: $Id: ngen.c 277 2003-05-09 19:36:04Z stefan $
16 *******************************************************************************/
18 #include "jitdef.h" /* phil */
20 /* *****************************************************************************
22 Datatypes and Register Allocations:
23 -----------------------------------
25 On 64-bit-machines (like the Alpha) all operands are stored in the
26 registers in a 64-bit form, even when the correspondig JavaVM operands
27 only need 32 bits. This is done by a canonical representation:
29 32-bit integers are allways stored as sign-extended 64-bit values (this
30 approach is directly supported by the Alpha architecture and is very easy
33 32-bit-floats are stored in a 64-bit doubleprecision register by simply
34 expanding the exponent and mantissa with zeroes. (also supported by the
40 The calling conventions and the layout of the stack is explained in detail
41 in the documention file: calling.doc
43 *******************************************************************************/
46 /* additional functions and macros to generate code ***************************/
48 /* #define BlockPtrOfPC(pc) block+block_index[pc] */
49 #define BlockPtrOfPC(pc) ((basicblock *) iptr->target)
53 #define COUNT_SPILLS count_spills++
59 /* gen_nullptr_check(objreg) */
61 #ifdef SOFTNULLPTRCHECK
62 #define gen_nullptr_check(objreg) \
65 mcode_addxnullrefs(mcodeptr);\
68 #define gen_nullptr_check(objreg)
72 /* MCODECHECK(icnt) */
74 #define MCODECHECK(icnt) \
75 if((mcodeptr+(icnt))>mcodeend)mcodeptr=mcode_increase((u1*)mcodeptr)
78 generates an integer-move from register a to b.
79 if a and b are the same int-register, no code will be generated.
82 #define M_INTMOVE(a,b) if(a!=b){M_MOV(a,b);}
86 generates a floating-point-move from register a to b.
87 if a and b are the same float-register, no code will be generated
90 #define M_FLTMOVE(a,b) if(a!=b){M_FMOV(a,b);}
94 this function generates code to fetch data from a pseudo-register
96 If the pseudo-register has actually been assigned to a real
97 register, no code will be emitted, since following operations
98 can use this register directly.
100 v: pseudoregister to be fetched from
101 tempregnum: temporary register to be used if v is actually spilled to ram
103 return: the register number, where the operand can be found after
104 fetching (this wil be either tempregnum or the register
105 number allready given to v)
108 #define var_to_reg_int(regnr,v,tempnr) { \
109 if ((v)->flags & INMEMORY) \
110 {COUNT_SPILLS;M_LLD(tempnr,REG_SP,8*(v)->regoff);regnr=tempnr;} \
111 else regnr=(v)->regoff; \
115 #define var_to_reg_flt(regnr,v,tempnr) { \
116 if ((v)->flags & INMEMORY) \
117 {COUNT_SPILLS;M_DLD(tempnr,REG_SP,8*(v)->regoff);regnr=tempnr;} \
118 else regnr=(v)->regoff; \
123 This function determines a register, to which the result of an operation
124 should go, when it is ultimatively intended to store the result in
126 If v is assigned to an actual register, this register will be returned.
127 Otherwise (when v is spilled) this function returns tempregnum.
128 If not already done, regoff and flags are set in the stack location.
131 static int reg_of_var(stackptr v, int tempregnum)
135 switch (v->varkind) {
137 if (!(v->flags & INMEMORY))
141 var = &(interfaces[v->varnum][v->type]);
142 v->regoff = var->regoff;
143 if (!(var->flags & INMEMORY))
147 var = &(locals[v->varnum][v->type]);
148 v->regoff = var->regoff;
149 if (!(var->flags & INMEMORY))
153 v->regoff = v->varnum;
154 if (IS_FLT_DBL_TYPE(v->type)) {
155 if (v->varnum < fltreg_argnum) {
156 v->regoff = argfltregs[v->varnum];
157 return(argfltregs[v->varnum]);
161 if (v->varnum < intreg_argnum) {
162 v->regoff = argintregs[v->varnum];
163 return(argintregs[v->varnum]);
165 v->regoff -= intreg_argnum;
168 v->flags |= INMEMORY;
173 /* store_reg_to_var_xxx:
174 This function generates the code to store the result of an operation
175 back into a spilled pseudo-variable.
176 If the pseudo-variable has not been spilled in the first place, this
177 function will generate nothing.
179 v ............ Pseudovariable
180 tempregnum ... Number of the temporary registers as returned by
184 #define store_reg_to_var_int(sptr, tempregnum) { \
185 if ((sptr)->flags & INMEMORY) { \
187 M_LST(tempregnum, REG_SP, 8 * (sptr)->regoff); \
191 #define store_reg_to_var_flt(sptr, tempregnum) { \
192 if ((sptr)->flags & INMEMORY) { \
194 M_DST(tempregnum, REG_SP, 8 * (sptr)->regoff); \
199 /* NullPointerException handlers and exception handling initialisation */
201 typedef struct sigctx_struct {
203 long sc_onstack; /* sigstack state to restore */
204 long sc_mask; /* signal mask to restore */
205 long sc_pc; /* pc at time of signal */
206 long sc_ps; /* psl to retore */
207 long sc_regs[32]; /* processor regs 0 to 31 */
208 long sc_ownedfp; /* fp has been used */
209 long sc_fpregs[32]; /* fp regs 0 to 31 */
210 unsigned long sc_fpcr; /* floating point control register */
211 unsigned long sc_fp_control; /* software fpcr */
213 unsigned long sc_reserved1, sc_reserved2;
214 unsigned long sc_ssize;
216 unsigned long sc_traparg_a0;
217 unsigned long sc_traparg_a1;
218 unsigned long sc_traparg_a2;
219 unsigned long sc_fp_trap_pc;
220 unsigned long sc_fp_trigger_sum;
221 unsigned long sc_fp_trigger_inst;
222 unsigned long sc_retcode[2];
226 /* NullPointerException signal handler for hardware null pointer check */
228 void catch_NullPointerException(int sig, int code, sigctx_struct *sigctx)
234 /* Reset signal handler - necessary for SysV, does no harm for BSD */
236 instr = *((int*)(sigctx->sc_pc));
237 faultaddr = sigctx->sc_regs[(instr >> 16) & 0x1f];
239 if (faultaddr == 0) {
240 signal(sig, (void*) catch_NullPointerException); /* reinstall handler */
242 sigaddset(&nsig, sig);
243 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
244 sigctx->sc_regs[REG_ITMP1_XPTR] =
245 (long) proto_java_lang_NullPointerException;
246 sigctx->sc_regs[REG_ITMP2_XPC] = sigctx->sc_pc;
247 sigctx->sc_pc = (long) asm_handle_exception;
251 faultaddr += (long) ((instr << 16) >> 16);
252 fprintf(stderr, "faulting address: 0x%16lx\n", faultaddr);
253 panic("Stack overflow");
260 void init_exceptions(void)
265 /* Linux on Digital Alpha needs an initialisation of the ieee floating point
266 control for IEEE compliant arithmetic (option -mieee of GCC). Under
267 Digital Unix this is done automatically.
272 extern unsigned long ieee_get_fp_control();
273 extern void ieee_set_fp_control(unsigned long fp_control);
275 void init_exceptions(void)
277 /* initialize floating point control */
279 ieee_set_fp_control(ieee_get_fp_control()
280 & ~IEEE_TRAP_ENABLE_INV
281 & ~IEEE_TRAP_ENABLE_DZE
282 /* & ~IEEE_TRAP_ENABLE_UNF we dont want underflow */
283 & ~IEEE_TRAP_ENABLE_OVF);
286 /* install signal handlers we need to convert to exceptions */
291 signal(SIGSEGV, (void*) catch_NullPointerException);
295 signal(SIGBUS, (void*) catch_NullPointerException);
301 /* function gen_mcode **********************************************************
303 generates machine code
305 *******************************************************************************/
307 #define MethodPointer -8
308 #define FrameSize -12
313 #define ExTableSize -32
314 #define ExTableStart -32
316 #define ExEntrySize -32
319 #define ExHandlerPC -24
320 #define ExCatchType -32
322 static void gen_mcode()
324 int len, s1, s2, s3, d, bbs;
336 savedregs_num = (isleafmethod) ? 0 : 1; /* space to save the RA */
338 /* space to save used callee saved registers */
340 savedregs_num += (savintregcnt - maxsavintreguse);
341 savedregs_num += (savfltregcnt - maxsavfltreguse);
343 parentargs_base = maxmemuse + savedregs_num;
345 #ifdef USE_THREADS /* space to save argument of monitor_enter */
347 if (checksync && (method->flags & ACC_SYNCHRONIZED))
352 /* create method header */
354 (void) dseg_addaddress(method); /* MethodPointer */
355 (void) dseg_adds4(parentargs_base * 8); /* FrameSize */
359 /* IsSync contains the offset relative to the stack pointer for the
360 argument of monitor_exit used in the exception handler. Since the
361 offset could be zero and give a wrong meaning of the flag it is
365 if (checksync && (method->flags & ACC_SYNCHRONIZED))
366 (void) dseg_adds4((maxmemuse + 1) * 8); /* IsSync */
371 (void) dseg_adds4(0); /* IsSync */
373 (void) dseg_adds4(isleafmethod); /* IsLeaf */
374 (void) dseg_adds4(savintregcnt - maxsavintreguse); /* IntSave */
375 (void) dseg_adds4(savfltregcnt - maxsavfltreguse); /* FltSave */
376 (void) dseg_adds4(exceptiontablelength); /* ExTableSize */
378 /* create exception table */
380 for (ex = extable; ex != NULL; ex = ex->down) {
383 if (ex->start != NULL)
384 printf("adding start - %d - ", ex->start->debug_nr);
386 printf("PANIC - start is NULL");
391 dseg_addtarget(ex->start);
395 printf("adding end - %d - ", ex->end->debug_nr);
397 printf("PANIC - end is NULL");
402 dseg_addtarget(ex->end);
405 if (ex->handler != NULL)
406 printf("adding handler - %d\n", ex->handler->debug_nr);
408 printf("PANIC - handler is NULL");
413 dseg_addtarget(ex->handler);
415 (void) dseg_addaddress(ex->catchtype);
418 /* initialize mcode variables */
420 mcodeptr = (s4*) mcodebase;
421 mcodeend = (s4*) (mcodebase + mcodesize);
422 MCODECHECK(128 + mparamcount);
424 /* create stack frame (if necessary) */
427 {M_LDA (REG_SP, REG_SP, -parentargs_base * 8);}
429 /* save return address and used callee saved registers */
433 {p--; M_AST (REG_RA, REG_SP, 8*p);}
434 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
435 {p--; M_LST (savintregs[r], REG_SP, 8 * p);}
436 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
437 {p--; M_DST (savfltregs[r], REG_SP, 8 * p);}
439 /* save monitorenter argument */
442 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
443 if (method->flags & ACC_STATIC) {
444 p = dseg_addaddress (class);
445 M_ALD(REG_ITMP1, REG_PV, p);
446 M_AST(REG_ITMP1, REG_SP, 8 * maxmemuse);
449 M_AST (argintregs[0], REG_SP, 8 * maxmemuse);
454 /* copy argument registers to stack and call trace function with pointer
455 to arguments on stack. ToDo: save floating point registers !!!!!!!!!
458 if (runverbose && isleafmethod) {
459 M_LDA (REG_SP, REG_SP, -(14*8));
460 M_AST(REG_RA, REG_SP, 1*8);
462 M_LST(argintregs[0], REG_SP, 2*8);
463 M_LST(argintregs[1], REG_SP, 3*8);
464 M_LST(argintregs[2], REG_SP, 4*8);
465 M_LST(argintregs[3], REG_SP, 5*8);
466 M_LST(argintregs[4], REG_SP, 6*8);
467 M_LST(argintregs[5], REG_SP, 7*8);
469 M_DST(argfltregs[0], REG_SP, 8*8);
470 M_DST(argfltregs[1], REG_SP, 9*8);
471 M_DST(argfltregs[2], REG_SP, 10*8);
472 M_DST(argfltregs[3], REG_SP, 11*8);
473 M_DST(argfltregs[4], REG_SP, 12*8);
474 M_DST(argfltregs[5], REG_SP, 13*8);
476 p = dseg_addaddress (method);
477 M_ALD(REG_ITMP1, REG_PV, p);
478 M_AST(REG_ITMP1, REG_SP, 0);
479 p = dseg_addaddress ((void*) (builtin_trace_args));
480 M_ALD(REG_PV, REG_PV, p);
481 M_JSR(REG_RA, REG_PV);
482 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
483 M_ALD(REG_RA, REG_SP, 1*8);
485 M_LLD(argintregs[0], REG_SP, 2*8);
486 M_LLD(argintregs[1], REG_SP, 3*8);
487 M_LLD(argintregs[2], REG_SP, 4*8);
488 M_LLD(argintregs[3], REG_SP, 5*8);
489 M_LLD(argintregs[4], REG_SP, 6*8);
490 M_LLD(argintregs[5], REG_SP, 7*8);
492 M_DLD(argfltregs[0], REG_SP, 8*8);
493 M_DLD(argfltregs[1], REG_SP, 9*8);
494 M_DLD(argfltregs[2], REG_SP, 10*8);
495 M_DLD(argfltregs[3], REG_SP, 11*8);
496 M_DLD(argfltregs[4], REG_SP, 12*8);
497 M_DLD(argfltregs[5], REG_SP, 13*8);
499 M_LDA (REG_SP, REG_SP, 14*8);
502 /* take arguments out of register or stack frame */
504 for (p = 0, l = 0; p < mparamcount; p++) {
506 var = &(locals[l][t]);
508 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
513 if (IS_INT_LNG_TYPE(t)) { /* integer args */
514 if (p < INT_ARG_CNT) { /* register arguments */
515 if (!(var->flags & INMEMORY)) /* reg arg -> register */
516 {M_INTMOVE (argintregs[p], r);}
517 else /* reg arg -> spilled */
518 M_LST (argintregs[p], REG_SP, 8 * r);
520 else { /* stack arguments */
521 pa = p - INT_ARG_CNT;
522 if (!(var->flags & INMEMORY)) /* stack arg -> register */
523 M_LLD (r, REG_SP, 8 * (parentargs_base + pa));
524 else { /* stack arg -> spilled */
525 M_LLD (REG_ITMP1, REG_SP, 8 * (parentargs_base + pa));
526 M_LST (REG_ITMP1, REG_SP, 8 * r);
530 else { /* floating args */
531 if (p < FLT_ARG_CNT) { /* register arguments */
532 if (!(var->flags & INMEMORY)) /* reg arg -> register */
533 {M_FLTMOVE (argfltregs[p], r);}
534 else /* reg arg -> spilled */
535 M_DST (argfltregs[p], REG_SP, 8 * r);
537 else { /* stack arguments */
538 pa = p - FLT_ARG_CNT;
539 if (!(var->flags & INMEMORY)) /* stack-arg -> register */
540 M_DLD (r, REG_SP, 8 * (parentargs_base + pa) );
541 else { /* stack-arg -> spilled */
542 M_DLD (REG_FTMP1, REG_SP, 8 * (parentargs_base + pa));
543 M_DST (REG_FTMP1, REG_SP, 8 * r);
549 /* call trace function */
551 if (runverbose && !isleafmethod) {
552 M_LDA (REG_SP, REG_SP, -8);
553 p = dseg_addaddress (method);
554 M_ALD(REG_ITMP1, REG_PV, p);
555 M_AST(REG_ITMP1, REG_SP, 0);
556 p = dseg_addaddress ((void*) (builtin_trace_args));
557 M_ALD(REG_PV, REG_PV, p);
558 M_JSR(REG_RA, REG_PV);
559 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
560 M_LDA(REG_SP, REG_SP, 8);
563 /* call monitorenter function */
566 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
567 p = dseg_addaddress ((void*) (builtin_monitorenter));
568 M_ALD(REG_PV, REG_PV, p);
569 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
570 M_JSR(REG_RA, REG_PV);
571 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
576 /* end of header generation */
578 /* walk through all basic blocks */
579 for (/* bbs = block_count, */ bptr = block; /* --bbs >= 0 */ bptr != NULL; bptr = bptr->next) {
581 bptr -> mpc = (int)((u1*) mcodeptr - mcodebase);
583 if (bptr->flags >= BBREACHED) {
585 /* branch resolving */
589 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
590 gen_resolvebranch((u1*) mcodebase + brefs->branchpos,
591 brefs->branchpos, bptr->mpc);
595 /* copy interface registers to their destination */
600 while (src != NULL) {
602 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
603 d = reg_of_var(src, REG_ITMP1);
604 M_INTMOVE(REG_ITMP1, d);
605 store_reg_to_var_int(src, d);
608 d = reg_of_var(src, REG_IFTMP);
609 if ((src->varkind != STACKVAR)) {
611 if (IS_FLT_DBL_TYPE(s2)) {
612 if (!(interfaces[len][s2].flags & INMEMORY)) {
613 s1 = interfaces[len][s2].regoff;
617 M_DLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
619 store_reg_to_var_flt(src, d);
622 if (!(interfaces[len][s2].flags & INMEMORY)) {
623 s1 = interfaces[len][s2].regoff;
627 M_LLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
629 store_reg_to_var_int(src, d);
636 /* walk through all instructions */
640 for (iptr = bptr->iinstr;
642 src = iptr->dst, len--, iptr++) {
644 MCODECHECK(64); /* an instruction usually needs < 64 words */
647 case ICMD_NOP: /* ... ==> ... */
650 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
652 var_to_reg_int(s1, src, REG_ITMP1);
654 mcode_addxnullrefs(mcodeptr);
657 /* constant operations ************************************************/
659 #define ICONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
660 else{a=dseg_adds4(c);M_ILD(r,REG_PV,a);}
662 #define LCONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
663 else{a=dseg_adds8(c);M_LLD(r,REG_PV,a);}
665 case ICMD_ICONST: /* ... ==> ..., constant */
666 /* op1 = 0, val.i = constant */
668 d = reg_of_var(iptr->dst, REG_ITMP1);
669 ICONST(d, iptr->val.i);
670 store_reg_to_var_int(iptr->dst, d);
673 case ICMD_LCONST: /* ... ==> ..., constant */
674 /* op1 = 0, val.l = constant */
676 d = reg_of_var(iptr->dst, REG_ITMP1);
677 LCONST(d, iptr->val.l);
678 store_reg_to_var_int(iptr->dst, d);
681 case ICMD_FCONST: /* ... ==> ..., constant */
682 /* op1 = 0, val.f = constant */
684 d = reg_of_var (iptr->dst, REG_FTMP1);
685 a = dseg_addfloat (iptr->val.f);
687 store_reg_to_var_flt (iptr->dst, d);
690 case ICMD_DCONST: /* ... ==> ..., constant */
691 /* op1 = 0, val.d = constant */
693 d = reg_of_var (iptr->dst, REG_FTMP1);
694 a = dseg_adddouble (iptr->val.d);
696 store_reg_to_var_flt (iptr->dst, d);
699 case ICMD_ACONST: /* ... ==> ..., constant */
700 /* op1 = 0, val.a = constant */
702 d = reg_of_var(iptr->dst, REG_ITMP1);
704 a = dseg_addaddress (iptr->val.a);
708 M_INTMOVE(REG_ZERO, d);
710 store_reg_to_var_int(iptr->dst, d);
714 /* load/store operations **********************************************/
716 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
717 case ICMD_LLOAD: /* op1 = local variable */
720 d = reg_of_var(iptr->dst, REG_ITMP1);
721 if ((iptr->dst->varkind == LOCALVAR) &&
722 (iptr->dst->varnum == iptr->op1))
724 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
725 if (var->flags & INMEMORY)
726 M_LLD(d, REG_SP, 8 * var->regoff);
728 {M_INTMOVE(var->regoff,d);}
729 store_reg_to_var_int(iptr->dst, d);
732 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
733 case ICMD_DLOAD: /* op1 = local variable */
735 d = reg_of_var(iptr->dst, REG_FTMP1);
736 if ((iptr->dst->varkind == LOCALVAR) &&
737 (iptr->dst->varnum == iptr->op1))
739 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
740 if (var->flags & INMEMORY)
741 M_DLD(d, REG_SP, 8 * var->regoff);
743 {M_FLTMOVE(var->regoff,d);}
744 store_reg_to_var_flt(iptr->dst, d);
748 case ICMD_ISTORE: /* ..., value ==> ... */
749 case ICMD_LSTORE: /* op1 = local variable */
752 if ((src->varkind == LOCALVAR) &&
753 (src->varnum == iptr->op1))
755 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
756 if (var->flags & INMEMORY) {
757 var_to_reg_int(s1, src, REG_ITMP1);
758 M_LST(s1, REG_SP, 8 * var->regoff);
761 var_to_reg_int(s1, src, var->regoff);
762 M_INTMOVE(s1, var->regoff);
766 case ICMD_FSTORE: /* ..., value ==> ... */
767 case ICMD_DSTORE: /* op1 = local variable */
769 if ((src->varkind == LOCALVAR) &&
770 (src->varnum == iptr->op1))
772 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
773 if (var->flags & INMEMORY) {
774 var_to_reg_flt(s1, src, REG_FTMP1);
775 M_DST(s1, REG_SP, 8 * var->regoff);
778 var_to_reg_flt(s1, src, var->regoff);
779 M_FLTMOVE(s1, var->regoff);
784 /* pop/dup/swap operations ********************************************/
786 /* attention: double and longs are only one entry in CACAO ICMDs */
788 case ICMD_POP: /* ..., value ==> ... */
789 case ICMD_POP2: /* ..., value, value ==> ... */
792 #define M_COPY(from,to) \
793 d = reg_of_var(to, REG_IFTMP); \
794 if ((from->regoff != to->regoff) || \
795 ((from->flags ^ to->flags) & INMEMORY)) { \
796 if (IS_FLT_DBL_TYPE(from->type)) { \
797 var_to_reg_flt(s1, from, d); \
799 store_reg_to_var_flt(to, d); \
802 var_to_reg_int(s1, from, d); \
804 store_reg_to_var_int(to, d); \
808 case ICMD_DUP: /* ..., a ==> ..., a, a */
809 M_COPY(src, iptr->dst);
812 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
814 M_COPY(src, iptr->dst->prev->prev);
816 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
818 M_COPY(src, iptr->dst);
819 M_COPY(src->prev, iptr->dst->prev);
822 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
824 M_COPY(src->prev, iptr->dst->prev->prev->prev);
826 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
828 M_COPY(src, iptr->dst);
829 M_COPY(src->prev, iptr->dst->prev);
830 M_COPY(src->prev->prev, iptr->dst->prev->prev);
831 M_COPY(src, iptr->dst->prev->prev->prev);
834 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
836 M_COPY(src, iptr->dst);
837 M_COPY(src->prev, iptr->dst->prev);
838 M_COPY(src->prev->prev, iptr->dst->prev->prev);
839 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
840 M_COPY(src, iptr->dst->prev->prev->prev->prev);
841 M_COPY(src->prev, iptr->dst->prev->prev->prev->prev->prev);
844 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
846 M_COPY(src, iptr->dst->prev);
847 M_COPY(src->prev, iptr->dst);
851 /* integer operations *************************************************/
853 case ICMD_INEG: /* ..., value ==> ..., - value */
855 var_to_reg_int(s1, src, REG_ITMP1);
856 d = reg_of_var(iptr->dst, REG_ITMP3);
857 M_ISUB(REG_ZERO, s1, d);
858 store_reg_to_var_int(iptr->dst, d);
861 case ICMD_LNEG: /* ..., value ==> ..., - value */
863 var_to_reg_int(s1, src, REG_ITMP1);
864 d = reg_of_var(iptr->dst, REG_ITMP3);
865 M_LSUB(REG_ZERO, s1, d);
866 store_reg_to_var_int(iptr->dst, d);
869 case ICMD_I2L: /* ..., value ==> ..., value */
871 var_to_reg_int(s1, src, REG_ITMP1);
872 d = reg_of_var(iptr->dst, REG_ITMP3);
874 store_reg_to_var_int(iptr->dst, d);
877 case ICMD_L2I: /* ..., value ==> ..., value */
879 var_to_reg_int(s1, src, REG_ITMP1);
880 d = reg_of_var(iptr->dst, REG_ITMP3);
881 M_IADD(s1, REG_ZERO, d );
882 store_reg_to_var_int(iptr->dst, d);
885 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
887 var_to_reg_int(s1, src, REG_ITMP1);
888 d = reg_of_var(iptr->dst, REG_ITMP3);
889 if (has_ext_instr_set) {
893 M_SLL_IMM(s1, 56, d);
894 M_SRA_IMM( d, 56, d);
896 store_reg_to_var_int(iptr->dst, d);
899 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
901 var_to_reg_int(s1, src, REG_ITMP1);
902 d = reg_of_var(iptr->dst, REG_ITMP3);
904 store_reg_to_var_int(iptr->dst, d);
907 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
909 var_to_reg_int(s1, src, REG_ITMP1);
910 d = reg_of_var(iptr->dst, REG_ITMP3);
911 if (has_ext_instr_set) {
915 M_SLL_IMM(s1, 48, d);
916 M_SRA_IMM( d, 48, d);
918 store_reg_to_var_int(iptr->dst, d);
922 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
924 var_to_reg_int(s1, src->prev, REG_ITMP1);
925 var_to_reg_int(s2, src, REG_ITMP2);
926 d = reg_of_var(iptr->dst, REG_ITMP3);
928 store_reg_to_var_int(iptr->dst, d);
931 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
932 /* val.i = constant */
934 var_to_reg_int(s1, src, REG_ITMP1);
935 d = reg_of_var(iptr->dst, REG_ITMP3);
936 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
937 M_IADD_IMM(s1, iptr->val.i, d);
940 ICONST(REG_ITMP2, iptr->val.i);
941 M_IADD(s1, REG_ITMP2, d);
943 store_reg_to_var_int(iptr->dst, d);
946 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
948 var_to_reg_int(s1, src->prev, REG_ITMP1);
949 var_to_reg_int(s2, src, REG_ITMP2);
950 d = reg_of_var(iptr->dst, REG_ITMP3);
952 store_reg_to_var_int(iptr->dst, d);
955 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
956 /* val.l = constant */
958 var_to_reg_int(s1, src, REG_ITMP1);
959 d = reg_of_var(iptr->dst, REG_ITMP3);
960 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
961 M_LADD_IMM(s1, iptr->val.l, d);
964 LCONST(REG_ITMP2, iptr->val.l);
965 M_LADD(s1, REG_ITMP2, d);
967 store_reg_to_var_int(iptr->dst, d);
970 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
972 var_to_reg_int(s1, src->prev, REG_ITMP1);
973 var_to_reg_int(s2, src, REG_ITMP2);
974 d = reg_of_var(iptr->dst, REG_ITMP3);
976 store_reg_to_var_int(iptr->dst, d);
979 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
980 /* val.i = constant */
982 var_to_reg_int(s1, src, REG_ITMP1);
983 d = reg_of_var(iptr->dst, REG_ITMP3);
984 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
985 M_ISUB_IMM(s1, iptr->val.i, d);
988 ICONST(REG_ITMP2, iptr->val.i);
989 M_ISUB(s1, REG_ITMP2, d);
991 store_reg_to_var_int(iptr->dst, d);
994 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
996 var_to_reg_int(s1, src->prev, REG_ITMP1);
997 var_to_reg_int(s2, src, REG_ITMP2);
998 d = reg_of_var(iptr->dst, REG_ITMP3);
1000 store_reg_to_var_int(iptr->dst, d);
1003 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
1004 /* val.l = constant */
1006 var_to_reg_int(s1, src, REG_ITMP1);
1007 d = reg_of_var(iptr->dst, REG_ITMP3);
1008 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1009 M_LSUB_IMM(s1, iptr->val.l, d);
1012 LCONST(REG_ITMP2, iptr->val.l);
1013 M_LSUB(s1, REG_ITMP2, d);
1015 store_reg_to_var_int(iptr->dst, d);
1018 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1020 var_to_reg_int(s1, src->prev, REG_ITMP1);
1021 var_to_reg_int(s2, src, REG_ITMP2);
1022 d = reg_of_var(iptr->dst, REG_ITMP3);
1024 store_reg_to_var_int(iptr->dst, d);
1027 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
1028 /* val.i = constant */
1030 var_to_reg_int(s1, src, REG_ITMP1);
1031 d = reg_of_var(iptr->dst, REG_ITMP3);
1032 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1033 M_IMUL_IMM(s1, iptr->val.i, d);
1036 ICONST(REG_ITMP2, iptr->val.i);
1037 M_IMUL(s1, REG_ITMP2, d);
1039 store_reg_to_var_int(iptr->dst, d);
1042 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1044 var_to_reg_int(s1, src->prev, REG_ITMP1);
1045 var_to_reg_int(s2, src, REG_ITMP2);
1046 d = reg_of_var(iptr->dst, REG_ITMP3);
1048 store_reg_to_var_int(iptr->dst, d);
1051 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
1052 /* val.l = constant */
1054 var_to_reg_int(s1, src, REG_ITMP1);
1055 d = reg_of_var(iptr->dst, REG_ITMP3);
1056 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1057 M_LMUL_IMM(s1, iptr->val.l, d);
1060 LCONST(REG_ITMP2, iptr->val.l);
1061 M_LMUL(s1, REG_ITMP2, d);
1063 store_reg_to_var_int(iptr->dst, d);
1066 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
1067 case ICMD_LDIVPOW2: /* val.i = constant */
1069 var_to_reg_int(s1, src, REG_ITMP1);
1070 d = reg_of_var(iptr->dst, REG_ITMP3);
1071 if (iptr->val.i <= 15) {
1072 M_LDA(REG_ITMP2, s1, (1 << iptr->val.i) -1);
1073 M_CMOVGE(s1, s1, REG_ITMP2);
1076 M_SRA_IMM(s1, 63, REG_ITMP2);
1077 M_SRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
1078 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1080 M_SRA_IMM(REG_ITMP2, iptr->val.i, d);
1081 store_reg_to_var_int(iptr->dst, d);
1084 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1086 var_to_reg_int(s1, src->prev, REG_ITMP1);
1087 var_to_reg_int(s2, src, REG_ITMP2);
1088 d = reg_of_var(iptr->dst, REG_ITMP3);
1089 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1090 M_SLL(s1, REG_ITMP3, d);
1091 M_IADD(d, REG_ZERO, d);
1092 store_reg_to_var_int(iptr->dst, d);
1095 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1096 /* val.i = constant */
1098 var_to_reg_int(s1, src, REG_ITMP1);
1099 d = reg_of_var(iptr->dst, REG_ITMP3);
1100 M_SLL_IMM(s1, iptr->val.i & 0x1f, d);
1101 M_IADD(d, REG_ZERO, d);
1102 store_reg_to_var_int(iptr->dst, d);
1105 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1107 var_to_reg_int(s1, src->prev, REG_ITMP1);
1108 var_to_reg_int(s2, src, REG_ITMP2);
1109 d = reg_of_var(iptr->dst, REG_ITMP3);
1110 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1111 M_SRA(s1, REG_ITMP3, d);
1112 store_reg_to_var_int(iptr->dst, d);
1115 case ICMD_ISHRCONST: /* ..., 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 M_SRA_IMM(s1, iptr->val.i & 0x1f, d);
1121 store_reg_to_var_int(iptr->dst, d);
1124 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1126 var_to_reg_int(s1, src->prev, REG_ITMP1);
1127 var_to_reg_int(s2, src, REG_ITMP2);
1128 d = reg_of_var(iptr->dst, REG_ITMP3);
1129 M_AND_IMM(s2, 0x1f, REG_ITMP2);
1131 M_SRL(d, REG_ITMP2, d);
1132 M_IADD(d, REG_ZERO, d);
1133 store_reg_to_var_int(iptr->dst, d);
1136 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1137 /* val.i = constant */
1139 var_to_reg_int(s1, src, REG_ITMP1);
1140 d = reg_of_var(iptr->dst, REG_ITMP3);
1142 M_SRL_IMM(d, iptr->val.i & 0x1f, d);
1143 M_IADD(d, REG_ZERO, d);
1144 store_reg_to_var_int(iptr->dst, d);
1147 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1149 var_to_reg_int(s1, src->prev, REG_ITMP1);
1150 var_to_reg_int(s2, src, REG_ITMP2);
1151 d = reg_of_var(iptr->dst, REG_ITMP3);
1153 store_reg_to_var_int(iptr->dst, d);
1156 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1157 /* val.l = constant */
1159 var_to_reg_int(s1, src, REG_ITMP1);
1160 d = reg_of_var(iptr->dst, REG_ITMP3);
1161 M_SLL_IMM(s1, iptr->val.l & 0x3f, d);
1162 store_reg_to_var_int(iptr->dst, d);
1165 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1167 var_to_reg_int(s1, src->prev, REG_ITMP1);
1168 var_to_reg_int(s2, src, REG_ITMP2);
1169 d = reg_of_var(iptr->dst, REG_ITMP3);
1171 store_reg_to_var_int(iptr->dst, d);
1174 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1175 /* val.l = constant */
1177 var_to_reg_int(s1, src, REG_ITMP1);
1178 d = reg_of_var(iptr->dst, REG_ITMP3);
1179 M_SRA_IMM(s1, iptr->val.l & 0x3f, d);
1180 store_reg_to_var_int(iptr->dst, d);
1183 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1185 var_to_reg_int(s1, src->prev, REG_ITMP1);
1186 var_to_reg_int(s2, src, REG_ITMP2);
1187 d = reg_of_var(iptr->dst, REG_ITMP3);
1189 store_reg_to_var_int(iptr->dst, d);
1192 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1193 /* val.l = constant */
1195 var_to_reg_int(s1, src, REG_ITMP1);
1196 d = reg_of_var(iptr->dst, REG_ITMP3);
1197 M_SRL_IMM(s1, iptr->val.l & 0x3f, d);
1198 store_reg_to_var_int(iptr->dst, d);
1201 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1204 var_to_reg_int(s1, src->prev, REG_ITMP1);
1205 var_to_reg_int(s2, src, REG_ITMP2);
1206 d = reg_of_var(iptr->dst, REG_ITMP3);
1208 store_reg_to_var_int(iptr->dst, d);
1211 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1212 /* val.i = constant */
1214 var_to_reg_int(s1, src, REG_ITMP1);
1215 d = reg_of_var(iptr->dst, REG_ITMP3);
1216 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1217 M_AND_IMM(s1, iptr->val.i, d);
1219 else if (iptr->val.i == 0xffff) {
1222 else if (iptr->val.i == 0xffffff) {
1223 M_ZAPNOT_IMM(s1, 0x07, d);
1226 ICONST(REG_ITMP2, iptr->val.i);
1227 M_AND(s1, REG_ITMP2, d);
1229 store_reg_to_var_int(iptr->dst, d);
1232 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1233 /* val.i = constant */
1235 var_to_reg_int(s1, src, REG_ITMP1);
1236 d = reg_of_var(iptr->dst, REG_ITMP3);
1238 M_MOV(s1, REG_ITMP1);
1241 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1242 M_AND_IMM(s1, iptr->val.i, d);
1244 M_ISUB(REG_ZERO, s1, d);
1245 M_AND_IMM(d, iptr->val.i, d);
1247 else if (iptr->val.i == 0xffff) {
1250 M_ISUB(REG_ZERO, s1, d);
1253 else if (iptr->val.i == 0xffffff) {
1254 M_ZAPNOT_IMM(s1, 0x07, d);
1256 M_ISUB(REG_ZERO, s1, d);
1257 M_ZAPNOT_IMM(d, 0x07, d);
1260 ICONST(REG_ITMP2, iptr->val.i);
1261 M_AND(s1, REG_ITMP2, d);
1263 M_ISUB(REG_ZERO, s1, d);
1264 M_AND(d, REG_ITMP2, d);
1266 M_ISUB(REG_ZERO, d, d);
1267 store_reg_to_var_int(iptr->dst, d);
1270 case ICMD_IREM0X10001: /* ..., value ==> ..., value % 0x100001 */
1272 /* b = value & 0xffff;
1274 a = ((b - a) & 0xffff) + (b < a);
1276 var_to_reg_int(s1, src, REG_ITMP1);
1277 d = reg_of_var(iptr->dst, REG_ITMP3);
1279 M_MOV(s1, REG_ITMP3);
1283 M_CZEXT(s1, REG_ITMP2);
1284 M_SRA_IMM(s1, 16, d);
1285 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1286 M_ISUB(REG_ITMP2, d, d);
1288 M_IADD(d, REG_ITMP1, d);
1289 M_BR(11 + (s1 == REG_ITMP1));
1290 M_ISUB(REG_ZERO, s1, REG_ITMP1);
1291 M_CZEXT(REG_ITMP1, REG_ITMP2);
1292 M_SRA_IMM(REG_ITMP1, 16, d);
1293 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1294 M_ISUB(REG_ITMP2, d, d);
1296 M_IADD(d, REG_ITMP1, d);
1297 M_ISUB(REG_ZERO, d, d);
1298 if (s1 == REG_ITMP1) {
1299 var_to_reg_int(s1, src, REG_ITMP1);
1301 M_SLL_IMM(s1, 33, REG_ITMP2);
1302 M_CMPEQ(REG_ITMP2, REG_ZERO, REG_ITMP2);
1303 M_ISUB(d, REG_ITMP2, d);
1304 store_reg_to_var_int(iptr->dst, d);
1307 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1308 /* val.l = constant */
1310 var_to_reg_int(s1, src, REG_ITMP1);
1311 d = reg_of_var(iptr->dst, REG_ITMP3);
1312 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1313 M_AND_IMM(s1, iptr->val.l, d);
1315 else if (iptr->val.l == 0xffffL) {
1318 else if (iptr->val.l == 0xffffffL) {
1319 M_ZAPNOT_IMM(s1, 0x07, d);
1321 else if (iptr->val.l == 0xffffffffL) {
1324 else if (iptr->val.l == 0xffffffffffL) {
1325 M_ZAPNOT_IMM(s1, 0x1f, d);
1327 else if (iptr->val.l == 0xffffffffffffL) {
1328 M_ZAPNOT_IMM(s1, 0x3f, d);
1330 else if (iptr->val.l == 0xffffffffffffffL) {
1331 M_ZAPNOT_IMM(s1, 0x7f, d);
1334 LCONST(REG_ITMP2, iptr->val.l);
1335 M_AND(s1, REG_ITMP2, d);
1337 store_reg_to_var_int(iptr->dst, d);
1340 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1341 /* val.l = constant */
1343 var_to_reg_int(s1, src, REG_ITMP1);
1344 d = reg_of_var(iptr->dst, REG_ITMP3);
1346 M_MOV(s1, REG_ITMP1);
1349 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1350 M_AND_IMM(s1, iptr->val.l, d);
1352 M_LSUB(REG_ZERO, s1, d);
1353 M_AND_IMM(d, iptr->val.l, d);
1355 else if (iptr->val.l == 0xffffL) {
1358 M_LSUB(REG_ZERO, s1, d);
1361 else if (iptr->val.l == 0xffffffL) {
1362 M_ZAPNOT_IMM(s1, 0x07, d);
1364 M_LSUB(REG_ZERO, s1, d);
1365 M_ZAPNOT_IMM(d, 0x07, d);
1367 else if (iptr->val.l == 0xffffffffL) {
1370 M_LSUB(REG_ZERO, s1, d);
1373 else if (iptr->val.l == 0xffffffffffL) {
1374 M_ZAPNOT_IMM(s1, 0x1f, d);
1376 M_LSUB(REG_ZERO, s1, d);
1377 M_ZAPNOT_IMM(d, 0x1f, d);
1379 else if (iptr->val.l == 0xffffffffffffL) {
1380 M_ZAPNOT_IMM(s1, 0x3f, d);
1382 M_LSUB(REG_ZERO, s1, d);
1383 M_ZAPNOT_IMM(d, 0x3f, d);
1385 else if (iptr->val.l == 0xffffffffffffffL) {
1386 M_ZAPNOT_IMM(s1, 0x7f, d);
1388 M_LSUB(REG_ZERO, s1, d);
1389 M_ZAPNOT_IMM(d, 0x7f, d);
1392 LCONST(REG_ITMP2, iptr->val.l);
1393 M_AND(s1, REG_ITMP2, d);
1395 M_LSUB(REG_ZERO, s1, d);
1396 M_AND(d, REG_ITMP2, d);
1398 M_LSUB(REG_ZERO, d, d);
1399 store_reg_to_var_int(iptr->dst, d);
1402 case ICMD_LREM0X10001:/* ..., value ==> ..., value % 0x10001 */
1404 var_to_reg_int(s1, src, REG_ITMP1);
1405 d = reg_of_var(iptr->dst, REG_ITMP3);
1407 M_MOV(s1, REG_ITMP3);
1410 M_CZEXT(s1, REG_ITMP2);
1411 M_SRA_IMM(s1, 16, d);
1412 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1413 M_LSUB(REG_ITMP2, d, d);
1415 M_LADD(d, REG_ITMP1, d);
1416 M_LDA(REG_ITMP2, REG_ZERO, -1);
1417 M_SRL_IMM(REG_ITMP2, 33, REG_ITMP2);
1418 if (s1 == REG_ITMP1) {
1419 var_to_reg_int(s1, src, REG_ITMP1);
1421 M_CMPULT(s1, REG_ITMP2, REG_ITMP2);
1422 M_BNEZ(REG_ITMP2, 11);
1423 M_LDA(d, REG_ZERO, -257);
1424 M_ZAPNOT_IMM(d, 0xcd, d);
1425 M_LSUB(REG_ZERO, s1, REG_ITMP2);
1426 M_CMOVGE(s1, s1, REG_ITMP2);
1427 M_UMULH(REG_ITMP2, d, REG_ITMP2);
1428 M_SRL_IMM(REG_ITMP2, 16, REG_ITMP2);
1429 M_LSUB(REG_ZERO, REG_ITMP2, d);
1430 M_CMOVGE(s1, REG_ITMP2, d);
1431 M_SLL_IMM(d, 16, REG_ITMP2);
1432 M_LADD(d, REG_ITMP2, d);
1434 store_reg_to_var_int(iptr->dst, d);
1437 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1440 var_to_reg_int(s1, src->prev, REG_ITMP1);
1441 var_to_reg_int(s2, src, REG_ITMP2);
1442 d = reg_of_var(iptr->dst, REG_ITMP3);
1444 store_reg_to_var_int(iptr->dst, d);
1447 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1448 /* val.i = constant */
1450 var_to_reg_int(s1, src, REG_ITMP1);
1451 d = reg_of_var(iptr->dst, REG_ITMP3);
1452 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1453 M_OR_IMM(s1, iptr->val.i, d);
1456 ICONST(REG_ITMP2, iptr->val.i);
1457 M_OR(s1, REG_ITMP2, d);
1459 store_reg_to_var_int(iptr->dst, d);
1462 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1463 /* val.l = constant */
1465 var_to_reg_int(s1, src, REG_ITMP1);
1466 d = reg_of_var(iptr->dst, REG_ITMP3);
1467 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1468 M_OR_IMM(s1, iptr->val.l, d);
1471 LCONST(REG_ITMP2, iptr->val.l);
1472 M_OR(s1, REG_ITMP2, d);
1474 store_reg_to_var_int(iptr->dst, d);
1477 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1480 var_to_reg_int(s1, src->prev, REG_ITMP1);
1481 var_to_reg_int(s2, src, REG_ITMP2);
1482 d = reg_of_var(iptr->dst, REG_ITMP3);
1484 store_reg_to_var_int(iptr->dst, d);
1487 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1488 /* val.i = constant */
1490 var_to_reg_int(s1, src, REG_ITMP1);
1491 d = reg_of_var(iptr->dst, REG_ITMP3);
1492 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1493 M_XOR_IMM(s1, iptr->val.i, d);
1496 ICONST(REG_ITMP2, iptr->val.i);
1497 M_XOR(s1, REG_ITMP2, d);
1499 store_reg_to_var_int(iptr->dst, d);
1502 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1503 /* val.l = constant */
1505 var_to_reg_int(s1, src, REG_ITMP1);
1506 d = reg_of_var(iptr->dst, REG_ITMP3);
1507 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1508 M_XOR_IMM(s1, iptr->val.l, d);
1511 LCONST(REG_ITMP2, iptr->val.l);
1512 M_XOR(s1, REG_ITMP2, d);
1514 store_reg_to_var_int(iptr->dst, d);
1518 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1520 var_to_reg_int(s1, src->prev, REG_ITMP1);
1521 var_to_reg_int(s2, src, REG_ITMP2);
1522 d = reg_of_var(iptr->dst, REG_ITMP3);
1523 M_CMPLT(s1, s2, REG_ITMP3);
1524 M_CMPLT(s2, s1, REG_ITMP1);
1525 M_LSUB (REG_ITMP1, REG_ITMP3, d);
1526 store_reg_to_var_int(iptr->dst, d);
1530 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1531 /* op1 = variable, val.i = constant */
1533 var = &(locals[iptr->op1][TYPE_INT]);
1534 if (var->flags & INMEMORY) {
1536 M_LLD(s1, REG_SP, 8 * var->regoff);
1540 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1541 M_IADD_IMM(s1, iptr->val.i, s1);
1543 else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1544 M_ISUB_IMM(s1, (-iptr->val.i), s1);
1547 M_LDA (s1, s1, iptr->val.i);
1548 M_IADD(s1, REG_ZERO, s1);
1550 if (var->flags & INMEMORY)
1551 M_LST(s1, REG_SP, 8 * var->regoff);
1555 /* floating operations ************************************************/
1557 case ICMD_FNEG: /* ..., value ==> ..., - value */
1559 var_to_reg_flt(s1, src, REG_FTMP1);
1560 d = reg_of_var(iptr->dst, REG_FTMP3);
1562 store_reg_to_var_flt(iptr->dst, d);
1565 case ICMD_DNEG: /* ..., value ==> ..., - value */
1567 var_to_reg_flt(s1, src, REG_FTMP1);
1568 d = reg_of_var(iptr->dst, REG_FTMP3);
1570 store_reg_to_var_flt(iptr->dst, d);
1573 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1575 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1576 var_to_reg_flt(s2, src, REG_FTMP2);
1577 d = reg_of_var(iptr->dst, REG_FTMP3);
1585 store_reg_to_var_flt(iptr->dst, d);
1588 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1590 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1591 var_to_reg_flt(s2, src, REG_FTMP2);
1592 d = reg_of_var(iptr->dst, REG_FTMP3);
1600 store_reg_to_var_flt(iptr->dst, d);
1603 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1605 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1606 var_to_reg_flt(s2, src, REG_FTMP2);
1607 d = reg_of_var(iptr->dst, REG_FTMP3);
1615 store_reg_to_var_flt(iptr->dst, d);
1618 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1620 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1621 var_to_reg_flt(s2, src, REG_FTMP2);
1622 d = reg_of_var(iptr->dst, REG_FTMP3);
1630 store_reg_to_var_flt(iptr->dst, d);
1633 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1635 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1636 var_to_reg_flt(s2, src, REG_FTMP2);
1637 d = reg_of_var(iptr->dst, REG_FTMP3);
1645 store_reg_to_var_flt(iptr->dst, d);
1648 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1650 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1651 var_to_reg_flt(s2, src, REG_FTMP2);
1652 d = reg_of_var(iptr->dst, REG_FTMP3);
1660 store_reg_to_var_flt(iptr->dst, d);
1663 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1665 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1666 var_to_reg_flt(s2, src, REG_FTMP2);
1667 d = reg_of_var(iptr->dst, REG_FTMP3);
1675 store_reg_to_var_flt(iptr->dst, d);
1678 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1680 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1681 var_to_reg_flt(s2, src, REG_FTMP2);
1682 d = reg_of_var(iptr->dst, REG_FTMP3);
1690 store_reg_to_var_flt(iptr->dst, d);
1693 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1695 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1696 var_to_reg_flt(s2, src, REG_FTMP2);
1697 d = reg_of_var(iptr->dst, REG_FTMP3);
1699 M_FDIVS(s1,s2, REG_FTMP3);
1701 M_CVTDL_CS(REG_FTMP3, REG_FTMP3); /* round to integer */
1703 M_CVTLF(REG_FTMP3, REG_FTMP3);
1704 M_FMULS(REG_FTMP3, s2, REG_FTMP3);
1706 M_FSUBS(s1, REG_FTMP3, d);
1710 M_FDIV(s1,s2, REG_FTMP3);
1711 M_CVTDL_C(REG_FTMP3, REG_FTMP3); /* round to integer */
1712 M_CVTLF(REG_FTMP3, REG_FTMP3);
1713 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1714 M_FSUB(s1, REG_FTMP3, d);
1716 store_reg_to_var_flt(iptr->dst, d);
1719 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1721 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1722 var_to_reg_flt(s2, src, REG_FTMP2);
1723 d = reg_of_var(iptr->dst, REG_FTMP3);
1725 M_DDIVS(s1,s2, REG_FTMP3);
1727 M_CVTDL_CS(REG_FTMP3, REG_FTMP3); /* round to integer */
1729 M_CVTLD(REG_FTMP3, REG_FTMP3);
1730 M_DMULS(REG_FTMP3, s2, REG_FTMP3);
1732 M_DSUBS(s1, REG_FTMP3, d);
1736 M_DDIV(s1,s2, REG_FTMP3);
1737 M_CVTDL_C(REG_FTMP3, REG_FTMP3); /* round to integer */
1738 M_CVTLD(REG_FTMP3, REG_FTMP3);
1739 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1740 M_DSUB(s1, REG_FTMP3, d);
1742 store_reg_to_var_flt(iptr->dst, d);
1745 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1747 var_to_reg_int(s1, src, REG_ITMP1);
1748 d = reg_of_var(iptr->dst, REG_FTMP3);
1749 a = dseg_adddouble(0.0);
1750 M_LST (s1, REG_PV, a);
1751 M_DLD (d, REG_PV, a);
1753 store_reg_to_var_flt(iptr->dst, d);
1756 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1758 var_to_reg_int(s1, src, REG_ITMP1);
1759 d = reg_of_var(iptr->dst, REG_FTMP3);
1760 a = dseg_adddouble(0.0);
1761 M_LST (s1, REG_PV, a);
1762 M_DLD (d, REG_PV, a);
1764 store_reg_to_var_flt(iptr->dst, d);
1767 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1769 var_to_reg_flt(s1, src, REG_FTMP1);
1770 d = reg_of_var(iptr->dst, REG_ITMP3);
1771 a = dseg_adddouble(0.0);
1773 M_CVTDL_CS(s1, REG_FTMP1);
1775 M_CVTLIS(REG_FTMP1, REG_FTMP2);
1779 M_CVTDL_C(s1, REG_FTMP1);
1780 M_CVTLI(REG_FTMP1, REG_FTMP2);
1782 M_DST (REG_FTMP1, REG_PV, a);
1783 M_ILD (d, REG_PV, a);
1784 store_reg_to_var_int(iptr->dst, d);
1787 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1789 var_to_reg_flt(s1, src, REG_FTMP1);
1790 d = reg_of_var(iptr->dst, REG_ITMP3);
1791 a = dseg_adddouble(0.0);
1793 M_CVTDL_CS(s1, REG_FTMP1);
1797 M_CVTDL_C(s1, REG_FTMP1);
1799 M_DST (REG_FTMP1, REG_PV, a);
1800 M_LLD (d, REG_PV, a);
1801 store_reg_to_var_int(iptr->dst, d);
1804 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1806 var_to_reg_flt(s1, src, REG_FTMP1);
1807 d = reg_of_var(iptr->dst, REG_FTMP3);
1809 store_reg_to_var_flt(iptr->dst, d);
1812 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1814 var_to_reg_flt(s1, src, REG_FTMP1);
1815 d = reg_of_var(iptr->dst, REG_FTMP3);
1823 store_reg_to_var_flt(iptr->dst, d);
1826 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1828 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1829 var_to_reg_flt(s2, src, REG_FTMP2);
1830 d = reg_of_var(iptr->dst, REG_ITMP3);
1832 M_LSUB_IMM(REG_ZERO, 1, d);
1833 M_FCMPEQS(s1, s2, REG_FTMP3);
1835 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1837 M_FCMPLTS(s2, s1, REG_FTMP3);
1839 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1840 M_LADD_IMM(REG_ZERO, 1, d);
1843 M_LSUB_IMM(REG_ZERO, 1, d);
1844 M_FCMPEQ(s1, s2, REG_FTMP3);
1845 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1847 M_FCMPLT(s2, s1, REG_FTMP3);
1848 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1849 M_LADD_IMM(REG_ZERO, 1, d);
1851 store_reg_to_var_int(iptr->dst, d);
1854 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1856 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1857 var_to_reg_flt(s2, src, REG_FTMP2);
1858 d = reg_of_var(iptr->dst, REG_ITMP3);
1860 M_LADD_IMM(REG_ZERO, 1, d);
1861 M_FCMPEQS(s1, s2, REG_FTMP3);
1863 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1865 M_FCMPLTS(s1, s2, REG_FTMP3);
1867 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1868 M_LSUB_IMM(REG_ZERO, 1, d);
1871 M_LADD_IMM(REG_ZERO, 1, d);
1872 M_FCMPEQ(s1, s2, REG_FTMP3);
1873 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1875 M_FCMPLT(s1, s2, REG_FTMP3);
1876 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1877 M_LSUB_IMM(REG_ZERO, 1, d);
1879 store_reg_to_var_int(iptr->dst, d);
1883 /* memory operations **************************************************/
1885 /* #define gen_bound_check \
1887 M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\
1888 M_CMPULT(s2, REG_ITMP3, REG_ITMP3);\
1889 M_BEQZ(REG_ITMP3, 0);\
1890 mcode_addxboundrefs(mcodeptr);\
1894 #define gen_bound_check \
1895 if (checkbounds) { \
1896 M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\
1897 M_CMPULT(s2, REG_ITMP3, REG_ITMP3);\
1898 M_BEQZ(REG_ITMP3, 0);\
1899 mcode_addxboundrefs(mcodeptr); \
1902 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1904 var_to_reg_int(s1, src, REG_ITMP1);
1905 d = reg_of_var(iptr->dst, REG_ITMP3);
1906 gen_nullptr_check(s1);
1907 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1908 store_reg_to_var_int(iptr->dst, d);
1911 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1913 var_to_reg_int(s1, src->prev, REG_ITMP1);
1914 var_to_reg_int(s2, src, REG_ITMP2);
1915 d = reg_of_var(iptr->dst, REG_ITMP3);
1916 if (iptr->op1 == 0) {
1917 gen_nullptr_check(s1);
1920 M_SAADDQ(s2, s1, REG_ITMP1);
1921 M_ALD( d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1922 store_reg_to_var_int(iptr->dst, d);
1925 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1927 var_to_reg_int(s1, src->prev, REG_ITMP1);
1928 var_to_reg_int(s2, src, REG_ITMP2);
1929 d = reg_of_var(iptr->dst, REG_ITMP3);
1930 if (iptr->op1 == 0) {
1931 gen_nullptr_check(s1);
1934 M_S8ADDQ(s2, s1, REG_ITMP1);
1935 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1936 store_reg_to_var_int(iptr->dst, d);
1939 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1941 var_to_reg_int(s1, src->prev, REG_ITMP1);
1942 var_to_reg_int(s2, src, REG_ITMP2);
1943 d = reg_of_var(iptr->dst, REG_ITMP3);
1944 if (iptr->op1 == 0) {
1945 gen_nullptr_check(s1);
1949 M_S4ADDQ(s2, s1, REG_ITMP1);
1950 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1951 store_reg_to_var_int(iptr->dst, d);
1954 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1956 var_to_reg_int(s1, src->prev, REG_ITMP1);
1957 var_to_reg_int(s2, src, REG_ITMP2);
1958 d = reg_of_var(iptr->dst, REG_FTMP3);
1959 if (iptr->op1 == 0) {
1960 gen_nullptr_check(s1);
1963 M_S4ADDQ(s2, s1, REG_ITMP1);
1964 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1965 store_reg_to_var_flt(iptr->dst, d);
1968 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1970 var_to_reg_int(s1, src->prev, REG_ITMP1);
1971 var_to_reg_int(s2, src, REG_ITMP2);
1972 d = reg_of_var(iptr->dst, REG_FTMP3);
1973 if (iptr->op1 == 0) {
1974 gen_nullptr_check(s1);
1977 M_S8ADDQ(s2, s1, REG_ITMP1);
1978 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1979 store_reg_to_var_flt(iptr->dst, d);
1982 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1984 var_to_reg_int(s1, src->prev, REG_ITMP1);
1985 var_to_reg_int(s2, src, REG_ITMP2);
1986 d = reg_of_var(iptr->dst, REG_ITMP3);
1987 if (iptr->op1 == 0) {
1988 gen_nullptr_check(s1);
1991 if (has_ext_instr_set) {
1992 M_LADD(s2, s1, REG_ITMP1);
1993 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1994 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1997 M_LADD (s2, s1, REG_ITMP1);
1998 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1999 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2000 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2001 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
2003 store_reg_to_var_int(iptr->dst, d);
2006 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
2008 var_to_reg_int(s1, src->prev, REG_ITMP1);
2009 var_to_reg_int(s2, src, REG_ITMP2);
2010 d = reg_of_var(iptr->dst, REG_ITMP3);
2011 if (iptr->op1 == 0) {
2012 gen_nullptr_check(s1);
2015 if (has_ext_instr_set) {
2016 M_LADD(s2, s1, REG_ITMP1);
2017 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2018 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
2022 M_LADD(s2, s1, REG_ITMP1);
2023 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2024 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2025 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
2026 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
2027 M_SRA_IMM(d, 48, d);
2029 store_reg_to_var_int(iptr->dst, d);
2032 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
2034 var_to_reg_int(s1, src->prev, REG_ITMP1);
2035 var_to_reg_int(s2, src, REG_ITMP2);
2036 d = reg_of_var(iptr->dst, REG_ITMP3);
2037 if (iptr->op1 == 0) {
2038 gen_nullptr_check(s1);
2041 if (has_ext_instr_set) {
2042 M_LADD (s2, s1, REG_ITMP1);
2043 M_BLDU (d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
2047 M_LADD(s2, s1, REG_ITMP1);
2048 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2049 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
2050 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
2051 M_SRA_IMM(d, 56, d);
2053 store_reg_to_var_int(iptr->dst, d);
2057 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
2059 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2060 var_to_reg_int(s2, src->prev, REG_ITMP2);
2061 if (iptr->op1 == 0) {
2062 gen_nullptr_check(s1);
2065 var_to_reg_int(s3, src, REG_ITMP3);
2066 M_SAADDQ(s2, s1, REG_ITMP1);
2067 M_AST (s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
2070 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
2072 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2073 var_to_reg_int(s2, src->prev, REG_ITMP2);
2074 if (iptr->op1 == 0) {
2075 gen_nullptr_check(s1);
2078 var_to_reg_int(s3, src, REG_ITMP3);
2079 M_S8ADDQ(s2, s1, REG_ITMP1);
2080 M_LST (s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
2083 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
2085 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2086 var_to_reg_int(s2, src->prev, REG_ITMP2);
2087 if (iptr->op1 == 0) {
2088 gen_nullptr_check(s1);
2092 var_to_reg_int(s3, src, REG_ITMP3);
2093 M_S4ADDQ(s2, s1, REG_ITMP1);
2094 M_IST (s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
2097 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
2099 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2100 var_to_reg_int(s2, src->prev, REG_ITMP2);
2101 if (iptr->op1 == 0) {
2102 gen_nullptr_check(s1);
2105 var_to_reg_flt(s3, src, REG_FTMP3);
2106 M_S4ADDQ(s2, s1, REG_ITMP1);
2107 M_FST (s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
2110 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
2112 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2113 var_to_reg_int(s2, src->prev, REG_ITMP2);
2114 if (iptr->op1 == 0) {
2115 gen_nullptr_check(s1);
2118 var_to_reg_flt(s3, src, REG_FTMP3);
2119 M_S8ADDQ(s2, s1, REG_ITMP1);
2120 M_DST (s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
2123 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
2125 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2126 var_to_reg_int(s2, src->prev, REG_ITMP2);
2127 if (iptr->op1 == 0) {
2128 gen_nullptr_check(s1);
2131 var_to_reg_int(s3, src, REG_ITMP3);
2132 if (has_ext_instr_set) {
2133 M_LADD(s2, s1, REG_ITMP1);
2134 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2135 M_SST (s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
2138 M_LADD (s2, s1, REG_ITMP1);
2139 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2140 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2141 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2142 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
2143 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2144 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2145 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2149 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
2151 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2152 var_to_reg_int(s2, src->prev, REG_ITMP2);
2153 if (iptr->op1 == 0) {
2154 gen_nullptr_check(s1);
2157 var_to_reg_int(s3, src, REG_ITMP3);
2158 if (has_ext_instr_set) {
2159 M_LADD(s2, s1, REG_ITMP1);
2160 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2161 M_SST (s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2164 M_LADD (s2, s1, REG_ITMP1);
2165 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2166 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2167 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2168 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
2169 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2170 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2171 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2175 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
2177 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2178 var_to_reg_int(s2, src->prev, REG_ITMP2);
2179 if (iptr->op1 == 0) {
2180 gen_nullptr_check(s1);
2183 var_to_reg_int(s3, src, REG_ITMP3);
2184 if (has_ext_instr_set) {
2185 M_LADD(s2, s1, REG_ITMP1);
2186 M_BST (s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2189 M_LADD (s2, s1, REG_ITMP1);
2190 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2191 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2192 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
2193 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2194 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2195 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2200 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2201 /* op1 = type, val.a = field address */
2203 a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value));
2204 M_ALD(REG_ITMP1, REG_PV, a);
2205 switch (iptr->op1) {
2207 var_to_reg_int(s2, src, REG_ITMP2);
2208 M_IST(s2, REG_ITMP1, 0);
2211 var_to_reg_int(s2, src, REG_ITMP2);
2212 M_LST(s2, REG_ITMP1, 0);
2215 var_to_reg_int(s2, src, REG_ITMP2);
2216 M_AST(s2, REG_ITMP1, 0);
2219 var_to_reg_flt(s2, src, REG_FTMP2);
2220 M_FST(s2, REG_ITMP1, 0);
2223 var_to_reg_flt(s2, src, REG_FTMP2);
2224 M_DST(s2, REG_ITMP1, 0);
2226 default: panic ("internal error");
2230 case ICMD_GETSTATIC: /* ... ==> ..., value */
2231 /* op1 = type, val.a = field address */
2233 a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value));
2234 M_ALD(REG_ITMP1, REG_PV, a);
2235 switch (iptr->op1) {
2237 d = reg_of_var(iptr->dst, REG_ITMP3);
2238 M_ILD(d, REG_ITMP1, 0);
2239 store_reg_to_var_int(iptr->dst, d);
2242 d = reg_of_var(iptr->dst, REG_ITMP3);
2243 M_LLD(d, REG_ITMP1, 0);
2244 store_reg_to_var_int(iptr->dst, d);
2247 d = reg_of_var(iptr->dst, REG_ITMP3);
2248 M_ALD(d, REG_ITMP1, 0);
2249 store_reg_to_var_int(iptr->dst, d);
2252 d = reg_of_var(iptr->dst, REG_FTMP1);
2253 M_FLD(d, REG_ITMP1, 0);
2254 store_reg_to_var_flt(iptr->dst, d);
2257 d = reg_of_var(iptr->dst, REG_FTMP1);
2258 M_DLD(d, REG_ITMP1, 0);
2259 store_reg_to_var_flt(iptr->dst, d);
2261 default: panic ("internal error");
2266 case ICMD_PUTFIELD: /* ..., value ==> ... */
2267 /* op1 = type, val.i = field offset */
2269 a = ((fieldinfo *)(iptr->val.a))->offset;
2270 switch (iptr->op1) {
2272 var_to_reg_int(s1, src->prev, REG_ITMP1);
2273 var_to_reg_int(s2, src, REG_ITMP2);
2274 gen_nullptr_check(s1);
2278 var_to_reg_int(s1, src->prev, REG_ITMP1);
2279 var_to_reg_int(s2, src, REG_ITMP2);
2280 gen_nullptr_check(s1);
2284 var_to_reg_int(s1, src->prev, REG_ITMP1);
2285 var_to_reg_int(s2, src, REG_ITMP2);
2286 gen_nullptr_check(s1);
2290 var_to_reg_int(s1, src->prev, REG_ITMP1);
2291 var_to_reg_flt(s2, src, REG_FTMP2);
2292 gen_nullptr_check(s1);
2296 var_to_reg_int(s1, src->prev, REG_ITMP1);
2297 var_to_reg_flt(s2, src, REG_FTMP2);
2298 gen_nullptr_check(s1);
2301 default: panic ("internal error");
2305 case ICMD_GETFIELD: /* ... ==> ..., value */
2306 /* op1 = type, val.i = field offset */
2308 a = ((fieldinfo *)(iptr->val.a))->offset;
2309 switch (iptr->op1) {
2311 var_to_reg_int(s1, src, REG_ITMP1);
2312 d = reg_of_var(iptr->dst, REG_ITMP3);
2313 gen_nullptr_check(s1);
2315 store_reg_to_var_int(iptr->dst, d);
2318 var_to_reg_int(s1, src, REG_ITMP1);
2319 d = reg_of_var(iptr->dst, REG_ITMP3);
2320 gen_nullptr_check(s1);
2322 store_reg_to_var_int(iptr->dst, d);
2325 var_to_reg_int(s1, src, REG_ITMP1);
2326 d = reg_of_var(iptr->dst, REG_ITMP3);
2327 gen_nullptr_check(s1);
2329 store_reg_to_var_int(iptr->dst, d);
2332 var_to_reg_int(s1, src, REG_ITMP1);
2333 d = reg_of_var(iptr->dst, REG_FTMP1);
2334 gen_nullptr_check(s1);
2336 store_reg_to_var_flt(iptr->dst, d);
2339 var_to_reg_int(s1, src, REG_ITMP1);
2340 d = reg_of_var(iptr->dst, REG_FTMP1);
2341 gen_nullptr_check(s1);
2343 store_reg_to_var_flt(iptr->dst, d);
2345 default: panic ("internal error");
2350 /* branch operations **************************************************/
2352 #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}}
2354 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2356 var_to_reg_int(s1, src, REG_ITMP1);
2357 M_INTMOVE(s1, REG_ITMP1_XPTR);
2358 a = dseg_addaddress(asm_handle_exception);
2359 M_ALD(REG_ITMP2, REG_PV, a);
2360 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2361 M_NOP; /* nop ensures that XPC is less than the end */
2362 /* of basic block */
2366 case ICMD_GOTO: /* ... ==> ... */
2367 /* op1 = target JavaVM pc */
2369 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2373 case ICMD_JSR: /* ... ==> ... */
2374 /* op1 = target JavaVM pc */
2376 M_BSR(REG_ITMP1, 0);
2377 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2380 case ICMD_RET: /* ... ==> ... */
2381 /* op1 = local variable */
2383 var = &(locals[iptr->op1][TYPE_ADR]);
2384 if (var->flags & INMEMORY) {
2385 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2386 M_RET(REG_ZERO, REG_ITMP1);
2389 M_RET(REG_ZERO, var->regoff);
2393 case ICMD_IFNULL: /* ..., value ==> ... */
2394 /* op1 = target JavaVM pc */
2396 var_to_reg_int(s1, src, REG_ITMP1);
2398 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2401 case ICMD_IFNONNULL: /* ..., value ==> ... */
2402 /* op1 = target JavaVM pc */
2404 var_to_reg_int(s1, src, REG_ITMP1);
2406 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2409 case ICMD_IFEQ: /* ..., value ==> ... */
2410 /* op1 = target JavaVM pc, val.i = constant */
2412 var_to_reg_int(s1, src, REG_ITMP1);
2413 if (iptr->val.i == 0) {
2417 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2418 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2421 ICONST(REG_ITMP2, iptr->val.i);
2422 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2424 M_BNEZ(REG_ITMP1, 0);
2426 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2429 case ICMD_IFLT: /* ..., value ==> ... */
2430 /* op1 = target JavaVM pc, val.i = constant */
2432 var_to_reg_int(s1, src, REG_ITMP1);
2433 if (iptr->val.i == 0) {
2437 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2438 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2441 ICONST(REG_ITMP2, iptr->val.i);
2442 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2444 M_BNEZ(REG_ITMP1, 0);
2446 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2449 case ICMD_IFLE: /* ..., value ==> ... */
2450 /* op1 = target JavaVM pc, val.i = constant */
2452 var_to_reg_int(s1, src, REG_ITMP1);
2453 if (iptr->val.i == 0) {
2457 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2458 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2461 ICONST(REG_ITMP2, iptr->val.i);
2462 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2464 M_BNEZ(REG_ITMP1, 0);
2466 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2469 case ICMD_IFNE: /* ..., value ==> ... */
2470 /* op1 = target JavaVM pc, val.i = constant */
2472 var_to_reg_int(s1, src, REG_ITMP1);
2473 if (iptr->val.i == 0) {
2477 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2478 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2481 ICONST(REG_ITMP2, iptr->val.i);
2482 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2484 M_BEQZ(REG_ITMP1, 0);
2486 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2489 case ICMD_IFGT: /* ..., value ==> ... */
2490 /* op1 = target JavaVM pc, val.i = constant */
2492 var_to_reg_int(s1, src, REG_ITMP1);
2493 if (iptr->val.i == 0) {
2497 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2498 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2501 ICONST(REG_ITMP2, iptr->val.i);
2502 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2504 M_BEQZ(REG_ITMP1, 0);
2506 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2509 case ICMD_IFGE: /* ..., value ==> ... */
2510 /* op1 = target JavaVM pc, val.i = constant */
2512 var_to_reg_int(s1, src, REG_ITMP1);
2513 if (iptr->val.i == 0) {
2517 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2518 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2521 ICONST(REG_ITMP2, iptr->val.i);
2522 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2524 M_BEQZ(REG_ITMP1, 0);
2526 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2529 case ICMD_IF_LEQ: /* ..., value ==> ... */
2530 /* op1 = target JavaVM pc, val.l = constant */
2532 var_to_reg_int(s1, src, REG_ITMP1);
2533 if (iptr->val.l == 0) {
2537 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2538 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2541 LCONST(REG_ITMP2, iptr->val.l);
2542 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2544 M_BNEZ(REG_ITMP1, 0);
2546 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2549 case ICMD_IF_LLT: /* ..., value ==> ... */
2550 /* op1 = target JavaVM pc, val.l = constant */
2552 var_to_reg_int(s1, src, REG_ITMP1);
2553 if (iptr->val.l == 0) {
2557 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2558 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2561 LCONST(REG_ITMP2, iptr->val.l);
2562 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2564 M_BNEZ(REG_ITMP1, 0);
2566 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2569 case ICMD_IF_LLE: /* ..., value ==> ... */
2570 /* op1 = target JavaVM pc, val.l = constant */
2572 var_to_reg_int(s1, src, REG_ITMP1);
2573 if (iptr->val.l == 0) {
2577 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2578 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2581 LCONST(REG_ITMP2, iptr->val.l);
2582 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2584 M_BNEZ(REG_ITMP1, 0);
2586 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2589 case ICMD_IF_LNE: /* ..., value ==> ... */
2590 /* op1 = target JavaVM pc, val.l = constant */
2592 var_to_reg_int(s1, src, REG_ITMP1);
2593 if (iptr->val.l == 0) {
2597 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2598 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2601 LCONST(REG_ITMP2, iptr->val.l);
2602 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2604 M_BEQZ(REG_ITMP1, 0);
2606 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2609 case ICMD_IF_LGT: /* ..., value ==> ... */
2610 /* op1 = target JavaVM pc, val.l = constant */
2612 var_to_reg_int(s1, src, REG_ITMP1);
2613 if (iptr->val.l == 0) {
2617 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2618 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2621 LCONST(REG_ITMP2, iptr->val.l);
2622 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2624 M_BEQZ(REG_ITMP1, 0);
2626 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2629 case ICMD_IF_LGE: /* ..., value ==> ... */
2630 /* op1 = target JavaVM pc, val.l = constant */
2632 var_to_reg_int(s1, src, REG_ITMP1);
2633 if (iptr->val.l == 0) {
2637 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2638 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2641 LCONST(REG_ITMP2, iptr->val.l);
2642 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2644 M_BEQZ(REG_ITMP1, 0);
2646 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2649 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2650 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2651 case ICMD_IF_ACMPEQ:
2653 var_to_reg_int(s1, src->prev, REG_ITMP1);
2654 var_to_reg_int(s2, src, REG_ITMP2);
2655 M_CMPEQ(s1, s2, REG_ITMP1);
2656 M_BNEZ(REG_ITMP1, 0);
2657 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2660 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2661 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2662 case ICMD_IF_ACMPNE:
2664 var_to_reg_int(s1, src->prev, REG_ITMP1);
2665 var_to_reg_int(s2, src, REG_ITMP2);
2666 M_CMPEQ(s1, s2, REG_ITMP1);
2667 M_BEQZ(REG_ITMP1, 0);
2668 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2671 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2672 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2674 var_to_reg_int(s1, src->prev, REG_ITMP1);
2675 var_to_reg_int(s2, src, REG_ITMP2);
2676 M_CMPLT(s1, s2, REG_ITMP1);
2677 M_BNEZ(REG_ITMP1, 0);
2678 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2681 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2682 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2684 var_to_reg_int(s1, src->prev, REG_ITMP1);
2685 var_to_reg_int(s2, src, REG_ITMP2);
2686 M_CMPLE(s1, s2, REG_ITMP1);
2687 M_BEQZ(REG_ITMP1, 0);
2688 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2691 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2692 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2694 var_to_reg_int(s1, src->prev, REG_ITMP1);
2695 var_to_reg_int(s2, src, REG_ITMP2);
2696 M_CMPLE(s1, s2, REG_ITMP1);
2697 M_BNEZ(REG_ITMP1, 0);
2698 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2701 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2702 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2704 var_to_reg_int(s1, src->prev, REG_ITMP1);
2705 var_to_reg_int(s2, src, REG_ITMP2);
2706 M_CMPLT(s1, s2, REG_ITMP1);
2707 M_BEQZ(REG_ITMP1, 0);
2708 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2711 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2713 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2716 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2717 /* val.i = constant */
2719 var_to_reg_int(s1, src, REG_ITMP1);
2720 d = reg_of_var(iptr->dst, REG_ITMP3);
2722 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2723 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2724 M_CMPEQ(s1, REG_ZERO, d);
2725 store_reg_to_var_int(iptr->dst, d);
2728 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2729 M_CMPEQ(s1, REG_ZERO, d);
2731 store_reg_to_var_int(iptr->dst, d);
2735 M_MOV(s1, REG_ITMP1);
2738 ICONST(d, iptr[1].val.i);
2740 if ((s3 >= 0) && (s3 <= 255)) {
2741 M_CMOVEQ_IMM(s1, s3, d);
2744 ICONST(REG_ITMP2, s3);
2745 M_CMOVEQ(s1, REG_ITMP2, d);
2747 store_reg_to_var_int(iptr->dst, d);
2750 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2751 /* val.i = constant */
2753 var_to_reg_int(s1, src, REG_ITMP1);
2754 d = reg_of_var(iptr->dst, REG_ITMP3);
2756 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2757 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2758 M_CMPEQ(s1, REG_ZERO, d);
2759 store_reg_to_var_int(iptr->dst, d);
2762 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2763 M_CMPEQ(s1, REG_ZERO, d);
2765 store_reg_to_var_int(iptr->dst, d);
2769 M_MOV(s1, REG_ITMP1);
2772 ICONST(d, iptr[1].val.i);
2774 if ((s3 >= 0) && (s3 <= 255)) {
2775 M_CMOVNE_IMM(s1, s3, d);
2778 ICONST(REG_ITMP2, s3);
2779 M_CMOVNE(s1, REG_ITMP2, d);
2781 store_reg_to_var_int(iptr->dst, d);
2784 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2785 /* val.i = constant */
2787 var_to_reg_int(s1, src, REG_ITMP1);
2788 d = reg_of_var(iptr->dst, REG_ITMP3);
2790 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2791 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2792 M_CMPLT(s1, REG_ZERO, d);
2793 store_reg_to_var_int(iptr->dst, d);
2796 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2797 M_CMPLE(REG_ZERO, s1, d);
2798 store_reg_to_var_int(iptr->dst, d);
2802 M_MOV(s1, REG_ITMP1);
2805 ICONST(d, iptr[1].val.i);
2807 if ((s3 >= 0) && (s3 <= 255)) {
2808 M_CMOVLT_IMM(s1, s3, d);
2811 ICONST(REG_ITMP2, s3);
2812 M_CMOVLT(s1, REG_ITMP2, d);
2814 store_reg_to_var_int(iptr->dst, d);
2817 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2818 /* val.i = constant */
2820 var_to_reg_int(s1, src, REG_ITMP1);
2821 d = reg_of_var(iptr->dst, REG_ITMP3);
2823 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2824 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2825 M_CMPLE(REG_ZERO, s1, d);
2826 store_reg_to_var_int(iptr->dst, d);
2829 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2830 M_CMPLT(s1, REG_ZERO, d);
2831 store_reg_to_var_int(iptr->dst, d);
2835 M_MOV(s1, REG_ITMP1);
2838 ICONST(d, iptr[1].val.i);
2840 if ((s3 >= 0) && (s3 <= 255)) {
2841 M_CMOVGE_IMM(s1, s3, d);
2844 ICONST(REG_ITMP2, s3);
2845 M_CMOVGE(s1, REG_ITMP2, d);
2847 store_reg_to_var_int(iptr->dst, d);
2850 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2851 /* val.i = constant */
2853 var_to_reg_int(s1, src, REG_ITMP1);
2854 d = reg_of_var(iptr->dst, REG_ITMP3);
2856 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2857 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2858 M_CMPLT(REG_ZERO, s1, d);
2859 store_reg_to_var_int(iptr->dst, d);
2862 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2863 M_CMPLE(s1, REG_ZERO, d);
2864 store_reg_to_var_int(iptr->dst, d);
2868 M_MOV(s1, REG_ITMP1);
2871 ICONST(d, iptr[1].val.i);
2873 if ((s3 >= 0) && (s3 <= 255)) {
2874 M_CMOVGT_IMM(s1, s3, d);
2877 ICONST(REG_ITMP2, s3);
2878 M_CMOVGT(s1, REG_ITMP2, d);
2880 store_reg_to_var_int(iptr->dst, d);
2883 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2884 /* val.i = constant */
2886 var_to_reg_int(s1, src, REG_ITMP1);
2887 d = reg_of_var(iptr->dst, REG_ITMP3);
2889 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2890 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2891 M_CMPLE(s1, REG_ZERO, d);
2892 store_reg_to_var_int(iptr->dst, d);
2895 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2896 M_CMPLT(REG_ZERO, s1, d);
2897 store_reg_to_var_int(iptr->dst, d);
2901 M_MOV(s1, REG_ITMP1);
2904 ICONST(d, iptr[1].val.i);
2906 if ((s3 >= 0) && (s3 <= 255)) {
2907 M_CMOVLE_IMM(s1, s3, d);
2910 ICONST(REG_ITMP2, s3);
2911 M_CMOVLE(s1, REG_ITMP2, d);
2913 store_reg_to_var_int(iptr->dst, d);
2917 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2922 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2923 a = dseg_addaddress ((void*) (builtin_monitorexit));
2924 M_ALD(REG_PV, REG_PV, a);
2925 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
2926 M_JSR(REG_RA, REG_PV);
2927 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2930 var_to_reg_int(s1, src, REG_RESULT);
2931 M_INTMOVE(s1, REG_RESULT);
2932 goto nowperformreturn;
2934 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2938 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2939 a = dseg_addaddress ((void*) (builtin_monitorexit));
2940 M_ALD(REG_PV, REG_PV, a);
2941 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
2942 M_JSR(REG_RA, REG_PV);
2943 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2946 var_to_reg_flt(s1, src, REG_FRESULT);
2947 M_FLTMOVE(s1, REG_FRESULT);
2948 goto nowperformreturn;
2950 case ICMD_RETURN: /* ... ==> ... */
2953 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2954 a = dseg_addaddress ((void*) (builtin_monitorexit));
2955 M_ALD(REG_PV, REG_PV, a);
2956 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
2957 M_JSR(REG_RA, REG_PV);
2958 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2966 p = parentargs_base;
2968 /* restore return address */
2971 {p--; M_LLD (REG_RA, REG_SP, 8 * p);}
2973 /* restore saved registers */
2975 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
2976 {p--; M_LLD(savintregs[r], REG_SP, 8 * p);}
2977 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
2978 {p--; M_DLD(savfltregs[r], REG_SP, 8 * p);}
2980 /* deallocate stack */
2982 if (parentargs_base)
2983 {M_LDA(REG_SP, REG_SP, parentargs_base*8);}
2985 /* call trace function */
2988 M_LDA (REG_SP, REG_SP, -24);
2989 M_AST(REG_RA, REG_SP, 0);
2990 M_LST(REG_RESULT, REG_SP, 8);
2991 M_DST(REG_FRESULT, REG_SP,16);
2992 a = dseg_addaddress (method);
2993 M_ALD(argintregs[0], REG_PV, a);
2994 M_MOV(REG_RESULT, argintregs[1]);
2995 M_FLTMOVE(REG_FRESULT, argfltregs[2]);
2996 a = dseg_addaddress ((void*) (builtin_displaymethodstop));
2997 M_ALD(REG_PV, REG_PV, a);
2998 M_JSR (REG_RA, REG_PV);
2999 s1 = (int)((u1*) mcodeptr - mcodebase);
3000 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
3003 while (ml<-32768) { ml+=65536; mh--; }
3004 M_LDA (REG_PV, REG_RA, ml );
3005 M_LDAH (REG_PV, REG_PV, mh );
3007 M_DLD(REG_FRESULT, REG_SP,16);
3008 M_LLD(REG_RESULT, REG_SP, 8);
3009 M_ALD(REG_RA, REG_SP, 0);
3010 M_LDA (REG_SP, REG_SP, 24);
3013 M_RET(REG_ZERO, REG_RA);
3019 case ICMD_TABLESWITCH: /* ..., index ==> ... */
3024 tptr = (void **) iptr->target;
3026 s4ptr = iptr->val.a;
3027 l = s4ptr[1]; /* low */
3028 i = s4ptr[2]; /* high */
3030 var_to_reg_int(s1, src, REG_ITMP1);
3032 {M_INTMOVE(s1, REG_ITMP1);}
3033 else if (l <= 32768) {
3034 M_LDA(REG_ITMP1, s1, -l);
3037 ICONST(REG_ITMP2, l);
3038 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
3045 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
3047 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
3048 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3050 M_BEQZ(REG_ITMP2, 0);
3053 /* mcode_addreference(BlockPtrOfPC(s4ptr[0]), mcodeptr); */
3054 mcode_addreference((basicblock *) tptr[0], mcodeptr);
3056 /* build jump table top down and use address of lowest entry */
3058 /* s4ptr += 3 + i; */
3062 /* dseg_addtarget(BlockPtrOfPC(*--s4ptr)); */
3063 dseg_addtarget((basicblock *) tptr[0]);
3068 /* length of dataseg after last dseg_addtarget is used by load */
3070 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
3071 M_ALD(REG_ITMP2, REG_ITMP2, -dseglen);
3072 M_JMP(REG_ZERO, REG_ITMP2);
3077 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3079 s4 i, l, val, *s4ptr;
3082 tptr = (void **) iptr->target;
3084 s4ptr = iptr->val.a;
3085 l = s4ptr[0]; /* default */
3086 i = s4ptr[1]; /* count */
3088 MCODECHECK((i<<2)+8);
3089 var_to_reg_int(s1, src, REG_ITMP1);
3095 if ((val >= 0) && (val <= 255)) {
3096 M_CMPEQ_IMM(s1, val, REG_ITMP2);
3099 if ((val >= -32768) && (val <= 32767)) {
3100 M_LDA(REG_ITMP2, REG_ZERO, val);
3103 a = dseg_adds4 (val);
3104 M_ILD(REG_ITMP2, REG_PV, a);
3106 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
3108 M_BNEZ(REG_ITMP2, 0);
3109 /* mcode_addreference(BlockPtrOfPC(s4ptr[1]), mcodeptr); */
3110 mcode_addreference((basicblock *) tptr[0], mcodeptr);
3114 /* mcode_addreference(BlockPtrOfPC(l), mcodeptr); */
3116 tptr = (void **) iptr->target;
3117 mcode_addreference((basicblock *) tptr[0], mcodeptr);
3124 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
3125 /* op1 = return type, val.a = function pointer*/
3129 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
3130 /* op1 = return type, val.a = function pointer*/
3134 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
3135 /* op1 = return type, val.a = function pointer*/
3139 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3140 /* op1 = arg count, val.a = method pointer */
3142 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3143 /* op1 = arg count, val.a = method pointer */
3145 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3146 /* op1 = arg count, val.a = method pointer */
3148 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
3149 /* op1 = arg count, val.a = method pointer */
3157 MCODECHECK((s3 << 1) + 64);
3159 /* copy arguments to registers or stack location */
3161 for (; --s3 >= 0; src = src->prev) {
3162 if (src->varkind == ARGVAR)
3164 if (IS_INT_LNG_TYPE(src->type)) {
3165 if (s3 < INT_ARG_CNT) {
3166 s1 = argintregs[s3];
3167 var_to_reg_int(d, src, s1);
3171 var_to_reg_int(d, src, REG_ITMP1);
3172 M_LST(d, REG_SP, 8 * (s3 - INT_ARG_CNT));
3176 if (s3 < FLT_ARG_CNT) {
3177 s1 = argfltregs[s3];
3178 var_to_reg_flt(d, src, s1);
3182 var_to_reg_flt(d, src, REG_FTMP1);
3183 M_DST(d, REG_SP, 8 * (s3 - FLT_ARG_CNT));
3188 switch (iptr->opc) {
3192 a = dseg_addaddress ((void*) (m));
3194 M_ALD(REG_PV, REG_PV, a); /* Pointer to built-in-function */
3196 goto makeactualcall;
3198 case ICMD_INVOKESTATIC:
3199 case ICMD_INVOKESPECIAL:
3200 a = dseg_addaddress (m->stubroutine);
3202 M_ALD(REG_PV, REG_PV, a ); /* method pointer in r27 */
3205 goto makeactualcall;
3207 case ICMD_INVOKEVIRTUAL:
3209 gen_nullptr_check(argintregs[0]);
3210 M_ALD(REG_METHODPTR, argintregs[0],
3211 OFFSET(java_objectheader, vftbl));
3212 M_ALD(REG_PV, REG_METHODPTR, OFFSET(vftbl, table[0]) +
3213 sizeof(methodptr) * m->vftblindex);
3216 goto makeactualcall;
3218 case ICMD_INVOKEINTERFACE:
3221 gen_nullptr_check(argintregs[0]);
3222 M_ALD(REG_METHODPTR, argintregs[0],
3223 OFFSET(java_objectheader, vftbl));
3224 M_ALD(REG_METHODPTR, REG_METHODPTR,
3225 OFFSET(vftbl, interfacetable[0]) -
3226 sizeof(methodptr*) * ci->index);
3227 M_ALD(REG_PV, REG_METHODPTR,
3228 sizeof(methodptr) * (m - ci->methods));
3231 goto makeactualcall;
3235 sprintf (logtext, "Unkown ICMD-Command: %d", iptr->opc);
3241 M_JSR (REG_RA, REG_PV);
3245 s1 = (int)((u1*) mcodeptr - mcodebase);
3246 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
3249 while (ml<-32768) { ml+=65536; mh--; }
3250 M_LDA (REG_PV, REG_RA, ml );
3251 M_LDAH (REG_PV, REG_PV, mh );
3254 /* d contains return type */
3256 if (d != TYPE_VOID) {
3257 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3258 s1 = reg_of_var(iptr->dst, REG_RESULT);
3259 M_INTMOVE(REG_RESULT, s1);
3260 store_reg_to_var_int(iptr->dst, s1);
3263 s1 = reg_of_var(iptr->dst, REG_FRESULT);
3264 M_FLTMOVE(REG_FRESULT, s1);
3265 store_reg_to_var_flt(iptr->dst, s1);
3272 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3274 /* op1: 0 == array, 1 == class */
3275 /* val.a: (classinfo*) superclass */
3277 /* superclass is an interface:
3279 * return (sub != NULL) &&
3280 * (sub->vftbl->interfacetablelength > super->index) &&
3281 * (sub->vftbl->interfacetable[-super->index] != NULL);
3283 * superclass is a class:
3285 * return ((sub != NULL) && (0
3286 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3287 * super->vftbl->diffvall));
3291 classinfo *super = (classinfo*) iptr->val.a;
3293 var_to_reg_int(s1, src, REG_ITMP1);
3294 d = reg_of_var(iptr->dst, REG_ITMP3);
3296 M_MOV(s1, REG_ITMP1);
3300 if (iptr->op1) { /* class/interface */
3301 if (super->flags & ACC_INTERFACE) { /* interface */
3303 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3304 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3305 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3306 M_BLEZ(REG_ITMP2, 2);
3307 M_ALD(REG_ITMP1, REG_ITMP1,
3308 OFFSET(vftbl, interfacetable[0]) -
3309 super->index * sizeof(methodptr*));
3310 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3314 s2 = super->vftbl->diffval;
3315 M_BEQZ(s1, 4 + (s2 > 255));
3316 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3317 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3318 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3320 M_CMPULE_IMM(REG_ITMP1, s2, d);
3322 M_LDA(REG_ITMP2, REG_ZERO, s2);
3323 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3327 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3328 a = dseg_addaddress ((void*) super->vftbl);
3329 M_ALD(REG_ITMP2, REG_PV, a);
3330 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3331 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl, baseval));
3332 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, diffval));
3333 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3334 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3338 panic ("internal error: no inlined array instanceof");
3340 store_reg_to_var_int(iptr->dst, d);
3343 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3345 /* op1: 0 == array, 1 == class */
3346 /* val.a: (classinfo*) superclass */
3348 /* superclass is an interface:
3350 * OK if ((sub == NULL) ||
3351 * (sub->vftbl->interfacetablelength > super->index) &&
3352 * (sub->vftbl->interfacetable[-super->index] != NULL));
3354 * superclass is a class:
3356 * OK if ((sub == NULL) || (0
3357 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3358 * super->vftbl->diffvall));
3362 classinfo *super = (classinfo*) iptr->val.a;
3364 d = reg_of_var(iptr->dst, REG_ITMP3);
3365 var_to_reg_int(s1, src, d);
3366 if (iptr->op1) { /* class/interface */
3367 if (super->flags & ACC_INTERFACE) { /* interface */
3369 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3370 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3371 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3372 M_BLEZ(REG_ITMP2, 0);
3373 mcode_addxcastrefs(mcodeptr);
3374 M_ALD(REG_ITMP2, REG_ITMP1,
3375 OFFSET(vftbl, interfacetable[0]) -
3376 super->index * sizeof(methodptr*));
3377 M_BEQZ(REG_ITMP2, 0);
3378 mcode_addxcastrefs(mcodeptr);
3382 s2 = super->vftbl->diffval;
3383 M_BEQZ(s1, 4 + (s2 != 0) + (s2 > 255));
3384 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3385 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3386 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3388 M_BNEZ(REG_ITMP1, 0);
3390 else if (s2 <= 255) {
3391 M_CMPULE_IMM(REG_ITMP1, s2, REG_ITMP2);
3392 M_BEQZ(REG_ITMP2, 0);
3395 M_LDA(REG_ITMP2, REG_ZERO, s2);
3396 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3397 M_BEQZ(REG_ITMP2, 0);
3400 M_BEQZ(s1, 8 + (d == REG_ITMP3));
3401 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3402 a = dseg_addaddress ((void*) super->vftbl);
3403 M_ALD(REG_ITMP2, REG_PV, a);
3404 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3405 if (d != REG_ITMP3) {
3406 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl, baseval));
3407 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, diffval));
3408 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3411 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, baseval));
3412 M_ISUB(REG_ITMP1, REG_ITMP2, REG_ITMP1);
3413 M_ALD(REG_ITMP2, REG_PV, a);
3414 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, diffval));
3416 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3417 M_BEQZ(REG_ITMP2, 0);
3418 mcode_addxcastrefs(mcodeptr);
3422 panic ("internal error: no inlined array checkcast");
3425 store_reg_to_var_int(iptr->dst, d);
3428 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
3430 var_to_reg_int(s1, src, REG_ITMP1);
3432 mcode_addxcheckarefs(mcodeptr);
3435 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3436 /* op1 = dimension, val.a = array descriptor */
3438 /* check for negative sizes and copy sizes to stack if necessary */
3440 MCODECHECK((iptr->op1 << 1) + 64);
3442 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3443 var_to_reg_int(s2, src, REG_ITMP1);
3445 mcode_addxcheckarefs(mcodeptr);
3447 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
3449 if (src->varkind != ARGVAR) {
3450 M_LST(s2, REG_SP, 8 * (s1 + INT_ARG_CNT));
3454 /* a0 = dimension count */
3456 ICONST(argintregs[0], iptr->op1);
3458 /* a1 = arraydescriptor */
3460 a = dseg_addaddress(iptr->val.a);
3461 M_ALD(argintregs[1], REG_PV, a);
3463 /* a2 = pointer to dimensions = stack pointer */
3465 M_INTMOVE(REG_SP, argintregs[2]);
3467 a = dseg_addaddress((void*) (builtin_nmultianewarray));
3468 M_ALD(REG_PV, REG_PV, a);
3469 M_JSR(REG_RA, REG_PV);
3470 s1 = (int)((u1*) mcodeptr - mcodebase);
3472 M_LDA (REG_PV, REG_RA, -s1);
3474 s4 ml = -s1, mh = 0;
3475 while (ml < -32768) {ml += 65536; mh--;}
3476 M_LDA(REG_PV, REG_RA, ml);
3477 M_LDAH(REG_PV, REG_PV, mh);
3479 s1 = reg_of_var(iptr->dst, REG_RESULT);
3480 M_INTMOVE(REG_RESULT, s1);
3481 store_reg_to_var_int(iptr->dst, s1);
3485 default: sprintf (logtext, "Unknown pseudo command: %d", iptr->opc);
3492 } /* for instruction */
3494 /* copy values to interface registers */
3496 src = bptr->outstack;
3497 len = bptr->outdepth;
3501 if ((src->varkind != STACKVAR)) {
3503 if (IS_FLT_DBL_TYPE(s2)) {
3504 var_to_reg_flt(s1, src, REG_FTMP1);
3505 if (!(interfaces[len][s2].flags & INMEMORY)) {
3506 M_FLTMOVE(s1,interfaces[len][s2].regoff);
3509 M_DST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3513 var_to_reg_int(s1, src, REG_ITMP1);
3514 if (!(interfaces[len][s2].flags & INMEMORY)) {
3515 M_INTMOVE(s1,interfaces[len][s2].regoff);
3518 M_LST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3524 } /* if (bptr -> flags >= BBREACHED) */
3525 } /* for basic block */
3527 /* bptr -> mpc = (int)((u1*) mcodeptr - mcodebase); */
3530 /* generate bound check stubs */
3532 s4 *xcodeptr = NULL;
3534 for (; xboundrefs != NULL; xboundrefs = xboundrefs->next) {
3535 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3536 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
3537 xboundrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3542 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
3543 xboundrefs->branchpos, (u1*) mcodeptr - mcodebase);
3547 M_LDA(REG_ITMP2_XPC, REG_PV, xboundrefs->branchpos - 4);
3549 if (xcodeptr != NULL) {
3550 M_BR((xcodeptr-mcodeptr)-1);
3553 xcodeptr = mcodeptr;
3555 a = dseg_addaddress(proto_java_lang_ArrayIndexOutOfBoundsException);
3556 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3558 a = dseg_addaddress(asm_handle_exception);
3559 M_ALD(REG_ITMP3, REG_PV, a);
3561 M_JMP(REG_ZERO, REG_ITMP3);
3565 /* generate negative array size check stubs */
3569 for (; xcheckarefs != NULL; xcheckarefs = xcheckarefs->next) {
3570 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3571 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3572 xcheckarefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3576 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3577 xcheckarefs->branchpos, (u1*) mcodeptr - mcodebase);
3581 M_LDA(REG_ITMP2_XPC, REG_PV, xcheckarefs->branchpos - 4);
3583 if (xcodeptr != NULL) {
3584 M_BR((xcodeptr-mcodeptr)-1);
3587 xcodeptr = mcodeptr;
3589 a = dseg_addaddress(proto_java_lang_NegativeArraySizeException);
3590 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3592 a = dseg_addaddress(asm_handle_exception);
3593 M_ALD(REG_ITMP3, REG_PV, a);
3595 M_JMP(REG_ZERO, REG_ITMP3);
3599 /* generate cast check stubs */
3603 for (; xcastrefs != NULL; xcastrefs = xcastrefs->next) {
3604 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3605 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3606 xcastrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3610 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3611 xcastrefs->branchpos, (u1*) mcodeptr - mcodebase);
3615 M_LDA(REG_ITMP2_XPC, REG_PV, xcastrefs->branchpos - 4);
3617 if (xcodeptr != NULL) {
3618 M_BR((xcodeptr-mcodeptr)-1);
3621 xcodeptr = mcodeptr;
3623 a = dseg_addaddress(proto_java_lang_ClassCastException);
3624 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3626 a = dseg_addaddress(asm_handle_exception);
3627 M_ALD(REG_ITMP3, REG_PV, a);
3629 M_JMP(REG_ZERO, REG_ITMP3);
3634 #ifdef SOFTNULLPTRCHECK
3636 /* generate null pointer check stubs */
3640 for (; xnullrefs != NULL; xnullrefs = xnullrefs->next) {
3641 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3642 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3643 xnullrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3647 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3648 xnullrefs->branchpos, (u1*) mcodeptr - mcodebase);
3652 M_LDA(REG_ITMP2_XPC, REG_PV, xnullrefs->branchpos - 4);
3654 if (xcodeptr != NULL) {
3655 M_BR((xcodeptr-mcodeptr)-1);
3658 xcodeptr = mcodeptr;
3660 a = dseg_addaddress(proto_java_lang_NullPointerException);
3661 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3663 a = dseg_addaddress(asm_handle_exception);
3664 M_ALD(REG_ITMP3, REG_PV, a);
3666 M_JMP(REG_ZERO, REG_ITMP3);
3673 mcode_finish((int)((u1*) mcodeptr - mcodebase));
3677 /* redefinition of code generation macros (compiling into array) **************/
3680 These macros are newly defined to allow code generation into an array.
3681 This is necessary, because the original M_.. macros generate code by
3682 calling 'mcode_adds4' that uses an additional data structure to
3685 For a faster (but less flexible) version to generate code, these
3686 macros directly use the (s4* p) - pointer to put the code directly
3687 in a locally defined array.
3688 This makes sense only for the stub-generation-routines below.
3692 #define M_OP3(op,fu,a,b,c,const) \
3693 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<(16-3*(const)))| \
3694 ((const)<<12)|((fu)<<5)|((c)) )
3696 #define M_FOP3(op,fu,a,b,c) \
3697 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<16)|((fu)<<5)|(c) )
3699 #define M_BRA(op,a,disp) \
3700 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((disp)&0x1fffff) )
3702 #define M_MEM(op,a,b,disp) \
3703 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<16)|((disp)&0xffff) )
3706 /* function createcompilerstub *************************************************
3708 creates a stub routine which calls the compiler
3710 *******************************************************************************/
3712 #define COMPSTUBSIZE 3
3714 u1 *createcompilerstub (methodinfo *m)
3716 u8 *s = CNEW (u8, COMPSTUBSIZE); /* memory to hold the stub */
3717 s4 *p = (s4*) s; /* code generation pointer */
3719 /* code for the stub */
3720 M_ALD (REG_PV, REG_PV, 16); /* load pointer to the compiler */
3721 M_JMP (0, REG_PV); /* jump to the compiler, return address
3722 in reg 0 is used as method pointer */
3723 s[1] = (u8) m; /* literals to be adressed */
3724 s[2] = (u8) asm_call_jit_compiler; /* jump directly via PV from above */
3727 count_cstub_len += COMPSTUBSIZE * 8;
3734 /* function removecompilerstub *************************************************
3736 deletes a compilerstub from memory (simply by freeing it)
3738 *******************************************************************************/
3740 void removecompilerstub (u1 *stub)
3742 CFREE (stub, COMPSTUBSIZE * 8);
3745 /* function: createnativestub **************************************************
3747 creates a stub routine which calls a native method
3749 *******************************************************************************/
3751 #define NATIVESTUBSIZE 18
3753 u1 *createnativestub (functionptr f, methodinfo *m)
3755 u8 *s = CNEW (u8, NATIVESTUBSIZE); /* memory to hold the stub */
3756 s4 *p = (s4*) s; /* code generation pointer */
3760 M_MOV (argintregs[4],argintregs[5]);
3761 M_FMOV (argfltregs[4],argfltregs[5]);
3763 M_MOV (argintregs[3],argintregs[4]);
3764 M_FMOV (argfltregs[3],argfltregs[4]);
3766 M_MOV (argintregs[2],argintregs[3]);
3767 M_FMOV (argfltregs[2],argfltregs[3]);
3769 M_MOV (argintregs[1],argintregs[2]);
3770 M_FMOV (argfltregs[1],argfltregs[2]);
3772 M_MOV (argintregs[0],argintregs[1]);
3773 M_FMOV (argfltregs[0],argfltregs[1]);
3775 M_ALD (argintregs[0], REG_PV, 17*8); /* load adress of jni_environement */
3777 M_LDA (REG_SP, REG_SP, -8); /* build up stackframe */
3778 M_AST (REG_RA, REG_SP, 0); /* store return address */
3780 M_ALD (REG_PV, REG_PV, 14*8); /* load adress of native method */
3781 M_JSR (REG_RA, REG_PV); /* call native method */
3783 M_LDA (REG_PV, REG_RA, -15*4); /* recompute pv from ra */
3784 M_ALD (REG_ITMP3, REG_PV, 15*8); /* get address of exceptionptr */
3786 M_ALD (REG_RA, REG_SP, 0); /* load return address */
3787 M_ALD (REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
3789 M_LDA (REG_SP, REG_SP, 8); /* remove stackframe */
3790 M_BNEZ (REG_ITMP1, 1); /* if no exception then return */
3792 M_RET (REG_ZERO, REG_RA); /* return to caller */
3794 M_AST (REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
3795 M_LDA (REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
3797 M_ALD (REG_ITMP3, REG_PV,16*8); /* load asm exception handler address */
3798 M_JMP (REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
3800 s[14] = (u8) f; /* address of native method */
3801 s[15] = (u8) (&exceptionptr); /* address of exceptionptr */
3802 s[16] = (u8) (asm_handle_nat_exception); /* addr of asm exception handler */
3803 s[17] = (u8) (&env); /* addr of jni_environement */
3806 count_nstub_len += NATIVESTUBSIZE * 8;
3812 /* function: removenativestub **************************************************
3814 removes a previously created native-stub from memory
3816 *******************************************************************************/
3818 void removenativestub (u1 *stub)
3820 CFREE (stub, NATIVESTUBSIZE * 8);
3825 * These are local overrides for various environment variables in Emacs.
3826 * Please do not remove this and leave it at the end of the file, where
3827 * Emacs will automagically detect them.
3828 * ---------------------------------------------------------------------
3831 * indent-tabs-mode: t