1 /* jit/alpha/codegen.c - machine code generator for alpha
3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4 Institut f. Computersprachen, TU Wien
5 R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser, M. Probst,
6 S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich,
9 This file is part of CACAO.
11 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License as
13 published by the Free Software Foundation; either version 2, or (at
14 your option) any later version.
16 This program is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
26 Contact: cacao@complang.tuwien.ac.at
28 Authors: Andreas Krall
31 $Id: codegen.c 865 2004-01-07 19:09:47Z edwin $
51 /* include independent code generation stuff */
52 #include "codegen.inc"
56 /* *****************************************************************************
58 Datatypes and Register Allocations:
59 -----------------------------------
61 On 64-bit-machines (like the Alpha) all operands are stored in the
62 registers in a 64-bit form, even when the correspondig JavaVM operands
63 only need 32 bits. This is done by a canonical representation:
65 32-bit integers are allways stored as sign-extended 64-bit values (this
66 approach is directly supported by the Alpha architecture and is very easy
69 32-bit-floats are stored in a 64-bit doubleprecision register by simply
70 expanding the exponent and mantissa with zeroes. (also supported by the
76 The calling conventions and the layout of the stack is explained in detail
77 in the documention file: calling.doc
79 *******************************************************************************/
82 /* register descripton - array ************************************************/
84 /* #define REG_RES 0 reserved register for OS or code generator */
85 /* #define REG_RET 1 return value register */
86 /* #define REG_EXC 2 exception value register (only old jit) */
87 /* #define REG_SAV 3 (callee) saved register */
88 /* #define REG_TMP 4 scratch temporary register (caller saved) */
89 /* #define REG_ARG 5 argument register (caller saved) */
91 /* #define REG_END -1 last entry in tables */
94 REG_RET, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
95 REG_TMP, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
96 REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_TMP, REG_TMP,
97 REG_TMP, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES,
100 /* for use of reserved registers, see comment above */
102 int nregdescfloat[] = {
103 REG_RET, REG_TMP, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
104 REG_SAV, REG_SAV, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
105 REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_TMP, REG_TMP,
106 REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_RES, REG_RES, REG_RES, REG_RES,
109 /* for use of reserved registers, see comment above */
112 /* parameter allocation mode */
114 int nreg_parammode = PARAMMODE_NUMBERED;
116 /* parameter-registers will be allocated by assigning the
117 1. parameter: int/float-reg 16
118 2. parameter: int/float-reg 17
119 3. parameter: int/float-reg 18 ....
123 /* stackframe-infos ***********************************************************/
125 int parentargs_base; /* offset in stackframe for the parameter from the caller*/
127 /* -> see file 'calling.doc' */
130 /* additional functions and macros to generate code ***************************/
132 /* #define BlockPtrOfPC(pc) block+block_index[pc] */
133 #define BlockPtrOfPC(pc) ((basicblock *) iptr->target)
137 #define COUNT_SPILLS count_spills++
143 /* gen_nullptr_check(objreg) */
145 #ifdef SOFTNULLPTRCHECK
146 #define gen_nullptr_check(objreg) \
148 M_BEQZ((objreg), 0);\
149 codegen_addxnullrefs(mcodeptr);\
152 #define gen_nullptr_check(objreg)
156 /* MCODECHECK(icnt) */
158 #define MCODECHECK(icnt) \
159 if((mcodeptr + (icnt)) > mcodeend) mcodeptr = codegen_increase((u1*) mcodeptr)
162 generates an integer-move from register a to b.
163 if a and b are the same int-register, no code will be generated.
166 #define M_INTMOVE(a,b) if(a!=b){M_MOV(a,b);}
170 generates a floating-point-move from register a to b.
171 if a and b are the same float-register, no code will be generated
174 #define M_FLTMOVE(a,b) if(a!=b){M_FMOV(a,b);}
178 this function generates code to fetch data from a pseudo-register
179 into a real register.
180 If the pseudo-register has actually been assigned to a real
181 register, no code will be emitted, since following operations
182 can use this register directly.
184 v: pseudoregister to be fetched from
185 tempregnum: temporary register to be used if v is actually spilled to ram
187 return: the register number, where the operand can be found after
188 fetching (this wil be either tempregnum or the register
189 number allready given to v)
192 #define var_to_reg_int(regnr,v,tempnr) { \
193 if ((v)->flags & INMEMORY) \
194 {COUNT_SPILLS;M_LLD(tempnr,REG_SP,8*(v)->regoff);regnr=tempnr;} \
195 else regnr=(v)->regoff; \
199 #define var_to_reg_flt(regnr,v,tempnr) { \
200 if ((v)->flags & INMEMORY) \
201 {COUNT_SPILLS;M_DLD(tempnr,REG_SP,8*(v)->regoff);regnr=tempnr;} \
202 else regnr=(v)->regoff; \
207 This function determines a register, to which the result of an operation
208 should go, when it is ultimatively intended to store the result in
210 If v is assigned to an actual register, this register will be returned.
211 Otherwise (when v is spilled) this function returns tempregnum.
212 If not already done, regoff and flags are set in the stack location.
215 static int reg_of_var(stackptr v, int tempregnum)
219 switch (v->varkind) {
221 if (!(v->flags & INMEMORY))
225 var = &(interfaces[v->varnum][v->type]);
226 v->regoff = var->regoff;
227 if (!(var->flags & INMEMORY))
231 var = &(locals[v->varnum][v->type]);
232 v->regoff = var->regoff;
233 if (!(var->flags & INMEMORY))
237 v->regoff = v->varnum;
238 if (IS_FLT_DBL_TYPE(v->type)) {
239 if (v->varnum < fltreg_argnum) {
240 v->regoff = argfltregs[v->varnum];
241 return(argfltregs[v->varnum]);
245 if (v->varnum < intreg_argnum) {
246 v->regoff = argintregs[v->varnum];
247 return(argintregs[v->varnum]);
249 v->regoff -= intreg_argnum;
252 v->flags |= INMEMORY;
257 /* store_reg_to_var_xxx:
258 This function generates the code to store the result of an operation
259 back into a spilled pseudo-variable.
260 If the pseudo-variable has not been spilled in the first place, this
261 function will generate nothing.
263 v ............ Pseudovariable
264 tempregnum ... Number of the temporary registers as returned by
268 #define store_reg_to_var_int(sptr, tempregnum) { \
269 if ((sptr)->flags & INMEMORY) { \
271 M_LST(tempregnum, REG_SP, 8 * (sptr)->regoff); \
275 #define store_reg_to_var_flt(sptr, tempregnum) { \
276 if ((sptr)->flags & INMEMORY) { \
278 M_DST(tempregnum, REG_SP, 8 * (sptr)->regoff); \
283 /* NullPointerException handlers and exception handling initialisation */
285 typedef struct sigctx_struct {
287 long sc_onstack; /* sigstack state to restore */
288 long sc_mask; /* signal mask to restore */
289 long sc_pc; /* pc at time of signal */
290 long sc_ps; /* psl to retore */
291 long sc_regs[32]; /* processor regs 0 to 31 */
292 long sc_ownedfp; /* fp has been used */
293 long sc_fpregs[32]; /* fp regs 0 to 31 */
294 unsigned long sc_fpcr; /* floating point control register */
295 unsigned long sc_fp_control; /* software fpcr */
297 unsigned long sc_reserved1, sc_reserved2;
298 unsigned long sc_ssize;
300 unsigned long sc_traparg_a0;
301 unsigned long sc_traparg_a1;
302 unsigned long sc_traparg_a2;
303 unsigned long sc_fp_trap_pc;
304 unsigned long sc_fp_trigger_sum;
305 unsigned long sc_fp_trigger_inst;
306 unsigned long sc_retcode[2];
310 /* NullPointerException signal handler for hardware null pointer check */
312 void catch_NullPointerException(int sig, int code, sigctx_struct *sigctx)
318 /* Reset signal handler - necessary for SysV, does no harm for BSD */
320 instr = *((int*)(sigctx->sc_pc));
321 faultaddr = sigctx->sc_regs[(instr >> 16) & 0x1f];
323 if (faultaddr == 0) {
324 signal(sig, (void*) catch_NullPointerException); /* reinstall handler */
326 sigaddset(&nsig, sig);
327 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
328 sigctx->sc_regs[REG_ITMP1_XPTR] =
329 (long) proto_java_lang_NullPointerException;
330 sigctx->sc_regs[REG_ITMP2_XPC] = sigctx->sc_pc;
331 sigctx->sc_pc = (long) asm_handle_exception;
335 faultaddr += (long) ((instr << 16) >> 16);
336 fprintf(stderr, "faulting address: 0x%16lx\n", faultaddr);
337 panic("Stack overflow");
344 void init_exceptions(void)
349 /* Linux on Digital Alpha needs an initialisation of the ieee floating point
350 control for IEEE compliant arithmetic (option -mieee of GCC). Under
351 Digital Unix this is done automatically.
356 extern unsigned long ieee_get_fp_control();
357 extern void ieee_set_fp_control(unsigned long fp_control);
359 void init_exceptions(void)
361 /* initialize floating point control */
363 ieee_set_fp_control(ieee_get_fp_control()
364 & ~IEEE_TRAP_ENABLE_INV
365 & ~IEEE_TRAP_ENABLE_DZE
366 /* & ~IEEE_TRAP_ENABLE_UNF we dont want underflow */
367 & ~IEEE_TRAP_ENABLE_OVF);
370 /* install signal handlers we need to convert to exceptions */
375 signal(SIGSEGV, (void*) catch_NullPointerException);
379 signal(SIGBUS, (void*) catch_NullPointerException);
385 /* function gen_mcode **********************************************************
387 generates machine code
389 *******************************************************************************/
391 #define MethodPointer -8
392 #define FrameSize -12
397 #define ExTableSize -32
398 #define ExTableStart -32
400 #define ExEntrySize -32
403 #define ExHandlerPC -24
404 #define ExCatchType -32
408 int len, s1, s2, s3, d;
420 savedregs_num = (isleafmethod) ? 0 : 1; /* space to save the RA */
422 /* space to save used callee saved registers */
424 savedregs_num += (savintregcnt - maxsavintreguse);
425 savedregs_num += (savfltregcnt - maxsavfltreguse);
427 parentargs_base = maxmemuse + savedregs_num;
429 #ifdef USE_THREADS /* space to save argument of monitor_enter */
431 if (checksync && (method->flags & ACC_SYNCHRONIZED))
436 /* create method header */
438 (void) dseg_addaddress(method); /* MethodPointer */
439 (void) dseg_adds4(parentargs_base * 8); /* FrameSize */
443 /* IsSync contains the offset relative to the stack pointer for the
444 argument of monitor_exit used in the exception handler. Since the
445 offset could be zero and give a wrong meaning of the flag it is
449 if (checksync && (method->flags & ACC_SYNCHRONIZED))
450 (void) dseg_adds4((maxmemuse + 1) * 8); /* IsSync */
455 (void) dseg_adds4(0); /* IsSync */
457 (void) dseg_adds4(isleafmethod); /* IsLeaf */
458 (void) dseg_adds4(savintregcnt - maxsavintreguse); /* IntSave */
459 (void) dseg_adds4(savfltregcnt - maxsavfltreguse); /* FltSave */
460 (void) dseg_adds4(exceptiontablelength); /* ExTableSize */
462 /* create exception table */
464 for (ex = extable; ex != NULL; ex = ex->down) {
467 if (ex->start != NULL)
468 printf("adding start - %d - ", ex->start->debug_nr);
470 printf("PANIC - start is NULL");
475 dseg_addtarget(ex->start);
479 printf("adding end - %d - ", ex->end->debug_nr);
481 printf("PANIC - end is NULL");
486 dseg_addtarget(ex->end);
489 if (ex->handler != NULL)
490 printf("adding handler - %d\n", ex->handler->debug_nr);
492 printf("PANIC - handler is NULL");
497 dseg_addtarget(ex->handler);
499 (void) dseg_addaddress(ex->catchtype);
502 /* initialize mcode variables */
504 mcodeptr = (s4*) mcodebase;
505 mcodeend = (s4*) (mcodebase + mcodesize);
506 MCODECHECK(128 + mparamcount);
508 /* create stack frame (if necessary) */
511 {M_LDA (REG_SP, REG_SP, -parentargs_base * 8);}
513 /* save return address and used callee saved registers */
517 {p--; M_AST (REG_RA, REG_SP, 8*p);}
518 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
519 {p--; M_LST (savintregs[r], REG_SP, 8 * p);}
520 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
521 {p--; M_DST (savfltregs[r], REG_SP, 8 * p);}
523 /* save monitorenter argument */
526 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
527 if (method->flags & ACC_STATIC) {
528 p = dseg_addaddress (class);
529 M_ALD(REG_ITMP1, REG_PV, p);
530 M_AST(REG_ITMP1, REG_SP, 8 * maxmemuse);
533 M_AST (argintregs[0], REG_SP, 8 * maxmemuse);
538 /* copy argument registers to stack and call trace function with pointer
539 to arguments on stack. ToDo: save floating point registers !!!!!!!!!
544 M_LDA (REG_SP, REG_SP, -(14*8));
545 M_AST(REG_RA, REG_SP, 1*8);
547 M_LST(argintregs[0], REG_SP, 2*8);
548 M_LST(argintregs[1], REG_SP, 3*8);
549 M_LST(argintregs[2], REG_SP, 4*8);
550 M_LST(argintregs[3], REG_SP, 5*8);
551 M_LST(argintregs[4], REG_SP, 6*8);
552 M_LST(argintregs[5], REG_SP, 7*8);
554 M_DST(argfltregs[0], REG_SP, 8*8);
555 M_DST(argfltregs[1], REG_SP, 9*8);
556 M_DST(argfltregs[2], REG_SP, 10*8);
557 M_DST(argfltregs[3], REG_SP, 11*8);
558 M_DST(argfltregs[4], REG_SP, 12*8);
559 M_DST(argfltregs[5], REG_SP, 13*8);
561 p = dseg_addaddress (method);
562 M_ALD(REG_ITMP1, REG_PV, p);
563 M_AST(REG_ITMP1, REG_SP, 0);
564 p = dseg_addaddress ((void*) (builtin_trace_args));
565 M_ALD(REG_PV, REG_PV, p);
566 M_JSR(REG_RA, REG_PV);
567 disp = -(int)((u1*) mcodeptr - mcodebase);
568 M_LDA(REG_PV, REG_RA, disp);
569 M_ALD(REG_RA, REG_SP, 1*8);
571 M_LLD(argintregs[0], REG_SP, 2*8);
572 M_LLD(argintregs[1], REG_SP, 3*8);
573 M_LLD(argintregs[2], REG_SP, 4*8);
574 M_LLD(argintregs[3], REG_SP, 5*8);
575 M_LLD(argintregs[4], REG_SP, 6*8);
576 M_LLD(argintregs[5], REG_SP, 7*8);
578 M_DLD(argfltregs[0], REG_SP, 8*8);
579 M_DLD(argfltregs[1], REG_SP, 9*8);
580 M_DLD(argfltregs[2], REG_SP, 10*8);
581 M_DLD(argfltregs[3], REG_SP, 11*8);
582 M_DLD(argfltregs[4], REG_SP, 12*8);
583 M_DLD(argfltregs[5], REG_SP, 13*8);
585 M_LDA (REG_SP, REG_SP, 14*8);
588 /* take arguments out of register or stack frame */
590 for (p = 0, l = 0; p < mparamcount; p++) {
592 var = &(locals[l][t]);
594 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
599 if (IS_INT_LNG_TYPE(t)) { /* integer args */
600 if (p < INT_ARG_CNT) { /* register arguments */
601 if (!(var->flags & INMEMORY)) /* reg arg -> register */
602 {M_INTMOVE (argintregs[p], r);}
603 else /* reg arg -> spilled */
604 M_LST (argintregs[p], REG_SP, 8 * r);
606 else { /* stack arguments */
607 pa = p - INT_ARG_CNT;
608 if (!(var->flags & INMEMORY)) /* stack arg -> register */
609 M_LLD (r, REG_SP, 8 * (parentargs_base + pa));
610 else { /* stack arg -> spilled */
611 M_LLD (REG_ITMP1, REG_SP, 8 * (parentargs_base + pa));
612 M_LST (REG_ITMP1, REG_SP, 8 * r);
616 else { /* floating args */
617 if (p < FLT_ARG_CNT) { /* register arguments */
618 if (!(var->flags & INMEMORY)) /* reg arg -> register */
619 {M_FLTMOVE (argfltregs[p], r);}
620 else /* reg arg -> spilled */
621 M_DST (argfltregs[p], REG_SP, 8 * r);
623 else { /* stack arguments */
624 pa = p - FLT_ARG_CNT;
625 if (!(var->flags & INMEMORY)) /* stack-arg -> register */
626 M_DLD (r, REG_SP, 8 * (parentargs_base + pa) );
627 else { /* stack-arg -> spilled */
628 M_DLD (REG_FTMP1, REG_SP, 8 * (parentargs_base + pa));
629 M_DST (REG_FTMP1, REG_SP, 8 * r);
635 /* call trace function */
638 if (runverbose && !isleafmethod) {
639 M_LDA (REG_SP, REG_SP, -8);
640 p = dseg_addaddress (method);
641 M_ALD(REG_ITMP1, REG_PV, p);
642 M_AST(REG_ITMP1, REG_SP, 0);
643 p = dseg_addaddress ((void*) (builtin_trace_args));
644 M_ALD(REG_PV, REG_PV, p);
645 M_JSR(REG_RA, REG_PV);
646 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
647 M_LDA(REG_SP, REG_SP, 8);
651 /* call monitorenter function */
654 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
656 p = dseg_addaddress ((void*) (builtin_monitorenter));
657 M_ALD(REG_PV, REG_PV, p);
658 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
659 M_JSR(REG_RA, REG_PV);
660 disp = -(int)((u1*) mcodeptr - mcodebase);
661 M_LDA(REG_PV, REG_RA, disp);
666 /* end of header generation */
668 /* walk through all basic blocks */
669 for (bptr = block; bptr != NULL; bptr = bptr->next) {
671 bptr->mpc = (int)((u1*) mcodeptr - mcodebase);
673 if (bptr->flags >= BBREACHED) {
675 /* branch resolving */
679 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
680 gen_resolvebranch((u1*) mcodebase + brefs->branchpos,
681 brefs->branchpos, bptr->mpc);
685 /* copy interface registers to their destination */
690 while (src != NULL) {
692 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
693 d = reg_of_var(src, REG_ITMP1);
694 M_INTMOVE(REG_ITMP1, d);
695 store_reg_to_var_int(src, d);
698 d = reg_of_var(src, REG_IFTMP);
699 if ((src->varkind != STACKVAR)) {
701 if (IS_FLT_DBL_TYPE(s2)) {
702 if (!(interfaces[len][s2].flags & INMEMORY)) {
703 s1 = interfaces[len][s2].regoff;
707 M_DLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
709 store_reg_to_var_flt(src, d);
712 if (!(interfaces[len][s2].flags & INMEMORY)) {
713 s1 = interfaces[len][s2].regoff;
717 M_LLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
719 store_reg_to_var_int(src, d);
726 /* walk through all instructions */
730 for (iptr = bptr->iinstr;
732 src = iptr->dst, len--, iptr++) {
734 MCODECHECK(64); /* an instruction usually needs < 64 words */
737 case ICMD_NOP: /* ... ==> ... */
740 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
742 var_to_reg_int(s1, src, REG_ITMP1);
744 codegen_addxnullrefs(mcodeptr);
747 /* constant operations ************************************************/
749 #define ICONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
750 else{a=dseg_adds4(c);M_ILD(r,REG_PV,a);}
752 #define LCONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
753 else{a=dseg_adds8(c);M_LLD(r,REG_PV,a);}
755 case ICMD_ICONST: /* ... ==> ..., constant */
756 /* op1 = 0, val.i = constant */
758 d = reg_of_var(iptr->dst, REG_ITMP1);
759 ICONST(d, iptr->val.i);
760 store_reg_to_var_int(iptr->dst, d);
763 case ICMD_LCONST: /* ... ==> ..., constant */
764 /* op1 = 0, val.l = constant */
766 d = reg_of_var(iptr->dst, REG_ITMP1);
767 LCONST(d, iptr->val.l);
768 store_reg_to_var_int(iptr->dst, d);
771 case ICMD_FCONST: /* ... ==> ..., constant */
772 /* op1 = 0, val.f = constant */
774 d = reg_of_var (iptr->dst, REG_FTMP1);
775 a = dseg_addfloat (iptr->val.f);
777 store_reg_to_var_flt (iptr->dst, d);
780 case ICMD_DCONST: /* ... ==> ..., constant */
781 /* op1 = 0, val.d = constant */
783 d = reg_of_var (iptr->dst, REG_FTMP1);
784 a = dseg_adddouble (iptr->val.d);
786 store_reg_to_var_flt (iptr->dst, d);
789 case ICMD_ACONST: /* ... ==> ..., constant */
790 /* op1 = 0, val.a = constant */
792 d = reg_of_var(iptr->dst, REG_ITMP1);
794 a = dseg_addaddress (iptr->val.a);
798 M_INTMOVE(REG_ZERO, d);
800 store_reg_to_var_int(iptr->dst, d);
804 /* load/store operations **********************************************/
806 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
807 case ICMD_LLOAD: /* op1 = local variable */
810 d = reg_of_var(iptr->dst, REG_ITMP1);
811 if ((iptr->dst->varkind == LOCALVAR) &&
812 (iptr->dst->varnum == iptr->op1))
814 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
815 if (var->flags & INMEMORY)
816 M_LLD(d, REG_SP, 8 * var->regoff);
818 {M_INTMOVE(var->regoff,d);}
819 store_reg_to_var_int(iptr->dst, d);
822 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
823 case ICMD_DLOAD: /* op1 = local variable */
825 d = reg_of_var(iptr->dst, REG_FTMP1);
826 if ((iptr->dst->varkind == LOCALVAR) &&
827 (iptr->dst->varnum == iptr->op1))
829 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
830 if (var->flags & INMEMORY)
831 M_DLD(d, REG_SP, 8 * var->regoff);
833 {M_FLTMOVE(var->regoff,d);}
834 store_reg_to_var_flt(iptr->dst, d);
838 case ICMD_ISTORE: /* ..., value ==> ... */
839 case ICMD_LSTORE: /* op1 = local variable */
842 if ((src->varkind == LOCALVAR) &&
843 (src->varnum == iptr->op1))
845 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
846 if (var->flags & INMEMORY) {
847 var_to_reg_int(s1, src, REG_ITMP1);
848 M_LST(s1, REG_SP, 8 * var->regoff);
851 var_to_reg_int(s1, src, var->regoff);
852 M_INTMOVE(s1, var->regoff);
856 case ICMD_FSTORE: /* ..., value ==> ... */
857 case ICMD_DSTORE: /* op1 = local variable */
859 if ((src->varkind == LOCALVAR) &&
860 (src->varnum == iptr->op1))
862 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
863 if (var->flags & INMEMORY) {
864 var_to_reg_flt(s1, src, REG_FTMP1);
865 M_DST(s1, REG_SP, 8 * var->regoff);
868 var_to_reg_flt(s1, src, var->regoff);
869 M_FLTMOVE(s1, var->regoff);
874 /* pop/dup/swap operations ********************************************/
876 /* attention: double and longs are only one entry in CACAO ICMDs */
878 case ICMD_POP: /* ..., value ==> ... */
879 case ICMD_POP2: /* ..., value, value ==> ... */
882 #define M_COPY(from,to) \
883 d = reg_of_var(to, REG_IFTMP); \
884 if ((from->regoff != to->regoff) || \
885 ((from->flags ^ to->flags) & INMEMORY)) { \
886 if (IS_FLT_DBL_TYPE(from->type)) { \
887 var_to_reg_flt(s1, from, d); \
889 store_reg_to_var_flt(to, d); \
892 var_to_reg_int(s1, from, d); \
894 store_reg_to_var_int(to, d); \
898 case ICMD_DUP: /* ..., a ==> ..., a, a */
899 M_COPY(src, iptr->dst);
902 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
904 M_COPY(src, iptr->dst->prev->prev);
906 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
908 M_COPY(src, iptr->dst);
909 M_COPY(src->prev, iptr->dst->prev);
912 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
914 M_COPY(src->prev, iptr->dst->prev->prev->prev);
916 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
918 M_COPY(src, iptr->dst);
919 M_COPY(src->prev, iptr->dst->prev);
920 M_COPY(src->prev->prev, iptr->dst->prev->prev);
921 M_COPY(src, iptr->dst->prev->prev->prev);
924 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
926 M_COPY(src, iptr->dst);
927 M_COPY(src->prev, iptr->dst->prev);
928 M_COPY(src->prev->prev, iptr->dst->prev->prev);
929 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
930 M_COPY(src, iptr->dst->prev->prev->prev->prev);
931 M_COPY(src->prev, iptr->dst->prev->prev->prev->prev->prev);
934 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
936 M_COPY(src, iptr->dst->prev);
937 M_COPY(src->prev, iptr->dst);
941 /* integer operations *************************************************/
943 case ICMD_INEG: /* ..., value ==> ..., - value */
945 var_to_reg_int(s1, src, REG_ITMP1);
946 d = reg_of_var(iptr->dst, REG_ITMP3);
947 M_ISUB(REG_ZERO, s1, d);
948 store_reg_to_var_int(iptr->dst, d);
951 case ICMD_LNEG: /* ..., value ==> ..., - value */
953 var_to_reg_int(s1, src, REG_ITMP1);
954 d = reg_of_var(iptr->dst, REG_ITMP3);
955 M_LSUB(REG_ZERO, s1, d);
956 store_reg_to_var_int(iptr->dst, d);
959 case ICMD_I2L: /* ..., value ==> ..., value */
961 var_to_reg_int(s1, src, REG_ITMP1);
962 d = reg_of_var(iptr->dst, REG_ITMP3);
964 store_reg_to_var_int(iptr->dst, d);
967 case ICMD_L2I: /* ..., value ==> ..., value */
969 var_to_reg_int(s1, src, REG_ITMP1);
970 d = reg_of_var(iptr->dst, REG_ITMP3);
971 M_IADD(s1, REG_ZERO, d );
972 store_reg_to_var_int(iptr->dst, d);
975 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
977 var_to_reg_int(s1, src, REG_ITMP1);
978 d = reg_of_var(iptr->dst, REG_ITMP3);
979 if (has_ext_instr_set) {
983 M_SLL_IMM(s1, 56, d);
984 M_SRA_IMM( d, 56, d);
986 store_reg_to_var_int(iptr->dst, d);
989 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
991 var_to_reg_int(s1, src, REG_ITMP1);
992 d = reg_of_var(iptr->dst, REG_ITMP3);
994 store_reg_to_var_int(iptr->dst, d);
997 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
999 var_to_reg_int(s1, src, REG_ITMP1);
1000 d = reg_of_var(iptr->dst, REG_ITMP3);
1001 if (has_ext_instr_set) {
1005 M_SLL_IMM(s1, 48, d);
1006 M_SRA_IMM( d, 48, d);
1008 store_reg_to_var_int(iptr->dst, d);
1012 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1014 var_to_reg_int(s1, src->prev, REG_ITMP1);
1015 var_to_reg_int(s2, src, REG_ITMP2);
1016 d = reg_of_var(iptr->dst, REG_ITMP3);
1018 store_reg_to_var_int(iptr->dst, d);
1021 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
1022 /* val.i = constant */
1024 var_to_reg_int(s1, src, REG_ITMP1);
1025 d = reg_of_var(iptr->dst, REG_ITMP3);
1026 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1027 M_IADD_IMM(s1, iptr->val.i, d);
1030 ICONST(REG_ITMP2, iptr->val.i);
1031 M_IADD(s1, REG_ITMP2, d);
1033 store_reg_to_var_int(iptr->dst, d);
1036 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1038 var_to_reg_int(s1, src->prev, REG_ITMP1);
1039 var_to_reg_int(s2, src, REG_ITMP2);
1040 d = reg_of_var(iptr->dst, REG_ITMP3);
1042 store_reg_to_var_int(iptr->dst, d);
1045 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
1046 /* val.l = constant */
1048 var_to_reg_int(s1, src, REG_ITMP1);
1049 d = reg_of_var(iptr->dst, REG_ITMP3);
1050 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1051 M_LADD_IMM(s1, iptr->val.l, d);
1054 LCONST(REG_ITMP2, iptr->val.l);
1055 M_LADD(s1, REG_ITMP2, d);
1057 store_reg_to_var_int(iptr->dst, d);
1060 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1062 var_to_reg_int(s1, src->prev, REG_ITMP1);
1063 var_to_reg_int(s2, src, REG_ITMP2);
1064 d = reg_of_var(iptr->dst, REG_ITMP3);
1066 store_reg_to_var_int(iptr->dst, d);
1069 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
1070 /* val.i = constant */
1072 var_to_reg_int(s1, src, REG_ITMP1);
1073 d = reg_of_var(iptr->dst, REG_ITMP3);
1074 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1075 M_ISUB_IMM(s1, iptr->val.i, d);
1078 ICONST(REG_ITMP2, iptr->val.i);
1079 M_ISUB(s1, REG_ITMP2, d);
1081 store_reg_to_var_int(iptr->dst, d);
1084 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1086 var_to_reg_int(s1, src->prev, REG_ITMP1);
1087 var_to_reg_int(s2, src, REG_ITMP2);
1088 d = reg_of_var(iptr->dst, REG_ITMP3);
1090 store_reg_to_var_int(iptr->dst, d);
1093 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
1094 /* val.l = constant */
1096 var_to_reg_int(s1, src, REG_ITMP1);
1097 d = reg_of_var(iptr->dst, REG_ITMP3);
1098 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1099 M_LSUB_IMM(s1, iptr->val.l, d);
1102 LCONST(REG_ITMP2, iptr->val.l);
1103 M_LSUB(s1, REG_ITMP2, d);
1105 store_reg_to_var_int(iptr->dst, d);
1108 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1110 var_to_reg_int(s1, src->prev, REG_ITMP1);
1111 var_to_reg_int(s2, src, REG_ITMP2);
1112 d = reg_of_var(iptr->dst, REG_ITMP3);
1114 store_reg_to_var_int(iptr->dst, d);
1117 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
1118 /* val.i = constant */
1120 var_to_reg_int(s1, src, REG_ITMP1);
1121 d = reg_of_var(iptr->dst, REG_ITMP3);
1122 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1123 M_IMUL_IMM(s1, iptr->val.i, d);
1126 ICONST(REG_ITMP2, iptr->val.i);
1127 M_IMUL(s1, REG_ITMP2, d);
1129 store_reg_to_var_int(iptr->dst, d);
1132 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1134 var_to_reg_int(s1, src->prev, REG_ITMP1);
1135 var_to_reg_int(s2, src, REG_ITMP2);
1136 d = reg_of_var(iptr->dst, REG_ITMP3);
1138 store_reg_to_var_int(iptr->dst, d);
1141 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
1142 /* val.l = constant */
1144 var_to_reg_int(s1, src, REG_ITMP1);
1145 d = reg_of_var(iptr->dst, REG_ITMP3);
1146 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1147 M_LMUL_IMM(s1, iptr->val.l, d);
1150 LCONST(REG_ITMP2, iptr->val.l);
1151 M_LMUL(s1, REG_ITMP2, d);
1153 store_reg_to_var_int(iptr->dst, d);
1156 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
1157 case ICMD_LDIVPOW2: /* val.i = constant */
1159 var_to_reg_int(s1, src, REG_ITMP1);
1160 d = reg_of_var(iptr->dst, REG_ITMP3);
1161 if (iptr->val.i <= 15) {
1162 M_LDA(REG_ITMP2, s1, (1 << iptr->val.i) -1);
1163 M_CMOVGE(s1, s1, REG_ITMP2);
1166 M_SRA_IMM(s1, 63, REG_ITMP2);
1167 M_SRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
1168 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1170 M_SRA_IMM(REG_ITMP2, iptr->val.i, d);
1171 store_reg_to_var_int(iptr->dst, d);
1174 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1176 var_to_reg_int(s1, src->prev, REG_ITMP1);
1177 var_to_reg_int(s2, src, REG_ITMP2);
1178 d = reg_of_var(iptr->dst, REG_ITMP3);
1179 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1180 M_SLL(s1, REG_ITMP3, d);
1181 M_IADD(d, REG_ZERO, d);
1182 store_reg_to_var_int(iptr->dst, d);
1185 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1186 /* val.i = constant */
1188 var_to_reg_int(s1, src, REG_ITMP1);
1189 d = reg_of_var(iptr->dst, REG_ITMP3);
1190 M_SLL_IMM(s1, iptr->val.i & 0x1f, d);
1191 M_IADD(d, REG_ZERO, d);
1192 store_reg_to_var_int(iptr->dst, d);
1195 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1197 var_to_reg_int(s1, src->prev, REG_ITMP1);
1198 var_to_reg_int(s2, src, REG_ITMP2);
1199 d = reg_of_var(iptr->dst, REG_ITMP3);
1200 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1201 M_SRA(s1, REG_ITMP3, d);
1202 store_reg_to_var_int(iptr->dst, d);
1205 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1206 /* val.i = constant */
1208 var_to_reg_int(s1, src, REG_ITMP1);
1209 d = reg_of_var(iptr->dst, REG_ITMP3);
1210 M_SRA_IMM(s1, iptr->val.i & 0x1f, d);
1211 store_reg_to_var_int(iptr->dst, d);
1214 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1216 var_to_reg_int(s1, src->prev, REG_ITMP1);
1217 var_to_reg_int(s2, src, REG_ITMP2);
1218 d = reg_of_var(iptr->dst, REG_ITMP3);
1219 M_AND_IMM(s2, 0x1f, REG_ITMP2);
1221 M_SRL(d, REG_ITMP2, d);
1222 M_IADD(d, REG_ZERO, d);
1223 store_reg_to_var_int(iptr->dst, d);
1226 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1227 /* val.i = constant */
1229 var_to_reg_int(s1, src, REG_ITMP1);
1230 d = reg_of_var(iptr->dst, REG_ITMP3);
1232 M_SRL_IMM(d, iptr->val.i & 0x1f, d);
1233 M_IADD(d, REG_ZERO, d);
1234 store_reg_to_var_int(iptr->dst, d);
1237 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1239 var_to_reg_int(s1, src->prev, REG_ITMP1);
1240 var_to_reg_int(s2, src, REG_ITMP2);
1241 d = reg_of_var(iptr->dst, REG_ITMP3);
1243 store_reg_to_var_int(iptr->dst, d);
1246 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1247 /* val.i = constant */
1249 var_to_reg_int(s1, src, REG_ITMP1);
1250 d = reg_of_var(iptr->dst, REG_ITMP3);
1251 M_SLL_IMM(s1, iptr->val.i & 0x3f, d);
1252 store_reg_to_var_int(iptr->dst, d);
1255 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1257 var_to_reg_int(s1, src->prev, REG_ITMP1);
1258 var_to_reg_int(s2, src, REG_ITMP2);
1259 d = reg_of_var(iptr->dst, REG_ITMP3);
1261 store_reg_to_var_int(iptr->dst, d);
1264 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1265 /* val.i = constant */
1267 var_to_reg_int(s1, src, REG_ITMP1);
1268 d = reg_of_var(iptr->dst, REG_ITMP3);
1269 M_SRA_IMM(s1, iptr->val.i & 0x3f, d);
1270 store_reg_to_var_int(iptr->dst, d);
1273 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1275 var_to_reg_int(s1, src->prev, REG_ITMP1);
1276 var_to_reg_int(s2, src, REG_ITMP2);
1277 d = reg_of_var(iptr->dst, REG_ITMP3);
1279 store_reg_to_var_int(iptr->dst, d);
1282 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1283 /* val.i = constant */
1285 var_to_reg_int(s1, src, REG_ITMP1);
1286 d = reg_of_var(iptr->dst, REG_ITMP3);
1287 M_SRL_IMM(s1, iptr->val.i & 0x3f, d);
1288 store_reg_to_var_int(iptr->dst, d);
1291 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1294 var_to_reg_int(s1, src->prev, REG_ITMP1);
1295 var_to_reg_int(s2, src, REG_ITMP2);
1296 d = reg_of_var(iptr->dst, REG_ITMP3);
1298 store_reg_to_var_int(iptr->dst, d);
1301 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1302 /* val.i = constant */
1304 var_to_reg_int(s1, src, REG_ITMP1);
1305 d = reg_of_var(iptr->dst, REG_ITMP3);
1306 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1307 M_AND_IMM(s1, iptr->val.i, d);
1309 else if (iptr->val.i == 0xffff) {
1312 else if (iptr->val.i == 0xffffff) {
1313 M_ZAPNOT_IMM(s1, 0x07, d);
1316 ICONST(REG_ITMP2, iptr->val.i);
1317 M_AND(s1, REG_ITMP2, d);
1319 store_reg_to_var_int(iptr->dst, d);
1322 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1323 /* val.i = constant */
1325 var_to_reg_int(s1, src, REG_ITMP1);
1326 d = reg_of_var(iptr->dst, REG_ITMP3);
1328 M_MOV(s1, REG_ITMP1);
1331 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1332 M_AND_IMM(s1, iptr->val.i, d);
1334 M_ISUB(REG_ZERO, s1, d);
1335 M_AND_IMM(d, iptr->val.i, d);
1337 else if (iptr->val.i == 0xffff) {
1340 M_ISUB(REG_ZERO, s1, d);
1343 else if (iptr->val.i == 0xffffff) {
1344 M_ZAPNOT_IMM(s1, 0x07, d);
1346 M_ISUB(REG_ZERO, s1, d);
1347 M_ZAPNOT_IMM(d, 0x07, d);
1350 ICONST(REG_ITMP2, iptr->val.i);
1351 M_AND(s1, REG_ITMP2, d);
1353 M_ISUB(REG_ZERO, s1, d);
1354 M_AND(d, REG_ITMP2, d);
1356 M_ISUB(REG_ZERO, d, d);
1357 store_reg_to_var_int(iptr->dst, d);
1360 case ICMD_IREM0X10001: /* ..., value ==> ..., value % 0x100001 */
1362 /* b = value & 0xffff;
1364 a = ((b - a) & 0xffff) + (b < a);
1366 var_to_reg_int(s1, src, REG_ITMP1);
1367 d = reg_of_var(iptr->dst, REG_ITMP3);
1369 M_MOV(s1, REG_ITMP3);
1373 M_CZEXT(s1, REG_ITMP2);
1374 M_SRA_IMM(s1, 16, d);
1375 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1376 M_ISUB(REG_ITMP2, d, d);
1378 M_IADD(d, REG_ITMP1, d);
1379 M_BR(11 + (s1 == REG_ITMP1));
1380 M_ISUB(REG_ZERO, s1, REG_ITMP1);
1381 M_CZEXT(REG_ITMP1, REG_ITMP2);
1382 M_SRA_IMM(REG_ITMP1, 16, d);
1383 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1384 M_ISUB(REG_ITMP2, d, d);
1386 M_IADD(d, REG_ITMP1, d);
1387 M_ISUB(REG_ZERO, d, d);
1388 if (s1 == REG_ITMP1) {
1389 var_to_reg_int(s1, src, REG_ITMP1);
1391 M_SLL_IMM(s1, 33, REG_ITMP2);
1392 M_CMPEQ(REG_ITMP2, REG_ZERO, REG_ITMP2);
1393 M_ISUB(d, REG_ITMP2, d);
1394 store_reg_to_var_int(iptr->dst, d);
1397 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1398 /* val.l = constant */
1400 var_to_reg_int(s1, src, REG_ITMP1);
1401 d = reg_of_var(iptr->dst, REG_ITMP3);
1402 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1403 M_AND_IMM(s1, iptr->val.l, d);
1405 else if (iptr->val.l == 0xffffL) {
1408 else if (iptr->val.l == 0xffffffL) {
1409 M_ZAPNOT_IMM(s1, 0x07, d);
1411 else if (iptr->val.l == 0xffffffffL) {
1414 else if (iptr->val.l == 0xffffffffffL) {
1415 M_ZAPNOT_IMM(s1, 0x1f, d);
1417 else if (iptr->val.l == 0xffffffffffffL) {
1418 M_ZAPNOT_IMM(s1, 0x3f, d);
1420 else if (iptr->val.l == 0xffffffffffffffL) {
1421 M_ZAPNOT_IMM(s1, 0x7f, d);
1424 LCONST(REG_ITMP2, iptr->val.l);
1425 M_AND(s1, REG_ITMP2, d);
1427 store_reg_to_var_int(iptr->dst, d);
1430 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1431 /* val.l = constant */
1433 var_to_reg_int(s1, src, REG_ITMP1);
1434 d = reg_of_var(iptr->dst, REG_ITMP3);
1436 M_MOV(s1, REG_ITMP1);
1439 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1440 M_AND_IMM(s1, iptr->val.l, d);
1442 M_LSUB(REG_ZERO, s1, d);
1443 M_AND_IMM(d, iptr->val.l, d);
1445 else if (iptr->val.l == 0xffffL) {
1448 M_LSUB(REG_ZERO, s1, d);
1451 else if (iptr->val.l == 0xffffffL) {
1452 M_ZAPNOT_IMM(s1, 0x07, d);
1454 M_LSUB(REG_ZERO, s1, d);
1455 M_ZAPNOT_IMM(d, 0x07, d);
1457 else if (iptr->val.l == 0xffffffffL) {
1460 M_LSUB(REG_ZERO, s1, d);
1463 else if (iptr->val.l == 0xffffffffffL) {
1464 M_ZAPNOT_IMM(s1, 0x1f, d);
1466 M_LSUB(REG_ZERO, s1, d);
1467 M_ZAPNOT_IMM(d, 0x1f, d);
1469 else if (iptr->val.l == 0xffffffffffffL) {
1470 M_ZAPNOT_IMM(s1, 0x3f, d);
1472 M_LSUB(REG_ZERO, s1, d);
1473 M_ZAPNOT_IMM(d, 0x3f, d);
1475 else if (iptr->val.l == 0xffffffffffffffL) {
1476 M_ZAPNOT_IMM(s1, 0x7f, d);
1478 M_LSUB(REG_ZERO, s1, d);
1479 M_ZAPNOT_IMM(d, 0x7f, d);
1482 LCONST(REG_ITMP2, iptr->val.l);
1483 M_AND(s1, REG_ITMP2, d);
1485 M_LSUB(REG_ZERO, s1, d);
1486 M_AND(d, REG_ITMP2, d);
1488 M_LSUB(REG_ZERO, d, d);
1489 store_reg_to_var_int(iptr->dst, d);
1492 case ICMD_LREM0X10001:/* ..., value ==> ..., value % 0x10001 */
1494 var_to_reg_int(s1, src, REG_ITMP1);
1495 d = reg_of_var(iptr->dst, REG_ITMP3);
1497 M_MOV(s1, REG_ITMP3);
1500 M_CZEXT(s1, REG_ITMP2);
1501 M_SRA_IMM(s1, 16, d);
1502 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1503 M_LSUB(REG_ITMP2, d, d);
1505 M_LADD(d, REG_ITMP1, d);
1506 M_LDA(REG_ITMP2, REG_ZERO, -1);
1507 M_SRL_IMM(REG_ITMP2, 33, REG_ITMP2);
1508 if (s1 == REG_ITMP1) {
1509 var_to_reg_int(s1, src, REG_ITMP1);
1511 M_CMPULT(s1, REG_ITMP2, REG_ITMP2);
1512 M_BNEZ(REG_ITMP2, 11);
1513 M_LDA(d, REG_ZERO, -257);
1514 M_ZAPNOT_IMM(d, 0xcd, d);
1515 M_LSUB(REG_ZERO, s1, REG_ITMP2);
1516 M_CMOVGE(s1, s1, REG_ITMP2);
1517 M_UMULH(REG_ITMP2, d, REG_ITMP2);
1518 M_SRL_IMM(REG_ITMP2, 16, REG_ITMP2);
1519 M_LSUB(REG_ZERO, REG_ITMP2, d);
1520 M_CMOVGE(s1, REG_ITMP2, d);
1521 M_SLL_IMM(d, 16, REG_ITMP2);
1522 M_LADD(d, REG_ITMP2, d);
1524 store_reg_to_var_int(iptr->dst, d);
1527 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1530 var_to_reg_int(s1, src->prev, REG_ITMP1);
1531 var_to_reg_int(s2, src, REG_ITMP2);
1532 d = reg_of_var(iptr->dst, REG_ITMP3);
1534 store_reg_to_var_int(iptr->dst, d);
1537 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1538 /* val.i = constant */
1540 var_to_reg_int(s1, src, REG_ITMP1);
1541 d = reg_of_var(iptr->dst, REG_ITMP3);
1542 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1543 M_OR_IMM(s1, iptr->val.i, d);
1546 ICONST(REG_ITMP2, iptr->val.i);
1547 M_OR(s1, REG_ITMP2, d);
1549 store_reg_to_var_int(iptr->dst, d);
1552 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1553 /* val.l = constant */
1555 var_to_reg_int(s1, src, REG_ITMP1);
1556 d = reg_of_var(iptr->dst, REG_ITMP3);
1557 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1558 M_OR_IMM(s1, iptr->val.l, d);
1561 LCONST(REG_ITMP2, iptr->val.l);
1562 M_OR(s1, REG_ITMP2, d);
1564 store_reg_to_var_int(iptr->dst, d);
1567 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1570 var_to_reg_int(s1, src->prev, REG_ITMP1);
1571 var_to_reg_int(s2, src, REG_ITMP2);
1572 d = reg_of_var(iptr->dst, REG_ITMP3);
1574 store_reg_to_var_int(iptr->dst, d);
1577 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1578 /* val.i = constant */
1580 var_to_reg_int(s1, src, REG_ITMP1);
1581 d = reg_of_var(iptr->dst, REG_ITMP3);
1582 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1583 M_XOR_IMM(s1, iptr->val.i, d);
1586 ICONST(REG_ITMP2, iptr->val.i);
1587 M_XOR(s1, REG_ITMP2, d);
1589 store_reg_to_var_int(iptr->dst, d);
1592 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1593 /* val.l = constant */
1595 var_to_reg_int(s1, src, REG_ITMP1);
1596 d = reg_of_var(iptr->dst, REG_ITMP3);
1597 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1598 M_XOR_IMM(s1, iptr->val.l, d);
1601 LCONST(REG_ITMP2, iptr->val.l);
1602 M_XOR(s1, REG_ITMP2, d);
1604 store_reg_to_var_int(iptr->dst, d);
1608 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1610 var_to_reg_int(s1, src->prev, REG_ITMP1);
1611 var_to_reg_int(s2, src, REG_ITMP2);
1612 d = reg_of_var(iptr->dst, REG_ITMP3);
1613 M_CMPLT(s1, s2, REG_ITMP3);
1614 M_CMPLT(s2, s1, REG_ITMP1);
1615 M_LSUB (REG_ITMP1, REG_ITMP3, d);
1616 store_reg_to_var_int(iptr->dst, d);
1620 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1621 /* op1 = variable, val.i = constant */
1623 var = &(locals[iptr->op1][TYPE_INT]);
1624 if (var->flags & INMEMORY) {
1626 M_LLD(s1, REG_SP, 8 * var->regoff);
1630 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1631 M_IADD_IMM(s1, iptr->val.i, s1);
1633 else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1634 M_ISUB_IMM(s1, (-iptr->val.i), s1);
1637 M_LDA (s1, s1, iptr->val.i);
1638 M_IADD(s1, REG_ZERO, s1);
1640 if (var->flags & INMEMORY)
1641 M_LST(s1, REG_SP, 8 * var->regoff);
1645 /* floating operations ************************************************/
1647 case ICMD_FNEG: /* ..., value ==> ..., - value */
1649 var_to_reg_flt(s1, src, REG_FTMP1);
1650 d = reg_of_var(iptr->dst, REG_FTMP3);
1652 store_reg_to_var_flt(iptr->dst, d);
1655 case ICMD_DNEG: /* ..., value ==> ..., - value */
1657 var_to_reg_flt(s1, src, REG_FTMP1);
1658 d = reg_of_var(iptr->dst, REG_FTMP3);
1660 store_reg_to_var_flt(iptr->dst, d);
1663 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1665 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1666 var_to_reg_flt(s2, src, REG_FTMP2);
1667 d = reg_of_var(iptr->dst, REG_FTMP3);
1672 if (d == s1 || d == s2) {
1673 M_FADDS(s1, s2, REG_FTMP3);
1675 M_FMOV(REG_FTMP3, d);
1682 store_reg_to_var_flt(iptr->dst, d);
1685 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1687 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1688 var_to_reg_flt(s2, src, REG_FTMP2);
1689 d = reg_of_var(iptr->dst, REG_FTMP3);
1694 if (d == s1 || d == s2) {
1695 M_DADDS(s1, s2, REG_FTMP3);
1697 M_FMOV(REG_FTMP3, d);
1704 store_reg_to_var_flt(iptr->dst, d);
1707 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1709 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1710 var_to_reg_flt(s2, src, REG_FTMP2);
1711 d = reg_of_var(iptr->dst, REG_FTMP3);
1716 if (d == s1 || d == s2) {
1717 M_FSUBS(s1, s2, REG_FTMP3);
1719 M_FMOV(REG_FTMP3, d);
1726 store_reg_to_var_flt(iptr->dst, d);
1729 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1731 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1732 var_to_reg_flt(s2, src, REG_FTMP2);
1733 d = reg_of_var(iptr->dst, REG_FTMP3);
1738 if (d == s1 || d == s2) {
1739 M_DSUBS(s1, s2, REG_FTMP3);
1741 M_FMOV(REG_FTMP3, d);
1748 store_reg_to_var_flt(iptr->dst, d);
1751 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1753 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1754 var_to_reg_flt(s2, src, REG_FTMP2);
1755 d = reg_of_var(iptr->dst, REG_FTMP3);
1760 if (d == s1 || d == s2) {
1761 M_FMULS(s1, s2, REG_FTMP3);
1763 M_FMOV(REG_FTMP3, d);
1770 store_reg_to_var_flt(iptr->dst, d);
1773 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1775 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1776 var_to_reg_flt(s2, src, REG_FTMP2);
1777 d = reg_of_var(iptr->dst, REG_FTMP3);
1782 if (d == s1 || d == s2) {
1783 M_DMULS(s1, s2, REG_FTMP3);
1785 M_FMOV(REG_FTMP3, d);
1792 store_reg_to_var_flt(iptr->dst, d);
1795 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1797 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1798 var_to_reg_flt(s2, src, REG_FTMP2);
1799 d = reg_of_var(iptr->dst, REG_FTMP3);
1804 if (d == s1 || d == s2) {
1805 M_FDIVS(s1, s2, REG_FTMP3);
1807 M_FMOV(REG_FTMP3, d);
1814 store_reg_to_var_flt(iptr->dst, d);
1817 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1819 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1820 var_to_reg_flt(s2, src, REG_FTMP2);
1821 d = reg_of_var(iptr->dst, REG_FTMP3);
1826 if (d == s1 || d == s2) {
1827 M_DDIVS(s1, s2, REG_FTMP3);
1829 M_FMOV(REG_FTMP3, d);
1836 store_reg_to_var_flt(iptr->dst, d);
1839 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1841 var_to_reg_int(s1, src, REG_ITMP1);
1842 d = reg_of_var(iptr->dst, REG_FTMP3);
1843 a = dseg_adddouble(0.0);
1844 M_LST (s1, REG_PV, a);
1845 M_DLD (d, REG_PV, a);
1847 store_reg_to_var_flt(iptr->dst, d);
1850 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1852 var_to_reg_int(s1, src, REG_ITMP1);
1853 d = reg_of_var(iptr->dst, REG_FTMP3);
1854 a = dseg_adddouble(0.0);
1855 M_LST (s1, REG_PV, a);
1856 M_DLD (d, REG_PV, a);
1858 store_reg_to_var_flt(iptr->dst, d);
1861 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1863 var_to_reg_flt(s1, src, REG_FTMP1);
1864 d = reg_of_var(iptr->dst, REG_ITMP3);
1865 a = dseg_adddouble(0.0);
1866 M_CVTDL_C(s1, REG_FTMP2);
1867 M_CVTLI(REG_FTMP2, REG_FTMP3);
1868 M_DST (REG_FTMP3, REG_PV, a);
1869 M_ILD (d, REG_PV, a);
1870 store_reg_to_var_int(iptr->dst, d);
1873 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1875 var_to_reg_flt(s1, src, REG_FTMP1);
1876 d = reg_of_var(iptr->dst, REG_ITMP3);
1877 a = dseg_adddouble(0.0);
1878 M_CVTDL_C(s1, REG_FTMP2);
1879 M_DST (REG_FTMP2, REG_PV, a);
1880 M_LLD (d, REG_PV, a);
1881 store_reg_to_var_int(iptr->dst, d);
1884 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1886 var_to_reg_flt(s1, src, REG_FTMP1);
1887 d = reg_of_var(iptr->dst, REG_FTMP3);
1889 store_reg_to_var_flt(iptr->dst, d);
1892 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1894 var_to_reg_flt(s1, src, REG_FTMP1);
1895 d = reg_of_var(iptr->dst, REG_FTMP3);
1903 store_reg_to_var_flt(iptr->dst, d);
1906 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1908 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1909 var_to_reg_flt(s2, src, REG_FTMP2);
1910 d = reg_of_var(iptr->dst, REG_ITMP3);
1912 M_LSUB_IMM(REG_ZERO, 1, d);
1913 M_FCMPEQ(s1, s2, REG_FTMP3);
1914 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1916 M_FCMPLT(s2, s1, REG_FTMP3);
1917 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1918 M_LADD_IMM(REG_ZERO, 1, d);
1921 M_LSUB_IMM(REG_ZERO, 1, d);
1922 M_FCMPEQS(s1, s2, REG_FTMP3);
1924 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1926 M_FCMPLTS(s2, s1, REG_FTMP3);
1928 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1929 M_LADD_IMM(REG_ZERO, 1, d);
1931 store_reg_to_var_int(iptr->dst, d);
1934 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1936 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1937 var_to_reg_flt(s2, src, REG_FTMP2);
1938 d = reg_of_var(iptr->dst, REG_ITMP3);
1940 M_LADD_IMM(REG_ZERO, 1, d);
1941 M_FCMPEQ(s1, s2, REG_FTMP3);
1942 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1944 M_FCMPLT(s1, s2, REG_FTMP3);
1945 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1946 M_LSUB_IMM(REG_ZERO, 1, d);
1949 M_LADD_IMM(REG_ZERO, 1, d);
1950 M_FCMPEQS(s1, s2, REG_FTMP3);
1952 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1954 M_FCMPLTS(s1, s2, REG_FTMP3);
1956 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1957 M_LSUB_IMM(REG_ZERO, 1, d);
1959 store_reg_to_var_int(iptr->dst, d);
1963 /* memory operations **************************************************/
1965 /* #define gen_bound_check \
1967 M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\
1968 M_CMPULT(s2, REG_ITMP3, REG_ITMP3);\
1969 M_BEQZ(REG_ITMP3, 0);\
1970 codegen_addxboundrefs(mcodeptr);\
1974 #define gen_bound_check \
1975 if (checkbounds) { \
1976 M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\
1977 M_CMPULT(s2, REG_ITMP3, REG_ITMP3);\
1978 M_BEQZ(REG_ITMP3, 0);\
1979 codegen_addxboundrefs(mcodeptr); \
1982 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1984 var_to_reg_int(s1, src, REG_ITMP1);
1985 d = reg_of_var(iptr->dst, REG_ITMP3);
1986 gen_nullptr_check(s1);
1987 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1988 store_reg_to_var_int(iptr->dst, d);
1991 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1993 var_to_reg_int(s1, src->prev, REG_ITMP1);
1994 var_to_reg_int(s2, src, REG_ITMP2);
1995 d = reg_of_var(iptr->dst, REG_ITMP3);
1996 if (iptr->op1 == 0) {
1997 gen_nullptr_check(s1);
2000 M_SAADDQ(s2, s1, REG_ITMP1);
2001 M_ALD( d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
2002 store_reg_to_var_int(iptr->dst, d);
2005 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
2007 var_to_reg_int(s1, src->prev, REG_ITMP1);
2008 var_to_reg_int(s2, src, REG_ITMP2);
2009 d = reg_of_var(iptr->dst, REG_ITMP3);
2010 if (iptr->op1 == 0) {
2011 gen_nullptr_check(s1);
2014 M_S8ADDQ(s2, s1, REG_ITMP1);
2015 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
2016 store_reg_to_var_int(iptr->dst, d);
2019 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
2021 var_to_reg_int(s1, src->prev, REG_ITMP1);
2022 var_to_reg_int(s2, src, REG_ITMP2);
2023 d = reg_of_var(iptr->dst, REG_ITMP3);
2024 if (iptr->op1 == 0) {
2025 gen_nullptr_check(s1);
2029 M_S4ADDQ(s2, s1, REG_ITMP1);
2030 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
2031 store_reg_to_var_int(iptr->dst, d);
2034 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
2036 var_to_reg_int(s1, src->prev, REG_ITMP1);
2037 var_to_reg_int(s2, src, REG_ITMP2);
2038 d = reg_of_var(iptr->dst, REG_FTMP3);
2039 if (iptr->op1 == 0) {
2040 gen_nullptr_check(s1);
2043 M_S4ADDQ(s2, s1, REG_ITMP1);
2044 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
2045 store_reg_to_var_flt(iptr->dst, d);
2048 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
2050 var_to_reg_int(s1, src->prev, REG_ITMP1);
2051 var_to_reg_int(s2, src, REG_ITMP2);
2052 d = reg_of_var(iptr->dst, REG_FTMP3);
2053 if (iptr->op1 == 0) {
2054 gen_nullptr_check(s1);
2057 M_S8ADDQ(s2, s1, REG_ITMP1);
2058 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
2059 store_reg_to_var_flt(iptr->dst, d);
2062 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
2064 var_to_reg_int(s1, src->prev, REG_ITMP1);
2065 var_to_reg_int(s2, src, REG_ITMP2);
2066 d = reg_of_var(iptr->dst, REG_ITMP3);
2067 if (iptr->op1 == 0) {
2068 gen_nullptr_check(s1);
2071 if (has_ext_instr_set) {
2072 M_LADD(s2, s1, REG_ITMP1);
2073 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2074 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
2077 M_LADD (s2, s1, REG_ITMP1);
2078 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2079 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2080 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2081 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
2083 store_reg_to_var_int(iptr->dst, d);
2086 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
2088 var_to_reg_int(s1, src->prev, REG_ITMP1);
2089 var_to_reg_int(s2, src, REG_ITMP2);
2090 d = reg_of_var(iptr->dst, REG_ITMP3);
2091 if (iptr->op1 == 0) {
2092 gen_nullptr_check(s1);
2095 if (has_ext_instr_set) {
2096 M_LADD(s2, s1, REG_ITMP1);
2097 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2098 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
2102 M_LADD(s2, s1, REG_ITMP1);
2103 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2104 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2105 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
2106 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
2107 M_SRA_IMM(d, 48, d);
2109 store_reg_to_var_int(iptr->dst, d);
2112 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
2114 var_to_reg_int(s1, src->prev, REG_ITMP1);
2115 var_to_reg_int(s2, src, REG_ITMP2);
2116 d = reg_of_var(iptr->dst, REG_ITMP3);
2117 if (iptr->op1 == 0) {
2118 gen_nullptr_check(s1);
2121 if (has_ext_instr_set) {
2122 M_LADD (s2, s1, REG_ITMP1);
2123 M_BLDU (d, REG_ITMP1, OFFSET (java_bytearray, data[0]));
2127 M_LADD(s2, s1, REG_ITMP1);
2128 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2129 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
2130 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
2131 M_SRA_IMM(d, 56, d);
2133 store_reg_to_var_int(iptr->dst, d);
2137 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
2139 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2140 var_to_reg_int(s2, src->prev, REG_ITMP2);
2141 if (iptr->op1 == 0) {
2142 gen_nullptr_check(s1);
2145 var_to_reg_int(s3, src, REG_ITMP3);
2146 M_SAADDQ(s2, s1, REG_ITMP1);
2147 M_AST (s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
2150 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
2152 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2153 var_to_reg_int(s2, src->prev, REG_ITMP2);
2154 if (iptr->op1 == 0) {
2155 gen_nullptr_check(s1);
2158 var_to_reg_int(s3, src, REG_ITMP3);
2159 M_S8ADDQ(s2, s1, REG_ITMP1);
2160 M_LST (s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
2163 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
2165 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2166 var_to_reg_int(s2, src->prev, REG_ITMP2);
2167 if (iptr->op1 == 0) {
2168 gen_nullptr_check(s1);
2172 var_to_reg_int(s3, src, REG_ITMP3);
2173 M_S4ADDQ(s2, s1, REG_ITMP1);
2174 M_IST (s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
2177 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
2179 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2180 var_to_reg_int(s2, src->prev, REG_ITMP2);
2181 if (iptr->op1 == 0) {
2182 gen_nullptr_check(s1);
2185 var_to_reg_flt(s3, src, REG_FTMP3);
2186 M_S4ADDQ(s2, s1, REG_ITMP1);
2187 M_FST (s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
2190 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
2192 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2193 var_to_reg_int(s2, src->prev, REG_ITMP2);
2194 if (iptr->op1 == 0) {
2195 gen_nullptr_check(s1);
2198 var_to_reg_flt(s3, src, REG_FTMP3);
2199 M_S8ADDQ(s2, s1, REG_ITMP1);
2200 M_DST (s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
2203 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
2205 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2206 var_to_reg_int(s2, src->prev, REG_ITMP2);
2207 if (iptr->op1 == 0) {
2208 gen_nullptr_check(s1);
2211 var_to_reg_int(s3, src, REG_ITMP3);
2212 if (has_ext_instr_set) {
2213 M_LADD(s2, s1, REG_ITMP1);
2214 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2215 M_SST (s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
2218 M_LADD (s2, s1, REG_ITMP1);
2219 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2220 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2221 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2222 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
2223 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2224 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2225 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2229 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
2231 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2232 var_to_reg_int(s2, src->prev, REG_ITMP2);
2233 if (iptr->op1 == 0) {
2234 gen_nullptr_check(s1);
2237 var_to_reg_int(s3, src, REG_ITMP3);
2238 if (has_ext_instr_set) {
2239 M_LADD(s2, s1, REG_ITMP1);
2240 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2241 M_SST (s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2244 M_LADD (s2, s1, REG_ITMP1);
2245 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2246 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2247 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2248 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
2249 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2250 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2251 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2255 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
2257 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2258 var_to_reg_int(s2, src->prev, REG_ITMP2);
2259 if (iptr->op1 == 0) {
2260 gen_nullptr_check(s1);
2263 var_to_reg_int(s3, src, REG_ITMP3);
2264 if (has_ext_instr_set) {
2265 M_LADD(s2, s1, REG_ITMP1);
2266 M_BST (s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2269 M_LADD (s2, s1, REG_ITMP1);
2270 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2271 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2272 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
2273 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2274 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2275 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2280 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2281 /* op1 = type, val.a = field address */
2283 /* if class isn't yet initialized, do it */
2284 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
2285 /* call helper function which patches this code */
2286 a = dseg_addaddress(((fieldinfo *) iptr->val.a)->class);
2287 M_ALD(REG_ITMP1, REG_PV, a);
2288 a = dseg_addaddress(asm_check_clinit);
2289 M_ALD(REG_PV, REG_PV, a);
2290 M_JSR(REG_RA, REG_PV);
2293 s1 = (int) ((u1*) mcodeptr - mcodebase);
2294 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
2296 s4 ml = -s1, mh = 0;
2297 while (ml < -32768) { ml += 65536; mh--; }
2298 M_LDA(REG_PV, REG_RA, ml);
2299 M_LDAH(REG_PV, REG_PV, mh);
2303 a = dseg_addaddress(&(((fieldinfo *)(iptr->val.a))->value));
2304 M_ALD(REG_ITMP1, REG_PV, a);
2305 switch (iptr->op1) {
2307 var_to_reg_int(s2, src, REG_ITMP2);
2308 M_IST(s2, REG_ITMP1, 0);
2311 var_to_reg_int(s2, src, REG_ITMP2);
2312 M_LST(s2, REG_ITMP1, 0);
2315 var_to_reg_int(s2, src, REG_ITMP2);
2316 M_AST(s2, REG_ITMP1, 0);
2319 var_to_reg_flt(s2, src, REG_FTMP2);
2320 M_FST(s2, REG_ITMP1, 0);
2323 var_to_reg_flt(s2, src, REG_FTMP2);
2324 M_DST(s2, REG_ITMP1, 0);
2326 default: panic ("internal error");
2330 case ICMD_GETSTATIC: /* ... ==> ..., value */
2331 /* op1 = type, val.a = field address */
2333 /* if class isn't yet initialized, do it */
2334 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
2335 /* call helper function which patches this code */
2336 a = dseg_addaddress(((fieldinfo *) iptr->val.a)->class);
2337 M_ALD(REG_ITMP1, REG_PV, a);
2338 a = dseg_addaddress(asm_check_clinit);
2339 M_ALD(REG_PV, REG_PV, a);
2340 M_JSR(REG_RA, REG_PV);
2343 s1 = (int) ((u1*) mcodeptr - mcodebase);
2344 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
2346 s4 ml = -s1, mh = 0;
2347 while (ml < -32768) { ml += 65536; mh--; }
2348 M_LDA(REG_PV, REG_RA, ml);
2349 M_LDAH(REG_PV, REG_PV, mh);
2353 a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value));
2354 M_ALD(REG_ITMP1, REG_PV, a);
2355 switch (iptr->op1) {
2357 d = reg_of_var(iptr->dst, REG_ITMP3);
2358 M_ILD(d, REG_ITMP1, 0);
2359 store_reg_to_var_int(iptr->dst, d);
2362 d = reg_of_var(iptr->dst, REG_ITMP3);
2363 M_LLD(d, REG_ITMP1, 0);
2364 store_reg_to_var_int(iptr->dst, d);
2367 d = reg_of_var(iptr->dst, REG_ITMP3);
2368 M_ALD(d, REG_ITMP1, 0);
2369 store_reg_to_var_int(iptr->dst, d);
2372 d = reg_of_var(iptr->dst, REG_FTMP1);
2373 M_FLD(d, REG_ITMP1, 0);
2374 store_reg_to_var_flt(iptr->dst, d);
2377 d = reg_of_var(iptr->dst, REG_FTMP1);
2378 M_DLD(d, REG_ITMP1, 0);
2379 store_reg_to_var_flt(iptr->dst, d);
2381 default: panic ("internal error");
2386 case ICMD_PUTFIELD: /* ..., value ==> ... */
2387 /* op1 = type, val.i = field offset */
2389 a = ((fieldinfo *)(iptr->val.a))->offset;
2390 switch (iptr->op1) {
2392 var_to_reg_int(s1, src->prev, REG_ITMP1);
2393 var_to_reg_int(s2, src, REG_ITMP2);
2394 gen_nullptr_check(s1);
2398 var_to_reg_int(s1, src->prev, REG_ITMP1);
2399 var_to_reg_int(s2, src, REG_ITMP2);
2400 gen_nullptr_check(s1);
2404 var_to_reg_int(s1, src->prev, REG_ITMP1);
2405 var_to_reg_int(s2, src, REG_ITMP2);
2406 gen_nullptr_check(s1);
2410 var_to_reg_int(s1, src->prev, REG_ITMP1);
2411 var_to_reg_flt(s2, src, REG_FTMP2);
2412 gen_nullptr_check(s1);
2416 var_to_reg_int(s1, src->prev, REG_ITMP1);
2417 var_to_reg_flt(s2, src, REG_FTMP2);
2418 gen_nullptr_check(s1);
2421 default: panic ("internal error");
2425 case ICMD_GETFIELD: /* ... ==> ..., value */
2426 /* op1 = type, val.i = field offset */
2428 a = ((fieldinfo *)(iptr->val.a))->offset;
2429 switch (iptr->op1) {
2431 var_to_reg_int(s1, src, REG_ITMP1);
2432 d = reg_of_var(iptr->dst, REG_ITMP3);
2433 gen_nullptr_check(s1);
2435 store_reg_to_var_int(iptr->dst, d);
2438 var_to_reg_int(s1, src, REG_ITMP1);
2439 d = reg_of_var(iptr->dst, REG_ITMP3);
2440 gen_nullptr_check(s1);
2442 store_reg_to_var_int(iptr->dst, d);
2445 var_to_reg_int(s1, src, REG_ITMP1);
2446 d = reg_of_var(iptr->dst, REG_ITMP3);
2447 gen_nullptr_check(s1);
2449 store_reg_to_var_int(iptr->dst, d);
2452 var_to_reg_int(s1, src, REG_ITMP1);
2453 d = reg_of_var(iptr->dst, REG_FTMP1);
2454 gen_nullptr_check(s1);
2456 store_reg_to_var_flt(iptr->dst, d);
2459 var_to_reg_int(s1, src, REG_ITMP1);
2460 d = reg_of_var(iptr->dst, REG_FTMP1);
2461 gen_nullptr_check(s1);
2463 store_reg_to_var_flt(iptr->dst, d);
2465 default: panic ("internal error");
2470 /* branch operations **************************************************/
2472 #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}}
2474 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2476 var_to_reg_int(s1, src, REG_ITMP1);
2477 M_INTMOVE(s1, REG_ITMP1_XPTR);
2478 a = dseg_addaddress(asm_handle_exception);
2479 M_ALD(REG_ITMP2, REG_PV, a);
2480 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2481 M_NOP; /* nop ensures that XPC is less than the end */
2482 /* of basic block */
2486 case ICMD_GOTO: /* ... ==> ... */
2487 /* op1 = target JavaVM pc */
2489 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2493 case ICMD_JSR: /* ... ==> ... */
2494 /* op1 = target JavaVM pc */
2496 M_BSR(REG_ITMP1, 0);
2497 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2500 case ICMD_RET: /* ... ==> ... */
2501 /* op1 = local variable */
2503 var = &(locals[iptr->op1][TYPE_ADR]);
2504 if (var->flags & INMEMORY) {
2505 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2506 M_RET(REG_ZERO, REG_ITMP1);
2509 M_RET(REG_ZERO, var->regoff);
2513 case ICMD_IFNULL: /* ..., value ==> ... */
2514 /* op1 = target JavaVM pc */
2516 var_to_reg_int(s1, src, REG_ITMP1);
2518 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2521 case ICMD_IFNONNULL: /* ..., value ==> ... */
2522 /* op1 = target JavaVM pc */
2524 var_to_reg_int(s1, src, REG_ITMP1);
2526 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2529 case ICMD_IFEQ: /* ..., value ==> ... */
2530 /* op1 = target JavaVM pc, val.i = constant */
2532 var_to_reg_int(s1, src, REG_ITMP1);
2533 if (iptr->val.i == 0) {
2537 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2538 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2541 ICONST(REG_ITMP2, iptr->val.i);
2542 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2544 M_BNEZ(REG_ITMP1, 0);
2546 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2549 case ICMD_IFLT: /* ..., value ==> ... */
2550 /* op1 = target JavaVM pc, val.i = constant */
2552 var_to_reg_int(s1, src, REG_ITMP1);
2553 if (iptr->val.i == 0) {
2557 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2558 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2561 ICONST(REG_ITMP2, iptr->val.i);
2562 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2564 M_BNEZ(REG_ITMP1, 0);
2566 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2569 case ICMD_IFLE: /* ..., value ==> ... */
2570 /* op1 = target JavaVM pc, val.i = constant */
2572 var_to_reg_int(s1, src, REG_ITMP1);
2573 if (iptr->val.i == 0) {
2577 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2578 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2581 ICONST(REG_ITMP2, iptr->val.i);
2582 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2584 M_BNEZ(REG_ITMP1, 0);
2586 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2589 case ICMD_IFNE: /* ..., value ==> ... */
2590 /* op1 = target JavaVM pc, val.i = constant */
2592 var_to_reg_int(s1, src, REG_ITMP1);
2593 if (iptr->val.i == 0) {
2597 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2598 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2601 ICONST(REG_ITMP2, iptr->val.i);
2602 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2604 M_BEQZ(REG_ITMP1, 0);
2606 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2609 case ICMD_IFGT: /* ..., value ==> ... */
2610 /* op1 = target JavaVM pc, val.i = constant */
2612 var_to_reg_int(s1, src, REG_ITMP1);
2613 if (iptr->val.i == 0) {
2617 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2618 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2621 ICONST(REG_ITMP2, iptr->val.i);
2622 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2624 M_BEQZ(REG_ITMP1, 0);
2626 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2629 case ICMD_IFGE: /* ..., value ==> ... */
2630 /* op1 = target JavaVM pc, val.i = constant */
2632 var_to_reg_int(s1, src, REG_ITMP1);
2633 if (iptr->val.i == 0) {
2637 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2638 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2641 ICONST(REG_ITMP2, iptr->val.i);
2642 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2644 M_BEQZ(REG_ITMP1, 0);
2646 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2649 case ICMD_IF_LEQ: /* ..., value ==> ... */
2650 /* op1 = target JavaVM pc, val.l = constant */
2652 var_to_reg_int(s1, src, REG_ITMP1);
2653 if (iptr->val.l == 0) {
2657 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2658 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2661 LCONST(REG_ITMP2, iptr->val.l);
2662 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2664 M_BNEZ(REG_ITMP1, 0);
2666 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2669 case ICMD_IF_LLT: /* ..., value ==> ... */
2670 /* op1 = target JavaVM pc, val.l = constant */
2672 var_to_reg_int(s1, src, REG_ITMP1);
2673 if (iptr->val.l == 0) {
2677 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2678 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2681 LCONST(REG_ITMP2, iptr->val.l);
2682 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2684 M_BNEZ(REG_ITMP1, 0);
2686 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2689 case ICMD_IF_LLE: /* ..., value ==> ... */
2690 /* op1 = target JavaVM pc, val.l = constant */
2692 var_to_reg_int(s1, src, REG_ITMP1);
2693 if (iptr->val.l == 0) {
2697 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2698 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2701 LCONST(REG_ITMP2, iptr->val.l);
2702 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2704 M_BNEZ(REG_ITMP1, 0);
2706 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2709 case ICMD_IF_LNE: /* ..., value ==> ... */
2710 /* op1 = target JavaVM pc, val.l = constant */
2712 var_to_reg_int(s1, src, REG_ITMP1);
2713 if (iptr->val.l == 0) {
2717 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2718 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2721 LCONST(REG_ITMP2, iptr->val.l);
2722 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2724 M_BEQZ(REG_ITMP1, 0);
2726 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2729 case ICMD_IF_LGT: /* ..., value ==> ... */
2730 /* op1 = target JavaVM pc, val.l = constant */
2732 var_to_reg_int(s1, src, REG_ITMP1);
2733 if (iptr->val.l == 0) {
2737 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2738 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2741 LCONST(REG_ITMP2, iptr->val.l);
2742 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2744 M_BEQZ(REG_ITMP1, 0);
2746 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2749 case ICMD_IF_LGE: /* ..., value ==> ... */
2750 /* op1 = target JavaVM pc, val.l = constant */
2752 var_to_reg_int(s1, src, REG_ITMP1);
2753 if (iptr->val.l == 0) {
2757 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2758 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2761 LCONST(REG_ITMP2, iptr->val.l);
2762 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2764 M_BEQZ(REG_ITMP1, 0);
2766 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2769 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2770 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2771 case ICMD_IF_ACMPEQ:
2773 var_to_reg_int(s1, src->prev, REG_ITMP1);
2774 var_to_reg_int(s2, src, REG_ITMP2);
2775 M_CMPEQ(s1, s2, REG_ITMP1);
2776 M_BNEZ(REG_ITMP1, 0);
2777 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2780 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2781 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2782 case ICMD_IF_ACMPNE:
2784 var_to_reg_int(s1, src->prev, REG_ITMP1);
2785 var_to_reg_int(s2, src, REG_ITMP2);
2786 M_CMPEQ(s1, s2, REG_ITMP1);
2787 M_BEQZ(REG_ITMP1, 0);
2788 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2791 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2792 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2794 var_to_reg_int(s1, src->prev, REG_ITMP1);
2795 var_to_reg_int(s2, src, REG_ITMP2);
2796 M_CMPLT(s1, s2, REG_ITMP1);
2797 M_BNEZ(REG_ITMP1, 0);
2798 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2801 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2802 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2804 var_to_reg_int(s1, src->prev, REG_ITMP1);
2805 var_to_reg_int(s2, src, REG_ITMP2);
2806 M_CMPLE(s1, s2, REG_ITMP1);
2807 M_BEQZ(REG_ITMP1, 0);
2808 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2811 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2812 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2814 var_to_reg_int(s1, src->prev, REG_ITMP1);
2815 var_to_reg_int(s2, src, REG_ITMP2);
2816 M_CMPLE(s1, s2, REG_ITMP1);
2817 M_BNEZ(REG_ITMP1, 0);
2818 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2821 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2822 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2824 var_to_reg_int(s1, src->prev, REG_ITMP1);
2825 var_to_reg_int(s2, src, REG_ITMP2);
2826 M_CMPLT(s1, s2, REG_ITMP1);
2827 M_BEQZ(REG_ITMP1, 0);
2828 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2831 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2833 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2836 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2837 /* val.i = constant */
2839 var_to_reg_int(s1, src, REG_ITMP1);
2840 d = reg_of_var(iptr->dst, REG_ITMP3);
2842 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2843 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2844 M_CMPEQ(s1, REG_ZERO, d);
2845 store_reg_to_var_int(iptr->dst, d);
2848 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2849 M_CMPEQ(s1, REG_ZERO, d);
2851 store_reg_to_var_int(iptr->dst, d);
2855 M_MOV(s1, REG_ITMP1);
2858 ICONST(d, iptr[1].val.i);
2860 if ((s3 >= 0) && (s3 <= 255)) {
2861 M_CMOVEQ_IMM(s1, s3, d);
2864 ICONST(REG_ITMP2, s3);
2865 M_CMOVEQ(s1, REG_ITMP2, d);
2867 store_reg_to_var_int(iptr->dst, d);
2870 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2871 /* val.i = constant */
2873 var_to_reg_int(s1, src, REG_ITMP1);
2874 d = reg_of_var(iptr->dst, REG_ITMP3);
2876 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2877 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2878 M_CMPEQ(s1, REG_ZERO, d);
2879 store_reg_to_var_int(iptr->dst, d);
2882 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2883 M_CMPEQ(s1, REG_ZERO, d);
2885 store_reg_to_var_int(iptr->dst, d);
2889 M_MOV(s1, REG_ITMP1);
2892 ICONST(d, iptr[1].val.i);
2894 if ((s3 >= 0) && (s3 <= 255)) {
2895 M_CMOVNE_IMM(s1, s3, d);
2898 ICONST(REG_ITMP2, s3);
2899 M_CMOVNE(s1, REG_ITMP2, d);
2901 store_reg_to_var_int(iptr->dst, d);
2904 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2905 /* val.i = constant */
2907 var_to_reg_int(s1, src, REG_ITMP1);
2908 d = reg_of_var(iptr->dst, REG_ITMP3);
2910 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2911 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2912 M_CMPLT(s1, REG_ZERO, d);
2913 store_reg_to_var_int(iptr->dst, d);
2916 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2917 M_CMPLE(REG_ZERO, s1, d);
2918 store_reg_to_var_int(iptr->dst, d);
2922 M_MOV(s1, REG_ITMP1);
2925 ICONST(d, iptr[1].val.i);
2927 if ((s3 >= 0) && (s3 <= 255)) {
2928 M_CMOVLT_IMM(s1, s3, d);
2931 ICONST(REG_ITMP2, s3);
2932 M_CMOVLT(s1, REG_ITMP2, d);
2934 store_reg_to_var_int(iptr->dst, d);
2937 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2938 /* val.i = constant */
2940 var_to_reg_int(s1, src, REG_ITMP1);
2941 d = reg_of_var(iptr->dst, REG_ITMP3);
2943 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2944 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2945 M_CMPLE(REG_ZERO, s1, d);
2946 store_reg_to_var_int(iptr->dst, d);
2949 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2950 M_CMPLT(s1, REG_ZERO, d);
2951 store_reg_to_var_int(iptr->dst, d);
2955 M_MOV(s1, REG_ITMP1);
2958 ICONST(d, iptr[1].val.i);
2960 if ((s3 >= 0) && (s3 <= 255)) {
2961 M_CMOVGE_IMM(s1, s3, d);
2964 ICONST(REG_ITMP2, s3);
2965 M_CMOVGE(s1, REG_ITMP2, d);
2967 store_reg_to_var_int(iptr->dst, d);
2970 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2971 /* val.i = constant */
2973 var_to_reg_int(s1, src, REG_ITMP1);
2974 d = reg_of_var(iptr->dst, REG_ITMP3);
2976 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2977 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2978 M_CMPLT(REG_ZERO, s1, d);
2979 store_reg_to_var_int(iptr->dst, d);
2982 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2983 M_CMPLE(s1, REG_ZERO, d);
2984 store_reg_to_var_int(iptr->dst, d);
2988 M_MOV(s1, REG_ITMP1);
2991 ICONST(d, iptr[1].val.i);
2993 if ((s3 >= 0) && (s3 <= 255)) {
2994 M_CMOVGT_IMM(s1, s3, d);
2997 ICONST(REG_ITMP2, s3);
2998 M_CMOVGT(s1, REG_ITMP2, d);
3000 store_reg_to_var_int(iptr->dst, d);
3003 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
3004 /* val.i = constant */
3006 var_to_reg_int(s1, src, REG_ITMP1);
3007 d = reg_of_var(iptr->dst, REG_ITMP3);
3009 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
3010 if ((s3 == 1) && (iptr[1].val.i == 0)) {
3011 M_CMPLE(s1, REG_ZERO, d);
3012 store_reg_to_var_int(iptr->dst, d);
3015 if ((s3 == 0) && (iptr[1].val.i == 1)) {
3016 M_CMPLT(REG_ZERO, s1, d);
3017 store_reg_to_var_int(iptr->dst, d);
3021 M_MOV(s1, REG_ITMP1);
3024 ICONST(d, iptr[1].val.i);
3026 if ((s3 >= 0) && (s3 <= 255)) {
3027 M_CMOVLE_IMM(s1, s3, d);
3030 ICONST(REG_ITMP2, s3);
3031 M_CMOVLE(s1, REG_ITMP2, d);
3033 store_reg_to_var_int(iptr->dst, d);
3037 case ICMD_IRETURN: /* ..., retvalue ==> ... */
3042 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3044 a = dseg_addaddress ((void*) (builtin_monitorexit));
3045 M_ALD(REG_PV, REG_PV, a);
3046 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
3047 M_JSR(REG_RA, REG_PV);
3048 disp = -(int)((u1*) mcodeptr - mcodebase);
3049 M_LDA(REG_PV, REG_RA, disp);
3052 var_to_reg_int(s1, src, REG_RESULT);
3053 M_INTMOVE(s1, REG_RESULT);
3054 goto nowperformreturn;
3056 case ICMD_FRETURN: /* ..., retvalue ==> ... */
3060 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3062 a = dseg_addaddress ((void*) (builtin_monitorexit));
3063 M_ALD(REG_PV, REG_PV, a);
3064 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
3065 M_JSR(REG_RA, REG_PV);
3066 disp = -(int)((u1*) mcodeptr - mcodebase);
3067 M_LDA(REG_PV, REG_RA, disp);
3070 var_to_reg_flt(s1, src, REG_FRESULT);
3071 M_FLTMOVE(s1, REG_FRESULT);
3072 goto nowperformreturn;
3074 case ICMD_RETURN: /* ... ==> ... */
3077 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3079 a = dseg_addaddress ((void*) (builtin_monitorexit));
3080 M_ALD(REG_PV, REG_PV, a);
3081 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
3082 M_JSR(REG_RA, REG_PV);
3083 disp = -(int)((u1*) mcodeptr - mcodebase);
3084 M_LDA(REG_PV, REG_RA, disp);
3092 p = parentargs_base;
3094 /* restore return address */
3097 {p--; M_LLD (REG_RA, REG_SP, 8 * p);}
3099 /* restore saved registers */
3101 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
3102 {p--; M_LLD(savintregs[r], REG_SP, 8 * p);}
3103 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
3104 {p--; M_DLD(savfltregs[r], REG_SP, 8 * p);}
3106 /* deallocate stack */
3108 if (parentargs_base)
3109 {M_LDA(REG_SP, REG_SP, parentargs_base*8);}
3111 /* call trace function */
3114 M_LDA (REG_SP, REG_SP, -24);
3115 M_AST(REG_RA, REG_SP, 0);
3116 M_LST(REG_RESULT, REG_SP, 8);
3117 M_DST(REG_FRESULT, REG_SP,16);
3118 a = dseg_addaddress (method);
3119 M_ALD(argintregs[0], REG_PV, a);
3120 M_MOV(REG_RESULT, argintregs[1]);
3121 M_FLTMOVE(REG_FRESULT, argfltregs[2]);
3122 M_FLTMOVE(REG_FRESULT, argfltregs[3]);
3123 a = dseg_addaddress ((void*) (builtin_displaymethodstop));
3124 M_ALD(REG_PV, REG_PV, a);
3125 M_JSR (REG_RA, REG_PV);
3126 s1 = (int)((u1*) mcodeptr - mcodebase);
3127 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
3130 while (ml<-32768) { ml+=65536; mh--; }
3131 M_LDA (REG_PV, REG_RA, ml );
3132 M_LDAH (REG_PV, REG_PV, mh );
3134 M_DLD(REG_FRESULT, REG_SP,16);
3135 M_LLD(REG_RESULT, REG_SP, 8);
3136 M_ALD(REG_RA, REG_SP, 0);
3137 M_LDA (REG_SP, REG_SP, 24);
3140 M_RET(REG_ZERO, REG_RA);
3146 case ICMD_TABLESWITCH: /* ..., index ==> ... */
3151 tptr = (void **) iptr->target;
3153 s4ptr = iptr->val.a;
3154 l = s4ptr[1]; /* low */
3155 i = s4ptr[2]; /* high */
3157 var_to_reg_int(s1, src, REG_ITMP1);
3159 {M_INTMOVE(s1, REG_ITMP1);}
3160 else if (l <= 32768) {
3161 M_LDA(REG_ITMP1, s1, -l);
3164 ICONST(REG_ITMP2, l);
3165 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
3172 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
3174 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
3175 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3177 M_BEQZ(REG_ITMP2, 0);
3180 /* codegen_addreference(BlockPtrOfPC(s4ptr[0]), mcodeptr); */
3181 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3183 /* build jump table top down and use address of lowest entry */
3185 /* s4ptr += 3 + i; */
3189 /* dseg_addtarget(BlockPtrOfPC(*--s4ptr)); */
3190 dseg_addtarget((basicblock *) tptr[0]);
3195 /* length of dataseg after last dseg_addtarget is used by load */
3197 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
3198 M_ALD(REG_ITMP2, REG_ITMP2, -dseglen);
3199 M_JMP(REG_ZERO, REG_ITMP2);
3204 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3206 s4 i, l, val, *s4ptr;
3209 tptr = (void **) iptr->target;
3211 s4ptr = iptr->val.a;
3212 l = s4ptr[0]; /* default */
3213 i = s4ptr[1]; /* count */
3215 MCODECHECK((i<<2)+8);
3216 var_to_reg_int(s1, src, REG_ITMP1);
3222 if ((val >= 0) && (val <= 255)) {
3223 M_CMPEQ_IMM(s1, val, REG_ITMP2);
3226 if ((val >= -32768) && (val <= 32767)) {
3227 M_LDA(REG_ITMP2, REG_ZERO, val);
3230 a = dseg_adds4 (val);
3231 M_ILD(REG_ITMP2, REG_PV, a);
3233 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
3235 M_BNEZ(REG_ITMP2, 0);
3236 /* codegen_addreference(BlockPtrOfPC(s4ptr[1]), mcodeptr); */
3237 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3241 /* codegen_addreference(BlockPtrOfPC(l), mcodeptr); */
3243 tptr = (void **) iptr->target;
3244 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3251 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
3252 /* op1 = return type, val.a = function pointer*/
3256 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
3257 /* op1 = return type, val.a = function pointer*/
3261 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
3262 /* op1 = return type, val.a = function pointer*/
3266 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3267 /* op1 = arg count, val.a = method pointer */
3269 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3270 /* op1 = arg count, val.a = method pointer */
3272 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3273 /* op1 = arg count, val.a = method pointer */
3275 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
3276 /* op1 = arg count, val.a = method pointer */
3284 MCODECHECK((s3 << 1) + 64);
3286 /* copy arguments to registers or stack location */
3288 for (; --s3 >= 0; src = src->prev) {
3289 if (src->varkind == ARGVAR)
3291 if (IS_INT_LNG_TYPE(src->type)) {
3292 if (s3 < INT_ARG_CNT) {
3293 s1 = argintregs[s3];
3294 var_to_reg_int(d, src, s1);
3298 var_to_reg_int(d, src, REG_ITMP1);
3299 M_LST(d, REG_SP, 8 * (s3 - INT_ARG_CNT));
3303 if (s3 < FLT_ARG_CNT) {
3304 s1 = argfltregs[s3];
3305 var_to_reg_flt(d, src, s1);
3309 var_to_reg_flt(d, src, REG_FTMP1);
3310 M_DST(d, REG_SP, 8 * (s3 - FLT_ARG_CNT));
3315 switch (iptr->opc) {
3319 a = dseg_addaddress ((void*) (m));
3321 M_ALD(REG_PV, REG_PV, a); /* Pointer to built-in-function */
3323 goto makeactualcall;
3325 case ICMD_INVOKESTATIC:
3326 case ICMD_INVOKESPECIAL:
3327 a = dseg_addaddress (m->stubroutine);
3329 M_ALD(REG_PV, REG_PV, a ); /* method pointer in r27 */
3332 goto makeactualcall;
3334 case ICMD_INVOKEVIRTUAL:
3336 gen_nullptr_check(argintregs[0]);
3337 M_ALD(REG_METHODPTR, argintregs[0],
3338 OFFSET(java_objectheader, vftbl));
3339 M_ALD(REG_PV, REG_METHODPTR, OFFSET(vftbl, table[0]) +
3340 sizeof(methodptr) * m->vftblindex);
3343 goto makeactualcall;
3345 case ICMD_INVOKEINTERFACE:
3348 gen_nullptr_check(argintregs[0]);
3349 M_ALD(REG_METHODPTR, argintregs[0],
3350 OFFSET(java_objectheader, vftbl));
3351 M_ALD(REG_METHODPTR, REG_METHODPTR,
3352 OFFSET(vftbl, interfacetable[0]) -
3353 sizeof(methodptr*) * ci->index);
3354 M_ALD(REG_PV, REG_METHODPTR,
3355 sizeof(methodptr) * (m - ci->methods));
3358 goto makeactualcall;
3362 error ("Unkown ICMD-Command: %d", iptr->opc);
3367 M_JSR (REG_RA, REG_PV);
3371 s1 = (int)((u1*) mcodeptr - mcodebase);
3372 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
3375 while (ml<-32768) { ml+=65536; mh--; }
3376 M_LDA (REG_PV, REG_RA, ml );
3377 M_LDAH (REG_PV, REG_PV, mh );
3380 /* d contains return type */
3382 if (d != TYPE_VOID) {
3383 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3384 s1 = reg_of_var(iptr->dst, REG_RESULT);
3385 M_INTMOVE(REG_RESULT, s1);
3386 store_reg_to_var_int(iptr->dst, s1);
3389 s1 = reg_of_var(iptr->dst, REG_FRESULT);
3390 M_FLTMOVE(REG_FRESULT, s1);
3391 store_reg_to_var_flt(iptr->dst, s1);
3398 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3400 /* op1: 0 == array, 1 == class */
3401 /* val.a: (classinfo*) superclass */
3403 /* superclass is an interface:
3405 * return (sub != NULL) &&
3406 * (sub->vftbl->interfacetablelength > super->index) &&
3407 * (sub->vftbl->interfacetable[-super->index] != NULL);
3409 * superclass is a class:
3411 * return ((sub != NULL) && (0
3412 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3413 * super->vftbl->diffvall));
3417 classinfo *super = (classinfo*) iptr->val.a;
3419 var_to_reg_int(s1, src, REG_ITMP1);
3420 d = reg_of_var(iptr->dst, REG_ITMP3);
3422 M_MOV(s1, REG_ITMP1);
3426 if (iptr->op1) { /* class/interface */
3427 if (super->flags & ACC_INTERFACE) { /* interface */
3429 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3430 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3431 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3432 M_BLEZ(REG_ITMP2, 2);
3433 M_ALD(REG_ITMP1, REG_ITMP1,
3434 OFFSET(vftbl, interfacetable[0]) -
3435 super->index * sizeof(methodptr*));
3436 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3440 s2 = super->vftbl->diffval;
3441 M_BEQZ(s1, 4 + (s2 > 255));
3442 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3443 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3444 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3446 M_CMPULE_IMM(REG_ITMP1, s2, d);
3448 M_LDA(REG_ITMP2, REG_ZERO, s2);
3449 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3453 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3454 a = dseg_addaddress ((void*) super->vftbl);
3455 M_ALD(REG_ITMP2, REG_PV, a);
3456 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3457 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl, baseval));
3458 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, diffval));
3459 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3460 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3464 panic ("internal error: no inlined array instanceof");
3466 store_reg_to_var_int(iptr->dst, d);
3469 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3471 /* op1: 0 == array, 1 == class */
3472 /* val.a: (classinfo*) superclass */
3474 /* superclass is an interface:
3476 * OK if ((sub == NULL) ||
3477 * (sub->vftbl->interfacetablelength > super->index) &&
3478 * (sub->vftbl->interfacetable[-super->index] != NULL));
3480 * superclass is a class:
3482 * OK if ((sub == NULL) || (0
3483 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3484 * super->vftbl->diffvall));
3488 classinfo *super = (classinfo*) iptr->val.a;
3490 d = reg_of_var(iptr->dst, REG_ITMP3);
3491 var_to_reg_int(s1, src, d);
3492 if (iptr->op1) { /* class/interface */
3493 if (super->flags & ACC_INTERFACE) { /* interface */
3495 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3496 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3497 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3498 M_BLEZ(REG_ITMP2, 0);
3499 codegen_addxcastrefs(mcodeptr);
3500 M_ALD(REG_ITMP2, REG_ITMP1,
3501 OFFSET(vftbl, interfacetable[0]) -
3502 super->index * sizeof(methodptr*));
3503 M_BEQZ(REG_ITMP2, 0);
3504 codegen_addxcastrefs(mcodeptr);
3508 s2 = super->vftbl->diffval;
3509 M_BEQZ(s1, 4 + (s2 != 0) + (s2 > 255));
3510 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3511 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3512 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3514 M_BNEZ(REG_ITMP1, 0);
3516 else if (s2 <= 255) {
3517 M_CMPULE_IMM(REG_ITMP1, s2, REG_ITMP2);
3518 M_BEQZ(REG_ITMP2, 0);
3521 M_LDA(REG_ITMP2, REG_ZERO, s2);
3522 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3523 M_BEQZ(REG_ITMP2, 0);
3526 M_BEQZ(s1, 8 + (d == REG_ITMP3));
3527 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3528 a = dseg_addaddress ((void*) super->vftbl);
3529 M_ALD(REG_ITMP2, REG_PV, a);
3530 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3531 if (d != REG_ITMP3) {
3532 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl, baseval));
3533 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, diffval));
3534 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3537 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, baseval));
3538 M_ISUB(REG_ITMP1, REG_ITMP2, REG_ITMP1);
3539 M_ALD(REG_ITMP2, REG_PV, a);
3540 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, diffval));
3542 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3543 M_BEQZ(REG_ITMP2, 0);
3544 codegen_addxcastrefs(mcodeptr);
3548 panic ("internal error: no inlined array checkcast");
3551 store_reg_to_var_int(iptr->dst, d);
3554 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
3556 var_to_reg_int(s1, src, REG_ITMP1);
3558 codegen_addxcheckarefs(mcodeptr);
3561 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3562 /* op1 = dimension, val.a = array descriptor */
3564 /* check for negative sizes and copy sizes to stack if necessary */
3566 MCODECHECK((iptr->op1 << 1) + 64);
3568 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3569 var_to_reg_int(s2, src, REG_ITMP1);
3571 codegen_addxcheckarefs(mcodeptr);
3573 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
3575 if (src->varkind != ARGVAR) {
3576 M_LST(s2, REG_SP, 8 * (s1 + INT_ARG_CNT));
3580 /* a0 = dimension count */
3582 ICONST(argintregs[0], iptr->op1);
3584 /* a1 = arraydescriptor */
3586 a = dseg_addaddress(iptr->val.a);
3587 M_ALD(argintregs[1], REG_PV, a);
3589 /* a2 = pointer to dimensions = stack pointer */
3591 M_INTMOVE(REG_SP, argintregs[2]);
3593 a = dseg_addaddress((void*) (builtin_nmultianewarray));
3594 M_ALD(REG_PV, REG_PV, a);
3595 M_JSR(REG_RA, REG_PV);
3596 s1 = (int)((u1*) mcodeptr - mcodebase);
3598 M_LDA (REG_PV, REG_RA, -s1);
3600 s4 ml = -s1, mh = 0;
3601 while (ml < -32768) {ml += 65536; mh--;}
3602 M_LDA(REG_PV, REG_RA, ml);
3603 M_LDAH(REG_PV, REG_PV, mh);
3605 s1 = reg_of_var(iptr->dst, REG_RESULT);
3606 M_INTMOVE(REG_RESULT, s1);
3607 store_reg_to_var_int(iptr->dst, s1);
3611 default: error ("Unknown pseudo command: %d", iptr->opc);
3617 } /* for instruction */
3619 /* copy values to interface registers */
3621 src = bptr->outstack;
3622 len = bptr->outdepth;
3626 if ((src->varkind != STACKVAR)) {
3628 if (IS_FLT_DBL_TYPE(s2)) {
3629 var_to_reg_flt(s1, src, REG_FTMP1);
3630 if (!(interfaces[len][s2].flags & INMEMORY)) {
3631 M_FLTMOVE(s1,interfaces[len][s2].regoff);
3634 M_DST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3638 var_to_reg_int(s1, src, REG_ITMP1);
3639 if (!(interfaces[len][s2].flags & INMEMORY)) {
3640 M_INTMOVE(s1,interfaces[len][s2].regoff);
3643 M_LST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3649 } /* if (bptr -> flags >= BBREACHED) */
3650 } /* for basic block */
3652 /* bptr -> mpc = (int)((u1*) mcodeptr - mcodebase); */
3655 /* generate bound check stubs */
3657 s4 *xcodeptr = NULL;
3659 for (; xboundrefs != NULL; xboundrefs = xboundrefs->next) {
3660 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3661 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
3662 xboundrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3667 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
3668 xboundrefs->branchpos, (u1*) mcodeptr - mcodebase);
3672 M_LDA(REG_ITMP2_XPC, REG_PV, xboundrefs->branchpos - 4);
3674 if (xcodeptr != NULL) {
3675 int disp = (xcodeptr-mcodeptr)-1;
3679 xcodeptr = mcodeptr;
3681 a = dseg_addaddress(proto_java_lang_ArrayIndexOutOfBoundsException);
3682 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3684 a = dseg_addaddress(asm_handle_exception);
3685 M_ALD(REG_ITMP3, REG_PV, a);
3687 M_JMP(REG_ZERO, REG_ITMP3);
3691 /* generate negative array size check stubs */
3695 for (; xcheckarefs != NULL; xcheckarefs = xcheckarefs->next) {
3696 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3697 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3698 xcheckarefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3702 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3703 xcheckarefs->branchpos, (u1*) mcodeptr - mcodebase);
3707 M_LDA(REG_ITMP2_XPC, REG_PV, xcheckarefs->branchpos - 4);
3709 if (xcodeptr != NULL) {
3710 int disp = (xcodeptr-mcodeptr)-1;
3714 xcodeptr = mcodeptr;
3716 a = dseg_addaddress(proto_java_lang_NegativeArraySizeException);
3717 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3719 a = dseg_addaddress(asm_handle_exception);
3720 M_ALD(REG_ITMP3, REG_PV, a);
3722 M_JMP(REG_ZERO, REG_ITMP3);
3726 /* generate cast check stubs */
3730 for (; xcastrefs != NULL; xcastrefs = xcastrefs->next) {
3731 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3732 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3733 xcastrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3737 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3738 xcastrefs->branchpos, (u1*) mcodeptr - mcodebase);
3742 M_LDA(REG_ITMP2_XPC, REG_PV, xcastrefs->branchpos - 4);
3744 if (xcodeptr != NULL) {
3745 int disp = (xcodeptr-mcodeptr)-1;
3749 xcodeptr = mcodeptr;
3751 a = dseg_addaddress(proto_java_lang_ClassCastException);
3752 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3754 a = dseg_addaddress(asm_handle_exception);
3755 M_ALD(REG_ITMP3, REG_PV, a);
3757 M_JMP(REG_ZERO, REG_ITMP3);
3762 #ifdef SOFTNULLPTRCHECK
3764 /* generate null pointer check stubs */
3768 for (; xnullrefs != NULL; xnullrefs = xnullrefs->next) {
3769 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3770 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3771 xnullrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3775 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3776 xnullrefs->branchpos, (u1*) mcodeptr - mcodebase);
3780 M_LDA(REG_ITMP2_XPC, REG_PV, xnullrefs->branchpos - 4);
3782 if (xcodeptr != NULL) {
3783 int disp = (xcodeptr-mcodeptr)-1;
3787 xcodeptr = mcodeptr;
3789 a = dseg_addaddress(proto_java_lang_NullPointerException);
3790 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3792 a = dseg_addaddress(asm_handle_exception);
3793 M_ALD(REG_ITMP3, REG_PV, a);
3795 M_JMP(REG_ZERO, REG_ITMP3);
3802 codegen_finish((int)((u1*) mcodeptr - mcodebase));
3806 /* function createcompilerstub *************************************************
3808 creates a stub routine which calls the compiler
3810 *******************************************************************************/
3812 #define COMPSTUBSIZE 3
3814 u1 *createcompilerstub(methodinfo *m)
3816 u8 *s = CNEW(u8, COMPSTUBSIZE); /* memory to hold the stub */
3817 s4 *mcodeptr = (s4 *) s; /* code generation pointer */
3819 /* code for the stub */
3820 M_ALD(REG_PV, REG_PV, 16); /* load pointer to the compiler */
3821 M_JMP(0, REG_PV); /* jump to the compiler, return address
3822 in reg 0 is used as method pointer */
3823 s[1] = (u8) m; /* literals to be adressed */
3824 s[2] = (u8) asm_call_jit_compiler; /* jump directly via PV from above */
3827 count_cstub_len += COMPSTUBSIZE * 8;
3834 /* function removecompilerstub *************************************************
3836 deletes a compilerstub from memory (simply by freeing it)
3838 *******************************************************************************/
3840 void removecompilerstub(u1 *stub)
3842 CFREE(stub, COMPSTUBSIZE * 8);
3846 /* function: createnativestub **************************************************
3848 creates a stub routine which calls a native method
3850 *******************************************************************************/
3852 #define NATIVESTUBSIZE 60
3853 #define NATIVESTUBOFFSET 8
3855 u1 *createnativestub(functionptr f, methodinfo *m)
3857 u8 *s; /* memory pointer to hold the stub */
3859 s4 *mcodeptr; /* code generation pointer */
3860 int stackframesize = 0; /* size of stackframe if needed */
3864 descriptor2types(m); /* set paramcount and paramtypes */
3866 s = CNEW(u8, NATIVESTUBSIZE); /* memory to hold the stub */
3867 cs = s + NATIVESTUBOFFSET;
3868 mcodeptr = (s4 *) (cs); /* code generation pointer */
3870 *(cs-1) = (u8) f; /* address of native method */
3871 *(cs-2) = (u8) (&_exceptionptr); /* address of exceptionptr */
3872 *(cs-3) = (u8) asm_handle_nat_exception; /* addr of asm exception handler */
3873 *(cs-4) = (u8) (&env); /* addr of jni_environement */
3874 *(cs-5) = (u8) asm_builtin_trace;
3876 *(cs-7) = (u8) asm_builtin_exittrace;
3877 *(cs-8) = (u8) m->class;
3879 M_LDA(REG_SP, REG_SP, -8); /* build up stackframe */
3880 M_AST(REG_RA, REG_SP, 0); /* store return address */
3883 M_ALD(REG_ITMP1, REG_PV, -6 * 8);
3884 M_ALD(REG_PV, REG_PV, -5 * 8);
3885 M_JSR(REG_RA, REG_PV);
3886 disp = -(int) (mcodeptr - (s4*) cs) * 4;
3887 M_LDA(REG_PV, REG_RA, disp);
3890 /* save argument registers on stack -- if we have to */
3891 if ((m->flags & ACC_STATIC && m->paramcount > (INT_ARG_CNT - 2)) || m->paramcount > (INT_ARG_CNT - 1)) {
3893 int paramshiftcnt = (m->flags & ACC_STATIC) ? 2 : 1;
3894 int stackparamcnt = (m->paramcount > INT_ARG_CNT) ? m->paramcount - INT_ARG_CNT : 0;
3896 stackframesize = stackparamcnt + paramshiftcnt;
3898 M_LDA(REG_SP, REG_SP, -stackframesize * 8);
3900 /* copy stack arguments into new stack frame -- if any */
3901 for (i = 0; i < stackparamcnt; i++) {
3902 M_LLD(REG_ITMP1, REG_SP, (stackparamcnt + 1 + i) * 8);
3903 M_LST(REG_ITMP1, REG_SP, (paramshiftcnt + i) * 8);
3906 if (m->flags & ACC_STATIC) {
3907 if (IS_FLT_DBL_TYPE(m->paramtypes[5])) {
3908 M_DST(argfltregs[5], REG_SP, 1 * 8);
3910 M_LST(argintregs[5], REG_SP, 1 * 8);
3913 if (IS_FLT_DBL_TYPE(m->paramtypes[4])) {
3914 M_DST(argfltregs[4], REG_SP, 0 * 8);
3916 M_LST(argintregs[4], REG_SP, 0 * 8);
3920 if (IS_FLT_DBL_TYPE(m->paramtypes[5])) {
3921 M_DST(argfltregs[5], REG_SP, 0 * 8);
3923 M_LST(argintregs[5], REG_SP, 0 * 8);
3928 if (m->flags & ACC_STATIC) {
3929 M_MOV(argintregs[3], argintregs[5]);
3930 M_MOV(argintregs[2], argintregs[4]);
3931 M_MOV(argintregs[1], argintregs[3]);
3932 M_MOV(argintregs[0], argintregs[2]);
3933 M_FMOV(argfltregs[3], argfltregs[5]);
3934 M_FMOV(argfltregs[2], argfltregs[4]);
3935 M_FMOV(argfltregs[1], argfltregs[3]);
3936 M_FMOV(argfltregs[0], argfltregs[2]);
3938 /* put class into second argument register */
3939 M_ALD(argintregs[1], REG_PV, -8 * 8);
3942 M_MOV(argintregs[4], argintregs[5]);
3943 M_MOV(argintregs[3], argintregs[4]);
3944 M_MOV(argintregs[2], argintregs[3]);
3945 M_MOV(argintregs[1], argintregs[2]);
3946 M_MOV(argintregs[0], argintregs[1]);
3947 M_FMOV(argfltregs[4], argfltregs[5]);
3948 M_FMOV(argfltregs[3], argfltregs[4]);
3949 M_FMOV(argfltregs[2], argfltregs[3]);
3950 M_FMOV(argfltregs[1], argfltregs[2]);
3951 M_FMOV(argfltregs[0], argfltregs[1]);
3954 /* put env into first argument register */
3955 M_ALD(argintregs[0], REG_PV, -4 * 8);
3957 M_ALD(REG_PV, REG_PV, -1 * 8); /* load adress of native method */
3958 M_JSR(REG_RA, REG_PV); /* call native method */
3959 disp = -(int) (mcodeptr - (s4*) cs) * 4;
3960 M_LDA(REG_PV, REG_RA, disp); /* recompute pv from ra */
3962 /* remove stackframe if there is one */
3963 if (stackframesize) {
3964 M_LDA(REG_SP, REG_SP, stackframesize * 8);
3968 M_ALD(argintregs[0], REG_PV, -6 * 8);
3969 M_MOV(REG_RESULT, argintregs[1]);
3970 M_FMOV(REG_FRESULT, argfltregs[2]);
3971 M_FMOV(REG_FRESULT, argfltregs[3]);
3972 M_ALD(REG_PV, REG_PV, -7 * 8); /* asm_builtin_exittrace */
3973 M_JSR(REG_RA, REG_PV);
3974 disp = -(int) (mcodeptr - (s4*) cs) * 4;
3975 M_LDA(REG_PV, REG_RA, disp);
3978 M_ALD(REG_ITMP3, REG_PV, -2 * 8); /* get address of exceptionptr */
3979 M_ALD(REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
3980 M_BNEZ(REG_ITMP1, 3); /* if no exception then return */
3982 M_ALD(REG_RA, REG_SP, 0); /* load return address */
3983 M_LDA(REG_SP, REG_SP, 8); /* remove stackframe */
3984 M_RET(REG_ZERO, REG_RA); /* return to caller */
3986 M_AST(REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
3988 M_ALD(REG_RA, REG_SP, 0); /* load return address */
3989 M_LDA(REG_SP, REG_SP, 8); /* remove stackframe */
3990 M_LDA(REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
3991 M_ALD(REG_ITMP3, REG_PV, -3 * 8); /* load asm exception handler address */
3992 M_JMP(REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
3995 dolog_plain("stubsize: %d (for %d params)\n", (int) (mcodeptr - (s4*) s), m->paramcount);
3999 count_nstub_len += NATIVESTUBSIZE * 8;
4002 return (u1*) (s + NATIVESTUBOFFSET);
4006 /* function: removenativestub **************************************************
4008 removes a previously created native-stub from memory
4010 *******************************************************************************/
4012 void removenativestub(u1 *stub)
4014 CFREE((u8*) stub - NATIVESTUBOFFSET, NATIVESTUBSIZE * 8);
4019 * These are local overrides for various environment variables in Emacs.
4020 * Please do not remove this and leave it at the end of the file, where
4021 * Emacs will automagically detect them.
4022 * ---------------------------------------------------------------------
4025 * indent-tabs-mode: t