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 616 2003-11-13 00:57:22Z stefan $
49 /* include independent code generation stuff */
50 #include "codegen.inc"
54 /* *****************************************************************************
56 Datatypes and Register Allocations:
57 -----------------------------------
59 On 64-bit-machines (like the Alpha) all operands are stored in the
60 registers in a 64-bit form, even when the correspondig JavaVM operands
61 only need 32 bits. This is done by a canonical representation:
63 32-bit integers are allways stored as sign-extended 64-bit values (this
64 approach is directly supported by the Alpha architecture and is very easy
67 32-bit-floats are stored in a 64-bit doubleprecision register by simply
68 expanding the exponent and mantissa with zeroes. (also supported by the
74 The calling conventions and the layout of the stack is explained in detail
75 in the documention file: calling.doc
77 *******************************************************************************/
80 /* register descripton - array ************************************************/
82 /* #define REG_RES 0 reserved register for OS or code generator */
83 /* #define REG_RET 1 return value register */
84 /* #define REG_EXC 2 exception value register (only old jit) */
85 /* #define REG_SAV 3 (callee) saved register */
86 /* #define REG_TMP 4 scratch temporary register (caller saved) */
87 /* #define REG_ARG 5 argument register (caller saved) */
89 /* #define REG_END -1 last entry in tables */
92 REG_RET, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
93 REG_TMP, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
94 REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_TMP, REG_TMP,
95 REG_TMP, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES,
98 /* for use of reserved registers, see comment above */
100 int nregdescfloat[] = {
101 REG_RET, REG_TMP, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
102 REG_SAV, REG_SAV, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
103 REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_TMP, REG_TMP,
104 REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_RES, REG_RES, REG_RES, REG_RES,
107 /* for use of reserved registers, see comment above */
110 /* parameter allocation mode */
112 int nreg_parammode = PARAMMODE_NUMBERED;
114 /* parameter-registers will be allocated by assigning the
115 1. parameter: int/float-reg 16
116 2. parameter: int/float-reg 17
117 3. parameter: int/float-reg 18 ....
121 /* stackframe-infos ***********************************************************/
123 int parentargs_base; /* offset in stackframe for the parameter from the caller*/
125 /* -> see file 'calling.doc' */
128 /* additional functions and macros to generate code ***************************/
130 /* #define BlockPtrOfPC(pc) block+block_index[pc] */
131 #define BlockPtrOfPC(pc) ((basicblock *) iptr->target)
135 #define COUNT_SPILLS count_spills++
141 /* gen_nullptr_check(objreg) */
143 #ifdef SOFTNULLPTRCHECK
144 #define gen_nullptr_check(objreg) \
146 M_BEQZ((objreg), 0);\
147 codegen_addxnullrefs(mcodeptr);\
150 #define gen_nullptr_check(objreg)
154 /* MCODECHECK(icnt) */
156 #define MCODECHECK(icnt) \
157 if((mcodeptr + (icnt)) > mcodeend) mcodeptr = codegen_increase((u1*) mcodeptr)
160 generates an integer-move from register a to b.
161 if a and b are the same int-register, no code will be generated.
164 #define M_INTMOVE(a,b) if(a!=b){M_MOV(a,b);}
168 generates a floating-point-move from register a to b.
169 if a and b are the same float-register, no code will be generated
172 #define M_FLTMOVE(a,b) if(a!=b){M_FMOV(a,b);}
176 this function generates code to fetch data from a pseudo-register
177 into a real register.
178 If the pseudo-register has actually been assigned to a real
179 register, no code will be emitted, since following operations
180 can use this register directly.
182 v: pseudoregister to be fetched from
183 tempregnum: temporary register to be used if v is actually spilled to ram
185 return: the register number, where the operand can be found after
186 fetching (this wil be either tempregnum or the register
187 number allready given to v)
190 #define var_to_reg_int(regnr,v,tempnr) { \
191 if ((v)->flags & INMEMORY) \
192 {COUNT_SPILLS;M_LLD(tempnr,REG_SP,8*(v)->regoff);regnr=tempnr;} \
193 else regnr=(v)->regoff; \
197 #define var_to_reg_flt(regnr,v,tempnr) { \
198 if ((v)->flags & INMEMORY) \
199 {COUNT_SPILLS;M_DLD(tempnr,REG_SP,8*(v)->regoff);regnr=tempnr;} \
200 else regnr=(v)->regoff; \
205 This function determines a register, to which the result of an operation
206 should go, when it is ultimatively intended to store the result in
208 If v is assigned to an actual register, this register will be returned.
209 Otherwise (when v is spilled) this function returns tempregnum.
210 If not already done, regoff and flags are set in the stack location.
213 static int reg_of_var(stackptr v, int tempregnum)
217 switch (v->varkind) {
219 if (!(v->flags & INMEMORY))
223 var = &(interfaces[v->varnum][v->type]);
224 v->regoff = var->regoff;
225 if (!(var->flags & INMEMORY))
229 var = &(locals[v->varnum][v->type]);
230 v->regoff = var->regoff;
231 if (!(var->flags & INMEMORY))
235 v->regoff = v->varnum;
236 if (IS_FLT_DBL_TYPE(v->type)) {
237 if (v->varnum < fltreg_argnum) {
238 v->regoff = argfltregs[v->varnum];
239 return(argfltregs[v->varnum]);
243 if (v->varnum < intreg_argnum) {
244 v->regoff = argintregs[v->varnum];
245 return(argintregs[v->varnum]);
247 v->regoff -= intreg_argnum;
250 v->flags |= INMEMORY;
255 /* store_reg_to_var_xxx:
256 This function generates the code to store the result of an operation
257 back into a spilled pseudo-variable.
258 If the pseudo-variable has not been spilled in the first place, this
259 function will generate nothing.
261 v ............ Pseudovariable
262 tempregnum ... Number of the temporary registers as returned by
266 #define store_reg_to_var_int(sptr, tempregnum) { \
267 if ((sptr)->flags & INMEMORY) { \
269 M_LST(tempregnum, REG_SP, 8 * (sptr)->regoff); \
273 #define store_reg_to_var_flt(sptr, tempregnum) { \
274 if ((sptr)->flags & INMEMORY) { \
276 M_DST(tempregnum, REG_SP, 8 * (sptr)->regoff); \
281 /* NullPointerException handlers and exception handling initialisation */
283 typedef struct sigctx_struct {
285 long sc_onstack; /* sigstack state to restore */
286 long sc_mask; /* signal mask to restore */
287 long sc_pc; /* pc at time of signal */
288 long sc_ps; /* psl to retore */
289 long sc_regs[32]; /* processor regs 0 to 31 */
290 long sc_ownedfp; /* fp has been used */
291 long sc_fpregs[32]; /* fp regs 0 to 31 */
292 unsigned long sc_fpcr; /* floating point control register */
293 unsigned long sc_fp_control; /* software fpcr */
295 unsigned long sc_reserved1, sc_reserved2;
296 unsigned long sc_ssize;
298 unsigned long sc_traparg_a0;
299 unsigned long sc_traparg_a1;
300 unsigned long sc_traparg_a2;
301 unsigned long sc_fp_trap_pc;
302 unsigned long sc_fp_trigger_sum;
303 unsigned long sc_fp_trigger_inst;
304 unsigned long sc_retcode[2];
308 /* NullPointerException signal handler for hardware null pointer check */
310 void catch_NullPointerException(int sig, int code, sigctx_struct *sigctx)
316 /* Reset signal handler - necessary for SysV, does no harm for BSD */
318 instr = *((int*)(sigctx->sc_pc));
319 faultaddr = sigctx->sc_regs[(instr >> 16) & 0x1f];
321 if (faultaddr == 0) {
322 signal(sig, (void*) catch_NullPointerException); /* reinstall handler */
324 sigaddset(&nsig, sig);
325 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
326 sigctx->sc_regs[REG_ITMP1_XPTR] =
327 (long) proto_java_lang_NullPointerException;
328 sigctx->sc_regs[REG_ITMP2_XPC] = sigctx->sc_pc;
329 sigctx->sc_pc = (long) asm_handle_exception;
333 faultaddr += (long) ((instr << 16) >> 16);
334 fprintf(stderr, "faulting address: 0x%16lx\n", faultaddr);
335 panic("Stack overflow");
342 void init_exceptions(void)
347 /* Linux on Digital Alpha needs an initialisation of the ieee floating point
348 control for IEEE compliant arithmetic (option -mieee of GCC). Under
349 Digital Unix this is done automatically.
354 extern unsigned long ieee_get_fp_control();
355 extern void ieee_set_fp_control(unsigned long fp_control);
357 void init_exceptions(void)
359 /* initialize floating point control */
361 ieee_set_fp_control(ieee_get_fp_control()
362 & ~IEEE_TRAP_ENABLE_INV
363 & ~IEEE_TRAP_ENABLE_DZE
364 /* & ~IEEE_TRAP_ENABLE_UNF we dont want underflow */
365 & ~IEEE_TRAP_ENABLE_OVF);
368 /* install signal handlers we need to convert to exceptions */
373 signal(SIGSEGV, (void*) catch_NullPointerException);
377 signal(SIGBUS, (void*) catch_NullPointerException);
383 /* function gen_mcode **********************************************************
385 generates machine code
387 *******************************************************************************/
389 #define MethodPointer -8
390 #define FrameSize -12
395 #define ExTableSize -32
396 #define ExTableStart -32
398 #define ExEntrySize -32
401 #define ExHandlerPC -24
402 #define ExCatchType -32
406 int len, s1, s2, s3, d, bbs;
418 savedregs_num = (isleafmethod) ? 0 : 1; /* space to save the RA */
420 /* space to save used callee saved registers */
422 savedregs_num += (savintregcnt - maxsavintreguse);
423 savedregs_num += (savfltregcnt - maxsavfltreguse);
425 parentargs_base = maxmemuse + savedregs_num;
427 #ifdef USE_THREADS /* space to save argument of monitor_enter */
429 if (checksync && (method->flags & ACC_SYNCHRONIZED))
434 /* create method header */
436 (void) dseg_addaddress(method); /* MethodPointer */
437 (void) dseg_adds4(parentargs_base * 8); /* FrameSize */
441 /* IsSync contains the offset relative to the stack pointer for the
442 argument of monitor_exit used in the exception handler. Since the
443 offset could be zero and give a wrong meaning of the flag it is
447 if (checksync && (method->flags & ACC_SYNCHRONIZED))
448 (void) dseg_adds4((maxmemuse + 1) * 8); /* IsSync */
453 (void) dseg_adds4(0); /* IsSync */
455 (void) dseg_adds4(isleafmethod); /* IsLeaf */
456 (void) dseg_adds4(savintregcnt - maxsavintreguse); /* IntSave */
457 (void) dseg_adds4(savfltregcnt - maxsavfltreguse); /* FltSave */
458 (void) dseg_adds4(exceptiontablelength); /* ExTableSize */
460 /* create exception table */
462 for (ex = extable; ex != NULL; ex = ex->down) {
465 if (ex->start != NULL)
466 printf("adding start - %d - ", ex->start->debug_nr);
468 printf("PANIC - start is NULL");
473 dseg_addtarget(ex->start);
477 printf("adding end - %d - ", ex->end->debug_nr);
479 printf("PANIC - end is NULL");
484 dseg_addtarget(ex->end);
487 if (ex->handler != NULL)
488 printf("adding handler - %d\n", ex->handler->debug_nr);
490 printf("PANIC - handler is NULL");
495 dseg_addtarget(ex->handler);
497 (void) dseg_addaddress(ex->catchtype);
500 /* initialize mcode variables */
502 mcodeptr = (s4*) mcodebase;
503 mcodeend = (s4*) (mcodebase + mcodesize);
504 MCODECHECK(128 + mparamcount);
506 /* create stack frame (if necessary) */
509 {M_LDA (REG_SP, REG_SP, -parentargs_base * 8);}
511 /* save return address and used callee saved registers */
515 {p--; M_AST (REG_RA, REG_SP, 8*p);}
516 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
517 {p--; M_LST (savintregs[r], REG_SP, 8 * p);}
518 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
519 {p--; M_DST (savfltregs[r], REG_SP, 8 * p);}
521 /* save monitorenter argument */
524 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
525 if (method->flags & ACC_STATIC) {
526 p = dseg_addaddress (class);
527 M_ALD(REG_ITMP1, REG_PV, p);
528 M_AST(REG_ITMP1, REG_SP, 8 * maxmemuse);
531 M_AST (argintregs[0], REG_SP, 8 * maxmemuse);
536 /* copy argument registers to stack and call trace function with pointer
537 to arguments on stack. ToDo: save floating point registers !!!!!!!!!
542 M_LDA (REG_SP, REG_SP, -(14*8));
543 M_AST(REG_RA, REG_SP, 1*8);
545 M_LST(argintregs[0], REG_SP, 2*8);
546 M_LST(argintregs[1], REG_SP, 3*8);
547 M_LST(argintregs[2], REG_SP, 4*8);
548 M_LST(argintregs[3], REG_SP, 5*8);
549 M_LST(argintregs[4], REG_SP, 6*8);
550 M_LST(argintregs[5], REG_SP, 7*8);
552 M_DST(argfltregs[0], REG_SP, 8*8);
553 M_DST(argfltregs[1], REG_SP, 9*8);
554 M_DST(argfltregs[2], REG_SP, 10*8);
555 M_DST(argfltregs[3], REG_SP, 11*8);
556 M_DST(argfltregs[4], REG_SP, 12*8);
557 M_DST(argfltregs[5], REG_SP, 13*8);
559 p = dseg_addaddress (method);
560 M_ALD(REG_ITMP1, REG_PV, p);
561 M_AST(REG_ITMP1, REG_SP, 0);
562 p = dseg_addaddress ((void*) (builtin_trace_args));
563 M_ALD(REG_PV, REG_PV, p);
564 M_JSR(REG_RA, REG_PV);
565 disp = -(int)((u1*) mcodeptr - mcodebase);
566 M_LDA(REG_PV, REG_RA, disp);
567 M_ALD(REG_RA, REG_SP, 1*8);
569 M_LLD(argintregs[0], REG_SP, 2*8);
570 M_LLD(argintregs[1], REG_SP, 3*8);
571 M_LLD(argintregs[2], REG_SP, 4*8);
572 M_LLD(argintregs[3], REG_SP, 5*8);
573 M_LLD(argintregs[4], REG_SP, 6*8);
574 M_LLD(argintregs[5], REG_SP, 7*8);
576 M_DLD(argfltregs[0], REG_SP, 8*8);
577 M_DLD(argfltregs[1], REG_SP, 9*8);
578 M_DLD(argfltregs[2], REG_SP, 10*8);
579 M_DLD(argfltregs[3], REG_SP, 11*8);
580 M_DLD(argfltregs[4], REG_SP, 12*8);
581 M_DLD(argfltregs[5], REG_SP, 13*8);
583 M_LDA (REG_SP, REG_SP, 14*8);
586 /* take arguments out of register or stack frame */
588 for (p = 0, l = 0; p < mparamcount; p++) {
590 var = &(locals[l][t]);
592 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
597 if (IS_INT_LNG_TYPE(t)) { /* integer args */
598 if (p < INT_ARG_CNT) { /* register arguments */
599 if (!(var->flags & INMEMORY)) /* reg arg -> register */
600 {M_INTMOVE (argintregs[p], r);}
601 else /* reg arg -> spilled */
602 M_LST (argintregs[p], REG_SP, 8 * r);
604 else { /* stack arguments */
605 pa = p - INT_ARG_CNT;
606 if (!(var->flags & INMEMORY)) /* stack arg -> register */
607 M_LLD (r, REG_SP, 8 * (parentargs_base + pa));
608 else { /* stack arg -> spilled */
609 M_LLD (REG_ITMP1, REG_SP, 8 * (parentargs_base + pa));
610 M_LST (REG_ITMP1, REG_SP, 8 * r);
614 else { /* floating args */
615 if (p < FLT_ARG_CNT) { /* register arguments */
616 if (!(var->flags & INMEMORY)) /* reg arg -> register */
617 {M_FLTMOVE (argfltregs[p], r);}
618 else /* reg arg -> spilled */
619 M_DST (argfltregs[p], REG_SP, 8 * r);
621 else { /* stack arguments */
622 pa = p - FLT_ARG_CNT;
623 if (!(var->flags & INMEMORY)) /* stack-arg -> register */
624 M_DLD (r, REG_SP, 8 * (parentargs_base + pa) );
625 else { /* stack-arg -> spilled */
626 M_DLD (REG_FTMP1, REG_SP, 8 * (parentargs_base + pa));
627 M_DST (REG_FTMP1, REG_SP, 8 * r);
633 /* call trace function */
636 if (runverbose && !isleafmethod) {
637 M_LDA (REG_SP, REG_SP, -8);
638 p = dseg_addaddress (method);
639 M_ALD(REG_ITMP1, REG_PV, p);
640 M_AST(REG_ITMP1, REG_SP, 0);
641 p = dseg_addaddress ((void*) (builtin_trace_args));
642 M_ALD(REG_PV, REG_PV, p);
643 M_JSR(REG_RA, REG_PV);
644 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
645 M_LDA(REG_SP, REG_SP, 8);
649 /* call monitorenter function */
652 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
654 p = dseg_addaddress ((void*) (builtin_monitorenter));
655 M_ALD(REG_PV, REG_PV, p);
656 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
657 M_JSR(REG_RA, REG_PV);
658 disp = -(int)((u1*) mcodeptr - mcodebase);
659 M_LDA(REG_PV, REG_RA, disp);
664 /* end of header generation */
666 /* walk through all basic blocks */
667 for (/* bbs = block_count, */ bptr = block; /* --bbs >= 0 */ bptr != NULL; bptr = bptr->next) {
669 bptr -> mpc = (int)((u1*) mcodeptr - mcodebase);
671 if (bptr->flags >= BBREACHED) {
673 /* branch resolving */
677 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
678 gen_resolvebranch((u1*) mcodebase + brefs->branchpos,
679 brefs->branchpos, bptr->mpc);
683 /* copy interface registers to their destination */
688 while (src != NULL) {
690 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
691 d = reg_of_var(src, REG_ITMP1);
692 M_INTMOVE(REG_ITMP1, d);
693 store_reg_to_var_int(src, d);
696 d = reg_of_var(src, REG_IFTMP);
697 if ((src->varkind != STACKVAR)) {
699 if (IS_FLT_DBL_TYPE(s2)) {
700 if (!(interfaces[len][s2].flags & INMEMORY)) {
701 s1 = interfaces[len][s2].regoff;
705 M_DLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
707 store_reg_to_var_flt(src, d);
710 if (!(interfaces[len][s2].flags & INMEMORY)) {
711 s1 = interfaces[len][s2].regoff;
715 M_LLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
717 store_reg_to_var_int(src, d);
724 /* walk through all instructions */
728 for (iptr = bptr->iinstr;
730 src = iptr->dst, len--, iptr++) {
732 MCODECHECK(64); /* an instruction usually needs < 64 words */
735 case ICMD_NOP: /* ... ==> ... */
738 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
740 var_to_reg_int(s1, src, REG_ITMP1);
742 codegen_addxnullrefs(mcodeptr);
745 /* constant operations ************************************************/
747 #define ICONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
748 else{a=dseg_adds4(c);M_ILD(r,REG_PV,a);}
750 #define LCONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
751 else{a=dseg_adds8(c);M_LLD(r,REG_PV,a);}
753 case ICMD_ICONST: /* ... ==> ..., constant */
754 /* op1 = 0, val.i = constant */
756 d = reg_of_var(iptr->dst, REG_ITMP1);
757 ICONST(d, iptr->val.i);
758 store_reg_to_var_int(iptr->dst, d);
761 case ICMD_LCONST: /* ... ==> ..., constant */
762 /* op1 = 0, val.l = constant */
764 d = reg_of_var(iptr->dst, REG_ITMP1);
765 LCONST(d, iptr->val.l);
766 store_reg_to_var_int(iptr->dst, d);
769 case ICMD_FCONST: /* ... ==> ..., constant */
770 /* op1 = 0, val.f = constant */
772 d = reg_of_var (iptr->dst, REG_FTMP1);
773 a = dseg_addfloat (iptr->val.f);
775 store_reg_to_var_flt (iptr->dst, d);
778 case ICMD_DCONST: /* ... ==> ..., constant */
779 /* op1 = 0, val.d = constant */
781 d = reg_of_var (iptr->dst, REG_FTMP1);
782 a = dseg_adddouble (iptr->val.d);
784 store_reg_to_var_flt (iptr->dst, d);
787 case ICMD_ACONST: /* ... ==> ..., constant */
788 /* op1 = 0, val.a = constant */
790 d = reg_of_var(iptr->dst, REG_ITMP1);
792 a = dseg_addaddress (iptr->val.a);
796 M_INTMOVE(REG_ZERO, d);
798 store_reg_to_var_int(iptr->dst, d);
802 /* load/store operations **********************************************/
804 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
805 case ICMD_LLOAD: /* op1 = local variable */
808 d = reg_of_var(iptr->dst, REG_ITMP1);
809 if ((iptr->dst->varkind == LOCALVAR) &&
810 (iptr->dst->varnum == iptr->op1))
812 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
813 if (var->flags & INMEMORY)
814 M_LLD(d, REG_SP, 8 * var->regoff);
816 {M_INTMOVE(var->regoff,d);}
817 store_reg_to_var_int(iptr->dst, d);
820 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
821 case ICMD_DLOAD: /* op1 = local variable */
823 d = reg_of_var(iptr->dst, REG_FTMP1);
824 if ((iptr->dst->varkind == LOCALVAR) &&
825 (iptr->dst->varnum == iptr->op1))
827 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
828 if (var->flags & INMEMORY)
829 M_DLD(d, REG_SP, 8 * var->regoff);
831 {M_FLTMOVE(var->regoff,d);}
832 store_reg_to_var_flt(iptr->dst, d);
836 case ICMD_ISTORE: /* ..., value ==> ... */
837 case ICMD_LSTORE: /* op1 = local variable */
840 if ((src->varkind == LOCALVAR) &&
841 (src->varnum == iptr->op1))
843 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
844 if (var->flags & INMEMORY) {
845 var_to_reg_int(s1, src, REG_ITMP1);
846 M_LST(s1, REG_SP, 8 * var->regoff);
849 var_to_reg_int(s1, src, var->regoff);
850 M_INTMOVE(s1, var->regoff);
854 case ICMD_FSTORE: /* ..., value ==> ... */
855 case ICMD_DSTORE: /* op1 = local variable */
857 if ((src->varkind == LOCALVAR) &&
858 (src->varnum == iptr->op1))
860 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
861 if (var->flags & INMEMORY) {
862 var_to_reg_flt(s1, src, REG_FTMP1);
863 M_DST(s1, REG_SP, 8 * var->regoff);
866 var_to_reg_flt(s1, src, var->regoff);
867 M_FLTMOVE(s1, var->regoff);
872 /* pop/dup/swap operations ********************************************/
874 /* attention: double and longs are only one entry in CACAO ICMDs */
876 case ICMD_POP: /* ..., value ==> ... */
877 case ICMD_POP2: /* ..., value, value ==> ... */
880 #define M_COPY(from,to) \
881 d = reg_of_var(to, REG_IFTMP); \
882 if ((from->regoff != to->regoff) || \
883 ((from->flags ^ to->flags) & INMEMORY)) { \
884 if (IS_FLT_DBL_TYPE(from->type)) { \
885 var_to_reg_flt(s1, from, d); \
887 store_reg_to_var_flt(to, d); \
890 var_to_reg_int(s1, from, d); \
892 store_reg_to_var_int(to, d); \
896 case ICMD_DUP: /* ..., a ==> ..., a, a */
897 M_COPY(src, iptr->dst);
900 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
902 M_COPY(src, iptr->dst->prev->prev);
904 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
906 M_COPY(src, iptr->dst);
907 M_COPY(src->prev, iptr->dst->prev);
910 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
912 M_COPY(src->prev, iptr->dst->prev->prev->prev);
914 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
916 M_COPY(src, iptr->dst);
917 M_COPY(src->prev, iptr->dst->prev);
918 M_COPY(src->prev->prev, iptr->dst->prev->prev);
919 M_COPY(src, iptr->dst->prev->prev->prev);
922 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
924 M_COPY(src, iptr->dst);
925 M_COPY(src->prev, iptr->dst->prev);
926 M_COPY(src->prev->prev, iptr->dst->prev->prev);
927 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
928 M_COPY(src, iptr->dst->prev->prev->prev->prev);
929 M_COPY(src->prev, iptr->dst->prev->prev->prev->prev->prev);
932 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
934 M_COPY(src, iptr->dst->prev);
935 M_COPY(src->prev, iptr->dst);
939 /* integer operations *************************************************/
941 case ICMD_INEG: /* ..., value ==> ..., - value */
943 var_to_reg_int(s1, src, REG_ITMP1);
944 d = reg_of_var(iptr->dst, REG_ITMP3);
945 M_ISUB(REG_ZERO, s1, d);
946 store_reg_to_var_int(iptr->dst, d);
949 case ICMD_LNEG: /* ..., value ==> ..., - value */
951 var_to_reg_int(s1, src, REG_ITMP1);
952 d = reg_of_var(iptr->dst, REG_ITMP3);
953 M_LSUB(REG_ZERO, s1, d);
954 store_reg_to_var_int(iptr->dst, d);
957 case ICMD_I2L: /* ..., value ==> ..., value */
959 var_to_reg_int(s1, src, REG_ITMP1);
960 d = reg_of_var(iptr->dst, REG_ITMP3);
962 store_reg_to_var_int(iptr->dst, d);
965 case ICMD_L2I: /* ..., value ==> ..., value */
967 var_to_reg_int(s1, src, REG_ITMP1);
968 d = reg_of_var(iptr->dst, REG_ITMP3);
969 M_IADD(s1, REG_ZERO, d );
970 store_reg_to_var_int(iptr->dst, d);
973 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
975 var_to_reg_int(s1, src, REG_ITMP1);
976 d = reg_of_var(iptr->dst, REG_ITMP3);
977 if (has_ext_instr_set) {
981 M_SLL_IMM(s1, 56, d);
982 M_SRA_IMM( d, 56, d);
984 store_reg_to_var_int(iptr->dst, d);
987 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
989 var_to_reg_int(s1, src, REG_ITMP1);
990 d = reg_of_var(iptr->dst, REG_ITMP3);
992 store_reg_to_var_int(iptr->dst, d);
995 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
997 var_to_reg_int(s1, src, REG_ITMP1);
998 d = reg_of_var(iptr->dst, REG_ITMP3);
999 if (has_ext_instr_set) {
1003 M_SLL_IMM(s1, 48, d);
1004 M_SRA_IMM( d, 48, d);
1006 store_reg_to_var_int(iptr->dst, d);
1010 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1012 var_to_reg_int(s1, src->prev, REG_ITMP1);
1013 var_to_reg_int(s2, src, REG_ITMP2);
1014 d = reg_of_var(iptr->dst, REG_ITMP3);
1016 store_reg_to_var_int(iptr->dst, d);
1019 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
1020 /* val.i = constant */
1022 var_to_reg_int(s1, src, REG_ITMP1);
1023 d = reg_of_var(iptr->dst, REG_ITMP3);
1024 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1025 M_IADD_IMM(s1, iptr->val.i, d);
1028 ICONST(REG_ITMP2, iptr->val.i);
1029 M_IADD(s1, REG_ITMP2, d);
1031 store_reg_to_var_int(iptr->dst, d);
1034 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1036 var_to_reg_int(s1, src->prev, REG_ITMP1);
1037 var_to_reg_int(s2, src, REG_ITMP2);
1038 d = reg_of_var(iptr->dst, REG_ITMP3);
1040 store_reg_to_var_int(iptr->dst, d);
1043 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
1044 /* val.l = constant */
1046 var_to_reg_int(s1, src, REG_ITMP1);
1047 d = reg_of_var(iptr->dst, REG_ITMP3);
1048 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1049 M_LADD_IMM(s1, iptr->val.l, d);
1052 LCONST(REG_ITMP2, iptr->val.l);
1053 M_LADD(s1, REG_ITMP2, d);
1055 store_reg_to_var_int(iptr->dst, d);
1058 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1060 var_to_reg_int(s1, src->prev, REG_ITMP1);
1061 var_to_reg_int(s2, src, REG_ITMP2);
1062 d = reg_of_var(iptr->dst, REG_ITMP3);
1064 store_reg_to_var_int(iptr->dst, d);
1067 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
1068 /* val.i = constant */
1070 var_to_reg_int(s1, src, REG_ITMP1);
1071 d = reg_of_var(iptr->dst, REG_ITMP3);
1072 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1073 M_ISUB_IMM(s1, iptr->val.i, d);
1076 ICONST(REG_ITMP2, iptr->val.i);
1077 M_ISUB(s1, REG_ITMP2, d);
1079 store_reg_to_var_int(iptr->dst, d);
1082 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1084 var_to_reg_int(s1, src->prev, REG_ITMP1);
1085 var_to_reg_int(s2, src, REG_ITMP2);
1086 d = reg_of_var(iptr->dst, REG_ITMP3);
1088 store_reg_to_var_int(iptr->dst, d);
1091 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
1092 /* val.l = constant */
1094 var_to_reg_int(s1, src, REG_ITMP1);
1095 d = reg_of_var(iptr->dst, REG_ITMP3);
1096 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1097 M_LSUB_IMM(s1, iptr->val.l, d);
1100 LCONST(REG_ITMP2, iptr->val.l);
1101 M_LSUB(s1, REG_ITMP2, d);
1103 store_reg_to_var_int(iptr->dst, d);
1106 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1108 var_to_reg_int(s1, src->prev, REG_ITMP1);
1109 var_to_reg_int(s2, src, REG_ITMP2);
1110 d = reg_of_var(iptr->dst, REG_ITMP3);
1112 store_reg_to_var_int(iptr->dst, d);
1115 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
1116 /* val.i = constant */
1118 var_to_reg_int(s1, src, REG_ITMP1);
1119 d = reg_of_var(iptr->dst, REG_ITMP3);
1120 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1121 M_IMUL_IMM(s1, iptr->val.i, d);
1124 ICONST(REG_ITMP2, iptr->val.i);
1125 M_IMUL(s1, REG_ITMP2, d);
1127 store_reg_to_var_int(iptr->dst, d);
1130 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1132 var_to_reg_int(s1, src->prev, REG_ITMP1);
1133 var_to_reg_int(s2, src, REG_ITMP2);
1134 d = reg_of_var(iptr->dst, REG_ITMP3);
1136 store_reg_to_var_int(iptr->dst, d);
1139 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
1140 /* val.l = constant */
1142 var_to_reg_int(s1, src, REG_ITMP1);
1143 d = reg_of_var(iptr->dst, REG_ITMP3);
1144 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1145 M_LMUL_IMM(s1, iptr->val.l, d);
1148 LCONST(REG_ITMP2, iptr->val.l);
1149 M_LMUL(s1, REG_ITMP2, d);
1151 store_reg_to_var_int(iptr->dst, d);
1154 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
1155 case ICMD_LDIVPOW2: /* val.i = constant */
1157 var_to_reg_int(s1, src, REG_ITMP1);
1158 d = reg_of_var(iptr->dst, REG_ITMP3);
1159 if (iptr->val.i <= 15) {
1160 M_LDA(REG_ITMP2, s1, (1 << iptr->val.i) -1);
1161 M_CMOVGE(s1, s1, REG_ITMP2);
1164 M_SRA_IMM(s1, 63, REG_ITMP2);
1165 M_SRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
1166 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1168 M_SRA_IMM(REG_ITMP2, iptr->val.i, d);
1169 store_reg_to_var_int(iptr->dst, d);
1172 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1174 var_to_reg_int(s1, src->prev, REG_ITMP1);
1175 var_to_reg_int(s2, src, REG_ITMP2);
1176 d = reg_of_var(iptr->dst, REG_ITMP3);
1177 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1178 M_SLL(s1, REG_ITMP3, d);
1179 M_IADD(d, REG_ZERO, d);
1180 store_reg_to_var_int(iptr->dst, d);
1183 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1184 /* val.i = constant */
1186 var_to_reg_int(s1, src, REG_ITMP1);
1187 d = reg_of_var(iptr->dst, REG_ITMP3);
1188 M_SLL_IMM(s1, iptr->val.i & 0x1f, d);
1189 M_IADD(d, REG_ZERO, d);
1190 store_reg_to_var_int(iptr->dst, d);
1193 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1195 var_to_reg_int(s1, src->prev, REG_ITMP1);
1196 var_to_reg_int(s2, src, REG_ITMP2);
1197 d = reg_of_var(iptr->dst, REG_ITMP3);
1198 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1199 M_SRA(s1, REG_ITMP3, d);
1200 store_reg_to_var_int(iptr->dst, d);
1203 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1204 /* val.i = constant */
1206 var_to_reg_int(s1, src, REG_ITMP1);
1207 d = reg_of_var(iptr->dst, REG_ITMP3);
1208 M_SRA_IMM(s1, iptr->val.i & 0x1f, d);
1209 store_reg_to_var_int(iptr->dst, d);
1212 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1214 var_to_reg_int(s1, src->prev, REG_ITMP1);
1215 var_to_reg_int(s2, src, REG_ITMP2);
1216 d = reg_of_var(iptr->dst, REG_ITMP3);
1217 M_AND_IMM(s2, 0x1f, REG_ITMP2);
1219 M_SRL(d, REG_ITMP2, d);
1220 M_IADD(d, REG_ZERO, d);
1221 store_reg_to_var_int(iptr->dst, d);
1224 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1225 /* val.i = constant */
1227 var_to_reg_int(s1, src, REG_ITMP1);
1228 d = reg_of_var(iptr->dst, REG_ITMP3);
1230 M_SRL_IMM(d, iptr->val.i & 0x1f, d);
1231 M_IADD(d, REG_ZERO, d);
1232 store_reg_to_var_int(iptr->dst, d);
1235 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1237 var_to_reg_int(s1, src->prev, REG_ITMP1);
1238 var_to_reg_int(s2, src, REG_ITMP2);
1239 d = reg_of_var(iptr->dst, REG_ITMP3);
1241 store_reg_to_var_int(iptr->dst, d);
1244 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1245 /* val.i = constant */
1247 var_to_reg_int(s1, src, REG_ITMP1);
1248 d = reg_of_var(iptr->dst, REG_ITMP3);
1249 M_SLL_IMM(s1, iptr->val.i & 0x3f, d);
1250 store_reg_to_var_int(iptr->dst, d);
1253 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1255 var_to_reg_int(s1, src->prev, REG_ITMP1);
1256 var_to_reg_int(s2, src, REG_ITMP2);
1257 d = reg_of_var(iptr->dst, REG_ITMP3);
1259 store_reg_to_var_int(iptr->dst, d);
1262 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1263 /* val.i = constant */
1265 var_to_reg_int(s1, src, REG_ITMP1);
1266 d = reg_of_var(iptr->dst, REG_ITMP3);
1267 M_SRA_IMM(s1, iptr->val.i & 0x3f, d);
1268 store_reg_to_var_int(iptr->dst, d);
1271 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1273 var_to_reg_int(s1, src->prev, REG_ITMP1);
1274 var_to_reg_int(s2, src, REG_ITMP2);
1275 d = reg_of_var(iptr->dst, REG_ITMP3);
1277 store_reg_to_var_int(iptr->dst, d);
1280 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1281 /* val.i = constant */
1283 var_to_reg_int(s1, src, REG_ITMP1);
1284 d = reg_of_var(iptr->dst, REG_ITMP3);
1285 M_SRL_IMM(s1, iptr->val.i & 0x3f, d);
1286 store_reg_to_var_int(iptr->dst, d);
1289 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1292 var_to_reg_int(s1, src->prev, REG_ITMP1);
1293 var_to_reg_int(s2, src, REG_ITMP2);
1294 d = reg_of_var(iptr->dst, REG_ITMP3);
1296 store_reg_to_var_int(iptr->dst, d);
1299 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1300 /* val.i = constant */
1302 var_to_reg_int(s1, src, REG_ITMP1);
1303 d = reg_of_var(iptr->dst, REG_ITMP3);
1304 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1305 M_AND_IMM(s1, iptr->val.i, d);
1307 else if (iptr->val.i == 0xffff) {
1310 else if (iptr->val.i == 0xffffff) {
1311 M_ZAPNOT_IMM(s1, 0x07, d);
1314 ICONST(REG_ITMP2, iptr->val.i);
1315 M_AND(s1, REG_ITMP2, d);
1317 store_reg_to_var_int(iptr->dst, d);
1320 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1321 /* val.i = constant */
1323 var_to_reg_int(s1, src, REG_ITMP1);
1324 d = reg_of_var(iptr->dst, REG_ITMP3);
1326 M_MOV(s1, REG_ITMP1);
1329 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1330 M_AND_IMM(s1, iptr->val.i, d);
1332 M_ISUB(REG_ZERO, s1, d);
1333 M_AND_IMM(d, iptr->val.i, d);
1335 else if (iptr->val.i == 0xffff) {
1338 M_ISUB(REG_ZERO, s1, d);
1341 else if (iptr->val.i == 0xffffff) {
1342 M_ZAPNOT_IMM(s1, 0x07, d);
1344 M_ISUB(REG_ZERO, s1, d);
1345 M_ZAPNOT_IMM(d, 0x07, d);
1348 ICONST(REG_ITMP2, iptr->val.i);
1349 M_AND(s1, REG_ITMP2, d);
1351 M_ISUB(REG_ZERO, s1, d);
1352 M_AND(d, REG_ITMP2, d);
1354 M_ISUB(REG_ZERO, d, d);
1355 store_reg_to_var_int(iptr->dst, d);
1358 case ICMD_IREM0X10001: /* ..., value ==> ..., value % 0x100001 */
1360 /* b = value & 0xffff;
1362 a = ((b - a) & 0xffff) + (b < a);
1364 var_to_reg_int(s1, src, REG_ITMP1);
1365 d = reg_of_var(iptr->dst, REG_ITMP3);
1367 M_MOV(s1, REG_ITMP3);
1371 M_CZEXT(s1, REG_ITMP2);
1372 M_SRA_IMM(s1, 16, d);
1373 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1374 M_ISUB(REG_ITMP2, d, d);
1376 M_IADD(d, REG_ITMP1, d);
1377 M_BR(11 + (s1 == REG_ITMP1));
1378 M_ISUB(REG_ZERO, s1, REG_ITMP1);
1379 M_CZEXT(REG_ITMP1, REG_ITMP2);
1380 M_SRA_IMM(REG_ITMP1, 16, d);
1381 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1382 M_ISUB(REG_ITMP2, d, d);
1384 M_IADD(d, REG_ITMP1, d);
1385 M_ISUB(REG_ZERO, d, d);
1386 if (s1 == REG_ITMP1) {
1387 var_to_reg_int(s1, src, REG_ITMP1);
1389 M_SLL_IMM(s1, 33, REG_ITMP2);
1390 M_CMPEQ(REG_ITMP2, REG_ZERO, REG_ITMP2);
1391 M_ISUB(d, REG_ITMP2, d);
1392 store_reg_to_var_int(iptr->dst, d);
1395 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1396 /* val.l = constant */
1398 var_to_reg_int(s1, src, REG_ITMP1);
1399 d = reg_of_var(iptr->dst, REG_ITMP3);
1400 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1401 M_AND_IMM(s1, iptr->val.l, d);
1403 else if (iptr->val.l == 0xffffL) {
1406 else if (iptr->val.l == 0xffffffL) {
1407 M_ZAPNOT_IMM(s1, 0x07, d);
1409 else if (iptr->val.l == 0xffffffffL) {
1412 else if (iptr->val.l == 0xffffffffffL) {
1413 M_ZAPNOT_IMM(s1, 0x1f, d);
1415 else if (iptr->val.l == 0xffffffffffffL) {
1416 M_ZAPNOT_IMM(s1, 0x3f, d);
1418 else if (iptr->val.l == 0xffffffffffffffL) {
1419 M_ZAPNOT_IMM(s1, 0x7f, d);
1422 LCONST(REG_ITMP2, iptr->val.l);
1423 M_AND(s1, REG_ITMP2, d);
1425 store_reg_to_var_int(iptr->dst, d);
1428 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1429 /* val.l = constant */
1431 var_to_reg_int(s1, src, REG_ITMP1);
1432 d = reg_of_var(iptr->dst, REG_ITMP3);
1434 M_MOV(s1, REG_ITMP1);
1437 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1438 M_AND_IMM(s1, iptr->val.l, d);
1440 M_LSUB(REG_ZERO, s1, d);
1441 M_AND_IMM(d, iptr->val.l, d);
1443 else if (iptr->val.l == 0xffffL) {
1446 M_LSUB(REG_ZERO, s1, d);
1449 else if (iptr->val.l == 0xffffffL) {
1450 M_ZAPNOT_IMM(s1, 0x07, d);
1452 M_LSUB(REG_ZERO, s1, d);
1453 M_ZAPNOT_IMM(d, 0x07, d);
1455 else if (iptr->val.l == 0xffffffffL) {
1458 M_LSUB(REG_ZERO, s1, d);
1461 else if (iptr->val.l == 0xffffffffffL) {
1462 M_ZAPNOT_IMM(s1, 0x1f, d);
1464 M_LSUB(REG_ZERO, s1, d);
1465 M_ZAPNOT_IMM(d, 0x1f, d);
1467 else if (iptr->val.l == 0xffffffffffffL) {
1468 M_ZAPNOT_IMM(s1, 0x3f, d);
1470 M_LSUB(REG_ZERO, s1, d);
1471 M_ZAPNOT_IMM(d, 0x3f, d);
1473 else if (iptr->val.l == 0xffffffffffffffL) {
1474 M_ZAPNOT_IMM(s1, 0x7f, d);
1476 M_LSUB(REG_ZERO, s1, d);
1477 M_ZAPNOT_IMM(d, 0x7f, d);
1480 LCONST(REG_ITMP2, iptr->val.l);
1481 M_AND(s1, REG_ITMP2, d);
1483 M_LSUB(REG_ZERO, s1, d);
1484 M_AND(d, REG_ITMP2, d);
1486 M_LSUB(REG_ZERO, d, d);
1487 store_reg_to_var_int(iptr->dst, d);
1490 case ICMD_LREM0X10001:/* ..., value ==> ..., value % 0x10001 */
1492 var_to_reg_int(s1, src, REG_ITMP1);
1493 d = reg_of_var(iptr->dst, REG_ITMP3);
1495 M_MOV(s1, REG_ITMP3);
1498 M_CZEXT(s1, REG_ITMP2);
1499 M_SRA_IMM(s1, 16, d);
1500 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1501 M_LSUB(REG_ITMP2, d, d);
1503 M_LADD(d, REG_ITMP1, d);
1504 M_LDA(REG_ITMP2, REG_ZERO, -1);
1505 M_SRL_IMM(REG_ITMP2, 33, REG_ITMP2);
1506 if (s1 == REG_ITMP1) {
1507 var_to_reg_int(s1, src, REG_ITMP1);
1509 M_CMPULT(s1, REG_ITMP2, REG_ITMP2);
1510 M_BNEZ(REG_ITMP2, 11);
1511 M_LDA(d, REG_ZERO, -257);
1512 M_ZAPNOT_IMM(d, 0xcd, d);
1513 M_LSUB(REG_ZERO, s1, REG_ITMP2);
1514 M_CMOVGE(s1, s1, REG_ITMP2);
1515 M_UMULH(REG_ITMP2, d, REG_ITMP2);
1516 M_SRL_IMM(REG_ITMP2, 16, REG_ITMP2);
1517 M_LSUB(REG_ZERO, REG_ITMP2, d);
1518 M_CMOVGE(s1, REG_ITMP2, d);
1519 M_SLL_IMM(d, 16, REG_ITMP2);
1520 M_LADD(d, REG_ITMP2, d);
1522 store_reg_to_var_int(iptr->dst, d);
1525 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1528 var_to_reg_int(s1, src->prev, REG_ITMP1);
1529 var_to_reg_int(s2, src, REG_ITMP2);
1530 d = reg_of_var(iptr->dst, REG_ITMP3);
1532 store_reg_to_var_int(iptr->dst, d);
1535 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1536 /* val.i = constant */
1538 var_to_reg_int(s1, src, REG_ITMP1);
1539 d = reg_of_var(iptr->dst, REG_ITMP3);
1540 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1541 M_OR_IMM(s1, iptr->val.i, d);
1544 ICONST(REG_ITMP2, iptr->val.i);
1545 M_OR(s1, REG_ITMP2, d);
1547 store_reg_to_var_int(iptr->dst, d);
1550 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1551 /* val.l = constant */
1553 var_to_reg_int(s1, src, REG_ITMP1);
1554 d = reg_of_var(iptr->dst, REG_ITMP3);
1555 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1556 M_OR_IMM(s1, iptr->val.l, d);
1559 LCONST(REG_ITMP2, iptr->val.l);
1560 M_OR(s1, REG_ITMP2, d);
1562 store_reg_to_var_int(iptr->dst, d);
1565 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1568 var_to_reg_int(s1, src->prev, REG_ITMP1);
1569 var_to_reg_int(s2, src, REG_ITMP2);
1570 d = reg_of_var(iptr->dst, REG_ITMP3);
1572 store_reg_to_var_int(iptr->dst, d);
1575 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1576 /* val.i = constant */
1578 var_to_reg_int(s1, src, REG_ITMP1);
1579 d = reg_of_var(iptr->dst, REG_ITMP3);
1580 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1581 M_XOR_IMM(s1, iptr->val.i, d);
1584 ICONST(REG_ITMP2, iptr->val.i);
1585 M_XOR(s1, REG_ITMP2, d);
1587 store_reg_to_var_int(iptr->dst, d);
1590 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1591 /* val.l = constant */
1593 var_to_reg_int(s1, src, REG_ITMP1);
1594 d = reg_of_var(iptr->dst, REG_ITMP3);
1595 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1596 M_XOR_IMM(s1, iptr->val.l, d);
1599 LCONST(REG_ITMP2, iptr->val.l);
1600 M_XOR(s1, REG_ITMP2, d);
1602 store_reg_to_var_int(iptr->dst, d);
1606 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1608 var_to_reg_int(s1, src->prev, REG_ITMP1);
1609 var_to_reg_int(s2, src, REG_ITMP2);
1610 d = reg_of_var(iptr->dst, REG_ITMP3);
1611 M_CMPLT(s1, s2, REG_ITMP3);
1612 M_CMPLT(s2, s1, REG_ITMP1);
1613 M_LSUB (REG_ITMP1, REG_ITMP3, d);
1614 store_reg_to_var_int(iptr->dst, d);
1618 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1619 /* op1 = variable, val.i = constant */
1621 var = &(locals[iptr->op1][TYPE_INT]);
1622 if (var->flags & INMEMORY) {
1624 M_LLD(s1, REG_SP, 8 * var->regoff);
1628 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1629 M_IADD_IMM(s1, iptr->val.i, s1);
1631 else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1632 M_ISUB_IMM(s1, (-iptr->val.i), s1);
1635 M_LDA (s1, s1, iptr->val.i);
1636 M_IADD(s1, REG_ZERO, s1);
1638 if (var->flags & INMEMORY)
1639 M_LST(s1, REG_SP, 8 * var->regoff);
1643 /* floating operations ************************************************/
1645 case ICMD_FNEG: /* ..., value ==> ..., - value */
1647 var_to_reg_flt(s1, src, REG_FTMP1);
1648 d = reg_of_var(iptr->dst, REG_FTMP3);
1650 store_reg_to_var_flt(iptr->dst, d);
1653 case ICMD_DNEG: /* ..., value ==> ..., - value */
1655 var_to_reg_flt(s1, src, REG_FTMP1);
1656 d = reg_of_var(iptr->dst, REG_FTMP3);
1658 store_reg_to_var_flt(iptr->dst, d);
1661 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1663 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1664 var_to_reg_flt(s2, src, REG_FTMP2);
1665 d = reg_of_var(iptr->dst, REG_FTMP3);
1673 store_reg_to_var_flt(iptr->dst, d);
1676 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1678 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1679 var_to_reg_flt(s2, src, REG_FTMP2);
1680 d = reg_of_var(iptr->dst, REG_FTMP3);
1688 store_reg_to_var_flt(iptr->dst, d);
1691 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1693 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1694 var_to_reg_flt(s2, src, REG_FTMP2);
1695 d = reg_of_var(iptr->dst, REG_FTMP3);
1703 store_reg_to_var_flt(iptr->dst, d);
1706 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1708 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1709 var_to_reg_flt(s2, src, REG_FTMP2);
1710 d = reg_of_var(iptr->dst, REG_FTMP3);
1718 store_reg_to_var_flt(iptr->dst, d);
1721 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1723 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1724 var_to_reg_flt(s2, src, REG_FTMP2);
1725 d = reg_of_var(iptr->dst, REG_FTMP3);
1733 store_reg_to_var_flt(iptr->dst, d);
1736 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1738 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1739 var_to_reg_flt(s2, src, REG_FTMP2);
1740 d = reg_of_var(iptr->dst, REG_FTMP3);
1748 store_reg_to_var_flt(iptr->dst, d);
1751 case ICMD_FDIV: /* ..., 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);
1763 store_reg_to_var_flt(iptr->dst, d);
1766 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1768 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1769 var_to_reg_flt(s2, src, REG_FTMP2);
1770 d = reg_of_var(iptr->dst, REG_FTMP3);
1778 store_reg_to_var_flt(iptr->dst, d);
1781 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1783 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1784 var_to_reg_flt(s2, src, REG_FTMP2);
1785 d = reg_of_var(iptr->dst, REG_FTMP3);
1787 M_FDIV(s1,s2, REG_FTMP3);
1788 M_CVTDL_C(REG_FTMP3, REG_FTMP3); /* round to integer */
1789 M_CVTLF(REG_FTMP3, REG_FTMP3);
1790 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1791 M_FSUB(s1, REG_FTMP3, d);
1794 M_FDIVS(s1,s2, REG_FTMP3);
1796 M_CVTDL_CS(REG_FTMP3, REG_FTMP3); /* round to integer */
1798 M_CVTLF(REG_FTMP3, REG_FTMP3);
1799 M_FMULS(REG_FTMP3, s2, REG_FTMP3);
1801 M_FSUBS(s1, REG_FTMP3, d);
1804 store_reg_to_var_flt(iptr->dst, d);
1807 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1809 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1810 var_to_reg_flt(s2, src, REG_FTMP2);
1811 d = reg_of_var(iptr->dst, REG_FTMP3);
1813 M_DDIV(s1,s2, REG_FTMP3);
1814 M_CVTDL_C(REG_FTMP3, REG_FTMP3); /* round to integer */
1815 M_CVTLD(REG_FTMP3, REG_FTMP3);
1816 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1817 M_DSUB(s1, REG_FTMP3, d);
1820 M_DDIVS(s1,s2, REG_FTMP3);
1822 M_CVTDL_CS(REG_FTMP3, REG_FTMP3); /* round to integer */
1824 M_CVTLD(REG_FTMP3, REG_FTMP3);
1825 M_DMULS(REG_FTMP3, s2, REG_FTMP3);
1827 M_DSUBS(s1, REG_FTMP3, d);
1830 store_reg_to_var_flt(iptr->dst, d);
1833 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1835 var_to_reg_int(s1, src, REG_ITMP1);
1836 d = reg_of_var(iptr->dst, REG_FTMP3);
1837 a = dseg_adddouble(0.0);
1838 M_LST (s1, REG_PV, a);
1839 M_DLD (d, REG_PV, a);
1841 store_reg_to_var_flt(iptr->dst, d);
1844 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1846 var_to_reg_int(s1, src, REG_ITMP1);
1847 d = reg_of_var(iptr->dst, REG_FTMP3);
1848 a = dseg_adddouble(0.0);
1849 M_LST (s1, REG_PV, a);
1850 M_DLD (d, REG_PV, a);
1852 store_reg_to_var_flt(iptr->dst, d);
1855 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1857 var_to_reg_flt(s1, src, REG_FTMP1);
1858 d = reg_of_var(iptr->dst, REG_ITMP3);
1859 a = dseg_adddouble(0.0);
1861 M_CVTDL_C(s1, REG_FTMP1);
1862 M_CVTLI(REG_FTMP1, REG_FTMP2);
1865 M_CVTDL_CS(s1, REG_FTMP1);
1867 M_CVTLIS(REG_FTMP1, REG_FTMP2);
1870 M_DST (REG_FTMP1, REG_PV, a);
1871 M_ILD (d, REG_PV, a);
1872 store_reg_to_var_int(iptr->dst, d);
1875 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1877 var_to_reg_flt(s1, src, REG_FTMP1);
1878 d = reg_of_var(iptr->dst, REG_ITMP3);
1879 a = dseg_adddouble(0.0);
1881 M_CVTDL_C(s1, REG_FTMP1);
1884 M_CVTDL_CS(s1, REG_FTMP1);
1887 M_DST (REG_FTMP1, REG_PV, a);
1888 M_LLD (d, REG_PV, a);
1889 store_reg_to_var_int(iptr->dst, d);
1892 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1894 var_to_reg_flt(s1, src, REG_FTMP1);
1895 d = reg_of_var(iptr->dst, REG_FTMP3);
1897 store_reg_to_var_flt(iptr->dst, d);
1900 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1902 var_to_reg_flt(s1, src, REG_FTMP1);
1903 d = reg_of_var(iptr->dst, REG_FTMP3);
1911 store_reg_to_var_flt(iptr->dst, d);
1914 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1916 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1917 var_to_reg_flt(s2, src, REG_FTMP2);
1918 d = reg_of_var(iptr->dst, REG_ITMP3);
1920 M_LSUB_IMM(REG_ZERO, 1, d);
1921 M_FCMPEQ(s1, s2, REG_FTMP3);
1922 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1924 M_FCMPLT(s2, s1, REG_FTMP3);
1925 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1926 M_LADD_IMM(REG_ZERO, 1, d);
1929 M_LSUB_IMM(REG_ZERO, 1, d);
1930 M_FCMPEQS(s1, s2, REG_FTMP3);
1932 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1934 M_FCMPLTS(s2, s1, REG_FTMP3);
1936 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1937 M_LADD_IMM(REG_ZERO, 1, d);
1939 store_reg_to_var_int(iptr->dst, d);
1942 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1944 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1945 var_to_reg_flt(s2, src, REG_FTMP2);
1946 d = reg_of_var(iptr->dst, REG_ITMP3);
1948 M_LADD_IMM(REG_ZERO, 1, d);
1949 M_FCMPEQ(s1, s2, REG_FTMP3);
1950 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1952 M_FCMPLT(s1, s2, REG_FTMP3);
1953 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1954 M_LSUB_IMM(REG_ZERO, 1, d);
1957 M_LADD_IMM(REG_ZERO, 1, d);
1958 M_FCMPEQS(s1, s2, REG_FTMP3);
1960 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1962 M_FCMPLTS(s1, s2, REG_FTMP3);
1964 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1965 M_LSUB_IMM(REG_ZERO, 1, d);
1967 store_reg_to_var_int(iptr->dst, d);
1971 /* memory operations **************************************************/
1973 /* #define gen_bound_check \
1975 M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\
1976 M_CMPULT(s2, REG_ITMP3, REG_ITMP3);\
1977 M_BEQZ(REG_ITMP3, 0);\
1978 codegen_addxboundrefs(mcodeptr);\
1982 #define gen_bound_check \
1983 if (checkbounds) { \
1984 M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\
1985 M_CMPULT(s2, REG_ITMP3, REG_ITMP3);\
1986 M_BEQZ(REG_ITMP3, 0);\
1987 codegen_addxboundrefs(mcodeptr); \
1990 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1992 var_to_reg_int(s1, src, REG_ITMP1);
1993 d = reg_of_var(iptr->dst, REG_ITMP3);
1994 gen_nullptr_check(s1);
1995 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1996 store_reg_to_var_int(iptr->dst, d);
1999 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
2001 var_to_reg_int(s1, src->prev, REG_ITMP1);
2002 var_to_reg_int(s2, src, REG_ITMP2);
2003 d = reg_of_var(iptr->dst, REG_ITMP3);
2004 if (iptr->op1 == 0) {
2005 gen_nullptr_check(s1);
2008 M_SAADDQ(s2, s1, REG_ITMP1);
2009 M_ALD( d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
2010 store_reg_to_var_int(iptr->dst, d);
2013 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
2015 var_to_reg_int(s1, src->prev, REG_ITMP1);
2016 var_to_reg_int(s2, src, REG_ITMP2);
2017 d = reg_of_var(iptr->dst, REG_ITMP3);
2018 if (iptr->op1 == 0) {
2019 gen_nullptr_check(s1);
2022 M_S8ADDQ(s2, s1, REG_ITMP1);
2023 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
2024 store_reg_to_var_int(iptr->dst, d);
2027 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
2029 var_to_reg_int(s1, src->prev, REG_ITMP1);
2030 var_to_reg_int(s2, src, REG_ITMP2);
2031 d = reg_of_var(iptr->dst, REG_ITMP3);
2032 if (iptr->op1 == 0) {
2033 gen_nullptr_check(s1);
2037 M_S4ADDQ(s2, s1, REG_ITMP1);
2038 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
2039 store_reg_to_var_int(iptr->dst, d);
2042 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
2044 var_to_reg_int(s1, src->prev, REG_ITMP1);
2045 var_to_reg_int(s2, src, REG_ITMP2);
2046 d = reg_of_var(iptr->dst, REG_FTMP3);
2047 if (iptr->op1 == 0) {
2048 gen_nullptr_check(s1);
2051 M_S4ADDQ(s2, s1, REG_ITMP1);
2052 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
2053 store_reg_to_var_flt(iptr->dst, d);
2056 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
2058 var_to_reg_int(s1, src->prev, REG_ITMP1);
2059 var_to_reg_int(s2, src, REG_ITMP2);
2060 d = reg_of_var(iptr->dst, REG_FTMP3);
2061 if (iptr->op1 == 0) {
2062 gen_nullptr_check(s1);
2065 M_S8ADDQ(s2, s1, REG_ITMP1);
2066 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
2067 store_reg_to_var_flt(iptr->dst, d);
2070 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
2072 var_to_reg_int(s1, src->prev, REG_ITMP1);
2073 var_to_reg_int(s2, src, REG_ITMP2);
2074 d = reg_of_var(iptr->dst, REG_ITMP3);
2075 if (iptr->op1 == 0) {
2076 gen_nullptr_check(s1);
2079 if (has_ext_instr_set) {
2080 M_LADD(s2, s1, REG_ITMP1);
2081 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2082 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
2085 M_LADD (s2, s1, REG_ITMP1);
2086 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2087 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2088 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2089 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
2091 store_reg_to_var_int(iptr->dst, d);
2094 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
2096 var_to_reg_int(s1, src->prev, REG_ITMP1);
2097 var_to_reg_int(s2, src, REG_ITMP2);
2098 d = reg_of_var(iptr->dst, REG_ITMP3);
2099 if (iptr->op1 == 0) {
2100 gen_nullptr_check(s1);
2103 if (has_ext_instr_set) {
2104 M_LADD(s2, s1, REG_ITMP1);
2105 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2106 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
2110 M_LADD(s2, s1, REG_ITMP1);
2111 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2112 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2113 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
2114 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
2115 M_SRA_IMM(d, 48, d);
2117 store_reg_to_var_int(iptr->dst, d);
2120 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
2122 var_to_reg_int(s1, src->prev, REG_ITMP1);
2123 var_to_reg_int(s2, src, REG_ITMP2);
2124 d = reg_of_var(iptr->dst, REG_ITMP3);
2125 if (iptr->op1 == 0) {
2126 gen_nullptr_check(s1);
2129 if (has_ext_instr_set) {
2130 M_LADD (s2, s1, REG_ITMP1);
2131 M_BLDU (d, REG_ITMP1, OFFSET (java_bytearray, data[0]));
2135 M_LADD(s2, s1, REG_ITMP1);
2136 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2137 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
2138 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
2139 M_SRA_IMM(d, 56, d);
2141 store_reg_to_var_int(iptr->dst, d);
2145 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
2147 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2148 var_to_reg_int(s2, src->prev, REG_ITMP2);
2149 if (iptr->op1 == 0) {
2150 gen_nullptr_check(s1);
2153 var_to_reg_int(s3, src, REG_ITMP3);
2154 M_SAADDQ(s2, s1, REG_ITMP1);
2155 M_AST (s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
2158 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
2160 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2161 var_to_reg_int(s2, src->prev, REG_ITMP2);
2162 if (iptr->op1 == 0) {
2163 gen_nullptr_check(s1);
2166 var_to_reg_int(s3, src, REG_ITMP3);
2167 M_S8ADDQ(s2, s1, REG_ITMP1);
2168 M_LST (s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
2171 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
2173 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2174 var_to_reg_int(s2, src->prev, REG_ITMP2);
2175 if (iptr->op1 == 0) {
2176 gen_nullptr_check(s1);
2180 var_to_reg_int(s3, src, REG_ITMP3);
2181 M_S4ADDQ(s2, s1, REG_ITMP1);
2182 M_IST (s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
2185 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
2187 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2188 var_to_reg_int(s2, src->prev, REG_ITMP2);
2189 if (iptr->op1 == 0) {
2190 gen_nullptr_check(s1);
2193 var_to_reg_flt(s3, src, REG_FTMP3);
2194 M_S4ADDQ(s2, s1, REG_ITMP1);
2195 M_FST (s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
2198 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
2200 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2201 var_to_reg_int(s2, src->prev, REG_ITMP2);
2202 if (iptr->op1 == 0) {
2203 gen_nullptr_check(s1);
2206 var_to_reg_flt(s3, src, REG_FTMP3);
2207 M_S8ADDQ(s2, s1, REG_ITMP1);
2208 M_DST (s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
2211 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
2213 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2214 var_to_reg_int(s2, src->prev, REG_ITMP2);
2215 if (iptr->op1 == 0) {
2216 gen_nullptr_check(s1);
2219 var_to_reg_int(s3, src, REG_ITMP3);
2220 if (has_ext_instr_set) {
2221 M_LADD(s2, s1, REG_ITMP1);
2222 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2223 M_SST (s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
2226 M_LADD (s2, s1, REG_ITMP1);
2227 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2228 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2229 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2230 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
2231 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2232 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2233 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2237 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
2239 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2240 var_to_reg_int(s2, src->prev, REG_ITMP2);
2241 if (iptr->op1 == 0) {
2242 gen_nullptr_check(s1);
2245 var_to_reg_int(s3, src, REG_ITMP3);
2246 if (has_ext_instr_set) {
2247 M_LADD(s2, s1, REG_ITMP1);
2248 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2249 M_SST (s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2252 M_LADD (s2, s1, REG_ITMP1);
2253 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2254 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2255 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2256 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
2257 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2258 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2259 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2263 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
2265 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2266 var_to_reg_int(s2, src->prev, REG_ITMP2);
2267 if (iptr->op1 == 0) {
2268 gen_nullptr_check(s1);
2271 var_to_reg_int(s3, src, REG_ITMP3);
2272 if (has_ext_instr_set) {
2273 M_LADD(s2, s1, REG_ITMP1);
2274 M_BST (s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2277 M_LADD (s2, s1, REG_ITMP1);
2278 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2279 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2280 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
2281 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2282 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2283 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2288 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2289 /* op1 = type, val.a = field address */
2291 a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value));
2292 M_ALD(REG_ITMP1, REG_PV, a);
2293 switch (iptr->op1) {
2295 var_to_reg_int(s2, src, REG_ITMP2);
2296 M_IST(s2, REG_ITMP1, 0);
2299 var_to_reg_int(s2, src, REG_ITMP2);
2300 M_LST(s2, REG_ITMP1, 0);
2303 var_to_reg_int(s2, src, REG_ITMP2);
2304 M_AST(s2, REG_ITMP1, 0);
2307 var_to_reg_flt(s2, src, REG_FTMP2);
2308 M_FST(s2, REG_ITMP1, 0);
2311 var_to_reg_flt(s2, src, REG_FTMP2);
2312 M_DST(s2, REG_ITMP1, 0);
2314 default: panic ("internal error");
2318 case ICMD_GETSTATIC: /* ... ==> ..., value */
2319 /* op1 = type, val.a = field address */
2321 a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value));
2322 M_ALD(REG_ITMP1, REG_PV, a);
2323 switch (iptr->op1) {
2325 d = reg_of_var(iptr->dst, REG_ITMP3);
2326 M_ILD(d, REG_ITMP1, 0);
2327 store_reg_to_var_int(iptr->dst, d);
2330 d = reg_of_var(iptr->dst, REG_ITMP3);
2331 M_LLD(d, REG_ITMP1, 0);
2332 store_reg_to_var_int(iptr->dst, d);
2335 d = reg_of_var(iptr->dst, REG_ITMP3);
2336 M_ALD(d, REG_ITMP1, 0);
2337 store_reg_to_var_int(iptr->dst, d);
2340 d = reg_of_var(iptr->dst, REG_FTMP1);
2341 M_FLD(d, REG_ITMP1, 0);
2342 store_reg_to_var_flt(iptr->dst, d);
2345 d = reg_of_var(iptr->dst, REG_FTMP1);
2346 M_DLD(d, REG_ITMP1, 0);
2347 store_reg_to_var_flt(iptr->dst, d);
2349 default: panic ("internal error");
2354 case ICMD_PUTFIELD: /* ..., value ==> ... */
2355 /* op1 = type, val.i = field offset */
2357 a = ((fieldinfo *)(iptr->val.a))->offset;
2358 switch (iptr->op1) {
2360 var_to_reg_int(s1, src->prev, REG_ITMP1);
2361 var_to_reg_int(s2, src, REG_ITMP2);
2362 gen_nullptr_check(s1);
2366 var_to_reg_int(s1, src->prev, REG_ITMP1);
2367 var_to_reg_int(s2, src, REG_ITMP2);
2368 gen_nullptr_check(s1);
2372 var_to_reg_int(s1, src->prev, REG_ITMP1);
2373 var_to_reg_int(s2, src, REG_ITMP2);
2374 gen_nullptr_check(s1);
2378 var_to_reg_int(s1, src->prev, REG_ITMP1);
2379 var_to_reg_flt(s2, src, REG_FTMP2);
2380 gen_nullptr_check(s1);
2384 var_to_reg_int(s1, src->prev, REG_ITMP1);
2385 var_to_reg_flt(s2, src, REG_FTMP2);
2386 gen_nullptr_check(s1);
2389 default: panic ("internal error");
2393 case ICMD_GETFIELD: /* ... ==> ..., value */
2394 /* op1 = type, val.i = field offset */
2396 a = ((fieldinfo *)(iptr->val.a))->offset;
2397 switch (iptr->op1) {
2399 var_to_reg_int(s1, src, REG_ITMP1);
2400 d = reg_of_var(iptr->dst, REG_ITMP3);
2401 gen_nullptr_check(s1);
2403 store_reg_to_var_int(iptr->dst, d);
2406 var_to_reg_int(s1, src, REG_ITMP1);
2407 d = reg_of_var(iptr->dst, REG_ITMP3);
2408 gen_nullptr_check(s1);
2410 store_reg_to_var_int(iptr->dst, d);
2413 var_to_reg_int(s1, src, REG_ITMP1);
2414 d = reg_of_var(iptr->dst, REG_ITMP3);
2415 gen_nullptr_check(s1);
2417 store_reg_to_var_int(iptr->dst, d);
2420 var_to_reg_int(s1, src, REG_ITMP1);
2421 d = reg_of_var(iptr->dst, REG_FTMP1);
2422 gen_nullptr_check(s1);
2424 store_reg_to_var_flt(iptr->dst, d);
2427 var_to_reg_int(s1, src, REG_ITMP1);
2428 d = reg_of_var(iptr->dst, REG_FTMP1);
2429 gen_nullptr_check(s1);
2431 store_reg_to_var_flt(iptr->dst, d);
2433 default: panic ("internal error");
2438 /* branch operations **************************************************/
2440 #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}}
2442 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2444 var_to_reg_int(s1, src, REG_ITMP1);
2445 M_INTMOVE(s1, REG_ITMP1_XPTR);
2446 a = dseg_addaddress(asm_handle_exception);
2447 M_ALD(REG_ITMP2, REG_PV, a);
2448 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2449 M_NOP; /* nop ensures that XPC is less than the end */
2450 /* of basic block */
2454 case ICMD_GOTO: /* ... ==> ... */
2455 /* op1 = target JavaVM pc */
2457 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2461 case ICMD_JSR: /* ... ==> ... */
2462 /* op1 = target JavaVM pc */
2464 M_BSR(REG_ITMP1, 0);
2465 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2468 case ICMD_RET: /* ... ==> ... */
2469 /* op1 = local variable */
2471 var = &(locals[iptr->op1][TYPE_ADR]);
2472 if (var->flags & INMEMORY) {
2473 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2474 M_RET(REG_ZERO, REG_ITMP1);
2477 M_RET(REG_ZERO, var->regoff);
2481 case ICMD_IFNULL: /* ..., value ==> ... */
2482 /* op1 = target JavaVM pc */
2484 var_to_reg_int(s1, src, REG_ITMP1);
2486 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2489 case ICMD_IFNONNULL: /* ..., value ==> ... */
2490 /* op1 = target JavaVM pc */
2492 var_to_reg_int(s1, src, REG_ITMP1);
2494 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2497 case ICMD_IFEQ: /* ..., value ==> ... */
2498 /* op1 = target JavaVM pc, val.i = constant */
2500 var_to_reg_int(s1, src, REG_ITMP1);
2501 if (iptr->val.i == 0) {
2505 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2506 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2509 ICONST(REG_ITMP2, iptr->val.i);
2510 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2512 M_BNEZ(REG_ITMP1, 0);
2514 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2517 case ICMD_IFLT: /* ..., value ==> ... */
2518 /* op1 = target JavaVM pc, val.i = constant */
2520 var_to_reg_int(s1, src, REG_ITMP1);
2521 if (iptr->val.i == 0) {
2525 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2526 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2529 ICONST(REG_ITMP2, iptr->val.i);
2530 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2532 M_BNEZ(REG_ITMP1, 0);
2534 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2537 case ICMD_IFLE: /* ..., value ==> ... */
2538 /* op1 = target JavaVM pc, val.i = constant */
2540 var_to_reg_int(s1, src, REG_ITMP1);
2541 if (iptr->val.i == 0) {
2545 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2546 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2549 ICONST(REG_ITMP2, iptr->val.i);
2550 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2552 M_BNEZ(REG_ITMP1, 0);
2554 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2557 case ICMD_IFNE: /* ..., value ==> ... */
2558 /* op1 = target JavaVM pc, val.i = constant */
2560 var_to_reg_int(s1, src, REG_ITMP1);
2561 if (iptr->val.i == 0) {
2565 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2566 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2569 ICONST(REG_ITMP2, iptr->val.i);
2570 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2572 M_BEQZ(REG_ITMP1, 0);
2574 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2577 case ICMD_IFGT: /* ..., value ==> ... */
2578 /* op1 = target JavaVM pc, val.i = constant */
2580 var_to_reg_int(s1, src, REG_ITMP1);
2581 if (iptr->val.i == 0) {
2585 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2586 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2589 ICONST(REG_ITMP2, iptr->val.i);
2590 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2592 M_BEQZ(REG_ITMP1, 0);
2594 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2597 case ICMD_IFGE: /* ..., value ==> ... */
2598 /* op1 = target JavaVM pc, val.i = constant */
2600 var_to_reg_int(s1, src, REG_ITMP1);
2601 if (iptr->val.i == 0) {
2605 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2606 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2609 ICONST(REG_ITMP2, iptr->val.i);
2610 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2612 M_BEQZ(REG_ITMP1, 0);
2614 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2617 case ICMD_IF_LEQ: /* ..., value ==> ... */
2618 /* op1 = target JavaVM pc, val.l = constant */
2620 var_to_reg_int(s1, src, REG_ITMP1);
2621 if (iptr->val.l == 0) {
2625 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2626 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2629 LCONST(REG_ITMP2, iptr->val.l);
2630 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2632 M_BNEZ(REG_ITMP1, 0);
2634 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2637 case ICMD_IF_LLT: /* ..., value ==> ... */
2638 /* op1 = target JavaVM pc, val.l = constant */
2640 var_to_reg_int(s1, src, REG_ITMP1);
2641 if (iptr->val.l == 0) {
2645 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2646 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2649 LCONST(REG_ITMP2, iptr->val.l);
2650 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2652 M_BNEZ(REG_ITMP1, 0);
2654 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2657 case ICMD_IF_LLE: /* ..., value ==> ... */
2658 /* op1 = target JavaVM pc, val.l = constant */
2660 var_to_reg_int(s1, src, REG_ITMP1);
2661 if (iptr->val.l == 0) {
2665 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2666 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2669 LCONST(REG_ITMP2, iptr->val.l);
2670 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2672 M_BNEZ(REG_ITMP1, 0);
2674 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2677 case ICMD_IF_LNE: /* ..., value ==> ... */
2678 /* op1 = target JavaVM pc, val.l = constant */
2680 var_to_reg_int(s1, src, REG_ITMP1);
2681 if (iptr->val.l == 0) {
2685 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2686 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2689 LCONST(REG_ITMP2, iptr->val.l);
2690 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2692 M_BEQZ(REG_ITMP1, 0);
2694 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2697 case ICMD_IF_LGT: /* ..., value ==> ... */
2698 /* op1 = target JavaVM pc, val.l = constant */
2700 var_to_reg_int(s1, src, REG_ITMP1);
2701 if (iptr->val.l == 0) {
2705 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2706 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2709 LCONST(REG_ITMP2, iptr->val.l);
2710 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2712 M_BEQZ(REG_ITMP1, 0);
2714 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2717 case ICMD_IF_LGE: /* ..., value ==> ... */
2718 /* op1 = target JavaVM pc, val.l = constant */
2720 var_to_reg_int(s1, src, REG_ITMP1);
2721 if (iptr->val.l == 0) {
2725 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2726 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2729 LCONST(REG_ITMP2, iptr->val.l);
2730 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2732 M_BEQZ(REG_ITMP1, 0);
2734 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2737 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2738 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2739 case ICMD_IF_ACMPEQ:
2741 var_to_reg_int(s1, src->prev, REG_ITMP1);
2742 var_to_reg_int(s2, src, REG_ITMP2);
2743 M_CMPEQ(s1, s2, REG_ITMP1);
2744 M_BNEZ(REG_ITMP1, 0);
2745 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2748 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2749 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2750 case ICMD_IF_ACMPNE:
2752 var_to_reg_int(s1, src->prev, REG_ITMP1);
2753 var_to_reg_int(s2, src, REG_ITMP2);
2754 M_CMPEQ(s1, s2, REG_ITMP1);
2755 M_BEQZ(REG_ITMP1, 0);
2756 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2759 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2760 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2762 var_to_reg_int(s1, src->prev, REG_ITMP1);
2763 var_to_reg_int(s2, src, REG_ITMP2);
2764 M_CMPLT(s1, s2, REG_ITMP1);
2765 M_BNEZ(REG_ITMP1, 0);
2766 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2769 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2770 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2772 var_to_reg_int(s1, src->prev, REG_ITMP1);
2773 var_to_reg_int(s2, src, REG_ITMP2);
2774 M_CMPLE(s1, s2, REG_ITMP1);
2775 M_BEQZ(REG_ITMP1, 0);
2776 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2779 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2780 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2782 var_to_reg_int(s1, src->prev, REG_ITMP1);
2783 var_to_reg_int(s2, src, REG_ITMP2);
2784 M_CMPLE(s1, s2, REG_ITMP1);
2785 M_BNEZ(REG_ITMP1, 0);
2786 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2789 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2790 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2792 var_to_reg_int(s1, src->prev, REG_ITMP1);
2793 var_to_reg_int(s2, src, REG_ITMP2);
2794 M_CMPLT(s1, s2, REG_ITMP1);
2795 M_BEQZ(REG_ITMP1, 0);
2796 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2799 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2801 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2804 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2805 /* val.i = constant */
2807 var_to_reg_int(s1, src, REG_ITMP1);
2808 d = reg_of_var(iptr->dst, REG_ITMP3);
2810 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2811 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2812 M_CMPEQ(s1, REG_ZERO, d);
2813 store_reg_to_var_int(iptr->dst, d);
2816 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2817 M_CMPEQ(s1, REG_ZERO, d);
2819 store_reg_to_var_int(iptr->dst, d);
2823 M_MOV(s1, REG_ITMP1);
2826 ICONST(d, iptr[1].val.i);
2828 if ((s3 >= 0) && (s3 <= 255)) {
2829 M_CMOVEQ_IMM(s1, s3, d);
2832 ICONST(REG_ITMP2, s3);
2833 M_CMOVEQ(s1, REG_ITMP2, d);
2835 store_reg_to_var_int(iptr->dst, d);
2838 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2839 /* val.i = constant */
2841 var_to_reg_int(s1, src, REG_ITMP1);
2842 d = reg_of_var(iptr->dst, REG_ITMP3);
2844 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2845 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2846 M_CMPEQ(s1, REG_ZERO, d);
2847 store_reg_to_var_int(iptr->dst, d);
2850 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2851 M_CMPEQ(s1, REG_ZERO, d);
2853 store_reg_to_var_int(iptr->dst, d);
2857 M_MOV(s1, REG_ITMP1);
2860 ICONST(d, iptr[1].val.i);
2862 if ((s3 >= 0) && (s3 <= 255)) {
2863 M_CMOVNE_IMM(s1, s3, d);
2866 ICONST(REG_ITMP2, s3);
2867 M_CMOVNE(s1, REG_ITMP2, d);
2869 store_reg_to_var_int(iptr->dst, d);
2872 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2873 /* val.i = constant */
2875 var_to_reg_int(s1, src, REG_ITMP1);
2876 d = reg_of_var(iptr->dst, REG_ITMP3);
2878 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2879 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2880 M_CMPLT(s1, REG_ZERO, d);
2881 store_reg_to_var_int(iptr->dst, d);
2884 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2885 M_CMPLE(REG_ZERO, s1, d);
2886 store_reg_to_var_int(iptr->dst, d);
2890 M_MOV(s1, REG_ITMP1);
2893 ICONST(d, iptr[1].val.i);
2895 if ((s3 >= 0) && (s3 <= 255)) {
2896 M_CMOVLT_IMM(s1, s3, d);
2899 ICONST(REG_ITMP2, s3);
2900 M_CMOVLT(s1, REG_ITMP2, d);
2902 store_reg_to_var_int(iptr->dst, d);
2905 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2906 /* val.i = constant */
2908 var_to_reg_int(s1, src, REG_ITMP1);
2909 d = reg_of_var(iptr->dst, REG_ITMP3);
2911 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2912 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2913 M_CMPLE(REG_ZERO, s1, d);
2914 store_reg_to_var_int(iptr->dst, d);
2917 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2918 M_CMPLT(s1, REG_ZERO, d);
2919 store_reg_to_var_int(iptr->dst, d);
2923 M_MOV(s1, REG_ITMP1);
2926 ICONST(d, iptr[1].val.i);
2928 if ((s3 >= 0) && (s3 <= 255)) {
2929 M_CMOVGE_IMM(s1, s3, d);
2932 ICONST(REG_ITMP2, s3);
2933 M_CMOVGE(s1, REG_ITMP2, d);
2935 store_reg_to_var_int(iptr->dst, d);
2938 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2939 /* val.i = constant */
2941 var_to_reg_int(s1, src, REG_ITMP1);
2942 d = reg_of_var(iptr->dst, REG_ITMP3);
2944 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2945 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2946 M_CMPLT(REG_ZERO, s1, d);
2947 store_reg_to_var_int(iptr->dst, d);
2950 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2951 M_CMPLE(s1, REG_ZERO, d);
2952 store_reg_to_var_int(iptr->dst, d);
2956 M_MOV(s1, REG_ITMP1);
2959 ICONST(d, iptr[1].val.i);
2961 if ((s3 >= 0) && (s3 <= 255)) {
2962 M_CMOVGT_IMM(s1, s3, d);
2965 ICONST(REG_ITMP2, s3);
2966 M_CMOVGT(s1, REG_ITMP2, d);
2968 store_reg_to_var_int(iptr->dst, d);
2971 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2972 /* val.i = constant */
2974 var_to_reg_int(s1, src, REG_ITMP1);
2975 d = reg_of_var(iptr->dst, REG_ITMP3);
2977 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2978 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2979 M_CMPLE(s1, REG_ZERO, d);
2980 store_reg_to_var_int(iptr->dst, d);
2983 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2984 M_CMPLT(REG_ZERO, s1, d);
2985 store_reg_to_var_int(iptr->dst, d);
2989 M_MOV(s1, REG_ITMP1);
2992 ICONST(d, iptr[1].val.i);
2994 if ((s3 >= 0) && (s3 <= 255)) {
2995 M_CMOVLE_IMM(s1, s3, d);
2998 ICONST(REG_ITMP2, s3);
2999 M_CMOVLE(s1, REG_ITMP2, d);
3001 store_reg_to_var_int(iptr->dst, d);
3005 case ICMD_IRETURN: /* ..., retvalue ==> ... */
3010 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3012 a = dseg_addaddress ((void*) (builtin_monitorexit));
3013 M_ALD(REG_PV, REG_PV, a);
3014 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
3015 M_JSR(REG_RA, REG_PV);
3016 disp = -(int)((u1*) mcodeptr - mcodebase);
3017 M_LDA(REG_PV, REG_RA, disp);
3020 var_to_reg_int(s1, src, REG_RESULT);
3021 M_INTMOVE(s1, REG_RESULT);
3022 goto nowperformreturn;
3024 case ICMD_FRETURN: /* ..., retvalue ==> ... */
3028 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3030 a = dseg_addaddress ((void*) (builtin_monitorexit));
3031 M_ALD(REG_PV, REG_PV, a);
3032 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
3033 M_JSR(REG_RA, REG_PV);
3034 disp = -(int)((u1*) mcodeptr - mcodebase);
3035 M_LDA(REG_PV, REG_RA, disp);
3038 var_to_reg_flt(s1, src, REG_FRESULT);
3039 M_FLTMOVE(s1, REG_FRESULT);
3040 goto nowperformreturn;
3042 case ICMD_RETURN: /* ... ==> ... */
3045 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3047 a = dseg_addaddress ((void*) (builtin_monitorexit));
3048 M_ALD(REG_PV, REG_PV, a);
3049 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
3050 M_JSR(REG_RA, REG_PV);
3051 disp = -(int)((u1*) mcodeptr - mcodebase);
3052 M_LDA(REG_PV, REG_RA, disp);
3060 p = parentargs_base;
3062 /* restore return address */
3065 {p--; M_LLD (REG_RA, REG_SP, 8 * p);}
3067 /* restore saved registers */
3069 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
3070 {p--; M_LLD(savintregs[r], REG_SP, 8 * p);}
3071 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
3072 {p--; M_DLD(savfltregs[r], REG_SP, 8 * p);}
3074 /* deallocate stack */
3076 if (parentargs_base)
3077 {M_LDA(REG_SP, REG_SP, parentargs_base*8);}
3079 /* call trace function */
3082 M_LDA (REG_SP, REG_SP, -24);
3083 M_AST(REG_RA, REG_SP, 0);
3084 M_LST(REG_RESULT, REG_SP, 8);
3085 M_DST(REG_FRESULT, REG_SP,16);
3086 a = dseg_addaddress (method);
3087 M_ALD(argintregs[0], REG_PV, a);
3088 M_MOV(REG_RESULT, argintregs[1]);
3089 M_FLTMOVE(REG_FRESULT, argfltregs[2]);
3090 M_FLTMOVE(REG_FRESULT, argfltregs[3]);
3091 a = dseg_addaddress ((void*) (builtin_displaymethodstop));
3092 M_ALD(REG_PV, REG_PV, a);
3093 M_JSR (REG_RA, REG_PV);
3094 s1 = (int)((u1*) mcodeptr - mcodebase);
3095 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
3098 while (ml<-32768) { ml+=65536; mh--; }
3099 M_LDA (REG_PV, REG_RA, ml );
3100 M_LDAH (REG_PV, REG_PV, mh );
3102 M_DLD(REG_FRESULT, REG_SP,16);
3103 M_LLD(REG_RESULT, REG_SP, 8);
3104 M_ALD(REG_RA, REG_SP, 0);
3105 M_LDA (REG_SP, REG_SP, 24);
3108 M_RET(REG_ZERO, REG_RA);
3114 case ICMD_TABLESWITCH: /* ..., index ==> ... */
3119 tptr = (void **) iptr->target;
3121 s4ptr = iptr->val.a;
3122 l = s4ptr[1]; /* low */
3123 i = s4ptr[2]; /* high */
3125 var_to_reg_int(s1, src, REG_ITMP1);
3127 {M_INTMOVE(s1, REG_ITMP1);}
3128 else if (l <= 32768) {
3129 M_LDA(REG_ITMP1, s1, -l);
3132 ICONST(REG_ITMP2, l);
3133 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
3140 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
3142 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
3143 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3145 M_BEQZ(REG_ITMP2, 0);
3148 /* codegen_addreference(BlockPtrOfPC(s4ptr[0]), mcodeptr); */
3149 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3151 /* build jump table top down and use address of lowest entry */
3153 /* s4ptr += 3 + i; */
3157 /* dseg_addtarget(BlockPtrOfPC(*--s4ptr)); */
3158 dseg_addtarget((basicblock *) tptr[0]);
3163 /* length of dataseg after last dseg_addtarget is used by load */
3165 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
3166 M_ALD(REG_ITMP2, REG_ITMP2, -dseglen);
3167 M_JMP(REG_ZERO, REG_ITMP2);
3172 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3174 s4 i, l, val, *s4ptr;
3177 tptr = (void **) iptr->target;
3179 s4ptr = iptr->val.a;
3180 l = s4ptr[0]; /* default */
3181 i = s4ptr[1]; /* count */
3183 MCODECHECK((i<<2)+8);
3184 var_to_reg_int(s1, src, REG_ITMP1);
3190 if ((val >= 0) && (val <= 255)) {
3191 M_CMPEQ_IMM(s1, val, REG_ITMP2);
3194 if ((val >= -32768) && (val <= 32767)) {
3195 M_LDA(REG_ITMP2, REG_ZERO, val);
3198 a = dseg_adds4 (val);
3199 M_ILD(REG_ITMP2, REG_PV, a);
3201 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
3203 M_BNEZ(REG_ITMP2, 0);
3204 /* codegen_addreference(BlockPtrOfPC(s4ptr[1]), mcodeptr); */
3205 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3209 /* codegen_addreference(BlockPtrOfPC(l), mcodeptr); */
3211 tptr = (void **) iptr->target;
3212 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3219 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
3220 /* op1 = return type, val.a = function pointer*/
3224 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
3225 /* op1 = return type, val.a = function pointer*/
3229 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
3230 /* op1 = return type, val.a = function pointer*/
3234 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3235 /* op1 = arg count, val.a = method pointer */
3237 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3238 /* op1 = arg count, val.a = method pointer */
3240 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3241 /* op1 = arg count, val.a = method pointer */
3243 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
3244 /* op1 = arg count, val.a = method pointer */
3252 MCODECHECK((s3 << 1) + 64);
3254 /* copy arguments to registers or stack location */
3256 for (; --s3 >= 0; src = src->prev) {
3257 if (src->varkind == ARGVAR)
3259 if (IS_INT_LNG_TYPE(src->type)) {
3260 if (s3 < INT_ARG_CNT) {
3261 s1 = argintregs[s3];
3262 var_to_reg_int(d, src, s1);
3266 var_to_reg_int(d, src, REG_ITMP1);
3267 M_LST(d, REG_SP, 8 * (s3 - INT_ARG_CNT));
3271 if (s3 < FLT_ARG_CNT) {
3272 s1 = argfltregs[s3];
3273 var_to_reg_flt(d, src, s1);
3277 var_to_reg_flt(d, src, REG_FTMP1);
3278 M_DST(d, REG_SP, 8 * (s3 - FLT_ARG_CNT));
3283 switch (iptr->opc) {
3287 a = dseg_addaddress ((void*) (m));
3289 M_ALD(REG_PV, REG_PV, a); /* Pointer to built-in-function */
3291 goto makeactualcall;
3293 case ICMD_INVOKESTATIC:
3294 case ICMD_INVOKESPECIAL:
3295 a = dseg_addaddress (m->stubroutine);
3297 M_ALD(REG_PV, REG_PV, a ); /* method pointer in r27 */
3300 goto makeactualcall;
3302 case ICMD_INVOKEVIRTUAL:
3304 gen_nullptr_check(argintregs[0]);
3305 M_ALD(REG_METHODPTR, argintregs[0],
3306 OFFSET(java_objectheader, vftbl));
3307 M_ALD(REG_PV, REG_METHODPTR, OFFSET(vftbl, table[0]) +
3308 sizeof(methodptr) * m->vftblindex);
3311 goto makeactualcall;
3313 case ICMD_INVOKEINTERFACE:
3316 gen_nullptr_check(argintregs[0]);
3317 M_ALD(REG_METHODPTR, argintregs[0],
3318 OFFSET(java_objectheader, vftbl));
3319 M_ALD(REG_METHODPTR, REG_METHODPTR,
3320 OFFSET(vftbl, interfacetable[0]) -
3321 sizeof(methodptr*) * ci->index);
3322 M_ALD(REG_PV, REG_METHODPTR,
3323 sizeof(methodptr) * (m - ci->methods));
3326 goto makeactualcall;
3330 sprintf (logtext, "Unkown ICMD-Command: %d", iptr->opc);
3336 M_JSR (REG_RA, REG_PV);
3340 s1 = (int)((u1*) mcodeptr - mcodebase);
3341 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
3344 while (ml<-32768) { ml+=65536; mh--; }
3345 M_LDA (REG_PV, REG_RA, ml );
3346 M_LDAH (REG_PV, REG_PV, mh );
3349 /* d contains return type */
3351 if (d != TYPE_VOID) {
3352 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3353 s1 = reg_of_var(iptr->dst, REG_RESULT);
3354 M_INTMOVE(REG_RESULT, s1);
3355 store_reg_to_var_int(iptr->dst, s1);
3358 s1 = reg_of_var(iptr->dst, REG_FRESULT);
3359 M_FLTMOVE(REG_FRESULT, s1);
3360 store_reg_to_var_flt(iptr->dst, s1);
3367 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3369 /* op1: 0 == array, 1 == class */
3370 /* val.a: (classinfo*) superclass */
3372 /* superclass is an interface:
3374 * return (sub != NULL) &&
3375 * (sub->vftbl->interfacetablelength > super->index) &&
3376 * (sub->vftbl->interfacetable[-super->index] != NULL);
3378 * superclass is a class:
3380 * return ((sub != NULL) && (0
3381 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3382 * super->vftbl->diffvall));
3386 classinfo *super = (classinfo*) iptr->val.a;
3388 var_to_reg_int(s1, src, REG_ITMP1);
3389 d = reg_of_var(iptr->dst, REG_ITMP3);
3391 M_MOV(s1, REG_ITMP1);
3395 if (iptr->op1) { /* class/interface */
3396 if (super->flags & ACC_INTERFACE) { /* interface */
3398 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3399 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3400 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3401 M_BLEZ(REG_ITMP2, 2);
3402 M_ALD(REG_ITMP1, REG_ITMP1,
3403 OFFSET(vftbl, interfacetable[0]) -
3404 super->index * sizeof(methodptr*));
3405 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3409 s2 = super->vftbl->diffval;
3410 M_BEQZ(s1, 4 + (s2 > 255));
3411 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3412 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3413 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3415 M_CMPULE_IMM(REG_ITMP1, s2, d);
3417 M_LDA(REG_ITMP2, REG_ZERO, s2);
3418 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3422 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3423 a = dseg_addaddress ((void*) super->vftbl);
3424 M_ALD(REG_ITMP2, REG_PV, a);
3425 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3426 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl, baseval));
3427 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, diffval));
3428 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3429 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3433 panic ("internal error: no inlined array instanceof");
3435 store_reg_to_var_int(iptr->dst, d);
3438 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3440 /* op1: 0 == array, 1 == class */
3441 /* val.a: (classinfo*) superclass */
3443 /* superclass is an interface:
3445 * OK if ((sub == NULL) ||
3446 * (sub->vftbl->interfacetablelength > super->index) &&
3447 * (sub->vftbl->interfacetable[-super->index] != NULL));
3449 * superclass is a class:
3451 * OK if ((sub == NULL) || (0
3452 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3453 * super->vftbl->diffvall));
3457 classinfo *super = (classinfo*) iptr->val.a;
3459 d = reg_of_var(iptr->dst, REG_ITMP3);
3460 var_to_reg_int(s1, src, d);
3461 if (iptr->op1) { /* class/interface */
3462 if (super->flags & ACC_INTERFACE) { /* interface */
3464 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3465 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3466 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3467 M_BLEZ(REG_ITMP2, 0);
3468 codegen_addxcastrefs(mcodeptr);
3469 M_ALD(REG_ITMP2, REG_ITMP1,
3470 OFFSET(vftbl, interfacetable[0]) -
3471 super->index * sizeof(methodptr*));
3472 M_BEQZ(REG_ITMP2, 0);
3473 codegen_addxcastrefs(mcodeptr);
3477 s2 = super->vftbl->diffval;
3478 M_BEQZ(s1, 4 + (s2 != 0) + (s2 > 255));
3479 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3480 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3481 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3483 M_BNEZ(REG_ITMP1, 0);
3485 else if (s2 <= 255) {
3486 M_CMPULE_IMM(REG_ITMP1, s2, REG_ITMP2);
3487 M_BEQZ(REG_ITMP2, 0);
3490 M_LDA(REG_ITMP2, REG_ZERO, s2);
3491 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3492 M_BEQZ(REG_ITMP2, 0);
3495 M_BEQZ(s1, 8 + (d == REG_ITMP3));
3496 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3497 a = dseg_addaddress ((void*) super->vftbl);
3498 M_ALD(REG_ITMP2, REG_PV, a);
3499 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3500 if (d != REG_ITMP3) {
3501 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl, baseval));
3502 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, diffval));
3503 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3506 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, baseval));
3507 M_ISUB(REG_ITMP1, REG_ITMP2, REG_ITMP1);
3508 M_ALD(REG_ITMP2, REG_PV, a);
3509 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, diffval));
3511 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3512 M_BEQZ(REG_ITMP2, 0);
3513 codegen_addxcastrefs(mcodeptr);
3517 panic ("internal error: no inlined array checkcast");
3520 store_reg_to_var_int(iptr->dst, d);
3523 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
3525 var_to_reg_int(s1, src, REG_ITMP1);
3527 codegen_addxcheckarefs(mcodeptr);
3530 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3531 /* op1 = dimension, val.a = array descriptor */
3533 /* check for negative sizes and copy sizes to stack if necessary */
3535 MCODECHECK((iptr->op1 << 1) + 64);
3537 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3538 var_to_reg_int(s2, src, REG_ITMP1);
3540 codegen_addxcheckarefs(mcodeptr);
3542 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
3544 if (src->varkind != ARGVAR) {
3545 M_LST(s2, REG_SP, 8 * (s1 + INT_ARG_CNT));
3549 /* a0 = dimension count */
3551 ICONST(argintregs[0], iptr->op1);
3553 /* a1 = arraydescriptor */
3555 a = dseg_addaddress(iptr->val.a);
3556 M_ALD(argintregs[1], REG_PV, a);
3558 /* a2 = pointer to dimensions = stack pointer */
3560 M_INTMOVE(REG_SP, argintregs[2]);
3562 a = dseg_addaddress((void*) (builtin_nmultianewarray));
3563 M_ALD(REG_PV, REG_PV, a);
3564 M_JSR(REG_RA, REG_PV);
3565 s1 = (int)((u1*) mcodeptr - mcodebase);
3567 M_LDA (REG_PV, REG_RA, -s1);
3569 s4 ml = -s1, mh = 0;
3570 while (ml < -32768) {ml += 65536; mh--;}
3571 M_LDA(REG_PV, REG_RA, ml);
3572 M_LDAH(REG_PV, REG_PV, mh);
3574 s1 = reg_of_var(iptr->dst, REG_RESULT);
3575 M_INTMOVE(REG_RESULT, s1);
3576 store_reg_to_var_int(iptr->dst, s1);
3580 default: sprintf (logtext, "Unknown pseudo command: %d", iptr->opc);
3587 } /* for instruction */
3589 /* copy values to interface registers */
3591 src = bptr->outstack;
3592 len = bptr->outdepth;
3596 if ((src->varkind != STACKVAR)) {
3598 if (IS_FLT_DBL_TYPE(s2)) {
3599 var_to_reg_flt(s1, src, REG_FTMP1);
3600 if (!(interfaces[len][s2].flags & INMEMORY)) {
3601 M_FLTMOVE(s1,interfaces[len][s2].regoff);
3604 M_DST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3608 var_to_reg_int(s1, src, REG_ITMP1);
3609 if (!(interfaces[len][s2].flags & INMEMORY)) {
3610 M_INTMOVE(s1,interfaces[len][s2].regoff);
3613 M_LST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3619 } /* if (bptr -> flags >= BBREACHED) */
3620 } /* for basic block */
3622 /* bptr -> mpc = (int)((u1*) mcodeptr - mcodebase); */
3625 /* generate bound check stubs */
3627 s4 *xcodeptr = NULL;
3629 for (; xboundrefs != NULL; xboundrefs = xboundrefs->next) {
3630 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3631 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
3632 xboundrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3637 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
3638 xboundrefs->branchpos, (u1*) mcodeptr - mcodebase);
3642 M_LDA(REG_ITMP2_XPC, REG_PV, xboundrefs->branchpos - 4);
3644 if (xcodeptr != NULL) {
3645 int disp = (xcodeptr-mcodeptr)-1;
3649 xcodeptr = mcodeptr;
3651 a = dseg_addaddress(proto_java_lang_ArrayIndexOutOfBoundsException);
3652 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3654 a = dseg_addaddress(asm_handle_exception);
3655 M_ALD(REG_ITMP3, REG_PV, a);
3657 M_JMP(REG_ZERO, REG_ITMP3);
3661 /* generate negative array size check stubs */
3665 for (; xcheckarefs != NULL; xcheckarefs = xcheckarefs->next) {
3666 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3667 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3668 xcheckarefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3672 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3673 xcheckarefs->branchpos, (u1*) mcodeptr - mcodebase);
3677 M_LDA(REG_ITMP2_XPC, REG_PV, xcheckarefs->branchpos - 4);
3679 if (xcodeptr != NULL) {
3680 int disp = (xcodeptr-mcodeptr)-1;
3684 xcodeptr = mcodeptr;
3686 a = dseg_addaddress(proto_java_lang_NegativeArraySizeException);
3687 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3689 a = dseg_addaddress(asm_handle_exception);
3690 M_ALD(REG_ITMP3, REG_PV, a);
3692 M_JMP(REG_ZERO, REG_ITMP3);
3696 /* generate cast check stubs */
3700 for (; xcastrefs != NULL; xcastrefs = xcastrefs->next) {
3701 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3702 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3703 xcastrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3707 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3708 xcastrefs->branchpos, (u1*) mcodeptr - mcodebase);
3712 M_LDA(REG_ITMP2_XPC, REG_PV, xcastrefs->branchpos - 4);
3714 if (xcodeptr != NULL) {
3715 int disp = (xcodeptr-mcodeptr)-1;
3719 xcodeptr = mcodeptr;
3721 a = dseg_addaddress(proto_java_lang_ClassCastException);
3722 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3724 a = dseg_addaddress(asm_handle_exception);
3725 M_ALD(REG_ITMP3, REG_PV, a);
3727 M_JMP(REG_ZERO, REG_ITMP3);
3732 #ifdef SOFTNULLPTRCHECK
3734 /* generate null pointer check stubs */
3738 for (; xnullrefs != NULL; xnullrefs = xnullrefs->next) {
3739 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3740 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3741 xnullrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3745 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3746 xnullrefs->branchpos, (u1*) mcodeptr - mcodebase);
3750 M_LDA(REG_ITMP2_XPC, REG_PV, xnullrefs->branchpos - 4);
3752 if (xcodeptr != NULL) {
3753 int disp = (xcodeptr-mcodeptr)-1;
3757 xcodeptr = mcodeptr;
3759 a = dseg_addaddress(proto_java_lang_NullPointerException);
3760 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3762 a = dseg_addaddress(asm_handle_exception);
3763 M_ALD(REG_ITMP3, REG_PV, a);
3765 M_JMP(REG_ZERO, REG_ITMP3);
3772 codegen_finish((int)((u1*) mcodeptr - mcodebase));
3776 /* redefinition of code generation macros (compiling into array) **************/
3779 These macros are newly defined to allow code generation into an array.
3780 This is necessary, because the original M_.. macros generate code by
3781 calling 'codegen_adds4' that uses an additional data structure to
3784 For a faster (but less flexible) version to generate code, these
3785 macros directly use the (s4* p) - pointer to put the code directly
3786 in a locally defined array.
3787 This makes sense only for the stub-generation-routines below.
3791 #define M_OP3(op,fu,a,b,c,const) \
3792 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<(16-3*(const)))| \
3793 ((const)<<12)|((fu)<<5)|((c)) )
3795 #define M_FOP3(op,fu,a,b,c) \
3796 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<16)|((fu)<<5)|(c) )
3798 #define M_BRA(op,a,disp) \
3799 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((disp)&0x1fffff) )
3801 #define M_MEM(op,a,b,disp) \
3802 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<16)|((disp)&0xffff) )
3805 /* function createcompilerstub *************************************************
3807 creates a stub routine which calls the compiler
3809 *******************************************************************************/
3811 #define COMPSTUBSIZE 3
3813 u1 *createcompilerstub (methodinfo *m)
3815 u8 *s = CNEW (u8, COMPSTUBSIZE); /* memory to hold the stub */
3816 s4 *p = (s4*) s; /* code generation pointer */
3818 /* code for the stub */
3819 M_ALD (REG_PV, REG_PV, 16); /* load pointer to the compiler */
3820 M_JMP (0, REG_PV); /* jump to the compiler, return address
3821 in reg 0 is used as method pointer */
3822 s[1] = (u8) m; /* literals to be adressed */
3823 s[2] = (u8) asm_call_jit_compiler; /* jump directly via PV from above */
3826 count_cstub_len += COMPSTUBSIZE * 8;
3833 /* function removecompilerstub *************************************************
3835 deletes a compilerstub from memory (simply by freeing it)
3837 *******************************************************************************/
3839 void removecompilerstub (u1 *stub)
3841 CFREE (stub, COMPSTUBSIZE * 8);
3844 /* function: createnativestub **************************************************
3846 creates a stub routine which calls a native method
3848 *******************************************************************************/
3850 #define NATIVESTUBSIZE 34
3851 #define NATIVESTUBOFFSET 8
3853 int runverbosenat = 0;
3855 u1 *createnativestub (functionptr f, methodinfo *m)
3858 u8 *s = CNEW (u8, NATIVESTUBSIZE); /* memory to hold the stub */
3859 u8 *cs = s + NATIVESTUBOFFSET;
3860 s4 *p = (s4*) (cs); /* code generation pointer */
3862 *(cs-1) = (u8) f; /* address of native method */
3863 *(cs-2) = (u8) (&exceptionptr); /* address of exceptionptr */
3864 *(cs-3) = (u8) asm_handle_nat_exception; /* addr of asm exception handler */
3865 *(cs-4) = (u8) (&env); /* addr of jni_environement */
3866 *(cs-5) = (u8) asm_builtin_trace;
3868 *(cs-7) = (u8) asm_builtin_exittrace;
3869 *(cs-8) = (u8) builtin_trace_exception;
3873 utf_display(m->class->name);
3875 utf_display(m->name);
3876 printf(" 0x%p\n", cs);
3879 M_LDA (REG_SP, REG_SP, -8); /* build up stackframe */
3880 M_AST (REG_RA, REG_SP, 0); /* store return address */
3883 if (runverbosenat) {
3884 M_ALD(REG_ITMP1, REG_PV, -6*8);
3885 M_ALD(REG_PV, REG_PV, -5*8);
3887 M_JSR(REG_RA, REG_PV);
3888 disp = -(int) (p - (s4*) cs)*4;
3889 M_LDA(REG_PV, REG_RA, disp);
3895 M_MOV (argintregs[4],argintregs[5]);
3896 M_FMOV (argfltregs[4],argfltregs[5]);
3898 M_MOV (argintregs[3],argintregs[4]);
3899 M_FMOV (argfltregs[3],argfltregs[4]);
3901 M_MOV (argintregs[2],argintregs[3]);
3902 M_FMOV (argfltregs[2],argfltregs[3]);
3904 M_MOV (argintregs[1],argintregs[2]);
3905 M_FMOV (argfltregs[1],argfltregs[2]);
3907 M_MOV (argintregs[0],argintregs[1]);
3908 M_FMOV (argfltregs[0],argfltregs[1]);
3910 M_ALD (argintregs[0], REG_PV, -4*8);/* load adress of jni_environement */
3912 M_ALD (REG_PV, REG_PV, -1*8); /* load adress of native method */
3913 M_JSR (REG_RA, REG_PV); /* call native method */
3915 disp = -(int) (p - (s4*) cs)*4;
3916 M_LDA (REG_PV, REG_RA, disp); /* recompute pv from ra */
3917 M_ALD (REG_ITMP3, REG_PV, -2*8); /* get address of exceptionptr */
3919 M_ALD (REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
3921 3 + (runverbosenat ? 6 : 0)); /* if no exception then return */
3924 if (runverbosenat) {
3925 M_ALD(argintregs[0], REG_PV, -6*8);
3926 M_MOV(REG_RESULT, argintregs[1]);
3927 M_FMOV(REG_FRESULT, argfltregs[2]);
3928 M_FMOV(REG_FRESULT, argfltregs[3]);
3929 M_ALD(REG_PV, REG_PV, -7*8);
3930 M_JSR(REG_RA, REG_PV);
3934 M_ALD (REG_RA, REG_SP, 0); /* load return address */
3935 M_LDA (REG_SP, REG_SP, 8); /* remove stackframe */
3937 M_RET (REG_ZERO, REG_RA); /* return to caller */
3939 M_AST (REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
3942 if (runverbosenat) {
3943 M_LDA(REG_SP, REG_SP, -8);
3944 M_AST(REG_ITMP1, REG_SP, 0);
3945 M_MOV(REG_ITMP1, argintregs[0]);
3946 M_ALD(argintregs[1], REG_PV, -6*8);
3947 M_ALD(argintregs[2], REG_SP, 0);
3948 M_CLR(argintregs[3]);
3949 M_ALD(REG_PV, REG_PV, -8*8);
3950 M_JSR(REG_RA, REG_PV);
3951 disp = -(int) (p - (s4*) cs)*4;
3952 M_LDA (REG_PV, REG_RA, disp);
3953 M_ALD(REG_ITMP1, REG_SP, 0);
3954 M_LDA(REG_SP, REG_SP, 8);
3958 M_ALD (REG_RA, REG_SP, 0); /* load return address */
3959 M_LDA (REG_SP, REG_SP, 8); /* remove stackframe */
3961 M_LDA (REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
3963 M_ALD (REG_ITMP3, REG_PV, -3*8); /* load asm exception handler address */
3964 M_JMP (REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
3968 static int stubprinted;
3970 printf("stubsize: %d/2\n", (int) (p - (s4*) s));
3976 count_nstub_len += NATIVESTUBSIZE * 8;
3979 return (u1*) (s + NATIVESTUBOFFSET);
3982 /* function: removenativestub **************************************************
3984 removes a previously created native-stub from memory
3986 *******************************************************************************/
3988 void removenativestub (u1 *stub)
3990 CFREE ((u8*) stub - NATIVESTUBOFFSET, NATIVESTUBSIZE * 8);
3995 * These are local overrides for various environment variables in Emacs.
3996 * Please do not remove this and leave it at the end of the file, where
3997 * Emacs will automagically detect them.
3998 * ---------------------------------------------------------------------
4001 * indent-tabs-mode: t