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 1066 2004-05-16 17:08:11Z stefan $
43 #include "jit/parse.h"
53 /* include independent code generation stuff */
54 #include "codegen.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;
411 if (compileverbose) {
412 char logtext[MAXLOGTEXT];
413 sprintf(logtext, "Generating code: ");
414 utf_sprint_classname(logtext + strlen(logtext), class->name);
415 sprintf(logtext + strlen(logtext), ".");
416 utf_sprint(logtext + strlen(logtext), method->name);
417 utf_sprint_classname(logtext + strlen(logtext), descriptor);
424 savedregs_num = (isleafmethod) ? 0 : 1; /* space to save the RA */
426 /* space to save used callee saved registers */
428 savedregs_num += (savintregcnt - maxsavintreguse);
429 savedregs_num += (savfltregcnt - maxsavfltreguse);
431 parentargs_base = maxmemuse + savedregs_num;
433 #ifdef USE_THREADS /* space to save argument of monitor_enter */
435 if (checksync && (method->flags & ACC_SYNCHRONIZED))
440 /* create method header */
442 (void) dseg_addaddress(method); /* MethodPointer */
443 (void) dseg_adds4(parentargs_base * 8); /* FrameSize */
447 /* IsSync contains the offset relative to the stack pointer for the
448 argument of monitor_exit used in the exception handler. Since the
449 offset could be zero and give a wrong meaning of the flag it is
453 if (checksync && (method->flags & ACC_SYNCHRONIZED))
454 (void) dseg_adds4((maxmemuse + 1) * 8); /* IsSync */
459 (void) dseg_adds4(0); /* IsSync */
461 (void) dseg_adds4(isleafmethod); /* IsLeaf */
462 (void) dseg_adds4(savintregcnt - maxsavintreguse); /* IntSave */
463 (void) dseg_adds4(savfltregcnt - maxsavfltreguse); /* FltSave */
465 dseg_addlinenumbertablesize();
468 (void) dseg_adds4(exceptiontablelength); /* ExTableSize */
470 /* create exception table */
472 for (ex = extable; ex != NULL; ex = ex->down) {
475 if (ex->start != NULL)
476 printf("adding start - %d - ", ex->start->debug_nr);
478 printf("PANIC - start is NULL");
483 dseg_addtarget(ex->start);
487 printf("adding end - %d - ", ex->end->debug_nr);
489 printf("PANIC - end is NULL");
494 dseg_addtarget(ex->end);
497 if (ex->handler != NULL)
498 printf("adding handler - %d\n", ex->handler->debug_nr);
500 printf("PANIC - handler is NULL");
505 dseg_addtarget(ex->handler);
507 (void) dseg_addaddress(ex->catchtype);
510 /* initialize mcode variables */
512 mcodeptr = (s4*) mcodebase;
513 mcodeend = (s4*) (mcodebase + mcodesize);
514 MCODECHECK(128 + mparamcount);
516 /* create stack frame (if necessary) */
519 {M_LDA (REG_SP, REG_SP, -parentargs_base * 8);}
521 /* save return address and used callee saved registers */
525 {p--; M_AST (REG_RA, REG_SP, 8*p);}
526 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
527 {p--; M_LST (savintregs[r], REG_SP, 8 * p);}
528 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
529 {p--; M_DST (savfltregs[r], REG_SP, 8 * p);}
531 /* save monitorenter argument */
534 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
535 if (method->flags & ACC_STATIC) {
536 p = dseg_addaddress (class);
537 M_ALD(REG_ITMP1, REG_PV, p);
538 M_AST(REG_ITMP1, REG_SP, 8 * maxmemuse);
541 M_AST (argintregs[0], REG_SP, 8 * maxmemuse);
546 /* copy argument registers to stack and call trace function with pointer
547 to arguments on stack.
552 M_LDA(REG_SP, REG_SP, -((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
553 M_AST(REG_RA, REG_SP, 1 * 8);
555 /* save integer argument registers */
556 for (p = 0; /* p < mparamcount && */ p < INT_ARG_CNT; p++) {
557 M_LST(argintregs[p], REG_SP, (2 + p) * 8);
560 /* save and copy float arguments into integer registers */
561 for (p = 0; /* p < mparamcount && */ p < FLT_ARG_CNT; p++) {
564 if (IS_FLT_DBL_TYPE(t)) {
565 if (IS_2_WORD_TYPE(t)) {
566 M_DST(argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
569 M_FST(argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
572 M_LLD(argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
575 M_DST(argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
579 p = dseg_addaddress(method);
580 M_ALD(REG_ITMP1, REG_PV, p);
581 M_AST(REG_ITMP1, REG_SP, 0 * 8);
582 p = dseg_addaddress((void *) builtin_trace_args);
583 M_ALD(REG_PV, REG_PV, p);
584 M_JSR(REG_RA, REG_PV);
585 disp = -(int) ((u1 *) mcodeptr - mcodebase);
586 M_LDA(REG_PV, REG_RA, disp);
587 M_ALD(REG_RA, REG_SP, 1 * 8);
589 for (p = 0; /* p < mparamcount && */ p < INT_ARG_CNT; p++) {
590 M_LLD(argintregs[p], REG_SP, (2 + p) * 8);
593 for (p = 0; /* p < mparamcount && */ p < FLT_ARG_CNT; p++) {
596 if (IS_FLT_DBL_TYPE(t)) {
597 if (IS_2_WORD_TYPE(t)) {
598 M_DLD(argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
601 M_FLD(argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
605 M_DLD(argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
609 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT + 2) * 8);
612 /* take arguments out of register or stack frame */
614 for (p = 0, l = 0; p < mparamcount; p++) {
616 var = &(locals[l][t]);
618 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
623 if (IS_INT_LNG_TYPE(t)) { /* integer args */
624 if (p < INT_ARG_CNT) { /* register arguments */
625 if (!(var->flags & INMEMORY)) /* reg arg -> register */
626 {M_INTMOVE (argintregs[p], r);}
627 else /* reg arg -> spilled */
628 M_LST (argintregs[p], REG_SP, 8 * r);
630 else { /* stack arguments */
631 pa = p - INT_ARG_CNT;
632 if (!(var->flags & INMEMORY)) /* stack arg -> register */
633 M_LLD (r, REG_SP, 8 * (parentargs_base + pa));
634 else { /* stack arg -> spilled */
635 M_LLD (REG_ITMP1, REG_SP, 8 * (parentargs_base + pa));
636 M_LST (REG_ITMP1, REG_SP, 8 * r);
640 else { /* floating args */
641 if (p < FLT_ARG_CNT) { /* register arguments */
642 if (!(var->flags & INMEMORY)) /* reg arg -> register */
643 {M_FLTMOVE (argfltregs[p], r);}
644 else /* reg arg -> spilled */
645 M_DST (argfltregs[p], REG_SP, 8 * r);
647 else { /* stack arguments */
648 pa = p - FLT_ARG_CNT;
649 if (!(var->flags & INMEMORY)) /* stack-arg -> register */
650 M_DLD (r, REG_SP, 8 * (parentargs_base + pa) );
651 else { /* stack-arg -> spilled */
652 M_DLD (REG_FTMP1, REG_SP, 8 * (parentargs_base + pa));
653 M_DST (REG_FTMP1, REG_SP, 8 * r);
659 /* call monitorenter function */
662 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
664 p = dseg_addaddress ((void*) (builtin_monitorenter));
665 M_ALD(REG_PV, REG_PV, p);
666 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
667 M_JSR(REG_RA, REG_PV);
668 disp = -(int)((u1*) mcodeptr - mcodebase);
669 M_LDA(REG_PV, REG_RA, disp);
674 /* end of header generation */
676 /* walk through all basic blocks */
677 for (bptr = block; bptr != NULL; bptr = bptr->next) {
679 bptr->mpc = (int)((u1*) mcodeptr - mcodebase);
681 if (bptr->flags >= BBREACHED) {
683 /* branch resolving */
687 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
688 gen_resolvebranch((u1*) mcodebase + brefs->branchpos,
689 brefs->branchpos, bptr->mpc);
693 /* copy interface registers to their destination */
698 while (src != NULL) {
700 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
701 d = reg_of_var(src, REG_ITMP1);
702 M_INTMOVE(REG_ITMP1, d);
703 store_reg_to_var_int(src, d);
706 d = reg_of_var(src, REG_IFTMP);
707 if ((src->varkind != STACKVAR)) {
709 if (IS_FLT_DBL_TYPE(s2)) {
710 if (!(interfaces[len][s2].flags & INMEMORY)) {
711 s1 = interfaces[len][s2].regoff;
715 M_DLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
717 store_reg_to_var_flt(src, d);
720 if (!(interfaces[len][s2].flags & INMEMORY)) {
721 s1 = interfaces[len][s2].regoff;
725 M_LLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
727 store_reg_to_var_int(src, d);
734 /* walk through all instructions */
738 for (iptr = bptr->iinstr;
740 src = iptr->dst, len--, iptr++) {
742 MCODECHECK(64); /* an instruction usually needs < 64 words */
745 case ICMD_NOP: /* ... ==> ... */
748 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
750 var_to_reg_int(s1, src, REG_ITMP1);
752 codegen_addxnullrefs(mcodeptr);
755 /* constant operations ************************************************/
757 #define ICONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
758 else{a=dseg_adds4(c);M_ILD(r,REG_PV,a);}
760 #define LCONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
761 else{a=dseg_adds8(c);M_LLD(r,REG_PV,a);}
763 case ICMD_ICONST: /* ... ==> ..., constant */
764 /* op1 = 0, val.i = constant */
766 d = reg_of_var(iptr->dst, REG_ITMP1);
767 ICONST(d, iptr->val.i);
768 store_reg_to_var_int(iptr->dst, d);
771 case ICMD_LCONST: /* ... ==> ..., constant */
772 /* op1 = 0, val.l = constant */
774 d = reg_of_var(iptr->dst, REG_ITMP1);
775 LCONST(d, iptr->val.l);
776 store_reg_to_var_int(iptr->dst, d);
779 case ICMD_FCONST: /* ... ==> ..., constant */
780 /* op1 = 0, val.f = constant */
782 d = reg_of_var(iptr->dst, REG_FTMP1);
783 a = dseg_addfloat(iptr->val.f);
785 store_reg_to_var_flt(iptr->dst, d);
788 case ICMD_DCONST: /* ... ==> ..., constant */
789 /* op1 = 0, val.d = constant */
791 d = reg_of_var(iptr->dst, REG_FTMP1);
792 a = dseg_adddouble(iptr->val.d);
794 store_reg_to_var_flt(iptr->dst, d);
797 case ICMD_ACONST: /* ... ==> ..., constant */
798 /* op1 = 0, val.a = constant */
800 d = reg_of_var(iptr->dst, REG_ITMP1);
802 a = dseg_addaddress (iptr->val.a);
806 M_INTMOVE(REG_ZERO, d);
808 store_reg_to_var_int(iptr->dst, d);
812 /* load/store operations **********************************************/
814 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
815 case ICMD_LLOAD: /* op1 = local variable */
818 d = reg_of_var(iptr->dst, REG_ITMP1);
819 if ((iptr->dst->varkind == LOCALVAR) &&
820 (iptr->dst->varnum == iptr->op1))
822 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
823 if (var->flags & INMEMORY)
824 M_LLD(d, REG_SP, 8 * var->regoff);
826 {M_INTMOVE(var->regoff,d);}
827 store_reg_to_var_int(iptr->dst, d);
830 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
831 case ICMD_DLOAD: /* op1 = local variable */
833 d = reg_of_var(iptr->dst, REG_FTMP1);
834 if ((iptr->dst->varkind == LOCALVAR) &&
835 (iptr->dst->varnum == iptr->op1))
837 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
838 if (var->flags & INMEMORY)
839 M_DLD(d, REG_SP, 8 * var->regoff);
841 {M_FLTMOVE(var->regoff,d);}
842 store_reg_to_var_flt(iptr->dst, d);
846 case ICMD_ISTORE: /* ..., value ==> ... */
847 case ICMD_LSTORE: /* op1 = local variable */
850 if ((src->varkind == LOCALVAR) &&
851 (src->varnum == iptr->op1))
853 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
854 if (var->flags & INMEMORY) {
855 var_to_reg_int(s1, src, REG_ITMP1);
856 M_LST(s1, REG_SP, 8 * var->regoff);
859 var_to_reg_int(s1, src, var->regoff);
860 M_INTMOVE(s1, var->regoff);
864 case ICMD_FSTORE: /* ..., value ==> ... */
865 case ICMD_DSTORE: /* op1 = local variable */
867 if ((src->varkind == LOCALVAR) &&
868 (src->varnum == iptr->op1))
870 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
871 if (var->flags & INMEMORY) {
872 var_to_reg_flt(s1, src, REG_FTMP1);
873 M_DST(s1, REG_SP, 8 * var->regoff);
876 var_to_reg_flt(s1, src, var->regoff);
877 M_FLTMOVE(s1, var->regoff);
882 /* pop/dup/swap operations ********************************************/
884 /* attention: double and longs are only one entry in CACAO ICMDs */
886 case ICMD_POP: /* ..., value ==> ... */
887 case ICMD_POP2: /* ..., value, value ==> ... */
890 #define M_COPY(from,to) \
891 d = reg_of_var(to, REG_IFTMP); \
892 if ((from->regoff != to->regoff) || \
893 ((from->flags ^ to->flags) & INMEMORY)) { \
894 if (IS_FLT_DBL_TYPE(from->type)) { \
895 var_to_reg_flt(s1, from, d); \
897 store_reg_to_var_flt(to, d); \
900 var_to_reg_int(s1, from, d); \
902 store_reg_to_var_int(to, d); \
906 case ICMD_DUP: /* ..., a ==> ..., a, a */
907 M_COPY(src, iptr->dst);
910 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
912 M_COPY(src, iptr->dst->prev->prev);
914 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
916 M_COPY(src, iptr->dst);
917 M_COPY(src->prev, iptr->dst->prev);
920 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
922 M_COPY(src->prev, iptr->dst->prev->prev->prev);
924 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
926 M_COPY(src, iptr->dst);
927 M_COPY(src->prev, iptr->dst->prev);
928 M_COPY(src->prev->prev, iptr->dst->prev->prev);
929 M_COPY(src, iptr->dst->prev->prev->prev);
932 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
934 M_COPY(src, iptr->dst);
935 M_COPY(src->prev, iptr->dst->prev);
936 M_COPY(src->prev->prev, iptr->dst->prev->prev);
937 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
938 M_COPY(src, iptr->dst->prev->prev->prev->prev);
939 M_COPY(src->prev, iptr->dst->prev->prev->prev->prev->prev);
942 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
944 M_COPY(src, iptr->dst->prev);
945 M_COPY(src->prev, iptr->dst);
949 /* integer operations *************************************************/
951 case ICMD_INEG: /* ..., value ==> ..., - value */
953 var_to_reg_int(s1, src, REG_ITMP1);
954 d = reg_of_var(iptr->dst, REG_ITMP3);
955 M_ISUB(REG_ZERO, s1, d);
956 store_reg_to_var_int(iptr->dst, d);
959 case ICMD_LNEG: /* ..., value ==> ..., - value */
961 var_to_reg_int(s1, src, REG_ITMP1);
962 d = reg_of_var(iptr->dst, REG_ITMP3);
963 M_LSUB(REG_ZERO, s1, d);
964 store_reg_to_var_int(iptr->dst, d);
967 case ICMD_I2L: /* ..., value ==> ..., value */
969 var_to_reg_int(s1, src, REG_ITMP1);
970 d = reg_of_var(iptr->dst, REG_ITMP3);
972 store_reg_to_var_int(iptr->dst, d);
975 case ICMD_L2I: /* ..., value ==> ..., value */
977 var_to_reg_int(s1, src, REG_ITMP1);
978 d = reg_of_var(iptr->dst, REG_ITMP3);
979 M_IADD(s1, REG_ZERO, d );
980 store_reg_to_var_int(iptr->dst, d);
983 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
985 var_to_reg_int(s1, src, REG_ITMP1);
986 d = reg_of_var(iptr->dst, REG_ITMP3);
987 if (has_ext_instr_set) {
991 M_SLL_IMM(s1, 56, d);
992 M_SRA_IMM( d, 56, d);
994 store_reg_to_var_int(iptr->dst, d);
997 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
999 var_to_reg_int(s1, src, REG_ITMP1);
1000 d = reg_of_var(iptr->dst, REG_ITMP3);
1002 store_reg_to_var_int(iptr->dst, d);
1005 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
1007 var_to_reg_int(s1, src, REG_ITMP1);
1008 d = reg_of_var(iptr->dst, REG_ITMP3);
1009 if (has_ext_instr_set) {
1013 M_SLL_IMM(s1, 48, d);
1014 M_SRA_IMM( d, 48, d);
1016 store_reg_to_var_int(iptr->dst, d);
1020 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1022 var_to_reg_int(s1, src->prev, REG_ITMP1);
1023 var_to_reg_int(s2, src, REG_ITMP2);
1024 d = reg_of_var(iptr->dst, REG_ITMP3);
1026 store_reg_to_var_int(iptr->dst, d);
1029 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
1030 /* val.i = constant */
1032 var_to_reg_int(s1, src, REG_ITMP1);
1033 d = reg_of_var(iptr->dst, REG_ITMP3);
1034 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1035 M_IADD_IMM(s1, iptr->val.i, d);
1038 ICONST(REG_ITMP2, iptr->val.i);
1039 M_IADD(s1, REG_ITMP2, d);
1041 store_reg_to_var_int(iptr->dst, d);
1044 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1046 var_to_reg_int(s1, src->prev, REG_ITMP1);
1047 var_to_reg_int(s2, src, REG_ITMP2);
1048 d = reg_of_var(iptr->dst, REG_ITMP3);
1050 store_reg_to_var_int(iptr->dst, d);
1053 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
1054 /* val.l = constant */
1056 var_to_reg_int(s1, src, REG_ITMP1);
1057 d = reg_of_var(iptr->dst, REG_ITMP3);
1058 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1059 M_LADD_IMM(s1, iptr->val.l, d);
1062 LCONST(REG_ITMP2, iptr->val.l);
1063 M_LADD(s1, REG_ITMP2, d);
1065 store_reg_to_var_int(iptr->dst, d);
1068 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1070 var_to_reg_int(s1, src->prev, REG_ITMP1);
1071 var_to_reg_int(s2, src, REG_ITMP2);
1072 d = reg_of_var(iptr->dst, REG_ITMP3);
1074 store_reg_to_var_int(iptr->dst, d);
1077 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
1078 /* val.i = constant */
1080 var_to_reg_int(s1, src, REG_ITMP1);
1081 d = reg_of_var(iptr->dst, REG_ITMP3);
1082 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1083 M_ISUB_IMM(s1, iptr->val.i, d);
1086 ICONST(REG_ITMP2, iptr->val.i);
1087 M_ISUB(s1, REG_ITMP2, d);
1089 store_reg_to_var_int(iptr->dst, d);
1092 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1094 var_to_reg_int(s1, src->prev, REG_ITMP1);
1095 var_to_reg_int(s2, src, REG_ITMP2);
1096 d = reg_of_var(iptr->dst, REG_ITMP3);
1098 store_reg_to_var_int(iptr->dst, d);
1101 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
1102 /* val.l = constant */
1104 var_to_reg_int(s1, src, REG_ITMP1);
1105 d = reg_of_var(iptr->dst, REG_ITMP3);
1106 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1107 M_LSUB_IMM(s1, iptr->val.l, d);
1110 LCONST(REG_ITMP2, iptr->val.l);
1111 M_LSUB(s1, REG_ITMP2, d);
1113 store_reg_to_var_int(iptr->dst, d);
1116 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1118 var_to_reg_int(s1, src->prev, REG_ITMP1);
1119 var_to_reg_int(s2, src, REG_ITMP2);
1120 d = reg_of_var(iptr->dst, REG_ITMP3);
1122 store_reg_to_var_int(iptr->dst, d);
1125 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
1126 /* val.i = constant */
1128 var_to_reg_int(s1, src, REG_ITMP1);
1129 d = reg_of_var(iptr->dst, REG_ITMP3);
1130 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1131 M_IMUL_IMM(s1, iptr->val.i, d);
1134 ICONST(REG_ITMP2, iptr->val.i);
1135 M_IMUL(s1, REG_ITMP2, d);
1137 store_reg_to_var_int(iptr->dst, d);
1140 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1142 var_to_reg_int(s1, src->prev, REG_ITMP1);
1143 var_to_reg_int(s2, src, REG_ITMP2);
1144 d = reg_of_var(iptr->dst, REG_ITMP3);
1146 store_reg_to_var_int(iptr->dst, d);
1149 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
1150 /* val.l = constant */
1152 var_to_reg_int(s1, src, REG_ITMP1);
1153 d = reg_of_var(iptr->dst, REG_ITMP3);
1154 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1155 M_LMUL_IMM(s1, iptr->val.l, d);
1158 LCONST(REG_ITMP2, iptr->val.l);
1159 M_LMUL(s1, REG_ITMP2, d);
1161 store_reg_to_var_int(iptr->dst, d);
1164 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
1165 case ICMD_LDIVPOW2: /* val.i = constant */
1167 var_to_reg_int(s1, src, REG_ITMP1);
1168 d = reg_of_var(iptr->dst, REG_ITMP3);
1169 if (iptr->val.i <= 15) {
1170 M_LDA(REG_ITMP2, s1, (1 << iptr->val.i) -1);
1171 M_CMOVGE(s1, s1, REG_ITMP2);
1174 M_SRA_IMM(s1, 63, REG_ITMP2);
1175 M_SRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
1176 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1178 M_SRA_IMM(REG_ITMP2, iptr->val.i, d);
1179 store_reg_to_var_int(iptr->dst, d);
1182 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1184 var_to_reg_int(s1, src->prev, REG_ITMP1);
1185 var_to_reg_int(s2, src, REG_ITMP2);
1186 d = reg_of_var(iptr->dst, REG_ITMP3);
1187 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1188 M_SLL(s1, REG_ITMP3, d);
1189 M_IADD(d, REG_ZERO, d);
1190 store_reg_to_var_int(iptr->dst, d);
1193 case ICMD_ISHLCONST: /* ..., 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);
1198 M_SLL_IMM(s1, iptr->val.i & 0x1f, d);
1199 M_IADD(d, REG_ZERO, d);
1200 store_reg_to_var_int(iptr->dst, d);
1203 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1205 var_to_reg_int(s1, src->prev, REG_ITMP1);
1206 var_to_reg_int(s2, src, REG_ITMP2);
1207 d = reg_of_var(iptr->dst, REG_ITMP3);
1208 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1209 M_SRA(s1, REG_ITMP3, d);
1210 store_reg_to_var_int(iptr->dst, d);
1213 case ICMD_ISHRCONST: /* ..., 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_SRA_IMM(s1, iptr->val.i & 0x1f, d);
1219 store_reg_to_var_int(iptr->dst, d);
1222 case ICMD_IUSHR: /* ..., 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);
1227 M_AND_IMM(s2, 0x1f, REG_ITMP2);
1229 M_SRL(d, REG_ITMP2, d);
1230 M_IADD(d, REG_ZERO, d);
1231 store_reg_to_var_int(iptr->dst, d);
1234 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1235 /* val.i = constant */
1237 var_to_reg_int(s1, src, REG_ITMP1);
1238 d = reg_of_var(iptr->dst, REG_ITMP3);
1240 M_SRL_IMM(d, iptr->val.i & 0x1f, d);
1241 M_IADD(d, REG_ZERO, d);
1242 store_reg_to_var_int(iptr->dst, d);
1245 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1247 var_to_reg_int(s1, src->prev, REG_ITMP1);
1248 var_to_reg_int(s2, src, REG_ITMP2);
1249 d = reg_of_var(iptr->dst, REG_ITMP3);
1251 store_reg_to_var_int(iptr->dst, d);
1254 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1255 /* val.i = constant */
1257 var_to_reg_int(s1, src, REG_ITMP1);
1258 d = reg_of_var(iptr->dst, REG_ITMP3);
1259 M_SLL_IMM(s1, iptr->val.i & 0x3f, d);
1260 store_reg_to_var_int(iptr->dst, d);
1263 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1265 var_to_reg_int(s1, src->prev, REG_ITMP1);
1266 var_to_reg_int(s2, src, REG_ITMP2);
1267 d = reg_of_var(iptr->dst, REG_ITMP3);
1269 store_reg_to_var_int(iptr->dst, d);
1272 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1273 /* val.i = constant */
1275 var_to_reg_int(s1, src, REG_ITMP1);
1276 d = reg_of_var(iptr->dst, REG_ITMP3);
1277 M_SRA_IMM(s1, iptr->val.i & 0x3f, d);
1278 store_reg_to_var_int(iptr->dst, d);
1281 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1283 var_to_reg_int(s1, src->prev, REG_ITMP1);
1284 var_to_reg_int(s2, src, REG_ITMP2);
1285 d = reg_of_var(iptr->dst, REG_ITMP3);
1287 store_reg_to_var_int(iptr->dst, d);
1290 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1291 /* val.i = constant */
1293 var_to_reg_int(s1, src, REG_ITMP1);
1294 d = reg_of_var(iptr->dst, REG_ITMP3);
1295 M_SRL_IMM(s1, iptr->val.i & 0x3f, d);
1296 store_reg_to_var_int(iptr->dst, d);
1299 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1302 var_to_reg_int(s1, src->prev, REG_ITMP1);
1303 var_to_reg_int(s2, src, REG_ITMP2);
1304 d = reg_of_var(iptr->dst, REG_ITMP3);
1306 store_reg_to_var_int(iptr->dst, d);
1309 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1310 /* val.i = constant */
1312 var_to_reg_int(s1, src, REG_ITMP1);
1313 d = reg_of_var(iptr->dst, REG_ITMP3);
1314 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1315 M_AND_IMM(s1, iptr->val.i, d);
1317 else if (iptr->val.i == 0xffff) {
1320 else if (iptr->val.i == 0xffffff) {
1321 M_ZAPNOT_IMM(s1, 0x07, d);
1324 ICONST(REG_ITMP2, iptr->val.i);
1325 M_AND(s1, REG_ITMP2, d);
1327 store_reg_to_var_int(iptr->dst, d);
1330 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1331 /* val.i = constant */
1333 var_to_reg_int(s1, src, REG_ITMP1);
1334 d = reg_of_var(iptr->dst, REG_ITMP3);
1336 M_MOV(s1, REG_ITMP1);
1339 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1340 M_AND_IMM(s1, iptr->val.i, d);
1342 M_ISUB(REG_ZERO, s1, d);
1343 M_AND_IMM(d, iptr->val.i, d);
1345 else if (iptr->val.i == 0xffff) {
1348 M_ISUB(REG_ZERO, s1, d);
1351 else if (iptr->val.i == 0xffffff) {
1352 M_ZAPNOT_IMM(s1, 0x07, d);
1354 M_ISUB(REG_ZERO, s1, d);
1355 M_ZAPNOT_IMM(d, 0x07, d);
1358 ICONST(REG_ITMP2, iptr->val.i);
1359 M_AND(s1, REG_ITMP2, d);
1361 M_ISUB(REG_ZERO, s1, d);
1362 M_AND(d, REG_ITMP2, d);
1364 M_ISUB(REG_ZERO, d, d);
1365 store_reg_to_var_int(iptr->dst, d);
1368 case ICMD_IREM0X10001: /* ..., value ==> ..., value % 0x100001 */
1370 /* b = value & 0xffff;
1372 a = ((b - a) & 0xffff) + (b < a);
1374 var_to_reg_int(s1, src, REG_ITMP1);
1375 d = reg_of_var(iptr->dst, REG_ITMP3);
1377 M_MOV(s1, REG_ITMP3);
1381 M_CZEXT(s1, REG_ITMP2);
1382 M_SRA_IMM(s1, 16, d);
1383 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1384 M_ISUB(REG_ITMP2, d, d);
1386 M_IADD(d, REG_ITMP1, d);
1387 M_BR(11 + (s1 == REG_ITMP1));
1388 M_ISUB(REG_ZERO, s1, REG_ITMP1);
1389 M_CZEXT(REG_ITMP1, REG_ITMP2);
1390 M_SRA_IMM(REG_ITMP1, 16, d);
1391 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1392 M_ISUB(REG_ITMP2, d, d);
1394 M_IADD(d, REG_ITMP1, d);
1395 M_ISUB(REG_ZERO, d, d);
1396 if (s1 == REG_ITMP1) {
1397 var_to_reg_int(s1, src, REG_ITMP1);
1399 M_SLL_IMM(s1, 33, REG_ITMP2);
1400 M_CMPEQ(REG_ITMP2, REG_ZERO, REG_ITMP2);
1401 M_ISUB(d, REG_ITMP2, d);
1402 store_reg_to_var_int(iptr->dst, d);
1405 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1406 /* val.l = constant */
1408 var_to_reg_int(s1, src, REG_ITMP1);
1409 d = reg_of_var(iptr->dst, REG_ITMP3);
1410 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1411 M_AND_IMM(s1, iptr->val.l, d);
1413 else if (iptr->val.l == 0xffffL) {
1416 else if (iptr->val.l == 0xffffffL) {
1417 M_ZAPNOT_IMM(s1, 0x07, d);
1419 else if (iptr->val.l == 0xffffffffL) {
1422 else if (iptr->val.l == 0xffffffffffL) {
1423 M_ZAPNOT_IMM(s1, 0x1f, d);
1425 else if (iptr->val.l == 0xffffffffffffL) {
1426 M_ZAPNOT_IMM(s1, 0x3f, d);
1428 else if (iptr->val.l == 0xffffffffffffffL) {
1429 M_ZAPNOT_IMM(s1, 0x7f, d);
1432 LCONST(REG_ITMP2, iptr->val.l);
1433 M_AND(s1, REG_ITMP2, d);
1435 store_reg_to_var_int(iptr->dst, d);
1438 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1439 /* val.l = constant */
1441 var_to_reg_int(s1, src, REG_ITMP1);
1442 d = reg_of_var(iptr->dst, REG_ITMP3);
1444 M_MOV(s1, REG_ITMP1);
1447 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1448 M_AND_IMM(s1, iptr->val.l, d);
1450 M_LSUB(REG_ZERO, s1, d);
1451 M_AND_IMM(d, iptr->val.l, d);
1453 else if (iptr->val.l == 0xffffL) {
1456 M_LSUB(REG_ZERO, s1, d);
1459 else if (iptr->val.l == 0xffffffL) {
1460 M_ZAPNOT_IMM(s1, 0x07, d);
1462 M_LSUB(REG_ZERO, s1, d);
1463 M_ZAPNOT_IMM(d, 0x07, d);
1465 else if (iptr->val.l == 0xffffffffL) {
1468 M_LSUB(REG_ZERO, s1, d);
1471 else if (iptr->val.l == 0xffffffffffL) {
1472 M_ZAPNOT_IMM(s1, 0x1f, d);
1474 M_LSUB(REG_ZERO, s1, d);
1475 M_ZAPNOT_IMM(d, 0x1f, d);
1477 else if (iptr->val.l == 0xffffffffffffL) {
1478 M_ZAPNOT_IMM(s1, 0x3f, d);
1480 M_LSUB(REG_ZERO, s1, d);
1481 M_ZAPNOT_IMM(d, 0x3f, d);
1483 else if (iptr->val.l == 0xffffffffffffffL) {
1484 M_ZAPNOT_IMM(s1, 0x7f, d);
1486 M_LSUB(REG_ZERO, s1, d);
1487 M_ZAPNOT_IMM(d, 0x7f, d);
1490 LCONST(REG_ITMP2, iptr->val.l);
1491 M_AND(s1, REG_ITMP2, d);
1493 M_LSUB(REG_ZERO, s1, d);
1494 M_AND(d, REG_ITMP2, d);
1496 M_LSUB(REG_ZERO, d, d);
1497 store_reg_to_var_int(iptr->dst, d);
1500 case ICMD_LREM0X10001:/* ..., value ==> ..., value % 0x10001 */
1502 var_to_reg_int(s1, src, REG_ITMP1);
1503 d = reg_of_var(iptr->dst, REG_ITMP3);
1505 M_MOV(s1, REG_ITMP3);
1508 M_CZEXT(s1, REG_ITMP2);
1509 M_SRA_IMM(s1, 16, d);
1510 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1511 M_LSUB(REG_ITMP2, d, d);
1513 M_LADD(d, REG_ITMP1, d);
1514 M_LDA(REG_ITMP2, REG_ZERO, -1);
1515 M_SRL_IMM(REG_ITMP2, 33, REG_ITMP2);
1516 if (s1 == REG_ITMP1) {
1517 var_to_reg_int(s1, src, REG_ITMP1);
1519 M_CMPULT(s1, REG_ITMP2, REG_ITMP2);
1520 M_BNEZ(REG_ITMP2, 11);
1521 M_LDA(d, REG_ZERO, -257);
1522 M_ZAPNOT_IMM(d, 0xcd, d);
1523 M_LSUB(REG_ZERO, s1, REG_ITMP2);
1524 M_CMOVGE(s1, s1, REG_ITMP2);
1525 M_UMULH(REG_ITMP2, d, REG_ITMP2);
1526 M_SRL_IMM(REG_ITMP2, 16, REG_ITMP2);
1527 M_LSUB(REG_ZERO, REG_ITMP2, d);
1528 M_CMOVGE(s1, REG_ITMP2, d);
1529 M_SLL_IMM(d, 16, REG_ITMP2);
1530 M_LADD(d, REG_ITMP2, d);
1532 store_reg_to_var_int(iptr->dst, d);
1535 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1538 var_to_reg_int(s1, src->prev, REG_ITMP1);
1539 var_to_reg_int(s2, src, REG_ITMP2);
1540 d = reg_of_var(iptr->dst, REG_ITMP3);
1542 store_reg_to_var_int(iptr->dst, d);
1545 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1546 /* val.i = constant */
1548 var_to_reg_int(s1, src, REG_ITMP1);
1549 d = reg_of_var(iptr->dst, REG_ITMP3);
1550 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1551 M_OR_IMM(s1, iptr->val.i, d);
1554 ICONST(REG_ITMP2, iptr->val.i);
1555 M_OR(s1, REG_ITMP2, d);
1557 store_reg_to_var_int(iptr->dst, d);
1560 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1561 /* val.l = constant */
1563 var_to_reg_int(s1, src, REG_ITMP1);
1564 d = reg_of_var(iptr->dst, REG_ITMP3);
1565 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1566 M_OR_IMM(s1, iptr->val.l, d);
1569 LCONST(REG_ITMP2, iptr->val.l);
1570 M_OR(s1, REG_ITMP2, d);
1572 store_reg_to_var_int(iptr->dst, d);
1575 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1578 var_to_reg_int(s1, src->prev, REG_ITMP1);
1579 var_to_reg_int(s2, src, REG_ITMP2);
1580 d = reg_of_var(iptr->dst, REG_ITMP3);
1582 store_reg_to_var_int(iptr->dst, d);
1585 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1586 /* val.i = constant */
1588 var_to_reg_int(s1, src, REG_ITMP1);
1589 d = reg_of_var(iptr->dst, REG_ITMP3);
1590 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1591 M_XOR_IMM(s1, iptr->val.i, d);
1594 ICONST(REG_ITMP2, iptr->val.i);
1595 M_XOR(s1, REG_ITMP2, d);
1597 store_reg_to_var_int(iptr->dst, d);
1600 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1601 /* val.l = constant */
1603 var_to_reg_int(s1, src, REG_ITMP1);
1604 d = reg_of_var(iptr->dst, REG_ITMP3);
1605 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1606 M_XOR_IMM(s1, iptr->val.l, d);
1609 LCONST(REG_ITMP2, iptr->val.l);
1610 M_XOR(s1, REG_ITMP2, d);
1612 store_reg_to_var_int(iptr->dst, d);
1616 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1618 var_to_reg_int(s1, src->prev, REG_ITMP1);
1619 var_to_reg_int(s2, src, REG_ITMP2);
1620 d = reg_of_var(iptr->dst, REG_ITMP3);
1621 M_CMPLT(s1, s2, REG_ITMP3);
1622 M_CMPLT(s2, s1, REG_ITMP1);
1623 M_LSUB (REG_ITMP1, REG_ITMP3, d);
1624 store_reg_to_var_int(iptr->dst, d);
1628 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1629 /* op1 = variable, val.i = constant */
1631 var = &(locals[iptr->op1][TYPE_INT]);
1632 if (var->flags & INMEMORY) {
1634 M_LLD(s1, REG_SP, 8 * var->regoff);
1638 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1639 M_IADD_IMM(s1, iptr->val.i, s1);
1641 else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1642 M_ISUB_IMM(s1, (-iptr->val.i), s1);
1645 M_LDA (s1, s1, iptr->val.i);
1646 M_IADD(s1, REG_ZERO, s1);
1648 if (var->flags & INMEMORY)
1649 M_LST(s1, REG_SP, 8 * var->regoff);
1653 /* floating operations ************************************************/
1655 case ICMD_FNEG: /* ..., value ==> ..., - value */
1657 var_to_reg_flt(s1, src, REG_FTMP1);
1658 d = reg_of_var(iptr->dst, REG_FTMP3);
1660 store_reg_to_var_flt(iptr->dst, d);
1663 case ICMD_DNEG: /* ..., value ==> ..., - value */
1665 var_to_reg_flt(s1, src, REG_FTMP1);
1666 d = reg_of_var(iptr->dst, REG_FTMP3);
1668 store_reg_to_var_flt(iptr->dst, d);
1671 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1673 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1674 var_to_reg_flt(s2, src, REG_FTMP2);
1675 d = reg_of_var(iptr->dst, REG_FTMP3);
1680 if (d == s1 || d == s2) {
1681 M_FADDS(s1, s2, REG_FTMP3);
1683 M_FMOV(REG_FTMP3, d);
1690 store_reg_to_var_flt(iptr->dst, d);
1693 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1695 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1696 var_to_reg_flt(s2, src, REG_FTMP2);
1697 d = reg_of_var(iptr->dst, REG_FTMP3);
1702 if (d == s1 || d == s2) {
1703 M_DADDS(s1, s2, REG_FTMP3);
1705 M_FMOV(REG_FTMP3, d);
1712 store_reg_to_var_flt(iptr->dst, d);
1715 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1717 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1718 var_to_reg_flt(s2, src, REG_FTMP2);
1719 d = reg_of_var(iptr->dst, REG_FTMP3);
1724 if (d == s1 || d == s2) {
1725 M_FSUBS(s1, s2, REG_FTMP3);
1727 M_FMOV(REG_FTMP3, d);
1734 store_reg_to_var_flt(iptr->dst, d);
1737 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1739 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1740 var_to_reg_flt(s2, src, REG_FTMP2);
1741 d = reg_of_var(iptr->dst, REG_FTMP3);
1746 if (d == s1 || d == s2) {
1747 M_DSUBS(s1, s2, REG_FTMP3);
1749 M_FMOV(REG_FTMP3, d);
1756 store_reg_to_var_flt(iptr->dst, d);
1759 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1761 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1762 var_to_reg_flt(s2, src, REG_FTMP2);
1763 d = reg_of_var(iptr->dst, REG_FTMP3);
1768 if (d == s1 || d == s2) {
1769 M_FMULS(s1, s2, REG_FTMP3);
1771 M_FMOV(REG_FTMP3, d);
1778 store_reg_to_var_flt(iptr->dst, d);
1781 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1783 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1784 var_to_reg_flt(s2, src, REG_FTMP2);
1785 d = reg_of_var(iptr->dst, REG_FTMP3);
1790 if (d == s1 || d == s2) {
1791 M_DMULS(s1, s2, REG_FTMP3);
1793 M_FMOV(REG_FTMP3, d);
1800 store_reg_to_var_flt(iptr->dst, d);
1803 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1805 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1806 var_to_reg_flt(s2, src, REG_FTMP2);
1807 d = reg_of_var(iptr->dst, REG_FTMP3);
1812 if (d == s1 || d == s2) {
1813 M_FDIVS(s1, s2, REG_FTMP3);
1815 M_FMOV(REG_FTMP3, d);
1822 store_reg_to_var_flt(iptr->dst, d);
1825 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1827 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1828 var_to_reg_flt(s2, src, REG_FTMP2);
1829 d = reg_of_var(iptr->dst, REG_FTMP3);
1834 if (d == s1 || d == s2) {
1835 M_DDIVS(s1, s2, REG_FTMP3);
1837 M_FMOV(REG_FTMP3, d);
1844 store_reg_to_var_flt(iptr->dst, d);
1847 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1849 var_to_reg_int(s1, src, REG_ITMP1);
1850 d = reg_of_var(iptr->dst, REG_FTMP3);
1851 a = dseg_adddouble(0.0);
1852 M_LST (s1, REG_PV, a);
1853 M_DLD (d, REG_PV, a);
1855 store_reg_to_var_flt(iptr->dst, d);
1858 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1860 var_to_reg_int(s1, src, REG_ITMP1);
1861 d = reg_of_var(iptr->dst, REG_FTMP3);
1862 a = dseg_adddouble(0.0);
1863 M_LST (s1, REG_PV, a);
1864 M_DLD (d, REG_PV, a);
1866 store_reg_to_var_flt(iptr->dst, d);
1869 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1871 var_to_reg_flt(s1, src, REG_FTMP1);
1872 d = reg_of_var(iptr->dst, REG_ITMP3);
1873 a = dseg_adddouble(0.0);
1874 M_CVTDL_C(s1, REG_FTMP2);
1875 M_CVTLI(REG_FTMP2, REG_FTMP3);
1876 M_DST (REG_FTMP3, REG_PV, a);
1877 M_ILD (d, REG_PV, a);
1878 store_reg_to_var_int(iptr->dst, d);
1881 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1883 var_to_reg_flt(s1, src, REG_FTMP1);
1884 d = reg_of_var(iptr->dst, REG_ITMP3);
1885 a = dseg_adddouble(0.0);
1886 M_CVTDL_C(s1, REG_FTMP2);
1887 M_DST (REG_FTMP2, REG_PV, a);
1888 M_LLD (d, REG_PV, a);
1889 store_reg_to_var_int(iptr->dst, d);
1892 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1894 var_to_reg_flt(s1, src, REG_FTMP1);
1895 d = reg_of_var(iptr->dst, REG_FTMP3);
1898 store_reg_to_var_flt(iptr->dst, d);
1901 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1903 var_to_reg_flt(s1, src, REG_FTMP1);
1904 d = reg_of_var(iptr->dst, REG_FTMP3);
1912 store_reg_to_var_flt(iptr->dst, d);
1915 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1917 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1918 var_to_reg_flt(s2, src, REG_FTMP2);
1919 d = reg_of_var(iptr->dst, REG_ITMP3);
1921 M_LSUB_IMM(REG_ZERO, 1, d);
1922 M_FCMPEQ(s1, s2, REG_FTMP3);
1923 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1925 M_FCMPLT(s2, s1, REG_FTMP3);
1926 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1927 M_LADD_IMM(REG_ZERO, 1, d);
1930 M_LSUB_IMM(REG_ZERO, 1, d);
1931 M_FCMPEQS(s1, s2, REG_FTMP3);
1933 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1935 M_FCMPLTS(s2, s1, REG_FTMP3);
1937 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1938 M_LADD_IMM(REG_ZERO, 1, d);
1940 store_reg_to_var_int(iptr->dst, d);
1943 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1945 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1946 var_to_reg_flt(s2, src, REG_FTMP2);
1947 d = reg_of_var(iptr->dst, REG_ITMP3);
1949 M_LADD_IMM(REG_ZERO, 1, d);
1950 M_FCMPEQ(s1, s2, REG_FTMP3);
1951 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1953 M_FCMPLT(s1, s2, REG_FTMP3);
1954 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1955 M_LSUB_IMM(REG_ZERO, 1, d);
1958 M_LADD_IMM(REG_ZERO, 1, d);
1959 M_FCMPEQS(s1, s2, REG_FTMP3);
1961 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1963 M_FCMPLTS(s1, s2, REG_FTMP3);
1965 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1966 M_LSUB_IMM(REG_ZERO, 1, d);
1968 store_reg_to_var_int(iptr->dst, d);
1972 /* memory operations **************************************************/
1974 /* #define gen_bound_check \
1976 M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\
1977 M_CMPULT(s2, REG_ITMP3, REG_ITMP3);\
1978 M_BEQZ(REG_ITMP3, 0);\
1979 codegen_addxboundrefs(mcodeptr);\
1983 #define gen_bound_check \
1984 if (checkbounds) { \
1985 M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\
1986 M_CMPULT(s2, REG_ITMP3, REG_ITMP3);\
1987 M_BEQZ(REG_ITMP3, 0);\
1988 codegen_addxboundrefs(mcodeptr, s2); \
1991 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1993 var_to_reg_int(s1, src, REG_ITMP1);
1994 d = reg_of_var(iptr->dst, REG_ITMP3);
1995 gen_nullptr_check(s1);
1996 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1997 store_reg_to_var_int(iptr->dst, d);
2000 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
2002 var_to_reg_int(s1, src->prev, REG_ITMP1);
2003 var_to_reg_int(s2, src, REG_ITMP2);
2004 d = reg_of_var(iptr->dst, REG_ITMP3);
2005 if (iptr->op1 == 0) {
2006 gen_nullptr_check(s1);
2009 M_SAADDQ(s2, s1, REG_ITMP1);
2010 M_ALD( d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
2011 store_reg_to_var_int(iptr->dst, d);
2014 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
2016 var_to_reg_int(s1, src->prev, REG_ITMP1);
2017 var_to_reg_int(s2, src, REG_ITMP2);
2018 d = reg_of_var(iptr->dst, REG_ITMP3);
2019 if (iptr->op1 == 0) {
2020 gen_nullptr_check(s1);
2023 M_S8ADDQ(s2, s1, REG_ITMP1);
2024 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
2025 store_reg_to_var_int(iptr->dst, d);
2028 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
2030 var_to_reg_int(s1, src->prev, REG_ITMP1);
2031 var_to_reg_int(s2, src, REG_ITMP2);
2032 d = reg_of_var(iptr->dst, REG_ITMP3);
2033 if (iptr->op1 == 0) {
2034 gen_nullptr_check(s1);
2038 M_S4ADDQ(s2, s1, REG_ITMP1);
2039 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
2040 store_reg_to_var_int(iptr->dst, d);
2043 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
2045 var_to_reg_int(s1, src->prev, REG_ITMP1);
2046 var_to_reg_int(s2, src, REG_ITMP2);
2047 d = reg_of_var(iptr->dst, REG_FTMP3);
2048 if (iptr->op1 == 0) {
2049 gen_nullptr_check(s1);
2052 M_S4ADDQ(s2, s1, REG_ITMP1);
2053 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
2054 store_reg_to_var_flt(iptr->dst, d);
2057 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
2059 var_to_reg_int(s1, src->prev, REG_ITMP1);
2060 var_to_reg_int(s2, src, REG_ITMP2);
2061 d = reg_of_var(iptr->dst, REG_FTMP3);
2062 if (iptr->op1 == 0) {
2063 gen_nullptr_check(s1);
2066 M_S8ADDQ(s2, s1, REG_ITMP1);
2067 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
2068 store_reg_to_var_flt(iptr->dst, d);
2071 case ICMD_CALOAD: /* ..., 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_LADD(s2, REG_ITMP1, REG_ITMP1);
2083 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
2086 M_LADD (s2, s1, REG_ITMP1);
2087 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2088 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2089 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2090 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
2092 store_reg_to_var_int(iptr->dst, d);
2095 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
2097 var_to_reg_int(s1, src->prev, REG_ITMP1);
2098 var_to_reg_int(s2, src, REG_ITMP2);
2099 d = reg_of_var(iptr->dst, REG_ITMP3);
2100 if (iptr->op1 == 0) {
2101 gen_nullptr_check(s1);
2104 if (has_ext_instr_set) {
2105 M_LADD(s2, s1, REG_ITMP1);
2106 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2107 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
2111 M_LADD(s2, s1, REG_ITMP1);
2112 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2113 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2114 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
2115 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
2116 M_SRA_IMM(d, 48, d);
2118 store_reg_to_var_int(iptr->dst, d);
2121 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
2123 var_to_reg_int(s1, src->prev, REG_ITMP1);
2124 var_to_reg_int(s2, src, REG_ITMP2);
2125 d = reg_of_var(iptr->dst, REG_ITMP3);
2126 if (iptr->op1 == 0) {
2127 gen_nullptr_check(s1);
2130 if (has_ext_instr_set) {
2131 M_LADD (s2, s1, REG_ITMP1);
2132 M_BLDU (d, REG_ITMP1, OFFSET (java_bytearray, data[0]));
2136 M_LADD(s2, s1, REG_ITMP1);
2137 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2138 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
2139 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
2140 M_SRA_IMM(d, 56, d);
2142 store_reg_to_var_int(iptr->dst, d);
2146 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
2148 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2149 var_to_reg_int(s2, src->prev, REG_ITMP2);
2150 if (iptr->op1 == 0) {
2151 gen_nullptr_check(s1);
2154 var_to_reg_int(s3, src, REG_ITMP3);
2155 M_SAADDQ(s2, s1, REG_ITMP1);
2156 M_AST (s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
2159 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
2161 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2162 var_to_reg_int(s2, src->prev, REG_ITMP2);
2163 if (iptr->op1 == 0) {
2164 gen_nullptr_check(s1);
2167 var_to_reg_int(s3, src, REG_ITMP3);
2168 M_S8ADDQ(s2, s1, REG_ITMP1);
2169 M_LST (s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
2172 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
2174 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2175 var_to_reg_int(s2, src->prev, REG_ITMP2);
2176 if (iptr->op1 == 0) {
2177 gen_nullptr_check(s1);
2181 var_to_reg_int(s3, src, REG_ITMP3);
2182 M_S4ADDQ(s2, s1, REG_ITMP1);
2183 M_IST (s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
2186 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
2188 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2189 var_to_reg_int(s2, src->prev, REG_ITMP2);
2190 if (iptr->op1 == 0) {
2191 gen_nullptr_check(s1);
2194 var_to_reg_flt(s3, src, REG_FTMP3);
2195 M_S4ADDQ(s2, s1, REG_ITMP1);
2196 M_FST (s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
2199 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
2201 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2202 var_to_reg_int(s2, src->prev, REG_ITMP2);
2203 if (iptr->op1 == 0) {
2204 gen_nullptr_check(s1);
2207 var_to_reg_flt(s3, src, REG_FTMP3);
2208 M_S8ADDQ(s2, s1, REG_ITMP1);
2209 M_DST (s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
2212 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
2214 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2215 var_to_reg_int(s2, src->prev, REG_ITMP2);
2216 if (iptr->op1 == 0) {
2217 gen_nullptr_check(s1);
2220 var_to_reg_int(s3, src, REG_ITMP3);
2221 if (has_ext_instr_set) {
2222 M_LADD(s2, s1, REG_ITMP1);
2223 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2224 M_SST (s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
2227 M_LADD (s2, s1, REG_ITMP1);
2228 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2229 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2230 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2231 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
2232 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2233 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2234 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2238 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
2240 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2241 var_to_reg_int(s2, src->prev, REG_ITMP2);
2242 if (iptr->op1 == 0) {
2243 gen_nullptr_check(s1);
2246 var_to_reg_int(s3, src, REG_ITMP3);
2247 if (has_ext_instr_set) {
2248 M_LADD(s2, s1, REG_ITMP1);
2249 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2250 M_SST (s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2253 M_LADD (s2, s1, REG_ITMP1);
2254 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2255 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2256 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2257 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
2258 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2259 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2260 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2264 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
2266 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2267 var_to_reg_int(s2, src->prev, REG_ITMP2);
2268 if (iptr->op1 == 0) {
2269 gen_nullptr_check(s1);
2272 var_to_reg_int(s3, src, REG_ITMP3);
2273 if (has_ext_instr_set) {
2274 M_LADD(s2, s1, REG_ITMP1);
2275 M_BST (s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2278 M_LADD (s2, s1, REG_ITMP1);
2279 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2280 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2281 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
2282 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2283 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2284 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2289 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2290 /* op1 = type, val.a = field address */
2292 /* if class isn't yet initialized, do it */
2293 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
2294 /* call helper function which patches this code */
2295 a = dseg_addaddress(((fieldinfo *) iptr->val.a)->class);
2296 M_ALD(REG_ITMP1, REG_PV, a);
2297 a = dseg_addaddress(asm_check_clinit);
2298 M_ALD(REG_PV, REG_PV, a);
2299 M_JSR(REG_RA, REG_PV);
2302 s1 = (int) ((u1*) mcodeptr - mcodebase);
2304 M_LDA(REG_PV, REG_RA, -s1);
2308 s4 ml = -s1, mh = 0;
2309 while (ml < -32768) { ml += 65536; mh--; }
2310 M_LDA(REG_PV, REG_RA, ml);
2311 M_LDAH(REG_PV, REG_PV, mh);
2315 a = dseg_addaddress(&(((fieldinfo *)(iptr->val.a))->value));
2316 M_ALD(REG_ITMP1, REG_PV, a);
2317 switch (iptr->op1) {
2319 var_to_reg_int(s2, src, REG_ITMP2);
2320 M_IST(s2, REG_ITMP1, 0);
2323 var_to_reg_int(s2, src, REG_ITMP2);
2324 M_LST(s2, REG_ITMP1, 0);
2327 var_to_reg_int(s2, src, REG_ITMP2);
2328 M_AST(s2, REG_ITMP1, 0);
2331 var_to_reg_flt(s2, src, REG_FTMP2);
2332 M_FST(s2, REG_ITMP1, 0);
2335 var_to_reg_flt(s2, src, REG_FTMP2);
2336 M_DST(s2, REG_ITMP1, 0);
2338 default: panic ("internal error");
2342 case ICMD_GETSTATIC: /* ... ==> ..., value */
2343 /* op1 = type, val.a = field address */
2345 /* if class isn't yet initialized, do it */
2346 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
2347 /* call helper function which patches this code */
2348 a = dseg_addaddress(((fieldinfo *) iptr->val.a)->class);
2349 M_ALD(REG_ITMP1, REG_PV, a);
2350 a = dseg_addaddress(asm_check_clinit);
2351 M_ALD(REG_PV, REG_PV, a);
2352 M_JSR(REG_RA, REG_PV);
2355 s1 = (int) ((u1*) mcodeptr - mcodebase);
2357 M_LDA(REG_PV, REG_RA, -s1);
2361 s4 ml = -s1, mh = 0;
2362 while (ml < -32768) { ml += 65536; mh--; }
2363 M_LDA(REG_PV, REG_RA, ml);
2364 M_LDAH(REG_PV, REG_PV, mh);
2368 a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value));
2369 M_ALD(REG_ITMP1, REG_PV, a);
2370 switch (iptr->op1) {
2372 d = reg_of_var(iptr->dst, REG_ITMP3);
2373 M_ILD(d, REG_ITMP1, 0);
2374 store_reg_to_var_int(iptr->dst, d);
2377 d = reg_of_var(iptr->dst, REG_ITMP3);
2378 M_LLD(d, REG_ITMP1, 0);
2379 store_reg_to_var_int(iptr->dst, d);
2382 d = reg_of_var(iptr->dst, REG_ITMP3);
2383 M_ALD(d, REG_ITMP1, 0);
2384 store_reg_to_var_int(iptr->dst, d);
2387 d = reg_of_var(iptr->dst, REG_FTMP1);
2388 M_FLD(d, REG_ITMP1, 0);
2389 store_reg_to_var_flt(iptr->dst, d);
2392 d = reg_of_var(iptr->dst, REG_FTMP1);
2393 M_DLD(d, REG_ITMP1, 0);
2394 store_reg_to_var_flt(iptr->dst, d);
2396 default: panic ("internal error");
2401 case ICMD_PUTFIELD: /* ..., value ==> ... */
2402 /* op1 = type, val.i = field offset */
2404 a = ((fieldinfo *)(iptr->val.a))->offset;
2405 switch (iptr->op1) {
2407 var_to_reg_int(s1, src->prev, REG_ITMP1);
2408 var_to_reg_int(s2, src, REG_ITMP2);
2409 gen_nullptr_check(s1);
2413 var_to_reg_int(s1, src->prev, REG_ITMP1);
2414 var_to_reg_int(s2, src, REG_ITMP2);
2415 gen_nullptr_check(s1);
2419 var_to_reg_int(s1, src->prev, REG_ITMP1);
2420 var_to_reg_int(s2, src, REG_ITMP2);
2421 gen_nullptr_check(s1);
2425 var_to_reg_int(s1, src->prev, REG_ITMP1);
2426 var_to_reg_flt(s2, src, REG_FTMP2);
2427 gen_nullptr_check(s1);
2431 var_to_reg_int(s1, src->prev, REG_ITMP1);
2432 var_to_reg_flt(s2, src, REG_FTMP2);
2433 gen_nullptr_check(s1);
2436 default: panic ("internal error");
2440 case ICMD_GETFIELD: /* ... ==> ..., value */
2441 /* op1 = type, val.i = field offset */
2443 a = ((fieldinfo *)(iptr->val.a))->offset;
2444 switch (iptr->op1) {
2446 var_to_reg_int(s1, src, REG_ITMP1);
2447 d = reg_of_var(iptr->dst, REG_ITMP3);
2448 gen_nullptr_check(s1);
2450 store_reg_to_var_int(iptr->dst, d);
2453 var_to_reg_int(s1, src, REG_ITMP1);
2454 d = reg_of_var(iptr->dst, REG_ITMP3);
2455 gen_nullptr_check(s1);
2457 store_reg_to_var_int(iptr->dst, d);
2460 var_to_reg_int(s1, src, REG_ITMP1);
2461 d = reg_of_var(iptr->dst, REG_ITMP3);
2462 gen_nullptr_check(s1);
2464 store_reg_to_var_int(iptr->dst, d);
2467 var_to_reg_int(s1, src, REG_ITMP1);
2468 d = reg_of_var(iptr->dst, REG_FTMP1);
2469 gen_nullptr_check(s1);
2471 store_reg_to_var_flt(iptr->dst, d);
2474 var_to_reg_int(s1, src, REG_ITMP1);
2475 d = reg_of_var(iptr->dst, REG_FTMP1);
2476 gen_nullptr_check(s1);
2478 store_reg_to_var_flt(iptr->dst, d);
2480 default: panic ("internal error");
2485 /* branch operations **************************************************/
2487 #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}}
2489 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2491 var_to_reg_int(s1, src, REG_ITMP1);
2492 M_INTMOVE(s1, REG_ITMP1_XPTR);
2493 a = dseg_addaddress(asm_handle_exception);
2494 M_ALD(REG_ITMP2, REG_PV, a);
2495 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2496 M_NOP; /* nop ensures that XPC is less than the end */
2497 /* of basic block */
2501 case ICMD_GOTO: /* ... ==> ... */
2502 /* op1 = target JavaVM pc */
2504 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2508 case ICMD_JSR: /* ... ==> ... */
2509 /* op1 = target JavaVM pc */
2511 M_BSR(REG_ITMP1, 0);
2512 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2515 case ICMD_RET: /* ... ==> ... */
2516 /* op1 = local variable */
2518 var = &(locals[iptr->op1][TYPE_ADR]);
2519 if (var->flags & INMEMORY) {
2520 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2521 M_RET(REG_ZERO, REG_ITMP1);
2524 M_RET(REG_ZERO, var->regoff);
2528 case ICMD_IFNULL: /* ..., value ==> ... */
2529 /* op1 = target JavaVM pc */
2531 var_to_reg_int(s1, src, REG_ITMP1);
2533 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2536 case ICMD_IFNONNULL: /* ..., value ==> ... */
2537 /* op1 = target JavaVM pc */
2539 var_to_reg_int(s1, src, REG_ITMP1);
2541 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2544 case ICMD_IFEQ: /* ..., value ==> ... */
2545 /* op1 = target JavaVM pc, val.i = constant */
2547 var_to_reg_int(s1, src, REG_ITMP1);
2548 if (iptr->val.i == 0) {
2552 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2553 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2556 ICONST(REG_ITMP2, iptr->val.i);
2557 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2559 M_BNEZ(REG_ITMP1, 0);
2561 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2564 case ICMD_IFLT: /* ..., value ==> ... */
2565 /* op1 = target JavaVM pc, val.i = constant */
2567 var_to_reg_int(s1, src, REG_ITMP1);
2568 if (iptr->val.i == 0) {
2572 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2573 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2576 ICONST(REG_ITMP2, iptr->val.i);
2577 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2579 M_BNEZ(REG_ITMP1, 0);
2581 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2584 case ICMD_IFLE: /* ..., value ==> ... */
2585 /* op1 = target JavaVM pc, val.i = constant */
2587 var_to_reg_int(s1, src, REG_ITMP1);
2588 if (iptr->val.i == 0) {
2592 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2593 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2596 ICONST(REG_ITMP2, iptr->val.i);
2597 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2599 M_BNEZ(REG_ITMP1, 0);
2601 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2604 case ICMD_IFNE: /* ..., value ==> ... */
2605 /* op1 = target JavaVM pc, val.i = constant */
2607 var_to_reg_int(s1, src, REG_ITMP1);
2608 if (iptr->val.i == 0) {
2612 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2613 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2616 ICONST(REG_ITMP2, iptr->val.i);
2617 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2619 M_BEQZ(REG_ITMP1, 0);
2621 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2624 case ICMD_IFGT: /* ..., value ==> ... */
2625 /* op1 = target JavaVM pc, val.i = constant */
2627 var_to_reg_int(s1, src, REG_ITMP1);
2628 if (iptr->val.i == 0) {
2632 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2633 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2636 ICONST(REG_ITMP2, iptr->val.i);
2637 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2639 M_BEQZ(REG_ITMP1, 0);
2641 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2644 case ICMD_IFGE: /* ..., value ==> ... */
2645 /* op1 = target JavaVM pc, val.i = constant */
2647 var_to_reg_int(s1, src, REG_ITMP1);
2648 if (iptr->val.i == 0) {
2652 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2653 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2656 ICONST(REG_ITMP2, iptr->val.i);
2657 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2659 M_BEQZ(REG_ITMP1, 0);
2661 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2664 case ICMD_IF_LEQ: /* ..., value ==> ... */
2665 /* op1 = target JavaVM pc, val.l = constant */
2667 var_to_reg_int(s1, src, REG_ITMP1);
2668 if (iptr->val.l == 0) {
2672 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2673 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2676 LCONST(REG_ITMP2, iptr->val.l);
2677 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2679 M_BNEZ(REG_ITMP1, 0);
2681 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2684 case ICMD_IF_LLT: /* ..., value ==> ... */
2685 /* op1 = target JavaVM pc, val.l = constant */
2687 var_to_reg_int(s1, src, REG_ITMP1);
2688 if (iptr->val.l == 0) {
2692 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2693 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2696 LCONST(REG_ITMP2, iptr->val.l);
2697 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2699 M_BNEZ(REG_ITMP1, 0);
2701 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2704 case ICMD_IF_LLE: /* ..., value ==> ... */
2705 /* op1 = target JavaVM pc, val.l = constant */
2707 var_to_reg_int(s1, src, REG_ITMP1);
2708 if (iptr->val.l == 0) {
2712 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2713 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2716 LCONST(REG_ITMP2, iptr->val.l);
2717 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2719 M_BNEZ(REG_ITMP1, 0);
2721 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2724 case ICMD_IF_LNE: /* ..., value ==> ... */
2725 /* op1 = target JavaVM pc, val.l = constant */
2727 var_to_reg_int(s1, src, REG_ITMP1);
2728 if (iptr->val.l == 0) {
2732 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2733 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2736 LCONST(REG_ITMP2, iptr->val.l);
2737 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2739 M_BEQZ(REG_ITMP1, 0);
2741 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2744 case ICMD_IF_LGT: /* ..., value ==> ... */
2745 /* op1 = target JavaVM pc, val.l = constant */
2747 var_to_reg_int(s1, src, REG_ITMP1);
2748 if (iptr->val.l == 0) {
2752 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2753 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2756 LCONST(REG_ITMP2, iptr->val.l);
2757 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2759 M_BEQZ(REG_ITMP1, 0);
2761 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2764 case ICMD_IF_LGE: /* ..., value ==> ... */
2765 /* op1 = target JavaVM pc, val.l = constant */
2767 var_to_reg_int(s1, src, REG_ITMP1);
2768 if (iptr->val.l == 0) {
2772 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2773 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2776 LCONST(REG_ITMP2, iptr->val.l);
2777 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2779 M_BEQZ(REG_ITMP1, 0);
2781 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2784 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2785 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2786 case ICMD_IF_ACMPEQ:
2788 var_to_reg_int(s1, src->prev, REG_ITMP1);
2789 var_to_reg_int(s2, src, REG_ITMP2);
2790 M_CMPEQ(s1, s2, REG_ITMP1);
2791 M_BNEZ(REG_ITMP1, 0);
2792 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2795 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2796 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2797 case ICMD_IF_ACMPNE:
2799 var_to_reg_int(s1, src->prev, REG_ITMP1);
2800 var_to_reg_int(s2, src, REG_ITMP2);
2801 M_CMPEQ(s1, s2, REG_ITMP1);
2802 M_BEQZ(REG_ITMP1, 0);
2803 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2806 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2807 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2809 var_to_reg_int(s1, src->prev, REG_ITMP1);
2810 var_to_reg_int(s2, src, REG_ITMP2);
2811 M_CMPLT(s1, s2, REG_ITMP1);
2812 M_BNEZ(REG_ITMP1, 0);
2813 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2816 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2817 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2819 var_to_reg_int(s1, src->prev, REG_ITMP1);
2820 var_to_reg_int(s2, src, REG_ITMP2);
2821 M_CMPLE(s1, s2, REG_ITMP1);
2822 M_BEQZ(REG_ITMP1, 0);
2823 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2826 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2827 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2829 var_to_reg_int(s1, src->prev, REG_ITMP1);
2830 var_to_reg_int(s2, src, REG_ITMP2);
2831 M_CMPLE(s1, s2, REG_ITMP1);
2832 M_BNEZ(REG_ITMP1, 0);
2833 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2836 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2837 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2839 var_to_reg_int(s1, src->prev, REG_ITMP1);
2840 var_to_reg_int(s2, src, REG_ITMP2);
2841 M_CMPLT(s1, s2, REG_ITMP1);
2842 M_BEQZ(REG_ITMP1, 0);
2843 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2846 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2848 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2851 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2852 /* val.i = constant */
2854 var_to_reg_int(s1, src, REG_ITMP1);
2855 d = reg_of_var(iptr->dst, REG_ITMP3);
2857 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2858 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2859 M_CMPEQ(s1, REG_ZERO, d);
2860 store_reg_to_var_int(iptr->dst, d);
2863 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2864 M_CMPEQ(s1, REG_ZERO, d);
2866 store_reg_to_var_int(iptr->dst, d);
2870 M_MOV(s1, REG_ITMP1);
2873 ICONST(d, iptr[1].val.i);
2875 if ((s3 >= 0) && (s3 <= 255)) {
2876 M_CMOVEQ_IMM(s1, s3, d);
2879 ICONST(REG_ITMP2, s3);
2880 M_CMOVEQ(s1, REG_ITMP2, d);
2882 store_reg_to_var_int(iptr->dst, d);
2885 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2886 /* val.i = constant */
2888 var_to_reg_int(s1, src, REG_ITMP1);
2889 d = reg_of_var(iptr->dst, REG_ITMP3);
2891 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2892 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2893 M_CMPEQ(s1, REG_ZERO, d);
2894 store_reg_to_var_int(iptr->dst, d);
2897 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2898 M_CMPEQ(s1, REG_ZERO, d);
2900 store_reg_to_var_int(iptr->dst, d);
2904 M_MOV(s1, REG_ITMP1);
2907 ICONST(d, iptr[1].val.i);
2909 if ((s3 >= 0) && (s3 <= 255)) {
2910 M_CMOVNE_IMM(s1, s3, d);
2913 ICONST(REG_ITMP2, s3);
2914 M_CMOVNE(s1, REG_ITMP2, d);
2916 store_reg_to_var_int(iptr->dst, d);
2919 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2920 /* val.i = constant */
2922 var_to_reg_int(s1, src, REG_ITMP1);
2923 d = reg_of_var(iptr->dst, REG_ITMP3);
2925 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2926 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2927 M_CMPLT(s1, REG_ZERO, d);
2928 store_reg_to_var_int(iptr->dst, d);
2931 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2932 M_CMPLE(REG_ZERO, s1, d);
2933 store_reg_to_var_int(iptr->dst, d);
2937 M_MOV(s1, REG_ITMP1);
2940 ICONST(d, iptr[1].val.i);
2942 if ((s3 >= 0) && (s3 <= 255)) {
2943 M_CMOVLT_IMM(s1, s3, d);
2946 ICONST(REG_ITMP2, s3);
2947 M_CMOVLT(s1, REG_ITMP2, d);
2949 store_reg_to_var_int(iptr->dst, d);
2952 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2953 /* val.i = constant */
2955 var_to_reg_int(s1, src, REG_ITMP1);
2956 d = reg_of_var(iptr->dst, REG_ITMP3);
2958 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2959 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2960 M_CMPLE(REG_ZERO, s1, d);
2961 store_reg_to_var_int(iptr->dst, d);
2964 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2965 M_CMPLT(s1, REG_ZERO, d);
2966 store_reg_to_var_int(iptr->dst, d);
2970 M_MOV(s1, REG_ITMP1);
2973 ICONST(d, iptr[1].val.i);
2975 if ((s3 >= 0) && (s3 <= 255)) {
2976 M_CMOVGE_IMM(s1, s3, d);
2979 ICONST(REG_ITMP2, s3);
2980 M_CMOVGE(s1, REG_ITMP2, d);
2982 store_reg_to_var_int(iptr->dst, d);
2985 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2986 /* val.i = constant */
2988 var_to_reg_int(s1, src, REG_ITMP1);
2989 d = reg_of_var(iptr->dst, REG_ITMP3);
2991 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2992 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2993 M_CMPLT(REG_ZERO, s1, d);
2994 store_reg_to_var_int(iptr->dst, d);
2997 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2998 M_CMPLE(s1, REG_ZERO, d);
2999 store_reg_to_var_int(iptr->dst, d);
3003 M_MOV(s1, REG_ITMP1);
3006 ICONST(d, iptr[1].val.i);
3008 if ((s3 >= 0) && (s3 <= 255)) {
3009 M_CMOVGT_IMM(s1, s3, d);
3012 ICONST(REG_ITMP2, s3);
3013 M_CMOVGT(s1, REG_ITMP2, d);
3015 store_reg_to_var_int(iptr->dst, d);
3018 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
3019 /* val.i = constant */
3021 var_to_reg_int(s1, src, REG_ITMP1);
3022 d = reg_of_var(iptr->dst, REG_ITMP3);
3024 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
3025 if ((s3 == 1) && (iptr[1].val.i == 0)) {
3026 M_CMPLE(s1, REG_ZERO, d);
3027 store_reg_to_var_int(iptr->dst, d);
3030 if ((s3 == 0) && (iptr[1].val.i == 1)) {
3031 M_CMPLT(REG_ZERO, s1, d);
3032 store_reg_to_var_int(iptr->dst, d);
3036 M_MOV(s1, REG_ITMP1);
3039 ICONST(d, iptr[1].val.i);
3041 if ((s3 >= 0) && (s3 <= 255)) {
3042 M_CMOVLE_IMM(s1, s3, d);
3045 ICONST(REG_ITMP2, s3);
3046 M_CMOVLE(s1, REG_ITMP2, d);
3048 store_reg_to_var_int(iptr->dst, d);
3052 case ICMD_IRETURN: /* ..., retvalue ==> ... */
3056 var_to_reg_int(s1, src, REG_RESULT);
3057 M_INTMOVE(s1, REG_RESULT);
3060 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3062 a = dseg_addaddress((void *) (builtin_monitorexit));
3063 M_ALD(REG_PV, REG_PV, a);
3064 M_ALD(argintregs[0], REG_SP, maxmemuse * 8);
3065 M_LST(REG_RESULT, REG_SP, maxmemuse * 8);
3066 M_JSR(REG_RA, REG_PV);
3067 disp = -(int) ((u1 *) mcodeptr - mcodebase);
3068 M_LDA(REG_PV, REG_RA, disp);
3069 M_LLD(REG_RESULT, REG_SP, maxmemuse * 8);
3073 goto nowperformreturn;
3075 case ICMD_FRETURN: /* ..., retvalue ==> ... */
3078 var_to_reg_flt(s1, src, REG_FRESULT);
3079 M_FLTMOVE(s1, REG_FRESULT);
3082 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3084 a = dseg_addaddress((void *) (builtin_monitorexit));
3085 M_ALD(REG_PV, REG_PV, a);
3086 M_ALD(argintregs[0], REG_SP, maxmemuse * 8);
3087 M_DST(REG_FRESULT, REG_SP, maxmemuse * 8);
3088 M_JSR(REG_RA, REG_PV);
3089 disp = -(int) ((u1 *) mcodeptr - mcodebase);
3090 M_LDA(REG_PV, REG_RA, disp);
3091 M_DLD(REG_FRESULT, REG_SP, maxmemuse * 8);
3095 goto nowperformreturn;
3097 case ICMD_RETURN: /* ... ==> ... */
3100 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3102 a = dseg_addaddress((void *) (builtin_monitorexit));
3103 M_ALD(REG_PV, REG_PV, a);
3104 M_ALD(argintregs[0], REG_SP, maxmemuse * 8);
3105 M_JSR(REG_RA, REG_PV);
3106 disp = -(int) ((u1 *) mcodeptr - mcodebase);
3107 M_LDA(REG_PV, REG_RA, disp);
3115 p = parentargs_base;
3117 /* restore return address */
3120 {p--; M_LLD (REG_RA, REG_SP, 8 * p);}
3122 /* restore saved registers */
3124 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
3125 {p--; M_LLD(savintregs[r], REG_SP, 8 * p);}
3126 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
3127 {p--; M_DLD(savfltregs[r], REG_SP, 8 * p);}
3129 /* deallocate stack */
3131 if (parentargs_base)
3132 {M_LDA(REG_SP, REG_SP, parentargs_base*8);}
3134 /* call trace function */
3137 M_LDA(REG_SP, REG_SP, -3 * 8);
3138 M_AST(REG_RA, REG_SP, 0 * 8);
3139 M_LST(REG_RESULT, REG_SP, 1 * 8);
3140 M_DST(REG_FRESULT, REG_SP, 2 * 8);
3141 a = dseg_addaddress(method);
3142 M_ALD(argintregs[0], REG_PV, a);
3143 M_MOV(REG_RESULT, argintregs[1]);
3144 M_FLTMOVE(REG_FRESULT, argfltregs[2]);
3145 M_FLTMOVE(REG_FRESULT, argfltregs[3]);
3146 a = dseg_addaddress((void *) builtin_displaymethodstop);
3147 M_ALD(REG_PV, REG_PV, a);
3148 M_JSR(REG_RA, REG_PV);
3149 s1 = (int) ((u1 *) mcodeptr - mcodebase);
3150 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3152 s4 ml = -s1, mh = 0;
3153 while (ml < -32768) { ml += 65536; mh--; }
3154 M_LDA(REG_PV, REG_RA, ml);
3155 M_LDAH(REG_PV, REG_PV, mh);
3157 M_DLD(REG_FRESULT, REG_SP, 2 * 8);
3158 M_LLD(REG_RESULT, REG_SP, 1 * 8);
3159 M_ALD(REG_RA, REG_SP, 0 * 8);
3160 M_LDA(REG_SP, REG_SP, 3 * 8);
3163 M_RET(REG_ZERO, REG_RA);
3169 case ICMD_TABLESWITCH: /* ..., index ==> ... */
3174 tptr = (void **) iptr->target;
3176 s4ptr = iptr->val.a;
3177 l = s4ptr[1]; /* low */
3178 i = s4ptr[2]; /* high */
3180 var_to_reg_int(s1, src, REG_ITMP1);
3182 {M_INTMOVE(s1, REG_ITMP1);}
3183 else if (l <= 32768) {
3184 M_LDA(REG_ITMP1, s1, -l);
3187 ICONST(REG_ITMP2, l);
3188 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
3195 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
3197 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
3198 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3200 M_BEQZ(REG_ITMP2, 0);
3203 /* codegen_addreference(BlockPtrOfPC(s4ptr[0]), mcodeptr); */
3204 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3206 /* build jump table top down and use address of lowest entry */
3208 /* s4ptr += 3 + i; */
3212 /* dseg_addtarget(BlockPtrOfPC(*--s4ptr)); */
3213 dseg_addtarget((basicblock *) tptr[0]);
3218 /* length of dataseg after last dseg_addtarget is used by load */
3220 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
3221 M_ALD(REG_ITMP2, REG_ITMP2, -dseglen);
3222 M_JMP(REG_ZERO, REG_ITMP2);
3227 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3229 s4 i, l, val, *s4ptr;
3232 tptr = (void **) iptr->target;
3234 s4ptr = iptr->val.a;
3235 l = s4ptr[0]; /* default */
3236 i = s4ptr[1]; /* count */
3238 MCODECHECK((i<<2)+8);
3239 var_to_reg_int(s1, src, REG_ITMP1);
3245 if ((val >= 0) && (val <= 255)) {
3246 M_CMPEQ_IMM(s1, val, REG_ITMP2);
3249 if ((val >= -32768) && (val <= 32767)) {
3250 M_LDA(REG_ITMP2, REG_ZERO, val);
3253 a = dseg_adds4 (val);
3254 M_ILD(REG_ITMP2, REG_PV, a);
3256 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
3258 M_BNEZ(REG_ITMP2, 0);
3259 /* codegen_addreference(BlockPtrOfPC(s4ptr[1]), mcodeptr); */
3260 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3264 /* codegen_addreference(BlockPtrOfPC(l), mcodeptr); */
3266 tptr = (void **) iptr->target;
3267 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3274 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
3275 /* op1 = return type, val.a = function pointer*/
3279 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
3280 /* op1 = return type, val.a = function pointer*/
3284 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
3285 /* op1 = return type, val.a = function pointer*/
3289 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3290 /* op1 = arg count, val.a = method pointer */
3292 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3293 /* op1 = arg count, val.a = method pointer */
3295 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3296 /* op1 = arg count, val.a = method pointer */
3298 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
3299 /* op1 = arg count, val.a = method pointer */
3307 MCODECHECK((s3 << 1) + 64);
3309 /* copy arguments to registers or stack location */
3311 for (; --s3 >= 0; src = src->prev) {
3312 if (src->varkind == ARGVAR)
3314 if (IS_INT_LNG_TYPE(src->type)) {
3315 if (s3 < INT_ARG_CNT) {
3316 s1 = argintregs[s3];
3317 var_to_reg_int(d, src, s1);
3321 var_to_reg_int(d, src, REG_ITMP1);
3322 M_LST(d, REG_SP, 8 * (s3 - INT_ARG_CNT));
3326 if (s3 < FLT_ARG_CNT) {
3327 s1 = argfltregs[s3];
3328 var_to_reg_flt(d, src, s1);
3332 var_to_reg_flt(d, src, REG_FTMP1);
3333 M_DST(d, REG_SP, 8 * (s3 - FLT_ARG_CNT));
3338 switch (iptr->opc) {
3342 a = dseg_addaddress ((void*) (m));
3344 M_ALD(REG_PV, REG_PV, a); /* Pointer to built-in-function */
3346 goto makeactualcall;
3348 case ICMD_INVOKESTATIC:
3349 case ICMD_INVOKESPECIAL:
3350 a = dseg_addaddress (m->stubroutine);
3352 M_ALD(REG_PV, REG_PV, a ); /* method pointer in r27 */
3355 goto makeactualcall;
3357 case ICMD_INVOKEVIRTUAL:
3359 gen_nullptr_check(argintregs[0]);
3360 M_ALD(REG_METHODPTR, argintregs[0],
3361 OFFSET(java_objectheader, vftbl));
3362 M_ALD(REG_PV, REG_METHODPTR, OFFSET(vftbl, table[0]) +
3363 sizeof(methodptr) * m->vftblindex);
3366 goto makeactualcall;
3368 case ICMD_INVOKEINTERFACE:
3371 gen_nullptr_check(argintregs[0]);
3372 M_ALD(REG_METHODPTR, argintregs[0],
3373 OFFSET(java_objectheader, vftbl));
3374 M_ALD(REG_METHODPTR, REG_METHODPTR,
3375 OFFSET(vftbl, interfacetable[0]) -
3376 sizeof(methodptr*) * ci->index);
3377 M_ALD(REG_PV, REG_METHODPTR,
3378 sizeof(methodptr) * (m - ci->methods));
3381 goto makeactualcall;
3385 error ("Unkown ICMD-Command: %d", iptr->opc);
3390 M_JSR (REG_RA, REG_PV);
3394 s1 = (int)((u1*) mcodeptr - mcodebase);
3395 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
3398 while (ml<-32768) { ml+=65536; mh--; }
3399 M_LDA (REG_PV, REG_RA, ml );
3400 M_LDAH (REG_PV, REG_PV, mh );
3403 /* d contains return type */
3405 if (d != TYPE_VOID) {
3406 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3407 s1 = reg_of_var(iptr->dst, REG_RESULT);
3408 M_INTMOVE(REG_RESULT, s1);
3409 store_reg_to_var_int(iptr->dst, s1);
3412 s1 = reg_of_var(iptr->dst, REG_FRESULT);
3413 M_FLTMOVE(REG_FRESULT, s1);
3414 store_reg_to_var_flt(iptr->dst, s1);
3421 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3423 /* op1: 0 == array, 1 == class */
3424 /* val.a: (classinfo*) superclass */
3426 /* superclass is an interface:
3428 * return (sub != NULL) &&
3429 * (sub->vftbl->interfacetablelength > super->index) &&
3430 * (sub->vftbl->interfacetable[-super->index] != NULL);
3432 * superclass is a class:
3434 * return ((sub != NULL) && (0
3435 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3436 * super->vftbl->diffvall));
3440 classinfo *super = (classinfo*) iptr->val.a;
3442 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3443 codegen_threadcritrestart((u1*) mcodeptr - mcodebase);
3445 var_to_reg_int(s1, src, REG_ITMP1);
3446 d = reg_of_var(iptr->dst, REG_ITMP3);
3448 M_MOV(s1, REG_ITMP1);
3452 if (iptr->op1) { /* class/interface */
3453 if (super->flags & ACC_INTERFACE) { /* interface */
3455 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3456 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3457 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3458 M_BLEZ(REG_ITMP2, 2);
3459 M_ALD(REG_ITMP1, REG_ITMP1,
3460 OFFSET(vftbl, interfacetable[0]) -
3461 super->index * sizeof(methodptr*));
3462 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3466 s2 = super->vftbl->diffval;
3467 M_BEQZ(s1, 4 + (s2 > 255));
3468 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3469 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3470 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3472 M_CMPULE_IMM(REG_ITMP1, s2, d);
3474 M_LDA(REG_ITMP2, REG_ZERO, s2);
3475 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3479 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3480 a = dseg_addaddress ((void*) super->vftbl);
3481 M_ALD(REG_ITMP2, REG_PV, a);
3482 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3483 codegen_threadcritstart((u1*) mcodeptr - mcodebase);
3485 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3486 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl, baseval));
3487 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, diffval));
3488 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3489 codegen_threadcritstop((u1*) mcodeptr - mcodebase);
3491 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3492 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3496 panic ("internal error: no inlined array instanceof");
3498 store_reg_to_var_int(iptr->dst, d);
3501 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3503 /* op1: 0 == array, 1 == class */
3504 /* val.a: (classinfo*) superclass */
3506 /* superclass is an interface:
3508 * OK if ((sub == NULL) ||
3509 * (sub->vftbl->interfacetablelength > super->index) &&
3510 * (sub->vftbl->interfacetable[-super->index] != NULL));
3512 * superclass is a class:
3514 * OK if ((sub == NULL) || (0
3515 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3516 * super->vftbl->diffvall));
3520 classinfo *super = (classinfo*) iptr->val.a;
3522 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3523 codegen_threadcritrestart((u1*) mcodeptr - mcodebase);
3525 d = reg_of_var(iptr->dst, REG_ITMP3);
3526 var_to_reg_int(s1, src, d);
3527 if (iptr->op1) { /* class/interface */
3528 if (super->flags & ACC_INTERFACE) { /* interface */
3530 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3531 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3532 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3533 M_BLEZ(REG_ITMP2, 0);
3534 codegen_addxcastrefs(mcodeptr);
3535 M_ALD(REG_ITMP2, REG_ITMP1,
3536 OFFSET(vftbl, interfacetable[0]) -
3537 super->index * sizeof(methodptr*));
3538 M_BEQZ(REG_ITMP2, 0);
3539 codegen_addxcastrefs(mcodeptr);
3543 s2 = super->vftbl->diffval;
3544 M_BEQZ(s1, 4 + (s2 != 0) + (s2 > 255));
3545 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3546 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3547 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3549 M_BNEZ(REG_ITMP1, 0);
3551 else if (s2 <= 255) {
3552 M_CMPULE_IMM(REG_ITMP1, s2, REG_ITMP2);
3553 M_BEQZ(REG_ITMP2, 0);
3556 M_LDA(REG_ITMP2, REG_ZERO, s2);
3557 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3558 M_BEQZ(REG_ITMP2, 0);
3561 M_BEQZ(s1, 8 + (d == REG_ITMP3));
3562 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3563 a = dseg_addaddress ((void*) super->vftbl);
3564 M_ALD(REG_ITMP2, REG_PV, a);
3565 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3566 codegen_threadcritstart((u1*) mcodeptr - mcodebase);
3568 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3569 if (d != REG_ITMP3) {
3570 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl, baseval));
3571 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, diffval));
3572 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3573 codegen_threadcritstop((u1*) mcodeptr - mcodebase);
3575 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3578 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, baseval));
3579 M_ISUB(REG_ITMP1, REG_ITMP2, REG_ITMP1);
3580 M_ALD(REG_ITMP2, REG_PV, a);
3581 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, diffval));
3582 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3583 codegen_threadcritstop((u1*) mcodeptr - mcodebase);
3586 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3587 M_BEQZ(REG_ITMP2, 0);
3588 codegen_addxcastrefs(mcodeptr);
3592 panic ("internal error: no inlined array checkcast");
3595 store_reg_to_var_int(iptr->dst, d);
3598 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
3600 var_to_reg_int(s1, src, REG_ITMP1);
3602 codegen_addxcheckarefs(mcodeptr);
3605 case ICMD_CHECKOOM: /* ... ==> ... */
3607 M_BEQZ(REG_RESULT, 0);
3608 codegen_addxoomrefs(mcodeptr);
3611 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3612 /* op1 = dimension, val.a = array descriptor */
3614 /* check for negative sizes and copy sizes to stack if necessary */
3616 MCODECHECK((iptr->op1 << 1) + 64);
3618 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3619 var_to_reg_int(s2, src, REG_ITMP1);
3621 codegen_addxcheckarefs(mcodeptr);
3623 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
3625 if (src->varkind != ARGVAR) {
3626 M_LST(s2, REG_SP, 8 * (s1 + INT_ARG_CNT));
3630 /* a0 = dimension count */
3632 ICONST(argintregs[0], iptr->op1);
3634 /* a1 = arraydescriptor */
3636 a = dseg_addaddress(iptr->val.a);
3637 M_ALD(argintregs[1], REG_PV, a);
3639 /* a2 = pointer to dimensions = stack pointer */
3641 M_INTMOVE(REG_SP, argintregs[2]);
3643 a = dseg_addaddress((void*) (builtin_nmultianewarray));
3644 M_ALD(REG_PV, REG_PV, a);
3645 M_JSR(REG_RA, REG_PV);
3646 s1 = (int)((u1*) mcodeptr - mcodebase);
3648 M_LDA (REG_PV, REG_RA, -s1);
3650 s4 ml = -s1, mh = 0;
3651 while (ml < -32768) {ml += 65536; mh--;}
3652 M_LDA(REG_PV, REG_RA, ml);
3653 M_LDAH(REG_PV, REG_PV, mh);
3655 s1 = reg_of_var(iptr->dst, REG_RESULT);
3656 M_INTMOVE(REG_RESULT, s1);
3657 store_reg_to_var_int(iptr->dst, s1);
3661 default: error ("Unknown pseudo command: %d", iptr->opc);
3667 } /* for instruction */
3669 /* copy values to interface registers */
3671 src = bptr->outstack;
3672 len = bptr->outdepth;
3676 if ((src->varkind != STACKVAR)) {
3678 if (IS_FLT_DBL_TYPE(s2)) {
3679 var_to_reg_flt(s1, src, REG_FTMP1);
3680 if (!(interfaces[len][s2].flags & INMEMORY)) {
3681 M_FLTMOVE(s1,interfaces[len][s2].regoff);
3684 M_DST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3688 var_to_reg_int(s1, src, REG_ITMP1);
3689 if (!(interfaces[len][s2].flags & INMEMORY)) {
3690 M_INTMOVE(s1,interfaces[len][s2].regoff);
3693 M_LST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3699 } /* if (bptr -> flags >= BBREACHED) */
3700 } /* for basic block */
3702 /* bptr -> mpc = (int)((u1*) mcodeptr - mcodebase); */
3705 /* generate bound check stubs */
3707 s4 *xcodeptr = NULL;
3709 for (; xboundrefs != NULL; xboundrefs = xboundrefs->next) {
3710 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3711 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
3712 xboundrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - (4 + 4));
3717 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
3718 xboundrefs->branchpos, (u1*) mcodeptr - mcodebase);
3722 M_MOV(xboundrefs->reg, REG_ITMP1);
3723 M_LDA(REG_ITMP2_XPC, REG_PV, xboundrefs->branchpos - 4);
3725 if (xcodeptr != NULL) {
3726 M_BR(xcodeptr - mcodeptr - 1);
3729 xcodeptr = mcodeptr;
3731 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3732 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3734 a = dseg_addaddress(string_java_lang_ArrayIndexOutOfBoundsException);
3735 M_ALD(argintregs[0], REG_PV, a);
3736 M_MOV(REG_ITMP1, argintregs[1]);
3738 a = dseg_addaddress(new_exception_int);
3739 M_ALD(REG_PV, REG_PV, a);
3740 M_JSR(REG_RA, REG_PV);
3743 s1 = (s4) ((u1 *) mcodeptr - mcodebase);
3744 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3746 s4 ml = -s1, mh = 0;
3747 while (ml < -32768) { ml += 65536; mh--; }
3748 M_LDA(REG_PV, REG_RA, ml);
3749 M_LDAH(REG_PV, REG_PV, mh);
3752 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3754 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3755 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3757 a = dseg_addaddress(asm_handle_exception);
3758 M_ALD(REG_ITMP3, REG_PV, a);
3760 M_JMP(REG_ZERO, REG_ITMP3);
3764 /* generate negative array size check stubs */
3768 for (; xcheckarefs != NULL; xcheckarefs = xcheckarefs->next) {
3769 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3770 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3771 xcheckarefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3775 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3776 xcheckarefs->branchpos, (u1*) mcodeptr - mcodebase);
3780 M_LDA(REG_ITMP2_XPC, REG_PV, xcheckarefs->branchpos - 4);
3782 if (xcodeptr != NULL) {
3783 M_BR(xcodeptr - mcodeptr - 1);
3786 xcodeptr = mcodeptr;
3788 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3789 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3791 a = dseg_addaddress(string_java_lang_NegativeArraySizeException);
3792 M_ALD(argintregs[0], REG_PV, a);
3794 a = dseg_addaddress(new_exception);
3795 M_ALD(REG_PV, REG_PV, a);
3796 M_JSR(REG_RA, REG_PV);
3799 s1 = (s4) ((u1 *) mcodeptr - mcodebase);
3800 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3802 s4 ml = -s1, mh = 0;
3803 while (ml < -32768) { ml += 65536; mh--; }
3804 M_LDA(REG_PV, REG_RA, ml);
3805 M_LDAH(REG_PV, REG_PV, mh);
3808 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3810 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3811 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3813 a = dseg_addaddress(asm_handle_exception);
3814 M_ALD(REG_ITMP3, REG_PV, a);
3816 M_JMP(REG_ZERO, REG_ITMP3);
3820 /* generate cast check stubs */
3824 for (; xcastrefs != NULL; xcastrefs = xcastrefs->next) {
3825 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3826 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3827 xcastrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3831 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3832 xcastrefs->branchpos, (u1*) mcodeptr - mcodebase);
3836 M_LDA(REG_ITMP2_XPC, REG_PV, xcastrefs->branchpos - 4);
3838 if (xcodeptr != NULL) {
3839 M_BR(xcodeptr - mcodeptr - 1);
3842 xcodeptr = mcodeptr;
3844 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3845 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3847 a = dseg_addaddress(string_java_lang_ClassCastException);
3848 M_ALD(argintregs[0], REG_PV, a);
3850 a = dseg_addaddress(new_exception);
3851 M_ALD(REG_PV, REG_PV, a);
3852 M_JSR(REG_RA, REG_PV);
3855 s1 = (s4) ((u1 *) mcodeptr - mcodebase);
3856 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3858 s4 ml = -s1, mh = 0;
3859 while (ml < -32768) { ml += 65536; mh--; }
3860 M_LDA(REG_PV, REG_RA, ml);
3861 M_LDAH(REG_PV, REG_PV, mh);
3864 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3866 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3867 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3869 a = dseg_addaddress(asm_handle_exception);
3870 M_ALD(REG_ITMP3, REG_PV, a);
3872 M_JMP(REG_ZERO, REG_ITMP3);
3876 /* generate oom check stubs */
3880 for (; xoomrefs != NULL; xoomrefs = xoomrefs->next) {
3881 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3882 gen_resolvebranch((u1*) mcodebase + xoomrefs->branchpos,
3883 xoomrefs->branchpos,
3884 (u1*) xcodeptr - (u1*) mcodebase - 4);
3888 gen_resolvebranch((u1*) mcodebase + xoomrefs->branchpos,
3889 xoomrefs->branchpos, (u1*) mcodeptr - mcodebase);
3893 M_LDA(REG_ITMP2_XPC, REG_PV, xoomrefs->branchpos - 4);
3895 if (xcodeptr != NULL) {
3896 M_BR(xcodeptr - mcodeptr - 1);
3899 xcodeptr = mcodeptr;
3901 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3902 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3903 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3905 a = dseg_addaddress(&builtin_get_exceptionptrptr);
3906 M_ALD(REG_PV, REG_PV, a);
3907 M_JSR(REG_RA, REG_PV);
3910 s1 = (s4) ((u1 *) mcodeptr - mcodebase);
3911 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3913 s4 ml = -s1, mh = 0;
3914 while (ml < -32768) { ml += 65536; mh--; }
3915 M_LDA(REG_PV, REG_RA, ml);
3916 M_LDAH(REG_PV, REG_PV, mh);
3919 M_ALD(REG_ITMP1_XPTR, REG_RESULT, 0);
3920 M_AST(REG_ZERO, REG_RESULT, 0);
3922 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3923 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3925 a = dseg_addaddress(&_exceptionptr);
3926 M_ALD(REG_ITMP3, REG_PV, a);
3927 M_ALD(REG_ITMP1_XPTR, REG_ITMP3, 0);
3928 M_AST(REG_ZERO, REG_ITMP3, 0);
3931 a = dseg_addaddress(asm_handle_exception);
3932 M_ALD(REG_ITMP3, REG_PV, a);
3934 M_JMP(REG_ZERO, REG_ITMP3);
3938 /* generate null pointer check stubs */
3942 for (; xnullrefs != NULL; xnullrefs = xnullrefs->next) {
3943 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3944 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3945 xnullrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3949 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3950 xnullrefs->branchpos, (u1*) mcodeptr - mcodebase);
3954 M_LDA(REG_ITMP2_XPC, REG_PV, xnullrefs->branchpos - 4);
3956 if (xcodeptr != NULL) {
3957 M_BR(xcodeptr - mcodeptr - 1);
3960 xcodeptr = mcodeptr;
3962 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3963 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3965 a = dseg_addaddress(string_java_lang_NullPointerException);
3966 M_ALD(argintregs[0], REG_PV, a);
3968 a = dseg_addaddress(new_exception);
3969 M_ALD(REG_PV, REG_PV, a);
3970 M_JSR(REG_RA, REG_PV);
3973 s1 = (s4) ((u1 *) mcodeptr - mcodebase);
3974 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3976 s4 ml = -s1, mh = 0;
3977 while (ml < -32768) { ml += 65536; mh--; }
3978 M_LDA(REG_PV, REG_RA, ml);
3979 M_LDAH(REG_PV, REG_PV, mh);
3982 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3984 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3985 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3987 a = dseg_addaddress(asm_handle_exception);
3988 M_ALD(REG_ITMP3, REG_PV, a);
3990 M_JMP(REG_ZERO, REG_ITMP3);
3995 codegen_finish((int)((u1*) mcodeptr - mcodebase));
3997 if (compileverbose) {
3998 char logtext[MAXLOGTEXT];
3999 sprintf(logtext, "Generating code done: ");
4000 utf_sprint_classname(logtext + strlen(logtext), class->name);
4001 sprintf(logtext + strlen(logtext), ".");
4002 utf_sprint(logtext + strlen(logtext), method->name);
4003 utf_sprint_classname(logtext + strlen(logtext), descriptor);
4009 /* function createcompilerstub *************************************************
4011 creates a stub routine which calls the compiler
4013 *******************************************************************************/
4015 #define COMPSTUBSIZE 3
4017 u1 *createcompilerstub(methodinfo *m)
4019 u8 *s = CNEW(u8, COMPSTUBSIZE); /* memory to hold the stub */
4020 s4 *mcodeptr = (s4 *) s; /* code generation pointer */
4022 /* code for the stub */
4023 M_ALD(REG_PV, REG_PV, 16); /* load pointer to the compiler */
4024 M_JMP(0, REG_PV); /* jump to the compiler, return address
4025 in reg 0 is used as method pointer */
4026 s[1] = (u8) m; /* literals to be adressed */
4027 s[2] = (u8) asm_call_jit_compiler; /* jump directly via PV from above */
4030 count_cstub_len += COMPSTUBSIZE * 8;
4037 /* function removecompilerstub *************************************************
4039 deletes a compilerstub from memory (simply by freeing it)
4041 *******************************************************************************/
4043 void removecompilerstub(u1 *stub)
4045 CFREE(stub, COMPSTUBSIZE * 8);
4049 /* function: createnativestub **************************************************
4051 creates a stub routine which calls a native method
4053 *******************************************************************************/
4055 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4056 #define NATIVESTUBSTACK 2
4057 #define NATIVESTUBTHREADEXTRA 5
4059 #define NATIVESTUBSTACK 1
4060 #define NATIVESTUBTHREADEXTRA 0
4063 #define NATIVESTUBSIZE (44 + NATIVESTUBTHREADEXTRA)
4064 #define NATIVESTATICSIZE 5
4065 #define NATIVEVERBOSESIZE (39 + 13)
4066 #define NATIVESTUBOFFSET 9
4068 u1 *createnativestub(functionptr f, methodinfo *m)
4070 u8 *s; /* memory pointer to hold the stub */
4072 s4 *mcodeptr; /* code generation pointer */
4073 s4 stackframesize = 0; /* size of stackframe if needed */
4078 descriptor2types(m); /* set paramcount and paramtypes */
4080 stubsize = NATIVESTUBSIZE; /* calculate nativestub size */
4081 if ((m->flags & ACC_STATIC) && !m->class->initialized)
4082 stubsize += NATIVESTATICSIZE;
4085 stubsize += NATIVEVERBOSESIZE;
4087 s = CNEW(u8, stubsize); /* memory to hold the stub */
4088 cs = s + NATIVESTUBOFFSET;
4089 mcodeptr = (s4 *) (cs); /* code generation pointer */
4091 *(cs-1) = (u8) f; /* address of native method */
4092 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4093 *(cs-2) = (u8) &builtin_get_exceptionptrptr;
4095 *(cs-2) = (u8) (&_exceptionptr); /* address of exceptionptr */
4097 *(cs-3) = (u8) asm_handle_nat_exception; /* addr of asm exception handler */
4098 *(cs-4) = (u8) (&env); /* addr of jni_environement */
4099 *(cs-5) = (u8) builtin_trace_args;
4101 *(cs-7) = (u8) builtin_displaymethodstop;
4102 *(cs-8) = (u8) m->class;
4103 *(cs-9) = (u8) asm_check_clinit;
4105 M_LDA(REG_SP, REG_SP, -NATIVESTUBSTACK * 8); /* build up stackframe */
4106 M_AST(REG_RA, REG_SP, 0 * 8); /* store return address */
4108 /* if function is static, check for initialized */
4110 if (m->flags & ACC_STATIC) {
4111 /* if class isn't yet initialized, do it */
4112 if (!m->class->initialized) {
4113 /* call helper function which patches this code */
4114 M_ALD(REG_ITMP1, REG_PV, -8 * 8); /* class */
4115 M_ALD(REG_PV, REG_PV, -9 * 8); /* asm_check_clinit */
4116 M_JSR(REG_RA, REG_PV);
4117 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4118 M_LDA(REG_PV, REG_RA, disp);
4119 M_NOP; /* this is essential for code patching */
4123 /* max. 39 instructions */
4127 M_LDA(REG_SP, REG_SP, -((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
4128 M_AST(REG_RA, REG_SP, 1 * 8);
4130 /* save integer argument registers */
4131 for (p = 0; p < m->paramcount && p < INT_ARG_CNT; p++) {
4132 M_LST(argintregs[p], REG_SP, (2 + p) * 8);
4135 /* save and copy float arguments into integer registers */
4136 for (p = 0; p < m->paramcount && p < FLT_ARG_CNT; p++) {
4137 t = m->paramtypes[p];
4139 if (IS_FLT_DBL_TYPE(t)) {
4140 if (IS_2_WORD_TYPE(t)) {
4141 M_DST(argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4142 M_LLD(argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4145 M_FST(argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4146 M_ILD(argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4150 M_DST(argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4154 M_ALD(REG_ITMP1, REG_PV, -6 * 8);
4155 M_AST(REG_ITMP1, REG_SP, 0 * 8);
4156 M_ALD(REG_PV, REG_PV, -5 * 8);
4157 M_JSR(REG_RA, REG_PV);
4158 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4159 M_LDA(REG_PV, REG_RA, disp);
4161 for (p = 0; p < m->paramcount && p < INT_ARG_CNT; p++) {
4162 M_LLD(argintregs[p], REG_SP, (2 + p) * 8);
4165 for (p = 0; p < m->paramcount && p < FLT_ARG_CNT; p++) {
4166 t = m->paramtypes[p];
4168 if (IS_FLT_DBL_TYPE(t)) {
4169 if (IS_2_WORD_TYPE(t)) {
4170 M_DLD(argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4173 M_FLD(argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4177 M_DLD(argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4181 M_ALD(REG_RA, REG_SP, 1 * 8);
4182 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT + 2) * 8);
4185 /* save argument registers on stack -- if we have to */
4186 if ((m->flags & ACC_STATIC && m->paramcount > (INT_ARG_CNT - 2)) || m->paramcount > (INT_ARG_CNT - 1)) {
4188 s4 paramshiftcnt = (m->flags & ACC_STATIC) ? 2 : 1;
4189 s4 stackparamcnt = (m->paramcount > INT_ARG_CNT) ? m->paramcount - INT_ARG_CNT : 0;
4191 stackframesize = stackparamcnt + paramshiftcnt;
4193 M_LDA(REG_SP, REG_SP, -stackframesize * 8);
4195 /* copy stack arguments into new stack frame -- if any */
4196 for (i = 0; i < stackparamcnt; i++) {
4197 M_LLD(REG_ITMP1, REG_SP, (stackparamcnt + 1 + i) * 8);
4198 M_LST(REG_ITMP1, REG_SP, (paramshiftcnt + i) * 8);
4201 if (m->flags & ACC_STATIC) {
4202 if (IS_FLT_DBL_TYPE(m->paramtypes[5])) {
4203 M_DST(argfltregs[5], REG_SP, 1 * 8);
4205 M_LST(argintregs[5], REG_SP, 1 * 8);
4208 if (IS_FLT_DBL_TYPE(m->paramtypes[4])) {
4209 M_DST(argfltregs[4], REG_SP, 0 * 8);
4211 M_LST(argintregs[4], REG_SP, 0 * 8);
4215 if (IS_FLT_DBL_TYPE(m->paramtypes[5])) {
4216 M_DST(argfltregs[5], REG_SP, 0 * 8);
4218 M_LST(argintregs[5], REG_SP, 0 * 8);
4223 if (m->flags & ACC_STATIC) {
4224 M_MOV(argintregs[3], argintregs[5]);
4225 M_MOV(argintregs[2], argintregs[4]);
4226 M_MOV(argintregs[1], argintregs[3]);
4227 M_MOV(argintregs[0], argintregs[2]);
4228 M_FMOV(argfltregs[3], argfltregs[5]);
4229 M_FMOV(argfltregs[2], argfltregs[4]);
4230 M_FMOV(argfltregs[1], argfltregs[3]);
4231 M_FMOV(argfltregs[0], argfltregs[2]);
4233 /* put class into second argument register */
4234 M_ALD(argintregs[1], REG_PV, -8 * 8);
4237 M_MOV(argintregs[4], argintregs[5]);
4238 M_MOV(argintregs[3], argintregs[4]);
4239 M_MOV(argintregs[2], argintregs[3]);
4240 M_MOV(argintregs[1], argintregs[2]);
4241 M_MOV(argintregs[0], argintregs[1]);
4242 M_FMOV(argfltregs[4], argfltregs[5]);
4243 M_FMOV(argfltregs[3], argfltregs[4]);
4244 M_FMOV(argfltregs[2], argfltregs[3]);
4245 M_FMOV(argfltregs[1], argfltregs[2]);
4246 M_FMOV(argfltregs[0], argfltregs[1]);
4249 /* put env into first argument register */
4250 M_ALD(argintregs[0], REG_PV, -4 * 8);
4252 M_ALD(REG_PV, REG_PV, -1 * 8); /* load adress of native method */
4253 M_JSR(REG_RA, REG_PV); /* call native method */
4254 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4255 M_LDA(REG_PV, REG_RA, disp); /* recompute pv from ra */
4257 /* remove stackframe if there is one */
4258 if (stackframesize) {
4259 M_LDA(REG_SP, REG_SP, stackframesize * 8);
4262 /* 13 instructions */
4264 M_LDA(REG_SP, REG_SP, -2 * 8);
4265 M_ALD(argintregs[0], REG_PV, -6 * 8); /* load method adress */
4266 M_LST(REG_RESULT, REG_SP, 0 * 8);
4267 M_DST(REG_FRESULT, REG_SP, 1 * 8);
4268 M_MOV(REG_RESULT, argintregs[1]);
4269 M_FMOV(REG_FRESULT, argfltregs[2]);
4270 M_FMOV(REG_FRESULT, argfltregs[3]);
4271 M_ALD(REG_PV, REG_PV, -7 * 8); /* builtin_displaymethodstop */
4272 M_JSR(REG_RA, REG_PV);
4273 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4274 M_LDA(REG_PV, REG_RA, disp);
4275 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4276 M_DLD(REG_FRESULT, REG_SP, 1 * 8);
4277 M_LDA(REG_SP, REG_SP, 2 * 8);
4280 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4281 if (IS_FLT_DBL_TYPE(m->returntype))
4282 M_DST(REG_FRESULT, REG_SP, 1 * 8);
4284 M_AST(REG_RESULT, REG_SP, 1 * 8);
4285 M_ALD(REG_PV, REG_PV, -2 * 8); /* builtin_get_exceptionptrptr */
4286 M_JSR(REG_RA, REG_PV);
4287 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4288 M_LDA(REG_PV, REG_RA, disp);
4289 M_MOV(REG_RESULT, REG_ITMP3);
4290 if (IS_FLT_DBL_TYPE(m->returntype))
4291 M_DLD(REG_FRESULT, REG_SP, 1 * 8);
4293 M_ALD(REG_RESULT, REG_SP, 1 * 8);
4295 M_ALD(REG_ITMP3, REG_PV, -2 * 8); /* get address of exceptionptr */
4297 M_ALD(REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
4298 M_BNEZ(REG_ITMP1, 3); /* if no exception then return */
4300 M_ALD(REG_RA, REG_SP, 0 * 8); /* load return address */
4301 M_LDA(REG_SP, REG_SP, NATIVESTUBSTACK * 8); /* remove stackframe */
4302 M_RET(REG_ZERO, REG_RA); /* return to caller */
4304 M_AST(REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
4306 M_ALD(REG_RA, REG_SP, 0 * 8); /* load return address */
4307 M_LDA(REG_SP, REG_SP, NATIVESTUBSTACK * 8); /* remove stackframe */
4308 M_LDA(REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
4309 M_ALD(REG_ITMP3, REG_PV, -3 * 8); /* load asm exception handler address */
4310 M_JMP(REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
4313 dolog_plain("stubsize: %d (for %d params)\n", (int) (mcodeptr - (s4*) s), m->paramcount);
4317 count_nstub_len += NATIVESTUBSIZE * 8;
4320 return (u1 *) (s + NATIVESTUBOFFSET);
4324 /* function: removenativestub **************************************************
4326 removes a previously created native-stub from memory
4328 *******************************************************************************/
4330 void removenativestub(u1 *stub)
4332 CFREE((u8 *) stub - NATIVESTUBOFFSET, NATIVESTUBSIZE * 8);
4337 * These are local overrides for various environment variables in Emacs.
4338 * Please do not remove this and leave it at the end of the file, where
4339 * Emacs will automagically detect them.
4340 * ---------------------------------------------------------------------
4343 * indent-tabs-mode: t