1 /* src/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
33 $Id: codegen.c 2178 2005-04-01 13:20:47Z twisti $
42 #include "cacao/cacao.h"
43 #include "native/native.h"
44 #include "vm/builtin.h"
45 #include "vm/global.h"
46 #include "vm/loader.h"
47 #include "vm/tables.h"
48 #include "vm/jit/asmpart.h"
49 #include "vm/jit/jit.h"
51 #include "vm/jit/lsra.h"
53 #include "vm/jit/parse.h"
54 #include "vm/jit/reg.h"
55 #include "vm/jit/alpha/arch.h"
56 #include "vm/jit/alpha/codegen.h"
57 #include "vm/jit/alpha/types.h"
58 #include "vm/jit/alpha/asmoffsets.h"
61 /* *****************************************************************************
63 Datatypes and Register Allocations:
64 -----------------------------------
66 On 64-bit-machines (like the Alpha) all operands are stored in the
67 registers in a 64-bit form, even when the correspondig JavaVM operands
68 only need 32 bits. This is done by a canonical representation:
70 32-bit integers are allways stored as sign-extended 64-bit values (this
71 approach is directly supported by the Alpha architecture and is very easy
74 32-bit-floats are stored in a 64-bit doubleprecision register by simply
75 expanding the exponent and mantissa with zeroes. (also supported by the
81 The calling conventions and the layout of the stack is explained in detail
82 in the documention file: calling.doc
84 *******************************************************************************/
87 /* register descripton - array ************************************************/
89 /* #define REG_RES 0 reserved register for OS or code generator */
90 /* #define REG_RET 1 return value register */
91 /* #define REG_EXC 2 exception value register (only old jit) */
92 /* #define REG_SAV 3 (callee) saved register */
93 /* #define REG_TMP 4 scratch temporary register (caller saved) */
94 /* #define REG_ARG 5 argument register (caller saved) */
96 /* #define REG_END -1 last entry in tables */
99 REG_RET, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
100 REG_TMP, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
101 REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_TMP, REG_TMP,
102 REG_TMP, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES,
105 /* for use of reserved registers, see comment above */
107 int nregdescfloat[] = {
108 REG_RET, REG_TMP, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
109 REG_SAV, REG_SAV, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
110 REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_TMP, REG_TMP,
111 REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_RES, REG_RES, REG_RES, REG_RES,
115 /* Include independent code generation stuff -- include after register */
116 /* descriptions to avoid extern definitions. */
118 #include "vm/jit/codegen.inc"
119 #include "vm/jit/reg.inc"
121 #include "vm/jit/lsra.inc"
125 /* NullPointerException handlers and exception handling initialisation */
127 typedef struct sigctx_struct {
128 long sc_onstack; /* sigstack state to restore */
129 long sc_mask; /* signal mask to restore */
130 long sc_pc; /* pc at time of signal */
131 long sc_ps; /* psl to retore */
132 long sc_regs[32]; /* processor regs 0 to 31 */
133 long sc_ownedfp; /* fp has been used */
134 long sc_fpregs[32]; /* fp regs 0 to 31 */
135 unsigned long sc_fpcr; /* floating point control register */
136 unsigned long sc_fp_control; /* software fpcr */
138 unsigned long sc_reserved1, sc_reserved2;
139 unsigned long sc_ssize;
141 unsigned long sc_traparg_a0;
142 unsigned long sc_traparg_a1;
143 unsigned long sc_traparg_a2;
144 unsigned long sc_fp_trap_pc;
145 unsigned long sc_fp_trigger_sum;
146 unsigned long sc_fp_trigger_inst;
147 unsigned long sc_retcode[2];
151 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
152 void thread_restartcriticalsection(ucontext_t *uc)
155 if ((critical = thread_checkcritical((void*) uc->uc_mcontext.sc_pc)) != NULL)
156 uc->uc_mcontext.sc_pc = (u8) critical;
161 /* NullPointerException signal handler for hardware null pointer check */
163 void catch_NullPointerException(int sig, siginfo_t *siginfo, void *_p)
165 struct sigaction act;
170 ucontext_t *_uc = (ucontext_t *) _p;
171 mcontext_t *sigctx = &_uc->uc_mcontext;
173 instr = *((s4 *) (sigctx->sc_pc));
174 faultaddr = sigctx->sc_regs[(instr >> 16) & 0x1f];
176 if (faultaddr == 0) {
177 /* Reset signal handler - necessary for SysV, does no harm for BSD */
178 act.sa_sigaction = catch_NullPointerException;
179 act.sa_flags = SA_SIGINFO;
180 sigaction(sig, &act, NULL);
183 sigaddset(&nsig, sig);
184 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
186 sigctx->sc_regs[REG_ITMP1_XPTR] = (u8) string_java_lang_NullPointerException;
187 sigctx->sc_regs[REG_ITMP2_XPC] = sigctx->sc_pc;
188 sigctx->sc_pc = (u8) asm_throw_and_handle_exception;
192 faultaddr += (long) ((instr << 16) >> 16);
193 fprintf(stderr, "faulting address: 0x%016lx\n", faultaddr);
194 panic("Stack overflow");
201 void init_exceptions(void)
206 /* Linux on Digital Alpha needs an initialisation of the ieee floating point
207 control for IEEE compliant arithmetic (option -mieee of GCC). Under
208 Digital Unix this is done automatically.
213 extern unsigned long ieee_get_fp_control();
214 extern void ieee_set_fp_control(unsigned long fp_control);
216 void init_exceptions(void)
218 struct sigaction act;
220 /* initialize floating point control */
222 ieee_set_fp_control(ieee_get_fp_control()
223 & ~IEEE_TRAP_ENABLE_INV
224 & ~IEEE_TRAP_ENABLE_DZE
225 /* & ~IEEE_TRAP_ENABLE_UNF we dont want underflow */
226 & ~IEEE_TRAP_ENABLE_OVF);
229 /* install signal handlers we need to convert to exceptions */
232 act.sa_sigaction = catch_NullPointerException;
233 act.sa_flags = SA_SIGINFO;
236 sigaction(SIGSEGV, &act, NULL);
240 sigaction(SIGBUS, &act, NULL);
246 /* function gen_mcode **********************************************************
248 generates machine code
250 *******************************************************************************/
252 void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
254 s4 len, s1, s2, s3, d;
268 savedregs_num = (m->isleafmethod) ? 0 : 1; /* space to save the RA */
270 /* space to save used callee saved registers */
272 savedregs_num += (rd->savintregcnt - rd->maxsavintreguse);
273 savedregs_num += (rd->savfltregcnt - rd->maxsavfltreguse);
275 parentargs_base = rd->maxmemuse + savedregs_num;
277 #if defined(USE_THREADS) /* space to save argument of monitor_enter */
279 if (checksync && (m->flags & ACC_SYNCHRONIZED))
284 /* create method header */
286 (void) dseg_addaddress(cd, m); /* MethodPointer */
287 (void) dseg_adds4(cd, parentargs_base * 8); /* FrameSize */
289 #if defined(USE_THREADS)
291 /* IsSync contains the offset relative to the stack pointer for the
292 argument of monitor_exit used in the exception handler. Since the
293 offset could be zero and give a wrong meaning of the flag it is
297 if (checksync && (m->flags & ACC_SYNCHRONIZED))
298 (void) dseg_adds4(cd, (rd->maxmemuse + 1) * 8); /* IsSync */
303 (void) dseg_adds4(cd, 0); /* IsSync */
305 (void) dseg_adds4(cd, m->isleafmethod); /* IsLeaf */
306 (void) dseg_adds4(cd, rd->savintregcnt - rd->maxsavintreguse);/* IntSave */
307 (void) dseg_adds4(cd, rd->savfltregcnt - rd->maxsavfltreguse);/* FltSave */
309 dseg_addlinenumbertablesize(cd);
311 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
313 /* create exception table */
315 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
316 dseg_addtarget(cd, ex->start);
317 dseg_addtarget(cd, ex->end);
318 dseg_addtarget(cd, ex->handler);
319 (void) dseg_addaddress(cd, ex->catchtype);
322 /* initialize mcode variables */
324 mcodeptr = (s4 *) cd->mcodebase;
325 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
326 MCODECHECK(128 + m->paramcount);
328 /* create stack frame (if necessary) */
330 if (parentargs_base) {
331 M_LDA(REG_SP, REG_SP, -parentargs_base * 8);
334 /* save return address and used callee saved registers */
337 if (!m->isleafmethod) {
338 p--; M_AST(REG_RA, REG_SP, p * 8);
340 for (i = rd->savintregcnt - 1; i >= rd->maxsavintreguse; i--) {
341 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
343 for (i = rd->savfltregcnt - 1; i >= rd->maxsavfltreguse; i--) {
344 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
347 /* save monitorenter argument */
349 #if defined(USE_THREADS)
350 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
351 if (m->flags & ACC_STATIC) {
352 p = dseg_addaddress(cd, m->class);
353 M_ALD(REG_ITMP1, REG_PV, p);
354 M_AST(REG_ITMP1, REG_SP, rd->maxmemuse * 8);
357 M_AST(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
362 /* copy argument registers to stack and call trace function with pointer
363 to arguments on stack.
368 M_LDA(REG_SP, REG_SP, -((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
369 M_AST(REG_RA, REG_SP, 1 * 8);
371 /* save integer argument registers */
372 for (p = 0; /* p < m->paramcount && */ p < INT_ARG_CNT; p++) {
373 M_LST(rd->argintregs[p], REG_SP, (2 + p) * 8);
376 /* save and copy float arguments into integer registers */
377 for (p = 0; /* p < m->paramcount && */ p < FLT_ARG_CNT; p++) {
378 t = m->paramtypes[p];
380 if (IS_FLT_DBL_TYPE(t)) {
381 if (IS_2_WORD_TYPE(t)) {
382 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
385 M_FST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
388 M_LLD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
391 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
395 p = dseg_addaddress(cd, m);
396 M_ALD(REG_ITMP1, REG_PV, p);
397 M_AST(REG_ITMP1, REG_SP, 0 * 8);
398 p = dseg_addaddress(cd, (void *) builtin_trace_args);
399 M_ALD(REG_PV, REG_PV, p);
400 M_JSR(REG_RA, REG_PV);
401 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
402 M_LDA(REG_PV, REG_RA, disp);
403 M_ALD(REG_RA, REG_SP, 1 * 8);
405 for (p = 0; /* p < mparamcount && */ p < INT_ARG_CNT; p++) {
406 M_LLD(rd->argintregs[p], REG_SP, (2 + p) * 8);
409 for (p = 0; /* p < mparamcount && */ p < FLT_ARG_CNT; p++) {
410 t = m->paramtypes[p];
412 if (IS_FLT_DBL_TYPE(t)) {
413 if (IS_2_WORD_TYPE(t)) {
414 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
417 M_FLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
421 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
425 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT + 2) * 8);
428 /* take arguments out of register or stack frame */
430 for (p = 0, l = 0; p < m->paramcount; p++) {
431 t = m->paramtypes[p];
432 var = &(rd->locals[l][t]);
434 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
438 if (IS_INT_LNG_TYPE(t)) { /* integer args */
439 if (p < INT_ARG_CNT) { /* register arguments */
440 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
441 M_INTMOVE(rd->argintregs[p], var->regoff);
442 } else { /* reg arg -> spilled */
443 M_LST(rd->argintregs[p], REG_SP, 8 * var->regoff);
446 } else { /* stack arguments */
447 pa = p - INT_ARG_CNT;
448 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
449 M_LLD(var->regoff, REG_SP, 8 * (parentargs_base + pa));
451 } else { /* stack arg -> spilled */
452 M_LLD(REG_ITMP1, REG_SP, 8 * (parentargs_base + pa));
453 M_LST(REG_ITMP1, REG_SP, 8 * var->regoff);
457 } else { /* floating args */
458 if (p < FLT_ARG_CNT) { /* register arguments */
459 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
460 M_FLTMOVE(rd->argfltregs[p], var->regoff);
462 } else { /* reg arg -> spilled */
463 M_DST(rd->argfltregs[p], REG_SP, 8 * var->regoff);
466 } else { /* stack arguments */
467 pa = p - FLT_ARG_CNT;
468 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
469 M_DLD(var->regoff, REG_SP, 8 * (parentargs_base + pa) );
471 } else { /* stack-arg -> spilled */
472 M_DLD(REG_FTMP1, REG_SP, 8 * (parentargs_base + pa));
473 M_DST(REG_FTMP1, REG_SP, 8 * var->regoff);
479 /* call monitorenter function */
481 #if defined(USE_THREADS)
482 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
484 s8 func_enter = (m->flags & ACC_STATIC) ?
485 (s8) builtin_staticmonitorenter : (s8) builtin_monitorenter;
486 p = dseg_addaddress(cd, (void*) func_enter);
487 M_ALD(REG_PV, REG_PV, p);
488 M_ALD(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
489 M_JSR(REG_RA, REG_PV);
490 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
491 M_LDA(REG_PV, REG_RA, disp);
496 /* end of header generation */
498 /* walk through all basic blocks */
499 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
501 bptr->mpc = (s4) ((u1 *) mcodeptr - cd->mcodebase);
503 if (bptr->flags >= BBREACHED) {
505 /* branch resolving */
509 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
510 gen_resolvebranch((u1*) cd->mcodebase + brefs->branchpos,
511 brefs->branchpos, bptr->mpc);
515 /* copy interface registers to their destination */
522 while (src != NULL) {
524 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
525 /* d = reg_of_var(m, src, REG_ITMP1); */
526 if (!(src->flags & INMEMORY))
530 M_INTMOVE(REG_ITMP1, d);
531 store_reg_to_var_int(src, d);
537 while (src != NULL) {
539 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
540 d = reg_of_var(rd, src, REG_ITMP1);
541 M_INTMOVE(REG_ITMP1, d);
542 store_reg_to_var_int(src, d);
545 d = reg_of_var(rd, src, REG_IFTMP);
546 if ((src->varkind != STACKVAR)) {
548 if (IS_FLT_DBL_TYPE(s2)) {
549 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
550 s1 = rd->interfaces[len][s2].regoff;
554 M_DLD(d, REG_SP, 8 * rd->interfaces[len][s2].regoff);
556 store_reg_to_var_flt(src, d);
559 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
560 s1 = rd->interfaces[len][s2].regoff;
564 M_LLD(d, REG_SP, 8 * rd->interfaces[len][s2].regoff);
566 store_reg_to_var_int(src, d);
576 /* walk through all instructions */
580 for (iptr = bptr->iinstr;
582 src = iptr->dst, len--, iptr++) {
584 if (iptr->line!=currentline) {
585 dseg_addlinenumber(cd,iptr->line,mcodeptr);
586 currentline=iptr->line;
589 MCODECHECK(64); /* an instruction usually needs < 64 words */
592 case ICMD_INLINE_START:
593 case ICMD_INLINE_END:
596 case ICMD_NOP: /* ... ==> ... */
599 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
601 var_to_reg_int(s1, src, REG_ITMP1);
603 codegen_addxnullrefs(cd, mcodeptr);
606 /* constant operations ************************************************/
608 case ICMD_ICONST: /* ... ==> ..., constant */
609 /* op1 = 0, val.i = constant */
611 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
612 ICONST(d, iptr->val.i);
613 store_reg_to_var_int(iptr->dst, d);
616 case ICMD_LCONST: /* ... ==> ..., constant */
617 /* op1 = 0, val.l = constant */
619 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
620 LCONST(d, iptr->val.l);
621 store_reg_to_var_int(iptr->dst, d);
624 case ICMD_FCONST: /* ... ==> ..., constant */
625 /* op1 = 0, val.f = constant */
627 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
628 a = dseg_addfloat(cd, iptr->val.f);
630 store_reg_to_var_flt(iptr->dst, d);
633 case ICMD_DCONST: /* ... ==> ..., constant */
634 /* op1 = 0, val.d = constant */
636 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
637 a = dseg_adddouble(cd, iptr->val.d);
639 store_reg_to_var_flt(iptr->dst, d);
642 case ICMD_ACONST: /* ... ==> ..., constant */
643 /* op1 = 0, val.a = constant */
645 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
647 a = dseg_addaddress(cd, iptr->val.a);
650 M_INTMOVE(REG_ZERO, d);
652 store_reg_to_var_int(iptr->dst, d);
656 /* load/store operations **********************************************/
658 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
659 case ICMD_LLOAD: /* op1 = local variable */
662 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
663 if ((iptr->dst->varkind == LOCALVAR) &&
664 (iptr->dst->varnum == iptr->op1))
666 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
667 if (var->flags & INMEMORY)
668 M_LLD(d, REG_SP, 8 * var->regoff);
670 {M_INTMOVE(var->regoff,d);}
671 store_reg_to_var_int(iptr->dst, d);
674 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
675 case ICMD_DLOAD: /* op1 = local variable */
677 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
678 if ((iptr->dst->varkind == LOCALVAR) &&
679 (iptr->dst->varnum == iptr->op1))
681 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
682 if (var->flags & INMEMORY)
683 M_DLD(d, REG_SP, 8 * var->regoff);
685 {M_FLTMOVE(var->regoff,d);}
686 store_reg_to_var_flt(iptr->dst, d);
690 case ICMD_ISTORE: /* ..., value ==> ... */
691 case ICMD_LSTORE: /* op1 = local variable */
694 if ((src->varkind == LOCALVAR) &&
695 (src->varnum == iptr->op1))
697 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
698 if (var->flags & INMEMORY) {
699 var_to_reg_int(s1, src, REG_ITMP1);
700 M_LST(s1, REG_SP, 8 * var->regoff);
703 var_to_reg_int(s1, src, var->regoff);
704 M_INTMOVE(s1, var->regoff);
708 case ICMD_FSTORE: /* ..., value ==> ... */
709 case ICMD_DSTORE: /* op1 = local variable */
711 if ((src->varkind == LOCALVAR) &&
712 (src->varnum == iptr->op1))
714 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
715 if (var->flags & INMEMORY) {
716 var_to_reg_flt(s1, src, REG_FTMP1);
717 M_DST(s1, REG_SP, 8 * var->regoff);
720 var_to_reg_flt(s1, src, var->regoff);
721 M_FLTMOVE(s1, var->regoff);
726 /* pop/dup/swap operations ********************************************/
728 /* attention: double and longs are only one entry in CACAO ICMDs */
730 case ICMD_POP: /* ..., value ==> ... */
731 case ICMD_POP2: /* ..., value, value ==> ... */
734 case ICMD_DUP: /* ..., a ==> ..., a, a */
735 M_COPY(src, iptr->dst);
738 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
740 M_COPY(src, iptr->dst);
741 M_COPY(src->prev, iptr->dst->prev);
742 M_COPY(iptr->dst, iptr->dst->prev->prev);
745 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
747 M_COPY(src, iptr->dst);
748 M_COPY(src->prev, iptr->dst->prev);
749 M_COPY(src->prev->prev, iptr->dst->prev->prev);
750 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
753 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
755 M_COPY(src, iptr->dst);
756 M_COPY(src->prev, iptr->dst->prev);
759 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
761 M_COPY(src, iptr->dst);
762 M_COPY(src->prev, iptr->dst->prev);
763 M_COPY(src->prev->prev, iptr->dst->prev->prev);
764 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
765 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev);
768 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
770 M_COPY(src, iptr->dst);
771 M_COPY(src->prev, iptr->dst->prev);
772 M_COPY(src->prev->prev, iptr->dst->prev->prev);
773 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
774 M_COPY(iptr->dst, iptr->dst->prev->prev->prev->prev);
775 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev->prev);
778 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
780 M_COPY(src, iptr->dst->prev);
781 M_COPY(src->prev, iptr->dst);
785 /* integer operations *************************************************/
787 case ICMD_INEG: /* ..., value ==> ..., - value */
789 var_to_reg_int(s1, src, REG_ITMP1);
790 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
791 M_ISUB(REG_ZERO, s1, d);
792 store_reg_to_var_int(iptr->dst, d);
795 case ICMD_LNEG: /* ..., value ==> ..., - value */
797 var_to_reg_int(s1, src, REG_ITMP1);
798 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
799 M_LSUB(REG_ZERO, s1, d);
800 store_reg_to_var_int(iptr->dst, d);
803 case ICMD_I2L: /* ..., value ==> ..., value */
805 var_to_reg_int(s1, src, REG_ITMP1);
806 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
808 store_reg_to_var_int(iptr->dst, d);
811 case ICMD_L2I: /* ..., value ==> ..., value */
813 var_to_reg_int(s1, src, REG_ITMP1);
814 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
815 M_IADD(s1, REG_ZERO, d );
816 store_reg_to_var_int(iptr->dst, d);
819 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
821 var_to_reg_int(s1, src, REG_ITMP1);
822 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
823 if (has_ext_instr_set) {
827 M_SLL_IMM(s1, 56, d);
828 M_SRA_IMM( d, 56, d);
830 store_reg_to_var_int(iptr->dst, d);
833 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
835 var_to_reg_int(s1, src, REG_ITMP1);
836 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
838 store_reg_to_var_int(iptr->dst, d);
841 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
843 var_to_reg_int(s1, src, REG_ITMP1);
844 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
845 if (has_ext_instr_set) {
849 M_SLL_IMM(s1, 48, d);
850 M_SRA_IMM( d, 48, d);
852 store_reg_to_var_int(iptr->dst, d);
856 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
858 var_to_reg_int(s1, src->prev, REG_ITMP1);
859 var_to_reg_int(s2, src, REG_ITMP2);
860 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
862 store_reg_to_var_int(iptr->dst, d);
865 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
866 /* val.i = constant */
868 var_to_reg_int(s1, src, REG_ITMP1);
869 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
870 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
871 M_IADD_IMM(s1, iptr->val.i, d);
874 ICONST(REG_ITMP2, iptr->val.i);
875 M_IADD(s1, REG_ITMP2, d);
877 store_reg_to_var_int(iptr->dst, d);
880 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
882 var_to_reg_int(s1, src->prev, REG_ITMP1);
883 var_to_reg_int(s2, src, REG_ITMP2);
884 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
886 store_reg_to_var_int(iptr->dst, d);
889 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
890 /* val.l = constant */
892 var_to_reg_int(s1, src, REG_ITMP1);
893 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
894 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
895 M_LADD_IMM(s1, iptr->val.l, d);
898 LCONST(REG_ITMP2, iptr->val.l);
899 M_LADD(s1, REG_ITMP2, d);
901 store_reg_to_var_int(iptr->dst, d);
904 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
906 var_to_reg_int(s1, src->prev, REG_ITMP1);
907 var_to_reg_int(s2, src, REG_ITMP2);
908 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
910 store_reg_to_var_int(iptr->dst, d);
913 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
914 /* val.i = constant */
916 var_to_reg_int(s1, src, REG_ITMP1);
917 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
918 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
919 M_ISUB_IMM(s1, iptr->val.i, d);
922 ICONST(REG_ITMP2, iptr->val.i);
923 M_ISUB(s1, REG_ITMP2, d);
925 store_reg_to_var_int(iptr->dst, d);
928 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
930 var_to_reg_int(s1, src->prev, REG_ITMP1);
931 var_to_reg_int(s2, src, REG_ITMP2);
932 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
934 store_reg_to_var_int(iptr->dst, d);
937 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
938 /* val.l = constant */
940 var_to_reg_int(s1, src, REG_ITMP1);
941 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
942 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
943 M_LSUB_IMM(s1, iptr->val.l, d);
946 LCONST(REG_ITMP2, iptr->val.l);
947 M_LSUB(s1, REG_ITMP2, d);
949 store_reg_to_var_int(iptr->dst, d);
952 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
954 var_to_reg_int(s1, src->prev, REG_ITMP1);
955 var_to_reg_int(s2, src, REG_ITMP2);
956 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
958 store_reg_to_var_int(iptr->dst, d);
961 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
962 /* val.i = constant */
964 var_to_reg_int(s1, src, REG_ITMP1);
965 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
966 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
967 M_IMUL_IMM(s1, iptr->val.i, d);
970 ICONST(REG_ITMP2, iptr->val.i);
971 M_IMUL(s1, REG_ITMP2, d);
973 store_reg_to_var_int(iptr->dst, d);
976 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
978 var_to_reg_int(s1, src->prev, REG_ITMP1);
979 var_to_reg_int(s2, src, REG_ITMP2);
980 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
982 store_reg_to_var_int(iptr->dst, d);
985 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
986 /* val.l = constant */
988 var_to_reg_int(s1, src, REG_ITMP1);
989 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
990 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
991 M_LMUL_IMM(s1, iptr->val.l, d);
994 LCONST(REG_ITMP2, iptr->val.l);
995 M_LMUL(s1, REG_ITMP2, d);
997 store_reg_to_var_int(iptr->dst, d);
1000 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
1001 case ICMD_LDIVPOW2: /* val.i = constant */
1003 var_to_reg_int(s1, src, REG_ITMP1);
1004 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1005 if (iptr->val.i <= 15) {
1006 M_LDA(REG_ITMP2, s1, (1 << iptr->val.i) -1);
1007 M_CMOVGE(s1, s1, REG_ITMP2);
1010 M_SRA_IMM(s1, 63, REG_ITMP2);
1011 M_SRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
1012 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1014 M_SRA_IMM(REG_ITMP2, iptr->val.i, d);
1015 store_reg_to_var_int(iptr->dst, d);
1018 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1020 var_to_reg_int(s1, src->prev, REG_ITMP1);
1021 var_to_reg_int(s2, src, REG_ITMP2);
1022 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1023 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1024 M_SLL(s1, REG_ITMP3, d);
1025 M_IADD(d, REG_ZERO, d);
1026 store_reg_to_var_int(iptr->dst, d);
1029 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1030 /* val.i = constant */
1032 var_to_reg_int(s1, src, REG_ITMP1);
1033 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1034 M_SLL_IMM(s1, iptr->val.i & 0x1f, d);
1035 M_IADD(d, REG_ZERO, d);
1036 store_reg_to_var_int(iptr->dst, d);
1039 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1041 var_to_reg_int(s1, src->prev, REG_ITMP1);
1042 var_to_reg_int(s2, src, REG_ITMP2);
1043 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1044 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1045 M_SRA(s1, REG_ITMP3, d);
1046 store_reg_to_var_int(iptr->dst, d);
1049 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1050 /* val.i = constant */
1052 var_to_reg_int(s1, src, REG_ITMP1);
1053 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1054 M_SRA_IMM(s1, iptr->val.i & 0x1f, d);
1055 store_reg_to_var_int(iptr->dst, d);
1058 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1060 var_to_reg_int(s1, src->prev, REG_ITMP1);
1061 var_to_reg_int(s2, src, REG_ITMP2);
1062 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1063 M_AND_IMM(s2, 0x1f, REG_ITMP2);
1065 M_SRL(d, REG_ITMP2, d);
1066 M_IADD(d, REG_ZERO, d);
1067 store_reg_to_var_int(iptr->dst, d);
1070 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1071 /* val.i = constant */
1073 var_to_reg_int(s1, src, REG_ITMP1);
1074 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1076 M_SRL_IMM(d, iptr->val.i & 0x1f, d);
1077 M_IADD(d, REG_ZERO, d);
1078 store_reg_to_var_int(iptr->dst, d);
1081 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1083 var_to_reg_int(s1, src->prev, REG_ITMP1);
1084 var_to_reg_int(s2, src, REG_ITMP2);
1085 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1087 store_reg_to_var_int(iptr->dst, d);
1090 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1091 /* val.i = constant */
1093 var_to_reg_int(s1, src, REG_ITMP1);
1094 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1095 M_SLL_IMM(s1, iptr->val.i & 0x3f, d);
1096 store_reg_to_var_int(iptr->dst, d);
1099 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1101 var_to_reg_int(s1, src->prev, REG_ITMP1);
1102 var_to_reg_int(s2, src, REG_ITMP2);
1103 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1105 store_reg_to_var_int(iptr->dst, d);
1108 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1109 /* val.i = constant */
1111 var_to_reg_int(s1, src, REG_ITMP1);
1112 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1113 M_SRA_IMM(s1, iptr->val.i & 0x3f, d);
1114 store_reg_to_var_int(iptr->dst, d);
1117 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1119 var_to_reg_int(s1, src->prev, REG_ITMP1);
1120 var_to_reg_int(s2, src, REG_ITMP2);
1121 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1123 store_reg_to_var_int(iptr->dst, d);
1126 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1127 /* val.i = constant */
1129 var_to_reg_int(s1, src, REG_ITMP1);
1130 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1131 M_SRL_IMM(s1, iptr->val.i & 0x3f, d);
1132 store_reg_to_var_int(iptr->dst, d);
1135 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1138 var_to_reg_int(s1, src->prev, REG_ITMP1);
1139 var_to_reg_int(s2, src, REG_ITMP2);
1140 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1142 store_reg_to_var_int(iptr->dst, d);
1145 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1146 /* val.i = constant */
1148 var_to_reg_int(s1, src, REG_ITMP1);
1149 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1150 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1151 M_AND_IMM(s1, iptr->val.i, d);
1153 else if (iptr->val.i == 0xffff) {
1156 else if (iptr->val.i == 0xffffff) {
1157 M_ZAPNOT_IMM(s1, 0x07, d);
1160 ICONST(REG_ITMP2, iptr->val.i);
1161 M_AND(s1, REG_ITMP2, d);
1163 store_reg_to_var_int(iptr->dst, d);
1166 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1167 /* val.i = constant */
1169 var_to_reg_int(s1, src, REG_ITMP1);
1170 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1172 M_MOV(s1, REG_ITMP1);
1175 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1176 M_AND_IMM(s1, iptr->val.i, d);
1178 M_ISUB(REG_ZERO, s1, d);
1179 M_AND_IMM(d, iptr->val.i, d);
1181 else if (iptr->val.i == 0xffff) {
1184 M_ISUB(REG_ZERO, s1, d);
1187 else if (iptr->val.i == 0xffffff) {
1188 M_ZAPNOT_IMM(s1, 0x07, d);
1190 M_ISUB(REG_ZERO, s1, d);
1191 M_ZAPNOT_IMM(d, 0x07, d);
1194 ICONST(REG_ITMP2, iptr->val.i);
1195 M_AND(s1, REG_ITMP2, d);
1197 M_ISUB(REG_ZERO, s1, d);
1198 M_AND(d, REG_ITMP2, d);
1200 M_ISUB(REG_ZERO, d, d);
1201 store_reg_to_var_int(iptr->dst, d);
1204 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1205 /* val.l = constant */
1207 var_to_reg_int(s1, src, REG_ITMP1);
1208 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1209 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1210 M_AND_IMM(s1, iptr->val.l, d);
1212 else if (iptr->val.l == 0xffffL) {
1215 else if (iptr->val.l == 0xffffffL) {
1216 M_ZAPNOT_IMM(s1, 0x07, d);
1218 else if (iptr->val.l == 0xffffffffL) {
1221 else if (iptr->val.l == 0xffffffffffL) {
1222 M_ZAPNOT_IMM(s1, 0x1f, d);
1224 else if (iptr->val.l == 0xffffffffffffL) {
1225 M_ZAPNOT_IMM(s1, 0x3f, d);
1227 else if (iptr->val.l == 0xffffffffffffffL) {
1228 M_ZAPNOT_IMM(s1, 0x7f, d);
1231 LCONST(REG_ITMP2, iptr->val.l);
1232 M_AND(s1, REG_ITMP2, d);
1234 store_reg_to_var_int(iptr->dst, d);
1237 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1238 /* val.l = constant */
1240 var_to_reg_int(s1, src, REG_ITMP1);
1241 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1243 M_MOV(s1, REG_ITMP1);
1246 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1247 M_AND_IMM(s1, iptr->val.l, d);
1249 M_LSUB(REG_ZERO, s1, d);
1250 M_AND_IMM(d, iptr->val.l, d);
1252 else if (iptr->val.l == 0xffffL) {
1255 M_LSUB(REG_ZERO, s1, d);
1258 else if (iptr->val.l == 0xffffffL) {
1259 M_ZAPNOT_IMM(s1, 0x07, d);
1261 M_LSUB(REG_ZERO, s1, d);
1262 M_ZAPNOT_IMM(d, 0x07, d);
1264 else if (iptr->val.l == 0xffffffffL) {
1267 M_LSUB(REG_ZERO, s1, d);
1270 else if (iptr->val.l == 0xffffffffffL) {
1271 M_ZAPNOT_IMM(s1, 0x1f, d);
1273 M_LSUB(REG_ZERO, s1, d);
1274 M_ZAPNOT_IMM(d, 0x1f, d);
1276 else if (iptr->val.l == 0xffffffffffffL) {
1277 M_ZAPNOT_IMM(s1, 0x3f, d);
1279 M_LSUB(REG_ZERO, s1, d);
1280 M_ZAPNOT_IMM(d, 0x3f, d);
1282 else if (iptr->val.l == 0xffffffffffffffL) {
1283 M_ZAPNOT_IMM(s1, 0x7f, d);
1285 M_LSUB(REG_ZERO, s1, d);
1286 M_ZAPNOT_IMM(d, 0x7f, d);
1289 LCONST(REG_ITMP2, iptr->val.l);
1290 M_AND(s1, REG_ITMP2, d);
1292 M_LSUB(REG_ZERO, s1, d);
1293 M_AND(d, REG_ITMP2, d);
1295 M_LSUB(REG_ZERO, d, d);
1296 store_reg_to_var_int(iptr->dst, d);
1299 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1302 var_to_reg_int(s1, src->prev, REG_ITMP1);
1303 var_to_reg_int(s2, src, REG_ITMP2);
1304 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1306 store_reg_to_var_int(iptr->dst, d);
1309 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1310 /* val.i = constant */
1312 var_to_reg_int(s1, src, REG_ITMP1);
1313 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1314 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1315 M_OR_IMM(s1, iptr->val.i, d);
1318 ICONST(REG_ITMP2, iptr->val.i);
1319 M_OR(s1, REG_ITMP2, d);
1321 store_reg_to_var_int(iptr->dst, d);
1324 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1325 /* val.l = constant */
1327 var_to_reg_int(s1, src, REG_ITMP1);
1328 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1329 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1330 M_OR_IMM(s1, iptr->val.l, d);
1333 LCONST(REG_ITMP2, iptr->val.l);
1334 M_OR(s1, REG_ITMP2, d);
1336 store_reg_to_var_int(iptr->dst, d);
1339 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1342 var_to_reg_int(s1, src->prev, REG_ITMP1);
1343 var_to_reg_int(s2, src, REG_ITMP2);
1344 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1346 store_reg_to_var_int(iptr->dst, d);
1349 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1350 /* val.i = constant */
1352 var_to_reg_int(s1, src, REG_ITMP1);
1353 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1354 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1355 M_XOR_IMM(s1, iptr->val.i, d);
1358 ICONST(REG_ITMP2, iptr->val.i);
1359 M_XOR(s1, REG_ITMP2, d);
1361 store_reg_to_var_int(iptr->dst, d);
1364 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1365 /* val.l = constant */
1367 var_to_reg_int(s1, src, REG_ITMP1);
1368 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1369 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1370 M_XOR_IMM(s1, iptr->val.l, d);
1373 LCONST(REG_ITMP2, iptr->val.l);
1374 M_XOR(s1, REG_ITMP2, d);
1376 store_reg_to_var_int(iptr->dst, d);
1380 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1382 var_to_reg_int(s1, src->prev, REG_ITMP1);
1383 var_to_reg_int(s2, src, REG_ITMP2);
1384 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1385 M_CMPLT(s1, s2, REG_ITMP3);
1386 M_CMPLT(s2, s1, REG_ITMP1);
1387 M_LSUB (REG_ITMP1, REG_ITMP3, d);
1388 store_reg_to_var_int(iptr->dst, d);
1392 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1393 /* op1 = variable, val.i = constant */
1395 var = &(rd->locals[iptr->op1][TYPE_INT]);
1396 if (var->flags & INMEMORY) {
1398 M_LLD(s1, REG_SP, 8 * var->regoff);
1402 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1403 M_IADD_IMM(s1, iptr->val.i, s1);
1405 else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1406 M_ISUB_IMM(s1, (-iptr->val.i), s1);
1409 M_LDA (s1, s1, iptr->val.i);
1410 M_IADD(s1, REG_ZERO, s1);
1412 if (var->flags & INMEMORY)
1413 M_LST(s1, REG_SP, 8 * var->regoff);
1417 /* floating operations ************************************************/
1419 case ICMD_FNEG: /* ..., value ==> ..., - value */
1421 var_to_reg_flt(s1, src, REG_FTMP1);
1422 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1424 store_reg_to_var_flt(iptr->dst, d);
1427 case ICMD_DNEG: /* ..., value ==> ..., - value */
1429 var_to_reg_flt(s1, src, REG_FTMP1);
1430 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1432 store_reg_to_var_flt(iptr->dst, d);
1435 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1437 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1438 var_to_reg_flt(s2, src, REG_FTMP2);
1439 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1444 if (d == s1 || d == s2) {
1445 M_FADDS(s1, s2, REG_FTMP3);
1447 M_FMOV(REG_FTMP3, d);
1454 store_reg_to_var_flt(iptr->dst, d);
1457 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1459 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1460 var_to_reg_flt(s2, src, REG_FTMP2);
1461 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1466 if (d == s1 || d == s2) {
1467 M_DADDS(s1, s2, REG_FTMP3);
1469 M_FMOV(REG_FTMP3, d);
1476 store_reg_to_var_flt(iptr->dst, d);
1479 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1481 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1482 var_to_reg_flt(s2, src, REG_FTMP2);
1483 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1488 if (d == s1 || d == s2) {
1489 M_FSUBS(s1, s2, REG_FTMP3);
1491 M_FMOV(REG_FTMP3, d);
1498 store_reg_to_var_flt(iptr->dst, d);
1501 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1503 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1504 var_to_reg_flt(s2, src, REG_FTMP2);
1505 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1510 if (d == s1 || d == s2) {
1511 M_DSUBS(s1, s2, REG_FTMP3);
1513 M_FMOV(REG_FTMP3, d);
1520 store_reg_to_var_flt(iptr->dst, d);
1523 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1525 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1526 var_to_reg_flt(s2, src, REG_FTMP2);
1527 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1532 if (d == s1 || d == s2) {
1533 M_FMULS(s1, s2, REG_FTMP3);
1535 M_FMOV(REG_FTMP3, d);
1542 store_reg_to_var_flt(iptr->dst, d);
1545 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1547 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1548 var_to_reg_flt(s2, src, REG_FTMP2);
1549 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1554 if (d == s1 || d == s2) {
1555 M_DMULS(s1, s2, REG_FTMP3);
1557 M_FMOV(REG_FTMP3, d);
1564 store_reg_to_var_flt(iptr->dst, d);
1567 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1569 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1570 var_to_reg_flt(s2, src, REG_FTMP2);
1571 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1576 if (d == s1 || d == s2) {
1577 M_FDIVS(s1, s2, REG_FTMP3);
1579 M_FMOV(REG_FTMP3, d);
1586 store_reg_to_var_flt(iptr->dst, d);
1589 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1591 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1592 var_to_reg_flt(s2, src, REG_FTMP2);
1593 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1598 if (d == s1 || d == s2) {
1599 M_DDIVS(s1, s2, REG_FTMP3);
1601 M_FMOV(REG_FTMP3, d);
1608 store_reg_to_var_flt(iptr->dst, d);
1611 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1613 var_to_reg_int(s1, src, REG_ITMP1);
1614 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1615 a = dseg_adddouble(cd, 0.0);
1616 M_LST (s1, REG_PV, a);
1617 M_DLD (d, REG_PV, a);
1619 store_reg_to_var_flt(iptr->dst, d);
1622 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1624 var_to_reg_int(s1, src, REG_ITMP1);
1625 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1626 a = dseg_adddouble(cd, 0.0);
1627 M_LST (s1, REG_PV, a);
1628 M_DLD (d, REG_PV, a);
1630 store_reg_to_var_flt(iptr->dst, d);
1633 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1635 var_to_reg_flt(s1, src, REG_FTMP1);
1636 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1637 a = dseg_adddouble(cd, 0.0);
1638 M_CVTDL_C(s1, REG_FTMP2);
1639 M_CVTLI(REG_FTMP2, REG_FTMP3);
1640 M_DST (REG_FTMP3, REG_PV, a);
1641 M_ILD (d, REG_PV, a);
1642 store_reg_to_var_int(iptr->dst, d);
1645 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1647 var_to_reg_flt(s1, src, REG_FTMP1);
1648 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1649 a = dseg_adddouble(cd, 0.0);
1650 M_CVTDL_C(s1, REG_FTMP2);
1651 M_DST (REG_FTMP2, REG_PV, a);
1652 M_LLD (d, REG_PV, a);
1653 store_reg_to_var_int(iptr->dst, d);
1656 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1658 var_to_reg_flt(s1, src, REG_FTMP1);
1659 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1662 store_reg_to_var_flt(iptr->dst, d);
1665 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1667 var_to_reg_flt(s1, src, REG_FTMP1);
1668 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1676 store_reg_to_var_flt(iptr->dst, d);
1679 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1681 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1682 var_to_reg_flt(s2, src, REG_FTMP2);
1683 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1685 M_LSUB_IMM(REG_ZERO, 1, d);
1686 M_FCMPEQ(s1, s2, REG_FTMP3);
1687 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1689 M_FCMPLT(s2, s1, REG_FTMP3);
1690 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1691 M_LADD_IMM(REG_ZERO, 1, d);
1694 M_LSUB_IMM(REG_ZERO, 1, d);
1695 M_FCMPEQS(s1, s2, REG_FTMP3);
1697 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1699 M_FCMPLTS(s2, s1, REG_FTMP3);
1701 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1702 M_LADD_IMM(REG_ZERO, 1, d);
1704 store_reg_to_var_int(iptr->dst, d);
1707 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1709 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1710 var_to_reg_flt(s2, src, REG_FTMP2);
1711 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1713 M_LADD_IMM(REG_ZERO, 1, d);
1714 M_FCMPEQ(s1, s2, REG_FTMP3);
1715 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1717 M_FCMPLT(s1, s2, REG_FTMP3);
1718 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1719 M_LSUB_IMM(REG_ZERO, 1, d);
1722 M_LADD_IMM(REG_ZERO, 1, d);
1723 M_FCMPEQS(s1, s2, REG_FTMP3);
1725 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1727 M_FCMPLTS(s1, s2, REG_FTMP3);
1729 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1730 M_LSUB_IMM(REG_ZERO, 1, d);
1732 store_reg_to_var_int(iptr->dst, d);
1736 /* memory operations **************************************************/
1738 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1740 var_to_reg_int(s1, src, REG_ITMP1);
1741 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1742 gen_nullptr_check(s1);
1743 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1744 store_reg_to_var_int(iptr->dst, d);
1747 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1749 var_to_reg_int(s1, src->prev, REG_ITMP1);
1750 var_to_reg_int(s2, src, REG_ITMP2);
1751 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1752 if (iptr->op1 == 0) {
1753 gen_nullptr_check(s1);
1756 M_SAADDQ(s2, s1, REG_ITMP1);
1757 M_ALD( d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1758 store_reg_to_var_int(iptr->dst, d);
1761 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1763 var_to_reg_int(s1, src->prev, REG_ITMP1);
1764 var_to_reg_int(s2, src, REG_ITMP2);
1765 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1766 if (iptr->op1 == 0) {
1767 gen_nullptr_check(s1);
1770 M_S8ADDQ(s2, s1, REG_ITMP1);
1771 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1772 store_reg_to_var_int(iptr->dst, d);
1775 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1777 var_to_reg_int(s1, src->prev, REG_ITMP1);
1778 var_to_reg_int(s2, src, REG_ITMP2);
1779 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1780 if (iptr->op1 == 0) {
1781 gen_nullptr_check(s1);
1785 M_S4ADDQ(s2, s1, REG_ITMP1);
1786 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1787 store_reg_to_var_int(iptr->dst, d);
1790 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1792 var_to_reg_int(s1, src->prev, REG_ITMP1);
1793 var_to_reg_int(s2, src, REG_ITMP2);
1794 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1795 if (iptr->op1 == 0) {
1796 gen_nullptr_check(s1);
1799 M_S4ADDQ(s2, s1, REG_ITMP1);
1800 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1801 store_reg_to_var_flt(iptr->dst, d);
1804 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1806 var_to_reg_int(s1, src->prev, REG_ITMP1);
1807 var_to_reg_int(s2, src, REG_ITMP2);
1808 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1809 if (iptr->op1 == 0) {
1810 gen_nullptr_check(s1);
1813 M_S8ADDQ(s2, s1, REG_ITMP1);
1814 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1815 store_reg_to_var_flt(iptr->dst, d);
1818 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1820 var_to_reg_int(s1, src->prev, REG_ITMP1);
1821 var_to_reg_int(s2, src, REG_ITMP2);
1822 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1823 if (iptr->op1 == 0) {
1824 gen_nullptr_check(s1);
1827 if (has_ext_instr_set) {
1828 M_LADD(s2, s1, REG_ITMP1);
1829 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1830 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1833 M_LADD (s2, s1, REG_ITMP1);
1834 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1835 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1836 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1837 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
1839 store_reg_to_var_int(iptr->dst, d);
1842 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1844 var_to_reg_int(s1, src->prev, REG_ITMP1);
1845 var_to_reg_int(s2, src, REG_ITMP2);
1846 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1847 if (iptr->op1 == 0) {
1848 gen_nullptr_check(s1);
1851 if (has_ext_instr_set) {
1852 M_LADD(s2, s1, REG_ITMP1);
1853 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1854 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1858 M_LADD(s2, s1, REG_ITMP1);
1859 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1860 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1861 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1862 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1863 M_SRA_IMM(d, 48, d);
1865 store_reg_to_var_int(iptr->dst, d);
1868 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1870 var_to_reg_int(s1, src->prev, REG_ITMP1);
1871 var_to_reg_int(s2, src, REG_ITMP2);
1872 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1873 if (iptr->op1 == 0) {
1874 gen_nullptr_check(s1);
1877 if (has_ext_instr_set) {
1878 M_LADD (s2, s1, REG_ITMP1);
1879 M_BLDU (d, REG_ITMP1, OFFSET (java_bytearray, data[0]));
1883 M_LADD(s2, s1, REG_ITMP1);
1884 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1885 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
1886 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1887 M_SRA_IMM(d, 56, d);
1889 store_reg_to_var_int(iptr->dst, d);
1893 case ICMD_AASTORE: /* ..., 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_SAADDQ(s2, s1, REG_ITMP1);
1903 M_AST (s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1906 case ICMD_LASTORE: /* ..., 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);
1914 var_to_reg_int(s3, src, REG_ITMP3);
1915 M_S8ADDQ(s2, s1, REG_ITMP1);
1916 M_LST (s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1919 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1921 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1922 var_to_reg_int(s2, src->prev, REG_ITMP2);
1923 if (iptr->op1 == 0) {
1924 gen_nullptr_check(s1);
1928 var_to_reg_int(s3, src, REG_ITMP3);
1929 M_S4ADDQ(s2, s1, REG_ITMP1);
1930 M_IST (s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1933 case ICMD_FASTORE: /* ..., 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_S4ADDQ(s2, s1, REG_ITMP1);
1943 M_FST (s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1946 case ICMD_DASTORE: /* ..., 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_flt(s3, src, REG_FTMP3);
1955 M_S8ADDQ(s2, s1, REG_ITMP1);
1956 M_DST (s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1959 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1961 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1962 var_to_reg_int(s2, src->prev, REG_ITMP2);
1963 if (iptr->op1 == 0) {
1964 gen_nullptr_check(s1);
1967 var_to_reg_int(s3, src, REG_ITMP3);
1968 if (has_ext_instr_set) {
1969 M_LADD(s2, s1, REG_ITMP1);
1970 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1971 M_SST (s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1974 M_LADD (s2, s1, REG_ITMP1);
1975 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1976 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1977 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1978 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1979 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1980 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
1981 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1985 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1987 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1988 var_to_reg_int(s2, src->prev, REG_ITMP2);
1989 if (iptr->op1 == 0) {
1990 gen_nullptr_check(s1);
1993 var_to_reg_int(s3, src, REG_ITMP3);
1994 if (has_ext_instr_set) {
1995 M_LADD(s2, s1, REG_ITMP1);
1996 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1997 M_SST (s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2000 M_LADD (s2, s1, REG_ITMP1);
2001 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2002 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2003 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2004 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
2005 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2006 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2007 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2011 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
2013 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2014 var_to_reg_int(s2, src->prev, REG_ITMP2);
2015 if (iptr->op1 == 0) {
2016 gen_nullptr_check(s1);
2019 var_to_reg_int(s3, src, REG_ITMP3);
2020 if (has_ext_instr_set) {
2021 M_LADD(s2, s1, REG_ITMP1);
2022 M_BST (s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2025 M_LADD (s2, s1, REG_ITMP1);
2026 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2027 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2028 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
2029 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2030 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2031 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2036 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
2038 var_to_reg_int(s1, src->prev, REG_ITMP1);
2039 var_to_reg_int(s2, src, REG_ITMP2);
2040 if (iptr->op1 == 0) {
2041 gen_nullptr_check(s1);
2044 M_S4ADDQ(s2, s1, REG_ITMP1);
2045 M_IST(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
2048 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
2050 var_to_reg_int(s1, src->prev, REG_ITMP1);
2051 var_to_reg_int(s2, src, REG_ITMP2);
2052 if (iptr->op1 == 0) {
2053 gen_nullptr_check(s1);
2056 M_S8ADDQ(s2, s1, REG_ITMP1);
2057 M_LST(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
2060 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
2062 var_to_reg_int(s1, src->prev, REG_ITMP1);
2063 var_to_reg_int(s2, src, REG_ITMP2);
2064 if (iptr->op1 == 0) {
2065 gen_nullptr_check(s1);
2068 M_SAADDQ(s2, s1, REG_ITMP1);
2069 M_AST(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
2072 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
2074 var_to_reg_int(s1, src->prev, REG_ITMP1);
2075 var_to_reg_int(s2, src, REG_ITMP2);
2076 if (iptr->op1 == 0) {
2077 gen_nullptr_check(s1);
2080 if (has_ext_instr_set) {
2081 M_LADD(s2, s1, REG_ITMP1);
2082 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2085 M_LADD(s2, s1, REG_ITMP1);
2086 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2087 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2088 M_INSBL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2089 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2090 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2091 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2095 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
2097 var_to_reg_int(s1, src->prev, REG_ITMP1);
2098 var_to_reg_int(s2, src, REG_ITMP2);
2099 if (iptr->op1 == 0) {
2100 gen_nullptr_check(s1);
2103 if (has_ext_instr_set) {
2104 M_LADD(s2, s1, REG_ITMP1);
2105 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2106 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
2109 M_LADD(s2, s1, REG_ITMP1);
2110 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2111 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2112 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2113 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2114 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2115 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2116 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2120 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
2122 var_to_reg_int(s1, src->prev, REG_ITMP1);
2123 var_to_reg_int(s2, src, REG_ITMP2);
2124 if (iptr->op1 == 0) {
2125 gen_nullptr_check(s1);
2128 if (has_ext_instr_set) {
2129 M_LADD(s2, s1, REG_ITMP1);
2130 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2131 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2134 M_LADD(s2, s1, REG_ITMP1);
2135 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2136 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2137 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2138 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2139 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2140 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2141 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2146 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2147 /* op1 = type, val.a = field address */
2149 /* If the static fields' class is not yet initialized, we do it */
2150 /* now. The call code is generated later. */
2151 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
2152 codegen_addclinitref(cd, mcodeptr, ((fieldinfo *) iptr->val.a)->class);
2154 /* This is just for debugging purposes. Is very difficult to */
2155 /* read patched code. Here we patch the following 2 nop's */
2156 /* so that the real code keeps untouched. */
2157 if (showdisassemble) {
2162 a = dseg_addaddress(cd, &(((fieldinfo *) iptr->val.a)->value));
2163 M_ALD(REG_ITMP1, REG_PV, a);
2164 switch (iptr->op1) {
2166 var_to_reg_int(s2, src, REG_ITMP2);
2167 M_IST(s2, REG_ITMP1, 0);
2170 var_to_reg_int(s2, src, REG_ITMP2);
2171 M_LST(s2, REG_ITMP1, 0);
2174 var_to_reg_int(s2, src, REG_ITMP2);
2175 M_AST(s2, REG_ITMP1, 0);
2178 var_to_reg_flt(s2, src, REG_FTMP2);
2179 M_FST(s2, REG_ITMP1, 0);
2182 var_to_reg_flt(s2, src, REG_FTMP2);
2183 M_DST(s2, REG_ITMP1, 0);
2188 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2189 /* val = value (in current instruction) */
2190 /* op1 = type, val.a = field address (in */
2191 /* following NOP) */
2193 /* If the static fields' class is not yet initialized, we do it */
2194 /* now. The call code is generated later. */
2195 if (!((fieldinfo *) iptr[1].val.a)->class->initialized) {
2196 codegen_addclinitref(cd, mcodeptr, ((fieldinfo *) iptr[1].val.a)->class);
2198 /* This is just for debugging purposes. Is very difficult to */
2199 /* read patched code. Here we patch the following 2 nop's */
2200 /* so that the real code keeps untouched. */
2201 if (showdisassemble)
2205 a = dseg_addaddress(cd, &(((fieldinfo *) iptr[1].val.a)->value));
2206 M_ALD(REG_ITMP1, REG_PV, a);
2207 switch (iptr[1].op1) {
2209 M_IST(REG_ZERO, REG_ITMP1, 0);
2212 M_LST(REG_ZERO, REG_ITMP1, 0);
2215 M_AST(REG_ZERO, REG_ITMP1, 0);
2218 M_FST(REG_ZERO, REG_ITMP1, 0);
2221 M_DST(REG_ZERO, REG_ITMP1, 0);
2226 case ICMD_GETSTATIC: /* ... ==> ..., value */
2227 /* op1 = type, val.a = field address */
2229 /* if class isn't yet initialized, do it */
2230 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
2231 codegen_addclinitref(cd, mcodeptr, ((fieldinfo *) iptr->val.a)->class);
2233 /* This is just for debugging purposes. Is very difficult to */
2234 /* read patched code. Here we patch the following 2 nop's */
2235 /* so that the real code keeps untouched. */
2236 if (showdisassemble)
2240 a = dseg_addaddress(cd, &(((fieldinfo *) iptr->val.a)->value));
2241 M_ALD(REG_ITMP1, REG_PV, a);
2242 switch (iptr->op1) {
2244 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2245 M_ILD(d, REG_ITMP1, 0);
2246 store_reg_to_var_int(iptr->dst, d);
2249 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2250 M_LLD(d, REG_ITMP1, 0);
2251 store_reg_to_var_int(iptr->dst, d);
2254 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2255 M_ALD(d, REG_ITMP1, 0);
2256 store_reg_to_var_int(iptr->dst, d);
2259 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2260 M_FLD(d, REG_ITMP1, 0);
2261 store_reg_to_var_flt(iptr->dst, d);
2264 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2265 M_DLD(d, REG_ITMP1, 0);
2266 store_reg_to_var_flt(iptr->dst, d);
2272 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2273 /* op1 = type, val.a = field address */
2275 a = ((fieldinfo *) iptr->val.a)->offset;
2276 var_to_reg_int(s1, src->prev, REG_ITMP1);
2277 gen_nullptr_check(s1);
2278 switch (iptr->op1) {
2280 var_to_reg_int(s2, src, REG_ITMP2);
2284 var_to_reg_int(s2, src, REG_ITMP2);
2288 var_to_reg_int(s2, src, REG_ITMP2);
2292 var_to_reg_flt(s2, src, REG_FTMP2);
2296 var_to_reg_flt(s2, src, REG_FTMP2);
2302 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2303 /* val = value (in current instruction) */
2304 /* op1 = type, val.a = field address (in */
2305 /* following NOP) */
2307 a = ((fieldinfo *) iptr[1].val.a)->offset;
2308 var_to_reg_int(s1, src, REG_ITMP1);
2309 gen_nullptr_check(s1);
2310 switch (iptr[1].op1) {
2312 M_IST(REG_ZERO, s1, a);
2315 M_LST(REG_ZERO, s1, a);
2318 M_AST(REG_ZERO, s1, a);
2321 M_FST(REG_ZERO, s1, a);
2324 M_DST(REG_ZERO, s1, a);
2329 case ICMD_GETFIELD: /* ... ==> ..., value */
2330 /* op1 = type, val.i = field offset */
2332 a = ((fieldinfo *)(iptr->val.a))->offset;
2333 var_to_reg_int(s1, src, REG_ITMP1);
2334 gen_nullptr_check(s1);
2335 switch (iptr->op1) {
2337 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2339 store_reg_to_var_int(iptr->dst, d);
2342 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2344 store_reg_to_var_int(iptr->dst, d);
2347 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2349 store_reg_to_var_int(iptr->dst, d);
2352 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2354 store_reg_to_var_flt(iptr->dst, d);
2357 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2359 store_reg_to_var_flt(iptr->dst, d);
2365 /* branch operations **************************************************/
2367 #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}}
2369 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2371 var_to_reg_int(s1, src, REG_ITMP1);
2372 M_INTMOVE(s1, REG_ITMP1_XPTR);
2373 a = dseg_addaddress(cd, asm_handle_exception);
2374 M_ALD(REG_ITMP2, REG_PV, a);
2375 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2376 M_NOP; /* nop ensures that XPC is less than the end */
2377 /* of basic block */
2381 case ICMD_GOTO: /* ... ==> ... */
2382 /* op1 = target JavaVM pc */
2384 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2388 case ICMD_JSR: /* ... ==> ... */
2389 /* op1 = target JavaVM pc */
2391 M_BSR(REG_ITMP1, 0);
2392 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2395 case ICMD_RET: /* ... ==> ... */
2396 /* op1 = local variable */
2398 var = &(rd->locals[iptr->op1][TYPE_ADR]);
2399 if (var->flags & INMEMORY) {
2400 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2401 M_RET(REG_ZERO, REG_ITMP1);
2404 M_RET(REG_ZERO, var->regoff);
2408 case ICMD_IFNULL: /* ..., value ==> ... */
2409 /* op1 = target JavaVM pc */
2411 var_to_reg_int(s1, src, REG_ITMP1);
2413 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2416 case ICMD_IFNONNULL: /* ..., value ==> ... */
2417 /* op1 = target JavaVM pc */
2419 var_to_reg_int(s1, src, REG_ITMP1);
2421 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2424 case ICMD_IFEQ: /* ..., value ==> ... */
2425 /* op1 = target JavaVM pc, val.i = constant */
2427 var_to_reg_int(s1, src, REG_ITMP1);
2428 if (iptr->val.i == 0) {
2432 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2433 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2436 ICONST(REG_ITMP2, iptr->val.i);
2437 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2439 M_BNEZ(REG_ITMP1, 0);
2441 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2444 case ICMD_IFLT: /* ..., value ==> ... */
2445 /* op1 = target JavaVM pc, val.i = constant */
2447 var_to_reg_int(s1, src, REG_ITMP1);
2448 if (iptr->val.i == 0) {
2452 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2453 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2456 ICONST(REG_ITMP2, iptr->val.i);
2457 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2459 M_BNEZ(REG_ITMP1, 0);
2461 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2464 case ICMD_IFLE: /* ..., value ==> ... */
2465 /* op1 = target JavaVM pc, val.i = constant */
2467 var_to_reg_int(s1, src, REG_ITMP1);
2468 if (iptr->val.i == 0) {
2472 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2473 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2476 ICONST(REG_ITMP2, iptr->val.i);
2477 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2479 M_BNEZ(REG_ITMP1, 0);
2481 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2484 case ICMD_IFNE: /* ..., value ==> ... */
2485 /* op1 = target JavaVM pc, val.i = constant */
2487 var_to_reg_int(s1, src, REG_ITMP1);
2488 if (iptr->val.i == 0) {
2492 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2493 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2496 ICONST(REG_ITMP2, iptr->val.i);
2497 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2499 M_BEQZ(REG_ITMP1, 0);
2501 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2504 case ICMD_IFGT: /* ..., value ==> ... */
2505 /* op1 = target JavaVM pc, val.i = constant */
2507 var_to_reg_int(s1, src, REG_ITMP1);
2508 if (iptr->val.i == 0) {
2512 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2513 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2516 ICONST(REG_ITMP2, iptr->val.i);
2517 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2519 M_BEQZ(REG_ITMP1, 0);
2521 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2524 case ICMD_IFGE: /* ..., value ==> ... */
2525 /* op1 = target JavaVM pc, val.i = constant */
2527 var_to_reg_int(s1, src, REG_ITMP1);
2528 if (iptr->val.i == 0) {
2532 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2533 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2536 ICONST(REG_ITMP2, iptr->val.i);
2537 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2539 M_BEQZ(REG_ITMP1, 0);
2541 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2544 case ICMD_IF_LEQ: /* ..., value ==> ... */
2545 /* op1 = target JavaVM pc, val.l = constant */
2547 var_to_reg_int(s1, src, REG_ITMP1);
2548 if (iptr->val.l == 0) {
2552 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2553 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2556 LCONST(REG_ITMP2, iptr->val.l);
2557 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2559 M_BNEZ(REG_ITMP1, 0);
2561 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2564 case ICMD_IF_LLT: /* ..., value ==> ... */
2565 /* op1 = target JavaVM pc, val.l = constant */
2567 var_to_reg_int(s1, src, REG_ITMP1);
2568 if (iptr->val.l == 0) {
2572 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2573 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2576 LCONST(REG_ITMP2, iptr->val.l);
2577 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2579 M_BNEZ(REG_ITMP1, 0);
2581 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2584 case ICMD_IF_LLE: /* ..., value ==> ... */
2585 /* op1 = target JavaVM pc, val.l = constant */
2587 var_to_reg_int(s1, src, REG_ITMP1);
2588 if (iptr->val.l == 0) {
2592 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2593 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2596 LCONST(REG_ITMP2, iptr->val.l);
2597 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2599 M_BNEZ(REG_ITMP1, 0);
2601 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2604 case ICMD_IF_LNE: /* ..., value ==> ... */
2605 /* op1 = target JavaVM pc, val.l = constant */
2607 var_to_reg_int(s1, src, REG_ITMP1);
2608 if (iptr->val.l == 0) {
2612 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2613 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2616 LCONST(REG_ITMP2, iptr->val.l);
2617 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2619 M_BEQZ(REG_ITMP1, 0);
2621 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2624 case ICMD_IF_LGT: /* ..., value ==> ... */
2625 /* op1 = target JavaVM pc, val.l = constant */
2627 var_to_reg_int(s1, src, REG_ITMP1);
2628 if (iptr->val.l == 0) {
2632 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2633 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2636 LCONST(REG_ITMP2, iptr->val.l);
2637 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2639 M_BEQZ(REG_ITMP1, 0);
2641 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2644 case ICMD_IF_LGE: /* ..., value ==> ... */
2645 /* op1 = target JavaVM pc, val.l = constant */
2647 var_to_reg_int(s1, src, REG_ITMP1);
2648 if (iptr->val.l == 0) {
2652 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2653 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2656 LCONST(REG_ITMP2, iptr->val.l);
2657 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2659 M_BEQZ(REG_ITMP1, 0);
2661 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2664 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2665 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2666 case ICMD_IF_ACMPEQ:
2668 var_to_reg_int(s1, src->prev, REG_ITMP1);
2669 var_to_reg_int(s2, src, REG_ITMP2);
2670 M_CMPEQ(s1, s2, REG_ITMP1);
2671 M_BNEZ(REG_ITMP1, 0);
2672 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2675 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2676 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2677 case ICMD_IF_ACMPNE:
2679 var_to_reg_int(s1, src->prev, REG_ITMP1);
2680 var_to_reg_int(s2, src, REG_ITMP2);
2681 M_CMPEQ(s1, s2, REG_ITMP1);
2682 M_BEQZ(REG_ITMP1, 0);
2683 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2686 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2687 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2689 var_to_reg_int(s1, src->prev, REG_ITMP1);
2690 var_to_reg_int(s2, src, REG_ITMP2);
2691 M_CMPLT(s1, s2, REG_ITMP1);
2692 M_BNEZ(REG_ITMP1, 0);
2693 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2696 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2697 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2699 var_to_reg_int(s1, src->prev, REG_ITMP1);
2700 var_to_reg_int(s2, src, REG_ITMP2);
2701 M_CMPLE(s1, s2, REG_ITMP1);
2702 M_BEQZ(REG_ITMP1, 0);
2703 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2706 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2707 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2709 var_to_reg_int(s1, src->prev, REG_ITMP1);
2710 var_to_reg_int(s2, src, REG_ITMP2);
2711 M_CMPLE(s1, s2, REG_ITMP1);
2712 M_BNEZ(REG_ITMP1, 0);
2713 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2716 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2717 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2719 var_to_reg_int(s1, src->prev, REG_ITMP1);
2720 var_to_reg_int(s2, src, REG_ITMP2);
2721 M_CMPLT(s1, s2, REG_ITMP1);
2722 M_BEQZ(REG_ITMP1, 0);
2723 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2726 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2728 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2731 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2732 /* val.i = constant */
2734 var_to_reg_int(s1, src, REG_ITMP1);
2735 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2737 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2738 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2739 M_CMPEQ(s1, REG_ZERO, d);
2740 store_reg_to_var_int(iptr->dst, d);
2743 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2744 M_CMPEQ(s1, REG_ZERO, d);
2746 store_reg_to_var_int(iptr->dst, d);
2750 M_MOV(s1, REG_ITMP1);
2753 ICONST(d, iptr[1].val.i);
2755 if ((s3 >= 0) && (s3 <= 255)) {
2756 M_CMOVEQ_IMM(s1, s3, d);
2759 ICONST(REG_ITMP2, s3);
2760 M_CMOVEQ(s1, REG_ITMP2, d);
2762 store_reg_to_var_int(iptr->dst, d);
2765 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2766 /* val.i = constant */
2768 var_to_reg_int(s1, src, REG_ITMP1);
2769 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2771 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2772 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2773 M_CMPEQ(s1, REG_ZERO, d);
2774 store_reg_to_var_int(iptr->dst, d);
2777 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2778 M_CMPEQ(s1, REG_ZERO, d);
2780 store_reg_to_var_int(iptr->dst, d);
2784 M_MOV(s1, REG_ITMP1);
2787 ICONST(d, iptr[1].val.i);
2789 if ((s3 >= 0) && (s3 <= 255)) {
2790 M_CMOVNE_IMM(s1, s3, d);
2793 ICONST(REG_ITMP2, s3);
2794 M_CMOVNE(s1, REG_ITMP2, d);
2796 store_reg_to_var_int(iptr->dst, d);
2799 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2800 /* val.i = constant */
2802 var_to_reg_int(s1, src, REG_ITMP1);
2803 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2805 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2806 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2807 M_CMPLT(s1, REG_ZERO, d);
2808 store_reg_to_var_int(iptr->dst, d);
2811 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2812 M_CMPLE(REG_ZERO, s1, d);
2813 store_reg_to_var_int(iptr->dst, d);
2817 M_MOV(s1, REG_ITMP1);
2820 ICONST(d, iptr[1].val.i);
2822 if ((s3 >= 0) && (s3 <= 255)) {
2823 M_CMOVLT_IMM(s1, s3, d);
2826 ICONST(REG_ITMP2, s3);
2827 M_CMOVLT(s1, REG_ITMP2, d);
2829 store_reg_to_var_int(iptr->dst, d);
2832 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2833 /* val.i = constant */
2835 var_to_reg_int(s1, src, REG_ITMP1);
2836 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2838 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2839 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2840 M_CMPLE(REG_ZERO, s1, d);
2841 store_reg_to_var_int(iptr->dst, d);
2844 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2845 M_CMPLT(s1, REG_ZERO, d);
2846 store_reg_to_var_int(iptr->dst, d);
2850 M_MOV(s1, REG_ITMP1);
2853 ICONST(d, iptr[1].val.i);
2855 if ((s3 >= 0) && (s3 <= 255)) {
2856 M_CMOVGE_IMM(s1, s3, d);
2859 ICONST(REG_ITMP2, s3);
2860 M_CMOVGE(s1, REG_ITMP2, d);
2862 store_reg_to_var_int(iptr->dst, d);
2865 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2866 /* val.i = constant */
2868 var_to_reg_int(s1, src, REG_ITMP1);
2869 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2871 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2872 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2873 M_CMPLT(REG_ZERO, s1, d);
2874 store_reg_to_var_int(iptr->dst, d);
2877 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2878 M_CMPLE(s1, REG_ZERO, d);
2879 store_reg_to_var_int(iptr->dst, d);
2883 M_MOV(s1, REG_ITMP1);
2886 ICONST(d, iptr[1].val.i);
2888 if ((s3 >= 0) && (s3 <= 255)) {
2889 M_CMOVGT_IMM(s1, s3, d);
2892 ICONST(REG_ITMP2, s3);
2893 M_CMOVGT(s1, REG_ITMP2, d);
2895 store_reg_to_var_int(iptr->dst, d);
2898 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2899 /* val.i = constant */
2901 var_to_reg_int(s1, src, REG_ITMP1);
2902 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2904 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2905 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2906 M_CMPLE(s1, REG_ZERO, d);
2907 store_reg_to_var_int(iptr->dst, d);
2910 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2911 M_CMPLT(REG_ZERO, s1, d);
2912 store_reg_to_var_int(iptr->dst, d);
2916 M_MOV(s1, REG_ITMP1);
2919 ICONST(d, iptr[1].val.i);
2921 if ((s3 >= 0) && (s3 <= 255)) {
2922 M_CMOVLE_IMM(s1, s3, d);
2925 ICONST(REG_ITMP2, s3);
2926 M_CMOVLE(s1, REG_ITMP2, d);
2928 store_reg_to_var_int(iptr->dst, d);
2932 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2936 var_to_reg_int(s1, src, REG_RESULT);
2937 M_INTMOVE(s1, REG_RESULT);
2939 #if defined(USE_THREADS)
2940 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2942 a = dseg_addaddress(cd, (void *) (builtin_monitorexit));
2943 M_ALD(REG_PV, REG_PV, a);
2944 M_ALD(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
2945 M_LST(REG_RESULT, REG_SP, rd->maxmemuse * 8);
2946 M_JSR(REG_RA, REG_PV);
2947 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
2948 M_LDA(REG_PV, REG_RA, disp);
2949 M_LLD(REG_RESULT, REG_SP, rd->maxmemuse * 8);
2953 goto nowperformreturn;
2955 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2958 var_to_reg_flt(s1, src, REG_FRESULT);
2959 M_FLTMOVE(s1, REG_FRESULT);
2961 #if defined(USE_THREADS)
2962 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2964 a = dseg_addaddress(cd, (void *) (builtin_monitorexit));
2965 M_ALD(REG_PV, REG_PV, a);
2966 M_ALD(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
2967 M_DST(REG_FRESULT, REG_SP, rd->maxmemuse * 8);
2968 M_JSR(REG_RA, REG_PV);
2969 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
2970 M_LDA(REG_PV, REG_RA, disp);
2971 M_DLD(REG_FRESULT, REG_SP, rd->maxmemuse * 8);
2975 goto nowperformreturn;
2977 case ICMD_RETURN: /* ... ==> ... */
2979 #if defined(USE_THREADS)
2980 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2982 a = dseg_addaddress(cd, (void *) (builtin_monitorexit));
2983 M_ALD(REG_PV, REG_PV, a);
2984 M_ALD(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
2985 M_JSR(REG_RA, REG_PV);
2986 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
2987 M_LDA(REG_PV, REG_RA, disp);
2995 p = parentargs_base;
2997 /* restore return address */
2999 if (!m->isleafmethod) {
3000 p--; M_LLD(REG_RA, REG_SP, p * 8);
3003 /* restore saved registers */
3005 for (i = rd->savintregcnt - 1; i >= rd->maxsavintreguse; i--) {
3006 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
3008 for (i = rd->savfltregcnt - 1; i >= rd->maxsavfltreguse; i--) {
3009 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
3012 /* deallocate stack */
3014 if (parentargs_base) {
3015 M_LDA(REG_SP, REG_SP, parentargs_base * 8);
3018 /* call trace function */
3021 M_LDA(REG_SP, REG_SP, -3 * 8);
3022 M_AST(REG_RA, REG_SP, 0 * 8);
3023 M_LST(REG_RESULT, REG_SP, 1 * 8);
3024 M_DST(REG_FRESULT, REG_SP, 2 * 8);
3025 a = dseg_addaddress(cd, m);
3026 M_ALD(rd->argintregs[0], REG_PV, a);
3027 M_MOV(REG_RESULT, rd->argintregs[1]);
3028 M_FLTMOVE(REG_FRESULT, rd->argfltregs[2]);
3029 M_FLTMOVE(REG_FRESULT, rd->argfltregs[3]);
3030 a = dseg_addaddress(cd, (void *) builtin_displaymethodstop);
3031 M_ALD(REG_PV, REG_PV, a);
3032 M_JSR(REG_RA, REG_PV);
3033 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3034 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3036 s4 ml = -s1, mh = 0;
3037 while (ml < -32768) { ml += 65536; mh--; }
3038 M_LDA(REG_PV, REG_RA, ml);
3039 M_LDAH(REG_PV, REG_PV, mh);
3041 M_DLD(REG_FRESULT, REG_SP, 2 * 8);
3042 M_LLD(REG_RESULT, REG_SP, 1 * 8);
3043 M_ALD(REG_RA, REG_SP, 0 * 8);
3044 M_LDA(REG_SP, REG_SP, 3 * 8);
3047 M_RET(REG_ZERO, REG_RA);
3053 case ICMD_TABLESWITCH: /* ..., index ==> ... */
3058 tptr = (void **) iptr->target;
3060 s4ptr = iptr->val.a;
3061 l = s4ptr[1]; /* low */
3062 i = s4ptr[2]; /* high */
3064 var_to_reg_int(s1, src, REG_ITMP1);
3066 {M_INTMOVE(s1, REG_ITMP1);}
3067 else if (l <= 32768) {
3068 M_LDA(REG_ITMP1, s1, -l);
3071 ICONST(REG_ITMP2, l);
3072 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
3079 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
3081 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
3082 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3084 M_BEQZ(REG_ITMP2, 0);
3087 /* codegen_addreference(cd, BlockPtrOfPC(s4ptr[0]), mcodeptr); */
3088 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3090 /* build jump table top down and use address of lowest entry */
3092 /* s4ptr += 3 + i; */
3096 /* dseg_addtarget(cd, BlockPtrOfPC(*--s4ptr)); */
3097 dseg_addtarget(cd, (basicblock *) tptr[0]);
3102 /* length of dataseg after last dseg_addtarget is used by load */
3104 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
3105 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
3106 M_JMP(REG_ZERO, REG_ITMP2);
3111 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3113 s4 i, l, val, *s4ptr;
3116 tptr = (void **) iptr->target;
3118 s4ptr = iptr->val.a;
3119 l = s4ptr[0]; /* default */
3120 i = s4ptr[1]; /* count */
3122 MCODECHECK((i<<2)+8);
3123 var_to_reg_int(s1, src, REG_ITMP1);
3129 if ((val >= 0) && (val <= 255)) {
3130 M_CMPEQ_IMM(s1, val, REG_ITMP2);
3133 if ((val >= -32768) && (val <= 32767)) {
3134 M_LDA(REG_ITMP2, REG_ZERO, val);
3137 a = dseg_adds4(cd, val);
3138 M_ILD(REG_ITMP2, REG_PV, a);
3140 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
3142 M_BNEZ(REG_ITMP2, 0);
3143 /* codegen_addreference(cd, BlockPtrOfPC(s4ptr[1]), mcodeptr); */
3144 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3148 /* codegen_addreference(cd, BlockPtrOfPC(l), mcodeptr); */
3150 tptr = (void **) iptr->target;
3151 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3158 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
3159 /* op1 = return type, val.a = function pointer*/
3163 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
3164 /* op1 = return type, val.a = function pointer*/
3168 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
3169 /* op1 = return type, val.a = function pointer*/
3173 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3174 /* op1 = arg count, val.a = method pointer */
3176 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3177 /* op1 = arg count, val.a = method pointer */
3179 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3180 /* op1 = arg count, val.a = method pointer */
3182 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
3183 /* op1 = arg count, val.a = method pointer */
3190 MCODECHECK((s3 << 1) + 64);
3192 /* copy arguments to registers or stack location */
3194 for (; --s3 >= 0; src = src->prev) {
3195 if (src->varkind == ARGVAR)
3197 if (IS_INT_LNG_TYPE(src->type)) {
3198 if (s3 < INT_ARG_CNT) {
3199 s1 = rd->argintregs[s3];
3200 var_to_reg_int(d, src, s1);
3204 var_to_reg_int(d, src, REG_ITMP1);
3205 M_LST(d, REG_SP, 8 * (s3 - INT_ARG_CNT));
3209 if (s3 < FLT_ARG_CNT) {
3210 s1 = rd->argfltregs[s3];
3211 var_to_reg_flt(d, src, s1);
3215 var_to_reg_flt(d, src, REG_FTMP1);
3216 M_DST(d, REG_SP, 8 * (s3 - FLT_ARG_CNT));
3222 switch (iptr->opc) {
3226 a = dseg_addaddress(cd, (void *) lm);
3229 M_ALD(REG_PV, REG_PV, a); /* Pointer to built-in-function */
3232 case ICMD_INVOKESTATIC:
3233 a = dseg_addaddress(cd, lm->stubroutine);
3236 M_ALD(REG_PV, REG_PV, a); /* method pointer in r27 */
3239 case ICMD_INVOKESPECIAL:
3240 a = dseg_addaddress(cd, lm->stubroutine);
3243 gen_nullptr_check(rd->argintregs[0]);
3244 M_ILD(REG_ITMP1, rd->argintregs[0], 0); /* hardware nullpointer */
3245 M_ALD(REG_PV, REG_PV, a); /* method pointer in r27 */
3248 case ICMD_INVOKEVIRTUAL:
3251 gen_nullptr_check(rd->argintregs[0]);
3252 M_ALD(REG_METHODPTR, rd->argintregs[0],
3253 OFFSET(java_objectheader, vftbl));
3254 M_ALD(REG_PV, REG_METHODPTR, OFFSET(vftbl_t, table[0]) +
3255 sizeof(methodptr) * lm->vftblindex);
3258 case ICMD_INVOKEINTERFACE:
3261 gen_nullptr_check(rd->argintregs[0]);
3262 M_ALD(REG_METHODPTR, rd->argintregs[0],
3263 OFFSET(java_objectheader, vftbl));
3264 M_ALD(REG_METHODPTR, REG_METHODPTR,
3265 OFFSET(vftbl_t, interfacetable[0]) -
3266 sizeof(methodptr*) * lm->class->index);
3267 M_ALD(REG_PV, REG_METHODPTR,
3268 sizeof(methodptr) * (lm - lm->class->methods));
3272 M_JSR(REG_RA, REG_PV);
3276 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3277 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3279 s4 ml = -s1, mh = 0;
3280 while (ml < -32768) { ml += 65536; mh--; }
3281 M_LDA(REG_PV, REG_RA, ml);
3282 M_LDAH(REG_PV, REG_PV, mh);
3285 /* d contains return type */
3287 if (d != TYPE_VOID) {
3288 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3289 s1 = reg_of_var(rd, iptr->dst, REG_RESULT);
3290 M_INTMOVE(REG_RESULT, s1);
3291 store_reg_to_var_int(iptr->dst, s1);
3294 s1 = reg_of_var(rd, iptr->dst, REG_FRESULT);
3295 M_FLTMOVE(REG_FRESULT, s1);
3296 store_reg_to_var_flt(iptr->dst, s1);
3303 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3305 /* op1: 0 == array, 1 == class */
3306 /* val.a: (classinfo*) superclass */
3308 /* superclass is an interface:
3310 * return (sub != NULL) &&
3311 * (sub->vftbl->interfacetablelength > super->index) &&
3312 * (sub->vftbl->interfacetable[-super->index] != NULL);
3314 * superclass is a class:
3316 * return ((sub != NULL) && (0
3317 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3318 * super->vftbl->diffvall));
3322 classinfo *super = (classinfo*) iptr->val.a;
3324 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3325 codegen_threadcritrestart(cd, (u1 *) mcodeptr - cd->mcodebase);
3327 var_to_reg_int(s1, src, REG_ITMP1);
3328 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
3330 M_MOV(s1, REG_ITMP1);
3334 if (iptr->op1) { /* class/interface */
3335 if (super->flags & ACC_INTERFACE) { /* interface */
3337 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3338 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3339 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3340 M_BLEZ(REG_ITMP2, 2);
3341 M_ALD(REG_ITMP1, REG_ITMP1,
3342 OFFSET(vftbl_t, interfacetable[0]) -
3343 super->index * sizeof(methodptr*));
3344 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3348 s2 = super->vftbl->diffval;
3349 M_BEQZ(s1, 4 + (s2 > 255));
3350 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3351 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3352 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3354 M_CMPULE_IMM(REG_ITMP1, s2, d);
3356 M_LDA(REG_ITMP2, REG_ZERO, s2);
3357 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3361 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3362 a = dseg_addaddress(cd, (void*) super->vftbl);
3363 M_ALD(REG_ITMP2, REG_PV, a);
3364 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3365 codegen_threadcritstart(cd, (u1 *) mcodeptr - cd->mcodebase);
3367 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3368 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3369 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3370 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3371 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3373 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3374 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3378 panic ("internal error: no inlined array instanceof");
3380 store_reg_to_var_int(iptr->dst, d);
3383 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3385 /* op1: 0 == array, 1 == class */
3386 /* val.a: (classinfo*) superclass */
3388 /* superclass is an interface:
3390 * OK if ((sub == NULL) ||
3391 * (sub->vftbl->interfacetablelength > super->index) &&
3392 * (sub->vftbl->interfacetable[-super->index] != NULL));
3394 * superclass is a class:
3396 * OK if ((sub == NULL) || (0
3397 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3398 * super->vftbl->diffval));
3402 classinfo *super = (classinfo *) iptr->val.a;
3404 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3405 codegen_threadcritrestart(cd, (u1 *) mcodeptr - cd->mcodebase);
3407 var_to_reg_int(s1, src, REG_ITMP1);
3408 if (iptr->op1) { /* class/interface */
3409 if (super->flags & ACC_INTERFACE) { /* interface */
3411 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3412 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
3413 M_LDA(REG_ITMP3, REG_ITMP3, - super->index);
3414 M_BLEZ(REG_ITMP3, 0);
3415 codegen_addxcastrefs(cd, mcodeptr);
3416 M_ALD(REG_ITMP3, REG_ITMP2,
3417 OFFSET(vftbl_t, interfacetable[0]) -
3418 super->index * sizeof(methodptr*));
3419 M_BEQZ(REG_ITMP3, 0);
3420 codegen_addxcastrefs(cd, mcodeptr);
3422 } else { /* class */
3424 s2 = super->vftbl->diffval;
3425 M_BEQZ(s1, 4 + (s2 != 0) + (s2 > 255));
3426 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3427 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3428 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3430 M_BNEZ(REG_ITMP1, 0);
3432 else if (s2 <= 255) {
3433 M_CMPULE_IMM(REG_ITMP1, s2, REG_ITMP2);
3434 M_BEQZ(REG_ITMP2, 0);
3437 M_LDA(REG_ITMP2, REG_ZERO, s2);
3438 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3439 M_BEQZ(REG_ITMP2, 0);
3442 M_BEQZ(s1, 8 + (s1 == REG_ITMP1));
3443 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3444 a = dseg_addaddress(cd, (void *) super->vftbl);
3445 M_ALD(REG_ITMP3, REG_PV, a);
3446 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3447 codegen_threadcritstart(cd, (u1 *) mcodeptr - cd->mcodebase);
3449 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3450 if (s1 != REG_ITMP1) {
3451 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval));
3452 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3453 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3454 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3456 M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2);
3459 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3460 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3461 M_ALD(REG_ITMP3, REG_PV, a);
3462 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3463 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3464 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3467 M_CMPULE(REG_ITMP2, REG_ITMP3, REG_ITMP3);
3468 M_BEQZ(REG_ITMP3, 0);
3469 codegen_addxcastrefs(cd, mcodeptr);
3473 panic ("internal error: no inlined array checkcast");
3475 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
3477 store_reg_to_var_int(iptr->dst, d);
3480 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
3482 var_to_reg_int(s1, src, REG_ITMP1);
3484 codegen_addxcheckarefs(cd, mcodeptr);
3487 case ICMD_CHECKEXCEPTION: /* ... ==> ... */
3489 M_BEQZ(REG_RESULT, 0);
3490 codegen_addxexceptionrefs(cd, mcodeptr);
3493 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3494 /* op1 = dimension, val.a = array descriptor */
3496 /* check for negative sizes and copy sizes to stack if necessary */
3498 MCODECHECK((iptr->op1 << 1) + 64);
3500 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3501 var_to_reg_int(s2, src, REG_ITMP1);
3503 codegen_addxcheckarefs(cd, mcodeptr);
3505 /* copy SAVEDVAR sizes to stack */
3507 if (src->varkind != ARGVAR) {
3508 M_LST(s2, REG_SP, s1 * 8);
3512 /* a0 = dimension count */
3514 ICONST(rd->argintregs[0], iptr->op1);
3516 /* a1 = arraydescriptor */
3518 a = dseg_addaddress(cd, iptr->val.a);
3519 M_ALD(rd->argintregs[1], REG_PV, a);
3521 /* a2 = pointer to dimensions = stack pointer */
3523 M_INTMOVE(REG_SP, rd->argintregs[2]);
3525 a = dseg_addaddress(cd, (void *) builtin_nmultianewarray);
3526 M_ALD(REG_PV, REG_PV, a);
3527 M_JSR(REG_RA, REG_PV);
3528 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3530 M_LDA(REG_PV, REG_RA, -s1);
3532 s4 ml = -s1, mh = 0;
3533 while (ml < -32768) { ml += 65536; mh--; }
3534 M_LDA(REG_PV, REG_RA, ml);
3535 M_LDAH(REG_PV, REG_PV, mh);
3537 s1 = reg_of_var(rd, iptr->dst, REG_RESULT);
3538 M_INTMOVE(REG_RESULT, s1);
3539 store_reg_to_var_int(iptr->dst, s1);
3543 throw_cacao_exception_exit(string_java_lang_InternalError,
3544 "Unknown ICMD %d", iptr->opc);
3547 } /* for instruction */
3549 /* copy values to interface registers */
3551 src = bptr->outstack;
3552 len = bptr->outdepth;
3559 if ((src->varkind != STACKVAR)) {
3561 if (IS_FLT_DBL_TYPE(s2)) {
3562 var_to_reg_flt(s1, src, REG_FTMP1);
3563 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3564 M_FLTMOVE(s1,rd->interfaces[len][s2].regoff);
3567 M_DST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3571 var_to_reg_int(s1, src, REG_ITMP1);
3572 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3573 M_INTMOVE(s1,rd->interfaces[len][s2].regoff);
3576 M_LST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3582 } /* if (bptr -> flags >= BBREACHED) */
3583 } /* for basic block */
3585 codegen_createlinenumbertable(cd);
3588 /* generate bound check stubs */
3590 s4 *xcodeptr = NULL;
3593 for (bref = cd->xboundrefs; bref != NULL; bref = bref->next) {
3594 gen_resolvebranch((u1*) cd->mcodebase + bref->branchpos,
3596 (u1*) mcodeptr - cd->mcodebase);
3600 /* move index register into REG_ITMP1 */
3601 M_MOV(bref->reg, REG_ITMP1);
3602 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3604 if (xcodeptr != NULL) {
3605 M_BR(xcodeptr - mcodeptr - 1);
3608 xcodeptr = mcodeptr;
3610 a = dseg_addaddress(cd, asm_throw_and_handle_arrayindexoutofbounds_exception);
3611 M_ALD(REG_PV, REG_PV, a);
3613 M_JSR(REG_RA, REG_PV);
3616 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3617 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3619 s4 ml = -s1, mh = 0;
3620 while (ml < -32768) { ml += 65536; mh--; }
3621 M_LDA(REG_PV, REG_RA, ml);
3622 M_LDAH(REG_PV, REG_PV, mh);
3627 /* generate negative array size check stubs */
3631 for (bref = cd->xcheckarefs; bref != NULL; bref = bref->next) {
3632 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3633 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3635 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3639 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3641 (u1 *) mcodeptr - cd->mcodebase);
3645 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3647 if (xcodeptr != NULL) {
3648 M_BR(xcodeptr - mcodeptr - 1);
3651 xcodeptr = mcodeptr;
3654 a = dseg_addaddress(cd, string_java_lang_NegativeArraySizeException);
3655 M_ALD(REG_ITMP1_XPTR,REG_PV,a);
3657 a = dseg_addaddress(cd, asm_throw_and_handle_nat_exception);
3658 M_ALD(REG_PV, REG_PV, a);
3660 M_JSR(REG_RA, REG_PV);
3663 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3664 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3666 s4 ml = -s1, mh = 0;
3667 while (ml < -32768) { ml += 65536; mh--; }
3668 M_LDA(REG_PV, REG_RA, ml);
3669 M_LDAH(REG_PV, REG_PV, mh);
3676 /* generate cast check stubs */
3680 for (bref = cd->xcastrefs; bref != NULL; bref = bref->next) {
3681 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3682 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3684 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3688 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3690 (u1 *) mcodeptr - cd->mcodebase);
3694 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3696 if (xcodeptr != NULL) {
3697 M_BR(xcodeptr - mcodeptr - 1);
3700 xcodeptr = mcodeptr;
3702 a = dseg_addaddress(cd, string_java_lang_ClassCastException);
3703 M_ALD(REG_ITMP1_XPTR,REG_PV,a);
3705 a = dseg_addaddress(cd, asm_throw_and_handle_nat_exception);
3706 M_ALD(REG_PV, REG_PV, a);
3708 M_JSR(REG_RA, REG_PV);
3711 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3712 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3714 s4 ml = -s1, mh = 0;
3715 while (ml < -32768) { ml += 65536; mh--; }
3716 M_LDA(REG_PV, REG_RA, ml);
3717 M_LDAH(REG_PV, REG_PV, mh);
3723 /* generate exception check stubs */
3727 for (bref = cd->xexceptionrefs; bref != NULL; bref = bref->next) {
3728 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3729 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3731 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3735 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3737 (u1 *) mcodeptr - cd->mcodebase);
3741 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3743 if (xcodeptr != NULL) {
3744 M_BR(xcodeptr - mcodeptr - 1);
3747 xcodeptr = mcodeptr;
3749 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3750 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3751 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3753 a = dseg_addaddress(cd, &builtin_get_exceptionptrptr);
3754 M_ALD(REG_PV, REG_PV, a);
3755 M_JSR(REG_RA, REG_PV);
3758 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3759 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3761 s4 ml = -s1, mh = 0;
3762 while (ml < -32768) { ml += 65536; mh--; }
3763 M_LDA(REG_PV, REG_RA, ml);
3764 M_LDAH(REG_PV, REG_PV, mh);
3767 M_ALD(REG_ITMP1_XPTR, REG_RESULT, 0);
3768 M_AST(REG_ZERO, REG_RESULT, 0);
3770 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3771 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3773 a = dseg_addaddress(cd, &_exceptionptr);
3774 M_ALD(REG_ITMP3, REG_PV, a);
3775 M_ALD(REG_ITMP1_XPTR, REG_ITMP3, 0);
3776 M_AST(REG_ZERO, REG_ITMP3, 0);
3779 a = dseg_addaddress(cd, asm_refillin_and_handle_exception);
3780 M_ALD(REG_PV, REG_PV, a);
3782 M_JMP(REG_RA, REG_PV);
3785 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3786 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3788 s4 ml = -s1, mh = 0;
3789 while (ml < -32768) { ml += 65536; mh--; }
3790 M_LDA(REG_PV, REG_RA, ml);
3791 M_LDAH(REG_PV, REG_PV, mh);
3797 /* generate null pointer check stubs */
3801 for (bref = cd->xnullrefs; bref != NULL; bref = bref->next) {
3802 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3803 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3805 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3809 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3811 (u1 *) mcodeptr - cd->mcodebase);
3815 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3817 if (xcodeptr != NULL) {
3818 M_BR(xcodeptr - mcodeptr - 1);
3821 xcodeptr = mcodeptr;
3823 a = dseg_addaddress(cd, string_java_lang_NullPointerException);
3824 M_ALD(REG_ITMP1_XPTR,REG_PV,a);
3826 a = dseg_addaddress(cd, asm_throw_and_handle_nat_exception);
3827 M_ALD(REG_PV, REG_PV, a);
3829 M_JSR(REG_RA, REG_PV);
3832 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3833 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3835 s4 ml = -s1, mh = 0;
3836 while (ml < -32768) { ml += 65536; mh--; }
3837 M_LDA(REG_PV, REG_RA, ml);
3838 M_LDAH(REG_PV, REG_PV, mh);
3844 /* generate put/getstatic stub call code */
3851 for (cref = cd->clinitrefs; cref != NULL; cref = cref->next) {
3852 /* Get machine code which is patched back in later. The call is */
3853 /* 1 instruction word long. */
3854 xcodeptr = (s4 *) (cd->mcodebase + cref->branchpos);
3857 /* patch in the call to call the following code (done at compile */
3860 tmpmcodeptr = mcodeptr; /* save current mcodeptr */
3861 mcodeptr = xcodeptr; /* set mcodeptr to patch position */
3863 M_BSR(REG_RA, tmpmcodeptr - (xcodeptr + 1));
3865 mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
3869 /* move class pointer into REG_ITMP2 */
3870 a = dseg_addaddress(cd, cref->class);
3871 M_ALD(REG_ITMP1, REG_PV, a);
3873 /* move machine code onto stack */
3874 a = dseg_adds4(cd, mcode);
3875 M_ILD(REG_ITMP3, REG_PV, a);
3876 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3877 M_IST(REG_ITMP3, REG_SP, 0);
3879 a = dseg_addaddress(cd, asm_check_clinit);
3880 M_ALD(REG_ITMP2, REG_PV, a);
3881 M_JMP(REG_ZERO, REG_ITMP2);
3886 codegen_finish(m, cd, (s4) ((u1 *) mcodeptr - cd->mcodebase));
3890 /* function createcompilerstub *************************************************
3892 creates a stub routine which calls the compiler
3894 *******************************************************************************/
3896 #define COMPSTUBSIZE 3
3898 u1 *createcompilerstub(methodinfo *m)
3900 u8 *s = CNEW(u8, COMPSTUBSIZE); /* memory to hold the stub */
3901 s4 *mcodeptr = (s4 *) s; /* code generation pointer */
3903 /* code for the stub */
3904 M_ALD(REG_PV, REG_PV, 16); /* load pointer to the compiler */
3905 M_JMP(0, REG_PV); /* jump to the compiler, return address
3906 in reg 0 is used as method pointer */
3907 s[1] = (u8) m; /* literals to be adressed */
3908 s[2] = (u8) asm_call_jit_compiler; /* jump directly via PV from above */
3910 #if defined(STATISTICS)
3912 count_cstub_len += COMPSTUBSIZE * 8;
3919 /* function removecompilerstub *************************************************
3921 deletes a compilerstub from memory (simply by freeing it)
3923 *******************************************************************************/
3925 void removecompilerstub(u1 *stub)
3927 CFREE(stub, COMPSTUBSIZE * 8);
3931 /* function: createnativestub **************************************************
3933 creates a stub routine which calls a native method
3935 *******************************************************************************/
3938 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3939 #define NATIVESTUB_STACK 8/*ra,native result, oldThreadspecificHeadValue, addressOfThreadspecificHead, method, 0,0,ra*/
3940 #define NATIVESTUB_THREAD_EXTRA (6 + 20) /*20 for additional frame creation*/
3941 #define NATIVESTUB_STACKTRACE_OFFSET 1
3943 #define NATIVESTUB_STACK 7/*ra,oldThreadspecificHeadValue, addressOfThreadspecificHead, method, 0,0,ra*/
3944 #define NATIVESTUB_THREAD_EXTRA (1 + 20) /*20 for additional frame creation*/
3945 #define NATIVESTUB_STACKTRACE_OFFSET 0
3948 #define NATIVESTUB_SIZE (44 + NATIVESTUB_THREAD_EXTRA - 1)
3949 #define NATIVESTUB_STATIC_SIZE 5
3950 #define NATIVESTUB_VERBOSE_SIZE (39 + 13)
3951 #define NATIVESTUB_OFFSET 11
3954 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3955 #define NATIVESTUB_STACK 2
3956 #define NATIVESTUB_THREAD_EXTRA 6
3958 #define NATIVESTUB_STACK 1
3959 #define NATIVESTUB_THREAD_EXTRA 1
3962 #define NATIVESTUB_SIZE (44 + NATIVESTUB_THREAD_EXTRA - 1)
3963 #define NATIVESTUB_STATIC_SIZE 4
3964 #define NATIVESTUB_VERBOSE_SIZE (39 + 13)
3965 #define NATIVESTUB_OFFSET 10
3968 u1 *createnativestub(functionptr f, methodinfo *m)
3970 u8 *s; /* memory pointer to hold the stub */
3972 s4 *mcodeptr; /* code generation pointer */
3973 s4 stackframesize = 0; /* size of stackframe if needed */
3978 t_inlining_globals *id;
3981 /* mark start of dump memory area */
3983 dumpsize = dump_size();
3985 /* setup registers before using it */
3987 cd = DNEW(codegendata);
3988 rd = DNEW(registerdata);
3989 id = DNEW(t_inlining_globals);
3991 inlining_setup(m, id);
3992 reg_setup(m, rd, id);
3994 descriptor2types(m); /* set paramcount and paramtypes */
3996 stubsize = NATIVESTUB_SIZE; /* calculate nativestub size */
3998 if ((m->flags & ACC_STATIC) && !m->class->initialized)
3999 stubsize += NATIVESTUB_STATIC_SIZE;
4002 stubsize += NATIVESTUB_VERBOSE_SIZE;
4004 s = CNEW(u8, stubsize); /* memory to hold the stub */
4005 cs = s + NATIVESTUB_OFFSET;
4006 mcodeptr = (s4 *) cs; /* code generation pointer */
4008 /* set some required varibles which are normally set by codegen_setup */
4009 cd->mcodebase = (u1 *) mcodeptr;
4010 cd->clinitrefs = NULL;
4012 *(cs-1) = (u8) f; /* address of native method */
4013 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4014 *(cs-2) = (u8) &builtin_get_exceptionptrptr;
4016 *(cs-2) = (u8) (&_exceptionptr); /* address of exceptionptr */
4018 *(cs-3) = (u8) asm_handle_nat_exception; /* addr of asm exception handler*/
4019 *(cs-4) = (u8) (&env); /* addr of jni_environement */
4020 *(cs-5) = (u8) builtin_trace_args;
4022 *(cs-7) = (u8) builtin_displaymethodstop;
4023 *(cs-8) = (u8) m->class;
4024 *(cs-9) = (u8) asm_check_clinit;
4025 *(cs-10) = (u8) &builtin_asm_get_stackframeinfo;
4026 *(cs-11) = (u8) NULL; /* filled with machine code */
4028 M_LDA(REG_SP, REG_SP, -NATIVESTUB_STACK * 8); /* build up stackframe */
4029 M_AST(REG_RA, REG_SP, 0 * 8); /* store return address */
4031 M_AST(REG_RA, REG_SP, (6+NATIVESTUB_STACKTRACE_OFFSET) * 8); /* store return address in stackinfo helper*/
4033 /* if function is static, check for initialized */
4035 if (m->flags & ACC_STATIC) {
4036 /* if class isn't yet initialized, do it */
4037 if (!m->class->initialized) {
4038 codegen_addclinitref(cd, mcodeptr, m->class);
4042 /* max. 39 +9 instructions */
4046 M_LDA(REG_SP, REG_SP, -((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
4047 M_AST(REG_RA, REG_SP, 1 * 8);
4049 /* save integer argument registers */
4050 for (p = 0; p < m->paramcount && p < INT_ARG_CNT; p++) {
4051 M_LST(rd->argintregs[p], REG_SP, (2 + p) * 8);
4054 /* save and copy float arguments into integer registers */
4055 for (p = 0; p < m->paramcount && p < FLT_ARG_CNT; p++) {
4056 t = m->paramtypes[p];
4058 if (IS_FLT_DBL_TYPE(t)) {
4059 if (IS_2_WORD_TYPE(t)) {
4060 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4061 M_LLD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4064 M_FST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4065 M_ILD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4069 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4074 M_ALD(REG_ITMP1, REG_PV, -6 * 8);
4075 M_AST(REG_ITMP1, REG_SP, 0 * 8);
4076 M_ALD(REG_PV, REG_PV, -5 * 8);
4077 M_JSR(REG_RA, REG_PV);
4078 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4079 M_LDA(REG_PV, REG_RA, disp);
4084 M_ALD(REG_PV, REG_PV, -10 * 8); /* builtin_asm_get_stackframeinfo */
4085 M_JSR(REG_RA, REG_PV);
4086 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4087 M_LDA(REG_PV, REG_RA, disp);
4090 M_MOV(REG_RESULT,REG_ITMP3);
4091 M_LST(REG_RESULT,REG_ITMP3,0);
4093 M_LST(REG_RESULT,REG_SP, ((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8)+(2+NATIVESTUB_STACKTRACE_OFFSET)*8);/*save adress of pointer*/
4094 M_LLD(REG_ITMP3,REG_RESULT,0); /* get pointer*/
4095 M_LST(REG_ITMP3,REG_SP,(1+NATIVESTUB_STACKTRACE_OFFSET)*8+((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8)); /*save old value*/
4096 M_LDA(REG_ITMP3,REG_SP,(1+NATIVESTUB_STACKTRACE_OFFSET)*8+((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8)); /*calculate new value*/
4097 M_LLD(REG_ITMP2,REG_ITMP3,8);
4098 M_LST(REG_ITMP3,REG_ITMP2,0); /*store new value*/
4099 M_LLD(REG_ITMP2,REG_PV,-6*8);
4100 M_LST(REG_ITMP2,REG_SP,(3+NATIVESTUB_STACKTRACE_OFFSET)*8+((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
4101 M_LST(REG_ZERO,REG_SP,(4+NATIVESTUB_STACKTRACE_OFFSET)*8+((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
4102 M_LST(REG_ZERO,REG_SP,(5+NATIVESTUB_STACKTRACE_OFFSET)*8+((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
4103 /*stack info -end */
4106 for (p = 0; p < m->paramcount && p < INT_ARG_CNT; p++) {
4107 M_LLD(rd->argintregs[p], REG_SP, (2 + p) * 8);
4110 for (p = 0; p < m->paramcount && p < FLT_ARG_CNT; p++) {
4111 t = m->paramtypes[p];
4113 if (IS_FLT_DBL_TYPE(t)) {
4114 if (IS_2_WORD_TYPE(t)) {
4115 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4118 M_FLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4122 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4126 M_ALD(REG_RA, REG_SP, 1 * 8);
4127 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT + 2) * 8);
4130 /* save argument registers on stack -- if we have to */
4131 if ((m->flags & ACC_STATIC && m->paramcount > (INT_ARG_CNT - 2)) || m->paramcount > (INT_ARG_CNT - 1)) {
4133 s4 paramshiftcnt = (m->flags & ACC_STATIC) ? 2 : 1;
4134 s4 stackparamcnt = (m->paramcount > INT_ARG_CNT) ? m->paramcount - INT_ARG_CNT : 0;
4136 stackframesize = stackparamcnt + paramshiftcnt;
4138 M_LDA(REG_SP, REG_SP, -stackframesize * 8);
4140 /* copy stack arguments into new stack frame -- if any */
4141 for (i = 0; i < stackparamcnt; i++) {
4142 M_LLD(REG_ITMP1, REG_SP, (stackparamcnt + 1 + i) * 8);
4143 M_LST(REG_ITMP1, REG_SP, (paramshiftcnt + i) * 8);
4146 if (m->flags & ACC_STATIC) {
4147 if (IS_FLT_DBL_TYPE(m->paramtypes[5])) {
4148 M_DST(rd->argfltregs[5], REG_SP, 1 * 8);
4150 M_LST(rd->argintregs[5], REG_SP, 1 * 8);
4153 if (IS_FLT_DBL_TYPE(m->paramtypes[4])) {
4154 M_DST(rd->argfltregs[4], REG_SP, 0 * 8);
4156 M_LST(rd->argintregs[4], REG_SP, 0 * 8);
4160 if (IS_FLT_DBL_TYPE(m->paramtypes[5])) {
4161 M_DST(rd->argfltregs[5], REG_SP, 0 * 8);
4163 M_LST(rd->argintregs[5], REG_SP, 0 * 8);
4168 if (m->flags & ACC_STATIC) {
4169 M_MOV(rd->argintregs[3], rd->argintregs[5]);
4170 M_MOV(rd->argintregs[2], rd->argintregs[4]);
4171 M_MOV(rd->argintregs[1], rd->argintregs[3]);
4172 M_MOV(rd->argintregs[0], rd->argintregs[2]);
4173 M_FMOV(rd->argfltregs[3], rd->argfltregs[5]);
4174 M_FMOV(rd->argfltregs[2], rd->argfltregs[4]);
4175 M_FMOV(rd->argfltregs[1], rd->argfltregs[3]);
4176 M_FMOV(rd->argfltregs[0], rd->argfltregs[2]);
4178 /* put class into second argument register */
4179 M_ALD(rd->argintregs[1], REG_PV, -8 * 8);
4182 M_MOV(rd->argintregs[4], rd->argintregs[5]);
4183 M_MOV(rd->argintregs[3], rd->argintregs[4]);
4184 M_MOV(rd->argintregs[2], rd->argintregs[3]);
4185 M_MOV(rd->argintregs[1], rd->argintregs[2]);
4186 M_MOV(rd->argintregs[0], rd->argintregs[1]);
4187 M_FMOV(rd->argfltregs[4], rd->argfltregs[5]);
4188 M_FMOV(rd->argfltregs[3], rd->argfltregs[4]);
4189 M_FMOV(rd->argfltregs[2], rd->argfltregs[3]);
4190 M_FMOV(rd->argfltregs[1], rd->argfltregs[2]);
4191 M_FMOV(rd->argfltregs[0], rd->argfltregs[1]);
4194 /* put env into first argument register */
4195 M_ALD(rd->argintregs[0], REG_PV, -4 * 8);
4197 M_ALD(REG_PV, REG_PV, -1 * 8); /* load adress of native method */
4198 M_JSR(REG_RA, REG_PV); /* call native method */
4199 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4200 M_LDA(REG_PV, REG_RA, disp); /* recompute pv from ra */
4202 /* remove stackframe if there is one */
4203 if (stackframesize) {
4204 M_LDA(REG_SP, REG_SP, stackframesize * 8);
4207 /* 13 instructions */
4209 M_LDA(REG_SP, REG_SP, -2 * 8);
4210 M_ALD(rd->argintregs[0], REG_PV, -6 * 8); /* load method adress */
4211 M_LST(REG_RESULT, REG_SP, 0 * 8);
4212 M_DST(REG_FRESULT, REG_SP, 1 * 8);
4213 M_MOV(REG_RESULT, rd->argintregs[1]);
4214 M_FMOV(REG_FRESULT, rd->argfltregs[2]);
4215 M_FMOV(REG_FRESULT, rd->argfltregs[3]);
4216 M_ALD(REG_PV, REG_PV, -7 * 8); /* builtin_displaymethodstop */
4217 M_JSR(REG_RA, REG_PV);
4218 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4219 M_LDA(REG_PV, REG_RA, disp);
4220 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4221 M_DLD(REG_FRESULT, REG_SP, 1 * 8);
4222 M_LDA(REG_SP, REG_SP, 2 * 8);
4225 M_LLD(REG_ITMP3,REG_SP,(2+NATIVESTUB_STACKTRACE_OFFSET)*8); /*get address of stacktrace helper pointer*/
4226 M_LLD(REG_ITMP1,REG_SP,(1+NATIVESTUB_STACKTRACE_OFFSET)*8); /*get old value*/
4227 M_LST(REG_ITMP1,REG_ITMP3,0); /*set old value*/
4229 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4230 if (IS_FLT_DBL_TYPE(m->returntype))
4231 M_DST(REG_FRESULT, REG_SP, 1 * 8);
4233 M_AST(REG_RESULT, REG_SP, 1 * 8);
4234 M_ALD(REG_PV, REG_PV, -2 * 8); /* builtin_get_exceptionptrptr */
4235 M_JSR(REG_RA, REG_PV);
4236 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4237 M_LDA(REG_PV, REG_RA, disp);
4238 M_MOV(REG_RESULT, REG_ITMP3);
4239 if (IS_FLT_DBL_TYPE(m->returntype))
4240 M_DLD(REG_FRESULT, REG_SP, 1 * 8);
4242 M_ALD(REG_RESULT, REG_SP, 1 * 8);
4244 M_ALD(REG_ITMP3, REG_PV, -2 * 8); /* get address of exceptionptr */
4246 M_ALD(REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
4247 M_BNEZ(REG_ITMP1, 3); /* if no exception then return */
4249 M_ALD(REG_RA, REG_SP, 0 * 8); /* load return address */
4250 M_LDA(REG_SP, REG_SP, NATIVESTUB_STACK * 8); /* remove stackframe */
4251 M_RET(REG_ZERO, REG_RA); /* return to caller */
4253 M_AST(REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
4255 M_ALD(REG_RA, REG_SP, 0 * 8); /* load return address */
4256 M_LDA(REG_SP, REG_SP, NATIVESTUB_STACK * 8); /* remove stackframe */
4257 M_LDA(REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
4258 M_ALD(REG_ITMP3, REG_PV, -3 * 8); /* load asm exception handler address */
4259 M_JMP(REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
4261 /* generate put/getstatic stub call code */
4268 /* there can only be one clinit ref entry */
4269 cref = cd->clinitrefs;
4272 /* Get machine code which is patched back in later. The call is */
4273 /* 1 instruction word long. */
4274 xcodeptr = (s4 *) (cd->mcodebase + cref->branchpos);
4275 *(cs-11) = (u4) *xcodeptr;
4277 /* patch in the call to call the following code (done at compile */
4280 tmpmcodeptr = mcodeptr; /* save current mcodeptr */
4281 mcodeptr = xcodeptr; /* set mcodeptr to patch position */
4283 M_BSR(REG_RA, tmpmcodeptr - (xcodeptr + 1));
4285 mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
4287 /* move class pointer into REG_ITMP2 */
4288 M_ALD(REG_ITMP1, REG_PV, -8 * 8); /* class */
4290 /* move machine code into REG_ITMP3 */
4291 M_ILD(REG_ITMP3, REG_PV, -11 * 8); /* machine code */
4292 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
4293 M_IST(REG_ITMP3, REG_SP, 0);
4295 M_ALD(REG_ITMP2, REG_PV, -9 * 8); /* asm_check_clinit */
4296 M_JMP(REG_ZERO, REG_ITMP2);
4300 /* Check if the stub size is big enough to hold the whole stub generated. */
4301 /* If not, this can lead into unpredictable crashes, because of heap */
4303 if ((s4) ((ptrint) mcodeptr - (ptrint) s) > stubsize * sizeof(u8)) {
4304 throw_cacao_exception_exit(string_java_lang_InternalError,
4305 "Native stub size %d is to small for current stub size %d",
4306 stubsize, (s4) ((ptrint) mcodeptr - (ptrint) s));
4309 #if defined(STATISTICS)
4311 count_nstub_len += NATIVESTUB_SIZE * 8;
4314 /* release dump area */
4316 dump_release(dumpsize);
4318 return (u1 *) (s + NATIVESTUB_OFFSET);
4322 /* function: removenativestub **************************************************
4324 removes a previously created native-stub from memory
4326 *******************************************************************************/
4328 void removenativestub(u1 *stub)
4330 CFREE((u8 *) stub - NATIVESTUBOFFSET, NATIVESTUBSIZE * 8);
4335 * These are local overrides for various environment variables in Emacs.
4336 * Please do not remove this and leave it at the end of the file, where
4337 * Emacs will automagically detect them.
4338 * ---------------------------------------------------------------------
4341 * indent-tabs-mode: t