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 594 2003-11-09 19:54:50Z twisti $
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 !!!!!!!!!
541 M_LDA (REG_SP, REG_SP, -(14*8));
542 M_AST(REG_RA, REG_SP, 1*8);
544 M_LST(argintregs[0], REG_SP, 2*8);
545 M_LST(argintregs[1], REG_SP, 3*8);
546 M_LST(argintregs[2], REG_SP, 4*8);
547 M_LST(argintregs[3], REG_SP, 5*8);
548 M_LST(argintregs[4], REG_SP, 6*8);
549 M_LST(argintregs[5], REG_SP, 7*8);
551 M_DST(argfltregs[0], REG_SP, 8*8);
552 M_DST(argfltregs[1], REG_SP, 9*8);
553 M_DST(argfltregs[2], REG_SP, 10*8);
554 M_DST(argfltregs[3], REG_SP, 11*8);
555 M_DST(argfltregs[4], REG_SP, 12*8);
556 M_DST(argfltregs[5], REG_SP, 13*8);
558 p = dseg_addaddress (method);
559 M_ALD(REG_ITMP1, REG_PV, p);
560 M_AST(REG_ITMP1, REG_SP, 0);
561 p = dseg_addaddress ((void*) (builtin_trace_args));
562 M_ALD(REG_PV, REG_PV, p);
563 M_JSR(REG_RA, REG_PV);
564 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
565 M_ALD(REG_RA, REG_SP, 1*8);
567 M_LLD(argintregs[0], REG_SP, 2*8);
568 M_LLD(argintregs[1], REG_SP, 3*8);
569 M_LLD(argintregs[2], REG_SP, 4*8);
570 M_LLD(argintregs[3], REG_SP, 5*8);
571 M_LLD(argintregs[4], REG_SP, 6*8);
572 M_LLD(argintregs[5], REG_SP, 7*8);
574 M_DLD(argfltregs[0], REG_SP, 8*8);
575 M_DLD(argfltregs[1], REG_SP, 9*8);
576 M_DLD(argfltregs[2], REG_SP, 10*8);
577 M_DLD(argfltregs[3], REG_SP, 11*8);
578 M_DLD(argfltregs[4], REG_SP, 12*8);
579 M_DLD(argfltregs[5], REG_SP, 13*8);
581 M_LDA (REG_SP, REG_SP, 14*8);
584 /* take arguments out of register or stack frame */
586 for (p = 0, l = 0; p < mparamcount; p++) {
588 var = &(locals[l][t]);
590 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
595 if (IS_INT_LNG_TYPE(t)) { /* integer args */
596 if (p < INT_ARG_CNT) { /* register arguments */
597 if (!(var->flags & INMEMORY)) /* reg arg -> register */
598 {M_INTMOVE (argintregs[p], r);}
599 else /* reg arg -> spilled */
600 M_LST (argintregs[p], REG_SP, 8 * r);
602 else { /* stack arguments */
603 pa = p - INT_ARG_CNT;
604 if (!(var->flags & INMEMORY)) /* stack arg -> register */
605 M_LLD (r, REG_SP, 8 * (parentargs_base + pa));
606 else { /* stack arg -> spilled */
607 M_LLD (REG_ITMP1, REG_SP, 8 * (parentargs_base + pa));
608 M_LST (REG_ITMP1, REG_SP, 8 * r);
612 else { /* floating args */
613 if (p < FLT_ARG_CNT) { /* register arguments */
614 if (!(var->flags & INMEMORY)) /* reg arg -> register */
615 {M_FLTMOVE (argfltregs[p], r);}
616 else /* reg arg -> spilled */
617 M_DST (argfltregs[p], REG_SP, 8 * r);
619 else { /* stack arguments */
620 pa = p - FLT_ARG_CNT;
621 if (!(var->flags & INMEMORY)) /* stack-arg -> register */
622 M_DLD (r, REG_SP, 8 * (parentargs_base + pa) );
623 else { /* stack-arg -> spilled */
624 M_DLD (REG_FTMP1, REG_SP, 8 * (parentargs_base + pa));
625 M_DST (REG_FTMP1, REG_SP, 8 * r);
631 /* call trace function */
634 if (runverbose && !isleafmethod) {
635 M_LDA (REG_SP, REG_SP, -8);
636 p = dseg_addaddress (method);
637 M_ALD(REG_ITMP1, REG_PV, p);
638 M_AST(REG_ITMP1, REG_SP, 0);
639 p = dseg_addaddress ((void*) (builtin_trace_args));
640 M_ALD(REG_PV, REG_PV, p);
641 M_JSR(REG_RA, REG_PV);
642 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
643 M_LDA(REG_SP, REG_SP, 8);
647 /* call monitorenter function */
650 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
651 p = dseg_addaddress ((void*) (builtin_monitorenter));
652 M_ALD(REG_PV, REG_PV, p);
653 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
654 M_JSR(REG_RA, REG_PV);
655 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
660 /* end of header generation */
662 /* walk through all basic blocks */
663 for (/* bbs = block_count, */ bptr = block; /* --bbs >= 0 */ bptr != NULL; bptr = bptr->next) {
665 bptr -> mpc = (int)((u1*) mcodeptr - mcodebase);
667 if (bptr->flags >= BBREACHED) {
669 /* branch resolving */
673 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
674 gen_resolvebranch((u1*) mcodebase + brefs->branchpos,
675 brefs->branchpos, bptr->mpc);
679 /* copy interface registers to their destination */
684 while (src != NULL) {
686 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
687 d = reg_of_var(src, REG_ITMP1);
688 M_INTMOVE(REG_ITMP1, d);
689 store_reg_to_var_int(src, d);
692 d = reg_of_var(src, REG_IFTMP);
693 if ((src->varkind != STACKVAR)) {
695 if (IS_FLT_DBL_TYPE(s2)) {
696 if (!(interfaces[len][s2].flags & INMEMORY)) {
697 s1 = interfaces[len][s2].regoff;
701 M_DLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
703 store_reg_to_var_flt(src, d);
706 if (!(interfaces[len][s2].flags & INMEMORY)) {
707 s1 = interfaces[len][s2].regoff;
711 M_LLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
713 store_reg_to_var_int(src, d);
720 /* walk through all instructions */
724 for (iptr = bptr->iinstr;
726 src = iptr->dst, len--, iptr++) {
728 MCODECHECK(64); /* an instruction usually needs < 64 words */
731 case ICMD_NOP: /* ... ==> ... */
734 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
736 var_to_reg_int(s1, src, REG_ITMP1);
738 codegen_addxnullrefs(mcodeptr);
741 /* constant operations ************************************************/
743 #define ICONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
744 else{a=dseg_adds4(c);M_ILD(r,REG_PV,a);}
746 #define LCONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
747 else{a=dseg_adds8(c);M_LLD(r,REG_PV,a);}
749 case ICMD_ICONST: /* ... ==> ..., constant */
750 /* op1 = 0, val.i = constant */
752 d = reg_of_var(iptr->dst, REG_ITMP1);
753 ICONST(d, iptr->val.i);
754 store_reg_to_var_int(iptr->dst, d);
757 case ICMD_LCONST: /* ... ==> ..., constant */
758 /* op1 = 0, val.l = constant */
760 d = reg_of_var(iptr->dst, REG_ITMP1);
761 LCONST(d, iptr->val.l);
762 store_reg_to_var_int(iptr->dst, d);
765 case ICMD_FCONST: /* ... ==> ..., constant */
766 /* op1 = 0, val.f = constant */
768 d = reg_of_var (iptr->dst, REG_FTMP1);
769 a = dseg_addfloat (iptr->val.f);
771 store_reg_to_var_flt (iptr->dst, d);
774 case ICMD_DCONST: /* ... ==> ..., constant */
775 /* op1 = 0, val.d = constant */
777 d = reg_of_var (iptr->dst, REG_FTMP1);
778 a = dseg_adddouble (iptr->val.d);
780 store_reg_to_var_flt (iptr->dst, d);
783 case ICMD_ACONST: /* ... ==> ..., constant */
784 /* op1 = 0, val.a = constant */
786 d = reg_of_var(iptr->dst, REG_ITMP1);
788 a = dseg_addaddress (iptr->val.a);
792 M_INTMOVE(REG_ZERO, d);
794 store_reg_to_var_int(iptr->dst, d);
798 /* load/store operations **********************************************/
800 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
801 case ICMD_LLOAD: /* op1 = local variable */
804 d = reg_of_var(iptr->dst, REG_ITMP1);
805 if ((iptr->dst->varkind == LOCALVAR) &&
806 (iptr->dst->varnum == iptr->op1))
808 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
809 if (var->flags & INMEMORY)
810 M_LLD(d, REG_SP, 8 * var->regoff);
812 {M_INTMOVE(var->regoff,d);}
813 store_reg_to_var_int(iptr->dst, d);
816 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
817 case ICMD_DLOAD: /* op1 = local variable */
819 d = reg_of_var(iptr->dst, REG_FTMP1);
820 if ((iptr->dst->varkind == LOCALVAR) &&
821 (iptr->dst->varnum == iptr->op1))
823 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
824 if (var->flags & INMEMORY)
825 M_DLD(d, REG_SP, 8 * var->regoff);
827 {M_FLTMOVE(var->regoff,d);}
828 store_reg_to_var_flt(iptr->dst, d);
832 case ICMD_ISTORE: /* ..., value ==> ... */
833 case ICMD_LSTORE: /* op1 = local variable */
836 if ((src->varkind == LOCALVAR) &&
837 (src->varnum == iptr->op1))
839 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
840 if (var->flags & INMEMORY) {
841 var_to_reg_int(s1, src, REG_ITMP1);
842 M_LST(s1, REG_SP, 8 * var->regoff);
845 var_to_reg_int(s1, src, var->regoff);
846 M_INTMOVE(s1, var->regoff);
850 case ICMD_FSTORE: /* ..., value ==> ... */
851 case ICMD_DSTORE: /* op1 = local variable */
853 if ((src->varkind == LOCALVAR) &&
854 (src->varnum == iptr->op1))
856 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
857 if (var->flags & INMEMORY) {
858 var_to_reg_flt(s1, src, REG_FTMP1);
859 M_DST(s1, REG_SP, 8 * var->regoff);
862 var_to_reg_flt(s1, src, var->regoff);
863 M_FLTMOVE(s1, var->regoff);
868 /* pop/dup/swap operations ********************************************/
870 /* attention: double and longs are only one entry in CACAO ICMDs */
872 case ICMD_POP: /* ..., value ==> ... */
873 case ICMD_POP2: /* ..., value, value ==> ... */
876 #define M_COPY(from,to) \
877 d = reg_of_var(to, REG_IFTMP); \
878 if ((from->regoff != to->regoff) || \
879 ((from->flags ^ to->flags) & INMEMORY)) { \
880 if (IS_FLT_DBL_TYPE(from->type)) { \
881 var_to_reg_flt(s1, from, d); \
883 store_reg_to_var_flt(to, d); \
886 var_to_reg_int(s1, from, d); \
888 store_reg_to_var_int(to, d); \
892 case ICMD_DUP: /* ..., a ==> ..., a, a */
893 M_COPY(src, iptr->dst);
896 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
898 M_COPY(src, iptr->dst->prev->prev);
900 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
902 M_COPY(src, iptr->dst);
903 M_COPY(src->prev, iptr->dst->prev);
906 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
908 M_COPY(src->prev, iptr->dst->prev->prev->prev);
910 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
912 M_COPY(src, iptr->dst);
913 M_COPY(src->prev, iptr->dst->prev);
914 M_COPY(src->prev->prev, iptr->dst->prev->prev);
915 M_COPY(src, iptr->dst->prev->prev->prev);
918 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
920 M_COPY(src, iptr->dst);
921 M_COPY(src->prev, iptr->dst->prev);
922 M_COPY(src->prev->prev, iptr->dst->prev->prev);
923 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
924 M_COPY(src, iptr->dst->prev->prev->prev->prev);
925 M_COPY(src->prev, iptr->dst->prev->prev->prev->prev->prev);
928 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
930 M_COPY(src, iptr->dst->prev);
931 M_COPY(src->prev, iptr->dst);
935 /* integer operations *************************************************/
937 case ICMD_INEG: /* ..., value ==> ..., - value */
939 var_to_reg_int(s1, src, REG_ITMP1);
940 d = reg_of_var(iptr->dst, REG_ITMP3);
941 M_ISUB(REG_ZERO, s1, d);
942 store_reg_to_var_int(iptr->dst, d);
945 case ICMD_LNEG: /* ..., value ==> ..., - value */
947 var_to_reg_int(s1, src, REG_ITMP1);
948 d = reg_of_var(iptr->dst, REG_ITMP3);
949 M_LSUB(REG_ZERO, s1, d);
950 store_reg_to_var_int(iptr->dst, d);
953 case ICMD_I2L: /* ..., value ==> ..., value */
955 var_to_reg_int(s1, src, REG_ITMP1);
956 d = reg_of_var(iptr->dst, REG_ITMP3);
958 store_reg_to_var_int(iptr->dst, d);
961 case ICMD_L2I: /* ..., value ==> ..., value */
963 var_to_reg_int(s1, src, REG_ITMP1);
964 d = reg_of_var(iptr->dst, REG_ITMP3);
965 M_IADD(s1, REG_ZERO, d );
966 store_reg_to_var_int(iptr->dst, d);
969 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
971 var_to_reg_int(s1, src, REG_ITMP1);
972 d = reg_of_var(iptr->dst, REG_ITMP3);
973 if (has_ext_instr_set) {
977 M_SLL_IMM(s1, 56, d);
978 M_SRA_IMM( d, 56, d);
980 store_reg_to_var_int(iptr->dst, d);
983 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
985 var_to_reg_int(s1, src, REG_ITMP1);
986 d = reg_of_var(iptr->dst, REG_ITMP3);
988 store_reg_to_var_int(iptr->dst, d);
991 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
993 var_to_reg_int(s1, src, REG_ITMP1);
994 d = reg_of_var(iptr->dst, REG_ITMP3);
995 if (has_ext_instr_set) {
999 M_SLL_IMM(s1, 48, d);
1000 M_SRA_IMM( d, 48, d);
1002 store_reg_to_var_int(iptr->dst, d);
1006 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1008 var_to_reg_int(s1, src->prev, REG_ITMP1);
1009 var_to_reg_int(s2, src, REG_ITMP2);
1010 d = reg_of_var(iptr->dst, REG_ITMP3);
1012 store_reg_to_var_int(iptr->dst, d);
1015 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
1016 /* val.i = constant */
1018 var_to_reg_int(s1, src, REG_ITMP1);
1019 d = reg_of_var(iptr->dst, REG_ITMP3);
1020 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1021 M_IADD_IMM(s1, iptr->val.i, d);
1024 ICONST(REG_ITMP2, iptr->val.i);
1025 M_IADD(s1, REG_ITMP2, d);
1027 store_reg_to_var_int(iptr->dst, d);
1030 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1032 var_to_reg_int(s1, src->prev, REG_ITMP1);
1033 var_to_reg_int(s2, src, REG_ITMP2);
1034 d = reg_of_var(iptr->dst, REG_ITMP3);
1036 store_reg_to_var_int(iptr->dst, d);
1039 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
1040 /* val.l = constant */
1042 var_to_reg_int(s1, src, REG_ITMP1);
1043 d = reg_of_var(iptr->dst, REG_ITMP3);
1044 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1045 M_LADD_IMM(s1, iptr->val.l, d);
1048 LCONST(REG_ITMP2, iptr->val.l);
1049 M_LADD(s1, REG_ITMP2, d);
1051 store_reg_to_var_int(iptr->dst, d);
1054 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1056 var_to_reg_int(s1, src->prev, REG_ITMP1);
1057 var_to_reg_int(s2, src, REG_ITMP2);
1058 d = reg_of_var(iptr->dst, REG_ITMP3);
1060 store_reg_to_var_int(iptr->dst, d);
1063 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
1064 /* val.i = constant */
1066 var_to_reg_int(s1, src, REG_ITMP1);
1067 d = reg_of_var(iptr->dst, REG_ITMP3);
1068 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1069 M_ISUB_IMM(s1, iptr->val.i, d);
1072 ICONST(REG_ITMP2, iptr->val.i);
1073 M_ISUB(s1, REG_ITMP2, d);
1075 store_reg_to_var_int(iptr->dst, d);
1078 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1080 var_to_reg_int(s1, src->prev, REG_ITMP1);
1081 var_to_reg_int(s2, src, REG_ITMP2);
1082 d = reg_of_var(iptr->dst, REG_ITMP3);
1084 store_reg_to_var_int(iptr->dst, d);
1087 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
1088 /* val.l = constant */
1090 var_to_reg_int(s1, src, REG_ITMP1);
1091 d = reg_of_var(iptr->dst, REG_ITMP3);
1092 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1093 M_LSUB_IMM(s1, iptr->val.l, d);
1096 LCONST(REG_ITMP2, iptr->val.l);
1097 M_LSUB(s1, REG_ITMP2, d);
1099 store_reg_to_var_int(iptr->dst, d);
1102 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1104 var_to_reg_int(s1, src->prev, REG_ITMP1);
1105 var_to_reg_int(s2, src, REG_ITMP2);
1106 d = reg_of_var(iptr->dst, REG_ITMP3);
1108 store_reg_to_var_int(iptr->dst, d);
1111 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
1112 /* val.i = constant */
1114 var_to_reg_int(s1, src, REG_ITMP1);
1115 d = reg_of_var(iptr->dst, REG_ITMP3);
1116 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1117 M_IMUL_IMM(s1, iptr->val.i, d);
1120 ICONST(REG_ITMP2, iptr->val.i);
1121 M_IMUL(s1, REG_ITMP2, d);
1123 store_reg_to_var_int(iptr->dst, d);
1126 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1128 var_to_reg_int(s1, src->prev, REG_ITMP1);
1129 var_to_reg_int(s2, src, REG_ITMP2);
1130 d = reg_of_var(iptr->dst, REG_ITMP3);
1132 store_reg_to_var_int(iptr->dst, d);
1135 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
1136 /* val.l = constant */
1138 var_to_reg_int(s1, src, REG_ITMP1);
1139 d = reg_of_var(iptr->dst, REG_ITMP3);
1140 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1141 M_LMUL_IMM(s1, iptr->val.l, d);
1144 LCONST(REG_ITMP2, iptr->val.l);
1145 M_LMUL(s1, REG_ITMP2, d);
1147 store_reg_to_var_int(iptr->dst, d);
1150 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
1151 case ICMD_LDIVPOW2: /* val.i = constant */
1153 var_to_reg_int(s1, src, REG_ITMP1);
1154 d = reg_of_var(iptr->dst, REG_ITMP3);
1155 if (iptr->val.i <= 15) {
1156 M_LDA(REG_ITMP2, s1, (1 << iptr->val.i) -1);
1157 M_CMOVGE(s1, s1, REG_ITMP2);
1160 M_SRA_IMM(s1, 63, REG_ITMP2);
1161 M_SRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
1162 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1164 M_SRA_IMM(REG_ITMP2, iptr->val.i, d);
1165 store_reg_to_var_int(iptr->dst, d);
1168 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1170 var_to_reg_int(s1, src->prev, REG_ITMP1);
1171 var_to_reg_int(s2, src, REG_ITMP2);
1172 d = reg_of_var(iptr->dst, REG_ITMP3);
1173 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1174 M_SLL(s1, REG_ITMP3, d);
1175 M_IADD(d, REG_ZERO, d);
1176 store_reg_to_var_int(iptr->dst, d);
1179 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1180 /* val.i = constant */
1182 var_to_reg_int(s1, src, REG_ITMP1);
1183 d = reg_of_var(iptr->dst, REG_ITMP3);
1184 M_SLL_IMM(s1, iptr->val.i & 0x1f, d);
1185 M_IADD(d, REG_ZERO, d);
1186 store_reg_to_var_int(iptr->dst, d);
1189 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1191 var_to_reg_int(s1, src->prev, REG_ITMP1);
1192 var_to_reg_int(s2, src, REG_ITMP2);
1193 d = reg_of_var(iptr->dst, REG_ITMP3);
1194 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1195 M_SRA(s1, REG_ITMP3, d);
1196 store_reg_to_var_int(iptr->dst, d);
1199 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1200 /* val.i = constant */
1202 var_to_reg_int(s1, src, REG_ITMP1);
1203 d = reg_of_var(iptr->dst, REG_ITMP3);
1204 M_SRA_IMM(s1, iptr->val.i & 0x1f, d);
1205 store_reg_to_var_int(iptr->dst, d);
1208 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1210 var_to_reg_int(s1, src->prev, REG_ITMP1);
1211 var_to_reg_int(s2, src, REG_ITMP2);
1212 d = reg_of_var(iptr->dst, REG_ITMP3);
1213 M_AND_IMM(s2, 0x1f, REG_ITMP2);
1215 M_SRL(d, REG_ITMP2, d);
1216 M_IADD(d, REG_ZERO, d);
1217 store_reg_to_var_int(iptr->dst, d);
1220 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1221 /* val.i = constant */
1223 var_to_reg_int(s1, src, REG_ITMP1);
1224 d = reg_of_var(iptr->dst, REG_ITMP3);
1226 M_SRL_IMM(d, iptr->val.i & 0x1f, d);
1227 M_IADD(d, REG_ZERO, d);
1228 store_reg_to_var_int(iptr->dst, d);
1231 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1233 var_to_reg_int(s1, src->prev, REG_ITMP1);
1234 var_to_reg_int(s2, src, REG_ITMP2);
1235 d = reg_of_var(iptr->dst, REG_ITMP3);
1237 store_reg_to_var_int(iptr->dst, d);
1240 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1241 /* val.i = constant */
1243 var_to_reg_int(s1, src, REG_ITMP1);
1244 d = reg_of_var(iptr->dst, REG_ITMP3);
1245 M_SLL_IMM(s1, iptr->val.i & 0x3f, d);
1246 store_reg_to_var_int(iptr->dst, d);
1249 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1251 var_to_reg_int(s1, src->prev, REG_ITMP1);
1252 var_to_reg_int(s2, src, REG_ITMP2);
1253 d = reg_of_var(iptr->dst, REG_ITMP3);
1255 store_reg_to_var_int(iptr->dst, d);
1258 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1259 /* val.i = constant */
1261 var_to_reg_int(s1, src, REG_ITMP1);
1262 d = reg_of_var(iptr->dst, REG_ITMP3);
1263 M_SRA_IMM(s1, iptr->val.i & 0x3f, d);
1264 store_reg_to_var_int(iptr->dst, d);
1267 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1269 var_to_reg_int(s1, src->prev, REG_ITMP1);
1270 var_to_reg_int(s2, src, REG_ITMP2);
1271 d = reg_of_var(iptr->dst, REG_ITMP3);
1273 store_reg_to_var_int(iptr->dst, d);
1276 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1277 /* val.i = constant */
1279 var_to_reg_int(s1, src, REG_ITMP1);
1280 d = reg_of_var(iptr->dst, REG_ITMP3);
1281 M_SRL_IMM(s1, iptr->val.i & 0x3f, d);
1282 store_reg_to_var_int(iptr->dst, d);
1285 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1288 var_to_reg_int(s1, src->prev, REG_ITMP1);
1289 var_to_reg_int(s2, src, REG_ITMP2);
1290 d = reg_of_var(iptr->dst, REG_ITMP3);
1292 store_reg_to_var_int(iptr->dst, d);
1295 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1296 /* val.i = constant */
1298 var_to_reg_int(s1, src, REG_ITMP1);
1299 d = reg_of_var(iptr->dst, REG_ITMP3);
1300 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1301 M_AND_IMM(s1, iptr->val.i, d);
1303 else if (iptr->val.i == 0xffff) {
1306 else if (iptr->val.i == 0xffffff) {
1307 M_ZAPNOT_IMM(s1, 0x07, d);
1310 ICONST(REG_ITMP2, iptr->val.i);
1311 M_AND(s1, REG_ITMP2, d);
1313 store_reg_to_var_int(iptr->dst, d);
1316 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1317 /* val.i = constant */
1319 var_to_reg_int(s1, src, REG_ITMP1);
1320 d = reg_of_var(iptr->dst, REG_ITMP3);
1322 M_MOV(s1, REG_ITMP1);
1325 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1326 M_AND_IMM(s1, iptr->val.i, d);
1328 M_ISUB(REG_ZERO, s1, d);
1329 M_AND_IMM(d, iptr->val.i, d);
1331 else if (iptr->val.i == 0xffff) {
1334 M_ISUB(REG_ZERO, s1, d);
1337 else if (iptr->val.i == 0xffffff) {
1338 M_ZAPNOT_IMM(s1, 0x07, d);
1340 M_ISUB(REG_ZERO, s1, d);
1341 M_ZAPNOT_IMM(d, 0x07, d);
1344 ICONST(REG_ITMP2, iptr->val.i);
1345 M_AND(s1, REG_ITMP2, d);
1347 M_ISUB(REG_ZERO, s1, d);
1348 M_AND(d, REG_ITMP2, d);
1350 M_ISUB(REG_ZERO, d, d);
1351 store_reg_to_var_int(iptr->dst, d);
1354 case ICMD_IREM0X10001: /* ..., value ==> ..., value % 0x100001 */
1356 /* b = value & 0xffff;
1358 a = ((b - a) & 0xffff) + (b < a);
1360 var_to_reg_int(s1, src, REG_ITMP1);
1361 d = reg_of_var(iptr->dst, REG_ITMP3);
1363 M_MOV(s1, REG_ITMP3);
1367 M_CZEXT(s1, REG_ITMP2);
1368 M_SRA_IMM(s1, 16, d);
1369 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1370 M_ISUB(REG_ITMP2, d, d);
1372 M_IADD(d, REG_ITMP1, d);
1373 M_BR(11 + (s1 == REG_ITMP1));
1374 M_ISUB(REG_ZERO, s1, REG_ITMP1);
1375 M_CZEXT(REG_ITMP1, REG_ITMP2);
1376 M_SRA_IMM(REG_ITMP1, 16, d);
1377 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1378 M_ISUB(REG_ITMP2, d, d);
1380 M_IADD(d, REG_ITMP1, d);
1381 M_ISUB(REG_ZERO, d, d);
1382 if (s1 == REG_ITMP1) {
1383 var_to_reg_int(s1, src, REG_ITMP1);
1385 M_SLL_IMM(s1, 33, REG_ITMP2);
1386 M_CMPEQ(REG_ITMP2, REG_ZERO, REG_ITMP2);
1387 M_ISUB(d, REG_ITMP2, d);
1388 store_reg_to_var_int(iptr->dst, d);
1391 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1392 /* val.l = constant */
1394 var_to_reg_int(s1, src, REG_ITMP1);
1395 d = reg_of_var(iptr->dst, REG_ITMP3);
1396 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1397 M_AND_IMM(s1, iptr->val.l, d);
1399 else if (iptr->val.l == 0xffffL) {
1402 else if (iptr->val.l == 0xffffffL) {
1403 M_ZAPNOT_IMM(s1, 0x07, d);
1405 else if (iptr->val.l == 0xffffffffL) {
1408 else if (iptr->val.l == 0xffffffffffL) {
1409 M_ZAPNOT_IMM(s1, 0x1f, d);
1411 else if (iptr->val.l == 0xffffffffffffL) {
1412 M_ZAPNOT_IMM(s1, 0x3f, d);
1414 else if (iptr->val.l == 0xffffffffffffffL) {
1415 M_ZAPNOT_IMM(s1, 0x7f, d);
1418 LCONST(REG_ITMP2, iptr->val.l);
1419 M_AND(s1, REG_ITMP2, d);
1421 store_reg_to_var_int(iptr->dst, d);
1424 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1425 /* val.l = constant */
1427 var_to_reg_int(s1, src, REG_ITMP1);
1428 d = reg_of_var(iptr->dst, REG_ITMP3);
1430 M_MOV(s1, REG_ITMP1);
1433 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1434 M_AND_IMM(s1, iptr->val.l, d);
1436 M_LSUB(REG_ZERO, s1, d);
1437 M_AND_IMM(d, iptr->val.l, d);
1439 else if (iptr->val.l == 0xffffL) {
1442 M_LSUB(REG_ZERO, s1, d);
1445 else if (iptr->val.l == 0xffffffL) {
1446 M_ZAPNOT_IMM(s1, 0x07, d);
1448 M_LSUB(REG_ZERO, s1, d);
1449 M_ZAPNOT_IMM(d, 0x07, d);
1451 else if (iptr->val.l == 0xffffffffL) {
1454 M_LSUB(REG_ZERO, s1, d);
1457 else if (iptr->val.l == 0xffffffffffL) {
1458 M_ZAPNOT_IMM(s1, 0x1f, d);
1460 M_LSUB(REG_ZERO, s1, d);
1461 M_ZAPNOT_IMM(d, 0x1f, d);
1463 else if (iptr->val.l == 0xffffffffffffL) {
1464 M_ZAPNOT_IMM(s1, 0x3f, d);
1466 M_LSUB(REG_ZERO, s1, d);
1467 M_ZAPNOT_IMM(d, 0x3f, d);
1469 else if (iptr->val.l == 0xffffffffffffffL) {
1470 M_ZAPNOT_IMM(s1, 0x7f, d);
1472 M_LSUB(REG_ZERO, s1, d);
1473 M_ZAPNOT_IMM(d, 0x7f, d);
1476 LCONST(REG_ITMP2, iptr->val.l);
1477 M_AND(s1, REG_ITMP2, d);
1479 M_LSUB(REG_ZERO, s1, d);
1480 M_AND(d, REG_ITMP2, d);
1482 M_LSUB(REG_ZERO, d, d);
1483 store_reg_to_var_int(iptr->dst, d);
1486 case ICMD_LREM0X10001:/* ..., value ==> ..., value % 0x10001 */
1488 var_to_reg_int(s1, src, REG_ITMP1);
1489 d = reg_of_var(iptr->dst, REG_ITMP3);
1491 M_MOV(s1, REG_ITMP3);
1494 M_CZEXT(s1, REG_ITMP2);
1495 M_SRA_IMM(s1, 16, d);
1496 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1497 M_LSUB(REG_ITMP2, d, d);
1499 M_LADD(d, REG_ITMP1, d);
1500 M_LDA(REG_ITMP2, REG_ZERO, -1);
1501 M_SRL_IMM(REG_ITMP2, 33, REG_ITMP2);
1502 if (s1 == REG_ITMP1) {
1503 var_to_reg_int(s1, src, REG_ITMP1);
1505 M_CMPULT(s1, REG_ITMP2, REG_ITMP2);
1506 M_BNEZ(REG_ITMP2, 11);
1507 M_LDA(d, REG_ZERO, -257);
1508 M_ZAPNOT_IMM(d, 0xcd, d);
1509 M_LSUB(REG_ZERO, s1, REG_ITMP2);
1510 M_CMOVGE(s1, s1, REG_ITMP2);
1511 M_UMULH(REG_ITMP2, d, REG_ITMP2);
1512 M_SRL_IMM(REG_ITMP2, 16, REG_ITMP2);
1513 M_LSUB(REG_ZERO, REG_ITMP2, d);
1514 M_CMOVGE(s1, REG_ITMP2, d);
1515 M_SLL_IMM(d, 16, REG_ITMP2);
1516 M_LADD(d, REG_ITMP2, d);
1518 store_reg_to_var_int(iptr->dst, d);
1521 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1524 var_to_reg_int(s1, src->prev, REG_ITMP1);
1525 var_to_reg_int(s2, src, REG_ITMP2);
1526 d = reg_of_var(iptr->dst, REG_ITMP3);
1528 store_reg_to_var_int(iptr->dst, d);
1531 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1532 /* val.i = constant */
1534 var_to_reg_int(s1, src, REG_ITMP1);
1535 d = reg_of_var(iptr->dst, REG_ITMP3);
1536 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1537 M_OR_IMM(s1, iptr->val.i, d);
1540 ICONST(REG_ITMP2, iptr->val.i);
1541 M_OR(s1, REG_ITMP2, d);
1543 store_reg_to_var_int(iptr->dst, d);
1546 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1547 /* val.l = constant */
1549 var_to_reg_int(s1, src, REG_ITMP1);
1550 d = reg_of_var(iptr->dst, REG_ITMP3);
1551 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1552 M_OR_IMM(s1, iptr->val.l, d);
1555 LCONST(REG_ITMP2, iptr->val.l);
1556 M_OR(s1, REG_ITMP2, d);
1558 store_reg_to_var_int(iptr->dst, d);
1561 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1564 var_to_reg_int(s1, src->prev, REG_ITMP1);
1565 var_to_reg_int(s2, src, REG_ITMP2);
1566 d = reg_of_var(iptr->dst, REG_ITMP3);
1568 store_reg_to_var_int(iptr->dst, d);
1571 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1572 /* val.i = constant */
1574 var_to_reg_int(s1, src, REG_ITMP1);
1575 d = reg_of_var(iptr->dst, REG_ITMP3);
1576 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1577 M_XOR_IMM(s1, iptr->val.i, d);
1580 ICONST(REG_ITMP2, iptr->val.i);
1581 M_XOR(s1, REG_ITMP2, d);
1583 store_reg_to_var_int(iptr->dst, d);
1586 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1587 /* val.l = constant */
1589 var_to_reg_int(s1, src, REG_ITMP1);
1590 d = reg_of_var(iptr->dst, REG_ITMP3);
1591 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1592 M_XOR_IMM(s1, iptr->val.l, d);
1595 LCONST(REG_ITMP2, iptr->val.l);
1596 M_XOR(s1, REG_ITMP2, d);
1598 store_reg_to_var_int(iptr->dst, d);
1602 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1604 var_to_reg_int(s1, src->prev, REG_ITMP1);
1605 var_to_reg_int(s2, src, REG_ITMP2);
1606 d = reg_of_var(iptr->dst, REG_ITMP3);
1607 M_CMPLT(s1, s2, REG_ITMP3);
1608 M_CMPLT(s2, s1, REG_ITMP1);
1609 M_LSUB (REG_ITMP1, REG_ITMP3, d);
1610 store_reg_to_var_int(iptr->dst, d);
1614 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1615 /* op1 = variable, val.i = constant */
1617 var = &(locals[iptr->op1][TYPE_INT]);
1618 if (var->flags & INMEMORY) {
1620 M_LLD(s1, REG_SP, 8 * var->regoff);
1624 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1625 M_IADD_IMM(s1, iptr->val.i, s1);
1627 else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1628 M_ISUB_IMM(s1, (-iptr->val.i), s1);
1631 M_LDA (s1, s1, iptr->val.i);
1632 M_IADD(s1, REG_ZERO, s1);
1634 if (var->flags & INMEMORY)
1635 M_LST(s1, REG_SP, 8 * var->regoff);
1639 /* floating operations ************************************************/
1641 case ICMD_FNEG: /* ..., value ==> ..., - value */
1643 var_to_reg_flt(s1, src, REG_FTMP1);
1644 d = reg_of_var(iptr->dst, REG_FTMP3);
1646 store_reg_to_var_flt(iptr->dst, d);
1649 case ICMD_DNEG: /* ..., value ==> ..., - value */
1651 var_to_reg_flt(s1, src, REG_FTMP1);
1652 d = reg_of_var(iptr->dst, REG_FTMP3);
1654 store_reg_to_var_flt(iptr->dst, d);
1657 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1659 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1660 var_to_reg_flt(s2, src, REG_FTMP2);
1661 d = reg_of_var(iptr->dst, REG_FTMP3);
1669 store_reg_to_var_flt(iptr->dst, d);
1672 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1674 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1675 var_to_reg_flt(s2, src, REG_FTMP2);
1676 d = reg_of_var(iptr->dst, REG_FTMP3);
1684 store_reg_to_var_flt(iptr->dst, d);
1687 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1689 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1690 var_to_reg_flt(s2, src, REG_FTMP2);
1691 d = reg_of_var(iptr->dst, REG_FTMP3);
1699 store_reg_to_var_flt(iptr->dst, d);
1702 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1704 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1705 var_to_reg_flt(s2, src, REG_FTMP2);
1706 d = reg_of_var(iptr->dst, REG_FTMP3);
1714 store_reg_to_var_flt(iptr->dst, d);
1717 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1719 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1720 var_to_reg_flt(s2, src, REG_FTMP2);
1721 d = reg_of_var(iptr->dst, REG_FTMP3);
1729 store_reg_to_var_flt(iptr->dst, d);
1732 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1734 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1735 var_to_reg_flt(s2, src, REG_FTMP2);
1736 d = reg_of_var(iptr->dst, REG_FTMP3);
1744 store_reg_to_var_flt(iptr->dst, d);
1747 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1749 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1750 var_to_reg_flt(s2, src, REG_FTMP2);
1751 d = reg_of_var(iptr->dst, REG_FTMP3);
1759 store_reg_to_var_flt(iptr->dst, d);
1762 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1764 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1765 var_to_reg_flt(s2, src, REG_FTMP2);
1766 d = reg_of_var(iptr->dst, REG_FTMP3);
1774 store_reg_to_var_flt(iptr->dst, d);
1777 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1779 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1780 var_to_reg_flt(s2, src, REG_FTMP2);
1781 d = reg_of_var(iptr->dst, REG_FTMP3);
1783 M_FDIV(s1,s2, REG_FTMP3);
1784 M_CVTDL_C(REG_FTMP3, REG_FTMP3); /* round to integer */
1785 M_CVTLF(REG_FTMP3, REG_FTMP3);
1786 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1787 M_FSUB(s1, REG_FTMP3, d);
1790 M_FDIVS(s1,s2, REG_FTMP3);
1792 M_CVTDL_CS(REG_FTMP3, REG_FTMP3); /* round to integer */
1794 M_CVTLF(REG_FTMP3, REG_FTMP3);
1795 M_FMULS(REG_FTMP3, s2, REG_FTMP3);
1797 M_FSUBS(s1, REG_FTMP3, d);
1800 store_reg_to_var_flt(iptr->dst, d);
1803 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1805 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1806 var_to_reg_flt(s2, src, REG_FTMP2);
1807 d = reg_of_var(iptr->dst, REG_FTMP3);
1809 M_DDIV(s1,s2, REG_FTMP3);
1810 M_CVTDL_C(REG_FTMP3, REG_FTMP3); /* round to integer */
1811 M_CVTLD(REG_FTMP3, REG_FTMP3);
1812 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1813 M_DSUB(s1, REG_FTMP3, d);
1816 M_DDIVS(s1,s2, REG_FTMP3);
1818 M_CVTDL_CS(REG_FTMP3, REG_FTMP3); /* round to integer */
1820 M_CVTLD(REG_FTMP3, REG_FTMP3);
1821 M_DMULS(REG_FTMP3, s2, REG_FTMP3);
1823 M_DSUBS(s1, REG_FTMP3, d);
1826 store_reg_to_var_flt(iptr->dst, d);
1829 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1831 var_to_reg_int(s1, src, REG_ITMP1);
1832 d = reg_of_var(iptr->dst, REG_FTMP3);
1833 a = dseg_adddouble(0.0);
1834 M_LST (s1, REG_PV, a);
1835 M_DLD (d, REG_PV, a);
1837 store_reg_to_var_flt(iptr->dst, d);
1840 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1842 var_to_reg_int(s1, src, REG_ITMP1);
1843 d = reg_of_var(iptr->dst, REG_FTMP3);
1844 a = dseg_adddouble(0.0);
1845 M_LST (s1, REG_PV, a);
1846 M_DLD (d, REG_PV, a);
1848 store_reg_to_var_flt(iptr->dst, d);
1851 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1853 var_to_reg_flt(s1, src, REG_FTMP1);
1854 d = reg_of_var(iptr->dst, REG_ITMP3);
1855 a = dseg_adddouble(0.0);
1857 M_CVTDL_C(s1, REG_FTMP1);
1858 M_CVTLI(REG_FTMP1, REG_FTMP2);
1861 M_CVTDL_CS(s1, REG_FTMP1);
1863 M_CVTLIS(REG_FTMP1, REG_FTMP2);
1866 M_DST (REG_FTMP1, REG_PV, a);
1867 M_ILD (d, REG_PV, a);
1868 store_reg_to_var_int(iptr->dst, d);
1871 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1873 var_to_reg_flt(s1, src, REG_FTMP1);
1874 d = reg_of_var(iptr->dst, REG_ITMP3);
1875 a = dseg_adddouble(0.0);
1877 M_CVTDL_C(s1, REG_FTMP1);
1880 M_CVTDL_CS(s1, REG_FTMP1);
1883 M_DST (REG_FTMP1, REG_PV, a);
1884 M_LLD (d, REG_PV, a);
1885 store_reg_to_var_int(iptr->dst, d);
1888 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1890 var_to_reg_flt(s1, src, REG_FTMP1);
1891 d = reg_of_var(iptr->dst, REG_FTMP3);
1893 store_reg_to_var_flt(iptr->dst, d);
1896 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1898 var_to_reg_flt(s1, src, REG_FTMP1);
1899 d = reg_of_var(iptr->dst, REG_FTMP3);
1907 store_reg_to_var_flt(iptr->dst, d);
1910 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1912 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1913 var_to_reg_flt(s2, src, REG_FTMP2);
1914 d = reg_of_var(iptr->dst, REG_ITMP3);
1916 M_LSUB_IMM(REG_ZERO, 1, d);
1917 M_FCMPEQ(s1, s2, REG_FTMP3);
1918 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1920 M_FCMPLT(s2, s1, REG_FTMP3);
1921 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1922 M_LADD_IMM(REG_ZERO, 1, d);
1925 M_LSUB_IMM(REG_ZERO, 1, d);
1926 M_FCMPEQS(s1, s2, REG_FTMP3);
1928 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1930 M_FCMPLTS(s2, s1, REG_FTMP3);
1932 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1933 M_LADD_IMM(REG_ZERO, 1, d);
1935 store_reg_to_var_int(iptr->dst, d);
1938 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1940 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1941 var_to_reg_flt(s2, src, REG_FTMP2);
1942 d = reg_of_var(iptr->dst, REG_ITMP3);
1944 M_LADD_IMM(REG_ZERO, 1, d);
1945 M_FCMPEQ(s1, s2, REG_FTMP3);
1946 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1948 M_FCMPLT(s1, s2, REG_FTMP3);
1949 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1950 M_LSUB_IMM(REG_ZERO, 1, d);
1953 M_LADD_IMM(REG_ZERO, 1, d);
1954 M_FCMPEQS(s1, s2, REG_FTMP3);
1956 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1958 M_FCMPLTS(s1, s2, REG_FTMP3);
1960 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1961 M_LSUB_IMM(REG_ZERO, 1, d);
1963 store_reg_to_var_int(iptr->dst, d);
1967 /* memory operations **************************************************/
1969 /* #define gen_bound_check \
1971 M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\
1972 M_CMPULT(s2, REG_ITMP3, REG_ITMP3);\
1973 M_BEQZ(REG_ITMP3, 0);\
1974 codegen_addxboundrefs(mcodeptr);\
1978 #define gen_bound_check \
1979 if (checkbounds) { \
1980 M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\
1981 M_CMPULT(s2, REG_ITMP3, REG_ITMP3);\
1982 M_BEQZ(REG_ITMP3, 0);\
1983 codegen_addxboundrefs(mcodeptr); \
1986 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1988 var_to_reg_int(s1, src, REG_ITMP1);
1989 d = reg_of_var(iptr->dst, REG_ITMP3);
1990 gen_nullptr_check(s1);
1991 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1992 store_reg_to_var_int(iptr->dst, d);
1995 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1997 var_to_reg_int(s1, src->prev, REG_ITMP1);
1998 var_to_reg_int(s2, src, REG_ITMP2);
1999 d = reg_of_var(iptr->dst, REG_ITMP3);
2000 if (iptr->op1 == 0) {
2001 gen_nullptr_check(s1);
2004 M_SAADDQ(s2, s1, REG_ITMP1);
2005 M_ALD( d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
2006 store_reg_to_var_int(iptr->dst, d);
2009 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
2011 var_to_reg_int(s1, src->prev, REG_ITMP1);
2012 var_to_reg_int(s2, src, REG_ITMP2);
2013 d = reg_of_var(iptr->dst, REG_ITMP3);
2014 if (iptr->op1 == 0) {
2015 gen_nullptr_check(s1);
2018 M_S8ADDQ(s2, s1, REG_ITMP1);
2019 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
2020 store_reg_to_var_int(iptr->dst, d);
2023 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
2025 var_to_reg_int(s1, src->prev, REG_ITMP1);
2026 var_to_reg_int(s2, src, REG_ITMP2);
2027 d = reg_of_var(iptr->dst, REG_ITMP3);
2028 if (iptr->op1 == 0) {
2029 gen_nullptr_check(s1);
2033 M_S4ADDQ(s2, s1, REG_ITMP1);
2034 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
2035 store_reg_to_var_int(iptr->dst, d);
2038 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
2040 var_to_reg_int(s1, src->prev, REG_ITMP1);
2041 var_to_reg_int(s2, src, REG_ITMP2);
2042 d = reg_of_var(iptr->dst, REG_FTMP3);
2043 if (iptr->op1 == 0) {
2044 gen_nullptr_check(s1);
2047 M_S4ADDQ(s2, s1, REG_ITMP1);
2048 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
2049 store_reg_to_var_flt(iptr->dst, d);
2052 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
2054 var_to_reg_int(s1, src->prev, REG_ITMP1);
2055 var_to_reg_int(s2, src, REG_ITMP2);
2056 d = reg_of_var(iptr->dst, REG_FTMP3);
2057 if (iptr->op1 == 0) {
2058 gen_nullptr_check(s1);
2061 M_S8ADDQ(s2, s1, REG_ITMP1);
2062 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
2063 store_reg_to_var_flt(iptr->dst, d);
2066 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
2068 var_to_reg_int(s1, src->prev, REG_ITMP1);
2069 var_to_reg_int(s2, src, REG_ITMP2);
2070 d = reg_of_var(iptr->dst, REG_ITMP3);
2071 if (iptr->op1 == 0) {
2072 gen_nullptr_check(s1);
2075 if (has_ext_instr_set) {
2076 M_LADD(s2, s1, REG_ITMP1);
2077 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2078 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
2081 M_LADD (s2, s1, REG_ITMP1);
2082 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2083 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2084 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2085 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
2087 store_reg_to_var_int(iptr->dst, d);
2090 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
2092 var_to_reg_int(s1, src->prev, REG_ITMP1);
2093 var_to_reg_int(s2, src, REG_ITMP2);
2094 d = reg_of_var(iptr->dst, REG_ITMP3);
2095 if (iptr->op1 == 0) {
2096 gen_nullptr_check(s1);
2099 if (has_ext_instr_set) {
2100 M_LADD(s2, s1, REG_ITMP1);
2101 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2102 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
2106 M_LADD(s2, s1, REG_ITMP1);
2107 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2108 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2109 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
2110 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
2111 M_SRA_IMM(d, 48, d);
2113 store_reg_to_var_int(iptr->dst, d);
2116 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
2118 var_to_reg_int(s1, src->prev, REG_ITMP1);
2119 var_to_reg_int(s2, src, REG_ITMP2);
2120 d = reg_of_var(iptr->dst, REG_ITMP3);
2121 if (iptr->op1 == 0) {
2122 gen_nullptr_check(s1);
2125 if (has_ext_instr_set) {
2126 M_LADD (s2, s1, REG_ITMP1);
2127 M_BLDU (d, REG_ITMP1, OFFSET (java_bytearray, data[0]));
2131 M_LADD(s2, s1, REG_ITMP1);
2132 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2133 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
2134 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
2135 M_SRA_IMM(d, 56, d);
2137 store_reg_to_var_int(iptr->dst, d);
2141 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
2143 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2144 var_to_reg_int(s2, src->prev, REG_ITMP2);
2145 if (iptr->op1 == 0) {
2146 gen_nullptr_check(s1);
2149 var_to_reg_int(s3, src, REG_ITMP3);
2150 M_SAADDQ(s2, s1, REG_ITMP1);
2151 M_AST (s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
2154 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
2156 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2157 var_to_reg_int(s2, src->prev, REG_ITMP2);
2158 if (iptr->op1 == 0) {
2159 gen_nullptr_check(s1);
2162 var_to_reg_int(s3, src, REG_ITMP3);
2163 M_S8ADDQ(s2, s1, REG_ITMP1);
2164 M_LST (s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
2167 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
2169 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2170 var_to_reg_int(s2, src->prev, REG_ITMP2);
2171 if (iptr->op1 == 0) {
2172 gen_nullptr_check(s1);
2176 var_to_reg_int(s3, src, REG_ITMP3);
2177 M_S4ADDQ(s2, s1, REG_ITMP1);
2178 M_IST (s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
2181 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
2183 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2184 var_to_reg_int(s2, src->prev, REG_ITMP2);
2185 if (iptr->op1 == 0) {
2186 gen_nullptr_check(s1);
2189 var_to_reg_flt(s3, src, REG_FTMP3);
2190 M_S4ADDQ(s2, s1, REG_ITMP1);
2191 M_FST (s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
2194 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
2196 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2197 var_to_reg_int(s2, src->prev, REG_ITMP2);
2198 if (iptr->op1 == 0) {
2199 gen_nullptr_check(s1);
2202 var_to_reg_flt(s3, src, REG_FTMP3);
2203 M_S8ADDQ(s2, s1, REG_ITMP1);
2204 M_DST (s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
2207 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
2209 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2210 var_to_reg_int(s2, src->prev, REG_ITMP2);
2211 if (iptr->op1 == 0) {
2212 gen_nullptr_check(s1);
2215 var_to_reg_int(s3, src, REG_ITMP3);
2216 if (has_ext_instr_set) {
2217 M_LADD(s2, s1, REG_ITMP1);
2218 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2219 M_SST (s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
2222 M_LADD (s2, s1, REG_ITMP1);
2223 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2224 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2225 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2226 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
2227 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2228 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2229 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2233 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
2235 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2236 var_to_reg_int(s2, src->prev, REG_ITMP2);
2237 if (iptr->op1 == 0) {
2238 gen_nullptr_check(s1);
2241 var_to_reg_int(s3, src, REG_ITMP3);
2242 if (has_ext_instr_set) {
2243 M_LADD(s2, s1, REG_ITMP1);
2244 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2245 M_SST (s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2248 M_LADD (s2, s1, REG_ITMP1);
2249 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2250 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2251 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2252 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
2253 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2254 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2255 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2259 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
2261 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2262 var_to_reg_int(s2, src->prev, REG_ITMP2);
2263 if (iptr->op1 == 0) {
2264 gen_nullptr_check(s1);
2267 var_to_reg_int(s3, src, REG_ITMP3);
2268 if (has_ext_instr_set) {
2269 M_LADD(s2, s1, REG_ITMP1);
2270 M_BST (s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2273 M_LADD (s2, s1, REG_ITMP1);
2274 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2275 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2276 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
2277 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2278 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2279 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2284 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2285 /* op1 = type, val.a = field address */
2287 a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value));
2288 M_ALD(REG_ITMP1, REG_PV, a);
2289 switch (iptr->op1) {
2291 var_to_reg_int(s2, src, REG_ITMP2);
2292 M_IST(s2, REG_ITMP1, 0);
2295 var_to_reg_int(s2, src, REG_ITMP2);
2296 M_LST(s2, REG_ITMP1, 0);
2299 var_to_reg_int(s2, src, REG_ITMP2);
2300 M_AST(s2, REG_ITMP1, 0);
2303 var_to_reg_flt(s2, src, REG_FTMP2);
2304 M_FST(s2, REG_ITMP1, 0);
2307 var_to_reg_flt(s2, src, REG_FTMP2);
2308 M_DST(s2, REG_ITMP1, 0);
2310 default: panic ("internal error");
2314 case ICMD_GETSTATIC: /* ... ==> ..., value */
2315 /* op1 = type, val.a = field address */
2317 a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value));
2318 M_ALD(REG_ITMP1, REG_PV, a);
2319 switch (iptr->op1) {
2321 d = reg_of_var(iptr->dst, REG_ITMP3);
2322 M_ILD(d, REG_ITMP1, 0);
2323 store_reg_to_var_int(iptr->dst, d);
2326 d = reg_of_var(iptr->dst, REG_ITMP3);
2327 M_LLD(d, REG_ITMP1, 0);
2328 store_reg_to_var_int(iptr->dst, d);
2331 d = reg_of_var(iptr->dst, REG_ITMP3);
2332 M_ALD(d, REG_ITMP1, 0);
2333 store_reg_to_var_int(iptr->dst, d);
2336 d = reg_of_var(iptr->dst, REG_FTMP1);
2337 M_FLD(d, REG_ITMP1, 0);
2338 store_reg_to_var_flt(iptr->dst, d);
2341 d = reg_of_var(iptr->dst, REG_FTMP1);
2342 M_DLD(d, REG_ITMP1, 0);
2343 store_reg_to_var_flt(iptr->dst, d);
2345 default: panic ("internal error");
2350 case ICMD_PUTFIELD: /* ..., value ==> ... */
2351 /* op1 = type, val.i = field offset */
2353 a = ((fieldinfo *)(iptr->val.a))->offset;
2354 switch (iptr->op1) {
2356 var_to_reg_int(s1, src->prev, REG_ITMP1);
2357 var_to_reg_int(s2, src, REG_ITMP2);
2358 gen_nullptr_check(s1);
2362 var_to_reg_int(s1, src->prev, REG_ITMP1);
2363 var_to_reg_int(s2, src, REG_ITMP2);
2364 gen_nullptr_check(s1);
2368 var_to_reg_int(s1, src->prev, REG_ITMP1);
2369 var_to_reg_int(s2, src, REG_ITMP2);
2370 gen_nullptr_check(s1);
2374 var_to_reg_int(s1, src->prev, REG_ITMP1);
2375 var_to_reg_flt(s2, src, REG_FTMP2);
2376 gen_nullptr_check(s1);
2380 var_to_reg_int(s1, src->prev, REG_ITMP1);
2381 var_to_reg_flt(s2, src, REG_FTMP2);
2382 gen_nullptr_check(s1);
2385 default: panic ("internal error");
2389 case ICMD_GETFIELD: /* ... ==> ..., value */
2390 /* op1 = type, val.i = field offset */
2392 a = ((fieldinfo *)(iptr->val.a))->offset;
2393 switch (iptr->op1) {
2395 var_to_reg_int(s1, src, REG_ITMP1);
2396 d = reg_of_var(iptr->dst, REG_ITMP3);
2397 gen_nullptr_check(s1);
2399 store_reg_to_var_int(iptr->dst, d);
2402 var_to_reg_int(s1, src, REG_ITMP1);
2403 d = reg_of_var(iptr->dst, REG_ITMP3);
2404 gen_nullptr_check(s1);
2406 store_reg_to_var_int(iptr->dst, d);
2409 var_to_reg_int(s1, src, REG_ITMP1);
2410 d = reg_of_var(iptr->dst, REG_ITMP3);
2411 gen_nullptr_check(s1);
2413 store_reg_to_var_int(iptr->dst, d);
2416 var_to_reg_int(s1, src, REG_ITMP1);
2417 d = reg_of_var(iptr->dst, REG_FTMP1);
2418 gen_nullptr_check(s1);
2420 store_reg_to_var_flt(iptr->dst, d);
2423 var_to_reg_int(s1, src, REG_ITMP1);
2424 d = reg_of_var(iptr->dst, REG_FTMP1);
2425 gen_nullptr_check(s1);
2427 store_reg_to_var_flt(iptr->dst, d);
2429 default: panic ("internal error");
2434 /* branch operations **************************************************/
2436 #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}}
2438 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2440 var_to_reg_int(s1, src, REG_ITMP1);
2441 M_INTMOVE(s1, REG_ITMP1_XPTR);
2442 a = dseg_addaddress(asm_handle_exception);
2443 M_ALD(REG_ITMP2, REG_PV, a);
2444 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2445 M_NOP; /* nop ensures that XPC is less than the end */
2446 /* of basic block */
2450 case ICMD_GOTO: /* ... ==> ... */
2451 /* op1 = target JavaVM pc */
2453 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2457 case ICMD_JSR: /* ... ==> ... */
2458 /* op1 = target JavaVM pc */
2460 M_BSR(REG_ITMP1, 0);
2461 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2464 case ICMD_RET: /* ... ==> ... */
2465 /* op1 = local variable */
2467 var = &(locals[iptr->op1][TYPE_ADR]);
2468 if (var->flags & INMEMORY) {
2469 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2470 M_RET(REG_ZERO, REG_ITMP1);
2473 M_RET(REG_ZERO, var->regoff);
2477 case ICMD_IFNULL: /* ..., value ==> ... */
2478 /* op1 = target JavaVM pc */
2480 var_to_reg_int(s1, src, REG_ITMP1);
2482 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2485 case ICMD_IFNONNULL: /* ..., value ==> ... */
2486 /* op1 = target JavaVM pc */
2488 var_to_reg_int(s1, src, REG_ITMP1);
2490 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2493 case ICMD_IFEQ: /* ..., value ==> ... */
2494 /* op1 = target JavaVM pc, val.i = constant */
2496 var_to_reg_int(s1, src, REG_ITMP1);
2497 if (iptr->val.i == 0) {
2501 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2502 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2505 ICONST(REG_ITMP2, iptr->val.i);
2506 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2508 M_BNEZ(REG_ITMP1, 0);
2510 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2513 case ICMD_IFLT: /* ..., value ==> ... */
2514 /* op1 = target JavaVM pc, val.i = constant */
2516 var_to_reg_int(s1, src, REG_ITMP1);
2517 if (iptr->val.i == 0) {
2521 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2522 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2525 ICONST(REG_ITMP2, iptr->val.i);
2526 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2528 M_BNEZ(REG_ITMP1, 0);
2530 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2533 case ICMD_IFLE: /* ..., value ==> ... */
2534 /* op1 = target JavaVM pc, val.i = constant */
2536 var_to_reg_int(s1, src, REG_ITMP1);
2537 if (iptr->val.i == 0) {
2541 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2542 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2545 ICONST(REG_ITMP2, iptr->val.i);
2546 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2548 M_BNEZ(REG_ITMP1, 0);
2550 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2553 case ICMD_IFNE: /* ..., value ==> ... */
2554 /* op1 = target JavaVM pc, val.i = constant */
2556 var_to_reg_int(s1, src, REG_ITMP1);
2557 if (iptr->val.i == 0) {
2561 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2562 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2565 ICONST(REG_ITMP2, iptr->val.i);
2566 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2568 M_BEQZ(REG_ITMP1, 0);
2570 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2573 case ICMD_IFGT: /* ..., value ==> ... */
2574 /* op1 = target JavaVM pc, val.i = constant */
2576 var_to_reg_int(s1, src, REG_ITMP1);
2577 if (iptr->val.i == 0) {
2581 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2582 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2585 ICONST(REG_ITMP2, iptr->val.i);
2586 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2588 M_BEQZ(REG_ITMP1, 0);
2590 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2593 case ICMD_IFGE: /* ..., value ==> ... */
2594 /* op1 = target JavaVM pc, val.i = constant */
2596 var_to_reg_int(s1, src, REG_ITMP1);
2597 if (iptr->val.i == 0) {
2601 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2602 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2605 ICONST(REG_ITMP2, iptr->val.i);
2606 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2608 M_BEQZ(REG_ITMP1, 0);
2610 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2613 case ICMD_IF_LEQ: /* ..., value ==> ... */
2614 /* op1 = target JavaVM pc, val.l = constant */
2616 var_to_reg_int(s1, src, REG_ITMP1);
2617 if (iptr->val.l == 0) {
2621 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2622 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2625 LCONST(REG_ITMP2, iptr->val.l);
2626 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2628 M_BNEZ(REG_ITMP1, 0);
2630 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2633 case ICMD_IF_LLT: /* ..., value ==> ... */
2634 /* op1 = target JavaVM pc, val.l = constant */
2636 var_to_reg_int(s1, src, REG_ITMP1);
2637 if (iptr->val.l == 0) {
2641 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2642 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2645 LCONST(REG_ITMP2, iptr->val.l);
2646 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2648 M_BNEZ(REG_ITMP1, 0);
2650 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2653 case ICMD_IF_LLE: /* ..., value ==> ... */
2654 /* op1 = target JavaVM pc, val.l = constant */
2656 var_to_reg_int(s1, src, REG_ITMP1);
2657 if (iptr->val.l == 0) {
2661 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2662 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2665 LCONST(REG_ITMP2, iptr->val.l);
2666 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2668 M_BNEZ(REG_ITMP1, 0);
2670 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2673 case ICMD_IF_LNE: /* ..., value ==> ... */
2674 /* op1 = target JavaVM pc, val.l = constant */
2676 var_to_reg_int(s1, src, REG_ITMP1);
2677 if (iptr->val.l == 0) {
2681 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2682 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2685 LCONST(REG_ITMP2, iptr->val.l);
2686 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2688 M_BEQZ(REG_ITMP1, 0);
2690 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2693 case ICMD_IF_LGT: /* ..., value ==> ... */
2694 /* op1 = target JavaVM pc, val.l = constant */
2696 var_to_reg_int(s1, src, REG_ITMP1);
2697 if (iptr->val.l == 0) {
2701 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2702 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2705 LCONST(REG_ITMP2, iptr->val.l);
2706 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2708 M_BEQZ(REG_ITMP1, 0);
2710 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2713 case ICMD_IF_LGE: /* ..., value ==> ... */
2714 /* op1 = target JavaVM pc, val.l = constant */
2716 var_to_reg_int(s1, src, REG_ITMP1);
2717 if (iptr->val.l == 0) {
2721 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2722 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2725 LCONST(REG_ITMP2, iptr->val.l);
2726 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2728 M_BEQZ(REG_ITMP1, 0);
2730 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2733 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2734 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2735 case ICMD_IF_ACMPEQ:
2737 var_to_reg_int(s1, src->prev, REG_ITMP1);
2738 var_to_reg_int(s2, src, REG_ITMP2);
2739 M_CMPEQ(s1, s2, REG_ITMP1);
2740 M_BNEZ(REG_ITMP1, 0);
2741 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2744 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2745 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2746 case ICMD_IF_ACMPNE:
2748 var_to_reg_int(s1, src->prev, REG_ITMP1);
2749 var_to_reg_int(s2, src, REG_ITMP2);
2750 M_CMPEQ(s1, s2, REG_ITMP1);
2751 M_BEQZ(REG_ITMP1, 0);
2752 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2755 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2756 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2758 var_to_reg_int(s1, src->prev, REG_ITMP1);
2759 var_to_reg_int(s2, src, REG_ITMP2);
2760 M_CMPLT(s1, s2, REG_ITMP1);
2761 M_BNEZ(REG_ITMP1, 0);
2762 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2765 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2766 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2768 var_to_reg_int(s1, src->prev, REG_ITMP1);
2769 var_to_reg_int(s2, src, REG_ITMP2);
2770 M_CMPLE(s1, s2, REG_ITMP1);
2771 M_BEQZ(REG_ITMP1, 0);
2772 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2775 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2776 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2778 var_to_reg_int(s1, src->prev, REG_ITMP1);
2779 var_to_reg_int(s2, src, REG_ITMP2);
2780 M_CMPLE(s1, s2, REG_ITMP1);
2781 M_BNEZ(REG_ITMP1, 0);
2782 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2785 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2786 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2788 var_to_reg_int(s1, src->prev, REG_ITMP1);
2789 var_to_reg_int(s2, src, REG_ITMP2);
2790 M_CMPLT(s1, s2, REG_ITMP1);
2791 M_BEQZ(REG_ITMP1, 0);
2792 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2795 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2797 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2800 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2801 /* val.i = constant */
2803 var_to_reg_int(s1, src, REG_ITMP1);
2804 d = reg_of_var(iptr->dst, REG_ITMP3);
2806 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2807 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2808 M_CMPEQ(s1, REG_ZERO, d);
2809 store_reg_to_var_int(iptr->dst, d);
2812 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2813 M_CMPEQ(s1, REG_ZERO, d);
2815 store_reg_to_var_int(iptr->dst, d);
2819 M_MOV(s1, REG_ITMP1);
2822 ICONST(d, iptr[1].val.i);
2824 if ((s3 >= 0) && (s3 <= 255)) {
2825 M_CMOVEQ_IMM(s1, s3, d);
2828 ICONST(REG_ITMP2, s3);
2829 M_CMOVEQ(s1, REG_ITMP2, d);
2831 store_reg_to_var_int(iptr->dst, d);
2834 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2835 /* val.i = constant */
2837 var_to_reg_int(s1, src, REG_ITMP1);
2838 d = reg_of_var(iptr->dst, REG_ITMP3);
2840 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2841 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2842 M_CMPEQ(s1, REG_ZERO, d);
2843 store_reg_to_var_int(iptr->dst, d);
2846 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2847 M_CMPEQ(s1, REG_ZERO, d);
2849 store_reg_to_var_int(iptr->dst, d);
2853 M_MOV(s1, REG_ITMP1);
2856 ICONST(d, iptr[1].val.i);
2858 if ((s3 >= 0) && (s3 <= 255)) {
2859 M_CMOVNE_IMM(s1, s3, d);
2862 ICONST(REG_ITMP2, s3);
2863 M_CMOVNE(s1, REG_ITMP2, d);
2865 store_reg_to_var_int(iptr->dst, d);
2868 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2869 /* val.i = constant */
2871 var_to_reg_int(s1, src, REG_ITMP1);
2872 d = reg_of_var(iptr->dst, REG_ITMP3);
2874 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2875 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2876 M_CMPLT(s1, REG_ZERO, d);
2877 store_reg_to_var_int(iptr->dst, d);
2880 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2881 M_CMPLE(REG_ZERO, s1, d);
2882 store_reg_to_var_int(iptr->dst, d);
2886 M_MOV(s1, REG_ITMP1);
2889 ICONST(d, iptr[1].val.i);
2891 if ((s3 >= 0) && (s3 <= 255)) {
2892 M_CMOVLT_IMM(s1, s3, d);
2895 ICONST(REG_ITMP2, s3);
2896 M_CMOVLT(s1, REG_ITMP2, d);
2898 store_reg_to_var_int(iptr->dst, d);
2901 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2902 /* val.i = constant */
2904 var_to_reg_int(s1, src, REG_ITMP1);
2905 d = reg_of_var(iptr->dst, REG_ITMP3);
2907 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2908 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2909 M_CMPLE(REG_ZERO, s1, d);
2910 store_reg_to_var_int(iptr->dst, d);
2913 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2914 M_CMPLT(s1, REG_ZERO, d);
2915 store_reg_to_var_int(iptr->dst, d);
2919 M_MOV(s1, REG_ITMP1);
2922 ICONST(d, iptr[1].val.i);
2924 if ((s3 >= 0) && (s3 <= 255)) {
2925 M_CMOVGE_IMM(s1, s3, d);
2928 ICONST(REG_ITMP2, s3);
2929 M_CMOVGE(s1, REG_ITMP2, d);
2931 store_reg_to_var_int(iptr->dst, d);
2934 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2935 /* val.i = constant */
2937 var_to_reg_int(s1, src, REG_ITMP1);
2938 d = reg_of_var(iptr->dst, REG_ITMP3);
2940 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2941 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2942 M_CMPLT(REG_ZERO, s1, d);
2943 store_reg_to_var_int(iptr->dst, d);
2946 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2947 M_CMPLE(s1, REG_ZERO, d);
2948 store_reg_to_var_int(iptr->dst, d);
2952 M_MOV(s1, REG_ITMP1);
2955 ICONST(d, iptr[1].val.i);
2957 if ((s3 >= 0) && (s3 <= 255)) {
2958 M_CMOVGT_IMM(s1, s3, d);
2961 ICONST(REG_ITMP2, s3);
2962 M_CMOVGT(s1, REG_ITMP2, d);
2964 store_reg_to_var_int(iptr->dst, d);
2967 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2968 /* val.i = constant */
2970 var_to_reg_int(s1, src, REG_ITMP1);
2971 d = reg_of_var(iptr->dst, REG_ITMP3);
2973 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2974 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2975 M_CMPLE(s1, REG_ZERO, d);
2976 store_reg_to_var_int(iptr->dst, d);
2979 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2980 M_CMPLT(REG_ZERO, s1, d);
2981 store_reg_to_var_int(iptr->dst, d);
2985 M_MOV(s1, REG_ITMP1);
2988 ICONST(d, iptr[1].val.i);
2990 if ((s3 >= 0) && (s3 <= 255)) {
2991 M_CMOVLE_IMM(s1, s3, d);
2994 ICONST(REG_ITMP2, s3);
2995 M_CMOVLE(s1, REG_ITMP2, d);
2997 store_reg_to_var_int(iptr->dst, d);
3001 case ICMD_IRETURN: /* ..., retvalue ==> ... */
3006 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3007 a = dseg_addaddress ((void*) (builtin_monitorexit));
3008 M_ALD(REG_PV, REG_PV, a);
3009 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
3010 M_JSR(REG_RA, REG_PV);
3011 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
3014 var_to_reg_int(s1, src, REG_RESULT);
3015 M_INTMOVE(s1, REG_RESULT);
3016 goto nowperformreturn;
3018 case ICMD_FRETURN: /* ..., retvalue ==> ... */
3022 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3023 a = dseg_addaddress ((void*) (builtin_monitorexit));
3024 M_ALD(REG_PV, REG_PV, a);
3025 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
3026 M_JSR(REG_RA, REG_PV);
3027 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
3030 var_to_reg_flt(s1, src, REG_FRESULT);
3031 M_FLTMOVE(s1, REG_FRESULT);
3032 goto nowperformreturn;
3034 case ICMD_RETURN: /* ... ==> ... */
3037 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3038 a = dseg_addaddress ((void*) (builtin_monitorexit));
3039 M_ALD(REG_PV, REG_PV, a);
3040 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
3041 M_JSR(REG_RA, REG_PV);
3042 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
3050 p = parentargs_base;
3052 /* restore return address */
3055 {p--; M_LLD (REG_RA, REG_SP, 8 * p);}
3057 /* restore saved registers */
3059 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
3060 {p--; M_LLD(savintregs[r], REG_SP, 8 * p);}
3061 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
3062 {p--; M_DLD(savfltregs[r], REG_SP, 8 * p);}
3064 /* deallocate stack */
3066 if (parentargs_base)
3067 {M_LDA(REG_SP, REG_SP, parentargs_base*8);}
3069 /* call trace function */
3072 M_LDA (REG_SP, REG_SP, -24);
3073 M_AST(REG_RA, REG_SP, 0);
3074 M_LST(REG_RESULT, REG_SP, 8);
3075 M_DST(REG_FRESULT, REG_SP,16);
3076 a = dseg_addaddress (method);
3077 M_ALD(argintregs[0], REG_PV, a);
3078 M_MOV(REG_RESULT, argintregs[1]);
3079 M_FLTMOVE(REG_FRESULT, argfltregs[2]);
3080 M_FLTMOVE(REG_FRESULT, argfltregs[3]);
3081 a = dseg_addaddress ((void*) (builtin_displaymethodstop));
3082 M_ALD(REG_PV, REG_PV, a);
3083 M_JSR (REG_RA, REG_PV);
3084 s1 = (int)((u1*) mcodeptr - mcodebase);
3085 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
3088 while (ml<-32768) { ml+=65536; mh--; }
3089 M_LDA (REG_PV, REG_RA, ml );
3090 M_LDAH (REG_PV, REG_PV, mh );
3092 M_DLD(REG_FRESULT, REG_SP,16);
3093 M_LLD(REG_RESULT, REG_SP, 8);
3094 M_ALD(REG_RA, REG_SP, 0);
3095 M_LDA (REG_SP, REG_SP, 24);
3098 M_RET(REG_ZERO, REG_RA);
3104 case ICMD_TABLESWITCH: /* ..., index ==> ... */
3109 tptr = (void **) iptr->target;
3111 s4ptr = iptr->val.a;
3112 l = s4ptr[1]; /* low */
3113 i = s4ptr[2]; /* high */
3115 var_to_reg_int(s1, src, REG_ITMP1);
3117 {M_INTMOVE(s1, REG_ITMP1);}
3118 else if (l <= 32768) {
3119 M_LDA(REG_ITMP1, s1, -l);
3122 ICONST(REG_ITMP2, l);
3123 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
3130 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
3132 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
3133 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3135 M_BEQZ(REG_ITMP2, 0);
3138 /* codegen_addreference(BlockPtrOfPC(s4ptr[0]), mcodeptr); */
3139 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3141 /* build jump table top down and use address of lowest entry */
3143 /* s4ptr += 3 + i; */
3147 /* dseg_addtarget(BlockPtrOfPC(*--s4ptr)); */
3148 dseg_addtarget((basicblock *) tptr[0]);
3153 /* length of dataseg after last dseg_addtarget is used by load */
3155 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
3156 M_ALD(REG_ITMP2, REG_ITMP2, -dseglen);
3157 M_JMP(REG_ZERO, REG_ITMP2);
3162 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3164 s4 i, l, val, *s4ptr;
3167 tptr = (void **) iptr->target;
3169 s4ptr = iptr->val.a;
3170 l = s4ptr[0]; /* default */
3171 i = s4ptr[1]; /* count */
3173 MCODECHECK((i<<2)+8);
3174 var_to_reg_int(s1, src, REG_ITMP1);
3180 if ((val >= 0) && (val <= 255)) {
3181 M_CMPEQ_IMM(s1, val, REG_ITMP2);
3184 if ((val >= -32768) && (val <= 32767)) {
3185 M_LDA(REG_ITMP2, REG_ZERO, val);
3188 a = dseg_adds4 (val);
3189 M_ILD(REG_ITMP2, REG_PV, a);
3191 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
3193 M_BNEZ(REG_ITMP2, 0);
3194 /* codegen_addreference(BlockPtrOfPC(s4ptr[1]), mcodeptr); */
3195 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3199 /* codegen_addreference(BlockPtrOfPC(l), mcodeptr); */
3201 tptr = (void **) iptr->target;
3202 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3209 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
3210 /* op1 = return type, val.a = function pointer*/
3214 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
3215 /* op1 = return type, val.a = function pointer*/
3219 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
3220 /* op1 = return type, val.a = function pointer*/
3224 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3225 /* op1 = arg count, val.a = method pointer */
3227 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3228 /* op1 = arg count, val.a = method pointer */
3230 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3231 /* op1 = arg count, val.a = method pointer */
3233 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
3234 /* op1 = arg count, val.a = method pointer */
3242 MCODECHECK((s3 << 1) + 64);
3244 /* copy arguments to registers or stack location */
3246 for (; --s3 >= 0; src = src->prev) {
3247 if (src->varkind == ARGVAR)
3249 if (IS_INT_LNG_TYPE(src->type)) {
3250 if (s3 < INT_ARG_CNT) {
3251 s1 = argintregs[s3];
3252 var_to_reg_int(d, src, s1);
3256 var_to_reg_int(d, src, REG_ITMP1);
3257 M_LST(d, REG_SP, 8 * (s3 - INT_ARG_CNT));
3261 if (s3 < FLT_ARG_CNT) {
3262 s1 = argfltregs[s3];
3263 var_to_reg_flt(d, src, s1);
3267 var_to_reg_flt(d, src, REG_FTMP1);
3268 M_DST(d, REG_SP, 8 * (s3 - FLT_ARG_CNT));
3273 switch (iptr->opc) {
3277 a = dseg_addaddress ((void*) (m));
3279 M_ALD(REG_PV, REG_PV, a); /* Pointer to built-in-function */
3281 goto makeactualcall;
3283 case ICMD_INVOKESTATIC:
3284 case ICMD_INVOKESPECIAL:
3285 a = dseg_addaddress (m->stubroutine);
3287 M_ALD(REG_PV, REG_PV, a ); /* method pointer in r27 */
3290 goto makeactualcall;
3292 case ICMD_INVOKEVIRTUAL:
3294 gen_nullptr_check(argintregs[0]);
3295 M_ALD(REG_METHODPTR, argintregs[0],
3296 OFFSET(java_objectheader, vftbl));
3297 M_ALD(REG_PV, REG_METHODPTR, OFFSET(vftbl, table[0]) +
3298 sizeof(methodptr) * m->vftblindex);
3301 goto makeactualcall;
3303 case ICMD_INVOKEINTERFACE:
3306 gen_nullptr_check(argintregs[0]);
3307 M_ALD(REG_METHODPTR, argintregs[0],
3308 OFFSET(java_objectheader, vftbl));
3309 M_ALD(REG_METHODPTR, REG_METHODPTR,
3310 OFFSET(vftbl, interfacetable[0]) -
3311 sizeof(methodptr*) * ci->index);
3312 M_ALD(REG_PV, REG_METHODPTR,
3313 sizeof(methodptr) * (m - ci->methods));
3316 goto makeactualcall;
3320 sprintf (logtext, "Unkown ICMD-Command: %d", iptr->opc);
3326 M_JSR (REG_RA, REG_PV);
3330 s1 = (int)((u1*) mcodeptr - mcodebase);
3331 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
3334 while (ml<-32768) { ml+=65536; mh--; }
3335 M_LDA (REG_PV, REG_RA, ml );
3336 M_LDAH (REG_PV, REG_PV, mh );
3339 /* d contains return type */
3341 if (d != TYPE_VOID) {
3342 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3343 s1 = reg_of_var(iptr->dst, REG_RESULT);
3344 M_INTMOVE(REG_RESULT, s1);
3345 store_reg_to_var_int(iptr->dst, s1);
3348 s1 = reg_of_var(iptr->dst, REG_FRESULT);
3349 M_FLTMOVE(REG_FRESULT, s1);
3350 store_reg_to_var_flt(iptr->dst, s1);
3357 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3359 /* op1: 0 == array, 1 == class */
3360 /* val.a: (classinfo*) superclass */
3362 /* superclass is an interface:
3364 * return (sub != NULL) &&
3365 * (sub->vftbl->interfacetablelength > super->index) &&
3366 * (sub->vftbl->interfacetable[-super->index] != NULL);
3368 * superclass is a class:
3370 * return ((sub != NULL) && (0
3371 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3372 * super->vftbl->diffvall));
3376 classinfo *super = (classinfo*) iptr->val.a;
3378 var_to_reg_int(s1, src, REG_ITMP1);
3379 d = reg_of_var(iptr->dst, REG_ITMP3);
3381 M_MOV(s1, REG_ITMP1);
3385 if (iptr->op1) { /* class/interface */
3386 if (super->flags & ACC_INTERFACE) { /* interface */
3388 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3389 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3390 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3391 M_BLEZ(REG_ITMP2, 2);
3392 M_ALD(REG_ITMP1, REG_ITMP1,
3393 OFFSET(vftbl, interfacetable[0]) -
3394 super->index * sizeof(methodptr*));
3395 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3399 s2 = super->vftbl->diffval;
3400 M_BEQZ(s1, 4 + (s2 > 255));
3401 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3402 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3403 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3405 M_CMPULE_IMM(REG_ITMP1, s2, d);
3407 M_LDA(REG_ITMP2, REG_ZERO, s2);
3408 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3412 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3413 a = dseg_addaddress ((void*) super->vftbl);
3414 M_ALD(REG_ITMP2, REG_PV, a);
3415 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3416 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl, baseval));
3417 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, diffval));
3418 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3419 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3423 panic ("internal error: no inlined array instanceof");
3425 store_reg_to_var_int(iptr->dst, d);
3428 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3430 /* op1: 0 == array, 1 == class */
3431 /* val.a: (classinfo*) superclass */
3433 /* superclass is an interface:
3435 * OK if ((sub == NULL) ||
3436 * (sub->vftbl->interfacetablelength > super->index) &&
3437 * (sub->vftbl->interfacetable[-super->index] != NULL));
3439 * superclass is a class:
3441 * OK if ((sub == NULL) || (0
3442 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3443 * super->vftbl->diffvall));
3447 classinfo *super = (classinfo*) iptr->val.a;
3449 d = reg_of_var(iptr->dst, REG_ITMP3);
3450 var_to_reg_int(s1, src, d);
3451 if (iptr->op1) { /* class/interface */
3452 if (super->flags & ACC_INTERFACE) { /* interface */
3454 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3455 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3456 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3457 M_BLEZ(REG_ITMP2, 0);
3458 codegen_addxcastrefs(mcodeptr);
3459 M_ALD(REG_ITMP2, REG_ITMP1,
3460 OFFSET(vftbl, interfacetable[0]) -
3461 super->index * sizeof(methodptr*));
3462 M_BEQZ(REG_ITMP2, 0);
3463 codegen_addxcastrefs(mcodeptr);
3467 s2 = super->vftbl->diffval;
3468 M_BEQZ(s1, 4 + (s2 != 0) + (s2 > 255));
3469 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3470 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3471 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3473 M_BNEZ(REG_ITMP1, 0);
3475 else if (s2 <= 255) {
3476 M_CMPULE_IMM(REG_ITMP1, s2, REG_ITMP2);
3477 M_BEQZ(REG_ITMP2, 0);
3480 M_LDA(REG_ITMP2, REG_ZERO, s2);
3481 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3482 M_BEQZ(REG_ITMP2, 0);
3485 M_BEQZ(s1, 8 + (d == REG_ITMP3));
3486 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3487 a = dseg_addaddress ((void*) super->vftbl);
3488 M_ALD(REG_ITMP2, REG_PV, a);
3489 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3490 if (d != REG_ITMP3) {
3491 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl, baseval));
3492 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, diffval));
3493 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3496 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, baseval));
3497 M_ISUB(REG_ITMP1, REG_ITMP2, REG_ITMP1);
3498 M_ALD(REG_ITMP2, REG_PV, a);
3499 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, diffval));
3501 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3502 M_BEQZ(REG_ITMP2, 0);
3503 codegen_addxcastrefs(mcodeptr);
3507 panic ("internal error: no inlined array checkcast");
3510 store_reg_to_var_int(iptr->dst, d);
3513 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
3515 var_to_reg_int(s1, src, REG_ITMP1);
3517 codegen_addxcheckarefs(mcodeptr);
3520 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3521 /* op1 = dimension, val.a = array descriptor */
3523 /* check for negative sizes and copy sizes to stack if necessary */
3525 MCODECHECK((iptr->op1 << 1) + 64);
3527 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3528 var_to_reg_int(s2, src, REG_ITMP1);
3530 codegen_addxcheckarefs(mcodeptr);
3532 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
3534 if (src->varkind != ARGVAR) {
3535 M_LST(s2, REG_SP, 8 * (s1 + INT_ARG_CNT));
3539 /* a0 = dimension count */
3541 ICONST(argintregs[0], iptr->op1);
3543 /* a1 = arraydescriptor */
3545 a = dseg_addaddress(iptr->val.a);
3546 M_ALD(argintregs[1], REG_PV, a);
3548 /* a2 = pointer to dimensions = stack pointer */
3550 M_INTMOVE(REG_SP, argintregs[2]);
3552 a = dseg_addaddress((void*) (builtin_nmultianewarray));
3553 M_ALD(REG_PV, REG_PV, a);
3554 M_JSR(REG_RA, REG_PV);
3555 s1 = (int)((u1*) mcodeptr - mcodebase);
3557 M_LDA (REG_PV, REG_RA, -s1);
3559 s4 ml = -s1, mh = 0;
3560 while (ml < -32768) {ml += 65536; mh--;}
3561 M_LDA(REG_PV, REG_RA, ml);
3562 M_LDAH(REG_PV, REG_PV, mh);
3564 s1 = reg_of_var(iptr->dst, REG_RESULT);
3565 M_INTMOVE(REG_RESULT, s1);
3566 store_reg_to_var_int(iptr->dst, s1);
3570 default: sprintf (logtext, "Unknown pseudo command: %d", iptr->opc);
3577 } /* for instruction */
3579 /* copy values to interface registers */
3581 src = bptr->outstack;
3582 len = bptr->outdepth;
3586 if ((src->varkind != STACKVAR)) {
3588 if (IS_FLT_DBL_TYPE(s2)) {
3589 var_to_reg_flt(s1, src, REG_FTMP1);
3590 if (!(interfaces[len][s2].flags & INMEMORY)) {
3591 M_FLTMOVE(s1,interfaces[len][s2].regoff);
3594 M_DST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3598 var_to_reg_int(s1, src, REG_ITMP1);
3599 if (!(interfaces[len][s2].flags & INMEMORY)) {
3600 M_INTMOVE(s1,interfaces[len][s2].regoff);
3603 M_LST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3609 } /* if (bptr -> flags >= BBREACHED) */
3610 } /* for basic block */
3612 /* bptr -> mpc = (int)((u1*) mcodeptr - mcodebase); */
3615 /* generate bound check stubs */
3617 s4 *xcodeptr = NULL;
3619 for (; xboundrefs != NULL; xboundrefs = xboundrefs->next) {
3620 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3621 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
3622 xboundrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3627 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
3628 xboundrefs->branchpos, (u1*) mcodeptr - mcodebase);
3632 M_LDA(REG_ITMP2_XPC, REG_PV, xboundrefs->branchpos - 4);
3634 if (xcodeptr != NULL) {
3635 M_BR((xcodeptr-mcodeptr)-1);
3638 xcodeptr = mcodeptr;
3640 a = dseg_addaddress(proto_java_lang_ArrayIndexOutOfBoundsException);
3641 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3643 a = dseg_addaddress(asm_handle_exception);
3644 M_ALD(REG_ITMP3, REG_PV, a);
3646 M_JMP(REG_ZERO, REG_ITMP3);
3650 /* generate negative array size check stubs */
3654 for (; xcheckarefs != NULL; xcheckarefs = xcheckarefs->next) {
3655 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3656 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3657 xcheckarefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3661 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3662 xcheckarefs->branchpos, (u1*) mcodeptr - mcodebase);
3666 M_LDA(REG_ITMP2_XPC, REG_PV, xcheckarefs->branchpos - 4);
3668 if (xcodeptr != NULL) {
3669 M_BR((xcodeptr-mcodeptr)-1);
3672 xcodeptr = mcodeptr;
3674 a = dseg_addaddress(proto_java_lang_NegativeArraySizeException);
3675 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3677 a = dseg_addaddress(asm_handle_exception);
3678 M_ALD(REG_ITMP3, REG_PV, a);
3680 M_JMP(REG_ZERO, REG_ITMP3);
3684 /* generate cast check stubs */
3688 for (; xcastrefs != NULL; xcastrefs = xcastrefs->next) {
3689 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3690 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3691 xcastrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3695 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3696 xcastrefs->branchpos, (u1*) mcodeptr - mcodebase);
3700 M_LDA(REG_ITMP2_XPC, REG_PV, xcastrefs->branchpos - 4);
3702 if (xcodeptr != NULL) {
3703 M_BR((xcodeptr-mcodeptr)-1);
3706 xcodeptr = mcodeptr;
3708 a = dseg_addaddress(proto_java_lang_ClassCastException);
3709 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3711 a = dseg_addaddress(asm_handle_exception);
3712 M_ALD(REG_ITMP3, REG_PV, a);
3714 M_JMP(REG_ZERO, REG_ITMP3);
3719 #ifdef SOFTNULLPTRCHECK
3721 /* generate null pointer check stubs */
3725 for (; xnullrefs != NULL; xnullrefs = xnullrefs->next) {
3726 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3727 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3728 xnullrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3732 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3733 xnullrefs->branchpos, (u1*) mcodeptr - mcodebase);
3737 M_LDA(REG_ITMP2_XPC, REG_PV, xnullrefs->branchpos - 4);
3739 if (xcodeptr != NULL) {
3740 M_BR((xcodeptr-mcodeptr)-1);
3743 xcodeptr = mcodeptr;
3745 a = dseg_addaddress(proto_java_lang_NullPointerException);
3746 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3748 a = dseg_addaddress(asm_handle_exception);
3749 M_ALD(REG_ITMP3, REG_PV, a);
3751 M_JMP(REG_ZERO, REG_ITMP3);
3758 codegen_finish((int)((u1*) mcodeptr - mcodebase));
3762 /* redefinition of code generation macros (compiling into array) **************/
3765 These macros are newly defined to allow code generation into an array.
3766 This is necessary, because the original M_.. macros generate code by
3767 calling 'codegen_adds4' that uses an additional data structure to
3770 For a faster (but less flexible) version to generate code, these
3771 macros directly use the (s4* p) - pointer to put the code directly
3772 in a locally defined array.
3773 This makes sense only for the stub-generation-routines below.
3777 #define M_OP3(op,fu,a,b,c,const) \
3778 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<(16-3*(const)))| \
3779 ((const)<<12)|((fu)<<5)|((c)) )
3781 #define M_FOP3(op,fu,a,b,c) \
3782 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<16)|((fu)<<5)|(c) )
3784 #define M_BRA(op,a,disp) \
3785 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((disp)&0x1fffff) )
3787 #define M_MEM(op,a,b,disp) \
3788 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<16)|((disp)&0xffff) )
3791 /* function createcompilerstub *************************************************
3793 creates a stub routine which calls the compiler
3795 *******************************************************************************/
3797 #define COMPSTUBSIZE 3
3799 u1 *createcompilerstub (methodinfo *m)
3801 u8 *s = CNEW (u8, COMPSTUBSIZE); /* memory to hold the stub */
3802 s4 *p = (s4*) s; /* code generation pointer */
3804 /* code for the stub */
3805 M_ALD (REG_PV, REG_PV, 16); /* load pointer to the compiler */
3806 M_JMP (0, REG_PV); /* jump to the compiler, return address
3807 in reg 0 is used as method pointer */
3808 s[1] = (u8) m; /* literals to be adressed */
3809 s[2] = (u8) asm_call_jit_compiler; /* jump directly via PV from above */
3812 count_cstub_len += COMPSTUBSIZE * 8;
3819 /* function removecompilerstub *************************************************
3821 deletes a compilerstub from memory (simply by freeing it)
3823 *******************************************************************************/
3825 void removecompilerstub (u1 *stub)
3827 CFREE (stub, COMPSTUBSIZE * 8);
3830 /* function: createnativestub **************************************************
3832 creates a stub routine which calls a native method
3834 *******************************************************************************/
3836 #define NATIVESTUBSIZE 34
3837 #define NATIVESTUBOFFSET 8
3839 int runverbosenat = 0;
3841 u1 *createnativestub (functionptr f, methodinfo *m)
3844 u8 *s = CNEW (u8, NATIVESTUBSIZE); /* memory to hold the stub */
3845 u8 *cs = s + NATIVESTUBOFFSET;
3846 s4 *p = (s4*) (cs); /* code generation pointer */
3848 *(cs-1) = (u8) f; /* address of native method */
3849 *(cs-2) = (u8) (&exceptionptr); /* address of exceptionptr */
3850 *(cs-3) = (u8) asm_handle_nat_exception; /* addr of asm exception handler */
3851 *(cs-4) = (u8) (&env); /* addr of jni_environement */
3852 *(cs-5) = (u8) asm_builtin_trace;
3854 *(cs-7) = (u8) asm_builtin_exittrace;
3855 *(cs-8) = (u8) builtin_trace_exception;
3859 utf_display(m->class->name);
3861 utf_display(m->name);
3862 printf(" 0x%p\n", cs);
3865 M_LDA (REG_SP, REG_SP, -8); /* build up stackframe */
3866 M_AST (REG_RA, REG_SP, 0); /* store return address */
3869 if (runverbosenat) {
3870 M_ALD(REG_ITMP1, REG_PV, -6*8);
3871 M_ALD(REG_PV, REG_PV, -5*8);
3873 M_JSR(REG_RA, REG_PV);
3874 disp = -(int) (p - (s4*) cs)*4;
3875 M_LDA(REG_PV, REG_RA, disp);
3881 M_MOV (argintregs[4],argintregs[5]);
3882 M_FMOV (argfltregs[4],argfltregs[5]);
3884 M_MOV (argintregs[3],argintregs[4]);
3885 M_FMOV (argfltregs[3],argfltregs[4]);
3887 M_MOV (argintregs[2],argintregs[3]);
3888 M_FMOV (argfltregs[2],argfltregs[3]);
3890 M_MOV (argintregs[1],argintregs[2]);
3891 M_FMOV (argfltregs[1],argfltregs[2]);
3893 M_MOV (argintregs[0],argintregs[1]);
3894 M_FMOV (argfltregs[0],argfltregs[1]);
3896 M_ALD (argintregs[0], REG_PV, -4*8);/* load adress of jni_environement */
3898 M_ALD (REG_PV, REG_PV, -1*8); /* load adress of native method */
3899 M_JSR (REG_RA, REG_PV); /* call native method */
3901 disp = -(int) (p - (s4*) cs)*4;
3902 M_LDA (REG_PV, REG_RA, disp); /* recompute pv from ra */
3903 M_ALD (REG_ITMP3, REG_PV, -2*8); /* get address of exceptionptr */
3905 M_ALD (REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
3907 3 + (runverbosenat ? 6 : 0)); /* if no exception then return */
3910 if (runverbosenat) {
3911 M_ALD(argintregs[0], REG_PV, -6*8);
3912 M_MOV(REG_RESULT, argintregs[1]);
3913 M_FMOV(REG_FRESULT, argfltregs[2]);
3914 M_FMOV(REG_FRESULT, argfltregs[3]);
3915 M_ALD(REG_PV, REG_PV, -7*8);
3916 M_JSR(REG_RA, REG_PV);
3920 M_ALD (REG_RA, REG_SP, 0); /* load return address */
3921 M_LDA (REG_SP, REG_SP, 8); /* remove stackframe */
3923 M_RET (REG_ZERO, REG_RA); /* return to caller */
3925 M_AST (REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
3928 if (runverbosenat) {
3929 M_LDA(REG_SP, REG_SP, -8);
3930 M_AST(REG_ITMP1, REG_SP, 0);
3931 M_MOV(REG_ITMP1, argintregs[0]);
3932 M_ALD(argintregs[1], REG_PV, -6*8);
3933 M_ALD(argintregs[2], REG_SP, 0);
3934 M_CLR(argintregs[3]);
3935 M_ALD(REG_PV, REG_PV, -8*8);
3936 M_JSR(REG_RA, REG_PV);
3937 disp = -(int) (p - (s4*) cs)*4;
3938 M_LDA (REG_PV, REG_RA, disp);
3939 M_ALD(REG_ITMP1, REG_SP, 0);
3940 M_LDA(REG_SP, REG_SP, 8);
3944 M_ALD (REG_RA, REG_SP, 0); /* load return address */
3945 M_LDA (REG_SP, REG_SP, 8); /* remove stackframe */
3947 M_LDA (REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
3949 M_ALD (REG_ITMP3, REG_PV, -3*8); /* load asm exception handler address */
3950 M_JMP (REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
3954 static int stubprinted;
3956 printf("stubsize: %d/2\n", (int) (p - (s4*) s));
3962 count_nstub_len += NATIVESTUBSIZE * 8;
3965 return (u1*) (s + NATIVESTUBOFFSET);
3968 /* function: removenativestub **************************************************
3970 removes a previously created native-stub from memory
3972 *******************************************************************************/
3974 void removenativestub (u1 *stub)
3976 CFREE ((u8*) stub - NATIVESTUBOFFSET, NATIVESTUBSIZE * 8);
3981 * These are local overrides for various environment variables in Emacs.
3982 * Please do not remove this and leave it at the end of the file, where
3983 * Emacs will automagically detect them.
3984 * ---------------------------------------------------------------------
3987 * indent-tabs-mode: t