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 2614 2005-06-08 20:54:05Z twisti $
47 #include "vm/jit/alpha/arch.h"
48 #include "vm/jit/alpha/codegen.h"
49 #include "vm/jit/alpha/types.h"
50 #include "vm/jit/alpha/asmoffsets.h"
52 #include "cacao/cacao.h"
53 #include "native/native.h"
54 #include "vm/builtin.h"
55 #include "vm/global.h"
56 #include "vm/loader.h"
57 #include "vm/stringlocal.h"
58 #include "vm/tables.h"
59 #include "vm/jit/asmpart.h"
60 #include "vm/jit/codegen.inc"
61 #include "vm/jit/jit.h"
64 # include "vm/jit/lsra.h"
65 # include "vm/jit/lsra.inc"
68 #include "vm/jit/parse.h"
69 #include "vm/jit/patcher.h"
70 #include "vm/jit/reg.h"
71 #include "vm/jit/reg.inc"
74 /* NullPointerException handlers and exception handling initialisation */
76 typedef struct sigctx_struct {
77 long sc_onstack; /* sigstack state to restore */
78 long sc_mask; /* signal mask to restore */
79 long sc_pc; /* pc at time of signal */
80 long sc_ps; /* psl to retore */
81 long sc_regs[32]; /* processor regs 0 to 31 */
82 long sc_ownedfp; /* fp has been used */
83 long sc_fpregs[32]; /* fp regs 0 to 31 */
84 unsigned long sc_fpcr; /* floating point control register */
85 unsigned long sc_fp_control; /* software fpcr */
87 unsigned long sc_reserved1, sc_reserved2;
88 unsigned long sc_ssize;
90 unsigned long sc_traparg_a0;
91 unsigned long sc_traparg_a1;
92 unsigned long sc_traparg_a2;
93 unsigned long sc_fp_trap_pc;
94 unsigned long sc_fp_trigger_sum;
95 unsigned long sc_fp_trigger_inst;
96 unsigned long sc_retcode[2];
100 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
101 void thread_restartcriticalsection(ucontext_t *uc)
104 if ((critical = thread_checkcritical((void*) uc->uc_mcontext.sc_pc)) != NULL)
105 uc->uc_mcontext.sc_pc = (u8) critical;
110 /* NullPointerException signal handler for hardware null pointer check */
112 void catch_NullPointerException(int sig, siginfo_t *siginfo, void *_p)
114 struct sigaction act;
119 ucontext_t *_uc = (ucontext_t *) _p;
120 mcontext_t *sigctx = &_uc->uc_mcontext;
122 instr = *((s4 *) (sigctx->sc_pc));
123 faultaddr = sigctx->sc_regs[(instr >> 16) & 0x1f];
125 if (faultaddr == 0) {
126 /* Reset signal handler - necessary for SysV, does no harm for BSD */
127 act.sa_sigaction = catch_NullPointerException;
128 act.sa_flags = SA_SIGINFO;
129 sigaction(sig, &act, NULL);
132 sigaddset(&nsig, sig);
133 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
135 sigctx->sc_regs[REG_ITMP1_XPTR] = (u8) string_java_lang_NullPointerException;
136 sigctx->sc_regs[REG_ITMP2_XPC] = sigctx->sc_pc;
137 sigctx->sc_pc = (u8) asm_throw_and_handle_exception;
141 faultaddr += (long) ((instr << 16) >> 16);
143 throw_cacao_exception_exit(string_java_lang_InternalError,
144 "faulting address: 0x%016lx\n", faultaddr);
151 void init_exceptions(void)
156 /* Linux on Digital Alpha needs an initialisation of the ieee floating point
157 control for IEEE compliant arithmetic (option -mieee of GCC). Under
158 Digital Unix this is done automatically.
163 extern unsigned long ieee_get_fp_control();
164 extern void ieee_set_fp_control(unsigned long fp_control);
166 void init_exceptions(void)
168 struct sigaction act;
170 /* initialize floating point control */
172 ieee_set_fp_control(ieee_get_fp_control()
173 & ~IEEE_TRAP_ENABLE_INV
174 & ~IEEE_TRAP_ENABLE_DZE
175 /* & ~IEEE_TRAP_ENABLE_UNF we dont want underflow */
176 & ~IEEE_TRAP_ENABLE_OVF);
179 /* install signal handlers we need to convert to exceptions */
182 act.sa_sigaction = catch_NullPointerException;
183 act.sa_flags = SA_SIGINFO;
186 sigaction(SIGSEGV, &act, NULL);
190 sigaction(SIGBUS, &act, NULL);
196 /* codegen *********************************************************************
198 Generates machine code.
200 *******************************************************************************/
202 void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
204 s4 len, s1, s2, s3, d;
214 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
215 builtintable_entry *bte;
222 savedregs_num = (m->isleafmethod) ? 0 : 1; /* space to save the RA */
224 /* space to save used callee saved registers */
226 savedregs_num += (rd->savintregcnt - rd->maxsavintreguse);
227 savedregs_num += (rd->savfltregcnt - rd->maxsavfltreguse);
229 parentargs_base = rd->maxmemuse + savedregs_num;
231 #if defined(USE_THREADS) /* space to save argument of monitor_enter */
233 if (checksync && (m->flags & ACC_SYNCHRONIZED))
238 /* create method header */
240 (void) dseg_addaddress(cd, m); /* MethodPointer */
241 (void) dseg_adds4(cd, parentargs_base * 8); /* FrameSize */
243 #if defined(USE_THREADS)
245 /* IsSync contains the offset relative to the stack pointer for the
246 argument of monitor_exit used in the exception handler. Since the
247 offset could be zero and give a wrong meaning of the flag it is
251 if (checksync && (m->flags & ACC_SYNCHRONIZED))
252 (void) dseg_adds4(cd, (rd->maxmemuse + 1) * 8); /* IsSync */
257 (void) dseg_adds4(cd, 0); /* IsSync */
259 (void) dseg_adds4(cd, m->isleafmethod); /* IsLeaf */
260 (void) dseg_adds4(cd, rd->savintregcnt - rd->maxsavintreguse);/* IntSave */
261 (void) dseg_adds4(cd, rd->savfltregcnt - rd->maxsavfltreguse);/* FltSave */
263 dseg_addlinenumbertablesize(cd);
265 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
267 /* create exception table */
269 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
270 dseg_addtarget(cd, ex->start);
271 dseg_addtarget(cd, ex->end);
272 dseg_addtarget(cd, ex->handler);
273 (void) dseg_addaddress(cd, ex->catchtype.cls);
276 /* initialize mcode variables */
278 mcodeptr = (s4 *) cd->mcodebase;
279 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
280 MCODECHECK(128 + m->paramcount);
282 /* create stack frame (if necessary) */
284 if (parentargs_base) {
285 M_LDA(REG_SP, REG_SP, -parentargs_base * 8);
288 /* save return address and used callee saved registers */
291 if (!m->isleafmethod) {
292 p--; M_AST(REG_RA, REG_SP, p * 8);
294 for (i = rd->savintregcnt - 1; i >= rd->maxsavintreguse; i--) {
295 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
297 for (i = rd->savfltregcnt - 1; i >= rd->maxsavfltreguse; i--) {
298 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
301 /* take arguments out of register or stack frame */
305 for (p = 0, l = 0; p < md->paramcount; p++) {
306 t = md->paramtypes[p].type;
307 var = &(rd->locals[l][t]);
309 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
313 s1 = md->params[p].regoff;
314 if (IS_INT_LNG_TYPE(t)) { /* integer args */
315 if (!md->params[p].inmemory) { /* register arguments */
316 s2 = rd->argintregs[s1];
317 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
318 M_INTMOVE(s2, var->regoff);
320 } else { /* reg arg -> spilled */
321 M_LST(s2, REG_SP, var->regoff * 8);
324 } else { /* stack arguments */
325 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
326 M_LLD(var->regoff, REG_SP, (parentargs_base + s1) * 8);
328 } else { /* stack arg -> spilled */
329 var->regoff = parentargs_base + s1;
333 } else { /* floating args */
334 if (!md->params[p].inmemory) { /* register arguments */
335 s2 = rd->argfltregs[s1];
336 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
337 M_FLTMOVE(s2, var->regoff);
339 } else { /* reg arg -> spilled */
340 M_DST(s2, REG_SP, var->regoff * 8);
343 } else { /* stack arguments */
344 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
345 M_DLD(var->regoff, REG_SP, (parentargs_base + s1) * 8);
347 } else { /* stack-arg -> spilled */
348 var->regoff = parentargs_base + s1;
354 /* call monitorenter function */
356 #if defined(USE_THREADS)
357 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
358 /* stack offset for monitor argument */
363 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
365 for (p = 0; p < INT_ARG_CNT; p++)
366 M_LST(rd->argintregs[p], REG_SP, p * 8);
368 for (p = 0; p < FLT_ARG_CNT; p++)
369 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
371 s1 += INT_ARG_CNT + FLT_ARG_CNT;
374 /* decide which monitor enter function to call */
376 if (m->flags & ACC_STATIC) {
377 p = dseg_addaddress(cd, m->class);
378 M_ALD(REG_ITMP1, REG_PV, p);
379 M_AST(REG_ITMP1, REG_SP, s1 * 8);
380 M_INTMOVE(REG_ITMP1, rd->argintregs[0]);
381 p = dseg_addaddress(cd, BUILTIN_staticmonitorenter);
382 M_ALD(REG_PV, REG_PV, p);
383 M_JSR(REG_RA, REG_PV);
384 d = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
385 M_LDA(REG_PV, REG_RA, d);
388 M_BEQZ(rd->argintregs[0], 0);
389 codegen_addxnullrefs(cd, mcodeptr);
390 M_AST(rd->argintregs[0], REG_SP, s1 * 8);
391 p = dseg_addaddress(cd, BUILTIN_monitorenter);
392 M_ALD(REG_PV, REG_PV, p);
393 M_JSR(REG_RA, REG_PV);
394 d = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
395 M_LDA(REG_PV, REG_RA, d);
399 for (p = 0; p < INT_ARG_CNT; p++)
400 M_LLD(rd->argintregs[p], REG_SP, p * 8);
402 for (p = 0; p < FLT_ARG_CNT; p++)
403 M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
405 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
410 /* call trace function */
413 M_LDA(REG_SP, REG_SP, -((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
414 M_AST(REG_RA, REG_SP, 1 * 8);
416 /* save integer argument registers */
418 for (p = 0; p < md->paramcount && p < INT_ARG_CNT; p++)
419 M_LST(rd->argintregs[p], REG_SP, (2 + p) * 8);
421 /* save and copy float arguments into integer registers */
423 for (p = 0; p < md->paramcount && p < FLT_ARG_CNT; p++) {
424 t = md->paramtypes[p].type;
426 if (IS_FLT_DBL_TYPE(t)) {
427 if (IS_2_WORD_TYPE(t)) {
428 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
431 M_FST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
434 M_LLD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
437 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
441 p = dseg_addaddress(cd, m);
442 M_ALD(REG_ITMP1, REG_PV, p);
443 M_AST(REG_ITMP1, REG_SP, 0 * 8);
444 p = dseg_addaddress(cd, (void *) builtin_trace_args);
445 M_ALD(REG_PV, REG_PV, p);
446 M_JSR(REG_RA, REG_PV);
447 d = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
448 M_LDA(REG_PV, REG_RA, d);
449 M_ALD(REG_RA, REG_SP, 1 * 8);
451 /* restore integer argument registers */
453 for (p = 0; p < md->paramcount && p < INT_ARG_CNT; p++)
454 M_LLD(rd->argintregs[p], REG_SP, (2 + p) * 8);
456 /* restore float argument registers */
458 for (p = 0; p < md->paramcount && p < FLT_ARG_CNT; p++) {
459 t = md->paramtypes[p].type;
461 if (IS_FLT_DBL_TYPE(t)) {
462 if (IS_2_WORD_TYPE(t)) {
463 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
466 M_FLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
470 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
474 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT + 2) * 8);
479 /* end of header generation */
481 /* walk through all basic blocks */
483 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
485 bptr->mpc = (s4) ((u1 *) mcodeptr - cd->mcodebase);
487 if (bptr->flags >= BBREACHED) {
489 /* branch resolving */
493 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
494 gen_resolvebranch((u1*) cd->mcodebase + brefs->branchpos,
495 brefs->branchpos, bptr->mpc);
499 /* copy interface registers to their destination */
506 while (src != NULL) {
508 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
509 /* d = reg_of_var(m, src, REG_ITMP1); */
510 if (!(src->flags & INMEMORY))
514 M_INTMOVE(REG_ITMP1, d);
515 store_reg_to_var_int(src, d);
521 while (src != NULL) {
523 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
524 d = reg_of_var(rd, src, REG_ITMP1);
525 M_INTMOVE(REG_ITMP1, d);
526 store_reg_to_var_int(src, d);
529 d = reg_of_var(rd, src, REG_IFTMP);
530 if ((src->varkind != STACKVAR)) {
532 if (IS_FLT_DBL_TYPE(s2)) {
533 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
534 s1 = rd->interfaces[len][s2].regoff;
538 M_DLD(d, REG_SP, 8 * rd->interfaces[len][s2].regoff);
540 store_reg_to_var_flt(src, d);
543 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
544 s1 = rd->interfaces[len][s2].regoff;
548 M_LLD(d, REG_SP, 8 * rd->interfaces[len][s2].regoff);
550 store_reg_to_var_int(src, d);
560 /* walk through all instructions */
565 for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
566 if (iptr->line != currentline) {
567 dseg_addlinenumber(cd, iptr->line, mcodeptr);
568 currentline = iptr->line;
571 MCODECHECK(64); /* an instruction usually needs < 64 words */
574 case ICMD_INLINE_START:
575 case ICMD_INLINE_END:
578 case ICMD_NOP: /* ... ==> ... */
581 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
583 var_to_reg_int(s1, src, REG_ITMP1);
585 codegen_addxnullrefs(cd, mcodeptr);
588 /* constant operations ************************************************/
590 case ICMD_ICONST: /* ... ==> ..., constant */
591 /* op1 = 0, val.i = constant */
593 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
594 ICONST(d, iptr->val.i);
595 store_reg_to_var_int(iptr->dst, d);
598 case ICMD_LCONST: /* ... ==> ..., constant */
599 /* op1 = 0, val.l = constant */
601 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
602 LCONST(d, iptr->val.l);
603 store_reg_to_var_int(iptr->dst, d);
606 case ICMD_FCONST: /* ... ==> ..., constant */
607 /* op1 = 0, val.f = constant */
609 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
610 a = dseg_addfloat(cd, iptr->val.f);
612 store_reg_to_var_flt(iptr->dst, d);
615 case ICMD_DCONST: /* ... ==> ..., constant */
616 /* op1 = 0, val.d = constant */
618 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
619 a = dseg_adddouble(cd, iptr->val.d);
621 store_reg_to_var_flt(iptr->dst, d);
624 case ICMD_ACONST: /* ... ==> ..., constant */
625 /* op1 = 0, val.a = constant */
627 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
629 a = dseg_addaddress(cd, iptr->val.a);
632 M_INTMOVE(REG_ZERO, d);
634 store_reg_to_var_int(iptr->dst, d);
638 /* load/store operations **********************************************/
640 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
641 case ICMD_LLOAD: /* op1 = local variable */
644 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
645 if ((iptr->dst->varkind == LOCALVAR) &&
646 (iptr->dst->varnum == iptr->op1))
648 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
649 if (var->flags & INMEMORY)
650 M_LLD(d, REG_SP, 8 * var->regoff);
652 {M_INTMOVE(var->regoff,d);}
653 store_reg_to_var_int(iptr->dst, d);
656 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
657 case ICMD_DLOAD: /* op1 = local variable */
659 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
660 if ((iptr->dst->varkind == LOCALVAR) &&
661 (iptr->dst->varnum == iptr->op1))
663 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
664 if (var->flags & INMEMORY)
665 M_DLD(d, REG_SP, 8 * var->regoff);
667 {M_FLTMOVE(var->regoff,d);}
668 store_reg_to_var_flt(iptr->dst, d);
672 case ICMD_ISTORE: /* ..., value ==> ... */
673 case ICMD_LSTORE: /* op1 = local variable */
676 if ((src->varkind == LOCALVAR) &&
677 (src->varnum == iptr->op1))
679 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
680 if (var->flags & INMEMORY) {
681 var_to_reg_int(s1, src, REG_ITMP1);
682 M_LST(s1, REG_SP, 8 * var->regoff);
685 var_to_reg_int(s1, src, var->regoff);
686 M_INTMOVE(s1, var->regoff);
690 case ICMD_FSTORE: /* ..., value ==> ... */
691 case ICMD_DSTORE: /* op1 = local variable */
693 if ((src->varkind == LOCALVAR) &&
694 (src->varnum == iptr->op1))
696 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
697 if (var->flags & INMEMORY) {
698 var_to_reg_flt(s1, src, REG_FTMP1);
699 M_DST(s1, REG_SP, 8 * var->regoff);
702 var_to_reg_flt(s1, src, var->regoff);
703 M_FLTMOVE(s1, var->regoff);
708 /* pop/dup/swap operations ********************************************/
710 /* attention: double and longs are only one entry in CACAO ICMDs */
712 case ICMD_POP: /* ..., value ==> ... */
713 case ICMD_POP2: /* ..., value, value ==> ... */
716 case ICMD_DUP: /* ..., a ==> ..., a, a */
717 M_COPY(src, iptr->dst);
720 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
722 M_COPY(src, iptr->dst);
723 M_COPY(src->prev, iptr->dst->prev);
724 M_COPY(iptr->dst, iptr->dst->prev->prev);
727 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
729 M_COPY(src, iptr->dst);
730 M_COPY(src->prev, iptr->dst->prev);
731 M_COPY(src->prev->prev, iptr->dst->prev->prev);
732 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
735 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
737 M_COPY(src, iptr->dst);
738 M_COPY(src->prev, iptr->dst->prev);
741 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
743 M_COPY(src, iptr->dst);
744 M_COPY(src->prev, iptr->dst->prev);
745 M_COPY(src->prev->prev, iptr->dst->prev->prev);
746 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
747 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev);
750 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
752 M_COPY(src, iptr->dst);
753 M_COPY(src->prev, iptr->dst->prev);
754 M_COPY(src->prev->prev, iptr->dst->prev->prev);
755 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
756 M_COPY(iptr->dst, iptr->dst->prev->prev->prev->prev);
757 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev->prev);
760 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
762 M_COPY(src, iptr->dst->prev);
763 M_COPY(src->prev, iptr->dst);
767 /* integer operations *************************************************/
769 case ICMD_INEG: /* ..., value ==> ..., - value */
771 var_to_reg_int(s1, src, REG_ITMP1);
772 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
773 M_ISUB(REG_ZERO, s1, d);
774 store_reg_to_var_int(iptr->dst, d);
777 case ICMD_LNEG: /* ..., value ==> ..., - value */
779 var_to_reg_int(s1, src, REG_ITMP1);
780 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
781 M_LSUB(REG_ZERO, s1, d);
782 store_reg_to_var_int(iptr->dst, d);
785 case ICMD_I2L: /* ..., value ==> ..., value */
787 var_to_reg_int(s1, src, REG_ITMP1);
788 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
790 store_reg_to_var_int(iptr->dst, d);
793 case ICMD_L2I: /* ..., value ==> ..., value */
795 var_to_reg_int(s1, src, REG_ITMP1);
796 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
797 M_IADD(s1, REG_ZERO, d );
798 store_reg_to_var_int(iptr->dst, d);
801 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
803 var_to_reg_int(s1, src, REG_ITMP1);
804 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
805 if (has_ext_instr_set) {
809 M_SLL_IMM(s1, 56, d);
810 M_SRA_IMM( d, 56, d);
812 store_reg_to_var_int(iptr->dst, d);
815 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
817 var_to_reg_int(s1, src, REG_ITMP1);
818 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
820 store_reg_to_var_int(iptr->dst, d);
823 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
825 var_to_reg_int(s1, src, REG_ITMP1);
826 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
827 if (has_ext_instr_set) {
831 M_SLL_IMM(s1, 48, d);
832 M_SRA_IMM( d, 48, d);
834 store_reg_to_var_int(iptr->dst, d);
838 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
840 var_to_reg_int(s1, src->prev, REG_ITMP1);
841 var_to_reg_int(s2, src, REG_ITMP2);
842 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
844 store_reg_to_var_int(iptr->dst, d);
847 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
848 /* val.i = constant */
850 var_to_reg_int(s1, src, REG_ITMP1);
851 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
852 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
853 M_IADD_IMM(s1, iptr->val.i, d);
856 ICONST(REG_ITMP2, iptr->val.i);
857 M_IADD(s1, REG_ITMP2, d);
859 store_reg_to_var_int(iptr->dst, d);
862 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
864 var_to_reg_int(s1, src->prev, REG_ITMP1);
865 var_to_reg_int(s2, src, REG_ITMP2);
866 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
868 store_reg_to_var_int(iptr->dst, d);
871 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
872 /* val.l = constant */
874 var_to_reg_int(s1, src, REG_ITMP1);
875 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
876 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
877 M_LADD_IMM(s1, iptr->val.l, d);
880 LCONST(REG_ITMP2, iptr->val.l);
881 M_LADD(s1, REG_ITMP2, d);
883 store_reg_to_var_int(iptr->dst, d);
886 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
888 var_to_reg_int(s1, src->prev, REG_ITMP1);
889 var_to_reg_int(s2, src, REG_ITMP2);
890 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
892 store_reg_to_var_int(iptr->dst, d);
895 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
896 /* val.i = constant */
898 var_to_reg_int(s1, src, REG_ITMP1);
899 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
900 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
901 M_ISUB_IMM(s1, iptr->val.i, d);
904 ICONST(REG_ITMP2, iptr->val.i);
905 M_ISUB(s1, REG_ITMP2, d);
907 store_reg_to_var_int(iptr->dst, d);
910 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
912 var_to_reg_int(s1, src->prev, REG_ITMP1);
913 var_to_reg_int(s2, src, REG_ITMP2);
914 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
916 store_reg_to_var_int(iptr->dst, d);
919 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
920 /* val.l = constant */
922 var_to_reg_int(s1, src, REG_ITMP1);
923 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
924 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
925 M_LSUB_IMM(s1, iptr->val.l, d);
928 LCONST(REG_ITMP2, iptr->val.l);
929 M_LSUB(s1, REG_ITMP2, d);
931 store_reg_to_var_int(iptr->dst, d);
934 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
936 var_to_reg_int(s1, src->prev, REG_ITMP1);
937 var_to_reg_int(s2, src, REG_ITMP2);
938 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
940 store_reg_to_var_int(iptr->dst, d);
943 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
944 /* val.i = constant */
946 var_to_reg_int(s1, src, REG_ITMP1);
947 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
948 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
949 M_IMUL_IMM(s1, iptr->val.i, d);
952 ICONST(REG_ITMP2, iptr->val.i);
953 M_IMUL(s1, REG_ITMP2, d);
955 store_reg_to_var_int(iptr->dst, d);
958 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
960 var_to_reg_int(s1, src->prev, REG_ITMP1);
961 var_to_reg_int(s2, src, REG_ITMP2);
962 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
964 store_reg_to_var_int(iptr->dst, d);
967 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
968 /* val.l = constant */
970 var_to_reg_int(s1, src, REG_ITMP1);
971 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
972 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
973 M_LMUL_IMM(s1, iptr->val.l, d);
976 LCONST(REG_ITMP2, iptr->val.l);
977 M_LMUL(s1, REG_ITMP2, d);
979 store_reg_to_var_int(iptr->dst, d);
982 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
983 case ICMD_LDIVPOW2: /* val.i = constant */
985 var_to_reg_int(s1, src, REG_ITMP1);
986 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
987 if (iptr->val.i <= 15) {
988 M_LDA(REG_ITMP2, s1, (1 << iptr->val.i) -1);
989 M_CMOVGE(s1, s1, REG_ITMP2);
992 M_SRA_IMM(s1, 63, REG_ITMP2);
993 M_SRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
994 M_LADD(s1, REG_ITMP2, REG_ITMP2);
996 M_SRA_IMM(REG_ITMP2, iptr->val.i, d);
997 store_reg_to_var_int(iptr->dst, d);
1000 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1002 var_to_reg_int(s1, src->prev, REG_ITMP1);
1003 var_to_reg_int(s2, src, REG_ITMP2);
1004 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1005 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1006 M_SLL(s1, REG_ITMP3, d);
1007 M_IADD(d, REG_ZERO, d);
1008 store_reg_to_var_int(iptr->dst, d);
1011 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1012 /* val.i = constant */
1014 var_to_reg_int(s1, src, REG_ITMP1);
1015 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1016 M_SLL_IMM(s1, iptr->val.i & 0x1f, d);
1017 M_IADD(d, REG_ZERO, d);
1018 store_reg_to_var_int(iptr->dst, d);
1021 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1023 var_to_reg_int(s1, src->prev, REG_ITMP1);
1024 var_to_reg_int(s2, src, REG_ITMP2);
1025 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1026 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1027 M_SRA(s1, REG_ITMP3, d);
1028 store_reg_to_var_int(iptr->dst, d);
1031 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1032 /* val.i = constant */
1034 var_to_reg_int(s1, src, REG_ITMP1);
1035 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1036 M_SRA_IMM(s1, iptr->val.i & 0x1f, d);
1037 store_reg_to_var_int(iptr->dst, d);
1040 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1042 var_to_reg_int(s1, src->prev, REG_ITMP1);
1043 var_to_reg_int(s2, src, REG_ITMP2);
1044 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1045 M_AND_IMM(s2, 0x1f, REG_ITMP2);
1047 M_SRL(d, REG_ITMP2, d);
1048 M_IADD(d, REG_ZERO, d);
1049 store_reg_to_var_int(iptr->dst, d);
1052 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1053 /* val.i = constant */
1055 var_to_reg_int(s1, src, REG_ITMP1);
1056 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1058 M_SRL_IMM(d, iptr->val.i & 0x1f, d);
1059 M_IADD(d, REG_ZERO, d);
1060 store_reg_to_var_int(iptr->dst, d);
1063 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1065 var_to_reg_int(s1, src->prev, REG_ITMP1);
1066 var_to_reg_int(s2, src, REG_ITMP2);
1067 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1069 store_reg_to_var_int(iptr->dst, d);
1072 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1073 /* val.i = constant */
1075 var_to_reg_int(s1, src, REG_ITMP1);
1076 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1077 M_SLL_IMM(s1, iptr->val.i & 0x3f, d);
1078 store_reg_to_var_int(iptr->dst, d);
1081 case ICMD_LSHR: /* ..., 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_LSHRCONST: /* ..., 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_SRA_IMM(s1, iptr->val.i & 0x3f, d);
1096 store_reg_to_var_int(iptr->dst, d);
1099 case ICMD_LUSHR: /* ..., 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_LUSHRCONST: /* ..., 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_SRL_IMM(s1, iptr->val.i & 0x3f, d);
1114 store_reg_to_var_int(iptr->dst, d);
1117 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1120 var_to_reg_int(s1, src->prev, REG_ITMP1);
1121 var_to_reg_int(s2, src, REG_ITMP2);
1122 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1124 store_reg_to_var_int(iptr->dst, d);
1127 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1128 /* val.i = constant */
1130 var_to_reg_int(s1, src, REG_ITMP1);
1131 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1132 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1133 M_AND_IMM(s1, iptr->val.i, d);
1135 else if (iptr->val.i == 0xffff) {
1138 else if (iptr->val.i == 0xffffff) {
1139 M_ZAPNOT_IMM(s1, 0x07, d);
1142 ICONST(REG_ITMP2, iptr->val.i);
1143 M_AND(s1, REG_ITMP2, d);
1145 store_reg_to_var_int(iptr->dst, d);
1148 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1149 /* val.i = constant */
1151 var_to_reg_int(s1, src, REG_ITMP1);
1152 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1154 M_MOV(s1, REG_ITMP1);
1157 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1158 M_AND_IMM(s1, iptr->val.i, d);
1160 M_ISUB(REG_ZERO, s1, d);
1161 M_AND_IMM(d, iptr->val.i, d);
1163 else if (iptr->val.i == 0xffff) {
1166 M_ISUB(REG_ZERO, s1, d);
1169 else if (iptr->val.i == 0xffffff) {
1170 M_ZAPNOT_IMM(s1, 0x07, d);
1172 M_ISUB(REG_ZERO, s1, d);
1173 M_ZAPNOT_IMM(d, 0x07, d);
1176 ICONST(REG_ITMP2, iptr->val.i);
1177 M_AND(s1, REG_ITMP2, d);
1179 M_ISUB(REG_ZERO, s1, d);
1180 M_AND(d, REG_ITMP2, d);
1182 M_ISUB(REG_ZERO, d, d);
1183 store_reg_to_var_int(iptr->dst, d);
1186 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1187 /* val.l = constant */
1189 var_to_reg_int(s1, src, REG_ITMP1);
1190 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1191 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1192 M_AND_IMM(s1, iptr->val.l, d);
1194 else if (iptr->val.l == 0xffffL) {
1197 else if (iptr->val.l == 0xffffffL) {
1198 M_ZAPNOT_IMM(s1, 0x07, d);
1200 else if (iptr->val.l == 0xffffffffL) {
1203 else if (iptr->val.l == 0xffffffffffL) {
1204 M_ZAPNOT_IMM(s1, 0x1f, d);
1206 else if (iptr->val.l == 0xffffffffffffL) {
1207 M_ZAPNOT_IMM(s1, 0x3f, d);
1209 else if (iptr->val.l == 0xffffffffffffffL) {
1210 M_ZAPNOT_IMM(s1, 0x7f, d);
1213 LCONST(REG_ITMP2, iptr->val.l);
1214 M_AND(s1, REG_ITMP2, d);
1216 store_reg_to_var_int(iptr->dst, d);
1219 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1220 /* val.l = constant */
1222 var_to_reg_int(s1, src, REG_ITMP1);
1223 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1225 M_MOV(s1, REG_ITMP1);
1228 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1229 M_AND_IMM(s1, iptr->val.l, d);
1231 M_LSUB(REG_ZERO, s1, d);
1232 M_AND_IMM(d, iptr->val.l, d);
1234 else if (iptr->val.l == 0xffffL) {
1237 M_LSUB(REG_ZERO, s1, d);
1240 else if (iptr->val.l == 0xffffffL) {
1241 M_ZAPNOT_IMM(s1, 0x07, d);
1243 M_LSUB(REG_ZERO, s1, d);
1244 M_ZAPNOT_IMM(d, 0x07, d);
1246 else if (iptr->val.l == 0xffffffffL) {
1249 M_LSUB(REG_ZERO, s1, d);
1252 else if (iptr->val.l == 0xffffffffffL) {
1253 M_ZAPNOT_IMM(s1, 0x1f, d);
1255 M_LSUB(REG_ZERO, s1, d);
1256 M_ZAPNOT_IMM(d, 0x1f, d);
1258 else if (iptr->val.l == 0xffffffffffffL) {
1259 M_ZAPNOT_IMM(s1, 0x3f, d);
1261 M_LSUB(REG_ZERO, s1, d);
1262 M_ZAPNOT_IMM(d, 0x3f, d);
1264 else if (iptr->val.l == 0xffffffffffffffL) {
1265 M_ZAPNOT_IMM(s1, 0x7f, d);
1267 M_LSUB(REG_ZERO, s1, d);
1268 M_ZAPNOT_IMM(d, 0x7f, d);
1271 LCONST(REG_ITMP2, iptr->val.l);
1272 M_AND(s1, REG_ITMP2, d);
1274 M_LSUB(REG_ZERO, s1, d);
1275 M_AND(d, REG_ITMP2, d);
1277 M_LSUB(REG_ZERO, d, d);
1278 store_reg_to_var_int(iptr->dst, d);
1281 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1284 var_to_reg_int(s1, src->prev, REG_ITMP1);
1285 var_to_reg_int(s2, src, REG_ITMP2);
1286 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1288 store_reg_to_var_int(iptr->dst, d);
1291 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1292 /* val.i = constant */
1294 var_to_reg_int(s1, src, REG_ITMP1);
1295 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1296 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1297 M_OR_IMM(s1, iptr->val.i, d);
1300 ICONST(REG_ITMP2, iptr->val.i);
1301 M_OR(s1, REG_ITMP2, d);
1303 store_reg_to_var_int(iptr->dst, d);
1306 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1307 /* val.l = constant */
1309 var_to_reg_int(s1, src, REG_ITMP1);
1310 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1311 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1312 M_OR_IMM(s1, iptr->val.l, d);
1315 LCONST(REG_ITMP2, iptr->val.l);
1316 M_OR(s1, REG_ITMP2, d);
1318 store_reg_to_var_int(iptr->dst, d);
1321 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1324 var_to_reg_int(s1, src->prev, REG_ITMP1);
1325 var_to_reg_int(s2, src, REG_ITMP2);
1326 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1328 store_reg_to_var_int(iptr->dst, d);
1331 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1332 /* val.i = constant */
1334 var_to_reg_int(s1, src, REG_ITMP1);
1335 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1336 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1337 M_XOR_IMM(s1, iptr->val.i, d);
1340 ICONST(REG_ITMP2, iptr->val.i);
1341 M_XOR(s1, REG_ITMP2, d);
1343 store_reg_to_var_int(iptr->dst, d);
1346 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1347 /* val.l = constant */
1349 var_to_reg_int(s1, src, REG_ITMP1);
1350 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1351 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1352 M_XOR_IMM(s1, iptr->val.l, d);
1355 LCONST(REG_ITMP2, iptr->val.l);
1356 M_XOR(s1, REG_ITMP2, d);
1358 store_reg_to_var_int(iptr->dst, d);
1362 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1364 var_to_reg_int(s1, src->prev, REG_ITMP1);
1365 var_to_reg_int(s2, src, REG_ITMP2);
1366 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1367 M_CMPLT(s1, s2, REG_ITMP3);
1368 M_CMPLT(s2, s1, REG_ITMP1);
1369 M_LSUB (REG_ITMP1, REG_ITMP3, d);
1370 store_reg_to_var_int(iptr->dst, d);
1374 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1375 /* op1 = variable, val.i = constant */
1377 var = &(rd->locals[iptr->op1][TYPE_INT]);
1378 if (var->flags & INMEMORY) {
1380 M_LLD(s1, REG_SP, 8 * var->regoff);
1384 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1385 M_IADD_IMM(s1, iptr->val.i, s1);
1387 else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1388 M_ISUB_IMM(s1, (-iptr->val.i), s1);
1391 M_LDA (s1, s1, iptr->val.i);
1392 M_IADD(s1, REG_ZERO, s1);
1394 if (var->flags & INMEMORY)
1395 M_LST(s1, REG_SP, 8 * var->regoff);
1399 /* floating operations ************************************************/
1401 case ICMD_FNEG: /* ..., value ==> ..., - value */
1403 var_to_reg_flt(s1, src, REG_FTMP1);
1404 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1406 store_reg_to_var_flt(iptr->dst, d);
1409 case ICMD_DNEG: /* ..., value ==> ..., - value */
1411 var_to_reg_flt(s1, src, REG_FTMP1);
1412 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1414 store_reg_to_var_flt(iptr->dst, d);
1417 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1419 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1420 var_to_reg_flt(s2, src, REG_FTMP2);
1421 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1426 if (d == s1 || d == s2) {
1427 M_FADDS(s1, s2, REG_FTMP3);
1429 M_FMOV(REG_FTMP3, d);
1436 store_reg_to_var_flt(iptr->dst, d);
1439 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1441 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1442 var_to_reg_flt(s2, src, REG_FTMP2);
1443 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1448 if (d == s1 || d == s2) {
1449 M_DADDS(s1, s2, REG_FTMP3);
1451 M_FMOV(REG_FTMP3, d);
1458 store_reg_to_var_flt(iptr->dst, d);
1461 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1463 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1464 var_to_reg_flt(s2, src, REG_FTMP2);
1465 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1470 if (d == s1 || d == s2) {
1471 M_FSUBS(s1, s2, REG_FTMP3);
1473 M_FMOV(REG_FTMP3, d);
1480 store_reg_to_var_flt(iptr->dst, d);
1483 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1485 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1486 var_to_reg_flt(s2, src, REG_FTMP2);
1487 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1492 if (d == s1 || d == s2) {
1493 M_DSUBS(s1, s2, REG_FTMP3);
1495 M_FMOV(REG_FTMP3, d);
1502 store_reg_to_var_flt(iptr->dst, d);
1505 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1507 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1508 var_to_reg_flt(s2, src, REG_FTMP2);
1509 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1514 if (d == s1 || d == s2) {
1515 M_FMULS(s1, s2, REG_FTMP3);
1517 M_FMOV(REG_FTMP3, d);
1524 store_reg_to_var_flt(iptr->dst, d);
1527 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1529 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1530 var_to_reg_flt(s2, src, REG_FTMP2);
1531 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1536 if (d == s1 || d == s2) {
1537 M_DMULS(s1, s2, REG_FTMP3);
1539 M_FMOV(REG_FTMP3, d);
1546 store_reg_to_var_flt(iptr->dst, d);
1549 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1551 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1552 var_to_reg_flt(s2, src, REG_FTMP2);
1553 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1558 if (d == s1 || d == s2) {
1559 M_FDIVS(s1, s2, REG_FTMP3);
1561 M_FMOV(REG_FTMP3, d);
1568 store_reg_to_var_flt(iptr->dst, d);
1571 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1573 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1574 var_to_reg_flt(s2, src, REG_FTMP2);
1575 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1580 if (d == s1 || d == s2) {
1581 M_DDIVS(s1, s2, REG_FTMP3);
1583 M_FMOV(REG_FTMP3, d);
1590 store_reg_to_var_flt(iptr->dst, d);
1593 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1595 var_to_reg_int(s1, src, REG_ITMP1);
1596 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1597 a = dseg_adddouble(cd, 0.0);
1598 M_LST (s1, REG_PV, a);
1599 M_DLD (d, REG_PV, a);
1601 store_reg_to_var_flt(iptr->dst, d);
1604 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1606 var_to_reg_int(s1, src, REG_ITMP1);
1607 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1608 a = dseg_adddouble(cd, 0.0);
1609 M_LST (s1, REG_PV, a);
1610 M_DLD (d, REG_PV, a);
1612 store_reg_to_var_flt(iptr->dst, d);
1615 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1617 var_to_reg_flt(s1, src, REG_FTMP1);
1618 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1619 a = dseg_adddouble(cd, 0.0);
1620 M_CVTDL_C(s1, REG_FTMP2);
1621 M_CVTLI(REG_FTMP2, REG_FTMP3);
1622 M_DST (REG_FTMP3, REG_PV, a);
1623 M_ILD (d, REG_PV, a);
1624 store_reg_to_var_int(iptr->dst, d);
1627 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1629 var_to_reg_flt(s1, src, REG_FTMP1);
1630 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1631 a = dseg_adddouble(cd, 0.0);
1632 M_CVTDL_C(s1, REG_FTMP2);
1633 M_DST (REG_FTMP2, REG_PV, a);
1634 M_LLD (d, REG_PV, a);
1635 store_reg_to_var_int(iptr->dst, d);
1638 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1640 var_to_reg_flt(s1, src, REG_FTMP1);
1641 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1644 store_reg_to_var_flt(iptr->dst, d);
1647 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1649 var_to_reg_flt(s1, src, REG_FTMP1);
1650 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1658 store_reg_to_var_flt(iptr->dst, d);
1661 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1663 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1664 var_to_reg_flt(s2, src, REG_FTMP2);
1665 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1667 M_LSUB_IMM(REG_ZERO, 1, d);
1668 M_FCMPEQ(s1, s2, REG_FTMP3);
1669 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1671 M_FCMPLT(s2, s1, REG_FTMP3);
1672 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1673 M_LADD_IMM(REG_ZERO, 1, d);
1676 M_LSUB_IMM(REG_ZERO, 1, d);
1677 M_FCMPEQS(s1, s2, REG_FTMP3);
1679 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1681 M_FCMPLTS(s2, s1, REG_FTMP3);
1683 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1684 M_LADD_IMM(REG_ZERO, 1, d);
1686 store_reg_to_var_int(iptr->dst, d);
1689 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1691 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1692 var_to_reg_flt(s2, src, REG_FTMP2);
1693 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1695 M_LADD_IMM(REG_ZERO, 1, d);
1696 M_FCMPEQ(s1, s2, REG_FTMP3);
1697 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1699 M_FCMPLT(s1, s2, REG_FTMP3);
1700 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1701 M_LSUB_IMM(REG_ZERO, 1, d);
1704 M_LADD_IMM(REG_ZERO, 1, d);
1705 M_FCMPEQS(s1, s2, REG_FTMP3);
1707 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1709 M_FCMPLTS(s1, s2, REG_FTMP3);
1711 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1712 M_LSUB_IMM(REG_ZERO, 1, d);
1714 store_reg_to_var_int(iptr->dst, d);
1718 /* memory operations **************************************************/
1720 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1722 var_to_reg_int(s1, src, REG_ITMP1);
1723 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1724 gen_nullptr_check(s1);
1725 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1726 store_reg_to_var_int(iptr->dst, d);
1729 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1731 var_to_reg_int(s1, src->prev, REG_ITMP1);
1732 var_to_reg_int(s2, src, REG_ITMP2);
1733 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1734 if (iptr->op1 == 0) {
1735 gen_nullptr_check(s1);
1738 M_SAADDQ(s2, s1, REG_ITMP1);
1739 M_ALD( d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1740 store_reg_to_var_int(iptr->dst, d);
1743 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1745 var_to_reg_int(s1, src->prev, REG_ITMP1);
1746 var_to_reg_int(s2, src, REG_ITMP2);
1747 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1748 if (iptr->op1 == 0) {
1749 gen_nullptr_check(s1);
1752 M_S8ADDQ(s2, s1, REG_ITMP1);
1753 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1754 store_reg_to_var_int(iptr->dst, d);
1757 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1759 var_to_reg_int(s1, src->prev, REG_ITMP1);
1760 var_to_reg_int(s2, src, REG_ITMP2);
1761 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1762 if (iptr->op1 == 0) {
1763 gen_nullptr_check(s1);
1767 M_S4ADDQ(s2, s1, REG_ITMP1);
1768 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1769 store_reg_to_var_int(iptr->dst, d);
1772 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1774 var_to_reg_int(s1, src->prev, REG_ITMP1);
1775 var_to_reg_int(s2, src, REG_ITMP2);
1776 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1777 if (iptr->op1 == 0) {
1778 gen_nullptr_check(s1);
1781 M_S4ADDQ(s2, s1, REG_ITMP1);
1782 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1783 store_reg_to_var_flt(iptr->dst, d);
1786 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1788 var_to_reg_int(s1, src->prev, REG_ITMP1);
1789 var_to_reg_int(s2, src, REG_ITMP2);
1790 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1791 if (iptr->op1 == 0) {
1792 gen_nullptr_check(s1);
1795 M_S8ADDQ(s2, s1, REG_ITMP1);
1796 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1797 store_reg_to_var_flt(iptr->dst, d);
1800 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1802 var_to_reg_int(s1, src->prev, REG_ITMP1);
1803 var_to_reg_int(s2, src, REG_ITMP2);
1804 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1805 if (iptr->op1 == 0) {
1806 gen_nullptr_check(s1);
1809 if (has_ext_instr_set) {
1810 M_LADD(s2, s1, REG_ITMP1);
1811 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1812 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1815 M_LADD (s2, s1, REG_ITMP1);
1816 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1817 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1818 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1819 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
1821 store_reg_to_var_int(iptr->dst, d);
1824 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1826 var_to_reg_int(s1, src->prev, REG_ITMP1);
1827 var_to_reg_int(s2, src, REG_ITMP2);
1828 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1829 if (iptr->op1 == 0) {
1830 gen_nullptr_check(s1);
1833 if (has_ext_instr_set) {
1834 M_LADD(s2, s1, REG_ITMP1);
1835 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1836 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1840 M_LADD(s2, s1, REG_ITMP1);
1841 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1842 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1843 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1844 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1845 M_SRA_IMM(d, 48, d);
1847 store_reg_to_var_int(iptr->dst, d);
1850 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1852 var_to_reg_int(s1, src->prev, REG_ITMP1);
1853 var_to_reg_int(s2, src, REG_ITMP2);
1854 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1855 if (iptr->op1 == 0) {
1856 gen_nullptr_check(s1);
1859 if (has_ext_instr_set) {
1860 M_LADD (s2, s1, REG_ITMP1);
1861 M_BLDU (d, REG_ITMP1, OFFSET (java_bytearray, data[0]));
1865 M_LADD(s2, s1, REG_ITMP1);
1866 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1867 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
1868 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1869 M_SRA_IMM(d, 56, d);
1871 store_reg_to_var_int(iptr->dst, d);
1875 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1877 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1878 var_to_reg_int(s2, src->prev, REG_ITMP2);
1879 if (iptr->op1 == 0) {
1880 gen_nullptr_check(s1);
1883 var_to_reg_int(s3, src, REG_ITMP3);
1884 M_SAADDQ(s2, s1, REG_ITMP1);
1885 M_AST (s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1888 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1890 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1891 var_to_reg_int(s2, src->prev, REG_ITMP2);
1892 if (iptr->op1 == 0) {
1893 gen_nullptr_check(s1);
1896 var_to_reg_int(s3, src, REG_ITMP3);
1897 M_S8ADDQ(s2, s1, REG_ITMP1);
1898 M_LST (s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1901 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1903 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1904 var_to_reg_int(s2, src->prev, REG_ITMP2);
1905 if (iptr->op1 == 0) {
1906 gen_nullptr_check(s1);
1910 var_to_reg_int(s3, src, REG_ITMP3);
1911 M_S4ADDQ(s2, s1, REG_ITMP1);
1912 M_IST (s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1915 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1917 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1918 var_to_reg_int(s2, src->prev, REG_ITMP2);
1919 if (iptr->op1 == 0) {
1920 gen_nullptr_check(s1);
1923 var_to_reg_flt(s3, src, REG_FTMP3);
1924 M_S4ADDQ(s2, s1, REG_ITMP1);
1925 M_FST (s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1928 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1930 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1931 var_to_reg_int(s2, src->prev, REG_ITMP2);
1932 if (iptr->op1 == 0) {
1933 gen_nullptr_check(s1);
1936 var_to_reg_flt(s3, src, REG_FTMP3);
1937 M_S8ADDQ(s2, s1, REG_ITMP1);
1938 M_DST (s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1941 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1943 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1944 var_to_reg_int(s2, src->prev, REG_ITMP2);
1945 if (iptr->op1 == 0) {
1946 gen_nullptr_check(s1);
1949 var_to_reg_int(s3, src, REG_ITMP3);
1950 if (has_ext_instr_set) {
1951 M_LADD(s2, s1, REG_ITMP1);
1952 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1953 M_SST (s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1956 M_LADD (s2, s1, REG_ITMP1);
1957 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1958 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1959 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1960 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1961 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1962 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
1963 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1967 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1969 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1970 var_to_reg_int(s2, src->prev, REG_ITMP2);
1971 if (iptr->op1 == 0) {
1972 gen_nullptr_check(s1);
1975 var_to_reg_int(s3, src, REG_ITMP3);
1976 if (has_ext_instr_set) {
1977 M_LADD(s2, s1, REG_ITMP1);
1978 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1979 M_SST (s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1982 M_LADD (s2, s1, REG_ITMP1);
1983 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1984 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1985 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1986 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1987 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1988 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
1989 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1993 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1995 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1996 var_to_reg_int(s2, src->prev, REG_ITMP2);
1997 if (iptr->op1 == 0) {
1998 gen_nullptr_check(s1);
2001 var_to_reg_int(s3, src, REG_ITMP3);
2002 if (has_ext_instr_set) {
2003 M_LADD(s2, s1, REG_ITMP1);
2004 M_BST (s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2007 M_LADD (s2, s1, REG_ITMP1);
2008 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2009 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2010 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
2011 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2012 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2013 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2018 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
2020 var_to_reg_int(s1, src->prev, REG_ITMP1);
2021 var_to_reg_int(s2, src, REG_ITMP2);
2022 if (iptr->op1 == 0) {
2023 gen_nullptr_check(s1);
2026 M_S4ADDQ(s2, s1, REG_ITMP1);
2027 M_IST(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
2030 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
2032 var_to_reg_int(s1, src->prev, REG_ITMP1);
2033 var_to_reg_int(s2, src, REG_ITMP2);
2034 if (iptr->op1 == 0) {
2035 gen_nullptr_check(s1);
2038 M_S8ADDQ(s2, s1, REG_ITMP1);
2039 M_LST(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
2042 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
2044 var_to_reg_int(s1, src->prev, REG_ITMP1);
2045 var_to_reg_int(s2, src, REG_ITMP2);
2046 if (iptr->op1 == 0) {
2047 gen_nullptr_check(s1);
2050 M_SAADDQ(s2, s1, REG_ITMP1);
2051 M_AST(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
2054 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
2056 var_to_reg_int(s1, src->prev, REG_ITMP1);
2057 var_to_reg_int(s2, src, REG_ITMP2);
2058 if (iptr->op1 == 0) {
2059 gen_nullptr_check(s1);
2062 if (has_ext_instr_set) {
2063 M_LADD(s2, s1, REG_ITMP1);
2064 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2067 M_LADD(s2, s1, REG_ITMP1);
2068 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2069 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2070 M_INSBL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2071 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2072 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2073 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2077 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
2079 var_to_reg_int(s1, src->prev, REG_ITMP1);
2080 var_to_reg_int(s2, src, REG_ITMP2);
2081 if (iptr->op1 == 0) {
2082 gen_nullptr_check(s1);
2085 if (has_ext_instr_set) {
2086 M_LADD(s2, s1, REG_ITMP1);
2087 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2088 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
2091 M_LADD(s2, s1, REG_ITMP1);
2092 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2093 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2094 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2095 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2096 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2097 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2098 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2102 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
2104 var_to_reg_int(s1, src->prev, REG_ITMP1);
2105 var_to_reg_int(s2, src, REG_ITMP2);
2106 if (iptr->op1 == 0) {
2107 gen_nullptr_check(s1);
2110 if (has_ext_instr_set) {
2111 M_LADD(s2, s1, REG_ITMP1);
2112 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2113 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2116 M_LADD(s2, s1, REG_ITMP1);
2117 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2118 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2119 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2120 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2121 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2122 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2123 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2128 case ICMD_GETSTATIC: /* ... ==> ..., value */
2129 /* op1 = type, val.a = field address */
2132 codegen_addpatchref(cd, mcodeptr,
2133 PATCHER_get_putstatic,
2134 (unresolved_field *) iptr->target);
2136 if (showdisassemble)
2142 fieldinfo *fi = iptr->val.a;
2144 if (!fi->class->initialized) {
2145 codegen_addpatchref(cd, mcodeptr,
2146 PATCHER_clinit, fi->class);
2148 if (showdisassemble)
2152 a = (ptrint) &(fi->value);
2155 a = dseg_addaddress(cd, a);
2156 M_ALD(REG_ITMP1, REG_PV, a);
2157 switch (iptr->op1) {
2159 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2160 M_ILD(d, REG_ITMP1, 0);
2161 store_reg_to_var_int(iptr->dst, d);
2164 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2165 M_LLD(d, REG_ITMP1, 0);
2166 store_reg_to_var_int(iptr->dst, d);
2169 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2170 M_ALD(d, REG_ITMP1, 0);
2171 store_reg_to_var_int(iptr->dst, d);
2174 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2175 M_FLD(d, REG_ITMP1, 0);
2176 store_reg_to_var_flt(iptr->dst, d);
2179 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2180 M_DLD(d, REG_ITMP1, 0);
2181 store_reg_to_var_flt(iptr->dst, d);
2186 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2187 /* op1 = type, val.a = field address */
2190 codegen_addpatchref(cd, mcodeptr,
2191 PATCHER_get_putstatic,
2192 (unresolved_field *) iptr->target);
2194 if (showdisassemble)
2200 fieldinfo *fi = iptr->val.a;
2202 if (!fi->class->initialized) {
2203 codegen_addpatchref(cd, mcodeptr,
2204 PATCHER_clinit, fi->class);
2206 if (showdisassemble)
2210 a = (ptrint) &(fi->value);
2213 a = dseg_addaddress(cd, a);
2214 M_ALD(REG_ITMP1, REG_PV, a);
2215 switch (iptr->op1) {
2217 var_to_reg_int(s2, src, REG_ITMP2);
2218 M_IST(s2, REG_ITMP1, 0);
2221 var_to_reg_int(s2, src, REG_ITMP2);
2222 M_LST(s2, REG_ITMP1, 0);
2225 var_to_reg_int(s2, src, REG_ITMP2);
2226 M_AST(s2, REG_ITMP1, 0);
2229 var_to_reg_flt(s2, src, REG_FTMP2);
2230 M_FST(s2, REG_ITMP1, 0);
2233 var_to_reg_flt(s2, src, REG_FTMP2);
2234 M_DST(s2, REG_ITMP1, 0);
2239 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2240 /* val = value (in current instruction) */
2241 /* op1 = type, val.a = field address (in */
2242 /* following NOP) */
2244 if (!iptr[1].val.a) {
2245 codegen_addpatchref(cd, mcodeptr,
2246 PATCHER_get_putstatic,
2247 (unresolved_field *) iptr[1].target);
2249 if (showdisassemble)
2255 fieldinfo *fi = iptr[1].val.a;
2257 if (!fi->class->initialized) {
2258 codegen_addpatchref(cd, mcodeptr,
2259 PATCHER_clinit, fi->class);
2261 if (showdisassemble)
2265 a = (ptrint) &(fi->value);
2268 a = dseg_addaddress(cd, a);
2269 M_ALD(REG_ITMP1, REG_PV, a);
2270 switch (iptr->op1) {
2272 M_IST(REG_ZERO, REG_ITMP1, 0);
2275 M_LST(REG_ZERO, REG_ITMP1, 0);
2278 M_AST(REG_ZERO, REG_ITMP1, 0);
2281 M_FST(REG_ZERO, REG_ITMP1, 0);
2284 M_DST(REG_ZERO, REG_ITMP1, 0);
2290 case ICMD_GETFIELD: /* ... ==> ..., value */
2291 /* op1 = type, val.i = field offset */
2293 var_to_reg_int(s1, src, REG_ITMP1);
2294 gen_nullptr_check(s1);
2297 codegen_addpatchref(cd, mcodeptr,
2298 PATCHER_get_putfield,
2299 (unresolved_field *) iptr->target);
2301 if (showdisassemble)
2307 a = ((fieldinfo *) (iptr->val.a))->offset;
2310 switch (iptr->op1) {
2312 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2314 store_reg_to_var_int(iptr->dst, d);
2317 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2319 store_reg_to_var_int(iptr->dst, d);
2322 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2324 store_reg_to_var_int(iptr->dst, d);
2327 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2329 store_reg_to_var_flt(iptr->dst, d);
2332 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2334 store_reg_to_var_flt(iptr->dst, d);
2339 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2340 /* op1 = type, val.a = field address */
2342 var_to_reg_int(s1, src->prev, REG_ITMP1);
2343 gen_nullptr_check(s1);
2345 if (!IS_FLT_DBL_TYPE(iptr->op1)) {
2346 var_to_reg_int(s2, src, REG_ITMP2);
2348 var_to_reg_flt(s2, src, REG_FTMP2);
2352 codegen_addpatchref(cd, mcodeptr,
2353 PATCHER_get_putfield,
2354 (unresolved_field *) iptr->target);
2356 if (showdisassemble)
2362 a = ((fieldinfo *) (iptr->val.a))->offset;
2365 switch (iptr->op1) {
2384 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2385 /* val = value (in current instruction) */
2386 /* op1 = type, val.a = field address (in */
2387 /* following NOP) */
2389 var_to_reg_int(s1, src, REG_ITMP1);
2390 gen_nullptr_check(s1);
2392 if (!iptr[1].val.a) {
2393 codegen_addpatchref(cd, mcodeptr,
2394 PATCHER_get_putfield,
2395 (unresolved_field *) iptr[1].target);
2397 if (showdisassemble)
2403 a = ((fieldinfo *) (iptr[1].val.a))->offset;
2406 switch (iptr[1].op1) {
2408 M_IST(REG_ZERO, s1, a);
2411 M_LST(REG_ZERO, s1, a);
2414 M_AST(REG_ZERO, s1, a);
2417 M_FST(REG_ZERO, s1, a);
2420 M_DST(REG_ZERO, s1, a);
2426 /* branch operations **************************************************/
2428 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2430 var_to_reg_int(s1, src, REG_ITMP1);
2431 M_INTMOVE(s1, REG_ITMP1_XPTR);
2432 a = dseg_addaddress(cd, asm_handle_exception);
2433 M_ALD(REG_ITMP2, REG_PV, a);
2434 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2435 M_NOP; /* nop ensures that XPC is less than the end */
2436 /* of basic block */
2440 case ICMD_GOTO: /* ... ==> ... */
2441 /* op1 = target JavaVM pc */
2443 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2447 case ICMD_JSR: /* ... ==> ... */
2448 /* op1 = target JavaVM pc */
2450 M_BSR(REG_ITMP1, 0);
2451 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2454 case ICMD_RET: /* ... ==> ... */
2455 /* op1 = local variable */
2457 var = &(rd->locals[iptr->op1][TYPE_ADR]);
2458 if (var->flags & INMEMORY) {
2459 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2460 M_RET(REG_ZERO, REG_ITMP1);
2463 M_RET(REG_ZERO, var->regoff);
2467 case ICMD_IFNULL: /* ..., value ==> ... */
2468 /* op1 = target JavaVM pc */
2470 var_to_reg_int(s1, src, REG_ITMP1);
2472 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2475 case ICMD_IFNONNULL: /* ..., value ==> ... */
2476 /* op1 = target JavaVM pc */
2478 var_to_reg_int(s1, src, REG_ITMP1);
2480 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2483 case ICMD_IFEQ: /* ..., value ==> ... */
2484 /* op1 = target JavaVM pc, val.i = constant */
2486 var_to_reg_int(s1, src, REG_ITMP1);
2487 if (iptr->val.i == 0) {
2491 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2492 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2495 ICONST(REG_ITMP2, iptr->val.i);
2496 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2498 M_BNEZ(REG_ITMP1, 0);
2500 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2503 case ICMD_IFLT: /* ..., value ==> ... */
2504 /* op1 = target JavaVM pc, val.i = constant */
2506 var_to_reg_int(s1, src, REG_ITMP1);
2507 if (iptr->val.i == 0) {
2511 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2512 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2515 ICONST(REG_ITMP2, iptr->val.i);
2516 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2518 M_BNEZ(REG_ITMP1, 0);
2520 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2523 case ICMD_IFLE: /* ..., value ==> ... */
2524 /* op1 = target JavaVM pc, val.i = constant */
2526 var_to_reg_int(s1, src, REG_ITMP1);
2527 if (iptr->val.i == 0) {
2531 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2532 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2535 ICONST(REG_ITMP2, iptr->val.i);
2536 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2538 M_BNEZ(REG_ITMP1, 0);
2540 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2543 case ICMD_IFNE: /* ..., value ==> ... */
2544 /* op1 = target JavaVM pc, val.i = constant */
2546 var_to_reg_int(s1, src, REG_ITMP1);
2547 if (iptr->val.i == 0) {
2551 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2552 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2555 ICONST(REG_ITMP2, iptr->val.i);
2556 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2558 M_BEQZ(REG_ITMP1, 0);
2560 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2563 case ICMD_IFGT: /* ..., value ==> ... */
2564 /* op1 = target JavaVM pc, val.i = constant */
2566 var_to_reg_int(s1, src, REG_ITMP1);
2567 if (iptr->val.i == 0) {
2571 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2572 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2575 ICONST(REG_ITMP2, iptr->val.i);
2576 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2578 M_BEQZ(REG_ITMP1, 0);
2580 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2583 case ICMD_IFGE: /* ..., value ==> ... */
2584 /* op1 = target JavaVM pc, val.i = constant */
2586 var_to_reg_int(s1, src, REG_ITMP1);
2587 if (iptr->val.i == 0) {
2591 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2592 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2595 ICONST(REG_ITMP2, iptr->val.i);
2596 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2598 M_BEQZ(REG_ITMP1, 0);
2600 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2603 case ICMD_IF_LEQ: /* ..., value ==> ... */
2604 /* op1 = target JavaVM pc, val.l = constant */
2606 var_to_reg_int(s1, src, REG_ITMP1);
2607 if (iptr->val.l == 0) {
2611 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2612 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2615 LCONST(REG_ITMP2, iptr->val.l);
2616 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2618 M_BNEZ(REG_ITMP1, 0);
2620 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2623 case ICMD_IF_LLT: /* ..., value ==> ... */
2624 /* op1 = target JavaVM pc, val.l = constant */
2626 var_to_reg_int(s1, src, REG_ITMP1);
2627 if (iptr->val.l == 0) {
2631 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2632 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2635 LCONST(REG_ITMP2, iptr->val.l);
2636 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2638 M_BNEZ(REG_ITMP1, 0);
2640 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2643 case ICMD_IF_LLE: /* ..., value ==> ... */
2644 /* op1 = target JavaVM pc, val.l = constant */
2646 var_to_reg_int(s1, src, REG_ITMP1);
2647 if (iptr->val.l == 0) {
2651 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2652 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2655 LCONST(REG_ITMP2, iptr->val.l);
2656 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2658 M_BNEZ(REG_ITMP1, 0);
2660 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2663 case ICMD_IF_LNE: /* ..., value ==> ... */
2664 /* op1 = target JavaVM pc, val.l = constant */
2666 var_to_reg_int(s1, src, REG_ITMP1);
2667 if (iptr->val.l == 0) {
2671 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2672 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2675 LCONST(REG_ITMP2, iptr->val.l);
2676 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2678 M_BEQZ(REG_ITMP1, 0);
2680 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2683 case ICMD_IF_LGT: /* ..., value ==> ... */
2684 /* op1 = target JavaVM pc, val.l = constant */
2686 var_to_reg_int(s1, src, REG_ITMP1);
2687 if (iptr->val.l == 0) {
2691 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2692 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2695 LCONST(REG_ITMP2, iptr->val.l);
2696 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2698 M_BEQZ(REG_ITMP1, 0);
2700 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2703 case ICMD_IF_LGE: /* ..., value ==> ... */
2704 /* op1 = target JavaVM pc, val.l = constant */
2706 var_to_reg_int(s1, src, REG_ITMP1);
2707 if (iptr->val.l == 0) {
2711 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2712 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2715 LCONST(REG_ITMP2, iptr->val.l);
2716 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2718 M_BEQZ(REG_ITMP1, 0);
2720 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2723 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2724 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2725 case ICMD_IF_ACMPEQ:
2727 var_to_reg_int(s1, src->prev, REG_ITMP1);
2728 var_to_reg_int(s2, src, REG_ITMP2);
2729 M_CMPEQ(s1, s2, REG_ITMP1);
2730 M_BNEZ(REG_ITMP1, 0);
2731 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2734 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2735 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2736 case ICMD_IF_ACMPNE:
2738 var_to_reg_int(s1, src->prev, REG_ITMP1);
2739 var_to_reg_int(s2, src, REG_ITMP2);
2740 M_CMPEQ(s1, s2, REG_ITMP1);
2741 M_BEQZ(REG_ITMP1, 0);
2742 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2745 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2746 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2748 var_to_reg_int(s1, src->prev, REG_ITMP1);
2749 var_to_reg_int(s2, src, REG_ITMP2);
2750 M_CMPLT(s1, s2, REG_ITMP1);
2751 M_BNEZ(REG_ITMP1, 0);
2752 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2755 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2756 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2758 var_to_reg_int(s1, src->prev, REG_ITMP1);
2759 var_to_reg_int(s2, src, REG_ITMP2);
2760 M_CMPLE(s1, s2, REG_ITMP1);
2761 M_BEQZ(REG_ITMP1, 0);
2762 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2765 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2766 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2768 var_to_reg_int(s1, src->prev, REG_ITMP1);
2769 var_to_reg_int(s2, src, REG_ITMP2);
2770 M_CMPLE(s1, s2, REG_ITMP1);
2771 M_BNEZ(REG_ITMP1, 0);
2772 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2775 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2776 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2778 var_to_reg_int(s1, src->prev, REG_ITMP1);
2779 var_to_reg_int(s2, src, REG_ITMP2);
2780 M_CMPLT(s1, s2, REG_ITMP1);
2781 M_BEQZ(REG_ITMP1, 0);
2782 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2785 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2787 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2790 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2791 /* val.i = constant */
2793 var_to_reg_int(s1, src, REG_ITMP1);
2794 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2796 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2797 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2798 M_CMPEQ(s1, REG_ZERO, d);
2799 store_reg_to_var_int(iptr->dst, d);
2802 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2803 M_CMPEQ(s1, REG_ZERO, d);
2805 store_reg_to_var_int(iptr->dst, d);
2809 M_MOV(s1, REG_ITMP1);
2812 ICONST(d, iptr[1].val.i);
2814 if ((s3 >= 0) && (s3 <= 255)) {
2815 M_CMOVEQ_IMM(s1, s3, d);
2818 ICONST(REG_ITMP2, s3);
2819 M_CMOVEQ(s1, REG_ITMP2, d);
2821 store_reg_to_var_int(iptr->dst, d);
2824 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2825 /* val.i = constant */
2827 var_to_reg_int(s1, src, REG_ITMP1);
2828 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2830 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2831 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2832 M_CMPEQ(s1, REG_ZERO, d);
2833 store_reg_to_var_int(iptr->dst, d);
2836 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2837 M_CMPEQ(s1, REG_ZERO, d);
2839 store_reg_to_var_int(iptr->dst, d);
2843 M_MOV(s1, REG_ITMP1);
2846 ICONST(d, iptr[1].val.i);
2848 if ((s3 >= 0) && (s3 <= 255)) {
2849 M_CMOVNE_IMM(s1, s3, d);
2852 ICONST(REG_ITMP2, s3);
2853 M_CMOVNE(s1, REG_ITMP2, d);
2855 store_reg_to_var_int(iptr->dst, d);
2858 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2859 /* val.i = constant */
2861 var_to_reg_int(s1, src, REG_ITMP1);
2862 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2864 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2865 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2866 M_CMPLT(s1, REG_ZERO, d);
2867 store_reg_to_var_int(iptr->dst, d);
2870 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2871 M_CMPLE(REG_ZERO, s1, d);
2872 store_reg_to_var_int(iptr->dst, d);
2876 M_MOV(s1, REG_ITMP1);
2879 ICONST(d, iptr[1].val.i);
2881 if ((s3 >= 0) && (s3 <= 255)) {
2882 M_CMOVLT_IMM(s1, s3, d);
2885 ICONST(REG_ITMP2, s3);
2886 M_CMOVLT(s1, REG_ITMP2, d);
2888 store_reg_to_var_int(iptr->dst, d);
2891 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2892 /* val.i = constant */
2894 var_to_reg_int(s1, src, REG_ITMP1);
2895 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2897 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2898 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2899 M_CMPLE(REG_ZERO, s1, d);
2900 store_reg_to_var_int(iptr->dst, d);
2903 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2904 M_CMPLT(s1, REG_ZERO, d);
2905 store_reg_to_var_int(iptr->dst, d);
2909 M_MOV(s1, REG_ITMP1);
2912 ICONST(d, iptr[1].val.i);
2914 if ((s3 >= 0) && (s3 <= 255)) {
2915 M_CMOVGE_IMM(s1, s3, d);
2918 ICONST(REG_ITMP2, s3);
2919 M_CMOVGE(s1, REG_ITMP2, d);
2921 store_reg_to_var_int(iptr->dst, d);
2924 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2925 /* val.i = constant */
2927 var_to_reg_int(s1, src, REG_ITMP1);
2928 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2930 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2931 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2932 M_CMPLT(REG_ZERO, s1, d);
2933 store_reg_to_var_int(iptr->dst, d);
2936 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2937 M_CMPLE(s1, REG_ZERO, d);
2938 store_reg_to_var_int(iptr->dst, d);
2942 M_MOV(s1, REG_ITMP1);
2945 ICONST(d, iptr[1].val.i);
2947 if ((s3 >= 0) && (s3 <= 255)) {
2948 M_CMOVGT_IMM(s1, s3, d);
2951 ICONST(REG_ITMP2, s3);
2952 M_CMOVGT(s1, REG_ITMP2, d);
2954 store_reg_to_var_int(iptr->dst, d);
2957 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2958 /* val.i = constant */
2960 var_to_reg_int(s1, src, REG_ITMP1);
2961 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2963 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2964 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2965 M_CMPLE(s1, REG_ZERO, d);
2966 store_reg_to_var_int(iptr->dst, d);
2969 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2970 M_CMPLT(REG_ZERO, s1, d);
2971 store_reg_to_var_int(iptr->dst, d);
2975 M_MOV(s1, REG_ITMP1);
2978 ICONST(d, iptr[1].val.i);
2980 if ((s3 >= 0) && (s3 <= 255)) {
2981 M_CMOVLE_IMM(s1, s3, d);
2984 ICONST(REG_ITMP2, s3);
2985 M_CMOVLE(s1, REG_ITMP2, d);
2987 store_reg_to_var_int(iptr->dst, d);
2991 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2995 var_to_reg_int(s1, src, REG_RESULT);
2996 M_INTMOVE(s1, REG_RESULT);
2998 goto nowperformreturn;
3000 case ICMD_FRETURN: /* ..., retvalue ==> ... */
3003 var_to_reg_flt(s1, src, REG_FRESULT);
3004 M_FLTMOVE(s1, REG_FRESULT);
3006 goto nowperformreturn;
3008 case ICMD_RETURN: /* ... ==> ... */
3014 p = parentargs_base;
3016 /* call trace function */
3019 M_LDA(REG_SP, REG_SP, -3 * 8);
3020 M_AST(REG_RA, REG_SP, 0 * 8);
3021 M_LST(REG_RESULT, REG_SP, 1 * 8);
3022 M_DST(REG_FRESULT, REG_SP, 2 * 8);
3023 a = dseg_addaddress(cd, m);
3024 M_ALD(rd->argintregs[0], REG_PV, a);
3025 M_MOV(REG_RESULT, rd->argintregs[1]);
3026 M_FLTMOVE(REG_FRESULT, rd->argfltregs[2]);
3027 M_FLTMOVE(REG_FRESULT, rd->argfltregs[3]);
3028 a = dseg_addaddress(cd, (void *) builtin_displaymethodstop);
3029 M_ALD(REG_PV, REG_PV, a);
3030 M_JSR(REG_RA, REG_PV);
3031 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3032 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3034 s4 ml = -s1, mh = 0;
3035 while (ml < -32768) { ml += 65536; mh--; }
3036 M_LDA(REG_PV, REG_RA, ml);
3037 M_LDAH(REG_PV, REG_PV, mh);
3039 M_DLD(REG_FRESULT, REG_SP, 2 * 8);
3040 M_LLD(REG_RESULT, REG_SP, 1 * 8);
3041 M_ALD(REG_RA, REG_SP, 0 * 8);
3042 M_LDA(REG_SP, REG_SP, 3 * 8);
3045 #if defined(USE_THREADS)
3046 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
3049 M_ALD(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
3051 switch (iptr->opc) {
3055 M_LST(REG_RESULT, REG_SP, rd->maxmemuse * 8);
3059 M_DST(REG_FRESULT, REG_SP, rd->maxmemuse * 8);
3063 a = dseg_addaddress(cd, BUILTIN_monitorexit);
3064 M_ALD(REG_PV, REG_PV, a);
3065 M_JSR(REG_RA, REG_PV);
3066 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
3067 M_LDA(REG_PV, REG_RA, disp);
3069 switch (iptr->opc) {
3073 M_LLD(REG_RESULT, REG_SP, rd->maxmemuse * 8);
3077 M_DLD(REG_FRESULT, REG_SP, rd->maxmemuse * 8);
3083 /* restore return address */
3085 if (!m->isleafmethod) {
3086 p--; M_LLD(REG_RA, REG_SP, p * 8);
3089 /* restore saved registers */
3091 for (i = rd->savintregcnt - 1; i >= rd->maxsavintreguse; i--) {
3092 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
3094 for (i = rd->savfltregcnt - 1; i >= rd->maxsavfltreguse; i--) {
3095 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
3098 /* deallocate stack */
3100 if (parentargs_base) {
3101 M_LDA(REG_SP, REG_SP, parentargs_base * 8);
3104 M_RET(REG_ZERO, REG_RA);
3110 case ICMD_TABLESWITCH: /* ..., index ==> ... */
3115 tptr = (void **) iptr->target;
3117 s4ptr = iptr->val.a;
3118 l = s4ptr[1]; /* low */
3119 i = s4ptr[2]; /* high */
3121 var_to_reg_int(s1, src, REG_ITMP1);
3123 {M_INTMOVE(s1, REG_ITMP1);}
3124 else if (l <= 32768) {
3125 M_LDA(REG_ITMP1, s1, -l);
3128 ICONST(REG_ITMP2, l);
3129 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
3136 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
3138 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
3139 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3141 M_BEQZ(REG_ITMP2, 0);
3144 /* codegen_addreference(cd, BlockPtrOfPC(s4ptr[0]), mcodeptr); */
3145 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3147 /* build jump table top down and use address of lowest entry */
3149 /* s4ptr += 3 + i; */
3153 /* dseg_addtarget(cd, BlockPtrOfPC(*--s4ptr)); */
3154 dseg_addtarget(cd, (basicblock *) tptr[0]);
3159 /* length of dataseg after last dseg_addtarget is used by load */
3161 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
3162 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
3163 M_JMP(REG_ZERO, REG_ITMP2);
3168 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3170 s4 i, l, val, *s4ptr;
3173 tptr = (void **) iptr->target;
3175 s4ptr = iptr->val.a;
3176 l = s4ptr[0]; /* default */
3177 i = s4ptr[1]; /* count */
3179 MCODECHECK((i<<2)+8);
3180 var_to_reg_int(s1, src, REG_ITMP1);
3186 if ((val >= 0) && (val <= 255)) {
3187 M_CMPEQ_IMM(s1, val, REG_ITMP2);
3190 if ((val >= -32768) && (val <= 32767)) {
3191 M_LDA(REG_ITMP2, REG_ZERO, val);
3194 a = dseg_adds4(cd, val);
3195 M_ILD(REG_ITMP2, REG_PV, a);
3197 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
3199 M_BNEZ(REG_ITMP2, 0);
3200 /* codegen_addreference(cd, BlockPtrOfPC(s4ptr[1]), mcodeptr); */
3201 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3205 /* codegen_addreference(cd, BlockPtrOfPC(l), mcodeptr); */
3207 tptr = (void **) iptr->target;
3208 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3215 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
3216 /* op1 = arg count val.a = builtintable entry */
3222 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3223 /* op1 = arg count, val.a = method pointer */
3225 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3226 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
3227 case ICMD_INVOKEINTERFACE:
3232 md = lm->parseddesc;
3234 unresolved_method *um = iptr->target;
3235 md = um->methodref->parseddesc.md;
3241 MCODECHECK((s3 << 1) + 64);
3243 /* copy arguments to registers or stack location */
3245 for (s3 = s3 - 1; s3 >= 0; s3--, src = src->prev) {
3246 if (src->varkind == ARGVAR)
3248 if (IS_INT_LNG_TYPE(src->type)) {
3249 if (!md->params[s3].inmemory) {
3250 s1 = rd->argintregs[md->params[s3].regoff];
3251 var_to_reg_int(d, src, s1);
3254 var_to_reg_int(d, src, REG_ITMP1);
3255 M_LST(d, REG_SP, md->params[s3].regoff * 8);
3259 if (!md->params[s3].inmemory) {
3260 s1 = rd->argfltregs[md->params[s3].regoff];
3261 var_to_reg_flt(d, src, s1);
3264 var_to_reg_flt(d, src, REG_FTMP1);
3265 M_DST(d, REG_SP, md->params[s3].regoff * 8);
3270 switch (iptr->opc) {
3273 codegen_addpatchref(cd, mcodeptr, bte->fp, iptr->target);
3275 if (showdisassemble)
3281 a = (ptrint) bte->fp;
3284 a = dseg_addaddress(cd, a);
3285 d = md->returntype.type;
3287 M_ALD(REG_PV, REG_PV, a); /* Pointer to built-in-function */
3290 case ICMD_INVOKESPECIAL:
3291 gen_nullptr_check(rd->argintregs[0]);
3292 M_ILD(REG_ITMP1, rd->argintregs[0], 0); /* hardware nullptr */
3295 case ICMD_INVOKESTATIC:
3297 unresolved_method *um = iptr->target;
3299 codegen_addpatchref(cd, mcodeptr,
3300 PATCHER_invokestatic_special, um);
3302 if (showdisassemble)
3306 d = um->methodref->parseddesc.md->returntype.type;
3309 a = (ptrint) lm->stubroutine;
3310 d = lm->parseddesc->returntype.type;
3313 a = dseg_addaddress(cd, a);
3314 M_ALD(REG_PV, REG_PV, a); /* method pointer in r27 */
3317 case ICMD_INVOKEVIRTUAL:
3318 gen_nullptr_check(rd->argintregs[0]);
3321 unresolved_method *um = iptr->target;
3323 codegen_addpatchref(cd, mcodeptr,
3324 PATCHER_invokevirtual, um);
3326 if (showdisassemble)
3330 d = um->methodref->parseddesc.md->returntype.type;
3333 s1 = OFFSET(vftbl_t, table[0]) +
3334 sizeof(methodptr) * lm->vftblindex;
3335 d = lm->parseddesc->returntype.type;
3338 M_ALD(REG_METHODPTR, rd->argintregs[0],
3339 OFFSET(java_objectheader, vftbl));
3340 M_ALD(REG_PV, REG_METHODPTR, s1);
3343 case ICMD_INVOKEINTERFACE:
3344 gen_nullptr_check(rd->argintregs[0]);
3347 unresolved_method *um = iptr->target;
3349 codegen_addpatchref(cd, mcodeptr,
3350 PATCHER_invokeinterface, um);
3352 if (showdisassemble)
3357 d = um->methodref->parseddesc.md->returntype.type;
3360 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3361 sizeof(methodptr*) * lm->class->index;
3363 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3365 d = lm->parseddesc->returntype.type;
3368 M_ALD(REG_METHODPTR, rd->argintregs[0],
3369 OFFSET(java_objectheader, vftbl));
3370 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3371 M_ALD(REG_PV, REG_METHODPTR, s2);
3375 M_JSR(REG_RA, REG_PV);
3379 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3380 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3382 s4 ml = -s1, mh = 0;
3383 while (ml < -32768) { ml += 65536; mh--; }
3384 M_LDA(REG_PV, REG_RA, ml);
3385 M_LDAH(REG_PV, REG_PV, mh);
3388 /* d contains return type */
3390 if (d != TYPE_VOID) {
3391 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3392 s1 = reg_of_var(rd, iptr->dst, REG_RESULT);
3393 M_INTMOVE(REG_RESULT, s1);
3394 store_reg_to_var_int(iptr->dst, s1);
3396 s1 = reg_of_var(rd, iptr->dst, REG_FRESULT);
3397 M_FLTMOVE(REG_FRESULT, s1);
3398 store_reg_to_var_flt(iptr->dst, s1);
3404 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3406 /* op1: 0 == array, 1 == class */
3407 /* val.a: (classinfo*) superclass */
3409 /* superclass is an interface:
3411 * OK if ((sub == NULL) ||
3412 * (sub->vftbl->interfacetablelength > super->index) &&
3413 * (sub->vftbl->interfacetable[-super->index] != NULL));
3415 * superclass is a class:
3417 * OK if ((sub == NULL) || (0
3418 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3419 * super->vftbl->diffval));
3424 vftbl_t *supervftbl;
3427 super = (classinfo *) iptr->val.a;
3434 superindex = super->index;
3435 supervftbl = super->vftbl;
3438 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3439 codegen_threadcritrestart(cd, (u1 *) mcodeptr - cd->mcodebase);
3441 var_to_reg_int(s1, src, REG_ITMP1);
3443 /* calculate interface checkcast code size */
3447 s2 += showdisassemble ? 1 : 0;
3449 /* calculate class checkcast code size */
3451 s3 = 9 /* 8 + (s1 == REG_ITMP1) */;
3453 s3 += showdisassemble ? 1 : 0;
3455 /* if class is not resolved, check which code to call */
3458 M_BEQZ(s1, 4 + (showdisassemble ? 1 : 0) + s2 + 1 + s3);
3460 codegen_addpatchref(cd, mcodeptr,
3461 PATCHER_checkcast_instanceof_flags,
3462 (constant_classref *) iptr->target);
3464 if (showdisassemble)
3467 a = dseg_adds4(cd, 0); /* super->flags */
3468 M_ILD(REG_ITMP2, REG_PV, a);
3469 a = dseg_adds4(cd, ACC_INTERFACE);
3470 M_ILD(REG_ITMP3, REG_PV, a);
3471 M_AND(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3472 M_BEQZ(REG_ITMP2, s2 + 1);
3475 /* interface checkcast code */
3477 if (!super || (super->flags & ACC_INTERFACE)) {
3482 codegen_addpatchref(cd, mcodeptr,
3483 PATCHER_checkcast_instanceof_interface,
3484 (constant_classref *) iptr->target);
3486 if (showdisassemble)
3490 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3491 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
3492 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
3493 M_BLEZ(REG_ITMP3, 0);
3494 codegen_addxcastrefs(cd, mcodeptr);
3495 M_ALD(REG_ITMP3, REG_ITMP2,
3496 OFFSET(vftbl_t, interfacetable[0]) -
3497 superindex * sizeof(methodptr*));
3498 M_BEQZ(REG_ITMP3, 0);
3499 codegen_addxcastrefs(cd, mcodeptr);
3505 /* class checkcast code */
3507 if (!super || !(super->flags & ACC_INTERFACE)) {
3512 codegen_addpatchref(cd, mcodeptr,
3513 PATCHER_checkcast_instanceof_class,
3514 (constant_classref *) iptr->target);
3516 if (showdisassemble)
3520 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3521 a = dseg_addaddress(cd, supervftbl);
3522 M_ALD(REG_ITMP3, REG_PV, a);
3523 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3524 codegen_threadcritstart(cd, (u1 *) mcodeptr - cd->mcodebase);
3526 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3527 /* if (s1 != REG_ITMP1) { */
3528 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3529 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3530 /* #if defined(USE_THREADS) && defined(NATIVE_THREADS) */
3531 /* codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase); */
3533 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3536 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3537 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3538 M_ALD(REG_ITMP3, REG_PV, a);
3539 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3540 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3541 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3544 M_CMPULE(REG_ITMP2, REG_ITMP3, REG_ITMP3);
3545 M_BEQZ(REG_ITMP3, 0);
3546 codegen_addxcastrefs(cd, mcodeptr);
3548 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
3550 store_reg_to_var_int(iptr->dst, d);
3554 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3556 /* op1: 0 == array, 1 == class */
3557 /* val.a: (classinfo*) superclass */
3559 /* superclass is an interface:
3561 * return (sub != NULL) &&
3562 * (sub->vftbl->interfacetablelength > super->index) &&
3563 * (sub->vftbl->interfacetable[-super->index] != NULL);
3565 * superclass is a class:
3567 * return ((sub != NULL) && (0
3568 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3569 * super->vftbl->diffvall));
3574 vftbl_t *supervftbl;
3577 super = (classinfo *) iptr->val.a;
3584 superindex = super->index;
3585 supervftbl = super->vftbl;
3588 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3589 codegen_threadcritrestart(cd, (u1 *) mcodeptr - cd->mcodebase);
3591 var_to_reg_int(s1, src, REG_ITMP1);
3592 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
3594 M_MOV(s1, REG_ITMP1);
3598 /* calculate interface instanceof code size */
3602 s2 += (d == REG_ITMP2 ? 1 : 0) + (showdisassemble ? 1 : 0);
3604 /* calculate class instanceof code size */
3608 s3 += (showdisassemble ? 1 : 0);
3610 /* if class is not resolved, check which code to call */
3614 M_BEQZ(s1, 4 + (showdisassemble ? 1 : 0) + s2 + 1 + s3);
3616 codegen_addpatchref(cd, mcodeptr,
3617 PATCHER_checkcast_instanceof_flags,
3618 (constant_classref *) iptr->target);
3620 if (showdisassemble)
3623 a = dseg_adds4(cd, 0); /* super->flags */
3624 M_ILD(REG_ITMP3, REG_PV, a);
3625 a = dseg_adds4(cd, ACC_INTERFACE);
3626 M_ILD(REG_ITMP2, REG_PV, a);
3627 M_AND(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3628 M_BEQZ(REG_ITMP3, s2 + 1);
3631 /* interface instanceof code */
3633 if (!super || (super->flags & ACC_INTERFACE)) {
3639 /* If d == REG_ITMP2, then it's destroyed in check code */
3644 codegen_addpatchref(cd, mcodeptr,
3645 PATCHER_checkcast_instanceof_interface,
3646 (constant_classref *) iptr->target);
3648 if (showdisassemble)
3652 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3653 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3654 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
3655 M_BLEZ(REG_ITMP3, 2);
3656 M_ALD(REG_ITMP1, REG_ITMP1,
3657 OFFSET(vftbl_t, interfacetable[0]) -
3658 superindex * sizeof(methodptr*));
3659 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3665 /* class instanceof code */
3667 if (!super || !(super->flags & ACC_INTERFACE)) {
3673 codegen_addpatchref(cd, mcodeptr,
3674 PATCHER_checkcast_instanceof_class,
3675 (constant_classref *) iptr->target);
3677 if (showdisassemble)
3681 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3682 a = dseg_addaddress(cd, supervftbl);
3683 M_ALD(REG_ITMP2, REG_PV, a);
3684 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3685 codegen_threadcritstart(cd, (u1 *) mcodeptr - cd->mcodebase);
3687 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3688 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3689 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3690 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3691 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3693 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3694 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3696 store_reg_to_var_int(iptr->dst, d);
3701 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
3703 var_to_reg_int(s1, src, REG_ITMP1);
3705 codegen_addxcheckarefs(cd, mcodeptr);
3708 case ICMD_CHECKEXCEPTION: /* ... ==> ... */
3710 M_BEQZ(REG_RESULT, 0);
3711 codegen_addxexceptionrefs(cd, mcodeptr);
3714 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3715 /* op1 = dimension, val.a = array descriptor */
3717 /* check for negative sizes and copy sizes to stack if necessary */
3719 MCODECHECK((iptr->op1 << 1) + 64);
3721 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3722 var_to_reg_int(s2, src, REG_ITMP1);
3724 codegen_addxcheckarefs(cd, mcodeptr);
3726 /* copy SAVEDVAR sizes to stack */
3728 if (src->varkind != ARGVAR) {
3729 M_LST(s2, REG_SP, s1 * 8);
3733 /* is patcher function set? */
3736 codegen_addpatchref(cd, mcodeptr,
3737 (functionptr) iptr->target, iptr->val.a);
3739 if (showdisassemble)
3745 a = (ptrint) iptr->val.a;
3748 /* a0 = dimension count */
3750 ICONST(rd->argintregs[0], iptr->op1);
3752 /* a1 = arraydescriptor */
3754 a = dseg_addaddress(cd, a);
3755 M_ALD(rd->argintregs[1], REG_PV, a);
3757 /* a2 = pointer to dimensions = stack pointer */
3759 M_INTMOVE(REG_SP, rd->argintregs[2]);
3761 a = dseg_addaddress(cd, (void *) BUILTIN_multianewarray);
3762 M_ALD(REG_PV, REG_PV, a);
3763 M_JSR(REG_RA, REG_PV);
3764 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3766 M_LDA(REG_PV, REG_RA, -s1);
3768 s4 ml = -s1, mh = 0;
3769 while (ml < -32768) { ml += 65536; mh--; }
3770 M_LDA(REG_PV, REG_RA, ml);
3771 M_LDAH(REG_PV, REG_PV, mh);
3773 s1 = reg_of_var(rd, iptr->dst, REG_RESULT);
3774 M_INTMOVE(REG_RESULT, s1);
3775 store_reg_to_var_int(iptr->dst, s1);
3779 throw_cacao_exception_exit(string_java_lang_InternalError,
3780 "Unknown ICMD %d", iptr->opc);
3783 } /* for instruction */
3785 /* copy values to interface registers */
3787 src = bptr->outstack;
3788 len = bptr->outdepth;
3795 if ((src->varkind != STACKVAR)) {
3797 if (IS_FLT_DBL_TYPE(s2)) {
3798 var_to_reg_flt(s1, src, REG_FTMP1);
3799 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3800 M_FLTMOVE(s1,rd->interfaces[len][s2].regoff);
3803 M_DST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3807 var_to_reg_int(s1, src, REG_ITMP1);
3808 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3809 M_INTMOVE(s1,rd->interfaces[len][s2].regoff);
3812 M_LST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3818 } /* if (bptr -> flags >= BBREACHED) */
3819 } /* for basic block */
3821 codegen_createlinenumbertable(cd);
3824 /* generate bound check stubs */
3826 s4 *xcodeptr = NULL;
3829 for (bref = cd->xboundrefs; bref != NULL; bref = bref->next) {
3830 gen_resolvebranch((u1*) cd->mcodebase + bref->branchpos,
3832 (u1*) mcodeptr - cd->mcodebase);
3836 /* move index register into REG_ITMP1 */
3837 M_MOV(bref->reg, REG_ITMP1);
3838 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3840 if (xcodeptr != NULL) {
3841 M_BR(xcodeptr - mcodeptr - 1);
3844 xcodeptr = mcodeptr;
3846 a = dseg_addaddress(cd, asm_throw_and_handle_arrayindexoutofbounds_exception);
3847 M_ALD(REG_PV, REG_PV, a);
3849 M_JSR(REG_RA, REG_PV);
3852 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3853 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3855 s4 ml = -s1, mh = 0;
3856 while (ml < -32768) { ml += 65536; mh--; }
3857 M_LDA(REG_PV, REG_RA, ml);
3858 M_LDAH(REG_PV, REG_PV, mh);
3863 /* generate negative array size check stubs */
3867 for (bref = cd->xcheckarefs; bref != NULL; bref = bref->next) {
3868 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3869 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3871 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3875 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3877 (u1 *) mcodeptr - cd->mcodebase);
3881 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3883 if (xcodeptr != NULL) {
3884 M_BR(xcodeptr - mcodeptr - 1);
3887 xcodeptr = mcodeptr;
3889 a = dseg_addaddress(cd, string_java_lang_NegativeArraySizeException);
3890 M_ALD(REG_ITMP1_XPTR,REG_PV,a);
3892 a = dseg_addaddress(cd, asm_throw_and_handle_nat_exception);
3893 M_ALD(REG_PV, REG_PV, a);
3895 M_JSR(REG_RA, REG_PV);
3898 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3899 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3901 s4 ml = -s1, mh = 0;
3902 while (ml < -32768) { ml += 65536; mh--; }
3903 M_LDA(REG_PV, REG_RA, ml);
3904 M_LDAH(REG_PV, REG_PV, mh);
3909 /* generate cast check stubs */
3913 for (bref = cd->xcastrefs; bref != NULL; bref = bref->next) {
3914 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3915 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3917 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3921 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3923 (u1 *) mcodeptr - cd->mcodebase);
3927 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3929 if (xcodeptr != NULL) {
3930 M_BR(xcodeptr - mcodeptr - 1);
3933 xcodeptr = mcodeptr;
3935 a = dseg_addaddress(cd, string_java_lang_ClassCastException);
3936 M_ALD(REG_ITMP1_XPTR,REG_PV,a);
3938 a = dseg_addaddress(cd, asm_throw_and_handle_nat_exception);
3939 M_ALD(REG_PV, REG_PV, a);
3941 M_JSR(REG_RA, REG_PV);
3944 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3945 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3947 s4 ml = -s1, mh = 0;
3948 while (ml < -32768) { ml += 65536; mh--; }
3949 M_LDA(REG_PV, REG_RA, ml);
3950 M_LDAH(REG_PV, REG_PV, mh);
3955 /* generate exception check stubs */
3959 for (bref = cd->xexceptionrefs; bref != NULL; bref = bref->next) {
3960 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3961 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3963 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3967 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3969 (u1 *) mcodeptr - cd->mcodebase);
3973 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3975 if (xcodeptr != NULL) {
3976 M_BR(xcodeptr - mcodeptr - 1);
3979 xcodeptr = mcodeptr;
3981 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3982 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3983 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3985 a = dseg_addaddress(cd, &builtin_get_exceptionptrptr);
3986 M_ALD(REG_PV, REG_PV, a);
3987 M_JSR(REG_RA, REG_PV);
3990 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3991 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3993 s4 ml = -s1, mh = 0;
3994 while (ml < -32768) { ml += 65536; mh--; }
3995 M_LDA(REG_PV, REG_RA, ml);
3996 M_LDAH(REG_PV, REG_PV, mh);
3999 M_ALD(REG_ITMP1_XPTR, REG_RESULT, 0);
4000 M_AST(REG_ZERO, REG_RESULT, 0);
4002 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
4003 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
4005 a = dseg_addaddress(cd, &_exceptionptr);
4006 M_ALD(REG_ITMP3, REG_PV, a);
4007 M_ALD(REG_ITMP1_XPTR, REG_ITMP3, 0);
4008 M_AST(REG_ZERO, REG_ITMP3, 0);
4011 a = dseg_addaddress(cd, asm_refillin_and_handle_exception);
4012 M_ALD(REG_PV, REG_PV, a);
4014 M_JMP(REG_RA, REG_PV);
4017 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4018 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
4020 s4 ml = -s1, mh = 0;
4021 while (ml < -32768) { ml += 65536; mh--; }
4022 M_LDA(REG_PV, REG_RA, ml);
4023 M_LDAH(REG_PV, REG_PV, mh);
4029 /* generate null pointer check stubs */
4033 for (bref = cd->xnullrefs; bref != NULL; bref = bref->next) {
4034 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
4035 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
4037 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
4041 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
4043 (u1 *) mcodeptr - cd->mcodebase);
4047 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
4049 if (xcodeptr != NULL) {
4050 M_BR(xcodeptr - mcodeptr - 1);
4053 xcodeptr = mcodeptr;
4055 a = dseg_addaddress(cd, string_java_lang_NullPointerException);
4056 M_ALD(REG_ITMP1_XPTR,REG_PV,a);
4058 a = dseg_addaddress(cd, asm_throw_and_handle_nat_exception);
4059 M_ALD(REG_PV, REG_PV, a);
4061 M_JSR(REG_RA, REG_PV);
4064 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4065 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
4067 s4 ml = -s1, mh = 0;
4068 while (ml < -32768) { ml += 65536; mh--; }
4069 M_LDA(REG_PV, REG_RA, ml);
4070 M_LDAH(REG_PV, REG_PV, mh);
4075 /* generate put/getstatic stub call code */
4082 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
4083 /* check code segment size */
4085 MCODECHECK(13 + 4 + 1);
4087 /* Get machine code which is patched back in later. The call is */
4088 /* 1 instruction word long. */
4090 xcodeptr = (s4 *) (cd->mcodebase + pref->branchpos);
4093 /* patch in the call to call the following code (done at compile */
4096 tmpmcodeptr = mcodeptr; /* save current mcodeptr */
4097 mcodeptr = xcodeptr; /* set mcodeptr to patch position */
4099 M_BSR(REG_ITMP3, tmpmcodeptr - (xcodeptr + 1));
4101 mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
4103 /* create stack frame */
4105 M_LSUB_IMM(REG_SP, 5 * 8, REG_SP);
4107 /* move return address onto stack */
4109 M_AST(REG_ITMP3, REG_SP, 4 * 8);
4111 /* move pointer to java_objectheader onto stack */
4113 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4114 /* create a virtual java_objectheader */
4116 (void) dseg_addaddress(cd, get_dummyLR()); /* monitorPtr */
4117 a = dseg_addaddress(cd, NULL); /* vftbl */
4120 M_LDA(REG_ITMP3, REG_PV, a);
4122 M_LDAH(REG_ITMP3, REG_PV, (a >> 16) & 0x0000ffff);
4123 M_LDA(REG_ITMP3, REG_ITMP3, a & 0x0000ffff);
4125 M_AST(REG_ITMP3, REG_SP, 3 * 8);
4127 M_AST(REG_ZERO, REG_SP, 3 * 8);
4130 /* move machine code onto stack */
4132 a = dseg_adds4(cd, mcode);
4134 M_ILD(REG_ITMP3, REG_PV, a);
4136 M_LDAH(REG_ITMP3, REG_PV, (a >> 16) & 0x0000ffff);
4137 M_ILD(REG_ITMP3, REG_ITMP3, a & 0x0000ffff);
4139 M_IST(REG_ITMP3, REG_SP, 2 * 8);
4141 /* move class/method/field reference onto stack */
4143 a = dseg_addaddress(cd, pref->ref);
4145 M_ALD(REG_ITMP3, REG_PV, a);
4147 M_LDAH(REG_ITMP3, REG_PV, (a >> 16) & 0x0000ffff);
4148 M_ALD(REG_ITMP3, REG_ITMP3, a & 0x0000ffff);
4150 M_AST(REG_ITMP3, REG_SP, 1 * 8);
4152 /* move patcher function pointer onto stack */
4154 a = dseg_addaddress(cd, pref->patcher);
4156 M_ALD(REG_ITMP3, REG_PV, a);
4158 M_LDAH(REG_ITMP3, REG_PV, (a >> 16) & 0x0000ffff);
4159 M_ALD(REG_ITMP3, REG_ITMP3, a & 0x0000ffff);
4161 M_AST(REG_ITMP3, REG_SP, 0 * 8);
4163 a = dseg_addaddress(cd, asm_wrapper_patcher);
4165 M_ALD(REG_ITMP3, REG_PV, a);
4167 M_LDAH(REG_ITMP3, REG_PV, (a >> 16) & 0x0000ffff);
4168 M_ALD(REG_ITMP3, REG_ITMP3, a & 0x0000ffff);
4170 M_JMP(REG_ZERO, REG_ITMP3);
4175 codegen_finish(m, cd, (s4) ((u1 *) mcodeptr - cd->mcodebase));
4179 /* createcompilerstub **********************************************************
4181 Creates a stub routine which calls the compiler.
4183 *******************************************************************************/
4185 #define COMPSTUBSIZE 3
4187 u1 *createcompilerstub(methodinfo *m)
4189 u8 *s = CNEW(u8, COMPSTUBSIZE); /* memory to hold the stub */
4190 s4 *mcodeptr = (s4 *) s; /* code generation pointer */
4192 /* code for the stub */
4193 M_ALD(REG_PV, REG_PV, 16); /* load pointer to the compiler */
4194 M_JMP(0, REG_PV); /* jump to the compiler, return address
4195 in reg 0 is used as method pointer */
4196 s[1] = (u8) m; /* literals to be adressed */
4197 s[2] = (u8) asm_call_jit_compiler; /* jump directly via PV from above */
4199 #if defined(STATISTICS)
4201 count_cstub_len += COMPSTUBSIZE * 8;
4208 /* removecompilerstub **********************************************************
4210 Deletes a compilerstub from memory (simply by freeing it).
4212 *******************************************************************************/
4214 void removecompilerstub(u1 *stub)
4216 CFREE(stub, COMPSTUBSIZE * 8);
4220 /* createnativestub ************************************************************
4222 Creates a stub routine which calls a native method.
4224 *******************************************************************************/
4227 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4229 #define NATIVESTUB_STACK 8/*ra,native result, oldThreadspecificHeadValue, addressOfThreadspecificHead, method, 0,0,ra*/
4230 #define NATIVESTUB_THREAD_EXTRA (6 + 20) /*20 for additional frame creation*/
4231 #define NATIVESTUB_STACKTRACE_OFFSET 1
4235 #define NATIVESTUB_STACK 7/*ra,oldThreadspecificHeadValue, addressOfThreadspecificHead, method, 0,0,ra*/
4236 #define NATIVESTUB_THREAD_EXTRA (1 + 20) /*20 for additional frame creation*/
4237 #define NATIVESTUB_STACKTRACE_OFFSET 0
4241 #define NATIVESTUB_SIZE (44 + NATIVESTUB_THREAD_EXTRA - 1)
4242 #define NATIVESTUB_STATIC_SIZE 5
4243 #define NATIVESTUB_VERBOSE_SIZE (39 + 13)
4244 #define NATIVESTUB_OFFSET 14
4247 u1 *createnativestub(functionptr f, methodinfo *m)
4249 u8 *s; /* memory pointer to hold the stub */
4251 s4 *mcodeptr; /* code generation pointer */
4253 s4 stackframesize; /* size of stackframe if needed */
4258 t_inlining_globals *id;
4262 s4 i, j; /* count variables */
4266 /* initialize variables */
4268 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
4270 /* mark start of dump memory area */
4272 dumpsize = dump_size();
4274 /* setup registers before using it */
4276 cd = DNEW(codegendata);
4277 rd = DNEW(registerdata);
4278 id = DNEW(t_inlining_globals);
4280 inlining_setup(m, id);
4281 reg_setup(m, rd, id);
4284 /* create new method descriptor with additional native parameters */
4288 nmd = (methoddesc *) DMNEW(u1, sizeof(methoddesc) - sizeof(typedesc) +
4289 md->paramcount * sizeof(typedesc) +
4290 nativeparams * sizeof(typedesc));
4292 nmd->paramcount = md->paramcount + nativeparams;
4294 nmd->params = DMNEW(paramdesc, nmd->paramcount);
4296 nmd->paramtypes[0].type = TYPE_ADR; /* add environment pointer */
4298 if (m->flags & ACC_STATIC)
4299 nmd->paramtypes[1].type = TYPE_ADR; /* add class pointer */
4301 MCOPY(nmd->paramtypes + nativeparams, md->paramtypes, typedesc,
4304 md_param_alloc(nmd);
4307 /* calculate native stub size */
4309 stubsize = NATIVESTUB_SIZE; /* calculate nativestub size */
4311 if ((m->flags & ACC_STATIC) && !m->class->initialized)
4312 stubsize += NATIVESTUB_STATIC_SIZE;
4315 stubsize += NATIVESTUB_VERBOSE_SIZE;
4317 s = CNEW(u8, stubsize); /* memory to hold the stub */
4318 cs = s + NATIVESTUB_OFFSET;
4319 mcodeptr = (s4 *) cs; /* code generation pointer */
4321 /* set some required varibles which are normally set by codegen_setup */
4323 cd->mcodebase = (u1 *) mcodeptr;
4324 cd->patchrefs = NULL;
4326 *(cs-1) = (u8) f; /* address of native method */
4327 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4328 *(cs-2) = (u8) &builtin_get_exceptionptrptr;
4330 *(cs-2) = (u8) (&_exceptionptr); /* address of exceptionptr */
4332 *(cs-3) = (u8) asm_handle_nat_exception; /* addr of asm exception handler*/
4333 *(cs-4) = (u8) (&env); /* addr of jni_environement */
4334 *(cs-5) = (u8) builtin_trace_args;
4336 *(cs-7) = (u8) builtin_displaymethodstop;
4337 *(cs-8) = (u8) m->class;
4338 *(cs-9) = (u8) asm_wrapper_patcher;
4339 *(cs-10) = (u8) &builtin_asm_get_stackframeinfo;
4340 *(cs-11) = (u8) NULL; /* filled with machine code */
4341 *(cs-12) = (u8) PATCHER_clinit;
4342 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4343 *(cs-13) = (ptrint) get_dummyLR(); /* monitorPtr */
4345 *(cs-13) = (ptrint) NULL; /* monitorPtr */
4347 *(cs-14) = (ptrint) NULL; /* vftbl */
4350 /* generate stub code */
4352 M_LDA(REG_SP, REG_SP, -NATIVESTUB_STACK * 8); /* build up stackframe */
4353 M_AST(REG_RA, REG_SP, 0 * 8); /* store return address */
4355 M_AST(REG_RA, REG_SP, (NATIVESTUB_STACKTRACE_OFFSET + 6) * 8); /* store return address in stackinfo helper*/
4357 /* if function is static, check for initialized */
4359 if ((m->flags & ACC_STATIC) && !m->class->initialized) {
4360 codegen_addpatchref(cd, mcodeptr, NULL, NULL);
4362 if (showdisassemble)
4366 /* max. 39 +9 instructions */
4369 M_LDA(REG_SP, REG_SP, -((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
4370 M_AST(REG_RA, REG_SP, 1 * 8);
4372 /* save integer argument registers */
4374 for (i = 0; i < md->paramcount && i < INT_ARG_CNT; i++)
4375 if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
4376 M_LST(rd->argintregs[i], REG_SP, (2 + i) * 8);
4378 /* save and copy float arguments into integer registers */
4380 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4381 t = md->paramtypes[i].type;
4383 if (IS_FLT_DBL_TYPE(t)) {
4384 if (IS_2_WORD_TYPE(t)) {
4385 M_DST(rd->argfltregs[i], REG_SP, (2 + INT_ARG_CNT + i) * 8);
4386 M_LLD(rd->argintregs[i], REG_SP, (2 + INT_ARG_CNT + i) * 8);
4389 M_FST(rd->argfltregs[i], REG_SP, (2 + INT_ARG_CNT + i) * 8);
4390 M_ILD(rd->argintregs[i], REG_SP, (2 + INT_ARG_CNT + i) * 8);
4395 M_ALD(REG_ITMP1, REG_PV, -6 * 8);
4396 M_AST(REG_ITMP1, REG_SP, 0 * 8);
4397 M_ALD(REG_PV, REG_PV, -5 * 8);
4398 M_JSR(REG_RA, REG_PV);
4399 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4400 M_LDA(REG_PV, REG_RA, disp);
4402 for (i = 0; i < md->paramcount && i < INT_ARG_CNT; i++)
4403 if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
4404 M_LLD(rd->argintregs[i], REG_SP, (2 + i) * 8);
4406 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4407 t = md->paramtypes[i].type;
4409 if (IS_FLT_DBL_TYPE(t)) {
4410 if (IS_2_WORD_TYPE(t)) {
4411 M_DLD(rd->argfltregs[i], REG_SP, (2 + INT_ARG_CNT + i) * 8);
4413 M_FLD(rd->argfltregs[i], REG_SP, (2 + INT_ARG_CNT + i) * 8);
4418 M_ALD(REG_RA, REG_SP, 1 * 8);
4419 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT + 2) * 8);
4425 M_LDA(REG_SP, REG_SP, -((INT_ARG_CNT + FLT_ARG_CNT) * 8));
4427 /* save integer and float argument registers */
4429 for (i = 0; i < md->paramcount && i < INT_ARG_CNT; i++)
4430 if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
4431 M_LST(rd->argintregs[i], REG_SP, i * 8);
4433 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++)
4434 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type))
4435 M_DST(rd->argfltregs[i], REG_SP, (INT_ARG_CNT + i) * 8);
4438 M_ALD(REG_PV, REG_PV, -10 * 8); /* builtin_asm_get_stackframeinfo */
4439 M_JSR(REG_RA, REG_PV);
4440 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4441 M_LDA(REG_PV, REG_RA, disp);
4443 M_LST(REG_RESULT, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT + NATIVESTUB_STACKTRACE_OFFSET + 2) * 8); /* save adress of pointer */
4444 M_LLD(REG_ITMP3, REG_RESULT, 0); /* get pointer */
4445 M_LST(REG_ITMP3, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT + NATIVESTUB_STACKTRACE_OFFSET + 1) * 8); /* save old value */
4446 M_LDA(REG_ITMP3, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT + NATIVESTUB_STACKTRACE_OFFSET + 1) * 8); /* calculate new value */
4447 M_LLD(REG_ITMP2, REG_ITMP3, 8);
4448 M_LST(REG_ITMP3, REG_ITMP2, 0); /* store new value */
4449 M_LLD(REG_ITMP2, REG_PV, -6 * 8);
4450 M_LST(REG_ITMP2, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT + NATIVESTUB_STACKTRACE_OFFSET + 3) * 8);
4451 M_LST(REG_ZERO, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT + NATIVESTUB_STACKTRACE_OFFSET + 4) * 8);
4452 M_LST(REG_ZERO, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT + NATIVESTUB_STACKTRACE_OFFSET + 5) * 8);
4453 /*stack info -end */
4455 /* restore integer and float argument registers */
4457 for (i = 0; i < md->paramcount && i < INT_ARG_CNT; i++)
4458 if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
4459 M_LLD(rd->argintregs[i], REG_SP, i * 8);
4461 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++)
4462 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type))
4463 M_DLD(rd->argfltregs[i], REG_SP, (INT_ARG_CNT + i) * 8);
4465 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
4468 /* calculate stack frame size */
4470 stackframesize = nmd->memuse;
4473 M_LDA(REG_SP, REG_SP, -stackframesize * 8);
4475 /* copy or spill arguments to new locations */
4477 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
4478 t = md->paramtypes[i].type;
4480 if (IS_INT_LNG_TYPE(t)) {
4481 if (!md->params[i].inmemory) {
4482 s1 = rd->argintregs[md->params[i].regoff];
4484 if (!nmd->params[j].inmemory) {
4485 s2 = rd->argintregs[nmd->params[j].regoff];
4489 s2 = nmd->params[j].regoff;
4490 M_LST(s1, REG_SP, s2 * 8);
4494 s1 = md->params[i].regoff + stackframesize;
4495 s2 = nmd->params[j].regoff;
4496 M_LLD(REG_ITMP1, REG_SP, s1 * 8);
4497 M_LST(REG_ITMP1, REG_SP, s2 * 8);
4501 if (!md->params[i].inmemory) {
4502 s1 = rd->argfltregs[md->params[i].regoff];
4504 if (!nmd->params[j].inmemory) {
4505 s2 = rd->argfltregs[nmd->params[j].regoff];
4509 s2 = nmd->params[j].regoff;
4510 M_DST(s1, REG_SP, s2 * 8);
4514 s1 = md->params[i].regoff + stackframesize;
4515 s2 = nmd->params[j].regoff;
4516 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
4517 M_DST(REG_FTMP1, REG_SP, s2 * 8);
4522 /* put class into second argument register */
4524 if (m->flags & ACC_STATIC)
4525 M_ALD(rd->argintregs[1], REG_PV, -8 * 8);
4527 /* put env into first argument register */
4529 M_ALD(rd->argintregs[0], REG_PV, -4 * 8);
4531 /* do the native function call */
4533 M_ALD(REG_PV, REG_PV, -1 * 8); /* load adress of native method */
4534 M_JSR(REG_RA, REG_PV); /* call native method */
4535 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4536 M_LDA(REG_PV, REG_RA, disp); /* recompute pv from ra */
4538 /* remove stackframe if there is one */
4541 M_LDA(REG_SP, REG_SP, stackframesize * 8);
4543 /* 13 instructions */
4546 M_LDA(REG_SP, REG_SP, -2 * 8);
4547 M_ALD(rd->argintregs[0], REG_PV, -6 * 8); /* load method adress */
4548 M_LST(REG_RESULT, REG_SP, 0 * 8);
4549 M_DST(REG_FRESULT, REG_SP, 1 * 8);
4550 M_MOV(REG_RESULT, rd->argintregs[1]);
4551 M_FMOV(REG_FRESULT, rd->argfltregs[2]);
4552 M_FMOV(REG_FRESULT, rd->argfltregs[3]);
4553 M_ALD(REG_PV, REG_PV, -7 * 8); /* builtin_displaymethodstop */
4554 M_JSR(REG_RA, REG_PV);
4555 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4556 M_LDA(REG_PV, REG_RA, disp);
4557 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4558 M_DLD(REG_FRESULT, REG_SP, 1 * 8);
4559 M_LDA(REG_SP, REG_SP, 2 * 8);
4562 M_LLD(REG_ITMP3, REG_SP, (NATIVESTUB_STACKTRACE_OFFSET + 2) * 8); /* get address of stacktrace helper pointer */
4563 M_LLD(REG_ITMP1, REG_SP, (NATIVESTUB_STACKTRACE_OFFSET + 1) * 8); /* get old value */
4564 M_LST(REG_ITMP1, REG_ITMP3, 0); /* set old value */
4566 /* check for exception */
4568 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4569 if (IS_FLT_DBL_TYPE(m->returntype))
4570 M_DST(REG_FRESULT, REG_SP, 1 * 8);
4572 M_AST(REG_RESULT, REG_SP, 1 * 8);
4574 M_ALD(REG_PV, REG_PV, -2 * 8); /* builtin_get_exceptionptrptr */
4575 M_JSR(REG_RA, REG_PV);
4576 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4577 M_LDA(REG_PV, REG_RA, disp);
4578 M_MOV(REG_RESULT, REG_ITMP3);
4580 if (IS_FLT_DBL_TYPE(m->returntype))
4581 M_DLD(REG_FRESULT, REG_SP, 1 * 8);
4583 M_ALD(REG_RESULT, REG_SP, 1 * 8);
4585 M_ALD(REG_ITMP3, REG_PV, -2 * 8); /* get address of exceptionptr */
4588 M_ALD(REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
4589 M_BNEZ(REG_ITMP1, 3); /* if no exception then return */
4591 M_ALD(REG_RA, REG_SP, 0 * 8); /* load return address */
4592 M_LDA(REG_SP, REG_SP, NATIVESTUB_STACK * 8); /* remove stackframe */
4593 M_RET(REG_ZERO, REG_RA); /* return to caller */
4595 /* handle exception */
4597 M_AST(REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
4599 M_ALD(REG_RA, REG_SP, 0 * 8); /* load return address */
4600 M_LDA(REG_SP, REG_SP, NATIVESTUB_STACK * 8); /* remove stackframe */
4601 M_LDA(REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
4602 M_ALD(REG_ITMP3, REG_PV, -3 * 8); /* load asm exception handler address */
4603 M_JMP(REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
4605 /* generate put/getstatic stub call code */
4612 /* there can only be one <clinit> ref entry */
4613 pref = cd->patchrefs;
4616 /* Get machine code which is patched back in later. The call is */
4617 /* 1 instruction word long. */
4619 xcodeptr = (s4 *) (cd->mcodebase + pref->branchpos);
4620 *(cs-11) = (u4) *xcodeptr;
4622 /* patch in the call to call the following code (done at compile */
4625 tmpmcodeptr = mcodeptr; /* save current mcodeptr */
4626 mcodeptr = xcodeptr; /* set mcodeptr to patch position */
4628 M_BSR(REG_ITMP3, tmpmcodeptr - (xcodeptr + 1));
4630 mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
4632 /* create stack frame */
4634 M_LSUB_IMM(REG_SP, 5 * 8, REG_SP);
4636 /* move return address onto stack */
4638 M_AST(REG_ITMP3, REG_SP, 4 * 8);
4640 /* move pointer to java_objectheader onto stack */
4642 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4643 M_LDA(REG_ITMP3, REG_PV, -14 * 8); /* virtual objectheader */
4644 M_AST(REG_ITMP3, REG_SP, 3 * 8);
4646 M_AST(REG_ZERO, REG_SP, 3 * 8);
4649 /* move machine code onto stack */
4651 M_ILD(REG_ITMP3, REG_PV, -11 * 8); /* machine code */
4652 M_IST(REG_ITMP3, REG_SP, 2 * 8);
4654 /* move class reference onto stack */
4656 M_ALD(REG_ITMP3, REG_PV, -8 * 8); /* class */
4657 M_AST(REG_ITMP3, REG_SP, 1 * 8);
4659 /* move patcher function pointer onto stack */
4661 M_ALD(REG_ITMP3, REG_PV, -12 * 8); /* patcher function */
4662 M_AST(REG_ITMP3, REG_SP, 0 * 8);
4664 M_ALD(REG_ITMP3, REG_PV, -9 * 8); /* asm_wrapper_patcher */
4665 M_JMP(REG_ZERO, REG_ITMP3);
4669 /* Check if the stub size is big enough to hold the whole stub generated. */
4670 /* If not, this can lead into unpredictable crashes, because of heap */
4672 if ((s4) ((ptrint) mcodeptr - (ptrint) s) > stubsize * sizeof(u8)) {
4673 throw_cacao_exception_exit(string_java_lang_InternalError,
4674 "Native stub size %d is to small for current stub size %d",
4675 stubsize, (s4) ((ptrint) mcodeptr - (ptrint) s));
4679 /* disassemble native stub */
4681 if (showdisassemble)
4682 codegen_disassemble_nativestub(m, (s4 *) (s + NATIVESTUB_OFFSET),
4683 (s4) ((ptrint) mcodeptr -
4684 (ptrint) (s + NATIVESTUB_OFFSET)));
4687 #if defined(STATISTICS)
4689 count_nstub_len += NATIVESTUB_SIZE * 8;
4692 /* release dump area */
4694 dump_release(dumpsize);
4696 return (u1 *) (s + NATIVESTUB_OFFSET);
4700 /* removenativestub ************************************************************
4702 Removes a previously created native-stub from memory.
4704 *******************************************************************************/
4706 void removenativestub(u1 *stub)
4708 CFREE((u8 *) stub - NATIVESTUBOFFSET, NATIVESTUBSIZE * 8);
4713 * These are local overrides for various environment variables in Emacs.
4714 * Please do not remove this and leave it at the end of the file, where
4715 * Emacs will automagically detect them.
4716 * ---------------------------------------------------------------------
4719 * indent-tabs-mode: t