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 1161 2004-06-11 20:41:38Z stefan $
41 #include "jit/alpha/codegen.h"
43 #include "jit/parse.h"
53 /* include independent code generation stuff */
54 #include "jit/codegen.inc"
55 #include "jit/reg.inc"
58 /* *****************************************************************************
60 Datatypes and Register Allocations:
61 -----------------------------------
63 On 64-bit-machines (like the Alpha) all operands are stored in the
64 registers in a 64-bit form, even when the correspondig JavaVM operands
65 only need 32 bits. This is done by a canonical representation:
67 32-bit integers are allways stored as sign-extended 64-bit values (this
68 approach is directly supported by the Alpha architecture and is very easy
71 32-bit-floats are stored in a 64-bit doubleprecision register by simply
72 expanding the exponent and mantissa with zeroes. (also supported by the
78 The calling conventions and the layout of the stack is explained in detail
79 in the documention file: calling.doc
81 *******************************************************************************/
84 /* register descripton - array ************************************************/
86 /* #define REG_RES 0 reserved register for OS or code generator */
87 /* #define REG_RET 1 return value register */
88 /* #define REG_EXC 2 exception value register (only old jit) */
89 /* #define REG_SAV 3 (callee) saved register */
90 /* #define REG_TMP 4 scratch temporary register (caller saved) */
91 /* #define REG_ARG 5 argument register (caller saved) */
93 /* #define REG_END -1 last entry in tables */
96 REG_RET, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
97 REG_TMP, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
98 REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_TMP, REG_TMP,
99 REG_TMP, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES,
102 /* for use of reserved registers, see comment above */
104 int nregdescfloat[] = {
105 REG_RET, REG_TMP, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
106 REG_SAV, REG_SAV, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
107 REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_TMP, REG_TMP,
108 REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_RES, REG_RES, REG_RES, REG_RES,
111 /* for use of reserved registers, see comment above */
114 /* parameter allocation mode */
116 int nreg_parammode = PARAMMODE_NUMBERED;
118 /* parameter-registers will be allocated by assigning the
119 1. parameter: int/float-reg 16
120 2. parameter: int/float-reg 17
121 3. parameter: int/float-reg 18 ....
125 /* stackframe-infos ***********************************************************/
127 int parentargs_base; /* offset in stackframe for the parameter from the caller*/
129 /* -> see file 'calling.doc' */
132 /* additional functions and macros to generate code ***************************/
134 /* #define BlockPtrOfPC(pc) block+block_index[pc] */
135 #define BlockPtrOfPC(pc) ((basicblock *) iptr->target)
139 #define COUNT_SPILLS count_spills++
145 /* gen_nullptr_check(objreg) */
147 #define gen_nullptr_check(objreg) \
149 M_BEQZ((objreg), 0); \
150 codegen_addxnullrefs(mcodeptr); \
154 /* MCODECHECK(icnt) */
156 #define MCODECHECK(icnt) \
157 if((mcodeptr + (icnt)) > mcodeend) mcodeptr = codegen_increase((u1*) mcodeptr)
160 generates an integer-move from register a to b.
161 if a and b are the same int-register, no code will be generated.
164 #define M_INTMOVE(a,b) if (a != b) { M_MOV(a, b); }
168 generates a floating-point-move from register a to b.
169 if a and b are the same float-register, no code will be generated
172 #define M_FLTMOVE(a,b) if (a != b) { M_FMOV(a, b); }
176 this function generates code to fetch data from a pseudo-register
177 into a real register.
178 If the pseudo-register has actually been assigned to a real
179 register, no code will be emitted, since following operations
180 can use this register directly.
182 v: pseudoregister to be fetched from
183 tempregnum: temporary register to be used if v is actually spilled to ram
185 return: the register number, where the operand can be found after
186 fetching (this wil be either tempregnum or the register
187 number allready given to v)
190 #define var_to_reg_int(regnr,v,tempnr) { \
191 if ((v)->flags & INMEMORY) \
192 {COUNT_SPILLS;M_LLD(tempnr,REG_SP,8*(v)->regoff);regnr=tempnr;} \
193 else regnr=(v)->regoff; \
197 #define var_to_reg_flt(regnr,v,tempnr) { \
198 if ((v)->flags & INMEMORY) \
199 {COUNT_SPILLS;M_DLD(tempnr,REG_SP,8*(v)->regoff);regnr=tempnr;} \
200 else regnr=(v)->regoff; \
205 This function determines a register, to which the result of an operation
206 should go, when it is ultimatively intended to store the result in
208 If v is assigned to an actual register, this register will be returned.
209 Otherwise (when v is spilled) this function returns tempregnum.
210 If not already done, regoff and flags are set in the stack location.
213 static int reg_of_var(stackptr v, int tempregnum)
217 switch (v->varkind) {
219 if (!(v->flags & INMEMORY))
223 var = &(interfaces[v->varnum][v->type]);
224 v->regoff = var->regoff;
225 if (!(var->flags & INMEMORY))
229 var = &(locals[v->varnum][v->type]);
230 v->regoff = var->regoff;
231 if (!(var->flags & INMEMORY))
235 v->regoff = v->varnum;
236 if (IS_FLT_DBL_TYPE(v->type)) {
237 if (v->varnum < fltreg_argnum) {
238 v->regoff = argfltregs[v->varnum];
239 return(argfltregs[v->varnum]);
243 if (v->varnum < intreg_argnum) {
244 v->regoff = argintregs[v->varnum];
245 return(argintregs[v->varnum]);
247 v->regoff -= intreg_argnum;
250 v->flags |= INMEMORY;
255 /* store_reg_to_var_xxx:
256 This function generates the code to store the result of an operation
257 back into a spilled pseudo-variable.
258 If the pseudo-variable has not been spilled in the first place, this
259 function will generate nothing.
261 v ............ Pseudovariable
262 tempregnum ... Number of the temporary registers as returned by
266 #define store_reg_to_var_int(sptr, tempregnum) { \
267 if ((sptr)->flags & INMEMORY) { \
269 M_LST(tempregnum, REG_SP, 8 * (sptr)->regoff); \
273 #define store_reg_to_var_flt(sptr, tempregnum) { \
274 if ((sptr)->flags & INMEMORY) { \
276 M_DST(tempregnum, REG_SP, 8 * (sptr)->regoff); \
281 /* NullPointerException handlers and exception handling initialisation */
283 typedef struct sigctx_struct {
285 long sc_onstack; /* sigstack state to restore */
286 long sc_mask; /* signal mask to restore */
287 long sc_pc; /* pc at time of signal */
288 long sc_ps; /* psl to retore */
289 long sc_regs[32]; /* processor regs 0 to 31 */
290 long sc_ownedfp; /* fp has been used */
291 long sc_fpregs[32]; /* fp regs 0 to 31 */
292 unsigned long sc_fpcr; /* floating point control register */
293 unsigned long sc_fp_control; /* software fpcr */
295 unsigned long sc_reserved1, sc_reserved2;
296 unsigned long sc_ssize;
298 unsigned long sc_traparg_a0;
299 unsigned long sc_traparg_a1;
300 unsigned long sc_traparg_a2;
301 unsigned long sc_fp_trap_pc;
302 unsigned long sc_fp_trigger_sum;
303 unsigned long sc_fp_trigger_inst;
304 unsigned long sc_retcode[2];
308 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
309 void thread_restartcriticalsection(ucontext_t *uc)
312 if ((critical = thread_checkcritical((void*) uc->uc_mcontext.sc_pc)) != NULL)
313 uc->uc_mcontext.sc_pc = (u8) critical;
317 /* NullPointerException signal handler for hardware null pointer check */
319 void catch_NullPointerException(int sig, int code, sigctx_struct *sigctx)
324 java_objectheader *xptr;
326 /* Reset signal handler - necessary for SysV, does no harm for BSD */
328 instr = *((int*)(sigctx->sc_pc));
329 faultaddr = sigctx->sc_regs[(instr >> 16) & 0x1f];
331 if (faultaddr == 0) {
332 signal(sig, (void*) catch_NullPointerException); /* reinstall handler */
334 sigaddset(&nsig, sig);
335 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
337 xptr = new_exception(string_java_lang_NullPointerException);
339 sigctx->sc_regs[REG_ITMP1_XPTR] = (u8) xptr;
340 sigctx->sc_regs[REG_ITMP2_XPC] = sigctx->sc_pc;
341 sigctx->sc_pc = (u8) asm_handle_exception;
345 faultaddr += (long) ((instr << 16) >> 16);
346 fprintf(stderr, "faulting address: 0x%016lx\n", faultaddr);
347 panic("Stack overflow");
354 void init_exceptions(void)
359 /* Linux on Digital Alpha needs an initialisation of the ieee floating point
360 control for IEEE compliant arithmetic (option -mieee of GCC). Under
361 Digital Unix this is done automatically.
366 extern unsigned long ieee_get_fp_control();
367 extern void ieee_set_fp_control(unsigned long fp_control);
369 void init_exceptions(void)
371 /* initialize floating point control */
373 ieee_set_fp_control(ieee_get_fp_control()
374 & ~IEEE_TRAP_ENABLE_INV
375 & ~IEEE_TRAP_ENABLE_DZE
376 /* & ~IEEE_TRAP_ENABLE_UNF we dont want underflow */
377 & ~IEEE_TRAP_ENABLE_OVF);
380 /* install signal handlers we need to convert to exceptions */
384 signal(SIGSEGV, (void*) catch_NullPointerException);
388 signal(SIGBUS, (void*) catch_NullPointerException);
394 /* function gen_mcode **********************************************************
396 generates machine code
398 *******************************************************************************/
402 int len, s1, s2, s3, d;
414 savedregs_num = (isleafmethod) ? 0 : 1; /* space to save the RA */
416 /* space to save used callee saved registers */
418 savedregs_num += (savintregcnt - maxsavintreguse);
419 savedregs_num += (savfltregcnt - maxsavfltreguse);
421 parentargs_base = maxmemuse + savedregs_num;
423 #if defined(USE_THREADS) /* space to save argument of monitor_enter */
425 if (checksync && (method->flags & ACC_SYNCHRONIZED))
430 /* create method header */
432 (void) dseg_addaddress(method); /* MethodPointer */
433 (void) dseg_adds4(parentargs_base * 8); /* FrameSize */
435 #if defined(USE_THREADS)
437 /* IsSync contains the offset relative to the stack pointer for the
438 argument of monitor_exit used in the exception handler. Since the
439 offset could be zero and give a wrong meaning of the flag it is
443 if (checksync && (method->flags & ACC_SYNCHRONIZED))
444 (void) dseg_adds4((maxmemuse + 1) * 8); /* IsSync */
449 (void) dseg_adds4(0); /* IsSync */
451 (void) dseg_adds4(isleafmethod); /* IsLeaf */
452 (void) dseg_adds4(savintregcnt - maxsavintreguse); /* IntSave */
453 (void) dseg_adds4(savfltregcnt - maxsavfltreguse); /* FltSave */
455 dseg_addlinenumbertablesize();
458 (void) dseg_adds4(exceptiontablelength); /* ExTableSize */
460 /* create exception table */
462 for (ex = extable; ex != NULL; ex = ex->down) {
463 dseg_addtarget(ex->start);
464 dseg_addtarget(ex->end);
465 dseg_addtarget(ex->handler);
466 (void) dseg_addaddress(ex->catchtype);
469 /* initialize mcode variables */
471 mcodeptr = (s4*) mcodebase;
472 mcodeend = (s4*) (mcodebase + mcodesize);
473 MCODECHECK(128 + mparamcount);
475 /* create stack frame (if necessary) */
478 {M_LDA (REG_SP, REG_SP, -parentargs_base * 8);}
480 /* save return address and used callee saved registers */
484 {p--; M_AST (REG_RA, REG_SP, 8*p);}
485 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
486 {p--; M_LST (savintregs[r], REG_SP, 8 * p);}
487 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
488 {p--; M_DST (savfltregs[r], REG_SP, 8 * p);}
490 /* save monitorenter argument */
492 #if defined(USE_THREADS)
493 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
494 if (method->flags & ACC_STATIC) {
495 p = dseg_addaddress(class);
496 M_ALD(REG_ITMP1, REG_PV, p);
497 M_AST(REG_ITMP1, REG_SP, maxmemuse * 8);
500 M_AST (argintregs[0], REG_SP, maxmemuse * 8);
505 /* copy argument registers to stack and call trace function with pointer
506 to arguments on stack.
511 M_LDA(REG_SP, REG_SP, -((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
512 M_AST(REG_RA, REG_SP, 1 * 8);
514 /* save integer argument registers */
515 for (p = 0; /* p < mparamcount && */ p < INT_ARG_CNT; p++) {
516 M_LST(argintregs[p], REG_SP, (2 + p) * 8);
519 /* save and copy float arguments into integer registers */
520 for (p = 0; /* p < mparamcount && */ p < FLT_ARG_CNT; p++) {
523 if (IS_FLT_DBL_TYPE(t)) {
524 if (IS_2_WORD_TYPE(t)) {
525 M_DST(argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
528 M_FST(argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
531 M_LLD(argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
534 M_DST(argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
538 p = dseg_addaddress(method);
539 M_ALD(REG_ITMP1, REG_PV, p);
540 M_AST(REG_ITMP1, REG_SP, 0 * 8);
541 p = dseg_addaddress((void *) builtin_trace_args);
542 M_ALD(REG_PV, REG_PV, p);
543 M_JSR(REG_RA, REG_PV);
544 disp = -(int) ((u1 *) mcodeptr - mcodebase);
545 M_LDA(REG_PV, REG_RA, disp);
546 M_ALD(REG_RA, REG_SP, 1 * 8);
548 for (p = 0; /* p < mparamcount && */ p < INT_ARG_CNT; p++) {
549 M_LLD(argintregs[p], REG_SP, (2 + p) * 8);
552 for (p = 0; /* p < mparamcount && */ p < FLT_ARG_CNT; p++) {
555 if (IS_FLT_DBL_TYPE(t)) {
556 if (IS_2_WORD_TYPE(t)) {
557 M_DLD(argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
560 M_FLD(argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
564 M_DLD(argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
568 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT + 2) * 8);
571 /* take arguments out of register or stack frame */
573 for (p = 0, l = 0; p < mparamcount; p++) {
575 var = &(locals[l][t]);
577 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
582 if (IS_INT_LNG_TYPE(t)) { /* integer args */
583 if (p < INT_ARG_CNT) { /* register arguments */
584 if (!(var->flags & INMEMORY)) /* reg arg -> register */
585 {M_INTMOVE (argintregs[p], r);}
586 else /* reg arg -> spilled */
587 M_LST (argintregs[p], REG_SP, 8 * r);
589 else { /* stack arguments */
590 pa = p - INT_ARG_CNT;
591 if (!(var->flags & INMEMORY)) /* stack arg -> register */
592 M_LLD (r, REG_SP, 8 * (parentargs_base + pa));
593 else { /* stack arg -> spilled */
594 M_LLD (REG_ITMP1, REG_SP, 8 * (parentargs_base + pa));
595 M_LST (REG_ITMP1, REG_SP, 8 * r);
599 else { /* floating args */
600 if (p < FLT_ARG_CNT) { /* register arguments */
601 if (!(var->flags & INMEMORY)) /* reg arg -> register */
602 {M_FLTMOVE (argfltregs[p], r);}
603 else /* reg arg -> spilled */
604 M_DST (argfltregs[p], REG_SP, 8 * r);
606 else { /* stack arguments */
607 pa = p - FLT_ARG_CNT;
608 if (!(var->flags & INMEMORY)) /* stack-arg -> register */
609 M_DLD (r, REG_SP, 8 * (parentargs_base + pa) );
610 else { /* stack-arg -> spilled */
611 M_DLD (REG_FTMP1, REG_SP, 8 * (parentargs_base + pa));
612 M_DST (REG_FTMP1, REG_SP, 8 * r);
618 /* call monitorenter function */
620 #if defined(USE_THREADS)
621 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
623 p = dseg_addaddress((void*) (builtin_monitorenter));
624 M_ALD(REG_PV, REG_PV, p);
625 M_ALD(argintregs[0], REG_SP, maxmemuse * 8);
626 M_JSR(REG_RA, REG_PV);
627 disp = -(int)((u1*) mcodeptr - mcodebase);
628 M_LDA(REG_PV, REG_RA, disp);
633 /* end of header generation */
635 /* walk through all basic blocks */
636 for (bptr = block; bptr != NULL; bptr = bptr->next) {
638 bptr->mpc = (int)((u1*) mcodeptr - mcodebase);
640 if (bptr->flags >= BBREACHED) {
642 /* branch resolving */
646 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
647 gen_resolvebranch((u1*) mcodebase + brefs->branchpos,
648 brefs->branchpos, bptr->mpc);
652 /* copy interface registers to their destination */
657 while (src != NULL) {
659 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
660 d = reg_of_var(src, REG_ITMP1);
661 M_INTMOVE(REG_ITMP1, d);
662 store_reg_to_var_int(src, d);
665 d = reg_of_var(src, REG_IFTMP);
666 if ((src->varkind != STACKVAR)) {
668 if (IS_FLT_DBL_TYPE(s2)) {
669 if (!(interfaces[len][s2].flags & INMEMORY)) {
670 s1 = interfaces[len][s2].regoff;
674 M_DLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
676 store_reg_to_var_flt(src, d);
679 if (!(interfaces[len][s2].flags & INMEMORY)) {
680 s1 = interfaces[len][s2].regoff;
684 M_LLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
686 store_reg_to_var_int(src, d);
693 /* walk through all instructions */
697 for (iptr = bptr->iinstr;
699 src = iptr->dst, len--, iptr++) {
701 MCODECHECK(64); /* an instruction usually needs < 64 words */
704 case ICMD_NOP: /* ... ==> ... */
707 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
709 var_to_reg_int(s1, src, REG_ITMP1);
711 codegen_addxnullrefs(mcodeptr);
714 /* constant operations ************************************************/
716 #define ICONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
717 else{a=dseg_adds4(c);M_ILD(r,REG_PV,a);}
719 #define LCONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
720 else{a=dseg_adds8(c);M_LLD(r,REG_PV,a);}
722 case ICMD_ICONST: /* ... ==> ..., constant */
723 /* op1 = 0, val.i = constant */
725 d = reg_of_var(iptr->dst, REG_ITMP1);
726 ICONST(d, iptr->val.i);
727 store_reg_to_var_int(iptr->dst, d);
730 case ICMD_LCONST: /* ... ==> ..., constant */
731 /* op1 = 0, val.l = constant */
733 d = reg_of_var(iptr->dst, REG_ITMP1);
734 LCONST(d, iptr->val.l);
735 store_reg_to_var_int(iptr->dst, d);
738 case ICMD_FCONST: /* ... ==> ..., constant */
739 /* op1 = 0, val.f = constant */
741 d = reg_of_var(iptr->dst, REG_FTMP1);
742 a = dseg_addfloat(iptr->val.f);
744 store_reg_to_var_flt(iptr->dst, d);
747 case ICMD_DCONST: /* ... ==> ..., constant */
748 /* op1 = 0, val.d = constant */
750 d = reg_of_var(iptr->dst, REG_FTMP1);
751 a = dseg_adddouble(iptr->val.d);
753 store_reg_to_var_flt(iptr->dst, d);
756 case ICMD_ACONST: /* ... ==> ..., constant */
757 /* op1 = 0, val.a = constant */
759 d = reg_of_var(iptr->dst, REG_ITMP1);
761 a = dseg_addaddress (iptr->val.a);
765 M_INTMOVE(REG_ZERO, d);
767 store_reg_to_var_int(iptr->dst, d);
771 /* load/store operations **********************************************/
773 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
774 case ICMD_LLOAD: /* op1 = local variable */
777 d = reg_of_var(iptr->dst, REG_ITMP1);
778 if ((iptr->dst->varkind == LOCALVAR) &&
779 (iptr->dst->varnum == iptr->op1))
781 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
782 if (var->flags & INMEMORY)
783 M_LLD(d, REG_SP, 8 * var->regoff);
785 {M_INTMOVE(var->regoff,d);}
786 store_reg_to_var_int(iptr->dst, d);
789 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
790 case ICMD_DLOAD: /* op1 = local variable */
792 d = reg_of_var(iptr->dst, REG_FTMP1);
793 if ((iptr->dst->varkind == LOCALVAR) &&
794 (iptr->dst->varnum == iptr->op1))
796 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
797 if (var->flags & INMEMORY)
798 M_DLD(d, REG_SP, 8 * var->regoff);
800 {M_FLTMOVE(var->regoff,d);}
801 store_reg_to_var_flt(iptr->dst, d);
805 case ICMD_ISTORE: /* ..., value ==> ... */
806 case ICMD_LSTORE: /* op1 = local variable */
809 if ((src->varkind == LOCALVAR) &&
810 (src->varnum == iptr->op1))
812 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
813 if (var->flags & INMEMORY) {
814 var_to_reg_int(s1, src, REG_ITMP1);
815 M_LST(s1, REG_SP, 8 * var->regoff);
818 var_to_reg_int(s1, src, var->regoff);
819 M_INTMOVE(s1, var->regoff);
823 case ICMD_FSTORE: /* ..., value ==> ... */
824 case ICMD_DSTORE: /* op1 = local variable */
826 if ((src->varkind == LOCALVAR) &&
827 (src->varnum == iptr->op1))
829 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
830 if (var->flags & INMEMORY) {
831 var_to_reg_flt(s1, src, REG_FTMP1);
832 M_DST(s1, REG_SP, 8 * var->regoff);
835 var_to_reg_flt(s1, src, var->regoff);
836 M_FLTMOVE(s1, var->regoff);
841 /* pop/dup/swap operations ********************************************/
843 /* attention: double and longs are only one entry in CACAO ICMDs */
845 case ICMD_POP: /* ..., value ==> ... */
846 case ICMD_POP2: /* ..., value, value ==> ... */
849 #define M_COPY(from,to) \
850 d = reg_of_var(to, REG_IFTMP); \
851 if ((from->regoff != to->regoff) || \
852 ((from->flags ^ to->flags) & INMEMORY)) { \
853 if (IS_FLT_DBL_TYPE(from->type)) { \
854 var_to_reg_flt(s1, from, d); \
856 store_reg_to_var_flt(to, d); \
859 var_to_reg_int(s1, from, d); \
861 store_reg_to_var_int(to, d); \
865 case ICMD_DUP: /* ..., a ==> ..., a, a */
866 M_COPY(src, iptr->dst);
869 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
871 M_COPY(src, iptr->dst->prev->prev);
873 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
875 M_COPY(src, iptr->dst);
876 M_COPY(src->prev, iptr->dst->prev);
879 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
881 M_COPY(src->prev, iptr->dst->prev->prev->prev);
883 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
885 M_COPY(src, iptr->dst);
886 M_COPY(src->prev, iptr->dst->prev);
887 M_COPY(src->prev->prev, iptr->dst->prev->prev);
888 M_COPY(src, iptr->dst->prev->prev->prev);
891 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
893 M_COPY(src, iptr->dst);
894 M_COPY(src->prev, iptr->dst->prev);
895 M_COPY(src->prev->prev, iptr->dst->prev->prev);
896 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
897 M_COPY(src, iptr->dst->prev->prev->prev->prev);
898 M_COPY(src->prev, iptr->dst->prev->prev->prev->prev->prev);
901 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
903 M_COPY(src, iptr->dst->prev);
904 M_COPY(src->prev, iptr->dst);
908 /* integer operations *************************************************/
910 case ICMD_INEG: /* ..., value ==> ..., - value */
912 var_to_reg_int(s1, src, REG_ITMP1);
913 d = reg_of_var(iptr->dst, REG_ITMP3);
914 M_ISUB(REG_ZERO, s1, d);
915 store_reg_to_var_int(iptr->dst, d);
918 case ICMD_LNEG: /* ..., value ==> ..., - value */
920 var_to_reg_int(s1, src, REG_ITMP1);
921 d = reg_of_var(iptr->dst, REG_ITMP3);
922 M_LSUB(REG_ZERO, s1, d);
923 store_reg_to_var_int(iptr->dst, d);
926 case ICMD_I2L: /* ..., value ==> ..., value */
928 var_to_reg_int(s1, src, REG_ITMP1);
929 d = reg_of_var(iptr->dst, REG_ITMP3);
931 store_reg_to_var_int(iptr->dst, d);
934 case ICMD_L2I: /* ..., value ==> ..., value */
936 var_to_reg_int(s1, src, REG_ITMP1);
937 d = reg_of_var(iptr->dst, REG_ITMP3);
938 M_IADD(s1, REG_ZERO, d );
939 store_reg_to_var_int(iptr->dst, d);
942 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
944 var_to_reg_int(s1, src, REG_ITMP1);
945 d = reg_of_var(iptr->dst, REG_ITMP3);
946 if (has_ext_instr_set) {
950 M_SLL_IMM(s1, 56, d);
951 M_SRA_IMM( d, 56, d);
953 store_reg_to_var_int(iptr->dst, d);
956 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
958 var_to_reg_int(s1, src, REG_ITMP1);
959 d = reg_of_var(iptr->dst, REG_ITMP3);
961 store_reg_to_var_int(iptr->dst, d);
964 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
966 var_to_reg_int(s1, src, REG_ITMP1);
967 d = reg_of_var(iptr->dst, REG_ITMP3);
968 if (has_ext_instr_set) {
972 M_SLL_IMM(s1, 48, d);
973 M_SRA_IMM( d, 48, d);
975 store_reg_to_var_int(iptr->dst, d);
979 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
981 var_to_reg_int(s1, src->prev, REG_ITMP1);
982 var_to_reg_int(s2, src, REG_ITMP2);
983 d = reg_of_var(iptr->dst, REG_ITMP3);
985 store_reg_to_var_int(iptr->dst, d);
988 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
989 /* val.i = constant */
991 var_to_reg_int(s1, src, REG_ITMP1);
992 d = reg_of_var(iptr->dst, REG_ITMP3);
993 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
994 M_IADD_IMM(s1, iptr->val.i, d);
997 ICONST(REG_ITMP2, iptr->val.i);
998 M_IADD(s1, REG_ITMP2, d);
1000 store_reg_to_var_int(iptr->dst, d);
1003 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1005 var_to_reg_int(s1, src->prev, REG_ITMP1);
1006 var_to_reg_int(s2, src, REG_ITMP2);
1007 d = reg_of_var(iptr->dst, REG_ITMP3);
1009 store_reg_to_var_int(iptr->dst, d);
1012 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
1013 /* val.l = constant */
1015 var_to_reg_int(s1, src, REG_ITMP1);
1016 d = reg_of_var(iptr->dst, REG_ITMP3);
1017 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1018 M_LADD_IMM(s1, iptr->val.l, d);
1021 LCONST(REG_ITMP2, iptr->val.l);
1022 M_LADD(s1, REG_ITMP2, d);
1024 store_reg_to_var_int(iptr->dst, d);
1027 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1029 var_to_reg_int(s1, src->prev, REG_ITMP1);
1030 var_to_reg_int(s2, src, REG_ITMP2);
1031 d = reg_of_var(iptr->dst, REG_ITMP3);
1033 store_reg_to_var_int(iptr->dst, d);
1036 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
1037 /* val.i = constant */
1039 var_to_reg_int(s1, src, REG_ITMP1);
1040 d = reg_of_var(iptr->dst, REG_ITMP3);
1041 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1042 M_ISUB_IMM(s1, iptr->val.i, d);
1045 ICONST(REG_ITMP2, iptr->val.i);
1046 M_ISUB(s1, REG_ITMP2, d);
1048 store_reg_to_var_int(iptr->dst, d);
1051 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1053 var_to_reg_int(s1, src->prev, REG_ITMP1);
1054 var_to_reg_int(s2, src, REG_ITMP2);
1055 d = reg_of_var(iptr->dst, REG_ITMP3);
1057 store_reg_to_var_int(iptr->dst, d);
1060 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
1061 /* val.l = constant */
1063 var_to_reg_int(s1, src, REG_ITMP1);
1064 d = reg_of_var(iptr->dst, REG_ITMP3);
1065 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1066 M_LSUB_IMM(s1, iptr->val.l, d);
1069 LCONST(REG_ITMP2, iptr->val.l);
1070 M_LSUB(s1, REG_ITMP2, d);
1072 store_reg_to_var_int(iptr->dst, d);
1075 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1077 var_to_reg_int(s1, src->prev, REG_ITMP1);
1078 var_to_reg_int(s2, src, REG_ITMP2);
1079 d = reg_of_var(iptr->dst, REG_ITMP3);
1081 store_reg_to_var_int(iptr->dst, d);
1084 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
1085 /* val.i = constant */
1087 var_to_reg_int(s1, src, REG_ITMP1);
1088 d = reg_of_var(iptr->dst, REG_ITMP3);
1089 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1090 M_IMUL_IMM(s1, iptr->val.i, d);
1093 ICONST(REG_ITMP2, iptr->val.i);
1094 M_IMUL(s1, REG_ITMP2, d);
1096 store_reg_to_var_int(iptr->dst, d);
1099 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1101 var_to_reg_int(s1, src->prev, REG_ITMP1);
1102 var_to_reg_int(s2, src, REG_ITMP2);
1103 d = reg_of_var(iptr->dst, REG_ITMP3);
1105 store_reg_to_var_int(iptr->dst, d);
1108 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
1109 /* val.l = constant */
1111 var_to_reg_int(s1, src, REG_ITMP1);
1112 d = reg_of_var(iptr->dst, REG_ITMP3);
1113 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1114 M_LMUL_IMM(s1, iptr->val.l, d);
1117 LCONST(REG_ITMP2, iptr->val.l);
1118 M_LMUL(s1, REG_ITMP2, d);
1120 store_reg_to_var_int(iptr->dst, d);
1123 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
1124 case ICMD_LDIVPOW2: /* val.i = constant */
1126 var_to_reg_int(s1, src, REG_ITMP1);
1127 d = reg_of_var(iptr->dst, REG_ITMP3);
1128 if (iptr->val.i <= 15) {
1129 M_LDA(REG_ITMP2, s1, (1 << iptr->val.i) -1);
1130 M_CMOVGE(s1, s1, REG_ITMP2);
1133 M_SRA_IMM(s1, 63, REG_ITMP2);
1134 M_SRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
1135 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1137 M_SRA_IMM(REG_ITMP2, iptr->val.i, d);
1138 store_reg_to_var_int(iptr->dst, d);
1141 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1143 var_to_reg_int(s1, src->prev, REG_ITMP1);
1144 var_to_reg_int(s2, src, REG_ITMP2);
1145 d = reg_of_var(iptr->dst, REG_ITMP3);
1146 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1147 M_SLL(s1, REG_ITMP3, d);
1148 M_IADD(d, REG_ZERO, d);
1149 store_reg_to_var_int(iptr->dst, d);
1152 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1153 /* val.i = constant */
1155 var_to_reg_int(s1, src, REG_ITMP1);
1156 d = reg_of_var(iptr->dst, REG_ITMP3);
1157 M_SLL_IMM(s1, iptr->val.i & 0x1f, d);
1158 M_IADD(d, REG_ZERO, d);
1159 store_reg_to_var_int(iptr->dst, d);
1162 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1164 var_to_reg_int(s1, src->prev, REG_ITMP1);
1165 var_to_reg_int(s2, src, REG_ITMP2);
1166 d = reg_of_var(iptr->dst, REG_ITMP3);
1167 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1168 M_SRA(s1, REG_ITMP3, d);
1169 store_reg_to_var_int(iptr->dst, d);
1172 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1173 /* val.i = constant */
1175 var_to_reg_int(s1, src, REG_ITMP1);
1176 d = reg_of_var(iptr->dst, REG_ITMP3);
1177 M_SRA_IMM(s1, iptr->val.i & 0x1f, d);
1178 store_reg_to_var_int(iptr->dst, d);
1181 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1183 var_to_reg_int(s1, src->prev, REG_ITMP1);
1184 var_to_reg_int(s2, src, REG_ITMP2);
1185 d = reg_of_var(iptr->dst, REG_ITMP3);
1186 M_AND_IMM(s2, 0x1f, REG_ITMP2);
1188 M_SRL(d, REG_ITMP2, d);
1189 M_IADD(d, REG_ZERO, d);
1190 store_reg_to_var_int(iptr->dst, d);
1193 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1194 /* val.i = constant */
1196 var_to_reg_int(s1, src, REG_ITMP1);
1197 d = reg_of_var(iptr->dst, REG_ITMP3);
1199 M_SRL_IMM(d, iptr->val.i & 0x1f, d);
1200 M_IADD(d, REG_ZERO, d);
1201 store_reg_to_var_int(iptr->dst, d);
1204 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1206 var_to_reg_int(s1, src->prev, REG_ITMP1);
1207 var_to_reg_int(s2, src, REG_ITMP2);
1208 d = reg_of_var(iptr->dst, REG_ITMP3);
1210 store_reg_to_var_int(iptr->dst, d);
1213 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1214 /* val.i = constant */
1216 var_to_reg_int(s1, src, REG_ITMP1);
1217 d = reg_of_var(iptr->dst, REG_ITMP3);
1218 M_SLL_IMM(s1, iptr->val.i & 0x3f, d);
1219 store_reg_to_var_int(iptr->dst, d);
1222 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1224 var_to_reg_int(s1, src->prev, REG_ITMP1);
1225 var_to_reg_int(s2, src, REG_ITMP2);
1226 d = reg_of_var(iptr->dst, REG_ITMP3);
1228 store_reg_to_var_int(iptr->dst, d);
1231 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1232 /* val.i = constant */
1234 var_to_reg_int(s1, src, REG_ITMP1);
1235 d = reg_of_var(iptr->dst, REG_ITMP3);
1236 M_SRA_IMM(s1, iptr->val.i & 0x3f, d);
1237 store_reg_to_var_int(iptr->dst, d);
1240 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1242 var_to_reg_int(s1, src->prev, REG_ITMP1);
1243 var_to_reg_int(s2, src, REG_ITMP2);
1244 d = reg_of_var(iptr->dst, REG_ITMP3);
1246 store_reg_to_var_int(iptr->dst, d);
1249 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1250 /* val.i = constant */
1252 var_to_reg_int(s1, src, REG_ITMP1);
1253 d = reg_of_var(iptr->dst, REG_ITMP3);
1254 M_SRL_IMM(s1, iptr->val.i & 0x3f, d);
1255 store_reg_to_var_int(iptr->dst, d);
1258 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1261 var_to_reg_int(s1, src->prev, REG_ITMP1);
1262 var_to_reg_int(s2, src, REG_ITMP2);
1263 d = reg_of_var(iptr->dst, REG_ITMP3);
1265 store_reg_to_var_int(iptr->dst, d);
1268 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1269 /* val.i = constant */
1271 var_to_reg_int(s1, src, REG_ITMP1);
1272 d = reg_of_var(iptr->dst, REG_ITMP3);
1273 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1274 M_AND_IMM(s1, iptr->val.i, d);
1276 else if (iptr->val.i == 0xffff) {
1279 else if (iptr->val.i == 0xffffff) {
1280 M_ZAPNOT_IMM(s1, 0x07, d);
1283 ICONST(REG_ITMP2, iptr->val.i);
1284 M_AND(s1, REG_ITMP2, d);
1286 store_reg_to_var_int(iptr->dst, d);
1289 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1290 /* val.i = constant */
1292 var_to_reg_int(s1, src, REG_ITMP1);
1293 d = reg_of_var(iptr->dst, REG_ITMP3);
1295 M_MOV(s1, REG_ITMP1);
1298 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1299 M_AND_IMM(s1, iptr->val.i, d);
1301 M_ISUB(REG_ZERO, s1, d);
1302 M_AND_IMM(d, iptr->val.i, d);
1304 else if (iptr->val.i == 0xffff) {
1307 M_ISUB(REG_ZERO, s1, d);
1310 else if (iptr->val.i == 0xffffff) {
1311 M_ZAPNOT_IMM(s1, 0x07, d);
1313 M_ISUB(REG_ZERO, s1, d);
1314 M_ZAPNOT_IMM(d, 0x07, d);
1317 ICONST(REG_ITMP2, iptr->val.i);
1318 M_AND(s1, REG_ITMP2, d);
1320 M_ISUB(REG_ZERO, s1, d);
1321 M_AND(d, REG_ITMP2, d);
1323 M_ISUB(REG_ZERO, d, d);
1324 store_reg_to_var_int(iptr->dst, d);
1327 case ICMD_IREM0X10001: /* ..., value ==> ..., value % 0x100001 */
1329 /* b = value & 0xffff;
1331 a = ((b - a) & 0xffff) + (b < a);
1333 var_to_reg_int(s1, src, REG_ITMP1);
1334 d = reg_of_var(iptr->dst, REG_ITMP3);
1336 M_MOV(s1, REG_ITMP3);
1340 M_CZEXT(s1, REG_ITMP2);
1341 M_SRA_IMM(s1, 16, d);
1342 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1343 M_ISUB(REG_ITMP2, d, d);
1345 M_IADD(d, REG_ITMP1, d);
1346 M_BR(11 + (s1 == REG_ITMP1));
1347 M_ISUB(REG_ZERO, s1, REG_ITMP1);
1348 M_CZEXT(REG_ITMP1, REG_ITMP2);
1349 M_SRA_IMM(REG_ITMP1, 16, d);
1350 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1351 M_ISUB(REG_ITMP2, d, d);
1353 M_IADD(d, REG_ITMP1, d);
1354 M_ISUB(REG_ZERO, d, d);
1355 if (s1 == REG_ITMP1) {
1356 var_to_reg_int(s1, src, REG_ITMP1);
1358 M_SLL_IMM(s1, 33, REG_ITMP2);
1359 M_CMPEQ(REG_ITMP2, REG_ZERO, REG_ITMP2);
1360 M_ISUB(d, REG_ITMP2, d);
1361 store_reg_to_var_int(iptr->dst, d);
1364 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1365 /* val.l = constant */
1367 var_to_reg_int(s1, src, REG_ITMP1);
1368 d = reg_of_var(iptr->dst, REG_ITMP3);
1369 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1370 M_AND_IMM(s1, iptr->val.l, d);
1372 else if (iptr->val.l == 0xffffL) {
1375 else if (iptr->val.l == 0xffffffL) {
1376 M_ZAPNOT_IMM(s1, 0x07, d);
1378 else if (iptr->val.l == 0xffffffffL) {
1381 else if (iptr->val.l == 0xffffffffffL) {
1382 M_ZAPNOT_IMM(s1, 0x1f, d);
1384 else if (iptr->val.l == 0xffffffffffffL) {
1385 M_ZAPNOT_IMM(s1, 0x3f, d);
1387 else if (iptr->val.l == 0xffffffffffffffL) {
1388 M_ZAPNOT_IMM(s1, 0x7f, d);
1391 LCONST(REG_ITMP2, iptr->val.l);
1392 M_AND(s1, REG_ITMP2, d);
1394 store_reg_to_var_int(iptr->dst, d);
1397 case ICMD_LREMPOW2: /* ..., 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);
1403 M_MOV(s1, REG_ITMP1);
1406 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1407 M_AND_IMM(s1, iptr->val.l, d);
1409 M_LSUB(REG_ZERO, s1, d);
1410 M_AND_IMM(d, iptr->val.l, d);
1412 else if (iptr->val.l == 0xffffL) {
1415 M_LSUB(REG_ZERO, s1, d);
1418 else if (iptr->val.l == 0xffffffL) {
1419 M_ZAPNOT_IMM(s1, 0x07, d);
1421 M_LSUB(REG_ZERO, s1, d);
1422 M_ZAPNOT_IMM(d, 0x07, d);
1424 else if (iptr->val.l == 0xffffffffL) {
1427 M_LSUB(REG_ZERO, s1, d);
1430 else if (iptr->val.l == 0xffffffffffL) {
1431 M_ZAPNOT_IMM(s1, 0x1f, d);
1433 M_LSUB(REG_ZERO, s1, d);
1434 M_ZAPNOT_IMM(d, 0x1f, d);
1436 else if (iptr->val.l == 0xffffffffffffL) {
1437 M_ZAPNOT_IMM(s1, 0x3f, d);
1439 M_LSUB(REG_ZERO, s1, d);
1440 M_ZAPNOT_IMM(d, 0x3f, d);
1442 else if (iptr->val.l == 0xffffffffffffffL) {
1443 M_ZAPNOT_IMM(s1, 0x7f, d);
1445 M_LSUB(REG_ZERO, s1, d);
1446 M_ZAPNOT_IMM(d, 0x7f, d);
1449 LCONST(REG_ITMP2, iptr->val.l);
1450 M_AND(s1, REG_ITMP2, d);
1452 M_LSUB(REG_ZERO, s1, d);
1453 M_AND(d, REG_ITMP2, d);
1455 M_LSUB(REG_ZERO, d, d);
1456 store_reg_to_var_int(iptr->dst, d);
1459 case ICMD_LREM0X10001:/* ..., value ==> ..., value % 0x10001 */
1461 var_to_reg_int(s1, src, REG_ITMP1);
1462 d = reg_of_var(iptr->dst, REG_ITMP3);
1464 M_MOV(s1, REG_ITMP3);
1467 M_CZEXT(s1, REG_ITMP2);
1468 M_SRA_IMM(s1, 16, d);
1469 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1470 M_LSUB(REG_ITMP2, d, d);
1472 M_LADD(d, REG_ITMP1, d);
1473 M_LDA(REG_ITMP2, REG_ZERO, -1);
1474 M_SRL_IMM(REG_ITMP2, 33, REG_ITMP2);
1475 if (s1 == REG_ITMP1) {
1476 var_to_reg_int(s1, src, REG_ITMP1);
1478 M_CMPULT(s1, REG_ITMP2, REG_ITMP2);
1479 M_BNEZ(REG_ITMP2, 11);
1480 M_LDA(d, REG_ZERO, -257);
1481 M_ZAPNOT_IMM(d, 0xcd, d);
1482 M_LSUB(REG_ZERO, s1, REG_ITMP2);
1483 M_CMOVGE(s1, s1, REG_ITMP2);
1484 M_UMULH(REG_ITMP2, d, REG_ITMP2);
1485 M_SRL_IMM(REG_ITMP2, 16, REG_ITMP2);
1486 M_LSUB(REG_ZERO, REG_ITMP2, d);
1487 M_CMOVGE(s1, REG_ITMP2, d);
1488 M_SLL_IMM(d, 16, REG_ITMP2);
1489 M_LADD(d, REG_ITMP2, d);
1491 store_reg_to_var_int(iptr->dst, d);
1494 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1497 var_to_reg_int(s1, src->prev, REG_ITMP1);
1498 var_to_reg_int(s2, src, REG_ITMP2);
1499 d = reg_of_var(iptr->dst, REG_ITMP3);
1501 store_reg_to_var_int(iptr->dst, d);
1504 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1505 /* val.i = constant */
1507 var_to_reg_int(s1, src, REG_ITMP1);
1508 d = reg_of_var(iptr->dst, REG_ITMP3);
1509 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1510 M_OR_IMM(s1, iptr->val.i, d);
1513 ICONST(REG_ITMP2, iptr->val.i);
1514 M_OR(s1, REG_ITMP2, d);
1516 store_reg_to_var_int(iptr->dst, d);
1519 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1520 /* val.l = constant */
1522 var_to_reg_int(s1, src, REG_ITMP1);
1523 d = reg_of_var(iptr->dst, REG_ITMP3);
1524 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1525 M_OR_IMM(s1, iptr->val.l, d);
1528 LCONST(REG_ITMP2, iptr->val.l);
1529 M_OR(s1, REG_ITMP2, d);
1531 store_reg_to_var_int(iptr->dst, d);
1534 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1537 var_to_reg_int(s1, src->prev, REG_ITMP1);
1538 var_to_reg_int(s2, src, REG_ITMP2);
1539 d = reg_of_var(iptr->dst, REG_ITMP3);
1541 store_reg_to_var_int(iptr->dst, d);
1544 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1545 /* val.i = constant */
1547 var_to_reg_int(s1, src, REG_ITMP1);
1548 d = reg_of_var(iptr->dst, REG_ITMP3);
1549 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1550 M_XOR_IMM(s1, iptr->val.i, d);
1553 ICONST(REG_ITMP2, iptr->val.i);
1554 M_XOR(s1, REG_ITMP2, d);
1556 store_reg_to_var_int(iptr->dst, d);
1559 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1560 /* val.l = constant */
1562 var_to_reg_int(s1, src, REG_ITMP1);
1563 d = reg_of_var(iptr->dst, REG_ITMP3);
1564 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1565 M_XOR_IMM(s1, iptr->val.l, d);
1568 LCONST(REG_ITMP2, iptr->val.l);
1569 M_XOR(s1, REG_ITMP2, d);
1571 store_reg_to_var_int(iptr->dst, d);
1575 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1577 var_to_reg_int(s1, src->prev, REG_ITMP1);
1578 var_to_reg_int(s2, src, REG_ITMP2);
1579 d = reg_of_var(iptr->dst, REG_ITMP3);
1580 M_CMPLT(s1, s2, REG_ITMP3);
1581 M_CMPLT(s2, s1, REG_ITMP1);
1582 M_LSUB (REG_ITMP1, REG_ITMP3, d);
1583 store_reg_to_var_int(iptr->dst, d);
1587 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1588 /* op1 = variable, val.i = constant */
1590 var = &(locals[iptr->op1][TYPE_INT]);
1591 if (var->flags & INMEMORY) {
1593 M_LLD(s1, REG_SP, 8 * var->regoff);
1597 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1598 M_IADD_IMM(s1, iptr->val.i, s1);
1600 else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1601 M_ISUB_IMM(s1, (-iptr->val.i), s1);
1604 M_LDA (s1, s1, iptr->val.i);
1605 M_IADD(s1, REG_ZERO, s1);
1607 if (var->flags & INMEMORY)
1608 M_LST(s1, REG_SP, 8 * var->regoff);
1612 /* floating operations ************************************************/
1614 case ICMD_FNEG: /* ..., value ==> ..., - value */
1616 var_to_reg_flt(s1, src, REG_FTMP1);
1617 d = reg_of_var(iptr->dst, REG_FTMP3);
1619 store_reg_to_var_flt(iptr->dst, d);
1622 case ICMD_DNEG: /* ..., value ==> ..., - value */
1624 var_to_reg_flt(s1, src, REG_FTMP1);
1625 d = reg_of_var(iptr->dst, REG_FTMP3);
1627 store_reg_to_var_flt(iptr->dst, d);
1630 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1632 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1633 var_to_reg_flt(s2, src, REG_FTMP2);
1634 d = reg_of_var(iptr->dst, REG_FTMP3);
1639 if (d == s1 || d == s2) {
1640 M_FADDS(s1, s2, REG_FTMP3);
1642 M_FMOV(REG_FTMP3, d);
1649 store_reg_to_var_flt(iptr->dst, d);
1652 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1654 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1655 var_to_reg_flt(s2, src, REG_FTMP2);
1656 d = reg_of_var(iptr->dst, REG_FTMP3);
1661 if (d == s1 || d == s2) {
1662 M_DADDS(s1, s2, REG_FTMP3);
1664 M_FMOV(REG_FTMP3, d);
1671 store_reg_to_var_flt(iptr->dst, d);
1674 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1676 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1677 var_to_reg_flt(s2, src, REG_FTMP2);
1678 d = reg_of_var(iptr->dst, REG_FTMP3);
1683 if (d == s1 || d == s2) {
1684 M_FSUBS(s1, s2, REG_FTMP3);
1686 M_FMOV(REG_FTMP3, d);
1693 store_reg_to_var_flt(iptr->dst, d);
1696 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1698 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1699 var_to_reg_flt(s2, src, REG_FTMP2);
1700 d = reg_of_var(iptr->dst, REG_FTMP3);
1705 if (d == s1 || d == s2) {
1706 M_DSUBS(s1, s2, REG_FTMP3);
1708 M_FMOV(REG_FTMP3, d);
1715 store_reg_to_var_flt(iptr->dst, d);
1718 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1720 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1721 var_to_reg_flt(s2, src, REG_FTMP2);
1722 d = reg_of_var(iptr->dst, REG_FTMP3);
1727 if (d == s1 || d == s2) {
1728 M_FMULS(s1, s2, REG_FTMP3);
1730 M_FMOV(REG_FTMP3, d);
1737 store_reg_to_var_flt(iptr->dst, d);
1740 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1742 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1743 var_to_reg_flt(s2, src, REG_FTMP2);
1744 d = reg_of_var(iptr->dst, REG_FTMP3);
1749 if (d == s1 || d == s2) {
1750 M_DMULS(s1, s2, REG_FTMP3);
1752 M_FMOV(REG_FTMP3, d);
1759 store_reg_to_var_flt(iptr->dst, d);
1762 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1764 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1765 var_to_reg_flt(s2, src, REG_FTMP2);
1766 d = reg_of_var(iptr->dst, REG_FTMP3);
1771 if (d == s1 || d == s2) {
1772 M_FDIVS(s1, s2, REG_FTMP3);
1774 M_FMOV(REG_FTMP3, d);
1781 store_reg_to_var_flt(iptr->dst, d);
1784 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1786 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1787 var_to_reg_flt(s2, src, REG_FTMP2);
1788 d = reg_of_var(iptr->dst, REG_FTMP3);
1793 if (d == s1 || d == s2) {
1794 M_DDIVS(s1, s2, REG_FTMP3);
1796 M_FMOV(REG_FTMP3, d);
1803 store_reg_to_var_flt(iptr->dst, d);
1806 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1808 var_to_reg_int(s1, src, REG_ITMP1);
1809 d = reg_of_var(iptr->dst, REG_FTMP3);
1810 a = dseg_adddouble(0.0);
1811 M_LST (s1, REG_PV, a);
1812 M_DLD (d, REG_PV, a);
1814 store_reg_to_var_flt(iptr->dst, d);
1817 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1819 var_to_reg_int(s1, src, REG_ITMP1);
1820 d = reg_of_var(iptr->dst, REG_FTMP3);
1821 a = dseg_adddouble(0.0);
1822 M_LST (s1, REG_PV, a);
1823 M_DLD (d, REG_PV, a);
1825 store_reg_to_var_flt(iptr->dst, d);
1828 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1830 var_to_reg_flt(s1, src, REG_FTMP1);
1831 d = reg_of_var(iptr->dst, REG_ITMP3);
1832 a = dseg_adddouble(0.0);
1833 M_CVTDL_C(s1, REG_FTMP2);
1834 M_CVTLI(REG_FTMP2, REG_FTMP3);
1835 M_DST (REG_FTMP3, REG_PV, a);
1836 M_ILD (d, REG_PV, a);
1837 store_reg_to_var_int(iptr->dst, d);
1840 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1842 var_to_reg_flt(s1, src, REG_FTMP1);
1843 d = reg_of_var(iptr->dst, REG_ITMP3);
1844 a = dseg_adddouble(0.0);
1845 M_CVTDL_C(s1, REG_FTMP2);
1846 M_DST (REG_FTMP2, REG_PV, a);
1847 M_LLD (d, REG_PV, a);
1848 store_reg_to_var_int(iptr->dst, d);
1851 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1853 var_to_reg_flt(s1, src, REG_FTMP1);
1854 d = reg_of_var(iptr->dst, REG_FTMP3);
1857 store_reg_to_var_flt(iptr->dst, d);
1860 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1862 var_to_reg_flt(s1, src, REG_FTMP1);
1863 d = reg_of_var(iptr->dst, REG_FTMP3);
1871 store_reg_to_var_flt(iptr->dst, d);
1874 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1876 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1877 var_to_reg_flt(s2, src, REG_FTMP2);
1878 d = reg_of_var(iptr->dst, REG_ITMP3);
1880 M_LSUB_IMM(REG_ZERO, 1, d);
1881 M_FCMPEQ(s1, s2, REG_FTMP3);
1882 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1884 M_FCMPLT(s2, s1, REG_FTMP3);
1885 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1886 M_LADD_IMM(REG_ZERO, 1, d);
1889 M_LSUB_IMM(REG_ZERO, 1, d);
1890 M_FCMPEQS(s1, s2, REG_FTMP3);
1892 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1894 M_FCMPLTS(s2, s1, REG_FTMP3);
1896 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1897 M_LADD_IMM(REG_ZERO, 1, d);
1899 store_reg_to_var_int(iptr->dst, d);
1902 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1904 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1905 var_to_reg_flt(s2, src, REG_FTMP2);
1906 d = reg_of_var(iptr->dst, REG_ITMP3);
1908 M_LADD_IMM(REG_ZERO, 1, d);
1909 M_FCMPEQ(s1, s2, REG_FTMP3);
1910 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1912 M_FCMPLT(s1, s2, REG_FTMP3);
1913 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1914 M_LSUB_IMM(REG_ZERO, 1, d);
1917 M_LADD_IMM(REG_ZERO, 1, d);
1918 M_FCMPEQS(s1, s2, REG_FTMP3);
1920 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1922 M_FCMPLTS(s1, s2, REG_FTMP3);
1924 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1925 M_LSUB_IMM(REG_ZERO, 1, d);
1927 store_reg_to_var_int(iptr->dst, d);
1931 /* memory operations **************************************************/
1933 #define gen_bound_check \
1934 if (checkbounds) { \
1935 M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\
1936 M_CMPULT(s2, REG_ITMP3, REG_ITMP3);\
1937 M_BEQZ(REG_ITMP3, 0);\
1938 codegen_addxboundrefs(mcodeptr, s2); \
1941 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1943 var_to_reg_int(s1, src, REG_ITMP1);
1944 d = reg_of_var(iptr->dst, REG_ITMP3);
1945 gen_nullptr_check(s1);
1946 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1947 store_reg_to_var_int(iptr->dst, d);
1950 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1952 var_to_reg_int(s1, src->prev, REG_ITMP1);
1953 var_to_reg_int(s2, src, REG_ITMP2);
1954 d = reg_of_var(iptr->dst, REG_ITMP3);
1955 if (iptr->op1 == 0) {
1956 gen_nullptr_check(s1);
1959 M_SAADDQ(s2, s1, REG_ITMP1);
1960 M_ALD( d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1961 store_reg_to_var_int(iptr->dst, d);
1964 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1966 var_to_reg_int(s1, src->prev, REG_ITMP1);
1967 var_to_reg_int(s2, src, REG_ITMP2);
1968 d = reg_of_var(iptr->dst, REG_ITMP3);
1969 if (iptr->op1 == 0) {
1970 gen_nullptr_check(s1);
1973 M_S8ADDQ(s2, s1, REG_ITMP1);
1974 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1975 store_reg_to_var_int(iptr->dst, d);
1978 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1980 var_to_reg_int(s1, src->prev, REG_ITMP1);
1981 var_to_reg_int(s2, src, REG_ITMP2);
1982 d = reg_of_var(iptr->dst, REG_ITMP3);
1983 if (iptr->op1 == 0) {
1984 gen_nullptr_check(s1);
1988 M_S4ADDQ(s2, s1, REG_ITMP1);
1989 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1990 store_reg_to_var_int(iptr->dst, d);
1993 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1995 var_to_reg_int(s1, src->prev, REG_ITMP1);
1996 var_to_reg_int(s2, src, REG_ITMP2);
1997 d = reg_of_var(iptr->dst, REG_FTMP3);
1998 if (iptr->op1 == 0) {
1999 gen_nullptr_check(s1);
2002 M_S4ADDQ(s2, s1, REG_ITMP1);
2003 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
2004 store_reg_to_var_flt(iptr->dst, d);
2007 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
2009 var_to_reg_int(s1, src->prev, REG_ITMP1);
2010 var_to_reg_int(s2, src, REG_ITMP2);
2011 d = reg_of_var(iptr->dst, REG_FTMP3);
2012 if (iptr->op1 == 0) {
2013 gen_nullptr_check(s1);
2016 M_S8ADDQ(s2, s1, REG_ITMP1);
2017 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
2018 store_reg_to_var_flt(iptr->dst, d);
2021 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
2023 var_to_reg_int(s1, src->prev, REG_ITMP1);
2024 var_to_reg_int(s2, src, REG_ITMP2);
2025 d = reg_of_var(iptr->dst, REG_ITMP3);
2026 if (iptr->op1 == 0) {
2027 gen_nullptr_check(s1);
2030 if (has_ext_instr_set) {
2031 M_LADD(s2, s1, REG_ITMP1);
2032 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2033 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
2036 M_LADD (s2, s1, REG_ITMP1);
2037 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2038 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2039 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2040 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
2042 store_reg_to_var_int(iptr->dst, d);
2045 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
2047 var_to_reg_int(s1, src->prev, REG_ITMP1);
2048 var_to_reg_int(s2, src, REG_ITMP2);
2049 d = reg_of_var(iptr->dst, REG_ITMP3);
2050 if (iptr->op1 == 0) {
2051 gen_nullptr_check(s1);
2054 if (has_ext_instr_set) {
2055 M_LADD(s2, s1, REG_ITMP1);
2056 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2057 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
2061 M_LADD(s2, s1, REG_ITMP1);
2062 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2063 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2064 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
2065 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
2066 M_SRA_IMM(d, 48, d);
2068 store_reg_to_var_int(iptr->dst, d);
2071 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
2073 var_to_reg_int(s1, src->prev, REG_ITMP1);
2074 var_to_reg_int(s2, src, REG_ITMP2);
2075 d = reg_of_var(iptr->dst, REG_ITMP3);
2076 if (iptr->op1 == 0) {
2077 gen_nullptr_check(s1);
2080 if (has_ext_instr_set) {
2081 M_LADD (s2, s1, REG_ITMP1);
2082 M_BLDU (d, REG_ITMP1, OFFSET (java_bytearray, data[0]));
2086 M_LADD(s2, s1, REG_ITMP1);
2087 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2088 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
2089 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
2090 M_SRA_IMM(d, 56, d);
2092 store_reg_to_var_int(iptr->dst, d);
2096 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
2098 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2099 var_to_reg_int(s2, src->prev, REG_ITMP2);
2100 if (iptr->op1 == 0) {
2101 gen_nullptr_check(s1);
2104 var_to_reg_int(s3, src, REG_ITMP3);
2105 M_SAADDQ(s2, s1, REG_ITMP1);
2106 M_AST (s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
2109 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
2111 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2112 var_to_reg_int(s2, src->prev, REG_ITMP2);
2113 if (iptr->op1 == 0) {
2114 gen_nullptr_check(s1);
2117 var_to_reg_int(s3, src, REG_ITMP3);
2118 M_S8ADDQ(s2, s1, REG_ITMP1);
2119 M_LST (s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
2122 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
2124 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2125 var_to_reg_int(s2, src->prev, REG_ITMP2);
2126 if (iptr->op1 == 0) {
2127 gen_nullptr_check(s1);
2131 var_to_reg_int(s3, src, REG_ITMP3);
2132 M_S4ADDQ(s2, s1, REG_ITMP1);
2133 M_IST (s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
2136 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
2138 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2139 var_to_reg_int(s2, src->prev, REG_ITMP2);
2140 if (iptr->op1 == 0) {
2141 gen_nullptr_check(s1);
2144 var_to_reg_flt(s3, src, REG_FTMP3);
2145 M_S4ADDQ(s2, s1, REG_ITMP1);
2146 M_FST (s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
2149 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
2151 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2152 var_to_reg_int(s2, src->prev, REG_ITMP2);
2153 if (iptr->op1 == 0) {
2154 gen_nullptr_check(s1);
2157 var_to_reg_flt(s3, src, REG_FTMP3);
2158 M_S8ADDQ(s2, s1, REG_ITMP1);
2159 M_DST (s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
2162 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
2164 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2165 var_to_reg_int(s2, src->prev, REG_ITMP2);
2166 if (iptr->op1 == 0) {
2167 gen_nullptr_check(s1);
2170 var_to_reg_int(s3, src, REG_ITMP3);
2171 if (has_ext_instr_set) {
2172 M_LADD(s2, s1, REG_ITMP1);
2173 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2174 M_SST (s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
2177 M_LADD (s2, s1, REG_ITMP1);
2178 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2179 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2180 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2181 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
2182 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2183 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2184 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2188 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
2190 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2191 var_to_reg_int(s2, src->prev, REG_ITMP2);
2192 if (iptr->op1 == 0) {
2193 gen_nullptr_check(s1);
2196 var_to_reg_int(s3, src, REG_ITMP3);
2197 if (has_ext_instr_set) {
2198 M_LADD(s2, s1, REG_ITMP1);
2199 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2200 M_SST (s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2203 M_LADD (s2, s1, REG_ITMP1);
2204 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2205 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2206 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2207 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
2208 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2209 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2210 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2214 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
2216 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2217 var_to_reg_int(s2, src->prev, REG_ITMP2);
2218 if (iptr->op1 == 0) {
2219 gen_nullptr_check(s1);
2222 var_to_reg_int(s3, src, REG_ITMP3);
2223 if (has_ext_instr_set) {
2224 M_LADD(s2, s1, REG_ITMP1);
2225 M_BST (s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2228 M_LADD (s2, s1, REG_ITMP1);
2229 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2230 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2231 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
2232 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2233 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2234 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2239 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2240 /* op1 = type, val.a = field address */
2242 /* if class isn't yet initialized, do it */
2243 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
2244 /* call helper function which patches this code */
2245 a = dseg_addaddress(((fieldinfo *) iptr->val.a)->class);
2246 M_ALD(REG_ITMP1, REG_PV, a);
2247 a = dseg_addaddress(asm_check_clinit);
2248 M_ALD(REG_PV, REG_PV, a);
2249 M_JSR(REG_RA, REG_PV);
2252 s1 = (int) ((u1*) mcodeptr - mcodebase);
2254 M_LDA(REG_PV, REG_RA, -s1);
2258 s4 ml = -s1, mh = 0;
2259 while (ml < -32768) { ml += 65536; mh--; }
2260 M_LDA(REG_PV, REG_RA, ml);
2261 M_LDAH(REG_PV, REG_PV, mh);
2265 a = dseg_addaddress(&(((fieldinfo *)(iptr->val.a))->value));
2266 M_ALD(REG_ITMP1, REG_PV, a);
2267 switch (iptr->op1) {
2269 var_to_reg_int(s2, src, REG_ITMP2);
2270 M_IST(s2, REG_ITMP1, 0);
2273 var_to_reg_int(s2, src, REG_ITMP2);
2274 M_LST(s2, REG_ITMP1, 0);
2277 var_to_reg_int(s2, src, REG_ITMP2);
2278 M_AST(s2, REG_ITMP1, 0);
2281 var_to_reg_flt(s2, src, REG_FTMP2);
2282 M_FST(s2, REG_ITMP1, 0);
2285 var_to_reg_flt(s2, src, REG_FTMP2);
2286 M_DST(s2, REG_ITMP1, 0);
2288 default: panic ("internal error");
2292 case ICMD_GETSTATIC: /* ... ==> ..., value */
2293 /* op1 = type, val.a = field address */
2295 /* if class isn't yet initialized, do it */
2296 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
2297 /* call helper function which patches this code */
2298 a = dseg_addaddress(((fieldinfo *) iptr->val.a)->class);
2299 M_ALD(REG_ITMP1, REG_PV, a);
2300 a = dseg_addaddress(asm_check_clinit);
2301 M_ALD(REG_PV, REG_PV, a);
2302 M_JSR(REG_RA, REG_PV);
2305 s1 = (int) ((u1*) mcodeptr - mcodebase);
2307 M_LDA(REG_PV, REG_RA, -s1);
2311 s4 ml = -s1, mh = 0;
2312 while (ml < -32768) { ml += 65536; mh--; }
2313 M_LDA(REG_PV, REG_RA, ml);
2314 M_LDAH(REG_PV, REG_PV, mh);
2318 a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value));
2319 M_ALD(REG_ITMP1, REG_PV, a);
2320 switch (iptr->op1) {
2322 d = reg_of_var(iptr->dst, REG_ITMP3);
2323 M_ILD(d, REG_ITMP1, 0);
2324 store_reg_to_var_int(iptr->dst, d);
2327 d = reg_of_var(iptr->dst, REG_ITMP3);
2328 M_LLD(d, REG_ITMP1, 0);
2329 store_reg_to_var_int(iptr->dst, d);
2332 d = reg_of_var(iptr->dst, REG_ITMP3);
2333 M_ALD(d, REG_ITMP1, 0);
2334 store_reg_to_var_int(iptr->dst, d);
2337 d = reg_of_var(iptr->dst, REG_FTMP1);
2338 M_FLD(d, REG_ITMP1, 0);
2339 store_reg_to_var_flt(iptr->dst, d);
2342 d = reg_of_var(iptr->dst, REG_FTMP1);
2343 M_DLD(d, REG_ITMP1, 0);
2344 store_reg_to_var_flt(iptr->dst, d);
2346 default: panic ("internal error");
2351 case ICMD_PUTFIELD: /* ..., value ==> ... */
2352 /* op1 = type, val.i = field offset */
2354 a = ((fieldinfo *)(iptr->val.a))->offset;
2355 switch (iptr->op1) {
2357 var_to_reg_int(s1, src->prev, REG_ITMP1);
2358 var_to_reg_int(s2, src, REG_ITMP2);
2359 gen_nullptr_check(s1);
2363 var_to_reg_int(s1, src->prev, REG_ITMP1);
2364 var_to_reg_int(s2, src, REG_ITMP2);
2365 gen_nullptr_check(s1);
2369 var_to_reg_int(s1, src->prev, REG_ITMP1);
2370 var_to_reg_int(s2, src, REG_ITMP2);
2371 gen_nullptr_check(s1);
2375 var_to_reg_int(s1, src->prev, REG_ITMP1);
2376 var_to_reg_flt(s2, src, REG_FTMP2);
2377 gen_nullptr_check(s1);
2381 var_to_reg_int(s1, src->prev, REG_ITMP1);
2382 var_to_reg_flt(s2, src, REG_FTMP2);
2383 gen_nullptr_check(s1);
2386 default: panic ("internal error");
2390 case ICMD_GETFIELD: /* ... ==> ..., value */
2391 /* op1 = type, val.i = field offset */
2393 a = ((fieldinfo *)(iptr->val.a))->offset;
2394 switch (iptr->op1) {
2396 var_to_reg_int(s1, src, REG_ITMP1);
2397 d = reg_of_var(iptr->dst, REG_ITMP3);
2398 gen_nullptr_check(s1);
2400 store_reg_to_var_int(iptr->dst, d);
2403 var_to_reg_int(s1, src, REG_ITMP1);
2404 d = reg_of_var(iptr->dst, REG_ITMP3);
2405 gen_nullptr_check(s1);
2407 store_reg_to_var_int(iptr->dst, d);
2410 var_to_reg_int(s1, src, REG_ITMP1);
2411 d = reg_of_var(iptr->dst, REG_ITMP3);
2412 gen_nullptr_check(s1);
2414 store_reg_to_var_int(iptr->dst, d);
2417 var_to_reg_int(s1, src, REG_ITMP1);
2418 d = reg_of_var(iptr->dst, REG_FTMP1);
2419 gen_nullptr_check(s1);
2421 store_reg_to_var_flt(iptr->dst, d);
2424 var_to_reg_int(s1, src, REG_ITMP1);
2425 d = reg_of_var(iptr->dst, REG_FTMP1);
2426 gen_nullptr_check(s1);
2428 store_reg_to_var_flt(iptr->dst, d);
2430 default: panic ("internal error");
2435 /* branch operations **************************************************/
2437 #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}}
2439 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2441 var_to_reg_int(s1, src, REG_ITMP1);
2442 M_INTMOVE(s1, REG_ITMP1_XPTR);
2443 a = dseg_addaddress(asm_handle_exception);
2444 M_ALD(REG_ITMP2, REG_PV, a);
2445 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2446 M_NOP; /* nop ensures that XPC is less than the end */
2447 /* of basic block */
2451 case ICMD_GOTO: /* ... ==> ... */
2452 /* op1 = target JavaVM pc */
2454 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2458 case ICMD_JSR: /* ... ==> ... */
2459 /* op1 = target JavaVM pc */
2461 M_BSR(REG_ITMP1, 0);
2462 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2465 case ICMD_RET: /* ... ==> ... */
2466 /* op1 = local variable */
2468 var = &(locals[iptr->op1][TYPE_ADR]);
2469 if (var->flags & INMEMORY) {
2470 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2471 M_RET(REG_ZERO, REG_ITMP1);
2474 M_RET(REG_ZERO, var->regoff);
2478 case ICMD_IFNULL: /* ..., value ==> ... */
2479 /* op1 = target JavaVM pc */
2481 var_to_reg_int(s1, src, REG_ITMP1);
2483 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2486 case ICMD_IFNONNULL: /* ..., value ==> ... */
2487 /* op1 = target JavaVM pc */
2489 var_to_reg_int(s1, src, REG_ITMP1);
2491 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2494 case ICMD_IFEQ: /* ..., value ==> ... */
2495 /* op1 = target JavaVM pc, val.i = constant */
2497 var_to_reg_int(s1, src, REG_ITMP1);
2498 if (iptr->val.i == 0) {
2502 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2503 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2506 ICONST(REG_ITMP2, iptr->val.i);
2507 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2509 M_BNEZ(REG_ITMP1, 0);
2511 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2514 case ICMD_IFLT: /* ..., value ==> ... */
2515 /* op1 = target JavaVM pc, val.i = constant */
2517 var_to_reg_int(s1, src, REG_ITMP1);
2518 if (iptr->val.i == 0) {
2522 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2523 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2526 ICONST(REG_ITMP2, iptr->val.i);
2527 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2529 M_BNEZ(REG_ITMP1, 0);
2531 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2534 case ICMD_IFLE: /* ..., value ==> ... */
2535 /* op1 = target JavaVM pc, val.i = constant */
2537 var_to_reg_int(s1, src, REG_ITMP1);
2538 if (iptr->val.i == 0) {
2542 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2543 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2546 ICONST(REG_ITMP2, iptr->val.i);
2547 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2549 M_BNEZ(REG_ITMP1, 0);
2551 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2554 case ICMD_IFNE: /* ..., value ==> ... */
2555 /* op1 = target JavaVM pc, val.i = constant */
2557 var_to_reg_int(s1, src, REG_ITMP1);
2558 if (iptr->val.i == 0) {
2562 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2563 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2566 ICONST(REG_ITMP2, iptr->val.i);
2567 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2569 M_BEQZ(REG_ITMP1, 0);
2571 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2574 case ICMD_IFGT: /* ..., value ==> ... */
2575 /* op1 = target JavaVM pc, val.i = constant */
2577 var_to_reg_int(s1, src, REG_ITMP1);
2578 if (iptr->val.i == 0) {
2582 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2583 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2586 ICONST(REG_ITMP2, iptr->val.i);
2587 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2589 M_BEQZ(REG_ITMP1, 0);
2591 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2594 case ICMD_IFGE: /* ..., value ==> ... */
2595 /* op1 = target JavaVM pc, val.i = constant */
2597 var_to_reg_int(s1, src, REG_ITMP1);
2598 if (iptr->val.i == 0) {
2602 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2603 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2606 ICONST(REG_ITMP2, iptr->val.i);
2607 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2609 M_BEQZ(REG_ITMP1, 0);
2611 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2614 case ICMD_IF_LEQ: /* ..., value ==> ... */
2615 /* op1 = target JavaVM pc, val.l = constant */
2617 var_to_reg_int(s1, src, REG_ITMP1);
2618 if (iptr->val.l == 0) {
2622 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2623 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2626 LCONST(REG_ITMP2, iptr->val.l);
2627 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2629 M_BNEZ(REG_ITMP1, 0);
2631 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2634 case ICMD_IF_LLT: /* ..., value ==> ... */
2635 /* op1 = target JavaVM pc, val.l = constant */
2637 var_to_reg_int(s1, src, REG_ITMP1);
2638 if (iptr->val.l == 0) {
2642 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2643 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2646 LCONST(REG_ITMP2, iptr->val.l);
2647 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2649 M_BNEZ(REG_ITMP1, 0);
2651 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2654 case ICMD_IF_LLE: /* ..., value ==> ... */
2655 /* op1 = target JavaVM pc, val.l = constant */
2657 var_to_reg_int(s1, src, REG_ITMP1);
2658 if (iptr->val.l == 0) {
2662 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2663 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2666 LCONST(REG_ITMP2, iptr->val.l);
2667 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2669 M_BNEZ(REG_ITMP1, 0);
2671 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2674 case ICMD_IF_LNE: /* ..., value ==> ... */
2675 /* op1 = target JavaVM pc, val.l = constant */
2677 var_to_reg_int(s1, src, REG_ITMP1);
2678 if (iptr->val.l == 0) {
2682 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2683 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2686 LCONST(REG_ITMP2, iptr->val.l);
2687 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2689 M_BEQZ(REG_ITMP1, 0);
2691 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2694 case ICMD_IF_LGT: /* ..., value ==> ... */
2695 /* op1 = target JavaVM pc, val.l = constant */
2697 var_to_reg_int(s1, src, REG_ITMP1);
2698 if (iptr->val.l == 0) {
2702 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2703 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2706 LCONST(REG_ITMP2, iptr->val.l);
2707 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2709 M_BEQZ(REG_ITMP1, 0);
2711 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2714 case ICMD_IF_LGE: /* ..., value ==> ... */
2715 /* op1 = target JavaVM pc, val.l = constant */
2717 var_to_reg_int(s1, src, REG_ITMP1);
2718 if (iptr->val.l == 0) {
2722 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2723 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2726 LCONST(REG_ITMP2, iptr->val.l);
2727 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2729 M_BEQZ(REG_ITMP1, 0);
2731 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2734 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2735 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2736 case ICMD_IF_ACMPEQ:
2738 var_to_reg_int(s1, src->prev, REG_ITMP1);
2739 var_to_reg_int(s2, src, REG_ITMP2);
2740 M_CMPEQ(s1, s2, REG_ITMP1);
2741 M_BNEZ(REG_ITMP1, 0);
2742 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2745 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2746 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2747 case ICMD_IF_ACMPNE:
2749 var_to_reg_int(s1, src->prev, REG_ITMP1);
2750 var_to_reg_int(s2, src, REG_ITMP2);
2751 M_CMPEQ(s1, s2, REG_ITMP1);
2752 M_BEQZ(REG_ITMP1, 0);
2753 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2756 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2757 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2759 var_to_reg_int(s1, src->prev, REG_ITMP1);
2760 var_to_reg_int(s2, src, REG_ITMP2);
2761 M_CMPLT(s1, s2, REG_ITMP1);
2762 M_BNEZ(REG_ITMP1, 0);
2763 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2766 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2767 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2769 var_to_reg_int(s1, src->prev, REG_ITMP1);
2770 var_to_reg_int(s2, src, REG_ITMP2);
2771 M_CMPLE(s1, s2, REG_ITMP1);
2772 M_BEQZ(REG_ITMP1, 0);
2773 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2776 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2777 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2779 var_to_reg_int(s1, src->prev, REG_ITMP1);
2780 var_to_reg_int(s2, src, REG_ITMP2);
2781 M_CMPLE(s1, s2, REG_ITMP1);
2782 M_BNEZ(REG_ITMP1, 0);
2783 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2786 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2787 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2789 var_to_reg_int(s1, src->prev, REG_ITMP1);
2790 var_to_reg_int(s2, src, REG_ITMP2);
2791 M_CMPLT(s1, s2, REG_ITMP1);
2792 M_BEQZ(REG_ITMP1, 0);
2793 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2796 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2798 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2801 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2802 /* val.i = constant */
2804 var_to_reg_int(s1, src, REG_ITMP1);
2805 d = reg_of_var(iptr->dst, REG_ITMP3);
2807 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2808 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2809 M_CMPEQ(s1, REG_ZERO, d);
2810 store_reg_to_var_int(iptr->dst, d);
2813 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2814 M_CMPEQ(s1, REG_ZERO, d);
2816 store_reg_to_var_int(iptr->dst, d);
2820 M_MOV(s1, REG_ITMP1);
2823 ICONST(d, iptr[1].val.i);
2825 if ((s3 >= 0) && (s3 <= 255)) {
2826 M_CMOVEQ_IMM(s1, s3, d);
2829 ICONST(REG_ITMP2, s3);
2830 M_CMOVEQ(s1, REG_ITMP2, d);
2832 store_reg_to_var_int(iptr->dst, d);
2835 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2836 /* val.i = constant */
2838 var_to_reg_int(s1, src, REG_ITMP1);
2839 d = reg_of_var(iptr->dst, REG_ITMP3);
2841 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2842 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2843 M_CMPEQ(s1, REG_ZERO, d);
2844 store_reg_to_var_int(iptr->dst, d);
2847 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2848 M_CMPEQ(s1, REG_ZERO, d);
2850 store_reg_to_var_int(iptr->dst, d);
2854 M_MOV(s1, REG_ITMP1);
2857 ICONST(d, iptr[1].val.i);
2859 if ((s3 >= 0) && (s3 <= 255)) {
2860 M_CMOVNE_IMM(s1, s3, d);
2863 ICONST(REG_ITMP2, s3);
2864 M_CMOVNE(s1, REG_ITMP2, d);
2866 store_reg_to_var_int(iptr->dst, d);
2869 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2870 /* val.i = constant */
2872 var_to_reg_int(s1, src, REG_ITMP1);
2873 d = reg_of_var(iptr->dst, REG_ITMP3);
2875 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2876 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2877 M_CMPLT(s1, REG_ZERO, d);
2878 store_reg_to_var_int(iptr->dst, d);
2881 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2882 M_CMPLE(REG_ZERO, s1, d);
2883 store_reg_to_var_int(iptr->dst, d);
2887 M_MOV(s1, REG_ITMP1);
2890 ICONST(d, iptr[1].val.i);
2892 if ((s3 >= 0) && (s3 <= 255)) {
2893 M_CMOVLT_IMM(s1, s3, d);
2896 ICONST(REG_ITMP2, s3);
2897 M_CMOVLT(s1, REG_ITMP2, d);
2899 store_reg_to_var_int(iptr->dst, d);
2902 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2903 /* val.i = constant */
2905 var_to_reg_int(s1, src, REG_ITMP1);
2906 d = reg_of_var(iptr->dst, REG_ITMP3);
2908 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2909 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2910 M_CMPLE(REG_ZERO, s1, d);
2911 store_reg_to_var_int(iptr->dst, d);
2914 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2915 M_CMPLT(s1, REG_ZERO, d);
2916 store_reg_to_var_int(iptr->dst, d);
2920 M_MOV(s1, REG_ITMP1);
2923 ICONST(d, iptr[1].val.i);
2925 if ((s3 >= 0) && (s3 <= 255)) {
2926 M_CMOVGE_IMM(s1, s3, d);
2929 ICONST(REG_ITMP2, s3);
2930 M_CMOVGE(s1, REG_ITMP2, d);
2932 store_reg_to_var_int(iptr->dst, d);
2935 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2936 /* val.i = constant */
2938 var_to_reg_int(s1, src, REG_ITMP1);
2939 d = reg_of_var(iptr->dst, REG_ITMP3);
2941 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2942 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2943 M_CMPLT(REG_ZERO, s1, d);
2944 store_reg_to_var_int(iptr->dst, d);
2947 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2948 M_CMPLE(s1, REG_ZERO, d);
2949 store_reg_to_var_int(iptr->dst, d);
2953 M_MOV(s1, REG_ITMP1);
2956 ICONST(d, iptr[1].val.i);
2958 if ((s3 >= 0) && (s3 <= 255)) {
2959 M_CMOVGT_IMM(s1, s3, d);
2962 ICONST(REG_ITMP2, s3);
2963 M_CMOVGT(s1, REG_ITMP2, d);
2965 store_reg_to_var_int(iptr->dst, d);
2968 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2969 /* val.i = constant */
2971 var_to_reg_int(s1, src, REG_ITMP1);
2972 d = reg_of_var(iptr->dst, REG_ITMP3);
2974 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2975 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2976 M_CMPLE(s1, REG_ZERO, d);
2977 store_reg_to_var_int(iptr->dst, d);
2980 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2981 M_CMPLT(REG_ZERO, s1, d);
2982 store_reg_to_var_int(iptr->dst, d);
2986 M_MOV(s1, REG_ITMP1);
2989 ICONST(d, iptr[1].val.i);
2991 if ((s3 >= 0) && (s3 <= 255)) {
2992 M_CMOVLE_IMM(s1, s3, d);
2995 ICONST(REG_ITMP2, s3);
2996 M_CMOVLE(s1, REG_ITMP2, d);
2998 store_reg_to_var_int(iptr->dst, d);
3002 case ICMD_IRETURN: /* ..., retvalue ==> ... */
3006 var_to_reg_int(s1, src, REG_RESULT);
3007 M_INTMOVE(s1, REG_RESULT);
3009 #if defined(USE_THREADS)
3010 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3012 a = dseg_addaddress((void *) (builtin_monitorexit));
3013 M_ALD(REG_PV, REG_PV, a);
3014 M_ALD(argintregs[0], REG_SP, maxmemuse * 8);
3015 M_LST(REG_RESULT, REG_SP, maxmemuse * 8);
3016 M_JSR(REG_RA, REG_PV);
3017 disp = -(s4) ((u1 *) mcodeptr - mcodebase);
3018 M_LDA(REG_PV, REG_RA, disp);
3019 M_LLD(REG_RESULT, REG_SP, maxmemuse * 8);
3023 goto nowperformreturn;
3025 case ICMD_FRETURN: /* ..., retvalue ==> ... */
3028 var_to_reg_flt(s1, src, REG_FRESULT);
3029 M_FLTMOVE(s1, REG_FRESULT);
3031 #if defined(USE_THREADS)
3032 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3034 a = dseg_addaddress((void *) (builtin_monitorexit));
3035 M_ALD(REG_PV, REG_PV, a);
3036 M_ALD(argintregs[0], REG_SP, maxmemuse * 8);
3037 M_DST(REG_FRESULT, REG_SP, maxmemuse * 8);
3038 M_JSR(REG_RA, REG_PV);
3039 disp = -(s4) ((u1 *) mcodeptr - mcodebase);
3040 M_LDA(REG_PV, REG_RA, disp);
3041 M_DLD(REG_FRESULT, REG_SP, maxmemuse * 8);
3045 goto nowperformreturn;
3047 case ICMD_RETURN: /* ... ==> ... */
3049 #if defined(USE_THREADS)
3050 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3052 a = dseg_addaddress((void *) (builtin_monitorexit));
3053 M_ALD(REG_PV, REG_PV, a);
3054 M_ALD(argintregs[0], REG_SP, maxmemuse * 8);
3055 M_JSR(REG_RA, REG_PV);
3056 disp = -(s4) ((u1 *) mcodeptr - mcodebase);
3057 M_LDA(REG_PV, REG_RA, disp);
3065 p = parentargs_base;
3067 /* restore return address */
3070 {p--; M_LLD (REG_RA, REG_SP, 8 * p);}
3072 /* restore saved registers */
3074 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
3075 {p--; M_LLD(savintregs[r], REG_SP, 8 * p);}
3076 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
3077 {p--; M_DLD(savfltregs[r], REG_SP, 8 * p);}
3079 /* deallocate stack */
3081 if (parentargs_base)
3082 {M_LDA(REG_SP, REG_SP, parentargs_base*8);}
3084 /* call trace function */
3087 M_LDA(REG_SP, REG_SP, -3 * 8);
3088 M_AST(REG_RA, REG_SP, 0 * 8);
3089 M_LST(REG_RESULT, REG_SP, 1 * 8);
3090 M_DST(REG_FRESULT, REG_SP, 2 * 8);
3091 a = dseg_addaddress(method);
3092 M_ALD(argintregs[0], REG_PV, a);
3093 M_MOV(REG_RESULT, argintregs[1]);
3094 M_FLTMOVE(REG_FRESULT, argfltregs[2]);
3095 M_FLTMOVE(REG_FRESULT, argfltregs[3]);
3096 a = dseg_addaddress((void *) builtin_displaymethodstop);
3097 M_ALD(REG_PV, REG_PV, a);
3098 M_JSR(REG_RA, REG_PV);
3099 s1 = (int) ((u1 *) mcodeptr - mcodebase);
3100 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3102 s4 ml = -s1, mh = 0;
3103 while (ml < -32768) { ml += 65536; mh--; }
3104 M_LDA(REG_PV, REG_RA, ml);
3105 M_LDAH(REG_PV, REG_PV, mh);
3107 M_DLD(REG_FRESULT, REG_SP, 2 * 8);
3108 M_LLD(REG_RESULT, REG_SP, 1 * 8);
3109 M_ALD(REG_RA, REG_SP, 0 * 8);
3110 M_LDA(REG_SP, REG_SP, 3 * 8);
3113 M_RET(REG_ZERO, REG_RA);
3119 case ICMD_TABLESWITCH: /* ..., index ==> ... */
3124 tptr = (void **) iptr->target;
3126 s4ptr = iptr->val.a;
3127 l = s4ptr[1]; /* low */
3128 i = s4ptr[2]; /* high */
3130 var_to_reg_int(s1, src, REG_ITMP1);
3132 {M_INTMOVE(s1, REG_ITMP1);}
3133 else if (l <= 32768) {
3134 M_LDA(REG_ITMP1, s1, -l);
3137 ICONST(REG_ITMP2, l);
3138 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
3145 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
3147 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
3148 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3150 M_BEQZ(REG_ITMP2, 0);
3153 /* codegen_addreference(BlockPtrOfPC(s4ptr[0]), mcodeptr); */
3154 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3156 /* build jump table top down and use address of lowest entry */
3158 /* s4ptr += 3 + i; */
3162 /* dseg_addtarget(BlockPtrOfPC(*--s4ptr)); */
3163 dseg_addtarget((basicblock *) tptr[0]);
3168 /* length of dataseg after last dseg_addtarget is used by load */
3170 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
3171 M_ALD(REG_ITMP2, REG_ITMP2, -dseglen);
3172 M_JMP(REG_ZERO, REG_ITMP2);
3177 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3179 s4 i, l, val, *s4ptr;
3182 tptr = (void **) iptr->target;
3184 s4ptr = iptr->val.a;
3185 l = s4ptr[0]; /* default */
3186 i = s4ptr[1]; /* count */
3188 MCODECHECK((i<<2)+8);
3189 var_to_reg_int(s1, src, REG_ITMP1);
3195 if ((val >= 0) && (val <= 255)) {
3196 M_CMPEQ_IMM(s1, val, REG_ITMP2);
3199 if ((val >= -32768) && (val <= 32767)) {
3200 M_LDA(REG_ITMP2, REG_ZERO, val);
3203 a = dseg_adds4 (val);
3204 M_ILD(REG_ITMP2, REG_PV, a);
3206 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
3208 M_BNEZ(REG_ITMP2, 0);
3209 /* codegen_addreference(BlockPtrOfPC(s4ptr[1]), mcodeptr); */
3210 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3214 /* codegen_addreference(BlockPtrOfPC(l), mcodeptr); */
3216 tptr = (void **) iptr->target;
3217 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3224 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
3225 /* op1 = return type, val.a = function pointer*/
3229 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
3230 /* op1 = return type, val.a = function pointer*/
3234 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
3235 /* op1 = return type, val.a = function pointer*/
3239 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3240 /* op1 = arg count, val.a = method pointer */
3242 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3243 /* op1 = arg count, val.a = method pointer */
3245 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3246 /* op1 = arg count, val.a = method pointer */
3248 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
3249 /* op1 = arg count, val.a = method pointer */
3257 MCODECHECK((s3 << 1) + 64);
3259 /* copy arguments to registers or stack location */
3261 for (; --s3 >= 0; src = src->prev) {
3262 if (src->varkind == ARGVAR)
3264 if (IS_INT_LNG_TYPE(src->type)) {
3265 if (s3 < INT_ARG_CNT) {
3266 s1 = argintregs[s3];
3267 var_to_reg_int(d, src, s1);
3271 var_to_reg_int(d, src, REG_ITMP1);
3272 M_LST(d, REG_SP, 8 * (s3 - INT_ARG_CNT));
3276 if (s3 < FLT_ARG_CNT) {
3277 s1 = argfltregs[s3];
3278 var_to_reg_flt(d, src, s1);
3282 var_to_reg_flt(d, src, REG_FTMP1);
3283 M_DST(d, REG_SP, 8 * (s3 - FLT_ARG_CNT));
3288 switch (iptr->opc) {
3292 a = dseg_addaddress ((void*) (m));
3294 M_ALD(REG_PV, REG_PV, a); /* Pointer to built-in-function */
3296 goto makeactualcall;
3298 case ICMD_INVOKESTATIC:
3299 case ICMD_INVOKESPECIAL:
3300 a = dseg_addaddress (m->stubroutine);
3302 M_ALD(REG_PV, REG_PV, a ); /* method pointer in r27 */
3305 goto makeactualcall;
3307 case ICMD_INVOKEVIRTUAL:
3309 gen_nullptr_check(argintregs[0]);
3310 M_ALD(REG_METHODPTR, argintregs[0],
3311 OFFSET(java_objectheader, vftbl));
3312 M_ALD(REG_PV, REG_METHODPTR, OFFSET(vftbl, table[0]) +
3313 sizeof(methodptr) * m->vftblindex);
3316 goto makeactualcall;
3318 case ICMD_INVOKEINTERFACE:
3321 gen_nullptr_check(argintregs[0]);
3322 M_ALD(REG_METHODPTR, argintregs[0],
3323 OFFSET(java_objectheader, vftbl));
3324 M_ALD(REG_METHODPTR, REG_METHODPTR,
3325 OFFSET(vftbl, interfacetable[0]) -
3326 sizeof(methodptr*) * ci->index);
3327 M_ALD(REG_PV, REG_METHODPTR,
3328 sizeof(methodptr) * (m - ci->methods));
3331 goto makeactualcall;
3335 error ("Unkown ICMD-Command: %d", iptr->opc);
3340 M_JSR (REG_RA, REG_PV);
3344 s1 = (int)((u1*) mcodeptr - mcodebase);
3345 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
3348 while (ml<-32768) { ml+=65536; mh--; }
3349 M_LDA (REG_PV, REG_RA, ml );
3350 M_LDAH (REG_PV, REG_PV, mh );
3353 /* d contains return type */
3355 if (d != TYPE_VOID) {
3356 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3357 s1 = reg_of_var(iptr->dst, REG_RESULT);
3358 M_INTMOVE(REG_RESULT, s1);
3359 store_reg_to_var_int(iptr->dst, s1);
3362 s1 = reg_of_var(iptr->dst, REG_FRESULT);
3363 M_FLTMOVE(REG_FRESULT, s1);
3364 store_reg_to_var_flt(iptr->dst, s1);
3371 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3373 /* op1: 0 == array, 1 == class */
3374 /* val.a: (classinfo*) superclass */
3376 /* superclass is an interface:
3378 * return (sub != NULL) &&
3379 * (sub->vftbl->interfacetablelength > super->index) &&
3380 * (sub->vftbl->interfacetable[-super->index] != NULL);
3382 * superclass is a class:
3384 * return ((sub != NULL) && (0
3385 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3386 * super->vftbl->diffvall));
3390 classinfo *super = (classinfo*) iptr->val.a;
3392 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3393 codegen_threadcritrestart((u1*) mcodeptr - mcodebase);
3395 var_to_reg_int(s1, src, REG_ITMP1);
3396 d = reg_of_var(iptr->dst, REG_ITMP3);
3398 M_MOV(s1, REG_ITMP1);
3402 if (iptr->op1) { /* class/interface */
3403 if (super->flags & ACC_INTERFACE) { /* interface */
3405 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3406 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3407 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3408 M_BLEZ(REG_ITMP2, 2);
3409 M_ALD(REG_ITMP1, REG_ITMP1,
3410 OFFSET(vftbl, interfacetable[0]) -
3411 super->index * sizeof(methodptr*));
3412 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3416 s2 = super->vftbl->diffval;
3417 M_BEQZ(s1, 4 + (s2 > 255));
3418 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3419 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3420 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3422 M_CMPULE_IMM(REG_ITMP1, s2, d);
3424 M_LDA(REG_ITMP2, REG_ZERO, s2);
3425 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3429 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3430 a = dseg_addaddress ((void*) super->vftbl);
3431 M_ALD(REG_ITMP2, REG_PV, a);
3432 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3433 codegen_threadcritstart((u1*) mcodeptr - mcodebase);
3435 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3436 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl, baseval));
3437 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, diffval));
3438 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3439 codegen_threadcritstop((u1*) mcodeptr - mcodebase);
3441 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3442 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3446 panic ("internal error: no inlined array instanceof");
3448 store_reg_to_var_int(iptr->dst, d);
3451 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3453 /* op1: 0 == array, 1 == class */
3454 /* val.a: (classinfo*) superclass */
3456 /* superclass is an interface:
3458 * OK if ((sub == NULL) ||
3459 * (sub->vftbl->interfacetablelength > super->index) &&
3460 * (sub->vftbl->interfacetable[-super->index] != NULL));
3462 * superclass is a class:
3464 * OK if ((sub == NULL) || (0
3465 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3466 * super->vftbl->diffvall));
3470 classinfo *super = (classinfo*) iptr->val.a;
3472 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3473 codegen_threadcritrestart((u1*) mcodeptr - mcodebase);
3475 d = reg_of_var(iptr->dst, REG_ITMP3);
3476 var_to_reg_int(s1, src, d);
3477 if (iptr->op1) { /* class/interface */
3478 if (super->flags & ACC_INTERFACE) { /* interface */
3480 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3481 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3482 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3483 M_BLEZ(REG_ITMP2, 0);
3484 codegen_addxcastrefs(mcodeptr);
3485 M_ALD(REG_ITMP2, REG_ITMP1,
3486 OFFSET(vftbl, interfacetable[0]) -
3487 super->index * sizeof(methodptr*));
3488 M_BEQZ(REG_ITMP2, 0);
3489 codegen_addxcastrefs(mcodeptr);
3493 s2 = super->vftbl->diffval;
3494 M_BEQZ(s1, 4 + (s2 != 0) + (s2 > 255));
3495 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3496 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3497 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3499 M_BNEZ(REG_ITMP1, 0);
3501 else if (s2 <= 255) {
3502 M_CMPULE_IMM(REG_ITMP1, s2, REG_ITMP2);
3503 M_BEQZ(REG_ITMP2, 0);
3506 M_LDA(REG_ITMP2, REG_ZERO, s2);
3507 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3508 M_BEQZ(REG_ITMP2, 0);
3511 M_BEQZ(s1, 8 + (d == REG_ITMP3));
3512 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3513 a = dseg_addaddress ((void*) super->vftbl);
3514 M_ALD(REG_ITMP2, REG_PV, a);
3515 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3516 codegen_threadcritstart((u1*) mcodeptr - mcodebase);
3518 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3519 if (d != REG_ITMP3) {
3520 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl, baseval));
3521 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, diffval));
3522 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3523 codegen_threadcritstop((u1*) mcodeptr - mcodebase);
3525 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3528 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, baseval));
3529 M_ISUB(REG_ITMP1, REG_ITMP2, REG_ITMP1);
3530 M_ALD(REG_ITMP2, REG_PV, a);
3531 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, diffval));
3532 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3533 codegen_threadcritstop((u1*) mcodeptr - mcodebase);
3536 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3537 M_BEQZ(REG_ITMP2, 0);
3538 codegen_addxcastrefs(mcodeptr);
3542 panic ("internal error: no inlined array checkcast");
3545 store_reg_to_var_int(iptr->dst, d);
3548 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
3550 var_to_reg_int(s1, src, REG_ITMP1);
3552 codegen_addxcheckarefs(mcodeptr);
3555 case ICMD_CHECKEXCEPTION: /* ... ==> ... */
3557 M_BEQZ(REG_RESULT, 0);
3558 codegen_addxexceptionrefs(mcodeptr);
3561 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3562 /* op1 = dimension, val.a = array descriptor */
3564 /* check for negative sizes and copy sizes to stack if necessary */
3566 MCODECHECK((iptr->op1 << 1) + 64);
3568 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3569 var_to_reg_int(s2, src, REG_ITMP1);
3571 codegen_addxcheckarefs(mcodeptr);
3573 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
3575 if (src->varkind != ARGVAR) {
3576 M_LST(s2, REG_SP, 8 * (s1 + INT_ARG_CNT));
3580 /* a0 = dimension count */
3582 ICONST(argintregs[0], iptr->op1);
3584 /* a1 = arraydescriptor */
3586 a = dseg_addaddress(iptr->val.a);
3587 M_ALD(argintregs[1], REG_PV, a);
3589 /* a2 = pointer to dimensions = stack pointer */
3591 M_INTMOVE(REG_SP, argintregs[2]);
3593 a = dseg_addaddress((void*) (builtin_nmultianewarray));
3594 M_ALD(REG_PV, REG_PV, a);
3595 M_JSR(REG_RA, REG_PV);
3596 s1 = (int)((u1*) mcodeptr - mcodebase);
3598 M_LDA (REG_PV, REG_RA, -s1);
3600 s4 ml = -s1, mh = 0;
3601 while (ml < -32768) {ml += 65536; mh--;}
3602 M_LDA(REG_PV, REG_RA, ml);
3603 M_LDAH(REG_PV, REG_PV, mh);
3605 s1 = reg_of_var(iptr->dst, REG_RESULT);
3606 M_INTMOVE(REG_RESULT, s1);
3607 store_reg_to_var_int(iptr->dst, s1);
3611 default: error ("Unknown pseudo command: %d", iptr->opc);
3617 } /* for instruction */
3619 /* copy values to interface registers */
3621 src = bptr->outstack;
3622 len = bptr->outdepth;
3626 if ((src->varkind != STACKVAR)) {
3628 if (IS_FLT_DBL_TYPE(s2)) {
3629 var_to_reg_flt(s1, src, REG_FTMP1);
3630 if (!(interfaces[len][s2].flags & INMEMORY)) {
3631 M_FLTMOVE(s1,interfaces[len][s2].regoff);
3634 M_DST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3638 var_to_reg_int(s1, src, REG_ITMP1);
3639 if (!(interfaces[len][s2].flags & INMEMORY)) {
3640 M_INTMOVE(s1,interfaces[len][s2].regoff);
3643 M_LST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3649 } /* if (bptr -> flags >= BBREACHED) */
3650 } /* for basic block */
3652 /* bptr -> mpc = (int)((u1*) mcodeptr - mcodebase); */
3655 /* generate bound check stubs */
3657 s4 *xcodeptr = NULL;
3659 for (; xboundrefs != NULL; xboundrefs = xboundrefs->next) {
3660 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
3661 xboundrefs->branchpos,
3662 (u1*) mcodeptr - mcodebase);
3666 /* move index register into REG_ITMP1 */
3667 M_MOV(xboundrefs->reg, REG_ITMP1);
3668 M_LDA(REG_ITMP2_XPC, REG_PV, xboundrefs->branchpos - 4);
3670 if (xcodeptr != NULL) {
3671 M_BR(xcodeptr - mcodeptr - 1);
3674 xcodeptr = mcodeptr;
3676 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3677 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3679 a = dseg_addaddress(string_java_lang_ArrayIndexOutOfBoundsException);
3680 M_ALD(argintregs[0], REG_PV, a);
3681 M_MOV(REG_ITMP1, argintregs[1]);
3683 a = dseg_addaddress(new_exception_int);
3684 M_ALD(REG_PV, REG_PV, a);
3685 M_JSR(REG_RA, REG_PV);
3688 s1 = (s4) ((u1 *) mcodeptr - mcodebase);
3689 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3691 s4 ml = -s1, mh = 0;
3692 while (ml < -32768) { ml += 65536; mh--; }
3693 M_LDA(REG_PV, REG_RA, ml);
3694 M_LDAH(REG_PV, REG_PV, mh);
3697 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3699 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3700 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3702 a = dseg_addaddress(asm_handle_exception);
3703 M_ALD(REG_ITMP3, REG_PV, a);
3705 M_JMP(REG_ZERO, REG_ITMP3);
3709 /* generate negative array size check stubs */
3713 for (; xcheckarefs != NULL; xcheckarefs = xcheckarefs->next) {
3714 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3715 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3716 xcheckarefs->branchpos,
3717 (u1*) xcodeptr - (u1*) mcodebase - 4);
3721 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3722 xcheckarefs->branchpos,
3723 (u1*) mcodeptr - mcodebase);
3727 M_LDA(REG_ITMP2_XPC, REG_PV, xcheckarefs->branchpos - 4);
3729 if (xcodeptr != NULL) {
3730 M_BR(xcodeptr - mcodeptr - 1);
3733 xcodeptr = mcodeptr;
3735 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3736 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3738 a = dseg_addaddress(string_java_lang_NegativeArraySizeException);
3739 M_ALD(argintregs[0], REG_PV, a);
3741 a = dseg_addaddress(new_exception);
3742 M_ALD(REG_PV, REG_PV, a);
3743 M_JSR(REG_RA, REG_PV);
3746 s1 = (s4) ((u1 *) mcodeptr - mcodebase);
3747 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3749 s4 ml = -s1, mh = 0;
3750 while (ml < -32768) { ml += 65536; mh--; }
3751 M_LDA(REG_PV, REG_RA, ml);
3752 M_LDAH(REG_PV, REG_PV, mh);
3755 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3757 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3758 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3760 a = dseg_addaddress(asm_handle_exception);
3761 M_ALD(REG_ITMP3, REG_PV, a);
3763 M_JMP(REG_ZERO, REG_ITMP3);
3767 /* generate cast check stubs */
3771 for (; xcastrefs != NULL; xcastrefs = xcastrefs->next) {
3772 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3773 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3774 xcastrefs->branchpos,
3775 (u1*) xcodeptr - (u1*) mcodebase - 4);
3779 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3780 xcastrefs->branchpos,
3781 (u1*) mcodeptr - mcodebase);
3785 M_LDA(REG_ITMP2_XPC, REG_PV, xcastrefs->branchpos - 4);
3787 if (xcodeptr != NULL) {
3788 M_BR(xcodeptr - mcodeptr - 1);
3791 xcodeptr = mcodeptr;
3793 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3794 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3796 a = dseg_addaddress(string_java_lang_ClassCastException);
3797 M_ALD(argintregs[0], REG_PV, a);
3799 a = dseg_addaddress(new_exception);
3800 M_ALD(REG_PV, REG_PV, a);
3801 M_JSR(REG_RA, REG_PV);
3804 s1 = (s4) ((u1 *) mcodeptr - mcodebase);
3805 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3807 s4 ml = -s1, mh = 0;
3808 while (ml < -32768) { ml += 65536; mh--; }
3809 M_LDA(REG_PV, REG_RA, ml);
3810 M_LDAH(REG_PV, REG_PV, mh);
3813 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3815 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3816 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3818 a = dseg_addaddress(asm_handle_exception);
3819 M_ALD(REG_ITMP3, REG_PV, a);
3821 M_JMP(REG_ZERO, REG_ITMP3);
3825 /* generate exception check stubs */
3829 for (; xexceptionrefs != NULL; xexceptionrefs = xexceptionrefs->next) {
3830 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3831 gen_resolvebranch((u1*) mcodebase + xexceptionrefs->branchpos,
3832 xexceptionrefs->branchpos,
3833 (u1*) xcodeptr - (u1*) mcodebase - 4);
3837 gen_resolvebranch((u1*) mcodebase + xexceptionrefs->branchpos,
3838 xexceptionrefs->branchpos,
3839 (u1*) mcodeptr - mcodebase);
3843 M_LDA(REG_ITMP2_XPC, REG_PV, xexceptionrefs->branchpos - 4);
3845 if (xcodeptr != NULL) {
3846 M_BR(xcodeptr - mcodeptr - 1);
3849 xcodeptr = mcodeptr;
3851 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3852 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3853 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3855 a = dseg_addaddress(&builtin_get_exceptionptrptr);
3856 M_ALD(REG_PV, REG_PV, a);
3857 M_JSR(REG_RA, REG_PV);
3860 s1 = (s4) ((u1 *) mcodeptr - mcodebase);
3861 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3863 s4 ml = -s1, mh = 0;
3864 while (ml < -32768) { ml += 65536; mh--; }
3865 M_LDA(REG_PV, REG_RA, ml);
3866 M_LDAH(REG_PV, REG_PV, mh);
3869 M_ALD(REG_ITMP1_XPTR, REG_RESULT, 0);
3870 M_AST(REG_ZERO, REG_RESULT, 0);
3872 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3873 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3875 a = dseg_addaddress(&_exceptionptr);
3876 M_ALD(REG_ITMP3, REG_PV, a);
3877 M_ALD(REG_ITMP1_XPTR, REG_ITMP3, 0);
3878 M_AST(REG_ZERO, REG_ITMP3, 0);
3881 a = dseg_addaddress(asm_handle_exception);
3882 M_ALD(REG_ITMP3, REG_PV, a);
3884 M_JMP(REG_ZERO, REG_ITMP3);
3888 /* generate null pointer check stubs */
3892 for (; xnullrefs != NULL; xnullrefs = xnullrefs->next) {
3893 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3894 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3895 xnullrefs->branchpos,
3896 (u1*) xcodeptr - (u1*) mcodebase - 4);
3900 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3901 xnullrefs->branchpos,
3902 (u1*) mcodeptr - mcodebase);
3906 M_LDA(REG_ITMP2_XPC, REG_PV, xnullrefs->branchpos - 4);
3908 if (xcodeptr != NULL) {
3909 M_BR(xcodeptr - mcodeptr - 1);
3912 xcodeptr = mcodeptr;
3914 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3915 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3917 a = dseg_addaddress(string_java_lang_NullPointerException);
3918 M_ALD(argintregs[0], REG_PV, a);
3920 a = dseg_addaddress(new_exception);
3921 M_ALD(REG_PV, REG_PV, a);
3922 M_JSR(REG_RA, REG_PV);
3925 s1 = (s4) ((u1 *) mcodeptr - mcodebase);
3926 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3928 s4 ml = -s1, mh = 0;
3929 while (ml < -32768) { ml += 65536; mh--; }
3930 M_LDA(REG_PV, REG_RA, ml);
3931 M_LDAH(REG_PV, REG_PV, mh);
3934 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3936 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3937 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3939 a = dseg_addaddress(asm_handle_exception);
3940 M_ALD(REG_ITMP3, REG_PV, a);
3942 M_JMP(REG_ZERO, REG_ITMP3);
3947 codegen_finish((int)((u1*) mcodeptr - mcodebase));
3951 /* function createcompilerstub *************************************************
3953 creates a stub routine which calls the compiler
3955 *******************************************************************************/
3957 #define COMPSTUBSIZE 3
3959 u1 *createcompilerstub(methodinfo *m)
3961 u8 *s = CNEW(u8, COMPSTUBSIZE); /* memory to hold the stub */
3962 s4 *mcodeptr = (s4 *) s; /* code generation pointer */
3964 /* code for the stub */
3965 M_ALD(REG_PV, REG_PV, 16); /* load pointer to the compiler */
3966 M_JMP(0, REG_PV); /* jump to the compiler, return address
3967 in reg 0 is used as method pointer */
3968 s[1] = (u8) m; /* literals to be adressed */
3969 s[2] = (u8) asm_call_jit_compiler; /* jump directly via PV from above */
3972 count_cstub_len += COMPSTUBSIZE * 8;
3979 /* function removecompilerstub *************************************************
3981 deletes a compilerstub from memory (simply by freeing it)
3983 *******************************************************************************/
3985 void removecompilerstub(u1 *stub)
3987 CFREE(stub, COMPSTUBSIZE * 8);
3991 /* function: createnativestub **************************************************
3993 creates a stub routine which calls a native method
3995 *******************************************************************************/
3997 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3998 #define NATIVESTUBSTACK 2
3999 #define NATIVESTUBTHREADEXTRA 5
4001 #define NATIVESTUBSTACK 1
4002 #define NATIVESTUBTHREADEXTRA 0
4005 #define NATIVESTUBSIZE (44 + NATIVESTUBTHREADEXTRA)
4006 #define NATIVESTATICSIZE 5
4007 #define NATIVEVERBOSESIZE (39 + 13 + NATIVESTUBTHREADEXTRA)
4008 #define NATIVESTUBOFFSET 9
4010 u1 *createnativestub(functionptr f, methodinfo *m)
4012 u8 *s; /* memory pointer to hold the stub */
4014 s4 *mcodeptr; /* code generation pointer */
4015 s4 stackframesize = 0; /* size of stackframe if needed */
4020 descriptor2types(m); /* set paramcount and paramtypes */
4022 stubsize = NATIVESTUBSIZE; /* calculate nativestub size */
4023 if ((m->flags & ACC_STATIC) && !m->class->initialized)
4024 stubsize += NATIVESTATICSIZE;
4027 stubsize += NATIVEVERBOSESIZE;
4029 s = CNEW(u8, stubsize); /* memory to hold the stub */
4030 cs = s + NATIVESTUBOFFSET;
4031 mcodeptr = (s4 *) (cs); /* code generation pointer */
4033 *(cs-1) = (u8) f; /* address of native method */
4034 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4035 *(cs-2) = (u8) &builtin_get_exceptionptrptr;
4037 *(cs-2) = (u8) (&_exceptionptr); /* address of exceptionptr */
4039 *(cs-3) = (u8) asm_handle_nat_exception; /* addr of asm exception handler */
4040 *(cs-4) = (u8) (&env); /* addr of jni_environement */
4041 *(cs-5) = (u8) builtin_trace_args;
4043 *(cs-7) = (u8) builtin_displaymethodstop;
4044 *(cs-8) = (u8) m->class;
4045 *(cs-9) = (u8) asm_check_clinit;
4047 M_LDA(REG_SP, REG_SP, -NATIVESTUBSTACK * 8); /* build up stackframe */
4048 M_AST(REG_RA, REG_SP, 0 * 8); /* store return address */
4050 /* if function is static, check for initialized */
4052 if (m->flags & ACC_STATIC) {
4053 /* if class isn't yet initialized, do it */
4054 if (!m->class->initialized) {
4055 /* call helper function which patches this code */
4056 M_ALD(REG_ITMP1, REG_PV, -8 * 8); /* class */
4057 M_ALD(REG_PV, REG_PV, -9 * 8); /* asm_check_clinit */
4058 M_JSR(REG_RA, REG_PV);
4059 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4060 M_LDA(REG_PV, REG_RA, disp);
4061 M_NOP; /* this is essential for code patching */
4065 /* max. 39 instructions */
4069 M_LDA(REG_SP, REG_SP, -((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
4070 M_AST(REG_RA, REG_SP, 1 * 8);
4072 /* save integer argument registers */
4073 for (p = 0; p < m->paramcount && p < INT_ARG_CNT; p++) {
4074 M_LST(argintregs[p], REG_SP, (2 + p) * 8);
4077 /* save and copy float arguments into integer registers */
4078 for (p = 0; p < m->paramcount && p < FLT_ARG_CNT; p++) {
4079 t = m->paramtypes[p];
4081 if (IS_FLT_DBL_TYPE(t)) {
4082 if (IS_2_WORD_TYPE(t)) {
4083 M_DST(argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4084 M_LLD(argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4087 M_FST(argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4088 M_ILD(argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4092 M_DST(argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4096 M_ALD(REG_ITMP1, REG_PV, -6 * 8);
4097 M_AST(REG_ITMP1, REG_SP, 0 * 8);
4098 M_ALD(REG_PV, REG_PV, -5 * 8);
4099 M_JSR(REG_RA, REG_PV);
4100 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4101 M_LDA(REG_PV, REG_RA, disp);
4103 for (p = 0; p < m->paramcount && p < INT_ARG_CNT; p++) {
4104 M_LLD(argintregs[p], REG_SP, (2 + p) * 8);
4107 for (p = 0; p < m->paramcount && p < FLT_ARG_CNT; p++) {
4108 t = m->paramtypes[p];
4110 if (IS_FLT_DBL_TYPE(t)) {
4111 if (IS_2_WORD_TYPE(t)) {
4112 M_DLD(argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4115 M_FLD(argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4119 M_DLD(argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4123 M_ALD(REG_RA, REG_SP, 1 * 8);
4124 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT + 2) * 8);
4127 /* save argument registers on stack -- if we have to */
4128 if ((m->flags & ACC_STATIC && m->paramcount > (INT_ARG_CNT - 2)) || m->paramcount > (INT_ARG_CNT - 1)) {
4130 s4 paramshiftcnt = (m->flags & ACC_STATIC) ? 2 : 1;
4131 s4 stackparamcnt = (m->paramcount > INT_ARG_CNT) ? m->paramcount - INT_ARG_CNT : 0;
4133 stackframesize = stackparamcnt + paramshiftcnt;
4135 M_LDA(REG_SP, REG_SP, -stackframesize * 8);
4137 /* copy stack arguments into new stack frame -- if any */
4138 for (i = 0; i < stackparamcnt; i++) {
4139 M_LLD(REG_ITMP1, REG_SP, (stackparamcnt + 1 + i) * 8);
4140 M_LST(REG_ITMP1, REG_SP, (paramshiftcnt + i) * 8);
4143 if (m->flags & ACC_STATIC) {
4144 if (IS_FLT_DBL_TYPE(m->paramtypes[5])) {
4145 M_DST(argfltregs[5], REG_SP, 1 * 8);
4147 M_LST(argintregs[5], REG_SP, 1 * 8);
4150 if (IS_FLT_DBL_TYPE(m->paramtypes[4])) {
4151 M_DST(argfltregs[4], REG_SP, 0 * 8);
4153 M_LST(argintregs[4], REG_SP, 0 * 8);
4157 if (IS_FLT_DBL_TYPE(m->paramtypes[5])) {
4158 M_DST(argfltregs[5], REG_SP, 0 * 8);
4160 M_LST(argintregs[5], REG_SP, 0 * 8);
4165 if (m->flags & ACC_STATIC) {
4166 M_MOV(argintregs[3], argintregs[5]);
4167 M_MOV(argintregs[2], argintregs[4]);
4168 M_MOV(argintregs[1], argintregs[3]);
4169 M_MOV(argintregs[0], argintregs[2]);
4170 M_FMOV(argfltregs[3], argfltregs[5]);
4171 M_FMOV(argfltregs[2], argfltregs[4]);
4172 M_FMOV(argfltregs[1], argfltregs[3]);
4173 M_FMOV(argfltregs[0], argfltregs[2]);
4175 /* put class into second argument register */
4176 M_ALD(argintregs[1], REG_PV, -8 * 8);
4179 M_MOV(argintregs[4], argintregs[5]);
4180 M_MOV(argintregs[3], argintregs[4]);
4181 M_MOV(argintregs[2], argintregs[3]);
4182 M_MOV(argintregs[1], argintregs[2]);
4183 M_MOV(argintregs[0], argintregs[1]);
4184 M_FMOV(argfltregs[4], argfltregs[5]);
4185 M_FMOV(argfltregs[3], argfltregs[4]);
4186 M_FMOV(argfltregs[2], argfltregs[3]);
4187 M_FMOV(argfltregs[1], argfltregs[2]);
4188 M_FMOV(argfltregs[0], argfltregs[1]);
4191 /* put env into first argument register */
4192 M_ALD(argintregs[0], REG_PV, -4 * 8);
4194 M_ALD(REG_PV, REG_PV, -1 * 8); /* load adress of native method */
4195 M_JSR(REG_RA, REG_PV); /* call native method */
4196 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4197 M_LDA(REG_PV, REG_RA, disp); /* recompute pv from ra */
4199 /* remove stackframe if there is one */
4200 if (stackframesize) {
4201 M_LDA(REG_SP, REG_SP, stackframesize * 8);
4204 /* 13 instructions */
4206 M_LDA(REG_SP, REG_SP, -2 * 8);
4207 M_ALD(argintregs[0], REG_PV, -6 * 8); /* load method adress */
4208 M_LST(REG_RESULT, REG_SP, 0 * 8);
4209 M_DST(REG_FRESULT, REG_SP, 1 * 8);
4210 M_MOV(REG_RESULT, argintregs[1]);
4211 M_FMOV(REG_FRESULT, argfltregs[2]);
4212 M_FMOV(REG_FRESULT, argfltregs[3]);
4213 M_ALD(REG_PV, REG_PV, -7 * 8); /* builtin_displaymethodstop */
4214 M_JSR(REG_RA, REG_PV);
4215 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4216 M_LDA(REG_PV, REG_RA, disp);
4217 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4218 M_DLD(REG_FRESULT, REG_SP, 1 * 8);
4219 M_LDA(REG_SP, REG_SP, 2 * 8);
4222 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4223 if (IS_FLT_DBL_TYPE(m->returntype))
4224 M_DST(REG_FRESULT, REG_SP, 1 * 8);
4226 M_AST(REG_RESULT, REG_SP, 1 * 8);
4227 M_ALD(REG_PV, REG_PV, -2 * 8); /* builtin_get_exceptionptrptr */
4228 M_JSR(REG_RA, REG_PV);
4229 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4230 M_LDA(REG_PV, REG_RA, disp);
4231 M_MOV(REG_RESULT, REG_ITMP3);
4232 if (IS_FLT_DBL_TYPE(m->returntype))
4233 M_DLD(REG_FRESULT, REG_SP, 1 * 8);
4235 M_ALD(REG_RESULT, REG_SP, 1 * 8);
4237 M_ALD(REG_ITMP3, REG_PV, -2 * 8); /* get address of exceptionptr */
4239 M_ALD(REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
4240 M_BNEZ(REG_ITMP1, 3); /* if no exception then return */
4242 M_ALD(REG_RA, REG_SP, 0 * 8); /* load return address */
4243 M_LDA(REG_SP, REG_SP, NATIVESTUBSTACK * 8); /* remove stackframe */
4244 M_RET(REG_ZERO, REG_RA); /* return to caller */
4246 M_AST(REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
4248 M_ALD(REG_RA, REG_SP, 0 * 8); /* load return address */
4249 M_LDA(REG_SP, REG_SP, NATIVESTUBSTACK * 8); /* remove stackframe */
4250 M_LDA(REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
4251 M_ALD(REG_ITMP3, REG_PV, -3 * 8); /* load asm exception handler address */
4252 M_JMP(REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
4255 dolog_plain("stubsize: %d (for %d params)\n", (int) (mcodeptr - (s4*) s), m->paramcount);
4259 count_nstub_len += NATIVESTUBSIZE * 8;
4262 return (u1 *) (s + NATIVESTUBOFFSET);
4266 /* function: removenativestub **************************************************
4268 removes a previously created native-stub from memory
4270 *******************************************************************************/
4272 void removenativestub(u1 *stub)
4274 CFREE((u8 *) stub - NATIVESTUBOFFSET, NATIVESTUBSIZE * 8);
4279 * These are local overrides for various environment variables in Emacs.
4280 * Please do not remove this and leave it at the end of the file, where
4281 * Emacs will automagically detect them.
4282 * ---------------------------------------------------------------------
4285 * indent-tabs-mode: t