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);\
65 #define gen_nullptr_check(objreg)
69 /* MCODECHECK(icnt) */
71 #define MCODECHECK(icnt) \
72 if((mcodeptr+(icnt))>mcodeend)mcodeptr=mcode_increase((u1*)mcodeptr)
75 generates an integer-move from register a to b.
76 if a and b are the same int-register, no code will be generated.
79 #define M_INTMOVE(a,b) if(a!=b){M_MOV(a,b);}
83 generates a floating-point-move from register a to b.
84 if a and b are the same float-register, no code will be generated
87 #define M_FLTMOVE(a,b) if(a!=b){M_FMOV(a,b);}
91 this function generates code to fetch data from a pseudo-register
93 If the pseudo-register has actually been assigned to a real
94 register, no code will be emitted, since following operations
95 can use this register directly.
97 v: pseudoregister to be fetched from
98 tempregnum: temporary register to be used if v is actually spilled to ram
100 return: the register number, where the operand can be found after
101 fetching (this wil be either tempregnum or the register
102 number allready given to v)
105 #define var_to_reg_int(regnr,v,tempnr) { \
106 if ((v)->flags & INMEMORY) \
107 {COUNT_SPILLS;M_LLD(tempnr,REG_SP,8*(v)->regoff);regnr=tempnr;} \
108 else regnr=(v)->regoff; \
112 #define var_to_reg_flt(regnr,v,tempnr) { \
113 if ((v)->flags & INMEMORY) \
114 {COUNT_SPILLS;M_DLD(tempnr,REG_SP,8*(v)->regoff);regnr=tempnr;} \
115 else regnr=(v)->regoff; \
120 This function determines a register, to which the result of an operation
121 should go, when it is ultimatively intended to store the result in
123 If v is assigned to an actual register, this register will be returned.
124 Otherwise (when v is spilled) this function returns tempregnum.
125 If not already done, regoff and flags are set in the stack location.
128 static int reg_of_var(stackptr v, int tempregnum)
132 switch (v->varkind) {
134 if (!(v->flags & INMEMORY))
138 var = &(interfaces[v->varnum][v->type]);
139 v->regoff = var->regoff;
140 if (!(var->flags & INMEMORY))
144 var = &(locals[v->varnum][v->type]);
145 v->regoff = var->regoff;
146 if (!(var->flags & INMEMORY))
150 v->regoff = v->varnum;
151 if (IS_FLT_DBL_TYPE(v->type)) {
152 if (v->varnum < fltreg_argnum) {
153 v->regoff = argfltregs[v->varnum];
154 return(argfltregs[v->varnum]);
158 if (v->varnum < intreg_argnum) {
159 v->regoff = argintregs[v->varnum];
160 return(argintregs[v->varnum]);
162 v->regoff -= intreg_argnum;
165 v->flags |= INMEMORY;
170 /* store_reg_to_var_xxx:
171 This function generates the code to store the result of an operation
172 back into a spilled pseudo-variable.
173 If the pseudo-variable has not been spilled in the first place, this
174 function will generate nothing.
176 v ............ Pseudovariable
177 tempregnum ... Number of the temporary registers as returned by
181 #define store_reg_to_var_int(sptr, tempregnum) { \
182 if ((sptr)->flags & INMEMORY) { \
184 M_LST(tempregnum, REG_SP, 8 * (sptr)->regoff); \
188 #define store_reg_to_var_flt(sptr, tempregnum) { \
189 if ((sptr)->flags & INMEMORY) { \
191 M_DST(tempregnum, REG_SP, 8 * (sptr)->regoff); \
196 /* NullPointerException handlers and exception handling initialisation */
198 typedef struct sigctx_struct {
200 long sc_onstack; /* sigstack state to restore */
201 long sc_mask; /* signal mask to restore */
202 long sc_pc; /* pc at time of signal */
203 long sc_ps; /* psl to retore */
204 long sc_regs[32]; /* processor regs 0 to 31 */
205 long sc_ownedfp; /* fp has been used */
206 long sc_fpregs[32]; /* fp regs 0 to 31 */
207 unsigned long sc_fpcr; /* floating point control register */
208 unsigned long sc_fp_control; /* software fpcr */
210 unsigned long sc_reserved1, sc_reserved2;
211 unsigned long sc_ssize;
213 unsigned long sc_traparg_a0;
214 unsigned long sc_traparg_a1;
215 unsigned long sc_traparg_a2;
216 unsigned long sc_fp_trap_pc;
217 unsigned long sc_fp_trigger_sum;
218 unsigned long sc_fp_trigger_inst;
219 unsigned long sc_retcode[2];
223 /* asm_signal_exception passes exception pointer and the signal context
224 structure (contains the saved registers) to the assembler handler which
225 restores registers and walks through the Java exception tables.
228 void asm_signal_exception(void *xptr, void *sigctx);
231 /* NullPointerException signal handler for hardware null pointer check */
233 void catch_NullPointerException(int sig, int code, sigctx_struct *sigctx)
239 /* Reset signal handler - necessary for SysV, does no harm for BSD */
241 instr = *((int*)(sigctx->sc_pc));
242 faultaddr = sigctx->sc_regs[(instr >> 16) & 0x1f];
244 if (faultaddr == 0) {
245 signal(sig, (void*) catch_NullPointerException); /* reinstall handler */
247 sigaddset(&nsig, sig);
248 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
249 asm_signal_exception(proto_java_lang_NullPointerException, sigctx);
252 faultaddr += (long) ((instr << 16) >> 16);
253 fprintf(stderr, "faulting address: 0x%16lx\n", faultaddr);
254 panic("Stack overflow");
261 void init_exceptions(void)
266 /* Linux on Digital Alpha needs an initialisation of the ieee floating point
267 control for IEEE compliant arithmetic (option -mieee of GCC). Under
268 Digital Unix this is done automatically.
273 extern unsigned long ieee_get_fp_control();
274 extern void ieee_set_fp_control(unsigned long fp_control);
276 void init_exceptions(void)
278 /* initialize floating point control */
280 ieee_set_fp_control(ieee_get_fp_control()
281 & ~IEEE_TRAP_ENABLE_INV
282 & ~IEEE_TRAP_ENABLE_DZE
283 /* & ~IEEE_TRAP_ENABLE_UNF we dont want underflow */
284 & ~IEEE_TRAP_ENABLE_OVF);
287 /* install signal handlers we need to convert to exceptions */
292 signal(SIGSEGV, (void*) catch_NullPointerException);
296 signal(SIGBUS, (void*) catch_NullPointerException);
302 /* function gen_mcode **********************************************************
304 generates machine code
306 *******************************************************************************/
308 #define MethodPointer -8
309 #define FrameSize -12
314 #define ExTableSize -32
315 #define ExTableStart -32
317 #define ExEntrySize -32
320 #define ExHandlerPC -24
321 #define ExCatchType -32
323 static void gen_mcode()
325 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 (len = 0; len < exceptiontablelength; len++) {
381 dseg_addtarget(BlockPtrOfPC(extable[len].startpc));
382 dseg_addtarget(BlockPtrOfPC(extable[len].endpc));
383 dseg_addtarget(BlockPtrOfPC(extable[len].handlerpc));
384 (void) dseg_addaddress(extable[len].catchtype);
387 /* initialize mcode variables */
389 mcodeptr = (s4*) mcodebase;
390 mcodeend = (s4*) (mcodebase + mcodesize);
391 MCODECHECK(128 + mparamcount);
393 /* create stack frame (if necessary) */
396 {M_LDA (REG_SP, REG_SP, -parentargs_base * 8);}
398 /* save return address and used callee saved registers */
402 {p--; M_AST (REG_RA, REG_SP, 8*p);}
403 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
404 {p--; M_LST (savintregs[r], REG_SP, 8 * p);}
405 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
406 {p--; M_DST (savfltregs[r], REG_SP, 8 * p);}
408 /* save monitorenter argument */
411 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
412 if (method->flags & ACC_STATIC) {
413 p = dseg_addaddress (class);
414 M_ALD(REG_ITMP1, REG_PV, p);
415 M_AST(REG_ITMP1, REG_SP, 8 * maxmemuse);
418 M_AST (argintregs[0], REG_SP, 8 * maxmemuse);
423 /* copy argument registers to stack and call trace function with pointer
424 to arguments on stack. ToDo: save floating point registers !!!!!!!!!
427 if (runverbose && isleafmethod) {
428 M_LDA (REG_SP, REG_SP, -(14*8));
429 M_AST(REG_RA, REG_SP, 1*8);
431 M_LST(argintregs[0], REG_SP, 2*8);
432 M_LST(argintregs[1], REG_SP, 3*8);
433 M_LST(argintregs[2], REG_SP, 4*8);
434 M_LST(argintregs[3], REG_SP, 5*8);
435 M_LST(argintregs[4], REG_SP, 6*8);
436 M_LST(argintregs[5], REG_SP, 7*8);
438 M_DST(argfltregs[0], REG_SP, 8*8);
439 M_DST(argfltregs[1], REG_SP, 9*8);
440 M_DST(argfltregs[2], REG_SP, 10*8);
441 M_DST(argfltregs[3], REG_SP, 11*8);
442 M_DST(argfltregs[4], REG_SP, 12*8);
443 M_DST(argfltregs[5], REG_SP, 13*8);
445 p = dseg_addaddress (method);
446 M_ALD(REG_ITMP1, REG_PV, p);
447 M_AST(REG_ITMP1, REG_SP, 0);
448 p = dseg_addaddress ((void*) (builtin_trace_args));
449 M_ALD(REG_PV, REG_PV, p);
450 M_JSR(REG_RA, REG_PV);
451 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
452 M_ALD(REG_RA, REG_SP, 1*8);
454 M_LLD(argintregs[0], REG_SP, 2*8);
455 M_LLD(argintregs[1], REG_SP, 3*8);
456 M_LLD(argintregs[2], REG_SP, 4*8);
457 M_LLD(argintregs[3], REG_SP, 5*8);
458 M_LLD(argintregs[4], REG_SP, 6*8);
459 M_LLD(argintregs[5], REG_SP, 7*8);
461 M_DLD(argfltregs[0], REG_SP, 8*8);
462 M_DLD(argfltregs[1], REG_SP, 9*8);
463 M_DLD(argfltregs[2], REG_SP, 10*8);
464 M_DLD(argfltregs[3], REG_SP, 11*8);
465 M_DLD(argfltregs[4], REG_SP, 12*8);
466 M_DLD(argfltregs[5], REG_SP, 13*8);
468 M_LDA (REG_SP, REG_SP, 14*8);
471 /* take arguments out of register or stack frame */
473 for (p = 0, l = 0; p < mparamcount; p++) {
475 var = &(locals[l][t]);
477 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
482 if (IS_INT_LNG_TYPE(t)) { /* integer args */
483 if (p < INT_ARG_CNT) { /* register arguments */
484 if (!(var->flags & INMEMORY)) /* reg arg -> register */
485 {M_INTMOVE (argintregs[p], r);}
486 else /* reg arg -> spilled */
487 M_LST (argintregs[p], REG_SP, 8 * r);
489 else { /* stack arguments */
490 pa = p - INT_ARG_CNT;
491 if (!(var->flags & INMEMORY)) /* stack arg -> register */
492 M_LLD (r, REG_SP, 8 * (parentargs_base + pa));
493 else { /* stack arg -> spilled */
494 M_LLD (REG_ITMP1, REG_SP, 8 * (parentargs_base + pa));
495 M_LST (REG_ITMP1, REG_SP, 8 * r);
499 else { /* floating args */
500 if (p < FLT_ARG_CNT) { /* register arguments */
501 if (!(var->flags & INMEMORY)) /* reg arg -> register */
502 {M_FLTMOVE (argfltregs[p], r);}
503 else /* reg arg -> spilled */
504 M_DST (argfltregs[p], REG_SP, 8 * r);
506 else { /* stack arguments */
507 pa = p - FLT_ARG_CNT;
508 if (!(var->flags & INMEMORY)) /* stack-arg -> register */
509 M_DLD (r, REG_SP, 8 * (parentargs_base + pa) );
510 else { /* stack-arg -> spilled */
511 M_DLD (REG_FTMP1, REG_SP, 8 * (parentargs_base + pa));
512 M_DST (REG_FTMP1, REG_SP, 8 * r);
518 /* call trace function */
520 if (runverbose && !isleafmethod) {
521 M_LDA (REG_SP, REG_SP, -8);
522 p = dseg_addaddress (method);
523 M_ALD(REG_ITMP1, REG_PV, p);
524 M_AST(REG_ITMP1, REG_SP, 0);
525 p = dseg_addaddress ((void*) (builtin_trace_args));
526 M_ALD(REG_PV, REG_PV, p);
527 M_JSR(REG_RA, REG_PV);
528 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
529 M_LDA(REG_SP, REG_SP, 8);
532 /* call monitorenter function */
535 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
536 p = dseg_addaddress ((void*) (builtin_monitorenter));
537 M_ALD(REG_PV, REG_PV, p);
538 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
539 M_JSR(REG_RA, REG_PV);
540 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
545 /* end of header generation */
547 /* walk through all basic blocks */
549 for (bbs = block_count, bptr = block; --bbs >= 0; bptr++) {
550 bptr -> mpc = (int)((u1*) mcodeptr - mcodebase);
552 if (bptr->flags >= BBREACHED) {
554 /* branch resolving */
558 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
559 gen_resolvebranch((u1*) mcodebase + brefs->branchpos,
560 brefs->branchpos, bptr->mpc);
564 /* copy interface registers to their destination */
569 while (src != NULL) {
571 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
572 d = reg_of_var(src, REG_ITMP1);
573 M_INTMOVE(REG_ITMP1, d);
574 store_reg_to_var_int(src, d);
577 d = reg_of_var(src, REG_IFTMP);
578 if ((src->varkind != STACKVAR)) {
580 if (IS_FLT_DBL_TYPE(s2)) {
581 if (!(interfaces[len][s2].flags & INMEMORY)) {
582 s1 = interfaces[len][s2].regoff;
586 M_DLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
588 store_reg_to_var_flt(src, d);
591 if (!(interfaces[len][s2].flags & INMEMORY)) {
592 s1 = interfaces[len][s2].regoff;
596 M_LLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
598 store_reg_to_var_int(src, d);
605 /* walk through all instructions */
609 for (iptr = bptr->iinstr;
611 src = iptr->dst, len--, iptr++) {
613 MCODECHECK(64); /* an instruction usually needs < 64 words */
616 case ICMD_NOP: /* ... ==> ... */
619 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
621 var_to_reg_int(s1, src, REG_ITMP1);
623 mcode_addxnullrefs(mcodeptr);
626 /* constant operations ************************************************/
628 #define ICONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
629 else{a=dseg_adds4(c);M_ILD(r,REG_PV,a);}
631 #define LCONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
632 else{a=dseg_adds8(c);M_LLD(r,REG_PV,a);}
634 case ICMD_ICONST: /* ... ==> ..., constant */
635 /* op1 = 0, val.i = constant */
637 d = reg_of_var(iptr->dst, REG_ITMP1);
638 ICONST(d, iptr->val.i);
639 store_reg_to_var_int(iptr->dst, d);
642 case ICMD_LCONST: /* ... ==> ..., constant */
643 /* op1 = 0, val.l = constant */
645 d = reg_of_var(iptr->dst, REG_ITMP1);
646 LCONST(d, iptr->val.l);
647 store_reg_to_var_int(iptr->dst, d);
650 case ICMD_FCONST: /* ... ==> ..., constant */
651 /* op1 = 0, val.f = constant */
653 d = reg_of_var (iptr->dst, REG_FTMP1);
654 a = dseg_addfloat (iptr->val.f);
656 store_reg_to_var_flt (iptr->dst, d);
659 case ICMD_DCONST: /* ... ==> ..., constant */
660 /* op1 = 0, val.d = constant */
662 d = reg_of_var (iptr->dst, REG_FTMP1);
663 a = dseg_adddouble (iptr->val.d);
665 store_reg_to_var_flt (iptr->dst, d);
668 case ICMD_ACONST: /* ... ==> ..., constant */
669 /* op1 = 0, val.a = constant */
671 d = reg_of_var(iptr->dst, REG_ITMP1);
673 a = dseg_addaddress (iptr->val.a);
677 M_INTMOVE(REG_ZERO, d);
679 store_reg_to_var_int(iptr->dst, d);
683 /* load/store operations **********************************************/
685 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
686 case ICMD_LLOAD: /* op1 = local variable */
689 d = reg_of_var(iptr->dst, REG_ITMP1);
690 if ((iptr->dst->varkind == LOCALVAR) &&
691 (iptr->dst->varnum == iptr->op1))
693 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
694 if (var->flags & INMEMORY)
695 M_LLD(d, REG_SP, 8 * var->regoff);
697 {M_INTMOVE(var->regoff,d);}
698 store_reg_to_var_int(iptr->dst, d);
701 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
702 case ICMD_DLOAD: /* op1 = local variable */
704 d = reg_of_var(iptr->dst, REG_FTMP1);
705 if ((iptr->dst->varkind == LOCALVAR) &&
706 (iptr->dst->varnum == iptr->op1))
708 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
709 if (var->flags & INMEMORY)
710 M_DLD(d, REG_SP, 8 * var->regoff);
712 {M_FLTMOVE(var->regoff,d);}
713 store_reg_to_var_flt(iptr->dst, d);
717 case ICMD_ISTORE: /* ..., value ==> ... */
718 case ICMD_LSTORE: /* op1 = local variable */
721 if ((src->varkind == LOCALVAR) &&
722 (src->varnum == iptr->op1))
724 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
725 if (var->flags & INMEMORY) {
726 var_to_reg_int(s1, src, REG_ITMP1);
727 M_LST(s1, REG_SP, 8 * var->regoff);
730 var_to_reg_int(s1, src, var->regoff);
731 M_INTMOVE(s1, var->regoff);
735 case ICMD_FSTORE: /* ..., value ==> ... */
736 case ICMD_DSTORE: /* op1 = local variable */
738 if ((src->varkind == LOCALVAR) &&
739 (src->varnum == iptr->op1))
741 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
742 if (var->flags & INMEMORY) {
743 var_to_reg_flt(s1, src, REG_FTMP1);
744 M_DST(s1, REG_SP, 8 * var->regoff);
747 var_to_reg_flt(s1, src, var->regoff);
748 M_FLTMOVE(s1, var->regoff);
753 /* pop/dup/swap operations ********************************************/
755 /* attention: double and longs are only one entry in CACAO ICMDs */
757 case ICMD_POP: /* ..., value ==> ... */
758 case ICMD_POP2: /* ..., value, value ==> ... */
761 #define M_COPY(from,to) \
762 d = reg_of_var(to, REG_IFTMP); \
763 if ((from->regoff != to->regoff) || \
764 ((from->flags ^ to->flags) & INMEMORY)) { \
765 if (IS_FLT_DBL_TYPE(from->type)) { \
766 var_to_reg_flt(s1, from, d); \
768 store_reg_to_var_flt(to, d); \
771 var_to_reg_int(s1, from, d); \
773 store_reg_to_var_int(to, d); \
777 case ICMD_DUP: /* ..., a ==> ..., a, a */
778 M_COPY(src, iptr->dst);
781 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
783 M_COPY(src, iptr->dst->prev->prev);
785 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
787 M_COPY(src, iptr->dst);
788 M_COPY(src->prev, iptr->dst->prev);
791 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
793 M_COPY(src->prev, iptr->dst->prev->prev->prev);
795 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
797 M_COPY(src, iptr->dst);
798 M_COPY(src->prev, iptr->dst->prev);
799 M_COPY(src->prev->prev, iptr->dst->prev->prev);
800 M_COPY(src, iptr->dst->prev->prev->prev);
803 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
805 M_COPY(src, iptr->dst);
806 M_COPY(src->prev, iptr->dst->prev);
807 M_COPY(src->prev->prev, iptr->dst->prev->prev);
808 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
809 M_COPY(src, iptr->dst->prev->prev->prev->prev);
810 M_COPY(src->prev, iptr->dst->prev->prev->prev->prev->prev);
813 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
815 M_COPY(src, iptr->dst->prev);
816 M_COPY(src->prev, iptr->dst);
820 /* integer operations *************************************************/
822 case ICMD_INEG: /* ..., value ==> ..., - value */
824 var_to_reg_int(s1, src, REG_ITMP1);
825 d = reg_of_var(iptr->dst, REG_ITMP3);
826 M_ISUB(REG_ZERO, s1, d);
827 store_reg_to_var_int(iptr->dst, d);
830 case ICMD_LNEG: /* ..., value ==> ..., - value */
832 var_to_reg_int(s1, src, REG_ITMP1);
833 d = reg_of_var(iptr->dst, REG_ITMP3);
834 M_LSUB(REG_ZERO, s1, d);
835 store_reg_to_var_int(iptr->dst, d);
838 case ICMD_I2L: /* ..., value ==> ..., value */
840 var_to_reg_int(s1, src, REG_ITMP1);
841 d = reg_of_var(iptr->dst, REG_ITMP3);
843 store_reg_to_var_int(iptr->dst, d);
846 case ICMD_L2I: /* ..., value ==> ..., value */
848 var_to_reg_int(s1, src, REG_ITMP1);
849 d = reg_of_var(iptr->dst, REG_ITMP3);
850 M_IADD(s1, REG_ZERO, d );
851 store_reg_to_var_int(iptr->dst, d);
854 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
856 var_to_reg_int(s1, src, REG_ITMP1);
857 d = reg_of_var(iptr->dst, REG_ITMP3);
858 if (has_ext_instr_set) {
862 M_SLL_IMM(s1, 56, d);
863 M_SRA_IMM( d, 56, d);
865 store_reg_to_var_int(iptr->dst, d);
868 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
870 var_to_reg_int(s1, src, REG_ITMP1);
871 d = reg_of_var(iptr->dst, REG_ITMP3);
873 store_reg_to_var_int(iptr->dst, d);
876 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
878 var_to_reg_int(s1, src, REG_ITMP1);
879 d = reg_of_var(iptr->dst, REG_ITMP3);
880 if (has_ext_instr_set) {
884 M_SLL_IMM(s1, 48, d);
885 M_SRA_IMM( d, 48, d);
887 store_reg_to_var_int(iptr->dst, d);
891 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
893 var_to_reg_int(s1, src->prev, REG_ITMP1);
894 var_to_reg_int(s2, src, REG_ITMP2);
895 d = reg_of_var(iptr->dst, REG_ITMP3);
897 store_reg_to_var_int(iptr->dst, d);
900 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
901 /* val.i = constant */
903 var_to_reg_int(s1, src, REG_ITMP1);
904 d = reg_of_var(iptr->dst, REG_ITMP3);
905 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
906 M_IADD_IMM(s1, iptr->val.i, d);
909 ICONST(REG_ITMP2, iptr->val.i);
910 M_IADD(s1, REG_ITMP2, d);
912 store_reg_to_var_int(iptr->dst, d);
915 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
917 var_to_reg_int(s1, src->prev, REG_ITMP1);
918 var_to_reg_int(s2, src, REG_ITMP2);
919 d = reg_of_var(iptr->dst, REG_ITMP3);
921 store_reg_to_var_int(iptr->dst, d);
924 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
925 /* val.l = constant */
927 var_to_reg_int(s1, src, REG_ITMP1);
928 d = reg_of_var(iptr->dst, REG_ITMP3);
929 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
930 M_LADD_IMM(s1, iptr->val.l, d);
933 LCONST(REG_ITMP2, iptr->val.l);
934 M_LADD(s1, REG_ITMP2, d);
936 store_reg_to_var_int(iptr->dst, d);
939 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
941 var_to_reg_int(s1, src->prev, REG_ITMP1);
942 var_to_reg_int(s2, src, REG_ITMP2);
943 d = reg_of_var(iptr->dst, REG_ITMP3);
945 store_reg_to_var_int(iptr->dst, d);
948 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
949 /* val.i = constant */
951 var_to_reg_int(s1, src, REG_ITMP1);
952 d = reg_of_var(iptr->dst, REG_ITMP3);
953 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
954 M_ISUB_IMM(s1, iptr->val.i, d);
957 ICONST(REG_ITMP2, iptr->val.i);
958 M_ISUB(s1, REG_ITMP2, d);
960 store_reg_to_var_int(iptr->dst, d);
963 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
965 var_to_reg_int(s1, src->prev, REG_ITMP1);
966 var_to_reg_int(s2, src, REG_ITMP2);
967 d = reg_of_var(iptr->dst, REG_ITMP3);
969 store_reg_to_var_int(iptr->dst, d);
972 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
973 /* val.l = constant */
975 var_to_reg_int(s1, src, REG_ITMP1);
976 d = reg_of_var(iptr->dst, REG_ITMP3);
977 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
978 M_LSUB_IMM(s1, iptr->val.l, d);
981 LCONST(REG_ITMP2, iptr->val.l);
982 M_LSUB(s1, REG_ITMP2, d);
984 store_reg_to_var_int(iptr->dst, d);
987 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
989 var_to_reg_int(s1, src->prev, REG_ITMP1);
990 var_to_reg_int(s2, src, REG_ITMP2);
991 d = reg_of_var(iptr->dst, REG_ITMP3);
993 store_reg_to_var_int(iptr->dst, d);
996 case ICMD_IMULCONST: /* ..., 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 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1002 M_IMUL_IMM(s1, iptr->val.i, d);
1005 ICONST(REG_ITMP2, iptr->val.i);
1006 M_IMUL(s1, REG_ITMP2, d);
1008 store_reg_to_var_int(iptr->dst, d);
1011 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1013 var_to_reg_int(s1, src->prev, REG_ITMP1);
1014 var_to_reg_int(s2, src, REG_ITMP2);
1015 d = reg_of_var(iptr->dst, REG_ITMP3);
1017 store_reg_to_var_int(iptr->dst, d);
1020 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
1021 /* val.l = constant */
1023 var_to_reg_int(s1, src, REG_ITMP1);
1024 d = reg_of_var(iptr->dst, REG_ITMP3);
1025 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1026 M_LMUL_IMM(s1, iptr->val.l, d);
1029 LCONST(REG_ITMP2, iptr->val.l);
1030 M_LMUL(s1, REG_ITMP2, d);
1032 store_reg_to_var_int(iptr->dst, d);
1035 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
1036 case ICMD_LDIVPOW2: /* val.i = constant */
1038 var_to_reg_int(s1, src, REG_ITMP1);
1039 d = reg_of_var(iptr->dst, REG_ITMP3);
1040 if (iptr->val.i <= 15) {
1041 M_LDA(REG_ITMP2, s1, (1 << iptr->val.i) -1);
1042 M_CMOVGE(s1, s1, REG_ITMP2);
1045 M_SRA_IMM(s1, 63, REG_ITMP2);
1046 M_SRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
1047 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1049 M_SRA_IMM(REG_ITMP2, iptr->val.i, d);
1050 store_reg_to_var_int(iptr->dst, d);
1053 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1055 var_to_reg_int(s1, src->prev, REG_ITMP1);
1056 var_to_reg_int(s2, src, REG_ITMP2);
1057 d = reg_of_var(iptr->dst, REG_ITMP3);
1058 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1059 M_SLL(s1, REG_ITMP3, d);
1060 M_IADD(d, REG_ZERO, d);
1061 store_reg_to_var_int(iptr->dst, d);
1064 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1065 /* val.i = constant */
1067 var_to_reg_int(s1, src, REG_ITMP1);
1068 d = reg_of_var(iptr->dst, REG_ITMP3);
1069 M_SLL_IMM(s1, iptr->val.i & 0x1f, d);
1070 M_IADD(d, REG_ZERO, d);
1071 store_reg_to_var_int(iptr->dst, d);
1074 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1076 var_to_reg_int(s1, src->prev, REG_ITMP1);
1077 var_to_reg_int(s2, src, REG_ITMP2);
1078 d = reg_of_var(iptr->dst, REG_ITMP3);
1079 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1080 M_SRA(s1, REG_ITMP3, d);
1081 store_reg_to_var_int(iptr->dst, d);
1084 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1085 /* val.i = constant */
1087 var_to_reg_int(s1, src, REG_ITMP1);
1088 d = reg_of_var(iptr->dst, REG_ITMP3);
1089 M_SRA_IMM(s1, iptr->val.i & 0x1f, d);
1090 store_reg_to_var_int(iptr->dst, d);
1093 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1095 var_to_reg_int(s1, src->prev, REG_ITMP1);
1096 var_to_reg_int(s2, src, REG_ITMP2);
1097 d = reg_of_var(iptr->dst, REG_ITMP3);
1098 M_AND_IMM(s2, 0x1f, REG_ITMP2);
1100 M_SRL(d, REG_ITMP2, d);
1101 M_IADD(d, REG_ZERO, d);
1102 store_reg_to_var_int(iptr->dst, d);
1105 case ICMD_IUSHRCONST: /* ..., 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);
1111 M_SRL_IMM(d, iptr->val.i & 0x1f, d);
1112 M_IADD(d, REG_ZERO, d);
1113 store_reg_to_var_int(iptr->dst, d);
1116 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1118 var_to_reg_int(s1, src->prev, REG_ITMP1);
1119 var_to_reg_int(s2, src, REG_ITMP2);
1120 d = reg_of_var(iptr->dst, REG_ITMP3);
1122 store_reg_to_var_int(iptr->dst, d);
1125 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1126 /* val.l = constant */
1128 var_to_reg_int(s1, src, REG_ITMP1);
1129 d = reg_of_var(iptr->dst, REG_ITMP3);
1130 M_SLL_IMM(s1, iptr->val.l & 0x3f, d);
1131 store_reg_to_var_int(iptr->dst, d);
1134 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1136 var_to_reg_int(s1, src->prev, REG_ITMP1);
1137 var_to_reg_int(s2, src, REG_ITMP2);
1138 d = reg_of_var(iptr->dst, REG_ITMP3);
1140 store_reg_to_var_int(iptr->dst, d);
1143 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1144 /* val.l = constant */
1146 var_to_reg_int(s1, src, REG_ITMP1);
1147 d = reg_of_var(iptr->dst, REG_ITMP3);
1148 M_SRA_IMM(s1, iptr->val.l & 0x3f, d);
1149 store_reg_to_var_int(iptr->dst, d);
1152 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1154 var_to_reg_int(s1, src->prev, REG_ITMP1);
1155 var_to_reg_int(s2, src, REG_ITMP2);
1156 d = reg_of_var(iptr->dst, REG_ITMP3);
1158 store_reg_to_var_int(iptr->dst, d);
1161 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1162 /* val.l = constant */
1164 var_to_reg_int(s1, src, REG_ITMP1);
1165 d = reg_of_var(iptr->dst, REG_ITMP3);
1166 M_SRL_IMM(s1, iptr->val.l & 0x3f, d);
1167 store_reg_to_var_int(iptr->dst, d);
1170 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1173 var_to_reg_int(s1, src->prev, REG_ITMP1);
1174 var_to_reg_int(s2, src, REG_ITMP2);
1175 d = reg_of_var(iptr->dst, REG_ITMP3);
1177 store_reg_to_var_int(iptr->dst, d);
1180 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1181 /* val.i = constant */
1183 var_to_reg_int(s1, src, REG_ITMP1);
1184 d = reg_of_var(iptr->dst, REG_ITMP3);
1185 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1186 M_AND_IMM(s1, iptr->val.i, d);
1188 else if (iptr->val.i == 0xffff) {
1191 else if (iptr->val.i == 0xffffff) {
1192 M_ZAPNOT_IMM(s1, 0x07, d);
1195 ICONST(REG_ITMP2, iptr->val.i);
1196 M_AND(s1, REG_ITMP2, d);
1198 store_reg_to_var_int(iptr->dst, d);
1201 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1202 /* val.i = constant */
1204 var_to_reg_int(s1, src, REG_ITMP1);
1205 d = reg_of_var(iptr->dst, REG_ITMP3);
1207 M_MOV(s1, REG_ITMP1);
1210 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1211 M_AND_IMM(s1, iptr->val.i, d);
1213 M_ISUB(REG_ZERO, s1, d);
1214 M_AND_IMM(d, iptr->val.i, d);
1216 else if (iptr->val.i == 0xffff) {
1219 M_ISUB(REG_ZERO, s1, d);
1222 else if (iptr->val.i == 0xffffff) {
1223 M_ZAPNOT_IMM(s1, 0x07, d);
1225 M_ISUB(REG_ZERO, s1, d);
1226 M_ZAPNOT_IMM(d, 0x07, d);
1229 ICONST(REG_ITMP2, iptr->val.i);
1230 M_AND(s1, REG_ITMP2, d);
1232 M_ISUB(REG_ZERO, s1, d);
1233 M_AND(d, REG_ITMP2, d);
1235 M_ISUB(REG_ZERO, d, d);
1236 store_reg_to_var_int(iptr->dst, d);
1239 case ICMD_IREM0X10001: /* ..., value ==> ..., value % 0x100001 */
1241 /* b = value & 0xffff;
1243 a = ((b - a) & 0xffff) + (b < a);
1245 var_to_reg_int(s1, src, REG_ITMP1);
1246 d = reg_of_var(iptr->dst, REG_ITMP3);
1248 M_MOV(s1, REG_ITMP3);
1252 M_CZEXT(s1, REG_ITMP2);
1253 M_SRA_IMM(s1, 16, d);
1254 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1255 M_ISUB(REG_ITMP2, d, d);
1257 M_IADD(d, REG_ITMP1, d);
1258 M_BR(11 + (s1 == REG_ITMP1));
1259 M_ISUB(REG_ZERO, s1, REG_ITMP1);
1260 M_CZEXT(REG_ITMP1, REG_ITMP2);
1261 M_SRA_IMM(REG_ITMP1, 16, d);
1262 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1263 M_ISUB(REG_ITMP2, d, d);
1265 M_IADD(d, REG_ITMP1, d);
1266 M_ISUB(REG_ZERO, d, d);
1267 if (s1 == REG_ITMP1) {
1268 var_to_reg_int(s1, src, REG_ITMP1);
1270 M_SLL_IMM(s1, 33, REG_ITMP2);
1271 M_CMPEQ(REG_ITMP2, REG_ZERO, REG_ITMP2);
1272 M_ISUB(d, REG_ITMP2, d);
1273 store_reg_to_var_int(iptr->dst, d);
1276 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1277 /* val.l = constant */
1279 var_to_reg_int(s1, src, REG_ITMP1);
1280 d = reg_of_var(iptr->dst, REG_ITMP3);
1281 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1282 M_AND_IMM(s1, iptr->val.l, d);
1284 else if (iptr->val.l == 0xffffL) {
1287 else if (iptr->val.l == 0xffffffL) {
1288 M_ZAPNOT_IMM(s1, 0x07, d);
1290 else if (iptr->val.l == 0xffffffffL) {
1293 else if (iptr->val.l == 0xffffffffffL) {
1294 M_ZAPNOT_IMM(s1, 0x1f, d);
1296 else if (iptr->val.l == 0xffffffffffffL) {
1297 M_ZAPNOT_IMM(s1, 0x3f, d);
1299 else if (iptr->val.l == 0xffffffffffffffL) {
1300 M_ZAPNOT_IMM(s1, 0x7f, d);
1303 LCONST(REG_ITMP2, iptr->val.l);
1304 M_AND(s1, REG_ITMP2, d);
1306 store_reg_to_var_int(iptr->dst, d);
1309 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1310 /* val.l = constant */
1312 var_to_reg_int(s1, src, REG_ITMP1);
1313 d = reg_of_var(iptr->dst, REG_ITMP3);
1315 M_MOV(s1, REG_ITMP1);
1318 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1319 M_AND_IMM(s1, iptr->val.l, d);
1321 M_LSUB(REG_ZERO, s1, d);
1322 M_AND_IMM(d, iptr->val.l, d);
1324 else if (iptr->val.l == 0xffffL) {
1327 M_LSUB(REG_ZERO, s1, d);
1330 else if (iptr->val.l == 0xffffffL) {
1331 M_ZAPNOT_IMM(s1, 0x07, d);
1333 M_LSUB(REG_ZERO, s1, d);
1334 M_ZAPNOT_IMM(d, 0x07, d);
1336 else if (iptr->val.l == 0xffffffffL) {
1339 M_LSUB(REG_ZERO, s1, d);
1342 else if (iptr->val.l == 0xffffffffffL) {
1343 M_ZAPNOT_IMM(s1, 0x1f, d);
1345 M_LSUB(REG_ZERO, s1, d);
1346 M_ZAPNOT_IMM(d, 0x1f, d);
1348 else if (iptr->val.l == 0xffffffffffffL) {
1349 M_ZAPNOT_IMM(s1, 0x3f, d);
1351 M_LSUB(REG_ZERO, s1, d);
1352 M_ZAPNOT_IMM(d, 0x3f, d);
1354 else if (iptr->val.l == 0xffffffffffffffL) {
1355 M_ZAPNOT_IMM(s1, 0x7f, d);
1357 M_LSUB(REG_ZERO, s1, d);
1358 M_ZAPNOT_IMM(d, 0x7f, d);
1361 LCONST(REG_ITMP2, iptr->val.l);
1362 M_AND(s1, REG_ITMP2, d);
1364 M_LSUB(REG_ZERO, s1, d);
1365 M_AND(d, REG_ITMP2, d);
1367 M_LSUB(REG_ZERO, d, d);
1368 store_reg_to_var_int(iptr->dst, d);
1371 case ICMD_LREM0X10001:/* ..., value ==> ..., value % 0x10001 */
1373 var_to_reg_int(s1, src, REG_ITMP1);
1374 d = reg_of_var(iptr->dst, REG_ITMP3);
1376 M_MOV(s1, REG_ITMP3);
1379 M_CZEXT(s1, REG_ITMP2);
1380 M_SRA_IMM(s1, 16, d);
1381 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1382 M_LSUB(REG_ITMP2, d, d);
1384 M_LADD(d, REG_ITMP1, d);
1385 M_LDA(REG_ITMP2, REG_ZERO, -1);
1386 M_SRL_IMM(REG_ITMP2, 33, REG_ITMP2);
1387 if (s1 == REG_ITMP1) {
1388 var_to_reg_int(s1, src, REG_ITMP1);
1390 M_CMPULT(s1, REG_ITMP2, REG_ITMP2);
1391 M_BNEZ(REG_ITMP2, 11);
1392 M_LDA(d, REG_ZERO, -257);
1393 M_ZAPNOT_IMM(d, 0xcd, d);
1394 M_LSUB(REG_ZERO, s1, REG_ITMP2);
1395 M_CMOVGE(s1, s1, REG_ITMP2);
1396 M_UMULH(REG_ITMP2, d, REG_ITMP2);
1397 M_SRL_IMM(REG_ITMP2, 16, REG_ITMP2);
1398 M_LSUB(REG_ZERO, REG_ITMP2, d);
1399 M_CMOVGE(s1, REG_ITMP2, d);
1400 M_SLL_IMM(d, 16, REG_ITMP2);
1401 M_LADD(d, REG_ITMP2, d);
1403 store_reg_to_var_int(iptr->dst, d);
1406 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1409 var_to_reg_int(s1, src->prev, REG_ITMP1);
1410 var_to_reg_int(s2, src, REG_ITMP2);
1411 d = reg_of_var(iptr->dst, REG_ITMP3);
1413 store_reg_to_var_int(iptr->dst, d);
1416 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1417 /* val.i = constant */
1419 var_to_reg_int(s1, src, REG_ITMP1);
1420 d = reg_of_var(iptr->dst, REG_ITMP3);
1421 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1422 M_OR_IMM(s1, iptr->val.i, d);
1425 ICONST(REG_ITMP2, iptr->val.i);
1426 M_OR(s1, REG_ITMP2, d);
1428 store_reg_to_var_int(iptr->dst, d);
1431 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1432 /* val.l = constant */
1434 var_to_reg_int(s1, src, REG_ITMP1);
1435 d = reg_of_var(iptr->dst, REG_ITMP3);
1436 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1437 M_OR_IMM(s1, iptr->val.l, d);
1440 LCONST(REG_ITMP2, iptr->val.l);
1441 M_OR(s1, REG_ITMP2, d);
1443 store_reg_to_var_int(iptr->dst, d);
1446 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1449 var_to_reg_int(s1, src->prev, REG_ITMP1);
1450 var_to_reg_int(s2, src, REG_ITMP2);
1451 d = reg_of_var(iptr->dst, REG_ITMP3);
1453 store_reg_to_var_int(iptr->dst, d);
1456 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1457 /* val.i = constant */
1459 var_to_reg_int(s1, src, REG_ITMP1);
1460 d = reg_of_var(iptr->dst, REG_ITMP3);
1461 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1462 M_XOR_IMM(s1, iptr->val.i, d);
1465 ICONST(REG_ITMP2, iptr->val.i);
1466 M_XOR(s1, REG_ITMP2, d);
1468 store_reg_to_var_int(iptr->dst, d);
1471 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1472 /* val.l = constant */
1474 var_to_reg_int(s1, src, REG_ITMP1);
1475 d = reg_of_var(iptr->dst, REG_ITMP3);
1476 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1477 M_XOR_IMM(s1, iptr->val.l, d);
1480 LCONST(REG_ITMP2, iptr->val.l);
1481 M_XOR(s1, REG_ITMP2, d);
1483 store_reg_to_var_int(iptr->dst, d);
1487 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1489 var_to_reg_int(s1, src->prev, REG_ITMP1);
1490 var_to_reg_int(s2, src, REG_ITMP2);
1491 d = reg_of_var(iptr->dst, REG_ITMP3);
1492 M_CMPLT(s1, s2, REG_ITMP3);
1493 M_CMPLT(s2, s1, REG_ITMP1);
1494 M_LSUB (REG_ITMP1, REG_ITMP3, d);
1495 store_reg_to_var_int(iptr->dst, d);
1499 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1500 /* op1 = variable, val.i = constant */
1502 var = &(locals[iptr->op1][TYPE_INT]);
1503 if (var->flags & INMEMORY) {
1505 M_LLD(s1, REG_SP, 8 * var->regoff);
1509 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1510 M_IADD_IMM(s1, iptr->val.i, s1);
1512 else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1513 M_ISUB_IMM(s1, (-iptr->val.i), s1);
1516 M_LDA (s1, s1, iptr->val.i);
1517 M_IADD(s1, REG_ZERO, s1);
1519 if (var->flags & INMEMORY)
1520 M_LST(s1, REG_SP, 8 * var->regoff);
1524 /* floating operations ************************************************/
1526 case ICMD_FNEG: /* ..., value ==> ..., - value */
1528 var_to_reg_flt(s1, src, REG_FTMP1);
1529 d = reg_of_var(iptr->dst, REG_FTMP3);
1531 store_reg_to_var_flt(iptr->dst, d);
1534 case ICMD_DNEG: /* ..., value ==> ..., - value */
1536 var_to_reg_flt(s1, src, REG_FTMP1);
1537 d = reg_of_var(iptr->dst, REG_FTMP3);
1539 store_reg_to_var_flt(iptr->dst, d);
1542 case ICMD_FADD: /* ..., 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);
1548 store_reg_to_var_flt(iptr->dst, d);
1551 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1553 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1554 var_to_reg_flt(s2, src, REG_FTMP2);
1555 d = reg_of_var(iptr->dst, REG_FTMP3);
1557 store_reg_to_var_flt(iptr->dst, d);
1560 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1562 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1563 var_to_reg_flt(s2, src, REG_FTMP2);
1564 d = reg_of_var(iptr->dst, REG_FTMP3);
1566 store_reg_to_var_flt(iptr->dst, d);
1569 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1571 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1572 var_to_reg_flt(s2, src, REG_FTMP2);
1573 d = reg_of_var(iptr->dst, REG_FTMP3);
1575 store_reg_to_var_flt(iptr->dst, d);
1578 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1580 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1581 var_to_reg_flt(s2, src, REG_FTMP2);
1582 d = reg_of_var(iptr->dst, REG_FTMP3);
1584 store_reg_to_var_flt(iptr->dst, d);
1587 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1589 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1590 var_to_reg_flt(s2, src, REG_FTMP2);
1591 d = reg_of_var(iptr->dst, REG_FTMP3);
1593 store_reg_to_var_flt(iptr->dst, d);
1596 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1598 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1599 var_to_reg_flt(s2, src, REG_FTMP2);
1600 d = reg_of_var(iptr->dst, REG_FTMP3);
1602 store_reg_to_var_flt(iptr->dst, d);
1605 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1607 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1608 var_to_reg_flt(s2, src, REG_FTMP2);
1609 d = reg_of_var(iptr->dst, REG_FTMP3);
1611 store_reg_to_var_flt(iptr->dst, d);
1614 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1616 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1617 var_to_reg_flt(s2, src, REG_FTMP2);
1618 d = reg_of_var(iptr->dst, REG_FTMP3);
1619 M_FDIV(s1,s2, REG_FTMP3);
1620 M_FLOORFL(REG_FTMP3, REG_FTMP3);
1621 M_CVTLF(REG_FTMP3, REG_FTMP3);
1622 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1623 M_FSUB(s1, REG_FTMP3, d);
1624 store_reg_to_var_flt(iptr->dst, d);
1627 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1629 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1630 var_to_reg_flt(s2, src, REG_FTMP2);
1631 d = reg_of_var(iptr->dst, REG_FTMP3);
1632 M_DDIV(s1,s2, REG_FTMP3);
1633 M_FLOORDL(REG_FTMP3, REG_FTMP3);
1634 M_CVTLD(REG_FTMP3, REG_FTMP3);
1635 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1636 M_DSUB(s1, REG_FTMP3, d);
1637 store_reg_to_var_flt(iptr->dst, d);
1640 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1642 var_to_reg_int(s1, src, REG_ITMP1);
1643 d = reg_of_var(iptr->dst, REG_FTMP3);
1646 store_reg_to_var_flt(iptr->dst, d);
1649 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1651 var_to_reg_int(s1, src, REG_ITMP1);
1652 d = reg_of_var(iptr->dst, REG_FTMP3);
1655 store_reg_to_var_flt(iptr->dst, d);
1658 case ICMD_F2I: /* ..., (float) value ==> ..., (int) value */
1660 var_to_reg_flt(s1, src, REG_FTMP1);
1661 d = reg_of_var(iptr->dst, REG_ITMP3);
1662 M_CVTFI(s1, REG_FTMP1);
1663 M_MOVDL(REG_FTMP1, d);
1664 store_reg_to_var_int(iptr->dst, d);
1667 case ICMD_D2I: /* ..., (double) value ==> ..., (int) value */
1669 var_to_reg_flt(s1, src, REG_FTMP1);
1670 d = reg_of_var(iptr->dst, REG_ITMP3);
1671 M_CVTDI(s1, REG_FTMP1);
1672 M_MOVDL(REG_FTMP1, d);
1673 store_reg_to_var_int(iptr->dst, d);
1676 case ICMD_F2L: /* ..., (float) value ==> ..., (long) value */
1678 var_to_reg_flt(s1, src, REG_FTMP1);
1679 d = reg_of_var(iptr->dst, REG_ITMP3);
1680 M_CVTFL(s1, REG_FTMP1);
1681 M_MOVDL(REG_FTMP1, d);
1682 store_reg_to_var_int(iptr->dst, d);
1685 case ICMD_D2L: /* ..., (double) value ==> ..., (long) value */
1687 var_to_reg_flt(s1, src, REG_FTMP1);
1688 d = reg_of_var(iptr->dst, REG_ITMP3);
1689 M_CVTDL(s1, REG_FTMP1);
1690 M_MOVDL(REG_FTMP1, d);
1691 store_reg_to_var_int(iptr->dst, d);
1694 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1696 var_to_reg_flt(s1, src, REG_FTMP1);
1697 d = reg_of_var(iptr->dst, REG_FTMP3);
1699 store_reg_to_var_flt(iptr->dst, d);
1702 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1704 var_to_reg_flt(s1, src, REG_FTMP1);
1705 d = reg_of_var(iptr->dst, REG_FTMP3);
1707 store_reg_to_var_flt(iptr->dst, d);
1710 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1712 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1713 var_to_reg_flt(s2, src, REG_FTMP2);
1714 d = reg_of_var(iptr->dst, REG_ITMP3);
1716 M_FBF(2); /* jump over next instructions */
1717 M_LSUB_IMM(REG_ZERO, 1, d);
1720 M_FBF(2); /* jump over next instruction */
1722 M_LADD_IMM(REG_ZERO, 1, d);
1723 store_reg_to_var_int(iptr->dst, d);
1726 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1728 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1729 var_to_reg_flt(s2, src, REG_FTMP2);
1730 d = reg_of_var(iptr->dst, REG_ITMP3);
1732 M_FBF(2); /* jump over next instructions */
1733 M_LSUB_IMM(REG_ZERO, 1, d);
1736 M_FBF(2); /* jump over next instruction */
1738 M_LADD_IMM(REG_ZERO, 1, d);
1739 store_reg_to_var_int(iptr->dst, d);
1742 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1744 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1745 var_to_reg_flt(s2, src, REG_FTMP2);
1746 d = reg_of_var(iptr->dst, REG_ITMP3);
1748 M_FBF(2); /* jump over next instruction */
1749 M_LADD_IMM(REG_ZERO, 1, d);
1752 M_FBF(2); /* jump over next instruction */
1754 M_LSUB_IMM(REG_ZERO, 1, d);
1755 store_reg_to_var_int(iptr->dst, d);
1758 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1760 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1761 var_to_reg_flt(s2, src, REG_FTMP2);
1762 d = reg_of_var(iptr->dst, REG_ITMP3);
1764 M_FBF(2); /* jump over next instruction */
1765 M_LADD_IMM(REG_ZERO, 1, d);
1768 M_FBF(2); /* jump over next instruction */
1770 M_LSUB_IMM(REG_ZERO, 1, d);
1771 store_reg_to_var_int(iptr->dst, d);
1775 /* memory operations **************************************************/
1777 #define gen_bound_check \
1779 M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\
1780 M_CMPULT(s2, REG_ITMP3, REG_ITMP3);\
1781 M_BEQZ(REG_ITMP3, 0);\
1782 mcode_addxboundrefs(mcodeptr);\
1785 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1787 var_to_reg_int(s1, src, REG_ITMP1);
1788 d = reg_of_var(iptr->dst, REG_ITMP3);
1789 gen_nullptr_check(s1);
1790 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1791 store_reg_to_var_int(iptr->dst, d);
1794 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1796 var_to_reg_int(s1, src->prev, REG_ITMP1);
1797 var_to_reg_int(s2, src, REG_ITMP2);
1798 d = reg_of_var(iptr->dst, REG_ITMP3);
1799 gen_nullptr_check(s1);
1801 M_SAADDQ(s2, s1, REG_ITMP1);
1802 M_ALD( d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1803 store_reg_to_var_int(iptr->dst, d);
1806 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1808 var_to_reg_int(s1, src->prev, REG_ITMP1);
1809 var_to_reg_int(s2, src, REG_ITMP2);
1810 d = reg_of_var(iptr->dst, REG_ITMP3);
1811 gen_nullptr_check(s1);
1813 M_S8ADDQ(s2, s1, REG_ITMP1);
1814 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1815 store_reg_to_var_int(iptr->dst, d);
1818 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1820 var_to_reg_int(s1, src->prev, REG_ITMP1);
1821 var_to_reg_int(s2, src, REG_ITMP2);
1822 d = reg_of_var(iptr->dst, REG_ITMP3);
1823 gen_nullptr_check(s1);
1825 M_S4ADDQ(s2, s1, REG_ITMP1);
1826 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1827 store_reg_to_var_int(iptr->dst, d);
1830 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1832 var_to_reg_int(s1, src->prev, REG_ITMP1);
1833 var_to_reg_int(s2, src, REG_ITMP2);
1834 d = reg_of_var(iptr->dst, REG_FTMP3);
1835 gen_nullptr_check(s1);
1837 M_S4ADDQ(s2, s1, REG_ITMP1);
1838 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1839 store_reg_to_var_flt(iptr->dst, d);
1842 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1844 var_to_reg_int(s1, src->prev, REG_ITMP1);
1845 var_to_reg_int(s2, src, REG_ITMP2);
1846 d = reg_of_var(iptr->dst, REG_FTMP3);
1847 gen_nullptr_check(s1);
1849 M_S8ADDQ(s2, s1, REG_ITMP1);
1850 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1851 store_reg_to_var_flt(iptr->dst, d);
1854 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1856 var_to_reg_int(s1, src->prev, REG_ITMP1);
1857 var_to_reg_int(s2, src, REG_ITMP2);
1858 d = reg_of_var(iptr->dst, REG_ITMP3);
1859 gen_nullptr_check(s1);
1861 if (has_ext_instr_set) {
1862 M_LADD(s2, s1, REG_ITMP1);
1863 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1864 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1867 M_LADD (s2, s1, REG_ITMP1);
1868 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1869 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1870 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1871 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
1873 store_reg_to_var_int(iptr->dst, d);
1876 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1878 var_to_reg_int(s1, src->prev, REG_ITMP1);
1879 var_to_reg_int(s2, src, REG_ITMP2);
1880 d = reg_of_var(iptr->dst, REG_ITMP3);
1881 gen_nullptr_check(s1);
1883 if (has_ext_instr_set) {
1884 M_LADD(s2, s1, REG_ITMP1);
1885 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1886 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1890 M_LADD(s2, s1, REG_ITMP1);
1891 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1892 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1893 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1894 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1895 M_SRA_IMM(d, 48, d);
1897 store_reg_to_var_int(iptr->dst, d);
1900 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1902 var_to_reg_int(s1, src->prev, REG_ITMP1);
1903 var_to_reg_int(s2, src, REG_ITMP2);
1904 d = reg_of_var(iptr->dst, REG_ITMP3);
1905 gen_nullptr_check(s1);
1907 if (has_ext_instr_set) {
1908 M_LADD (s2, s1, REG_ITMP1);
1909 M_BLDU (d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1913 M_LADD(s2, s1, REG_ITMP1);
1914 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1915 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
1916 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1917 M_SRA_IMM(d, 56, d);
1919 store_reg_to_var_int(iptr->dst, d);
1923 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1925 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1926 var_to_reg_int(s2, src->prev, REG_ITMP2);
1927 gen_nullptr_check(s1);
1929 var_to_reg_int(s3, src, REG_ITMP3);
1930 M_SAADDQ(s2, s1, REG_ITMP1);
1931 M_AST (s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1934 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1936 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1937 var_to_reg_int(s2, src->prev, REG_ITMP2);
1938 gen_nullptr_check(s1);
1940 var_to_reg_int(s3, src, REG_ITMP3);
1941 M_S8ADDQ(s2, s1, REG_ITMP1);
1942 M_LST (s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1945 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1947 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1948 var_to_reg_int(s2, src->prev, REG_ITMP2);
1949 gen_nullptr_check(s1);
1951 var_to_reg_int(s3, src, REG_ITMP3);
1952 M_S4ADDQ(s2, s1, REG_ITMP1);
1953 M_IST (s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1956 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1958 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1959 var_to_reg_int(s2, src->prev, REG_ITMP2);
1960 gen_nullptr_check(s1);
1962 var_to_reg_flt(s3, src, REG_FTMP3);
1963 M_S4ADDQ(s2, s1, REG_ITMP1);
1964 M_FST (s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1967 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1969 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1970 var_to_reg_int(s2, src->prev, REG_ITMP2);
1971 gen_nullptr_check(s1);
1973 var_to_reg_flt(s3, src, REG_FTMP3);
1974 M_S8ADDQ(s2, s1, REG_ITMP1);
1975 M_DST (s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1978 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1980 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1981 var_to_reg_int(s2, src->prev, REG_ITMP2);
1982 gen_nullptr_check(s1);
1984 var_to_reg_int(s3, src, REG_ITMP3);
1985 if (has_ext_instr_set) {
1986 M_LADD(s2, s1, REG_ITMP1);
1987 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1988 M_SST (s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1991 M_LADD (s2, s1, REG_ITMP1);
1992 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1993 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1994 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1995 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1996 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1997 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
1998 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2002 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
2004 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2005 var_to_reg_int(s2, src->prev, REG_ITMP2);
2006 gen_nullptr_check(s1);
2008 var_to_reg_int(s3, src, REG_ITMP3);
2009 if (has_ext_instr_set) {
2010 M_LADD(s2, s1, REG_ITMP1);
2011 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2012 M_SST (s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2015 M_LADD (s2, s1, REG_ITMP1);
2016 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2017 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2018 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2019 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
2020 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2021 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2022 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2026 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
2028 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2029 var_to_reg_int(s2, src->prev, REG_ITMP2);
2030 gen_nullptr_check(s1);
2032 var_to_reg_int(s3, src, REG_ITMP3);
2033 if (has_ext_instr_set) {
2034 M_LADD(s2, s1, REG_ITMP1);
2035 M_BST (s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2038 M_LADD (s2, s1, REG_ITMP1);
2039 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2040 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2041 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
2042 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2043 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2044 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2049 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2050 /* op1 = type, val.a = field address */
2052 a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value));
2053 M_ALD(REG_ITMP1, REG_PV, a);
2054 switch (iptr->op1) {
2056 var_to_reg_int(s2, src, REG_ITMP2);
2057 M_IST(s2, REG_ITMP1, 0);
2060 var_to_reg_int(s2, src, REG_ITMP2);
2061 M_LST(s2, REG_ITMP1, 0);
2064 var_to_reg_int(s2, src, REG_ITMP2);
2065 M_AST(s2, REG_ITMP1, 0);
2068 var_to_reg_flt(s2, src, REG_FTMP2);
2069 M_FST(s2, REG_ITMP1, 0);
2072 var_to_reg_flt(s2, src, REG_FTMP2);
2073 M_DST(s2, REG_ITMP1, 0);
2075 default: panic ("internal error");
2079 case ICMD_GETSTATIC: /* ... ==> ..., value */
2080 /* op1 = type, val.a = field address */
2082 a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value));
2083 M_ALD(REG_ITMP1, REG_PV, a);
2084 switch (iptr->op1) {
2086 d = reg_of_var(iptr->dst, REG_ITMP3);
2087 M_ILD(d, REG_ITMP1, 0);
2088 store_reg_to_var_int(iptr->dst, d);
2091 d = reg_of_var(iptr->dst, REG_ITMP3);
2092 M_LLD(d, REG_ITMP1, 0);
2093 store_reg_to_var_int(iptr->dst, d);
2096 d = reg_of_var(iptr->dst, REG_ITMP3);
2097 M_ALD(d, REG_ITMP1, 0);
2098 store_reg_to_var_int(iptr->dst, d);
2101 d = reg_of_var(iptr->dst, REG_FTMP1);
2102 M_FLD(d, REG_ITMP1, 0);
2103 store_reg_to_var_flt(iptr->dst, d);
2106 d = reg_of_var(iptr->dst, REG_FTMP1);
2107 M_DLD(d, REG_ITMP1, 0);
2108 store_reg_to_var_flt(iptr->dst, d);
2110 default: panic ("internal error");
2115 case ICMD_PUTFIELD: /* ..., value ==> ... */
2116 /* op1 = type, val.i = field offset */
2118 a = ((fieldinfo *)(iptr->val.a))->offset;
2119 switch (iptr->op1) {
2121 var_to_reg_int(s1, src->prev, REG_ITMP1);
2122 var_to_reg_int(s2, src, REG_ITMP2);
2123 gen_nullptr_check(s1);
2127 var_to_reg_int(s1, src->prev, REG_ITMP1);
2128 var_to_reg_int(s2, src, REG_ITMP2);
2129 gen_nullptr_check(s1);
2133 var_to_reg_int(s1, src->prev, REG_ITMP1);
2134 var_to_reg_int(s2, src, REG_ITMP2);
2135 gen_nullptr_check(s1);
2139 var_to_reg_int(s1, src->prev, REG_ITMP1);
2140 var_to_reg_flt(s2, src, REG_FTMP2);
2141 gen_nullptr_check(s1);
2145 var_to_reg_int(s1, src->prev, REG_ITMP1);
2146 var_to_reg_flt(s2, src, REG_FTMP2);
2147 gen_nullptr_check(s1);
2150 default: panic ("internal error");
2154 case ICMD_GETFIELD: /* ... ==> ..., value */
2155 /* op1 = type, val.i = field offset */
2157 a = ((fieldinfo *)(iptr->val.a))->offset;
2158 switch (iptr->op1) {
2160 var_to_reg_int(s1, src, REG_ITMP1);
2161 d = reg_of_var(iptr->dst, REG_ITMP3);
2162 gen_nullptr_check(s1);
2164 store_reg_to_var_int(iptr->dst, d);
2167 var_to_reg_int(s1, src, REG_ITMP1);
2168 d = reg_of_var(iptr->dst, REG_ITMP3);
2169 gen_nullptr_check(s1);
2171 store_reg_to_var_int(iptr->dst, d);
2174 var_to_reg_int(s1, src, REG_ITMP1);
2175 d = reg_of_var(iptr->dst, REG_ITMP3);
2176 gen_nullptr_check(s1);
2178 store_reg_to_var_int(iptr->dst, d);
2181 var_to_reg_int(s1, src, REG_ITMP1);
2182 d = reg_of_var(iptr->dst, REG_FTMP1);
2183 gen_nullptr_check(s1);
2185 store_reg_to_var_flt(iptr->dst, d);
2188 var_to_reg_int(s1, src, REG_ITMP1);
2189 d = reg_of_var(iptr->dst, REG_FTMP1);
2190 gen_nullptr_check(s1);
2192 store_reg_to_var_flt(iptr->dst, d);
2194 default: panic ("internal error");
2199 /* branch operations **************************************************/
2201 #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}}
2203 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2205 var_to_reg_int(s1, src, REG_ITMP1);
2206 M_INTMOVE(s1, REG_ITMP1_XPTR);
2207 a = dseg_addaddress(asm_handle_exception);
2208 M_ALD(REG_ITMP2, REG_PV, a);
2209 M_JSR(REG_ITMP2_XPC, REG_ITMP2);
2213 case ICMD_GOTO: /* ... ==> ... */
2214 /* op1 = target JavaVM pc */
2216 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2220 case ICMD_JSR: /* ... ==> ... */
2221 /* op1 = target JavaVM pc */
2223 M_BSR(REG_ITMP1, 0);
2224 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2227 case ICMD_RET: /* ... ==> ... */
2228 /* op1 = local variable */
2230 var = &(locals[iptr->op1][TYPE_ADR]);
2231 if (var->flags & INMEMORY) {
2232 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2240 case ICMD_IFNULL: /* ..., value ==> ... */
2241 /* op1 = target JavaVM pc */
2243 var_to_reg_int(s1, src, REG_ITMP1);
2245 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2248 case ICMD_IFNONNULL: /* ..., value ==> ... */
2249 /* op1 = target JavaVM pc */
2251 var_to_reg_int(s1, src, REG_ITMP1);
2253 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2256 case ICMD_IFEQ: /* ..., value ==> ... */
2257 /* op1 = target JavaVM pc, val.i = constant */
2259 var_to_reg_int(s1, src, REG_ITMP1);
2260 if (iptr->val.i == 0) {
2264 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2265 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2268 ICONST(REG_ITMP2, iptr->val.i);
2269 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2271 M_BNEZ(REG_ITMP1, 0);
2273 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2276 case ICMD_IFLT: /* ..., value ==> ... */
2277 /* op1 = target JavaVM pc, val.i = constant */
2279 var_to_reg_int(s1, src, REG_ITMP1);
2280 if (iptr->val.i == 0) {
2284 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2285 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2288 ICONST(REG_ITMP2, iptr->val.i);
2289 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2291 M_BNEZ(REG_ITMP1, 0);
2293 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2296 case ICMD_IFLE: /* ..., value ==> ... */
2297 /* op1 = target JavaVM pc, val.i = constant */
2299 var_to_reg_int(s1, src, REG_ITMP1);
2300 if (iptr->val.i == 0) {
2304 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2305 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2308 ICONST(REG_ITMP2, iptr->val.i);
2309 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2311 M_BNEZ(REG_ITMP1, 0);
2313 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2316 case ICMD_IFNE: /* ..., value ==> ... */
2317 /* op1 = target JavaVM pc, val.i = constant */
2319 var_to_reg_int(s1, src, REG_ITMP1);
2320 if (iptr->val.i == 0) {
2324 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2325 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2328 ICONST(REG_ITMP2, iptr->val.i);
2329 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2331 M_BEQZ(REG_ITMP1, 0);
2333 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2336 case ICMD_IFGT: /* ..., value ==> ... */
2337 /* op1 = target JavaVM pc, val.i = constant */
2339 var_to_reg_int(s1, src, REG_ITMP1);
2340 if (iptr->val.i == 0) {
2344 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2345 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2348 ICONST(REG_ITMP2, iptr->val.i);
2349 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2351 M_BEQZ(REG_ITMP1, 0);
2353 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2356 case ICMD_IFGE: /* ..., value ==> ... */
2357 /* op1 = target JavaVM pc, val.i = constant */
2359 var_to_reg_int(s1, src, REG_ITMP1);
2360 if (iptr->val.i == 0) {
2364 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2365 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2368 ICONST(REG_ITMP2, iptr->val.i);
2369 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2371 M_BEQZ(REG_ITMP1, 0);
2373 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2376 case ICMD_IF_LEQ: /* ..., value ==> ... */
2377 /* op1 = target JavaVM pc, val.l = constant */
2379 var_to_reg_int(s1, src, REG_ITMP1);
2380 if (iptr->val.l == 0) {
2384 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2385 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2388 LCONST(REG_ITMP2, iptr->val.l);
2389 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2391 M_BNEZ(REG_ITMP1, 0);
2393 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2396 case ICMD_IF_LLT: /* ..., value ==> ... */
2397 /* op1 = target JavaVM pc, val.l = constant */
2399 var_to_reg_int(s1, src, REG_ITMP1);
2400 if (iptr->val.l == 0) {
2404 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2405 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2408 LCONST(REG_ITMP2, iptr->val.l);
2409 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2411 M_BNEZ(REG_ITMP1, 0);
2413 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2416 case ICMD_IF_LLE: /* ..., value ==> ... */
2417 /* op1 = target JavaVM pc, val.l = constant */
2419 var_to_reg_int(s1, src, REG_ITMP1);
2420 if (iptr->val.l == 0) {
2424 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2425 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2428 LCONST(REG_ITMP2, iptr->val.l);
2429 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2431 M_BNEZ(REG_ITMP1, 0);
2433 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2436 case ICMD_IF_LNE: /* ..., value ==> ... */
2437 /* op1 = target JavaVM pc, val.l = constant */
2439 var_to_reg_int(s1, src, REG_ITMP1);
2440 if (iptr->val.l == 0) {
2444 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2445 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2448 LCONST(REG_ITMP2, iptr->val.l);
2449 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2451 M_BEQZ(REG_ITMP1, 0);
2453 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2456 case ICMD_IF_LGT: /* ..., value ==> ... */
2457 /* op1 = target JavaVM pc, val.l = constant */
2459 var_to_reg_int(s1, src, REG_ITMP1);
2460 if (iptr->val.l == 0) {
2464 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2465 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2468 LCONST(REG_ITMP2, iptr->val.l);
2469 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2471 M_BEQZ(REG_ITMP1, 0);
2473 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2476 case ICMD_IF_LGE: /* ..., value ==> ... */
2477 /* op1 = target JavaVM pc, val.l = constant */
2479 var_to_reg_int(s1, src, REG_ITMP1);
2480 if (iptr->val.l == 0) {
2484 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2485 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2488 LCONST(REG_ITMP2, iptr->val.l);
2489 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2491 M_BEQZ(REG_ITMP1, 0);
2493 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2496 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2497 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2498 case ICMD_IF_ACMPEQ:
2500 var_to_reg_int(s1, src->prev, REG_ITMP1);
2501 var_to_reg_int(s2, src, REG_ITMP2);
2502 M_CMPEQ(s1, s2, REG_ITMP1);
2503 M_BNEZ(REG_ITMP1, 0);
2504 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2507 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2508 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2509 case ICMD_IF_ACMPNE:
2511 var_to_reg_int(s1, src->prev, REG_ITMP1);
2512 var_to_reg_int(s2, src, REG_ITMP2);
2513 M_CMPEQ(s1, s2, REG_ITMP1);
2514 M_BEQZ(REG_ITMP1, 0);
2515 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2518 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2519 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2521 var_to_reg_int(s1, src->prev, REG_ITMP1);
2522 var_to_reg_int(s2, src, REG_ITMP2);
2523 M_CMPLT(s1, s2, REG_ITMP1);
2524 M_BNEZ(REG_ITMP1, 0);
2525 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2528 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2529 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2531 var_to_reg_int(s1, src->prev, REG_ITMP1);
2532 var_to_reg_int(s2, src, REG_ITMP2);
2533 M_CMPLE(s1, s2, REG_ITMP1);
2534 M_BEQZ(REG_ITMP1, 0);
2535 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2538 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2539 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2541 var_to_reg_int(s1, src->prev, REG_ITMP1);
2542 var_to_reg_int(s2, src, REG_ITMP2);
2543 M_CMPLE(s1, s2, REG_ITMP1);
2544 M_BNEZ(REG_ITMP1, 0);
2545 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2548 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2549 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2551 var_to_reg_int(s1, src->prev, REG_ITMP1);
2552 var_to_reg_int(s2, src, REG_ITMP2);
2553 M_CMPLT(s1, s2, REG_ITMP1);
2554 M_BEQZ(REG_ITMP1, 0);
2555 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2558 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2560 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2563 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2564 /* val.i = constant */
2566 var_to_reg_int(s1, src, REG_ITMP1);
2567 d = reg_of_var(iptr->dst, REG_ITMP3);
2569 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2570 if ((a == 1) && (iptr[1].val.i == 0)) {
2571 M_CMPEQ(s1, REG_ZERO, d);
2572 store_reg_to_var_int(iptr->dst, d);
2575 if ((a == 0) && (iptr[1].val.i == 1)) {
2576 M_CMPEQ(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_CMOVEQ_IMM(s1, a, d);
2591 ICONST(REG_ITMP2, a);
2592 M_CMOVEQ(s1, REG_ITMP2, d);
2594 store_reg_to_var_int(iptr->dst, d);
2597 case ICMD_IFNE_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 == 0) && (iptr[1].val.i == 1)) {
2605 M_CMPEQ(s1, REG_ZERO, d);
2606 store_reg_to_var_int(iptr->dst, d);
2609 if ((a == 1) && (iptr[1].val.i == 0)) {
2610 M_CMPEQ(s1, REG_ZERO, d);
2612 store_reg_to_var_int(iptr->dst, d);
2616 M_MOV(s1, REG_ITMP1);
2619 ICONST(d, iptr[1].val.i);
2621 if ((a >= 0) && (a <= 255)) {
2622 M_CMOVNE_IMM(s1, a, d);
2625 ICONST(REG_ITMP2, a);
2626 M_CMOVNE(s1, REG_ITMP2, d);
2628 store_reg_to_var_int(iptr->dst, d);
2631 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2632 /* val.i = constant */
2634 var_to_reg_int(s1, src, REG_ITMP1);
2635 d = reg_of_var(iptr->dst, REG_ITMP3);
2637 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2638 if ((a == 1) && (iptr[1].val.i == 0)) {
2639 M_CMPLT(s1, REG_ZERO, d);
2640 store_reg_to_var_int(iptr->dst, d);
2643 if ((a == 0) && (iptr[1].val.i == 1)) {
2644 M_CMPLE(REG_ZERO, s1, d);
2645 store_reg_to_var_int(iptr->dst, d);
2649 M_MOV(s1, REG_ITMP1);
2652 ICONST(d, iptr[1].val.i);
2654 if ((a >= 0) && (a <= 255)) {
2655 M_CMOVLT_IMM(s1, a, d);
2658 ICONST(REG_ITMP2, a);
2659 M_CMOVLT(s1, REG_ITMP2, d);
2661 store_reg_to_var_int(iptr->dst, d);
2664 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2665 /* val.i = constant */
2667 var_to_reg_int(s1, src, REG_ITMP1);
2668 d = reg_of_var(iptr->dst, REG_ITMP3);
2670 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2671 if ((a == 1) && (iptr[1].val.i == 0)) {
2672 M_CMPLE(REG_ZERO, s1, d);
2673 store_reg_to_var_int(iptr->dst, d);
2676 if ((a == 0) && (iptr[1].val.i == 1)) {
2677 M_CMPLT(s1, REG_ZERO, d);
2678 store_reg_to_var_int(iptr->dst, d);
2682 M_MOV(s1, REG_ITMP1);
2685 ICONST(d, iptr[1].val.i);
2687 if ((a >= 0) && (a <= 255)) {
2688 M_CMOVGE_IMM(s1, a, d);
2691 ICONST(REG_ITMP2, a);
2692 M_CMOVGE(s1, REG_ITMP2, d);
2694 store_reg_to_var_int(iptr->dst, d);
2697 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2698 /* val.i = constant */
2700 var_to_reg_int(s1, src, REG_ITMP1);
2701 d = reg_of_var(iptr->dst, REG_ITMP3);
2703 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2704 if ((a == 1) && (iptr[1].val.i == 0)) {
2705 M_CMPLT(REG_ZERO, s1, d);
2706 store_reg_to_var_int(iptr->dst, d);
2709 if ((a == 0) && (iptr[1].val.i == 1)) {
2710 M_CMPLE(s1, REG_ZERO, d);
2711 store_reg_to_var_int(iptr->dst, d);
2715 M_MOV(s1, REG_ITMP1);
2718 ICONST(d, iptr[1].val.i);
2720 if ((a >= 0) && (a <= 255)) {
2721 M_CMOVGT_IMM(s1, a, d);
2724 ICONST(REG_ITMP2, a);
2725 M_CMOVGT(s1, REG_ITMP2, d);
2727 store_reg_to_var_int(iptr->dst, d);
2730 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2731 /* val.i = constant */
2733 var_to_reg_int(s1, src, REG_ITMP1);
2734 d = reg_of_var(iptr->dst, REG_ITMP3);
2736 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2737 if ((a == 1) && (iptr[1].val.i == 0)) {
2738 M_CMPLE(s1, REG_ZERO, d);
2739 store_reg_to_var_int(iptr->dst, d);
2742 if ((a == 0) && (iptr[1].val.i == 1)) {
2743 M_CMPLT(REG_ZERO, s1, d);
2744 store_reg_to_var_int(iptr->dst, d);
2748 M_MOV(s1, REG_ITMP1);
2751 ICONST(d, iptr[1].val.i);
2753 if ((a >= 0) && (a <= 255)) {
2754 M_CMOVLE_IMM(s1, a, d);
2757 ICONST(REG_ITMP2, a);
2758 M_CMOVLE(s1, REG_ITMP2, d);
2760 store_reg_to_var_int(iptr->dst, d);
2764 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2769 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2770 a = dseg_addaddress ((void*) (builtin_monitorexit));
2771 M_ALD(REG_PV, REG_PV, a);
2772 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
2773 M_JSR(REG_RA, REG_PV);
2774 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2777 var_to_reg_int(s1, src, REG_RESULT);
2778 M_INTMOVE(s1, REG_RESULT);
2779 goto nowperformreturn;
2781 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2785 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2786 a = dseg_addaddress ((void*) (builtin_monitorexit));
2787 M_ALD(REG_PV, REG_PV, a);
2788 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
2789 M_JSR(REG_RA, REG_PV);
2790 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2793 var_to_reg_flt(s1, src, REG_FRESULT);
2794 M_FLTMOVE(s1, REG_FRESULT);
2795 goto nowperformreturn;
2797 case ICMD_RETURN: /* ... ==> ... */
2800 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2801 a = dseg_addaddress ((void*) (builtin_monitorexit));
2802 M_ALD(REG_PV, REG_PV, a);
2803 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
2804 M_JSR(REG_RA, REG_PV);
2805 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2813 p = parentargs_base;
2815 /* restore return address */
2818 {p--; M_LLD (REG_RA, REG_SP, 8 * p);}
2820 /* restore saved registers */
2822 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
2823 {p--; M_LLD(savintregs[r], REG_SP, 8 * p);}
2824 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
2825 {p--; M_DLD(savfltregs[r], REG_SP, 8 * p);}
2827 /* deallocate stack */
2829 if (parentargs_base)
2830 {M_LDA(REG_SP, REG_SP, parentargs_base*8);}
2832 /* call trace function */
2835 M_LDA (REG_SP, REG_SP, -24);
2836 M_AST(REG_RA, REG_SP, 0);
2837 M_LST(REG_RESULT, REG_SP, 8);
2838 M_DST(REG_FRESULT, REG_SP,16);
2839 a = dseg_addaddress (method);
2840 M_ALD(argintregs[0], REG_PV, a);
2841 M_MOV(REG_RESULT, argintregs[1]);
2842 M_FLTMOVE(REG_FRESULT, argfltregs[2]);
2843 a = dseg_addaddress ((void*) (builtin_displaymethodstop));
2844 M_ALD(REG_PV, REG_PV, a);
2845 M_JSR (REG_RA, REG_PV);
2846 s1 = (int)((u1*) mcodeptr - mcodebase);
2847 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
2850 while (ml<-32768) { ml+=65536; mh--; }
2851 M_LDA (REG_PV, REG_RA, ml );
2852 M_LDAH (REG_PV, REG_PV, mh );
2854 M_DLD(REG_FRESULT, REG_SP,16);
2855 M_LLD(REG_RESULT, REG_SP, 8);
2856 M_ALD(REG_RA, REG_SP, 0);
2857 M_LDA (REG_SP, REG_SP, 24);
2866 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2870 s4ptr = iptr->val.a;
2871 l = s4ptr[1]; /* low */
2872 i = s4ptr[2]; /* high */
2874 var_to_reg_int(s1, src, REG_ITMP1);
2876 {M_INTMOVE(s1, REG_ITMP1);}
2878 M_LDA(REG_ITMP1, s1, -l);
2884 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
2886 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
2887 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
2889 M_BEQZ(REG_ITMP2, 0);
2890 mcode_addreference(BlockPtrOfPC(s4ptr[0]), mcodeptr);
2892 /* build jump table top down and use address of lowest entry */
2896 dseg_addtarget(BlockPtrOfPC(*--s4ptr));
2900 /* length of dataseg after last dseg_addtarget is used by load */
2902 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
2903 M_ALD(REG_ITMP2, REG_ITMP2, -dseglen);
2909 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2911 s4 i, l, val, *s4ptr;
2913 s4ptr = iptr->val.a;
2914 l = s4ptr[0]; /* default */
2915 i = s4ptr[1]; /* count */
2917 MCODECHECK((i<<2)+8);
2918 var_to_reg_int(s1, src, REG_ITMP1);
2922 if ((val >= 0) && (val <= 255)) {
2923 M_CMPEQ_IMM(s1, val, REG_ITMP2);
2926 if ((val >= -32768) && (val <= 32767)) {
2927 M_LDA(REG_ITMP2, REG_ZERO, val);
2930 a = dseg_adds4 (val);
2931 M_ILD(REG_ITMP2, REG_PV, a);
2933 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
2935 M_BNEZ(REG_ITMP2, 0);
2936 mcode_addreference(BlockPtrOfPC(s4ptr[1]), mcodeptr);
2940 mcode_addreference(BlockPtrOfPC(l), mcodeptr);
2946 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
2947 /* op1 = return type, val.a = function pointer*/
2951 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
2952 /* op1 = return type, val.a = function pointer*/
2956 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
2957 /* op1 = return type, val.a = function pointer*/
2961 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2962 /* op1 = arg count, val.a = method pointer */
2964 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2965 /* op1 = arg count, val.a = method pointer */
2967 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2968 /* op1 = arg count, val.a = method pointer */
2970 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
2971 /* op1 = arg count, val.a = method pointer */
2979 MCODECHECK((s3 << 1) + 64);
2981 /* copy arguments to registers or stack location */
2983 for (; --s3 >= 0; src = src->prev) {
2984 if (src->varkind == ARGVAR)
2986 if (IS_INT_LNG_TYPE(src->type)) {
2987 if (s3 < INT_ARG_CNT) {
2988 s1 = argintregs[s3];
2989 var_to_reg_int(d, src, s1);
2993 var_to_reg_int(d, src, REG_ITMP1);
2994 M_LST(d, REG_SP, 8 * (s3 - INT_ARG_CNT));
2998 if (s3 < FLT_ARG_CNT) {
2999 s1 = argfltregs[s3];
3000 var_to_reg_flt(d, src, s1);
3004 var_to_reg_flt(d, src, REG_FTMP1);
3005 M_DST(d, REG_SP, 8 * (s3 - FLT_ARG_CNT));
3010 switch (iptr->opc) {
3014 a = dseg_addaddress ((void*) (m));
3016 M_ALD(REG_PV, REG_PV, a); /* Pointer to built-in-function */
3018 goto makeactualcall;
3020 case ICMD_INVOKESTATIC:
3021 case ICMD_INVOKESPECIAL:
3022 a = dseg_addaddress (m->stubroutine);
3024 M_ALD(REG_PV, REG_PV, a ); /* method pointer in r27 */
3027 goto makeactualcall;
3029 case ICMD_INVOKEVIRTUAL:
3031 gen_nullptr_check(argintregs[0]);
3032 M_ALD(REG_METHODPTR, argintregs[0],
3033 OFFSET(java_objectheader, vftbl));
3034 M_ALD(REG_PV, REG_METHODPTR, OFFSET(vftbl, table[0]) +
3035 sizeof(methodptr) * m->vftblindex);
3038 goto makeactualcall;
3040 case ICMD_INVOKEINTERFACE:
3043 gen_nullptr_check(argintregs[0]);
3044 M_ALD(REG_METHODPTR, argintregs[0],
3045 OFFSET(java_objectheader, vftbl));
3046 M_ALD(REG_METHODPTR, REG_METHODPTR,
3047 OFFSET(vftbl, interfacetable[0]) -
3048 sizeof(methodptr*) * ci->index);
3049 M_ALD(REG_PV, REG_METHODPTR,
3050 sizeof(methodptr) * (m - ci->methods));
3053 goto makeactualcall;
3057 sprintf (logtext, "Unkown ICMD-Command: %d", iptr->opc);
3063 M_JSR (REG_RA, REG_PV);
3067 s1 = (int)((u1*) mcodeptr - mcodebase);
3068 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
3071 while (ml<-32768) { ml+=65536; mh--; }
3072 M_LDA (REG_PV, REG_RA, ml );
3073 M_LDAH (REG_PV, REG_PV, mh );
3076 /* d contains return type */
3078 if (d != TYPE_VOID) {
3079 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3080 s1 = reg_of_var(iptr->dst, REG_RESULT);
3081 M_INTMOVE(REG_RESULT, s1);
3082 store_reg_to_var_int(iptr->dst, s1);
3085 s1 = reg_of_var(iptr->dst, REG_FRESULT);
3086 M_FLTMOVE(REG_FRESULT, s1);
3087 store_reg_to_var_flt(iptr->dst, s1);
3094 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3096 /* op1: 0 == array, 1 == class */
3097 /* val.a: (classinfo*) superclass */
3099 /* superclass is an interface:
3101 * return (sub != NULL) &&
3102 * (sub->vftbl->interfacetablelength > super->index) &&
3103 * (sub->vftbl->interfacetable[-super->index] != NULL);
3105 * superclass is a class:
3107 * return ((sub != NULL) && (0
3108 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3109 * super->vftbl->diffvall));
3113 classinfo *super = (classinfo*) iptr->val.a;
3115 var_to_reg_int(s1, src, REG_ITMP1);
3116 d = reg_of_var(iptr->dst, REG_ITMP3);
3118 M_MOV(s1, REG_ITMP1);
3122 if (iptr->op1) { /* class/interface */
3123 if (super->flags & ACC_INTERFACE) { /* interface */
3125 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3126 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3127 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3128 M_BLEZ(REG_ITMP2, 2);
3129 M_ALD(REG_ITMP1, REG_ITMP1,
3130 OFFSET(vftbl, interfacetable[0]) -
3131 super->index * sizeof(methodptr*));
3132 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3135 s2 = super->vftbl->diffval;
3136 M_BEQZ(s1, 4 + (s2 > 255));
3137 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3138 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3139 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3141 M_CMPULE_IMM(REG_ITMP1, s2, d);
3143 M_LDA(REG_ITMP2, REG_ZERO, s2);
3144 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3149 panic ("internal error: no inlined array instanceof");
3151 store_reg_to_var_int(iptr->dst, d);
3154 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3156 /* op1: 0 == array, 1 == class */
3157 /* val.a: (classinfo*) superclass */
3159 /* superclass is an interface:
3161 * OK if ((sub == NULL) ||
3162 * (sub->vftbl->interfacetablelength > super->index) &&
3163 * (sub->vftbl->interfacetable[-super->index] != NULL));
3165 * superclass is a class:
3167 * OK if ((sub == NULL) || (0
3168 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3169 * super->vftbl->diffvall));
3173 classinfo *super = (classinfo*) iptr->val.a;
3175 d = reg_of_var(iptr->dst, REG_ITMP3);
3176 var_to_reg_int(s1, src, d);
3177 if (iptr->op1) { /* class/interface */
3178 if (super->flags & ACC_INTERFACE) { /* interface */
3180 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3181 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3182 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3183 M_BLEZ(REG_ITMP2, 0);
3184 mcode_addxcastrefs(mcodeptr);
3185 M_ALD(REG_ITMP2, REG_ITMP1,
3186 OFFSET(vftbl, interfacetable[0]) -
3187 super->index * sizeof(methodptr*));
3188 M_BEQZ(REG_ITMP2, 0);
3189 mcode_addxcastrefs(mcodeptr);
3192 s2 = super->vftbl->diffval;
3193 M_BEQZ(s1, 4 + (s2 != 0) + (s2 > 255));
3194 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3195 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3196 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3198 M_BNEZ(REG_ITMP1, 0);
3200 else if (s2 <= 255) {
3201 M_CMPULE_IMM(REG_ITMP1, s2, REG_ITMP2);
3202 M_BEQZ(REG_ITMP2, 0);
3205 M_LDA(REG_ITMP2, REG_ZERO, s2);
3206 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3207 M_BEQZ(REG_ITMP2, 0);
3209 mcode_addxcastrefs(mcodeptr);
3213 panic ("internal error: no inlined array checkcast");
3216 store_reg_to_var_int(iptr->dst, d);
3219 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
3221 var_to_reg_int(s1, src, REG_ITMP1);
3223 mcode_addxcheckarefs(mcodeptr);
3226 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3227 /* op1 = dimension, val.a = array descriptor */
3229 /* check for negative sizes and copy sizes to stack if necessary */
3231 MCODECHECK((iptr->op1 << 1) + 64);
3233 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3234 var_to_reg_int(s2, src, REG_ITMP1);
3236 mcode_addxcheckarefs(mcodeptr);
3238 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
3240 if (src->varkind != ARGVAR) {
3241 M_LST(s2, REG_SP, 8 * (s1 + INT_ARG_CNT));
3245 /* a0 = dimension count */
3247 M_LDA(argintregs[0], REG_ZERO, iptr->op1);
3249 /* a1 = arraydescriptor */
3251 a = dseg_addaddress(iptr->val.a);
3252 M_ALD(argintregs[1], REG_PV, a);
3254 /* a2 = pointer to dimensions = stack pointer */
3256 M_INTMOVE(REG_SP, argintregs[2]);
3258 a = dseg_addaddress((void*) (builtin_nmultianewarray));
3259 M_ALD(REG_PV, REG_PV, a);
3260 M_JSR(REG_RA, REG_PV);
3261 s1 = (int)((u1*) mcodeptr - mcodebase);
3263 M_LDA (REG_PV, REG_RA, -s1);
3265 s4 ml = -s1, mh = 0;
3266 while (ml < -32768) {ml += 65536; mh--;}
3267 M_LDA(REG_PV, REG_RA, ml);
3268 M_LDAH(REG_PV, REG_PV, mh);
3270 s1 = reg_of_var(iptr->dst, REG_RESULT);
3271 M_INTMOVE(REG_RESULT, s1);
3272 store_reg_to_var_int(iptr->dst, s1);
3276 default: sprintf (logtext, "Unknown pseudo command: %d", iptr->opc);
3279 } /* for instruction */
3281 /* copy values to interface registers */
3283 src = bptr->outstack;
3284 len = bptr->outdepth;
3288 if ((src->varkind != STACKVAR)) {
3290 if (IS_FLT_DBL_TYPE(s2)) {
3291 var_to_reg_flt(s1, src, REG_FTMP1);
3292 if (!(interfaces[len][s2].flags & INMEMORY)) {
3293 M_FLTMOVE(s1,interfaces[len][s2].regoff);
3296 M_DST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3300 var_to_reg_int(s1, src, REG_ITMP1);
3301 if (!(interfaces[len][s2].flags & INMEMORY)) {
3302 M_INTMOVE(s1,interfaces[len][s2].regoff);
3305 M_LST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3311 } /* if (bptr -> flags >= BBREACHED) */
3312 } /* for basic block */
3314 bptr -> mpc = (int)((u1*) mcodeptr - mcodebase);
3317 /* generate bound check stubs */
3319 s4 *xcodeptr = NULL;
3321 for (; xboundrefs != NULL; xboundrefs = xboundrefs->next) {
3322 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3323 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
3324 xboundrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3328 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
3329 xboundrefs->branchpos, (u1*) mcodeptr - mcodebase);
3333 M_LDA(REG_ITMP2_XPC, REG_PV, xboundrefs->branchpos);
3335 if (xcodeptr != NULL) {
3336 M_BR((xcodeptr-mcodeptr)-1);
3339 xcodeptr = mcodeptr;
3341 a = dseg_addaddress(proto_java_lang_ArrayIndexOutOfBoundsException);
3342 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3344 a = dseg_addaddress(asm_handle_exception);
3345 M_ALD(REG_ITMP3, REG_PV, a);
3351 /* generate negative array size check stubs */
3355 for (; xcheckarefs != NULL; xcheckarefs = xcheckarefs->next) {
3356 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3357 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3358 xcheckarefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3362 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3363 xcheckarefs->branchpos, (u1*) mcodeptr - mcodebase);
3367 M_LDA(REG_ITMP2_XPC, REG_PV, xcheckarefs->branchpos);
3369 if (xcodeptr != NULL) {
3370 M_BR((xcodeptr-mcodeptr)-1);
3373 xcodeptr = mcodeptr;
3375 a = dseg_addaddress(proto_java_lang_NegativeArraySizeException);
3376 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3378 a = dseg_addaddress(asm_handle_exception);
3379 M_ALD(REG_ITMP3, REG_PV, a);
3385 /* generate cast check stubs */
3389 for (; xcastrefs != NULL; xcastrefs = xcastrefs->next) {
3390 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3391 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3392 xcastrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3396 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3397 xcastrefs->branchpos, (u1*) mcodeptr - mcodebase);
3401 M_LDA(REG_ITMP2_XPC, REG_PV, xcastrefs->branchpos);
3403 if (xcodeptr != NULL) {
3404 M_BR((xcodeptr-mcodeptr)-1);
3407 xcodeptr = mcodeptr;
3409 a = dseg_addaddress(proto_java_lang_ClassCastException);
3410 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3412 a = dseg_addaddress(asm_handle_exception);
3413 M_ALD(REG_ITMP3, REG_PV, a);
3420 #ifdef SOFTNULLPTRCHECK
3422 /* generate null pointer check stubs */
3426 for (; xnullrefs != NULL; xnullrefs = xnullrefs->next) {
3427 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3428 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3429 xnullrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3433 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3434 xnullrefs->branchpos, (u1*) mcodeptr - mcodebase);
3438 M_LDA(REG_ITMP2_XPC, REG_PV, xnullrefs->branchpos - 4);
3440 if (xcodeptr != NULL) {
3441 M_BR((xcodeptr-mcodeptr)-1);
3444 xcodeptr = mcodeptr;
3446 a = dseg_addaddress(proto_java_lang_NullPointerException);
3447 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3449 a = dseg_addaddress(asm_handle_exception);
3450 M_ALD(REG_ITMP3, REG_PV, a);
3459 mcode_finish((int)((u1*) mcodeptr - mcodebase));
3463 /* redefinition of code generation macros (compiling into array) **************/
3466 These macros are newly defined to allow code generation into an array.
3467 This is necessary, because the original M_.. macros generate code by
3468 calling 'mcode_adds4' that uses an additional data structure to
3471 For a faster (but less flexible) version to generate code, these
3472 macros directly use the (s4* p) - pointer to put the code directly
3473 in a locally defined array.
3474 This makes sense only for the stub-generation-routines below.
3478 #define M_OP3(op,fu,a,b,c,const) \
3479 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<(16-3*(const)))| \
3480 ((const)<<12)|((fu)<<5)|((c)) )
3482 #define M_FOP3(op,fu,a,b,c) \
3483 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<16)|((fu)<<5)|(c) )
3485 #define M_BRA(op,a,disp) \
3486 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((disp)&0x1fffff) )
3488 #define M_MEM(op,a,b,disp) \
3489 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<16)|((disp)&0xffff) )
3492 /* function createcompilerstub *************************************************
3494 creates a stub routine which calls the compiler
3496 *******************************************************************************/
3498 #define COMPSTUBSIZE 3
3500 u1 *createcompilerstub (methodinfo *m)
3502 u8 *s = CNEW (u8, COMPSTUBSIZE); /* memory to hold the stub */
3503 s4 *p = (s4*) s; /* code generation pointer */
3505 /* code for the stub */
3506 M_ALD (REG_PV, REG_PV, 16); /* load pointer to the compiler */
3507 M_JSR (0, REG_PV); /* jump to the compiler, return address
3508 in reg 0 is used as method pointer */
3509 s[1] = (u8) m; /* literals to be adressed */
3510 s[2] = (u8) asm_call_jit_compiler; /* jump directly via PV from above */
3513 count_cstub_len += COMPSTUBSIZE * 8;
3520 /* function removecompilerstub *************************************************
3522 deletes a compilerstub from memory (simply by freeing it)
3524 *******************************************************************************/
3526 void removecompilerstub (u1 *stub)
3528 CFREE (stub, COMPSTUBSIZE * 8);
3532 /* function: createnativestub **************************************************
3534 creates a stub routine which calls a native method
3536 *******************************************************************************/
3538 #define NATIVESTUBSIZE 11
3540 u1 *createnativestub (functionptr f, methodinfo *m)
3542 u8 *s = CNEW (u8, NATIVESTUBSIZE); /* memory to hold the stub */
3543 s4 *p = (s4*) s; /* code generation pointer */
3545 M_LDA (REG_SP, REG_SP, -8); /* build up stackframe */
3546 M_AST (REG_RA, REG_SP, 0); /* store return address */
3548 M_ALD (REG_PV, REG_PV, 8*8); /* load adress of native method */
3549 M_JSR (REG_RA, REG_PV); /* call native method */
3551 M_LDA (REG_PV, REG_RA, -4*4); /* recompute pv from ra */
3552 M_ALD (REG_ITMP3, REG_PV, 9*8); /* get address of exceptionptr */
3554 M_ALD (REG_RA, REG_SP, 0); /* load return address */
3555 M_ALD (REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
3557 M_LDA (REG_SP, REG_SP, 8); /* remove stackframe */
3558 M_BNEZ (REG_ITMP1, 1); /* if no exception then return */
3560 M_RET (REG_RA); /* return to caller */
3562 M_AST (REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
3563 M_LDA (REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
3565 M_ALD (REG_ITMP3, REG_PV,10*8); /* load asm exception handler address */
3566 M_JMP (REG_ITMP3); /* jump to asm exception handler */
3569 s[8] = (u8) f; /* address of native method */
3570 s[9] = (u8) (&exceptionptr); /* address of exceptionptr */
3571 s[10]= (u8) (asm_handle_nat_exception); /* addr of asm exception handler */
3574 count_nstub_len += NATIVESTUBSIZE * 8;
3581 /* function: removenativestub **************************************************
3583 removes a previously created native-stub from memory
3585 *******************************************************************************/
3587 void removenativestub (u1 *stub)
3589 CFREE (stub, NATIVESTUBSIZE * 8);
3594 * These are local overrides for various environment variables in Emacs.
3595 * Please do not remove this and leave it at the end of the file, where
3596 * Emacs will automagically detect them.
3597 * ---------------------------------------------------------------------
3600 * indent-tabs-mode: t