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 1054 2004-05-05 21:08:55Z stefan $
52 /* include independent code generation stuff */
53 #include "codegen.inc"
57 /* *****************************************************************************
59 Datatypes and Register Allocations:
60 -----------------------------------
62 On 64-bit-machines (like the Alpha) all operands are stored in the
63 registers in a 64-bit form, even when the correspondig JavaVM operands
64 only need 32 bits. This is done by a canonical representation:
66 32-bit integers are allways stored as sign-extended 64-bit values (this
67 approach is directly supported by the Alpha architecture and is very easy
70 32-bit-floats are stored in a 64-bit doubleprecision register by simply
71 expanding the exponent and mantissa with zeroes. (also supported by the
77 The calling conventions and the layout of the stack is explained in detail
78 in the documention file: calling.doc
80 *******************************************************************************/
83 /* register descripton - array ************************************************/
85 /* #define REG_RES 0 reserved register for OS or code generator */
86 /* #define REG_RET 1 return value register */
87 /* #define REG_EXC 2 exception value register (only old jit) */
88 /* #define REG_SAV 3 (callee) saved register */
89 /* #define REG_TMP 4 scratch temporary register (caller saved) */
90 /* #define REG_ARG 5 argument register (caller saved) */
92 /* #define REG_END -1 last entry in tables */
95 REG_RET, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
96 REG_TMP, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
97 REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_TMP, REG_TMP,
98 REG_TMP, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES,
101 /* for use of reserved registers, see comment above */
103 int nregdescfloat[] = {
104 REG_RET, REG_TMP, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
105 REG_SAV, REG_SAV, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
106 REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_TMP, REG_TMP,
107 REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_RES, REG_RES, REG_RES, REG_RES,
110 /* for use of reserved registers, see comment above */
113 /* parameter allocation mode */
115 int nreg_parammode = PARAMMODE_NUMBERED;
117 /* parameter-registers will be allocated by assigning the
118 1. parameter: int/float-reg 16
119 2. parameter: int/float-reg 17
120 3. parameter: int/float-reg 18 ....
124 /* stackframe-infos ***********************************************************/
126 int parentargs_base; /* offset in stackframe for the parameter from the caller*/
128 /* -> see file 'calling.doc' */
131 /* additional functions and macros to generate code ***************************/
133 /* #define BlockPtrOfPC(pc) block+block_index[pc] */
134 #define BlockPtrOfPC(pc) ((basicblock *) iptr->target)
138 #define COUNT_SPILLS count_spills++
144 /* gen_nullptr_check(objreg) */
146 #define gen_nullptr_check(objreg) \
148 M_BEQZ((objreg), 0); \
149 codegen_addxnullrefs(mcodeptr); \
153 /* MCODECHECK(icnt) */
155 #define MCODECHECK(icnt) \
156 if((mcodeptr + (icnt)) > mcodeend) mcodeptr = codegen_increase((u1*) mcodeptr)
159 generates an integer-move from register a to b.
160 if a and b are the same int-register, no code will be generated.
163 #define M_INTMOVE(a,b) if (a != b) { M_MOV(a, b); }
167 generates a floating-point-move from register a to b.
168 if a and b are the same float-register, no code will be generated
171 #define M_FLTMOVE(a,b) if (a != b) { M_FMOV(a, b); }
175 this function generates code to fetch data from a pseudo-register
176 into a real register.
177 If the pseudo-register has actually been assigned to a real
178 register, no code will be emitted, since following operations
179 can use this register directly.
181 v: pseudoregister to be fetched from
182 tempregnum: temporary register to be used if v is actually spilled to ram
184 return: the register number, where the operand can be found after
185 fetching (this wil be either tempregnum or the register
186 number allready given to v)
189 #define var_to_reg_int(regnr,v,tempnr) { \
190 if ((v)->flags & INMEMORY) \
191 {COUNT_SPILLS;M_LLD(tempnr,REG_SP,8*(v)->regoff);regnr=tempnr;} \
192 else regnr=(v)->regoff; \
196 #define var_to_reg_flt(regnr,v,tempnr) { \
197 if ((v)->flags & INMEMORY) \
198 {COUNT_SPILLS;M_DLD(tempnr,REG_SP,8*(v)->regoff);regnr=tempnr;} \
199 else regnr=(v)->regoff; \
204 This function determines a register, to which the result of an operation
205 should go, when it is ultimatively intended to store the result in
207 If v is assigned to an actual register, this register will be returned.
208 Otherwise (when v is spilled) this function returns tempregnum.
209 If not already done, regoff and flags are set in the stack location.
212 static int reg_of_var(stackptr v, int tempregnum)
216 switch (v->varkind) {
218 if (!(v->flags & INMEMORY))
222 var = &(interfaces[v->varnum][v->type]);
223 v->regoff = var->regoff;
224 if (!(var->flags & INMEMORY))
228 var = &(locals[v->varnum][v->type]);
229 v->regoff = var->regoff;
230 if (!(var->flags & INMEMORY))
234 v->regoff = v->varnum;
235 if (IS_FLT_DBL_TYPE(v->type)) {
236 if (v->varnum < fltreg_argnum) {
237 v->regoff = argfltregs[v->varnum];
238 return(argfltregs[v->varnum]);
242 if (v->varnum < intreg_argnum) {
243 v->regoff = argintregs[v->varnum];
244 return(argintregs[v->varnum]);
246 v->regoff -= intreg_argnum;
249 v->flags |= INMEMORY;
254 /* store_reg_to_var_xxx:
255 This function generates the code to store the result of an operation
256 back into a spilled pseudo-variable.
257 If the pseudo-variable has not been spilled in the first place, this
258 function will generate nothing.
260 v ............ Pseudovariable
261 tempregnum ... Number of the temporary registers as returned by
265 #define store_reg_to_var_int(sptr, tempregnum) { \
266 if ((sptr)->flags & INMEMORY) { \
268 M_LST(tempregnum, REG_SP, 8 * (sptr)->regoff); \
272 #define store_reg_to_var_flt(sptr, tempregnum) { \
273 if ((sptr)->flags & INMEMORY) { \
275 M_DST(tempregnum, REG_SP, 8 * (sptr)->regoff); \
280 /* NullPointerException handlers and exception handling initialisation */
282 typedef struct sigctx_struct {
284 long sc_onstack; /* sigstack state to restore */
285 long sc_mask; /* signal mask to restore */
286 long sc_pc; /* pc at time of signal */
287 long sc_ps; /* psl to retore */
288 long sc_regs[32]; /* processor regs 0 to 31 */
289 long sc_ownedfp; /* fp has been used */
290 long sc_fpregs[32]; /* fp regs 0 to 31 */
291 unsigned long sc_fpcr; /* floating point control register */
292 unsigned long sc_fp_control; /* software fpcr */
294 unsigned long sc_reserved1, sc_reserved2;
295 unsigned long sc_ssize;
297 unsigned long sc_traparg_a0;
298 unsigned long sc_traparg_a1;
299 unsigned long sc_traparg_a2;
300 unsigned long sc_fp_trap_pc;
301 unsigned long sc_fp_trigger_sum;
302 unsigned long sc_fp_trigger_inst;
303 unsigned long sc_retcode[2];
307 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
308 void thread_restartcriticalsection(ucontext_t *uc)
311 if ((critical = thread_checkcritical((void*) uc->uc_mcontext.sc_pc)) != NULL)
312 uc->uc_mcontext.sc_pc = (u8) critical;
316 /* NullPointerException signal handler for hardware null pointer check */
318 void catch_NullPointerException(int sig, int code, sigctx_struct *sigctx)
324 /* Reset signal handler - necessary for SysV, does no harm for BSD */
326 instr = *((int*)(sigctx->sc_pc));
327 faultaddr = sigctx->sc_regs[(instr >> 16) & 0x1f];
329 if (faultaddr == 0) {
330 signal(sig, (void*) catch_NullPointerException); /* reinstall handler */
332 sigaddset(&nsig, sig);
333 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
335 if (!proto_java_lang_NullPointerException) {
336 proto_java_lang_NullPointerException =
337 new_exception(string_java_lang_NullPointerException);
340 sigctx->sc_regs[REG_ITMP1_XPTR] =
341 (long) proto_java_lang_NullPointerException;
342 sigctx->sc_regs[REG_ITMP2_XPC] = sigctx->sc_pc;
343 sigctx->sc_pc = (long) asm_handle_exception;
347 faultaddr += (long) ((instr << 16) >> 16);
348 fprintf(stderr, "faulting address: 0x%016lx\n", faultaddr);
349 panic("Stack overflow");
356 void init_exceptions(void)
361 /* Linux on Digital Alpha needs an initialisation of the ieee floating point
362 control for IEEE compliant arithmetic (option -mieee of GCC). Under
363 Digital Unix this is done automatically.
368 extern unsigned long ieee_get_fp_control();
369 extern void ieee_set_fp_control(unsigned long fp_control);
371 void init_exceptions(void)
373 /* initialize floating point control */
375 ieee_set_fp_control(ieee_get_fp_control()
376 & ~IEEE_TRAP_ENABLE_INV
377 & ~IEEE_TRAP_ENABLE_DZE
378 /* & ~IEEE_TRAP_ENABLE_UNF we dont want underflow */
379 & ~IEEE_TRAP_ENABLE_OVF);
382 /* install signal handlers we need to convert to exceptions */
386 signal(SIGSEGV, (void*) catch_NullPointerException);
390 signal(SIGBUS, (void*) catch_NullPointerException);
396 /* function gen_mcode **********************************************************
398 generates machine code
400 *******************************************************************************/
404 int len, s1, s2, s3, d;
416 savedregs_num = (isleafmethod) ? 0 : 1; /* space to save the RA */
418 /* space to save used callee saved registers */
420 savedregs_num += (savintregcnt - maxsavintreguse);
421 savedregs_num += (savfltregcnt - maxsavfltreguse);
423 parentargs_base = maxmemuse + savedregs_num;
425 #ifdef USE_THREADS /* space to save argument of monitor_enter */
427 if (checksync && (method->flags & ACC_SYNCHRONIZED))
432 /* create method header */
434 (void) dseg_addaddress(method); /* MethodPointer */
435 (void) dseg_adds4(parentargs_base * 8); /* FrameSize */
439 /* IsSync contains the offset relative to the stack pointer for the
440 argument of monitor_exit used in the exception handler. Since the
441 offset could be zero and give a wrong meaning of the flag it is
445 if (checksync && (method->flags & ACC_SYNCHRONIZED))
446 (void) dseg_adds4((maxmemuse + 1) * 8); /* IsSync */
451 (void) dseg_adds4(0); /* IsSync */
453 (void) dseg_adds4(isleafmethod); /* IsLeaf */
454 (void) dseg_adds4(savintregcnt - maxsavintreguse); /* IntSave */
455 (void) dseg_adds4(savfltregcnt - maxsavfltreguse); /* FltSave */
457 dseg_addlinenumbertablesize();
460 (void) dseg_adds4(exceptiontablelength); /* ExTableSize */
462 /* create exception table */
464 for (ex = extable; ex != NULL; ex = ex->down) {
467 if (ex->start != NULL)
468 printf("adding start - %d - ", ex->start->debug_nr);
470 printf("PANIC - start is NULL");
475 dseg_addtarget(ex->start);
479 printf("adding end - %d - ", ex->end->debug_nr);
481 printf("PANIC - end is NULL");
486 dseg_addtarget(ex->end);
489 if (ex->handler != NULL)
490 printf("adding handler - %d\n", ex->handler->debug_nr);
492 printf("PANIC - handler is NULL");
497 dseg_addtarget(ex->handler);
499 (void) dseg_addaddress(ex->catchtype);
502 /* initialize mcode variables */
504 mcodeptr = (s4*) mcodebase;
505 mcodeend = (s4*) (mcodebase + mcodesize);
506 MCODECHECK(128 + mparamcount);
508 /* create stack frame (if necessary) */
511 {M_LDA (REG_SP, REG_SP, -parentargs_base * 8);}
513 /* save return address and used callee saved registers */
517 {p--; M_AST (REG_RA, REG_SP, 8*p);}
518 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
519 {p--; M_LST (savintregs[r], REG_SP, 8 * p);}
520 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
521 {p--; M_DST (savfltregs[r], REG_SP, 8 * p);}
523 /* save monitorenter argument */
526 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
527 if (method->flags & ACC_STATIC) {
528 p = dseg_addaddress (class);
529 M_ALD(REG_ITMP1, REG_PV, p);
530 M_AST(REG_ITMP1, REG_SP, 8 * maxmemuse);
533 M_AST (argintregs[0], REG_SP, 8 * maxmemuse);
538 /* copy argument registers to stack and call trace function with pointer
539 to arguments on stack.
544 M_LDA(REG_SP, REG_SP, -((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
545 M_AST(REG_RA, REG_SP, 1 * 8);
547 /* save integer argument registers */
548 for (p = 0; /* p < mparamcount && */ p < INT_ARG_CNT; p++) {
549 M_LST(argintregs[p], REG_SP, (2 + p) * 8);
552 /* save and copy float arguments into integer registers */
553 for (p = 0; /* p < mparamcount && */ p < FLT_ARG_CNT; p++) {
556 if (IS_FLT_DBL_TYPE(t)) {
557 if (IS_2_WORD_TYPE(t)) {
558 M_DST(argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
561 M_FST(argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
564 M_LLD(argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
567 M_DST(argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
571 p = dseg_addaddress(method);
572 M_ALD(REG_ITMP1, REG_PV, p);
573 M_AST(REG_ITMP1, REG_SP, 0 * 8);
574 p = dseg_addaddress((void *) builtin_trace_args);
575 M_ALD(REG_PV, REG_PV, p);
576 M_JSR(REG_RA, REG_PV);
577 disp = -(int) ((u1 *) mcodeptr - mcodebase);
578 M_LDA(REG_PV, REG_RA, disp);
579 M_ALD(REG_RA, REG_SP, 1 * 8);
581 for (p = 0; /* p < mparamcount && */ p < INT_ARG_CNT; p++) {
582 M_LLD(argintregs[p], REG_SP, (2 + p) * 8);
585 for (p = 0; /* p < mparamcount && */ p < FLT_ARG_CNT; p++) {
588 if (IS_FLT_DBL_TYPE(t)) {
589 if (IS_2_WORD_TYPE(t)) {
590 M_DLD(argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
593 M_FLD(argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
597 M_DLD(argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
601 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT + 2) * 8);
604 /* take arguments out of register or stack frame */
606 for (p = 0, l = 0; p < mparamcount; p++) {
608 var = &(locals[l][t]);
610 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
615 if (IS_INT_LNG_TYPE(t)) { /* integer args */
616 if (p < INT_ARG_CNT) { /* register arguments */
617 if (!(var->flags & INMEMORY)) /* reg arg -> register */
618 {M_INTMOVE (argintregs[p], r);}
619 else /* reg arg -> spilled */
620 M_LST (argintregs[p], REG_SP, 8 * r);
622 else { /* stack arguments */
623 pa = p - INT_ARG_CNT;
624 if (!(var->flags & INMEMORY)) /* stack arg -> register */
625 M_LLD (r, REG_SP, 8 * (parentargs_base + pa));
626 else { /* stack arg -> spilled */
627 M_LLD (REG_ITMP1, REG_SP, 8 * (parentargs_base + pa));
628 M_LST (REG_ITMP1, REG_SP, 8 * r);
632 else { /* floating args */
633 if (p < FLT_ARG_CNT) { /* register arguments */
634 if (!(var->flags & INMEMORY)) /* reg arg -> register */
635 {M_FLTMOVE (argfltregs[p], r);}
636 else /* reg arg -> spilled */
637 M_DST (argfltregs[p], REG_SP, 8 * r);
639 else { /* stack arguments */
640 pa = p - FLT_ARG_CNT;
641 if (!(var->flags & INMEMORY)) /* stack-arg -> register */
642 M_DLD (r, REG_SP, 8 * (parentargs_base + pa) );
643 else { /* stack-arg -> spilled */
644 M_DLD (REG_FTMP1, REG_SP, 8 * (parentargs_base + pa));
645 M_DST (REG_FTMP1, REG_SP, 8 * r);
651 /* call monitorenter function */
654 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
656 p = dseg_addaddress ((void*) (builtin_monitorenter));
657 M_ALD(REG_PV, REG_PV, p);
658 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
659 M_JSR(REG_RA, REG_PV);
660 disp = -(int)((u1*) mcodeptr - mcodebase);
661 M_LDA(REG_PV, REG_RA, disp);
666 /* end of header generation */
668 /* walk through all basic blocks */
669 for (bptr = block; bptr != NULL; bptr = bptr->next) {
671 bptr->mpc = (int)((u1*) mcodeptr - mcodebase);
673 if (bptr->flags >= BBREACHED) {
675 /* branch resolving */
679 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
680 gen_resolvebranch((u1*) mcodebase + brefs->branchpos,
681 brefs->branchpos, bptr->mpc);
685 /* copy interface registers to their destination */
690 while (src != NULL) {
692 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
693 d = reg_of_var(src, REG_ITMP1);
694 M_INTMOVE(REG_ITMP1, d);
695 store_reg_to_var_int(src, d);
698 d = reg_of_var(src, REG_IFTMP);
699 if ((src->varkind != STACKVAR)) {
701 if (IS_FLT_DBL_TYPE(s2)) {
702 if (!(interfaces[len][s2].flags & INMEMORY)) {
703 s1 = interfaces[len][s2].regoff;
707 M_DLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
709 store_reg_to_var_flt(src, d);
712 if (!(interfaces[len][s2].flags & INMEMORY)) {
713 s1 = interfaces[len][s2].regoff;
717 M_LLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
719 store_reg_to_var_int(src, d);
726 /* walk through all instructions */
730 for (iptr = bptr->iinstr;
732 src = iptr->dst, len--, iptr++) {
734 MCODECHECK(64); /* an instruction usually needs < 64 words */
737 case ICMD_NOP: /* ... ==> ... */
740 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
742 var_to_reg_int(s1, src, REG_ITMP1);
744 codegen_addxnullrefs(mcodeptr);
747 /* constant operations ************************************************/
749 #define ICONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
750 else{a=dseg_adds4(c);M_ILD(r,REG_PV,a);}
752 #define LCONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
753 else{a=dseg_adds8(c);M_LLD(r,REG_PV,a);}
755 case ICMD_ICONST: /* ... ==> ..., constant */
756 /* op1 = 0, val.i = constant */
758 d = reg_of_var(iptr->dst, REG_ITMP1);
759 ICONST(d, iptr->val.i);
760 store_reg_to_var_int(iptr->dst, d);
763 case ICMD_LCONST: /* ... ==> ..., constant */
764 /* op1 = 0, val.l = constant */
766 d = reg_of_var(iptr->dst, REG_ITMP1);
767 LCONST(d, iptr->val.l);
768 store_reg_to_var_int(iptr->dst, d);
771 case ICMD_FCONST: /* ... ==> ..., constant */
772 /* op1 = 0, val.f = constant */
774 d = reg_of_var(iptr->dst, REG_FTMP1);
775 a = dseg_addfloat(iptr->val.f);
777 store_reg_to_var_flt(iptr->dst, d);
780 case ICMD_DCONST: /* ... ==> ..., constant */
781 /* op1 = 0, val.d = constant */
783 d = reg_of_var(iptr->dst, REG_FTMP1);
784 a = dseg_adddouble(iptr->val.d);
786 store_reg_to_var_flt(iptr->dst, d);
789 case ICMD_ACONST: /* ... ==> ..., constant */
790 /* op1 = 0, val.a = constant */
792 d = reg_of_var(iptr->dst, REG_ITMP1);
794 a = dseg_addaddress (iptr->val.a);
798 M_INTMOVE(REG_ZERO, d);
800 store_reg_to_var_int(iptr->dst, d);
804 /* load/store operations **********************************************/
806 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
807 case ICMD_LLOAD: /* op1 = local variable */
810 d = reg_of_var(iptr->dst, REG_ITMP1);
811 if ((iptr->dst->varkind == LOCALVAR) &&
812 (iptr->dst->varnum == iptr->op1))
814 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
815 if (var->flags & INMEMORY)
816 M_LLD(d, REG_SP, 8 * var->regoff);
818 {M_INTMOVE(var->regoff,d);}
819 store_reg_to_var_int(iptr->dst, d);
822 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
823 case ICMD_DLOAD: /* op1 = local variable */
825 d = reg_of_var(iptr->dst, REG_FTMP1);
826 if ((iptr->dst->varkind == LOCALVAR) &&
827 (iptr->dst->varnum == iptr->op1))
829 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
830 if (var->flags & INMEMORY)
831 M_DLD(d, REG_SP, 8 * var->regoff);
833 {M_FLTMOVE(var->regoff,d);}
834 store_reg_to_var_flt(iptr->dst, d);
838 case ICMD_ISTORE: /* ..., value ==> ... */
839 case ICMD_LSTORE: /* op1 = local variable */
842 if ((src->varkind == LOCALVAR) &&
843 (src->varnum == iptr->op1))
845 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
846 if (var->flags & INMEMORY) {
847 var_to_reg_int(s1, src, REG_ITMP1);
848 M_LST(s1, REG_SP, 8 * var->regoff);
851 var_to_reg_int(s1, src, var->regoff);
852 M_INTMOVE(s1, var->regoff);
856 case ICMD_FSTORE: /* ..., value ==> ... */
857 case ICMD_DSTORE: /* op1 = local variable */
859 if ((src->varkind == LOCALVAR) &&
860 (src->varnum == iptr->op1))
862 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
863 if (var->flags & INMEMORY) {
864 var_to_reg_flt(s1, src, REG_FTMP1);
865 M_DST(s1, REG_SP, 8 * var->regoff);
868 var_to_reg_flt(s1, src, var->regoff);
869 M_FLTMOVE(s1, var->regoff);
874 /* pop/dup/swap operations ********************************************/
876 /* attention: double and longs are only one entry in CACAO ICMDs */
878 case ICMD_POP: /* ..., value ==> ... */
879 case ICMD_POP2: /* ..., value, value ==> ... */
882 #define M_COPY(from,to) \
883 d = reg_of_var(to, REG_IFTMP); \
884 if ((from->regoff != to->regoff) || \
885 ((from->flags ^ to->flags) & INMEMORY)) { \
886 if (IS_FLT_DBL_TYPE(from->type)) { \
887 var_to_reg_flt(s1, from, d); \
889 store_reg_to_var_flt(to, d); \
892 var_to_reg_int(s1, from, d); \
894 store_reg_to_var_int(to, d); \
898 case ICMD_DUP: /* ..., a ==> ..., a, a */
899 M_COPY(src, iptr->dst);
902 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
904 M_COPY(src, iptr->dst->prev->prev);
906 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
908 M_COPY(src, iptr->dst);
909 M_COPY(src->prev, iptr->dst->prev);
912 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
914 M_COPY(src->prev, iptr->dst->prev->prev->prev);
916 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
918 M_COPY(src, iptr->dst);
919 M_COPY(src->prev, iptr->dst->prev);
920 M_COPY(src->prev->prev, iptr->dst->prev->prev);
921 M_COPY(src, iptr->dst->prev->prev->prev);
924 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
926 M_COPY(src, iptr->dst);
927 M_COPY(src->prev, iptr->dst->prev);
928 M_COPY(src->prev->prev, iptr->dst->prev->prev);
929 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
930 M_COPY(src, iptr->dst->prev->prev->prev->prev);
931 M_COPY(src->prev, iptr->dst->prev->prev->prev->prev->prev);
934 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
936 M_COPY(src, iptr->dst->prev);
937 M_COPY(src->prev, iptr->dst);
941 /* integer operations *************************************************/
943 case ICMD_INEG: /* ..., value ==> ..., - value */
945 var_to_reg_int(s1, src, REG_ITMP1);
946 d = reg_of_var(iptr->dst, REG_ITMP3);
947 M_ISUB(REG_ZERO, s1, d);
948 store_reg_to_var_int(iptr->dst, d);
951 case ICMD_LNEG: /* ..., value ==> ..., - value */
953 var_to_reg_int(s1, src, REG_ITMP1);
954 d = reg_of_var(iptr->dst, REG_ITMP3);
955 M_LSUB(REG_ZERO, s1, d);
956 store_reg_to_var_int(iptr->dst, d);
959 case ICMD_I2L: /* ..., value ==> ..., value */
961 var_to_reg_int(s1, src, REG_ITMP1);
962 d = reg_of_var(iptr->dst, REG_ITMP3);
964 store_reg_to_var_int(iptr->dst, d);
967 case ICMD_L2I: /* ..., value ==> ..., value */
969 var_to_reg_int(s1, src, REG_ITMP1);
970 d = reg_of_var(iptr->dst, REG_ITMP3);
971 M_IADD(s1, REG_ZERO, d );
972 store_reg_to_var_int(iptr->dst, d);
975 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
977 var_to_reg_int(s1, src, REG_ITMP1);
978 d = reg_of_var(iptr->dst, REG_ITMP3);
979 if (has_ext_instr_set) {
983 M_SLL_IMM(s1, 56, d);
984 M_SRA_IMM( d, 56, d);
986 store_reg_to_var_int(iptr->dst, d);
989 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
991 var_to_reg_int(s1, src, REG_ITMP1);
992 d = reg_of_var(iptr->dst, REG_ITMP3);
994 store_reg_to_var_int(iptr->dst, d);
997 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
999 var_to_reg_int(s1, src, REG_ITMP1);
1000 d = reg_of_var(iptr->dst, REG_ITMP3);
1001 if (has_ext_instr_set) {
1005 M_SLL_IMM(s1, 48, d);
1006 M_SRA_IMM( d, 48, d);
1008 store_reg_to_var_int(iptr->dst, d);
1012 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1014 var_to_reg_int(s1, src->prev, REG_ITMP1);
1015 var_to_reg_int(s2, src, REG_ITMP2);
1016 d = reg_of_var(iptr->dst, REG_ITMP3);
1018 store_reg_to_var_int(iptr->dst, d);
1021 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
1022 /* val.i = constant */
1024 var_to_reg_int(s1, src, REG_ITMP1);
1025 d = reg_of_var(iptr->dst, REG_ITMP3);
1026 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1027 M_IADD_IMM(s1, iptr->val.i, d);
1030 ICONST(REG_ITMP2, iptr->val.i);
1031 M_IADD(s1, REG_ITMP2, d);
1033 store_reg_to_var_int(iptr->dst, d);
1036 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1038 var_to_reg_int(s1, src->prev, REG_ITMP1);
1039 var_to_reg_int(s2, src, REG_ITMP2);
1040 d = reg_of_var(iptr->dst, REG_ITMP3);
1042 store_reg_to_var_int(iptr->dst, d);
1045 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
1046 /* val.l = constant */
1048 var_to_reg_int(s1, src, REG_ITMP1);
1049 d = reg_of_var(iptr->dst, REG_ITMP3);
1050 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1051 M_LADD_IMM(s1, iptr->val.l, d);
1054 LCONST(REG_ITMP2, iptr->val.l);
1055 M_LADD(s1, REG_ITMP2, d);
1057 store_reg_to_var_int(iptr->dst, d);
1060 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1062 var_to_reg_int(s1, src->prev, REG_ITMP1);
1063 var_to_reg_int(s2, src, REG_ITMP2);
1064 d = reg_of_var(iptr->dst, REG_ITMP3);
1066 store_reg_to_var_int(iptr->dst, d);
1069 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
1070 /* val.i = constant */
1072 var_to_reg_int(s1, src, REG_ITMP1);
1073 d = reg_of_var(iptr->dst, REG_ITMP3);
1074 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1075 M_ISUB_IMM(s1, iptr->val.i, d);
1078 ICONST(REG_ITMP2, iptr->val.i);
1079 M_ISUB(s1, REG_ITMP2, d);
1081 store_reg_to_var_int(iptr->dst, d);
1084 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1086 var_to_reg_int(s1, src->prev, REG_ITMP1);
1087 var_to_reg_int(s2, src, REG_ITMP2);
1088 d = reg_of_var(iptr->dst, REG_ITMP3);
1090 store_reg_to_var_int(iptr->dst, d);
1093 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
1094 /* val.l = constant */
1096 var_to_reg_int(s1, src, REG_ITMP1);
1097 d = reg_of_var(iptr->dst, REG_ITMP3);
1098 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1099 M_LSUB_IMM(s1, iptr->val.l, d);
1102 LCONST(REG_ITMP2, iptr->val.l);
1103 M_LSUB(s1, REG_ITMP2, d);
1105 store_reg_to_var_int(iptr->dst, d);
1108 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1110 var_to_reg_int(s1, src->prev, REG_ITMP1);
1111 var_to_reg_int(s2, src, REG_ITMP2);
1112 d = reg_of_var(iptr->dst, REG_ITMP3);
1114 store_reg_to_var_int(iptr->dst, d);
1117 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
1118 /* val.i = constant */
1120 var_to_reg_int(s1, src, REG_ITMP1);
1121 d = reg_of_var(iptr->dst, REG_ITMP3);
1122 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1123 M_IMUL_IMM(s1, iptr->val.i, d);
1126 ICONST(REG_ITMP2, iptr->val.i);
1127 M_IMUL(s1, REG_ITMP2, d);
1129 store_reg_to_var_int(iptr->dst, d);
1132 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1134 var_to_reg_int(s1, src->prev, REG_ITMP1);
1135 var_to_reg_int(s2, src, REG_ITMP2);
1136 d = reg_of_var(iptr->dst, REG_ITMP3);
1138 store_reg_to_var_int(iptr->dst, d);
1141 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
1142 /* val.l = constant */
1144 var_to_reg_int(s1, src, REG_ITMP1);
1145 d = reg_of_var(iptr->dst, REG_ITMP3);
1146 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1147 M_LMUL_IMM(s1, iptr->val.l, d);
1150 LCONST(REG_ITMP2, iptr->val.l);
1151 M_LMUL(s1, REG_ITMP2, d);
1153 store_reg_to_var_int(iptr->dst, d);
1156 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
1157 case ICMD_LDIVPOW2: /* val.i = constant */
1159 var_to_reg_int(s1, src, REG_ITMP1);
1160 d = reg_of_var(iptr->dst, REG_ITMP3);
1161 if (iptr->val.i <= 15) {
1162 M_LDA(REG_ITMP2, s1, (1 << iptr->val.i) -1);
1163 M_CMOVGE(s1, s1, REG_ITMP2);
1166 M_SRA_IMM(s1, 63, REG_ITMP2);
1167 M_SRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
1168 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1170 M_SRA_IMM(REG_ITMP2, iptr->val.i, d);
1171 store_reg_to_var_int(iptr->dst, d);
1174 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1176 var_to_reg_int(s1, src->prev, REG_ITMP1);
1177 var_to_reg_int(s2, src, REG_ITMP2);
1178 d = reg_of_var(iptr->dst, REG_ITMP3);
1179 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1180 M_SLL(s1, REG_ITMP3, d);
1181 M_IADD(d, REG_ZERO, d);
1182 store_reg_to_var_int(iptr->dst, d);
1185 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1186 /* val.i = constant */
1188 var_to_reg_int(s1, src, REG_ITMP1);
1189 d = reg_of_var(iptr->dst, REG_ITMP3);
1190 M_SLL_IMM(s1, iptr->val.i & 0x1f, d);
1191 M_IADD(d, REG_ZERO, d);
1192 store_reg_to_var_int(iptr->dst, d);
1195 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1197 var_to_reg_int(s1, src->prev, REG_ITMP1);
1198 var_to_reg_int(s2, src, REG_ITMP2);
1199 d = reg_of_var(iptr->dst, REG_ITMP3);
1200 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1201 M_SRA(s1, REG_ITMP3, d);
1202 store_reg_to_var_int(iptr->dst, d);
1205 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1206 /* val.i = constant */
1208 var_to_reg_int(s1, src, REG_ITMP1);
1209 d = reg_of_var(iptr->dst, REG_ITMP3);
1210 M_SRA_IMM(s1, iptr->val.i & 0x1f, d);
1211 store_reg_to_var_int(iptr->dst, d);
1214 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1216 var_to_reg_int(s1, src->prev, REG_ITMP1);
1217 var_to_reg_int(s2, src, REG_ITMP2);
1218 d = reg_of_var(iptr->dst, REG_ITMP3);
1219 M_AND_IMM(s2, 0x1f, REG_ITMP2);
1221 M_SRL(d, REG_ITMP2, d);
1222 M_IADD(d, REG_ZERO, d);
1223 store_reg_to_var_int(iptr->dst, d);
1226 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1227 /* val.i = constant */
1229 var_to_reg_int(s1, src, REG_ITMP1);
1230 d = reg_of_var(iptr->dst, REG_ITMP3);
1232 M_SRL_IMM(d, iptr->val.i & 0x1f, d);
1233 M_IADD(d, REG_ZERO, d);
1234 store_reg_to_var_int(iptr->dst, d);
1237 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1239 var_to_reg_int(s1, src->prev, REG_ITMP1);
1240 var_to_reg_int(s2, src, REG_ITMP2);
1241 d = reg_of_var(iptr->dst, REG_ITMP3);
1243 store_reg_to_var_int(iptr->dst, d);
1246 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1247 /* val.i = constant */
1249 var_to_reg_int(s1, src, REG_ITMP1);
1250 d = reg_of_var(iptr->dst, REG_ITMP3);
1251 M_SLL_IMM(s1, iptr->val.i & 0x3f, d);
1252 store_reg_to_var_int(iptr->dst, d);
1255 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1257 var_to_reg_int(s1, src->prev, REG_ITMP1);
1258 var_to_reg_int(s2, src, REG_ITMP2);
1259 d = reg_of_var(iptr->dst, REG_ITMP3);
1261 store_reg_to_var_int(iptr->dst, d);
1264 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1265 /* val.i = constant */
1267 var_to_reg_int(s1, src, REG_ITMP1);
1268 d = reg_of_var(iptr->dst, REG_ITMP3);
1269 M_SRA_IMM(s1, iptr->val.i & 0x3f, d);
1270 store_reg_to_var_int(iptr->dst, d);
1273 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1275 var_to_reg_int(s1, src->prev, REG_ITMP1);
1276 var_to_reg_int(s2, src, REG_ITMP2);
1277 d = reg_of_var(iptr->dst, REG_ITMP3);
1279 store_reg_to_var_int(iptr->dst, d);
1282 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1283 /* val.i = constant */
1285 var_to_reg_int(s1, src, REG_ITMP1);
1286 d = reg_of_var(iptr->dst, REG_ITMP3);
1287 M_SRL_IMM(s1, iptr->val.i & 0x3f, d);
1288 store_reg_to_var_int(iptr->dst, d);
1291 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1294 var_to_reg_int(s1, src->prev, REG_ITMP1);
1295 var_to_reg_int(s2, src, REG_ITMP2);
1296 d = reg_of_var(iptr->dst, REG_ITMP3);
1298 store_reg_to_var_int(iptr->dst, d);
1301 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1302 /* val.i = constant */
1304 var_to_reg_int(s1, src, REG_ITMP1);
1305 d = reg_of_var(iptr->dst, REG_ITMP3);
1306 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1307 M_AND_IMM(s1, iptr->val.i, d);
1309 else if (iptr->val.i == 0xffff) {
1312 else if (iptr->val.i == 0xffffff) {
1313 M_ZAPNOT_IMM(s1, 0x07, d);
1316 ICONST(REG_ITMP2, iptr->val.i);
1317 M_AND(s1, REG_ITMP2, d);
1319 store_reg_to_var_int(iptr->dst, d);
1322 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1323 /* val.i = constant */
1325 var_to_reg_int(s1, src, REG_ITMP1);
1326 d = reg_of_var(iptr->dst, REG_ITMP3);
1328 M_MOV(s1, REG_ITMP1);
1331 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1332 M_AND_IMM(s1, iptr->val.i, d);
1334 M_ISUB(REG_ZERO, s1, d);
1335 M_AND_IMM(d, iptr->val.i, d);
1337 else if (iptr->val.i == 0xffff) {
1340 M_ISUB(REG_ZERO, s1, d);
1343 else if (iptr->val.i == 0xffffff) {
1344 M_ZAPNOT_IMM(s1, 0x07, d);
1346 M_ISUB(REG_ZERO, s1, d);
1347 M_ZAPNOT_IMM(d, 0x07, d);
1350 ICONST(REG_ITMP2, iptr->val.i);
1351 M_AND(s1, REG_ITMP2, d);
1353 M_ISUB(REG_ZERO, s1, d);
1354 M_AND(d, REG_ITMP2, d);
1356 M_ISUB(REG_ZERO, d, d);
1357 store_reg_to_var_int(iptr->dst, d);
1360 case ICMD_IREM0X10001: /* ..., value ==> ..., value % 0x100001 */
1362 /* b = value & 0xffff;
1364 a = ((b - a) & 0xffff) + (b < a);
1366 var_to_reg_int(s1, src, REG_ITMP1);
1367 d = reg_of_var(iptr->dst, REG_ITMP3);
1369 M_MOV(s1, REG_ITMP3);
1373 M_CZEXT(s1, REG_ITMP2);
1374 M_SRA_IMM(s1, 16, d);
1375 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1376 M_ISUB(REG_ITMP2, d, d);
1378 M_IADD(d, REG_ITMP1, d);
1379 M_BR(11 + (s1 == REG_ITMP1));
1380 M_ISUB(REG_ZERO, s1, REG_ITMP1);
1381 M_CZEXT(REG_ITMP1, REG_ITMP2);
1382 M_SRA_IMM(REG_ITMP1, 16, d);
1383 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1384 M_ISUB(REG_ITMP2, d, d);
1386 M_IADD(d, REG_ITMP1, d);
1387 M_ISUB(REG_ZERO, d, d);
1388 if (s1 == REG_ITMP1) {
1389 var_to_reg_int(s1, src, REG_ITMP1);
1391 M_SLL_IMM(s1, 33, REG_ITMP2);
1392 M_CMPEQ(REG_ITMP2, REG_ZERO, REG_ITMP2);
1393 M_ISUB(d, REG_ITMP2, d);
1394 store_reg_to_var_int(iptr->dst, d);
1397 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1398 /* val.l = constant */
1400 var_to_reg_int(s1, src, REG_ITMP1);
1401 d = reg_of_var(iptr->dst, REG_ITMP3);
1402 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1403 M_AND_IMM(s1, iptr->val.l, d);
1405 else if (iptr->val.l == 0xffffL) {
1408 else if (iptr->val.l == 0xffffffL) {
1409 M_ZAPNOT_IMM(s1, 0x07, d);
1411 else if (iptr->val.l == 0xffffffffL) {
1414 else if (iptr->val.l == 0xffffffffffL) {
1415 M_ZAPNOT_IMM(s1, 0x1f, d);
1417 else if (iptr->val.l == 0xffffffffffffL) {
1418 M_ZAPNOT_IMM(s1, 0x3f, d);
1420 else if (iptr->val.l == 0xffffffffffffffL) {
1421 M_ZAPNOT_IMM(s1, 0x7f, d);
1424 LCONST(REG_ITMP2, iptr->val.l);
1425 M_AND(s1, REG_ITMP2, d);
1427 store_reg_to_var_int(iptr->dst, d);
1430 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1431 /* val.l = constant */
1433 var_to_reg_int(s1, src, REG_ITMP1);
1434 d = reg_of_var(iptr->dst, REG_ITMP3);
1436 M_MOV(s1, REG_ITMP1);
1439 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1440 M_AND_IMM(s1, iptr->val.l, d);
1442 M_LSUB(REG_ZERO, s1, d);
1443 M_AND_IMM(d, iptr->val.l, d);
1445 else if (iptr->val.l == 0xffffL) {
1448 M_LSUB(REG_ZERO, s1, d);
1451 else if (iptr->val.l == 0xffffffL) {
1452 M_ZAPNOT_IMM(s1, 0x07, d);
1454 M_LSUB(REG_ZERO, s1, d);
1455 M_ZAPNOT_IMM(d, 0x07, d);
1457 else if (iptr->val.l == 0xffffffffL) {
1460 M_LSUB(REG_ZERO, s1, d);
1463 else if (iptr->val.l == 0xffffffffffL) {
1464 M_ZAPNOT_IMM(s1, 0x1f, d);
1466 M_LSUB(REG_ZERO, s1, d);
1467 M_ZAPNOT_IMM(d, 0x1f, d);
1469 else if (iptr->val.l == 0xffffffffffffL) {
1470 M_ZAPNOT_IMM(s1, 0x3f, d);
1472 M_LSUB(REG_ZERO, s1, d);
1473 M_ZAPNOT_IMM(d, 0x3f, d);
1475 else if (iptr->val.l == 0xffffffffffffffL) {
1476 M_ZAPNOT_IMM(s1, 0x7f, d);
1478 M_LSUB(REG_ZERO, s1, d);
1479 M_ZAPNOT_IMM(d, 0x7f, d);
1482 LCONST(REG_ITMP2, iptr->val.l);
1483 M_AND(s1, REG_ITMP2, d);
1485 M_LSUB(REG_ZERO, s1, d);
1486 M_AND(d, REG_ITMP2, d);
1488 M_LSUB(REG_ZERO, d, d);
1489 store_reg_to_var_int(iptr->dst, d);
1492 case ICMD_LREM0X10001:/* ..., value ==> ..., value % 0x10001 */
1494 var_to_reg_int(s1, src, REG_ITMP1);
1495 d = reg_of_var(iptr->dst, REG_ITMP3);
1497 M_MOV(s1, REG_ITMP3);
1500 M_CZEXT(s1, REG_ITMP2);
1501 M_SRA_IMM(s1, 16, d);
1502 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1503 M_LSUB(REG_ITMP2, d, d);
1505 M_LADD(d, REG_ITMP1, d);
1506 M_LDA(REG_ITMP2, REG_ZERO, -1);
1507 M_SRL_IMM(REG_ITMP2, 33, REG_ITMP2);
1508 if (s1 == REG_ITMP1) {
1509 var_to_reg_int(s1, src, REG_ITMP1);
1511 M_CMPULT(s1, REG_ITMP2, REG_ITMP2);
1512 M_BNEZ(REG_ITMP2, 11);
1513 M_LDA(d, REG_ZERO, -257);
1514 M_ZAPNOT_IMM(d, 0xcd, d);
1515 M_LSUB(REG_ZERO, s1, REG_ITMP2);
1516 M_CMOVGE(s1, s1, REG_ITMP2);
1517 M_UMULH(REG_ITMP2, d, REG_ITMP2);
1518 M_SRL_IMM(REG_ITMP2, 16, REG_ITMP2);
1519 M_LSUB(REG_ZERO, REG_ITMP2, d);
1520 M_CMOVGE(s1, REG_ITMP2, d);
1521 M_SLL_IMM(d, 16, REG_ITMP2);
1522 M_LADD(d, REG_ITMP2, d);
1524 store_reg_to_var_int(iptr->dst, d);
1527 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1530 var_to_reg_int(s1, src->prev, REG_ITMP1);
1531 var_to_reg_int(s2, src, REG_ITMP2);
1532 d = reg_of_var(iptr->dst, REG_ITMP3);
1534 store_reg_to_var_int(iptr->dst, d);
1537 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1538 /* val.i = constant */
1540 var_to_reg_int(s1, src, REG_ITMP1);
1541 d = reg_of_var(iptr->dst, REG_ITMP3);
1542 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1543 M_OR_IMM(s1, iptr->val.i, d);
1546 ICONST(REG_ITMP2, iptr->val.i);
1547 M_OR(s1, REG_ITMP2, d);
1549 store_reg_to_var_int(iptr->dst, d);
1552 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1553 /* val.l = constant */
1555 var_to_reg_int(s1, src, REG_ITMP1);
1556 d = reg_of_var(iptr->dst, REG_ITMP3);
1557 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1558 M_OR_IMM(s1, iptr->val.l, d);
1561 LCONST(REG_ITMP2, iptr->val.l);
1562 M_OR(s1, REG_ITMP2, d);
1564 store_reg_to_var_int(iptr->dst, d);
1567 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1570 var_to_reg_int(s1, src->prev, REG_ITMP1);
1571 var_to_reg_int(s2, src, REG_ITMP2);
1572 d = reg_of_var(iptr->dst, REG_ITMP3);
1574 store_reg_to_var_int(iptr->dst, d);
1577 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1578 /* val.i = constant */
1580 var_to_reg_int(s1, src, REG_ITMP1);
1581 d = reg_of_var(iptr->dst, REG_ITMP3);
1582 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1583 M_XOR_IMM(s1, iptr->val.i, d);
1586 ICONST(REG_ITMP2, iptr->val.i);
1587 M_XOR(s1, REG_ITMP2, d);
1589 store_reg_to_var_int(iptr->dst, d);
1592 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1593 /* val.l = constant */
1595 var_to_reg_int(s1, src, REG_ITMP1);
1596 d = reg_of_var(iptr->dst, REG_ITMP3);
1597 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1598 M_XOR_IMM(s1, iptr->val.l, d);
1601 LCONST(REG_ITMP2, iptr->val.l);
1602 M_XOR(s1, REG_ITMP2, d);
1604 store_reg_to_var_int(iptr->dst, d);
1608 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1610 var_to_reg_int(s1, src->prev, REG_ITMP1);
1611 var_to_reg_int(s2, src, REG_ITMP2);
1612 d = reg_of_var(iptr->dst, REG_ITMP3);
1613 M_CMPLT(s1, s2, REG_ITMP3);
1614 M_CMPLT(s2, s1, REG_ITMP1);
1615 M_LSUB (REG_ITMP1, REG_ITMP3, d);
1616 store_reg_to_var_int(iptr->dst, d);
1620 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1621 /* op1 = variable, val.i = constant */
1623 var = &(locals[iptr->op1][TYPE_INT]);
1624 if (var->flags & INMEMORY) {
1626 M_LLD(s1, REG_SP, 8 * var->regoff);
1630 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1631 M_IADD_IMM(s1, iptr->val.i, s1);
1633 else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1634 M_ISUB_IMM(s1, (-iptr->val.i), s1);
1637 M_LDA (s1, s1, iptr->val.i);
1638 M_IADD(s1, REG_ZERO, s1);
1640 if (var->flags & INMEMORY)
1641 M_LST(s1, REG_SP, 8 * var->regoff);
1645 /* floating operations ************************************************/
1647 case ICMD_FNEG: /* ..., value ==> ..., - value */
1649 var_to_reg_flt(s1, src, REG_FTMP1);
1650 d = reg_of_var(iptr->dst, REG_FTMP3);
1652 store_reg_to_var_flt(iptr->dst, d);
1655 case ICMD_DNEG: /* ..., value ==> ..., - value */
1657 var_to_reg_flt(s1, src, REG_FTMP1);
1658 d = reg_of_var(iptr->dst, REG_FTMP3);
1660 store_reg_to_var_flt(iptr->dst, d);
1663 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1665 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1666 var_to_reg_flt(s2, src, REG_FTMP2);
1667 d = reg_of_var(iptr->dst, REG_FTMP3);
1672 if (d == s1 || d == s2) {
1673 M_FADDS(s1, s2, REG_FTMP3);
1675 M_FMOV(REG_FTMP3, d);
1682 store_reg_to_var_flt(iptr->dst, d);
1685 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1687 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1688 var_to_reg_flt(s2, src, REG_FTMP2);
1689 d = reg_of_var(iptr->dst, REG_FTMP3);
1694 if (d == s1 || d == s2) {
1695 M_DADDS(s1, s2, REG_FTMP3);
1697 M_FMOV(REG_FTMP3, d);
1704 store_reg_to_var_flt(iptr->dst, d);
1707 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1709 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1710 var_to_reg_flt(s2, src, REG_FTMP2);
1711 d = reg_of_var(iptr->dst, REG_FTMP3);
1716 if (d == s1 || d == s2) {
1717 M_FSUBS(s1, s2, REG_FTMP3);
1719 M_FMOV(REG_FTMP3, d);
1726 store_reg_to_var_flt(iptr->dst, d);
1729 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1731 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1732 var_to_reg_flt(s2, src, REG_FTMP2);
1733 d = reg_of_var(iptr->dst, REG_FTMP3);
1738 if (d == s1 || d == s2) {
1739 M_DSUBS(s1, s2, REG_FTMP3);
1741 M_FMOV(REG_FTMP3, d);
1748 store_reg_to_var_flt(iptr->dst, d);
1751 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1753 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1754 var_to_reg_flt(s2, src, REG_FTMP2);
1755 d = reg_of_var(iptr->dst, REG_FTMP3);
1760 if (d == s1 || d == s2) {
1761 M_FMULS(s1, s2, REG_FTMP3);
1763 M_FMOV(REG_FTMP3, d);
1770 store_reg_to_var_flt(iptr->dst, d);
1773 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1775 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1776 var_to_reg_flt(s2, src, REG_FTMP2);
1777 d = reg_of_var(iptr->dst, REG_FTMP3);
1782 if (d == s1 || d == s2) {
1783 M_DMULS(s1, s2, REG_FTMP3);
1785 M_FMOV(REG_FTMP3, d);
1792 store_reg_to_var_flt(iptr->dst, d);
1795 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1797 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1798 var_to_reg_flt(s2, src, REG_FTMP2);
1799 d = reg_of_var(iptr->dst, REG_FTMP3);
1804 if (d == s1 || d == s2) {
1805 M_FDIVS(s1, s2, REG_FTMP3);
1807 M_FMOV(REG_FTMP3, d);
1814 store_reg_to_var_flt(iptr->dst, d);
1817 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1819 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1820 var_to_reg_flt(s2, src, REG_FTMP2);
1821 d = reg_of_var(iptr->dst, REG_FTMP3);
1826 if (d == s1 || d == s2) {
1827 M_DDIVS(s1, s2, REG_FTMP3);
1829 M_FMOV(REG_FTMP3, d);
1836 store_reg_to_var_flt(iptr->dst, d);
1839 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1841 var_to_reg_int(s1, src, REG_ITMP1);
1842 d = reg_of_var(iptr->dst, REG_FTMP3);
1843 a = dseg_adddouble(0.0);
1844 M_LST (s1, REG_PV, a);
1845 M_DLD (d, REG_PV, a);
1847 store_reg_to_var_flt(iptr->dst, d);
1850 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1852 var_to_reg_int(s1, src, REG_ITMP1);
1853 d = reg_of_var(iptr->dst, REG_FTMP3);
1854 a = dseg_adddouble(0.0);
1855 M_LST (s1, REG_PV, a);
1856 M_DLD (d, REG_PV, a);
1858 store_reg_to_var_flt(iptr->dst, d);
1861 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1863 var_to_reg_flt(s1, src, REG_FTMP1);
1864 d = reg_of_var(iptr->dst, REG_ITMP3);
1865 a = dseg_adddouble(0.0);
1866 M_CVTDL_C(s1, REG_FTMP2);
1867 M_CVTLI(REG_FTMP2, REG_FTMP3);
1868 M_DST (REG_FTMP3, REG_PV, a);
1869 M_ILD (d, REG_PV, a);
1870 store_reg_to_var_int(iptr->dst, d);
1873 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1875 var_to_reg_flt(s1, src, REG_FTMP1);
1876 d = reg_of_var(iptr->dst, REG_ITMP3);
1877 a = dseg_adddouble(0.0);
1878 M_CVTDL_C(s1, REG_FTMP2);
1879 M_DST (REG_FTMP2, REG_PV, a);
1880 M_LLD (d, REG_PV, a);
1881 store_reg_to_var_int(iptr->dst, d);
1884 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1886 var_to_reg_flt(s1, src, REG_FTMP1);
1887 d = reg_of_var(iptr->dst, REG_FTMP3);
1890 store_reg_to_var_flt(iptr->dst, d);
1893 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1895 var_to_reg_flt(s1, src, REG_FTMP1);
1896 d = reg_of_var(iptr->dst, REG_FTMP3);
1904 store_reg_to_var_flt(iptr->dst, d);
1907 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1909 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1910 var_to_reg_flt(s2, src, REG_FTMP2);
1911 d = reg_of_var(iptr->dst, REG_ITMP3);
1913 M_LSUB_IMM(REG_ZERO, 1, d);
1914 M_FCMPEQ(s1, s2, REG_FTMP3);
1915 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1917 M_FCMPLT(s2, s1, REG_FTMP3);
1918 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1919 M_LADD_IMM(REG_ZERO, 1, d);
1922 M_LSUB_IMM(REG_ZERO, 1, d);
1923 M_FCMPEQS(s1, s2, REG_FTMP3);
1925 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1927 M_FCMPLTS(s2, s1, REG_FTMP3);
1929 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1930 M_LADD_IMM(REG_ZERO, 1, d);
1932 store_reg_to_var_int(iptr->dst, d);
1935 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1937 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1938 var_to_reg_flt(s2, src, REG_FTMP2);
1939 d = reg_of_var(iptr->dst, REG_ITMP3);
1941 M_LADD_IMM(REG_ZERO, 1, d);
1942 M_FCMPEQ(s1, s2, REG_FTMP3);
1943 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1945 M_FCMPLT(s1, s2, REG_FTMP3);
1946 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1947 M_LSUB_IMM(REG_ZERO, 1, d);
1950 M_LADD_IMM(REG_ZERO, 1, d);
1951 M_FCMPEQS(s1, s2, REG_FTMP3);
1953 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1955 M_FCMPLTS(s1, s2, REG_FTMP3);
1957 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1958 M_LSUB_IMM(REG_ZERO, 1, d);
1960 store_reg_to_var_int(iptr->dst, d);
1964 /* memory operations **************************************************/
1966 /* #define gen_bound_check \
1968 M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\
1969 M_CMPULT(s2, REG_ITMP3, REG_ITMP3);\
1970 M_BEQZ(REG_ITMP3, 0);\
1971 codegen_addxboundrefs(mcodeptr);\
1975 #define gen_bound_check \
1976 if (checkbounds) { \
1977 M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\
1978 M_CMPULT(s2, REG_ITMP3, REG_ITMP3);\
1979 M_BEQZ(REG_ITMP3, 0);\
1980 codegen_addxboundrefs(mcodeptr, s2); \
1983 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1985 var_to_reg_int(s1, src, REG_ITMP1);
1986 d = reg_of_var(iptr->dst, REG_ITMP3);
1987 gen_nullptr_check(s1);
1988 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1989 store_reg_to_var_int(iptr->dst, d);
1992 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1994 var_to_reg_int(s1, src->prev, REG_ITMP1);
1995 var_to_reg_int(s2, src, REG_ITMP2);
1996 d = reg_of_var(iptr->dst, REG_ITMP3);
1997 if (iptr->op1 == 0) {
1998 gen_nullptr_check(s1);
2001 M_SAADDQ(s2, s1, REG_ITMP1);
2002 M_ALD( d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
2003 store_reg_to_var_int(iptr->dst, d);
2006 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
2008 var_to_reg_int(s1, src->prev, REG_ITMP1);
2009 var_to_reg_int(s2, src, REG_ITMP2);
2010 d = reg_of_var(iptr->dst, REG_ITMP3);
2011 if (iptr->op1 == 0) {
2012 gen_nullptr_check(s1);
2015 M_S8ADDQ(s2, s1, REG_ITMP1);
2016 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
2017 store_reg_to_var_int(iptr->dst, d);
2020 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
2022 var_to_reg_int(s1, src->prev, REG_ITMP1);
2023 var_to_reg_int(s2, src, REG_ITMP2);
2024 d = reg_of_var(iptr->dst, REG_ITMP3);
2025 if (iptr->op1 == 0) {
2026 gen_nullptr_check(s1);
2030 M_S4ADDQ(s2, s1, REG_ITMP1);
2031 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
2032 store_reg_to_var_int(iptr->dst, d);
2035 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
2037 var_to_reg_int(s1, src->prev, REG_ITMP1);
2038 var_to_reg_int(s2, src, REG_ITMP2);
2039 d = reg_of_var(iptr->dst, REG_FTMP3);
2040 if (iptr->op1 == 0) {
2041 gen_nullptr_check(s1);
2044 M_S4ADDQ(s2, s1, REG_ITMP1);
2045 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
2046 store_reg_to_var_flt(iptr->dst, d);
2049 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
2051 var_to_reg_int(s1, src->prev, REG_ITMP1);
2052 var_to_reg_int(s2, src, REG_ITMP2);
2053 d = reg_of_var(iptr->dst, REG_FTMP3);
2054 if (iptr->op1 == 0) {
2055 gen_nullptr_check(s1);
2058 M_S8ADDQ(s2, s1, REG_ITMP1);
2059 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
2060 store_reg_to_var_flt(iptr->dst, d);
2063 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
2065 var_to_reg_int(s1, src->prev, REG_ITMP1);
2066 var_to_reg_int(s2, src, REG_ITMP2);
2067 d = reg_of_var(iptr->dst, REG_ITMP3);
2068 if (iptr->op1 == 0) {
2069 gen_nullptr_check(s1);
2072 if (has_ext_instr_set) {
2073 M_LADD(s2, s1, REG_ITMP1);
2074 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2075 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
2078 M_LADD (s2, s1, REG_ITMP1);
2079 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2080 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2081 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2082 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
2084 store_reg_to_var_int(iptr->dst, d);
2087 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
2089 var_to_reg_int(s1, src->prev, REG_ITMP1);
2090 var_to_reg_int(s2, src, REG_ITMP2);
2091 d = reg_of_var(iptr->dst, REG_ITMP3);
2092 if (iptr->op1 == 0) {
2093 gen_nullptr_check(s1);
2096 if (has_ext_instr_set) {
2097 M_LADD(s2, s1, REG_ITMP1);
2098 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2099 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
2103 M_LADD(s2, s1, REG_ITMP1);
2104 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2105 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2106 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
2107 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
2108 M_SRA_IMM(d, 48, d);
2110 store_reg_to_var_int(iptr->dst, d);
2113 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
2115 var_to_reg_int(s1, src->prev, REG_ITMP1);
2116 var_to_reg_int(s2, src, REG_ITMP2);
2117 d = reg_of_var(iptr->dst, REG_ITMP3);
2118 if (iptr->op1 == 0) {
2119 gen_nullptr_check(s1);
2122 if (has_ext_instr_set) {
2123 M_LADD (s2, s1, REG_ITMP1);
2124 M_BLDU (d, REG_ITMP1, OFFSET (java_bytearray, data[0]));
2128 M_LADD(s2, s1, REG_ITMP1);
2129 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2130 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
2131 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
2132 M_SRA_IMM(d, 56, d);
2134 store_reg_to_var_int(iptr->dst, d);
2138 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
2140 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2141 var_to_reg_int(s2, src->prev, REG_ITMP2);
2142 if (iptr->op1 == 0) {
2143 gen_nullptr_check(s1);
2146 var_to_reg_int(s3, src, REG_ITMP3);
2147 M_SAADDQ(s2, s1, REG_ITMP1);
2148 M_AST (s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
2151 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
2153 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2154 var_to_reg_int(s2, src->prev, REG_ITMP2);
2155 if (iptr->op1 == 0) {
2156 gen_nullptr_check(s1);
2159 var_to_reg_int(s3, src, REG_ITMP3);
2160 M_S8ADDQ(s2, s1, REG_ITMP1);
2161 M_LST (s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
2164 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
2166 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2167 var_to_reg_int(s2, src->prev, REG_ITMP2);
2168 if (iptr->op1 == 0) {
2169 gen_nullptr_check(s1);
2173 var_to_reg_int(s3, src, REG_ITMP3);
2174 M_S4ADDQ(s2, s1, REG_ITMP1);
2175 M_IST (s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
2178 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
2180 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2181 var_to_reg_int(s2, src->prev, REG_ITMP2);
2182 if (iptr->op1 == 0) {
2183 gen_nullptr_check(s1);
2186 var_to_reg_flt(s3, src, REG_FTMP3);
2187 M_S4ADDQ(s2, s1, REG_ITMP1);
2188 M_FST (s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
2191 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
2193 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2194 var_to_reg_int(s2, src->prev, REG_ITMP2);
2195 if (iptr->op1 == 0) {
2196 gen_nullptr_check(s1);
2199 var_to_reg_flt(s3, src, REG_FTMP3);
2200 M_S8ADDQ(s2, s1, REG_ITMP1);
2201 M_DST (s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
2204 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
2206 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2207 var_to_reg_int(s2, src->prev, REG_ITMP2);
2208 if (iptr->op1 == 0) {
2209 gen_nullptr_check(s1);
2212 var_to_reg_int(s3, src, REG_ITMP3);
2213 if (has_ext_instr_set) {
2214 M_LADD(s2, s1, REG_ITMP1);
2215 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2216 M_SST (s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
2219 M_LADD (s2, s1, REG_ITMP1);
2220 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2221 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2222 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2223 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
2224 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2225 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2226 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2230 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
2232 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2233 var_to_reg_int(s2, src->prev, REG_ITMP2);
2234 if (iptr->op1 == 0) {
2235 gen_nullptr_check(s1);
2238 var_to_reg_int(s3, src, REG_ITMP3);
2239 if (has_ext_instr_set) {
2240 M_LADD(s2, s1, REG_ITMP1);
2241 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2242 M_SST (s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2245 M_LADD (s2, s1, REG_ITMP1);
2246 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2247 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2248 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2249 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
2250 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2251 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2252 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2256 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
2258 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2259 var_to_reg_int(s2, src->prev, REG_ITMP2);
2260 if (iptr->op1 == 0) {
2261 gen_nullptr_check(s1);
2264 var_to_reg_int(s3, src, REG_ITMP3);
2265 if (has_ext_instr_set) {
2266 M_LADD(s2, s1, REG_ITMP1);
2267 M_BST (s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2270 M_LADD (s2, s1, REG_ITMP1);
2271 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2272 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2273 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
2274 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2275 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2276 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2281 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2282 /* op1 = type, val.a = field address */
2284 /* if class isn't yet initialized, do it */
2285 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
2286 /* call helper function which patches this code */
2287 a = dseg_addaddress(((fieldinfo *) iptr->val.a)->class);
2288 M_ALD(REG_ITMP1, REG_PV, a);
2289 a = dseg_addaddress(asm_check_clinit);
2290 M_ALD(REG_PV, REG_PV, a);
2291 M_JSR(REG_RA, REG_PV);
2294 s1 = (int) ((u1*) mcodeptr - mcodebase);
2296 M_LDA(REG_PV, REG_RA, -s1);
2300 s4 ml = -s1, mh = 0;
2301 while (ml < -32768) { ml += 65536; mh--; }
2302 M_LDA(REG_PV, REG_RA, ml);
2303 M_LDAH(REG_PV, REG_PV, mh);
2307 a = dseg_addaddress(&(((fieldinfo *)(iptr->val.a))->value));
2308 M_ALD(REG_ITMP1, REG_PV, a);
2309 switch (iptr->op1) {
2311 var_to_reg_int(s2, src, REG_ITMP2);
2312 M_IST(s2, REG_ITMP1, 0);
2315 var_to_reg_int(s2, src, REG_ITMP2);
2316 M_LST(s2, REG_ITMP1, 0);
2319 var_to_reg_int(s2, src, REG_ITMP2);
2320 M_AST(s2, REG_ITMP1, 0);
2323 var_to_reg_flt(s2, src, REG_FTMP2);
2324 M_FST(s2, REG_ITMP1, 0);
2327 var_to_reg_flt(s2, src, REG_FTMP2);
2328 M_DST(s2, REG_ITMP1, 0);
2330 default: panic ("internal error");
2334 case ICMD_GETSTATIC: /* ... ==> ..., value */
2335 /* op1 = type, val.a = field address */
2337 /* if class isn't yet initialized, do it */
2338 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
2339 /* call helper function which patches this code */
2340 a = dseg_addaddress(((fieldinfo *) iptr->val.a)->class);
2341 M_ALD(REG_ITMP1, REG_PV, a);
2342 a = dseg_addaddress(asm_check_clinit);
2343 M_ALD(REG_PV, REG_PV, a);
2344 M_JSR(REG_RA, REG_PV);
2347 s1 = (int) ((u1*) mcodeptr - mcodebase);
2349 M_LDA(REG_PV, REG_RA, -s1);
2353 s4 ml = -s1, mh = 0;
2354 while (ml < -32768) { ml += 65536; mh--; }
2355 M_LDA(REG_PV, REG_RA, ml);
2356 M_LDAH(REG_PV, REG_PV, mh);
2360 a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value));
2361 M_ALD(REG_ITMP1, REG_PV, a);
2362 switch (iptr->op1) {
2364 d = reg_of_var(iptr->dst, REG_ITMP3);
2365 M_ILD(d, REG_ITMP1, 0);
2366 store_reg_to_var_int(iptr->dst, d);
2369 d = reg_of_var(iptr->dst, REG_ITMP3);
2370 M_LLD(d, REG_ITMP1, 0);
2371 store_reg_to_var_int(iptr->dst, d);
2374 d = reg_of_var(iptr->dst, REG_ITMP3);
2375 M_ALD(d, REG_ITMP1, 0);
2376 store_reg_to_var_int(iptr->dst, d);
2379 d = reg_of_var(iptr->dst, REG_FTMP1);
2380 M_FLD(d, REG_ITMP1, 0);
2381 store_reg_to_var_flt(iptr->dst, d);
2384 d = reg_of_var(iptr->dst, REG_FTMP1);
2385 M_DLD(d, REG_ITMP1, 0);
2386 store_reg_to_var_flt(iptr->dst, d);
2388 default: panic ("internal error");
2393 case ICMD_PUTFIELD: /* ..., value ==> ... */
2394 /* op1 = type, val.i = field offset */
2396 a = ((fieldinfo *)(iptr->val.a))->offset;
2397 switch (iptr->op1) {
2399 var_to_reg_int(s1, src->prev, REG_ITMP1);
2400 var_to_reg_int(s2, src, REG_ITMP2);
2401 gen_nullptr_check(s1);
2405 var_to_reg_int(s1, src->prev, REG_ITMP1);
2406 var_to_reg_int(s2, src, REG_ITMP2);
2407 gen_nullptr_check(s1);
2411 var_to_reg_int(s1, src->prev, REG_ITMP1);
2412 var_to_reg_int(s2, src, REG_ITMP2);
2413 gen_nullptr_check(s1);
2417 var_to_reg_int(s1, src->prev, REG_ITMP1);
2418 var_to_reg_flt(s2, src, REG_FTMP2);
2419 gen_nullptr_check(s1);
2423 var_to_reg_int(s1, src->prev, REG_ITMP1);
2424 var_to_reg_flt(s2, src, REG_FTMP2);
2425 gen_nullptr_check(s1);
2428 default: panic ("internal error");
2432 case ICMD_GETFIELD: /* ... ==> ..., value */
2433 /* op1 = type, val.i = field offset */
2435 a = ((fieldinfo *)(iptr->val.a))->offset;
2436 switch (iptr->op1) {
2438 var_to_reg_int(s1, src, REG_ITMP1);
2439 d = reg_of_var(iptr->dst, REG_ITMP3);
2440 gen_nullptr_check(s1);
2442 store_reg_to_var_int(iptr->dst, d);
2445 var_to_reg_int(s1, src, REG_ITMP1);
2446 d = reg_of_var(iptr->dst, REG_ITMP3);
2447 gen_nullptr_check(s1);
2449 store_reg_to_var_int(iptr->dst, d);
2452 var_to_reg_int(s1, src, REG_ITMP1);
2453 d = reg_of_var(iptr->dst, REG_ITMP3);
2454 gen_nullptr_check(s1);
2456 store_reg_to_var_int(iptr->dst, d);
2459 var_to_reg_int(s1, src, REG_ITMP1);
2460 d = reg_of_var(iptr->dst, REG_FTMP1);
2461 gen_nullptr_check(s1);
2463 store_reg_to_var_flt(iptr->dst, d);
2466 var_to_reg_int(s1, src, REG_ITMP1);
2467 d = reg_of_var(iptr->dst, REG_FTMP1);
2468 gen_nullptr_check(s1);
2470 store_reg_to_var_flt(iptr->dst, d);
2472 default: panic ("internal error");
2477 /* branch operations **************************************************/
2479 #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}}
2481 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2483 var_to_reg_int(s1, src, REG_ITMP1);
2484 M_INTMOVE(s1, REG_ITMP1_XPTR);
2485 a = dseg_addaddress(asm_handle_exception);
2486 M_ALD(REG_ITMP2, REG_PV, a);
2487 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2488 M_NOP; /* nop ensures that XPC is less than the end */
2489 /* of basic block */
2493 case ICMD_GOTO: /* ... ==> ... */
2494 /* op1 = target JavaVM pc */
2496 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2500 case ICMD_JSR: /* ... ==> ... */
2501 /* op1 = target JavaVM pc */
2503 M_BSR(REG_ITMP1, 0);
2504 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2507 case ICMD_RET: /* ... ==> ... */
2508 /* op1 = local variable */
2510 var = &(locals[iptr->op1][TYPE_ADR]);
2511 if (var->flags & INMEMORY) {
2512 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2513 M_RET(REG_ZERO, REG_ITMP1);
2516 M_RET(REG_ZERO, var->regoff);
2520 case ICMD_IFNULL: /* ..., 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_IFNONNULL: /* ..., value ==> ... */
2529 /* op1 = target JavaVM pc */
2531 var_to_reg_int(s1, src, REG_ITMP1);
2533 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2536 case ICMD_IFEQ: /* ..., value ==> ... */
2537 /* op1 = target JavaVM pc, val.i = constant */
2539 var_to_reg_int(s1, src, REG_ITMP1);
2540 if (iptr->val.i == 0) {
2544 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2545 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2548 ICONST(REG_ITMP2, iptr->val.i);
2549 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2551 M_BNEZ(REG_ITMP1, 0);
2553 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2556 case ICMD_IFLT: /* ..., value ==> ... */
2557 /* op1 = target JavaVM pc, val.i = constant */
2559 var_to_reg_int(s1, src, REG_ITMP1);
2560 if (iptr->val.i == 0) {
2564 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2565 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2568 ICONST(REG_ITMP2, iptr->val.i);
2569 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2571 M_BNEZ(REG_ITMP1, 0);
2573 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2576 case ICMD_IFLE: /* ..., value ==> ... */
2577 /* op1 = target JavaVM pc, val.i = constant */
2579 var_to_reg_int(s1, src, REG_ITMP1);
2580 if (iptr->val.i == 0) {
2584 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2585 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2588 ICONST(REG_ITMP2, iptr->val.i);
2589 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2591 M_BNEZ(REG_ITMP1, 0);
2593 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2596 case ICMD_IFNE: /* ..., value ==> ... */
2597 /* op1 = target JavaVM pc, val.i = constant */
2599 var_to_reg_int(s1, src, REG_ITMP1);
2600 if (iptr->val.i == 0) {
2604 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2605 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2608 ICONST(REG_ITMP2, iptr->val.i);
2609 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2611 M_BEQZ(REG_ITMP1, 0);
2613 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2616 case ICMD_IFGT: /* ..., value ==> ... */
2617 /* op1 = target JavaVM pc, val.i = constant */
2619 var_to_reg_int(s1, src, REG_ITMP1);
2620 if (iptr->val.i == 0) {
2624 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2625 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2628 ICONST(REG_ITMP2, iptr->val.i);
2629 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2631 M_BEQZ(REG_ITMP1, 0);
2633 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2636 case ICMD_IFGE: /* ..., value ==> ... */
2637 /* op1 = target JavaVM pc, val.i = constant */
2639 var_to_reg_int(s1, src, REG_ITMP1);
2640 if (iptr->val.i == 0) {
2644 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2645 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2648 ICONST(REG_ITMP2, iptr->val.i);
2649 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2651 M_BEQZ(REG_ITMP1, 0);
2653 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2656 case ICMD_IF_LEQ: /* ..., value ==> ... */
2657 /* op1 = target JavaVM pc, val.l = constant */
2659 var_to_reg_int(s1, src, REG_ITMP1);
2660 if (iptr->val.l == 0) {
2664 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2665 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2668 LCONST(REG_ITMP2, iptr->val.l);
2669 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2671 M_BNEZ(REG_ITMP1, 0);
2673 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2676 case ICMD_IF_LLT: /* ..., value ==> ... */
2677 /* op1 = target JavaVM pc, val.l = constant */
2679 var_to_reg_int(s1, src, REG_ITMP1);
2680 if (iptr->val.l == 0) {
2684 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2685 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2688 LCONST(REG_ITMP2, iptr->val.l);
2689 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2691 M_BNEZ(REG_ITMP1, 0);
2693 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2696 case ICMD_IF_LLE: /* ..., value ==> ... */
2697 /* op1 = target JavaVM pc, val.l = constant */
2699 var_to_reg_int(s1, src, REG_ITMP1);
2700 if (iptr->val.l == 0) {
2704 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2705 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2708 LCONST(REG_ITMP2, iptr->val.l);
2709 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2711 M_BNEZ(REG_ITMP1, 0);
2713 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2716 case ICMD_IF_LNE: /* ..., value ==> ... */
2717 /* op1 = target JavaVM pc, val.l = constant */
2719 var_to_reg_int(s1, src, REG_ITMP1);
2720 if (iptr->val.l == 0) {
2724 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2725 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2728 LCONST(REG_ITMP2, iptr->val.l);
2729 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2731 M_BEQZ(REG_ITMP1, 0);
2733 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2736 case ICMD_IF_LGT: /* ..., value ==> ... */
2737 /* op1 = target JavaVM pc, val.l = constant */
2739 var_to_reg_int(s1, src, REG_ITMP1);
2740 if (iptr->val.l == 0) {
2744 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2745 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2748 LCONST(REG_ITMP2, iptr->val.l);
2749 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2751 M_BEQZ(REG_ITMP1, 0);
2753 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2756 case ICMD_IF_LGE: /* ..., value ==> ... */
2757 /* op1 = target JavaVM pc, val.l = constant */
2759 var_to_reg_int(s1, src, REG_ITMP1);
2760 if (iptr->val.l == 0) {
2764 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2765 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2768 LCONST(REG_ITMP2, iptr->val.l);
2769 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2771 M_BEQZ(REG_ITMP1, 0);
2773 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2776 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2777 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2778 case ICMD_IF_ACMPEQ:
2780 var_to_reg_int(s1, src->prev, REG_ITMP1);
2781 var_to_reg_int(s2, src, REG_ITMP2);
2782 M_CMPEQ(s1, s2, REG_ITMP1);
2783 M_BNEZ(REG_ITMP1, 0);
2784 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2787 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2788 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2789 case ICMD_IF_ACMPNE:
2791 var_to_reg_int(s1, src->prev, REG_ITMP1);
2792 var_to_reg_int(s2, src, REG_ITMP2);
2793 M_CMPEQ(s1, s2, REG_ITMP1);
2794 M_BEQZ(REG_ITMP1, 0);
2795 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2798 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2799 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2801 var_to_reg_int(s1, src->prev, REG_ITMP1);
2802 var_to_reg_int(s2, src, REG_ITMP2);
2803 M_CMPLT(s1, s2, REG_ITMP1);
2804 M_BNEZ(REG_ITMP1, 0);
2805 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2808 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2809 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2811 var_to_reg_int(s1, src->prev, REG_ITMP1);
2812 var_to_reg_int(s2, src, REG_ITMP2);
2813 M_CMPLE(s1, s2, REG_ITMP1);
2814 M_BEQZ(REG_ITMP1, 0);
2815 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2818 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2819 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2821 var_to_reg_int(s1, src->prev, REG_ITMP1);
2822 var_to_reg_int(s2, src, REG_ITMP2);
2823 M_CMPLE(s1, s2, REG_ITMP1);
2824 M_BNEZ(REG_ITMP1, 0);
2825 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2828 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2829 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2831 var_to_reg_int(s1, src->prev, REG_ITMP1);
2832 var_to_reg_int(s2, src, REG_ITMP2);
2833 M_CMPLT(s1, s2, REG_ITMP1);
2834 M_BEQZ(REG_ITMP1, 0);
2835 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2838 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2840 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2843 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2844 /* val.i = constant */
2846 var_to_reg_int(s1, src, REG_ITMP1);
2847 d = reg_of_var(iptr->dst, REG_ITMP3);
2849 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2850 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2851 M_CMPEQ(s1, REG_ZERO, d);
2852 store_reg_to_var_int(iptr->dst, d);
2855 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2856 M_CMPEQ(s1, REG_ZERO, d);
2858 store_reg_to_var_int(iptr->dst, d);
2862 M_MOV(s1, REG_ITMP1);
2865 ICONST(d, iptr[1].val.i);
2867 if ((s3 >= 0) && (s3 <= 255)) {
2868 M_CMOVEQ_IMM(s1, s3, d);
2871 ICONST(REG_ITMP2, s3);
2872 M_CMOVEQ(s1, REG_ITMP2, d);
2874 store_reg_to_var_int(iptr->dst, d);
2877 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2878 /* val.i = constant */
2880 var_to_reg_int(s1, src, REG_ITMP1);
2881 d = reg_of_var(iptr->dst, REG_ITMP3);
2883 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2884 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2885 M_CMPEQ(s1, REG_ZERO, d);
2886 store_reg_to_var_int(iptr->dst, d);
2889 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2890 M_CMPEQ(s1, REG_ZERO, d);
2892 store_reg_to_var_int(iptr->dst, d);
2896 M_MOV(s1, REG_ITMP1);
2899 ICONST(d, iptr[1].val.i);
2901 if ((s3 >= 0) && (s3 <= 255)) {
2902 M_CMOVNE_IMM(s1, s3, d);
2905 ICONST(REG_ITMP2, s3);
2906 M_CMOVNE(s1, REG_ITMP2, d);
2908 store_reg_to_var_int(iptr->dst, d);
2911 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2912 /* val.i = constant */
2914 var_to_reg_int(s1, src, REG_ITMP1);
2915 d = reg_of_var(iptr->dst, REG_ITMP3);
2917 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2918 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2919 M_CMPLT(s1, REG_ZERO, d);
2920 store_reg_to_var_int(iptr->dst, d);
2923 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2924 M_CMPLE(REG_ZERO, s1, d);
2925 store_reg_to_var_int(iptr->dst, d);
2929 M_MOV(s1, REG_ITMP1);
2932 ICONST(d, iptr[1].val.i);
2934 if ((s3 >= 0) && (s3 <= 255)) {
2935 M_CMOVLT_IMM(s1, s3, d);
2938 ICONST(REG_ITMP2, s3);
2939 M_CMOVLT(s1, REG_ITMP2, d);
2941 store_reg_to_var_int(iptr->dst, d);
2944 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2945 /* val.i = constant */
2947 var_to_reg_int(s1, src, REG_ITMP1);
2948 d = reg_of_var(iptr->dst, REG_ITMP3);
2950 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2951 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2952 M_CMPLE(REG_ZERO, s1, d);
2953 store_reg_to_var_int(iptr->dst, d);
2956 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2957 M_CMPLT(s1, REG_ZERO, d);
2958 store_reg_to_var_int(iptr->dst, d);
2962 M_MOV(s1, REG_ITMP1);
2965 ICONST(d, iptr[1].val.i);
2967 if ((s3 >= 0) && (s3 <= 255)) {
2968 M_CMOVGE_IMM(s1, s3, d);
2971 ICONST(REG_ITMP2, s3);
2972 M_CMOVGE(s1, REG_ITMP2, d);
2974 store_reg_to_var_int(iptr->dst, d);
2977 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2978 /* val.i = constant */
2980 var_to_reg_int(s1, src, REG_ITMP1);
2981 d = reg_of_var(iptr->dst, REG_ITMP3);
2983 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2984 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2985 M_CMPLT(REG_ZERO, s1, d);
2986 store_reg_to_var_int(iptr->dst, d);
2989 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2990 M_CMPLE(s1, REG_ZERO, d);
2991 store_reg_to_var_int(iptr->dst, d);
2995 M_MOV(s1, REG_ITMP1);
2998 ICONST(d, iptr[1].val.i);
3000 if ((s3 >= 0) && (s3 <= 255)) {
3001 M_CMOVGT_IMM(s1, s3, d);
3004 ICONST(REG_ITMP2, s3);
3005 M_CMOVGT(s1, REG_ITMP2, d);
3007 store_reg_to_var_int(iptr->dst, d);
3010 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
3011 /* val.i = constant */
3013 var_to_reg_int(s1, src, REG_ITMP1);
3014 d = reg_of_var(iptr->dst, REG_ITMP3);
3016 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
3017 if ((s3 == 1) && (iptr[1].val.i == 0)) {
3018 M_CMPLE(s1, REG_ZERO, d);
3019 store_reg_to_var_int(iptr->dst, d);
3022 if ((s3 == 0) && (iptr[1].val.i == 1)) {
3023 M_CMPLT(REG_ZERO, s1, d);
3024 store_reg_to_var_int(iptr->dst, d);
3028 M_MOV(s1, REG_ITMP1);
3031 ICONST(d, iptr[1].val.i);
3033 if ((s3 >= 0) && (s3 <= 255)) {
3034 M_CMOVLE_IMM(s1, s3, d);
3037 ICONST(REG_ITMP2, s3);
3038 M_CMOVLE(s1, REG_ITMP2, d);
3040 store_reg_to_var_int(iptr->dst, d);
3044 case ICMD_IRETURN: /* ..., retvalue ==> ... */
3048 var_to_reg_int(s1, src, REG_RESULT);
3049 M_INTMOVE(s1, REG_RESULT);
3052 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3054 a = dseg_addaddress((void *) (builtin_monitorexit));
3055 M_ALD(REG_PV, REG_PV, a);
3056 M_ALD(argintregs[0], REG_SP, maxmemuse * 8);
3057 M_LST(REG_RESULT, REG_SP, maxmemuse * 8);
3058 M_JSR(REG_RA, REG_PV);
3059 disp = -(int) ((u1 *) mcodeptr - mcodebase);
3060 M_LDA(REG_PV, REG_RA, disp);
3061 M_LLD(REG_RESULT, REG_SP, maxmemuse * 8);
3065 goto nowperformreturn;
3067 case ICMD_FRETURN: /* ..., retvalue ==> ... */
3070 var_to_reg_flt(s1, src, REG_FRESULT);
3071 M_FLTMOVE(s1, REG_FRESULT);
3074 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3076 a = dseg_addaddress((void *) (builtin_monitorexit));
3077 M_ALD(REG_PV, REG_PV, a);
3078 M_ALD(argintregs[0], REG_SP, maxmemuse * 8);
3079 M_DST(REG_FRESULT, REG_SP, maxmemuse * 8);
3080 M_JSR(REG_RA, REG_PV);
3081 disp = -(int) ((u1 *) mcodeptr - mcodebase);
3082 M_LDA(REG_PV, REG_RA, disp);
3083 M_DLD(REG_FRESULT, REG_SP, maxmemuse * 8);
3087 goto nowperformreturn;
3089 case ICMD_RETURN: /* ... ==> ... */
3092 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3094 a = dseg_addaddress((void *) (builtin_monitorexit));
3095 M_ALD(REG_PV, REG_PV, a);
3096 M_ALD(argintregs[0], REG_SP, maxmemuse * 8);
3097 M_JSR(REG_RA, REG_PV);
3098 disp = -(int) ((u1 *) mcodeptr - mcodebase);
3099 M_LDA(REG_PV, REG_RA, disp);
3107 p = parentargs_base;
3109 /* restore return address */
3112 {p--; M_LLD (REG_RA, REG_SP, 8 * p);}
3114 /* restore saved registers */
3116 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
3117 {p--; M_LLD(savintregs[r], REG_SP, 8 * p);}
3118 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
3119 {p--; M_DLD(savfltregs[r], REG_SP, 8 * p);}
3121 /* deallocate stack */
3123 if (parentargs_base)
3124 {M_LDA(REG_SP, REG_SP, parentargs_base*8);}
3126 /* call trace function */
3129 M_LDA(REG_SP, REG_SP, -3 * 8);
3130 M_AST(REG_RA, REG_SP, 0 * 8);
3131 M_LST(REG_RESULT, REG_SP, 1 * 8);
3132 M_DST(REG_FRESULT, REG_SP, 2 * 8);
3133 a = dseg_addaddress(method);
3134 M_ALD(argintregs[0], REG_PV, a);
3135 M_MOV(REG_RESULT, argintregs[1]);
3136 M_FLTMOVE(REG_FRESULT, argfltregs[2]);
3137 M_FLTMOVE(REG_FRESULT, argfltregs[3]);
3138 a = dseg_addaddress((void *) builtin_displaymethodstop);
3139 M_ALD(REG_PV, REG_PV, a);
3140 M_JSR(REG_RA, REG_PV);
3141 s1 = (int) ((u1 *) mcodeptr - mcodebase);
3142 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3144 s4 ml = -s1, mh = 0;
3145 while (ml < -32768) { ml += 65536; mh--; }
3146 M_LDA(REG_PV, REG_RA, ml);
3147 M_LDAH(REG_PV, REG_PV, mh);
3149 M_DLD(REG_FRESULT, REG_SP, 2 * 8);
3150 M_LLD(REG_RESULT, REG_SP, 1 * 8);
3151 M_ALD(REG_RA, REG_SP, 0 * 8);
3152 M_LDA(REG_SP, REG_SP, 3 * 8);
3155 M_RET(REG_ZERO, REG_RA);
3161 case ICMD_TABLESWITCH: /* ..., index ==> ... */
3166 tptr = (void **) iptr->target;
3168 s4ptr = iptr->val.a;
3169 l = s4ptr[1]; /* low */
3170 i = s4ptr[2]; /* high */
3172 var_to_reg_int(s1, src, REG_ITMP1);
3174 {M_INTMOVE(s1, REG_ITMP1);}
3175 else if (l <= 32768) {
3176 M_LDA(REG_ITMP1, s1, -l);
3179 ICONST(REG_ITMP2, l);
3180 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
3187 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
3189 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
3190 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3192 M_BEQZ(REG_ITMP2, 0);
3195 /* codegen_addreference(BlockPtrOfPC(s4ptr[0]), mcodeptr); */
3196 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3198 /* build jump table top down and use address of lowest entry */
3200 /* s4ptr += 3 + i; */
3204 /* dseg_addtarget(BlockPtrOfPC(*--s4ptr)); */
3205 dseg_addtarget((basicblock *) tptr[0]);
3210 /* length of dataseg after last dseg_addtarget is used by load */
3212 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
3213 M_ALD(REG_ITMP2, REG_ITMP2, -dseglen);
3214 M_JMP(REG_ZERO, REG_ITMP2);
3219 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3221 s4 i, l, val, *s4ptr;
3224 tptr = (void **) iptr->target;
3226 s4ptr = iptr->val.a;
3227 l = s4ptr[0]; /* default */
3228 i = s4ptr[1]; /* count */
3230 MCODECHECK((i<<2)+8);
3231 var_to_reg_int(s1, src, REG_ITMP1);
3237 if ((val >= 0) && (val <= 255)) {
3238 M_CMPEQ_IMM(s1, val, REG_ITMP2);
3241 if ((val >= -32768) && (val <= 32767)) {
3242 M_LDA(REG_ITMP2, REG_ZERO, val);
3245 a = dseg_adds4 (val);
3246 M_ILD(REG_ITMP2, REG_PV, a);
3248 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
3250 M_BNEZ(REG_ITMP2, 0);
3251 /* codegen_addreference(BlockPtrOfPC(s4ptr[1]), mcodeptr); */
3252 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3256 /* codegen_addreference(BlockPtrOfPC(l), mcodeptr); */
3258 tptr = (void **) iptr->target;
3259 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3266 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
3267 /* op1 = return type, val.a = function pointer*/
3271 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
3272 /* op1 = return type, val.a = function pointer*/
3276 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
3277 /* op1 = return type, val.a = function pointer*/
3281 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3282 /* op1 = arg count, val.a = method pointer */
3284 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3285 /* op1 = arg count, val.a = method pointer */
3287 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3288 /* op1 = arg count, val.a = method pointer */
3290 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
3291 /* op1 = arg count, val.a = method pointer */
3299 MCODECHECK((s3 << 1) + 64);
3301 /* copy arguments to registers or stack location */
3303 for (; --s3 >= 0; src = src->prev) {
3304 if (src->varkind == ARGVAR)
3306 if (IS_INT_LNG_TYPE(src->type)) {
3307 if (s3 < INT_ARG_CNT) {
3308 s1 = argintregs[s3];
3309 var_to_reg_int(d, src, s1);
3313 var_to_reg_int(d, src, REG_ITMP1);
3314 M_LST(d, REG_SP, 8 * (s3 - INT_ARG_CNT));
3318 if (s3 < FLT_ARG_CNT) {
3319 s1 = argfltregs[s3];
3320 var_to_reg_flt(d, src, s1);
3324 var_to_reg_flt(d, src, REG_FTMP1);
3325 M_DST(d, REG_SP, 8 * (s3 - FLT_ARG_CNT));
3330 switch (iptr->opc) {
3334 a = dseg_addaddress ((void*) (m));
3336 M_ALD(REG_PV, REG_PV, a); /* Pointer to built-in-function */
3338 goto makeactualcall;
3340 case ICMD_INVOKESTATIC:
3341 case ICMD_INVOKESPECIAL:
3342 a = dseg_addaddress (m->stubroutine);
3344 M_ALD(REG_PV, REG_PV, a ); /* method pointer in r27 */
3347 goto makeactualcall;
3349 case ICMD_INVOKEVIRTUAL:
3351 gen_nullptr_check(argintregs[0]);
3352 M_ALD(REG_METHODPTR, argintregs[0],
3353 OFFSET(java_objectheader, vftbl));
3354 M_ALD(REG_PV, REG_METHODPTR, OFFSET(vftbl, table[0]) +
3355 sizeof(methodptr) * m->vftblindex);
3358 goto makeactualcall;
3360 case ICMD_INVOKEINTERFACE:
3363 gen_nullptr_check(argintregs[0]);
3364 M_ALD(REG_METHODPTR, argintregs[0],
3365 OFFSET(java_objectheader, vftbl));
3366 M_ALD(REG_METHODPTR, REG_METHODPTR,
3367 OFFSET(vftbl, interfacetable[0]) -
3368 sizeof(methodptr*) * ci->index);
3369 M_ALD(REG_PV, REG_METHODPTR,
3370 sizeof(methodptr) * (m - ci->methods));
3373 goto makeactualcall;
3377 error ("Unkown ICMD-Command: %d", iptr->opc);
3382 M_JSR (REG_RA, REG_PV);
3386 s1 = (int)((u1*) mcodeptr - mcodebase);
3387 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
3390 while (ml<-32768) { ml+=65536; mh--; }
3391 M_LDA (REG_PV, REG_RA, ml );
3392 M_LDAH (REG_PV, REG_PV, mh );
3395 /* d contains return type */
3397 if (d != TYPE_VOID) {
3398 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3399 s1 = reg_of_var(iptr->dst, REG_RESULT);
3400 M_INTMOVE(REG_RESULT, s1);
3401 store_reg_to_var_int(iptr->dst, s1);
3404 s1 = reg_of_var(iptr->dst, REG_FRESULT);
3405 M_FLTMOVE(REG_FRESULT, s1);
3406 store_reg_to_var_flt(iptr->dst, s1);
3413 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3415 /* op1: 0 == array, 1 == class */
3416 /* val.a: (classinfo*) superclass */
3418 /* superclass is an interface:
3420 * return (sub != NULL) &&
3421 * (sub->vftbl->interfacetablelength > super->index) &&
3422 * (sub->vftbl->interfacetable[-super->index] != NULL);
3424 * superclass is a class:
3426 * return ((sub != NULL) && (0
3427 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3428 * super->vftbl->diffvall));
3432 classinfo *super = (classinfo*) iptr->val.a;
3434 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3435 codegen_threadcritrestart((u1*) mcodeptr - mcodebase);
3437 var_to_reg_int(s1, src, REG_ITMP1);
3438 d = reg_of_var(iptr->dst, REG_ITMP3);
3440 M_MOV(s1, REG_ITMP1);
3444 if (iptr->op1) { /* class/interface */
3445 if (super->flags & ACC_INTERFACE) { /* interface */
3447 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3448 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3449 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3450 M_BLEZ(REG_ITMP2, 2);
3451 M_ALD(REG_ITMP1, REG_ITMP1,
3452 OFFSET(vftbl, interfacetable[0]) -
3453 super->index * sizeof(methodptr*));
3454 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3458 s2 = super->vftbl->diffval;
3459 M_BEQZ(s1, 4 + (s2 > 255));
3460 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3461 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3462 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3464 M_CMPULE_IMM(REG_ITMP1, s2, d);
3466 M_LDA(REG_ITMP2, REG_ZERO, s2);
3467 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3471 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3472 a = dseg_addaddress ((void*) super->vftbl);
3473 M_ALD(REG_ITMP2, REG_PV, a);
3474 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3475 codegen_threadcritstart((u1*) mcodeptr - mcodebase);
3477 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3478 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl, baseval));
3479 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, diffval));
3480 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3481 codegen_threadcritstop((u1*) mcodeptr - mcodebase);
3483 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3484 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3488 panic ("internal error: no inlined array instanceof");
3490 store_reg_to_var_int(iptr->dst, d);
3493 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3495 /* op1: 0 == array, 1 == class */
3496 /* val.a: (classinfo*) superclass */
3498 /* superclass is an interface:
3500 * OK if ((sub == NULL) ||
3501 * (sub->vftbl->interfacetablelength > super->index) &&
3502 * (sub->vftbl->interfacetable[-super->index] != NULL));
3504 * superclass is a class:
3506 * OK if ((sub == NULL) || (0
3507 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3508 * super->vftbl->diffvall));
3512 classinfo *super = (classinfo*) iptr->val.a;
3514 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3515 codegen_threadcritrestart((u1*) mcodeptr - mcodebase);
3517 d = reg_of_var(iptr->dst, REG_ITMP3);
3518 var_to_reg_int(s1, src, d);
3519 if (iptr->op1) { /* class/interface */
3520 if (super->flags & ACC_INTERFACE) { /* interface */
3522 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3523 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3524 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3525 M_BLEZ(REG_ITMP2, 0);
3526 codegen_addxcastrefs(mcodeptr);
3527 M_ALD(REG_ITMP2, REG_ITMP1,
3528 OFFSET(vftbl, interfacetable[0]) -
3529 super->index * sizeof(methodptr*));
3530 M_BEQZ(REG_ITMP2, 0);
3531 codegen_addxcastrefs(mcodeptr);
3535 s2 = super->vftbl->diffval;
3536 M_BEQZ(s1, 4 + (s2 != 0) + (s2 > 255));
3537 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3538 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3539 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3541 M_BNEZ(REG_ITMP1, 0);
3543 else if (s2 <= 255) {
3544 M_CMPULE_IMM(REG_ITMP1, s2, REG_ITMP2);
3545 M_BEQZ(REG_ITMP2, 0);
3548 M_LDA(REG_ITMP2, REG_ZERO, s2);
3549 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3550 M_BEQZ(REG_ITMP2, 0);
3553 M_BEQZ(s1, 8 + (d == REG_ITMP3));
3554 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3555 a = dseg_addaddress ((void*) super->vftbl);
3556 M_ALD(REG_ITMP2, REG_PV, a);
3557 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3558 codegen_threadcritstart((u1*) mcodeptr - mcodebase);
3560 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3561 if (d != REG_ITMP3) {
3562 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl, baseval));
3563 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, diffval));
3564 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3565 codegen_threadcritstop((u1*) mcodeptr - mcodebase);
3567 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3570 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, baseval));
3571 M_ISUB(REG_ITMP1, REG_ITMP2, REG_ITMP1);
3572 M_ALD(REG_ITMP2, REG_PV, a);
3573 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, diffval));
3574 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3575 codegen_threadcritstop((u1*) mcodeptr - mcodebase);
3578 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3579 M_BEQZ(REG_ITMP2, 0);
3580 codegen_addxcastrefs(mcodeptr);
3584 panic ("internal error: no inlined array checkcast");
3587 store_reg_to_var_int(iptr->dst, d);
3590 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
3592 var_to_reg_int(s1, src, REG_ITMP1);
3594 codegen_addxcheckarefs(mcodeptr);
3597 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3598 /* op1 = dimension, val.a = array descriptor */
3600 /* check for negative sizes and copy sizes to stack if necessary */
3602 MCODECHECK((iptr->op1 << 1) + 64);
3604 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3605 var_to_reg_int(s2, src, REG_ITMP1);
3607 codegen_addxcheckarefs(mcodeptr);
3609 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
3611 if (src->varkind != ARGVAR) {
3612 M_LST(s2, REG_SP, 8 * (s1 + INT_ARG_CNT));
3616 /* a0 = dimension count */
3618 ICONST(argintregs[0], iptr->op1);
3620 /* a1 = arraydescriptor */
3622 a = dseg_addaddress(iptr->val.a);
3623 M_ALD(argintregs[1], REG_PV, a);
3625 /* a2 = pointer to dimensions = stack pointer */
3627 M_INTMOVE(REG_SP, argintregs[2]);
3629 a = dseg_addaddress((void*) (builtin_nmultianewarray));
3630 M_ALD(REG_PV, REG_PV, a);
3631 M_JSR(REG_RA, REG_PV);
3632 s1 = (int)((u1*) mcodeptr - mcodebase);
3634 M_LDA (REG_PV, REG_RA, -s1);
3636 s4 ml = -s1, mh = 0;
3637 while (ml < -32768) {ml += 65536; mh--;}
3638 M_LDA(REG_PV, REG_RA, ml);
3639 M_LDAH(REG_PV, REG_PV, mh);
3641 s1 = reg_of_var(iptr->dst, REG_RESULT);
3642 M_INTMOVE(REG_RESULT, s1);
3643 store_reg_to_var_int(iptr->dst, s1);
3647 default: error ("Unknown pseudo command: %d", iptr->opc);
3653 } /* for instruction */
3655 /* copy values to interface registers */
3657 src = bptr->outstack;
3658 len = bptr->outdepth;
3662 if ((src->varkind != STACKVAR)) {
3664 if (IS_FLT_DBL_TYPE(s2)) {
3665 var_to_reg_flt(s1, src, REG_FTMP1);
3666 if (!(interfaces[len][s2].flags & INMEMORY)) {
3667 M_FLTMOVE(s1,interfaces[len][s2].regoff);
3670 M_DST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3674 var_to_reg_int(s1, src, REG_ITMP1);
3675 if (!(interfaces[len][s2].flags & INMEMORY)) {
3676 M_INTMOVE(s1,interfaces[len][s2].regoff);
3679 M_LST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3685 } /* if (bptr -> flags >= BBREACHED) */
3686 } /* for basic block */
3688 /* bptr -> mpc = (int)((u1*) mcodeptr - mcodebase); */
3691 /* generate bound check stubs */
3693 s4 *xcodeptr = NULL;
3695 for (; xboundrefs != NULL; xboundrefs = xboundrefs->next) {
3696 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3697 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
3698 xboundrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - (4 + 4));
3703 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
3704 xboundrefs->branchpos, (u1*) mcodeptr - mcodebase);
3708 M_MOV(xboundrefs->reg, REG_ITMP1);
3709 M_LDA(REG_ITMP2_XPC, REG_PV, xboundrefs->branchpos - 4);
3711 if (xcodeptr != NULL) {
3712 M_BR(xcodeptr - mcodeptr - 1);
3715 xcodeptr = mcodeptr;
3717 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3718 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3720 a = dseg_addaddress(string_java_lang_ArrayIndexOutOfBoundsException);
3721 M_ALD(argintregs[0], REG_PV, a);
3722 M_MOV(REG_ITMP1, argintregs[1]);
3724 a = dseg_addaddress(new_exception_int);
3725 M_ALD(REG_PV, REG_PV, a);
3726 M_JSR(REG_RA, REG_PV);
3729 s1 = (s4) ((u1 *) mcodeptr - mcodebase);
3730 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3732 s4 ml = -s1, mh = 0;
3733 while (ml < -32768) { ml += 65536; mh--; }
3734 M_LDA(REG_PV, REG_RA, ml);
3735 M_LDAH(REG_PV, REG_PV, mh);
3738 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3740 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3741 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3743 a = dseg_addaddress(asm_handle_exception);
3744 M_ALD(REG_ITMP3, REG_PV, a);
3746 M_JMP(REG_ZERO, REG_ITMP3);
3750 /* generate negative array size check stubs */
3754 for (; xcheckarefs != NULL; xcheckarefs = xcheckarefs->next) {
3755 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3756 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3757 xcheckarefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3761 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3762 xcheckarefs->branchpos, (u1*) mcodeptr - mcodebase);
3766 M_LDA(REG_ITMP2_XPC, REG_PV, xcheckarefs->branchpos - 4);
3768 if (xcodeptr != NULL) {
3769 M_BR(xcodeptr - mcodeptr - 1);
3772 xcodeptr = mcodeptr;
3774 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3775 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3777 a = dseg_addaddress(string_java_lang_NegativeArraySizeException);
3778 M_ALD(argintregs[0], REG_PV, a);
3780 a = dseg_addaddress(new_exception);
3781 M_ALD(REG_PV, REG_PV, a);
3782 M_JSR(REG_RA, REG_PV);
3785 s1 = (s4) ((u1 *) mcodeptr - mcodebase);
3786 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3788 s4 ml = -s1, mh = 0;
3789 while (ml < -32768) { ml += 65536; mh--; }
3790 M_LDA(REG_PV, REG_RA, ml);
3791 M_LDAH(REG_PV, REG_PV, mh);
3794 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3796 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3797 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3799 a = dseg_addaddress(asm_handle_exception);
3800 M_ALD(REG_ITMP3, REG_PV, a);
3802 M_JMP(REG_ZERO, REG_ITMP3);
3806 /* generate cast check stubs */
3810 for (; xcastrefs != NULL; xcastrefs = xcastrefs->next) {
3811 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3812 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3813 xcastrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3817 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3818 xcastrefs->branchpos, (u1*) mcodeptr - mcodebase);
3822 M_LDA(REG_ITMP2_XPC, REG_PV, xcastrefs->branchpos - 4);
3824 if (xcodeptr != NULL) {
3825 M_BR(xcodeptr - mcodeptr - 1);
3828 xcodeptr = mcodeptr;
3830 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3831 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3833 a = dseg_addaddress(string_java_lang_ClassCastException);
3834 M_ALD(argintregs[0], REG_PV, a);
3836 a = dseg_addaddress(new_exception);
3837 M_ALD(REG_PV, REG_PV, a);
3838 M_JSR(REG_RA, REG_PV);
3841 s1 = (s4) ((u1 *) mcodeptr - mcodebase);
3842 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3844 s4 ml = -s1, mh = 0;
3845 while (ml < -32768) { ml += 65536; mh--; }
3846 M_LDA(REG_PV, REG_RA, ml);
3847 M_LDAH(REG_PV, REG_PV, mh);
3850 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3852 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3853 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3855 a = dseg_addaddress(asm_handle_exception);
3856 M_ALD(REG_ITMP3, REG_PV, a);
3858 M_JMP(REG_ZERO, REG_ITMP3);
3862 /* generate null pointer check stubs */
3866 for (; xnullrefs != NULL; xnullrefs = xnullrefs->next) {
3867 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3868 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3869 xnullrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3873 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3874 xnullrefs->branchpos, (u1*) mcodeptr - mcodebase);
3878 M_LDA(REG_ITMP2_XPC, REG_PV, xnullrefs->branchpos - 4);
3880 if (xcodeptr != NULL) {
3881 M_BR(xcodeptr - mcodeptr - 1);
3884 xcodeptr = mcodeptr;
3886 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3887 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3889 a = dseg_addaddress(string_java_lang_NullPointerException);
3890 M_ALD(argintregs[0], REG_PV, a);
3892 a = dseg_addaddress(new_exception);
3893 M_ALD(REG_PV, REG_PV, a);
3894 M_JSR(REG_RA, REG_PV);
3897 s1 = (s4) ((u1 *) mcodeptr - mcodebase);
3898 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3900 s4 ml = -s1, mh = 0;
3901 while (ml < -32768) { ml += 65536; mh--; }
3902 M_LDA(REG_PV, REG_RA, ml);
3903 M_LDAH(REG_PV, REG_PV, mh);
3906 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3908 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3909 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3911 a = dseg_addaddress(asm_handle_exception);
3912 M_ALD(REG_ITMP3, REG_PV, a);
3914 M_JMP(REG_ZERO, REG_ITMP3);
3919 codegen_finish((int)((u1*) mcodeptr - mcodebase));
3923 /* function createcompilerstub *************************************************
3925 creates a stub routine which calls the compiler
3927 *******************************************************************************/
3929 #define COMPSTUBSIZE 3
3931 u1 *createcompilerstub(methodinfo *m)
3933 u8 *s = CNEW(u8, COMPSTUBSIZE); /* memory to hold the stub */
3934 s4 *mcodeptr = (s4 *) s; /* code generation pointer */
3936 /* code for the stub */
3937 M_ALD(REG_PV, REG_PV, 16); /* load pointer to the compiler */
3938 M_JMP(0, REG_PV); /* jump to the compiler, return address
3939 in reg 0 is used as method pointer */
3940 s[1] = (u8) m; /* literals to be adressed */
3941 s[2] = (u8) asm_call_jit_compiler; /* jump directly via PV from above */
3944 count_cstub_len += COMPSTUBSIZE * 8;
3951 /* function removecompilerstub *************************************************
3953 deletes a compilerstub from memory (simply by freeing it)
3955 *******************************************************************************/
3957 void removecompilerstub(u1 *stub)
3959 CFREE(stub, COMPSTUBSIZE * 8);
3963 /* function: createnativestub **************************************************
3965 creates a stub routine which calls a native method
3967 *******************************************************************************/
3969 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3970 #define NATIVESTUBSTACK 2
3971 #define NATIVESTUBTHREADEXTRA 5
3973 #define NATIVESTUBSTACK 1
3974 #define NATIVESTUBTHREADEXTRA 0
3977 #define NATIVESTUBSIZE (44 + NATIVESTUBTHREADEXTRA)
3978 #define NATIVEVERBOSESIZE (39 + 13)
3979 #define NATIVESTUBOFFSET 8
3981 u1 *createnativestub(functionptr f, methodinfo *m)
3983 u8 *s; /* memory pointer to hold the stub */
3985 s4 *mcodeptr; /* code generation pointer */
3986 s4 stackframesize = 0; /* size of stackframe if needed */
3991 descriptor2types(m); /* set paramcount and paramtypes */
3993 stubsize = runverbose ? NATIVESTUBSIZE + NATIVEVERBOSESIZE : NATIVESTUBSIZE;
3994 s = CNEW(u8, stubsize); /* memory to hold the stub */
3995 cs = s + NATIVESTUBOFFSET;
3996 mcodeptr = (s4 *) (cs); /* code generation pointer */
3998 *(cs-1) = (u8) f; /* address of native method */
3999 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4000 *(cs-2) = (u8) &builtin_get_exceptionptrptr;
4002 *(cs-2) = (u8) (&_exceptionptr); /* address of exceptionptr */
4004 *(cs-3) = (u8) asm_handle_nat_exception; /* addr of asm exception handler */
4005 *(cs-4) = (u8) (&env); /* addr of jni_environement */
4006 *(cs-5) = (u8) builtin_trace_args;
4008 *(cs-7) = (u8) builtin_displaymethodstop;
4009 *(cs-8) = (u8) m->class;
4011 M_LDA(REG_SP, REG_SP, -NATIVESTUBSTACK * 8); /* build up stackframe */
4012 M_AST(REG_RA, REG_SP, 0 * 8); /* store return address */
4014 /* max. 39 instructions */
4018 M_LDA(REG_SP, REG_SP, -((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
4019 M_AST(REG_RA, REG_SP, 1 * 8);
4021 /* save integer argument registers */
4022 for (p = 0; p < m->paramcount && p < INT_ARG_CNT; p++) {
4023 M_LST(argintregs[p], REG_SP, (2 + p) * 8);
4026 /* save and copy float arguments into integer registers */
4027 for (p = 0; p < m->paramcount && p < FLT_ARG_CNT; p++) {
4028 t = m->paramtypes[p];
4030 if (IS_FLT_DBL_TYPE(t)) {
4031 if (IS_2_WORD_TYPE(t)) {
4032 M_DST(argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4033 M_LLD(argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4036 M_FST(argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4037 M_ILD(argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4041 M_DST(argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4045 M_ALD(REG_ITMP1, REG_PV, -6 * 8);
4046 M_AST(REG_ITMP1, REG_SP, 0 * 8);
4047 M_ALD(REG_PV, REG_PV, -5 * 8);
4048 M_JSR(REG_RA, REG_PV);
4049 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4050 M_LDA(REG_PV, REG_RA, disp);
4052 for (p = 0; p < m->paramcount && p < INT_ARG_CNT; p++) {
4053 M_LLD(argintregs[p], REG_SP, (2 + p) * 8);
4056 for (p = 0; p < m->paramcount && p < FLT_ARG_CNT; p++) {
4057 t = m->paramtypes[p];
4059 if (IS_FLT_DBL_TYPE(t)) {
4060 if (IS_2_WORD_TYPE(t)) {
4061 M_DLD(argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4064 M_FLD(argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4068 M_DLD(argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4072 M_ALD(REG_RA, REG_SP, 1 * 8);
4073 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT + 2) * 8);
4076 /* save argument registers on stack -- if we have to */
4077 if ((m->flags & ACC_STATIC && m->paramcount > (INT_ARG_CNT - 2)) || m->paramcount > (INT_ARG_CNT - 1)) {
4079 s4 paramshiftcnt = (m->flags & ACC_STATIC) ? 2 : 1;
4080 s4 stackparamcnt = (m->paramcount > INT_ARG_CNT) ? m->paramcount - INT_ARG_CNT : 0;
4082 stackframesize = stackparamcnt + paramshiftcnt;
4084 M_LDA(REG_SP, REG_SP, -stackframesize * 8);
4086 /* copy stack arguments into new stack frame -- if any */
4087 for (i = 0; i < stackparamcnt; i++) {
4088 M_LLD(REG_ITMP1, REG_SP, (stackparamcnt + 1 + i) * 8);
4089 M_LST(REG_ITMP1, REG_SP, (paramshiftcnt + i) * 8);
4092 if (m->flags & ACC_STATIC) {
4093 if (IS_FLT_DBL_TYPE(m->paramtypes[5])) {
4094 M_DST(argfltregs[5], REG_SP, 1 * 8);
4096 M_LST(argintregs[5], REG_SP, 1 * 8);
4099 if (IS_FLT_DBL_TYPE(m->paramtypes[4])) {
4100 M_DST(argfltregs[4], REG_SP, 0 * 8);
4102 M_LST(argintregs[4], REG_SP, 0 * 8);
4106 if (IS_FLT_DBL_TYPE(m->paramtypes[5])) {
4107 M_DST(argfltregs[5], REG_SP, 0 * 8);
4109 M_LST(argintregs[5], REG_SP, 0 * 8);
4114 if (m->flags & ACC_STATIC) {
4115 M_MOV(argintregs[3], argintregs[5]);
4116 M_MOV(argintregs[2], argintregs[4]);
4117 M_MOV(argintregs[1], argintregs[3]);
4118 M_MOV(argintregs[0], argintregs[2]);
4119 M_FMOV(argfltregs[3], argfltregs[5]);
4120 M_FMOV(argfltregs[2], argfltregs[4]);
4121 M_FMOV(argfltregs[1], argfltregs[3]);
4122 M_FMOV(argfltregs[0], argfltregs[2]);
4124 /* put class into second argument register */
4125 M_ALD(argintregs[1], REG_PV, -8 * 8);
4128 M_MOV(argintregs[4], argintregs[5]);
4129 M_MOV(argintregs[3], argintregs[4]);
4130 M_MOV(argintregs[2], argintregs[3]);
4131 M_MOV(argintregs[1], argintregs[2]);
4132 M_MOV(argintregs[0], argintregs[1]);
4133 M_FMOV(argfltregs[4], argfltregs[5]);
4134 M_FMOV(argfltregs[3], argfltregs[4]);
4135 M_FMOV(argfltregs[2], argfltregs[3]);
4136 M_FMOV(argfltregs[1], argfltregs[2]);
4137 M_FMOV(argfltregs[0], argfltregs[1]);
4140 /* put env into first argument register */
4141 M_ALD(argintregs[0], REG_PV, -4 * 8);
4143 M_ALD(REG_PV, REG_PV, -1 * 8); /* load adress of native method */
4144 M_JSR(REG_RA, REG_PV); /* call native method */
4145 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4146 M_LDA(REG_PV, REG_RA, disp); /* recompute pv from ra */
4148 /* remove stackframe if there is one */
4149 if (stackframesize) {
4150 M_LDA(REG_SP, REG_SP, stackframesize * 8);
4153 /* 13 instructions */
4155 M_LDA(REG_SP, REG_SP, -2 * 8);
4156 M_ALD(argintregs[0], REG_PV, -6 * 8); /* load method adress */
4157 M_LST(REG_RESULT, REG_SP, 0 * 8);
4158 M_DST(REG_FRESULT, REG_SP, 1 * 8);
4159 M_MOV(REG_RESULT, argintregs[1]);
4160 M_FMOV(REG_FRESULT, argfltregs[2]);
4161 M_FMOV(REG_FRESULT, argfltregs[3]);
4162 M_ALD(REG_PV, REG_PV, -7 * 8); /* builtin_displaymethodstop */
4163 M_JSR(REG_RA, REG_PV);
4164 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4165 M_LDA(REG_PV, REG_RA, disp);
4166 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4167 M_DLD(REG_FRESULT, REG_SP, 1 * 8);
4168 M_LDA(REG_SP, REG_SP, 2 * 8);
4171 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4172 if (IS_FLT_DBL_TYPE(m->returntype))
4173 M_DST(REG_FRESULT, REG_SP, 1 * 8);
4175 M_AST(REG_RESULT, REG_SP, 1 * 8);
4176 M_ALD(REG_PV, REG_PV, -2 * 8); /* builtin_get_exceptionptrptr */
4177 M_JSR(REG_RA, REG_PV);
4178 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4179 M_LDA(REG_PV, REG_RA, disp);
4180 M_MOV(REG_RESULT, REG_ITMP3);
4181 if (IS_FLT_DBL_TYPE(m->returntype))
4182 M_DLD(REG_FRESULT, REG_SP, 1 * 8);
4184 M_ALD(REG_RESULT, REG_SP, 1 * 8);
4186 M_ALD(REG_ITMP3, REG_PV, -2 * 8); /* get address of exceptionptr */
4188 M_ALD(REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
4189 M_BNEZ(REG_ITMP1, 3); /* if no exception then return */
4191 M_ALD(REG_RA, REG_SP, 0 * 8); /* load return address */
4192 M_LDA(REG_SP, REG_SP, NATIVESTUBSTACK * 8); /* remove stackframe */
4193 M_RET(REG_ZERO, REG_RA); /* return to caller */
4195 M_AST(REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
4197 M_ALD(REG_RA, REG_SP, 0 * 8); /* load return address */
4198 M_LDA(REG_SP, REG_SP, NATIVESTUBSTACK * 8); /* remove stackframe */
4199 M_LDA(REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
4200 M_ALD(REG_ITMP3, REG_PV, -3 * 8); /* load asm exception handler address */
4201 M_JMP(REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
4204 dolog_plain("stubsize: %d (for %d params)\n", (int) (mcodeptr - (s4*) s), m->paramcount);
4208 count_nstub_len += NATIVESTUBSIZE * 8;
4211 return (u1 *) (s + NATIVESTUBOFFSET);
4215 /* function: removenativestub **************************************************
4217 removes a previously created native-stub from memory
4219 *******************************************************************************/
4221 void removenativestub(u1 *stub)
4223 CFREE((u8 *) stub - NATIVESTUBOFFSET, NATIVESTUBSIZE * 8);
4228 * These are local overrides for various environment variables in Emacs.
4229 * Please do not remove this and leave it at the end of the file, where
4230 * Emacs will automagically detect them.
4231 * ---------------------------------------------------------------------
4234 * indent-tabs-mode: t