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: 1998/08/10
16 *******************************************************************************/
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]
51 #define COUNT_SPILLS count_spills++
57 /* gen_nullptr_check(objreg) */
59 #ifdef SOFTNULLPTRCHECK
60 #define gen_nullptr_check(objreg) \
62 M_BEQZ((objreg), REG);\
63 mcode_addxnullrefs(mcodeptr);\
66 #define gen_nullptr_check(objreg)
70 /* MCODECHECK(icnt) */
72 #define MCODECHECK(icnt) \
73 if((mcodeptr+(icnt))>mcodeend)mcodeptr=mcode_increase((u1*)mcodeptr)
76 generates an integer-move from register a to b.
77 if a and b are the same int-register, no code will be generated.
80 #define M_INTMOVE(a,b) if(a!=b){M_MOV(a,b);}
84 generates a floating-point-move from register a to b.
85 if a and b are the same float-register, no code will be generated
88 #define M_FLTMOVE(a,b) if(a!=b){M_FMOV(a,b);}
92 this function generates code to fetch data from a pseudo-register
94 If the pseudo-register has actually been assigned to a real
95 register, no code will be emitted, since following operations
96 can use this register directly.
98 v: pseudoregister to be fetched from
99 tempregnum: temporary register to be used if v is actually spilled to ram
101 return: the register number, where the operand can be found after
102 fetching (this wil be either tempregnum or the register
103 number allready given to v)
106 #define var_to_reg_int(regnr,v,tempnr) { \
107 if ((v)->flags & INMEMORY) \
108 {COUNT_SPILLS;M_LLD(tempnr,REG_SP,8*(v)->regoff);regnr=tempnr;} \
109 else regnr=(v)->regoff; \
113 #define var_to_reg_flt(regnr,v,tempnr) { \
114 if ((v)->flags & INMEMORY) \
115 {COUNT_SPILLS;M_DLD(tempnr,REG_SP,8*(v)->regoff);regnr=tempnr;} \
116 else regnr=(v)->regoff; \
121 This function determines a register, to which the result of an operation
122 should go, when it is ultimatively intended to store the result in
124 If v is assigned to an actual register, this register will be returned.
125 Otherwise (when v is spilled) this function returns tempregnum.
126 If not already done, regoff and flags are set in the stack location.
129 static int reg_of_var(stackptr v, int tempregnum)
133 switch (v->varkind) {
135 if (!(v->flags & INMEMORY))
139 var = &(interfaces[v->varnum][v->type]);
140 v->regoff = var->regoff;
141 if (!(var->flags & INMEMORY))
145 var = &(locals[v->varnum][v->type]);
146 v->regoff = var->regoff;
147 if (!(var->flags & INMEMORY))
151 v->regoff = v->varnum;
152 if (IS_FLT_DBL_TYPE(v->type)) {
153 if (v->varnum < fltreg_argnum) {
154 v->regoff = argfltregs[v->varnum];
155 return(argfltregs[v->varnum]);
159 if (v->varnum < intreg_argnum) {
160 v->regoff = argintregs[v->varnum];
161 return(argintregs[v->varnum]);
163 v->regoff -= intreg_argnum;
166 v->flags |= INMEMORY;
171 /* store_reg_to_var_xxx:
172 This function generates the code to store the result of an operation
173 back into a spilled pseudo-variable.
174 If the pseudo-variable has not been spilled in the first place, this
175 function will generate nothing.
177 v ............ Pseudovariable
178 tempregnum ... Number of the temporary registers as returned by
182 #define store_reg_to_var_int(sptr, tempregnum) { \
183 if ((sptr)->flags & INMEMORY) { \
185 M_LST(tempregnum, REG_SP, 8 * (sptr)->regoff); \
189 #define store_reg_to_var_flt(sptr, tempregnum) { \
190 if ((sptr)->flags & INMEMORY) { \
192 M_DST(tempregnum, REG_SP, 8 * (sptr)->regoff); \
197 /* NullPointerException handlers and exception handling initialisation */
199 /* asm_signal_exception passes exception pointer and the signal context
200 structure (contains the saved registers) to the assembler handler which
201 restores registers and walks through the Java exception tables.
204 void asm_signal_exception(void *xptr, void *sigctx);
207 /* NullPointerException signal handler for hardware null pointer check */
209 void catch_NullPointerException(int sig, int code, void *sigctx)
213 /* Reset signal handler - necessary for SysV, does no harm for BSD */
215 signal(sig, (void*) catch_NullPointerException); /* reinstall handler */
217 sigaddset(&nsig, sig);
218 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
219 asm_signal_exception(proto_java_lang_NullPointerException, sigctx);
225 void init_exceptions(void)
230 /* Linux on Digital Alpha needs an initialisation of the ieee floating point
231 control for IEEE compliant arithmetic (option -mieee of GCC). Under
232 Digital Unix this is done automatically.
237 extern unsigned long ieee_get_fp_control();
238 extern void ieee_set_fp_control(unsigned long fp_control);
240 void init_exceptions(void)
242 /* initialize floating point control */
244 ieee_set_fp_control(ieee_get_fp_control()
245 & ~IEEE_TRAP_ENABLE_INV
246 & ~IEEE_TRAP_ENABLE_DZE
247 /* & ~IEEE_TRAP_ENABLE_UNF we dont want underflow */
248 & ~IEEE_TRAP_ENABLE_OVF);
251 /* install signal handlers we need to convert to exceptions */
256 signal(SIGSEGV, (void*) catch_NullPointerException);
260 signal(SIGBUS, (void*) catch_NullPointerException);
266 /* function gen_mcode **********************************************************
268 generates machine code
270 *******************************************************************************/
272 #define MethodPointer -8
273 #define FrameSize -12
278 #define ExTableSize -32
279 #define ExTableStart -32
281 #define ExEntrySize -32
284 #define ExHandlerPC -24
285 #define ExCatchType -32
287 static void gen_mcode()
289 int len, s1, s2, s3, d, bbs;
300 savedregs_num = (isleafmethod) ? 0 : 1; /* space to save the RA */
302 /* space to save used callee saved registers */
304 savedregs_num += (savintregcnt - maxsavintreguse);
305 savedregs_num += (savfltregcnt - maxsavfltreguse);
307 parentargs_base = maxmemuse + savedregs_num;
309 #ifdef USE_THREADS /* space to save argument of monitor_enter */
311 if (checksync && (method->flags & ACC_SYNCHRONIZED))
316 /* create method header */
318 (void) dseg_addaddress(method); /* MethodPointer */
319 (void) dseg_adds4(parentargs_base * 8); /* FrameSize */
323 /* IsSync contains the offset relative to the stack pointer for the
324 argument of monitor_exit used in the exception handler. Since the
325 offset could be zero and give a wrong meaning of the flag it is
329 if (checksync && (method->flags & ACC_SYNCHRONIZED))
330 (void) dseg_adds4((maxmemuse + 1) * 8); /* IsSync */
335 (void) dseg_adds4(0); /* IsSync */
337 (void) dseg_adds4(isleafmethod); /* IsLeaf */
338 (void) dseg_adds4(savintregcnt - maxsavintreguse); /* IntSave */
339 (void) dseg_adds4(savfltregcnt - maxsavfltreguse); /* FltSave */
340 (void) dseg_adds4(exceptiontablelength); /* ExTableSize */
342 /* create exception table */
344 for (len = 0; len < exceptiontablelength; len++) {
345 dseg_addtarget(BlockPtrOfPC(extable[len].startpc));
346 dseg_addtarget(BlockPtrOfPC(extable[len].endpc));
347 dseg_addtarget(BlockPtrOfPC(extable[len].handlerpc));
348 (void) dseg_addaddress(extable[len].catchtype);
351 /* initialize mcode variables */
353 mcodeptr = (s4*) mcodebase;
354 mcodeend = (s4*) (mcodebase + mcodesize);
355 MCODECHECK(128 + mparamcount);
357 /* create stack frame (if necessary) */
360 {M_LDA (REG_SP, REG_SP, -parentargs_base * 8);}
362 /* save return address and used callee saved registers */
366 {p--; M_AST (REG_RA, REG_SP, 8*p);}
367 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
368 {p--; M_LST (savintregs[r], REG_SP, 8 * p);}
369 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
370 {p--; M_DST (savfltregs[r], REG_SP, 8 * p);}
372 /* save monitorenter argument */
375 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
376 if (method->flags & ACC_STATIC) {
377 p = dseg_addaddress (class);
378 M_ALD(REG_ITMP1, REG_PV, p);
379 M_AST(REG_ITMP1, REG_SP, 8 * maxmemuse);
382 M_AST (argintregs[0], REG_SP, 8 * maxmemuse);
387 /* copy argument registers to stack and call trace function with pointer
388 to arguments on stack. ToDo: save floating point registers !!!!!!!!!
391 if (runverbose && isleafmethod) {
392 M_LDA (REG_SP, REG_SP, -(8*8));
393 M_AST(REG_RA, REG_SP, 1*8);
394 M_LST(argintregs[0], REG_SP, 2*8);
395 M_LST(argintregs[1], REG_SP, 3*8);
396 M_LST(argintregs[2], REG_SP, 4*8);
397 M_LST(argintregs[3], REG_SP, 5*8);
398 M_LST(argintregs[4], REG_SP, 6*8);
399 M_LST(argintregs[5], REG_SP, 7*8);
400 p = dseg_addaddress (method);
401 M_ALD(REG_ITMP1, REG_PV, p);
402 M_AST(REG_ITMP1, REG_SP, REG);
403 p = dseg_addaddress ((void*) (builtin_trace_args));
404 M_ALD(REG_PV, REG_PV, p);
405 M_JSR(REG_RA, REG_PV);
406 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
407 M_ALD(REG_RA, REG_SP, 1*8);
408 M_LLD(argintregs[0], REG_SP, 2*8);
409 M_LLD(argintregs[1], REG_SP, 3*8);
410 M_LLD(argintregs[2], REG_SP, 4*8);
411 M_LLD(argintregs[3], REG_SP, 5*8);
412 M_LLD(argintregs[4], REG_SP, 6*8);
413 M_LLD(argintregs[5], REG_SP, 7*8);
414 M_LDA (REG_SP, REG_SP, 8*8);
417 /* take arguments out of register or stack frame */
419 for (p = 0, l = 0; p < mparamcount; p++) {
421 var = &(locals[l][t]);
423 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
428 if (IS_INT_LNG_TYPE(t)) { /* integer args */
429 if (p < INT_ARG_CNT) { /* register arguments */
430 if (!(var->flags & INMEMORY)) /* reg arg -> register */
431 {M_INTMOVE (argintregs[p], r);}
432 else /* reg arg -> spilled */
433 M_LST (argintregs[p], REG_SP, 8 * r);
435 else { /* stack arguments */
436 pa = p - INT_ARG_CNT;
437 if (!(var->flags & INMEMORY)) /* stack arg -> register */
438 M_LLD (r, REG_SP, 8 * (parentargs_base + pa));
439 else { /* stack arg -> spilled */
440 M_LLD (REG_ITMP1, REG_SP, 8 * (parentargs_base + pa));
441 M_LST (REG_ITMP1, REG_SP, 8 * r);
445 else { /* floating args */
446 if (p < FLT_ARG_CNT) { /* register arguments */
447 if (!(var->flags & INMEMORY)) /* reg arg -> register */
448 {M_FLTMOVE (argfltregs[p], r);}
449 else /* reg arg -> spilled */
450 M_DST (argfltregs[p], REG_SP, 8 * r);
452 else { /* stack arguments */
453 pa = p - FLT_ARG_CNT;
454 if (!(var->flags & INMEMORY)) /* stack-arg -> register */
455 M_DLD (r, REG_SP, 8 * (parentargs_base + pa) );
456 else { /* stack-arg -> spilled */
457 M_DLD (REG_FTMP1, REG_SP, 8 * (parentargs_base + pa));
458 M_DST (REG_FTMP1, REG_SP, 8 * r);
464 /* call trace function */
466 if (runverbose && !isleafmethod) {
467 M_LDA (REG_SP, REG_SP, -8);
468 p = dseg_addaddress (method);
469 M_ALD(REG_ITMP1, REG_PV, p);
470 M_AST(REG_ITMP1, REG_SP, REG);
471 p = dseg_addaddress ((void*) (builtin_trace_args));
472 M_ALD(REG_PV, REG_PV, p);
473 M_JSR(REG_RA, REG_PV);
474 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
475 M_LDA(REG_SP, REG_SP, 8);
478 /* call monitorenter function */
481 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
482 p = dseg_addaddress ((void*) (builtin_monitorenter));
483 M_ALD(REG_PV, REG_PV, p);
484 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
485 M_JSR(REG_RA, REG_PV);
486 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
491 /* end of header generation */
493 /* walk through all basic blocks */
495 for (bbs = block_count, bptr = block; --bbs >= 0; bptr++) {
496 bptr -> mpc = (int)((u1*) mcodeptr - mcodebase);
498 if (bptr->flags >= BBREACHED) {
500 /* branch resolving */
504 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
505 gen_resolvebranch((u1*) mcodebase + brefs->branchpos,
506 brefs->branchpos, bptr->mpc);
510 /* copy interface registers to their destination */
515 while (src != NULL) {
517 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
518 d = reg_of_var(src, REG_ITMP1);
519 M_INTMOVE(REG_ITMP1, d);
520 store_reg_to_var_int(src, d);
523 d = reg_of_var(src, REG_IFTMP);
524 if ((src->varkind != STACKVAR)) {
526 if (IS_FLT_DBL_TYPE(s2)) {
527 if (!(interfaces[len][s2].flags & INMEMORY)) {
528 s1 = interfaces[len][s2].regoff;
532 M_DLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
534 store_reg_to_var_flt(src, d);
537 if (!(interfaces[len][s2].flags & INMEMORY)) {
538 s1 = interfaces[len][s2].regoff;
542 M_LLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
544 store_reg_to_var_int(src, d);
551 /* walk through all instructions */
555 for (iptr = bptr->iinstr;
557 src = iptr->dst, len--, iptr++) {
559 MCODECHECK(64); /* an instruction usually needs < 64 words */
562 case ICMD_NOP: /* ... ==> ... */
565 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
567 var_to_reg_int(s1, src, REG_ITMP1);
568 gen_nullptr_check(s1);
571 /* constant operations ************************************************/
573 #define ICONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
574 else{a=dseg_adds4(c);M_ILD(r,REG_PV,a);}
576 #define LCONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
577 else{a=dseg_adds8(c);M_LLD(r,REG_PV,a);}
579 case ICMD_ICONST: /* ... ==> ..., constant */
580 /* op1 = 0, val.i = constant */
582 d = reg_of_var(iptr->dst, REG_ITMP1);
583 ICONST(d, iptr->val.i);
584 store_reg_to_var_int(iptr->dst, d);
587 case ICMD_LCONST: /* ... ==> ..., constant */
588 /* op1 = 0, val.l = constant */
590 d = reg_of_var(iptr->dst, REG_ITMP1);
591 LCONST(d, iptr->val.l);
592 store_reg_to_var_int(iptr->dst, d);
595 case ICMD_FCONST: /* ... ==> ..., constant */
596 /* op1 = 0, val.f = constant */
598 d = reg_of_var (iptr->dst, REG_FTMP1);
599 a = dseg_addfloat (iptr->val.f);
601 store_reg_to_var_flt (iptr->dst, d);
604 case ICMD_DCONST: /* ... ==> ..., constant */
605 /* op1 = 0, val.d = constant */
607 d = reg_of_var (iptr->dst, REG_FTMP1);
608 a = dseg_adddouble (iptr->val.d);
610 store_reg_to_var_flt (iptr->dst, d);
613 case ICMD_ACONST: /* ... ==> ..., constant */
614 /* op1 = 0, val.a = constant */
616 d = reg_of_var(iptr->dst, REG_ITMP1);
618 a = dseg_addaddress (iptr->val.a);
622 M_INTMOVE(REG_ZERO, d);
624 store_reg_to_var_int(iptr->dst, d);
628 /* load/store operations **********************************************/
630 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
631 case ICMD_LLOAD: /* op1 = local variable */
634 d = reg_of_var(iptr->dst, REG_ITMP1);
635 if ((iptr->dst->varkind == LOCALVAR) &&
636 (iptr->dst->varnum == iptr->op1))
638 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
639 if (var->flags & INMEMORY)
640 M_LLD(d, REG_SP, 8 * var->regoff);
642 {M_INTMOVE(var->regoff,d);}
643 store_reg_to_var_int(iptr->dst, d);
646 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
647 case ICMD_DLOAD: /* op1 = local variable */
649 d = reg_of_var(iptr->dst, REG_FTMP1);
650 if ((iptr->dst->varkind == LOCALVAR) &&
651 (iptr->dst->varnum == iptr->op1))
653 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
654 if (var->flags & INMEMORY)
655 M_DLD(d, REG_SP, 8 * var->regoff);
657 {M_FLTMOVE(var->regoff,d);}
658 store_reg_to_var_flt(iptr->dst, d);
662 case ICMD_ISTORE: /* ..., value ==> ... */
663 case ICMD_LSTORE: /* op1 = local variable */
666 if ((src->varkind == LOCALVAR) &&
667 (src->varnum == iptr->op1))
669 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
670 if (var->flags & INMEMORY) {
671 var_to_reg_int(s1, src, REG_ITMP1);
672 M_LST(s1, REG_SP, 8 * var->regoff);
675 var_to_reg_int(s1, src, var->regoff);
676 M_INTMOVE(s1, var->regoff);
680 case ICMD_FSTORE: /* ..., value ==> ... */
681 case ICMD_DSTORE: /* op1 = local variable */
683 if ((src->varkind == LOCALVAR) &&
684 (src->varnum == iptr->op1))
686 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
687 if (var->flags & INMEMORY) {
688 var_to_reg_flt(s1, src, REG_FTMP1);
689 M_DST(s1, REG_SP, 8 * var->regoff);
692 var_to_reg_flt(s1, src, var->regoff);
693 M_FLTMOVE(s1, var->regoff);
698 /* pop/dup/swap operations ********************************************/
700 /* attention: double and longs are only one entry in CACAO ICMDs */
702 case ICMD_POP: /* ..., value ==> ... */
703 case ICMD_POP2: /* ..., value, value ==> ... */
706 #define M_COPY(from,to) \
707 d = reg_of_var(to, REG_IFTMP); \
708 if ((from->regoff != to->regoff) || \
709 ((from->flags ^ to->flags) & INMEMORY)) { \
710 if (IS_FLT_DBL_TYPE(from->type)) { \
711 var_to_reg_flt(s1, from, d); \
713 store_reg_to_var_flt(to, d); \
716 var_to_reg_int(s1, from, d); \
718 store_reg_to_var_int(to, d); \
722 case ICMD_DUP: /* ..., a ==> ..., a, a */
723 M_COPY(src, iptr->dst);
726 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
728 M_COPY(src, iptr->dst->prev->prev);
730 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
732 M_COPY(src, iptr->dst);
733 M_COPY(src->prev, iptr->dst->prev);
736 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
738 M_COPY(src->prev, iptr->dst->prev->prev->prev);
740 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
742 M_COPY(src, iptr->dst);
743 M_COPY(src->prev, iptr->dst->prev);
744 M_COPY(src->prev->prev, iptr->dst->prev->prev);
745 M_COPY(src, iptr->dst->prev->prev->prev);
748 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
750 M_COPY(src, iptr->dst);
751 M_COPY(src->prev, iptr->dst->prev);
752 M_COPY(src->prev->prev, iptr->dst->prev->prev);
753 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
754 M_COPY(src, iptr->dst->prev->prev->prev->prev);
755 M_COPY(src->prev, iptr->dst->prev->prev->prev->prev->prev);
758 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
760 M_COPY(src, iptr->dst->prev);
761 M_COPY(src->prev, iptr->dst);
765 /* integer operations *************************************************/
767 case ICMD_INEG: /* ..., value ==> ..., - value */
769 var_to_reg_int(s1, src, REG_ITMP1);
770 d = reg_of_var(iptr->dst, REG_ITMP3);
771 M_ISUB(REG_ZERO, s1, d, REG);
772 store_reg_to_var_int(iptr->dst, d);
775 case ICMD_LNEG: /* ..., value ==> ..., - value */
777 var_to_reg_int(s1, src, REG_ITMP1);
778 d = reg_of_var(iptr->dst, REG_ITMP3);
779 M_LSUB(REG_ZERO, s1, d, REG);
780 store_reg_to_var_int(iptr->dst, d);
783 case ICMD_I2L: /* ..., value ==> ..., value */
785 var_to_reg_int(s1, src, REG_ITMP1);
786 d = reg_of_var(iptr->dst, REG_ITMP3);
788 store_reg_to_var_int(iptr->dst, d);
791 case ICMD_L2I: /* ..., value ==> ..., value */
793 var_to_reg_int(s1, src, REG_ITMP1);
794 d = reg_of_var(iptr->dst, REG_ITMP3);
795 M_IADD(s1, REG_ZERO, d , REG);
796 store_reg_to_var_int(iptr->dst, d);
799 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
801 var_to_reg_int(s1, src, REG_ITMP1);
802 d = reg_of_var(iptr->dst, REG_ITMP3);
803 if (has_ext_instr_set) {
807 M_SLL(s1, 56, d, CONST);
808 M_SRA( d, 56, d, CONST);
810 store_reg_to_var_int(iptr->dst, d);
813 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
815 var_to_reg_int(s1, src, REG_ITMP1);
816 d = reg_of_var(iptr->dst, REG_ITMP3);
818 store_reg_to_var_int(iptr->dst, d);
821 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
823 var_to_reg_int(s1, src, REG_ITMP1);
824 d = reg_of_var(iptr->dst, REG_ITMP3);
825 if (has_ext_instr_set) {
829 M_SLL(s1, 48, d, CONST);
830 M_SRA( d, 48, d, CONST);
832 store_reg_to_var_int(iptr->dst, d);
836 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
838 var_to_reg_int(s1, src->prev, REG_ITMP1);
839 var_to_reg_int(s2, src, REG_ITMP2);
840 d = reg_of_var(iptr->dst, REG_ITMP3);
841 M_IADD(s1, s2, d, 0);
842 store_reg_to_var_int(iptr->dst, d);
845 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
846 /* val.i = constant */
848 var_to_reg_int(s1, src, REG_ITMP1);
849 d = reg_of_var(iptr->dst, REG_ITMP3);
850 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
851 M_IADD(s1, iptr->val.i, d, CONST);
854 ICONST(REG_ITMP2, iptr->val.i);
855 M_IADD(s1, REG_ITMP2, d, REG);
857 store_reg_to_var_int(iptr->dst, d);
860 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
862 var_to_reg_int(s1, src->prev, REG_ITMP1);
863 var_to_reg_int(s2, src, REG_ITMP2);
864 d = reg_of_var(iptr->dst, REG_ITMP3);
865 M_LADD(s1, s2, d, 0);
866 store_reg_to_var_int(iptr->dst, d);
869 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
870 /* val.l = constant */
872 var_to_reg_int(s1, src, REG_ITMP1);
873 d = reg_of_var(iptr->dst, REG_ITMP3);
874 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
875 M_LADD(s1, iptr->val.l, d, CONST);
878 LCONST(REG_ITMP2, iptr->val.l);
879 M_LADD(s1, REG_ITMP2, d, REG);
881 store_reg_to_var_int(iptr->dst, d);
884 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
886 var_to_reg_int(s1, src->prev, REG_ITMP1);
887 var_to_reg_int(s2, src, REG_ITMP2);
888 d = reg_of_var(iptr->dst, REG_ITMP3);
889 M_ISUB(s1, s2, d, REG);
890 store_reg_to_var_int(iptr->dst, d);
893 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
894 /* val.i = constant */
896 var_to_reg_int(s1, src, REG_ITMP1);
897 d = reg_of_var(iptr->dst, REG_ITMP3);
898 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
899 M_ISUB(s1, iptr->val.i, d, CONST);
902 ICONST(REG_ITMP2, iptr->val.i);
903 M_ISUB(s1, REG_ITMP2, d, REG);
905 store_reg_to_var_int(iptr->dst, d);
908 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
910 var_to_reg_int(s1, src->prev, REG_ITMP1);
911 var_to_reg_int(s2, src, REG_ITMP2);
912 d = reg_of_var(iptr->dst, REG_ITMP3);
913 M_LSUB(s1, s2, d, REG);
914 store_reg_to_var_int(iptr->dst, d);
917 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
918 /* val.l = constant */
920 var_to_reg_int(s1, src, REG_ITMP1);
921 d = reg_of_var(iptr->dst, REG_ITMP3);
922 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
923 M_LSUB(s1, iptr->val.l, d, CONST);
926 LCONST(REG_ITMP2, iptr->val.l);
927 M_LSUB(s1, REG_ITMP2, d, REG);
929 store_reg_to_var_int(iptr->dst, d);
932 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
934 var_to_reg_int(s1, src->prev, REG_ITMP1);
935 var_to_reg_int(s2, src, REG_ITMP2);
936 d = reg_of_var(iptr->dst, REG_ITMP3);
937 M_IMUL(s1, s2, d, REG);
938 store_reg_to_var_int(iptr->dst, d);
941 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
942 /* val.i = constant */
944 var_to_reg_int(s1, src, REG_ITMP1);
945 d = reg_of_var(iptr->dst, REG_ITMP3);
946 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
947 M_IMUL(s1, iptr->val.i, d, CONST);
950 ICONST(REG_ITMP2, iptr->val.i);
951 M_IMUL(s1, REG_ITMP2, d, REG);
953 store_reg_to_var_int(iptr->dst, d);
956 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
958 var_to_reg_int(s1, src->prev, REG_ITMP1);
959 var_to_reg_int(s2, src, REG_ITMP2);
960 d = reg_of_var(iptr->dst, REG_ITMP3);
961 M_LMUL (s1, s2, d, REG);
962 store_reg_to_var_int(iptr->dst, d);
965 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
966 /* val.l = constant */
968 var_to_reg_int(s1, src, REG_ITMP1);
969 d = reg_of_var(iptr->dst, REG_ITMP3);
970 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
971 M_LMUL(s1, iptr->val.l, d, CONST);
974 LCONST(REG_ITMP2, iptr->val.l);
975 M_LMUL(s1, REG_ITMP2, d, REG);
977 store_reg_to_var_int(iptr->dst, d);
980 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
981 case ICMD_LDIVPOW2: /* val.i = constant */
983 var_to_reg_int(s1, src, REG_ITMP1);
984 d = reg_of_var(iptr->dst, REG_ITMP3);
985 if (iptr->val.i <= 15) {
986 M_LDA(REG_ITMP2, s1, (1 << iptr->val.i) -1);
987 M_CMOVGE(s1, s1, REG_ITMP2, REG);
990 M_SRA(s1, 63, REG_ITMP2, CONST);
991 M_SRL(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2, CONST);
992 M_LADD(s1, REG_ITMP2, REG_ITMP2, REG);
994 M_SRA(REG_ITMP2, iptr->val.i, d, CONST);
995 store_reg_to_var_int(iptr->dst, d);
998 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1000 var_to_reg_int(s1, src->prev, REG_ITMP1);
1001 var_to_reg_int(s2, src, REG_ITMP2);
1002 d = reg_of_var(iptr->dst, REG_ITMP3);
1003 M_AND(s2, 0x1f, REG_ITMP3, CONST);
1004 M_SLL(s1, REG_ITMP3, d, REG);
1005 M_IADD(d, REG_ZERO, d, REG);
1006 store_reg_to_var_int(iptr->dst, d);
1009 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1010 /* val.i = constant */
1012 var_to_reg_int(s1, src, REG_ITMP1);
1013 d = reg_of_var(iptr->dst, REG_ITMP3);
1014 M_SLL(s1, iptr->val.i & 0x1f, d, CONST);
1015 M_IADD(d, REG_ZERO, d, REG);
1016 store_reg_to_var_int(iptr->dst, d);
1019 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1021 var_to_reg_int(s1, src->prev, REG_ITMP1);
1022 var_to_reg_int(s2, src, REG_ITMP2);
1023 d = reg_of_var(iptr->dst, REG_ITMP3);
1024 M_AND(s2, 0x1f, REG_ITMP3, 1);
1025 M_SRA(s1, REG_ITMP3, d, 0);
1026 store_reg_to_var_int(iptr->dst, d);
1029 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1030 /* val.i = constant */
1032 var_to_reg_int(s1, src, REG_ITMP1);
1033 d = reg_of_var(iptr->dst, REG_ITMP3);
1034 M_SRA(s1, iptr->val.i & 0x1f, d, CONST);
1035 store_reg_to_var_int(iptr->dst, d);
1038 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1040 var_to_reg_int(s1, src->prev, REG_ITMP1);
1041 var_to_reg_int(s2, src, REG_ITMP2);
1042 d = reg_of_var(iptr->dst, REG_ITMP3);
1043 M_AND (s2, 0x1f, REG_ITMP2, 1);
1045 M_SRL ( d, REG_ITMP2, d, REG);
1046 M_IADD ( d, REG_ZERO, d, REG);
1047 store_reg_to_var_int(iptr->dst, d);
1050 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1051 /* val.i = constant */
1053 var_to_reg_int(s1, src, REG_ITMP1);
1054 d = reg_of_var(iptr->dst, REG_ITMP3);
1056 M_SRL(d, iptr->val.i & 0x1f, d, CONST);
1057 M_IADD(d, REG_ZERO, d, REG);
1058 store_reg_to_var_int(iptr->dst, d);
1061 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1063 var_to_reg_int(s1, src->prev, REG_ITMP1);
1064 var_to_reg_int(s2, src, REG_ITMP2);
1065 d = reg_of_var(iptr->dst, REG_ITMP3);
1066 M_SLL(s1, s2, d, REG);
1067 store_reg_to_var_int(iptr->dst, d);
1070 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1071 /* val.l = constant */
1073 var_to_reg_int(s1, src, REG_ITMP1);
1074 d = reg_of_var(iptr->dst, REG_ITMP3);
1075 M_SLL(s1, iptr->val.l & 0x3f, d, CONST);
1076 store_reg_to_var_int(iptr->dst, d);
1079 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1081 var_to_reg_int(s1, src->prev, REG_ITMP1);
1082 var_to_reg_int(s2, src, REG_ITMP2);
1083 d = reg_of_var(iptr->dst, REG_ITMP3);
1084 M_SRA(s1, s2, d, 0);
1085 store_reg_to_var_int(iptr->dst, d);
1088 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1089 /* val.l = constant */
1091 var_to_reg_int(s1, src, REG_ITMP1);
1092 d = reg_of_var(iptr->dst, REG_ITMP3);
1093 M_SRA(s1, iptr->val.l & 0x3f, d, CONST);
1094 store_reg_to_var_int(iptr->dst, d);
1097 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1099 var_to_reg_int(s1, src->prev, REG_ITMP1);
1100 var_to_reg_int(s2, src, REG_ITMP2);
1101 d = reg_of_var(iptr->dst, REG_ITMP3);
1102 M_SRL(s1, s2, d, 0);
1103 store_reg_to_var_int(iptr->dst, d);
1106 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1107 /* val.l = constant */
1109 var_to_reg_int(s1, src, REG_ITMP1);
1110 d = reg_of_var(iptr->dst, REG_ITMP3);
1111 M_SRL(s1, iptr->val.l & 0x3f, d, CONST);
1112 store_reg_to_var_int(iptr->dst, d);
1115 case ICMD_IAND: /* ..., 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);
1121 M_AND(s1, s2, d, REG);
1122 store_reg_to_var_int(iptr->dst, d);
1125 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1126 /* val.i = constant */
1128 var_to_reg_int(s1, src, REG_ITMP1);
1129 d = reg_of_var(iptr->dst, REG_ITMP3);
1130 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1131 M_AND(s1, iptr->val.i, d, CONST);
1133 else if (iptr->val.i == 0xffff) {
1136 else if (iptr->val.i == 0xffffff) {
1137 M_ZAPNOT(s1, 0x07, d, CONST);
1140 ICONST(REG_ITMP2, iptr->val.i);
1141 M_AND(s1, REG_ITMP2, d, REG);
1143 store_reg_to_var_int(iptr->dst, d);
1146 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1147 /* val.i = constant */
1149 var_to_reg_int(s1, src, REG_ITMP1);
1150 d = reg_of_var(iptr->dst, REG_ITMP3);
1152 M_MOV(s1, REG_ITMP1);
1155 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1156 M_AND(s1, iptr->val.i, d, CONST);
1158 M_ISUB(REG_ZERO, s1, d, REG);
1159 M_AND(d, iptr->val.i, d, CONST);
1161 else if (iptr->val.i == 0xffff) {
1164 M_ISUB(REG_ZERO, s1, d, REG);
1167 else if (iptr->val.i == 0xffffff) {
1168 M_ZAPNOT(s1, 0x07, d, CONST);
1170 M_ISUB(REG_ZERO, s1, d, REG);
1171 M_ZAPNOT(d, 0x07, d, CONST);
1174 ICONST(REG_ITMP2, iptr->val.i);
1175 M_AND(s1, REG_ITMP2, d, REG);
1177 M_ISUB(REG_ZERO, s1, d, REG);
1178 M_AND(d, REG_ITMP2, d, REG);
1180 M_ISUB(REG_ZERO, d, d, REG);
1181 store_reg_to_var_int(iptr->dst, d);
1184 case ICMD_IREM0X10001: /* ..., value ==> ..., value % 0x100001 */
1186 /* b = value & 0xffff;
1188 a = ((b - a) & 0xffff) + (b < a);
1190 var_to_reg_int(s1, src, REG_ITMP1);
1191 d = reg_of_var(iptr->dst, REG_ITMP3);
1193 M_MOV(s1, REG_ITMP3);
1197 M_CZEXT(s1, REG_ITMP2);
1198 M_SRA(s1, 16, d, CONST);
1199 M_CMPLT(REG_ITMP2, d, REG_ITMP1, REG);
1200 M_ISUB(REG_ITMP2, d, d, REG);
1202 M_IADD(d, REG_ITMP1, d, REG);
1203 M_BR(11 + (s1 == REG_ITMP1));
1204 M_ISUB(REG_ZERO, s1, REG_ITMP1, REG);
1205 M_CZEXT(REG_ITMP1, REG_ITMP2);
1206 M_SRA(REG_ITMP1, 16, d, CONST);
1207 M_CMPLT(REG_ITMP2, d, REG_ITMP1, REG);
1208 M_ISUB(REG_ITMP2, d, d, REG);
1210 M_IADD(d, REG_ITMP1, d, REG);
1211 M_ISUB(REG_ZERO, d, d, REG);
1212 if (s1 == REG_ITMP1) {
1213 var_to_reg_int(s1, src, REG_ITMP1);
1215 M_SLL(s1, 33, REG_ITMP2, CONST);
1216 M_CMPEQ(REG_ITMP2, REG_ZERO, REG_ITMP2, REG);
1217 M_ISUB(d, REG_ITMP2, d, REG);
1218 store_reg_to_var_int(iptr->dst, d);
1221 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1222 /* val.l = constant */
1224 var_to_reg_int(s1, src, REG_ITMP1);
1225 d = reg_of_var(iptr->dst, REG_ITMP3);
1226 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1227 M_AND(s1, iptr->val.l, d, CONST);
1229 else if (iptr->val.l == 0xffffL) {
1232 else if (iptr->val.l == 0xffffffL) {
1233 M_ZAPNOT(s1, 0x07, d, CONST);
1235 else if (iptr->val.l == 0xffffffffL) {
1238 else if (iptr->val.l == 0xffffffffffL) {
1239 M_ZAPNOT(s1, 0x1f, d, CONST);
1241 else if (iptr->val.l == 0xffffffffffffL) {
1242 M_ZAPNOT(s1, 0x3f, d, CONST);
1244 else if (iptr->val.l == 0xffffffffffffffL) {
1245 M_ZAPNOT(s1, 0x7f, d, CONST);
1248 LCONST(REG_ITMP2, iptr->val.l);
1249 M_AND(s1, REG_ITMP2, d, REG);
1251 store_reg_to_var_int(iptr->dst, d);
1254 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1255 /* val.l = constant */
1257 var_to_reg_int(s1, src, REG_ITMP1);
1258 d = reg_of_var(iptr->dst, REG_ITMP3);
1260 M_MOV(s1, REG_ITMP1);
1263 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1264 M_AND(s1, iptr->val.l, d, CONST);
1266 M_LSUB(REG_ZERO, s1, d, REG);
1267 M_AND(d, iptr->val.l, d, CONST);
1269 else if (iptr->val.l == 0xffffL) {
1272 M_LSUB(REG_ZERO, s1, d, REG);
1275 else if (iptr->val.l == 0xffffffL) {
1276 M_ZAPNOT(s1, 0x07, d, CONST);
1278 M_LSUB(REG_ZERO, s1, d, REG);
1279 M_ZAPNOT(d, 0x07, d, CONST);
1281 else if (iptr->val.l == 0xffffffffL) {
1284 M_LSUB(REG_ZERO, s1, d, REG);
1287 else if (iptr->val.l == 0xffffffffffL) {
1288 M_ZAPNOT(s1, 0x1f, d, CONST);
1290 M_LSUB(REG_ZERO, s1, d, REG);
1291 M_ZAPNOT(d, 0x1f, d, CONST);
1293 else if (iptr->val.l == 0xffffffffffffL) {
1294 M_ZAPNOT(s1, 0x3f, d, CONST);
1296 M_LSUB(REG_ZERO, s1, d, REG);
1297 M_ZAPNOT(d, 0x3f, d, CONST);
1299 else if (iptr->val.l == 0xffffffffffffffL) {
1300 M_ZAPNOT(s1, 0x7f, d, CONST);
1302 M_LSUB(REG_ZERO, s1, d, REG);
1303 M_ZAPNOT(d, 0x7f, d, CONST);
1306 LCONST(REG_ITMP2, iptr->val.l);
1307 M_AND(s1, REG_ITMP2, d, REG);
1309 M_LSUB(REG_ZERO, s1, d, REG);
1310 M_AND(d, REG_ITMP2, d, REG);
1312 M_LSUB(REG_ZERO, d, d, REG);
1313 store_reg_to_var_int(iptr->dst, d);
1316 case ICMD_LREM0X10001:/* ..., value ==> ..., value % 0x10001 */
1318 var_to_reg_int(s1, src, REG_ITMP1);
1319 d = reg_of_var(iptr->dst, REG_ITMP3);
1321 M_MOV(s1, REG_ITMP3);
1324 M_CZEXT(s1, REG_ITMP2);
1325 M_SRA(s1, 16, d, CONST);
1326 M_CMPLT(REG_ITMP2, d, REG_ITMP1, REG);
1327 M_LSUB(REG_ITMP2, d, d, REG);
1329 M_LADD(d, REG_ITMP1, d, REG);
1330 M_LDA(REG_ITMP2, REG_ZERO, -1);
1331 M_SRL(REG_ITMP2, 33, REG_ITMP2, CONST);
1332 if (s1 == REG_ITMP1) {
1333 var_to_reg_int(s1, src, REG_ITMP1);
1335 M_CMPULT(s1, REG_ITMP2, REG_ITMP2, REG);
1336 M_BNEZ(REG_ITMP2, 11);
1337 M_LDA(d, REG_ZERO, -257);
1338 M_ZAPNOT(d, 0xcd, d, CONST);
1339 M_LSUB(REG_ZERO, s1, REG_ITMP2, REG);
1340 M_CMOVGE(s1, s1, REG_ITMP2, REG);
1341 M_UMULH(REG_ITMP2, d, REG_ITMP2, REG);
1342 M_SRL(REG_ITMP2, 16, REG_ITMP2, CONST);
1343 M_LSUB(REG_ZERO, REG_ITMP2, d, REG);
1344 M_CMOVGE(s1, REG_ITMP2, d, REG);
1345 M_SLL(d, 16, REG_ITMP2, CONST);
1346 M_LADD(d, REG_ITMP2, d, REG);
1347 M_LSUB(s1, d, d, REG);
1348 store_reg_to_var_int(iptr->dst, d);
1351 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1354 var_to_reg_int(s1, src->prev, REG_ITMP1);
1355 var_to_reg_int(s2, src, REG_ITMP2);
1356 d = reg_of_var(iptr->dst, REG_ITMP3);
1357 M_OR( s1,s2, d, REG);
1358 store_reg_to_var_int(iptr->dst, d);
1361 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1362 /* val.i = constant */
1364 var_to_reg_int(s1, src, REG_ITMP1);
1365 d = reg_of_var(iptr->dst, REG_ITMP3);
1366 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1367 M_OR(s1, iptr->val.i, d, CONST);
1370 ICONST(REG_ITMP2, iptr->val.i);
1371 M_OR(s1, REG_ITMP2, d, REG);
1373 store_reg_to_var_int(iptr->dst, d);
1376 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1377 /* val.l = constant */
1379 var_to_reg_int(s1, src, REG_ITMP1);
1380 d = reg_of_var(iptr->dst, REG_ITMP3);
1381 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1382 M_OR(s1, iptr->val.l, d, CONST);
1385 LCONST(REG_ITMP2, iptr->val.l);
1386 M_OR(s1, REG_ITMP2, d, REG);
1388 store_reg_to_var_int(iptr->dst, d);
1391 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1394 var_to_reg_int(s1, src->prev, REG_ITMP1);
1395 var_to_reg_int(s2, src, REG_ITMP2);
1396 d = reg_of_var(iptr->dst, REG_ITMP3);
1397 M_XOR(s1, s2, d, REG);
1398 store_reg_to_var_int(iptr->dst, d);
1401 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1402 /* val.i = constant */
1404 var_to_reg_int(s1, src, REG_ITMP1);
1405 d = reg_of_var(iptr->dst, REG_ITMP3);
1406 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1407 M_XOR(s1, iptr->val.i, d, CONST);
1410 ICONST(REG_ITMP2, iptr->val.i);
1411 M_XOR(s1, REG_ITMP2, d, REG);
1413 store_reg_to_var_int(iptr->dst, d);
1416 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1417 /* val.l = constant */
1419 var_to_reg_int(s1, src, REG_ITMP1);
1420 d = reg_of_var(iptr->dst, REG_ITMP3);
1421 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1422 M_XOR(s1, iptr->val.l, d, CONST);
1425 LCONST(REG_ITMP2, iptr->val.l);
1426 M_XOR(s1, REG_ITMP2, d, REG);
1428 store_reg_to_var_int(iptr->dst, d);
1432 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1434 var_to_reg_int(s1, src->prev, REG_ITMP1);
1435 var_to_reg_int(s2, src, REG_ITMP2);
1436 d = reg_of_var(iptr->dst, REG_ITMP3);
1437 M_CMPLT(s1, s2, REG_ITMP3, REG);
1438 M_CMPLT(s2, s1, REG_ITMP1, REG);
1439 M_LSUB (REG_ITMP1, REG_ITMP3, d, REG);
1440 store_reg_to_var_int(iptr->dst, d);
1444 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1445 /* op1 = variable, val.i = constant */
1447 var = &(locals[iptr->op1][TYPE_INT]);
1448 if (var->flags & INMEMORY) {
1450 M_LLD(s1, REG_SP, 8 * var->regoff);
1454 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1455 M_IADD(s1, iptr->val.i, s1, CONST);
1457 else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1458 M_ISUB(s1, (-iptr->val.i), s1, CONST);
1461 M_LDA (s1, s1, iptr->val.i);
1462 M_IADD(s1, REG_ZERO, s1, REG);
1464 if (var->flags & INMEMORY)
1465 M_LST(s1, REG_SP, 8 * var->regoff);
1469 /* floating operations ************************************************/
1471 case ICMD_FNEG: /* ..., value ==> ..., - value */
1473 var_to_reg_flt(s1, src, REG_FTMP1);
1474 d = reg_of_var(iptr->dst, REG_FTMP3);
1476 store_reg_to_var_flt(iptr->dst, d);
1479 case ICMD_DNEG: /* ..., value ==> ..., - value */
1481 var_to_reg_flt(s1, src, REG_FTMP1);
1482 d = reg_of_var(iptr->dst, REG_FTMP3);
1484 store_reg_to_var_flt(iptr->dst, d);
1487 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1489 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1490 var_to_reg_flt(s2, src, REG_FTMP2);
1491 d = reg_of_var(iptr->dst, REG_FTMP3);
1499 store_reg_to_var_flt(iptr->dst, d);
1502 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1504 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1505 var_to_reg_flt(s2, src, REG_FTMP2);
1506 d = reg_of_var(iptr->dst, REG_FTMP3);
1514 store_reg_to_var_flt(iptr->dst, d);
1517 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1519 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1520 var_to_reg_flt(s2, src, REG_FTMP2);
1521 d = reg_of_var(iptr->dst, REG_FTMP3);
1529 store_reg_to_var_flt(iptr->dst, d);
1532 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1534 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1535 var_to_reg_flt(s2, src, REG_FTMP2);
1536 d = reg_of_var(iptr->dst, REG_FTMP3);
1544 store_reg_to_var_flt(iptr->dst, d);
1547 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1549 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1550 var_to_reg_flt(s2, src, REG_FTMP2);
1551 d = reg_of_var(iptr->dst, REG_FTMP3);
1559 store_reg_to_var_flt(iptr->dst, d);
1562 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1564 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1565 var_to_reg_flt(s2, src, REG_FTMP2);
1566 d = reg_of_var(iptr->dst, REG_FTMP3);
1574 store_reg_to_var_flt(iptr->dst, d);
1577 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1579 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1580 var_to_reg_flt(s2, src, REG_FTMP2);
1581 d = reg_of_var(iptr->dst, REG_FTMP3);
1589 store_reg_to_var_flt(iptr->dst, d);
1592 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1594 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1595 var_to_reg_flt(s2, src, REG_FTMP2);
1596 d = reg_of_var(iptr->dst, REG_FTMP3);
1604 store_reg_to_var_flt(iptr->dst, d);
1607 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1609 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1610 var_to_reg_flt(s2, src, REG_FTMP2);
1611 d = reg_of_var(iptr->dst, REG_FTMP3);
1613 M_FDIVS(s1,s2, REG_FTMP3);
1615 M_CVTDL_CS(REG_ZERO, REG_FTMP3, REG_FTMP3); /* round to integer */
1617 M_CVTLF(REG_ZERO, REG_FTMP3, REG_FTMP3);
1618 M_FMULS(REG_FTMP3, s2, REG_FTMP3);
1620 M_FSUBS(s1, REG_FTMP3, d);
1624 M_FDIV(s1,s2, REG_FTMP3);
1625 M_CVTDL_C(REG_ZERO, REG_FTMP3, REG_FTMP3); /* round to integer */
1626 M_CVTLF(REG_ZERO, REG_FTMP3, REG_FTMP3);
1627 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1628 M_FSUB(s1, REG_FTMP3, d);
1630 store_reg_to_var_flt(iptr->dst, d);
1633 case ICMD_DREM: /* ..., 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);
1639 M_DDIVS(s1,s2, REG_FTMP3);
1641 M_CVTDL_CS(REG_ZERO, REG_FTMP3, REG_FTMP3); /* round to integer */
1643 M_CVTLD(REG_ZERO, REG_FTMP3, REG_FTMP3);
1644 M_DMULS(REG_FTMP3, s2, REG_FTMP3);
1646 M_DSUBS(s1, REG_FTMP3, d);
1650 M_DDIV(s1,s2, REG_FTMP3);
1651 M_CVTDL_C(REG_ZERO, REG_FTMP3, REG_FTMP3); /* round to integer */
1652 M_CVTLD(REG_ZERO, REG_FTMP3, REG_FTMP3);
1653 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1654 M_DSUB(s1, REG_FTMP3, d);
1656 store_reg_to_var_flt(iptr->dst, d);
1659 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1661 var_to_reg_int(s1, src, REG_ITMP1);
1662 d = reg_of_var(iptr->dst, REG_FTMP3);
1663 a = dseg_adddouble(0.0);
1664 M_LST (s1, REG_PV, a);
1665 M_DLD (d, REG_PV, a);
1666 M_CVTLF(REG_ZERO, d, d);
1667 store_reg_to_var_flt(iptr->dst, d);
1670 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1672 var_to_reg_int(s1, src, REG_ITMP1);
1673 d = reg_of_var(iptr->dst, REG_FTMP3);
1674 a = dseg_adddouble(0.0);
1675 M_LST (s1, REG_PV, a);
1676 M_DLD (d, REG_PV, a);
1677 M_CVTLD(REG_ZERO, d, d);
1678 store_reg_to_var_flt(iptr->dst, d);
1681 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1683 var_to_reg_flt(s1, src, REG_FTMP1);
1684 d = reg_of_var(iptr->dst, REG_ITMP3);
1685 a = dseg_adddouble(0.0);
1687 M_CVTDL_CS(REG_ZERO, s1, REG_FTMP1);
1689 M_CVTLIS(REG_FTMP1, REG_FTMP2);
1693 M_CVTDL_C(REG_ZERO, s1, REG_FTMP1);
1694 M_CVTLI(REG_FTMP1, REG_FTMP2);
1696 M_DST (REG_FTMP1, REG_PV, a);
1697 M_ILD (d, REG_PV, a);
1698 store_reg_to_var_int(iptr->dst, d);
1701 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1703 var_to_reg_flt(s1, src, REG_FTMP1);
1704 d = reg_of_var(iptr->dst, REG_ITMP3);
1705 a = dseg_adddouble(0.0);
1707 M_CVTDL_CS(REG_ZERO, s1, REG_FTMP1);
1711 M_CVTDL_C(REG_ZERO, s1, REG_FTMP1);
1713 M_DST (REG_FTMP1, REG_PV, a);
1714 M_LLD (d, REG_PV, a);
1715 store_reg_to_var_int(iptr->dst, d);
1718 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1720 var_to_reg_flt(s1, src, REG_FTMP1);
1721 d = reg_of_var(iptr->dst, REG_FTMP3);
1723 store_reg_to_var_flt(iptr->dst, d);
1726 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1728 var_to_reg_flt(s1, src, REG_FTMP1);
1729 d = reg_of_var(iptr->dst, REG_FTMP3);
1731 M_CVTDFS(REG_ZERO, s1, d);
1735 M_CVTDF(REG_ZERO, s1, d);
1737 store_reg_to_var_flt(iptr->dst, d);
1740 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1742 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1743 var_to_reg_flt(s2, src, REG_FTMP2);
1744 d = reg_of_var(iptr->dst, REG_ITMP3);
1746 M_LSUB (REG_ZERO, 1, d, CONST);
1747 M_FCMPEQS(s1, s2, REG_FTMP3);
1749 M_FBEQZ (REG_FTMP3, CONST); /* jump over next instructions */
1751 M_FCMPLTS(s2, s1, REG_FTMP3);
1753 M_FBEQZ (REG_FTMP3, CONST); /* jump over next instruction */
1754 M_LADD (REG_ZERO, 1, d, CONST);
1757 M_LSUB (REG_ZERO, 1, d, CONST);
1758 M_FCMPEQ(s1, s2, REG_FTMP3);
1759 M_FBEQZ (REG_FTMP3, CONST); /* jump over next instructions */
1761 M_FCMPLT(s2, s1, REG_FTMP3);
1762 M_FBEQZ (REG_FTMP3, CONST); /* jump over next instruction */
1763 M_LADD (REG_ZERO, 1, d, CONST);
1765 store_reg_to_var_int(iptr->dst, d);
1768 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1770 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1771 var_to_reg_flt(s2, src, REG_FTMP2);
1772 d = reg_of_var(iptr->dst, REG_ITMP3);
1774 M_LADD (REG_ZERO, 1, d, CONST);
1775 M_FCMPEQS(s1, s2, REG_FTMP3);
1777 M_FBEQZ (REG_FTMP3, CONST); /* jump over next instruction */
1779 M_FCMPLTS(s1, s2, REG_FTMP3);
1781 M_FBEQZ (REG_FTMP3, CONST); /* jump over next instruction */
1782 M_LSUB (REG_ZERO, 1, d, CONST);
1785 M_LADD (REG_ZERO, 1, d, CONST);
1786 M_FCMPEQ(s1, s2, REG_FTMP3);
1787 M_FBEQZ (REG_FTMP3, CONST); /* jump over next instruction */
1789 M_FCMPLT(s1, s2, REG_FTMP3);
1790 M_FBEQZ (REG_FTMP3, CONST); /* jump over next instruction */
1791 M_LSUB (REG_ZERO, 1, d, CONST);
1793 store_reg_to_var_int(iptr->dst, d);
1797 /* memory operations **************************************************/
1799 #define gen_bound_check \
1801 M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\
1802 M_CMPULT(s2, REG_ITMP3, REG_ITMP3, REG);\
1803 M_BEQZ(REG_ITMP3, REG);\
1804 mcode_addxboundrefs(mcodeptr);\
1807 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1809 var_to_reg_int(s1, src, REG_ITMP1);
1810 d = reg_of_var(iptr->dst, REG_ITMP3);
1811 gen_nullptr_check(s1);
1812 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1813 store_reg_to_var_int(iptr->dst, d);
1816 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1818 var_to_reg_int(s1, src->prev, REG_ITMP1);
1819 var_to_reg_int(s2, src, REG_ITMP2);
1820 d = reg_of_var(iptr->dst, REG_ITMP3);
1821 gen_nullptr_check(s1);
1823 M_SAADDQ(s2, s1, REG_ITMP1, REG);
1824 M_ALD( d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1825 store_reg_to_var_int(iptr->dst, d);
1828 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1830 var_to_reg_int(s1, src->prev, REG_ITMP1);
1831 var_to_reg_int(s2, src, REG_ITMP2);
1832 d = reg_of_var(iptr->dst, REG_ITMP3);
1833 gen_nullptr_check(s1);
1835 M_S8ADDQ(s2, s1, REG_ITMP1, REG);
1836 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1837 store_reg_to_var_int(iptr->dst, d);
1840 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1842 var_to_reg_int(s1, src->prev, REG_ITMP1);
1843 var_to_reg_int(s2, src, REG_ITMP2);
1844 d = reg_of_var(iptr->dst, REG_ITMP3);
1845 gen_nullptr_check(s1);
1847 M_S4ADDQ(s2, s1, REG_ITMP1, REG);
1848 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1849 store_reg_to_var_int(iptr->dst, d);
1852 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1854 var_to_reg_int(s1, src->prev, REG_ITMP1);
1855 var_to_reg_int(s2, src, REG_ITMP2);
1856 d = reg_of_var(iptr->dst, REG_FTMP3);
1857 gen_nullptr_check(s1);
1859 M_S4ADDQ(s2, s1, REG_ITMP1, REG);
1860 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1861 store_reg_to_var_flt(iptr->dst, d);
1864 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1866 var_to_reg_int(s1, src->prev, REG_ITMP1);
1867 var_to_reg_int(s2, src, REG_ITMP2);
1868 d = reg_of_var(iptr->dst, REG_FTMP3);
1869 gen_nullptr_check(s1);
1871 M_S8ADDQ(s2, s1, REG_ITMP1, REG);
1872 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1873 store_reg_to_var_flt(iptr->dst, d);
1876 case ICMD_CALOAD: /* ..., 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, REG);
1885 M_LADD(s2, REG_ITMP1, REG_ITMP1, REG);
1886 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1889 M_LADD (s2, s1, REG_ITMP1, 0);
1890 M_LADD (s2, REG_ITMP1, REG_ITMP1, REG);
1891 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1892 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1893 M_EXTWL(REG_ITMP2, REG_ITMP1, d, REG);
1895 store_reg_to_var_int(iptr->dst, d);
1898 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1900 var_to_reg_int(s1, src->prev, REG_ITMP1);
1901 var_to_reg_int(s2, src, REG_ITMP2);
1902 d = reg_of_var(iptr->dst, REG_ITMP3);
1903 gen_nullptr_check(s1);
1905 if (has_ext_instr_set) {
1906 M_LADD(s2, s1, REG_ITMP1, REG);
1907 M_LADD(s2, REG_ITMP1, REG_ITMP1, REG);
1908 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1912 M_LADD(s2, s1, REG_ITMP1, 0);
1913 M_LADD(s2, REG_ITMP1, REG_ITMP1, REG);
1914 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1915 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1916 M_EXTQH(REG_ITMP2, REG_ITMP1, d, REG);
1917 M_SRA(d, 48, d, CONST);
1919 store_reg_to_var_int(iptr->dst, d);
1922 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1924 var_to_reg_int(s1, src->prev, REG_ITMP1);
1925 var_to_reg_int(s2, src, REG_ITMP2);
1926 d = reg_of_var(iptr->dst, REG_ITMP3);
1927 gen_nullptr_check(s1);
1929 if (has_ext_instr_set) {
1930 M_LADD (s2, s1, REG_ITMP1, REG);
1931 M_BLDU (d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1935 M_LADD(s2, s1, REG_ITMP1, REG);
1936 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1937 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
1938 M_EXTQH(REG_ITMP2, REG_ITMP1, d, REG);
1939 M_SRA(d, 56, d, CONST);
1941 store_reg_to_var_int(iptr->dst, d);
1945 case ICMD_AASTORE: /* ..., 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_SAADDQ(s2, s1, REG_ITMP1, REG);
1953 M_AST (s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1956 case ICMD_LASTORE: /* ..., 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_int(s3, src, REG_ITMP3);
1963 M_S8ADDQ(s2, s1, REG_ITMP1, REG);
1964 M_LST (s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1967 case ICMD_IASTORE: /* ..., 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_int(s3, src, REG_ITMP3);
1974 M_S4ADDQ(s2, s1, REG_ITMP1, REG);
1975 M_IST (s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1978 case ICMD_FASTORE: /* ..., 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_flt(s3, src, REG_FTMP3);
1985 M_S4ADDQ(s2, s1, REG_ITMP1, REG);
1986 M_FST (s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1989 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1991 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1992 var_to_reg_int(s2, src->prev, REG_ITMP2);
1993 gen_nullptr_check(s1);
1995 var_to_reg_flt(s3, src, REG_FTMP3);
1996 M_S8ADDQ(s2, s1, REG_ITMP1, REG);
1997 M_DST (s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
2000 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
2002 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2003 var_to_reg_int(s2, src->prev, REG_ITMP2);
2004 gen_nullptr_check(s1);
2006 var_to_reg_int(s3, src, REG_ITMP3);
2007 if (has_ext_instr_set) {
2008 M_LADD(s2, s1, REG_ITMP1, REG);
2009 M_LADD(s2, REG_ITMP1, REG_ITMP1, REG);
2010 M_SST (s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
2013 M_LADD (s2, s1, REG_ITMP1, REG);
2014 M_LADD (s2, REG_ITMP1, REG_ITMP1, REG);
2015 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2016 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2017 M_INSWL(s3, REG_ITMP1, REG_ITMP3, REG);
2018 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2, REG);
2019 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2, REG);
2020 M_LST_U(REG_ITMP2, REG_ITMP1, REG);
2024 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
2026 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2027 var_to_reg_int(s2, src->prev, REG_ITMP2);
2028 gen_nullptr_check(s1);
2030 var_to_reg_int(s3, src, REG_ITMP3);
2031 if (has_ext_instr_set) {
2032 M_LADD(s2, s1, REG_ITMP1, REG);
2033 M_LADD(s2, REG_ITMP1, REG_ITMP1, REG);
2034 M_SST (s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2037 M_LADD (s2, s1, REG_ITMP1, REG);
2038 M_LADD (s2, REG_ITMP1, REG_ITMP1, REG);
2039 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2040 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2041 M_INSWL(s3, REG_ITMP1, REG_ITMP3, REG);
2042 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2, REG);
2043 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2, REG);
2044 M_LST_U(REG_ITMP2, REG_ITMP1, REG);
2048 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
2050 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2051 var_to_reg_int(s2, src->prev, REG_ITMP2);
2052 gen_nullptr_check(s1);
2054 var_to_reg_int(s3, src, REG_ITMP3);
2055 if (has_ext_instr_set) {
2056 M_LADD(s2, s1, REG_ITMP1, REG);
2057 M_BST (s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2060 M_LADD (s2, s1, REG_ITMP1, 0);
2061 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2062 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2063 M_INSBL(s3, REG_ITMP1, REG_ITMP3, REG);
2064 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2, REG);
2065 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2, REG);
2066 M_LST_U(REG_ITMP2, REG_ITMP1, REG);
2071 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2072 /* op1 = type, val.a = field address */
2074 a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value));
2075 M_ALD(REG_ITMP1, REG_PV, a);
2076 switch (iptr->op1) {
2078 var_to_reg_int(s2, src, REG_ITMP2);
2079 M_IST(s2, REG_ITMP1, REG);
2082 var_to_reg_int(s2, src, REG_ITMP2);
2083 M_LST(s2, REG_ITMP1, REG);
2086 var_to_reg_int(s2, src, REG_ITMP2);
2087 M_AST(s2, REG_ITMP1, REG);
2090 var_to_reg_flt(s2, src, REG_FTMP2);
2091 M_FST(s2, REG_ITMP1, REG);
2094 var_to_reg_flt(s2, src, REG_FTMP2);
2095 M_DST(s2, REG_ITMP1, REG);
2097 default: panic ("internal error");
2101 case ICMD_GETSTATIC: /* ... ==> ..., value */
2102 /* op1 = type, val.a = field address */
2104 a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value));
2105 M_ALD(REG_ITMP1, REG_PV, a);
2106 switch (iptr->op1) {
2108 d = reg_of_var(iptr->dst, REG_ITMP3);
2109 M_ILD(d, REG_ITMP1, REG);
2110 store_reg_to_var_int(iptr->dst, d);
2113 d = reg_of_var(iptr->dst, REG_ITMP3);
2114 M_LLD(d, REG_ITMP1, REG);
2115 store_reg_to_var_int(iptr->dst, d);
2118 d = reg_of_var(iptr->dst, REG_ITMP3);
2119 M_ALD(d, REG_ITMP1, REG);
2120 store_reg_to_var_int(iptr->dst, d);
2123 d = reg_of_var(iptr->dst, REG_FTMP1);
2124 M_FLD(d, REG_ITMP1, REG);
2125 store_reg_to_var_flt(iptr->dst, d);
2128 d = reg_of_var(iptr->dst, REG_FTMP1);
2129 M_DLD(d, REG_ITMP1, REG);
2130 store_reg_to_var_flt(iptr->dst, d);
2132 default: panic ("internal error");
2137 case ICMD_PUTFIELD: /* ..., value ==> ... */
2138 /* op1 = type, val.i = field offset */
2140 a = ((fieldinfo *)(iptr->val.a))->offset;
2141 switch (iptr->op1) {
2143 var_to_reg_int(s1, src->prev, REG_ITMP1);
2144 var_to_reg_int(s2, src, REG_ITMP2);
2145 gen_nullptr_check(s1);
2149 var_to_reg_int(s1, src->prev, REG_ITMP1);
2150 var_to_reg_int(s2, src, REG_ITMP2);
2151 gen_nullptr_check(s1);
2155 var_to_reg_int(s1, src->prev, REG_ITMP1);
2156 var_to_reg_int(s2, src, REG_ITMP2);
2157 gen_nullptr_check(s1);
2161 var_to_reg_int(s1, src->prev, REG_ITMP1);
2162 var_to_reg_flt(s2, src, REG_FTMP2);
2163 gen_nullptr_check(s1);
2167 var_to_reg_int(s1, src->prev, REG_ITMP1);
2168 var_to_reg_flt(s2, src, REG_FTMP2);
2169 gen_nullptr_check(s1);
2172 default: panic ("internal error");
2176 case ICMD_GETFIELD: /* ... ==> ..., value */
2177 /* op1 = type, val.i = field offset */
2179 a = ((fieldinfo *)(iptr->val.a))->offset;
2180 switch (iptr->op1) {
2182 var_to_reg_int(s1, src, REG_ITMP1);
2183 d = reg_of_var(iptr->dst, REG_ITMP3);
2184 gen_nullptr_check(s1);
2186 store_reg_to_var_int(iptr->dst, d);
2189 var_to_reg_int(s1, src, REG_ITMP1);
2190 d = reg_of_var(iptr->dst, REG_ITMP3);
2191 gen_nullptr_check(s1);
2193 store_reg_to_var_int(iptr->dst, d);
2196 var_to_reg_int(s1, src, REG_ITMP1);
2197 d = reg_of_var(iptr->dst, REG_ITMP3);
2198 gen_nullptr_check(s1);
2200 store_reg_to_var_int(iptr->dst, d);
2203 var_to_reg_int(s1, src, REG_ITMP1);
2204 d = reg_of_var(iptr->dst, REG_FTMP1);
2205 gen_nullptr_check(s1);
2207 store_reg_to_var_flt(iptr->dst, d);
2210 var_to_reg_int(s1, src, REG_ITMP1);
2211 d = reg_of_var(iptr->dst, REG_FTMP1);
2212 gen_nullptr_check(s1);
2214 store_reg_to_var_flt(iptr->dst, d);
2216 default: panic ("internal error");
2221 /* branch operations **************************************************/
2223 #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}}
2225 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2227 var_to_reg_int(s1, src, REG_ITMP1);
2228 M_INTMOVE(s1, REG_ITMP1_XPTR);
2229 a = dseg_addaddress(asm_handle_exception);
2230 M_ALD(REG_ITMP2, REG_PV, a);
2231 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2235 case ICMD_GOTO: /* ... ==> ... */
2236 /* op1 = target JavaVM pc */
2238 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2242 case ICMD_JSR: /* ... ==> ... */
2243 /* op1 = target JavaVM pc */
2245 M_BSR(REG_ITMP1, REG);
2246 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2249 case ICMD_RET: /* ... ==> ... */
2250 /* op1 = local variable */
2252 var = &(locals[iptr->op1][TYPE_ADR]);
2253 if (var->flags & INMEMORY) {
2254 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2255 M_RET(REG_ZERO, REG_ITMP1);
2258 M_RET(REG_ZERO, var->regoff);
2262 case ICMD_IFNULL: /* ..., value ==> ... */
2263 /* op1 = target JavaVM pc */
2265 var_to_reg_int(s1, src, REG_ITMP1);
2267 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2270 case ICMD_IFNONNULL: /* ..., value ==> ... */
2271 /* op1 = target JavaVM pc */
2273 var_to_reg_int(s1, src, REG_ITMP1);
2275 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2278 case ICMD_IFEQ: /* ..., value ==> ... */
2279 /* op1 = target JavaVM pc, val.i = constant */
2281 var_to_reg_int(s1, src, REG_ITMP1);
2282 if (iptr->val.i == 0) {
2286 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2287 M_CMPEQ(s1, iptr->val.i, REG_ITMP1, CONST);
2290 ICONST(REG_ITMP2, iptr->val.i);
2291 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1, REG);
2293 M_BNEZ(REG_ITMP1, REG);
2295 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2298 case ICMD_IFLT: /* ..., value ==> ... */
2299 /* op1 = target JavaVM pc, val.i = constant */
2301 var_to_reg_int(s1, src, REG_ITMP1);
2302 if (iptr->val.i == 0) {
2306 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2307 M_CMPLT(s1, iptr->val.i, REG_ITMP1, CONST);
2310 ICONST(REG_ITMP2, iptr->val.i);
2311 M_CMPLT(s1, REG_ITMP2, REG_ITMP1, REG);
2313 M_BNEZ(REG_ITMP1, REG);
2315 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2318 case ICMD_IFLE: /* ..., value ==> ... */
2319 /* op1 = target JavaVM pc, val.i = constant */
2321 var_to_reg_int(s1, src, REG_ITMP1);
2322 if (iptr->val.i == 0) {
2326 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2327 M_CMPLE(s1, iptr->val.i, REG_ITMP1, CONST);
2330 ICONST(REG_ITMP2, iptr->val.i);
2331 M_CMPLE(s1, REG_ITMP2, REG_ITMP1, REG);
2333 M_BNEZ(REG_ITMP1, REG);
2335 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2338 case ICMD_IFNE: /* ..., value ==> ... */
2339 /* op1 = target JavaVM pc, val.i = constant */
2341 var_to_reg_int(s1, src, REG_ITMP1);
2342 if (iptr->val.i == 0) {
2346 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2347 M_CMPEQ(s1, iptr->val.i, REG_ITMP1, CONST);
2350 ICONST(REG_ITMP2, iptr->val.i);
2351 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1, REG);
2353 M_BEQZ(REG_ITMP1, REG);
2355 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2358 case ICMD_IFGT: /* ..., value ==> ... */
2359 /* op1 = target JavaVM pc, val.i = constant */
2361 var_to_reg_int(s1, src, REG_ITMP1);
2362 if (iptr->val.i == 0) {
2366 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2367 M_CMPLE(s1, iptr->val.i, REG_ITMP1, CONST);
2370 ICONST(REG_ITMP2, iptr->val.i);
2371 M_CMPLE(s1, REG_ITMP2, REG_ITMP1, REG);
2373 M_BEQZ(REG_ITMP1, REG);
2375 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2378 case ICMD_IFGE: /* ..., value ==> ... */
2379 /* op1 = target JavaVM pc, val.i = constant */
2381 var_to_reg_int(s1, src, REG_ITMP1);
2382 if (iptr->val.i == 0) {
2386 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2387 M_CMPLT(s1, iptr->val.i, REG_ITMP1, CONST);
2390 ICONST(REG_ITMP2, iptr->val.i);
2391 M_CMPLT(s1, REG_ITMP2, REG_ITMP1, REG);
2393 M_BEQZ(REG_ITMP1, REG);
2395 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2398 case ICMD_IF_LEQ: /* ..., value ==> ... */
2399 /* op1 = target JavaVM pc, val.l = constant */
2401 var_to_reg_int(s1, src, REG_ITMP1);
2402 if (iptr->val.l == 0) {
2406 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2407 M_CMPEQ(s1, iptr->val.l, REG_ITMP1, CONST);
2410 LCONST(REG_ITMP2, iptr->val.l);
2411 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1, REG);
2413 M_BNEZ(REG_ITMP1, REG);
2415 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2418 case ICMD_IF_LLT: /* ..., value ==> ... */
2419 /* op1 = target JavaVM pc, val.l = constant */
2421 var_to_reg_int(s1, src, REG_ITMP1);
2422 if (iptr->val.l == 0) {
2426 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2427 M_CMPLT(s1, iptr->val.l, REG_ITMP1, CONST);
2430 LCONST(REG_ITMP2, iptr->val.l);
2431 M_CMPLT(s1, REG_ITMP2, REG_ITMP1, REG);
2433 M_BNEZ(REG_ITMP1, REG);
2435 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2438 case ICMD_IF_LLE: /* ..., value ==> ... */
2439 /* op1 = target JavaVM pc, val.l = constant */
2441 var_to_reg_int(s1, src, REG_ITMP1);
2442 if (iptr->val.l == 0) {
2446 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2447 M_CMPLE(s1, iptr->val.l, REG_ITMP1, CONST);
2450 LCONST(REG_ITMP2, iptr->val.l);
2451 M_CMPLE(s1, REG_ITMP2, REG_ITMP1, REG);
2453 M_BNEZ(REG_ITMP1, REG);
2455 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2458 case ICMD_IF_LNE: /* ..., value ==> ... */
2459 /* op1 = target JavaVM pc, val.l = constant */
2461 var_to_reg_int(s1, src, REG_ITMP1);
2462 if (iptr->val.l == 0) {
2466 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2467 M_CMPEQ(s1, iptr->val.l, REG_ITMP1, CONST);
2470 LCONST(REG_ITMP2, iptr->val.l);
2471 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1, REG);
2473 M_BEQZ(REG_ITMP1, REG);
2475 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2478 case ICMD_IF_LGT: /* ..., value ==> ... */
2479 /* op1 = target JavaVM pc, val.l = constant */
2481 var_to_reg_int(s1, src, REG_ITMP1);
2482 if (iptr->val.l == 0) {
2486 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2487 M_CMPLE(s1, iptr->val.l, REG_ITMP1, CONST);
2490 LCONST(REG_ITMP2, iptr->val.l);
2491 M_CMPLE(s1, REG_ITMP2, REG_ITMP1, REG);
2493 M_BEQZ(REG_ITMP1, REG);
2495 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2498 case ICMD_IF_LGE: /* ..., value ==> ... */
2499 /* op1 = target JavaVM pc, val.l = constant */
2501 var_to_reg_int(s1, src, REG_ITMP1);
2502 if (iptr->val.l == 0) {
2506 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2507 M_CMPLT(s1, iptr->val.l, REG_ITMP1, CONST);
2510 LCONST(REG_ITMP2, iptr->val.l);
2511 M_CMPLT(s1, REG_ITMP2, REG_ITMP1, REG);
2513 M_BEQZ(REG_ITMP1, REG);
2515 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2518 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2519 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2520 case ICMD_IF_ACMPEQ:
2522 var_to_reg_int(s1, src->prev, REG_ITMP1);
2523 var_to_reg_int(s2, src, REG_ITMP2);
2524 M_CMPEQ(s1, s2, REG_ITMP1, REG);
2525 M_BNEZ(REG_ITMP1, REG);
2526 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2529 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2530 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2531 case ICMD_IF_ACMPNE:
2533 var_to_reg_int(s1, src->prev, REG_ITMP1);
2534 var_to_reg_int(s2, src, REG_ITMP2);
2535 M_CMPEQ(s1, s2, REG_ITMP1, REG);
2536 M_BEQZ(REG_ITMP1, REG);
2537 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2540 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2541 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2543 var_to_reg_int(s1, src->prev, REG_ITMP1);
2544 var_to_reg_int(s2, src, REG_ITMP2);
2545 M_CMPLT(s1, s2, REG_ITMP1, REG);
2546 M_BNEZ(REG_ITMP1, REG);
2547 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2550 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2551 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2553 var_to_reg_int(s1, src->prev, REG_ITMP1);
2554 var_to_reg_int(s2, src, REG_ITMP2);
2555 M_CMPLE(s1, s2, REG_ITMP1, REG);
2556 M_BEQZ(REG_ITMP1, REG);
2557 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2560 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2561 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2563 var_to_reg_int(s1, src->prev, REG_ITMP1);
2564 var_to_reg_int(s2, src, REG_ITMP2);
2565 M_CMPLE(s1, s2, REG_ITMP1, REG);
2566 M_BNEZ(REG_ITMP1, REG);
2567 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2570 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2571 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2573 var_to_reg_int(s1, src->prev, REG_ITMP1);
2574 var_to_reg_int(s2, src, REG_ITMP2);
2575 M_CMPLT(s1, s2, REG_ITMP1, 0);
2576 M_BEQZ(REG_ITMP1, REG);
2577 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2580 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2582 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2585 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2586 /* val.i = constant */
2588 var_to_reg_int(s1, src, REG_ITMP1);
2589 d = reg_of_var(iptr->dst, REG_ITMP3);
2591 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2592 if ((a == 1) && (iptr[1].val.i == 0)) {
2593 M_CMPEQ(s1, REG_ZERO, d, 0);
2594 store_reg_to_var_int(iptr->dst, d);
2597 if ((a == 0) && (iptr[1].val.i == 1)) {
2598 M_CMPEQ(s1, REG_ZERO, d, 0);
2599 M_XOR(d, 1, d, CONST);
2600 store_reg_to_var_int(iptr->dst, d);
2604 M_MOV(s1, REG_ITMP1);
2607 ICONST(d, iptr[1].val.i);
2609 if ((a >= 0) && (a <= 255)) {
2610 M_CMOVEQ(s1, a, d, CONST);
2613 ICONST(REG_ITMP2, a);
2614 M_CMOVEQ(s1, REG_ITMP2, d, REG);
2616 store_reg_to_var_int(iptr->dst, d);
2619 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2620 /* val.i = constant */
2622 var_to_reg_int(s1, src, REG_ITMP1);
2623 d = reg_of_var(iptr->dst, REG_ITMP3);
2625 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2626 if ((a == 0) && (iptr[1].val.i == 1)) {
2627 M_CMPEQ(s1, REG_ZERO, d, 0);
2628 store_reg_to_var_int(iptr->dst, d);
2631 if ((a == 1) && (iptr[1].val.i == 0)) {
2632 M_CMPEQ(s1, REG_ZERO, d, 0);
2633 M_XOR(d, 1, d, CONST);
2634 store_reg_to_var_int(iptr->dst, d);
2638 M_MOV(s1, REG_ITMP1);
2641 ICONST(d, iptr[1].val.i);
2643 if ((a >= 0) && (a <= 255)) {
2644 M_CMOVNE(s1, a, d, CONST);
2647 ICONST(REG_ITMP2, a);
2648 M_CMOVNE(s1, REG_ITMP2, d, REG);
2650 store_reg_to_var_int(iptr->dst, d);
2653 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2654 /* val.i = constant */
2656 var_to_reg_int(s1, src, REG_ITMP1);
2657 d = reg_of_var(iptr->dst, REG_ITMP3);
2659 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2660 if ((a == 1) && (iptr[1].val.i == 0)) {
2661 M_CMPLT(s1, REG_ZERO, d, 0);
2662 store_reg_to_var_int(iptr->dst, d);
2665 if ((a == 0) && (iptr[1].val.i == 1)) {
2666 M_CMPLE(REG_ZERO, s1, d, 0);
2667 store_reg_to_var_int(iptr->dst, d);
2671 M_MOV(s1, REG_ITMP1);
2674 ICONST(d, iptr[1].val.i);
2676 if ((a >= 0) && (a <= 255)) {
2677 M_CMOVLT(s1, a, d, CONST);
2680 ICONST(REG_ITMP2, a);
2681 M_CMOVLT(s1, REG_ITMP2, d, REG);
2683 store_reg_to_var_int(iptr->dst, d);
2686 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2687 /* val.i = constant */
2689 var_to_reg_int(s1, src, REG_ITMP1);
2690 d = reg_of_var(iptr->dst, REG_ITMP3);
2692 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2693 if ((a == 1) && (iptr[1].val.i == 0)) {
2694 M_CMPLE(REG_ZERO, s1, d, 0);
2695 store_reg_to_var_int(iptr->dst, d);
2698 if ((a == 0) && (iptr[1].val.i == 1)) {
2699 M_CMPLT(s1, REG_ZERO, d, 0);
2700 store_reg_to_var_int(iptr->dst, d);
2704 M_MOV(s1, REG_ITMP1);
2707 ICONST(d, iptr[1].val.i);
2709 if ((a >= 0) && (a <= 255)) {
2710 M_CMOVGE(s1, a, d, CONST);
2713 ICONST(REG_ITMP2, a);
2714 M_CMOVGE(s1, REG_ITMP2, d, REG);
2716 store_reg_to_var_int(iptr->dst, d);
2719 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2720 /* val.i = constant */
2722 var_to_reg_int(s1, src, REG_ITMP1);
2723 d = reg_of_var(iptr->dst, REG_ITMP3);
2725 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2726 if ((a == 1) && (iptr[1].val.i == 0)) {
2727 M_CMPLT(REG_ZERO, s1, d, 0);
2728 store_reg_to_var_int(iptr->dst, d);
2731 if ((a == 0) && (iptr[1].val.i == 1)) {
2732 M_CMPLE(s1, REG_ZERO, d, 0);
2733 store_reg_to_var_int(iptr->dst, d);
2737 M_MOV(s1, REG_ITMP1);
2740 ICONST(d, iptr[1].val.i);
2742 if ((a >= 0) && (a <= 255)) {
2743 M_CMOVGT(s1, a, d, CONST);
2746 ICONST(REG_ITMP2, a);
2747 M_CMOVGT(s1, REG_ITMP2, d, REG);
2749 store_reg_to_var_int(iptr->dst, d);
2752 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2753 /* val.i = constant */
2755 var_to_reg_int(s1, src, REG_ITMP1);
2756 d = reg_of_var(iptr->dst, REG_ITMP3);
2758 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2759 if ((a == 1) && (iptr[1].val.i == 0)) {
2760 M_CMPLE(s1, REG_ZERO, d, 0);
2761 store_reg_to_var_int(iptr->dst, d);
2764 if ((a == 0) && (iptr[1].val.i == 1)) {
2765 M_CMPLT(REG_ZERO, s1, d, 0);
2766 store_reg_to_var_int(iptr->dst, d);
2770 M_MOV(s1, REG_ITMP1);
2773 ICONST(d, iptr[1].val.i);
2775 if ((a >= 0) && (a <= 255)) {
2776 M_CMOVLE(s1, a, d, CONST);
2779 ICONST(REG_ITMP2, a);
2780 M_CMOVLE(s1, REG_ITMP2, d, REG);
2782 store_reg_to_var_int(iptr->dst, d);
2786 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2791 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2792 a = dseg_addaddress ((void*) (builtin_monitorexit));
2793 M_ALD(REG_PV, REG_PV, a);
2794 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
2795 M_JSR(REG_RA, REG_PV);
2796 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2799 var_to_reg_int(s1, src, REG_RESULT);
2800 M_INTMOVE(s1, REG_RESULT);
2801 goto nowperformreturn;
2803 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2807 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2808 a = dseg_addaddress ((void*) (builtin_monitorexit));
2809 M_ALD(REG_PV, REG_PV, a);
2810 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
2811 M_JSR(REG_RA, REG_PV);
2812 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2815 var_to_reg_flt(s1, src, REG_FRESULT);
2816 M_FLTMOVE(s1, REG_FRESULT);
2817 goto nowperformreturn;
2819 case ICMD_RETURN: /* ... ==> ... */
2822 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2823 a = dseg_addaddress ((void*) (builtin_monitorexit));
2824 M_ALD(REG_PV, REG_PV, a);
2825 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
2826 M_JSR(REG_RA, REG_PV);
2827 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2835 p = parentargs_base;
2837 /* restore return address */
2840 {p--; M_LLD (REG_RA, REG_SP, 8 * p);}
2842 /* restore saved registers */
2844 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
2845 {p--; M_LLD(savintregs[r], REG_SP, 8 * p);}
2846 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
2847 {p--; M_DLD(savfltregs[r], REG_SP, 8 * p);}
2849 /* deallocate stack */
2851 if (parentargs_base)
2852 {M_LDA(REG_SP, REG_SP, parentargs_base*8);}
2854 /* call trace function */
2857 M_LDA (REG_SP, REG_SP, -24);
2858 M_AST(REG_RA, REG_SP, REG);
2859 M_LST(REG_RESULT, REG_SP, 8);
2860 M_DST(REG_FRESULT, REG_SP,16);
2861 a = dseg_addaddress (method);
2862 M_ALD(argintregs[0], REG_PV, a);
2863 M_MOV(REG_RESULT, argintregs[1]);
2864 M_FLTMOVE(REG_FRESULT, argfltregs[2]);
2865 a = dseg_addaddress ((void*) (builtin_displaymethodstop));
2866 M_ALD(REG_PV, REG_PV, a);
2867 M_JSR (REG_RA, REG_PV);
2868 s1 = (int)((u1*) mcodeptr - mcodebase);
2869 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
2872 while (ml<-32768) { ml+=65536; mh--; }
2873 M_LDA (REG_PV, REG_RA, ml );
2874 M_LDAH (REG_PV, REG_PV, mh );
2876 M_DLD(REG_FRESULT, REG_SP,16);
2877 M_LLD(REG_RESULT, REG_SP, 8);
2878 M_ALD(REG_RA, REG_SP, REG);
2879 M_LDA (REG_SP, REG_SP, 24);
2882 M_RET(REG_ZERO, REG_RA);
2888 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2892 s4ptr = iptr->val.a;
2893 l = s4ptr[1]; /* low */
2894 i = s4ptr[2]; /* high */
2896 var_to_reg_int(s1, src, REG_ITMP1);
2898 {M_INTMOVE(s1, REG_ITMP1);}
2900 M_LDA(REG_ITMP1, s1, -l);
2906 M_CMPULE(REG_ITMP1, i - 1, REG_ITMP2, CONST);
2908 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
2909 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2, REG);
2911 M_BEQZ(REG_ITMP2, REG);
2912 mcode_addreference(BlockPtrOfPC(s4ptr[0]), mcodeptr);
2914 /* build jump table top down and use address of lowest entry */
2918 dseg_addtarget(BlockPtrOfPC(*--s4ptr));
2922 /* length of dataseg after last dseg_addtarget is used by load */
2924 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2, REG);
2925 M_ALD(REG_ITMP2, REG_ITMP2, -dseglen);
2926 M_JMP(REG_ZERO, REG_ITMP2);
2931 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2933 s4 i, l, val, *s4ptr;
2935 s4ptr = iptr->val.a;
2936 l = s4ptr[0]; /* default */
2937 i = s4ptr[1]; /* count */
2939 MCODECHECK((i<<2)+8);
2940 var_to_reg_int(s1, src, REG_ITMP1);
2944 if ((val >= 0) && (val <= 255)) {
2945 M_CMPEQ(s1, val, REG_ITMP2, CONST);
2948 if ((val >= -32768) && (val <= 32767)) {
2949 M_LDA(REG_ITMP2, REG_ZERO, val);
2952 a = dseg_adds4 (val);
2953 M_ILD(REG_ITMP2, REG_PV, a);
2955 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2, REG);
2957 M_BNEZ(REG_ITMP2, REG);
2958 mcode_addreference(BlockPtrOfPC(s4ptr[1]), mcodeptr);
2962 mcode_addreference(BlockPtrOfPC(l), mcodeptr);
2968 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
2969 /* op1 = return type, val.a = function pointer*/
2973 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
2974 /* op1 = return type, val.a = function pointer*/
2978 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
2979 /* op1 = return type, val.a = function pointer*/
2983 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2984 /* op1 = arg count, val.a = method pointer */
2986 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2987 /* op1 = arg count, val.a = method pointer */
2989 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2990 /* op1 = arg count, val.a = method pointer */
2992 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
2993 /* op1 = arg count, val.a = method pointer */
3001 MCODECHECK((s3 << 1) + 64);
3003 /* copy arguments to registers or stack location */
3005 for (; --s3 >= 0; src = src->prev) {
3006 if (src->varkind == ARGVAR)
3008 if (IS_INT_LNG_TYPE(src->type)) {
3009 if (s3 < INT_ARG_CNT) {
3010 s1 = argintregs[s3];
3011 var_to_reg_int(d, src, s1);
3015 var_to_reg_int(d, src, REG_ITMP1);
3016 M_LST(d, REG_SP, 8 * (s3 - INT_ARG_CNT));
3020 if (s3 < FLT_ARG_CNT) {
3021 s1 = argfltregs[s3];
3022 var_to_reg_flt(d, src, s1);
3026 var_to_reg_flt(d, src, REG_FTMP1);
3027 M_DST(d, REG_SP, 8 * (s3 - FLT_ARG_CNT));
3032 switch (iptr->opc) {
3036 a = dseg_addaddress ((void*) (m));
3038 M_ALD(REG_PV, REG_PV, a); /* Pointer to built-in-function */
3040 goto makeactualcall;
3042 case ICMD_INVOKESTATIC:
3043 case ICMD_INVOKESPECIAL:
3044 a = dseg_addaddress (m->stubroutine);
3046 M_ALD(REG_PV, REG_PV, a ); /* method pointer in r27 */
3049 goto makeactualcall;
3051 case ICMD_INVOKEVIRTUAL:
3053 gen_nullptr_check(argintregs[0]);
3054 M_ALD(REG_METHODPTR, argintregs[0],
3055 OFFSET(java_objectheader, vftbl));
3056 M_ALD(REG_PV, REG_METHODPTR, OFFSET(vftbl, table[0]) +
3057 sizeof(methodptr) * m->vftblindex);
3060 goto makeactualcall;
3062 case ICMD_INVOKEINTERFACE:
3065 gen_nullptr_check(argintregs[0]);
3066 M_ALD(REG_METHODPTR, argintregs[0],
3067 OFFSET(java_objectheader, vftbl));
3068 M_ALD(REG_METHODPTR, REG_METHODPTR,
3069 OFFSET(vftbl, interfacetable[0]) -
3070 sizeof(methodptr*) * ci->index);
3071 M_ALD(REG_PV, REG_METHODPTR,
3072 sizeof(methodptr) * (m - ci->methods));
3075 goto makeactualcall;
3079 sprintf (logtext, "Unkown ICMD-Command: %d", iptr->opc);
3085 M_JSR (REG_RA, REG_PV);
3089 s1 = (int)((u1*) mcodeptr - mcodebase);
3090 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
3093 while (ml<-32768) { ml+=65536; mh--; }
3094 M_LDA (REG_PV, REG_RA, ml );
3095 M_LDAH (REG_PV, REG_PV, mh );
3098 /* d contains return type */
3100 if (d != TYPE_VOID) {
3101 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3102 s1 = reg_of_var(iptr->dst, REG_RESULT);
3103 M_INTMOVE(REG_RESULT, s1);
3104 store_reg_to_var_int(iptr->dst, s1);
3107 s1 = reg_of_var(iptr->dst, REG_FRESULT);
3108 M_FLTMOVE(REG_FRESULT, s1);
3109 store_reg_to_var_flt(iptr->dst, s1);
3116 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3118 /* op1: 0 == array, 1 == class */
3119 /* val.a: (classinfo*) superclass */
3121 /* superclass is an interface:
3123 * return (sub != NULL) &&
3124 * (sub->vftbl->interfacetablelength > super->index) &&
3125 * (sub->vftbl->interfacetable[-super->index] != NULL);
3127 * superclass is a class:
3129 * return ((sub != NULL) && (0
3130 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3131 * super->vftbl->diffvall));
3135 classinfo *super = (classinfo*) iptr->val.a;
3137 var_to_reg_int(s1, src, REG_ITMP1);
3138 d = reg_of_var(iptr->dst, REG_ITMP3);
3140 M_MOV(s1, REG_ITMP1);
3144 if (iptr->op1) { /* class/interface */
3145 if (super->flags & ACC_INTERFACE) { /* interface */
3147 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3148 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3149 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3150 M_BLEZ(REG_ITMP2, 2);
3151 M_ALD(REG_ITMP1, REG_ITMP1,
3152 OFFSET(vftbl, interfacetable[0]) -
3153 super->index * sizeof(methodptr*));
3154 M_CMPULT(REG_ZERO, REG_ITMP1, d, REG); /* REG_ITMP1 != 0 */
3157 s2 = super->vftbl->diffval;
3158 M_BEQZ(s1, 4 + (s2 > 255));
3159 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3160 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3161 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3163 M_CMPULE(REG_ITMP1, s2, d, CONST);
3165 M_LDA(REG_ITMP2, REG_ZERO, s2);
3166 M_CMPULE(REG_ITMP1, REG_ITMP2, d, REG);
3171 panic ("internal error: no inlined array instanceof");
3173 store_reg_to_var_int(iptr->dst, d);
3176 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3178 /* op1: 0 == array, 1 == class */
3179 /* val.a: (classinfo*) superclass */
3181 /* superclass is an interface:
3183 * OK if ((sub == NULL) ||
3184 * (sub->vftbl->interfacetablelength > super->index) &&
3185 * (sub->vftbl->interfacetable[-super->index] != NULL));
3187 * superclass is a class:
3189 * OK if ((sub == NULL) || (0
3190 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3191 * super->vftbl->diffvall));
3195 classinfo *super = (classinfo*) iptr->val.a;
3197 d = reg_of_var(iptr->dst, REG_ITMP3);
3198 var_to_reg_int(s1, src, d);
3199 if (iptr->op1) { /* class/interface */
3200 if (super->flags & ACC_INTERFACE) { /* interface */
3202 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3203 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3204 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3205 M_BLEZ(REG_ITMP2, REG);
3206 mcode_addxcastrefs(mcodeptr);
3207 M_ALD(REG_ITMP2, REG_ITMP1,
3208 OFFSET(vftbl, interfacetable[0]) -
3209 super->index * sizeof(methodptr*));
3210 M_BEQZ(REG_ITMP2, REG);
3211 mcode_addxcastrefs(mcodeptr);
3214 s2 = super->vftbl->diffval;
3215 M_BEQZ(s1, 4 + (s2 != 0) + (s2 > 255));
3216 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3217 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3218 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3220 M_BNEZ(REG_ITMP1, REG);
3222 else if (s2 <= 255) {
3223 M_CMPULE(REG_ITMP1, s2, REG_ITMP2, CONST);
3224 M_BEQZ(REG_ITMP2, REG);
3227 M_LDA(REG_ITMP2, REG_ZERO, s2);
3228 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2, REG);
3229 M_BEQZ(REG_ITMP2, REG);
3231 mcode_addxcastrefs(mcodeptr);
3235 panic ("internal error: no inlined array checkcast");
3238 store_reg_to_var_int(iptr->dst, d);
3241 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
3243 var_to_reg_int(s1, src, REG_ITMP1);
3245 mcode_addxcheckarefs(mcodeptr);
3248 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3249 /* op1 = dimension, val.a = array descriptor */
3251 /* check for negative sizes and copy sizes to stack if necessary */
3253 MCODECHECK((iptr->op1 << 1) + 64);
3255 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3256 var_to_reg_int(s2, src, REG_ITMP1);
3258 mcode_addxcheckarefs(mcodeptr);
3260 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
3262 if (src->varkind != ARGVAR) {
3263 M_LST(s2, REG_SP, 8 * (s1 + INT_ARG_CNT));
3267 /* a0 = dimension count */
3269 M_LDA(argintregs[0], REG_ZERO, iptr->op1);
3271 /* a1 = arraydescriptor */
3273 a = dseg_addaddress(iptr->val.a);
3274 M_ALD(argintregs[1], REG_PV, a);
3276 /* a2 = pointer to dimensions = stack pointer */
3278 M_INTMOVE(REG_SP, argintregs[2]);
3280 a = dseg_addaddress((void*) (builtin_nmultianewarray));
3281 M_ALD(REG_PV, REG_PV, a);
3282 M_JSR(REG_RA, REG_PV);
3283 s1 = (int)((u1*) mcodeptr - mcodebase);
3285 M_LDA (REG_PV, REG_RA, -s1);
3287 s4 ml = -s1, mh = 0;
3288 while (ml < -32768) {ml += 65536; mh--;}
3289 M_LDA(REG_PV, REG_RA, ml);
3290 M_LDAH(REG_PV, REG_PV, mh);
3292 s1 = reg_of_var(iptr->dst, REG_RESULT);
3293 M_INTMOVE(REG_RESULT, s1);
3294 store_reg_to_var_int(iptr->dst, s1);
3298 default: sprintf (logtext, "Unknown pseudo command: %d", iptr->opc);
3301 } /* for instruction */
3303 /* copy values to interface registers */
3305 src = bptr->outstack;
3306 len = bptr->outdepth;
3310 if ((src->varkind != STACKVAR)) {
3312 if (IS_FLT_DBL_TYPE(s2)) {
3313 var_to_reg_flt(s1, src, REG_FTMP1);
3314 if (!(interfaces[len][s2].flags & INMEMORY)) {
3315 M_FLTMOVE(s1,interfaces[len][s2].regoff);
3318 M_DST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3322 var_to_reg_int(s1, src, REG_ITMP1);
3323 if (!(interfaces[len][s2].flags & INMEMORY)) {
3324 M_INTMOVE(s1,interfaces[len][s2].regoff);
3327 M_LST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3333 } /* if (bptr -> flags >= BBREACHED) */
3334 } /* for basic block */
3336 bptr -> mpc = (int)((u1*) mcodeptr - mcodebase);
3339 /* generate bound check stubs */
3341 s4 *xcodeptr = NULL;
3343 for (; xboundrefs != NULL; xboundrefs = xboundrefs->next) {
3344 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3345 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
3346 xboundrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3350 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
3351 xboundrefs->branchpos, (u1*) mcodeptr - mcodebase);
3355 M_LDA(REG_ITMP2_XPC, REG_PV, xboundrefs->branchpos);
3357 if (xcodeptr != NULL) {
3358 M_BR((xcodeptr-mcodeptr)-1);
3361 xcodeptr = mcodeptr;
3363 a = dseg_addaddress(proto_java_lang_ArrayIndexOutOfBoundsException);
3364 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3366 a = dseg_addaddress(asm_handle_exception);
3367 M_ALD(REG_ITMP3, REG_PV, a);
3369 M_JMP(REG_ZERO, REG_ITMP3);
3373 /* generate negative array size check stubs */
3377 for (; xcheckarefs != NULL; xcheckarefs = xcheckarefs->next) {
3378 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3379 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3380 xcheckarefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3384 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3385 xcheckarefs->branchpos, (u1*) mcodeptr - mcodebase);
3389 M_LDA(REG_ITMP2_XPC, REG_PV, xcheckarefs->branchpos);
3391 if (xcodeptr != NULL) {
3392 M_BR((xcodeptr-mcodeptr)-1);
3395 xcodeptr = mcodeptr;
3397 a = dseg_addaddress(proto_java_lang_NegativeArraySizeException);
3398 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3400 a = dseg_addaddress(asm_handle_exception);
3401 M_ALD(REG_ITMP3, REG_PV, a);
3403 M_JMP(REG_ZERO, REG_ITMP3);
3407 /* generate cast check stubs */
3411 for (; xcastrefs != NULL; xcastrefs = xcastrefs->next) {
3412 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3413 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3414 xcastrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3418 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3419 xcastrefs->branchpos, (u1*) mcodeptr - mcodebase);
3423 M_LDA(REG_ITMP2_XPC, REG_PV, xcastrefs->branchpos);
3425 if (xcodeptr != NULL) {
3426 M_BR((xcodeptr-mcodeptr)-1);
3429 xcodeptr = mcodeptr;
3431 a = dseg_addaddress(proto_java_lang_ClassCastException);
3432 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3434 a = dseg_addaddress(asm_handle_exception);
3435 M_ALD(REG_ITMP3, REG_PV, a);
3437 M_JMP(REG_ZERO, REG_ITMP3);
3442 #ifdef SOFTNULLPTRCHECK
3444 /* generate null pointer check stubs */
3448 for (; xnullrefs != NULL; xnullrefs = xnullrefs->next) {
3449 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3450 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3451 xnullrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3455 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3456 xnullrefs->branchpos, (u1*) mcodeptr - mcodebase);
3460 M_LDA(REG_ITMP2_XPC, REG_PV, xnullrefs->branchpos - 4);
3462 if (xcodeptr != NULL) {
3463 M_BR((xcodeptr-mcodeptr)-1);
3466 xcodeptr = mcodeptr;
3468 a = dseg_addaddress(proto_java_lang_NullPointerException);
3469 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3471 a = dseg_addaddress(asm_handle_exception);
3472 M_ALD(REG_ITMP3, REG_PV, a);
3474 M_JMP(REG_ZERO, REG_ITMP3);
3481 mcode_finish((int)((u1*) mcodeptr - mcodebase));
3485 /* redefinition of code generation macros (compiling into array) **************/
3488 These macros are newly defined to allow code generation into an array.
3489 This is necessary, because the original M_.. macros generate code by
3490 calling 'mcode_adds4' that uses an additional data structure to
3493 For a faster (but less flexible) version to generate code, these
3494 macros directly use the (s4* p) - pointer to put the code directly
3495 in a locally defined array.
3496 This makes sense only for the stub-generation-routines below.
3500 #define M_OP3(op,fu,a,b,c,const) \
3501 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<(16-3*(const)))| \
3502 ((const)<<12)|((fu)<<5)|((c)) )
3504 #define M_FOP3(op,fu,a,b,c) \
3505 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<16)|((fu)<<5)|(c) )
3507 #define M_BRA(op,a,disp) \
3508 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((disp)&0x1fffff) )
3510 #define M_MEM(op,a,b,disp) \
3511 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<16)|((disp)&0xffff) )
3514 /* function createcompilerstub *************************************************
3516 creates a stub routine which calls the compiler
3518 *******************************************************************************/
3520 #define COMPSTUBSIZE 3
3522 u1 *createcompilerstub (methodinfo *m)
3524 u8 *s = CNEW (u8, COMPSTUBSIZE); /* memory to hold the stub */
3525 s4 *p = (s4*) s; /* code generation pointer */
3527 /* code for the stub */
3528 M_ALD (REG_PV, REG_PV, 16); /* load pointer to the compiler */
3529 M_JMP (0, REG_PV); /* jump to the compiler, return address
3530 in reg 0 is used as method pointer */
3531 s[1] = (u8) m; /* literals to be adressed */
3532 s[2] = (u8) asm_call_jit_compiler; /* jump directly via PV from above */
3535 count_cstub_len += COMPSTUBSIZE * 8;
3542 /* function removecompilerstub *************************************************
3544 deletes a compilerstub from memory (simply by freeing it)
3546 *******************************************************************************/
3548 void removecompilerstub (u1 *stub)
3550 CFREE (stub, COMPSTUBSIZE * 8);
3554 /* function: ncreatenativestub *************************************************
3556 creates a stub routine which calls a native method
3558 *******************************************************************************/
3560 #define NATIVESTUBSIZE 11
3562 u1 *ncreatenativestub (functionptr f, methodinfo *m)
3564 u8 *s = CNEW (u8, NATIVESTUBSIZE); /* memory to hold the stub */
3565 s4 *p = (s4*) s; /* code generation pointer */
3567 M_LDA (REG_SP, REG_SP, -8); /* build up stackframe */
3568 M_AST (REG_RA, REG_SP, REG); /* store return address */
3570 M_ALD (REG_PV, REG_PV, 8*8); /* load adress of native method */
3571 M_JSR (REG_RA, REG_PV); /* call native method */
3573 M_LDA (REG_PV, REG_RA, -4*4); /* recompute pv from ra */
3574 M_ALD (REG_ITMP3, REG_PV, 9*8); /* get address of exceptionptr */
3576 M_ALD (REG_RA, REG_SP, REG); /* load return address */
3577 M_ALD (REG_ITMP1, REG_ITMP3, REG); /* load exception into reg. itmp1 */
3579 M_LDA (REG_SP, REG_SP, 8); /* remove stackframe */
3580 M_BNEZ (REG_ITMP1, CONST); /* if no exception then return */
3582 M_RET (REG_ZERO, REG_RA); /* return to caller */
3584 M_AST (REG_ZERO, REG_ITMP3, REG); /* store NULL into exceptionptr */
3585 M_LDA (REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
3587 M_ALD (REG_ITMP3, REG_PV,10*8); /* load asm exception handler address */
3588 M_JMP (REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
3591 s[8] = (u8) f; /* address of native method */
3592 s[9] = (u8) (&exceptionptr); /* address of exceptionptr */
3593 s[10]= (u8) (asm_handle_nat_exception); /* addr of asm exception handler */
3596 count_nstub_len += NATIVESTUBSIZE * 8;
3603 /* function: removenativestub **************************************************
3605 removes a previously created native-stub from memory
3607 *******************************************************************************/
3609 void removenativestub (u1 *stub)
3611 CFREE (stub, NATIVESTUBSIZE * 8);
3616 * These are local overrides for various environment variables in Emacs.
3617 * Please do not remove this and leave it at the end of the file, where
3618 * Emacs will automagically detect them.
3619 * ---------------------------------------------------------------------
3622 * indent-tabs-mode: t