1 /* vm/jit/alpha/codegen.c - machine code generator for alpha
3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Andreas Krall
30 Changes: Joseph Wenninger
32 $Id: codegen.c 1735 2004-12-07 14:33:27Z twisti $
40 #include "vm/jit/alpha/arch.h"
41 #include "native/native.h"
42 #include "vm/builtin.h"
43 #include "vm/global.h"
44 #include "vm/loader.h"
45 #include "vm/tables.h"
46 #include "vm/jit/asmpart.h"
47 #include "vm/jit/jit.h"
49 #include "vm/jit/lsra.h"
51 #include "vm/jit/parse.h"
52 #include "vm/jit/reg.h"
53 #include "vm/jit/alpha/codegen.h"
54 #include "vm/jit/alpha/types.h"
55 #include "vm/jit/alpha/asmoffsets.h"
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,
112 /* Include independent code generation stuff -- include after register */
113 /* descriptions to avoid extern definitions. */
115 #include "vm/jit/codegen.inc"
116 #include "vm/jit/reg.inc"
118 #include "vm/jit/lsra.inc"
122 /* NullPointerException handlers and exception handling initialisation */
124 typedef struct sigctx_struct {
125 long sc_onstack; /* sigstack state to restore */
126 long sc_mask; /* signal mask to restore */
127 long sc_pc; /* pc at time of signal */
128 long sc_ps; /* psl to retore */
129 long sc_regs[32]; /* processor regs 0 to 31 */
130 long sc_ownedfp; /* fp has been used */
131 long sc_fpregs[32]; /* fp regs 0 to 31 */
132 unsigned long sc_fpcr; /* floating point control register */
133 unsigned long sc_fp_control; /* software fpcr */
135 unsigned long sc_reserved1, sc_reserved2;
136 unsigned long sc_ssize;
138 unsigned long sc_traparg_a0;
139 unsigned long sc_traparg_a1;
140 unsigned long sc_traparg_a2;
141 unsigned long sc_fp_trap_pc;
142 unsigned long sc_fp_trigger_sum;
143 unsigned long sc_fp_trigger_inst;
144 unsigned long sc_retcode[2];
148 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
149 void thread_restartcriticalsection(ucontext_t *uc)
152 if ((critical = thread_checkcritical((void*) uc->uc_mcontext.sc_pc)) != NULL)
153 uc->uc_mcontext.sc_pc = (u8) critical;
157 /* NullPointerException signal handler for hardware null pointer check */
159 void catch_NullPointerException(int sig, int code, sigctx_struct *sigctx)
164 java_objectheader *xptr;
166 /* Reset signal handler - necessary for SysV, does no harm for BSD */
168 instr = *((int*)(sigctx->sc_pc));
169 faultaddr = sigctx->sc_regs[(instr >> 16) & 0x1f];
171 if (faultaddr == 0) {
172 /* reinstall handler */
173 signal(sig, (functionptr) catch_NullPointerException);
175 sigaddset(&nsig, sig);
176 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
178 /*xptr = new_nullpointerexception();
179 sigctx->sc_regs[REG_ITMP1_XPTR] = (u8) xptr;*/
181 sigctx->sc_regs[REG_ITMP1_XPTR]=string_java_lang_NullPointerException;
182 sigctx->sc_regs[REG_ITMP2_XPC] = sigctx->sc_pc;
183 /*sigctx->sc_pc = (u8) asm_handle_exception;*/
184 sigctx->sc_pc = (u8) asm_throw_and_handle_exception;
188 faultaddr += (long) ((instr << 16) >> 16);
189 fprintf(stderr, "faulting address: 0x%016lx\n", faultaddr);
190 panic("Stack overflow");
197 void init_exceptions(void)
202 /* Linux on Digital Alpha needs an initialisation of the ieee floating point
203 control for IEEE compliant arithmetic (option -mieee of GCC). Under
204 Digital Unix this is done automatically.
209 extern unsigned long ieee_get_fp_control();
210 extern void ieee_set_fp_control(unsigned long fp_control);
212 void init_exceptions(void)
214 /* initialize floating point control */
216 ieee_set_fp_control(ieee_get_fp_control()
217 & ~IEEE_TRAP_ENABLE_INV
218 & ~IEEE_TRAP_ENABLE_DZE
219 /* & ~IEEE_TRAP_ENABLE_UNF we dont want underflow */
220 & ~IEEE_TRAP_ENABLE_OVF);
223 /* install signal handlers we need to convert to exceptions */
227 signal(SIGSEGV, (functionptr) catch_NullPointerException);
231 signal(SIGBUS, (functionptr) catch_NullPointerException);
237 /* function gen_mcode **********************************************************
239 generates machine code
241 *******************************************************************************/
243 void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
245 s4 len, s1, s2, s3, d;
259 savedregs_num = (m->isleafmethod) ? 0 : 1; /* space to save the RA */
261 /* space to save used callee saved registers */
263 savedregs_num += (rd->savintregcnt - rd->maxsavintreguse);
264 savedregs_num += (rd->savfltregcnt - rd->maxsavfltreguse);
266 parentargs_base = rd->maxmemuse + savedregs_num;
268 #if defined(USE_THREADS) /* space to save argument of monitor_enter */
270 if (checksync && (m->flags & ACC_SYNCHRONIZED))
275 /* create method header */
277 (void) dseg_addaddress(cd, m); /* MethodPointer */
278 (void) dseg_adds4(cd, parentargs_base * 8); /* FrameSize */
280 #if defined(USE_THREADS)
282 /* IsSync contains the offset relative to the stack pointer for the
283 argument of monitor_exit used in the exception handler. Since the
284 offset could be zero and give a wrong meaning of the flag it is
288 if (checksync && (m->flags & ACC_SYNCHRONIZED))
289 (void) dseg_adds4(cd, (rd->maxmemuse + 1) * 8); /* IsSync */
294 (void) dseg_adds4(cd, 0); /* IsSync */
296 (void) dseg_adds4(cd, m->isleafmethod); /* IsLeaf */
297 (void) dseg_adds4(cd, rd->savintregcnt - rd->maxsavintreguse);/* IntSave */
298 (void) dseg_adds4(cd, rd->savfltregcnt - rd->maxsavfltreguse);/* FltSave */
300 dseg_addlinenumbertablesize(cd);
302 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
304 /* create exception table */
306 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
307 dseg_addtarget(cd, ex->start);
308 dseg_addtarget(cd, ex->end);
309 dseg_addtarget(cd, ex->handler);
310 (void) dseg_addaddress(cd, ex->catchtype);
313 /* initialize mcode variables */
315 mcodeptr = (s4 *) cd->mcodebase;
316 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
317 MCODECHECK(128 + m->paramcount);
319 /* create stack frame (if necessary) */
321 if (parentargs_base) {
322 M_LDA(REG_SP, REG_SP, -parentargs_base * 8);
325 /* save return address and used callee saved registers */
328 if (!m->isleafmethod) {
329 p--; M_AST(REG_RA, REG_SP, p * 8);
331 for (i = rd->savintregcnt - 1; i >= rd->maxsavintreguse; i--) {
332 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
334 for (i = rd->savfltregcnt - 1; i >= rd->maxsavfltreguse; i--) {
335 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
338 /* save monitorenter argument */
340 #if defined(USE_THREADS)
341 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
342 if (m->flags & ACC_STATIC) {
343 p = dseg_addaddress(cd, m->class);
344 M_ALD(REG_ITMP1, REG_PV, p);
345 M_AST(REG_ITMP1, REG_SP, rd->maxmemuse * 8);
348 M_AST(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
353 /* copy argument registers to stack and call trace function with pointer
354 to arguments on stack.
359 M_LDA(REG_SP, REG_SP, -((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
360 M_AST(REG_RA, REG_SP, 1 * 8);
362 /* save integer argument registers */
363 for (p = 0; /* p < m->paramcount && */ p < INT_ARG_CNT; p++) {
364 M_LST(rd->argintregs[p], REG_SP, (2 + p) * 8);
367 /* save and copy float arguments into integer registers */
368 for (p = 0; /* p < m->paramcount && */ p < FLT_ARG_CNT; p++) {
369 t = m->paramtypes[p];
371 if (IS_FLT_DBL_TYPE(t)) {
372 if (IS_2_WORD_TYPE(t)) {
373 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
376 M_FST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
379 M_LLD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
382 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
386 p = dseg_addaddress(cd, m);
387 M_ALD(REG_ITMP1, REG_PV, p);
388 M_AST(REG_ITMP1, REG_SP, 0 * 8);
389 p = dseg_addaddress(cd, (void *) builtin_trace_args);
390 M_ALD(REG_PV, REG_PV, p);
391 M_JSR(REG_RA, REG_PV);
392 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
393 M_LDA(REG_PV, REG_RA, disp);
394 M_ALD(REG_RA, REG_SP, 1 * 8);
396 for (p = 0; /* p < mparamcount && */ p < INT_ARG_CNT; p++) {
397 M_LLD(rd->argintregs[p], REG_SP, (2 + p) * 8);
400 for (p = 0; /* p < mparamcount && */ p < FLT_ARG_CNT; p++) {
401 t = m->paramtypes[p];
403 if (IS_FLT_DBL_TYPE(t)) {
404 if (IS_2_WORD_TYPE(t)) {
405 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
408 M_FLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
412 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
416 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT + 2) * 8);
419 /* take arguments out of register or stack frame */
421 for (p = 0, l = 0; p < m->paramcount; p++) {
422 t = m->paramtypes[p];
423 var = &(rd->locals[l][t]);
425 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
429 if (IS_INT_LNG_TYPE(t)) { /* integer args */
430 if (p < INT_ARG_CNT) { /* register arguments */
431 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
432 M_INTMOVE(rd->argintregs[p], var->regoff);
433 } else { /* reg arg -> spilled */
434 M_LST(rd->argintregs[p], REG_SP, 8 * var->regoff);
437 } else { /* stack arguments */
438 pa = p - INT_ARG_CNT;
439 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
440 M_LLD(var->regoff, REG_SP, 8 * (parentargs_base + pa));
442 } else { /* stack arg -> spilled */
443 M_LLD(REG_ITMP1, REG_SP, 8 * (parentargs_base + pa));
444 M_LST(REG_ITMP1, REG_SP, 8 * var->regoff);
448 } else { /* floating args */
449 if (p < FLT_ARG_CNT) { /* register arguments */
450 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
451 M_FLTMOVE(rd->argfltregs[p], var->regoff);
453 } else { /* reg arg -> spilled */
454 M_DST(rd->argfltregs[p], REG_SP, 8 * var->regoff);
457 } else { /* stack arguments */
458 pa = p - FLT_ARG_CNT;
459 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
460 M_DLD(var->regoff, REG_SP, 8 * (parentargs_base + pa) );
462 } else { /* stack-arg -> spilled */
463 M_DLD(REG_FTMP1, REG_SP, 8 * (parentargs_base + pa));
464 M_DST(REG_FTMP1, REG_SP, 8 * var->regoff);
470 /* call monitorenter function */
472 #if defined(USE_THREADS)
473 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
475 s8 func_enter = (m->flags & ACC_STATIC) ?
476 (s8) builtin_staticmonitorenter : (s8) builtin_monitorenter;
477 p = dseg_addaddress(cd, (void*) func_enter);
478 M_ALD(REG_PV, REG_PV, p);
479 M_ALD(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
480 M_JSR(REG_RA, REG_PV);
481 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
482 M_LDA(REG_PV, REG_RA, disp);
487 /* end of header generation */
489 /* walk through all basic blocks */
490 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
492 bptr->mpc = (s4) ((u1 *) mcodeptr - cd->mcodebase);
494 if (bptr->flags >= BBREACHED) {
496 /* branch resolving */
500 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
501 gen_resolvebranch((u1*) cd->mcodebase + brefs->branchpos,
502 brefs->branchpos, bptr->mpc);
506 /* copy interface registers to their destination */
513 while (src != NULL) {
515 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
516 /* d = reg_of_var(m, src, REG_ITMP1); */
517 if (!(src->flags & INMEMORY))
521 M_INTMOVE(REG_ITMP1, d);
522 store_reg_to_var_int(src, d);
528 while (src != NULL) {
530 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
531 d = reg_of_var(rd, src, REG_ITMP1);
532 M_INTMOVE(REG_ITMP1, d);
533 store_reg_to_var_int(src, d);
536 d = reg_of_var(rd, src, REG_IFTMP);
537 if ((src->varkind != STACKVAR)) {
539 if (IS_FLT_DBL_TYPE(s2)) {
540 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
541 s1 = rd->interfaces[len][s2].regoff;
545 M_DLD(d, REG_SP, 8 * rd->interfaces[len][s2].regoff);
547 store_reg_to_var_flt(src, d);
550 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
551 s1 = rd->interfaces[len][s2].regoff;
555 M_LLD(d, REG_SP, 8 * rd->interfaces[len][s2].regoff);
557 store_reg_to_var_int(src, d);
567 /* walk through all instructions */
571 for (iptr = bptr->iinstr;
573 src = iptr->dst, len--, iptr++) {
575 if (iptr->line!=currentline) {
576 dseg_addlinenumber(cd,iptr->line,mcodeptr);
577 currentline=iptr->line;
580 MCODECHECK(64); /* an instruction usually needs < 64 words */
583 case ICMD_NOP: /* ... ==> ... */
586 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
588 var_to_reg_int(s1, src, REG_ITMP1);
590 codegen_addxnullrefs(cd, mcodeptr);
593 /* constant operations ************************************************/
595 case ICMD_ICONST: /* ... ==> ..., constant */
596 /* op1 = 0, val.i = constant */
598 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
599 ICONST(d, iptr->val.i);
600 store_reg_to_var_int(iptr->dst, d);
603 case ICMD_LCONST: /* ... ==> ..., constant */
604 /* op1 = 0, val.l = constant */
606 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
607 LCONST(d, iptr->val.l);
608 store_reg_to_var_int(iptr->dst, d);
611 case ICMD_FCONST: /* ... ==> ..., constant */
612 /* op1 = 0, val.f = constant */
614 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
615 a = dseg_addfloat(cd, iptr->val.f);
617 store_reg_to_var_flt(iptr->dst, d);
620 case ICMD_DCONST: /* ... ==> ..., constant */
621 /* op1 = 0, val.d = constant */
623 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
624 a = dseg_adddouble(cd, iptr->val.d);
626 store_reg_to_var_flt(iptr->dst, d);
629 case ICMD_ACONST: /* ... ==> ..., constant */
630 /* op1 = 0, val.a = constant */
632 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
634 a = dseg_addaddress(cd, iptr->val.a);
637 M_INTMOVE(REG_ZERO, d);
639 store_reg_to_var_int(iptr->dst, d);
643 /* load/store operations **********************************************/
645 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
646 case ICMD_LLOAD: /* op1 = local variable */
649 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
650 if ((iptr->dst->varkind == LOCALVAR) &&
651 (iptr->dst->varnum == iptr->op1))
653 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
654 if (var->flags & INMEMORY)
655 M_LLD(d, REG_SP, 8 * var->regoff);
657 {M_INTMOVE(var->regoff,d);}
658 store_reg_to_var_int(iptr->dst, d);
661 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
662 case ICMD_DLOAD: /* op1 = local variable */
664 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
665 if ((iptr->dst->varkind == LOCALVAR) &&
666 (iptr->dst->varnum == iptr->op1))
668 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
669 if (var->flags & INMEMORY)
670 M_DLD(d, REG_SP, 8 * var->regoff);
672 {M_FLTMOVE(var->regoff,d);}
673 store_reg_to_var_flt(iptr->dst, d);
677 case ICMD_ISTORE: /* ..., value ==> ... */
678 case ICMD_LSTORE: /* op1 = local variable */
681 if ((src->varkind == LOCALVAR) &&
682 (src->varnum == iptr->op1))
684 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
685 if (var->flags & INMEMORY) {
686 var_to_reg_int(s1, src, REG_ITMP1);
687 M_LST(s1, REG_SP, 8 * var->regoff);
690 var_to_reg_int(s1, src, var->regoff);
691 M_INTMOVE(s1, var->regoff);
695 case ICMD_FSTORE: /* ..., value ==> ... */
696 case ICMD_DSTORE: /* op1 = local variable */
698 if ((src->varkind == LOCALVAR) &&
699 (src->varnum == iptr->op1))
701 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
702 if (var->flags & INMEMORY) {
703 var_to_reg_flt(s1, src, REG_FTMP1);
704 M_DST(s1, REG_SP, 8 * var->regoff);
707 var_to_reg_flt(s1, src, var->regoff);
708 M_FLTMOVE(s1, var->regoff);
713 /* pop/dup/swap operations ********************************************/
715 /* attention: double and longs are only one entry in CACAO ICMDs */
717 case ICMD_POP: /* ..., value ==> ... */
718 case ICMD_POP2: /* ..., value, value ==> ... */
721 case ICMD_DUP: /* ..., a ==> ..., a, a */
722 M_COPY(src, iptr->dst);
725 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
727 M_COPY(src, iptr->dst);
728 M_COPY(src->prev, iptr->dst->prev);
729 M_COPY(iptr->dst, iptr->dst->prev->prev);
732 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
734 M_COPY(src, iptr->dst);
735 M_COPY(src->prev, iptr->dst->prev);
736 M_COPY(src->prev->prev, iptr->dst->prev->prev);
737 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
740 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
742 M_COPY(src, iptr->dst);
743 M_COPY(src->prev, iptr->dst->prev);
746 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
748 M_COPY(src, iptr->dst);
749 M_COPY(src->prev, iptr->dst->prev);
750 M_COPY(src->prev->prev, iptr->dst->prev->prev);
751 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
752 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev);
755 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
757 M_COPY(src, iptr->dst);
758 M_COPY(src->prev, iptr->dst->prev);
759 M_COPY(src->prev->prev, iptr->dst->prev->prev);
760 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
761 M_COPY(iptr->dst, iptr->dst->prev->prev->prev->prev);
762 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev->prev);
765 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
767 M_COPY(src, iptr->dst->prev);
768 M_COPY(src->prev, iptr->dst);
772 /* integer operations *************************************************/
774 case ICMD_INEG: /* ..., value ==> ..., - value */
776 var_to_reg_int(s1, src, REG_ITMP1);
777 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
778 M_ISUB(REG_ZERO, s1, d);
779 store_reg_to_var_int(iptr->dst, d);
782 case ICMD_LNEG: /* ..., value ==> ..., - value */
784 var_to_reg_int(s1, src, REG_ITMP1);
785 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
786 M_LSUB(REG_ZERO, s1, d);
787 store_reg_to_var_int(iptr->dst, d);
790 case ICMD_I2L: /* ..., value ==> ..., value */
792 var_to_reg_int(s1, src, REG_ITMP1);
793 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
795 store_reg_to_var_int(iptr->dst, d);
798 case ICMD_L2I: /* ..., value ==> ..., value */
800 var_to_reg_int(s1, src, REG_ITMP1);
801 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
802 M_IADD(s1, REG_ZERO, d );
803 store_reg_to_var_int(iptr->dst, d);
806 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
808 var_to_reg_int(s1, src, REG_ITMP1);
809 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
810 if (has_ext_instr_set) {
814 M_SLL_IMM(s1, 56, d);
815 M_SRA_IMM( d, 56, d);
817 store_reg_to_var_int(iptr->dst, d);
820 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
822 var_to_reg_int(s1, src, REG_ITMP1);
823 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
825 store_reg_to_var_int(iptr->dst, d);
828 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
830 var_to_reg_int(s1, src, REG_ITMP1);
831 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
832 if (has_ext_instr_set) {
836 M_SLL_IMM(s1, 48, d);
837 M_SRA_IMM( d, 48, d);
839 store_reg_to_var_int(iptr->dst, d);
843 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
845 var_to_reg_int(s1, src->prev, REG_ITMP1);
846 var_to_reg_int(s2, src, REG_ITMP2);
847 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
849 store_reg_to_var_int(iptr->dst, d);
852 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
853 /* val.i = constant */
855 var_to_reg_int(s1, src, REG_ITMP1);
856 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
857 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
858 M_IADD_IMM(s1, iptr->val.i, d);
861 ICONST(REG_ITMP2, iptr->val.i);
862 M_IADD(s1, REG_ITMP2, d);
864 store_reg_to_var_int(iptr->dst, d);
867 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
869 var_to_reg_int(s1, src->prev, REG_ITMP1);
870 var_to_reg_int(s2, src, REG_ITMP2);
871 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
873 store_reg_to_var_int(iptr->dst, d);
876 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
877 /* val.l = constant */
879 var_to_reg_int(s1, src, REG_ITMP1);
880 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
881 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
882 M_LADD_IMM(s1, iptr->val.l, d);
885 LCONST(REG_ITMP2, iptr->val.l);
886 M_LADD(s1, REG_ITMP2, d);
888 store_reg_to_var_int(iptr->dst, d);
891 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
893 var_to_reg_int(s1, src->prev, REG_ITMP1);
894 var_to_reg_int(s2, src, REG_ITMP2);
895 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
897 store_reg_to_var_int(iptr->dst, d);
900 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
901 /* val.i = constant */
903 var_to_reg_int(s1, src, REG_ITMP1);
904 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
905 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
906 M_ISUB_IMM(s1, iptr->val.i, d);
909 ICONST(REG_ITMP2, iptr->val.i);
910 M_ISUB(s1, REG_ITMP2, d);
912 store_reg_to_var_int(iptr->dst, d);
915 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
917 var_to_reg_int(s1, src->prev, REG_ITMP1);
918 var_to_reg_int(s2, src, REG_ITMP2);
919 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
921 store_reg_to_var_int(iptr->dst, d);
924 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
925 /* val.l = constant */
927 var_to_reg_int(s1, src, REG_ITMP1);
928 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
929 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
930 M_LSUB_IMM(s1, iptr->val.l, d);
933 LCONST(REG_ITMP2, iptr->val.l);
934 M_LSUB(s1, REG_ITMP2, d);
936 store_reg_to_var_int(iptr->dst, d);
939 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
941 var_to_reg_int(s1, src->prev, REG_ITMP1);
942 var_to_reg_int(s2, src, REG_ITMP2);
943 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
945 store_reg_to_var_int(iptr->dst, d);
948 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
949 /* val.i = constant */
951 var_to_reg_int(s1, src, REG_ITMP1);
952 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
953 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
954 M_IMUL_IMM(s1, iptr->val.i, d);
957 ICONST(REG_ITMP2, iptr->val.i);
958 M_IMUL(s1, REG_ITMP2, d);
960 store_reg_to_var_int(iptr->dst, d);
963 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
965 var_to_reg_int(s1, src->prev, REG_ITMP1);
966 var_to_reg_int(s2, src, REG_ITMP2);
967 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
969 store_reg_to_var_int(iptr->dst, d);
972 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
973 /* val.l = constant */
975 var_to_reg_int(s1, src, REG_ITMP1);
976 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
977 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
978 M_LMUL_IMM(s1, iptr->val.l, d);
981 LCONST(REG_ITMP2, iptr->val.l);
982 M_LMUL(s1, REG_ITMP2, d);
984 store_reg_to_var_int(iptr->dst, d);
987 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
988 case ICMD_LDIVPOW2: /* val.i = constant */
990 var_to_reg_int(s1, src, REG_ITMP1);
991 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
992 if (iptr->val.i <= 15) {
993 M_LDA(REG_ITMP2, s1, (1 << iptr->val.i) -1);
994 M_CMOVGE(s1, s1, REG_ITMP2);
997 M_SRA_IMM(s1, 63, REG_ITMP2);
998 M_SRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
999 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1001 M_SRA_IMM(REG_ITMP2, iptr->val.i, d);
1002 store_reg_to_var_int(iptr->dst, d);
1005 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1007 var_to_reg_int(s1, src->prev, REG_ITMP1);
1008 var_to_reg_int(s2, src, REG_ITMP2);
1009 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1010 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1011 M_SLL(s1, REG_ITMP3, d);
1012 M_IADD(d, REG_ZERO, d);
1013 store_reg_to_var_int(iptr->dst, d);
1016 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1017 /* val.i = constant */
1019 var_to_reg_int(s1, src, REG_ITMP1);
1020 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1021 M_SLL_IMM(s1, iptr->val.i & 0x1f, d);
1022 M_IADD(d, REG_ZERO, d);
1023 store_reg_to_var_int(iptr->dst, d);
1026 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1028 var_to_reg_int(s1, src->prev, REG_ITMP1);
1029 var_to_reg_int(s2, src, REG_ITMP2);
1030 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1031 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1032 M_SRA(s1, REG_ITMP3, d);
1033 store_reg_to_var_int(iptr->dst, d);
1036 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1037 /* val.i = constant */
1039 var_to_reg_int(s1, src, REG_ITMP1);
1040 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1041 M_SRA_IMM(s1, iptr->val.i & 0x1f, d);
1042 store_reg_to_var_int(iptr->dst, d);
1045 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1047 var_to_reg_int(s1, src->prev, REG_ITMP1);
1048 var_to_reg_int(s2, src, REG_ITMP2);
1049 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1050 M_AND_IMM(s2, 0x1f, REG_ITMP2);
1052 M_SRL(d, REG_ITMP2, d);
1053 M_IADD(d, REG_ZERO, d);
1054 store_reg_to_var_int(iptr->dst, d);
1057 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1058 /* val.i = constant */
1060 var_to_reg_int(s1, src, REG_ITMP1);
1061 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1063 M_SRL_IMM(d, iptr->val.i & 0x1f, d);
1064 M_IADD(d, REG_ZERO, d);
1065 store_reg_to_var_int(iptr->dst, d);
1068 case ICMD_LSHL: /* ..., 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(rd, iptr->dst, REG_ITMP3);
1074 store_reg_to_var_int(iptr->dst, d);
1077 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1078 /* val.i = constant */
1080 var_to_reg_int(s1, src, REG_ITMP1);
1081 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1082 M_SLL_IMM(s1, iptr->val.i & 0x3f, d);
1083 store_reg_to_var_int(iptr->dst, d);
1086 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1088 var_to_reg_int(s1, src->prev, REG_ITMP1);
1089 var_to_reg_int(s2, src, REG_ITMP2);
1090 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1092 store_reg_to_var_int(iptr->dst, d);
1095 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1096 /* val.i = constant */
1098 var_to_reg_int(s1, src, REG_ITMP1);
1099 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1100 M_SRA_IMM(s1, iptr->val.i & 0x3f, d);
1101 store_reg_to_var_int(iptr->dst, d);
1104 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1106 var_to_reg_int(s1, src->prev, REG_ITMP1);
1107 var_to_reg_int(s2, src, REG_ITMP2);
1108 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1110 store_reg_to_var_int(iptr->dst, d);
1113 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1114 /* val.i = constant */
1116 var_to_reg_int(s1, src, REG_ITMP1);
1117 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1118 M_SRL_IMM(s1, iptr->val.i & 0x3f, d);
1119 store_reg_to_var_int(iptr->dst, d);
1122 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1125 var_to_reg_int(s1, src->prev, REG_ITMP1);
1126 var_to_reg_int(s2, src, REG_ITMP2);
1127 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1129 store_reg_to_var_int(iptr->dst, d);
1132 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1133 /* val.i = constant */
1135 var_to_reg_int(s1, src, REG_ITMP1);
1136 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1137 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1138 M_AND_IMM(s1, iptr->val.i, d);
1140 else if (iptr->val.i == 0xffff) {
1143 else if (iptr->val.i == 0xffffff) {
1144 M_ZAPNOT_IMM(s1, 0x07, d);
1147 ICONST(REG_ITMP2, iptr->val.i);
1148 M_AND(s1, REG_ITMP2, d);
1150 store_reg_to_var_int(iptr->dst, d);
1153 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1154 /* val.i = constant */
1156 var_to_reg_int(s1, src, REG_ITMP1);
1157 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1159 M_MOV(s1, REG_ITMP1);
1162 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1163 M_AND_IMM(s1, iptr->val.i, d);
1165 M_ISUB(REG_ZERO, s1, d);
1166 M_AND_IMM(d, iptr->val.i, d);
1168 else if (iptr->val.i == 0xffff) {
1171 M_ISUB(REG_ZERO, s1, d);
1174 else if (iptr->val.i == 0xffffff) {
1175 M_ZAPNOT_IMM(s1, 0x07, d);
1177 M_ISUB(REG_ZERO, s1, d);
1178 M_ZAPNOT_IMM(d, 0x07, d);
1181 ICONST(REG_ITMP2, iptr->val.i);
1182 M_AND(s1, REG_ITMP2, d);
1184 M_ISUB(REG_ZERO, s1, d);
1185 M_AND(d, REG_ITMP2, d);
1187 M_ISUB(REG_ZERO, d, d);
1188 store_reg_to_var_int(iptr->dst, d);
1191 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1192 /* val.l = constant */
1194 var_to_reg_int(s1, src, REG_ITMP1);
1195 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1196 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1197 M_AND_IMM(s1, iptr->val.l, d);
1199 else if (iptr->val.l == 0xffffL) {
1202 else if (iptr->val.l == 0xffffffL) {
1203 M_ZAPNOT_IMM(s1, 0x07, d);
1205 else if (iptr->val.l == 0xffffffffL) {
1208 else if (iptr->val.l == 0xffffffffffL) {
1209 M_ZAPNOT_IMM(s1, 0x1f, d);
1211 else if (iptr->val.l == 0xffffffffffffL) {
1212 M_ZAPNOT_IMM(s1, 0x3f, d);
1214 else if (iptr->val.l == 0xffffffffffffffL) {
1215 M_ZAPNOT_IMM(s1, 0x7f, d);
1218 LCONST(REG_ITMP2, iptr->val.l);
1219 M_AND(s1, REG_ITMP2, d);
1221 store_reg_to_var_int(iptr->dst, d);
1224 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1225 /* val.l = constant */
1227 var_to_reg_int(s1, src, REG_ITMP1);
1228 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1230 M_MOV(s1, REG_ITMP1);
1233 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1234 M_AND_IMM(s1, iptr->val.l, d);
1236 M_LSUB(REG_ZERO, s1, d);
1237 M_AND_IMM(d, iptr->val.l, d);
1239 else if (iptr->val.l == 0xffffL) {
1242 M_LSUB(REG_ZERO, s1, d);
1245 else if (iptr->val.l == 0xffffffL) {
1246 M_ZAPNOT_IMM(s1, 0x07, d);
1248 M_LSUB(REG_ZERO, s1, d);
1249 M_ZAPNOT_IMM(d, 0x07, d);
1251 else if (iptr->val.l == 0xffffffffL) {
1254 M_LSUB(REG_ZERO, s1, d);
1257 else if (iptr->val.l == 0xffffffffffL) {
1258 M_ZAPNOT_IMM(s1, 0x1f, d);
1260 M_LSUB(REG_ZERO, s1, d);
1261 M_ZAPNOT_IMM(d, 0x1f, d);
1263 else if (iptr->val.l == 0xffffffffffffL) {
1264 M_ZAPNOT_IMM(s1, 0x3f, d);
1266 M_LSUB(REG_ZERO, s1, d);
1267 M_ZAPNOT_IMM(d, 0x3f, d);
1269 else if (iptr->val.l == 0xffffffffffffffL) {
1270 M_ZAPNOT_IMM(s1, 0x7f, d);
1272 M_LSUB(REG_ZERO, s1, d);
1273 M_ZAPNOT_IMM(d, 0x7f, d);
1276 LCONST(REG_ITMP2, iptr->val.l);
1277 M_AND(s1, REG_ITMP2, d);
1279 M_LSUB(REG_ZERO, s1, d);
1280 M_AND(d, REG_ITMP2, d);
1282 M_LSUB(REG_ZERO, d, d);
1283 store_reg_to_var_int(iptr->dst, d);
1286 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1289 var_to_reg_int(s1, src->prev, REG_ITMP1);
1290 var_to_reg_int(s2, src, REG_ITMP2);
1291 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1293 store_reg_to_var_int(iptr->dst, d);
1296 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1297 /* val.i = constant */
1299 var_to_reg_int(s1, src, REG_ITMP1);
1300 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1301 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1302 M_OR_IMM(s1, iptr->val.i, d);
1305 ICONST(REG_ITMP2, iptr->val.i);
1306 M_OR(s1, REG_ITMP2, d);
1308 store_reg_to_var_int(iptr->dst, d);
1311 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1312 /* val.l = constant */
1314 var_to_reg_int(s1, src, REG_ITMP1);
1315 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1316 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1317 M_OR_IMM(s1, iptr->val.l, d);
1320 LCONST(REG_ITMP2, iptr->val.l);
1321 M_OR(s1, REG_ITMP2, d);
1323 store_reg_to_var_int(iptr->dst, d);
1326 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1329 var_to_reg_int(s1, src->prev, REG_ITMP1);
1330 var_to_reg_int(s2, src, REG_ITMP2);
1331 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1333 store_reg_to_var_int(iptr->dst, d);
1336 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1337 /* val.i = constant */
1339 var_to_reg_int(s1, src, REG_ITMP1);
1340 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1341 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1342 M_XOR_IMM(s1, iptr->val.i, d);
1345 ICONST(REG_ITMP2, iptr->val.i);
1346 M_XOR(s1, REG_ITMP2, d);
1348 store_reg_to_var_int(iptr->dst, d);
1351 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1352 /* val.l = constant */
1354 var_to_reg_int(s1, src, REG_ITMP1);
1355 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1356 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1357 M_XOR_IMM(s1, iptr->val.l, d);
1360 LCONST(REG_ITMP2, iptr->val.l);
1361 M_XOR(s1, REG_ITMP2, d);
1363 store_reg_to_var_int(iptr->dst, d);
1367 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1369 var_to_reg_int(s1, src->prev, REG_ITMP1);
1370 var_to_reg_int(s2, src, REG_ITMP2);
1371 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1372 M_CMPLT(s1, s2, REG_ITMP3);
1373 M_CMPLT(s2, s1, REG_ITMP1);
1374 M_LSUB (REG_ITMP1, REG_ITMP3, d);
1375 store_reg_to_var_int(iptr->dst, d);
1379 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1380 /* op1 = variable, val.i = constant */
1382 var = &(rd->locals[iptr->op1][TYPE_INT]);
1383 if (var->flags & INMEMORY) {
1385 M_LLD(s1, REG_SP, 8 * var->regoff);
1389 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1390 M_IADD_IMM(s1, iptr->val.i, s1);
1392 else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1393 M_ISUB_IMM(s1, (-iptr->val.i), s1);
1396 M_LDA (s1, s1, iptr->val.i);
1397 M_IADD(s1, REG_ZERO, s1);
1399 if (var->flags & INMEMORY)
1400 M_LST(s1, REG_SP, 8 * var->regoff);
1404 /* floating operations ************************************************/
1406 case ICMD_FNEG: /* ..., value ==> ..., - value */
1408 var_to_reg_flt(s1, src, REG_FTMP1);
1409 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1411 store_reg_to_var_flt(iptr->dst, d);
1414 case ICMD_DNEG: /* ..., value ==> ..., - value */
1416 var_to_reg_flt(s1, src, REG_FTMP1);
1417 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1419 store_reg_to_var_flt(iptr->dst, d);
1422 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1424 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1425 var_to_reg_flt(s2, src, REG_FTMP2);
1426 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1431 if (d == s1 || d == s2) {
1432 M_FADDS(s1, s2, REG_FTMP3);
1434 M_FMOV(REG_FTMP3, d);
1441 store_reg_to_var_flt(iptr->dst, d);
1444 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1446 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1447 var_to_reg_flt(s2, src, REG_FTMP2);
1448 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1453 if (d == s1 || d == s2) {
1454 M_DADDS(s1, s2, REG_FTMP3);
1456 M_FMOV(REG_FTMP3, d);
1463 store_reg_to_var_flt(iptr->dst, d);
1466 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1468 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1469 var_to_reg_flt(s2, src, REG_FTMP2);
1470 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1475 if (d == s1 || d == s2) {
1476 M_FSUBS(s1, s2, REG_FTMP3);
1478 M_FMOV(REG_FTMP3, d);
1485 store_reg_to_var_flt(iptr->dst, d);
1488 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1490 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1491 var_to_reg_flt(s2, src, REG_FTMP2);
1492 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1497 if (d == s1 || d == s2) {
1498 M_DSUBS(s1, s2, REG_FTMP3);
1500 M_FMOV(REG_FTMP3, d);
1507 store_reg_to_var_flt(iptr->dst, d);
1510 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1512 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1513 var_to_reg_flt(s2, src, REG_FTMP2);
1514 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1519 if (d == s1 || d == s2) {
1520 M_FMULS(s1, s2, REG_FTMP3);
1522 M_FMOV(REG_FTMP3, d);
1529 store_reg_to_var_flt(iptr->dst, d);
1532 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1534 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1535 var_to_reg_flt(s2, src, REG_FTMP2);
1536 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1541 if (d == s1 || d == s2) {
1542 M_DMULS(s1, s2, REG_FTMP3);
1544 M_FMOV(REG_FTMP3, d);
1551 store_reg_to_var_flt(iptr->dst, d);
1554 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1556 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1557 var_to_reg_flt(s2, src, REG_FTMP2);
1558 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1563 if (d == s1 || d == s2) {
1564 M_FDIVS(s1, s2, REG_FTMP3);
1566 M_FMOV(REG_FTMP3, d);
1573 store_reg_to_var_flt(iptr->dst, d);
1576 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1578 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1579 var_to_reg_flt(s2, src, REG_FTMP2);
1580 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1585 if (d == s1 || d == s2) {
1586 M_DDIVS(s1, s2, REG_FTMP3);
1588 M_FMOV(REG_FTMP3, d);
1595 store_reg_to_var_flt(iptr->dst, d);
1598 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1600 var_to_reg_int(s1, src, REG_ITMP1);
1601 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1602 a = dseg_adddouble(cd, 0.0);
1603 M_LST (s1, REG_PV, a);
1604 M_DLD (d, REG_PV, a);
1606 store_reg_to_var_flt(iptr->dst, d);
1609 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1611 var_to_reg_int(s1, src, REG_ITMP1);
1612 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1613 a = dseg_adddouble(cd, 0.0);
1614 M_LST (s1, REG_PV, a);
1615 M_DLD (d, REG_PV, a);
1617 store_reg_to_var_flt(iptr->dst, d);
1620 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1622 var_to_reg_flt(s1, src, REG_FTMP1);
1623 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1624 a = dseg_adddouble(cd, 0.0);
1625 M_CVTDL_C(s1, REG_FTMP2);
1626 M_CVTLI(REG_FTMP2, REG_FTMP3);
1627 M_DST (REG_FTMP3, REG_PV, a);
1628 M_ILD (d, REG_PV, a);
1629 store_reg_to_var_int(iptr->dst, d);
1632 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1634 var_to_reg_flt(s1, src, REG_FTMP1);
1635 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1636 a = dseg_adddouble(cd, 0.0);
1637 M_CVTDL_C(s1, REG_FTMP2);
1638 M_DST (REG_FTMP2, REG_PV, a);
1639 M_LLD (d, REG_PV, a);
1640 store_reg_to_var_int(iptr->dst, d);
1643 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1645 var_to_reg_flt(s1, src, REG_FTMP1);
1646 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1649 store_reg_to_var_flt(iptr->dst, d);
1652 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1654 var_to_reg_flt(s1, src, REG_FTMP1);
1655 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1663 store_reg_to_var_flt(iptr->dst, d);
1666 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1668 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1669 var_to_reg_flt(s2, src, REG_FTMP2);
1670 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1672 M_LSUB_IMM(REG_ZERO, 1, d);
1673 M_FCMPEQ(s1, s2, REG_FTMP3);
1674 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1676 M_FCMPLT(s2, s1, REG_FTMP3);
1677 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1678 M_LADD_IMM(REG_ZERO, 1, d);
1681 M_LSUB_IMM(REG_ZERO, 1, d);
1682 M_FCMPEQS(s1, s2, REG_FTMP3);
1684 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1686 M_FCMPLTS(s2, s1, REG_FTMP3);
1688 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1689 M_LADD_IMM(REG_ZERO, 1, d);
1691 store_reg_to_var_int(iptr->dst, d);
1694 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1696 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1697 var_to_reg_flt(s2, src, REG_FTMP2);
1698 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1700 M_LADD_IMM(REG_ZERO, 1, d);
1701 M_FCMPEQ(s1, s2, REG_FTMP3);
1702 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1704 M_FCMPLT(s1, s2, REG_FTMP3);
1705 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1706 M_LSUB_IMM(REG_ZERO, 1, d);
1709 M_LADD_IMM(REG_ZERO, 1, d);
1710 M_FCMPEQS(s1, s2, REG_FTMP3);
1712 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1714 M_FCMPLTS(s1, s2, REG_FTMP3);
1716 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1717 M_LSUB_IMM(REG_ZERO, 1, d);
1719 store_reg_to_var_int(iptr->dst, d);
1723 /* memory operations **************************************************/
1725 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1727 var_to_reg_int(s1, src, REG_ITMP1);
1728 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1729 gen_nullptr_check(s1);
1730 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1731 store_reg_to_var_int(iptr->dst, d);
1734 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1736 var_to_reg_int(s1, src->prev, REG_ITMP1);
1737 var_to_reg_int(s2, src, REG_ITMP2);
1738 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1739 if (iptr->op1 == 0) {
1740 gen_nullptr_check(s1);
1743 M_SAADDQ(s2, s1, REG_ITMP1);
1744 M_ALD( d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1745 store_reg_to_var_int(iptr->dst, d);
1748 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1750 var_to_reg_int(s1, src->prev, REG_ITMP1);
1751 var_to_reg_int(s2, src, REG_ITMP2);
1752 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1753 if (iptr->op1 == 0) {
1754 gen_nullptr_check(s1);
1757 M_S8ADDQ(s2, s1, REG_ITMP1);
1758 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1759 store_reg_to_var_int(iptr->dst, d);
1762 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1764 var_to_reg_int(s1, src->prev, REG_ITMP1);
1765 var_to_reg_int(s2, src, REG_ITMP2);
1766 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1767 if (iptr->op1 == 0) {
1768 gen_nullptr_check(s1);
1772 M_S4ADDQ(s2, s1, REG_ITMP1);
1773 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1774 store_reg_to_var_int(iptr->dst, d);
1777 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1779 var_to_reg_int(s1, src->prev, REG_ITMP1);
1780 var_to_reg_int(s2, src, REG_ITMP2);
1781 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1782 if (iptr->op1 == 0) {
1783 gen_nullptr_check(s1);
1786 M_S4ADDQ(s2, s1, REG_ITMP1);
1787 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1788 store_reg_to_var_flt(iptr->dst, d);
1791 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1793 var_to_reg_int(s1, src->prev, REG_ITMP1);
1794 var_to_reg_int(s2, src, REG_ITMP2);
1795 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1796 if (iptr->op1 == 0) {
1797 gen_nullptr_check(s1);
1800 M_S8ADDQ(s2, s1, REG_ITMP1);
1801 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1802 store_reg_to_var_flt(iptr->dst, d);
1805 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1807 var_to_reg_int(s1, src->prev, REG_ITMP1);
1808 var_to_reg_int(s2, src, REG_ITMP2);
1809 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1810 if (iptr->op1 == 0) {
1811 gen_nullptr_check(s1);
1814 if (has_ext_instr_set) {
1815 M_LADD(s2, s1, REG_ITMP1);
1816 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1817 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1820 M_LADD (s2, s1, REG_ITMP1);
1821 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1822 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1823 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1824 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
1826 store_reg_to_var_int(iptr->dst, d);
1829 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1831 var_to_reg_int(s1, src->prev, REG_ITMP1);
1832 var_to_reg_int(s2, src, REG_ITMP2);
1833 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1834 if (iptr->op1 == 0) {
1835 gen_nullptr_check(s1);
1838 if (has_ext_instr_set) {
1839 M_LADD(s2, s1, REG_ITMP1);
1840 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1841 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1845 M_LADD(s2, s1, REG_ITMP1);
1846 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1847 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1848 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1849 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1850 M_SRA_IMM(d, 48, d);
1852 store_reg_to_var_int(iptr->dst, d);
1855 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1857 var_to_reg_int(s1, src->prev, REG_ITMP1);
1858 var_to_reg_int(s2, src, REG_ITMP2);
1859 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1860 if (iptr->op1 == 0) {
1861 gen_nullptr_check(s1);
1864 if (has_ext_instr_set) {
1865 M_LADD (s2, s1, REG_ITMP1);
1866 M_BLDU (d, REG_ITMP1, OFFSET (java_bytearray, data[0]));
1870 M_LADD(s2, s1, REG_ITMP1);
1871 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1872 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
1873 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1874 M_SRA_IMM(d, 56, d);
1876 store_reg_to_var_int(iptr->dst, d);
1880 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1882 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1883 var_to_reg_int(s2, src->prev, REG_ITMP2);
1884 if (iptr->op1 == 0) {
1885 gen_nullptr_check(s1);
1888 var_to_reg_int(s3, src, REG_ITMP3);
1889 M_SAADDQ(s2, s1, REG_ITMP1);
1890 M_AST (s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1893 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1895 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1896 var_to_reg_int(s2, src->prev, REG_ITMP2);
1897 if (iptr->op1 == 0) {
1898 gen_nullptr_check(s1);
1901 var_to_reg_int(s3, src, REG_ITMP3);
1902 M_S8ADDQ(s2, s1, REG_ITMP1);
1903 M_LST (s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1906 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1908 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1909 var_to_reg_int(s2, src->prev, REG_ITMP2);
1910 if (iptr->op1 == 0) {
1911 gen_nullptr_check(s1);
1915 var_to_reg_int(s3, src, REG_ITMP3);
1916 M_S4ADDQ(s2, s1, REG_ITMP1);
1917 M_IST (s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1920 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1922 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1923 var_to_reg_int(s2, src->prev, REG_ITMP2);
1924 if (iptr->op1 == 0) {
1925 gen_nullptr_check(s1);
1928 var_to_reg_flt(s3, src, REG_FTMP3);
1929 M_S4ADDQ(s2, s1, REG_ITMP1);
1930 M_FST (s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1933 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1935 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1936 var_to_reg_int(s2, src->prev, REG_ITMP2);
1937 if (iptr->op1 == 0) {
1938 gen_nullptr_check(s1);
1941 var_to_reg_flt(s3, src, REG_FTMP3);
1942 M_S8ADDQ(s2, s1, REG_ITMP1);
1943 M_DST (s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1946 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1948 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1949 var_to_reg_int(s2, src->prev, REG_ITMP2);
1950 if (iptr->op1 == 0) {
1951 gen_nullptr_check(s1);
1954 var_to_reg_int(s3, src, REG_ITMP3);
1955 if (has_ext_instr_set) {
1956 M_LADD(s2, s1, REG_ITMP1);
1957 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1958 M_SST (s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1961 M_LADD (s2, s1, REG_ITMP1);
1962 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1963 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1964 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1965 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1966 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1967 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
1968 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1972 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1974 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1975 var_to_reg_int(s2, src->prev, REG_ITMP2);
1976 if (iptr->op1 == 0) {
1977 gen_nullptr_check(s1);
1980 var_to_reg_int(s3, src, REG_ITMP3);
1981 if (has_ext_instr_set) {
1982 M_LADD(s2, s1, REG_ITMP1);
1983 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1984 M_SST (s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1987 M_LADD (s2, s1, REG_ITMP1);
1988 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1989 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1990 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1991 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1992 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1993 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
1994 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1998 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
2000 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2001 var_to_reg_int(s2, src->prev, REG_ITMP2);
2002 if (iptr->op1 == 0) {
2003 gen_nullptr_check(s1);
2006 var_to_reg_int(s3, src, REG_ITMP3);
2007 if (has_ext_instr_set) {
2008 M_LADD(s2, s1, REG_ITMP1);
2009 M_BST (s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2012 M_LADD (s2, s1, REG_ITMP1);
2013 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2014 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2015 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
2016 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2017 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2018 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2023 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
2025 var_to_reg_int(s1, src->prev, REG_ITMP1);
2026 var_to_reg_int(s2, src, REG_ITMP2);
2027 if (iptr->op1 == 0) {
2028 gen_nullptr_check(s1);
2031 M_S4ADDQ(s2, s1, REG_ITMP1);
2032 M_IST(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
2035 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
2037 var_to_reg_int(s1, src->prev, REG_ITMP1);
2038 var_to_reg_int(s2, src, REG_ITMP2);
2039 if (iptr->op1 == 0) {
2040 gen_nullptr_check(s1);
2043 M_S8ADDQ(s2, s1, REG_ITMP1);
2044 M_LST(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
2047 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
2049 var_to_reg_int(s1, src->prev, REG_ITMP1);
2050 var_to_reg_int(s2, src, REG_ITMP2);
2051 if (iptr->op1 == 0) {
2052 gen_nullptr_check(s1);
2055 M_SAADDQ(s2, s1, REG_ITMP1);
2056 M_AST(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
2059 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
2061 var_to_reg_int(s1, src->prev, REG_ITMP1);
2062 var_to_reg_int(s2, src, REG_ITMP2);
2063 if (iptr->op1 == 0) {
2064 gen_nullptr_check(s1);
2067 if (has_ext_instr_set) {
2068 M_LADD(s2, s1, REG_ITMP1);
2069 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2072 M_LADD(s2, s1, REG_ITMP1);
2073 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2074 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2075 M_INSBL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2076 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2077 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2078 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2082 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
2084 var_to_reg_int(s1, src->prev, REG_ITMP1);
2085 var_to_reg_int(s2, src, REG_ITMP2);
2086 if (iptr->op1 == 0) {
2087 gen_nullptr_check(s1);
2090 if (has_ext_instr_set) {
2091 M_LADD(s2, s1, REG_ITMP1);
2092 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2093 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
2096 M_LADD(s2, s1, REG_ITMP1);
2097 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2098 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2099 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2100 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2101 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2102 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2103 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2107 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
2109 var_to_reg_int(s1, src->prev, REG_ITMP1);
2110 var_to_reg_int(s2, src, REG_ITMP2);
2111 if (iptr->op1 == 0) {
2112 gen_nullptr_check(s1);
2115 if (has_ext_instr_set) {
2116 M_LADD(s2, s1, REG_ITMP1);
2117 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2118 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2121 M_LADD(s2, s1, REG_ITMP1);
2122 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2123 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2124 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2125 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2126 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2127 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2128 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2133 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2134 /* op1 = type, val.a = field address */
2136 /* If the static fields' class is not yet initialized, we do it */
2137 /* now. The call code is generated later. */
2138 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
2139 codegen_addclinitref(cd, mcodeptr, ((fieldinfo *) iptr->val.a)->class);
2141 /* This is just for debugging purposes. Is very difficult to */
2142 /* read patched code. Here we patch the following 2 nop's */
2143 /* so that the real code keeps untouched. */
2144 if (showdisassemble) {
2149 a = dseg_addaddress(cd, &(((fieldinfo *)(iptr->val.a))->value));
2150 M_ALD(REG_ITMP1, REG_PV, a);
2151 switch (iptr->op1) {
2153 var_to_reg_int(s2, src, REG_ITMP2);
2154 M_IST(s2, REG_ITMP1, 0);
2157 var_to_reg_int(s2, src, REG_ITMP2);
2158 M_LST(s2, REG_ITMP1, 0);
2161 var_to_reg_int(s2, src, REG_ITMP2);
2162 M_AST(s2, REG_ITMP1, 0);
2165 var_to_reg_flt(s2, src, REG_FTMP2);
2166 M_FST(s2, REG_ITMP1, 0);
2169 var_to_reg_flt(s2, src, REG_FTMP2);
2170 M_DST(s2, REG_ITMP1, 0);
2172 default: panic ("internal error");
2176 case ICMD_GETSTATIC: /* ... ==> ..., value */
2177 /* op1 = type, val.a = field address */
2179 /* if class isn't yet initialized, do it */
2180 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
2181 codegen_addclinitref(cd, mcodeptr, ((fieldinfo *) iptr->val.a)->class);
2183 /* This is just for debugging purposes. Is very difficult to */
2184 /* read patched code. Here we patch the following 2 nop's */
2185 /* so that the real code keeps untouched. */
2186 if (showdisassemble) {
2191 a = dseg_addaddress(cd, &(((fieldinfo *) iptr->val.a)->value));
2192 M_ALD(REG_ITMP1, REG_PV, a);
2193 switch (iptr->op1) {
2195 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2196 M_ILD(d, REG_ITMP1, 0);
2197 store_reg_to_var_int(iptr->dst, d);
2200 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2201 M_LLD(d, REG_ITMP1, 0);
2202 store_reg_to_var_int(iptr->dst, d);
2205 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2206 M_ALD(d, REG_ITMP1, 0);
2207 store_reg_to_var_int(iptr->dst, d);
2210 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2211 M_FLD(d, REG_ITMP1, 0);
2212 store_reg_to_var_flt(iptr->dst, d);
2215 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2216 M_DLD(d, REG_ITMP1, 0);
2217 store_reg_to_var_flt(iptr->dst, d);
2219 default: panic ("internal error");
2224 case ICMD_PUTFIELD: /* ..., value ==> ... */
2225 /* op1 = type, val.i = field offset */
2227 a = ((fieldinfo *) iptr->val.a)->offset;
2228 switch (iptr->op1) {
2230 var_to_reg_int(s1, src->prev, REG_ITMP1);
2231 var_to_reg_int(s2, src, REG_ITMP2);
2232 gen_nullptr_check(s1);
2236 var_to_reg_int(s1, src->prev, REG_ITMP1);
2237 var_to_reg_int(s2, src, REG_ITMP2);
2238 gen_nullptr_check(s1);
2242 var_to_reg_int(s1, src->prev, REG_ITMP1);
2243 var_to_reg_int(s2, src, REG_ITMP2);
2244 gen_nullptr_check(s1);
2248 var_to_reg_int(s1, src->prev, REG_ITMP1);
2249 var_to_reg_flt(s2, src, REG_FTMP2);
2250 gen_nullptr_check(s1);
2254 var_to_reg_int(s1, src->prev, REG_ITMP1);
2255 var_to_reg_flt(s2, src, REG_FTMP2);
2256 gen_nullptr_check(s1);
2259 default: panic ("internal error");
2263 case ICMD_GETFIELD: /* ... ==> ..., value */
2264 /* op1 = type, val.i = field offset */
2266 a = ((fieldinfo *)(iptr->val.a))->offset;
2267 switch (iptr->op1) {
2269 var_to_reg_int(s1, src, REG_ITMP1);
2270 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2271 gen_nullptr_check(s1);
2273 store_reg_to_var_int(iptr->dst, d);
2276 var_to_reg_int(s1, src, REG_ITMP1);
2277 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2278 gen_nullptr_check(s1);
2280 store_reg_to_var_int(iptr->dst, d);
2283 var_to_reg_int(s1, src, REG_ITMP1);
2284 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2285 gen_nullptr_check(s1);
2287 store_reg_to_var_int(iptr->dst, d);
2290 var_to_reg_int(s1, src, REG_ITMP1);
2291 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2292 gen_nullptr_check(s1);
2294 store_reg_to_var_flt(iptr->dst, d);
2297 var_to_reg_int(s1, src, REG_ITMP1);
2298 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2299 gen_nullptr_check(s1);
2301 store_reg_to_var_flt(iptr->dst, d);
2303 default: panic ("internal error");
2308 /* branch operations **************************************************/
2310 #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}}
2312 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2314 var_to_reg_int(s1, src, REG_ITMP1);
2315 M_INTMOVE(s1, REG_ITMP1_XPTR);
2316 a = dseg_addaddress(cd, asm_handle_exception);
2317 M_ALD(REG_ITMP2, REG_PV, a);
2318 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2319 M_NOP; /* nop ensures that XPC is less than the end */
2320 /* of basic block */
2324 case ICMD_GOTO: /* ... ==> ... */
2325 /* op1 = target JavaVM pc */
2327 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2331 case ICMD_JSR: /* ... ==> ... */
2332 /* op1 = target JavaVM pc */
2334 M_BSR(REG_ITMP1, 0);
2335 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2338 case ICMD_RET: /* ... ==> ... */
2339 /* op1 = local variable */
2341 var = &(rd->locals[iptr->op1][TYPE_ADR]);
2342 if (var->flags & INMEMORY) {
2343 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2344 M_RET(REG_ZERO, REG_ITMP1);
2347 M_RET(REG_ZERO, var->regoff);
2351 case ICMD_IFNULL: /* ..., value ==> ... */
2352 /* op1 = target JavaVM pc */
2354 var_to_reg_int(s1, src, REG_ITMP1);
2356 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2359 case ICMD_IFNONNULL: /* ..., value ==> ... */
2360 /* op1 = target JavaVM pc */
2362 var_to_reg_int(s1, src, REG_ITMP1);
2364 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2367 case ICMD_IFEQ: /* ..., value ==> ... */
2368 /* op1 = target JavaVM pc, val.i = constant */
2370 var_to_reg_int(s1, src, REG_ITMP1);
2371 if (iptr->val.i == 0) {
2375 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2376 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2379 ICONST(REG_ITMP2, iptr->val.i);
2380 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2382 M_BNEZ(REG_ITMP1, 0);
2384 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2387 case ICMD_IFLT: /* ..., value ==> ... */
2388 /* op1 = target JavaVM pc, val.i = constant */
2390 var_to_reg_int(s1, src, REG_ITMP1);
2391 if (iptr->val.i == 0) {
2395 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2396 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2399 ICONST(REG_ITMP2, iptr->val.i);
2400 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2402 M_BNEZ(REG_ITMP1, 0);
2404 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2407 case ICMD_IFLE: /* ..., value ==> ... */
2408 /* op1 = target JavaVM pc, val.i = constant */
2410 var_to_reg_int(s1, src, REG_ITMP1);
2411 if (iptr->val.i == 0) {
2415 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2416 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2419 ICONST(REG_ITMP2, iptr->val.i);
2420 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2422 M_BNEZ(REG_ITMP1, 0);
2424 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2427 case ICMD_IFNE: /* ..., value ==> ... */
2428 /* op1 = target JavaVM pc, val.i = constant */
2430 var_to_reg_int(s1, src, REG_ITMP1);
2431 if (iptr->val.i == 0) {
2435 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2436 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2439 ICONST(REG_ITMP2, iptr->val.i);
2440 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2442 M_BEQZ(REG_ITMP1, 0);
2444 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2447 case ICMD_IFGT: /* ..., value ==> ... */
2448 /* op1 = target JavaVM pc, val.i = constant */
2450 var_to_reg_int(s1, src, REG_ITMP1);
2451 if (iptr->val.i == 0) {
2455 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2456 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2459 ICONST(REG_ITMP2, iptr->val.i);
2460 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2462 M_BEQZ(REG_ITMP1, 0);
2464 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2467 case ICMD_IFGE: /* ..., value ==> ... */
2468 /* op1 = target JavaVM pc, val.i = constant */
2470 var_to_reg_int(s1, src, REG_ITMP1);
2471 if (iptr->val.i == 0) {
2475 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2476 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2479 ICONST(REG_ITMP2, iptr->val.i);
2480 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2482 M_BEQZ(REG_ITMP1, 0);
2484 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2487 case ICMD_IF_LEQ: /* ..., value ==> ... */
2488 /* op1 = target JavaVM pc, val.l = constant */
2490 var_to_reg_int(s1, src, REG_ITMP1);
2491 if (iptr->val.l == 0) {
2495 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2496 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2499 LCONST(REG_ITMP2, iptr->val.l);
2500 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2502 M_BNEZ(REG_ITMP1, 0);
2504 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2507 case ICMD_IF_LLT: /* ..., value ==> ... */
2508 /* op1 = target JavaVM pc, val.l = constant */
2510 var_to_reg_int(s1, src, REG_ITMP1);
2511 if (iptr->val.l == 0) {
2515 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2516 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2519 LCONST(REG_ITMP2, iptr->val.l);
2520 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2522 M_BNEZ(REG_ITMP1, 0);
2524 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2527 case ICMD_IF_LLE: /* ..., value ==> ... */
2528 /* op1 = target JavaVM pc, val.l = constant */
2530 var_to_reg_int(s1, src, REG_ITMP1);
2531 if (iptr->val.l == 0) {
2535 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2536 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2539 LCONST(REG_ITMP2, iptr->val.l);
2540 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2542 M_BNEZ(REG_ITMP1, 0);
2544 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2547 case ICMD_IF_LNE: /* ..., value ==> ... */
2548 /* op1 = target JavaVM pc, val.l = constant */
2550 var_to_reg_int(s1, src, REG_ITMP1);
2551 if (iptr->val.l == 0) {
2555 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2556 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2559 LCONST(REG_ITMP2, iptr->val.l);
2560 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2562 M_BEQZ(REG_ITMP1, 0);
2564 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2567 case ICMD_IF_LGT: /* ..., value ==> ... */
2568 /* op1 = target JavaVM pc, val.l = constant */
2570 var_to_reg_int(s1, src, REG_ITMP1);
2571 if (iptr->val.l == 0) {
2575 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2576 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2579 LCONST(REG_ITMP2, iptr->val.l);
2580 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2582 M_BEQZ(REG_ITMP1, 0);
2584 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2587 case ICMD_IF_LGE: /* ..., value ==> ... */
2588 /* op1 = target JavaVM pc, val.l = constant */
2590 var_to_reg_int(s1, src, REG_ITMP1);
2591 if (iptr->val.l == 0) {
2595 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2596 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2599 LCONST(REG_ITMP2, iptr->val.l);
2600 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2602 M_BEQZ(REG_ITMP1, 0);
2604 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2607 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2608 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2609 case ICMD_IF_ACMPEQ:
2611 var_to_reg_int(s1, src->prev, REG_ITMP1);
2612 var_to_reg_int(s2, src, REG_ITMP2);
2613 M_CMPEQ(s1, s2, REG_ITMP1);
2614 M_BNEZ(REG_ITMP1, 0);
2615 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2618 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2619 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2620 case ICMD_IF_ACMPNE:
2622 var_to_reg_int(s1, src->prev, REG_ITMP1);
2623 var_to_reg_int(s2, src, REG_ITMP2);
2624 M_CMPEQ(s1, s2, REG_ITMP1);
2625 M_BEQZ(REG_ITMP1, 0);
2626 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2629 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2630 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2632 var_to_reg_int(s1, src->prev, REG_ITMP1);
2633 var_to_reg_int(s2, src, REG_ITMP2);
2634 M_CMPLT(s1, s2, REG_ITMP1);
2635 M_BNEZ(REG_ITMP1, 0);
2636 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2639 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2640 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2642 var_to_reg_int(s1, src->prev, REG_ITMP1);
2643 var_to_reg_int(s2, src, REG_ITMP2);
2644 M_CMPLE(s1, s2, REG_ITMP1);
2645 M_BEQZ(REG_ITMP1, 0);
2646 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2649 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2650 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2652 var_to_reg_int(s1, src->prev, REG_ITMP1);
2653 var_to_reg_int(s2, src, REG_ITMP2);
2654 M_CMPLE(s1, s2, REG_ITMP1);
2655 M_BNEZ(REG_ITMP1, 0);
2656 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2659 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2660 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2662 var_to_reg_int(s1, src->prev, REG_ITMP1);
2663 var_to_reg_int(s2, src, REG_ITMP2);
2664 M_CMPLT(s1, s2, REG_ITMP1);
2665 M_BEQZ(REG_ITMP1, 0);
2666 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2669 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2671 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2674 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2675 /* val.i = constant */
2677 var_to_reg_int(s1, src, REG_ITMP1);
2678 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2680 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2681 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2682 M_CMPEQ(s1, REG_ZERO, d);
2683 store_reg_to_var_int(iptr->dst, d);
2686 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2687 M_CMPEQ(s1, REG_ZERO, d);
2689 store_reg_to_var_int(iptr->dst, d);
2693 M_MOV(s1, REG_ITMP1);
2696 ICONST(d, iptr[1].val.i);
2698 if ((s3 >= 0) && (s3 <= 255)) {
2699 M_CMOVEQ_IMM(s1, s3, d);
2702 ICONST(REG_ITMP2, s3);
2703 M_CMOVEQ(s1, REG_ITMP2, d);
2705 store_reg_to_var_int(iptr->dst, d);
2708 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2709 /* val.i = constant */
2711 var_to_reg_int(s1, src, REG_ITMP1);
2712 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2714 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2715 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2716 M_CMPEQ(s1, REG_ZERO, d);
2717 store_reg_to_var_int(iptr->dst, d);
2720 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2721 M_CMPEQ(s1, REG_ZERO, d);
2723 store_reg_to_var_int(iptr->dst, d);
2727 M_MOV(s1, REG_ITMP1);
2730 ICONST(d, iptr[1].val.i);
2732 if ((s3 >= 0) && (s3 <= 255)) {
2733 M_CMOVNE_IMM(s1, s3, d);
2736 ICONST(REG_ITMP2, s3);
2737 M_CMOVNE(s1, REG_ITMP2, d);
2739 store_reg_to_var_int(iptr->dst, d);
2742 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2743 /* val.i = constant */
2745 var_to_reg_int(s1, src, REG_ITMP1);
2746 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2748 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2749 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2750 M_CMPLT(s1, REG_ZERO, d);
2751 store_reg_to_var_int(iptr->dst, d);
2754 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2755 M_CMPLE(REG_ZERO, s1, d);
2756 store_reg_to_var_int(iptr->dst, d);
2760 M_MOV(s1, REG_ITMP1);
2763 ICONST(d, iptr[1].val.i);
2765 if ((s3 >= 0) && (s3 <= 255)) {
2766 M_CMOVLT_IMM(s1, s3, d);
2769 ICONST(REG_ITMP2, s3);
2770 M_CMOVLT(s1, REG_ITMP2, d);
2772 store_reg_to_var_int(iptr->dst, d);
2775 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2776 /* val.i = constant */
2778 var_to_reg_int(s1, src, REG_ITMP1);
2779 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2781 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2782 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2783 M_CMPLE(REG_ZERO, s1, d);
2784 store_reg_to_var_int(iptr->dst, d);
2787 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2788 M_CMPLT(s1, REG_ZERO, d);
2789 store_reg_to_var_int(iptr->dst, d);
2793 M_MOV(s1, REG_ITMP1);
2796 ICONST(d, iptr[1].val.i);
2798 if ((s3 >= 0) && (s3 <= 255)) {
2799 M_CMOVGE_IMM(s1, s3, d);
2802 ICONST(REG_ITMP2, s3);
2803 M_CMOVGE(s1, REG_ITMP2, d);
2805 store_reg_to_var_int(iptr->dst, d);
2808 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2809 /* val.i = constant */
2811 var_to_reg_int(s1, src, REG_ITMP1);
2812 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2814 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2815 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2816 M_CMPLT(REG_ZERO, s1, d);
2817 store_reg_to_var_int(iptr->dst, d);
2820 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2821 M_CMPLE(s1, REG_ZERO, d);
2822 store_reg_to_var_int(iptr->dst, d);
2826 M_MOV(s1, REG_ITMP1);
2829 ICONST(d, iptr[1].val.i);
2831 if ((s3 >= 0) && (s3 <= 255)) {
2832 M_CMOVGT_IMM(s1, s3, d);
2835 ICONST(REG_ITMP2, s3);
2836 M_CMOVGT(s1, REG_ITMP2, d);
2838 store_reg_to_var_int(iptr->dst, d);
2841 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2842 /* val.i = constant */
2844 var_to_reg_int(s1, src, REG_ITMP1);
2845 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2847 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2848 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2849 M_CMPLE(s1, REG_ZERO, d);
2850 store_reg_to_var_int(iptr->dst, d);
2853 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2854 M_CMPLT(REG_ZERO, s1, d);
2855 store_reg_to_var_int(iptr->dst, d);
2859 M_MOV(s1, REG_ITMP1);
2862 ICONST(d, iptr[1].val.i);
2864 if ((s3 >= 0) && (s3 <= 255)) {
2865 M_CMOVLE_IMM(s1, s3, d);
2868 ICONST(REG_ITMP2, s3);
2869 M_CMOVLE(s1, REG_ITMP2, d);
2871 store_reg_to_var_int(iptr->dst, d);
2875 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2879 var_to_reg_int(s1, src, REG_RESULT);
2880 M_INTMOVE(s1, REG_RESULT);
2882 #if defined(USE_THREADS)
2883 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2885 a = dseg_addaddress(cd, (void *) (builtin_monitorexit));
2886 M_ALD(REG_PV, REG_PV, a);
2887 M_ALD(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
2888 M_LST(REG_RESULT, REG_SP, rd->maxmemuse * 8);
2889 M_JSR(REG_RA, REG_PV);
2890 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
2891 M_LDA(REG_PV, REG_RA, disp);
2892 M_LLD(REG_RESULT, REG_SP, rd->maxmemuse * 8);
2896 goto nowperformreturn;
2898 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2901 var_to_reg_flt(s1, src, REG_FRESULT);
2902 M_FLTMOVE(s1, REG_FRESULT);
2904 #if defined(USE_THREADS)
2905 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2907 a = dseg_addaddress(cd, (void *) (builtin_monitorexit));
2908 M_ALD(REG_PV, REG_PV, a);
2909 M_ALD(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
2910 M_DST(REG_FRESULT, REG_SP, rd->maxmemuse * 8);
2911 M_JSR(REG_RA, REG_PV);
2912 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
2913 M_LDA(REG_PV, REG_RA, disp);
2914 M_DLD(REG_FRESULT, REG_SP, rd->maxmemuse * 8);
2918 goto nowperformreturn;
2920 case ICMD_RETURN: /* ... ==> ... */
2922 #if defined(USE_THREADS)
2923 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2925 a = dseg_addaddress(cd, (void *) (builtin_monitorexit));
2926 M_ALD(REG_PV, REG_PV, a);
2927 M_ALD(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
2928 M_JSR(REG_RA, REG_PV);
2929 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
2930 M_LDA(REG_PV, REG_RA, disp);
2938 p = parentargs_base;
2940 /* restore return address */
2942 if (!m->isleafmethod) {
2943 p--; M_LLD(REG_RA, REG_SP, p * 8);
2946 /* restore saved registers */
2948 for (i = rd->savintregcnt - 1; i >= rd->maxsavintreguse; i--) {
2949 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2951 for (i = rd->savfltregcnt - 1; i >= rd->maxsavfltreguse; i--) {
2952 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2955 /* deallocate stack */
2957 if (parentargs_base) {
2958 M_LDA(REG_SP, REG_SP, parentargs_base * 8);
2961 /* call trace function */
2964 M_LDA(REG_SP, REG_SP, -3 * 8);
2965 M_AST(REG_RA, REG_SP, 0 * 8);
2966 M_LST(REG_RESULT, REG_SP, 1 * 8);
2967 M_DST(REG_FRESULT, REG_SP, 2 * 8);
2968 a = dseg_addaddress(cd, m);
2969 M_ALD(rd->argintregs[0], REG_PV, a);
2970 M_MOV(REG_RESULT, rd->argintregs[1]);
2971 M_FLTMOVE(REG_FRESULT, rd->argfltregs[2]);
2972 M_FLTMOVE(REG_FRESULT, rd->argfltregs[3]);
2973 a = dseg_addaddress(cd, (void *) builtin_displaymethodstop);
2974 M_ALD(REG_PV, REG_PV, a);
2975 M_JSR(REG_RA, REG_PV);
2976 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
2977 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
2979 s4 ml = -s1, mh = 0;
2980 while (ml < -32768) { ml += 65536; mh--; }
2981 M_LDA(REG_PV, REG_RA, ml);
2982 M_LDAH(REG_PV, REG_PV, mh);
2984 M_DLD(REG_FRESULT, REG_SP, 2 * 8);
2985 M_LLD(REG_RESULT, REG_SP, 1 * 8);
2986 M_ALD(REG_RA, REG_SP, 0 * 8);
2987 M_LDA(REG_SP, REG_SP, 3 * 8);
2990 M_RET(REG_ZERO, REG_RA);
2996 case ICMD_TABLESWITCH: /* ..., index ==> ... */
3001 tptr = (void **) iptr->target;
3003 s4ptr = iptr->val.a;
3004 l = s4ptr[1]; /* low */
3005 i = s4ptr[2]; /* high */
3007 var_to_reg_int(s1, src, REG_ITMP1);
3009 {M_INTMOVE(s1, REG_ITMP1);}
3010 else if (l <= 32768) {
3011 M_LDA(REG_ITMP1, s1, -l);
3014 ICONST(REG_ITMP2, l);
3015 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
3022 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
3024 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
3025 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3027 M_BEQZ(REG_ITMP2, 0);
3030 /* codegen_addreference(cd, BlockPtrOfPC(s4ptr[0]), mcodeptr); */
3031 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3033 /* build jump table top down and use address of lowest entry */
3035 /* s4ptr += 3 + i; */
3039 /* dseg_addtarget(cd, BlockPtrOfPC(*--s4ptr)); */
3040 dseg_addtarget(cd, (basicblock *) tptr[0]);
3045 /* length of dataseg after last dseg_addtarget is used by load */
3047 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
3048 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
3049 M_JMP(REG_ZERO, REG_ITMP2);
3054 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3056 s4 i, l, val, *s4ptr;
3059 tptr = (void **) iptr->target;
3061 s4ptr = iptr->val.a;
3062 l = s4ptr[0]; /* default */
3063 i = s4ptr[1]; /* count */
3065 MCODECHECK((i<<2)+8);
3066 var_to_reg_int(s1, src, REG_ITMP1);
3072 if ((val >= 0) && (val <= 255)) {
3073 M_CMPEQ_IMM(s1, val, REG_ITMP2);
3076 if ((val >= -32768) && (val <= 32767)) {
3077 M_LDA(REG_ITMP2, REG_ZERO, val);
3080 a = dseg_adds4(cd, val);
3081 M_ILD(REG_ITMP2, REG_PV, a);
3083 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
3085 M_BNEZ(REG_ITMP2, 0);
3086 /* codegen_addreference(cd, BlockPtrOfPC(s4ptr[1]), mcodeptr); */
3087 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3091 /* codegen_addreference(cd, BlockPtrOfPC(l), mcodeptr); */
3093 tptr = (void **) iptr->target;
3094 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3101 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
3102 /* op1 = return type, val.a = function pointer*/
3106 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
3107 /* op1 = return type, val.a = function pointer*/
3111 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
3112 /* op1 = return type, val.a = function pointer*/
3116 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3117 /* op1 = arg count, val.a = method pointer */
3119 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3120 /* op1 = arg count, val.a = method pointer */
3122 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3123 /* op1 = arg count, val.a = method pointer */
3125 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
3126 /* op1 = arg count, val.a = method pointer */
3133 MCODECHECK((s3 << 1) + 64);
3135 /* copy arguments to registers or stack location */
3137 for (; --s3 >= 0; src = src->prev) {
3138 if (src->varkind == ARGVAR)
3140 if (IS_INT_LNG_TYPE(src->type)) {
3141 if (s3 < INT_ARG_CNT) {
3142 s1 = rd->argintregs[s3];
3143 var_to_reg_int(d, src, s1);
3147 var_to_reg_int(d, src, REG_ITMP1);
3148 M_LST(d, REG_SP, 8 * (s3 - INT_ARG_CNT));
3152 if (s3 < FLT_ARG_CNT) {
3153 s1 = rd->argfltregs[s3];
3154 var_to_reg_flt(d, src, s1);
3158 var_to_reg_flt(d, src, REG_FTMP1);
3159 M_DST(d, REG_SP, 8 * (s3 - FLT_ARG_CNT));
3165 switch (iptr->opc) {
3169 a = dseg_addaddress(cd, (void *) lm);
3172 M_ALD(REG_PV, REG_PV, a); /* Pointer to built-in-function */
3175 case ICMD_INVOKESTATIC:
3176 case ICMD_INVOKESPECIAL:
3177 a = dseg_addaddress(cd, lm->stubroutine);
3180 M_ALD(REG_PV, REG_PV, a); /* method pointer in r27 */
3183 case ICMD_INVOKEVIRTUAL:
3186 gen_nullptr_check(rd->argintregs[0]);
3187 M_ALD(REG_METHODPTR, rd->argintregs[0],
3188 OFFSET(java_objectheader, vftbl));
3189 M_ALD(REG_PV, REG_METHODPTR, OFFSET(vftbl_t, table[0]) +
3190 sizeof(methodptr) * lm->vftblindex);
3193 case ICMD_INVOKEINTERFACE:
3196 gen_nullptr_check(rd->argintregs[0]);
3197 M_ALD(REG_METHODPTR, rd->argintregs[0],
3198 OFFSET(java_objectheader, vftbl));
3199 M_ALD(REG_METHODPTR, REG_METHODPTR,
3200 OFFSET(vftbl_t, interfacetable[0]) -
3201 sizeof(methodptr*) * lm->class->index);
3202 M_ALD(REG_PV, REG_METHODPTR,
3203 sizeof(methodptr) * (lm - lm->class->methods));
3207 M_JSR(REG_RA, REG_PV);
3211 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3212 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3214 s4 ml = -s1, mh = 0;
3215 while (ml < -32768) { ml += 65536; mh--; }
3216 M_LDA(REG_PV, REG_RA, ml);
3217 M_LDAH(REG_PV, REG_PV, mh);
3220 /* d contains return type */
3222 if (d != TYPE_VOID) {
3223 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3224 s1 = reg_of_var(rd, iptr->dst, REG_RESULT);
3225 M_INTMOVE(REG_RESULT, s1);
3226 store_reg_to_var_int(iptr->dst, s1);
3229 s1 = reg_of_var(rd, iptr->dst, REG_FRESULT);
3230 M_FLTMOVE(REG_FRESULT, s1);
3231 store_reg_to_var_flt(iptr->dst, s1);
3238 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3240 /* op1: 0 == array, 1 == class */
3241 /* val.a: (classinfo*) superclass */
3243 /* superclass is an interface:
3245 * return (sub != NULL) &&
3246 * (sub->vftbl->interfacetablelength > super->index) &&
3247 * (sub->vftbl->interfacetable[-super->index] != NULL);
3249 * superclass is a class:
3251 * return ((sub != NULL) && (0
3252 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3253 * super->vftbl->diffvall));
3257 classinfo *super = (classinfo*) iptr->val.a;
3259 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3260 codegen_threadcritrestart(cd, (u1 *) mcodeptr - cd->mcodebase);
3262 var_to_reg_int(s1, src, REG_ITMP1);
3263 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
3265 M_MOV(s1, REG_ITMP1);
3269 if (iptr->op1) { /* class/interface */
3270 if (super->flags & ACC_INTERFACE) { /* interface */
3272 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3273 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3274 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3275 M_BLEZ(REG_ITMP2, 2);
3276 M_ALD(REG_ITMP1, REG_ITMP1,
3277 OFFSET(vftbl_t, interfacetable[0]) -
3278 super->index * sizeof(methodptr*));
3279 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3283 s2 = super->vftbl->diffval;
3284 M_BEQZ(s1, 4 + (s2 > 255));
3285 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3286 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3287 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3289 M_CMPULE_IMM(REG_ITMP1, s2, d);
3291 M_LDA(REG_ITMP2, REG_ZERO, s2);
3292 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3296 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3297 a = dseg_addaddress(cd, (void*) super->vftbl);
3298 M_ALD(REG_ITMP2, REG_PV, a);
3299 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3300 codegen_threadcritstart(cd, (u1 *) mcodeptr - cd->mcodebase);
3302 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3303 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3304 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3305 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3306 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3308 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3309 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3313 panic ("internal error: no inlined array instanceof");
3315 store_reg_to_var_int(iptr->dst, d);
3318 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3320 /* op1: 0 == array, 1 == class */
3321 /* val.a: (classinfo*) superclass */
3323 /* superclass is an interface:
3325 * OK if ((sub == NULL) ||
3326 * (sub->vftbl->interfacetablelength > super->index) &&
3327 * (sub->vftbl->interfacetable[-super->index] != NULL));
3329 * superclass is a class:
3331 * OK if ((sub == NULL) || (0
3332 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3333 * super->vftbl->diffvall));
3337 classinfo *super = (classinfo *) iptr->val.a;
3339 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3340 codegen_threadcritrestart(cd, (u1 *) mcodeptr - cd->mcodebase);
3342 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
3343 var_to_reg_int(s1, src, d);
3344 if (iptr->op1) { /* class/interface */
3345 if (super->flags & ACC_INTERFACE) { /* interface */
3347 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3348 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3349 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3350 M_BLEZ(REG_ITMP2, 0);
3351 codegen_addxcastrefs(cd, mcodeptr);
3352 M_ALD(REG_ITMP2, REG_ITMP1,
3353 OFFSET(vftbl_t, interfacetable[0]) -
3354 super->index * sizeof(methodptr*));
3355 M_BEQZ(REG_ITMP2, 0);
3356 codegen_addxcastrefs(cd, mcodeptr);
3360 s2 = super->vftbl->diffval;
3361 M_BEQZ(s1, 4 + (s2 != 0) + (s2 > 255));
3362 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3363 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3364 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3366 M_BNEZ(REG_ITMP1, 0);
3368 else if (s2 <= 255) {
3369 M_CMPULE_IMM(REG_ITMP1, s2, REG_ITMP2);
3370 M_BEQZ(REG_ITMP2, 0);
3373 M_LDA(REG_ITMP2, REG_ZERO, s2);
3374 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3375 M_BEQZ(REG_ITMP2, 0);
3378 M_BEQZ(s1, 8 + (d == REG_ITMP3));
3379 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3380 a = dseg_addaddress(cd, (void *) super->vftbl);
3381 M_ALD(REG_ITMP2, REG_PV, a);
3382 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3383 codegen_threadcritstart(cd, (u1 *) mcodeptr - cd->mcodebase);
3385 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3386 if (d != REG_ITMP3) {
3387 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3388 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3389 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3390 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3392 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3395 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3396 M_ISUB(REG_ITMP1, REG_ITMP2, REG_ITMP1);
3397 M_ALD(REG_ITMP2, REG_PV, a);
3398 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3399 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3400 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3403 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3404 M_BEQZ(REG_ITMP2, 0);
3405 codegen_addxcastrefs(cd, mcodeptr);
3409 panic ("internal error: no inlined array checkcast");
3412 store_reg_to_var_int(iptr->dst, d);
3415 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
3417 var_to_reg_int(s1, src, REG_ITMP1);
3419 codegen_addxcheckarefs(cd, mcodeptr);
3422 case ICMD_CHECKEXCEPTION: /* ... ==> ... */
3424 M_BEQZ(REG_RESULT, 0);
3425 codegen_addxexceptionrefs(cd, mcodeptr);
3428 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3429 /* op1 = dimension, val.a = array descriptor */
3431 /* check for negative sizes and copy sizes to stack if necessary */
3433 MCODECHECK((iptr->op1 << 1) + 64);
3435 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3436 var_to_reg_int(s2, src, REG_ITMP1);
3438 codegen_addxcheckarefs(cd, mcodeptr);
3440 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
3442 if (src->varkind != ARGVAR) {
3443 M_LST(s2, REG_SP, 8 * (s1 + INT_ARG_CNT));
3447 /* a0 = dimension count */
3449 ICONST(rd->argintregs[0], iptr->op1);
3451 /* a1 = arraydescriptor */
3453 a = dseg_addaddress(cd, iptr->val.a);
3454 M_ALD(rd->argintregs[1], REG_PV, a);
3456 /* a2 = pointer to dimensions = stack pointer */
3458 M_INTMOVE(REG_SP, rd->argintregs[2]);
3460 a = dseg_addaddress(cd, (void *) builtin_nmultianewarray);
3461 M_ALD(REG_PV, REG_PV, a);
3462 M_JSR(REG_RA, REG_PV);
3463 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3465 M_LDA(REG_PV, REG_RA, -s1);
3467 s4 ml = -s1, mh = 0;
3468 while (ml < -32768) { ml += 65536; mh--; }
3469 M_LDA(REG_PV, REG_RA, ml);
3470 M_LDAH(REG_PV, REG_PV, mh);
3472 s1 = reg_of_var(rd, iptr->dst, REG_RESULT);
3473 M_INTMOVE(REG_RESULT, s1);
3474 store_reg_to_var_int(iptr->dst, s1);
3477 case ICMD_INLINE_START:
3478 case ICMD_INLINE_END:
3481 default: error ("Unknown pseudo command: %d", iptr->opc);
3487 } /* for instruction */
3489 /* copy values to interface registers */
3491 src = bptr->outstack;
3492 len = bptr->outdepth;
3499 if ((src->varkind != STACKVAR)) {
3501 if (IS_FLT_DBL_TYPE(s2)) {
3502 var_to_reg_flt(s1, src, REG_FTMP1);
3503 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3504 M_FLTMOVE(s1,rd->interfaces[len][s2].regoff);
3507 M_DST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3511 var_to_reg_int(s1, src, REG_ITMP1);
3512 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3513 M_INTMOVE(s1,rd->interfaces[len][s2].regoff);
3516 M_LST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3522 } /* if (bptr -> flags >= BBREACHED) */
3523 } /* for basic block */
3525 codegen_createlinenumbertable(cd);
3528 /* generate bound check stubs */
3530 s4 *xcodeptr = NULL;
3533 for (bref = cd->xboundrefs; bref != NULL; bref = bref->next) {
3534 gen_resolvebranch((u1*) cd->mcodebase + bref->branchpos,
3536 (u1*) mcodeptr - cd->mcodebase);
3540 /* move index register into REG_ITMP1 */
3541 M_MOV(bref->reg, REG_ITMP1);
3542 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3544 if (xcodeptr != NULL) {
3545 M_BR(xcodeptr - mcodeptr - 1);
3548 xcodeptr = mcodeptr;
3550 a = dseg_addaddress(cd, asm_throw_and_handle_arrayindexoutofbounds_exception);
3551 M_ALD(REG_PV, REG_PV, a);
3553 M_JSR(REG_RA, REG_PV);
3556 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3557 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3559 s4 ml = -s1, mh = 0;
3560 while (ml < -32768) { ml += 65536; mh--; }
3561 M_LDA(REG_PV, REG_RA, ml);
3562 M_LDAH(REG_PV, REG_PV, mh);
3567 /* generate negative array size check stubs */
3571 for (bref = cd->xcheckarefs; bref != NULL; bref = bref->next) {
3572 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3573 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3575 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3579 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3581 (u1 *) mcodeptr - cd->mcodebase);
3585 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3587 if (xcodeptr != NULL) {
3588 M_BR(xcodeptr - mcodeptr - 1);
3591 xcodeptr = mcodeptr;
3594 a = dseg_addaddress(cd, string_java_lang_NegativeArraySizeException);
3595 M_ALD(REG_ITMP1_XPTR,REG_PV,a);
3597 a = dseg_addaddress(cd, asm_throw_and_handle_nat_exception);
3598 M_ALD(REG_PV, REG_PV, a);
3600 M_JSR(REG_RA, REG_PV);
3603 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3604 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3606 s4 ml = -s1, mh = 0;
3607 while (ml < -32768) { ml += 65536; mh--; }
3608 M_LDA(REG_PV, REG_RA, ml);
3609 M_LDAH(REG_PV, REG_PV, mh);
3616 /* generate cast check stubs */
3620 for (bref = cd->xcastrefs; bref != NULL; bref = bref->next) {
3621 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3622 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3624 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3628 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3630 (u1 *) mcodeptr - cd->mcodebase);
3634 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3636 if (xcodeptr != NULL) {
3637 M_BR(xcodeptr - mcodeptr - 1);
3640 xcodeptr = mcodeptr;
3642 a = dseg_addaddress(cd, string_java_lang_ClassCastException);
3643 M_ALD(REG_ITMP1_XPTR,REG_PV,a);
3645 a = dseg_addaddress(cd, asm_throw_and_handle_nat_exception);
3646 M_ALD(REG_PV, REG_PV, a);
3648 M_JSR(REG_RA, REG_PV);
3651 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3652 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3654 s4 ml = -s1, mh = 0;
3655 while (ml < -32768) { ml += 65536; mh--; }
3656 M_LDA(REG_PV, REG_RA, ml);
3657 M_LDAH(REG_PV, REG_PV, mh);
3663 /* generate exception check stubs */
3667 for (bref = cd->xexceptionrefs; bref != NULL; bref = bref->next) {
3668 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3669 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3671 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3675 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3677 (u1 *) mcodeptr - cd->mcodebase);
3681 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3683 if (xcodeptr != NULL) {
3684 M_BR(xcodeptr - mcodeptr - 1);
3687 xcodeptr = mcodeptr;
3689 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3690 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3691 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3693 a = dseg_addaddress(cd, &builtin_get_exceptionptrptr);
3694 M_ALD(REG_PV, REG_PV, a);
3695 M_JSR(REG_RA, REG_PV);
3698 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3699 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3701 s4 ml = -s1, mh = 0;
3702 while (ml < -32768) { ml += 65536; mh--; }
3703 M_LDA(REG_PV, REG_RA, ml);
3704 M_LDAH(REG_PV, REG_PV, mh);
3707 M_ALD(REG_ITMP1_XPTR, REG_RESULT, 0);
3708 M_AST(REG_ZERO, REG_RESULT, 0);
3710 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3711 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3713 a = dseg_addaddress(cd, &_exceptionptr);
3714 M_ALD(REG_ITMP3, REG_PV, a);
3715 M_ALD(REG_ITMP1_XPTR, REG_ITMP3, 0);
3716 M_AST(REG_ZERO, REG_ITMP3, 0);
3719 a = dseg_addaddress(cd, asm_refillin_and_handle_exception);
3720 M_ALD(REG_PV, REG_PV, a);
3722 M_JMP(REG_RA, REG_PV);
3725 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3726 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3728 s4 ml = -s1, mh = 0;
3729 while (ml < -32768) { ml += 65536; mh--; }
3730 M_LDA(REG_PV, REG_RA, ml);
3731 M_LDAH(REG_PV, REG_PV, mh);
3737 /* generate null pointer check stubs */
3741 for (bref = cd->xnullrefs; bref != NULL; bref = bref->next) {
3742 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3743 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3745 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3749 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3751 (u1 *) mcodeptr - cd->mcodebase);
3755 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3757 if (xcodeptr != NULL) {
3758 M_BR(xcodeptr - mcodeptr - 1);
3761 xcodeptr = mcodeptr;
3763 a = dseg_addaddress(cd, string_java_lang_NullPointerException);
3764 M_ALD(REG_ITMP1_XPTR,REG_PV,a);
3766 a = dseg_addaddress(cd, asm_throw_and_handle_nat_exception);
3767 M_ALD(REG_PV, REG_PV, a);
3769 M_JSR(REG_RA, REG_PV);
3772 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3773 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3775 s4 ml = -s1, mh = 0;
3776 while (ml < -32768) { ml += 65536; mh--; }
3777 M_LDA(REG_PV, REG_RA, ml);
3778 M_LDAH(REG_PV, REG_PV, mh);
3784 /* generate put/getstatic stub call code */
3791 for (cref = cd->clinitrefs; cref != NULL; cref = cref->next) {
3792 /* Get machine code which is patched back in later. The call is */
3793 /* 1 instruction word long. */
3794 xcodeptr = (s4 *) (cd->mcodebase + cref->branchpos);
3797 /* patch in the call to call the following code (done at compile */
3800 tmpmcodeptr = mcodeptr; /* save current mcodeptr */
3801 mcodeptr = xcodeptr; /* set mcodeptr to patch position */
3803 M_BSR(REG_RA, tmpmcodeptr - (xcodeptr + 1));
3805 mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
3809 /* move class pointer into REG_ITMP2 */
3810 a = dseg_addaddress(cd, cref->class);
3811 M_ALD(REG_ITMP1, REG_PV, a);
3813 /* move machine code onto stack */
3814 a = dseg_adds4(cd, mcode);
3815 M_ILD(REG_ITMP3, REG_PV, a);
3816 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3817 M_IST(REG_ITMP3, REG_SP, 0);
3819 a = dseg_addaddress(cd, asm_check_clinit);
3820 M_ALD(REG_ITMP2, REG_PV, a);
3821 M_JMP(REG_ZERO, REG_ITMP2);
3826 codegen_finish(m, cd, (s4) ((u1 *) mcodeptr - cd->mcodebase));
3830 /* function createcompilerstub *************************************************
3832 creates a stub routine which calls the compiler
3834 *******************************************************************************/
3836 #define COMPSTUBSIZE 3
3838 u1 *createcompilerstub(methodinfo *m)
3840 u8 *s = CNEW(u8, COMPSTUBSIZE); /* memory to hold the stub */
3841 s4 *mcodeptr = (s4 *) s; /* code generation pointer */
3843 /* code for the stub */
3844 M_ALD(REG_PV, REG_PV, 16); /* load pointer to the compiler */
3845 M_JMP(0, REG_PV); /* jump to the compiler, return address
3846 in reg 0 is used as method pointer */
3847 s[1] = (u8) m; /* literals to be adressed */
3848 s[2] = (u8) asm_call_jit_compiler; /* jump directly via PV from above */
3850 #if defined(STATISTICS)
3852 count_cstub_len += COMPSTUBSIZE * 8;
3859 /* function removecompilerstub *************************************************
3861 deletes a compilerstub from memory (simply by freeing it)
3863 *******************************************************************************/
3865 void removecompilerstub(u1 *stub)
3867 CFREE(stub, COMPSTUBSIZE * 8);
3871 /* function: createnativestub **************************************************
3873 creates a stub routine which calls a native method
3875 *******************************************************************************/
3878 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3879 #define NATIVESTUB_STACK 8/*ra,native result, oldThreadspecificHeadValue, addressOfThreadspecificHead, method, 0,0,ra*/
3880 #define NATIVESTUB_THREAD_EXTRA (6 + 20) /*20 for additional frame creation*/
3881 #define NATIVESTUB_STACKTRACE_OFFSET 1
3883 #define NATIVESTUB_STACK 7/*ra,oldThreadspecificHeadValue, addressOfThreadspecificHead, method, 0,0,ra*/
3884 #define NATIVESTUB_THREAD_EXTRA (1 + 20) /*20 for additional frame creation*/
3885 #define NATIVESTUB_STACKTRACE_OFFSET 0
3888 #define NATIVESTUB_SIZE (44 + NATIVESTUB_THREAD_EXTRA - 1)
3889 #define NATIVESTUB_STATIC_SIZE 5
3890 #define NATIVESTUB_VERBOSE_SIZE (39 + 13)
3891 #define NATIVESTUB_OFFSET 11
3894 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3895 #define NATIVESTUB_STACK 2
3896 #define NATIVESTUB_THREAD_EXTRA 6
3898 #define NATIVESTUB_STACK 1
3899 #define NATIVESTUB_THREAD_EXTRA 1
3902 #define NATIVESTUB_SIZE (44 + NATIVESTUB_THREAD_EXTRA - 1)
3903 #define NATIVESTUB_STATIC_SIZE 4
3904 #define NATIVESTUB_VERBOSE_SIZE (39 + 13)
3905 #define NATIVESTUB_OFFSET 10
3908 u1 *createnativestub(functionptr f, methodinfo *m)
3910 u8 *s; /* memory pointer to hold the stub */
3912 s4 *mcodeptr; /* code generation pointer */
3913 s4 stackframesize = 0; /* size of stackframe if needed */
3918 t_inlining_globals *id;
3921 /* mark start of dump memory area */
3923 dumpsize = dump_size();
3925 /* setup registers before using it */
3927 cd = DNEW(codegendata);
3928 rd = DNEW(registerdata);
3929 id = DNEW(t_inlining_globals);
3931 inlining_setup(m, id);
3932 reg_setup(m, rd, id);
3934 descriptor2types(m); /* set paramcount and paramtypes */
3936 stubsize = NATIVESTUB_SIZE; /* calculate nativestub size */
3938 if ((m->flags & ACC_STATIC) && !m->class->initialized)
3939 stubsize += NATIVESTUB_STATIC_SIZE;
3942 stubsize += NATIVESTUB_VERBOSE_SIZE;
3944 s = CNEW(u8, stubsize); /* memory to hold the stub */
3945 cs = s + NATIVESTUB_OFFSET;
3946 mcodeptr = (s4 *) cs; /* code generation pointer */
3948 /* set some required varibles which are normally set by codegen_setup */
3949 cd->mcodebase = (u1 *) mcodeptr;
3950 cd->clinitrefs = NULL;
3952 *(cs-1) = (u8) f; /* address of native method */
3953 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3954 *(cs-2) = (u8) &builtin_get_exceptionptrptr;
3956 *(cs-2) = (u8) (&_exceptionptr); /* address of exceptionptr */
3958 *(cs-3) = (u8) asm_handle_nat_exception; /* addr of asm exception handler*/
3959 *(cs-4) = (u8) (&env); /* addr of jni_environement */
3960 *(cs-5) = (u8) builtin_trace_args;
3962 *(cs-7) = (u8) builtin_displaymethodstop;
3963 *(cs-8) = (u8) m->class;
3964 *(cs-9) = (u8) asm_check_clinit;
3965 *(cs-10) = (u8) &builtin_asm_get_stackframeinfo;
3966 *(cs-11) = (u8) NULL; /* filled with machine code */
3968 M_LDA(REG_SP, REG_SP, -NATIVESTUB_STACK * 8); /* build up stackframe */
3969 M_AST(REG_RA, REG_SP, 0 * 8); /* store return address */
3971 M_AST(REG_RA, REG_SP, (6+NATIVESTUB_STACKTRACE_OFFSET) * 8); /* store return address in stackinfo helper*/
3973 /* if function is static, check for initialized */
3975 if (m->flags & ACC_STATIC) {
3976 /* if class isn't yet initialized, do it */
3977 if (!m->class->initialized) {
3978 codegen_addclinitref(cd, mcodeptr, m->class);
3982 /* max. 39 +9 instructions */
3986 M_LDA(REG_SP, REG_SP, -((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
3987 M_AST(REG_RA, REG_SP, 1 * 8);
3989 /* save integer argument registers */
3990 for (p = 0; p < m->paramcount && p < INT_ARG_CNT; p++) {
3991 M_LST(rd->argintregs[p], REG_SP, (2 + p) * 8);
3994 /* save and copy float arguments into integer registers */
3995 for (p = 0; p < m->paramcount && p < FLT_ARG_CNT; p++) {
3996 t = m->paramtypes[p];
3998 if (IS_FLT_DBL_TYPE(t)) {
3999 if (IS_2_WORD_TYPE(t)) {
4000 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4001 M_LLD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4004 M_FST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4005 M_ILD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4009 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4014 M_ALD(REG_ITMP1, REG_PV, -6 * 8);
4015 M_AST(REG_ITMP1, REG_SP, 0 * 8);
4016 M_ALD(REG_PV, REG_PV, -5 * 8);
4017 M_JSR(REG_RA, REG_PV);
4018 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4019 M_LDA(REG_PV, REG_RA, disp);
4024 M_ALD(REG_PV, REG_PV, -10 * 8); /* builtin_asm_get_stackframeinfo */
4025 M_JSR(REG_RA, REG_PV);
4026 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4027 M_LDA(REG_PV, REG_RA, disp);
4030 M_MOV(REG_RESULT,REG_ITMP3);
4031 M_LST(REG_RESULT,REG_ITMP3,0);
4033 M_LST(REG_RESULT,REG_SP, ((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8)+(2+NATIVESTUB_STACKTRACE_OFFSET)*8);/*save adress of pointer*/
4034 M_LLD(REG_ITMP3,REG_RESULT,0); /* get pointer*/
4035 M_LST(REG_ITMP3,REG_SP,(1+NATIVESTUB_STACKTRACE_OFFSET)*8+((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8)); /*save old value*/
4036 M_LDA(REG_ITMP3,REG_SP,(1+NATIVESTUB_STACKTRACE_OFFSET)*8+((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8)); /*calculate new value*/
4037 M_LLD(REG_ITMP2,REG_ITMP3,8);
4038 M_LST(REG_ITMP3,REG_ITMP2,0); /*store new value*/
4039 M_LLD(REG_ITMP2,REG_PV,-6*8);
4040 M_LST(REG_ITMP2,REG_SP,(3+NATIVESTUB_STACKTRACE_OFFSET)*8+((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
4041 M_LST(REG_ZERO,REG_SP,(4+NATIVESTUB_STACKTRACE_OFFSET)*8+((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
4042 M_LST(REG_ZERO,REG_SP,(5+NATIVESTUB_STACKTRACE_OFFSET)*8+((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
4043 /*stack info -end */
4046 for (p = 0; p < m->paramcount && p < INT_ARG_CNT; p++) {
4047 M_LLD(rd->argintregs[p], REG_SP, (2 + p) * 8);
4050 for (p = 0; p < m->paramcount && p < FLT_ARG_CNT; p++) {
4051 t = m->paramtypes[p];
4053 if (IS_FLT_DBL_TYPE(t)) {
4054 if (IS_2_WORD_TYPE(t)) {
4055 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4058 M_FLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4062 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4066 M_ALD(REG_RA, REG_SP, 1 * 8);
4067 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT + 2) * 8);
4070 /* save argument registers on stack -- if we have to */
4071 if ((m->flags & ACC_STATIC && m->paramcount > (INT_ARG_CNT - 2)) || m->paramcount > (INT_ARG_CNT - 1)) {
4073 s4 paramshiftcnt = (m->flags & ACC_STATIC) ? 2 : 1;
4074 s4 stackparamcnt = (m->paramcount > INT_ARG_CNT) ? m->paramcount - INT_ARG_CNT : 0;
4076 stackframesize = stackparamcnt + paramshiftcnt;
4078 M_LDA(REG_SP, REG_SP, -stackframesize * 8);
4080 /* copy stack arguments into new stack frame -- if any */
4081 for (i = 0; i < stackparamcnt; i++) {
4082 M_LLD(REG_ITMP1, REG_SP, (stackparamcnt + 1 + i) * 8);
4083 M_LST(REG_ITMP1, REG_SP, (paramshiftcnt + i) * 8);
4086 if (m->flags & ACC_STATIC) {
4087 if (IS_FLT_DBL_TYPE(m->paramtypes[5])) {
4088 M_DST(rd->argfltregs[5], REG_SP, 1 * 8);
4090 M_LST(rd->argintregs[5], REG_SP, 1 * 8);
4093 if (IS_FLT_DBL_TYPE(m->paramtypes[4])) {
4094 M_DST(rd->argfltregs[4], REG_SP, 0 * 8);
4096 M_LST(rd->argintregs[4], REG_SP, 0 * 8);
4100 if (IS_FLT_DBL_TYPE(m->paramtypes[5])) {
4101 M_DST(rd->argfltregs[5], REG_SP, 0 * 8);
4103 M_LST(rd->argintregs[5], REG_SP, 0 * 8);
4108 if (m->flags & ACC_STATIC) {
4109 M_MOV(rd->argintregs[3], rd->argintregs[5]);
4110 M_MOV(rd->argintregs[2], rd->argintregs[4]);
4111 M_MOV(rd->argintregs[1], rd->argintregs[3]);
4112 M_MOV(rd->argintregs[0], rd->argintregs[2]);
4113 M_FMOV(rd->argfltregs[3], rd->argfltregs[5]);
4114 M_FMOV(rd->argfltregs[2], rd->argfltregs[4]);
4115 M_FMOV(rd->argfltregs[1], rd->argfltregs[3]);
4116 M_FMOV(rd->argfltregs[0], rd->argfltregs[2]);
4118 /* put class into second argument register */
4119 M_ALD(rd->argintregs[1], REG_PV, -8 * 8);
4122 M_MOV(rd->argintregs[4], rd->argintregs[5]);
4123 M_MOV(rd->argintregs[3], rd->argintregs[4]);
4124 M_MOV(rd->argintregs[2], rd->argintregs[3]);
4125 M_MOV(rd->argintregs[1], rd->argintregs[2]);
4126 M_MOV(rd->argintregs[0], rd->argintregs[1]);
4127 M_FMOV(rd->argfltregs[4], rd->argfltregs[5]);
4128 M_FMOV(rd->argfltregs[3], rd->argfltregs[4]);
4129 M_FMOV(rd->argfltregs[2], rd->argfltregs[3]);
4130 M_FMOV(rd->argfltregs[1], rd->argfltregs[2]);
4131 M_FMOV(rd->argfltregs[0], rd->argfltregs[1]);
4134 /* put env into first argument register */
4135 M_ALD(rd->argintregs[0], REG_PV, -4 * 8);
4137 M_ALD(REG_PV, REG_PV, -1 * 8); /* load adress of native method */
4138 M_JSR(REG_RA, REG_PV); /* call native method */
4139 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4140 M_LDA(REG_PV, REG_RA, disp); /* recompute pv from ra */
4142 /* remove stackframe if there is one */
4143 if (stackframesize) {
4144 M_LDA(REG_SP, REG_SP, stackframesize * 8);
4147 /* 13 instructions */
4149 M_LDA(REG_SP, REG_SP, -2 * 8);
4150 M_ALD(rd->argintregs[0], REG_PV, -6 * 8); /* load method adress */
4151 M_LST(REG_RESULT, REG_SP, 0 * 8);
4152 M_DST(REG_FRESULT, REG_SP, 1 * 8);
4153 M_MOV(REG_RESULT, rd->argintregs[1]);
4154 M_FMOV(REG_FRESULT, rd->argfltregs[2]);
4155 M_FMOV(REG_FRESULT, rd->argfltregs[3]);
4156 M_ALD(REG_PV, REG_PV, -7 * 8); /* builtin_displaymethodstop */
4157 M_JSR(REG_RA, REG_PV);
4158 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4159 M_LDA(REG_PV, REG_RA, disp);
4160 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4161 M_DLD(REG_FRESULT, REG_SP, 1 * 8);
4162 M_LDA(REG_SP, REG_SP, 2 * 8);
4165 M_LLD(REG_ITMP3,REG_SP,(2+NATIVESTUB_STACKTRACE_OFFSET)*8); /*get address of stacktrace helper pointer*/
4166 M_LLD(REG_ITMP1,REG_SP,(1+NATIVESTUB_STACKTRACE_OFFSET)*8); /*get old value*/
4167 M_LST(REG_ITMP1,REG_ITMP3,0); /*set old value*/
4169 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4170 if (IS_FLT_DBL_TYPE(m->returntype))
4171 M_DST(REG_FRESULT, REG_SP, 1 * 8);
4173 M_AST(REG_RESULT, REG_SP, 1 * 8);
4174 M_ALD(REG_PV, REG_PV, -2 * 8); /* builtin_get_exceptionptrptr */
4175 M_JSR(REG_RA, REG_PV);
4176 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4177 M_LDA(REG_PV, REG_RA, disp);
4178 M_MOV(REG_RESULT, REG_ITMP3);
4179 if (IS_FLT_DBL_TYPE(m->returntype))
4180 M_DLD(REG_FRESULT, REG_SP, 1 * 8);
4182 M_ALD(REG_RESULT, REG_SP, 1 * 8);
4184 M_ALD(REG_ITMP3, REG_PV, -2 * 8); /* get address of exceptionptr */
4186 M_ALD(REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
4187 M_BNEZ(REG_ITMP1, 3); /* if no exception then return */
4189 M_ALD(REG_RA, REG_SP, 0 * 8); /* load return address */
4190 M_LDA(REG_SP, REG_SP, NATIVESTUB_STACK * 8); /* remove stackframe */
4191 M_RET(REG_ZERO, REG_RA); /* return to caller */
4193 M_AST(REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
4195 M_ALD(REG_RA, REG_SP, 0 * 8); /* load return address */
4196 M_LDA(REG_SP, REG_SP, NATIVESTUB_STACK * 8); /* remove stackframe */
4197 M_LDA(REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
4198 M_ALD(REG_ITMP3, REG_PV, -3 * 8); /* load asm exception handler address */
4199 M_JMP(REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
4201 /* generate put/getstatic stub call code */
4208 /* there can only be one clinit ref entry */
4209 cref = cd->clinitrefs;
4212 /* Get machine code which is patched back in later. The call is */
4213 /* 1 instruction word long. */
4214 xcodeptr = (s4 *) (cd->mcodebase + cref->branchpos);
4215 *(cs-11) = (u4) *xcodeptr;
4217 /* patch in the call to call the following code (done at compile */
4220 tmpmcodeptr = mcodeptr; /* save current mcodeptr */
4221 mcodeptr = xcodeptr; /* set mcodeptr to patch position */
4223 M_BSR(REG_RA, tmpmcodeptr - (xcodeptr + 1));
4225 mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
4227 /* move class pointer into REG_ITMP2 */
4228 M_ALD(REG_ITMP1, REG_PV, -8 * 8); /* class */
4230 /* move machine code into REG_ITMP3 */
4231 M_ILD(REG_ITMP3, REG_PV, -11 * 8); /* machine code */
4232 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
4233 M_IST(REG_ITMP3, REG_SP, 0);
4235 M_ALD(REG_ITMP2, REG_PV, -9 * 8); /* asm_check_clinit */
4236 M_JMP(REG_ZERO, REG_ITMP2);
4241 dolog_plain("stubsize: %d (for %d params)\n", (int) (mcodeptr - (s4*) s), m->paramcount);
4244 #if defined(STATISTICS)
4246 count_nstub_len += NATIVESTUB_SIZE * 8;
4249 /* release dump area */
4251 dump_release(dumpsize);
4253 return (u1 *) (s + NATIVESTUB_OFFSET);
4257 /* function: removenativestub **************************************************
4259 removes a previously created native-stub from memory
4261 *******************************************************************************/
4263 void removenativestub(u1 *stub)
4265 CFREE((u8 *) stub - NATIVESTUBOFFSET, NATIVESTUBSIZE * 8);
4270 * These are local overrides for various environment variables in Emacs.
4271 * Please do not remove this and leave it at the end of the file, where
4272 * Emacs will automagically detect them.
4273 * ---------------------------------------------------------------------
4276 * indent-tabs-mode: t