1 /* vm/jit/alpha/codegen.c - machine code generator for alpha
3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4 Institut f. Computersprachen, TU Wien
5 R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser, M. Probst,
6 S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich,
9 This file is part of CACAO.
11 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License as
13 published by the Free Software Foundation; either version 2, or (at
14 your option) any later version.
16 This program is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
26 Contact: cacao@complang.tuwien.ac.at
28 Authors: Andreas Krall
31 Changes: Joseph Wenninger
33 $Id: codegen.c 1694 2004-12-06 12:30:59Z twisti $
41 #include "vm/jit/alpha/arch.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/codegen.h"
55 #include "vm/jit/alpha/types.h"
56 #include "vm/jit/alpha/asmoffsets.h"
59 /* *****************************************************************************
61 Datatypes and Register Allocations:
62 -----------------------------------
64 On 64-bit-machines (like the Alpha) all operands are stored in the
65 registers in a 64-bit form, even when the correspondig JavaVM operands
66 only need 32 bits. This is done by a canonical representation:
68 32-bit integers are allways stored as sign-extended 64-bit values (this
69 approach is directly supported by the Alpha architecture and is very easy
72 32-bit-floats are stored in a 64-bit doubleprecision register by simply
73 expanding the exponent and mantissa with zeroes. (also supported by the
79 The calling conventions and the layout of the stack is explained in detail
80 in the documention file: calling.doc
82 *******************************************************************************/
85 /* register descripton - array ************************************************/
87 /* #define REG_RES 0 reserved register for OS or code generator */
88 /* #define REG_RET 1 return value register */
89 /* #define REG_EXC 2 exception value register (only old jit) */
90 /* #define REG_SAV 3 (callee) saved register */
91 /* #define REG_TMP 4 scratch temporary register (caller saved) */
92 /* #define REG_ARG 5 argument register (caller saved) */
94 /* #define REG_END -1 last entry in tables */
97 REG_RET, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
98 REG_TMP, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
99 REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_TMP, REG_TMP,
100 REG_TMP, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES,
103 /* for use of reserved registers, see comment above */
105 int nregdescfloat[] = {
106 REG_RET, REG_TMP, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
107 REG_SAV, REG_SAV, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
108 REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_TMP, REG_TMP,
109 REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_RES, REG_RES, REG_RES, REG_RES,
113 /* Include independent code generation stuff -- include after register */
114 /* descriptions to avoid extern definitions. */
116 #include "vm/jit/codegen.inc"
117 #include "vm/jit/reg.inc"
119 #include "vm/jit/lsra.inc"
123 /* NullPointerException handlers and exception handling initialisation */
125 typedef struct sigctx_struct {
126 long sc_onstack; /* sigstack state to restore */
127 long sc_mask; /* signal mask to restore */
128 long sc_pc; /* pc at time of signal */
129 long sc_ps; /* psl to retore */
130 long sc_regs[32]; /* processor regs 0 to 31 */
131 long sc_ownedfp; /* fp has been used */
132 long sc_fpregs[32]; /* fp regs 0 to 31 */
133 unsigned long sc_fpcr; /* floating point control register */
134 unsigned long sc_fp_control; /* software fpcr */
136 unsigned long sc_reserved1, sc_reserved2;
137 unsigned long sc_ssize;
139 unsigned long sc_traparg_a0;
140 unsigned long sc_traparg_a1;
141 unsigned long sc_traparg_a2;
142 unsigned long sc_fp_trap_pc;
143 unsigned long sc_fp_trigger_sum;
144 unsigned long sc_fp_trigger_inst;
145 unsigned long sc_retcode[2];
149 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
150 void thread_restartcriticalsection(ucontext_t *uc)
153 if ((critical = thread_checkcritical((void*) uc->uc_mcontext.sc_pc)) != NULL)
154 uc->uc_mcontext.sc_pc = (u8) critical;
158 /* NullPointerException signal handler for hardware null pointer check */
160 void catch_NullPointerException(int sig, int code, sigctx_struct *sigctx)
165 java_objectheader *xptr;
167 /* Reset signal handler - necessary for SysV, does no harm for BSD */
169 instr = *((int*)(sigctx->sc_pc));
170 faultaddr = sigctx->sc_regs[(instr >> 16) & 0x1f];
172 if (faultaddr == 0) {
173 /* reinstall handler */
174 signal(sig, (functionptr) catch_NullPointerException);
176 sigaddset(&nsig, sig);
177 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
179 /*xptr = new_nullpointerexception();
180 sigctx->sc_regs[REG_ITMP1_XPTR] = (u8) xptr;*/
182 sigctx->sc_regs[REG_ITMP1_XPTR]=string_java_lang_NullPointerException;
183 sigctx->sc_regs[REG_ITMP2_XPC] = sigctx->sc_pc;
184 /*sigctx->sc_pc = (u8) asm_handle_exception;*/
185 sigctx->sc_pc = (u8) asm_throw_and_handle_exception;
189 faultaddr += (long) ((instr << 16) >> 16);
190 fprintf(stderr, "faulting address: 0x%016lx\n", faultaddr);
191 panic("Stack overflow");
198 void init_exceptions(void)
203 /* Linux on Digital Alpha needs an initialisation of the ieee floating point
204 control for IEEE compliant arithmetic (option -mieee of GCC). Under
205 Digital Unix this is done automatically.
210 extern unsigned long ieee_get_fp_control();
211 extern void ieee_set_fp_control(unsigned long fp_control);
213 void init_exceptions(void)
215 /* initialize floating point control */
217 ieee_set_fp_control(ieee_get_fp_control()
218 & ~IEEE_TRAP_ENABLE_INV
219 & ~IEEE_TRAP_ENABLE_DZE
220 /* & ~IEEE_TRAP_ENABLE_UNF we dont want underflow */
221 & ~IEEE_TRAP_ENABLE_OVF);
224 /* install signal handlers we need to convert to exceptions */
228 signal(SIGSEGV, (functionptr) catch_NullPointerException);
232 signal(SIGBUS, (functionptr) catch_NullPointerException);
238 /* function gen_mcode **********************************************************
240 generates machine code
242 *******************************************************************************/
244 void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
246 s4 len, s1, s2, s3, d;
260 savedregs_num = (m->isleafmethod) ? 0 : 1; /* space to save the RA */
262 /* space to save used callee saved registers */
264 savedregs_num += (rd->savintregcnt - rd->maxsavintreguse);
265 savedregs_num += (rd->savfltregcnt - rd->maxsavfltreguse);
267 parentargs_base = rd->maxmemuse + savedregs_num;
269 #if defined(USE_THREADS) /* space to save argument of monitor_enter */
271 if (checksync && (m->flags & ACC_SYNCHRONIZED))
276 /* create method header */
278 (void) dseg_addaddress(cd, m); /* MethodPointer */
279 (void) dseg_adds4(cd, parentargs_base * 8); /* FrameSize */
281 #if defined(USE_THREADS)
283 /* IsSync contains the offset relative to the stack pointer for the
284 argument of monitor_exit used in the exception handler. Since the
285 offset could be zero and give a wrong meaning of the flag it is
289 if (checksync && (m->flags & ACC_SYNCHRONIZED))
290 (void) dseg_adds4(cd, (rd->maxmemuse + 1) * 8); /* IsSync */
295 (void) dseg_adds4(cd, 0); /* IsSync */
297 (void) dseg_adds4(cd, m->isleafmethod); /* IsLeaf */
298 (void) dseg_adds4(cd, rd->savintregcnt - rd->maxsavintreguse);/* IntSave */
299 (void) dseg_adds4(cd, rd->savfltregcnt - rd->maxsavfltreguse);/* FltSave */
301 dseg_addlinenumbertablesize(cd);
303 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
305 /* create exception table */
307 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
308 dseg_addtarget(cd, ex->start);
309 dseg_addtarget(cd, ex->end);
310 dseg_addtarget(cd, ex->handler);
311 (void) dseg_addaddress(cd, ex->catchtype);
314 /* initialize mcode variables */
316 mcodeptr = (s4 *) cd->mcodebase;
317 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
318 MCODECHECK(128 + m->paramcount);
320 /* create stack frame (if necessary) */
322 if (parentargs_base) {
323 M_LDA(REG_SP, REG_SP, -parentargs_base * 8);
326 /* save return address and used callee saved registers */
329 if (!m->isleafmethod) {
330 p--; M_AST(REG_RA, REG_SP, p * 8);
332 for (i = rd->savintregcnt - 1; i >= rd->maxsavintreguse; i--) {
333 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
335 for (i = rd->savfltregcnt - 1; i >= rd->maxsavfltreguse; i--) {
336 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
339 /* save monitorenter argument */
341 #if defined(USE_THREADS)
342 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
343 if (m->flags & ACC_STATIC) {
344 p = dseg_addaddress(cd, m->class);
345 M_ALD(REG_ITMP1, REG_PV, p);
346 M_AST(REG_ITMP1, REG_SP, rd->maxmemuse * 8);
349 M_AST(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
354 /* copy argument registers to stack and call trace function with pointer
355 to arguments on stack.
360 M_LDA(REG_SP, REG_SP, -((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
361 M_AST(REG_RA, REG_SP, 1 * 8);
363 /* save integer argument registers */
364 for (p = 0; /* p < m->paramcount && */ p < INT_ARG_CNT; p++) {
365 M_LST(rd->argintregs[p], REG_SP, (2 + p) * 8);
368 /* save and copy float arguments into integer registers */
369 for (p = 0; /* p < m->paramcount && */ p < FLT_ARG_CNT; p++) {
370 t = m->paramtypes[p];
372 if (IS_FLT_DBL_TYPE(t)) {
373 if (IS_2_WORD_TYPE(t)) {
374 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
377 M_FST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
380 M_LLD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
383 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
387 p = dseg_addaddress(cd, m);
388 M_ALD(REG_ITMP1, REG_PV, p);
389 M_AST(REG_ITMP1, REG_SP, 0 * 8);
390 p = dseg_addaddress(cd, (void *) builtin_trace_args);
391 M_ALD(REG_PV, REG_PV, p);
392 M_JSR(REG_RA, REG_PV);
393 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
394 M_LDA(REG_PV, REG_RA, disp);
395 M_ALD(REG_RA, REG_SP, 1 * 8);
397 for (p = 0; /* p < mparamcount && */ p < INT_ARG_CNT; p++) {
398 M_LLD(rd->argintregs[p], REG_SP, (2 + p) * 8);
401 for (p = 0; /* p < mparamcount && */ p < FLT_ARG_CNT; p++) {
402 t = m->paramtypes[p];
404 if (IS_FLT_DBL_TYPE(t)) {
405 if (IS_2_WORD_TYPE(t)) {
406 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
409 M_FLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
413 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
417 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT + 2) * 8);
420 /* take arguments out of register or stack frame */
422 for (p = 0, l = 0; p < m->paramcount; p++) {
423 t = m->paramtypes[p];
424 var = &(rd->locals[l][t]);
426 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
430 if (IS_INT_LNG_TYPE(t)) { /* integer args */
431 if (p < INT_ARG_CNT) { /* register arguments */
432 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
433 M_INTMOVE(rd->argintregs[p], var->regoff);
434 } else { /* reg arg -> spilled */
435 M_LST(rd->argintregs[p], REG_SP, 8 * var->regoff);
438 } else { /* stack arguments */
439 pa = p - INT_ARG_CNT;
440 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
441 M_LLD(var->regoff, REG_SP, 8 * (parentargs_base + pa));
443 } else { /* stack arg -> spilled */
444 M_LLD(REG_ITMP1, REG_SP, 8 * (parentargs_base + pa));
445 M_LST(REG_ITMP1, REG_SP, 8 * var->regoff);
449 } else { /* floating args */
450 if (p < FLT_ARG_CNT) { /* register arguments */
451 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
452 M_FLTMOVE(rd->argfltregs[p], var->regoff);
454 } else { /* reg arg -> spilled */
455 M_DST(rd->argfltregs[p], REG_SP, 8 * var->regoff);
458 } else { /* stack arguments */
459 pa = p - FLT_ARG_CNT;
460 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
461 M_DLD(var->regoff, REG_SP, 8 * (parentargs_base + pa) );
463 } else { /* stack-arg -> spilled */
464 M_DLD(REG_FTMP1, REG_SP, 8 * (parentargs_base + pa));
465 M_DST(REG_FTMP1, REG_SP, 8 * var->regoff);
471 /* call monitorenter function */
473 #if defined(USE_THREADS)
474 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
476 s8 func_enter = (m->flags & ACC_STATIC) ?
477 (s8) builtin_staticmonitorenter : (s8) builtin_monitorenter;
478 p = dseg_addaddress(cd, (void*) func_enter);
479 M_ALD(REG_PV, REG_PV, p);
480 M_ALD(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
481 M_JSR(REG_RA, REG_PV);
482 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
483 M_LDA(REG_PV, REG_RA, disp);
488 /* end of header generation */
490 /* walk through all basic blocks */
491 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
493 bptr->mpc = (s4) ((u1 *) mcodeptr - cd->mcodebase);
495 if (bptr->flags >= BBREACHED) {
497 /* branch resolving */
501 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
502 gen_resolvebranch((u1*) cd->mcodebase + brefs->branchpos,
503 brefs->branchpos, bptr->mpc);
507 /* copy interface registers to their destination */
514 while (src != NULL) {
516 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
517 /* d = reg_of_var(m, src, REG_ITMP1); */
518 if (!(src->flags & INMEMORY))
522 M_INTMOVE(REG_ITMP1, d);
523 store_reg_to_var_int(src, d);
529 while (src != NULL) {
531 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
532 d = reg_of_var(rd, src, REG_ITMP1);
533 M_INTMOVE(REG_ITMP1, d);
534 store_reg_to_var_int(src, d);
537 d = reg_of_var(rd, src, REG_IFTMP);
538 if ((src->varkind != STACKVAR)) {
540 if (IS_FLT_DBL_TYPE(s2)) {
541 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
542 s1 = rd->interfaces[len][s2].regoff;
546 M_DLD(d, REG_SP, 8 * rd->interfaces[len][s2].regoff);
548 store_reg_to_var_flt(src, d);
551 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
552 s1 = rd->interfaces[len][s2].regoff;
556 M_LLD(d, REG_SP, 8 * rd->interfaces[len][s2].regoff);
558 store_reg_to_var_int(src, d);
568 /* walk through all instructions */
572 for (iptr = bptr->iinstr;
574 src = iptr->dst, len--, iptr++) {
576 if (iptr->line!=currentline) {
577 dseg_addlinenumber(cd,iptr->line,mcodeptr);
578 currentline=iptr->line;
581 MCODECHECK(64); /* an instruction usually needs < 64 words */
584 case ICMD_NOP: /* ... ==> ... */
587 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
589 var_to_reg_int(s1, src, REG_ITMP1);
591 codegen_addxnullrefs(cd, mcodeptr);
594 /* constant operations ************************************************/
596 case ICMD_ICONST: /* ... ==> ..., constant */
597 /* op1 = 0, val.i = constant */
599 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
600 ICONST(d, iptr->val.i);
601 store_reg_to_var_int(iptr->dst, d);
604 case ICMD_LCONST: /* ... ==> ..., constant */
605 /* op1 = 0, val.l = constant */
607 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
608 LCONST(d, iptr->val.l);
609 store_reg_to_var_int(iptr->dst, d);
612 case ICMD_FCONST: /* ... ==> ..., constant */
613 /* op1 = 0, val.f = constant */
615 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
616 a = dseg_addfloat(cd, iptr->val.f);
618 store_reg_to_var_flt(iptr->dst, d);
621 case ICMD_DCONST: /* ... ==> ..., constant */
622 /* op1 = 0, val.d = constant */
624 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
625 a = dseg_adddouble(cd, iptr->val.d);
627 store_reg_to_var_flt(iptr->dst, d);
630 case ICMD_ACONST: /* ... ==> ..., constant */
631 /* op1 = 0, val.a = constant */
633 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
635 a = dseg_addaddress(cd, iptr->val.a);
638 M_INTMOVE(REG_ZERO, d);
640 store_reg_to_var_int(iptr->dst, d);
644 /* load/store operations **********************************************/
646 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
647 case ICMD_LLOAD: /* op1 = local variable */
650 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
651 if ((iptr->dst->varkind == LOCALVAR) &&
652 (iptr->dst->varnum == iptr->op1))
654 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
655 if (var->flags & INMEMORY)
656 M_LLD(d, REG_SP, 8 * var->regoff);
658 {M_INTMOVE(var->regoff,d);}
659 store_reg_to_var_int(iptr->dst, d);
662 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
663 case ICMD_DLOAD: /* op1 = local variable */
665 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
666 if ((iptr->dst->varkind == LOCALVAR) &&
667 (iptr->dst->varnum == iptr->op1))
669 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
670 if (var->flags & INMEMORY)
671 M_DLD(d, REG_SP, 8 * var->regoff);
673 {M_FLTMOVE(var->regoff,d);}
674 store_reg_to_var_flt(iptr->dst, d);
678 case ICMD_ISTORE: /* ..., value ==> ... */
679 case ICMD_LSTORE: /* op1 = local variable */
682 if ((src->varkind == LOCALVAR) &&
683 (src->varnum == iptr->op1))
685 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
686 if (var->flags & INMEMORY) {
687 var_to_reg_int(s1, src, REG_ITMP1);
688 M_LST(s1, REG_SP, 8 * var->regoff);
691 var_to_reg_int(s1, src, var->regoff);
692 M_INTMOVE(s1, var->regoff);
696 case ICMD_FSTORE: /* ..., value ==> ... */
697 case ICMD_DSTORE: /* op1 = local variable */
699 if ((src->varkind == LOCALVAR) &&
700 (src->varnum == iptr->op1))
702 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
703 if (var->flags & INMEMORY) {
704 var_to_reg_flt(s1, src, REG_FTMP1);
705 M_DST(s1, REG_SP, 8 * var->regoff);
708 var_to_reg_flt(s1, src, var->regoff);
709 M_FLTMOVE(s1, var->regoff);
714 /* pop/dup/swap operations ********************************************/
716 /* attention: double and longs are only one entry in CACAO ICMDs */
718 case ICMD_POP: /* ..., value ==> ... */
719 case ICMD_POP2: /* ..., value, value ==> ... */
722 case ICMD_DUP: /* ..., a ==> ..., a, a */
723 M_COPY(src, iptr->dst);
726 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
728 M_COPY(src, iptr->dst);
729 M_COPY(src->prev, iptr->dst->prev);
730 M_COPY(iptr->dst, iptr->dst->prev->prev);
733 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
735 M_COPY(src, iptr->dst);
736 M_COPY(src->prev, iptr->dst->prev);
737 M_COPY(src->prev->prev, iptr->dst->prev->prev);
738 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
741 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
743 M_COPY(src, iptr->dst);
744 M_COPY(src->prev, iptr->dst->prev);
747 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
749 M_COPY(src, iptr->dst);
750 M_COPY(src->prev, iptr->dst->prev);
751 M_COPY(src->prev->prev, iptr->dst->prev->prev);
752 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
753 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev);
756 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
758 M_COPY(src, iptr->dst);
759 M_COPY(src->prev, iptr->dst->prev);
760 M_COPY(src->prev->prev, iptr->dst->prev->prev);
761 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
762 M_COPY(iptr->dst, iptr->dst->prev->prev->prev->prev);
763 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev->prev);
766 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
768 M_COPY(src, iptr->dst->prev);
769 M_COPY(src->prev, iptr->dst);
773 /* integer operations *************************************************/
775 case ICMD_INEG: /* ..., value ==> ..., - value */
777 var_to_reg_int(s1, src, REG_ITMP1);
778 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
779 M_ISUB(REG_ZERO, s1, d);
780 store_reg_to_var_int(iptr->dst, d);
783 case ICMD_LNEG: /* ..., value ==> ..., - value */
785 var_to_reg_int(s1, src, REG_ITMP1);
786 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
787 M_LSUB(REG_ZERO, s1, d);
788 store_reg_to_var_int(iptr->dst, d);
791 case ICMD_I2L: /* ..., value ==> ..., value */
793 var_to_reg_int(s1, src, REG_ITMP1);
794 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
796 store_reg_to_var_int(iptr->dst, d);
799 case ICMD_L2I: /* ..., value ==> ..., value */
801 var_to_reg_int(s1, src, REG_ITMP1);
802 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
803 M_IADD(s1, REG_ZERO, d );
804 store_reg_to_var_int(iptr->dst, d);
807 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
809 var_to_reg_int(s1, src, REG_ITMP1);
810 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
811 if (has_ext_instr_set) {
815 M_SLL_IMM(s1, 56, d);
816 M_SRA_IMM( d, 56, d);
818 store_reg_to_var_int(iptr->dst, d);
821 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
823 var_to_reg_int(s1, src, REG_ITMP1);
824 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
826 store_reg_to_var_int(iptr->dst, d);
829 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
831 var_to_reg_int(s1, src, REG_ITMP1);
832 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
833 if (has_ext_instr_set) {
837 M_SLL_IMM(s1, 48, d);
838 M_SRA_IMM( d, 48, d);
840 store_reg_to_var_int(iptr->dst, d);
844 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
846 var_to_reg_int(s1, src->prev, REG_ITMP1);
847 var_to_reg_int(s2, src, REG_ITMP2);
848 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
850 store_reg_to_var_int(iptr->dst, d);
853 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
854 /* val.i = constant */
856 var_to_reg_int(s1, src, REG_ITMP1);
857 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
858 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
859 M_IADD_IMM(s1, iptr->val.i, d);
862 ICONST(REG_ITMP2, iptr->val.i);
863 M_IADD(s1, REG_ITMP2, d);
865 store_reg_to_var_int(iptr->dst, d);
868 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
870 var_to_reg_int(s1, src->prev, REG_ITMP1);
871 var_to_reg_int(s2, src, REG_ITMP2);
872 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
874 store_reg_to_var_int(iptr->dst, d);
877 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
878 /* val.l = constant */
880 var_to_reg_int(s1, src, REG_ITMP1);
881 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
882 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
883 M_LADD_IMM(s1, iptr->val.l, d);
886 LCONST(REG_ITMP2, iptr->val.l);
887 M_LADD(s1, REG_ITMP2, d);
889 store_reg_to_var_int(iptr->dst, d);
892 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
894 var_to_reg_int(s1, src->prev, REG_ITMP1);
895 var_to_reg_int(s2, src, REG_ITMP2);
896 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
898 store_reg_to_var_int(iptr->dst, d);
901 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
902 /* val.i = constant */
904 var_to_reg_int(s1, src, REG_ITMP1);
905 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
906 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
907 M_ISUB_IMM(s1, iptr->val.i, d);
910 ICONST(REG_ITMP2, iptr->val.i);
911 M_ISUB(s1, REG_ITMP2, d);
913 store_reg_to_var_int(iptr->dst, d);
916 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
918 var_to_reg_int(s1, src->prev, REG_ITMP1);
919 var_to_reg_int(s2, src, REG_ITMP2);
920 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
922 store_reg_to_var_int(iptr->dst, d);
925 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
926 /* val.l = constant */
928 var_to_reg_int(s1, src, REG_ITMP1);
929 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
930 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
931 M_LSUB_IMM(s1, iptr->val.l, d);
934 LCONST(REG_ITMP2, iptr->val.l);
935 M_LSUB(s1, REG_ITMP2, d);
937 store_reg_to_var_int(iptr->dst, d);
940 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
942 var_to_reg_int(s1, src->prev, REG_ITMP1);
943 var_to_reg_int(s2, src, REG_ITMP2);
944 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
946 store_reg_to_var_int(iptr->dst, d);
949 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
950 /* val.i = constant */
952 var_to_reg_int(s1, src, REG_ITMP1);
953 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
954 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
955 M_IMUL_IMM(s1, iptr->val.i, d);
958 ICONST(REG_ITMP2, iptr->val.i);
959 M_IMUL(s1, REG_ITMP2, d);
961 store_reg_to_var_int(iptr->dst, d);
964 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
966 var_to_reg_int(s1, src->prev, REG_ITMP1);
967 var_to_reg_int(s2, src, REG_ITMP2);
968 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
970 store_reg_to_var_int(iptr->dst, d);
973 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
974 /* val.l = constant */
976 var_to_reg_int(s1, src, REG_ITMP1);
977 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
978 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
979 M_LMUL_IMM(s1, iptr->val.l, d);
982 LCONST(REG_ITMP2, iptr->val.l);
983 M_LMUL(s1, REG_ITMP2, d);
985 store_reg_to_var_int(iptr->dst, d);
988 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
989 case ICMD_LDIVPOW2: /* val.i = constant */
991 var_to_reg_int(s1, src, REG_ITMP1);
992 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
993 if (iptr->val.i <= 15) {
994 M_LDA(REG_ITMP2, s1, (1 << iptr->val.i) -1);
995 M_CMOVGE(s1, s1, REG_ITMP2);
998 M_SRA_IMM(s1, 63, REG_ITMP2);
999 M_SRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
1000 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1002 M_SRA_IMM(REG_ITMP2, iptr->val.i, d);
1003 store_reg_to_var_int(iptr->dst, d);
1006 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1008 var_to_reg_int(s1, src->prev, REG_ITMP1);
1009 var_to_reg_int(s2, src, REG_ITMP2);
1010 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1011 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1012 M_SLL(s1, REG_ITMP3, d);
1013 M_IADD(d, REG_ZERO, d);
1014 store_reg_to_var_int(iptr->dst, d);
1017 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1018 /* val.i = constant */
1020 var_to_reg_int(s1, src, REG_ITMP1);
1021 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1022 M_SLL_IMM(s1, iptr->val.i & 0x1f, d);
1023 M_IADD(d, REG_ZERO, d);
1024 store_reg_to_var_int(iptr->dst, d);
1027 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1029 var_to_reg_int(s1, src->prev, REG_ITMP1);
1030 var_to_reg_int(s2, src, REG_ITMP2);
1031 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1032 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1033 M_SRA(s1, REG_ITMP3, d);
1034 store_reg_to_var_int(iptr->dst, d);
1037 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1038 /* val.i = constant */
1040 var_to_reg_int(s1, src, REG_ITMP1);
1041 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1042 M_SRA_IMM(s1, iptr->val.i & 0x1f, d);
1043 store_reg_to_var_int(iptr->dst, d);
1046 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1048 var_to_reg_int(s1, src->prev, REG_ITMP1);
1049 var_to_reg_int(s2, src, REG_ITMP2);
1050 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1051 M_AND_IMM(s2, 0x1f, REG_ITMP2);
1053 M_SRL(d, REG_ITMP2, d);
1054 M_IADD(d, REG_ZERO, d);
1055 store_reg_to_var_int(iptr->dst, d);
1058 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1059 /* val.i = constant */
1061 var_to_reg_int(s1, src, REG_ITMP1);
1062 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1064 M_SRL_IMM(d, iptr->val.i & 0x1f, d);
1065 M_IADD(d, REG_ZERO, d);
1066 store_reg_to_var_int(iptr->dst, d);
1069 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1071 var_to_reg_int(s1, src->prev, REG_ITMP1);
1072 var_to_reg_int(s2, src, REG_ITMP2);
1073 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1075 store_reg_to_var_int(iptr->dst, d);
1078 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1079 /* val.i = constant */
1081 var_to_reg_int(s1, src, REG_ITMP1);
1082 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1083 M_SLL_IMM(s1, iptr->val.i & 0x3f, d);
1084 store_reg_to_var_int(iptr->dst, d);
1087 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1089 var_to_reg_int(s1, src->prev, REG_ITMP1);
1090 var_to_reg_int(s2, src, REG_ITMP2);
1091 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1093 store_reg_to_var_int(iptr->dst, d);
1096 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1097 /* val.i = constant */
1099 var_to_reg_int(s1, src, REG_ITMP1);
1100 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1101 M_SRA_IMM(s1, iptr->val.i & 0x3f, d);
1102 store_reg_to_var_int(iptr->dst, d);
1105 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1107 var_to_reg_int(s1, src->prev, REG_ITMP1);
1108 var_to_reg_int(s2, src, REG_ITMP2);
1109 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1111 store_reg_to_var_int(iptr->dst, d);
1114 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1115 /* val.i = constant */
1117 var_to_reg_int(s1, src, REG_ITMP1);
1118 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1119 M_SRL_IMM(s1, iptr->val.i & 0x3f, d);
1120 store_reg_to_var_int(iptr->dst, d);
1123 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1126 var_to_reg_int(s1, src->prev, REG_ITMP1);
1127 var_to_reg_int(s2, src, REG_ITMP2);
1128 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1130 store_reg_to_var_int(iptr->dst, d);
1133 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1134 /* val.i = constant */
1136 var_to_reg_int(s1, src, REG_ITMP1);
1137 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1138 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1139 M_AND_IMM(s1, iptr->val.i, d);
1141 else if (iptr->val.i == 0xffff) {
1144 else if (iptr->val.i == 0xffffff) {
1145 M_ZAPNOT_IMM(s1, 0x07, d);
1148 ICONST(REG_ITMP2, iptr->val.i);
1149 M_AND(s1, REG_ITMP2, d);
1151 store_reg_to_var_int(iptr->dst, d);
1154 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1155 /* val.i = constant */
1157 var_to_reg_int(s1, src, REG_ITMP1);
1158 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1160 M_MOV(s1, REG_ITMP1);
1163 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1164 M_AND_IMM(s1, iptr->val.i, d);
1166 M_ISUB(REG_ZERO, s1, d);
1167 M_AND_IMM(d, iptr->val.i, d);
1169 else if (iptr->val.i == 0xffff) {
1172 M_ISUB(REG_ZERO, s1, d);
1175 else if (iptr->val.i == 0xffffff) {
1176 M_ZAPNOT_IMM(s1, 0x07, d);
1178 M_ISUB(REG_ZERO, s1, d);
1179 M_ZAPNOT_IMM(d, 0x07, d);
1182 ICONST(REG_ITMP2, iptr->val.i);
1183 M_AND(s1, REG_ITMP2, d);
1185 M_ISUB(REG_ZERO, s1, d);
1186 M_AND(d, REG_ITMP2, d);
1188 M_ISUB(REG_ZERO, d, d);
1189 store_reg_to_var_int(iptr->dst, d);
1192 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1193 /* val.l = constant */
1195 var_to_reg_int(s1, src, REG_ITMP1);
1196 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1197 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1198 M_AND_IMM(s1, iptr->val.l, d);
1200 else if (iptr->val.l == 0xffffL) {
1203 else if (iptr->val.l == 0xffffffL) {
1204 M_ZAPNOT_IMM(s1, 0x07, d);
1206 else if (iptr->val.l == 0xffffffffL) {
1209 else if (iptr->val.l == 0xffffffffffL) {
1210 M_ZAPNOT_IMM(s1, 0x1f, d);
1212 else if (iptr->val.l == 0xffffffffffffL) {
1213 M_ZAPNOT_IMM(s1, 0x3f, d);
1215 else if (iptr->val.l == 0xffffffffffffffL) {
1216 M_ZAPNOT_IMM(s1, 0x7f, d);
1219 LCONST(REG_ITMP2, iptr->val.l);
1220 M_AND(s1, REG_ITMP2, d);
1222 store_reg_to_var_int(iptr->dst, d);
1225 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1226 /* val.l = constant */
1228 var_to_reg_int(s1, src, REG_ITMP1);
1229 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1231 M_MOV(s1, REG_ITMP1);
1234 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1235 M_AND_IMM(s1, iptr->val.l, d);
1237 M_LSUB(REG_ZERO, s1, d);
1238 M_AND_IMM(d, iptr->val.l, d);
1240 else if (iptr->val.l == 0xffffL) {
1243 M_LSUB(REG_ZERO, s1, d);
1246 else if (iptr->val.l == 0xffffffL) {
1247 M_ZAPNOT_IMM(s1, 0x07, d);
1249 M_LSUB(REG_ZERO, s1, d);
1250 M_ZAPNOT_IMM(d, 0x07, d);
1252 else if (iptr->val.l == 0xffffffffL) {
1255 M_LSUB(REG_ZERO, s1, d);
1258 else if (iptr->val.l == 0xffffffffffL) {
1259 M_ZAPNOT_IMM(s1, 0x1f, d);
1261 M_LSUB(REG_ZERO, s1, d);
1262 M_ZAPNOT_IMM(d, 0x1f, d);
1264 else if (iptr->val.l == 0xffffffffffffL) {
1265 M_ZAPNOT_IMM(s1, 0x3f, d);
1267 M_LSUB(REG_ZERO, s1, d);
1268 M_ZAPNOT_IMM(d, 0x3f, d);
1270 else if (iptr->val.l == 0xffffffffffffffL) {
1271 M_ZAPNOT_IMM(s1, 0x7f, d);
1273 M_LSUB(REG_ZERO, s1, d);
1274 M_ZAPNOT_IMM(d, 0x7f, d);
1277 LCONST(REG_ITMP2, iptr->val.l);
1278 M_AND(s1, REG_ITMP2, d);
1280 M_LSUB(REG_ZERO, s1, d);
1281 M_AND(d, REG_ITMP2, d);
1283 M_LSUB(REG_ZERO, d, d);
1284 store_reg_to_var_int(iptr->dst, d);
1287 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1290 var_to_reg_int(s1, src->prev, REG_ITMP1);
1291 var_to_reg_int(s2, src, REG_ITMP2);
1292 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1294 store_reg_to_var_int(iptr->dst, d);
1297 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1298 /* val.i = constant */
1300 var_to_reg_int(s1, src, REG_ITMP1);
1301 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1302 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1303 M_OR_IMM(s1, iptr->val.i, d);
1306 ICONST(REG_ITMP2, iptr->val.i);
1307 M_OR(s1, REG_ITMP2, d);
1309 store_reg_to_var_int(iptr->dst, d);
1312 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1313 /* val.l = constant */
1315 var_to_reg_int(s1, src, REG_ITMP1);
1316 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1317 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1318 M_OR_IMM(s1, iptr->val.l, d);
1321 LCONST(REG_ITMP2, iptr->val.l);
1322 M_OR(s1, REG_ITMP2, d);
1324 store_reg_to_var_int(iptr->dst, d);
1327 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1330 var_to_reg_int(s1, src->prev, REG_ITMP1);
1331 var_to_reg_int(s2, src, REG_ITMP2);
1332 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1334 store_reg_to_var_int(iptr->dst, d);
1337 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1338 /* val.i = constant */
1340 var_to_reg_int(s1, src, REG_ITMP1);
1341 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1342 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1343 M_XOR_IMM(s1, iptr->val.i, d);
1346 ICONST(REG_ITMP2, iptr->val.i);
1347 M_XOR(s1, REG_ITMP2, d);
1349 store_reg_to_var_int(iptr->dst, d);
1352 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1353 /* val.l = constant */
1355 var_to_reg_int(s1, src, REG_ITMP1);
1356 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1357 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1358 M_XOR_IMM(s1, iptr->val.l, d);
1361 LCONST(REG_ITMP2, iptr->val.l);
1362 M_XOR(s1, REG_ITMP2, d);
1364 store_reg_to_var_int(iptr->dst, d);
1368 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1370 var_to_reg_int(s1, src->prev, REG_ITMP1);
1371 var_to_reg_int(s2, src, REG_ITMP2);
1372 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1373 M_CMPLT(s1, s2, REG_ITMP3);
1374 M_CMPLT(s2, s1, REG_ITMP1);
1375 M_LSUB (REG_ITMP1, REG_ITMP3, d);
1376 store_reg_to_var_int(iptr->dst, d);
1380 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1381 /* op1 = variable, val.i = constant */
1383 var = &(rd->locals[iptr->op1][TYPE_INT]);
1384 if (var->flags & INMEMORY) {
1386 M_LLD(s1, REG_SP, 8 * var->regoff);
1390 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1391 M_IADD_IMM(s1, iptr->val.i, s1);
1393 else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1394 M_ISUB_IMM(s1, (-iptr->val.i), s1);
1397 M_LDA (s1, s1, iptr->val.i);
1398 M_IADD(s1, REG_ZERO, s1);
1400 if (var->flags & INMEMORY)
1401 M_LST(s1, REG_SP, 8 * var->regoff);
1405 /* floating operations ************************************************/
1407 case ICMD_FNEG: /* ..., value ==> ..., - value */
1409 var_to_reg_flt(s1, src, REG_FTMP1);
1410 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1412 store_reg_to_var_flt(iptr->dst, d);
1415 case ICMD_DNEG: /* ..., value ==> ..., - value */
1417 var_to_reg_flt(s1, src, REG_FTMP1);
1418 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1420 store_reg_to_var_flt(iptr->dst, d);
1423 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1425 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1426 var_to_reg_flt(s2, src, REG_FTMP2);
1427 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1432 if (d == s1 || d == s2) {
1433 M_FADDS(s1, s2, REG_FTMP3);
1435 M_FMOV(REG_FTMP3, d);
1442 store_reg_to_var_flt(iptr->dst, d);
1445 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1447 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1448 var_to_reg_flt(s2, src, REG_FTMP2);
1449 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1454 if (d == s1 || d == s2) {
1455 M_DADDS(s1, s2, REG_FTMP3);
1457 M_FMOV(REG_FTMP3, d);
1464 store_reg_to_var_flt(iptr->dst, d);
1467 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1469 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1470 var_to_reg_flt(s2, src, REG_FTMP2);
1471 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1476 if (d == s1 || d == s2) {
1477 M_FSUBS(s1, s2, REG_FTMP3);
1479 M_FMOV(REG_FTMP3, d);
1486 store_reg_to_var_flt(iptr->dst, d);
1489 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1491 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1492 var_to_reg_flt(s2, src, REG_FTMP2);
1493 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1498 if (d == s1 || d == s2) {
1499 M_DSUBS(s1, s2, REG_FTMP3);
1501 M_FMOV(REG_FTMP3, d);
1508 store_reg_to_var_flt(iptr->dst, d);
1511 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1513 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1514 var_to_reg_flt(s2, src, REG_FTMP2);
1515 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1520 if (d == s1 || d == s2) {
1521 M_FMULS(s1, s2, REG_FTMP3);
1523 M_FMOV(REG_FTMP3, d);
1530 store_reg_to_var_flt(iptr->dst, d);
1533 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1535 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1536 var_to_reg_flt(s2, src, REG_FTMP2);
1537 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1542 if (d == s1 || d == s2) {
1543 M_DMULS(s1, s2, REG_FTMP3);
1545 M_FMOV(REG_FTMP3, d);
1552 store_reg_to_var_flt(iptr->dst, d);
1555 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1557 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1558 var_to_reg_flt(s2, src, REG_FTMP2);
1559 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1564 if (d == s1 || d == s2) {
1565 M_FDIVS(s1, s2, REG_FTMP3);
1567 M_FMOV(REG_FTMP3, d);
1574 store_reg_to_var_flt(iptr->dst, d);
1577 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1579 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1580 var_to_reg_flt(s2, src, REG_FTMP2);
1581 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1586 if (d == s1 || d == s2) {
1587 M_DDIVS(s1, s2, REG_FTMP3);
1589 M_FMOV(REG_FTMP3, d);
1596 store_reg_to_var_flt(iptr->dst, d);
1599 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1601 var_to_reg_int(s1, src, REG_ITMP1);
1602 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1603 a = dseg_adddouble(cd, 0.0);
1604 M_LST (s1, REG_PV, a);
1605 M_DLD (d, REG_PV, a);
1607 store_reg_to_var_flt(iptr->dst, d);
1610 case ICMD_I2D: /* ..., value ==> ..., (double) 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_F2I: /* ..., value ==> ..., (int) value */
1623 var_to_reg_flt(s1, src, REG_FTMP1);
1624 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1625 a = dseg_adddouble(cd, 0.0);
1626 M_CVTDL_C(s1, REG_FTMP2);
1627 M_CVTLI(REG_FTMP2, REG_FTMP3);
1628 M_DST (REG_FTMP3, REG_PV, a);
1629 M_ILD (d, REG_PV, a);
1630 store_reg_to_var_int(iptr->dst, d);
1633 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1635 var_to_reg_flt(s1, src, REG_FTMP1);
1636 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1637 a = dseg_adddouble(cd, 0.0);
1638 M_CVTDL_C(s1, REG_FTMP2);
1639 M_DST (REG_FTMP2, REG_PV, a);
1640 M_LLD (d, REG_PV, a);
1641 store_reg_to_var_int(iptr->dst, d);
1644 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1646 var_to_reg_flt(s1, src, REG_FTMP1);
1647 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1650 store_reg_to_var_flt(iptr->dst, d);
1653 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1655 var_to_reg_flt(s1, src, REG_FTMP1);
1656 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1664 store_reg_to_var_flt(iptr->dst, d);
1667 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1669 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1670 var_to_reg_flt(s2, src, REG_FTMP2);
1671 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1673 M_LSUB_IMM(REG_ZERO, 1, d);
1674 M_FCMPEQ(s1, s2, REG_FTMP3);
1675 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1677 M_FCMPLT(s2, s1, REG_FTMP3);
1678 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1679 M_LADD_IMM(REG_ZERO, 1, d);
1682 M_LSUB_IMM(REG_ZERO, 1, d);
1683 M_FCMPEQS(s1, s2, REG_FTMP3);
1685 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1687 M_FCMPLTS(s2, s1, REG_FTMP3);
1689 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1690 M_LADD_IMM(REG_ZERO, 1, d);
1692 store_reg_to_var_int(iptr->dst, d);
1695 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1697 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1698 var_to_reg_flt(s2, src, REG_FTMP2);
1699 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1701 M_LADD_IMM(REG_ZERO, 1, d);
1702 M_FCMPEQ(s1, s2, REG_FTMP3);
1703 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1705 M_FCMPLT(s1, s2, REG_FTMP3);
1706 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1707 M_LSUB_IMM(REG_ZERO, 1, d);
1710 M_LADD_IMM(REG_ZERO, 1, d);
1711 M_FCMPEQS(s1, s2, REG_FTMP3);
1713 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1715 M_FCMPLTS(s1, s2, REG_FTMP3);
1717 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1718 M_LSUB_IMM(REG_ZERO, 1, d);
1720 store_reg_to_var_int(iptr->dst, d);
1724 /* memory operations **************************************************/
1726 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1728 var_to_reg_int(s1, src, REG_ITMP1);
1729 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1730 gen_nullptr_check(s1);
1731 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1732 store_reg_to_var_int(iptr->dst, d);
1735 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1737 var_to_reg_int(s1, src->prev, REG_ITMP1);
1738 var_to_reg_int(s2, src, REG_ITMP2);
1739 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1740 if (iptr->op1 == 0) {
1741 gen_nullptr_check(s1);
1744 M_SAADDQ(s2, s1, REG_ITMP1);
1745 M_ALD( d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1746 store_reg_to_var_int(iptr->dst, d);
1749 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1751 var_to_reg_int(s1, src->prev, REG_ITMP1);
1752 var_to_reg_int(s2, src, REG_ITMP2);
1753 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1754 if (iptr->op1 == 0) {
1755 gen_nullptr_check(s1);
1758 M_S8ADDQ(s2, s1, REG_ITMP1);
1759 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1760 store_reg_to_var_int(iptr->dst, d);
1763 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1765 var_to_reg_int(s1, src->prev, REG_ITMP1);
1766 var_to_reg_int(s2, src, REG_ITMP2);
1767 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1768 if (iptr->op1 == 0) {
1769 gen_nullptr_check(s1);
1773 M_S4ADDQ(s2, s1, REG_ITMP1);
1774 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1775 store_reg_to_var_int(iptr->dst, d);
1778 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1780 var_to_reg_int(s1, src->prev, REG_ITMP1);
1781 var_to_reg_int(s2, src, REG_ITMP2);
1782 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1783 if (iptr->op1 == 0) {
1784 gen_nullptr_check(s1);
1787 M_S4ADDQ(s2, s1, REG_ITMP1);
1788 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1789 store_reg_to_var_flt(iptr->dst, d);
1792 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1794 var_to_reg_int(s1, src->prev, REG_ITMP1);
1795 var_to_reg_int(s2, src, REG_ITMP2);
1796 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1797 if (iptr->op1 == 0) {
1798 gen_nullptr_check(s1);
1801 M_S8ADDQ(s2, s1, REG_ITMP1);
1802 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1803 store_reg_to_var_flt(iptr->dst, d);
1806 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1808 var_to_reg_int(s1, src->prev, REG_ITMP1);
1809 var_to_reg_int(s2, src, REG_ITMP2);
1810 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1811 if (iptr->op1 == 0) {
1812 gen_nullptr_check(s1);
1815 if (has_ext_instr_set) {
1816 M_LADD(s2, s1, REG_ITMP1);
1817 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1818 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1821 M_LADD (s2, s1, REG_ITMP1);
1822 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1823 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1824 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1825 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
1827 store_reg_to_var_int(iptr->dst, d);
1830 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1832 var_to_reg_int(s1, src->prev, REG_ITMP1);
1833 var_to_reg_int(s2, src, REG_ITMP2);
1834 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1835 if (iptr->op1 == 0) {
1836 gen_nullptr_check(s1);
1839 if (has_ext_instr_set) {
1840 M_LADD(s2, s1, REG_ITMP1);
1841 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1842 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1846 M_LADD(s2, s1, REG_ITMP1);
1847 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1848 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1849 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1850 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1851 M_SRA_IMM(d, 48, d);
1853 store_reg_to_var_int(iptr->dst, d);
1856 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1858 var_to_reg_int(s1, src->prev, REG_ITMP1);
1859 var_to_reg_int(s2, src, REG_ITMP2);
1860 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1861 if (iptr->op1 == 0) {
1862 gen_nullptr_check(s1);
1865 if (has_ext_instr_set) {
1866 M_LADD (s2, s1, REG_ITMP1);
1867 M_BLDU (d, REG_ITMP1, OFFSET (java_bytearray, data[0]));
1871 M_LADD(s2, s1, REG_ITMP1);
1872 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1873 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
1874 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1875 M_SRA_IMM(d, 56, d);
1877 store_reg_to_var_int(iptr->dst, d);
1881 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1883 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1884 var_to_reg_int(s2, src->prev, REG_ITMP2);
1885 if (iptr->op1 == 0) {
1886 gen_nullptr_check(s1);
1889 var_to_reg_int(s3, src, REG_ITMP3);
1890 M_SAADDQ(s2, s1, REG_ITMP1);
1891 M_AST (s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1894 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1896 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1897 var_to_reg_int(s2, src->prev, REG_ITMP2);
1898 if (iptr->op1 == 0) {
1899 gen_nullptr_check(s1);
1902 var_to_reg_int(s3, src, REG_ITMP3);
1903 M_S8ADDQ(s2, s1, REG_ITMP1);
1904 M_LST (s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1907 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1909 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1910 var_to_reg_int(s2, src->prev, REG_ITMP2);
1911 if (iptr->op1 == 0) {
1912 gen_nullptr_check(s1);
1916 var_to_reg_int(s3, src, REG_ITMP3);
1917 M_S4ADDQ(s2, s1, REG_ITMP1);
1918 M_IST (s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1921 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1923 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1924 var_to_reg_int(s2, src->prev, REG_ITMP2);
1925 if (iptr->op1 == 0) {
1926 gen_nullptr_check(s1);
1929 var_to_reg_flt(s3, src, REG_FTMP3);
1930 M_S4ADDQ(s2, s1, REG_ITMP1);
1931 M_FST (s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1934 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1936 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1937 var_to_reg_int(s2, src->prev, REG_ITMP2);
1938 if (iptr->op1 == 0) {
1939 gen_nullptr_check(s1);
1942 var_to_reg_flt(s3, src, REG_FTMP3);
1943 M_S8ADDQ(s2, s1, REG_ITMP1);
1944 M_DST (s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1947 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1949 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1950 var_to_reg_int(s2, src->prev, REG_ITMP2);
1951 if (iptr->op1 == 0) {
1952 gen_nullptr_check(s1);
1955 var_to_reg_int(s3, src, REG_ITMP3);
1956 if (has_ext_instr_set) {
1957 M_LADD(s2, s1, REG_ITMP1);
1958 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1959 M_SST (s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1962 M_LADD (s2, s1, REG_ITMP1);
1963 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1964 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1965 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1966 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1967 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1968 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
1969 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1973 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1975 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1976 var_to_reg_int(s2, src->prev, REG_ITMP2);
1977 if (iptr->op1 == 0) {
1978 gen_nullptr_check(s1);
1981 var_to_reg_int(s3, src, REG_ITMP3);
1982 if (has_ext_instr_set) {
1983 M_LADD(s2, s1, REG_ITMP1);
1984 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1985 M_SST (s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1988 M_LADD (s2, s1, REG_ITMP1);
1989 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1990 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1991 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1992 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1993 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1994 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
1995 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1999 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
2001 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2002 var_to_reg_int(s2, src->prev, REG_ITMP2);
2003 if (iptr->op1 == 0) {
2004 gen_nullptr_check(s1);
2007 var_to_reg_int(s3, src, REG_ITMP3);
2008 if (has_ext_instr_set) {
2009 M_LADD(s2, s1, REG_ITMP1);
2010 M_BST (s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2013 M_LADD (s2, s1, REG_ITMP1);
2014 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2015 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2016 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
2017 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2018 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2019 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2024 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
2026 var_to_reg_int(s1, src->prev, REG_ITMP1);
2027 var_to_reg_int(s2, src, REG_ITMP2);
2028 if (iptr->op1 == 0) {
2029 gen_nullptr_check(s1);
2032 M_S4ADDQ(s2, s1, REG_ITMP1);
2033 M_IST(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
2036 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
2038 var_to_reg_int(s1, src->prev, REG_ITMP1);
2039 var_to_reg_int(s2, src, REG_ITMP2);
2040 if (iptr->op1 == 0) {
2041 gen_nullptr_check(s1);
2044 M_S8ADDQ(s2, s1, REG_ITMP1);
2045 M_LST(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
2048 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
2050 var_to_reg_int(s1, src->prev, REG_ITMP1);
2051 var_to_reg_int(s2, src, REG_ITMP2);
2052 if (iptr->op1 == 0) {
2053 gen_nullptr_check(s1);
2056 M_SAADDQ(s2, s1, REG_ITMP1);
2057 M_AST(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
2060 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
2062 var_to_reg_int(s1, src->prev, REG_ITMP1);
2063 var_to_reg_int(s2, src, REG_ITMP2);
2064 if (iptr->op1 == 0) {
2065 gen_nullptr_check(s1);
2068 if (has_ext_instr_set) {
2069 M_LADD(s2, s1, REG_ITMP1);
2070 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2073 M_LADD(s2, s1, REG_ITMP1);
2074 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2075 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2076 M_INSBL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2077 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2078 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2079 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2083 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
2085 var_to_reg_int(s1, src->prev, REG_ITMP1);
2086 var_to_reg_int(s2, src, REG_ITMP2);
2087 if (iptr->op1 == 0) {
2088 gen_nullptr_check(s1);
2091 if (has_ext_instr_set) {
2092 M_LADD(s2, s1, REG_ITMP1);
2093 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2094 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
2097 M_LADD(s2, s1, REG_ITMP1);
2098 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2099 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2100 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2101 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2102 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2103 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2104 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2108 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
2110 var_to_reg_int(s1, src->prev, REG_ITMP1);
2111 var_to_reg_int(s2, src, REG_ITMP2);
2112 if (iptr->op1 == 0) {
2113 gen_nullptr_check(s1);
2116 if (has_ext_instr_set) {
2117 M_LADD(s2, s1, REG_ITMP1);
2118 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2119 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2122 M_LADD(s2, s1, REG_ITMP1);
2123 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2124 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2125 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2126 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2127 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2128 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2129 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2134 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2135 /* op1 = type, val.a = field address */
2137 /* If the static fields' class is not yet initialized, we do it */
2138 /* now. The call code is generated later. */
2139 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
2140 codegen_addclinitref(cd, mcodeptr, ((fieldinfo *) iptr->val.a)->class);
2142 /* This is just for debugging purposes. Is very difficult to */
2143 /* read patched code. Here we patch the following 2 nop's */
2144 /* so that the real code keeps untouched. */
2145 if (showdisassemble) {
2150 a = dseg_addaddress(cd, &(((fieldinfo *)(iptr->val.a))->value));
2151 M_ALD(REG_ITMP1, REG_PV, a);
2152 switch (iptr->op1) {
2154 var_to_reg_int(s2, src, REG_ITMP2);
2155 M_IST(s2, REG_ITMP1, 0);
2158 var_to_reg_int(s2, src, REG_ITMP2);
2159 M_LST(s2, REG_ITMP1, 0);
2162 var_to_reg_int(s2, src, REG_ITMP2);
2163 M_AST(s2, REG_ITMP1, 0);
2166 var_to_reg_flt(s2, src, REG_FTMP2);
2167 M_FST(s2, REG_ITMP1, 0);
2170 var_to_reg_flt(s2, src, REG_FTMP2);
2171 M_DST(s2, REG_ITMP1, 0);
2173 default: panic ("internal error");
2177 case ICMD_GETSTATIC: /* ... ==> ..., value */
2178 /* op1 = type, val.a = field address */
2180 /* if class isn't yet initialized, do it */
2181 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
2182 codegen_addclinitref(cd, mcodeptr, ((fieldinfo *) iptr->val.a)->class);
2184 /* This is just for debugging purposes. Is very difficult to */
2185 /* read patched code. Here we patch the following 2 nop's */
2186 /* so that the real code keeps untouched. */
2187 if (showdisassemble) {
2192 a = dseg_addaddress(cd, &(((fieldinfo *) iptr->val.a)->value));
2193 M_ALD(REG_ITMP1, REG_PV, a);
2194 switch (iptr->op1) {
2196 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2197 M_ILD(d, REG_ITMP1, 0);
2198 store_reg_to_var_int(iptr->dst, d);
2201 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2202 M_LLD(d, REG_ITMP1, 0);
2203 store_reg_to_var_int(iptr->dst, d);
2206 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2207 M_ALD(d, REG_ITMP1, 0);
2208 store_reg_to_var_int(iptr->dst, d);
2211 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2212 M_FLD(d, REG_ITMP1, 0);
2213 store_reg_to_var_flt(iptr->dst, d);
2216 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2217 M_DLD(d, REG_ITMP1, 0);
2218 store_reg_to_var_flt(iptr->dst, d);
2220 default: panic ("internal error");
2225 case ICMD_PUTFIELD: /* ..., value ==> ... */
2226 /* op1 = type, val.i = field offset */
2228 a = ((fieldinfo *) iptr->val.a)->offset;
2229 switch (iptr->op1) {
2231 var_to_reg_int(s1, src->prev, REG_ITMP1);
2232 var_to_reg_int(s2, src, REG_ITMP2);
2233 gen_nullptr_check(s1);
2237 var_to_reg_int(s1, src->prev, REG_ITMP1);
2238 var_to_reg_int(s2, src, REG_ITMP2);
2239 gen_nullptr_check(s1);
2243 var_to_reg_int(s1, src->prev, REG_ITMP1);
2244 var_to_reg_int(s2, src, REG_ITMP2);
2245 gen_nullptr_check(s1);
2249 var_to_reg_int(s1, src->prev, REG_ITMP1);
2250 var_to_reg_flt(s2, src, REG_FTMP2);
2251 gen_nullptr_check(s1);
2255 var_to_reg_int(s1, src->prev, REG_ITMP1);
2256 var_to_reg_flt(s2, src, REG_FTMP2);
2257 gen_nullptr_check(s1);
2260 default: panic ("internal error");
2264 case ICMD_GETFIELD: /* ... ==> ..., value */
2265 /* op1 = type, val.i = field offset */
2267 a = ((fieldinfo *)(iptr->val.a))->offset;
2268 switch (iptr->op1) {
2270 var_to_reg_int(s1, src, REG_ITMP1);
2271 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2272 gen_nullptr_check(s1);
2274 store_reg_to_var_int(iptr->dst, d);
2277 var_to_reg_int(s1, src, REG_ITMP1);
2278 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2279 gen_nullptr_check(s1);
2281 store_reg_to_var_int(iptr->dst, d);
2284 var_to_reg_int(s1, src, REG_ITMP1);
2285 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2286 gen_nullptr_check(s1);
2288 store_reg_to_var_int(iptr->dst, d);
2291 var_to_reg_int(s1, src, REG_ITMP1);
2292 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2293 gen_nullptr_check(s1);
2295 store_reg_to_var_flt(iptr->dst, d);
2298 var_to_reg_int(s1, src, REG_ITMP1);
2299 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2300 gen_nullptr_check(s1);
2302 store_reg_to_var_flt(iptr->dst, d);
2304 default: panic ("internal error");
2309 /* branch operations **************************************************/
2311 #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}}
2313 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2315 var_to_reg_int(s1, src, REG_ITMP1);
2316 M_INTMOVE(s1, REG_ITMP1_XPTR);
2317 a = dseg_addaddress(cd, asm_handle_exception);
2318 M_ALD(REG_ITMP2, REG_PV, a);
2319 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2320 M_NOP; /* nop ensures that XPC is less than the end */
2321 /* of basic block */
2325 case ICMD_GOTO: /* ... ==> ... */
2326 /* op1 = target JavaVM pc */
2328 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2332 case ICMD_JSR: /* ... ==> ... */
2333 /* op1 = target JavaVM pc */
2335 M_BSR(REG_ITMP1, 0);
2336 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2339 case ICMD_RET: /* ... ==> ... */
2340 /* op1 = local variable */
2342 var = &(rd->locals[iptr->op1][TYPE_ADR]);
2343 if (var->flags & INMEMORY) {
2344 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2345 M_RET(REG_ZERO, REG_ITMP1);
2348 M_RET(REG_ZERO, var->regoff);
2352 case ICMD_IFNULL: /* ..., value ==> ... */
2353 /* op1 = target JavaVM pc */
2355 var_to_reg_int(s1, src, REG_ITMP1);
2357 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2360 case ICMD_IFNONNULL: /* ..., value ==> ... */
2361 /* op1 = target JavaVM pc */
2363 var_to_reg_int(s1, src, REG_ITMP1);
2365 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2368 case ICMD_IFEQ: /* ..., value ==> ... */
2369 /* op1 = target JavaVM pc, val.i = constant */
2371 var_to_reg_int(s1, src, REG_ITMP1);
2372 if (iptr->val.i == 0) {
2376 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2377 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2380 ICONST(REG_ITMP2, iptr->val.i);
2381 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2383 M_BNEZ(REG_ITMP1, 0);
2385 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2388 case ICMD_IFLT: /* ..., value ==> ... */
2389 /* op1 = target JavaVM pc, val.i = constant */
2391 var_to_reg_int(s1, src, REG_ITMP1);
2392 if (iptr->val.i == 0) {
2396 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2397 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2400 ICONST(REG_ITMP2, iptr->val.i);
2401 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2403 M_BNEZ(REG_ITMP1, 0);
2405 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2408 case ICMD_IFLE: /* ..., value ==> ... */
2409 /* op1 = target JavaVM pc, val.i = constant */
2411 var_to_reg_int(s1, src, REG_ITMP1);
2412 if (iptr->val.i == 0) {
2416 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2417 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2420 ICONST(REG_ITMP2, iptr->val.i);
2421 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2423 M_BNEZ(REG_ITMP1, 0);
2425 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2428 case ICMD_IFNE: /* ..., value ==> ... */
2429 /* op1 = target JavaVM pc, val.i = constant */
2431 var_to_reg_int(s1, src, REG_ITMP1);
2432 if (iptr->val.i == 0) {
2436 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2437 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2440 ICONST(REG_ITMP2, iptr->val.i);
2441 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2443 M_BEQZ(REG_ITMP1, 0);
2445 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2448 case ICMD_IFGT: /* ..., value ==> ... */
2449 /* op1 = target JavaVM pc, val.i = constant */
2451 var_to_reg_int(s1, src, REG_ITMP1);
2452 if (iptr->val.i == 0) {
2456 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2457 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2460 ICONST(REG_ITMP2, iptr->val.i);
2461 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2463 M_BEQZ(REG_ITMP1, 0);
2465 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2468 case ICMD_IFGE: /* ..., value ==> ... */
2469 /* op1 = target JavaVM pc, val.i = constant */
2471 var_to_reg_int(s1, src, REG_ITMP1);
2472 if (iptr->val.i == 0) {
2476 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2477 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2480 ICONST(REG_ITMP2, iptr->val.i);
2481 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2483 M_BEQZ(REG_ITMP1, 0);
2485 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2488 case ICMD_IF_LEQ: /* ..., value ==> ... */
2489 /* op1 = target JavaVM pc, val.l = constant */
2491 var_to_reg_int(s1, src, REG_ITMP1);
2492 if (iptr->val.l == 0) {
2496 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2497 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2500 LCONST(REG_ITMP2, iptr->val.l);
2501 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2503 M_BNEZ(REG_ITMP1, 0);
2505 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2508 case ICMD_IF_LLT: /* ..., value ==> ... */
2509 /* op1 = target JavaVM pc, val.l = constant */
2511 var_to_reg_int(s1, src, REG_ITMP1);
2512 if (iptr->val.l == 0) {
2516 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2517 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2520 LCONST(REG_ITMP2, iptr->val.l);
2521 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2523 M_BNEZ(REG_ITMP1, 0);
2525 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2528 case ICMD_IF_LLE: /* ..., value ==> ... */
2529 /* op1 = target JavaVM pc, val.l = constant */
2531 var_to_reg_int(s1, src, REG_ITMP1);
2532 if (iptr->val.l == 0) {
2536 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2537 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2540 LCONST(REG_ITMP2, iptr->val.l);
2541 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2543 M_BNEZ(REG_ITMP1, 0);
2545 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2548 case ICMD_IF_LNE: /* ..., value ==> ... */
2549 /* op1 = target JavaVM pc, val.l = constant */
2551 var_to_reg_int(s1, src, REG_ITMP1);
2552 if (iptr->val.l == 0) {
2556 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2557 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2560 LCONST(REG_ITMP2, iptr->val.l);
2561 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2563 M_BEQZ(REG_ITMP1, 0);
2565 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2568 case ICMD_IF_LGT: /* ..., value ==> ... */
2569 /* op1 = target JavaVM pc, val.l = constant */
2571 var_to_reg_int(s1, src, REG_ITMP1);
2572 if (iptr->val.l == 0) {
2576 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2577 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2580 LCONST(REG_ITMP2, iptr->val.l);
2581 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2583 M_BEQZ(REG_ITMP1, 0);
2585 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2588 case ICMD_IF_LGE: /* ..., value ==> ... */
2589 /* op1 = target JavaVM pc, val.l = constant */
2591 var_to_reg_int(s1, src, REG_ITMP1);
2592 if (iptr->val.l == 0) {
2596 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2597 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2600 LCONST(REG_ITMP2, iptr->val.l);
2601 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2603 M_BEQZ(REG_ITMP1, 0);
2605 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2608 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2609 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2610 case ICMD_IF_ACMPEQ:
2612 var_to_reg_int(s1, src->prev, REG_ITMP1);
2613 var_to_reg_int(s2, src, REG_ITMP2);
2614 M_CMPEQ(s1, s2, REG_ITMP1);
2615 M_BNEZ(REG_ITMP1, 0);
2616 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2619 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2620 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2621 case ICMD_IF_ACMPNE:
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_BEQZ(REG_ITMP1, 0);
2627 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2630 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2631 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2633 var_to_reg_int(s1, src->prev, REG_ITMP1);
2634 var_to_reg_int(s2, src, REG_ITMP2);
2635 M_CMPLT(s1, s2, REG_ITMP1);
2636 M_BNEZ(REG_ITMP1, 0);
2637 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2640 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2641 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2643 var_to_reg_int(s1, src->prev, REG_ITMP1);
2644 var_to_reg_int(s2, src, REG_ITMP2);
2645 M_CMPLE(s1, s2, REG_ITMP1);
2646 M_BEQZ(REG_ITMP1, 0);
2647 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2650 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2651 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2653 var_to_reg_int(s1, src->prev, REG_ITMP1);
2654 var_to_reg_int(s2, src, REG_ITMP2);
2655 M_CMPLE(s1, s2, REG_ITMP1);
2656 M_BNEZ(REG_ITMP1, 0);
2657 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2660 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2661 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2663 var_to_reg_int(s1, src->prev, REG_ITMP1);
2664 var_to_reg_int(s2, src, REG_ITMP2);
2665 M_CMPLT(s1, s2, REG_ITMP1);
2666 M_BEQZ(REG_ITMP1, 0);
2667 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2670 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2672 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2675 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2676 /* val.i = constant */
2678 var_to_reg_int(s1, src, REG_ITMP1);
2679 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2681 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2682 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2683 M_CMPEQ(s1, REG_ZERO, d);
2684 store_reg_to_var_int(iptr->dst, d);
2687 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2688 M_CMPEQ(s1, REG_ZERO, d);
2690 store_reg_to_var_int(iptr->dst, d);
2694 M_MOV(s1, REG_ITMP1);
2697 ICONST(d, iptr[1].val.i);
2699 if ((s3 >= 0) && (s3 <= 255)) {
2700 M_CMOVEQ_IMM(s1, s3, d);
2703 ICONST(REG_ITMP2, s3);
2704 M_CMOVEQ(s1, REG_ITMP2, d);
2706 store_reg_to_var_int(iptr->dst, d);
2709 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2710 /* val.i = constant */
2712 var_to_reg_int(s1, src, REG_ITMP1);
2713 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2715 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2716 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2717 M_CMPEQ(s1, REG_ZERO, d);
2718 store_reg_to_var_int(iptr->dst, d);
2721 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2722 M_CMPEQ(s1, REG_ZERO, d);
2724 store_reg_to_var_int(iptr->dst, d);
2728 M_MOV(s1, REG_ITMP1);
2731 ICONST(d, iptr[1].val.i);
2733 if ((s3 >= 0) && (s3 <= 255)) {
2734 M_CMOVNE_IMM(s1, s3, d);
2737 ICONST(REG_ITMP2, s3);
2738 M_CMOVNE(s1, REG_ITMP2, d);
2740 store_reg_to_var_int(iptr->dst, d);
2743 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2744 /* val.i = constant */
2746 var_to_reg_int(s1, src, REG_ITMP1);
2747 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2749 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2750 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2751 M_CMPLT(s1, REG_ZERO, d);
2752 store_reg_to_var_int(iptr->dst, d);
2755 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2756 M_CMPLE(REG_ZERO, s1, d);
2757 store_reg_to_var_int(iptr->dst, d);
2761 M_MOV(s1, REG_ITMP1);
2764 ICONST(d, iptr[1].val.i);
2766 if ((s3 >= 0) && (s3 <= 255)) {
2767 M_CMOVLT_IMM(s1, s3, d);
2770 ICONST(REG_ITMP2, s3);
2771 M_CMOVLT(s1, REG_ITMP2, d);
2773 store_reg_to_var_int(iptr->dst, d);
2776 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2777 /* val.i = constant */
2779 var_to_reg_int(s1, src, REG_ITMP1);
2780 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2782 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2783 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2784 M_CMPLE(REG_ZERO, s1, d);
2785 store_reg_to_var_int(iptr->dst, d);
2788 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2789 M_CMPLT(s1, REG_ZERO, d);
2790 store_reg_to_var_int(iptr->dst, d);
2794 M_MOV(s1, REG_ITMP1);
2797 ICONST(d, iptr[1].val.i);
2799 if ((s3 >= 0) && (s3 <= 255)) {
2800 M_CMOVGE_IMM(s1, s3, d);
2803 ICONST(REG_ITMP2, s3);
2804 M_CMOVGE(s1, REG_ITMP2, d);
2806 store_reg_to_var_int(iptr->dst, d);
2809 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2810 /* val.i = constant */
2812 var_to_reg_int(s1, src, REG_ITMP1);
2813 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2815 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2816 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2817 M_CMPLT(REG_ZERO, s1, d);
2818 store_reg_to_var_int(iptr->dst, d);
2821 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2822 M_CMPLE(s1, REG_ZERO, d);
2823 store_reg_to_var_int(iptr->dst, d);
2827 M_MOV(s1, REG_ITMP1);
2830 ICONST(d, iptr[1].val.i);
2832 if ((s3 >= 0) && (s3 <= 255)) {
2833 M_CMOVGT_IMM(s1, s3, d);
2836 ICONST(REG_ITMP2, s3);
2837 M_CMOVGT(s1, REG_ITMP2, d);
2839 store_reg_to_var_int(iptr->dst, d);
2842 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2843 /* val.i = constant */
2845 var_to_reg_int(s1, src, REG_ITMP1);
2846 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2848 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2849 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2850 M_CMPLE(s1, REG_ZERO, d);
2851 store_reg_to_var_int(iptr->dst, d);
2854 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2855 M_CMPLT(REG_ZERO, s1, d);
2856 store_reg_to_var_int(iptr->dst, d);
2860 M_MOV(s1, REG_ITMP1);
2863 ICONST(d, iptr[1].val.i);
2865 if ((s3 >= 0) && (s3 <= 255)) {
2866 M_CMOVLE_IMM(s1, s3, d);
2869 ICONST(REG_ITMP2, s3);
2870 M_CMOVLE(s1, REG_ITMP2, d);
2872 store_reg_to_var_int(iptr->dst, d);
2876 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2880 var_to_reg_int(s1, src, REG_RESULT);
2881 M_INTMOVE(s1, REG_RESULT);
2883 #if defined(USE_THREADS)
2884 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2886 a = dseg_addaddress(cd, (void *) (builtin_monitorexit));
2887 M_ALD(REG_PV, REG_PV, a);
2888 M_ALD(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
2889 M_LST(REG_RESULT, REG_SP, rd->maxmemuse * 8);
2890 M_JSR(REG_RA, REG_PV);
2891 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
2892 M_LDA(REG_PV, REG_RA, disp);
2893 M_LLD(REG_RESULT, REG_SP, rd->maxmemuse * 8);
2897 goto nowperformreturn;
2899 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2902 var_to_reg_flt(s1, src, REG_FRESULT);
2903 M_FLTMOVE(s1, REG_FRESULT);
2905 #if defined(USE_THREADS)
2906 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2908 a = dseg_addaddress(cd, (void *) (builtin_monitorexit));
2909 M_ALD(REG_PV, REG_PV, a);
2910 M_ALD(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
2911 M_DST(REG_FRESULT, REG_SP, rd->maxmemuse * 8);
2912 M_JSR(REG_RA, REG_PV);
2913 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
2914 M_LDA(REG_PV, REG_RA, disp);
2915 M_DLD(REG_FRESULT, REG_SP, rd->maxmemuse * 8);
2919 goto nowperformreturn;
2921 case ICMD_RETURN: /* ... ==> ... */
2923 #if defined(USE_THREADS)
2924 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2926 a = dseg_addaddress(cd, (void *) (builtin_monitorexit));
2927 M_ALD(REG_PV, REG_PV, a);
2928 M_ALD(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
2929 M_JSR(REG_RA, REG_PV);
2930 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
2931 M_LDA(REG_PV, REG_RA, disp);
2939 p = parentargs_base;
2941 /* restore return address */
2943 if (!m->isleafmethod) {
2944 p--; M_LLD(REG_RA, REG_SP, p * 8);
2947 /* restore saved registers */
2949 for (i = rd->savintregcnt - 1; i >= rd->maxsavintreguse; i--) {
2950 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2952 for (i = rd->savfltregcnt - 1; i >= rd->maxsavfltreguse; i--) {
2953 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2956 /* deallocate stack */
2958 if (parentargs_base) {
2959 M_LDA(REG_SP, REG_SP, parentargs_base * 8);
2962 /* call trace function */
2965 M_LDA(REG_SP, REG_SP, -3 * 8);
2966 M_AST(REG_RA, REG_SP, 0 * 8);
2967 M_LST(REG_RESULT, REG_SP, 1 * 8);
2968 M_DST(REG_FRESULT, REG_SP, 2 * 8);
2969 a = dseg_addaddress(cd, m);
2970 M_ALD(rd->argintregs[0], REG_PV, a);
2971 M_MOV(REG_RESULT, rd->argintregs[1]);
2972 M_FLTMOVE(REG_FRESULT, rd->argfltregs[2]);
2973 M_FLTMOVE(REG_FRESULT, rd->argfltregs[3]);
2974 a = dseg_addaddress(cd, (void *) builtin_displaymethodstop);
2975 M_ALD(REG_PV, REG_PV, a);
2976 M_JSR(REG_RA, REG_PV);
2977 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
2978 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
2980 s4 ml = -s1, mh = 0;
2981 while (ml < -32768) { ml += 65536; mh--; }
2982 M_LDA(REG_PV, REG_RA, ml);
2983 M_LDAH(REG_PV, REG_PV, mh);
2985 M_DLD(REG_FRESULT, REG_SP, 2 * 8);
2986 M_LLD(REG_RESULT, REG_SP, 1 * 8);
2987 M_ALD(REG_RA, REG_SP, 0 * 8);
2988 M_LDA(REG_SP, REG_SP, 3 * 8);
2991 M_RET(REG_ZERO, REG_RA);
2997 case ICMD_TABLESWITCH: /* ..., index ==> ... */
3002 tptr = (void **) iptr->target;
3004 s4ptr = iptr->val.a;
3005 l = s4ptr[1]; /* low */
3006 i = s4ptr[2]; /* high */
3008 var_to_reg_int(s1, src, REG_ITMP1);
3010 {M_INTMOVE(s1, REG_ITMP1);}
3011 else if (l <= 32768) {
3012 M_LDA(REG_ITMP1, s1, -l);
3015 ICONST(REG_ITMP2, l);
3016 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
3023 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
3025 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
3026 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3028 M_BEQZ(REG_ITMP2, 0);
3031 /* codegen_addreference(cd, BlockPtrOfPC(s4ptr[0]), mcodeptr); */
3032 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3034 /* build jump table top down and use address of lowest entry */
3036 /* s4ptr += 3 + i; */
3040 /* dseg_addtarget(cd, BlockPtrOfPC(*--s4ptr)); */
3041 dseg_addtarget(cd, (basicblock *) tptr[0]);
3046 /* length of dataseg after last dseg_addtarget is used by load */
3048 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
3049 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
3050 M_JMP(REG_ZERO, REG_ITMP2);
3055 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3057 s4 i, l, val, *s4ptr;
3060 tptr = (void **) iptr->target;
3062 s4ptr = iptr->val.a;
3063 l = s4ptr[0]; /* default */
3064 i = s4ptr[1]; /* count */
3066 MCODECHECK((i<<2)+8);
3067 var_to_reg_int(s1, src, REG_ITMP1);
3073 if ((val >= 0) && (val <= 255)) {
3074 M_CMPEQ_IMM(s1, val, REG_ITMP2);
3077 if ((val >= -32768) && (val <= 32767)) {
3078 M_LDA(REG_ITMP2, REG_ZERO, val);
3081 a = dseg_adds4(cd, val);
3082 M_ILD(REG_ITMP2, REG_PV, a);
3084 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
3086 M_BNEZ(REG_ITMP2, 0);
3087 /* codegen_addreference(cd, BlockPtrOfPC(s4ptr[1]), mcodeptr); */
3088 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3092 /* codegen_addreference(cd, BlockPtrOfPC(l), mcodeptr); */
3094 tptr = (void **) iptr->target;
3095 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3102 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
3103 /* op1 = return type, val.a = function pointer*/
3107 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
3108 /* op1 = return type, val.a = function pointer*/
3112 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
3113 /* op1 = return type, val.a = function pointer*/
3117 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3118 /* op1 = arg count, val.a = method pointer */
3120 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3121 /* op1 = arg count, val.a = method pointer */
3123 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3124 /* op1 = arg count, val.a = method pointer */
3126 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
3127 /* op1 = arg count, val.a = method pointer */
3134 MCODECHECK((s3 << 1) + 64);
3136 /* copy arguments to registers or stack location */
3138 for (; --s3 >= 0; src = src->prev) {
3139 if (src->varkind == ARGVAR)
3141 if (IS_INT_LNG_TYPE(src->type)) {
3142 if (s3 < INT_ARG_CNT) {
3143 s1 = rd->argintregs[s3];
3144 var_to_reg_int(d, src, s1);
3148 var_to_reg_int(d, src, REG_ITMP1);
3149 M_LST(d, REG_SP, 8 * (s3 - INT_ARG_CNT));
3153 if (s3 < FLT_ARG_CNT) {
3154 s1 = rd->argfltregs[s3];
3155 var_to_reg_flt(d, src, s1);
3159 var_to_reg_flt(d, src, REG_FTMP1);
3160 M_DST(d, REG_SP, 8 * (s3 - FLT_ARG_CNT));
3166 switch (iptr->opc) {
3170 a = dseg_addaddress(cd, (void *) lm);
3173 M_ALD(REG_PV, REG_PV, a); /* Pointer to built-in-function */
3176 case ICMD_INVOKESTATIC:
3177 case ICMD_INVOKESPECIAL:
3178 a = dseg_addaddress(cd, lm->stubroutine);
3181 M_ALD(REG_PV, REG_PV, a); /* method pointer in r27 */
3184 case ICMD_INVOKEVIRTUAL:
3187 gen_nullptr_check(rd->argintregs[0]);
3188 M_ALD(REG_METHODPTR, rd->argintregs[0],
3189 OFFSET(java_objectheader, vftbl));
3190 M_ALD(REG_PV, REG_METHODPTR, OFFSET(vftbl_t, table[0]) +
3191 sizeof(methodptr) * lm->vftblindex);
3194 case ICMD_INVOKEINTERFACE:
3197 gen_nullptr_check(rd->argintregs[0]);
3198 M_ALD(REG_METHODPTR, rd->argintregs[0],
3199 OFFSET(java_objectheader, vftbl));
3200 M_ALD(REG_METHODPTR, REG_METHODPTR,
3201 OFFSET(vftbl_t, interfacetable[0]) -
3202 sizeof(methodptr*) * lm->class->index);
3203 M_ALD(REG_PV, REG_METHODPTR,
3204 sizeof(methodptr) * (lm - lm->class->methods));
3208 M_JSR(REG_RA, REG_PV);
3212 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3213 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3215 s4 ml = -s1, mh = 0;
3216 while (ml < -32768) { ml += 65536; mh--; }
3217 M_LDA(REG_PV, REG_RA, ml);
3218 M_LDAH(REG_PV, REG_PV, mh);
3221 /* d contains return type */
3223 if (d != TYPE_VOID) {
3224 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3225 s1 = reg_of_var(rd, iptr->dst, REG_RESULT);
3226 M_INTMOVE(REG_RESULT, s1);
3227 store_reg_to_var_int(iptr->dst, s1);
3230 s1 = reg_of_var(rd, iptr->dst, REG_FRESULT);
3231 M_FLTMOVE(REG_FRESULT, s1);
3232 store_reg_to_var_flt(iptr->dst, s1);
3239 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3241 /* op1: 0 == array, 1 == class */
3242 /* val.a: (classinfo*) superclass */
3244 /* superclass is an interface:
3246 * return (sub != NULL) &&
3247 * (sub->vftbl->interfacetablelength > super->index) &&
3248 * (sub->vftbl->interfacetable[-super->index] != NULL);
3250 * superclass is a class:
3252 * return ((sub != NULL) && (0
3253 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3254 * super->vftbl->diffvall));
3258 classinfo *super = (classinfo*) iptr->val.a;
3260 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3261 codegen_threadcritrestart(cd, (u1 *) mcodeptr - cd->mcodebase);
3263 var_to_reg_int(s1, src, REG_ITMP1);
3264 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
3266 M_MOV(s1, REG_ITMP1);
3270 if (iptr->op1) { /* class/interface */
3271 if (super->flags & ACC_INTERFACE) { /* interface */
3273 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3274 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3275 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3276 M_BLEZ(REG_ITMP2, 2);
3277 M_ALD(REG_ITMP1, REG_ITMP1,
3278 OFFSET(vftbl_t, interfacetable[0]) -
3279 super->index * sizeof(methodptr*));
3280 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3284 s2 = super->vftbl->diffval;
3285 M_BEQZ(s1, 4 + (s2 > 255));
3286 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3287 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3288 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3290 M_CMPULE_IMM(REG_ITMP1, s2, d);
3292 M_LDA(REG_ITMP2, REG_ZERO, s2);
3293 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3297 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3298 a = dseg_addaddress(cd, (void*) super->vftbl);
3299 M_ALD(REG_ITMP2, REG_PV, a);
3300 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3301 codegen_threadcritstart(cd, (u1 *) mcodeptr - cd->mcodebase);
3303 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3304 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3305 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3306 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3307 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3309 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3310 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3314 panic ("internal error: no inlined array instanceof");
3316 store_reg_to_var_int(iptr->dst, d);
3319 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3321 /* op1: 0 == array, 1 == class */
3322 /* val.a: (classinfo*) superclass */
3324 /* superclass is an interface:
3326 * OK if ((sub == NULL) ||
3327 * (sub->vftbl->interfacetablelength > super->index) &&
3328 * (sub->vftbl->interfacetable[-super->index] != NULL));
3330 * superclass is a class:
3332 * OK if ((sub == NULL) || (0
3333 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3334 * super->vftbl->diffvall));
3338 classinfo *super = (classinfo *) iptr->val.a;
3340 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3341 codegen_threadcritrestart(cd, (u1 *) mcodeptr - cd->mcodebase);
3343 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
3344 var_to_reg_int(s1, src, d);
3345 if (iptr->op1) { /* class/interface */
3346 if (super->flags & ACC_INTERFACE) { /* interface */
3348 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3349 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3350 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3351 M_BLEZ(REG_ITMP2, 0);
3352 codegen_addxcastrefs(cd, mcodeptr);
3353 M_ALD(REG_ITMP2, REG_ITMP1,
3354 OFFSET(vftbl_t, interfacetable[0]) -
3355 super->index * sizeof(methodptr*));
3356 M_BEQZ(REG_ITMP2, 0);
3357 codegen_addxcastrefs(cd, mcodeptr);
3361 s2 = super->vftbl->diffval;
3362 M_BEQZ(s1, 4 + (s2 != 0) + (s2 > 255));
3363 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3364 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3365 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3367 M_BNEZ(REG_ITMP1, 0);
3369 else if (s2 <= 255) {
3370 M_CMPULE_IMM(REG_ITMP1, s2, REG_ITMP2);
3371 M_BEQZ(REG_ITMP2, 0);
3374 M_LDA(REG_ITMP2, REG_ZERO, s2);
3375 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3376 M_BEQZ(REG_ITMP2, 0);
3379 M_BEQZ(s1, 8 + (d == REG_ITMP3));
3380 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3381 a = dseg_addaddress(cd, (void *) super->vftbl);
3382 M_ALD(REG_ITMP2, REG_PV, a);
3383 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3384 codegen_threadcritstart(cd, (u1 *) mcodeptr - cd->mcodebase);
3386 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3387 if (d != REG_ITMP3) {
3388 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3389 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3390 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3391 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3393 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3396 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3397 M_ISUB(REG_ITMP1, REG_ITMP2, REG_ITMP1);
3398 M_ALD(REG_ITMP2, REG_PV, a);
3399 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3400 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3401 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3404 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3405 M_BEQZ(REG_ITMP2, 0);
3406 codegen_addxcastrefs(cd, mcodeptr);
3410 panic ("internal error: no inlined array checkcast");
3413 store_reg_to_var_int(iptr->dst, d);
3416 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
3418 var_to_reg_int(s1, src, REG_ITMP1);
3420 codegen_addxcheckarefs(cd, mcodeptr);
3423 case ICMD_CHECKEXCEPTION: /* ... ==> ... */
3425 M_BEQZ(REG_RESULT, 0);
3426 codegen_addxexceptionrefs(cd, mcodeptr);
3429 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3430 /* op1 = dimension, val.a = array descriptor */
3432 /* check for negative sizes and copy sizes to stack if necessary */
3434 MCODECHECK((iptr->op1 << 1) + 64);
3436 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3437 var_to_reg_int(s2, src, REG_ITMP1);
3439 codegen_addxcheckarefs(cd, mcodeptr);
3441 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
3443 if (src->varkind != ARGVAR) {
3444 M_LST(s2, REG_SP, 8 * (s1 + INT_ARG_CNT));
3448 /* a0 = dimension count */
3450 ICONST(rd->argintregs[0], iptr->op1);
3452 /* a1 = arraydescriptor */
3454 a = dseg_addaddress(cd, iptr->val.a);
3455 M_ALD(rd->argintregs[1], REG_PV, a);
3457 /* a2 = pointer to dimensions = stack pointer */
3459 M_INTMOVE(REG_SP, rd->argintregs[2]);
3461 a = dseg_addaddress(cd, (void *) builtin_nmultianewarray);
3462 M_ALD(REG_PV, REG_PV, a);
3463 M_JSR(REG_RA, REG_PV);
3464 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3466 M_LDA(REG_PV, REG_RA, -s1);
3468 s4 ml = -s1, mh = 0;
3469 while (ml < -32768) { ml += 65536; mh--; }
3470 M_LDA(REG_PV, REG_RA, ml);
3471 M_LDAH(REG_PV, REG_PV, mh);
3473 s1 = reg_of_var(rd, iptr->dst, REG_RESULT);
3474 M_INTMOVE(REG_RESULT, s1);
3475 store_reg_to_var_int(iptr->dst, s1);
3478 case ICMD_INLINE_START:
3479 case ICMD_INLINE_END:
3482 default: error ("Unknown pseudo command: %d", iptr->opc);
3488 } /* for instruction */
3490 /* copy values to interface registers */
3492 src = bptr->outstack;
3493 len = bptr->outdepth;
3500 if ((src->varkind != STACKVAR)) {
3502 if (IS_FLT_DBL_TYPE(s2)) {
3503 var_to_reg_flt(s1, src, REG_FTMP1);
3504 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3505 M_FLTMOVE(s1,rd->interfaces[len][s2].regoff);
3508 M_DST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3512 var_to_reg_int(s1, src, REG_ITMP1);
3513 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3514 M_INTMOVE(s1,rd->interfaces[len][s2].regoff);
3517 M_LST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3523 } /* if (bptr -> flags >= BBREACHED) */
3524 } /* for basic block */
3526 codegen_createlinenumbertable(cd);
3529 /* generate bound check stubs */
3531 s4 *xcodeptr = NULL;
3534 for (bref = cd->xboundrefs; bref != NULL; bref = bref->next) {
3535 gen_resolvebranch((u1*) cd->mcodebase + bref->branchpos,
3537 (u1*) mcodeptr - cd->mcodebase);
3541 /* move index register into REG_ITMP1 */
3542 M_MOV(bref->reg, REG_ITMP1);
3543 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3545 if (xcodeptr != NULL) {
3546 M_BR(xcodeptr - mcodeptr - 1);
3549 xcodeptr = mcodeptr;
3551 a = dseg_addaddress(cd, asm_throw_and_handle_arrayindexoutofbounds_exception);
3552 M_ALD(REG_PV, REG_PV, a);
3554 M_JSR(REG_RA, REG_PV);
3557 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3558 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3560 s4 ml = -s1, mh = 0;
3561 while (ml < -32768) { ml += 65536; mh--; }
3562 M_LDA(REG_PV, REG_RA, ml);
3563 M_LDAH(REG_PV, REG_PV, mh);
3568 /* generate negative array size check stubs */
3572 for (bref = cd->xcheckarefs; bref != NULL; bref = bref->next) {
3573 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3574 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3576 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3580 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3582 (u1 *) mcodeptr - cd->mcodebase);
3586 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3588 if (xcodeptr != NULL) {
3589 M_BR(xcodeptr - mcodeptr - 1);
3592 xcodeptr = mcodeptr;
3595 a = dseg_addaddress(cd, string_java_lang_NegativeArraySizeException);
3596 M_ALD(REG_ITMP1_XPTR,REG_PV,a);
3598 a = dseg_addaddress(cd, asm_throw_and_handle_nat_exception);
3599 M_ALD(REG_PV, REG_PV, a);
3601 M_JSR(REG_RA, REG_PV);
3604 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3605 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3607 s4 ml = -s1, mh = 0;
3608 while (ml < -32768) { ml += 65536; mh--; }
3609 M_LDA(REG_PV, REG_RA, ml);
3610 M_LDAH(REG_PV, REG_PV, mh);
3617 /* generate cast check stubs */
3621 for (bref = cd->xcastrefs; bref != NULL; bref = bref->next) {
3622 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3623 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3625 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3629 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3631 (u1 *) mcodeptr - cd->mcodebase);
3635 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3637 if (xcodeptr != NULL) {
3638 M_BR(xcodeptr - mcodeptr - 1);
3641 xcodeptr = mcodeptr;
3643 a = dseg_addaddress(cd, string_java_lang_ClassCastException);
3644 M_ALD(REG_ITMP1_XPTR,REG_PV,a);
3646 a = dseg_addaddress(cd, asm_throw_and_handle_nat_exception);
3647 M_ALD(REG_PV, REG_PV, a);
3649 M_JSR(REG_RA, REG_PV);
3652 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3653 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3655 s4 ml = -s1, mh = 0;
3656 while (ml < -32768) { ml += 65536; mh--; }
3657 M_LDA(REG_PV, REG_RA, ml);
3658 M_LDAH(REG_PV, REG_PV, mh);
3664 /* generate exception check stubs */
3668 for (bref = cd->xexceptionrefs; bref != NULL; bref = bref->next) {
3669 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3670 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3672 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3676 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3678 (u1 *) mcodeptr - cd->mcodebase);
3682 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3684 if (xcodeptr != NULL) {
3685 M_BR(xcodeptr - mcodeptr - 1);
3688 xcodeptr = mcodeptr;
3690 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3691 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3692 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3694 a = dseg_addaddress(cd, &builtin_get_exceptionptrptr);
3695 M_ALD(REG_PV, REG_PV, a);
3696 M_JSR(REG_RA, REG_PV);
3699 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3700 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3702 s4 ml = -s1, mh = 0;
3703 while (ml < -32768) { ml += 65536; mh--; }
3704 M_LDA(REG_PV, REG_RA, ml);
3705 M_LDAH(REG_PV, REG_PV, mh);
3708 M_ALD(REG_ITMP1_XPTR, REG_RESULT, 0);
3709 M_AST(REG_ZERO, REG_RESULT, 0);
3711 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3712 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3714 a = dseg_addaddress(cd, &_exceptionptr);
3715 M_ALD(REG_ITMP3, REG_PV, a);
3716 M_ALD(REG_ITMP1_XPTR, REG_ITMP3, 0);
3717 M_AST(REG_ZERO, REG_ITMP3, 0);
3720 a = dseg_addaddress(cd, asm_refillin_and_handle_exception);
3721 M_ALD(REG_PV, REG_PV, a);
3723 M_JMP(REG_RA, REG_PV);
3726 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3727 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3729 s4 ml = -s1, mh = 0;
3730 while (ml < -32768) { ml += 65536; mh--; }
3731 M_LDA(REG_PV, REG_RA, ml);
3732 M_LDAH(REG_PV, REG_PV, mh);
3738 /* generate null pointer check stubs */
3742 for (bref = cd->xnullrefs; bref != NULL; bref = bref->next) {
3743 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3744 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3746 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3750 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3752 (u1 *) mcodeptr - cd->mcodebase);
3756 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3758 if (xcodeptr != NULL) {
3759 M_BR(xcodeptr - mcodeptr - 1);
3762 xcodeptr = mcodeptr;
3764 a = dseg_addaddress(cd, string_java_lang_NullPointerException);
3765 M_ALD(REG_ITMP1_XPTR,REG_PV,a);
3767 a = dseg_addaddress(cd, asm_throw_and_handle_nat_exception);
3768 M_ALD(REG_PV, REG_PV, a);
3770 M_JSR(REG_RA, REG_PV);
3773 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3774 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3776 s4 ml = -s1, mh = 0;
3777 while (ml < -32768) { ml += 65536; mh--; }
3778 M_LDA(REG_PV, REG_RA, ml);
3779 M_LDAH(REG_PV, REG_PV, mh);
3785 /* generate put/getstatic stub call code */
3792 for (cref = cd->clinitrefs; cref != NULL; cref = cref->next) {
3793 /* Get machine code which is patched back in later. The call is */
3794 /* 1 instruction word long. */
3795 xcodeptr = (s4 *) (cd->mcodebase + cref->branchpos);
3798 /* patch in the call to call the following code (done at compile */
3801 tmpmcodeptr = mcodeptr; /* save current mcodeptr */
3802 mcodeptr = xcodeptr; /* set mcodeptr to patch position */
3804 M_BSR(REG_RA, tmpmcodeptr - (xcodeptr + 1));
3806 mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
3810 /* move class pointer into REG_ITMP2 */
3811 a = dseg_addaddress(cd, cref->class);
3812 M_ALD(REG_ITMP1, REG_PV, a);
3814 /* move machine code onto stack */
3815 a = dseg_adds4(cd, mcode);
3816 M_ILD(REG_ITMP3, REG_PV, a);
3817 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3818 M_IST(REG_ITMP3, REG_SP, 0);
3820 a = dseg_addaddress(cd, asm_check_clinit);
3821 M_ALD(REG_ITMP2, REG_PV, a);
3822 M_JMP(REG_ZERO, REG_ITMP2);
3827 codegen_finish(m, cd, (s4) ((u1 *) mcodeptr - cd->mcodebase));
3831 /* function createcompilerstub *************************************************
3833 creates a stub routine which calls the compiler
3835 *******************************************************************************/
3837 #define COMPSTUBSIZE 3
3839 u1 *createcompilerstub(methodinfo *m)
3841 u8 *s = CNEW(u8, COMPSTUBSIZE); /* memory to hold the stub */
3842 s4 *mcodeptr = (s4 *) s; /* code generation pointer */
3844 /* code for the stub */
3845 M_ALD(REG_PV, REG_PV, 16); /* load pointer to the compiler */
3846 M_JMP(0, REG_PV); /* jump to the compiler, return address
3847 in reg 0 is used as method pointer */
3848 s[1] = (u8) m; /* literals to be adressed */
3849 s[2] = (u8) asm_call_jit_compiler; /* jump directly via PV from above */
3851 #if defined(STATISTICS)
3853 count_cstub_len += COMPSTUBSIZE * 8;
3860 /* function removecompilerstub *************************************************
3862 deletes a compilerstub from memory (simply by freeing it)
3864 *******************************************************************************/
3866 void removecompilerstub(u1 *stub)
3868 CFREE(stub, COMPSTUBSIZE * 8);
3872 /* function: createnativestub **************************************************
3874 creates a stub routine which calls a native method
3876 *******************************************************************************/
3879 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3880 #define NATIVESTUB_STACK 8/*ra,native result, oldThreadspecificHeadValue, addressOfThreadspecificHead, method, 0,0,ra*/
3881 #define NATIVESTUB_THREAD_EXTRA (6 + 20) /*20 for additional frame creation*/
3882 #define NATIVESTUB_STACKTRACE_OFFSET 1
3884 #define NATIVESTUB_STACK 7/*ra,oldThreadspecificHeadValue, addressOfThreadspecificHead, method, 0,0,ra*/
3885 #define NATIVESTUB_THREAD_EXTRA (1 + 20) /*20 for additional frame creation*/
3886 #define NATIVESTUB_STACKTRACE_OFFSET 0
3889 #define NATIVESTUB_SIZE (44 + NATIVESTUB_THREAD_EXTRA - 1)
3890 #define NATIVESTUB_STATIC_SIZE 5
3891 #define NATIVESTUB_VERBOSE_SIZE (39 + 13)
3892 #define NATIVESTUB_OFFSET 11
3895 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3896 #define NATIVESTUB_STACK 2
3897 #define NATIVESTUB_THREAD_EXTRA 6
3899 #define NATIVESTUB_STACK 1
3900 #define NATIVESTUB_THREAD_EXTRA 1
3903 #define NATIVESTUB_SIZE (44 + NATIVESTUB_THREAD_EXTRA - 1)
3904 #define NATIVESTUB_STATIC_SIZE 4
3905 #define NATIVESTUB_VERBOSE_SIZE (39 + 13)
3906 #define NATIVESTUB_OFFSET 10
3909 u1 *createnativestub(functionptr f, methodinfo *m)
3911 u8 *s; /* memory pointer to hold the stub */
3913 s4 *mcodeptr; /* code generation pointer */
3914 s4 stackframesize = 0; /* size of stackframe if needed */
3919 t_inlining_globals *id;
3922 /* mark start of dump memory area */
3924 dumpsize = dump_size();
3926 /* setup registers before using it */
3928 cd = DNEW(codegendata);
3929 rd = DNEW(registerdata);
3930 id = DNEW(t_inlining_globals);
3932 inlining_setup(m, id);
3933 reg_setup(m, rd, id);
3935 descriptor2types(m); /* set paramcount and paramtypes */
3937 stubsize = NATIVESTUB_SIZE; /* calculate nativestub size */
3939 if ((m->flags & ACC_STATIC) && !m->class->initialized)
3940 stubsize += NATIVESTUB_STATIC_SIZE;
3943 stubsize += NATIVESTUB_VERBOSE_SIZE;
3945 s = CNEW(u8, stubsize); /* memory to hold the stub */
3946 cs = s + NATIVESTUB_OFFSET;
3947 mcodeptr = (s4 *) cs; /* code generation pointer */
3949 /* set some required varibles which are normally set by codegen_setup */
3950 cd->mcodebase = (u1 *) mcodeptr;
3951 cd->clinitrefs = NULL;
3953 *(cs-1) = (u8) f; /* address of native method */
3954 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3955 *(cs-2) = (u8) &builtin_get_exceptionptrptr;
3957 *(cs-2) = (u8) (&_exceptionptr); /* address of exceptionptr */
3959 *(cs-3) = (u8) asm_handle_nat_exception; /* addr of asm exception handler*/
3960 *(cs-4) = (u8) (&env); /* addr of jni_environement */
3961 *(cs-5) = (u8) builtin_trace_args;
3963 *(cs-7) = (u8) builtin_displaymethodstop;
3964 *(cs-8) = (u8) m->class;
3965 *(cs-9) = (u8) asm_check_clinit;
3966 *(cs-10) = (u8) &builtin_asm_get_stackframeinfo;
3967 *(cs-11) = (u8) NULL; /* filled with machine code */
3969 M_LDA(REG_SP, REG_SP, -NATIVESTUB_STACK * 8); /* build up stackframe */
3970 M_AST(REG_RA, REG_SP, 0 * 8); /* store return address */
3972 M_AST(REG_RA, REG_SP, (6+NATIVESTUB_STACKTRACE_OFFSET) * 8); /* store return address in stackinfo helper*/
3974 /* if function is static, check for initialized */
3976 if (m->flags & ACC_STATIC) {
3977 /* if class isn't yet initialized, do it */
3978 if (!m->class->initialized) {
3979 codegen_addclinitref(cd, mcodeptr, m->class);
3983 /* max. 39 +9 instructions */
3987 M_LDA(REG_SP, REG_SP, -((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
3988 M_AST(REG_RA, REG_SP, 1 * 8);
3990 /* save integer argument registers */
3991 for (p = 0; p < m->paramcount && p < INT_ARG_CNT; p++) {
3992 M_LST(rd->argintregs[p], REG_SP, (2 + p) * 8);
3995 /* save and copy float arguments into integer registers */
3996 for (p = 0; p < m->paramcount && p < FLT_ARG_CNT; p++) {
3997 t = m->paramtypes[p];
3999 if (IS_FLT_DBL_TYPE(t)) {
4000 if (IS_2_WORD_TYPE(t)) {
4001 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4002 M_LLD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4005 M_FST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4006 M_ILD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4010 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4015 M_ALD(REG_ITMP1, REG_PV, -6 * 8);
4016 M_AST(REG_ITMP1, REG_SP, 0 * 8);
4017 M_ALD(REG_PV, REG_PV, -5 * 8);
4018 M_JSR(REG_RA, REG_PV);
4019 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4020 M_LDA(REG_PV, REG_RA, disp);
4025 M_ALD(REG_PV, REG_PV, -10 * 8); /* builtin_asm_get_stackframeinfo */
4026 M_JSR(REG_RA, REG_PV);
4027 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4028 M_LDA(REG_PV, REG_RA, disp);
4031 M_MOV(REG_RESULT,REG_ITMP3);
4032 M_LST(REG_RESULT,REG_ITMP3,0);
4034 M_LST(REG_RESULT,REG_SP, ((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8)+(2+NATIVESTUB_STACKTRACE_OFFSET)*8);/*save adress of pointer*/
4035 M_LLD(REG_ITMP3,REG_RESULT,0); /* get pointer*/
4036 M_LST(REG_ITMP3,REG_SP,(1+NATIVESTUB_STACKTRACE_OFFSET)*8+((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8)); /*save old value*/
4037 M_LDA(REG_ITMP3,REG_SP,(1+NATIVESTUB_STACKTRACE_OFFSET)*8+((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8)); /*calculate new value*/
4038 M_LLD(REG_ITMP2,REG_ITMP3,8);
4039 M_LST(REG_ITMP3,REG_ITMP2,0); /*store new value*/
4040 M_LLD(REG_ITMP2,REG_PV,-6*8);
4041 M_LST(REG_ITMP2,REG_SP,(3+NATIVESTUB_STACKTRACE_OFFSET)*8+((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
4042 M_LST(REG_ZERO,REG_SP,(4+NATIVESTUB_STACKTRACE_OFFSET)*8+((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
4043 M_LST(REG_ZERO,REG_SP,(5+NATIVESTUB_STACKTRACE_OFFSET)*8+((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
4044 /*stack info -end */
4047 for (p = 0; p < m->paramcount && p < INT_ARG_CNT; p++) {
4048 M_LLD(rd->argintregs[p], REG_SP, (2 + p) * 8);
4051 for (p = 0; p < m->paramcount && p < FLT_ARG_CNT; p++) {
4052 t = m->paramtypes[p];
4054 if (IS_FLT_DBL_TYPE(t)) {
4055 if (IS_2_WORD_TYPE(t)) {
4056 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4059 M_FLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4063 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4067 M_ALD(REG_RA, REG_SP, 1 * 8);
4068 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT + 2) * 8);
4071 /* save argument registers on stack -- if we have to */
4072 if ((m->flags & ACC_STATIC && m->paramcount > (INT_ARG_CNT - 2)) || m->paramcount > (INT_ARG_CNT - 1)) {
4074 s4 paramshiftcnt = (m->flags & ACC_STATIC) ? 2 : 1;
4075 s4 stackparamcnt = (m->paramcount > INT_ARG_CNT) ? m->paramcount - INT_ARG_CNT : 0;
4077 stackframesize = stackparamcnt + paramshiftcnt;
4079 M_LDA(REG_SP, REG_SP, -stackframesize * 8);
4081 /* copy stack arguments into new stack frame -- if any */
4082 for (i = 0; i < stackparamcnt; i++) {
4083 M_LLD(REG_ITMP1, REG_SP, (stackparamcnt + 1 + i) * 8);
4084 M_LST(REG_ITMP1, REG_SP, (paramshiftcnt + i) * 8);
4087 if (m->flags & ACC_STATIC) {
4088 if (IS_FLT_DBL_TYPE(m->paramtypes[5])) {
4089 M_DST(rd->argfltregs[5], REG_SP, 1 * 8);
4091 M_LST(rd->argintregs[5], REG_SP, 1 * 8);
4094 if (IS_FLT_DBL_TYPE(m->paramtypes[4])) {
4095 M_DST(rd->argfltregs[4], REG_SP, 0 * 8);
4097 M_LST(rd->argintregs[4], REG_SP, 0 * 8);
4101 if (IS_FLT_DBL_TYPE(m->paramtypes[5])) {
4102 M_DST(rd->argfltregs[5], REG_SP, 0 * 8);
4104 M_LST(rd->argintregs[5], REG_SP, 0 * 8);
4109 if (m->flags & ACC_STATIC) {
4110 M_MOV(rd->argintregs[3], rd->argintregs[5]);
4111 M_MOV(rd->argintregs[2], rd->argintregs[4]);
4112 M_MOV(rd->argintregs[1], rd->argintregs[3]);
4113 M_MOV(rd->argintregs[0], rd->argintregs[2]);
4114 M_FMOV(rd->argfltregs[3], rd->argfltregs[5]);
4115 M_FMOV(rd->argfltregs[2], rd->argfltregs[4]);
4116 M_FMOV(rd->argfltregs[1], rd->argfltregs[3]);
4117 M_FMOV(rd->argfltregs[0], rd->argfltregs[2]);
4119 /* put class into second argument register */
4120 M_ALD(rd->argintregs[1], REG_PV, -8 * 8);
4123 M_MOV(rd->argintregs[4], rd->argintregs[5]);
4124 M_MOV(rd->argintregs[3], rd->argintregs[4]);
4125 M_MOV(rd->argintregs[2], rd->argintregs[3]);
4126 M_MOV(rd->argintregs[1], rd->argintregs[2]);
4127 M_MOV(rd->argintregs[0], rd->argintregs[1]);
4128 M_FMOV(rd->argfltregs[4], rd->argfltregs[5]);
4129 M_FMOV(rd->argfltregs[3], rd->argfltregs[4]);
4130 M_FMOV(rd->argfltregs[2], rd->argfltregs[3]);
4131 M_FMOV(rd->argfltregs[1], rd->argfltregs[2]);
4132 M_FMOV(rd->argfltregs[0], rd->argfltregs[1]);
4135 /* put env into first argument register */
4136 M_ALD(rd->argintregs[0], REG_PV, -4 * 8);
4138 M_ALD(REG_PV, REG_PV, -1 * 8); /* load adress of native method */
4139 M_JSR(REG_RA, REG_PV); /* call native method */
4140 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4141 M_LDA(REG_PV, REG_RA, disp); /* recompute pv from ra */
4143 /* remove stackframe if there is one */
4144 if (stackframesize) {
4145 M_LDA(REG_SP, REG_SP, stackframesize * 8);
4148 /* 13 instructions */
4150 M_LDA(REG_SP, REG_SP, -2 * 8);
4151 M_ALD(rd->argintregs[0], REG_PV, -6 * 8); /* load method adress */
4152 M_LST(REG_RESULT, REG_SP, 0 * 8);
4153 M_DST(REG_FRESULT, REG_SP, 1 * 8);
4154 M_MOV(REG_RESULT, rd->argintregs[1]);
4155 M_FMOV(REG_FRESULT, rd->argfltregs[2]);
4156 M_FMOV(REG_FRESULT, rd->argfltregs[3]);
4157 M_ALD(REG_PV, REG_PV, -7 * 8); /* builtin_displaymethodstop */
4158 M_JSR(REG_RA, REG_PV);
4159 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4160 M_LDA(REG_PV, REG_RA, disp);
4161 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4162 M_DLD(REG_FRESULT, REG_SP, 1 * 8);
4163 M_LDA(REG_SP, REG_SP, 2 * 8);
4166 M_LLD(REG_ITMP3,REG_SP,(2+NATIVESTUB_STACKTRACE_OFFSET)*8); /*get address of stacktrace helper pointer*/
4167 M_LLD(REG_ITMP1,REG_SP,(1+NATIVESTUB_STACKTRACE_OFFSET)*8); /*get old value*/
4168 M_LST(REG_ITMP1,REG_ITMP3,0); /*set old value*/
4170 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4171 if (IS_FLT_DBL_TYPE(m->returntype))
4172 M_DST(REG_FRESULT, REG_SP, 1 * 8);
4174 M_AST(REG_RESULT, REG_SP, 1 * 8);
4175 M_ALD(REG_PV, REG_PV, -2 * 8); /* builtin_get_exceptionptrptr */
4176 M_JSR(REG_RA, REG_PV);
4177 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4178 M_LDA(REG_PV, REG_RA, disp);
4179 M_MOV(REG_RESULT, REG_ITMP3);
4180 if (IS_FLT_DBL_TYPE(m->returntype))
4181 M_DLD(REG_FRESULT, REG_SP, 1 * 8);
4183 M_ALD(REG_RESULT, REG_SP, 1 * 8);
4185 M_ALD(REG_ITMP3, REG_PV, -2 * 8); /* get address of exceptionptr */
4187 M_ALD(REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
4188 M_BNEZ(REG_ITMP1, 3); /* if no exception then return */
4190 M_ALD(REG_RA, REG_SP, 0 * 8); /* load return address */
4191 M_LDA(REG_SP, REG_SP, NATIVESTUB_STACK * 8); /* remove stackframe */
4192 M_RET(REG_ZERO, REG_RA); /* return to caller */
4194 M_AST(REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
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_LDA(REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
4199 M_ALD(REG_ITMP3, REG_PV, -3 * 8); /* load asm exception handler address */
4200 M_JMP(REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
4202 /* generate put/getstatic stub call code */
4209 /* there can only be one clinit ref entry */
4210 cref = cd->clinitrefs;
4213 /* Get machine code which is patched back in later. The call is */
4214 /* 1 instruction word long. */
4215 xcodeptr = (s4 *) (cd->mcodebase + cref->branchpos);
4216 *(cs-11) = (u4) *xcodeptr;
4218 /* patch in the call to call the following code (done at compile */
4221 tmpmcodeptr = mcodeptr; /* save current mcodeptr */
4222 mcodeptr = xcodeptr; /* set mcodeptr to patch position */
4224 M_BSR(REG_RA, tmpmcodeptr - (xcodeptr + 1));
4226 mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
4228 /* move class pointer into REG_ITMP2 */
4229 M_ALD(REG_ITMP1, REG_PV, -8 * 8); /* class */
4231 /* move machine code into REG_ITMP3 */
4232 M_ILD(REG_ITMP3, REG_PV, -11 * 8); /* machine code */
4233 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
4234 M_IST(REG_ITMP3, REG_SP, 0);
4236 M_ALD(REG_ITMP2, REG_PV, -9 * 8); /* asm_check_clinit */
4237 M_JMP(REG_ZERO, REG_ITMP2);
4242 dolog_plain("stubsize: %d (for %d params)\n", (int) (mcodeptr - (s4*) s), m->paramcount);
4245 #if defined(STATISTICS)
4247 count_nstub_len += NATIVESTUB_SIZE * 8;
4250 /* release dump area */
4252 dump_release(dumpsize);
4254 return (u1 *) (s + NATIVESTUB_OFFSET);
4258 /* function: removenativestub **************************************************
4260 removes a previously created native-stub from memory
4262 *******************************************************************************/
4264 void removenativestub(u1 *stub)
4266 CFREE((u8 *) stub - NATIVESTUBOFFSET, NATIVESTUBSIZE * 8);
4271 * These are local overrides for various environment variables in Emacs.
4272 * Please do not remove this and leave it at the end of the file, where
4273 * Emacs will automagically detect them.
4274 * ---------------------------------------------------------------------
4277 * indent-tabs-mode: t