1 /* vm/jit/alpha/codegen.c - machine code generator for alpha
3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Andreas Krall
30 Changes: Joseph Wenninger
32 $Id: codegen.c 1946 2005-02-15 16:52:08Z twisti $
41 #include "cacao/cacao.h"
42 #include "native/native.h"
43 #include "vm/builtin.h"
44 #include "vm/global.h"
45 #include "vm/loader.h"
46 #include "vm/tables.h"
47 #include "vm/jit/asmpart.h"
48 #include "vm/jit/jit.h"
50 #include "vm/jit/lsra.h"
52 #include "vm/jit/parse.h"
53 #include "vm/jit/reg.h"
54 #include "vm/jit/alpha/arch.h"
55 #include "vm/jit/alpha/codegen.h"
56 #include "vm/jit/alpha/types.h"
57 #include "vm/jit/alpha/asmoffsets.h"
60 /* *****************************************************************************
62 Datatypes and Register Allocations:
63 -----------------------------------
65 On 64-bit-machines (like the Alpha) all operands are stored in the
66 registers in a 64-bit form, even when the correspondig JavaVM operands
67 only need 32 bits. This is done by a canonical representation:
69 32-bit integers are allways stored as sign-extended 64-bit values (this
70 approach is directly supported by the Alpha architecture and is very easy
73 32-bit-floats are stored in a 64-bit doubleprecision register by simply
74 expanding the exponent and mantissa with zeroes. (also supported by the
80 The calling conventions and the layout of the stack is explained in detail
81 in the documention file: calling.doc
83 *******************************************************************************/
86 /* register descripton - array ************************************************/
88 /* #define REG_RES 0 reserved register for OS or code generator */
89 /* #define REG_RET 1 return value register */
90 /* #define REG_EXC 2 exception value register (only old jit) */
91 /* #define REG_SAV 3 (callee) saved register */
92 /* #define REG_TMP 4 scratch temporary register (caller saved) */
93 /* #define REG_ARG 5 argument register (caller saved) */
95 /* #define REG_END -1 last entry in tables */
98 REG_RET, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
99 REG_TMP, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
100 REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_TMP, REG_TMP,
101 REG_TMP, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES,
104 /* for use of reserved registers, see comment above */
106 int nregdescfloat[] = {
107 REG_RET, REG_TMP, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
108 REG_SAV, REG_SAV, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
109 REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_TMP, REG_TMP,
110 REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_RES, REG_RES, REG_RES, REG_RES,
114 /* Include independent code generation stuff -- include after register */
115 /* descriptions to avoid extern definitions. */
117 #include "vm/jit/codegen.inc"
118 #include "vm/jit/reg.inc"
120 #include "vm/jit/lsra.inc"
124 /* NullPointerException handlers and exception handling initialisation */
126 typedef struct sigctx_struct {
127 long sc_onstack; /* sigstack state to restore */
128 long sc_mask; /* signal mask to restore */
129 long sc_pc; /* pc at time of signal */
130 long sc_ps; /* psl to retore */
131 long sc_regs[32]; /* processor regs 0 to 31 */
132 long sc_ownedfp; /* fp has been used */
133 long sc_fpregs[32]; /* fp regs 0 to 31 */
134 unsigned long sc_fpcr; /* floating point control register */
135 unsigned long sc_fp_control; /* software fpcr */
137 unsigned long sc_reserved1, sc_reserved2;
138 unsigned long sc_ssize;
140 unsigned long sc_traparg_a0;
141 unsigned long sc_traparg_a1;
142 unsigned long sc_traparg_a2;
143 unsigned long sc_fp_trap_pc;
144 unsigned long sc_fp_trigger_sum;
145 unsigned long sc_fp_trigger_inst;
146 unsigned long sc_retcode[2];
150 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
151 void thread_restartcriticalsection(ucontext_t *uc)
154 if ((critical = thread_checkcritical((void*) uc->uc_mcontext.sc_pc)) != NULL)
155 uc->uc_mcontext.sc_pc = (u8) critical;
160 /* NullPointerException signal handler for hardware null pointer check */
162 void catch_NullPointerException(int sig, siginfo_t *siginfo, void *_p)
164 struct sigaction act;
169 ucontext_t *_uc = (ucontext_t *) _p;
170 mcontext_t *sigctx = &_uc->uc_mcontext;
172 instr = *((s4 *) (sigctx->sc_pc));
173 faultaddr = sigctx->sc_regs[(instr >> 16) & 0x1f];
175 if (faultaddr == 0) {
176 /* Reset signal handler - necessary for SysV, does no harm for BSD */
177 act.sa_sigaction = catch_NullPointerException;
178 act.sa_flags = SA_SIGINFO;
179 sigaction(sig, &act, NULL);
182 sigaddset(&nsig, sig);
183 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
185 sigctx->sc_regs[REG_ITMP1_XPTR] = (u8) string_java_lang_NullPointerException;
186 sigctx->sc_regs[REG_ITMP2_XPC] = sigctx->sc_pc;
187 sigctx->sc_pc = (u8) asm_throw_and_handle_exception;
191 faultaddr += (long) ((instr << 16) >> 16);
192 fprintf(stderr, "faulting address: 0x%016lx\n", faultaddr);
193 panic("Stack overflow");
200 void init_exceptions(void)
205 /* Linux on Digital Alpha needs an initialisation of the ieee floating point
206 control for IEEE compliant arithmetic (option -mieee of GCC). Under
207 Digital Unix this is done automatically.
212 extern unsigned long ieee_get_fp_control();
213 extern void ieee_set_fp_control(unsigned long fp_control);
215 void init_exceptions(void)
217 struct sigaction act;
219 /* initialize floating point control */
221 ieee_set_fp_control(ieee_get_fp_control()
222 & ~IEEE_TRAP_ENABLE_INV
223 & ~IEEE_TRAP_ENABLE_DZE
224 /* & ~IEEE_TRAP_ENABLE_UNF we dont want underflow */
225 & ~IEEE_TRAP_ENABLE_OVF);
228 /* install signal handlers we need to convert to exceptions */
231 act.sa_sigaction = catch_NullPointerException;
232 act.sa_flags = SA_SIGINFO;
235 sigaction(SIGSEGV, &act, NULL);
239 sigaction(SIGBUS, &act, NULL);
245 /* function gen_mcode **********************************************************
247 generates machine code
249 *******************************************************************************/
251 void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
253 s4 len, s1, s2, s3, d;
267 savedregs_num = (m->isleafmethod) ? 0 : 1; /* space to save the RA */
269 /* space to save used callee saved registers */
271 savedregs_num += (rd->savintregcnt - rd->maxsavintreguse);
272 savedregs_num += (rd->savfltregcnt - rd->maxsavfltreguse);
274 parentargs_base = rd->maxmemuse + savedregs_num;
276 #if defined(USE_THREADS) /* space to save argument of monitor_enter */
278 if (checksync && (m->flags & ACC_SYNCHRONIZED))
283 /* create method header */
285 (void) dseg_addaddress(cd, m); /* MethodPointer */
286 (void) dseg_adds4(cd, parentargs_base * 8); /* FrameSize */
288 #if defined(USE_THREADS)
290 /* IsSync contains the offset relative to the stack pointer for the
291 argument of monitor_exit used in the exception handler. Since the
292 offset could be zero and give a wrong meaning of the flag it is
296 if (checksync && (m->flags & ACC_SYNCHRONIZED))
297 (void) dseg_adds4(cd, (rd->maxmemuse + 1) * 8); /* IsSync */
302 (void) dseg_adds4(cd, 0); /* IsSync */
304 (void) dseg_adds4(cd, m->isleafmethod); /* IsLeaf */
305 (void) dseg_adds4(cd, rd->savintregcnt - rd->maxsavintreguse);/* IntSave */
306 (void) dseg_adds4(cd, rd->savfltregcnt - rd->maxsavfltreguse);/* FltSave */
308 dseg_addlinenumbertablesize(cd);
310 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
312 /* create exception table */
314 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
315 dseg_addtarget(cd, ex->start);
316 dseg_addtarget(cd, ex->end);
317 dseg_addtarget(cd, ex->handler);
318 (void) dseg_addaddress(cd, ex->catchtype);
321 /* initialize mcode variables */
323 mcodeptr = (s4 *) cd->mcodebase;
324 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
325 MCODECHECK(128 + m->paramcount);
327 /* create stack frame (if necessary) */
329 if (parentargs_base) {
330 M_LDA(REG_SP, REG_SP, -parentargs_base * 8);
333 /* save return address and used callee saved registers */
336 if (!m->isleafmethod) {
337 p--; M_AST(REG_RA, REG_SP, p * 8);
339 for (i = rd->savintregcnt - 1; i >= rd->maxsavintreguse; i--) {
340 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
342 for (i = rd->savfltregcnt - 1; i >= rd->maxsavfltreguse; i--) {
343 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
346 /* save monitorenter argument */
348 #if defined(USE_THREADS)
349 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
350 if (m->flags & ACC_STATIC) {
351 p = dseg_addaddress(cd, m->class);
352 M_ALD(REG_ITMP1, REG_PV, p);
353 M_AST(REG_ITMP1, REG_SP, rd->maxmemuse * 8);
356 M_AST(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
361 /* copy argument registers to stack and call trace function with pointer
362 to arguments on stack.
367 M_LDA(REG_SP, REG_SP, -((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
368 M_AST(REG_RA, REG_SP, 1 * 8);
370 /* save integer argument registers */
371 for (p = 0; /* p < m->paramcount && */ p < INT_ARG_CNT; p++) {
372 M_LST(rd->argintregs[p], REG_SP, (2 + p) * 8);
375 /* save and copy float arguments into integer registers */
376 for (p = 0; /* p < m->paramcount && */ p < FLT_ARG_CNT; p++) {
377 t = m->paramtypes[p];
379 if (IS_FLT_DBL_TYPE(t)) {
380 if (IS_2_WORD_TYPE(t)) {
381 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
384 M_FST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
387 M_LLD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
390 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
394 p = dseg_addaddress(cd, m);
395 M_ALD(REG_ITMP1, REG_PV, p);
396 M_AST(REG_ITMP1, REG_SP, 0 * 8);
397 p = dseg_addaddress(cd, (void *) builtin_trace_args);
398 M_ALD(REG_PV, REG_PV, p);
399 M_JSR(REG_RA, REG_PV);
400 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
401 M_LDA(REG_PV, REG_RA, disp);
402 M_ALD(REG_RA, REG_SP, 1 * 8);
404 for (p = 0; /* p < mparamcount && */ p < INT_ARG_CNT; p++) {
405 M_LLD(rd->argintregs[p], REG_SP, (2 + p) * 8);
408 for (p = 0; /* p < mparamcount && */ p < FLT_ARG_CNT; p++) {
409 t = m->paramtypes[p];
411 if (IS_FLT_DBL_TYPE(t)) {
412 if (IS_2_WORD_TYPE(t)) {
413 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
416 M_FLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
420 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
424 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT + 2) * 8);
427 /* take arguments out of register or stack frame */
429 for (p = 0, l = 0; p < m->paramcount; p++) {
430 t = m->paramtypes[p];
431 var = &(rd->locals[l][t]);
433 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
437 if (IS_INT_LNG_TYPE(t)) { /* integer args */
438 if (p < INT_ARG_CNT) { /* register arguments */
439 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
440 M_INTMOVE(rd->argintregs[p], var->regoff);
441 } else { /* reg arg -> spilled */
442 M_LST(rd->argintregs[p], REG_SP, 8 * var->regoff);
445 } else { /* stack arguments */
446 pa = p - INT_ARG_CNT;
447 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
448 M_LLD(var->regoff, REG_SP, 8 * (parentargs_base + pa));
450 } else { /* stack arg -> spilled */
451 M_LLD(REG_ITMP1, REG_SP, 8 * (parentargs_base + pa));
452 M_LST(REG_ITMP1, REG_SP, 8 * var->regoff);
456 } else { /* floating args */
457 if (p < FLT_ARG_CNT) { /* register arguments */
458 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
459 M_FLTMOVE(rd->argfltregs[p], var->regoff);
461 } else { /* reg arg -> spilled */
462 M_DST(rd->argfltregs[p], REG_SP, 8 * var->regoff);
465 } else { /* stack arguments */
466 pa = p - FLT_ARG_CNT;
467 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
468 M_DLD(var->regoff, REG_SP, 8 * (parentargs_base + pa) );
470 } else { /* stack-arg -> spilled */
471 M_DLD(REG_FTMP1, REG_SP, 8 * (parentargs_base + pa));
472 M_DST(REG_FTMP1, REG_SP, 8 * var->regoff);
478 /* call monitorenter function */
480 #if defined(USE_THREADS)
481 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
483 s8 func_enter = (m->flags & ACC_STATIC) ?
484 (s8) builtin_staticmonitorenter : (s8) builtin_monitorenter;
485 p = dseg_addaddress(cd, (void*) func_enter);
486 M_ALD(REG_PV, REG_PV, p);
487 M_ALD(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
488 M_JSR(REG_RA, REG_PV);
489 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
490 M_LDA(REG_PV, REG_RA, disp);
495 /* end of header generation */
497 /* walk through all basic blocks */
498 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
500 bptr->mpc = (s4) ((u1 *) mcodeptr - cd->mcodebase);
502 if (bptr->flags >= BBREACHED) {
504 /* branch resolving */
508 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
509 gen_resolvebranch((u1*) cd->mcodebase + brefs->branchpos,
510 brefs->branchpos, bptr->mpc);
514 /* copy interface registers to their destination */
521 while (src != NULL) {
523 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
524 /* d = reg_of_var(m, src, REG_ITMP1); */
525 if (!(src->flags & INMEMORY))
529 M_INTMOVE(REG_ITMP1, d);
530 store_reg_to_var_int(src, d);
536 while (src != NULL) {
538 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
539 d = reg_of_var(rd, src, REG_ITMP1);
540 M_INTMOVE(REG_ITMP1, d);
541 store_reg_to_var_int(src, d);
544 d = reg_of_var(rd, src, REG_IFTMP);
545 if ((src->varkind != STACKVAR)) {
547 if (IS_FLT_DBL_TYPE(s2)) {
548 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
549 s1 = rd->interfaces[len][s2].regoff;
553 M_DLD(d, REG_SP, 8 * rd->interfaces[len][s2].regoff);
555 store_reg_to_var_flt(src, d);
558 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
559 s1 = rd->interfaces[len][s2].regoff;
563 M_LLD(d, REG_SP, 8 * rd->interfaces[len][s2].regoff);
565 store_reg_to_var_int(src, d);
575 /* walk through all instructions */
579 for (iptr = bptr->iinstr;
581 src = iptr->dst, len--, iptr++) {
583 if (iptr->line!=currentline) {
584 dseg_addlinenumber(cd,iptr->line,mcodeptr);
585 currentline=iptr->line;
588 MCODECHECK(64); /* an instruction usually needs < 64 words */
591 case ICMD_INLINE_START:
592 case ICMD_INLINE_END:
595 case ICMD_NOP: /* ... ==> ... */
598 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
600 var_to_reg_int(s1, src, REG_ITMP1);
602 codegen_addxnullrefs(cd, mcodeptr);
605 /* constant operations ************************************************/
607 case ICMD_ICONST: /* ... ==> ..., constant */
608 /* op1 = 0, val.i = constant */
610 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
611 ICONST(d, iptr->val.i);
612 store_reg_to_var_int(iptr->dst, d);
615 case ICMD_LCONST: /* ... ==> ..., constant */
616 /* op1 = 0, val.l = constant */
618 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
619 LCONST(d, iptr->val.l);
620 store_reg_to_var_int(iptr->dst, d);
623 case ICMD_FCONST: /* ... ==> ..., constant */
624 /* op1 = 0, val.f = constant */
626 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
627 a = dseg_addfloat(cd, iptr->val.f);
629 store_reg_to_var_flt(iptr->dst, d);
632 case ICMD_DCONST: /* ... ==> ..., constant */
633 /* op1 = 0, val.d = constant */
635 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
636 a = dseg_adddouble(cd, iptr->val.d);
638 store_reg_to_var_flt(iptr->dst, d);
641 case ICMD_ACONST: /* ... ==> ..., constant */
642 /* op1 = 0, val.a = constant */
644 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
646 a = dseg_addaddress(cd, iptr->val.a);
649 M_INTMOVE(REG_ZERO, d);
651 store_reg_to_var_int(iptr->dst, d);
655 /* load/store operations **********************************************/
657 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
658 case ICMD_LLOAD: /* op1 = local variable */
661 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
662 if ((iptr->dst->varkind == LOCALVAR) &&
663 (iptr->dst->varnum == iptr->op1))
665 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
666 if (var->flags & INMEMORY)
667 M_LLD(d, REG_SP, 8 * var->regoff);
669 {M_INTMOVE(var->regoff,d);}
670 store_reg_to_var_int(iptr->dst, d);
673 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
674 case ICMD_DLOAD: /* op1 = local variable */
676 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
677 if ((iptr->dst->varkind == LOCALVAR) &&
678 (iptr->dst->varnum == iptr->op1))
680 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
681 if (var->flags & INMEMORY)
682 M_DLD(d, REG_SP, 8 * var->regoff);
684 {M_FLTMOVE(var->regoff,d);}
685 store_reg_to_var_flt(iptr->dst, d);
689 case ICMD_ISTORE: /* ..., value ==> ... */
690 case ICMD_LSTORE: /* 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_int(s1, src, REG_ITMP1);
699 M_LST(s1, REG_SP, 8 * var->regoff);
702 var_to_reg_int(s1, src, var->regoff);
703 M_INTMOVE(s1, var->regoff);
707 case ICMD_FSTORE: /* ..., value ==> ... */
708 case ICMD_DSTORE: /* op1 = local variable */
710 if ((src->varkind == LOCALVAR) &&
711 (src->varnum == iptr->op1))
713 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
714 if (var->flags & INMEMORY) {
715 var_to_reg_flt(s1, src, REG_FTMP1);
716 M_DST(s1, REG_SP, 8 * var->regoff);
719 var_to_reg_flt(s1, src, var->regoff);
720 M_FLTMOVE(s1, var->regoff);
725 /* pop/dup/swap operations ********************************************/
727 /* attention: double and longs are only one entry in CACAO ICMDs */
729 case ICMD_POP: /* ..., value ==> ... */
730 case ICMD_POP2: /* ..., value, value ==> ... */
733 case ICMD_DUP: /* ..., a ==> ..., a, a */
734 M_COPY(src, iptr->dst);
737 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
739 M_COPY(src, iptr->dst);
740 M_COPY(src->prev, iptr->dst->prev);
741 M_COPY(iptr->dst, iptr->dst->prev->prev);
744 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
746 M_COPY(src, iptr->dst);
747 M_COPY(src->prev, iptr->dst->prev);
748 M_COPY(src->prev->prev, iptr->dst->prev->prev);
749 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
752 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
754 M_COPY(src, iptr->dst);
755 M_COPY(src->prev, iptr->dst->prev);
758 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
760 M_COPY(src, iptr->dst);
761 M_COPY(src->prev, iptr->dst->prev);
762 M_COPY(src->prev->prev, iptr->dst->prev->prev);
763 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
764 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev);
767 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
769 M_COPY(src, iptr->dst);
770 M_COPY(src->prev, iptr->dst->prev);
771 M_COPY(src->prev->prev, iptr->dst->prev->prev);
772 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
773 M_COPY(iptr->dst, iptr->dst->prev->prev->prev->prev);
774 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev->prev);
777 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
779 M_COPY(src, iptr->dst->prev);
780 M_COPY(src->prev, iptr->dst);
784 /* integer operations *************************************************/
786 case ICMD_INEG: /* ..., value ==> ..., - value */
788 var_to_reg_int(s1, src, REG_ITMP1);
789 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
790 M_ISUB(REG_ZERO, s1, d);
791 store_reg_to_var_int(iptr->dst, d);
794 case ICMD_LNEG: /* ..., value ==> ..., - value */
796 var_to_reg_int(s1, src, REG_ITMP1);
797 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
798 M_LSUB(REG_ZERO, s1, d);
799 store_reg_to_var_int(iptr->dst, d);
802 case ICMD_I2L: /* ..., value ==> ..., value */
804 var_to_reg_int(s1, src, REG_ITMP1);
805 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
807 store_reg_to_var_int(iptr->dst, d);
810 case ICMD_L2I: /* ..., value ==> ..., value */
812 var_to_reg_int(s1, src, REG_ITMP1);
813 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
814 M_IADD(s1, REG_ZERO, d );
815 store_reg_to_var_int(iptr->dst, d);
818 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
820 var_to_reg_int(s1, src, REG_ITMP1);
821 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
822 if (has_ext_instr_set) {
826 M_SLL_IMM(s1, 56, d);
827 M_SRA_IMM( d, 56, d);
829 store_reg_to_var_int(iptr->dst, d);
832 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
834 var_to_reg_int(s1, src, REG_ITMP1);
835 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
837 store_reg_to_var_int(iptr->dst, d);
840 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
842 var_to_reg_int(s1, src, REG_ITMP1);
843 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
844 if (has_ext_instr_set) {
848 M_SLL_IMM(s1, 48, d);
849 M_SRA_IMM( d, 48, d);
851 store_reg_to_var_int(iptr->dst, d);
855 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
857 var_to_reg_int(s1, src->prev, REG_ITMP1);
858 var_to_reg_int(s2, src, REG_ITMP2);
859 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
861 store_reg_to_var_int(iptr->dst, d);
864 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
865 /* val.i = constant */
867 var_to_reg_int(s1, src, REG_ITMP1);
868 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
869 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
870 M_IADD_IMM(s1, iptr->val.i, d);
873 ICONST(REG_ITMP2, iptr->val.i);
874 M_IADD(s1, REG_ITMP2, d);
876 store_reg_to_var_int(iptr->dst, d);
879 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
881 var_to_reg_int(s1, src->prev, REG_ITMP1);
882 var_to_reg_int(s2, src, REG_ITMP2);
883 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
885 store_reg_to_var_int(iptr->dst, d);
888 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
889 /* val.l = constant */
891 var_to_reg_int(s1, src, REG_ITMP1);
892 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
893 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
894 M_LADD_IMM(s1, iptr->val.l, d);
897 LCONST(REG_ITMP2, iptr->val.l);
898 M_LADD(s1, REG_ITMP2, d);
900 store_reg_to_var_int(iptr->dst, d);
903 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
905 var_to_reg_int(s1, src->prev, REG_ITMP1);
906 var_to_reg_int(s2, src, REG_ITMP2);
907 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
909 store_reg_to_var_int(iptr->dst, d);
912 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
913 /* val.i = constant */
915 var_to_reg_int(s1, src, REG_ITMP1);
916 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
917 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
918 M_ISUB_IMM(s1, iptr->val.i, d);
921 ICONST(REG_ITMP2, iptr->val.i);
922 M_ISUB(s1, REG_ITMP2, d);
924 store_reg_to_var_int(iptr->dst, d);
927 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
929 var_to_reg_int(s1, src->prev, REG_ITMP1);
930 var_to_reg_int(s2, src, REG_ITMP2);
931 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
933 store_reg_to_var_int(iptr->dst, d);
936 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
937 /* val.l = constant */
939 var_to_reg_int(s1, src, REG_ITMP1);
940 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
941 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
942 M_LSUB_IMM(s1, iptr->val.l, d);
945 LCONST(REG_ITMP2, iptr->val.l);
946 M_LSUB(s1, REG_ITMP2, d);
948 store_reg_to_var_int(iptr->dst, d);
951 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
953 var_to_reg_int(s1, src->prev, REG_ITMP1);
954 var_to_reg_int(s2, src, REG_ITMP2);
955 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
957 store_reg_to_var_int(iptr->dst, d);
960 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
961 /* val.i = constant */
963 var_to_reg_int(s1, src, REG_ITMP1);
964 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
965 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
966 M_IMUL_IMM(s1, iptr->val.i, d);
969 ICONST(REG_ITMP2, iptr->val.i);
970 M_IMUL(s1, REG_ITMP2, d);
972 store_reg_to_var_int(iptr->dst, d);
975 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
977 var_to_reg_int(s1, src->prev, REG_ITMP1);
978 var_to_reg_int(s2, src, REG_ITMP2);
979 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
981 store_reg_to_var_int(iptr->dst, d);
984 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
985 /* val.l = constant */
987 var_to_reg_int(s1, src, REG_ITMP1);
988 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
989 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
990 M_LMUL_IMM(s1, iptr->val.l, d);
993 LCONST(REG_ITMP2, iptr->val.l);
994 M_LMUL(s1, REG_ITMP2, d);
996 store_reg_to_var_int(iptr->dst, d);
999 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
1000 case ICMD_LDIVPOW2: /* val.i = constant */
1002 var_to_reg_int(s1, src, REG_ITMP1);
1003 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1004 if (iptr->val.i <= 15) {
1005 M_LDA(REG_ITMP2, s1, (1 << iptr->val.i) -1);
1006 M_CMOVGE(s1, s1, REG_ITMP2);
1009 M_SRA_IMM(s1, 63, REG_ITMP2);
1010 M_SRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
1011 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1013 M_SRA_IMM(REG_ITMP2, iptr->val.i, d);
1014 store_reg_to_var_int(iptr->dst, d);
1017 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1019 var_to_reg_int(s1, src->prev, REG_ITMP1);
1020 var_to_reg_int(s2, src, REG_ITMP2);
1021 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1022 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1023 M_SLL(s1, REG_ITMP3, d);
1024 M_IADD(d, REG_ZERO, d);
1025 store_reg_to_var_int(iptr->dst, d);
1028 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1029 /* val.i = constant */
1031 var_to_reg_int(s1, src, REG_ITMP1);
1032 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1033 M_SLL_IMM(s1, iptr->val.i & 0x1f, d);
1034 M_IADD(d, REG_ZERO, d);
1035 store_reg_to_var_int(iptr->dst, d);
1038 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1040 var_to_reg_int(s1, src->prev, REG_ITMP1);
1041 var_to_reg_int(s2, src, REG_ITMP2);
1042 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1043 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1044 M_SRA(s1, REG_ITMP3, d);
1045 store_reg_to_var_int(iptr->dst, d);
1048 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1049 /* val.i = constant */
1051 var_to_reg_int(s1, src, REG_ITMP1);
1052 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1053 M_SRA_IMM(s1, iptr->val.i & 0x1f, d);
1054 store_reg_to_var_int(iptr->dst, d);
1057 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1059 var_to_reg_int(s1, src->prev, REG_ITMP1);
1060 var_to_reg_int(s2, src, REG_ITMP2);
1061 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1062 M_AND_IMM(s2, 0x1f, REG_ITMP2);
1064 M_SRL(d, REG_ITMP2, d);
1065 M_IADD(d, REG_ZERO, d);
1066 store_reg_to_var_int(iptr->dst, d);
1069 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1070 /* val.i = constant */
1072 var_to_reg_int(s1, src, REG_ITMP1);
1073 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1075 M_SRL_IMM(d, iptr->val.i & 0x1f, d);
1076 M_IADD(d, REG_ZERO, d);
1077 store_reg_to_var_int(iptr->dst, d);
1080 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1082 var_to_reg_int(s1, src->prev, REG_ITMP1);
1083 var_to_reg_int(s2, src, REG_ITMP2);
1084 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1086 store_reg_to_var_int(iptr->dst, d);
1089 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1090 /* val.i = constant */
1092 var_to_reg_int(s1, src, REG_ITMP1);
1093 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1094 M_SLL_IMM(s1, iptr->val.i & 0x3f, d);
1095 store_reg_to_var_int(iptr->dst, d);
1098 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1100 var_to_reg_int(s1, src->prev, REG_ITMP1);
1101 var_to_reg_int(s2, src, REG_ITMP2);
1102 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1104 store_reg_to_var_int(iptr->dst, d);
1107 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1108 /* val.i = constant */
1110 var_to_reg_int(s1, src, REG_ITMP1);
1111 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1112 M_SRA_IMM(s1, iptr->val.i & 0x3f, d);
1113 store_reg_to_var_int(iptr->dst, d);
1116 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1118 var_to_reg_int(s1, src->prev, REG_ITMP1);
1119 var_to_reg_int(s2, src, REG_ITMP2);
1120 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1122 store_reg_to_var_int(iptr->dst, d);
1125 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1126 /* val.i = constant */
1128 var_to_reg_int(s1, src, REG_ITMP1);
1129 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1130 M_SRL_IMM(s1, iptr->val.i & 0x3f, d);
1131 store_reg_to_var_int(iptr->dst, d);
1134 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1137 var_to_reg_int(s1, src->prev, REG_ITMP1);
1138 var_to_reg_int(s2, src, REG_ITMP2);
1139 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1141 store_reg_to_var_int(iptr->dst, d);
1144 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1145 /* val.i = constant */
1147 var_to_reg_int(s1, src, REG_ITMP1);
1148 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1149 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1150 M_AND_IMM(s1, iptr->val.i, d);
1152 else if (iptr->val.i == 0xffff) {
1155 else if (iptr->val.i == 0xffffff) {
1156 M_ZAPNOT_IMM(s1, 0x07, d);
1159 ICONST(REG_ITMP2, iptr->val.i);
1160 M_AND(s1, REG_ITMP2, d);
1162 store_reg_to_var_int(iptr->dst, d);
1165 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1166 /* val.i = constant */
1168 var_to_reg_int(s1, src, REG_ITMP1);
1169 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1171 M_MOV(s1, REG_ITMP1);
1174 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1175 M_AND_IMM(s1, iptr->val.i, d);
1177 M_ISUB(REG_ZERO, s1, d);
1178 M_AND_IMM(d, iptr->val.i, d);
1180 else if (iptr->val.i == 0xffff) {
1183 M_ISUB(REG_ZERO, s1, d);
1186 else if (iptr->val.i == 0xffffff) {
1187 M_ZAPNOT_IMM(s1, 0x07, d);
1189 M_ISUB(REG_ZERO, s1, d);
1190 M_ZAPNOT_IMM(d, 0x07, d);
1193 ICONST(REG_ITMP2, iptr->val.i);
1194 M_AND(s1, REG_ITMP2, d);
1196 M_ISUB(REG_ZERO, s1, d);
1197 M_AND(d, REG_ITMP2, d);
1199 M_ISUB(REG_ZERO, d, d);
1200 store_reg_to_var_int(iptr->dst, d);
1203 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1204 /* val.l = constant */
1206 var_to_reg_int(s1, src, REG_ITMP1);
1207 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1208 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1209 M_AND_IMM(s1, iptr->val.l, d);
1211 else if (iptr->val.l == 0xffffL) {
1214 else if (iptr->val.l == 0xffffffL) {
1215 M_ZAPNOT_IMM(s1, 0x07, d);
1217 else if (iptr->val.l == 0xffffffffL) {
1220 else if (iptr->val.l == 0xffffffffffL) {
1221 M_ZAPNOT_IMM(s1, 0x1f, d);
1223 else if (iptr->val.l == 0xffffffffffffL) {
1224 M_ZAPNOT_IMM(s1, 0x3f, d);
1226 else if (iptr->val.l == 0xffffffffffffffL) {
1227 M_ZAPNOT_IMM(s1, 0x7f, d);
1230 LCONST(REG_ITMP2, iptr->val.l);
1231 M_AND(s1, REG_ITMP2, d);
1233 store_reg_to_var_int(iptr->dst, d);
1236 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1237 /* val.l = constant */
1239 var_to_reg_int(s1, src, REG_ITMP1);
1240 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1242 M_MOV(s1, REG_ITMP1);
1245 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1246 M_AND_IMM(s1, iptr->val.l, d);
1248 M_LSUB(REG_ZERO, s1, d);
1249 M_AND_IMM(d, iptr->val.l, d);
1251 else if (iptr->val.l == 0xffffL) {
1254 M_LSUB(REG_ZERO, s1, d);
1257 else if (iptr->val.l == 0xffffffL) {
1258 M_ZAPNOT_IMM(s1, 0x07, d);
1260 M_LSUB(REG_ZERO, s1, d);
1261 M_ZAPNOT_IMM(d, 0x07, d);
1263 else if (iptr->val.l == 0xffffffffL) {
1266 M_LSUB(REG_ZERO, s1, d);
1269 else if (iptr->val.l == 0xffffffffffL) {
1270 M_ZAPNOT_IMM(s1, 0x1f, d);
1272 M_LSUB(REG_ZERO, s1, d);
1273 M_ZAPNOT_IMM(d, 0x1f, d);
1275 else if (iptr->val.l == 0xffffffffffffL) {
1276 M_ZAPNOT_IMM(s1, 0x3f, d);
1278 M_LSUB(REG_ZERO, s1, d);
1279 M_ZAPNOT_IMM(d, 0x3f, d);
1281 else if (iptr->val.l == 0xffffffffffffffL) {
1282 M_ZAPNOT_IMM(s1, 0x7f, d);
1284 M_LSUB(REG_ZERO, s1, d);
1285 M_ZAPNOT_IMM(d, 0x7f, d);
1288 LCONST(REG_ITMP2, iptr->val.l);
1289 M_AND(s1, REG_ITMP2, d);
1291 M_LSUB(REG_ZERO, s1, d);
1292 M_AND(d, REG_ITMP2, d);
1294 M_LSUB(REG_ZERO, d, d);
1295 store_reg_to_var_int(iptr->dst, d);
1298 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1301 var_to_reg_int(s1, src->prev, REG_ITMP1);
1302 var_to_reg_int(s2, src, REG_ITMP2);
1303 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1305 store_reg_to_var_int(iptr->dst, d);
1308 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1309 /* val.i = constant */
1311 var_to_reg_int(s1, src, REG_ITMP1);
1312 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1313 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1314 M_OR_IMM(s1, iptr->val.i, d);
1317 ICONST(REG_ITMP2, iptr->val.i);
1318 M_OR(s1, REG_ITMP2, d);
1320 store_reg_to_var_int(iptr->dst, d);
1323 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1324 /* val.l = constant */
1326 var_to_reg_int(s1, src, REG_ITMP1);
1327 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1328 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1329 M_OR_IMM(s1, iptr->val.l, d);
1332 LCONST(REG_ITMP2, iptr->val.l);
1333 M_OR(s1, REG_ITMP2, d);
1335 store_reg_to_var_int(iptr->dst, d);
1338 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1341 var_to_reg_int(s1, src->prev, REG_ITMP1);
1342 var_to_reg_int(s2, src, REG_ITMP2);
1343 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1345 store_reg_to_var_int(iptr->dst, d);
1348 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1349 /* val.i = constant */
1351 var_to_reg_int(s1, src, REG_ITMP1);
1352 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1353 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1354 M_XOR_IMM(s1, iptr->val.i, d);
1357 ICONST(REG_ITMP2, iptr->val.i);
1358 M_XOR(s1, REG_ITMP2, d);
1360 store_reg_to_var_int(iptr->dst, d);
1363 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1364 /* val.l = constant */
1366 var_to_reg_int(s1, src, REG_ITMP1);
1367 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1368 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1369 M_XOR_IMM(s1, iptr->val.l, d);
1372 LCONST(REG_ITMP2, iptr->val.l);
1373 M_XOR(s1, REG_ITMP2, d);
1375 store_reg_to_var_int(iptr->dst, d);
1379 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1381 var_to_reg_int(s1, src->prev, REG_ITMP1);
1382 var_to_reg_int(s2, src, REG_ITMP2);
1383 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1384 M_CMPLT(s1, s2, REG_ITMP3);
1385 M_CMPLT(s2, s1, REG_ITMP1);
1386 M_LSUB (REG_ITMP1, REG_ITMP3, d);
1387 store_reg_to_var_int(iptr->dst, d);
1391 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1392 /* op1 = variable, val.i = constant */
1394 var = &(rd->locals[iptr->op1][TYPE_INT]);
1395 if (var->flags & INMEMORY) {
1397 M_LLD(s1, REG_SP, 8 * var->regoff);
1401 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1402 M_IADD_IMM(s1, iptr->val.i, s1);
1404 else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1405 M_ISUB_IMM(s1, (-iptr->val.i), s1);
1408 M_LDA (s1, s1, iptr->val.i);
1409 M_IADD(s1, REG_ZERO, s1);
1411 if (var->flags & INMEMORY)
1412 M_LST(s1, REG_SP, 8 * var->regoff);
1416 /* floating operations ************************************************/
1418 case ICMD_FNEG: /* ..., value ==> ..., - value */
1420 var_to_reg_flt(s1, src, REG_FTMP1);
1421 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1423 store_reg_to_var_flt(iptr->dst, d);
1426 case ICMD_DNEG: /* ..., value ==> ..., - value */
1428 var_to_reg_flt(s1, src, REG_FTMP1);
1429 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1431 store_reg_to_var_flt(iptr->dst, d);
1434 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1436 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1437 var_to_reg_flt(s2, src, REG_FTMP2);
1438 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1443 if (d == s1 || d == s2) {
1444 M_FADDS(s1, s2, REG_FTMP3);
1446 M_FMOV(REG_FTMP3, d);
1453 store_reg_to_var_flt(iptr->dst, d);
1456 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1458 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1459 var_to_reg_flt(s2, src, REG_FTMP2);
1460 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1465 if (d == s1 || d == s2) {
1466 M_DADDS(s1, s2, REG_FTMP3);
1468 M_FMOV(REG_FTMP3, d);
1475 store_reg_to_var_flt(iptr->dst, d);
1478 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1480 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1481 var_to_reg_flt(s2, src, REG_FTMP2);
1482 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1487 if (d == s1 || d == s2) {
1488 M_FSUBS(s1, s2, REG_FTMP3);
1490 M_FMOV(REG_FTMP3, d);
1497 store_reg_to_var_flt(iptr->dst, d);
1500 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1502 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1503 var_to_reg_flt(s2, src, REG_FTMP2);
1504 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1509 if (d == s1 || d == s2) {
1510 M_DSUBS(s1, s2, REG_FTMP3);
1512 M_FMOV(REG_FTMP3, d);
1519 store_reg_to_var_flt(iptr->dst, d);
1522 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1524 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1525 var_to_reg_flt(s2, src, REG_FTMP2);
1526 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1531 if (d == s1 || d == s2) {
1532 M_FMULS(s1, s2, REG_FTMP3);
1534 M_FMOV(REG_FTMP3, d);
1541 store_reg_to_var_flt(iptr->dst, d);
1544 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1546 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1547 var_to_reg_flt(s2, src, REG_FTMP2);
1548 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1553 if (d == s1 || d == s2) {
1554 M_DMULS(s1, s2, REG_FTMP3);
1556 M_FMOV(REG_FTMP3, d);
1563 store_reg_to_var_flt(iptr->dst, d);
1566 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1568 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1569 var_to_reg_flt(s2, src, REG_FTMP2);
1570 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1575 if (d == s1 || d == s2) {
1576 M_FDIVS(s1, s2, REG_FTMP3);
1578 M_FMOV(REG_FTMP3, d);
1585 store_reg_to_var_flt(iptr->dst, d);
1588 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1590 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1591 var_to_reg_flt(s2, src, REG_FTMP2);
1592 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1597 if (d == s1 || d == s2) {
1598 M_DDIVS(s1, s2, REG_FTMP3);
1600 M_FMOV(REG_FTMP3, d);
1607 store_reg_to_var_flt(iptr->dst, d);
1610 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1612 var_to_reg_int(s1, src, REG_ITMP1);
1613 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1614 a = dseg_adddouble(cd, 0.0);
1615 M_LST (s1, REG_PV, a);
1616 M_DLD (d, REG_PV, a);
1618 store_reg_to_var_flt(iptr->dst, d);
1621 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1623 var_to_reg_int(s1, src, REG_ITMP1);
1624 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1625 a = dseg_adddouble(cd, 0.0);
1626 M_LST (s1, REG_PV, a);
1627 M_DLD (d, REG_PV, a);
1629 store_reg_to_var_flt(iptr->dst, d);
1632 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1634 var_to_reg_flt(s1, src, REG_FTMP1);
1635 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1636 a = dseg_adddouble(cd, 0.0);
1637 M_CVTDL_C(s1, REG_FTMP2);
1638 M_CVTLI(REG_FTMP2, REG_FTMP3);
1639 M_DST (REG_FTMP3, REG_PV, a);
1640 M_ILD (d, REG_PV, a);
1641 store_reg_to_var_int(iptr->dst, d);
1644 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1646 var_to_reg_flt(s1, src, REG_FTMP1);
1647 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1648 a = dseg_adddouble(cd, 0.0);
1649 M_CVTDL_C(s1, REG_FTMP2);
1650 M_DST (REG_FTMP2, REG_PV, a);
1651 M_LLD (d, REG_PV, a);
1652 store_reg_to_var_int(iptr->dst, d);
1655 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1657 var_to_reg_flt(s1, src, REG_FTMP1);
1658 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1661 store_reg_to_var_flt(iptr->dst, d);
1664 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1666 var_to_reg_flt(s1, src, REG_FTMP1);
1667 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1675 store_reg_to_var_flt(iptr->dst, d);
1678 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1680 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1681 var_to_reg_flt(s2, src, REG_FTMP2);
1682 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1684 M_LSUB_IMM(REG_ZERO, 1, d);
1685 M_FCMPEQ(s1, s2, REG_FTMP3);
1686 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1688 M_FCMPLT(s2, s1, REG_FTMP3);
1689 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1690 M_LADD_IMM(REG_ZERO, 1, d);
1693 M_LSUB_IMM(REG_ZERO, 1, d);
1694 M_FCMPEQS(s1, s2, REG_FTMP3);
1696 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1698 M_FCMPLTS(s2, s1, REG_FTMP3);
1700 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1701 M_LADD_IMM(REG_ZERO, 1, d);
1703 store_reg_to_var_int(iptr->dst, d);
1706 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1708 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1709 var_to_reg_flt(s2, src, REG_FTMP2);
1710 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1712 M_LADD_IMM(REG_ZERO, 1, d);
1713 M_FCMPEQ(s1, s2, REG_FTMP3);
1714 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1716 M_FCMPLT(s1, s2, REG_FTMP3);
1717 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1718 M_LSUB_IMM(REG_ZERO, 1, d);
1721 M_LADD_IMM(REG_ZERO, 1, d);
1722 M_FCMPEQS(s1, s2, REG_FTMP3);
1724 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1726 M_FCMPLTS(s1, s2, REG_FTMP3);
1728 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1729 M_LSUB_IMM(REG_ZERO, 1, d);
1731 store_reg_to_var_int(iptr->dst, d);
1735 /* memory operations **************************************************/
1737 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1739 var_to_reg_int(s1, src, REG_ITMP1);
1740 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1741 gen_nullptr_check(s1);
1742 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1743 store_reg_to_var_int(iptr->dst, d);
1746 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1748 var_to_reg_int(s1, src->prev, REG_ITMP1);
1749 var_to_reg_int(s2, src, REG_ITMP2);
1750 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1751 if (iptr->op1 == 0) {
1752 gen_nullptr_check(s1);
1755 M_SAADDQ(s2, s1, REG_ITMP1);
1756 M_ALD( d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1757 store_reg_to_var_int(iptr->dst, d);
1760 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1762 var_to_reg_int(s1, src->prev, REG_ITMP1);
1763 var_to_reg_int(s2, src, REG_ITMP2);
1764 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1765 if (iptr->op1 == 0) {
1766 gen_nullptr_check(s1);
1769 M_S8ADDQ(s2, s1, REG_ITMP1);
1770 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1771 store_reg_to_var_int(iptr->dst, d);
1774 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1776 var_to_reg_int(s1, src->prev, REG_ITMP1);
1777 var_to_reg_int(s2, src, REG_ITMP2);
1778 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1779 if (iptr->op1 == 0) {
1780 gen_nullptr_check(s1);
1784 M_S4ADDQ(s2, s1, REG_ITMP1);
1785 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1786 store_reg_to_var_int(iptr->dst, d);
1789 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1791 var_to_reg_int(s1, src->prev, REG_ITMP1);
1792 var_to_reg_int(s2, src, REG_ITMP2);
1793 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1794 if (iptr->op1 == 0) {
1795 gen_nullptr_check(s1);
1798 M_S4ADDQ(s2, s1, REG_ITMP1);
1799 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1800 store_reg_to_var_flt(iptr->dst, d);
1803 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1805 var_to_reg_int(s1, src->prev, REG_ITMP1);
1806 var_to_reg_int(s2, src, REG_ITMP2);
1807 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1808 if (iptr->op1 == 0) {
1809 gen_nullptr_check(s1);
1812 M_S8ADDQ(s2, s1, REG_ITMP1);
1813 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1814 store_reg_to_var_flt(iptr->dst, d);
1817 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1819 var_to_reg_int(s1, src->prev, REG_ITMP1);
1820 var_to_reg_int(s2, src, REG_ITMP2);
1821 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1822 if (iptr->op1 == 0) {
1823 gen_nullptr_check(s1);
1826 if (has_ext_instr_set) {
1827 M_LADD(s2, s1, REG_ITMP1);
1828 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1829 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1832 M_LADD (s2, s1, REG_ITMP1);
1833 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1834 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1835 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1836 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
1838 store_reg_to_var_int(iptr->dst, d);
1841 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1843 var_to_reg_int(s1, src->prev, REG_ITMP1);
1844 var_to_reg_int(s2, src, REG_ITMP2);
1845 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1846 if (iptr->op1 == 0) {
1847 gen_nullptr_check(s1);
1850 if (has_ext_instr_set) {
1851 M_LADD(s2, s1, REG_ITMP1);
1852 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1853 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1857 M_LADD(s2, s1, REG_ITMP1);
1858 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1859 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1860 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1861 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1862 M_SRA_IMM(d, 48, d);
1864 store_reg_to_var_int(iptr->dst, d);
1867 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1869 var_to_reg_int(s1, src->prev, REG_ITMP1);
1870 var_to_reg_int(s2, src, REG_ITMP2);
1871 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1872 if (iptr->op1 == 0) {
1873 gen_nullptr_check(s1);
1876 if (has_ext_instr_set) {
1877 M_LADD (s2, s1, REG_ITMP1);
1878 M_BLDU (d, REG_ITMP1, OFFSET (java_bytearray, data[0]));
1882 M_LADD(s2, s1, REG_ITMP1);
1883 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1884 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
1885 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1886 M_SRA_IMM(d, 56, d);
1888 store_reg_to_var_int(iptr->dst, d);
1892 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1894 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1895 var_to_reg_int(s2, src->prev, REG_ITMP2);
1896 if (iptr->op1 == 0) {
1897 gen_nullptr_check(s1);
1900 var_to_reg_int(s3, src, REG_ITMP3);
1901 M_SAADDQ(s2, s1, REG_ITMP1);
1902 M_AST (s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1905 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1907 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1908 var_to_reg_int(s2, src->prev, REG_ITMP2);
1909 if (iptr->op1 == 0) {
1910 gen_nullptr_check(s1);
1913 var_to_reg_int(s3, src, REG_ITMP3);
1914 M_S8ADDQ(s2, s1, REG_ITMP1);
1915 M_LST (s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1918 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1920 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1921 var_to_reg_int(s2, src->prev, REG_ITMP2);
1922 if (iptr->op1 == 0) {
1923 gen_nullptr_check(s1);
1927 var_to_reg_int(s3, src, REG_ITMP3);
1928 M_S4ADDQ(s2, s1, REG_ITMP1);
1929 M_IST (s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1932 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1934 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1935 var_to_reg_int(s2, src->prev, REG_ITMP2);
1936 if (iptr->op1 == 0) {
1937 gen_nullptr_check(s1);
1940 var_to_reg_flt(s3, src, REG_FTMP3);
1941 M_S4ADDQ(s2, s1, REG_ITMP1);
1942 M_FST (s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1945 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1947 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1948 var_to_reg_int(s2, src->prev, REG_ITMP2);
1949 if (iptr->op1 == 0) {
1950 gen_nullptr_check(s1);
1953 var_to_reg_flt(s3, src, REG_FTMP3);
1954 M_S8ADDQ(s2, s1, REG_ITMP1);
1955 M_DST (s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1958 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1960 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1961 var_to_reg_int(s2, src->prev, REG_ITMP2);
1962 if (iptr->op1 == 0) {
1963 gen_nullptr_check(s1);
1966 var_to_reg_int(s3, src, REG_ITMP3);
1967 if (has_ext_instr_set) {
1968 M_LADD(s2, s1, REG_ITMP1);
1969 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1970 M_SST (s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1973 M_LADD (s2, s1, REG_ITMP1);
1974 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1975 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1976 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1977 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1978 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1979 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
1980 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1984 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1986 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1987 var_to_reg_int(s2, src->prev, REG_ITMP2);
1988 if (iptr->op1 == 0) {
1989 gen_nullptr_check(s1);
1992 var_to_reg_int(s3, src, REG_ITMP3);
1993 if (has_ext_instr_set) {
1994 M_LADD(s2, s1, REG_ITMP1);
1995 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1996 M_SST (s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1999 M_LADD (s2, s1, REG_ITMP1);
2000 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2001 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2002 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2003 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
2004 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2005 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2006 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2010 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
2012 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2013 var_to_reg_int(s2, src->prev, REG_ITMP2);
2014 if (iptr->op1 == 0) {
2015 gen_nullptr_check(s1);
2018 var_to_reg_int(s3, src, REG_ITMP3);
2019 if (has_ext_instr_set) {
2020 M_LADD(s2, s1, REG_ITMP1);
2021 M_BST (s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2024 M_LADD (s2, s1, REG_ITMP1);
2025 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2026 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2027 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
2028 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2029 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2030 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2035 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
2037 var_to_reg_int(s1, src->prev, REG_ITMP1);
2038 var_to_reg_int(s2, src, REG_ITMP2);
2039 if (iptr->op1 == 0) {
2040 gen_nullptr_check(s1);
2043 M_S4ADDQ(s2, s1, REG_ITMP1);
2044 M_IST(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
2047 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
2049 var_to_reg_int(s1, src->prev, REG_ITMP1);
2050 var_to_reg_int(s2, src, REG_ITMP2);
2051 if (iptr->op1 == 0) {
2052 gen_nullptr_check(s1);
2055 M_S8ADDQ(s2, s1, REG_ITMP1);
2056 M_LST(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
2059 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
2061 var_to_reg_int(s1, src->prev, REG_ITMP1);
2062 var_to_reg_int(s2, src, REG_ITMP2);
2063 if (iptr->op1 == 0) {
2064 gen_nullptr_check(s1);
2067 M_SAADDQ(s2, s1, REG_ITMP1);
2068 M_AST(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
2071 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
2073 var_to_reg_int(s1, src->prev, REG_ITMP1);
2074 var_to_reg_int(s2, src, REG_ITMP2);
2075 if (iptr->op1 == 0) {
2076 gen_nullptr_check(s1);
2079 if (has_ext_instr_set) {
2080 M_LADD(s2, s1, REG_ITMP1);
2081 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2084 M_LADD(s2, s1, REG_ITMP1);
2085 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2086 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2087 M_INSBL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2088 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2089 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2090 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2094 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
2096 var_to_reg_int(s1, src->prev, REG_ITMP1);
2097 var_to_reg_int(s2, src, REG_ITMP2);
2098 if (iptr->op1 == 0) {
2099 gen_nullptr_check(s1);
2102 if (has_ext_instr_set) {
2103 M_LADD(s2, s1, REG_ITMP1);
2104 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2105 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
2108 M_LADD(s2, s1, REG_ITMP1);
2109 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2110 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2111 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2112 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2113 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2114 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2115 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2119 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
2121 var_to_reg_int(s1, src->prev, REG_ITMP1);
2122 var_to_reg_int(s2, src, REG_ITMP2);
2123 if (iptr->op1 == 0) {
2124 gen_nullptr_check(s1);
2127 if (has_ext_instr_set) {
2128 M_LADD(s2, s1, REG_ITMP1);
2129 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2130 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2133 M_LADD(s2, s1, REG_ITMP1);
2134 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2135 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2136 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2137 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2138 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2139 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2140 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2145 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2146 /* op1 = type, val.a = field address */
2148 /* If the static fields' class is not yet initialized, we do it */
2149 /* now. The call code is generated later. */
2150 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
2151 codegen_addclinitref(cd, mcodeptr, ((fieldinfo *) iptr->val.a)->class);
2153 /* This is just for debugging purposes. Is very difficult to */
2154 /* read patched code. Here we patch the following 2 nop's */
2155 /* so that the real code keeps untouched. */
2156 if (showdisassemble) {
2161 a = dseg_addaddress(cd, &(((fieldinfo *)(iptr->val.a))->value));
2162 M_ALD(REG_ITMP1, REG_PV, a);
2163 switch (iptr->op1) {
2165 var_to_reg_int(s2, src, REG_ITMP2);
2166 M_IST(s2, REG_ITMP1, 0);
2169 var_to_reg_int(s2, src, REG_ITMP2);
2170 M_LST(s2, REG_ITMP1, 0);
2173 var_to_reg_int(s2, src, REG_ITMP2);
2174 M_AST(s2, REG_ITMP1, 0);
2177 var_to_reg_flt(s2, src, REG_FTMP2);
2178 M_FST(s2, REG_ITMP1, 0);
2181 var_to_reg_flt(s2, src, REG_FTMP2);
2182 M_DST(s2, REG_ITMP1, 0);
2184 default: panic ("internal error");
2188 case ICMD_GETSTATIC: /* ... ==> ..., value */
2189 /* op1 = type, val.a = field address */
2191 /* if class isn't yet initialized, do it */
2192 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
2193 codegen_addclinitref(cd, mcodeptr, ((fieldinfo *) iptr->val.a)->class);
2195 /* This is just for debugging purposes. Is very difficult to */
2196 /* read patched code. Here we patch the following 2 nop's */
2197 /* so that the real code keeps untouched. */
2198 if (showdisassemble) {
2203 a = dseg_addaddress(cd, &(((fieldinfo *) iptr->val.a)->value));
2204 M_ALD(REG_ITMP1, REG_PV, a);
2205 switch (iptr->op1) {
2207 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2208 M_ILD(d, REG_ITMP1, 0);
2209 store_reg_to_var_int(iptr->dst, d);
2212 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2213 M_LLD(d, REG_ITMP1, 0);
2214 store_reg_to_var_int(iptr->dst, d);
2217 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2218 M_ALD(d, REG_ITMP1, 0);
2219 store_reg_to_var_int(iptr->dst, d);
2222 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2223 M_FLD(d, REG_ITMP1, 0);
2224 store_reg_to_var_flt(iptr->dst, d);
2227 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2228 M_DLD(d, REG_ITMP1, 0);
2229 store_reg_to_var_flt(iptr->dst, d);
2231 default: panic ("internal error");
2236 case ICMD_PUTFIELD: /* ..., value ==> ... */
2237 /* op1 = type, val.i = field offset */
2239 a = ((fieldinfo *) iptr->val.a)->offset;
2240 switch (iptr->op1) {
2242 var_to_reg_int(s1, src->prev, REG_ITMP1);
2243 var_to_reg_int(s2, src, REG_ITMP2);
2244 gen_nullptr_check(s1);
2248 var_to_reg_int(s1, src->prev, REG_ITMP1);
2249 var_to_reg_int(s2, src, REG_ITMP2);
2250 gen_nullptr_check(s1);
2254 var_to_reg_int(s1, src->prev, REG_ITMP1);
2255 var_to_reg_int(s2, src, REG_ITMP2);
2256 gen_nullptr_check(s1);
2260 var_to_reg_int(s1, src->prev, REG_ITMP1);
2261 var_to_reg_flt(s2, src, REG_FTMP2);
2262 gen_nullptr_check(s1);
2266 var_to_reg_int(s1, src->prev, REG_ITMP1);
2267 var_to_reg_flt(s2, src, REG_FTMP2);
2268 gen_nullptr_check(s1);
2271 default: panic ("internal error");
2275 case ICMD_GETFIELD: /* ... ==> ..., value */
2276 /* op1 = type, val.i = field offset */
2278 a = ((fieldinfo *)(iptr->val.a))->offset;
2279 switch (iptr->op1) {
2281 var_to_reg_int(s1, src, REG_ITMP1);
2282 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2283 gen_nullptr_check(s1);
2285 store_reg_to_var_int(iptr->dst, d);
2288 var_to_reg_int(s1, src, REG_ITMP1);
2289 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2290 gen_nullptr_check(s1);
2292 store_reg_to_var_int(iptr->dst, d);
2295 var_to_reg_int(s1, src, REG_ITMP1);
2296 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2297 gen_nullptr_check(s1);
2299 store_reg_to_var_int(iptr->dst, d);
2302 var_to_reg_int(s1, src, REG_ITMP1);
2303 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2304 gen_nullptr_check(s1);
2306 store_reg_to_var_flt(iptr->dst, d);
2309 var_to_reg_int(s1, src, REG_ITMP1);
2310 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2311 gen_nullptr_check(s1);
2313 store_reg_to_var_flt(iptr->dst, d);
2315 default: panic ("internal error");
2320 /* branch operations **************************************************/
2322 #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}}
2324 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2326 var_to_reg_int(s1, src, REG_ITMP1);
2327 M_INTMOVE(s1, REG_ITMP1_XPTR);
2328 a = dseg_addaddress(cd, asm_handle_exception);
2329 M_ALD(REG_ITMP2, REG_PV, a);
2330 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2331 M_NOP; /* nop ensures that XPC is less than the end */
2332 /* of basic block */
2336 case ICMD_GOTO: /* ... ==> ... */
2337 /* op1 = target JavaVM pc */
2339 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2343 case ICMD_JSR: /* ... ==> ... */
2344 /* op1 = target JavaVM pc */
2346 M_BSR(REG_ITMP1, 0);
2347 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2350 case ICMD_RET: /* ... ==> ... */
2351 /* op1 = local variable */
2353 var = &(rd->locals[iptr->op1][TYPE_ADR]);
2354 if (var->flags & INMEMORY) {
2355 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2356 M_RET(REG_ZERO, REG_ITMP1);
2359 M_RET(REG_ZERO, var->regoff);
2363 case ICMD_IFNULL: /* ..., value ==> ... */
2364 /* op1 = target JavaVM pc */
2366 var_to_reg_int(s1, src, REG_ITMP1);
2368 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2371 case ICMD_IFNONNULL: /* ..., value ==> ... */
2372 /* op1 = target JavaVM pc */
2374 var_to_reg_int(s1, src, REG_ITMP1);
2376 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2379 case ICMD_IFEQ: /* ..., value ==> ... */
2380 /* op1 = target JavaVM pc, val.i = constant */
2382 var_to_reg_int(s1, src, REG_ITMP1);
2383 if (iptr->val.i == 0) {
2387 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2388 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2391 ICONST(REG_ITMP2, iptr->val.i);
2392 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2394 M_BNEZ(REG_ITMP1, 0);
2396 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2399 case ICMD_IFLT: /* ..., value ==> ... */
2400 /* op1 = target JavaVM pc, val.i = constant */
2402 var_to_reg_int(s1, src, REG_ITMP1);
2403 if (iptr->val.i == 0) {
2407 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2408 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2411 ICONST(REG_ITMP2, iptr->val.i);
2412 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2414 M_BNEZ(REG_ITMP1, 0);
2416 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2419 case ICMD_IFLE: /* ..., value ==> ... */
2420 /* op1 = target JavaVM pc, val.i = constant */
2422 var_to_reg_int(s1, src, REG_ITMP1);
2423 if (iptr->val.i == 0) {
2427 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2428 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2431 ICONST(REG_ITMP2, iptr->val.i);
2432 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2434 M_BNEZ(REG_ITMP1, 0);
2436 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2439 case ICMD_IFNE: /* ..., value ==> ... */
2440 /* op1 = target JavaVM pc, val.i = constant */
2442 var_to_reg_int(s1, src, REG_ITMP1);
2443 if (iptr->val.i == 0) {
2447 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2448 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2451 ICONST(REG_ITMP2, iptr->val.i);
2452 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2454 M_BEQZ(REG_ITMP1, 0);
2456 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2459 case ICMD_IFGT: /* ..., value ==> ... */
2460 /* op1 = target JavaVM pc, val.i = constant */
2462 var_to_reg_int(s1, src, REG_ITMP1);
2463 if (iptr->val.i == 0) {
2467 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2468 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2471 ICONST(REG_ITMP2, iptr->val.i);
2472 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2474 M_BEQZ(REG_ITMP1, 0);
2476 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2479 case ICMD_IFGE: /* ..., value ==> ... */
2480 /* op1 = target JavaVM pc, val.i = constant */
2482 var_to_reg_int(s1, src, REG_ITMP1);
2483 if (iptr->val.i == 0) {
2487 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2488 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2491 ICONST(REG_ITMP2, iptr->val.i);
2492 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2494 M_BEQZ(REG_ITMP1, 0);
2496 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2499 case ICMD_IF_LEQ: /* ..., value ==> ... */
2500 /* op1 = target JavaVM pc, val.l = constant */
2502 var_to_reg_int(s1, src, REG_ITMP1);
2503 if (iptr->val.l == 0) {
2507 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2508 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2511 LCONST(REG_ITMP2, iptr->val.l);
2512 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2514 M_BNEZ(REG_ITMP1, 0);
2516 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2519 case ICMD_IF_LLT: /* ..., value ==> ... */
2520 /* op1 = target JavaVM pc, val.l = constant */
2522 var_to_reg_int(s1, src, REG_ITMP1);
2523 if (iptr->val.l == 0) {
2527 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2528 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2531 LCONST(REG_ITMP2, iptr->val.l);
2532 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2534 M_BNEZ(REG_ITMP1, 0);
2536 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2539 case ICMD_IF_LLE: /* ..., value ==> ... */
2540 /* op1 = target JavaVM pc, val.l = constant */
2542 var_to_reg_int(s1, src, REG_ITMP1);
2543 if (iptr->val.l == 0) {
2547 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2548 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2551 LCONST(REG_ITMP2, iptr->val.l);
2552 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2554 M_BNEZ(REG_ITMP1, 0);
2556 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2559 case ICMD_IF_LNE: /* ..., value ==> ... */
2560 /* op1 = target JavaVM pc, val.l = constant */
2562 var_to_reg_int(s1, src, REG_ITMP1);
2563 if (iptr->val.l == 0) {
2567 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2568 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2571 LCONST(REG_ITMP2, iptr->val.l);
2572 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2574 M_BEQZ(REG_ITMP1, 0);
2576 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2579 case ICMD_IF_LGT: /* ..., value ==> ... */
2580 /* op1 = target JavaVM pc, val.l = constant */
2582 var_to_reg_int(s1, src, REG_ITMP1);
2583 if (iptr->val.l == 0) {
2587 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2588 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2591 LCONST(REG_ITMP2, iptr->val.l);
2592 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2594 M_BEQZ(REG_ITMP1, 0);
2596 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2599 case ICMD_IF_LGE: /* ..., value ==> ... */
2600 /* op1 = target JavaVM pc, val.l = constant */
2602 var_to_reg_int(s1, src, REG_ITMP1);
2603 if (iptr->val.l == 0) {
2607 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2608 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2611 LCONST(REG_ITMP2, iptr->val.l);
2612 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2614 M_BEQZ(REG_ITMP1, 0);
2616 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2619 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2620 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2621 case ICMD_IF_ACMPEQ:
2623 var_to_reg_int(s1, src->prev, REG_ITMP1);
2624 var_to_reg_int(s2, src, REG_ITMP2);
2625 M_CMPEQ(s1, s2, REG_ITMP1);
2626 M_BNEZ(REG_ITMP1, 0);
2627 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2630 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2631 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2632 case ICMD_IF_ACMPNE:
2634 var_to_reg_int(s1, src->prev, REG_ITMP1);
2635 var_to_reg_int(s2, src, REG_ITMP2);
2636 M_CMPEQ(s1, s2, REG_ITMP1);
2637 M_BEQZ(REG_ITMP1, 0);
2638 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2641 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2642 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2644 var_to_reg_int(s1, src->prev, REG_ITMP1);
2645 var_to_reg_int(s2, src, REG_ITMP2);
2646 M_CMPLT(s1, s2, REG_ITMP1);
2647 M_BNEZ(REG_ITMP1, 0);
2648 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2651 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2652 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2654 var_to_reg_int(s1, src->prev, REG_ITMP1);
2655 var_to_reg_int(s2, src, REG_ITMP2);
2656 M_CMPLE(s1, s2, REG_ITMP1);
2657 M_BEQZ(REG_ITMP1, 0);
2658 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2661 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2662 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2664 var_to_reg_int(s1, src->prev, REG_ITMP1);
2665 var_to_reg_int(s2, src, REG_ITMP2);
2666 M_CMPLE(s1, s2, REG_ITMP1);
2667 M_BNEZ(REG_ITMP1, 0);
2668 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2671 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2672 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2674 var_to_reg_int(s1, src->prev, REG_ITMP1);
2675 var_to_reg_int(s2, src, REG_ITMP2);
2676 M_CMPLT(s1, s2, REG_ITMP1);
2677 M_BEQZ(REG_ITMP1, 0);
2678 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2681 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2683 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2686 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2687 /* val.i = constant */
2689 var_to_reg_int(s1, src, REG_ITMP1);
2690 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2692 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2693 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2694 M_CMPEQ(s1, REG_ZERO, d);
2695 store_reg_to_var_int(iptr->dst, d);
2698 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2699 M_CMPEQ(s1, REG_ZERO, d);
2701 store_reg_to_var_int(iptr->dst, d);
2705 M_MOV(s1, REG_ITMP1);
2708 ICONST(d, iptr[1].val.i);
2710 if ((s3 >= 0) && (s3 <= 255)) {
2711 M_CMOVEQ_IMM(s1, s3, d);
2714 ICONST(REG_ITMP2, s3);
2715 M_CMOVEQ(s1, REG_ITMP2, d);
2717 store_reg_to_var_int(iptr->dst, d);
2720 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2721 /* val.i = constant */
2723 var_to_reg_int(s1, src, REG_ITMP1);
2724 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2726 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2727 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2728 M_CMPEQ(s1, REG_ZERO, d);
2729 store_reg_to_var_int(iptr->dst, d);
2732 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2733 M_CMPEQ(s1, REG_ZERO, d);
2735 store_reg_to_var_int(iptr->dst, d);
2739 M_MOV(s1, REG_ITMP1);
2742 ICONST(d, iptr[1].val.i);
2744 if ((s3 >= 0) && (s3 <= 255)) {
2745 M_CMOVNE_IMM(s1, s3, d);
2748 ICONST(REG_ITMP2, s3);
2749 M_CMOVNE(s1, REG_ITMP2, d);
2751 store_reg_to_var_int(iptr->dst, d);
2754 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2755 /* val.i = constant */
2757 var_to_reg_int(s1, src, REG_ITMP1);
2758 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2760 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2761 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2762 M_CMPLT(s1, REG_ZERO, d);
2763 store_reg_to_var_int(iptr->dst, d);
2766 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2767 M_CMPLE(REG_ZERO, s1, d);
2768 store_reg_to_var_int(iptr->dst, d);
2772 M_MOV(s1, REG_ITMP1);
2775 ICONST(d, iptr[1].val.i);
2777 if ((s3 >= 0) && (s3 <= 255)) {
2778 M_CMOVLT_IMM(s1, s3, d);
2781 ICONST(REG_ITMP2, s3);
2782 M_CMOVLT(s1, REG_ITMP2, d);
2784 store_reg_to_var_int(iptr->dst, d);
2787 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2788 /* val.i = constant */
2790 var_to_reg_int(s1, src, REG_ITMP1);
2791 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2793 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2794 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2795 M_CMPLE(REG_ZERO, s1, d);
2796 store_reg_to_var_int(iptr->dst, d);
2799 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2800 M_CMPLT(s1, REG_ZERO, d);
2801 store_reg_to_var_int(iptr->dst, d);
2805 M_MOV(s1, REG_ITMP1);
2808 ICONST(d, iptr[1].val.i);
2810 if ((s3 >= 0) && (s3 <= 255)) {
2811 M_CMOVGE_IMM(s1, s3, d);
2814 ICONST(REG_ITMP2, s3);
2815 M_CMOVGE(s1, REG_ITMP2, d);
2817 store_reg_to_var_int(iptr->dst, d);
2820 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2821 /* val.i = constant */
2823 var_to_reg_int(s1, src, REG_ITMP1);
2824 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2826 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2827 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2828 M_CMPLT(REG_ZERO, s1, d);
2829 store_reg_to_var_int(iptr->dst, d);
2832 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2833 M_CMPLE(s1, REG_ZERO, d);
2834 store_reg_to_var_int(iptr->dst, d);
2838 M_MOV(s1, REG_ITMP1);
2841 ICONST(d, iptr[1].val.i);
2843 if ((s3 >= 0) && (s3 <= 255)) {
2844 M_CMOVGT_IMM(s1, s3, d);
2847 ICONST(REG_ITMP2, s3);
2848 M_CMOVGT(s1, REG_ITMP2, d);
2850 store_reg_to_var_int(iptr->dst, d);
2853 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2854 /* val.i = constant */
2856 var_to_reg_int(s1, src, REG_ITMP1);
2857 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2859 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2860 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2861 M_CMPLE(s1, REG_ZERO, d);
2862 store_reg_to_var_int(iptr->dst, d);
2865 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2866 M_CMPLT(REG_ZERO, s1, d);
2867 store_reg_to_var_int(iptr->dst, d);
2871 M_MOV(s1, REG_ITMP1);
2874 ICONST(d, iptr[1].val.i);
2876 if ((s3 >= 0) && (s3 <= 255)) {
2877 M_CMOVLE_IMM(s1, s3, d);
2880 ICONST(REG_ITMP2, s3);
2881 M_CMOVLE(s1, REG_ITMP2, d);
2883 store_reg_to_var_int(iptr->dst, d);
2887 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2891 var_to_reg_int(s1, src, REG_RESULT);
2892 M_INTMOVE(s1, REG_RESULT);
2894 #if defined(USE_THREADS)
2895 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2897 a = dseg_addaddress(cd, (void *) (builtin_monitorexit));
2898 M_ALD(REG_PV, REG_PV, a);
2899 M_ALD(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
2900 M_LST(REG_RESULT, REG_SP, rd->maxmemuse * 8);
2901 M_JSR(REG_RA, REG_PV);
2902 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
2903 M_LDA(REG_PV, REG_RA, disp);
2904 M_LLD(REG_RESULT, REG_SP, rd->maxmemuse * 8);
2908 goto nowperformreturn;
2910 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2913 var_to_reg_flt(s1, src, REG_FRESULT);
2914 M_FLTMOVE(s1, REG_FRESULT);
2916 #if defined(USE_THREADS)
2917 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2919 a = dseg_addaddress(cd, (void *) (builtin_monitorexit));
2920 M_ALD(REG_PV, REG_PV, a);
2921 M_ALD(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
2922 M_DST(REG_FRESULT, REG_SP, rd->maxmemuse * 8);
2923 M_JSR(REG_RA, REG_PV);
2924 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
2925 M_LDA(REG_PV, REG_RA, disp);
2926 M_DLD(REG_FRESULT, REG_SP, rd->maxmemuse * 8);
2930 goto nowperformreturn;
2932 case ICMD_RETURN: /* ... ==> ... */
2934 #if defined(USE_THREADS)
2935 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2937 a = dseg_addaddress(cd, (void *) (builtin_monitorexit));
2938 M_ALD(REG_PV, REG_PV, a);
2939 M_ALD(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
2940 M_JSR(REG_RA, REG_PV);
2941 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
2942 M_LDA(REG_PV, REG_RA, disp);
2950 p = parentargs_base;
2952 /* restore return address */
2954 if (!m->isleafmethod) {
2955 p--; M_LLD(REG_RA, REG_SP, p * 8);
2958 /* restore saved registers */
2960 for (i = rd->savintregcnt - 1; i >= rd->maxsavintreguse; i--) {
2961 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2963 for (i = rd->savfltregcnt - 1; i >= rd->maxsavfltreguse; i--) {
2964 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2967 /* deallocate stack */
2969 if (parentargs_base) {
2970 M_LDA(REG_SP, REG_SP, parentargs_base * 8);
2973 /* call trace function */
2976 M_LDA(REG_SP, REG_SP, -3 * 8);
2977 M_AST(REG_RA, REG_SP, 0 * 8);
2978 M_LST(REG_RESULT, REG_SP, 1 * 8);
2979 M_DST(REG_FRESULT, REG_SP, 2 * 8);
2980 a = dseg_addaddress(cd, m);
2981 M_ALD(rd->argintregs[0], REG_PV, a);
2982 M_MOV(REG_RESULT, rd->argintregs[1]);
2983 M_FLTMOVE(REG_FRESULT, rd->argfltregs[2]);
2984 M_FLTMOVE(REG_FRESULT, rd->argfltregs[3]);
2985 a = dseg_addaddress(cd, (void *) builtin_displaymethodstop);
2986 M_ALD(REG_PV, REG_PV, a);
2987 M_JSR(REG_RA, REG_PV);
2988 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
2989 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
2991 s4 ml = -s1, mh = 0;
2992 while (ml < -32768) { ml += 65536; mh--; }
2993 M_LDA(REG_PV, REG_RA, ml);
2994 M_LDAH(REG_PV, REG_PV, mh);
2996 M_DLD(REG_FRESULT, REG_SP, 2 * 8);
2997 M_LLD(REG_RESULT, REG_SP, 1 * 8);
2998 M_ALD(REG_RA, REG_SP, 0 * 8);
2999 M_LDA(REG_SP, REG_SP, 3 * 8);
3002 M_RET(REG_ZERO, REG_RA);
3008 case ICMD_TABLESWITCH: /* ..., index ==> ... */
3013 tptr = (void **) iptr->target;
3015 s4ptr = iptr->val.a;
3016 l = s4ptr[1]; /* low */
3017 i = s4ptr[2]; /* high */
3019 var_to_reg_int(s1, src, REG_ITMP1);
3021 {M_INTMOVE(s1, REG_ITMP1);}
3022 else if (l <= 32768) {
3023 M_LDA(REG_ITMP1, s1, -l);
3026 ICONST(REG_ITMP2, l);
3027 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
3034 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
3036 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
3037 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3039 M_BEQZ(REG_ITMP2, 0);
3042 /* codegen_addreference(cd, BlockPtrOfPC(s4ptr[0]), mcodeptr); */
3043 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3045 /* build jump table top down and use address of lowest entry */
3047 /* s4ptr += 3 + i; */
3051 /* dseg_addtarget(cd, BlockPtrOfPC(*--s4ptr)); */
3052 dseg_addtarget(cd, (basicblock *) tptr[0]);
3057 /* length of dataseg after last dseg_addtarget is used by load */
3059 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
3060 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
3061 M_JMP(REG_ZERO, REG_ITMP2);
3066 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3068 s4 i, l, val, *s4ptr;
3071 tptr = (void **) iptr->target;
3073 s4ptr = iptr->val.a;
3074 l = s4ptr[0]; /* default */
3075 i = s4ptr[1]; /* count */
3077 MCODECHECK((i<<2)+8);
3078 var_to_reg_int(s1, src, REG_ITMP1);
3084 if ((val >= 0) && (val <= 255)) {
3085 M_CMPEQ_IMM(s1, val, REG_ITMP2);
3088 if ((val >= -32768) && (val <= 32767)) {
3089 M_LDA(REG_ITMP2, REG_ZERO, val);
3092 a = dseg_adds4(cd, val);
3093 M_ILD(REG_ITMP2, REG_PV, a);
3095 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
3097 M_BNEZ(REG_ITMP2, 0);
3098 /* codegen_addreference(cd, BlockPtrOfPC(s4ptr[1]), mcodeptr); */
3099 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3103 /* codegen_addreference(cd, BlockPtrOfPC(l), mcodeptr); */
3105 tptr = (void **) iptr->target;
3106 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3113 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
3114 /* op1 = return type, val.a = function pointer*/
3118 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
3119 /* op1 = return type, val.a = function pointer*/
3123 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
3124 /* op1 = return type, val.a = function pointer*/
3128 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3129 /* op1 = arg count, val.a = method pointer */
3131 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3132 /* op1 = arg count, val.a = method pointer */
3134 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3135 /* op1 = arg count, val.a = method pointer */
3137 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
3138 /* op1 = arg count, val.a = method pointer */
3145 MCODECHECK((s3 << 1) + 64);
3147 /* copy arguments to registers or stack location */
3149 for (; --s3 >= 0; src = src->prev) {
3150 if (src->varkind == ARGVAR)
3152 if (IS_INT_LNG_TYPE(src->type)) {
3153 if (s3 < INT_ARG_CNT) {
3154 s1 = rd->argintregs[s3];
3155 var_to_reg_int(d, src, s1);
3159 var_to_reg_int(d, src, REG_ITMP1);
3160 M_LST(d, REG_SP, 8 * (s3 - INT_ARG_CNT));
3164 if (s3 < FLT_ARG_CNT) {
3165 s1 = rd->argfltregs[s3];
3166 var_to_reg_flt(d, src, s1);
3170 var_to_reg_flt(d, src, REG_FTMP1);
3171 M_DST(d, REG_SP, 8 * (s3 - FLT_ARG_CNT));
3177 switch (iptr->opc) {
3181 a = dseg_addaddress(cd, (void *) lm);
3184 M_ALD(REG_PV, REG_PV, a); /* Pointer to built-in-function */
3187 case ICMD_INVOKESTATIC:
3188 case ICMD_INVOKESPECIAL:
3189 a = dseg_addaddress(cd, lm->stubroutine);
3192 M_ALD(REG_PV, REG_PV, a); /* method pointer in r27 */
3195 case ICMD_INVOKEVIRTUAL:
3198 gen_nullptr_check(rd->argintregs[0]);
3199 M_ALD(REG_METHODPTR, rd->argintregs[0],
3200 OFFSET(java_objectheader, vftbl));
3201 M_ALD(REG_PV, REG_METHODPTR, OFFSET(vftbl_t, table[0]) +
3202 sizeof(methodptr) * lm->vftblindex);
3205 case ICMD_INVOKEINTERFACE:
3208 gen_nullptr_check(rd->argintregs[0]);
3209 M_ALD(REG_METHODPTR, rd->argintregs[0],
3210 OFFSET(java_objectheader, vftbl));
3211 M_ALD(REG_METHODPTR, REG_METHODPTR,
3212 OFFSET(vftbl_t, interfacetable[0]) -
3213 sizeof(methodptr*) * lm->class->index);
3214 M_ALD(REG_PV, REG_METHODPTR,
3215 sizeof(methodptr) * (lm - lm->class->methods));
3219 M_JSR(REG_RA, REG_PV);
3223 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3224 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3226 s4 ml = -s1, mh = 0;
3227 while (ml < -32768) { ml += 65536; mh--; }
3228 M_LDA(REG_PV, REG_RA, ml);
3229 M_LDAH(REG_PV, REG_PV, mh);
3232 /* d contains return type */
3234 if (d != TYPE_VOID) {
3235 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3236 s1 = reg_of_var(rd, iptr->dst, REG_RESULT);
3237 M_INTMOVE(REG_RESULT, s1);
3238 store_reg_to_var_int(iptr->dst, s1);
3241 s1 = reg_of_var(rd, iptr->dst, REG_FRESULT);
3242 M_FLTMOVE(REG_FRESULT, s1);
3243 store_reg_to_var_flt(iptr->dst, s1);
3250 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3252 /* op1: 0 == array, 1 == class */
3253 /* val.a: (classinfo*) superclass */
3255 /* superclass is an interface:
3257 * return (sub != NULL) &&
3258 * (sub->vftbl->interfacetablelength > super->index) &&
3259 * (sub->vftbl->interfacetable[-super->index] != NULL);
3261 * superclass is a class:
3263 * return ((sub != NULL) && (0
3264 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3265 * super->vftbl->diffvall));
3269 classinfo *super = (classinfo*) iptr->val.a;
3271 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3272 codegen_threadcritrestart(cd, (u1 *) mcodeptr - cd->mcodebase);
3274 var_to_reg_int(s1, src, REG_ITMP1);
3275 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
3277 M_MOV(s1, REG_ITMP1);
3281 if (iptr->op1) { /* class/interface */
3282 if (super->flags & ACC_INTERFACE) { /* interface */
3284 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3285 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3286 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3287 M_BLEZ(REG_ITMP2, 2);
3288 M_ALD(REG_ITMP1, REG_ITMP1,
3289 OFFSET(vftbl_t, interfacetable[0]) -
3290 super->index * sizeof(methodptr*));
3291 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3295 s2 = super->vftbl->diffval;
3296 M_BEQZ(s1, 4 + (s2 > 255));
3297 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3298 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3299 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3301 M_CMPULE_IMM(REG_ITMP1, s2, d);
3303 M_LDA(REG_ITMP2, REG_ZERO, s2);
3304 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3308 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3309 a = dseg_addaddress(cd, (void*) super->vftbl);
3310 M_ALD(REG_ITMP2, REG_PV, a);
3311 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3312 codegen_threadcritstart(cd, (u1 *) mcodeptr - cd->mcodebase);
3314 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3315 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3316 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3317 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3318 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3320 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3321 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3325 panic ("internal error: no inlined array instanceof");
3327 store_reg_to_var_int(iptr->dst, d);
3330 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3332 /* op1: 0 == array, 1 == class */
3333 /* val.a: (classinfo*) superclass */
3335 /* superclass is an interface:
3337 * OK if ((sub == NULL) ||
3338 * (sub->vftbl->interfacetablelength > super->index) &&
3339 * (sub->vftbl->interfacetable[-super->index] != NULL));
3341 * superclass is a class:
3343 * OK if ((sub == NULL) || (0
3344 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3345 * super->vftbl->diffvall));
3349 classinfo *super = (classinfo *) iptr->val.a;
3351 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3352 codegen_threadcritrestart(cd, (u1 *) mcodeptr - cd->mcodebase);
3354 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
3355 var_to_reg_int(s1, src, d);
3356 if (iptr->op1) { /* class/interface */
3357 if (super->flags & ACC_INTERFACE) { /* interface */
3359 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3360 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3361 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3362 M_BLEZ(REG_ITMP2, 0);
3363 codegen_addxcastrefs(cd, mcodeptr);
3364 M_ALD(REG_ITMP2, REG_ITMP1,
3365 OFFSET(vftbl_t, interfacetable[0]) -
3366 super->index * sizeof(methodptr*));
3367 M_BEQZ(REG_ITMP2, 0);
3368 codegen_addxcastrefs(cd, mcodeptr);
3372 s2 = super->vftbl->diffval;
3373 M_BEQZ(s1, 4 + (s2 != 0) + (s2 > 255));
3374 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3375 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3376 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3378 M_BNEZ(REG_ITMP1, 0);
3380 else if (s2 <= 255) {
3381 M_CMPULE_IMM(REG_ITMP1, s2, REG_ITMP2);
3382 M_BEQZ(REG_ITMP2, 0);
3385 M_LDA(REG_ITMP2, REG_ZERO, s2);
3386 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3387 M_BEQZ(REG_ITMP2, 0);
3390 M_BEQZ(s1, 8 + (d == REG_ITMP3));
3391 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3392 a = dseg_addaddress(cd, (void *) super->vftbl);
3393 M_ALD(REG_ITMP2, REG_PV, a);
3394 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3395 codegen_threadcritstart(cd, (u1 *) mcodeptr - cd->mcodebase);
3397 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3398 if (d != REG_ITMP3) {
3399 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3400 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3401 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3402 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3404 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3407 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3408 M_ISUB(REG_ITMP1, REG_ITMP2, REG_ITMP1);
3409 M_ALD(REG_ITMP2, REG_PV, a);
3410 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3411 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3412 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3415 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3416 M_BEQZ(REG_ITMP2, 0);
3417 codegen_addxcastrefs(cd, mcodeptr);
3421 panic ("internal error: no inlined array checkcast");
3424 store_reg_to_var_int(iptr->dst, d);
3427 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
3429 var_to_reg_int(s1, src, REG_ITMP1);
3431 codegen_addxcheckarefs(cd, mcodeptr);
3434 case ICMD_CHECKEXCEPTION: /* ... ==> ... */
3436 M_BEQZ(REG_RESULT, 0);
3437 codegen_addxexceptionrefs(cd, mcodeptr);
3440 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3441 /* op1 = dimension, val.a = array descriptor */
3443 /* check for negative sizes and copy sizes to stack if necessary */
3445 MCODECHECK((iptr->op1 << 1) + 64);
3447 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3448 var_to_reg_int(s2, src, REG_ITMP1);
3450 codegen_addxcheckarefs(cd, mcodeptr);
3452 /* copy SAVEDVAR sizes to stack */
3454 if (src->varkind != ARGVAR) {
3455 M_LST(s2, REG_SP, s1 * 8);
3459 /* a0 = dimension count */
3461 ICONST(rd->argintregs[0], iptr->op1);
3463 /* a1 = arraydescriptor */
3465 a = dseg_addaddress(cd, iptr->val.a);
3466 M_ALD(rd->argintregs[1], REG_PV, a);
3468 /* a2 = pointer to dimensions = stack pointer */
3470 M_INTMOVE(REG_SP, rd->argintregs[2]);
3472 a = dseg_addaddress(cd, (void *) builtin_nmultianewarray);
3473 M_ALD(REG_PV, REG_PV, a);
3474 M_JSR(REG_RA, REG_PV);
3475 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3477 M_LDA(REG_PV, REG_RA, -s1);
3479 s4 ml = -s1, mh = 0;
3480 while (ml < -32768) { ml += 65536; mh--; }
3481 M_LDA(REG_PV, REG_RA, ml);
3482 M_LDAH(REG_PV, REG_PV, mh);
3484 s1 = reg_of_var(rd, iptr->dst, REG_RESULT);
3485 M_INTMOVE(REG_RESULT, s1);
3486 store_reg_to_var_int(iptr->dst, s1);
3490 throw_cacao_exception_exit(string_java_lang_InternalError,
3491 "Unknown ICMD %d", iptr->opc);
3494 } /* for instruction */
3496 /* copy values to interface registers */
3498 src = bptr->outstack;
3499 len = bptr->outdepth;
3506 if ((src->varkind != STACKVAR)) {
3508 if (IS_FLT_DBL_TYPE(s2)) {
3509 var_to_reg_flt(s1, src, REG_FTMP1);
3510 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3511 M_FLTMOVE(s1,rd->interfaces[len][s2].regoff);
3514 M_DST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3518 var_to_reg_int(s1, src, REG_ITMP1);
3519 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3520 M_INTMOVE(s1,rd->interfaces[len][s2].regoff);
3523 M_LST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3529 } /* if (bptr -> flags >= BBREACHED) */
3530 } /* for basic block */
3532 codegen_createlinenumbertable(cd);
3535 /* generate bound check stubs */
3537 s4 *xcodeptr = NULL;
3540 for (bref = cd->xboundrefs; bref != NULL; bref = bref->next) {
3541 gen_resolvebranch((u1*) cd->mcodebase + bref->branchpos,
3543 (u1*) mcodeptr - cd->mcodebase);
3547 /* move index register into REG_ITMP1 */
3548 M_MOV(bref->reg, REG_ITMP1);
3549 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3551 if (xcodeptr != NULL) {
3552 M_BR(xcodeptr - mcodeptr - 1);
3555 xcodeptr = mcodeptr;
3557 a = dseg_addaddress(cd, asm_throw_and_handle_arrayindexoutofbounds_exception);
3558 M_ALD(REG_PV, REG_PV, a);
3560 M_JSR(REG_RA, REG_PV);
3563 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3564 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3566 s4 ml = -s1, mh = 0;
3567 while (ml < -32768) { ml += 65536; mh--; }
3568 M_LDA(REG_PV, REG_RA, ml);
3569 M_LDAH(REG_PV, REG_PV, mh);
3574 /* generate negative array size check stubs */
3578 for (bref = cd->xcheckarefs; bref != NULL; bref = bref->next) {
3579 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3580 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3582 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3586 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3588 (u1 *) mcodeptr - cd->mcodebase);
3592 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3594 if (xcodeptr != NULL) {
3595 M_BR(xcodeptr - mcodeptr - 1);
3598 xcodeptr = mcodeptr;
3601 a = dseg_addaddress(cd, string_java_lang_NegativeArraySizeException);
3602 M_ALD(REG_ITMP1_XPTR,REG_PV,a);
3604 a = dseg_addaddress(cd, asm_throw_and_handle_nat_exception);
3605 M_ALD(REG_PV, REG_PV, a);
3607 M_JSR(REG_RA, REG_PV);
3610 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3611 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3613 s4 ml = -s1, mh = 0;
3614 while (ml < -32768) { ml += 65536; mh--; }
3615 M_LDA(REG_PV, REG_RA, ml);
3616 M_LDAH(REG_PV, REG_PV, mh);
3623 /* generate cast check stubs */
3627 for (bref = cd->xcastrefs; bref != NULL; bref = bref->next) {
3628 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3629 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3631 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3635 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3637 (u1 *) mcodeptr - cd->mcodebase);
3641 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3643 if (xcodeptr != NULL) {
3644 M_BR(xcodeptr - mcodeptr - 1);
3647 xcodeptr = mcodeptr;
3649 a = dseg_addaddress(cd, string_java_lang_ClassCastException);
3650 M_ALD(REG_ITMP1_XPTR,REG_PV,a);
3652 a = dseg_addaddress(cd, asm_throw_and_handle_nat_exception);
3653 M_ALD(REG_PV, REG_PV, a);
3655 M_JSR(REG_RA, REG_PV);
3658 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3659 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3661 s4 ml = -s1, mh = 0;
3662 while (ml < -32768) { ml += 65536; mh--; }
3663 M_LDA(REG_PV, REG_RA, ml);
3664 M_LDAH(REG_PV, REG_PV, mh);
3670 /* generate exception check stubs */
3674 for (bref = cd->xexceptionrefs; bref != NULL; bref = bref->next) {
3675 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3676 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3678 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3682 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3684 (u1 *) mcodeptr - cd->mcodebase);
3688 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3690 if (xcodeptr != NULL) {
3691 M_BR(xcodeptr - mcodeptr - 1);
3694 xcodeptr = mcodeptr;
3696 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3697 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3698 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3700 a = dseg_addaddress(cd, &builtin_get_exceptionptrptr);
3701 M_ALD(REG_PV, REG_PV, a);
3702 M_JSR(REG_RA, REG_PV);
3705 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3706 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3708 s4 ml = -s1, mh = 0;
3709 while (ml < -32768) { ml += 65536; mh--; }
3710 M_LDA(REG_PV, REG_RA, ml);
3711 M_LDAH(REG_PV, REG_PV, mh);
3714 M_ALD(REG_ITMP1_XPTR, REG_RESULT, 0);
3715 M_AST(REG_ZERO, REG_RESULT, 0);
3717 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3718 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3720 a = dseg_addaddress(cd, &_exceptionptr);
3721 M_ALD(REG_ITMP3, REG_PV, a);
3722 M_ALD(REG_ITMP1_XPTR, REG_ITMP3, 0);
3723 M_AST(REG_ZERO, REG_ITMP3, 0);
3726 a = dseg_addaddress(cd, asm_refillin_and_handle_exception);
3727 M_ALD(REG_PV, REG_PV, a);
3729 M_JMP(REG_RA, REG_PV);
3732 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3733 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3735 s4 ml = -s1, mh = 0;
3736 while (ml < -32768) { ml += 65536; mh--; }
3737 M_LDA(REG_PV, REG_RA, ml);
3738 M_LDAH(REG_PV, REG_PV, mh);
3744 /* generate null pointer check stubs */
3748 for (bref = cd->xnullrefs; bref != NULL; bref = bref->next) {
3749 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3750 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3752 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3756 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3758 (u1 *) mcodeptr - cd->mcodebase);
3762 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3764 if (xcodeptr != NULL) {
3765 M_BR(xcodeptr - mcodeptr - 1);
3768 xcodeptr = mcodeptr;
3770 a = dseg_addaddress(cd, string_java_lang_NullPointerException);
3771 M_ALD(REG_ITMP1_XPTR,REG_PV,a);
3773 a = dseg_addaddress(cd, asm_throw_and_handle_nat_exception);
3774 M_ALD(REG_PV, REG_PV, a);
3776 M_JSR(REG_RA, REG_PV);
3779 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3780 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3782 s4 ml = -s1, mh = 0;
3783 while (ml < -32768) { ml += 65536; mh--; }
3784 M_LDA(REG_PV, REG_RA, ml);
3785 M_LDAH(REG_PV, REG_PV, mh);
3791 /* generate put/getstatic stub call code */
3798 for (cref = cd->clinitrefs; cref != NULL; cref = cref->next) {
3799 /* Get machine code which is patched back in later. The call is */
3800 /* 1 instruction word long. */
3801 xcodeptr = (s4 *) (cd->mcodebase + cref->branchpos);
3804 /* patch in the call to call the following code (done at compile */
3807 tmpmcodeptr = mcodeptr; /* save current mcodeptr */
3808 mcodeptr = xcodeptr; /* set mcodeptr to patch position */
3810 M_BSR(REG_RA, tmpmcodeptr - (xcodeptr + 1));
3812 mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
3816 /* move class pointer into REG_ITMP2 */
3817 a = dseg_addaddress(cd, cref->class);
3818 M_ALD(REG_ITMP1, REG_PV, a);
3820 /* move machine code onto stack */
3821 a = dseg_adds4(cd, mcode);
3822 M_ILD(REG_ITMP3, REG_PV, a);
3823 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3824 M_IST(REG_ITMP3, REG_SP, 0);
3826 a = dseg_addaddress(cd, asm_check_clinit);
3827 M_ALD(REG_ITMP2, REG_PV, a);
3828 M_JMP(REG_ZERO, REG_ITMP2);
3833 codegen_finish(m, cd, (s4) ((u1 *) mcodeptr - cd->mcodebase));
3837 /* function createcompilerstub *************************************************
3839 creates a stub routine which calls the compiler
3841 *******************************************************************************/
3843 #define COMPSTUBSIZE 3
3845 u1 *createcompilerstub(methodinfo *m)
3847 u8 *s = CNEW(u8, COMPSTUBSIZE); /* memory to hold the stub */
3848 s4 *mcodeptr = (s4 *) s; /* code generation pointer */
3850 /* code for the stub */
3851 M_ALD(REG_PV, REG_PV, 16); /* load pointer to the compiler */
3852 M_JMP(0, REG_PV); /* jump to the compiler, return address
3853 in reg 0 is used as method pointer */
3854 s[1] = (u8) m; /* literals to be adressed */
3855 s[2] = (u8) asm_call_jit_compiler; /* jump directly via PV from above */
3857 #if defined(STATISTICS)
3859 count_cstub_len += COMPSTUBSIZE * 8;
3866 /* function removecompilerstub *************************************************
3868 deletes a compilerstub from memory (simply by freeing it)
3870 *******************************************************************************/
3872 void removecompilerstub(u1 *stub)
3874 CFREE(stub, COMPSTUBSIZE * 8);
3878 /* function: createnativestub **************************************************
3880 creates a stub routine which calls a native method
3882 *******************************************************************************/
3885 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3886 #define NATIVESTUB_STACK 8/*ra,native result, oldThreadspecificHeadValue, addressOfThreadspecificHead, method, 0,0,ra*/
3887 #define NATIVESTUB_THREAD_EXTRA (6 + 20) /*20 for additional frame creation*/
3888 #define NATIVESTUB_STACKTRACE_OFFSET 1
3890 #define NATIVESTUB_STACK 7/*ra,oldThreadspecificHeadValue, addressOfThreadspecificHead, method, 0,0,ra*/
3891 #define NATIVESTUB_THREAD_EXTRA (1 + 20) /*20 for additional frame creation*/
3892 #define NATIVESTUB_STACKTRACE_OFFSET 0
3895 #define NATIVESTUB_SIZE (44 + NATIVESTUB_THREAD_EXTRA - 1)
3896 #define NATIVESTUB_STATIC_SIZE 5
3897 #define NATIVESTUB_VERBOSE_SIZE (39 + 13)
3898 #define NATIVESTUB_OFFSET 11
3901 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3902 #define NATIVESTUB_STACK 2
3903 #define NATIVESTUB_THREAD_EXTRA 6
3905 #define NATIVESTUB_STACK 1
3906 #define NATIVESTUB_THREAD_EXTRA 1
3909 #define NATIVESTUB_SIZE (44 + NATIVESTUB_THREAD_EXTRA - 1)
3910 #define NATIVESTUB_STATIC_SIZE 4
3911 #define NATIVESTUB_VERBOSE_SIZE (39 + 13)
3912 #define NATIVESTUB_OFFSET 10
3915 u1 *createnativestub(functionptr f, methodinfo *m)
3917 u8 *s; /* memory pointer to hold the stub */
3919 s4 *mcodeptr; /* code generation pointer */
3920 s4 stackframesize = 0; /* size of stackframe if needed */
3925 t_inlining_globals *id;
3928 /* mark start of dump memory area */
3930 dumpsize = dump_size();
3932 /* setup registers before using it */
3934 cd = DNEW(codegendata);
3935 rd = DNEW(registerdata);
3936 id = DNEW(t_inlining_globals);
3938 inlining_setup(m, id);
3939 reg_setup(m, rd, id);
3941 descriptor2types(m); /* set paramcount and paramtypes */
3943 stubsize = NATIVESTUB_SIZE; /* calculate nativestub size */
3945 if ((m->flags & ACC_STATIC) && !m->class->initialized)
3946 stubsize += NATIVESTUB_STATIC_SIZE;
3949 stubsize += NATIVESTUB_VERBOSE_SIZE;
3951 s = CNEW(u8, stubsize); /* memory to hold the stub */
3952 cs = s + NATIVESTUB_OFFSET;
3953 mcodeptr = (s4 *) cs; /* code generation pointer */
3955 /* set some required varibles which are normally set by codegen_setup */
3956 cd->mcodebase = (u1 *) mcodeptr;
3957 cd->clinitrefs = NULL;
3959 *(cs-1) = (u8) f; /* address of native method */
3960 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3961 *(cs-2) = (u8) &builtin_get_exceptionptrptr;
3963 *(cs-2) = (u8) (&_exceptionptr); /* address of exceptionptr */
3965 *(cs-3) = (u8) asm_handle_nat_exception; /* addr of asm exception handler*/
3966 *(cs-4) = (u8) (&env); /* addr of jni_environement */
3967 *(cs-5) = (u8) builtin_trace_args;
3969 *(cs-7) = (u8) builtin_displaymethodstop;
3970 *(cs-8) = (u8) m->class;
3971 *(cs-9) = (u8) asm_check_clinit;
3972 *(cs-10) = (u8) &builtin_asm_get_stackframeinfo;
3973 *(cs-11) = (u8) NULL; /* filled with machine code */
3975 M_LDA(REG_SP, REG_SP, -NATIVESTUB_STACK * 8); /* build up stackframe */
3976 M_AST(REG_RA, REG_SP, 0 * 8); /* store return address */
3978 M_AST(REG_RA, REG_SP, (6+NATIVESTUB_STACKTRACE_OFFSET) * 8); /* store return address in stackinfo helper*/
3980 /* if function is static, check for initialized */
3982 if (m->flags & ACC_STATIC) {
3983 /* if class isn't yet initialized, do it */
3984 if (!m->class->initialized) {
3985 codegen_addclinitref(cd, mcodeptr, m->class);
3989 /* max. 39 +9 instructions */
3993 M_LDA(REG_SP, REG_SP, -((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
3994 M_AST(REG_RA, REG_SP, 1 * 8);
3996 /* save integer argument registers */
3997 for (p = 0; p < m->paramcount && p < INT_ARG_CNT; p++) {
3998 M_LST(rd->argintregs[p], REG_SP, (2 + p) * 8);
4001 /* save and copy float arguments into integer registers */
4002 for (p = 0; p < m->paramcount && p < FLT_ARG_CNT; p++) {
4003 t = m->paramtypes[p];
4005 if (IS_FLT_DBL_TYPE(t)) {
4006 if (IS_2_WORD_TYPE(t)) {
4007 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4008 M_LLD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4011 M_FST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4012 M_ILD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4016 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4021 M_ALD(REG_ITMP1, REG_PV, -6 * 8);
4022 M_AST(REG_ITMP1, REG_SP, 0 * 8);
4023 M_ALD(REG_PV, REG_PV, -5 * 8);
4024 M_JSR(REG_RA, REG_PV);
4025 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4026 M_LDA(REG_PV, REG_RA, disp);
4031 M_ALD(REG_PV, REG_PV, -10 * 8); /* builtin_asm_get_stackframeinfo */
4032 M_JSR(REG_RA, REG_PV);
4033 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4034 M_LDA(REG_PV, REG_RA, disp);
4037 M_MOV(REG_RESULT,REG_ITMP3);
4038 M_LST(REG_RESULT,REG_ITMP3,0);
4040 M_LST(REG_RESULT,REG_SP, ((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8)+(2+NATIVESTUB_STACKTRACE_OFFSET)*8);/*save adress of pointer*/
4041 M_LLD(REG_ITMP3,REG_RESULT,0); /* get pointer*/
4042 M_LST(REG_ITMP3,REG_SP,(1+NATIVESTUB_STACKTRACE_OFFSET)*8+((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8)); /*save old value*/
4043 M_LDA(REG_ITMP3,REG_SP,(1+NATIVESTUB_STACKTRACE_OFFSET)*8+((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8)); /*calculate new value*/
4044 M_LLD(REG_ITMP2,REG_ITMP3,8);
4045 M_LST(REG_ITMP3,REG_ITMP2,0); /*store new value*/
4046 M_LLD(REG_ITMP2,REG_PV,-6*8);
4047 M_LST(REG_ITMP2,REG_SP,(3+NATIVESTUB_STACKTRACE_OFFSET)*8+((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
4048 M_LST(REG_ZERO,REG_SP,(4+NATIVESTUB_STACKTRACE_OFFSET)*8+((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
4049 M_LST(REG_ZERO,REG_SP,(5+NATIVESTUB_STACKTRACE_OFFSET)*8+((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
4050 /*stack info -end */
4053 for (p = 0; p < m->paramcount && p < INT_ARG_CNT; p++) {
4054 M_LLD(rd->argintregs[p], REG_SP, (2 + p) * 8);
4057 for (p = 0; p < m->paramcount && p < FLT_ARG_CNT; p++) {
4058 t = m->paramtypes[p];
4060 if (IS_FLT_DBL_TYPE(t)) {
4061 if (IS_2_WORD_TYPE(t)) {
4062 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4065 M_FLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4069 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4073 M_ALD(REG_RA, REG_SP, 1 * 8);
4074 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT + 2) * 8);
4077 /* save argument registers on stack -- if we have to */
4078 if ((m->flags & ACC_STATIC && m->paramcount > (INT_ARG_CNT - 2)) || m->paramcount > (INT_ARG_CNT - 1)) {
4080 s4 paramshiftcnt = (m->flags & ACC_STATIC) ? 2 : 1;
4081 s4 stackparamcnt = (m->paramcount > INT_ARG_CNT) ? m->paramcount - INT_ARG_CNT : 0;
4083 stackframesize = stackparamcnt + paramshiftcnt;
4085 M_LDA(REG_SP, REG_SP, -stackframesize * 8);
4087 /* copy stack arguments into new stack frame -- if any */
4088 for (i = 0; i < stackparamcnt; i++) {
4089 M_LLD(REG_ITMP1, REG_SP, (stackparamcnt + 1 + i) * 8);
4090 M_LST(REG_ITMP1, REG_SP, (paramshiftcnt + i) * 8);
4093 if (m->flags & ACC_STATIC) {
4094 if (IS_FLT_DBL_TYPE(m->paramtypes[5])) {
4095 M_DST(rd->argfltregs[5], REG_SP, 1 * 8);
4097 M_LST(rd->argintregs[5], REG_SP, 1 * 8);
4100 if (IS_FLT_DBL_TYPE(m->paramtypes[4])) {
4101 M_DST(rd->argfltregs[4], REG_SP, 0 * 8);
4103 M_LST(rd->argintregs[4], REG_SP, 0 * 8);
4107 if (IS_FLT_DBL_TYPE(m->paramtypes[5])) {
4108 M_DST(rd->argfltregs[5], REG_SP, 0 * 8);
4110 M_LST(rd->argintregs[5], REG_SP, 0 * 8);
4115 if (m->flags & ACC_STATIC) {
4116 M_MOV(rd->argintregs[3], rd->argintregs[5]);
4117 M_MOV(rd->argintregs[2], rd->argintregs[4]);
4118 M_MOV(rd->argintregs[1], rd->argintregs[3]);
4119 M_MOV(rd->argintregs[0], rd->argintregs[2]);
4120 M_FMOV(rd->argfltregs[3], rd->argfltregs[5]);
4121 M_FMOV(rd->argfltregs[2], rd->argfltregs[4]);
4122 M_FMOV(rd->argfltregs[1], rd->argfltregs[3]);
4123 M_FMOV(rd->argfltregs[0], rd->argfltregs[2]);
4125 /* put class into second argument register */
4126 M_ALD(rd->argintregs[1], REG_PV, -8 * 8);
4129 M_MOV(rd->argintregs[4], rd->argintregs[5]);
4130 M_MOV(rd->argintregs[3], rd->argintregs[4]);
4131 M_MOV(rd->argintregs[2], rd->argintregs[3]);
4132 M_MOV(rd->argintregs[1], rd->argintregs[2]);
4133 M_MOV(rd->argintregs[0], rd->argintregs[1]);
4134 M_FMOV(rd->argfltregs[4], rd->argfltregs[5]);
4135 M_FMOV(rd->argfltregs[3], rd->argfltregs[4]);
4136 M_FMOV(rd->argfltregs[2], rd->argfltregs[3]);
4137 M_FMOV(rd->argfltregs[1], rd->argfltregs[2]);
4138 M_FMOV(rd->argfltregs[0], rd->argfltregs[1]);
4141 /* put env into first argument register */
4142 M_ALD(rd->argintregs[0], REG_PV, -4 * 8);
4144 M_ALD(REG_PV, REG_PV, -1 * 8); /* load adress of native method */
4145 M_JSR(REG_RA, REG_PV); /* call native method */
4146 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4147 M_LDA(REG_PV, REG_RA, disp); /* recompute pv from ra */
4149 /* remove stackframe if there is one */
4150 if (stackframesize) {
4151 M_LDA(REG_SP, REG_SP, stackframesize * 8);
4154 /* 13 instructions */
4156 M_LDA(REG_SP, REG_SP, -2 * 8);
4157 M_ALD(rd->argintregs[0], REG_PV, -6 * 8); /* load method adress */
4158 M_LST(REG_RESULT, REG_SP, 0 * 8);
4159 M_DST(REG_FRESULT, REG_SP, 1 * 8);
4160 M_MOV(REG_RESULT, rd->argintregs[1]);
4161 M_FMOV(REG_FRESULT, rd->argfltregs[2]);
4162 M_FMOV(REG_FRESULT, rd->argfltregs[3]);
4163 M_ALD(REG_PV, REG_PV, -7 * 8); /* builtin_displaymethodstop */
4164 M_JSR(REG_RA, REG_PV);
4165 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4166 M_LDA(REG_PV, REG_RA, disp);
4167 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4168 M_DLD(REG_FRESULT, REG_SP, 1 * 8);
4169 M_LDA(REG_SP, REG_SP, 2 * 8);
4172 M_LLD(REG_ITMP3,REG_SP,(2+NATIVESTUB_STACKTRACE_OFFSET)*8); /*get address of stacktrace helper pointer*/
4173 M_LLD(REG_ITMP1,REG_SP,(1+NATIVESTUB_STACKTRACE_OFFSET)*8); /*get old value*/
4174 M_LST(REG_ITMP1,REG_ITMP3,0); /*set old value*/
4176 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4177 if (IS_FLT_DBL_TYPE(m->returntype))
4178 M_DST(REG_FRESULT, REG_SP, 1 * 8);
4180 M_AST(REG_RESULT, REG_SP, 1 * 8);
4181 M_ALD(REG_PV, REG_PV, -2 * 8); /* builtin_get_exceptionptrptr */
4182 M_JSR(REG_RA, REG_PV);
4183 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4184 M_LDA(REG_PV, REG_RA, disp);
4185 M_MOV(REG_RESULT, REG_ITMP3);
4186 if (IS_FLT_DBL_TYPE(m->returntype))
4187 M_DLD(REG_FRESULT, REG_SP, 1 * 8);
4189 M_ALD(REG_RESULT, REG_SP, 1 * 8);
4191 M_ALD(REG_ITMP3, REG_PV, -2 * 8); /* get address of exceptionptr */
4193 M_ALD(REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
4194 M_BNEZ(REG_ITMP1, 3); /* if no exception then return */
4196 M_ALD(REG_RA, REG_SP, 0 * 8); /* load return address */
4197 M_LDA(REG_SP, REG_SP, NATIVESTUB_STACK * 8); /* remove stackframe */
4198 M_RET(REG_ZERO, REG_RA); /* return to caller */
4200 M_AST(REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
4202 M_ALD(REG_RA, REG_SP, 0 * 8); /* load return address */
4203 M_LDA(REG_SP, REG_SP, NATIVESTUB_STACK * 8); /* remove stackframe */
4204 M_LDA(REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
4205 M_ALD(REG_ITMP3, REG_PV, -3 * 8); /* load asm exception handler address */
4206 M_JMP(REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
4208 /* generate put/getstatic stub call code */
4215 /* there can only be one clinit ref entry */
4216 cref = cd->clinitrefs;
4219 /* Get machine code which is patched back in later. The call is */
4220 /* 1 instruction word long. */
4221 xcodeptr = (s4 *) (cd->mcodebase + cref->branchpos);
4222 *(cs-11) = (u4) *xcodeptr;
4224 /* patch in the call to call the following code (done at compile */
4227 tmpmcodeptr = mcodeptr; /* save current mcodeptr */
4228 mcodeptr = xcodeptr; /* set mcodeptr to patch position */
4230 M_BSR(REG_RA, tmpmcodeptr - (xcodeptr + 1));
4232 mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
4234 /* move class pointer into REG_ITMP2 */
4235 M_ALD(REG_ITMP1, REG_PV, -8 * 8); /* class */
4237 /* move machine code into REG_ITMP3 */
4238 M_ILD(REG_ITMP3, REG_PV, -11 * 8); /* machine code */
4239 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
4240 M_IST(REG_ITMP3, REG_SP, 0);
4242 M_ALD(REG_ITMP2, REG_PV, -9 * 8); /* asm_check_clinit */
4243 M_JMP(REG_ZERO, REG_ITMP2);
4247 /* Check if the stub size is big enough to hold the whole stub generated. */
4248 /* If not, this can lead into unpredictable crashes, because of heap */
4250 if ((s4) ((ptrint) mcodeptr - (ptrint) s) > stubsize * sizeof(u8)) {
4251 throw_cacao_exception_exit(string_java_lang_InternalError,
4252 "Native stub size %d is to small for current stub size %d",
4253 stubsize, (s4) ((ptrint) mcodeptr - (ptrint) s));
4256 #if defined(STATISTICS)
4258 count_nstub_len += NATIVESTUB_SIZE * 8;
4261 /* release dump area */
4263 dump_release(dumpsize);
4265 return (u1 *) (s + NATIVESTUB_OFFSET);
4269 /* function: removenativestub **************************************************
4271 removes a previously created native-stub from memory
4273 *******************************************************************************/
4275 void removenativestub(u1 *stub)
4277 CFREE((u8 *) stub - NATIVESTUBOFFSET, NATIVESTUBSIZE * 8);
4282 * These are local overrides for various environment variables in Emacs.
4283 * Please do not remove this and leave it at the end of the file, where
4284 * Emacs will automagically detect them.
4285 * ---------------------------------------------------------------------
4288 * indent-tabs-mode: t