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 837 2004-01-05 00:04:51Z twisti $
50 /* include independent code generation stuff */
51 #include "codegen.inc"
55 /* *****************************************************************************
57 Datatypes and Register Allocations:
58 -----------------------------------
60 On 64-bit-machines (like the Alpha) all operands are stored in the
61 registers in a 64-bit form, even when the correspondig JavaVM operands
62 only need 32 bits. This is done by a canonical representation:
64 32-bit integers are allways stored as sign-extended 64-bit values (this
65 approach is directly supported by the Alpha architecture and is very easy
68 32-bit-floats are stored in a 64-bit doubleprecision register by simply
69 expanding the exponent and mantissa with zeroes. (also supported by the
75 The calling conventions and the layout of the stack is explained in detail
76 in the documention file: calling.doc
78 *******************************************************************************/
81 /* register descripton - array ************************************************/
83 /* #define REG_RES 0 reserved register for OS or code generator */
84 /* #define REG_RET 1 return value register */
85 /* #define REG_EXC 2 exception value register (only old jit) */
86 /* #define REG_SAV 3 (callee) saved register */
87 /* #define REG_TMP 4 scratch temporary register (caller saved) */
88 /* #define REG_ARG 5 argument register (caller saved) */
90 /* #define REG_END -1 last entry in tables */
93 REG_RET, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
94 REG_TMP, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
95 REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_TMP, REG_TMP,
96 REG_TMP, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES,
99 /* for use of reserved registers, see comment above */
101 int nregdescfloat[] = {
102 REG_RET, REG_TMP, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
103 REG_SAV, REG_SAV, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
104 REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_TMP, REG_TMP,
105 REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_RES, REG_RES, REG_RES, REG_RES,
108 /* for use of reserved registers, see comment above */
111 /* parameter allocation mode */
113 int nreg_parammode = PARAMMODE_NUMBERED;
115 /* parameter-registers will be allocated by assigning the
116 1. parameter: int/float-reg 16
117 2. parameter: int/float-reg 17
118 3. parameter: int/float-reg 18 ....
122 /* stackframe-infos ***********************************************************/
124 int parentargs_base; /* offset in stackframe for the parameter from the caller*/
126 /* -> see file 'calling.doc' */
129 /* additional functions and macros to generate code ***************************/
131 /* #define BlockPtrOfPC(pc) block+block_index[pc] */
132 #define BlockPtrOfPC(pc) ((basicblock *) iptr->target)
136 #define COUNT_SPILLS count_spills++
142 /* gen_nullptr_check(objreg) */
144 #ifdef SOFTNULLPTRCHECK
145 #define gen_nullptr_check(objreg) \
147 M_BEQZ((objreg), 0);\
148 codegen_addxnullrefs(mcodeptr);\
151 #define gen_nullptr_check(objreg)
155 /* MCODECHECK(icnt) */
157 #define MCODECHECK(icnt) \
158 if((mcodeptr + (icnt)) > mcodeend) mcodeptr = codegen_increase((u1*) mcodeptr)
161 generates an integer-move from register a to b.
162 if a and b are the same int-register, no code will be generated.
165 #define M_INTMOVE(a,b) if(a!=b){M_MOV(a,b);}
169 generates a floating-point-move from register a to b.
170 if a and b are the same float-register, no code will be generated
173 #define M_FLTMOVE(a,b) if(a!=b){M_FMOV(a,b);}
177 this function generates code to fetch data from a pseudo-register
178 into a real register.
179 If the pseudo-register has actually been assigned to a real
180 register, no code will be emitted, since following operations
181 can use this register directly.
183 v: pseudoregister to be fetched from
184 tempregnum: temporary register to be used if v is actually spilled to ram
186 return: the register number, where the operand can be found after
187 fetching (this wil be either tempregnum or the register
188 number allready given to v)
191 #define var_to_reg_int(regnr,v,tempnr) { \
192 if ((v)->flags & INMEMORY) \
193 {COUNT_SPILLS;M_LLD(tempnr,REG_SP,8*(v)->regoff);regnr=tempnr;} \
194 else regnr=(v)->regoff; \
198 #define var_to_reg_flt(regnr,v,tempnr) { \
199 if ((v)->flags & INMEMORY) \
200 {COUNT_SPILLS;M_DLD(tempnr,REG_SP,8*(v)->regoff);regnr=tempnr;} \
201 else regnr=(v)->regoff; \
206 This function determines a register, to which the result of an operation
207 should go, when it is ultimatively intended to store the result in
209 If v is assigned to an actual register, this register will be returned.
210 Otherwise (when v is spilled) this function returns tempregnum.
211 If not already done, regoff and flags are set in the stack location.
214 static int reg_of_var(stackptr v, int tempregnum)
218 switch (v->varkind) {
220 if (!(v->flags & INMEMORY))
224 var = &(interfaces[v->varnum][v->type]);
225 v->regoff = var->regoff;
226 if (!(var->flags & INMEMORY))
230 var = &(locals[v->varnum][v->type]);
231 v->regoff = var->regoff;
232 if (!(var->flags & INMEMORY))
236 v->regoff = v->varnum;
237 if (IS_FLT_DBL_TYPE(v->type)) {
238 if (v->varnum < fltreg_argnum) {
239 v->regoff = argfltregs[v->varnum];
240 return(argfltregs[v->varnum]);
244 if (v->varnum < intreg_argnum) {
245 v->regoff = argintregs[v->varnum];
246 return(argintregs[v->varnum]);
248 v->regoff -= intreg_argnum;
251 v->flags |= INMEMORY;
256 /* store_reg_to_var_xxx:
257 This function generates the code to store the result of an operation
258 back into a spilled pseudo-variable.
259 If the pseudo-variable has not been spilled in the first place, this
260 function will generate nothing.
262 v ............ Pseudovariable
263 tempregnum ... Number of the temporary registers as returned by
267 #define store_reg_to_var_int(sptr, tempregnum) { \
268 if ((sptr)->flags & INMEMORY) { \
270 M_LST(tempregnum, REG_SP, 8 * (sptr)->regoff); \
274 #define store_reg_to_var_flt(sptr, tempregnum) { \
275 if ((sptr)->flags & INMEMORY) { \
277 M_DST(tempregnum, REG_SP, 8 * (sptr)->regoff); \
282 /* NullPointerException handlers and exception handling initialisation */
284 typedef struct sigctx_struct {
286 long sc_onstack; /* sigstack state to restore */
287 long sc_mask; /* signal mask to restore */
288 long sc_pc; /* pc at time of signal */
289 long sc_ps; /* psl to retore */
290 long sc_regs[32]; /* processor regs 0 to 31 */
291 long sc_ownedfp; /* fp has been used */
292 long sc_fpregs[32]; /* fp regs 0 to 31 */
293 unsigned long sc_fpcr; /* floating point control register */
294 unsigned long sc_fp_control; /* software fpcr */
296 unsigned long sc_reserved1, sc_reserved2;
297 unsigned long sc_ssize;
299 unsigned long sc_traparg_a0;
300 unsigned long sc_traparg_a1;
301 unsigned long sc_traparg_a2;
302 unsigned long sc_fp_trap_pc;
303 unsigned long sc_fp_trigger_sum;
304 unsigned long sc_fp_trigger_inst;
305 unsigned long sc_retcode[2];
309 /* NullPointerException signal handler for hardware null pointer check */
311 void catch_NullPointerException(int sig, int code, sigctx_struct *sigctx)
317 /* Reset signal handler - necessary for SysV, does no harm for BSD */
319 instr = *((int*)(sigctx->sc_pc));
320 faultaddr = sigctx->sc_regs[(instr >> 16) & 0x1f];
322 if (faultaddr == 0) {
323 signal(sig, (void*) catch_NullPointerException); /* reinstall handler */
325 sigaddset(&nsig, sig);
326 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
327 sigctx->sc_regs[REG_ITMP1_XPTR] =
328 (long) proto_java_lang_NullPointerException;
329 sigctx->sc_regs[REG_ITMP2_XPC] = sigctx->sc_pc;
330 sigctx->sc_pc = (long) asm_handle_exception;
334 faultaddr += (long) ((instr << 16) >> 16);
335 fprintf(stderr, "faulting address: 0x%16lx\n", faultaddr);
336 panic("Stack overflow");
343 void init_exceptions(void)
348 /* Linux on Digital Alpha needs an initialisation of the ieee floating point
349 control for IEEE compliant arithmetic (option -mieee of GCC). Under
350 Digital Unix this is done automatically.
355 extern unsigned long ieee_get_fp_control();
356 extern void ieee_set_fp_control(unsigned long fp_control);
358 void init_exceptions(void)
360 /* initialize floating point control */
362 ieee_set_fp_control(ieee_get_fp_control()
363 & ~IEEE_TRAP_ENABLE_INV
364 & ~IEEE_TRAP_ENABLE_DZE
365 /* & ~IEEE_TRAP_ENABLE_UNF we dont want underflow */
366 & ~IEEE_TRAP_ENABLE_OVF);
369 /* install signal handlers we need to convert to exceptions */
374 signal(SIGSEGV, (void*) catch_NullPointerException);
378 signal(SIGBUS, (void*) catch_NullPointerException);
384 /* function gen_mcode **********************************************************
386 generates machine code
388 *******************************************************************************/
390 #define MethodPointer -8
391 #define FrameSize -12
396 #define ExTableSize -32
397 #define ExTableStart -32
399 #define ExEntrySize -32
402 #define ExHandlerPC -24
403 #define ExCatchType -32
407 int len, s1, s2, s3, d;
419 savedregs_num = (isleafmethod) ? 0 : 1; /* space to save the RA */
421 /* space to save used callee saved registers */
423 savedregs_num += (savintregcnt - maxsavintreguse);
424 savedregs_num += (savfltregcnt - maxsavfltreguse);
426 parentargs_base = maxmemuse + savedregs_num;
428 #ifdef USE_THREADS /* space to save argument of monitor_enter */
430 if (checksync && (method->flags & ACC_SYNCHRONIZED))
435 /* create method header */
437 (void) dseg_addaddress(method); /* MethodPointer */
438 (void) dseg_adds4(parentargs_base * 8); /* FrameSize */
442 /* IsSync contains the offset relative to the stack pointer for the
443 argument of monitor_exit used in the exception handler. Since the
444 offset could be zero and give a wrong meaning of the flag it is
448 if (checksync && (method->flags & ACC_SYNCHRONIZED))
449 (void) dseg_adds4((maxmemuse + 1) * 8); /* IsSync */
454 (void) dseg_adds4(0); /* IsSync */
456 (void) dseg_adds4(isleafmethod); /* IsLeaf */
457 (void) dseg_adds4(savintregcnt - maxsavintreguse); /* IntSave */
458 (void) dseg_adds4(savfltregcnt - maxsavfltreguse); /* FltSave */
459 (void) dseg_adds4(exceptiontablelength); /* ExTableSize */
461 /* create exception table */
463 for (ex = extable; ex != NULL; ex = ex->down) {
466 if (ex->start != NULL)
467 printf("adding start - %d - ", ex->start->debug_nr);
469 printf("PANIC - start is NULL");
474 dseg_addtarget(ex->start);
478 printf("adding end - %d - ", ex->end->debug_nr);
480 printf("PANIC - end is NULL");
485 dseg_addtarget(ex->end);
488 if (ex->handler != NULL)
489 printf("adding handler - %d\n", ex->handler->debug_nr);
491 printf("PANIC - handler is NULL");
496 dseg_addtarget(ex->handler);
498 (void) dseg_addaddress(ex->catchtype);
501 /* initialize mcode variables */
503 mcodeptr = (s4*) mcodebase;
504 mcodeend = (s4*) (mcodebase + mcodesize);
505 MCODECHECK(128 + mparamcount);
507 /* create stack frame (if necessary) */
510 {M_LDA (REG_SP, REG_SP, -parentargs_base * 8);}
512 /* save return address and used callee saved registers */
516 {p--; M_AST (REG_RA, REG_SP, 8*p);}
517 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
518 {p--; M_LST (savintregs[r], REG_SP, 8 * p);}
519 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
520 {p--; M_DST (savfltregs[r], REG_SP, 8 * p);}
522 /* save monitorenter argument */
525 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
526 if (method->flags & ACC_STATIC) {
527 p = dseg_addaddress (class);
528 M_ALD(REG_ITMP1, REG_PV, p);
529 M_AST(REG_ITMP1, REG_SP, 8 * maxmemuse);
532 M_AST (argintregs[0], REG_SP, 8 * maxmemuse);
537 /* copy argument registers to stack and call trace function with pointer
538 to arguments on stack. ToDo: save floating point registers !!!!!!!!!
543 M_LDA (REG_SP, REG_SP, -(14*8));
544 M_AST(REG_RA, REG_SP, 1*8);
546 M_LST(argintregs[0], REG_SP, 2*8);
547 M_LST(argintregs[1], REG_SP, 3*8);
548 M_LST(argintregs[2], REG_SP, 4*8);
549 M_LST(argintregs[3], REG_SP, 5*8);
550 M_LST(argintregs[4], REG_SP, 6*8);
551 M_LST(argintregs[5], REG_SP, 7*8);
553 M_DST(argfltregs[0], REG_SP, 8*8);
554 M_DST(argfltregs[1], REG_SP, 9*8);
555 M_DST(argfltregs[2], REG_SP, 10*8);
556 M_DST(argfltregs[3], REG_SP, 11*8);
557 M_DST(argfltregs[4], REG_SP, 12*8);
558 M_DST(argfltregs[5], REG_SP, 13*8);
560 p = dseg_addaddress (method);
561 M_ALD(REG_ITMP1, REG_PV, p);
562 M_AST(REG_ITMP1, REG_SP, 0);
563 p = dseg_addaddress ((void*) (builtin_trace_args));
564 M_ALD(REG_PV, REG_PV, p);
565 M_JSR(REG_RA, REG_PV);
566 disp = -(int)((u1*) mcodeptr - mcodebase);
567 M_LDA(REG_PV, REG_RA, disp);
568 M_ALD(REG_RA, REG_SP, 1*8);
570 M_LLD(argintregs[0], REG_SP, 2*8);
571 M_LLD(argintregs[1], REG_SP, 3*8);
572 M_LLD(argintregs[2], REG_SP, 4*8);
573 M_LLD(argintregs[3], REG_SP, 5*8);
574 M_LLD(argintregs[4], REG_SP, 6*8);
575 M_LLD(argintregs[5], REG_SP, 7*8);
577 M_DLD(argfltregs[0], REG_SP, 8*8);
578 M_DLD(argfltregs[1], REG_SP, 9*8);
579 M_DLD(argfltregs[2], REG_SP, 10*8);
580 M_DLD(argfltregs[3], REG_SP, 11*8);
581 M_DLD(argfltregs[4], REG_SP, 12*8);
582 M_DLD(argfltregs[5], REG_SP, 13*8);
584 M_LDA (REG_SP, REG_SP, 14*8);
587 /* take arguments out of register or stack frame */
589 for (p = 0, l = 0; p < mparamcount; p++) {
591 var = &(locals[l][t]);
593 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
598 if (IS_INT_LNG_TYPE(t)) { /* integer args */
599 if (p < INT_ARG_CNT) { /* register arguments */
600 if (!(var->flags & INMEMORY)) /* reg arg -> register */
601 {M_INTMOVE (argintregs[p], r);}
602 else /* reg arg -> spilled */
603 M_LST (argintregs[p], REG_SP, 8 * r);
605 else { /* stack arguments */
606 pa = p - INT_ARG_CNT;
607 if (!(var->flags & INMEMORY)) /* stack arg -> register */
608 M_LLD (r, REG_SP, 8 * (parentargs_base + pa));
609 else { /* stack arg -> spilled */
610 M_LLD (REG_ITMP1, REG_SP, 8 * (parentargs_base + pa));
611 M_LST (REG_ITMP1, REG_SP, 8 * r);
615 else { /* floating args */
616 if (p < FLT_ARG_CNT) { /* register arguments */
617 if (!(var->flags & INMEMORY)) /* reg arg -> register */
618 {M_FLTMOVE (argfltregs[p], r);}
619 else /* reg arg -> spilled */
620 M_DST (argfltregs[p], REG_SP, 8 * r);
622 else { /* stack arguments */
623 pa = p - FLT_ARG_CNT;
624 if (!(var->flags & INMEMORY)) /* stack-arg -> register */
625 M_DLD (r, REG_SP, 8 * (parentargs_base + pa) );
626 else { /* stack-arg -> spilled */
627 M_DLD (REG_FTMP1, REG_SP, 8 * (parentargs_base + pa));
628 M_DST (REG_FTMP1, REG_SP, 8 * r);
634 /* call trace function */
637 if (runverbose && !isleafmethod) {
638 M_LDA (REG_SP, REG_SP, -8);
639 p = dseg_addaddress (method);
640 M_ALD(REG_ITMP1, REG_PV, p);
641 M_AST(REG_ITMP1, REG_SP, 0);
642 p = dseg_addaddress ((void*) (builtin_trace_args));
643 M_ALD(REG_PV, REG_PV, p);
644 M_JSR(REG_RA, REG_PV);
645 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
646 M_LDA(REG_SP, REG_SP, 8);
650 /* call monitorenter function */
653 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
655 p = dseg_addaddress ((void*) (builtin_monitorenter));
656 M_ALD(REG_PV, REG_PV, p);
657 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
658 M_JSR(REG_RA, REG_PV);
659 disp = -(int)((u1*) mcodeptr - mcodebase);
660 M_LDA(REG_PV, REG_RA, disp);
665 /* end of header generation */
667 /* walk through all basic blocks */
668 for (bptr = block; bptr != NULL; bptr = bptr->next) {
670 bptr->mpc = (int)((u1*) mcodeptr - mcodebase);
672 if (bptr->flags >= BBREACHED) {
674 /* branch resolving */
678 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
679 gen_resolvebranch((u1*) mcodebase + brefs->branchpos,
680 brefs->branchpos, bptr->mpc);
684 /* copy interface registers to their destination */
689 while (src != NULL) {
691 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
692 d = reg_of_var(src, REG_ITMP1);
693 M_INTMOVE(REG_ITMP1, d);
694 store_reg_to_var_int(src, d);
697 d = reg_of_var(src, REG_IFTMP);
698 if ((src->varkind != STACKVAR)) {
700 if (IS_FLT_DBL_TYPE(s2)) {
701 if (!(interfaces[len][s2].flags & INMEMORY)) {
702 s1 = interfaces[len][s2].regoff;
706 M_DLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
708 store_reg_to_var_flt(src, d);
711 if (!(interfaces[len][s2].flags & INMEMORY)) {
712 s1 = interfaces[len][s2].regoff;
716 M_LLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
718 store_reg_to_var_int(src, d);
725 /* walk through all instructions */
729 for (iptr = bptr->iinstr;
731 src = iptr->dst, len--, iptr++) {
733 MCODECHECK(64); /* an instruction usually needs < 64 words */
736 case ICMD_NOP: /* ... ==> ... */
739 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
741 var_to_reg_int(s1, src, REG_ITMP1);
743 codegen_addxnullrefs(mcodeptr);
746 /* constant operations ************************************************/
748 #define ICONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
749 else{a=dseg_adds4(c);M_ILD(r,REG_PV,a);}
751 #define LCONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
752 else{a=dseg_adds8(c);M_LLD(r,REG_PV,a);}
754 case ICMD_ICONST: /* ... ==> ..., constant */
755 /* op1 = 0, val.i = constant */
757 d = reg_of_var(iptr->dst, REG_ITMP1);
758 ICONST(d, iptr->val.i);
759 store_reg_to_var_int(iptr->dst, d);
762 case ICMD_LCONST: /* ... ==> ..., constant */
763 /* op1 = 0, val.l = constant */
765 d = reg_of_var(iptr->dst, REG_ITMP1);
766 LCONST(d, iptr->val.l);
767 store_reg_to_var_int(iptr->dst, d);
770 case ICMD_FCONST: /* ... ==> ..., constant */
771 /* op1 = 0, val.f = constant */
773 d = reg_of_var (iptr->dst, REG_FTMP1);
774 a = dseg_addfloat (iptr->val.f);
776 store_reg_to_var_flt (iptr->dst, d);
779 case ICMD_DCONST: /* ... ==> ..., constant */
780 /* op1 = 0, val.d = constant */
782 d = reg_of_var (iptr->dst, REG_FTMP1);
783 a = dseg_adddouble (iptr->val.d);
785 store_reg_to_var_flt (iptr->dst, d);
788 case ICMD_ACONST: /* ... ==> ..., constant */
789 /* op1 = 0, val.a = constant */
791 d = reg_of_var(iptr->dst, REG_ITMP1);
793 a = dseg_addaddress (iptr->val.a);
797 M_INTMOVE(REG_ZERO, d);
799 store_reg_to_var_int(iptr->dst, d);
803 /* load/store operations **********************************************/
805 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
806 case ICMD_LLOAD: /* op1 = local variable */
809 d = reg_of_var(iptr->dst, REG_ITMP1);
810 if ((iptr->dst->varkind == LOCALVAR) &&
811 (iptr->dst->varnum == iptr->op1))
813 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
814 if (var->flags & INMEMORY)
815 M_LLD(d, REG_SP, 8 * var->regoff);
817 {M_INTMOVE(var->regoff,d);}
818 store_reg_to_var_int(iptr->dst, d);
821 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
822 case ICMD_DLOAD: /* op1 = local variable */
824 d = reg_of_var(iptr->dst, REG_FTMP1);
825 if ((iptr->dst->varkind == LOCALVAR) &&
826 (iptr->dst->varnum == iptr->op1))
828 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
829 if (var->flags & INMEMORY)
830 M_DLD(d, REG_SP, 8 * var->regoff);
832 {M_FLTMOVE(var->regoff,d);}
833 store_reg_to_var_flt(iptr->dst, d);
837 case ICMD_ISTORE: /* ..., value ==> ... */
838 case ICMD_LSTORE: /* op1 = local variable */
841 if ((src->varkind == LOCALVAR) &&
842 (src->varnum == iptr->op1))
844 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
845 if (var->flags & INMEMORY) {
846 var_to_reg_int(s1, src, REG_ITMP1);
847 M_LST(s1, REG_SP, 8 * var->regoff);
850 var_to_reg_int(s1, src, var->regoff);
851 M_INTMOVE(s1, var->regoff);
855 case ICMD_FSTORE: /* ..., value ==> ... */
856 case ICMD_DSTORE: /* op1 = local variable */
858 if ((src->varkind == LOCALVAR) &&
859 (src->varnum == iptr->op1))
861 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
862 if (var->flags & INMEMORY) {
863 var_to_reg_flt(s1, src, REG_FTMP1);
864 M_DST(s1, REG_SP, 8 * var->regoff);
867 var_to_reg_flt(s1, src, var->regoff);
868 M_FLTMOVE(s1, var->regoff);
873 /* pop/dup/swap operations ********************************************/
875 /* attention: double and longs are only one entry in CACAO ICMDs */
877 case ICMD_POP: /* ..., value ==> ... */
878 case ICMD_POP2: /* ..., value, value ==> ... */
881 #define M_COPY(from,to) \
882 d = reg_of_var(to, REG_IFTMP); \
883 if ((from->regoff != to->regoff) || \
884 ((from->flags ^ to->flags) & INMEMORY)) { \
885 if (IS_FLT_DBL_TYPE(from->type)) { \
886 var_to_reg_flt(s1, from, d); \
888 store_reg_to_var_flt(to, d); \
891 var_to_reg_int(s1, from, d); \
893 store_reg_to_var_int(to, d); \
897 case ICMD_DUP: /* ..., a ==> ..., a, a */
898 M_COPY(src, iptr->dst);
901 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
903 M_COPY(src, iptr->dst->prev->prev);
905 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
907 M_COPY(src, iptr->dst);
908 M_COPY(src->prev, iptr->dst->prev);
911 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
913 M_COPY(src->prev, iptr->dst->prev->prev->prev);
915 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
917 M_COPY(src, iptr->dst);
918 M_COPY(src->prev, iptr->dst->prev);
919 M_COPY(src->prev->prev, iptr->dst->prev->prev);
920 M_COPY(src, iptr->dst->prev->prev->prev);
923 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
925 M_COPY(src, iptr->dst);
926 M_COPY(src->prev, iptr->dst->prev);
927 M_COPY(src->prev->prev, iptr->dst->prev->prev);
928 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
929 M_COPY(src, iptr->dst->prev->prev->prev->prev);
930 M_COPY(src->prev, iptr->dst->prev->prev->prev->prev->prev);
933 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
935 M_COPY(src, iptr->dst->prev);
936 M_COPY(src->prev, iptr->dst);
940 /* integer operations *************************************************/
942 case ICMD_INEG: /* ..., value ==> ..., - value */
944 var_to_reg_int(s1, src, REG_ITMP1);
945 d = reg_of_var(iptr->dst, REG_ITMP3);
946 M_ISUB(REG_ZERO, s1, d);
947 store_reg_to_var_int(iptr->dst, d);
950 case ICMD_LNEG: /* ..., value ==> ..., - value */
952 var_to_reg_int(s1, src, REG_ITMP1);
953 d = reg_of_var(iptr->dst, REG_ITMP3);
954 M_LSUB(REG_ZERO, s1, d);
955 store_reg_to_var_int(iptr->dst, d);
958 case ICMD_I2L: /* ..., value ==> ..., value */
960 var_to_reg_int(s1, src, REG_ITMP1);
961 d = reg_of_var(iptr->dst, REG_ITMP3);
963 store_reg_to_var_int(iptr->dst, d);
966 case ICMD_L2I: /* ..., value ==> ..., value */
968 var_to_reg_int(s1, src, REG_ITMP1);
969 d = reg_of_var(iptr->dst, REG_ITMP3);
970 M_IADD(s1, REG_ZERO, d );
971 store_reg_to_var_int(iptr->dst, d);
974 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
976 var_to_reg_int(s1, src, REG_ITMP1);
977 d = reg_of_var(iptr->dst, REG_ITMP3);
978 if (has_ext_instr_set) {
982 M_SLL_IMM(s1, 56, d);
983 M_SRA_IMM( d, 56, d);
985 store_reg_to_var_int(iptr->dst, d);
988 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
990 var_to_reg_int(s1, src, REG_ITMP1);
991 d = reg_of_var(iptr->dst, REG_ITMP3);
993 store_reg_to_var_int(iptr->dst, d);
996 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
998 var_to_reg_int(s1, src, REG_ITMP1);
999 d = reg_of_var(iptr->dst, REG_ITMP3);
1000 if (has_ext_instr_set) {
1004 M_SLL_IMM(s1, 48, d);
1005 M_SRA_IMM( d, 48, d);
1007 store_reg_to_var_int(iptr->dst, d);
1011 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1013 var_to_reg_int(s1, src->prev, REG_ITMP1);
1014 var_to_reg_int(s2, src, REG_ITMP2);
1015 d = reg_of_var(iptr->dst, REG_ITMP3);
1017 store_reg_to_var_int(iptr->dst, d);
1020 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
1021 /* val.i = constant */
1023 var_to_reg_int(s1, src, REG_ITMP1);
1024 d = reg_of_var(iptr->dst, REG_ITMP3);
1025 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1026 M_IADD_IMM(s1, iptr->val.i, d);
1029 ICONST(REG_ITMP2, iptr->val.i);
1030 M_IADD(s1, REG_ITMP2, d);
1032 store_reg_to_var_int(iptr->dst, d);
1035 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1037 var_to_reg_int(s1, src->prev, REG_ITMP1);
1038 var_to_reg_int(s2, src, REG_ITMP2);
1039 d = reg_of_var(iptr->dst, REG_ITMP3);
1041 store_reg_to_var_int(iptr->dst, d);
1044 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
1045 /* val.l = constant */
1047 var_to_reg_int(s1, src, REG_ITMP1);
1048 d = reg_of_var(iptr->dst, REG_ITMP3);
1049 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1050 M_LADD_IMM(s1, iptr->val.l, d);
1053 LCONST(REG_ITMP2, iptr->val.l);
1054 M_LADD(s1, REG_ITMP2, d);
1056 store_reg_to_var_int(iptr->dst, d);
1059 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1061 var_to_reg_int(s1, src->prev, REG_ITMP1);
1062 var_to_reg_int(s2, src, REG_ITMP2);
1063 d = reg_of_var(iptr->dst, REG_ITMP3);
1065 store_reg_to_var_int(iptr->dst, d);
1068 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
1069 /* val.i = constant */
1071 var_to_reg_int(s1, src, REG_ITMP1);
1072 d = reg_of_var(iptr->dst, REG_ITMP3);
1073 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1074 M_ISUB_IMM(s1, iptr->val.i, d);
1077 ICONST(REG_ITMP2, iptr->val.i);
1078 M_ISUB(s1, REG_ITMP2, d);
1080 store_reg_to_var_int(iptr->dst, d);
1083 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1085 var_to_reg_int(s1, src->prev, REG_ITMP1);
1086 var_to_reg_int(s2, src, REG_ITMP2);
1087 d = reg_of_var(iptr->dst, REG_ITMP3);
1089 store_reg_to_var_int(iptr->dst, d);
1092 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
1093 /* val.l = constant */
1095 var_to_reg_int(s1, src, REG_ITMP1);
1096 d = reg_of_var(iptr->dst, REG_ITMP3);
1097 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1098 M_LSUB_IMM(s1, iptr->val.l, d);
1101 LCONST(REG_ITMP2, iptr->val.l);
1102 M_LSUB(s1, REG_ITMP2, d);
1104 store_reg_to_var_int(iptr->dst, d);
1107 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1109 var_to_reg_int(s1, src->prev, REG_ITMP1);
1110 var_to_reg_int(s2, src, REG_ITMP2);
1111 d = reg_of_var(iptr->dst, REG_ITMP3);
1113 store_reg_to_var_int(iptr->dst, d);
1116 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
1117 /* val.i = constant */
1119 var_to_reg_int(s1, src, REG_ITMP1);
1120 d = reg_of_var(iptr->dst, REG_ITMP3);
1121 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1122 M_IMUL_IMM(s1, iptr->val.i, d);
1125 ICONST(REG_ITMP2, iptr->val.i);
1126 M_IMUL(s1, REG_ITMP2, d);
1128 store_reg_to_var_int(iptr->dst, d);
1131 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1133 var_to_reg_int(s1, src->prev, REG_ITMP1);
1134 var_to_reg_int(s2, src, REG_ITMP2);
1135 d = reg_of_var(iptr->dst, REG_ITMP3);
1137 store_reg_to_var_int(iptr->dst, d);
1140 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
1141 /* val.l = constant */
1143 var_to_reg_int(s1, src, REG_ITMP1);
1144 d = reg_of_var(iptr->dst, REG_ITMP3);
1145 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1146 M_LMUL_IMM(s1, iptr->val.l, d);
1149 LCONST(REG_ITMP2, iptr->val.l);
1150 M_LMUL(s1, REG_ITMP2, d);
1152 store_reg_to_var_int(iptr->dst, d);
1155 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
1156 case ICMD_LDIVPOW2: /* val.i = constant */
1158 var_to_reg_int(s1, src, REG_ITMP1);
1159 d = reg_of_var(iptr->dst, REG_ITMP3);
1160 if (iptr->val.i <= 15) {
1161 M_LDA(REG_ITMP2, s1, (1 << iptr->val.i) -1);
1162 M_CMOVGE(s1, s1, REG_ITMP2);
1165 M_SRA_IMM(s1, 63, REG_ITMP2);
1166 M_SRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
1167 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1169 M_SRA_IMM(REG_ITMP2, iptr->val.i, d);
1170 store_reg_to_var_int(iptr->dst, d);
1173 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1175 var_to_reg_int(s1, src->prev, REG_ITMP1);
1176 var_to_reg_int(s2, src, REG_ITMP2);
1177 d = reg_of_var(iptr->dst, REG_ITMP3);
1178 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1179 M_SLL(s1, REG_ITMP3, d);
1180 M_IADD(d, REG_ZERO, d);
1181 store_reg_to_var_int(iptr->dst, d);
1184 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1185 /* val.i = constant */
1187 var_to_reg_int(s1, src, REG_ITMP1);
1188 d = reg_of_var(iptr->dst, REG_ITMP3);
1189 M_SLL_IMM(s1, iptr->val.i & 0x1f, d);
1190 M_IADD(d, REG_ZERO, d);
1191 store_reg_to_var_int(iptr->dst, d);
1194 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1196 var_to_reg_int(s1, src->prev, REG_ITMP1);
1197 var_to_reg_int(s2, src, REG_ITMP2);
1198 d = reg_of_var(iptr->dst, REG_ITMP3);
1199 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1200 M_SRA(s1, REG_ITMP3, d);
1201 store_reg_to_var_int(iptr->dst, d);
1204 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1205 /* val.i = constant */
1207 var_to_reg_int(s1, src, REG_ITMP1);
1208 d = reg_of_var(iptr->dst, REG_ITMP3);
1209 M_SRA_IMM(s1, iptr->val.i & 0x1f, d);
1210 store_reg_to_var_int(iptr->dst, d);
1213 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1215 var_to_reg_int(s1, src->prev, REG_ITMP1);
1216 var_to_reg_int(s2, src, REG_ITMP2);
1217 d = reg_of_var(iptr->dst, REG_ITMP3);
1218 M_AND_IMM(s2, 0x1f, REG_ITMP2);
1220 M_SRL(d, REG_ITMP2, d);
1221 M_IADD(d, REG_ZERO, d);
1222 store_reg_to_var_int(iptr->dst, d);
1225 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1226 /* val.i = constant */
1228 var_to_reg_int(s1, src, REG_ITMP1);
1229 d = reg_of_var(iptr->dst, REG_ITMP3);
1231 M_SRL_IMM(d, iptr->val.i & 0x1f, d);
1232 M_IADD(d, REG_ZERO, d);
1233 store_reg_to_var_int(iptr->dst, d);
1236 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1238 var_to_reg_int(s1, src->prev, REG_ITMP1);
1239 var_to_reg_int(s2, src, REG_ITMP2);
1240 d = reg_of_var(iptr->dst, REG_ITMP3);
1242 store_reg_to_var_int(iptr->dst, d);
1245 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1246 /* val.i = constant */
1248 var_to_reg_int(s1, src, REG_ITMP1);
1249 d = reg_of_var(iptr->dst, REG_ITMP3);
1250 M_SLL_IMM(s1, iptr->val.i & 0x3f, d);
1251 store_reg_to_var_int(iptr->dst, d);
1254 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1256 var_to_reg_int(s1, src->prev, REG_ITMP1);
1257 var_to_reg_int(s2, src, REG_ITMP2);
1258 d = reg_of_var(iptr->dst, REG_ITMP3);
1260 store_reg_to_var_int(iptr->dst, d);
1263 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1264 /* val.i = constant */
1266 var_to_reg_int(s1, src, REG_ITMP1);
1267 d = reg_of_var(iptr->dst, REG_ITMP3);
1268 M_SRA_IMM(s1, iptr->val.i & 0x3f, d);
1269 store_reg_to_var_int(iptr->dst, d);
1272 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1274 var_to_reg_int(s1, src->prev, REG_ITMP1);
1275 var_to_reg_int(s2, src, REG_ITMP2);
1276 d = reg_of_var(iptr->dst, REG_ITMP3);
1278 store_reg_to_var_int(iptr->dst, d);
1281 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1282 /* val.i = constant */
1284 var_to_reg_int(s1, src, REG_ITMP1);
1285 d = reg_of_var(iptr->dst, REG_ITMP3);
1286 M_SRL_IMM(s1, iptr->val.i & 0x3f, d);
1287 store_reg_to_var_int(iptr->dst, d);
1290 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1293 var_to_reg_int(s1, src->prev, REG_ITMP1);
1294 var_to_reg_int(s2, src, REG_ITMP2);
1295 d = reg_of_var(iptr->dst, REG_ITMP3);
1297 store_reg_to_var_int(iptr->dst, d);
1300 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1301 /* val.i = constant */
1303 var_to_reg_int(s1, src, REG_ITMP1);
1304 d = reg_of_var(iptr->dst, REG_ITMP3);
1305 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1306 M_AND_IMM(s1, iptr->val.i, d);
1308 else if (iptr->val.i == 0xffff) {
1311 else if (iptr->val.i == 0xffffff) {
1312 M_ZAPNOT_IMM(s1, 0x07, d);
1315 ICONST(REG_ITMP2, iptr->val.i);
1316 M_AND(s1, REG_ITMP2, d);
1318 store_reg_to_var_int(iptr->dst, d);
1321 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1322 /* val.i = constant */
1324 var_to_reg_int(s1, src, REG_ITMP1);
1325 d = reg_of_var(iptr->dst, REG_ITMP3);
1327 M_MOV(s1, REG_ITMP1);
1330 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1331 M_AND_IMM(s1, iptr->val.i, d);
1333 M_ISUB(REG_ZERO, s1, d);
1334 M_AND_IMM(d, iptr->val.i, d);
1336 else if (iptr->val.i == 0xffff) {
1339 M_ISUB(REG_ZERO, s1, d);
1342 else if (iptr->val.i == 0xffffff) {
1343 M_ZAPNOT_IMM(s1, 0x07, d);
1345 M_ISUB(REG_ZERO, s1, d);
1346 M_ZAPNOT_IMM(d, 0x07, d);
1349 ICONST(REG_ITMP2, iptr->val.i);
1350 M_AND(s1, REG_ITMP2, d);
1352 M_ISUB(REG_ZERO, s1, d);
1353 M_AND(d, REG_ITMP2, d);
1355 M_ISUB(REG_ZERO, d, d);
1356 store_reg_to_var_int(iptr->dst, d);
1359 case ICMD_IREM0X10001: /* ..., value ==> ..., value % 0x100001 */
1361 /* b = value & 0xffff;
1363 a = ((b - a) & 0xffff) + (b < a);
1365 var_to_reg_int(s1, src, REG_ITMP1);
1366 d = reg_of_var(iptr->dst, REG_ITMP3);
1368 M_MOV(s1, REG_ITMP3);
1372 M_CZEXT(s1, REG_ITMP2);
1373 M_SRA_IMM(s1, 16, d);
1374 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1375 M_ISUB(REG_ITMP2, d, d);
1377 M_IADD(d, REG_ITMP1, d);
1378 M_BR(11 + (s1 == REG_ITMP1));
1379 M_ISUB(REG_ZERO, s1, REG_ITMP1);
1380 M_CZEXT(REG_ITMP1, REG_ITMP2);
1381 M_SRA_IMM(REG_ITMP1, 16, d);
1382 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1383 M_ISUB(REG_ITMP2, d, d);
1385 M_IADD(d, REG_ITMP1, d);
1386 M_ISUB(REG_ZERO, d, d);
1387 if (s1 == REG_ITMP1) {
1388 var_to_reg_int(s1, src, REG_ITMP1);
1390 M_SLL_IMM(s1, 33, REG_ITMP2);
1391 M_CMPEQ(REG_ITMP2, REG_ZERO, REG_ITMP2);
1392 M_ISUB(d, REG_ITMP2, d);
1393 store_reg_to_var_int(iptr->dst, d);
1396 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1397 /* val.l = constant */
1399 var_to_reg_int(s1, src, REG_ITMP1);
1400 d = reg_of_var(iptr->dst, REG_ITMP3);
1401 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1402 M_AND_IMM(s1, iptr->val.l, d);
1404 else if (iptr->val.l == 0xffffL) {
1407 else if (iptr->val.l == 0xffffffL) {
1408 M_ZAPNOT_IMM(s1, 0x07, d);
1410 else if (iptr->val.l == 0xffffffffL) {
1413 else if (iptr->val.l == 0xffffffffffL) {
1414 M_ZAPNOT_IMM(s1, 0x1f, d);
1416 else if (iptr->val.l == 0xffffffffffffL) {
1417 M_ZAPNOT_IMM(s1, 0x3f, d);
1419 else if (iptr->val.l == 0xffffffffffffffL) {
1420 M_ZAPNOT_IMM(s1, 0x7f, d);
1423 LCONST(REG_ITMP2, iptr->val.l);
1424 M_AND(s1, REG_ITMP2, d);
1426 store_reg_to_var_int(iptr->dst, d);
1429 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1430 /* val.l = constant */
1432 var_to_reg_int(s1, src, REG_ITMP1);
1433 d = reg_of_var(iptr->dst, REG_ITMP3);
1435 M_MOV(s1, REG_ITMP1);
1438 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1439 M_AND_IMM(s1, iptr->val.l, d);
1441 M_LSUB(REG_ZERO, s1, d);
1442 M_AND_IMM(d, iptr->val.l, d);
1444 else if (iptr->val.l == 0xffffL) {
1447 M_LSUB(REG_ZERO, s1, d);
1450 else if (iptr->val.l == 0xffffffL) {
1451 M_ZAPNOT_IMM(s1, 0x07, d);
1453 M_LSUB(REG_ZERO, s1, d);
1454 M_ZAPNOT_IMM(d, 0x07, d);
1456 else if (iptr->val.l == 0xffffffffL) {
1459 M_LSUB(REG_ZERO, s1, d);
1462 else if (iptr->val.l == 0xffffffffffL) {
1463 M_ZAPNOT_IMM(s1, 0x1f, d);
1465 M_LSUB(REG_ZERO, s1, d);
1466 M_ZAPNOT_IMM(d, 0x1f, d);
1468 else if (iptr->val.l == 0xffffffffffffL) {
1469 M_ZAPNOT_IMM(s1, 0x3f, d);
1471 M_LSUB(REG_ZERO, s1, d);
1472 M_ZAPNOT_IMM(d, 0x3f, d);
1474 else if (iptr->val.l == 0xffffffffffffffL) {
1475 M_ZAPNOT_IMM(s1, 0x7f, d);
1477 M_LSUB(REG_ZERO, s1, d);
1478 M_ZAPNOT_IMM(d, 0x7f, d);
1481 LCONST(REG_ITMP2, iptr->val.l);
1482 M_AND(s1, REG_ITMP2, d);
1484 M_LSUB(REG_ZERO, s1, d);
1485 M_AND(d, REG_ITMP2, d);
1487 M_LSUB(REG_ZERO, d, d);
1488 store_reg_to_var_int(iptr->dst, d);
1491 case ICMD_LREM0X10001:/* ..., value ==> ..., value % 0x10001 */
1493 var_to_reg_int(s1, src, REG_ITMP1);
1494 d = reg_of_var(iptr->dst, REG_ITMP3);
1496 M_MOV(s1, REG_ITMP3);
1499 M_CZEXT(s1, REG_ITMP2);
1500 M_SRA_IMM(s1, 16, d);
1501 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1502 M_LSUB(REG_ITMP2, d, d);
1504 M_LADD(d, REG_ITMP1, d);
1505 M_LDA(REG_ITMP2, REG_ZERO, -1);
1506 M_SRL_IMM(REG_ITMP2, 33, REG_ITMP2);
1507 if (s1 == REG_ITMP1) {
1508 var_to_reg_int(s1, src, REG_ITMP1);
1510 M_CMPULT(s1, REG_ITMP2, REG_ITMP2);
1511 M_BNEZ(REG_ITMP2, 11);
1512 M_LDA(d, REG_ZERO, -257);
1513 M_ZAPNOT_IMM(d, 0xcd, d);
1514 M_LSUB(REG_ZERO, s1, REG_ITMP2);
1515 M_CMOVGE(s1, s1, REG_ITMP2);
1516 M_UMULH(REG_ITMP2, d, REG_ITMP2);
1517 M_SRL_IMM(REG_ITMP2, 16, REG_ITMP2);
1518 M_LSUB(REG_ZERO, REG_ITMP2, d);
1519 M_CMOVGE(s1, REG_ITMP2, d);
1520 M_SLL_IMM(d, 16, REG_ITMP2);
1521 M_LADD(d, REG_ITMP2, d);
1523 store_reg_to_var_int(iptr->dst, d);
1526 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1529 var_to_reg_int(s1, src->prev, REG_ITMP1);
1530 var_to_reg_int(s2, src, REG_ITMP2);
1531 d = reg_of_var(iptr->dst, REG_ITMP3);
1533 store_reg_to_var_int(iptr->dst, d);
1536 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1537 /* val.i = constant */
1539 var_to_reg_int(s1, src, REG_ITMP1);
1540 d = reg_of_var(iptr->dst, REG_ITMP3);
1541 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1542 M_OR_IMM(s1, iptr->val.i, d);
1545 ICONST(REG_ITMP2, iptr->val.i);
1546 M_OR(s1, REG_ITMP2, d);
1548 store_reg_to_var_int(iptr->dst, d);
1551 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1552 /* val.l = constant */
1554 var_to_reg_int(s1, src, REG_ITMP1);
1555 d = reg_of_var(iptr->dst, REG_ITMP3);
1556 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1557 M_OR_IMM(s1, iptr->val.l, d);
1560 LCONST(REG_ITMP2, iptr->val.l);
1561 M_OR(s1, REG_ITMP2, d);
1563 store_reg_to_var_int(iptr->dst, d);
1566 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1569 var_to_reg_int(s1, src->prev, REG_ITMP1);
1570 var_to_reg_int(s2, src, REG_ITMP2);
1571 d = reg_of_var(iptr->dst, REG_ITMP3);
1573 store_reg_to_var_int(iptr->dst, d);
1576 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1577 /* val.i = constant */
1579 var_to_reg_int(s1, src, REG_ITMP1);
1580 d = reg_of_var(iptr->dst, REG_ITMP3);
1581 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1582 M_XOR_IMM(s1, iptr->val.i, d);
1585 ICONST(REG_ITMP2, iptr->val.i);
1586 M_XOR(s1, REG_ITMP2, d);
1588 store_reg_to_var_int(iptr->dst, d);
1591 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1592 /* val.l = constant */
1594 var_to_reg_int(s1, src, REG_ITMP1);
1595 d = reg_of_var(iptr->dst, REG_ITMP3);
1596 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1597 M_XOR_IMM(s1, iptr->val.l, d);
1600 LCONST(REG_ITMP2, iptr->val.l);
1601 M_XOR(s1, REG_ITMP2, d);
1603 store_reg_to_var_int(iptr->dst, d);
1607 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1609 var_to_reg_int(s1, src->prev, REG_ITMP1);
1610 var_to_reg_int(s2, src, REG_ITMP2);
1611 d = reg_of_var(iptr->dst, REG_ITMP3);
1612 M_CMPLT(s1, s2, REG_ITMP3);
1613 M_CMPLT(s2, s1, REG_ITMP1);
1614 M_LSUB (REG_ITMP1, REG_ITMP3, d);
1615 store_reg_to_var_int(iptr->dst, d);
1619 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1620 /* op1 = variable, val.i = constant */
1622 var = &(locals[iptr->op1][TYPE_INT]);
1623 if (var->flags & INMEMORY) {
1625 M_LLD(s1, REG_SP, 8 * var->regoff);
1629 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1630 M_IADD_IMM(s1, iptr->val.i, s1);
1632 else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1633 M_ISUB_IMM(s1, (-iptr->val.i), s1);
1636 M_LDA (s1, s1, iptr->val.i);
1637 M_IADD(s1, REG_ZERO, s1);
1639 if (var->flags & INMEMORY)
1640 M_LST(s1, REG_SP, 8 * var->regoff);
1644 /* floating operations ************************************************/
1646 case ICMD_FNEG: /* ..., value ==> ..., - value */
1648 var_to_reg_flt(s1, src, REG_FTMP1);
1649 d = reg_of_var(iptr->dst, REG_FTMP3);
1651 store_reg_to_var_flt(iptr->dst, d);
1654 case ICMD_DNEG: /* ..., value ==> ..., - value */
1656 var_to_reg_flt(s1, src, REG_FTMP1);
1657 d = reg_of_var(iptr->dst, REG_FTMP3);
1659 store_reg_to_var_flt(iptr->dst, d);
1662 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1664 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1665 var_to_reg_flt(s2, src, REG_FTMP2);
1666 d = reg_of_var(iptr->dst, REG_FTMP3);
1671 if (d == s1 || d == s2) {
1672 M_FADDS(s1, s2, REG_FTMP3);
1674 M_FMOV(REG_FTMP3, d);
1681 store_reg_to_var_flt(iptr->dst, d);
1684 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1686 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1687 var_to_reg_flt(s2, src, REG_FTMP2);
1688 d = reg_of_var(iptr->dst, REG_FTMP3);
1693 if (d == s1 || d == s2) {
1694 M_DADDS(s1, s2, REG_FTMP3);
1696 M_FMOV(REG_FTMP3, d);
1703 store_reg_to_var_flt(iptr->dst, d);
1706 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1708 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1709 var_to_reg_flt(s2, src, REG_FTMP2);
1710 d = reg_of_var(iptr->dst, REG_FTMP3);
1715 if (d == s1 || d == s2) {
1716 M_FSUBS(s1, s2, REG_FTMP3);
1718 M_FMOV(REG_FTMP3, d);
1725 store_reg_to_var_flt(iptr->dst, d);
1728 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1730 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1731 var_to_reg_flt(s2, src, REG_FTMP2);
1732 d = reg_of_var(iptr->dst, REG_FTMP3);
1737 if (d == s1 || d == s2) {
1738 M_DSUBS(s1, s2, REG_FTMP3);
1740 M_FMOV(REG_FTMP3, d);
1747 store_reg_to_var_flt(iptr->dst, d);
1750 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1752 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1753 var_to_reg_flt(s2, src, REG_FTMP2);
1754 d = reg_of_var(iptr->dst, REG_FTMP3);
1759 if (d == s1 || d == s2) {
1760 M_FMULS(s1, s2, REG_FTMP3);
1762 M_FMOV(REG_FTMP3, d);
1769 store_reg_to_var_flt(iptr->dst, d);
1772 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1774 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1775 var_to_reg_flt(s2, src, REG_FTMP2);
1776 d = reg_of_var(iptr->dst, REG_FTMP3);
1781 if (d == s1 || d == s2) {
1782 M_DMULS(s1, s2, REG_FTMP3);
1784 M_FMOV(REG_FTMP3, d);
1791 store_reg_to_var_flt(iptr->dst, d);
1794 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1796 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1797 var_to_reg_flt(s2, src, REG_FTMP2);
1798 d = reg_of_var(iptr->dst, REG_FTMP3);
1803 if (d == s1 || d == s2) {
1804 M_FDIVS(s1, s2, REG_FTMP3);
1806 M_FMOV(REG_FTMP3, d);
1813 store_reg_to_var_flt(iptr->dst, d);
1816 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1818 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1819 var_to_reg_flt(s2, src, REG_FTMP2);
1820 d = reg_of_var(iptr->dst, REG_FTMP3);
1825 if (d == s1 || d == s2) {
1826 M_DDIVS(s1, s2, REG_FTMP3);
1828 M_FMOV(REG_FTMP3, d);
1835 store_reg_to_var_flt(iptr->dst, d);
1838 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1840 var_to_reg_int(s1, src, REG_ITMP1);
1841 d = reg_of_var(iptr->dst, REG_FTMP3);
1842 a = dseg_adddouble(0.0);
1843 M_LST (s1, REG_PV, a);
1844 M_DLD (d, REG_PV, a);
1846 store_reg_to_var_flt(iptr->dst, d);
1849 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1851 var_to_reg_int(s1, src, REG_ITMP1);
1852 d = reg_of_var(iptr->dst, REG_FTMP3);
1853 a = dseg_adddouble(0.0);
1854 M_LST (s1, REG_PV, a);
1855 M_DLD (d, REG_PV, a);
1857 store_reg_to_var_flt(iptr->dst, d);
1860 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1862 var_to_reg_flt(s1, src, REG_FTMP1);
1863 d = reg_of_var(iptr->dst, REG_ITMP3);
1864 a = dseg_adddouble(0.0);
1865 M_CVTDL_C(s1, REG_FTMP2);
1866 M_CVTLI(REG_FTMP2, REG_FTMP3);
1867 M_DST (REG_FTMP3, REG_PV, a);
1868 M_ILD (d, REG_PV, a);
1869 store_reg_to_var_int(iptr->dst, d);
1872 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1874 var_to_reg_flt(s1, src, REG_FTMP1);
1875 d = reg_of_var(iptr->dst, REG_ITMP3);
1876 a = dseg_adddouble(0.0);
1877 M_CVTDL_C(s1, REG_FTMP2);
1878 M_DST (REG_FTMP2, REG_PV, a);
1879 M_LLD (d, REG_PV, a);
1880 store_reg_to_var_int(iptr->dst, d);
1883 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1885 var_to_reg_flt(s1, src, REG_FTMP1);
1886 d = reg_of_var(iptr->dst, REG_FTMP3);
1888 store_reg_to_var_flt(iptr->dst, d);
1891 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1893 var_to_reg_flt(s1, src, REG_FTMP1);
1894 d = reg_of_var(iptr->dst, REG_FTMP3);
1902 store_reg_to_var_flt(iptr->dst, d);
1905 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1907 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1908 var_to_reg_flt(s2, src, REG_FTMP2);
1909 d = reg_of_var(iptr->dst, REG_ITMP3);
1911 M_LSUB_IMM(REG_ZERO, 1, d);
1912 M_FCMPEQ(s1, s2, REG_FTMP3);
1913 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1915 M_FCMPLT(s2, s1, REG_FTMP3);
1916 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1917 M_LADD_IMM(REG_ZERO, 1, d);
1920 M_LSUB_IMM(REG_ZERO, 1, d);
1921 M_FCMPEQS(s1, s2, REG_FTMP3);
1923 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1925 M_FCMPLTS(s2, s1, REG_FTMP3);
1927 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1928 M_LADD_IMM(REG_ZERO, 1, d);
1930 store_reg_to_var_int(iptr->dst, d);
1933 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1935 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1936 var_to_reg_flt(s2, src, REG_FTMP2);
1937 d = reg_of_var(iptr->dst, REG_ITMP3);
1939 M_LADD_IMM(REG_ZERO, 1, d);
1940 M_FCMPEQ(s1, s2, REG_FTMP3);
1941 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1943 M_FCMPLT(s1, s2, REG_FTMP3);
1944 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1945 M_LSUB_IMM(REG_ZERO, 1, d);
1948 M_LADD_IMM(REG_ZERO, 1, d);
1949 M_FCMPEQS(s1, s2, REG_FTMP3);
1951 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1953 M_FCMPLTS(s1, s2, REG_FTMP3);
1955 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1956 M_LSUB_IMM(REG_ZERO, 1, d);
1958 store_reg_to_var_int(iptr->dst, d);
1962 /* memory operations **************************************************/
1964 /* #define gen_bound_check \
1966 M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\
1967 M_CMPULT(s2, REG_ITMP3, REG_ITMP3);\
1968 M_BEQZ(REG_ITMP3, 0);\
1969 codegen_addxboundrefs(mcodeptr);\
1973 #define gen_bound_check \
1974 if (checkbounds) { \
1975 M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\
1976 M_CMPULT(s2, REG_ITMP3, REG_ITMP3);\
1977 M_BEQZ(REG_ITMP3, 0);\
1978 codegen_addxboundrefs(mcodeptr); \
1981 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1983 var_to_reg_int(s1, src, REG_ITMP1);
1984 d = reg_of_var(iptr->dst, REG_ITMP3);
1985 gen_nullptr_check(s1);
1986 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1987 store_reg_to_var_int(iptr->dst, d);
1990 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1992 var_to_reg_int(s1, src->prev, REG_ITMP1);
1993 var_to_reg_int(s2, src, REG_ITMP2);
1994 d = reg_of_var(iptr->dst, REG_ITMP3);
1995 if (iptr->op1 == 0) {
1996 gen_nullptr_check(s1);
1999 M_SAADDQ(s2, s1, REG_ITMP1);
2000 M_ALD( d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
2001 store_reg_to_var_int(iptr->dst, d);
2004 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
2006 var_to_reg_int(s1, src->prev, REG_ITMP1);
2007 var_to_reg_int(s2, src, REG_ITMP2);
2008 d = reg_of_var(iptr->dst, REG_ITMP3);
2009 if (iptr->op1 == 0) {
2010 gen_nullptr_check(s1);
2013 M_S8ADDQ(s2, s1, REG_ITMP1);
2014 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
2015 store_reg_to_var_int(iptr->dst, d);
2018 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
2020 var_to_reg_int(s1, src->prev, REG_ITMP1);
2021 var_to_reg_int(s2, src, REG_ITMP2);
2022 d = reg_of_var(iptr->dst, REG_ITMP3);
2023 if (iptr->op1 == 0) {
2024 gen_nullptr_check(s1);
2028 M_S4ADDQ(s2, s1, REG_ITMP1);
2029 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
2030 store_reg_to_var_int(iptr->dst, d);
2033 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
2035 var_to_reg_int(s1, src->prev, REG_ITMP1);
2036 var_to_reg_int(s2, src, REG_ITMP2);
2037 d = reg_of_var(iptr->dst, REG_FTMP3);
2038 if (iptr->op1 == 0) {
2039 gen_nullptr_check(s1);
2042 M_S4ADDQ(s2, s1, REG_ITMP1);
2043 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
2044 store_reg_to_var_flt(iptr->dst, d);
2047 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
2049 var_to_reg_int(s1, src->prev, REG_ITMP1);
2050 var_to_reg_int(s2, src, REG_ITMP2);
2051 d = reg_of_var(iptr->dst, REG_FTMP3);
2052 if (iptr->op1 == 0) {
2053 gen_nullptr_check(s1);
2056 M_S8ADDQ(s2, s1, REG_ITMP1);
2057 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
2058 store_reg_to_var_flt(iptr->dst, d);
2061 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
2063 var_to_reg_int(s1, src->prev, REG_ITMP1);
2064 var_to_reg_int(s2, src, REG_ITMP2);
2065 d = reg_of_var(iptr->dst, REG_ITMP3);
2066 if (iptr->op1 == 0) {
2067 gen_nullptr_check(s1);
2070 if (has_ext_instr_set) {
2071 M_LADD(s2, s1, REG_ITMP1);
2072 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2073 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
2076 M_LADD (s2, s1, REG_ITMP1);
2077 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2078 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2079 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2080 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
2082 store_reg_to_var_int(iptr->dst, d);
2085 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
2087 var_to_reg_int(s1, src->prev, REG_ITMP1);
2088 var_to_reg_int(s2, src, REG_ITMP2);
2089 d = reg_of_var(iptr->dst, REG_ITMP3);
2090 if (iptr->op1 == 0) {
2091 gen_nullptr_check(s1);
2094 if (has_ext_instr_set) {
2095 M_LADD(s2, s1, REG_ITMP1);
2096 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2097 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
2101 M_LADD(s2, s1, REG_ITMP1);
2102 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2103 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2104 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
2105 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
2106 M_SRA_IMM(d, 48, d);
2108 store_reg_to_var_int(iptr->dst, d);
2111 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
2113 var_to_reg_int(s1, src->prev, REG_ITMP1);
2114 var_to_reg_int(s2, src, REG_ITMP2);
2115 d = reg_of_var(iptr->dst, REG_ITMP3);
2116 if (iptr->op1 == 0) {
2117 gen_nullptr_check(s1);
2120 if (has_ext_instr_set) {
2121 M_LADD (s2, s1, REG_ITMP1);
2122 M_BLDU (d, REG_ITMP1, OFFSET (java_bytearray, data[0]));
2126 M_LADD(s2, s1, REG_ITMP1);
2127 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2128 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
2129 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
2130 M_SRA_IMM(d, 56, d);
2132 store_reg_to_var_int(iptr->dst, d);
2136 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
2138 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2139 var_to_reg_int(s2, src->prev, REG_ITMP2);
2140 if (iptr->op1 == 0) {
2141 gen_nullptr_check(s1);
2144 var_to_reg_int(s3, src, REG_ITMP3);
2145 M_SAADDQ(s2, s1, REG_ITMP1);
2146 M_AST (s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
2149 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
2151 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2152 var_to_reg_int(s2, src->prev, REG_ITMP2);
2153 if (iptr->op1 == 0) {
2154 gen_nullptr_check(s1);
2157 var_to_reg_int(s3, src, REG_ITMP3);
2158 M_S8ADDQ(s2, s1, REG_ITMP1);
2159 M_LST (s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
2162 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
2164 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2165 var_to_reg_int(s2, src->prev, REG_ITMP2);
2166 if (iptr->op1 == 0) {
2167 gen_nullptr_check(s1);
2171 var_to_reg_int(s3, src, REG_ITMP3);
2172 M_S4ADDQ(s2, s1, REG_ITMP1);
2173 M_IST (s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
2176 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
2178 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2179 var_to_reg_int(s2, src->prev, REG_ITMP2);
2180 if (iptr->op1 == 0) {
2181 gen_nullptr_check(s1);
2184 var_to_reg_flt(s3, src, REG_FTMP3);
2185 M_S4ADDQ(s2, s1, REG_ITMP1);
2186 M_FST (s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
2189 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
2191 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2192 var_to_reg_int(s2, src->prev, REG_ITMP2);
2193 if (iptr->op1 == 0) {
2194 gen_nullptr_check(s1);
2197 var_to_reg_flt(s3, src, REG_FTMP3);
2198 M_S8ADDQ(s2, s1, REG_ITMP1);
2199 M_DST (s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
2202 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
2204 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2205 var_to_reg_int(s2, src->prev, REG_ITMP2);
2206 if (iptr->op1 == 0) {
2207 gen_nullptr_check(s1);
2210 var_to_reg_int(s3, src, REG_ITMP3);
2211 if (has_ext_instr_set) {
2212 M_LADD(s2, s1, REG_ITMP1);
2213 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2214 M_SST (s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
2217 M_LADD (s2, s1, REG_ITMP1);
2218 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2219 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2220 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2221 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
2222 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2223 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2224 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2228 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
2230 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2231 var_to_reg_int(s2, src->prev, REG_ITMP2);
2232 if (iptr->op1 == 0) {
2233 gen_nullptr_check(s1);
2236 var_to_reg_int(s3, src, REG_ITMP3);
2237 if (has_ext_instr_set) {
2238 M_LADD(s2, s1, REG_ITMP1);
2239 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2240 M_SST (s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2243 M_LADD (s2, s1, REG_ITMP1);
2244 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2245 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2246 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2247 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
2248 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2249 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2250 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2254 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
2256 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2257 var_to_reg_int(s2, src->prev, REG_ITMP2);
2258 if (iptr->op1 == 0) {
2259 gen_nullptr_check(s1);
2262 var_to_reg_int(s3, src, REG_ITMP3);
2263 if (has_ext_instr_set) {
2264 M_LADD(s2, s1, REG_ITMP1);
2265 M_BST (s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2268 M_LADD (s2, s1, REG_ITMP1);
2269 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2270 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2271 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
2272 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2273 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2274 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2279 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2280 /* op1 = type, val.a = field address */
2282 /* if class isn't yet initialized, do it */
2283 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
2284 /* call helper function which patches this code */
2285 a = dseg_addaddress(((fieldinfo *) iptr->val.a)->class);
2286 M_ALD(REG_ITMP1, REG_PV, a);
2287 a = dseg_addaddress(asm_check_clinit);
2288 M_ALD(REG_PV, REG_PV, a);
2289 M_JSR(REG_RA, REG_PV);
2292 s1 = (int) ((u1*) mcodeptr - mcodebase);
2293 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
2295 s4 ml = -s1, mh = 0;
2296 while (ml < -32768) { ml += 65536; mh--; }
2297 M_LDA(REG_PV, REG_RA, ml);
2298 M_LDAH(REG_PV, REG_PV, mh);
2302 a = dseg_addaddress(&(((fieldinfo *)(iptr->val.a))->value));
2303 M_ALD(REG_ITMP1, REG_PV, a);
2304 switch (iptr->op1) {
2306 var_to_reg_int(s2, src, REG_ITMP2);
2307 M_IST(s2, REG_ITMP1, 0);
2310 var_to_reg_int(s2, src, REG_ITMP2);
2311 M_LST(s2, REG_ITMP1, 0);
2314 var_to_reg_int(s2, src, REG_ITMP2);
2315 M_AST(s2, REG_ITMP1, 0);
2318 var_to_reg_flt(s2, src, REG_FTMP2);
2319 M_FST(s2, REG_ITMP1, 0);
2322 var_to_reg_flt(s2, src, REG_FTMP2);
2323 M_DST(s2, REG_ITMP1, 0);
2325 default: panic ("internal error");
2329 case ICMD_GETSTATIC: /* ... ==> ..., value */
2330 /* op1 = type, val.a = field address */
2332 /* if class isn't yet initialized, do it */
2333 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
2334 /* call helper function which patches this code */
2335 a = dseg_addaddress(((fieldinfo *) iptr->val.a)->class);
2336 M_ALD(REG_ITMP1, REG_PV, a);
2337 a = dseg_addaddress(asm_check_clinit);
2338 M_ALD(REG_PV, REG_PV, a);
2339 M_JSR(REG_RA, REG_PV);
2342 s1 = (int) ((u1*) mcodeptr - mcodebase);
2343 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
2345 s4 ml = -s1, mh = 0;
2346 while (ml < -32768) { ml += 65536; mh--; }
2347 M_LDA(REG_PV, REG_RA, ml);
2348 M_LDAH(REG_PV, REG_PV, mh);
2352 a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value));
2353 M_ALD(REG_ITMP1, REG_PV, a);
2354 switch (iptr->op1) {
2356 d = reg_of_var(iptr->dst, REG_ITMP3);
2357 M_ILD(d, REG_ITMP1, 0);
2358 store_reg_to_var_int(iptr->dst, d);
2361 d = reg_of_var(iptr->dst, REG_ITMP3);
2362 M_LLD(d, REG_ITMP1, 0);
2363 store_reg_to_var_int(iptr->dst, d);
2366 d = reg_of_var(iptr->dst, REG_ITMP3);
2367 M_ALD(d, REG_ITMP1, 0);
2368 store_reg_to_var_int(iptr->dst, d);
2371 d = reg_of_var(iptr->dst, REG_FTMP1);
2372 M_FLD(d, REG_ITMP1, 0);
2373 store_reg_to_var_flt(iptr->dst, d);
2376 d = reg_of_var(iptr->dst, REG_FTMP1);
2377 M_DLD(d, REG_ITMP1, 0);
2378 store_reg_to_var_flt(iptr->dst, d);
2380 default: panic ("internal error");
2385 case ICMD_PUTFIELD: /* ..., value ==> ... */
2386 /* op1 = type, val.i = field offset */
2388 a = ((fieldinfo *)(iptr->val.a))->offset;
2389 switch (iptr->op1) {
2391 var_to_reg_int(s1, src->prev, REG_ITMP1);
2392 var_to_reg_int(s2, src, REG_ITMP2);
2393 gen_nullptr_check(s1);
2397 var_to_reg_int(s1, src->prev, REG_ITMP1);
2398 var_to_reg_int(s2, src, REG_ITMP2);
2399 gen_nullptr_check(s1);
2403 var_to_reg_int(s1, src->prev, REG_ITMP1);
2404 var_to_reg_int(s2, src, REG_ITMP2);
2405 gen_nullptr_check(s1);
2409 var_to_reg_int(s1, src->prev, REG_ITMP1);
2410 var_to_reg_flt(s2, src, REG_FTMP2);
2411 gen_nullptr_check(s1);
2415 var_to_reg_int(s1, src->prev, REG_ITMP1);
2416 var_to_reg_flt(s2, src, REG_FTMP2);
2417 gen_nullptr_check(s1);
2420 default: panic ("internal error");
2424 case ICMD_GETFIELD: /* ... ==> ..., value */
2425 /* op1 = type, val.i = field offset */
2427 a = ((fieldinfo *)(iptr->val.a))->offset;
2428 switch (iptr->op1) {
2430 var_to_reg_int(s1, src, REG_ITMP1);
2431 d = reg_of_var(iptr->dst, REG_ITMP3);
2432 gen_nullptr_check(s1);
2434 store_reg_to_var_int(iptr->dst, d);
2437 var_to_reg_int(s1, src, REG_ITMP1);
2438 d = reg_of_var(iptr->dst, REG_ITMP3);
2439 gen_nullptr_check(s1);
2441 store_reg_to_var_int(iptr->dst, d);
2444 var_to_reg_int(s1, src, REG_ITMP1);
2445 d = reg_of_var(iptr->dst, REG_ITMP3);
2446 gen_nullptr_check(s1);
2448 store_reg_to_var_int(iptr->dst, d);
2451 var_to_reg_int(s1, src, REG_ITMP1);
2452 d = reg_of_var(iptr->dst, REG_FTMP1);
2453 gen_nullptr_check(s1);
2455 store_reg_to_var_flt(iptr->dst, d);
2458 var_to_reg_int(s1, src, REG_ITMP1);
2459 d = reg_of_var(iptr->dst, REG_FTMP1);
2460 gen_nullptr_check(s1);
2462 store_reg_to_var_flt(iptr->dst, d);
2464 default: panic ("internal error");
2469 /* branch operations **************************************************/
2471 #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}}
2473 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2475 var_to_reg_int(s1, src, REG_ITMP1);
2476 M_INTMOVE(s1, REG_ITMP1_XPTR);
2477 a = dseg_addaddress(asm_handle_exception);
2478 M_ALD(REG_ITMP2, REG_PV, a);
2479 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2480 M_NOP; /* nop ensures that XPC is less than the end */
2481 /* of basic block */
2485 case ICMD_GOTO: /* ... ==> ... */
2486 /* op1 = target JavaVM pc */
2488 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2492 case ICMD_JSR: /* ... ==> ... */
2493 /* op1 = target JavaVM pc */
2495 M_BSR(REG_ITMP1, 0);
2496 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2499 case ICMD_RET: /* ... ==> ... */
2500 /* op1 = local variable */
2502 var = &(locals[iptr->op1][TYPE_ADR]);
2503 if (var->flags & INMEMORY) {
2504 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2505 M_RET(REG_ZERO, REG_ITMP1);
2508 M_RET(REG_ZERO, var->regoff);
2512 case ICMD_IFNULL: /* ..., value ==> ... */
2513 /* op1 = target JavaVM pc */
2515 var_to_reg_int(s1, src, REG_ITMP1);
2517 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2520 case ICMD_IFNONNULL: /* ..., value ==> ... */
2521 /* op1 = target JavaVM pc */
2523 var_to_reg_int(s1, src, REG_ITMP1);
2525 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2528 case ICMD_IFEQ: /* ..., value ==> ... */
2529 /* op1 = target JavaVM pc, val.i = constant */
2531 var_to_reg_int(s1, src, REG_ITMP1);
2532 if (iptr->val.i == 0) {
2536 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2537 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2540 ICONST(REG_ITMP2, iptr->val.i);
2541 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2543 M_BNEZ(REG_ITMP1, 0);
2545 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2548 case ICMD_IFLT: /* ..., value ==> ... */
2549 /* op1 = target JavaVM pc, val.i = constant */
2551 var_to_reg_int(s1, src, REG_ITMP1);
2552 if (iptr->val.i == 0) {
2556 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2557 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2560 ICONST(REG_ITMP2, iptr->val.i);
2561 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2563 M_BNEZ(REG_ITMP1, 0);
2565 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2568 case ICMD_IFLE: /* ..., value ==> ... */
2569 /* op1 = target JavaVM pc, val.i = constant */
2571 var_to_reg_int(s1, src, REG_ITMP1);
2572 if (iptr->val.i == 0) {
2576 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2577 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2580 ICONST(REG_ITMP2, iptr->val.i);
2581 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2583 M_BNEZ(REG_ITMP1, 0);
2585 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2588 case ICMD_IFNE: /* ..., value ==> ... */
2589 /* op1 = target JavaVM pc, val.i = constant */
2591 var_to_reg_int(s1, src, REG_ITMP1);
2592 if (iptr->val.i == 0) {
2596 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2597 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2600 ICONST(REG_ITMP2, iptr->val.i);
2601 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2603 M_BEQZ(REG_ITMP1, 0);
2605 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2608 case ICMD_IFGT: /* ..., value ==> ... */
2609 /* op1 = target JavaVM pc, val.i = constant */
2611 var_to_reg_int(s1, src, REG_ITMP1);
2612 if (iptr->val.i == 0) {
2616 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2617 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2620 ICONST(REG_ITMP2, iptr->val.i);
2621 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2623 M_BEQZ(REG_ITMP1, 0);
2625 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2628 case ICMD_IFGE: /* ..., value ==> ... */
2629 /* op1 = target JavaVM pc, val.i = constant */
2631 var_to_reg_int(s1, src, REG_ITMP1);
2632 if (iptr->val.i == 0) {
2636 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2637 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2640 ICONST(REG_ITMP2, iptr->val.i);
2641 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2643 M_BEQZ(REG_ITMP1, 0);
2645 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2648 case ICMD_IF_LEQ: /* ..., value ==> ... */
2649 /* op1 = target JavaVM pc, val.l = constant */
2651 var_to_reg_int(s1, src, REG_ITMP1);
2652 if (iptr->val.l == 0) {
2656 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2657 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2660 LCONST(REG_ITMP2, iptr->val.l);
2661 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2663 M_BNEZ(REG_ITMP1, 0);
2665 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2668 case ICMD_IF_LLT: /* ..., value ==> ... */
2669 /* op1 = target JavaVM pc, val.l = constant */
2671 var_to_reg_int(s1, src, REG_ITMP1);
2672 if (iptr->val.l == 0) {
2676 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2677 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2680 LCONST(REG_ITMP2, iptr->val.l);
2681 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2683 M_BNEZ(REG_ITMP1, 0);
2685 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2688 case ICMD_IF_LLE: /* ..., value ==> ... */
2689 /* op1 = target JavaVM pc, val.l = constant */
2691 var_to_reg_int(s1, src, REG_ITMP1);
2692 if (iptr->val.l == 0) {
2696 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2697 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2700 LCONST(REG_ITMP2, iptr->val.l);
2701 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2703 M_BNEZ(REG_ITMP1, 0);
2705 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2708 case ICMD_IF_LNE: /* ..., value ==> ... */
2709 /* op1 = target JavaVM pc, val.l = constant */
2711 var_to_reg_int(s1, src, REG_ITMP1);
2712 if (iptr->val.l == 0) {
2716 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2717 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2720 LCONST(REG_ITMP2, iptr->val.l);
2721 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2723 M_BEQZ(REG_ITMP1, 0);
2725 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2728 case ICMD_IF_LGT: /* ..., value ==> ... */
2729 /* op1 = target JavaVM pc, val.l = constant */
2731 var_to_reg_int(s1, src, REG_ITMP1);
2732 if (iptr->val.l == 0) {
2736 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2737 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2740 LCONST(REG_ITMP2, iptr->val.l);
2741 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2743 M_BEQZ(REG_ITMP1, 0);
2745 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2748 case ICMD_IF_LGE: /* ..., value ==> ... */
2749 /* op1 = target JavaVM pc, val.l = constant */
2751 var_to_reg_int(s1, src, REG_ITMP1);
2752 if (iptr->val.l == 0) {
2756 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2757 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2760 LCONST(REG_ITMP2, iptr->val.l);
2761 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2763 M_BEQZ(REG_ITMP1, 0);
2765 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2768 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2769 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2770 case ICMD_IF_ACMPEQ:
2772 var_to_reg_int(s1, src->prev, REG_ITMP1);
2773 var_to_reg_int(s2, src, REG_ITMP2);
2774 M_CMPEQ(s1, s2, REG_ITMP1);
2775 M_BNEZ(REG_ITMP1, 0);
2776 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2779 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2780 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2781 case ICMD_IF_ACMPNE:
2783 var_to_reg_int(s1, src->prev, REG_ITMP1);
2784 var_to_reg_int(s2, src, REG_ITMP2);
2785 M_CMPEQ(s1, s2, REG_ITMP1);
2786 M_BEQZ(REG_ITMP1, 0);
2787 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2790 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2791 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2793 var_to_reg_int(s1, src->prev, REG_ITMP1);
2794 var_to_reg_int(s2, src, REG_ITMP2);
2795 M_CMPLT(s1, s2, REG_ITMP1);
2796 M_BNEZ(REG_ITMP1, 0);
2797 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2800 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2801 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2803 var_to_reg_int(s1, src->prev, REG_ITMP1);
2804 var_to_reg_int(s2, src, REG_ITMP2);
2805 M_CMPLE(s1, s2, REG_ITMP1);
2806 M_BEQZ(REG_ITMP1, 0);
2807 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2810 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2811 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2813 var_to_reg_int(s1, src->prev, REG_ITMP1);
2814 var_to_reg_int(s2, src, REG_ITMP2);
2815 M_CMPLE(s1, s2, REG_ITMP1);
2816 M_BNEZ(REG_ITMP1, 0);
2817 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2820 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2821 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2823 var_to_reg_int(s1, src->prev, REG_ITMP1);
2824 var_to_reg_int(s2, src, REG_ITMP2);
2825 M_CMPLT(s1, s2, REG_ITMP1);
2826 M_BEQZ(REG_ITMP1, 0);
2827 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2830 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2832 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2835 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2836 /* val.i = constant */
2838 var_to_reg_int(s1, src, REG_ITMP1);
2839 d = reg_of_var(iptr->dst, REG_ITMP3);
2841 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2842 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2843 M_CMPEQ(s1, REG_ZERO, d);
2844 store_reg_to_var_int(iptr->dst, d);
2847 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2848 M_CMPEQ(s1, REG_ZERO, d);
2850 store_reg_to_var_int(iptr->dst, d);
2854 M_MOV(s1, REG_ITMP1);
2857 ICONST(d, iptr[1].val.i);
2859 if ((s3 >= 0) && (s3 <= 255)) {
2860 M_CMOVEQ_IMM(s1, s3, d);
2863 ICONST(REG_ITMP2, s3);
2864 M_CMOVEQ(s1, REG_ITMP2, d);
2866 store_reg_to_var_int(iptr->dst, d);
2869 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2870 /* val.i = constant */
2872 var_to_reg_int(s1, src, REG_ITMP1);
2873 d = reg_of_var(iptr->dst, REG_ITMP3);
2875 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2876 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2877 M_CMPEQ(s1, REG_ZERO, d);
2878 store_reg_to_var_int(iptr->dst, d);
2881 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2882 M_CMPEQ(s1, REG_ZERO, d);
2884 store_reg_to_var_int(iptr->dst, d);
2888 M_MOV(s1, REG_ITMP1);
2891 ICONST(d, iptr[1].val.i);
2893 if ((s3 >= 0) && (s3 <= 255)) {
2894 M_CMOVNE_IMM(s1, s3, d);
2897 ICONST(REG_ITMP2, s3);
2898 M_CMOVNE(s1, REG_ITMP2, d);
2900 store_reg_to_var_int(iptr->dst, d);
2903 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2904 /* val.i = constant */
2906 var_to_reg_int(s1, src, REG_ITMP1);
2907 d = reg_of_var(iptr->dst, REG_ITMP3);
2909 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2910 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2911 M_CMPLT(s1, REG_ZERO, d);
2912 store_reg_to_var_int(iptr->dst, d);
2915 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2916 M_CMPLE(REG_ZERO, s1, d);
2917 store_reg_to_var_int(iptr->dst, d);
2921 M_MOV(s1, REG_ITMP1);
2924 ICONST(d, iptr[1].val.i);
2926 if ((s3 >= 0) && (s3 <= 255)) {
2927 M_CMOVLT_IMM(s1, s3, d);
2930 ICONST(REG_ITMP2, s3);
2931 M_CMOVLT(s1, REG_ITMP2, d);
2933 store_reg_to_var_int(iptr->dst, d);
2936 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2937 /* val.i = constant */
2939 var_to_reg_int(s1, src, REG_ITMP1);
2940 d = reg_of_var(iptr->dst, REG_ITMP3);
2942 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2943 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2944 M_CMPLE(REG_ZERO, s1, d);
2945 store_reg_to_var_int(iptr->dst, d);
2948 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2949 M_CMPLT(s1, REG_ZERO, d);
2950 store_reg_to_var_int(iptr->dst, d);
2954 M_MOV(s1, REG_ITMP1);
2957 ICONST(d, iptr[1].val.i);
2959 if ((s3 >= 0) && (s3 <= 255)) {
2960 M_CMOVGE_IMM(s1, s3, d);
2963 ICONST(REG_ITMP2, s3);
2964 M_CMOVGE(s1, REG_ITMP2, d);
2966 store_reg_to_var_int(iptr->dst, d);
2969 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2970 /* val.i = constant */
2972 var_to_reg_int(s1, src, REG_ITMP1);
2973 d = reg_of_var(iptr->dst, REG_ITMP3);
2975 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2976 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2977 M_CMPLT(REG_ZERO, s1, d);
2978 store_reg_to_var_int(iptr->dst, d);
2981 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2982 M_CMPLE(s1, REG_ZERO, d);
2983 store_reg_to_var_int(iptr->dst, d);
2987 M_MOV(s1, REG_ITMP1);
2990 ICONST(d, iptr[1].val.i);
2992 if ((s3 >= 0) && (s3 <= 255)) {
2993 M_CMOVGT_IMM(s1, s3, d);
2996 ICONST(REG_ITMP2, s3);
2997 M_CMOVGT(s1, REG_ITMP2, d);
2999 store_reg_to_var_int(iptr->dst, d);
3002 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
3003 /* val.i = constant */
3005 var_to_reg_int(s1, src, REG_ITMP1);
3006 d = reg_of_var(iptr->dst, REG_ITMP3);
3008 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
3009 if ((s3 == 1) && (iptr[1].val.i == 0)) {
3010 M_CMPLE(s1, REG_ZERO, d);
3011 store_reg_to_var_int(iptr->dst, d);
3014 if ((s3 == 0) && (iptr[1].val.i == 1)) {
3015 M_CMPLT(REG_ZERO, s1, d);
3016 store_reg_to_var_int(iptr->dst, d);
3020 M_MOV(s1, REG_ITMP1);
3023 ICONST(d, iptr[1].val.i);
3025 if ((s3 >= 0) && (s3 <= 255)) {
3026 M_CMOVLE_IMM(s1, s3, d);
3029 ICONST(REG_ITMP2, s3);
3030 M_CMOVLE(s1, REG_ITMP2, d);
3032 store_reg_to_var_int(iptr->dst, d);
3036 case ICMD_IRETURN: /* ..., retvalue ==> ... */
3041 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3043 a = dseg_addaddress ((void*) (builtin_monitorexit));
3044 M_ALD(REG_PV, REG_PV, a);
3045 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
3046 M_JSR(REG_RA, REG_PV);
3047 disp = -(int)((u1*) mcodeptr - mcodebase);
3048 M_LDA(REG_PV, REG_RA, disp);
3051 var_to_reg_int(s1, src, REG_RESULT);
3052 M_INTMOVE(s1, REG_RESULT);
3053 goto nowperformreturn;
3055 case ICMD_FRETURN: /* ..., retvalue ==> ... */
3059 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3061 a = dseg_addaddress ((void*) (builtin_monitorexit));
3062 M_ALD(REG_PV, REG_PV, a);
3063 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
3064 M_JSR(REG_RA, REG_PV);
3065 disp = -(int)((u1*) mcodeptr - mcodebase);
3066 M_LDA(REG_PV, REG_RA, disp);
3069 var_to_reg_flt(s1, src, REG_FRESULT);
3070 M_FLTMOVE(s1, REG_FRESULT);
3071 goto nowperformreturn;
3073 case ICMD_RETURN: /* ... ==> ... */
3076 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3078 a = dseg_addaddress ((void*) (builtin_monitorexit));
3079 M_ALD(REG_PV, REG_PV, a);
3080 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
3081 M_JSR(REG_RA, REG_PV);
3082 disp = -(int)((u1*) mcodeptr - mcodebase);
3083 M_LDA(REG_PV, REG_RA, disp);
3091 p = parentargs_base;
3093 /* restore return address */
3096 {p--; M_LLD (REG_RA, REG_SP, 8 * p);}
3098 /* restore saved registers */
3100 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
3101 {p--; M_LLD(savintregs[r], REG_SP, 8 * p);}
3102 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
3103 {p--; M_DLD(savfltregs[r], REG_SP, 8 * p);}
3105 /* deallocate stack */
3107 if (parentargs_base)
3108 {M_LDA(REG_SP, REG_SP, parentargs_base*8);}
3110 /* call trace function */
3113 M_LDA (REG_SP, REG_SP, -24);
3114 M_AST(REG_RA, REG_SP, 0);
3115 M_LST(REG_RESULT, REG_SP, 8);
3116 M_DST(REG_FRESULT, REG_SP,16);
3117 a = dseg_addaddress (method);
3118 M_ALD(argintregs[0], REG_PV, a);
3119 M_MOV(REG_RESULT, argintregs[1]);
3120 M_FLTMOVE(REG_FRESULT, argfltregs[2]);
3121 M_FLTMOVE(REG_FRESULT, argfltregs[3]);
3122 a = dseg_addaddress ((void*) (builtin_displaymethodstop));
3123 M_ALD(REG_PV, REG_PV, a);
3124 M_JSR (REG_RA, REG_PV);
3125 s1 = (int)((u1*) mcodeptr - mcodebase);
3126 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
3129 while (ml<-32768) { ml+=65536; mh--; }
3130 M_LDA (REG_PV, REG_RA, ml );
3131 M_LDAH (REG_PV, REG_PV, mh );
3133 M_DLD(REG_FRESULT, REG_SP,16);
3134 M_LLD(REG_RESULT, REG_SP, 8);
3135 M_ALD(REG_RA, REG_SP, 0);
3136 M_LDA (REG_SP, REG_SP, 24);
3139 M_RET(REG_ZERO, REG_RA);
3145 case ICMD_TABLESWITCH: /* ..., index ==> ... */
3150 tptr = (void **) iptr->target;
3152 s4ptr = iptr->val.a;
3153 l = s4ptr[1]; /* low */
3154 i = s4ptr[2]; /* high */
3156 var_to_reg_int(s1, src, REG_ITMP1);
3158 {M_INTMOVE(s1, REG_ITMP1);}
3159 else if (l <= 32768) {
3160 M_LDA(REG_ITMP1, s1, -l);
3163 ICONST(REG_ITMP2, l);
3164 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
3171 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
3173 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
3174 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3176 M_BEQZ(REG_ITMP2, 0);
3179 /* codegen_addreference(BlockPtrOfPC(s4ptr[0]), mcodeptr); */
3180 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3182 /* build jump table top down and use address of lowest entry */
3184 /* s4ptr += 3 + i; */
3188 /* dseg_addtarget(BlockPtrOfPC(*--s4ptr)); */
3189 dseg_addtarget((basicblock *) tptr[0]);
3194 /* length of dataseg after last dseg_addtarget is used by load */
3196 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
3197 M_ALD(REG_ITMP2, REG_ITMP2, -dseglen);
3198 M_JMP(REG_ZERO, REG_ITMP2);
3203 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3205 s4 i, l, val, *s4ptr;
3208 tptr = (void **) iptr->target;
3210 s4ptr = iptr->val.a;
3211 l = s4ptr[0]; /* default */
3212 i = s4ptr[1]; /* count */
3214 MCODECHECK((i<<2)+8);
3215 var_to_reg_int(s1, src, REG_ITMP1);
3221 if ((val >= 0) && (val <= 255)) {
3222 M_CMPEQ_IMM(s1, val, REG_ITMP2);
3225 if ((val >= -32768) && (val <= 32767)) {
3226 M_LDA(REG_ITMP2, REG_ZERO, val);
3229 a = dseg_adds4 (val);
3230 M_ILD(REG_ITMP2, REG_PV, a);
3232 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
3234 M_BNEZ(REG_ITMP2, 0);
3235 /* codegen_addreference(BlockPtrOfPC(s4ptr[1]), mcodeptr); */
3236 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3240 /* codegen_addreference(BlockPtrOfPC(l), mcodeptr); */
3242 tptr = (void **) iptr->target;
3243 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3250 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
3251 /* op1 = return type, val.a = function pointer*/
3255 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
3256 /* op1 = return type, val.a = function pointer*/
3260 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
3261 /* op1 = return type, val.a = function pointer*/
3265 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3266 /* op1 = arg count, val.a = method pointer */
3268 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3269 /* op1 = arg count, val.a = method pointer */
3271 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3272 /* op1 = arg count, val.a = method pointer */
3274 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
3275 /* op1 = arg count, val.a = method pointer */
3283 MCODECHECK((s3 << 1) + 64);
3285 /* copy arguments to registers or stack location */
3287 for (; --s3 >= 0; src = src->prev) {
3288 if (src->varkind == ARGVAR)
3290 if (IS_INT_LNG_TYPE(src->type)) {
3291 if (s3 < INT_ARG_CNT) {
3292 s1 = argintregs[s3];
3293 var_to_reg_int(d, src, s1);
3297 var_to_reg_int(d, src, REG_ITMP1);
3298 M_LST(d, REG_SP, 8 * (s3 - INT_ARG_CNT));
3302 if (s3 < FLT_ARG_CNT) {
3303 s1 = argfltregs[s3];
3304 var_to_reg_flt(d, src, s1);
3308 var_to_reg_flt(d, src, REG_FTMP1);
3309 M_DST(d, REG_SP, 8 * (s3 - FLT_ARG_CNT));
3314 switch (iptr->opc) {
3318 a = dseg_addaddress ((void*) (m));
3320 M_ALD(REG_PV, REG_PV, a); /* Pointer to built-in-function */
3322 goto makeactualcall;
3324 case ICMD_INVOKESTATIC:
3325 case ICMD_INVOKESPECIAL:
3326 a = dseg_addaddress (m->stubroutine);
3328 M_ALD(REG_PV, REG_PV, a ); /* method pointer in r27 */
3331 goto makeactualcall;
3333 case ICMD_INVOKEVIRTUAL:
3335 gen_nullptr_check(argintregs[0]);
3336 M_ALD(REG_METHODPTR, argintregs[0],
3337 OFFSET(java_objectheader, vftbl));
3338 M_ALD(REG_PV, REG_METHODPTR, OFFSET(vftbl, table[0]) +
3339 sizeof(methodptr) * m->vftblindex);
3342 goto makeactualcall;
3344 case ICMD_INVOKEINTERFACE:
3347 gen_nullptr_check(argintregs[0]);
3348 M_ALD(REG_METHODPTR, argintregs[0],
3349 OFFSET(java_objectheader, vftbl));
3350 M_ALD(REG_METHODPTR, REG_METHODPTR,
3351 OFFSET(vftbl, interfacetable[0]) -
3352 sizeof(methodptr*) * ci->index);
3353 M_ALD(REG_PV, REG_METHODPTR,
3354 sizeof(methodptr) * (m - ci->methods));
3357 goto makeactualcall;
3361 error ("Unkown ICMD-Command: %d", iptr->opc);
3366 M_JSR (REG_RA, REG_PV);
3370 s1 = (int)((u1*) mcodeptr - mcodebase);
3371 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
3374 while (ml<-32768) { ml+=65536; mh--; }
3375 M_LDA (REG_PV, REG_RA, ml );
3376 M_LDAH (REG_PV, REG_PV, mh );
3379 /* d contains return type */
3381 if (d != TYPE_VOID) {
3382 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3383 s1 = reg_of_var(iptr->dst, REG_RESULT);
3384 M_INTMOVE(REG_RESULT, s1);
3385 store_reg_to_var_int(iptr->dst, s1);
3388 s1 = reg_of_var(iptr->dst, REG_FRESULT);
3389 M_FLTMOVE(REG_FRESULT, s1);
3390 store_reg_to_var_flt(iptr->dst, s1);
3397 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3399 /* op1: 0 == array, 1 == class */
3400 /* val.a: (classinfo*) superclass */
3402 /* superclass is an interface:
3404 * return (sub != NULL) &&
3405 * (sub->vftbl->interfacetablelength > super->index) &&
3406 * (sub->vftbl->interfacetable[-super->index] != NULL);
3408 * superclass is a class:
3410 * return ((sub != NULL) && (0
3411 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3412 * super->vftbl->diffvall));
3416 classinfo *super = (classinfo*) iptr->val.a;
3418 var_to_reg_int(s1, src, REG_ITMP1);
3419 d = reg_of_var(iptr->dst, REG_ITMP3);
3421 M_MOV(s1, REG_ITMP1);
3425 if (iptr->op1) { /* class/interface */
3426 if (super->flags & ACC_INTERFACE) { /* interface */
3428 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3429 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3430 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3431 M_BLEZ(REG_ITMP2, 2);
3432 M_ALD(REG_ITMP1, REG_ITMP1,
3433 OFFSET(vftbl, interfacetable[0]) -
3434 super->index * sizeof(methodptr*));
3435 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3439 s2 = super->vftbl->diffval;
3440 M_BEQZ(s1, 4 + (s2 > 255));
3441 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3442 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3443 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3445 M_CMPULE_IMM(REG_ITMP1, s2, d);
3447 M_LDA(REG_ITMP2, REG_ZERO, s2);
3448 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3452 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3453 a = dseg_addaddress ((void*) super->vftbl);
3454 M_ALD(REG_ITMP2, REG_PV, a);
3455 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3456 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl, baseval));
3457 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, diffval));
3458 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3459 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3463 panic ("internal error: no inlined array instanceof");
3465 store_reg_to_var_int(iptr->dst, d);
3468 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3470 /* op1: 0 == array, 1 == class */
3471 /* val.a: (classinfo*) superclass */
3473 /* superclass is an interface:
3475 * OK if ((sub == NULL) ||
3476 * (sub->vftbl->interfacetablelength > super->index) &&
3477 * (sub->vftbl->interfacetable[-super->index] != NULL));
3479 * superclass is a class:
3481 * OK if ((sub == NULL) || (0
3482 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3483 * super->vftbl->diffvall));
3487 classinfo *super = (classinfo*) iptr->val.a;
3489 d = reg_of_var(iptr->dst, REG_ITMP3);
3490 var_to_reg_int(s1, src, d);
3491 if (iptr->op1) { /* class/interface */
3492 if (super->flags & ACC_INTERFACE) { /* interface */
3494 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3495 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3496 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3497 M_BLEZ(REG_ITMP2, 0);
3498 codegen_addxcastrefs(mcodeptr);
3499 M_ALD(REG_ITMP2, REG_ITMP1,
3500 OFFSET(vftbl, interfacetable[0]) -
3501 super->index * sizeof(methodptr*));
3502 M_BEQZ(REG_ITMP2, 0);
3503 codegen_addxcastrefs(mcodeptr);
3507 s2 = super->vftbl->diffval;
3508 M_BEQZ(s1, 4 + (s2 != 0) + (s2 > 255));
3509 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3510 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3511 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3513 M_BNEZ(REG_ITMP1, 0);
3515 else if (s2 <= 255) {
3516 M_CMPULE_IMM(REG_ITMP1, s2, REG_ITMP2);
3517 M_BEQZ(REG_ITMP2, 0);
3520 M_LDA(REG_ITMP2, REG_ZERO, s2);
3521 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3522 M_BEQZ(REG_ITMP2, 0);
3525 M_BEQZ(s1, 8 + (d == REG_ITMP3));
3526 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3527 a = dseg_addaddress ((void*) super->vftbl);
3528 M_ALD(REG_ITMP2, REG_PV, a);
3529 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3530 if (d != REG_ITMP3) {
3531 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl, baseval));
3532 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, diffval));
3533 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3536 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, baseval));
3537 M_ISUB(REG_ITMP1, REG_ITMP2, REG_ITMP1);
3538 M_ALD(REG_ITMP2, REG_PV, a);
3539 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, diffval));
3541 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3542 M_BEQZ(REG_ITMP2, 0);
3543 codegen_addxcastrefs(mcodeptr);
3547 panic ("internal error: no inlined array checkcast");
3550 store_reg_to_var_int(iptr->dst, d);
3553 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
3555 var_to_reg_int(s1, src, REG_ITMP1);
3557 codegen_addxcheckarefs(mcodeptr);
3560 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3561 /* op1 = dimension, val.a = array descriptor */
3563 /* check for negative sizes and copy sizes to stack if necessary */
3565 MCODECHECK((iptr->op1 << 1) + 64);
3567 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3568 var_to_reg_int(s2, src, REG_ITMP1);
3570 codegen_addxcheckarefs(mcodeptr);
3572 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
3574 if (src->varkind != ARGVAR) {
3575 M_LST(s2, REG_SP, 8 * (s1 + INT_ARG_CNT));
3579 /* a0 = dimension count */
3581 ICONST(argintregs[0], iptr->op1);
3583 /* a1 = arraydescriptor */
3585 a = dseg_addaddress(iptr->val.a);
3586 M_ALD(argintregs[1], REG_PV, a);
3588 /* a2 = pointer to dimensions = stack pointer */
3590 M_INTMOVE(REG_SP, argintregs[2]);
3592 a = dseg_addaddress((void*) (builtin_nmultianewarray));
3593 M_ALD(REG_PV, REG_PV, a);
3594 M_JSR(REG_RA, REG_PV);
3595 s1 = (int)((u1*) mcodeptr - mcodebase);
3597 M_LDA (REG_PV, REG_RA, -s1);
3599 s4 ml = -s1, mh = 0;
3600 while (ml < -32768) {ml += 65536; mh--;}
3601 M_LDA(REG_PV, REG_RA, ml);
3602 M_LDAH(REG_PV, REG_PV, mh);
3604 s1 = reg_of_var(iptr->dst, REG_RESULT);
3605 M_INTMOVE(REG_RESULT, s1);
3606 store_reg_to_var_int(iptr->dst, s1);
3610 default: error ("Unknown pseudo command: %d", iptr->opc);
3616 } /* for instruction */
3618 /* copy values to interface registers */
3620 src = bptr->outstack;
3621 len = bptr->outdepth;
3625 if ((src->varkind != STACKVAR)) {
3627 if (IS_FLT_DBL_TYPE(s2)) {
3628 var_to_reg_flt(s1, src, REG_FTMP1);
3629 if (!(interfaces[len][s2].flags & INMEMORY)) {
3630 M_FLTMOVE(s1,interfaces[len][s2].regoff);
3633 M_DST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3637 var_to_reg_int(s1, src, REG_ITMP1);
3638 if (!(interfaces[len][s2].flags & INMEMORY)) {
3639 M_INTMOVE(s1,interfaces[len][s2].regoff);
3642 M_LST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3648 } /* if (bptr -> flags >= BBREACHED) */
3649 } /* for basic block */
3651 /* bptr -> mpc = (int)((u1*) mcodeptr - mcodebase); */
3654 /* generate bound check stubs */
3656 s4 *xcodeptr = NULL;
3658 for (; xboundrefs != NULL; xboundrefs = xboundrefs->next) {
3659 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3660 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
3661 xboundrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3666 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
3667 xboundrefs->branchpos, (u1*) mcodeptr - mcodebase);
3671 M_LDA(REG_ITMP2_XPC, REG_PV, xboundrefs->branchpos - 4);
3673 if (xcodeptr != NULL) {
3674 int disp = (xcodeptr-mcodeptr)-1;
3678 xcodeptr = mcodeptr;
3680 a = dseg_addaddress(proto_java_lang_ArrayIndexOutOfBoundsException);
3681 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3683 a = dseg_addaddress(asm_handle_exception);
3684 M_ALD(REG_ITMP3, REG_PV, a);
3686 M_JMP(REG_ZERO, REG_ITMP3);
3690 /* generate negative array size check stubs */
3694 for (; xcheckarefs != NULL; xcheckarefs = xcheckarefs->next) {
3695 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3696 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3697 xcheckarefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3701 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3702 xcheckarefs->branchpos, (u1*) mcodeptr - mcodebase);
3706 M_LDA(REG_ITMP2_XPC, REG_PV, xcheckarefs->branchpos - 4);
3708 if (xcodeptr != NULL) {
3709 int disp = (xcodeptr-mcodeptr)-1;
3713 xcodeptr = mcodeptr;
3715 a = dseg_addaddress(proto_java_lang_NegativeArraySizeException);
3716 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3718 a = dseg_addaddress(asm_handle_exception);
3719 M_ALD(REG_ITMP3, REG_PV, a);
3721 M_JMP(REG_ZERO, REG_ITMP3);
3725 /* generate cast check stubs */
3729 for (; xcastrefs != NULL; xcastrefs = xcastrefs->next) {
3730 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3731 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3732 xcastrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3736 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3737 xcastrefs->branchpos, (u1*) mcodeptr - mcodebase);
3741 M_LDA(REG_ITMP2_XPC, REG_PV, xcastrefs->branchpos - 4);
3743 if (xcodeptr != NULL) {
3744 int disp = (xcodeptr-mcodeptr)-1;
3748 xcodeptr = mcodeptr;
3750 a = dseg_addaddress(proto_java_lang_ClassCastException);
3751 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3753 a = dseg_addaddress(asm_handle_exception);
3754 M_ALD(REG_ITMP3, REG_PV, a);
3756 M_JMP(REG_ZERO, REG_ITMP3);
3761 #ifdef SOFTNULLPTRCHECK
3763 /* generate null pointer check stubs */
3767 for (; xnullrefs != NULL; xnullrefs = xnullrefs->next) {
3768 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3769 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3770 xnullrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3774 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3775 xnullrefs->branchpos, (u1*) mcodeptr - mcodebase);
3779 M_LDA(REG_ITMP2_XPC, REG_PV, xnullrefs->branchpos - 4);
3781 if (xcodeptr != NULL) {
3782 int disp = (xcodeptr-mcodeptr)-1;
3786 xcodeptr = mcodeptr;
3788 a = dseg_addaddress(proto_java_lang_NullPointerException);
3789 M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3791 a = dseg_addaddress(asm_handle_exception);
3792 M_ALD(REG_ITMP3, REG_PV, a);
3794 M_JMP(REG_ZERO, REG_ITMP3);
3801 codegen_finish((int)((u1*) mcodeptr - mcodebase));
3805 /* function createcompilerstub *************************************************
3807 creates a stub routine which calls the compiler
3809 *******************************************************************************/
3811 #define COMPSTUBSIZE 3
3813 u1 *createcompilerstub(methodinfo *m)
3815 u8 *s = CNEW(u8, COMPSTUBSIZE); /* memory to hold the stub */
3816 s4 *mcodeptr = (s4 *) s; /* code generation pointer */
3818 /* code for the stub */
3819 M_ALD(REG_PV, REG_PV, 16); /* load pointer to the compiler */
3820 M_JMP(0, REG_PV); /* jump to the compiler, return address
3821 in reg 0 is used as method pointer */
3822 s[1] = (u8) m; /* literals to be adressed */
3823 s[2] = (u8) asm_call_jit_compiler; /* jump directly via PV from above */
3826 count_cstub_len += COMPSTUBSIZE * 8;
3833 /* function removecompilerstub *************************************************
3835 deletes a compilerstub from memory (simply by freeing it)
3837 *******************************************************************************/
3839 void removecompilerstub(u1 *stub)
3841 CFREE(stub, COMPSTUBSIZE * 8);
3845 /* function: createnativestub **************************************************
3847 creates a stub routine which calls a native method
3849 *******************************************************************************/
3851 #define NATIVESTUBSIZE 60
3852 #define NATIVESTUBOFFSET 8
3854 u1 *createnativestub(functionptr f, methodinfo *m)
3856 u8 *s; /* memory pointer to hold the stub */
3858 s4 *mcodeptr; /* code generation pointer */
3859 int stackframesize = 0; /* size of stackframe if needed */
3863 descriptor2types(m); /* set paramcount and paramtypes */
3865 s = CNEW(u8, NATIVESTUBSIZE); /* memory to hold the stub */
3866 cs = s + NATIVESTUBOFFSET;
3867 mcodeptr = (s4 *) (cs); /* code generation pointer */
3869 *(cs-1) = (u8) f; /* address of native method */
3870 *(cs-2) = (u8) (&exceptionptr); /* address of exceptionptr */
3871 *(cs-3) = (u8) asm_handle_nat_exception; /* addr of asm exception handler */
3872 *(cs-4) = (u8) (&env); /* addr of jni_environement */
3873 *(cs-5) = (u8) asm_builtin_trace;
3875 *(cs-7) = (u8) asm_builtin_exittrace;
3876 *(cs-8) = (u8) m->class;
3878 M_LDA(REG_SP, REG_SP, -8); /* build up stackframe */
3879 M_AST(REG_RA, REG_SP, 0); /* store return address */
3882 M_ALD(REG_ITMP1, REG_PV, -6 * 8);
3883 M_ALD(REG_PV, REG_PV, -5 * 8);
3884 M_JSR(REG_RA, REG_PV);
3885 disp = -(int) (mcodeptr - (s4*) cs) * 4;
3886 M_LDA(REG_PV, REG_RA, disp);
3889 /* save argument registers on stack -- if we have to */
3890 if ((m->flags & ACC_STATIC && m->paramcount > (INT_ARG_CNT - 2)) || m->paramcount > (INT_ARG_CNT - 1)) {
3892 int paramshiftcnt = (m->flags & ACC_STATIC) ? 2 : 1;
3893 int stackparamcnt = (m->paramcount > INT_ARG_CNT) ? m->paramcount - INT_ARG_CNT : 0;
3895 stackframesize = stackparamcnt + paramshiftcnt;
3897 M_LDA(REG_SP, REG_SP, -stackframesize * 8);
3899 /* copy stack arguments into new stack frame -- if any */
3900 for (i = 0; i < stackparamcnt; i++) {
3901 M_LLD(REG_ITMP1, REG_SP, (stackparamcnt + 1 + i) * 8);
3902 M_LST(REG_ITMP1, REG_SP, (paramshiftcnt + i) * 8);
3905 if (m->flags & ACC_STATIC) {
3906 if (IS_FLT_DBL_TYPE(m->paramtypes[5])) {
3907 M_DST(argfltregs[5], REG_SP, 1 * 8);
3909 M_LST(argintregs[5], REG_SP, 1 * 8);
3912 if (IS_FLT_DBL_TYPE(m->paramtypes[4])) {
3913 M_DST(argfltregs[4], REG_SP, 0 * 8);
3915 M_LST(argintregs[4], REG_SP, 0 * 8);
3919 if (IS_FLT_DBL_TYPE(m->paramtypes[5])) {
3920 M_DST(argfltregs[5], REG_SP, 0 * 8);
3922 M_LST(argintregs[5], REG_SP, 0 * 8);
3927 if (m->flags & ACC_STATIC) {
3928 M_MOV(argintregs[3], argintregs[5]);
3929 M_MOV(argintregs[2], argintregs[4]);
3930 M_MOV(argintregs[1], argintregs[3]);
3931 M_MOV(argintregs[0], argintregs[2]);
3932 M_FMOV(argfltregs[3], argfltregs[5]);
3933 M_FMOV(argfltregs[2], argfltregs[4]);
3934 M_FMOV(argfltregs[1], argfltregs[3]);
3935 M_FMOV(argfltregs[0], argfltregs[2]);
3937 /* put class into second argument register */
3938 M_ALD(argintregs[1], REG_PV, -8 * 8);
3941 M_MOV(argintregs[4], argintregs[5]);
3942 M_MOV(argintregs[3], argintregs[4]);
3943 M_MOV(argintregs[2], argintregs[3]);
3944 M_MOV(argintregs[1], argintregs[2]);
3945 M_MOV(argintregs[0], argintregs[1]);
3946 M_FMOV(argfltregs[4], argfltregs[5]);
3947 M_FMOV(argfltregs[3], argfltregs[4]);
3948 M_FMOV(argfltregs[2], argfltregs[3]);
3949 M_FMOV(argfltregs[1], argfltregs[2]);
3950 M_FMOV(argfltregs[0], argfltregs[1]);
3953 /* put env into first argument register */
3954 M_ALD(argintregs[0], REG_PV, -4 * 8);
3956 M_ALD(REG_PV, REG_PV, -1 * 8); /* load adress of native method */
3957 M_JSR(REG_RA, REG_PV); /* call native method */
3958 disp = -(int) (mcodeptr - (s4*) cs) * 4;
3959 M_LDA(REG_PV, REG_RA, disp); /* recompute pv from ra */
3961 /* remove stackframe if there is one */
3962 if (stackframesize) {
3963 M_LDA(REG_SP, REG_SP, stackframesize * 8);
3967 M_ALD(argintregs[0], REG_PV, -6 * 8);
3968 M_MOV(REG_RESULT, argintregs[1]);
3969 M_FMOV(REG_FRESULT, argfltregs[2]);
3970 M_FMOV(REG_FRESULT, argfltregs[3]);
3971 M_ALD(REG_PV, REG_PV, -7 * 8); /* asm_builtin_exittrace */
3972 M_JSR(REG_RA, REG_PV);
3973 disp = -(int) (mcodeptr - (s4*) cs) * 4;
3974 M_LDA(REG_PV, REG_RA, disp);
3977 M_ALD(REG_ITMP3, REG_PV, -2 * 8); /* get address of exceptionptr */
3978 M_ALD(REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
3979 M_BNEZ(REG_ITMP1, 3); /* if no exception then return */
3981 M_ALD(REG_RA, REG_SP, 0); /* load return address */
3982 M_LDA(REG_SP, REG_SP, 8); /* remove stackframe */
3983 M_RET(REG_ZERO, REG_RA); /* return to caller */
3985 M_AST(REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
3987 M_ALD(REG_RA, REG_SP, 0); /* load return address */
3988 M_LDA(REG_SP, REG_SP, 8); /* remove stackframe */
3989 M_LDA(REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
3990 M_ALD(REG_ITMP3, REG_PV, -3 * 8); /* load asm exception handler address */
3991 M_JMP(REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
3994 dolog_plain("stubsize: %d (for %d params)\n", (int) (mcodeptr - (s4*) s), m->paramcount);
3998 count_nstub_len += NATIVESTUBSIZE * 8;
4001 return (u1*) (s + NATIVESTUBOFFSET);
4005 /* function: removenativestub **************************************************
4007 removes a previously created native-stub from memory
4009 *******************************************************************************/
4011 void removenativestub(u1 *stub)
4013 CFREE((u8*) stub - NATIVESTUBOFFSET, NATIVESTUBSIZE * 8);
4018 * These are local overrides for various environment variables in Emacs.
4019 * Please do not remove this and leave it at the end of the file, where
4020 * Emacs will automagically detect them.
4021 * ---------------------------------------------------------------------
4024 * indent-tabs-mode: t