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 $Id: codegen.c 1624 2004-11-30 14:49:45Z twisti $
39 #include "native/native.h"
40 #include "vm/builtin.h"
41 #include "vm/global.h"
42 #include "vm/loader.h"
43 #include "vm/tables.h"
44 #include "vm/jit/asmpart.h"
45 #include "vm/jit/jit.h"
46 #include "vm/jit/lsra.h"
47 #include "vm/jit/parse.h"
48 #include "vm/jit/reg.h"
49 #include "vm/jit/alpha/codegen.h"
50 #include "vm/jit/alpha/arch.h"
51 #include "vm/jit/alpha/types.h"
54 /* *****************************************************************************
56 Datatypes and Register Allocations:
57 -----------------------------------
59 On 64-bit-machines (like the Alpha) all operands are stored in the
60 registers in a 64-bit form, even when the correspondig JavaVM operands
61 only need 32 bits. This is done by a canonical representation:
63 32-bit integers are allways stored as sign-extended 64-bit values (this
64 approach is directly supported by the Alpha architecture and is very easy
67 32-bit-floats are stored in a 64-bit doubleprecision register by simply
68 expanding the exponent and mantissa with zeroes. (also supported by the
74 The calling conventions and the layout of the stack is explained in detail
75 in the documention file: calling.doc
77 *******************************************************************************/
80 /* register descripton - array ************************************************/
82 /* #define REG_RES 0 reserved register for OS or code generator */
83 /* #define REG_RET 1 return value register */
84 /* #define REG_EXC 2 exception value register (only old jit) */
85 /* #define REG_SAV 3 (callee) saved register */
86 /* #define REG_TMP 4 scratch temporary register (caller saved) */
87 /* #define REG_ARG 5 argument register (caller saved) */
89 /* #define REG_END -1 last entry in tables */
92 REG_RET, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
93 REG_TMP, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
94 REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_TMP, REG_TMP,
95 REG_TMP, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES,
98 /* for use of reserved registers, see comment above */
100 int nregdescfloat[] = {
101 REG_RET, REG_TMP, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
102 REG_SAV, REG_SAV, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
103 REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_TMP, REG_TMP,
104 REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_RES, REG_RES, REG_RES, REG_RES,
108 /* Include independent code generation stuff -- include after register */
109 /* descriptions to avoid extern definitions. */
111 #include "vm/jit/codegen.inc"
112 #include "vm/jit/reg.inc"
113 #include "vm/jit/lsra.inc"
116 /* NullPointerException handlers and exception handling initialisation */
118 typedef struct sigctx_struct {
119 long sc_onstack; /* sigstack state to restore */
120 long sc_mask; /* signal mask to restore */
121 long sc_pc; /* pc at time of signal */
122 long sc_ps; /* psl to retore */
123 long sc_regs[32]; /* processor regs 0 to 31 */
124 long sc_ownedfp; /* fp has been used */
125 long sc_fpregs[32]; /* fp regs 0 to 31 */
126 unsigned long sc_fpcr; /* floating point control register */
127 unsigned long sc_fp_control; /* software fpcr */
129 unsigned long sc_reserved1, sc_reserved2;
130 unsigned long sc_ssize;
132 unsigned long sc_traparg_a0;
133 unsigned long sc_traparg_a1;
134 unsigned long sc_traparg_a2;
135 unsigned long sc_fp_trap_pc;
136 unsigned long sc_fp_trigger_sum;
137 unsigned long sc_fp_trigger_inst;
138 unsigned long sc_retcode[2];
142 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
143 void thread_restartcriticalsection(ucontext_t *uc)
146 if ((critical = thread_checkcritical((void*) uc->uc_mcontext.sc_pc)) != NULL)
147 uc->uc_mcontext.sc_pc = (u8) critical;
151 /* NullPointerException signal handler for hardware null pointer check */
153 void catch_NullPointerException(int sig, int code, sigctx_struct *sigctx)
158 java_objectheader *xptr;
160 /* Reset signal handler - necessary for SysV, does no harm for BSD */
162 instr = *((int*)(sigctx->sc_pc));
163 faultaddr = sigctx->sc_regs[(instr >> 16) & 0x1f];
165 if (faultaddr == 0) {
166 /* reinstall handler */
167 signal(sig, (functionptr) catch_NullPointerException);
169 sigaddset(&nsig, sig);
170 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
172 xptr = new_nullpointerexception();
174 sigctx->sc_regs[REG_ITMP1_XPTR] = (u8) xptr;
175 sigctx->sc_regs[REG_ITMP2_XPC] = sigctx->sc_pc;
176 sigctx->sc_pc = (u8) asm_handle_exception;
180 faultaddr += (long) ((instr << 16) >> 16);
181 fprintf(stderr, "faulting address: 0x%016lx\n", faultaddr);
182 panic("Stack overflow");
189 void init_exceptions(void)
194 /* Linux on Digital Alpha needs an initialisation of the ieee floating point
195 control for IEEE compliant arithmetic (option -mieee of GCC). Under
196 Digital Unix this is done automatically.
201 extern unsigned long ieee_get_fp_control();
202 extern void ieee_set_fp_control(unsigned long fp_control);
204 void init_exceptions(void)
206 /* initialize floating point control */
208 ieee_set_fp_control(ieee_get_fp_control()
209 & ~IEEE_TRAP_ENABLE_INV
210 & ~IEEE_TRAP_ENABLE_DZE
211 /* & ~IEEE_TRAP_ENABLE_UNF we dont want underflow */
212 & ~IEEE_TRAP_ENABLE_OVF);
215 /* install signal handlers we need to convert to exceptions */
219 signal(SIGSEGV, (functionptr) catch_NullPointerException);
223 signal(SIGBUS, (functionptr) catch_NullPointerException);
229 /* function gen_mcode **********************************************************
231 generates machine code
233 *******************************************************************************/
235 void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
237 s4 len, s1, s2, s3, d;
251 savedregs_num = (m->isleafmethod) ? 0 : 1; /* space to save the RA */
253 /* space to save used callee saved registers */
255 savedregs_num += (rd->savintregcnt - rd->maxsavintreguse);
256 savedregs_num += (rd->savfltregcnt - rd->maxsavfltreguse);
258 parentargs_base = rd->maxmemuse + savedregs_num;
260 #if defined(USE_THREADS) /* space to save argument of monitor_enter */
262 if (checksync && (m->flags & ACC_SYNCHRONIZED))
267 /* create method header */
269 (void) dseg_addaddress(cd, m); /* MethodPointer */
270 (void) dseg_adds4(cd, parentargs_base * 8); /* FrameSize */
272 #if defined(USE_THREADS)
274 /* IsSync contains the offset relative to the stack pointer for the
275 argument of monitor_exit used in the exception handler. Since the
276 offset could be zero and give a wrong meaning of the flag it is
280 if (checksync && (m->flags & ACC_SYNCHRONIZED))
281 (void) dseg_adds4(cd, (rd->maxmemuse + 1) * 8); /* IsSync */
286 (void) dseg_adds4(cd, 0); /* IsSync */
288 (void) dseg_adds4(cd, m->isleafmethod); /* IsLeaf */
289 (void) dseg_adds4(cd, rd->savintregcnt - rd->maxsavintreguse);/* IntSave */
290 (void) dseg_adds4(cd, rd->savfltregcnt - rd->maxsavfltreguse);/* FltSave */
292 dseg_addlinenumbertablesize(cd);
294 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
296 /* create exception table */
298 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
299 dseg_addtarget(cd, ex->start);
300 dseg_addtarget(cd, ex->end);
301 dseg_addtarget(cd, ex->handler);
302 (void) dseg_addaddress(cd, ex->catchtype);
305 /* initialize mcode variables */
307 mcodeptr = (s4 *) cd->mcodebase;
308 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
309 MCODECHECK(128 + m->paramcount);
311 /* create stack frame (if necessary) */
313 if (parentargs_base) {
314 M_LDA(REG_SP, REG_SP, -parentargs_base * 8);
317 /* save return address and used callee saved registers */
320 if (!m->isleafmethod) {
321 p--; M_AST(REG_RA, REG_SP, p * 8);
323 for (i = rd->savintregcnt - 1; i >= rd->maxsavintreguse; i--) {
324 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
326 for (i = rd->savfltregcnt - 1; i >= rd->maxsavfltreguse; i--) {
327 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
330 /* save monitorenter argument */
332 #if defined(USE_THREADS)
333 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
334 if (m->flags & ACC_STATIC) {
335 p = dseg_addaddress(cd, m->class);
336 M_ALD(REG_ITMP1, REG_PV, p);
337 M_AST(REG_ITMP1, REG_SP, rd->maxmemuse * 8);
340 M_AST(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
345 /* copy argument registers to stack and call trace function with pointer
346 to arguments on stack.
351 M_LDA(REG_SP, REG_SP, -((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
352 M_AST(REG_RA, REG_SP, 1 * 8);
354 /* save integer argument registers */
355 for (p = 0; /* p < m->paramcount && */ p < INT_ARG_CNT; p++) {
356 M_LST(rd->argintregs[p], REG_SP, (2 + p) * 8);
359 /* save and copy float arguments into integer registers */
360 for (p = 0; /* p < m->paramcount && */ p < FLT_ARG_CNT; p++) {
361 t = m->paramtypes[p];
363 if (IS_FLT_DBL_TYPE(t)) {
364 if (IS_2_WORD_TYPE(t)) {
365 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
368 M_FST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
371 M_LLD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
374 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
378 p = dseg_addaddress(cd, m);
379 M_ALD(REG_ITMP1, REG_PV, p);
380 M_AST(REG_ITMP1, REG_SP, 0 * 8);
381 p = dseg_addaddress(cd, (void *) builtin_trace_args);
382 M_ALD(REG_PV, REG_PV, p);
383 M_JSR(REG_RA, REG_PV);
384 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
385 M_LDA(REG_PV, REG_RA, disp);
386 M_ALD(REG_RA, REG_SP, 1 * 8);
388 for (p = 0; /* p < mparamcount && */ p < INT_ARG_CNT; p++) {
389 M_LLD(rd->argintregs[p], REG_SP, (2 + p) * 8);
392 for (p = 0; /* p < mparamcount && */ p < FLT_ARG_CNT; p++) {
393 t = m->paramtypes[p];
395 if (IS_FLT_DBL_TYPE(t)) {
396 if (IS_2_WORD_TYPE(t)) {
397 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
400 M_FLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
404 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
408 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT + 2) * 8);
411 /* take arguments out of register or stack frame */
413 for (p = 0, l = 0; p < m->paramcount; p++) {
414 t = m->paramtypes[p];
415 var = &(rd->locals[l][t]);
417 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
421 if (IS_INT_LNG_TYPE(t)) { /* integer args */
422 if (p < INT_ARG_CNT) { /* register arguments */
423 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
424 M_INTMOVE(rd->argintregs[p], var->regoff);
425 } else { /* reg arg -> spilled */
426 M_LST(rd->argintregs[p], REG_SP, 8 * var->regoff);
429 } else { /* stack arguments */
430 pa = p - INT_ARG_CNT;
431 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
432 M_LLD(var->regoff, REG_SP, 8 * (parentargs_base + pa));
434 } else { /* stack arg -> spilled */
435 M_LLD(REG_ITMP1, REG_SP, 8 * (parentargs_base + pa));
436 M_LST(REG_ITMP1, REG_SP, 8 * var->regoff);
440 } else { /* floating args */
441 if (p < FLT_ARG_CNT) { /* register arguments */
442 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
443 M_FLTMOVE(rd->argfltregs[p], var->regoff);
445 } else { /* reg arg -> spilled */
446 M_DST(rd->argfltregs[p], REG_SP, 8 * var->regoff);
449 } else { /* stack arguments */
450 pa = p - FLT_ARG_CNT;
451 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
452 M_DLD(var->regoff, REG_SP, 8 * (parentargs_base + pa) );
454 } else { /* stack-arg -> spilled */
455 M_DLD(REG_FTMP1, REG_SP, 8 * (parentargs_base + pa));
456 M_DST(REG_FTMP1, REG_SP, 8 * var->regoff);
462 /* call monitorenter function */
464 #if defined(USE_THREADS)
465 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
467 s8 func_enter = (m->flags & ACC_STATIC) ?
468 (s8) builtin_staticmonitorenter : (s8) builtin_monitorenter;
469 p = dseg_addaddress(cd, (void*) func_enter);
470 M_ALD(REG_PV, REG_PV, p);
471 M_ALD(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
472 M_JSR(REG_RA, REG_PV);
473 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
474 M_LDA(REG_PV, REG_RA, disp);
479 /* end of header generation */
481 /* walk through all basic blocks */
482 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
484 bptr->mpc = (s4) ((u1 *) mcodeptr - cd->mcodebase);
486 if (bptr->flags >= BBREACHED) {
488 /* branch resolving */
492 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
493 gen_resolvebranch((u1*) cd->mcodebase + brefs->branchpos,
494 brefs->branchpos, bptr->mpc);
498 /* copy interface registers to their destination */
504 while (src != NULL) {
506 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
507 /* d = reg_of_var(m, src, REG_ITMP1); */
508 if (!(src->flags & INMEMORY))
512 M_INTMOVE(REG_ITMP1, d);
513 store_reg_to_var_int(src, d);
518 while (src != NULL) {
520 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
521 d = reg_of_var(rd, src, REG_ITMP1);
522 M_INTMOVE(REG_ITMP1, d);
523 store_reg_to_var_int(src, d);
526 d = reg_of_var(rd, src, REG_IFTMP);
527 if ((src->varkind != STACKVAR)) {
529 if (IS_FLT_DBL_TYPE(s2)) {
530 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
531 s1 = rd->interfaces[len][s2].regoff;
535 M_DLD(d, REG_SP, 8 * rd->interfaces[len][s2].regoff);
537 store_reg_to_var_flt(src, d);
540 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
541 s1 = rd->interfaces[len][s2].regoff;
545 M_LLD(d, REG_SP, 8 * rd->interfaces[len][s2].regoff);
547 store_reg_to_var_int(src, d);
555 /* walk through all instructions */
559 for (iptr = bptr->iinstr;
561 src = iptr->dst, len--, iptr++) {
563 MCODECHECK(64); /* an instruction usually needs < 64 words */
566 case ICMD_NOP: /* ... ==> ... */
569 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
571 var_to_reg_int(s1, src, REG_ITMP1);
573 codegen_addxnullrefs(cd, mcodeptr);
576 /* constant operations ************************************************/
578 case ICMD_ICONST: /* ... ==> ..., constant */
579 /* op1 = 0, val.i = constant */
581 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
582 ICONST(d, iptr->val.i);
583 store_reg_to_var_int(iptr->dst, d);
586 case ICMD_LCONST: /* ... ==> ..., constant */
587 /* op1 = 0, val.l = constant */
589 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
590 LCONST(d, iptr->val.l);
591 store_reg_to_var_int(iptr->dst, d);
594 case ICMD_FCONST: /* ... ==> ..., constant */
595 /* op1 = 0, val.f = constant */
597 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
598 a = dseg_addfloat(cd, iptr->val.f);
600 store_reg_to_var_flt(iptr->dst, d);
603 case ICMD_DCONST: /* ... ==> ..., constant */
604 /* op1 = 0, val.d = constant */
606 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
607 a = dseg_adddouble(cd, iptr->val.d);
609 store_reg_to_var_flt(iptr->dst, d);
612 case ICMD_ACONST: /* ... ==> ..., constant */
613 /* op1 = 0, val.a = constant */
615 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
617 a = dseg_addaddress(cd, iptr->val.a);
620 M_INTMOVE(REG_ZERO, d);
622 store_reg_to_var_int(iptr->dst, d);
626 /* load/store operations **********************************************/
628 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
629 case ICMD_LLOAD: /* op1 = local variable */
632 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
633 if ((iptr->dst->varkind == LOCALVAR) &&
634 (iptr->dst->varnum == iptr->op1))
636 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
637 if (var->flags & INMEMORY)
638 M_LLD(d, REG_SP, 8 * var->regoff);
640 {M_INTMOVE(var->regoff,d);}
641 store_reg_to_var_int(iptr->dst, d);
644 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
645 case ICMD_DLOAD: /* op1 = local variable */
647 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
648 if ((iptr->dst->varkind == LOCALVAR) &&
649 (iptr->dst->varnum == iptr->op1))
651 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
652 if (var->flags & INMEMORY)
653 M_DLD(d, REG_SP, 8 * var->regoff);
655 {M_FLTMOVE(var->regoff,d);}
656 store_reg_to_var_flt(iptr->dst, d);
660 case ICMD_ISTORE: /* ..., value ==> ... */
661 case ICMD_LSTORE: /* op1 = local variable */
664 if ((src->varkind == LOCALVAR) &&
665 (src->varnum == iptr->op1))
667 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
668 if (var->flags & INMEMORY) {
669 var_to_reg_int(s1, src, REG_ITMP1);
670 M_LST(s1, REG_SP, 8 * var->regoff);
673 var_to_reg_int(s1, src, var->regoff);
674 M_INTMOVE(s1, var->regoff);
678 case ICMD_FSTORE: /* ..., value ==> ... */
679 case ICMD_DSTORE: /* op1 = local variable */
681 if ((src->varkind == LOCALVAR) &&
682 (src->varnum == iptr->op1))
684 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
685 if (var->flags & INMEMORY) {
686 var_to_reg_flt(s1, src, REG_FTMP1);
687 M_DST(s1, REG_SP, 8 * var->regoff);
690 var_to_reg_flt(s1, src, var->regoff);
691 M_FLTMOVE(s1, var->regoff);
696 /* pop/dup/swap operations ********************************************/
698 /* attention: double and longs are only one entry in CACAO ICMDs */
700 case ICMD_POP: /* ..., value ==> ... */
701 case ICMD_POP2: /* ..., value, value ==> ... */
704 case ICMD_DUP: /* ..., a ==> ..., a, a */
705 M_COPY(src, iptr->dst);
708 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
710 M_COPY(src, iptr->dst);
711 M_COPY(src->prev, iptr->dst->prev);
712 M_COPY(iptr->dst, iptr->dst->prev->prev);
715 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
717 M_COPY(src, iptr->dst);
718 M_COPY(src->prev, iptr->dst->prev);
719 M_COPY(src->prev->prev, iptr->dst->prev->prev);
720 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
723 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
725 M_COPY(src, iptr->dst);
726 M_COPY(src->prev, iptr->dst->prev);
729 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
731 M_COPY(src, iptr->dst);
732 M_COPY(src->prev, iptr->dst->prev);
733 M_COPY(src->prev->prev, iptr->dst->prev->prev);
734 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
735 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev);
738 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
740 M_COPY(src, iptr->dst);
741 M_COPY(src->prev, iptr->dst->prev);
742 M_COPY(src->prev->prev, iptr->dst->prev->prev);
743 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
744 M_COPY(iptr->dst, iptr->dst->prev->prev->prev->prev);
745 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev->prev);
748 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
750 M_COPY(src, iptr->dst->prev);
751 M_COPY(src->prev, iptr->dst);
755 /* integer operations *************************************************/
757 case ICMD_INEG: /* ..., value ==> ..., - value */
759 var_to_reg_int(s1, src, REG_ITMP1);
760 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
761 M_ISUB(REG_ZERO, s1, d);
762 store_reg_to_var_int(iptr->dst, d);
765 case ICMD_LNEG: /* ..., value ==> ..., - value */
767 var_to_reg_int(s1, src, REG_ITMP1);
768 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
769 M_LSUB(REG_ZERO, s1, d);
770 store_reg_to_var_int(iptr->dst, d);
773 case ICMD_I2L: /* ..., value ==> ..., value */
775 var_to_reg_int(s1, src, REG_ITMP1);
776 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
778 store_reg_to_var_int(iptr->dst, d);
781 case ICMD_L2I: /* ..., value ==> ..., value */
783 var_to_reg_int(s1, src, REG_ITMP1);
784 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
785 M_IADD(s1, REG_ZERO, d );
786 store_reg_to_var_int(iptr->dst, d);
789 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
791 var_to_reg_int(s1, src, REG_ITMP1);
792 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
793 if (has_ext_instr_set) {
797 M_SLL_IMM(s1, 56, d);
798 M_SRA_IMM( d, 56, d);
800 store_reg_to_var_int(iptr->dst, d);
803 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
805 var_to_reg_int(s1, src, REG_ITMP1);
806 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
808 store_reg_to_var_int(iptr->dst, d);
811 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
813 var_to_reg_int(s1, src, REG_ITMP1);
814 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
815 if (has_ext_instr_set) {
819 M_SLL_IMM(s1, 48, d);
820 M_SRA_IMM( d, 48, d);
822 store_reg_to_var_int(iptr->dst, d);
826 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
828 var_to_reg_int(s1, src->prev, REG_ITMP1);
829 var_to_reg_int(s2, src, REG_ITMP2);
830 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
832 store_reg_to_var_int(iptr->dst, d);
835 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
836 /* val.i = constant */
838 var_to_reg_int(s1, src, REG_ITMP1);
839 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
840 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
841 M_IADD_IMM(s1, iptr->val.i, d);
844 ICONST(REG_ITMP2, iptr->val.i);
845 M_IADD(s1, REG_ITMP2, d);
847 store_reg_to_var_int(iptr->dst, d);
850 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
852 var_to_reg_int(s1, src->prev, REG_ITMP1);
853 var_to_reg_int(s2, src, REG_ITMP2);
854 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
856 store_reg_to_var_int(iptr->dst, d);
859 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
860 /* val.l = constant */
862 var_to_reg_int(s1, src, REG_ITMP1);
863 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
864 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
865 M_LADD_IMM(s1, iptr->val.l, d);
868 LCONST(REG_ITMP2, iptr->val.l);
869 M_LADD(s1, REG_ITMP2, d);
871 store_reg_to_var_int(iptr->dst, d);
874 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
876 var_to_reg_int(s1, src->prev, REG_ITMP1);
877 var_to_reg_int(s2, src, REG_ITMP2);
878 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
880 store_reg_to_var_int(iptr->dst, d);
883 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
884 /* val.i = constant */
886 var_to_reg_int(s1, src, REG_ITMP1);
887 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
888 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
889 M_ISUB_IMM(s1, iptr->val.i, d);
892 ICONST(REG_ITMP2, iptr->val.i);
893 M_ISUB(s1, REG_ITMP2, d);
895 store_reg_to_var_int(iptr->dst, d);
898 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
900 var_to_reg_int(s1, src->prev, REG_ITMP1);
901 var_to_reg_int(s2, src, REG_ITMP2);
902 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
904 store_reg_to_var_int(iptr->dst, d);
907 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
908 /* val.l = constant */
910 var_to_reg_int(s1, src, REG_ITMP1);
911 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
912 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
913 M_LSUB_IMM(s1, iptr->val.l, d);
916 LCONST(REG_ITMP2, iptr->val.l);
917 M_LSUB(s1, REG_ITMP2, d);
919 store_reg_to_var_int(iptr->dst, d);
922 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
924 var_to_reg_int(s1, src->prev, REG_ITMP1);
925 var_to_reg_int(s2, src, REG_ITMP2);
926 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
928 store_reg_to_var_int(iptr->dst, d);
931 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
932 /* val.i = constant */
934 var_to_reg_int(s1, src, REG_ITMP1);
935 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
936 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
937 M_IMUL_IMM(s1, iptr->val.i, d);
940 ICONST(REG_ITMP2, iptr->val.i);
941 M_IMUL(s1, REG_ITMP2, d);
943 store_reg_to_var_int(iptr->dst, d);
946 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
948 var_to_reg_int(s1, src->prev, REG_ITMP1);
949 var_to_reg_int(s2, src, REG_ITMP2);
950 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
952 store_reg_to_var_int(iptr->dst, d);
955 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
956 /* val.l = constant */
958 var_to_reg_int(s1, src, REG_ITMP1);
959 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
960 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
961 M_LMUL_IMM(s1, iptr->val.l, d);
964 LCONST(REG_ITMP2, iptr->val.l);
965 M_LMUL(s1, REG_ITMP2, d);
967 store_reg_to_var_int(iptr->dst, d);
970 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
971 case ICMD_LDIVPOW2: /* val.i = constant */
973 var_to_reg_int(s1, src, REG_ITMP1);
974 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
975 if (iptr->val.i <= 15) {
976 M_LDA(REG_ITMP2, s1, (1 << iptr->val.i) -1);
977 M_CMOVGE(s1, s1, REG_ITMP2);
980 M_SRA_IMM(s1, 63, REG_ITMP2);
981 M_SRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
982 M_LADD(s1, REG_ITMP2, REG_ITMP2);
984 M_SRA_IMM(REG_ITMP2, iptr->val.i, d);
985 store_reg_to_var_int(iptr->dst, d);
988 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
990 var_to_reg_int(s1, src->prev, REG_ITMP1);
991 var_to_reg_int(s2, src, REG_ITMP2);
992 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
993 M_AND_IMM(s2, 0x1f, REG_ITMP3);
994 M_SLL(s1, REG_ITMP3, d);
995 M_IADD(d, REG_ZERO, d);
996 store_reg_to_var_int(iptr->dst, d);
999 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1000 /* val.i = constant */
1002 var_to_reg_int(s1, src, REG_ITMP1);
1003 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1004 M_SLL_IMM(s1, iptr->val.i & 0x1f, d);
1005 M_IADD(d, REG_ZERO, d);
1006 store_reg_to_var_int(iptr->dst, d);
1009 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1011 var_to_reg_int(s1, src->prev, REG_ITMP1);
1012 var_to_reg_int(s2, src, REG_ITMP2);
1013 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1014 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1015 M_SRA(s1, REG_ITMP3, d);
1016 store_reg_to_var_int(iptr->dst, d);
1019 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1020 /* val.i = constant */
1022 var_to_reg_int(s1, src, REG_ITMP1);
1023 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1024 M_SRA_IMM(s1, iptr->val.i & 0x1f, d);
1025 store_reg_to_var_int(iptr->dst, d);
1028 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1030 var_to_reg_int(s1, src->prev, REG_ITMP1);
1031 var_to_reg_int(s2, src, REG_ITMP2);
1032 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1033 M_AND_IMM(s2, 0x1f, REG_ITMP2);
1035 M_SRL(d, REG_ITMP2, d);
1036 M_IADD(d, REG_ZERO, d);
1037 store_reg_to_var_int(iptr->dst, d);
1040 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1041 /* val.i = constant */
1043 var_to_reg_int(s1, src, REG_ITMP1);
1044 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1046 M_SRL_IMM(d, iptr->val.i & 0x1f, d);
1047 M_IADD(d, REG_ZERO, d);
1048 store_reg_to_var_int(iptr->dst, d);
1051 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1053 var_to_reg_int(s1, src->prev, REG_ITMP1);
1054 var_to_reg_int(s2, src, REG_ITMP2);
1055 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1057 store_reg_to_var_int(iptr->dst, d);
1060 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1061 /* val.i = constant */
1063 var_to_reg_int(s1, src, REG_ITMP1);
1064 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1065 M_SLL_IMM(s1, iptr->val.i & 0x3f, d);
1066 store_reg_to_var_int(iptr->dst, d);
1069 case ICMD_LSHR: /* ..., 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_LSHRCONST: /* ..., 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_SRA_IMM(s1, iptr->val.i & 0x3f, d);
1084 store_reg_to_var_int(iptr->dst, d);
1087 case ICMD_LUSHR: /* ..., 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_LUSHRCONST: /* ..., 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_SRL_IMM(s1, iptr->val.i & 0x3f, d);
1102 store_reg_to_var_int(iptr->dst, d);
1105 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1108 var_to_reg_int(s1, src->prev, REG_ITMP1);
1109 var_to_reg_int(s2, src, REG_ITMP2);
1110 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1112 store_reg_to_var_int(iptr->dst, d);
1115 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1116 /* val.i = constant */
1118 var_to_reg_int(s1, src, REG_ITMP1);
1119 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1120 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1121 M_AND_IMM(s1, iptr->val.i, d);
1123 else if (iptr->val.i == 0xffff) {
1126 else if (iptr->val.i == 0xffffff) {
1127 M_ZAPNOT_IMM(s1, 0x07, d);
1130 ICONST(REG_ITMP2, iptr->val.i);
1131 M_AND(s1, REG_ITMP2, d);
1133 store_reg_to_var_int(iptr->dst, d);
1136 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1137 /* val.i = constant */
1139 var_to_reg_int(s1, src, REG_ITMP1);
1140 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1142 M_MOV(s1, REG_ITMP1);
1145 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1146 M_AND_IMM(s1, iptr->val.i, d);
1148 M_ISUB(REG_ZERO, s1, d);
1149 M_AND_IMM(d, iptr->val.i, d);
1151 else if (iptr->val.i == 0xffff) {
1154 M_ISUB(REG_ZERO, s1, d);
1157 else if (iptr->val.i == 0xffffff) {
1158 M_ZAPNOT_IMM(s1, 0x07, d);
1160 M_ISUB(REG_ZERO, s1, d);
1161 M_ZAPNOT_IMM(d, 0x07, d);
1164 ICONST(REG_ITMP2, iptr->val.i);
1165 M_AND(s1, REG_ITMP2, d);
1167 M_ISUB(REG_ZERO, s1, d);
1168 M_AND(d, REG_ITMP2, d);
1170 M_ISUB(REG_ZERO, d, d);
1171 store_reg_to_var_int(iptr->dst, d);
1174 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1175 /* val.l = constant */
1177 var_to_reg_int(s1, src, REG_ITMP1);
1178 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1179 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1180 M_AND_IMM(s1, iptr->val.l, d);
1182 else if (iptr->val.l == 0xffffL) {
1185 else if (iptr->val.l == 0xffffffL) {
1186 M_ZAPNOT_IMM(s1, 0x07, d);
1188 else if (iptr->val.l == 0xffffffffL) {
1191 else if (iptr->val.l == 0xffffffffffL) {
1192 M_ZAPNOT_IMM(s1, 0x1f, d);
1194 else if (iptr->val.l == 0xffffffffffffL) {
1195 M_ZAPNOT_IMM(s1, 0x3f, d);
1197 else if (iptr->val.l == 0xffffffffffffffL) {
1198 M_ZAPNOT_IMM(s1, 0x7f, d);
1201 LCONST(REG_ITMP2, iptr->val.l);
1202 M_AND(s1, REG_ITMP2, d);
1204 store_reg_to_var_int(iptr->dst, d);
1207 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1208 /* val.l = constant */
1210 var_to_reg_int(s1, src, REG_ITMP1);
1211 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1213 M_MOV(s1, REG_ITMP1);
1216 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1217 M_AND_IMM(s1, iptr->val.l, d);
1219 M_LSUB(REG_ZERO, s1, d);
1220 M_AND_IMM(d, iptr->val.l, d);
1222 else if (iptr->val.l == 0xffffL) {
1225 M_LSUB(REG_ZERO, s1, d);
1228 else if (iptr->val.l == 0xffffffL) {
1229 M_ZAPNOT_IMM(s1, 0x07, d);
1231 M_LSUB(REG_ZERO, s1, d);
1232 M_ZAPNOT_IMM(d, 0x07, d);
1234 else if (iptr->val.l == 0xffffffffL) {
1237 M_LSUB(REG_ZERO, s1, d);
1240 else if (iptr->val.l == 0xffffffffffL) {
1241 M_ZAPNOT_IMM(s1, 0x1f, d);
1243 M_LSUB(REG_ZERO, s1, d);
1244 M_ZAPNOT_IMM(d, 0x1f, d);
1246 else if (iptr->val.l == 0xffffffffffffL) {
1247 M_ZAPNOT_IMM(s1, 0x3f, d);
1249 M_LSUB(REG_ZERO, s1, d);
1250 M_ZAPNOT_IMM(d, 0x3f, d);
1252 else if (iptr->val.l == 0xffffffffffffffL) {
1253 M_ZAPNOT_IMM(s1, 0x7f, d);
1255 M_LSUB(REG_ZERO, s1, d);
1256 M_ZAPNOT_IMM(d, 0x7f, d);
1259 LCONST(REG_ITMP2, iptr->val.l);
1260 M_AND(s1, REG_ITMP2, d);
1262 M_LSUB(REG_ZERO, s1, d);
1263 M_AND(d, REG_ITMP2, d);
1265 M_LSUB(REG_ZERO, d, d);
1266 store_reg_to_var_int(iptr->dst, d);
1269 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1272 var_to_reg_int(s1, src->prev, REG_ITMP1);
1273 var_to_reg_int(s2, src, REG_ITMP2);
1274 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1276 store_reg_to_var_int(iptr->dst, d);
1279 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1280 /* val.i = constant */
1282 var_to_reg_int(s1, src, REG_ITMP1);
1283 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1284 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1285 M_OR_IMM(s1, iptr->val.i, d);
1288 ICONST(REG_ITMP2, iptr->val.i);
1289 M_OR(s1, REG_ITMP2, d);
1291 store_reg_to_var_int(iptr->dst, d);
1294 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1295 /* val.l = constant */
1297 var_to_reg_int(s1, src, REG_ITMP1);
1298 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1299 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1300 M_OR_IMM(s1, iptr->val.l, d);
1303 LCONST(REG_ITMP2, iptr->val.l);
1304 M_OR(s1, REG_ITMP2, d);
1306 store_reg_to_var_int(iptr->dst, d);
1309 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1312 var_to_reg_int(s1, src->prev, REG_ITMP1);
1313 var_to_reg_int(s2, src, REG_ITMP2);
1314 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1316 store_reg_to_var_int(iptr->dst, d);
1319 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1320 /* val.i = constant */
1322 var_to_reg_int(s1, src, REG_ITMP1);
1323 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1324 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1325 M_XOR_IMM(s1, iptr->val.i, d);
1328 ICONST(REG_ITMP2, iptr->val.i);
1329 M_XOR(s1, REG_ITMP2, d);
1331 store_reg_to_var_int(iptr->dst, d);
1334 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1335 /* val.l = constant */
1337 var_to_reg_int(s1, src, REG_ITMP1);
1338 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1339 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1340 M_XOR_IMM(s1, iptr->val.l, d);
1343 LCONST(REG_ITMP2, iptr->val.l);
1344 M_XOR(s1, REG_ITMP2, d);
1346 store_reg_to_var_int(iptr->dst, d);
1350 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1352 var_to_reg_int(s1, src->prev, REG_ITMP1);
1353 var_to_reg_int(s2, src, REG_ITMP2);
1354 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1355 M_CMPLT(s1, s2, REG_ITMP3);
1356 M_CMPLT(s2, s1, REG_ITMP1);
1357 M_LSUB (REG_ITMP1, REG_ITMP3, d);
1358 store_reg_to_var_int(iptr->dst, d);
1362 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1363 /* op1 = variable, val.i = constant */
1365 var = &(rd->locals[iptr->op1][TYPE_INT]);
1366 if (var->flags & INMEMORY) {
1368 M_LLD(s1, REG_SP, 8 * var->regoff);
1372 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1373 M_IADD_IMM(s1, iptr->val.i, s1);
1375 else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1376 M_ISUB_IMM(s1, (-iptr->val.i), s1);
1379 M_LDA (s1, s1, iptr->val.i);
1380 M_IADD(s1, REG_ZERO, s1);
1382 if (var->flags & INMEMORY)
1383 M_LST(s1, REG_SP, 8 * var->regoff);
1387 /* floating operations ************************************************/
1389 case ICMD_FNEG: /* ..., value ==> ..., - value */
1391 var_to_reg_flt(s1, src, REG_FTMP1);
1392 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1394 store_reg_to_var_flt(iptr->dst, d);
1397 case ICMD_DNEG: /* ..., value ==> ..., - value */
1399 var_to_reg_flt(s1, src, REG_FTMP1);
1400 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1402 store_reg_to_var_flt(iptr->dst, d);
1405 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1407 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1408 var_to_reg_flt(s2, src, REG_FTMP2);
1409 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1414 if (d == s1 || d == s2) {
1415 M_FADDS(s1, s2, REG_FTMP3);
1417 M_FMOV(REG_FTMP3, d);
1424 store_reg_to_var_flt(iptr->dst, d);
1427 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1429 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1430 var_to_reg_flt(s2, src, REG_FTMP2);
1431 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1436 if (d == s1 || d == s2) {
1437 M_DADDS(s1, s2, REG_FTMP3);
1439 M_FMOV(REG_FTMP3, d);
1446 store_reg_to_var_flt(iptr->dst, d);
1449 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1451 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1452 var_to_reg_flt(s2, src, REG_FTMP2);
1453 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1458 if (d == s1 || d == s2) {
1459 M_FSUBS(s1, s2, REG_FTMP3);
1461 M_FMOV(REG_FTMP3, d);
1468 store_reg_to_var_flt(iptr->dst, d);
1471 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1473 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1474 var_to_reg_flt(s2, src, REG_FTMP2);
1475 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1480 if (d == s1 || d == s2) {
1481 M_DSUBS(s1, s2, REG_FTMP3);
1483 M_FMOV(REG_FTMP3, d);
1490 store_reg_to_var_flt(iptr->dst, d);
1493 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1495 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1496 var_to_reg_flt(s2, src, REG_FTMP2);
1497 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1502 if (d == s1 || d == s2) {
1503 M_FMULS(s1, s2, REG_FTMP3);
1505 M_FMOV(REG_FTMP3, d);
1512 store_reg_to_var_flt(iptr->dst, d);
1515 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1517 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1518 var_to_reg_flt(s2, src, REG_FTMP2);
1519 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1524 if (d == s1 || d == s2) {
1525 M_DMULS(s1, s2, REG_FTMP3);
1527 M_FMOV(REG_FTMP3, d);
1534 store_reg_to_var_flt(iptr->dst, d);
1537 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1539 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1540 var_to_reg_flt(s2, src, REG_FTMP2);
1541 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1546 if (d == s1 || d == s2) {
1547 M_FDIVS(s1, s2, REG_FTMP3);
1549 M_FMOV(REG_FTMP3, d);
1556 store_reg_to_var_flt(iptr->dst, d);
1559 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1561 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1562 var_to_reg_flt(s2, src, REG_FTMP2);
1563 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1568 if (d == s1 || d == s2) {
1569 M_DDIVS(s1, s2, REG_FTMP3);
1571 M_FMOV(REG_FTMP3, d);
1578 store_reg_to_var_flt(iptr->dst, d);
1581 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1583 var_to_reg_int(s1, src, REG_ITMP1);
1584 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1585 a = dseg_adddouble(cd, 0.0);
1586 M_LST (s1, REG_PV, a);
1587 M_DLD (d, REG_PV, a);
1589 store_reg_to_var_flt(iptr->dst, d);
1592 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1594 var_to_reg_int(s1, src, REG_ITMP1);
1595 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1596 a = dseg_adddouble(cd, 0.0);
1597 M_LST (s1, REG_PV, a);
1598 M_DLD (d, REG_PV, a);
1600 store_reg_to_var_flt(iptr->dst, d);
1603 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1605 var_to_reg_flt(s1, src, REG_FTMP1);
1606 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1607 a = dseg_adddouble(cd, 0.0);
1608 M_CVTDL_C(s1, REG_FTMP2);
1609 M_CVTLI(REG_FTMP2, REG_FTMP3);
1610 M_DST (REG_FTMP3, REG_PV, a);
1611 M_ILD (d, REG_PV, a);
1612 store_reg_to_var_int(iptr->dst, d);
1615 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1617 var_to_reg_flt(s1, src, REG_FTMP1);
1618 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1619 a = dseg_adddouble(cd, 0.0);
1620 M_CVTDL_C(s1, REG_FTMP2);
1621 M_DST (REG_FTMP2, REG_PV, a);
1622 M_LLD (d, REG_PV, a);
1623 store_reg_to_var_int(iptr->dst, d);
1626 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1628 var_to_reg_flt(s1, src, REG_FTMP1);
1629 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1632 store_reg_to_var_flt(iptr->dst, d);
1635 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1637 var_to_reg_flt(s1, src, REG_FTMP1);
1638 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1646 store_reg_to_var_flt(iptr->dst, d);
1649 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1651 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1652 var_to_reg_flt(s2, src, REG_FTMP2);
1653 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1655 M_LSUB_IMM(REG_ZERO, 1, d);
1656 M_FCMPEQ(s1, s2, REG_FTMP3);
1657 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1659 M_FCMPLT(s2, s1, REG_FTMP3);
1660 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1661 M_LADD_IMM(REG_ZERO, 1, d);
1664 M_LSUB_IMM(REG_ZERO, 1, d);
1665 M_FCMPEQS(s1, s2, REG_FTMP3);
1667 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1669 M_FCMPLTS(s2, s1, REG_FTMP3);
1671 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1672 M_LADD_IMM(REG_ZERO, 1, d);
1674 store_reg_to_var_int(iptr->dst, d);
1677 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1679 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1680 var_to_reg_flt(s2, src, REG_FTMP2);
1681 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1683 M_LADD_IMM(REG_ZERO, 1, d);
1684 M_FCMPEQ(s1, s2, REG_FTMP3);
1685 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1687 M_FCMPLT(s1, s2, REG_FTMP3);
1688 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1689 M_LSUB_IMM(REG_ZERO, 1, d);
1692 M_LADD_IMM(REG_ZERO, 1, d);
1693 M_FCMPEQS(s1, s2, REG_FTMP3);
1695 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1697 M_FCMPLTS(s1, s2, REG_FTMP3);
1699 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1700 M_LSUB_IMM(REG_ZERO, 1, d);
1702 store_reg_to_var_int(iptr->dst, d);
1706 /* memory operations **************************************************/
1708 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1710 var_to_reg_int(s1, src, REG_ITMP1);
1711 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1712 gen_nullptr_check(s1);
1713 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1714 store_reg_to_var_int(iptr->dst, d);
1717 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1719 var_to_reg_int(s1, src->prev, REG_ITMP1);
1720 var_to_reg_int(s2, src, REG_ITMP2);
1721 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1722 if (iptr->op1 == 0) {
1723 gen_nullptr_check(s1);
1726 M_SAADDQ(s2, s1, REG_ITMP1);
1727 M_ALD( d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1728 store_reg_to_var_int(iptr->dst, d);
1731 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1733 var_to_reg_int(s1, src->prev, REG_ITMP1);
1734 var_to_reg_int(s2, src, REG_ITMP2);
1735 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1736 if (iptr->op1 == 0) {
1737 gen_nullptr_check(s1);
1740 M_S8ADDQ(s2, s1, REG_ITMP1);
1741 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1742 store_reg_to_var_int(iptr->dst, d);
1745 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1747 var_to_reg_int(s1, src->prev, REG_ITMP1);
1748 var_to_reg_int(s2, src, REG_ITMP2);
1749 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1750 if (iptr->op1 == 0) {
1751 gen_nullptr_check(s1);
1755 M_S4ADDQ(s2, s1, REG_ITMP1);
1756 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1757 store_reg_to_var_int(iptr->dst, d);
1760 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1762 var_to_reg_int(s1, src->prev, REG_ITMP1);
1763 var_to_reg_int(s2, src, REG_ITMP2);
1764 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1765 if (iptr->op1 == 0) {
1766 gen_nullptr_check(s1);
1769 M_S4ADDQ(s2, s1, REG_ITMP1);
1770 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1771 store_reg_to_var_flt(iptr->dst, d);
1774 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1776 var_to_reg_int(s1, src->prev, REG_ITMP1);
1777 var_to_reg_int(s2, src, REG_ITMP2);
1778 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1779 if (iptr->op1 == 0) {
1780 gen_nullptr_check(s1);
1783 M_S8ADDQ(s2, s1, REG_ITMP1);
1784 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1785 store_reg_to_var_flt(iptr->dst, d);
1788 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1790 var_to_reg_int(s1, src->prev, REG_ITMP1);
1791 var_to_reg_int(s2, src, REG_ITMP2);
1792 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1793 if (iptr->op1 == 0) {
1794 gen_nullptr_check(s1);
1797 if (has_ext_instr_set) {
1798 M_LADD(s2, s1, REG_ITMP1);
1799 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1800 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1803 M_LADD (s2, s1, REG_ITMP1);
1804 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1805 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1806 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1807 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
1809 store_reg_to_var_int(iptr->dst, d);
1812 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1814 var_to_reg_int(s1, src->prev, REG_ITMP1);
1815 var_to_reg_int(s2, src, REG_ITMP2);
1816 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1817 if (iptr->op1 == 0) {
1818 gen_nullptr_check(s1);
1821 if (has_ext_instr_set) {
1822 M_LADD(s2, s1, REG_ITMP1);
1823 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1824 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1828 M_LADD(s2, s1, REG_ITMP1);
1829 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1830 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1831 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1832 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1833 M_SRA_IMM(d, 48, d);
1835 store_reg_to_var_int(iptr->dst, d);
1838 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1840 var_to_reg_int(s1, src->prev, REG_ITMP1);
1841 var_to_reg_int(s2, src, REG_ITMP2);
1842 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1843 if (iptr->op1 == 0) {
1844 gen_nullptr_check(s1);
1847 if (has_ext_instr_set) {
1848 M_LADD (s2, s1, REG_ITMP1);
1849 M_BLDU (d, REG_ITMP1, OFFSET (java_bytearray, data[0]));
1853 M_LADD(s2, s1, REG_ITMP1);
1854 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1855 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
1856 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1857 M_SRA_IMM(d, 56, d);
1859 store_reg_to_var_int(iptr->dst, d);
1863 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1865 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1866 var_to_reg_int(s2, src->prev, REG_ITMP2);
1867 if (iptr->op1 == 0) {
1868 gen_nullptr_check(s1);
1871 var_to_reg_int(s3, src, REG_ITMP3);
1872 M_SAADDQ(s2, s1, REG_ITMP1);
1873 M_AST (s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1876 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1878 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1879 var_to_reg_int(s2, src->prev, REG_ITMP2);
1880 if (iptr->op1 == 0) {
1881 gen_nullptr_check(s1);
1884 var_to_reg_int(s3, src, REG_ITMP3);
1885 M_S8ADDQ(s2, s1, REG_ITMP1);
1886 M_LST (s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1889 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1891 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1892 var_to_reg_int(s2, src->prev, REG_ITMP2);
1893 if (iptr->op1 == 0) {
1894 gen_nullptr_check(s1);
1898 var_to_reg_int(s3, src, REG_ITMP3);
1899 M_S4ADDQ(s2, s1, REG_ITMP1);
1900 M_IST (s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1903 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1905 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1906 var_to_reg_int(s2, src->prev, REG_ITMP2);
1907 if (iptr->op1 == 0) {
1908 gen_nullptr_check(s1);
1911 var_to_reg_flt(s3, src, REG_FTMP3);
1912 M_S4ADDQ(s2, s1, REG_ITMP1);
1913 M_FST (s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1916 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1918 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1919 var_to_reg_int(s2, src->prev, REG_ITMP2);
1920 if (iptr->op1 == 0) {
1921 gen_nullptr_check(s1);
1924 var_to_reg_flt(s3, src, REG_FTMP3);
1925 M_S8ADDQ(s2, s1, REG_ITMP1);
1926 M_DST (s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1929 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1931 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1932 var_to_reg_int(s2, src->prev, REG_ITMP2);
1933 if (iptr->op1 == 0) {
1934 gen_nullptr_check(s1);
1937 var_to_reg_int(s3, src, REG_ITMP3);
1938 if (has_ext_instr_set) {
1939 M_LADD(s2, s1, REG_ITMP1);
1940 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1941 M_SST (s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1944 M_LADD (s2, s1, REG_ITMP1);
1945 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1946 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1947 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1948 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1949 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1950 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
1951 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1955 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1957 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1958 var_to_reg_int(s2, src->prev, REG_ITMP2);
1959 if (iptr->op1 == 0) {
1960 gen_nullptr_check(s1);
1963 var_to_reg_int(s3, src, REG_ITMP3);
1964 if (has_ext_instr_set) {
1965 M_LADD(s2, s1, REG_ITMP1);
1966 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1967 M_SST (s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1970 M_LADD (s2, s1, REG_ITMP1);
1971 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1972 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1973 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1974 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1975 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1976 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
1977 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1981 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1983 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1984 var_to_reg_int(s2, src->prev, REG_ITMP2);
1985 if (iptr->op1 == 0) {
1986 gen_nullptr_check(s1);
1989 var_to_reg_int(s3, src, REG_ITMP3);
1990 if (has_ext_instr_set) {
1991 M_LADD(s2, s1, REG_ITMP1);
1992 M_BST (s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1995 M_LADD (s2, s1, REG_ITMP1);
1996 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1997 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1998 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
1999 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2000 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2001 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2006 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
2008 var_to_reg_int(s1, src->prev, REG_ITMP1);
2009 var_to_reg_int(s2, src, REG_ITMP2);
2010 if (iptr->op1 == 0) {
2011 gen_nullptr_check(s1);
2014 M_S4ADDQ(s2, s1, REG_ITMP1);
2015 M_IST(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
2018 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
2020 var_to_reg_int(s1, src->prev, REG_ITMP1);
2021 var_to_reg_int(s2, src, REG_ITMP2);
2022 if (iptr->op1 == 0) {
2023 gen_nullptr_check(s1);
2026 M_S8ADDQ(s2, s1, REG_ITMP1);
2027 M_LST(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
2030 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
2032 var_to_reg_int(s1, src->prev, REG_ITMP1);
2033 var_to_reg_int(s2, src, REG_ITMP2);
2034 if (iptr->op1 == 0) {
2035 gen_nullptr_check(s1);
2038 M_SAADDQ(s2, s1, REG_ITMP1);
2039 M_AST(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
2042 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
2044 var_to_reg_int(s1, src->prev, REG_ITMP1);
2045 var_to_reg_int(s2, src, REG_ITMP2);
2046 if (iptr->op1 == 0) {
2047 gen_nullptr_check(s1);
2050 if (has_ext_instr_set) {
2051 M_LADD(s2, s1, REG_ITMP1);
2052 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2055 M_LADD(s2, s1, REG_ITMP1);
2056 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2057 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2058 M_INSBL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2059 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2060 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2061 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2065 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
2067 var_to_reg_int(s1, src->prev, REG_ITMP1);
2068 var_to_reg_int(s2, src, REG_ITMP2);
2069 if (iptr->op1 == 0) {
2070 gen_nullptr_check(s1);
2073 if (has_ext_instr_set) {
2074 M_LADD(s2, s1, REG_ITMP1);
2075 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2076 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
2079 M_LADD(s2, s1, REG_ITMP1);
2080 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2081 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2082 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2083 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2084 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2085 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2086 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2090 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
2092 var_to_reg_int(s1, src->prev, REG_ITMP1);
2093 var_to_reg_int(s2, src, REG_ITMP2);
2094 if (iptr->op1 == 0) {
2095 gen_nullptr_check(s1);
2098 if (has_ext_instr_set) {
2099 M_LADD(s2, s1, REG_ITMP1);
2100 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2101 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2104 M_LADD(s2, s1, REG_ITMP1);
2105 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2106 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2107 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2108 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2109 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2110 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2111 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2116 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2117 /* op1 = type, val.a = field address */
2119 /* If the static fields' class is not yet initialized, we do it */
2120 /* now. The call code is generated later. */
2121 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
2122 codegen_addclinitref(cd, mcodeptr, ((fieldinfo *) iptr->val.a)->class);
2124 /* This is just for debugging purposes. Is very difficult to */
2125 /* read patched code. Here we patch the following 2 nop's */
2126 /* so that the real code keeps untouched. */
2127 if (showdisassemble) {
2132 a = dseg_addaddress(cd, &(((fieldinfo *)(iptr->val.a))->value));
2133 M_ALD(REG_ITMP1, REG_PV, a);
2134 switch (iptr->op1) {
2136 var_to_reg_int(s2, src, REG_ITMP2);
2137 M_IST(s2, REG_ITMP1, 0);
2140 var_to_reg_int(s2, src, REG_ITMP2);
2141 M_LST(s2, REG_ITMP1, 0);
2144 var_to_reg_int(s2, src, REG_ITMP2);
2145 M_AST(s2, REG_ITMP1, 0);
2148 var_to_reg_flt(s2, src, REG_FTMP2);
2149 M_FST(s2, REG_ITMP1, 0);
2152 var_to_reg_flt(s2, src, REG_FTMP2);
2153 M_DST(s2, REG_ITMP1, 0);
2155 default: panic ("internal error");
2159 case ICMD_GETSTATIC: /* ... ==> ..., value */
2160 /* op1 = type, val.a = field address */
2162 /* if class isn't yet initialized, do it */
2163 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
2164 codegen_addclinitref(cd, mcodeptr, ((fieldinfo *) iptr->val.a)->class);
2166 /* This is just for debugging purposes. Is very difficult to */
2167 /* read patched code. Here we patch the following 2 nop's */
2168 /* so that the real code keeps untouched. */
2169 if (showdisassemble) {
2174 a = dseg_addaddress(cd, &(((fieldinfo *) iptr->val.a)->value));
2175 M_ALD(REG_ITMP1, REG_PV, a);
2176 switch (iptr->op1) {
2178 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2179 M_ILD(d, REG_ITMP1, 0);
2180 store_reg_to_var_int(iptr->dst, d);
2183 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2184 M_LLD(d, REG_ITMP1, 0);
2185 store_reg_to_var_int(iptr->dst, d);
2188 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2189 M_ALD(d, REG_ITMP1, 0);
2190 store_reg_to_var_int(iptr->dst, d);
2193 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2194 M_FLD(d, REG_ITMP1, 0);
2195 store_reg_to_var_flt(iptr->dst, d);
2198 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2199 M_DLD(d, REG_ITMP1, 0);
2200 store_reg_to_var_flt(iptr->dst, d);
2202 default: panic ("internal error");
2207 case ICMD_PUTFIELD: /* ..., value ==> ... */
2208 /* op1 = type, val.i = field offset */
2210 a = ((fieldinfo *) iptr->val.a)->offset;
2211 switch (iptr->op1) {
2213 var_to_reg_int(s1, src->prev, REG_ITMP1);
2214 var_to_reg_int(s2, src, REG_ITMP2);
2215 gen_nullptr_check(s1);
2219 var_to_reg_int(s1, src->prev, REG_ITMP1);
2220 var_to_reg_int(s2, src, REG_ITMP2);
2221 gen_nullptr_check(s1);
2225 var_to_reg_int(s1, src->prev, REG_ITMP1);
2226 var_to_reg_int(s2, src, REG_ITMP2);
2227 gen_nullptr_check(s1);
2231 var_to_reg_int(s1, src->prev, REG_ITMP1);
2232 var_to_reg_flt(s2, src, REG_FTMP2);
2233 gen_nullptr_check(s1);
2237 var_to_reg_int(s1, src->prev, REG_ITMP1);
2238 var_to_reg_flt(s2, src, REG_FTMP2);
2239 gen_nullptr_check(s1);
2242 default: panic ("internal error");
2246 case ICMD_GETFIELD: /* ... ==> ..., value */
2247 /* op1 = type, val.i = field offset */
2249 a = ((fieldinfo *)(iptr->val.a))->offset;
2250 switch (iptr->op1) {
2252 var_to_reg_int(s1, src, REG_ITMP1);
2253 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2254 gen_nullptr_check(s1);
2256 store_reg_to_var_int(iptr->dst, d);
2259 var_to_reg_int(s1, src, REG_ITMP1);
2260 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2261 gen_nullptr_check(s1);
2263 store_reg_to_var_int(iptr->dst, d);
2266 var_to_reg_int(s1, src, REG_ITMP1);
2267 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2268 gen_nullptr_check(s1);
2270 store_reg_to_var_int(iptr->dst, d);
2273 var_to_reg_int(s1, src, REG_ITMP1);
2274 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2275 gen_nullptr_check(s1);
2277 store_reg_to_var_flt(iptr->dst, d);
2280 var_to_reg_int(s1, src, REG_ITMP1);
2281 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2282 gen_nullptr_check(s1);
2284 store_reg_to_var_flt(iptr->dst, d);
2286 default: panic ("internal error");
2291 /* branch operations **************************************************/
2293 #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}}
2295 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2297 var_to_reg_int(s1, src, REG_ITMP1);
2298 M_INTMOVE(s1, REG_ITMP1_XPTR);
2299 a = dseg_addaddress(cd, asm_handle_exception);
2300 M_ALD(REG_ITMP2, REG_PV, a);
2301 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2302 M_NOP; /* nop ensures that XPC is less than the end */
2303 /* of basic block */
2307 case ICMD_GOTO: /* ... ==> ... */
2308 /* op1 = target JavaVM pc */
2310 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2314 case ICMD_JSR: /* ... ==> ... */
2315 /* op1 = target JavaVM pc */
2317 M_BSR(REG_ITMP1, 0);
2318 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2321 case ICMD_RET: /* ... ==> ... */
2322 /* op1 = local variable */
2324 var = &(rd->locals[iptr->op1][TYPE_ADR]);
2325 if (var->flags & INMEMORY) {
2326 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2327 M_RET(REG_ZERO, REG_ITMP1);
2330 M_RET(REG_ZERO, var->regoff);
2334 case ICMD_IFNULL: /* ..., value ==> ... */
2335 /* op1 = target JavaVM pc */
2337 var_to_reg_int(s1, src, REG_ITMP1);
2339 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2342 case ICMD_IFNONNULL: /* ..., value ==> ... */
2343 /* op1 = target JavaVM pc */
2345 var_to_reg_int(s1, src, REG_ITMP1);
2347 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2350 case ICMD_IFEQ: /* ..., value ==> ... */
2351 /* op1 = target JavaVM pc, val.i = constant */
2353 var_to_reg_int(s1, src, REG_ITMP1);
2354 if (iptr->val.i == 0) {
2358 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2359 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2362 ICONST(REG_ITMP2, iptr->val.i);
2363 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2365 M_BNEZ(REG_ITMP1, 0);
2367 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2370 case ICMD_IFLT: /* ..., value ==> ... */
2371 /* op1 = target JavaVM pc, val.i = constant */
2373 var_to_reg_int(s1, src, REG_ITMP1);
2374 if (iptr->val.i == 0) {
2378 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2379 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2382 ICONST(REG_ITMP2, iptr->val.i);
2383 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2385 M_BNEZ(REG_ITMP1, 0);
2387 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2390 case ICMD_IFLE: /* ..., value ==> ... */
2391 /* op1 = target JavaVM pc, val.i = constant */
2393 var_to_reg_int(s1, src, REG_ITMP1);
2394 if (iptr->val.i == 0) {
2398 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2399 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2402 ICONST(REG_ITMP2, iptr->val.i);
2403 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2405 M_BNEZ(REG_ITMP1, 0);
2407 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2410 case ICMD_IFNE: /* ..., value ==> ... */
2411 /* op1 = target JavaVM pc, val.i = constant */
2413 var_to_reg_int(s1, src, REG_ITMP1);
2414 if (iptr->val.i == 0) {
2418 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2419 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2422 ICONST(REG_ITMP2, iptr->val.i);
2423 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2425 M_BEQZ(REG_ITMP1, 0);
2427 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2430 case ICMD_IFGT: /* ..., value ==> ... */
2431 /* op1 = target JavaVM pc, val.i = constant */
2433 var_to_reg_int(s1, src, REG_ITMP1);
2434 if (iptr->val.i == 0) {
2438 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2439 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2442 ICONST(REG_ITMP2, iptr->val.i);
2443 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2445 M_BEQZ(REG_ITMP1, 0);
2447 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2450 case ICMD_IFGE: /* ..., value ==> ... */
2451 /* op1 = target JavaVM pc, val.i = constant */
2453 var_to_reg_int(s1, src, REG_ITMP1);
2454 if (iptr->val.i == 0) {
2458 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2459 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2462 ICONST(REG_ITMP2, iptr->val.i);
2463 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2465 M_BEQZ(REG_ITMP1, 0);
2467 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2470 case ICMD_IF_LEQ: /* ..., value ==> ... */
2471 /* op1 = target JavaVM pc, val.l = constant */
2473 var_to_reg_int(s1, src, REG_ITMP1);
2474 if (iptr->val.l == 0) {
2478 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2479 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2482 LCONST(REG_ITMP2, iptr->val.l);
2483 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2485 M_BNEZ(REG_ITMP1, 0);
2487 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2490 case ICMD_IF_LLT: /* ..., value ==> ... */
2491 /* op1 = target JavaVM pc, val.l = constant */
2493 var_to_reg_int(s1, src, REG_ITMP1);
2494 if (iptr->val.l == 0) {
2498 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2499 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2502 LCONST(REG_ITMP2, iptr->val.l);
2503 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2505 M_BNEZ(REG_ITMP1, 0);
2507 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2510 case ICMD_IF_LLE: /* ..., value ==> ... */
2511 /* op1 = target JavaVM pc, val.l = constant */
2513 var_to_reg_int(s1, src, REG_ITMP1);
2514 if (iptr->val.l == 0) {
2518 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2519 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2522 LCONST(REG_ITMP2, iptr->val.l);
2523 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2525 M_BNEZ(REG_ITMP1, 0);
2527 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2530 case ICMD_IF_LNE: /* ..., value ==> ... */
2531 /* op1 = target JavaVM pc, val.l = constant */
2533 var_to_reg_int(s1, src, REG_ITMP1);
2534 if (iptr->val.l == 0) {
2538 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2539 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2542 LCONST(REG_ITMP2, iptr->val.l);
2543 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2545 M_BEQZ(REG_ITMP1, 0);
2547 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2550 case ICMD_IF_LGT: /* ..., value ==> ... */
2551 /* op1 = target JavaVM pc, val.l = constant */
2553 var_to_reg_int(s1, src, REG_ITMP1);
2554 if (iptr->val.l == 0) {
2558 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2559 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2562 LCONST(REG_ITMP2, iptr->val.l);
2563 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2565 M_BEQZ(REG_ITMP1, 0);
2567 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2570 case ICMD_IF_LGE: /* ..., value ==> ... */
2571 /* op1 = target JavaVM pc, val.l = constant */
2573 var_to_reg_int(s1, src, REG_ITMP1);
2574 if (iptr->val.l == 0) {
2578 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2579 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2582 LCONST(REG_ITMP2, iptr->val.l);
2583 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2585 M_BEQZ(REG_ITMP1, 0);
2587 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2590 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2591 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2592 case ICMD_IF_ACMPEQ:
2594 var_to_reg_int(s1, src->prev, REG_ITMP1);
2595 var_to_reg_int(s2, src, REG_ITMP2);
2596 M_CMPEQ(s1, s2, REG_ITMP1);
2597 M_BNEZ(REG_ITMP1, 0);
2598 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2601 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2602 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2603 case ICMD_IF_ACMPNE:
2605 var_to_reg_int(s1, src->prev, REG_ITMP1);
2606 var_to_reg_int(s2, src, REG_ITMP2);
2607 M_CMPEQ(s1, s2, REG_ITMP1);
2608 M_BEQZ(REG_ITMP1, 0);
2609 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2612 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2613 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2615 var_to_reg_int(s1, src->prev, REG_ITMP1);
2616 var_to_reg_int(s2, src, REG_ITMP2);
2617 M_CMPLT(s1, s2, REG_ITMP1);
2618 M_BNEZ(REG_ITMP1, 0);
2619 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2622 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2623 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2625 var_to_reg_int(s1, src->prev, REG_ITMP1);
2626 var_to_reg_int(s2, src, REG_ITMP2);
2627 M_CMPLE(s1, s2, REG_ITMP1);
2628 M_BEQZ(REG_ITMP1, 0);
2629 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2632 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2633 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2635 var_to_reg_int(s1, src->prev, REG_ITMP1);
2636 var_to_reg_int(s2, src, REG_ITMP2);
2637 M_CMPLE(s1, s2, REG_ITMP1);
2638 M_BNEZ(REG_ITMP1, 0);
2639 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2642 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2643 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2645 var_to_reg_int(s1, src->prev, REG_ITMP1);
2646 var_to_reg_int(s2, src, REG_ITMP2);
2647 M_CMPLT(s1, s2, REG_ITMP1);
2648 M_BEQZ(REG_ITMP1, 0);
2649 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2652 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2654 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2657 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2658 /* val.i = constant */
2660 var_to_reg_int(s1, src, REG_ITMP1);
2661 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2663 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2664 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2665 M_CMPEQ(s1, REG_ZERO, d);
2666 store_reg_to_var_int(iptr->dst, d);
2669 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2670 M_CMPEQ(s1, REG_ZERO, d);
2672 store_reg_to_var_int(iptr->dst, d);
2676 M_MOV(s1, REG_ITMP1);
2679 ICONST(d, iptr[1].val.i);
2681 if ((s3 >= 0) && (s3 <= 255)) {
2682 M_CMOVEQ_IMM(s1, s3, d);
2685 ICONST(REG_ITMP2, s3);
2686 M_CMOVEQ(s1, REG_ITMP2, d);
2688 store_reg_to_var_int(iptr->dst, d);
2691 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2692 /* val.i = constant */
2694 var_to_reg_int(s1, src, REG_ITMP1);
2695 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2697 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2698 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2699 M_CMPEQ(s1, REG_ZERO, d);
2700 store_reg_to_var_int(iptr->dst, d);
2703 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2704 M_CMPEQ(s1, REG_ZERO, d);
2706 store_reg_to_var_int(iptr->dst, d);
2710 M_MOV(s1, REG_ITMP1);
2713 ICONST(d, iptr[1].val.i);
2715 if ((s3 >= 0) && (s3 <= 255)) {
2716 M_CMOVNE_IMM(s1, s3, d);
2719 ICONST(REG_ITMP2, s3);
2720 M_CMOVNE(s1, REG_ITMP2, d);
2722 store_reg_to_var_int(iptr->dst, d);
2725 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2726 /* val.i = constant */
2728 var_to_reg_int(s1, src, REG_ITMP1);
2729 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2731 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2732 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2733 M_CMPLT(s1, REG_ZERO, d);
2734 store_reg_to_var_int(iptr->dst, d);
2737 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2738 M_CMPLE(REG_ZERO, s1, d);
2739 store_reg_to_var_int(iptr->dst, d);
2743 M_MOV(s1, REG_ITMP1);
2746 ICONST(d, iptr[1].val.i);
2748 if ((s3 >= 0) && (s3 <= 255)) {
2749 M_CMOVLT_IMM(s1, s3, d);
2752 ICONST(REG_ITMP2, s3);
2753 M_CMOVLT(s1, REG_ITMP2, d);
2755 store_reg_to_var_int(iptr->dst, d);
2758 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2759 /* val.i = constant */
2761 var_to_reg_int(s1, src, REG_ITMP1);
2762 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2764 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2765 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2766 M_CMPLE(REG_ZERO, s1, d);
2767 store_reg_to_var_int(iptr->dst, d);
2770 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2771 M_CMPLT(s1, REG_ZERO, d);
2772 store_reg_to_var_int(iptr->dst, d);
2776 M_MOV(s1, REG_ITMP1);
2779 ICONST(d, iptr[1].val.i);
2781 if ((s3 >= 0) && (s3 <= 255)) {
2782 M_CMOVGE_IMM(s1, s3, d);
2785 ICONST(REG_ITMP2, s3);
2786 M_CMOVGE(s1, REG_ITMP2, d);
2788 store_reg_to_var_int(iptr->dst, d);
2791 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2792 /* val.i = constant */
2794 var_to_reg_int(s1, src, REG_ITMP1);
2795 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2797 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2798 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2799 M_CMPLT(REG_ZERO, s1, d);
2800 store_reg_to_var_int(iptr->dst, d);
2803 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2804 M_CMPLE(s1, REG_ZERO, d);
2805 store_reg_to_var_int(iptr->dst, d);
2809 M_MOV(s1, REG_ITMP1);
2812 ICONST(d, iptr[1].val.i);
2814 if ((s3 >= 0) && (s3 <= 255)) {
2815 M_CMOVGT_IMM(s1, s3, d);
2818 ICONST(REG_ITMP2, s3);
2819 M_CMOVGT(s1, REG_ITMP2, d);
2821 store_reg_to_var_int(iptr->dst, d);
2824 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2825 /* val.i = constant */
2827 var_to_reg_int(s1, src, REG_ITMP1);
2828 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2830 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2831 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2832 M_CMPLE(s1, REG_ZERO, d);
2833 store_reg_to_var_int(iptr->dst, d);
2836 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2837 M_CMPLT(REG_ZERO, s1, d);
2838 store_reg_to_var_int(iptr->dst, d);
2842 M_MOV(s1, REG_ITMP1);
2845 ICONST(d, iptr[1].val.i);
2847 if ((s3 >= 0) && (s3 <= 255)) {
2848 M_CMOVLE_IMM(s1, s3, d);
2851 ICONST(REG_ITMP2, s3);
2852 M_CMOVLE(s1, REG_ITMP2, d);
2854 store_reg_to_var_int(iptr->dst, d);
2858 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2862 var_to_reg_int(s1, src, REG_RESULT);
2863 M_INTMOVE(s1, REG_RESULT);
2865 #if defined(USE_THREADS)
2866 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2868 a = dseg_addaddress(cd, (void *) (builtin_monitorexit));
2869 M_ALD(REG_PV, REG_PV, a);
2870 M_ALD(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
2871 M_LST(REG_RESULT, REG_SP, rd->maxmemuse * 8);
2872 M_JSR(REG_RA, REG_PV);
2873 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
2874 M_LDA(REG_PV, REG_RA, disp);
2875 M_LLD(REG_RESULT, REG_SP, rd->maxmemuse * 8);
2879 goto nowperformreturn;
2881 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2884 var_to_reg_flt(s1, src, REG_FRESULT);
2885 M_FLTMOVE(s1, REG_FRESULT);
2887 #if defined(USE_THREADS)
2888 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2890 a = dseg_addaddress(cd, (void *) (builtin_monitorexit));
2891 M_ALD(REG_PV, REG_PV, a);
2892 M_ALD(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
2893 M_DST(REG_FRESULT, REG_SP, rd->maxmemuse * 8);
2894 M_JSR(REG_RA, REG_PV);
2895 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
2896 M_LDA(REG_PV, REG_RA, disp);
2897 M_DLD(REG_FRESULT, REG_SP, rd->maxmemuse * 8);
2901 goto nowperformreturn;
2903 case ICMD_RETURN: /* ... ==> ... */
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_JSR(REG_RA, REG_PV);
2912 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
2913 M_LDA(REG_PV, REG_RA, disp);
2921 p = parentargs_base;
2923 /* restore return address */
2925 if (!m->isleafmethod) {
2926 p--; M_LLD(REG_RA, REG_SP, p * 8);
2929 /* restore saved registers */
2931 for (i = rd->savintregcnt - 1; i >= rd->maxsavintreguse; i--) {
2932 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2934 for (i = rd->savfltregcnt - 1; i >= rd->maxsavfltreguse; i--) {
2935 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2938 /* deallocate stack */
2940 if (parentargs_base) {
2941 M_LDA(REG_SP, REG_SP, parentargs_base * 8);
2944 /* call trace function */
2947 M_LDA(REG_SP, REG_SP, -3 * 8);
2948 M_AST(REG_RA, REG_SP, 0 * 8);
2949 M_LST(REG_RESULT, REG_SP, 1 * 8);
2950 M_DST(REG_FRESULT, REG_SP, 2 * 8);
2951 a = dseg_addaddress(cd, m);
2952 M_ALD(rd->argintregs[0], REG_PV, a);
2953 M_MOV(REG_RESULT, rd->argintregs[1]);
2954 M_FLTMOVE(REG_FRESULT, rd->argfltregs[2]);
2955 M_FLTMOVE(REG_FRESULT, rd->argfltregs[3]);
2956 a = dseg_addaddress(cd, (void *) builtin_displaymethodstop);
2957 M_ALD(REG_PV, REG_PV, a);
2958 M_JSR(REG_RA, REG_PV);
2959 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
2960 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
2962 s4 ml = -s1, mh = 0;
2963 while (ml < -32768) { ml += 65536; mh--; }
2964 M_LDA(REG_PV, REG_RA, ml);
2965 M_LDAH(REG_PV, REG_PV, mh);
2967 M_DLD(REG_FRESULT, REG_SP, 2 * 8);
2968 M_LLD(REG_RESULT, REG_SP, 1 * 8);
2969 M_ALD(REG_RA, REG_SP, 0 * 8);
2970 M_LDA(REG_SP, REG_SP, 3 * 8);
2973 M_RET(REG_ZERO, REG_RA);
2979 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2984 tptr = (void **) iptr->target;
2986 s4ptr = iptr->val.a;
2987 l = s4ptr[1]; /* low */
2988 i = s4ptr[2]; /* high */
2990 var_to_reg_int(s1, src, REG_ITMP1);
2992 {M_INTMOVE(s1, REG_ITMP1);}
2993 else if (l <= 32768) {
2994 M_LDA(REG_ITMP1, s1, -l);
2997 ICONST(REG_ITMP2, l);
2998 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
3005 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
3007 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
3008 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3010 M_BEQZ(REG_ITMP2, 0);
3013 /* codegen_addreference(cd, BlockPtrOfPC(s4ptr[0]), mcodeptr); */
3014 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3016 /* build jump table top down and use address of lowest entry */
3018 /* s4ptr += 3 + i; */
3022 /* dseg_addtarget(cd, BlockPtrOfPC(*--s4ptr)); */
3023 dseg_addtarget(cd, (basicblock *) tptr[0]);
3028 /* length of dataseg after last dseg_addtarget is used by load */
3030 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
3031 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
3032 M_JMP(REG_ZERO, REG_ITMP2);
3037 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3039 s4 i, l, val, *s4ptr;
3042 tptr = (void **) iptr->target;
3044 s4ptr = iptr->val.a;
3045 l = s4ptr[0]; /* default */
3046 i = s4ptr[1]; /* count */
3048 MCODECHECK((i<<2)+8);
3049 var_to_reg_int(s1, src, REG_ITMP1);
3055 if ((val >= 0) && (val <= 255)) {
3056 M_CMPEQ_IMM(s1, val, REG_ITMP2);
3059 if ((val >= -32768) && (val <= 32767)) {
3060 M_LDA(REG_ITMP2, REG_ZERO, val);
3063 a = dseg_adds4(cd, val);
3064 M_ILD(REG_ITMP2, REG_PV, a);
3066 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
3068 M_BNEZ(REG_ITMP2, 0);
3069 /* codegen_addreference(cd, BlockPtrOfPC(s4ptr[1]), mcodeptr); */
3070 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3074 /* codegen_addreference(cd, BlockPtrOfPC(l), mcodeptr); */
3076 tptr = (void **) iptr->target;
3077 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3084 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
3085 /* op1 = return type, val.a = function pointer*/
3089 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
3090 /* op1 = return type, val.a = function pointer*/
3094 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
3095 /* op1 = return type, val.a = function pointer*/
3099 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3100 /* op1 = arg count, val.a = method pointer */
3102 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3103 /* op1 = arg count, val.a = method pointer */
3105 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3106 /* op1 = arg count, val.a = method pointer */
3108 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
3109 /* op1 = arg count, val.a = method pointer */
3116 MCODECHECK((s3 << 1) + 64);
3118 /* copy arguments to registers or stack location */
3120 for (; --s3 >= 0; src = src->prev) {
3121 if (src->varkind == ARGVAR)
3123 if (IS_INT_LNG_TYPE(src->type)) {
3124 if (s3 < INT_ARG_CNT) {
3125 s1 = rd->argintregs[s3];
3126 var_to_reg_int(d, src, s1);
3130 var_to_reg_int(d, src, REG_ITMP1);
3131 M_LST(d, REG_SP, 8 * (s3 - INT_ARG_CNT));
3135 if (s3 < FLT_ARG_CNT) {
3136 s1 = rd->argfltregs[s3];
3137 var_to_reg_flt(d, src, s1);
3141 var_to_reg_flt(d, src, REG_FTMP1);
3142 M_DST(d, REG_SP, 8 * (s3 - FLT_ARG_CNT));
3148 switch (iptr->opc) {
3152 a = dseg_addaddress(cd, (void *) lm);
3155 M_ALD(REG_PV, REG_PV, a); /* Pointer to built-in-function */
3158 case ICMD_INVOKESTATIC:
3159 case ICMD_INVOKESPECIAL:
3160 a = dseg_addaddress(cd, lm->stubroutine);
3163 M_ALD(REG_PV, REG_PV, a); /* method pointer in r27 */
3166 case ICMD_INVOKEVIRTUAL:
3169 gen_nullptr_check(rd->argintregs[0]);
3170 M_ALD(REG_METHODPTR, rd->argintregs[0],
3171 OFFSET(java_objectheader, vftbl));
3172 M_ALD(REG_PV, REG_METHODPTR, OFFSET(vftbl_t, table[0]) +
3173 sizeof(methodptr) * lm->vftblindex);
3176 case ICMD_INVOKEINTERFACE:
3179 gen_nullptr_check(rd->argintregs[0]);
3180 M_ALD(REG_METHODPTR, rd->argintregs[0],
3181 OFFSET(java_objectheader, vftbl));
3182 M_ALD(REG_METHODPTR, REG_METHODPTR,
3183 OFFSET(vftbl_t, interfacetable[0]) -
3184 sizeof(methodptr*) * lm->class->index);
3185 M_ALD(REG_PV, REG_METHODPTR,
3186 sizeof(methodptr) * (lm - lm->class->methods));
3190 M_JSR(REG_RA, REG_PV);
3194 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3195 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3197 s4 ml = -s1, mh = 0;
3198 while (ml < -32768) { ml += 65536; mh--; }
3199 M_LDA(REG_PV, REG_RA, ml);
3200 M_LDAH(REG_PV, REG_PV, mh);
3203 /* d contains return type */
3205 if (d != TYPE_VOID) {
3206 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3207 s1 = reg_of_var(rd, iptr->dst, REG_RESULT);
3208 M_INTMOVE(REG_RESULT, s1);
3209 store_reg_to_var_int(iptr->dst, s1);
3212 s1 = reg_of_var(rd, iptr->dst, REG_FRESULT);
3213 M_FLTMOVE(REG_FRESULT, s1);
3214 store_reg_to_var_flt(iptr->dst, s1);
3221 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3223 /* op1: 0 == array, 1 == class */
3224 /* val.a: (classinfo*) superclass */
3226 /* superclass is an interface:
3228 * return (sub != NULL) &&
3229 * (sub->vftbl->interfacetablelength > super->index) &&
3230 * (sub->vftbl->interfacetable[-super->index] != NULL);
3232 * superclass is a class:
3234 * return ((sub != NULL) && (0
3235 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3236 * super->vftbl->diffvall));
3240 classinfo *super = (classinfo*) iptr->val.a;
3242 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3243 codegen_threadcritrestart(cd, (u1 *) mcodeptr - cd->mcodebase);
3245 var_to_reg_int(s1, src, REG_ITMP1);
3246 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
3248 M_MOV(s1, REG_ITMP1);
3252 if (iptr->op1) { /* class/interface */
3253 if (super->flags & ACC_INTERFACE) { /* interface */
3255 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3256 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3257 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3258 M_BLEZ(REG_ITMP2, 2);
3259 M_ALD(REG_ITMP1, REG_ITMP1,
3260 OFFSET(vftbl_t, interfacetable[0]) -
3261 super->index * sizeof(methodptr*));
3262 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3266 s2 = super->vftbl->diffval;
3267 M_BEQZ(s1, 4 + (s2 > 255));
3268 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3269 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3270 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3272 M_CMPULE_IMM(REG_ITMP1, s2, d);
3274 M_LDA(REG_ITMP2, REG_ZERO, s2);
3275 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3279 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3280 a = dseg_addaddress(cd, (void*) super->vftbl);
3281 M_ALD(REG_ITMP2, REG_PV, a);
3282 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3283 codegen_threadcritstart(cd, (u1 *) mcodeptr - cd->mcodebase);
3285 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3286 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3287 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3288 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3289 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3291 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3292 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3296 panic ("internal error: no inlined array instanceof");
3298 store_reg_to_var_int(iptr->dst, d);
3301 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3303 /* op1: 0 == array, 1 == class */
3304 /* val.a: (classinfo*) superclass */
3306 /* superclass is an interface:
3308 * OK if ((sub == NULL) ||
3309 * (sub->vftbl->interfacetablelength > super->index) &&
3310 * (sub->vftbl->interfacetable[-super->index] != NULL));
3312 * superclass is a class:
3314 * OK if ((sub == NULL) || (0
3315 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3316 * super->vftbl->diffvall));
3320 classinfo *super = (classinfo *) iptr->val.a;
3322 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3323 codegen_threadcritrestart(cd, (u1 *) mcodeptr - cd->mcodebase);
3325 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
3326 var_to_reg_int(s1, src, d);
3327 if (iptr->op1) { /* class/interface */
3328 if (super->flags & ACC_INTERFACE) { /* interface */
3330 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3331 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3332 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3333 M_BLEZ(REG_ITMP2, 0);
3334 codegen_addxcastrefs(cd, mcodeptr);
3335 M_ALD(REG_ITMP2, REG_ITMP1,
3336 OFFSET(vftbl_t, interfacetable[0]) -
3337 super->index * sizeof(methodptr*));
3338 M_BEQZ(REG_ITMP2, 0);
3339 codegen_addxcastrefs(cd, mcodeptr);
3343 s2 = super->vftbl->diffval;
3344 M_BEQZ(s1, 4 + (s2 != 0) + (s2 > 255));
3345 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3346 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3347 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3349 M_BNEZ(REG_ITMP1, 0);
3351 else if (s2 <= 255) {
3352 M_CMPULE_IMM(REG_ITMP1, s2, REG_ITMP2);
3353 M_BEQZ(REG_ITMP2, 0);
3356 M_LDA(REG_ITMP2, REG_ZERO, s2);
3357 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3358 M_BEQZ(REG_ITMP2, 0);
3361 M_BEQZ(s1, 8 + (d == REG_ITMP3));
3362 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3363 a = dseg_addaddress(cd, (void *) super->vftbl);
3364 M_ALD(REG_ITMP2, REG_PV, a);
3365 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3366 codegen_threadcritstart(cd, (u1 *) mcodeptr - cd->mcodebase);
3368 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3369 if (d != REG_ITMP3) {
3370 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3371 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3372 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3373 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3375 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3378 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3379 M_ISUB(REG_ITMP1, REG_ITMP2, REG_ITMP1);
3380 M_ALD(REG_ITMP2, REG_PV, a);
3381 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3382 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3383 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3386 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3387 M_BEQZ(REG_ITMP2, 0);
3388 codegen_addxcastrefs(cd, mcodeptr);
3392 panic ("internal error: no inlined array checkcast");
3395 store_reg_to_var_int(iptr->dst, d);
3398 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
3400 var_to_reg_int(s1, src, REG_ITMP1);
3402 codegen_addxcheckarefs(cd, mcodeptr);
3405 case ICMD_CHECKEXCEPTION: /* ... ==> ... */
3407 M_BEQZ(REG_RESULT, 0);
3408 codegen_addxexceptionrefs(cd, mcodeptr);
3411 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3412 /* op1 = dimension, val.a = array descriptor */
3414 /* check for negative sizes and copy sizes to stack if necessary */
3416 MCODECHECK((iptr->op1 << 1) + 64);
3418 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3419 var_to_reg_int(s2, src, REG_ITMP1);
3421 codegen_addxcheckarefs(cd, mcodeptr);
3423 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
3425 if (src->varkind != ARGVAR) {
3426 M_LST(s2, REG_SP, 8 * (s1 + INT_ARG_CNT));
3430 /* a0 = dimension count */
3432 ICONST(rd->argintregs[0], iptr->op1);
3434 /* a1 = arraydescriptor */
3436 a = dseg_addaddress(cd, iptr->val.a);
3437 M_ALD(rd->argintregs[1], REG_PV, a);
3439 /* a2 = pointer to dimensions = stack pointer */
3441 M_INTMOVE(REG_SP, rd->argintregs[2]);
3443 a = dseg_addaddress(cd, (void *) builtin_nmultianewarray);
3444 M_ALD(REG_PV, REG_PV, a);
3445 M_JSR(REG_RA, REG_PV);
3446 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3448 M_LDA(REG_PV, REG_RA, -s1);
3450 s4 ml = -s1, mh = 0;
3451 while (ml < -32768) { ml += 65536; mh--; }
3452 M_LDA(REG_PV, REG_RA, ml);
3453 M_LDAH(REG_PV, REG_PV, mh);
3455 s1 = reg_of_var(rd, iptr->dst, REG_RESULT);
3456 M_INTMOVE(REG_RESULT, s1);
3457 store_reg_to_var_int(iptr->dst, s1);
3460 case ICMD_INLINE_START:
3461 case ICMD_INLINE_END:
3464 default: error ("Unknown pseudo command: %d", iptr->opc);
3470 } /* for instruction */
3472 /* copy values to interface registers */
3474 src = bptr->outstack;
3475 len = bptr->outdepth;
3480 if ((src->varkind != STACKVAR)) {
3482 if (IS_FLT_DBL_TYPE(s2)) {
3483 var_to_reg_flt(s1, src, REG_FTMP1);
3484 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3485 M_FLTMOVE(s1,rd->interfaces[len][s2].regoff);
3488 M_DST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3492 var_to_reg_int(s1, src, REG_ITMP1);
3493 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3494 M_INTMOVE(s1,rd->interfaces[len][s2].regoff);
3497 M_LST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3503 } /* if (bptr -> flags >= BBREACHED) */
3504 } /* for basic block */
3507 /* generate bound check stubs */
3509 s4 *xcodeptr = NULL;
3512 for (bref = cd->xboundrefs; bref != NULL; bref = bref->next) {
3513 gen_resolvebranch((u1*) cd->mcodebase + bref->branchpos,
3515 (u1*) mcodeptr - cd->mcodebase);
3519 /* move index register into REG_ITMP1 */
3520 M_MOV(bref->reg, REG_ITMP1);
3521 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3523 if (xcodeptr != NULL) {
3524 M_BR(xcodeptr - mcodeptr - 1);
3527 xcodeptr = mcodeptr;
3529 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3530 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3532 a = dseg_addaddress(cd, string_java_lang_ArrayIndexOutOfBoundsException);
3533 M_ALD(rd->argintregs[0], REG_PV, a);
3534 M_MOV(REG_ITMP1, rd->argintregs[1]);
3536 a = dseg_addaddress(cd, new_exception_int);
3537 M_ALD(REG_PV, REG_PV, a);
3538 M_JSR(REG_RA, REG_PV);
3541 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3542 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3544 s4 ml = -s1, mh = 0;
3545 while (ml < -32768) { ml += 65536; mh--; }
3546 M_LDA(REG_PV, REG_RA, ml);
3547 M_LDAH(REG_PV, REG_PV, mh);
3550 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3552 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3553 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3555 a = dseg_addaddress(cd, asm_handle_exception);
3556 M_ALD(REG_ITMP3, REG_PV, a);
3558 M_JMP(REG_ZERO, REG_ITMP3);
3562 /* generate negative array size check stubs */
3566 for (bref = cd->xcheckarefs; bref != NULL; bref = bref->next) {
3567 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3568 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3570 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3574 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3576 (u1 *) mcodeptr - cd->mcodebase);
3580 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3582 if (xcodeptr != NULL) {
3583 M_BR(xcodeptr - mcodeptr - 1);
3586 xcodeptr = mcodeptr;
3588 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3589 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3591 a = dseg_addaddress(cd, string_java_lang_NegativeArraySizeException);
3592 M_ALD(rd->argintregs[0], REG_PV, a);
3594 a = dseg_addaddress(cd, new_exception);
3595 M_ALD(REG_PV, REG_PV, a);
3596 M_JSR(REG_RA, REG_PV);
3599 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3600 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3602 s4 ml = -s1, mh = 0;
3603 while (ml < -32768) { ml += 65536; mh--; }
3604 M_LDA(REG_PV, REG_RA, ml);
3605 M_LDAH(REG_PV, REG_PV, mh);
3608 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3610 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3611 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3613 a = dseg_addaddress(cd, asm_handle_exception);
3614 M_ALD(REG_ITMP3, REG_PV, a);
3616 M_JMP(REG_ZERO, REG_ITMP3);
3620 /* generate cast check stubs */
3624 for (bref = cd->xcastrefs; bref != NULL; bref = bref->next) {
3625 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3626 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3628 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3632 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3634 (u1 *) mcodeptr - cd->mcodebase);
3638 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3640 if (xcodeptr != NULL) {
3641 M_BR(xcodeptr - mcodeptr - 1);
3644 xcodeptr = mcodeptr;
3646 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3647 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3649 a = dseg_addaddress(cd, string_java_lang_ClassCastException);
3650 M_ALD(rd->argintregs[0], REG_PV, a);
3652 a = dseg_addaddress(cd, new_exception);
3653 M_ALD(REG_PV, REG_PV, a);
3654 M_JSR(REG_RA, REG_PV);
3657 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3658 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3660 s4 ml = -s1, mh = 0;
3661 while (ml < -32768) { ml += 65536; mh--; }
3662 M_LDA(REG_PV, REG_RA, ml);
3663 M_LDAH(REG_PV, REG_PV, mh);
3666 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3668 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3669 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3671 a = dseg_addaddress(cd, asm_handle_exception);
3672 M_ALD(REG_ITMP3, REG_PV, a);
3674 M_JMP(REG_ZERO, REG_ITMP3);
3678 /* generate exception check stubs */
3682 for (bref = cd->xexceptionrefs; bref != NULL; bref = bref->next) {
3683 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3684 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3686 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3690 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3692 (u1 *) mcodeptr - cd->mcodebase);
3696 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3698 if (xcodeptr != NULL) {
3699 M_BR(xcodeptr - mcodeptr - 1);
3702 xcodeptr = mcodeptr;
3704 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3705 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3706 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3708 a = dseg_addaddress(cd, &builtin_get_exceptionptrptr);
3709 M_ALD(REG_PV, REG_PV, a);
3710 M_JSR(REG_RA, REG_PV);
3713 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3714 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3716 s4 ml = -s1, mh = 0;
3717 while (ml < -32768) { ml += 65536; mh--; }
3718 M_LDA(REG_PV, REG_RA, ml);
3719 M_LDAH(REG_PV, REG_PV, mh);
3722 M_ALD(REG_ITMP1_XPTR, REG_RESULT, 0);
3723 M_AST(REG_ZERO, REG_RESULT, 0);
3725 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3726 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3728 a = dseg_addaddress(cd, &_exceptionptr);
3729 M_ALD(REG_ITMP3, REG_PV, a);
3730 M_ALD(REG_ITMP1_XPTR, REG_ITMP3, 0);
3731 M_AST(REG_ZERO, REG_ITMP3, 0);
3734 a = dseg_addaddress(cd, asm_handle_exception);
3735 M_ALD(REG_ITMP3, REG_PV, a);
3737 M_JMP(REG_ZERO, REG_ITMP3);
3741 /* generate null pointer check stubs */
3745 for (bref = cd->xnullrefs; bref != NULL; bref = bref->next) {
3746 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3747 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3749 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3753 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3755 (u1 *) mcodeptr - cd->mcodebase);
3759 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3761 if (xcodeptr != NULL) {
3762 M_BR(xcodeptr - mcodeptr - 1);
3765 xcodeptr = mcodeptr;
3767 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3768 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3770 a = dseg_addaddress(cd, string_java_lang_NullPointerException);
3771 M_ALD(rd->argintregs[0], REG_PV, a);
3773 a = dseg_addaddress(cd, new_exception);
3774 M_ALD(REG_PV, REG_PV, a);
3775 M_JSR(REG_RA, REG_PV);
3778 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3779 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3781 s4 ml = -s1, mh = 0;
3782 while (ml < -32768) { ml += 65536; mh--; }
3783 M_LDA(REG_PV, REG_RA, ml);
3784 M_LDAH(REG_PV, REG_PV, mh);
3787 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3789 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3790 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3792 a = dseg_addaddress(cd, asm_handle_exception);
3793 M_ALD(REG_ITMP3, REG_PV, a);
3795 M_JMP(REG_ZERO, REG_ITMP3);
3799 /* generate put/getstatic stub call code */
3806 for (cref = cd->clinitrefs; cref != NULL; cref = cref->next) {
3807 /* Get machine code which is patched back in later. The call is */
3808 /* 1 instruction word long. */
3809 xcodeptr = (s4 *) (cd->mcodebase + cref->branchpos);
3812 /* patch in the call to call the following code (done at compile */
3815 tmpmcodeptr = mcodeptr; /* save current mcodeptr */
3816 mcodeptr = xcodeptr; /* set mcodeptr to patch position */
3818 M_BSR(REG_RA, tmpmcodeptr - (xcodeptr + 1));
3820 mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
3824 /* move class pointer into REG_ITMP2 */
3825 a = dseg_addaddress(cd, cref->class);
3826 M_ALD(REG_ITMP1, REG_PV, a);
3828 /* move machine code onto stack */
3829 a = dseg_adds4(cd, mcode);
3830 M_ILD(REG_ITMP3, REG_PV, a);
3831 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3832 M_IST(REG_ITMP3, REG_SP, 0);
3834 a = dseg_addaddress(cd, asm_check_clinit);
3835 M_ALD(REG_ITMP2, REG_PV, a);
3836 M_JMP(REG_ZERO, REG_ITMP2);
3841 codegen_finish(m, cd, (s4) ((u1 *) mcodeptr - cd->mcodebase));
3845 /* function createcompilerstub *************************************************
3847 creates a stub routine which calls the compiler
3849 *******************************************************************************/
3851 #define COMPSTUBSIZE 3
3853 u1 *createcompilerstub(methodinfo *m)
3855 u8 *s = CNEW(u8, COMPSTUBSIZE); /* memory to hold the stub */
3856 s4 *mcodeptr = (s4 *) s; /* code generation pointer */
3858 /* code for the stub */
3859 M_ALD(REG_PV, REG_PV, 16); /* load pointer to the compiler */
3860 M_JMP(0, REG_PV); /* jump to the compiler, return address
3861 in reg 0 is used as method pointer */
3862 s[1] = (u8) m; /* literals to be adressed */
3863 s[2] = (u8) asm_call_jit_compiler; /* jump directly via PV from above */
3865 #if defined(STATISTICS)
3867 count_cstub_len += COMPSTUBSIZE * 8;
3874 /* function removecompilerstub *************************************************
3876 deletes a compilerstub from memory (simply by freeing it)
3878 *******************************************************************************/
3880 void removecompilerstub(u1 *stub)
3882 CFREE(stub, COMPSTUBSIZE * 8);
3886 /* function: createnativestub **************************************************
3888 creates a stub routine which calls a native method
3890 *******************************************************************************/
3892 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3893 #define NATIVESTUB_STACK 2
3894 #define NATIVESTUB_THREAD_EXTRA 6
3896 #define NATIVESTUB_STACK 1
3897 #define NATIVESTUB_THREAD_EXTRA 1
3900 #define NATIVESTUB_SIZE (44 + NATIVESTUB_THREAD_EXTRA - 1)
3901 #define NATIVESTUB_STATIC_SIZE 4
3902 #define NATIVESTUB_VERBOSE_SIZE (39 + 13)
3903 #define NATIVESTUB_OFFSET 10
3905 u1 *createnativestub(functionptr f, methodinfo *m)
3907 u8 *s; /* memory pointer to hold the stub */
3909 s4 *mcodeptr; /* code generation pointer */
3910 s4 stackframesize = 0; /* size of stackframe if needed */
3915 t_inlining_globals *id;
3918 /* mark start of dump memory area */
3920 dumpsize = dump_size();
3922 /* setup registers before using it */
3924 cd = DNEW(codegendata);
3925 rd = DNEW(registerdata);
3926 id = DNEW(t_inlining_globals);
3928 inlining_setup(m, id);
3929 reg_setup(m, rd, id);
3931 descriptor2types(m); /* set paramcount and paramtypes */
3933 stubsize = NATIVESTUB_SIZE; /* calculate nativestub size */
3935 if ((m->flags & ACC_STATIC) && !m->class->initialized)
3936 stubsize += NATIVESTUB_STATIC_SIZE;
3939 stubsize += NATIVESTUB_VERBOSE_SIZE;
3941 s = CNEW(u8, stubsize); /* memory to hold the stub */
3942 cs = s + NATIVESTUB_OFFSET;
3943 mcodeptr = (s4 *) cs; /* code generation pointer */
3945 /* set some required varibles which are normally set by codegen_setup */
3946 cd->mcodebase = (u1 *) mcodeptr;
3947 cd->clinitrefs = NULL;
3949 *(cs-1) = (u8) f; /* address of native method */
3950 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3951 *(cs-2) = (u8) &builtin_get_exceptionptrptr;
3953 *(cs-2) = (u8) (&_exceptionptr); /* address of exceptionptr */
3955 *(cs-3) = (u8) asm_handle_nat_exception; /* addr of asm exception handler*/
3956 *(cs-4) = (u8) (&env); /* addr of jni_environement */
3957 *(cs-5) = (u8) builtin_trace_args;
3959 *(cs-7) = (u8) builtin_displaymethodstop;
3960 *(cs-8) = (u8) m->class;
3961 *(cs-9) = (u8) asm_check_clinit;
3962 *(cs-10) = (u8) NULL; /* filled with machine code */
3964 M_LDA(REG_SP, REG_SP, -NATIVESTUB_STACK * 8); /* build up stackframe */
3965 M_AST(REG_RA, REG_SP, 0 * 8); /* store return address */
3967 /* if function is static, check for initialized */
3969 if (m->flags & ACC_STATIC) {
3970 /* if class isn't yet initialized, do it */
3971 if (!m->class->initialized) {
3972 codegen_addclinitref(cd, mcodeptr, m->class);
3976 /* max. 39 instructions */
3980 M_LDA(REG_SP, REG_SP, -((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
3981 M_AST(REG_RA, REG_SP, 1 * 8);
3983 /* save integer argument registers */
3984 for (p = 0; p < m->paramcount && p < INT_ARG_CNT; p++) {
3985 M_LST(rd->argintregs[p], REG_SP, (2 + p) * 8);
3988 /* save and copy float arguments into integer registers */
3989 for (p = 0; p < m->paramcount && p < FLT_ARG_CNT; p++) {
3990 t = m->paramtypes[p];
3992 if (IS_FLT_DBL_TYPE(t)) {
3993 if (IS_2_WORD_TYPE(t)) {
3994 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
3995 M_LLD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
3998 M_FST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
3999 M_ILD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4003 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4007 M_ALD(REG_ITMP1, REG_PV, -6 * 8);
4008 M_AST(REG_ITMP1, REG_SP, 0 * 8);
4009 M_ALD(REG_PV, REG_PV, -5 * 8);
4010 M_JSR(REG_RA, REG_PV);
4011 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4012 M_LDA(REG_PV, REG_RA, disp);
4014 for (p = 0; p < m->paramcount && p < INT_ARG_CNT; p++) {
4015 M_LLD(rd->argintregs[p], REG_SP, (2 + p) * 8);
4018 for (p = 0; p < m->paramcount && p < FLT_ARG_CNT; p++) {
4019 t = m->paramtypes[p];
4021 if (IS_FLT_DBL_TYPE(t)) {
4022 if (IS_2_WORD_TYPE(t)) {
4023 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4026 M_FLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4030 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4034 M_ALD(REG_RA, REG_SP, 1 * 8);
4035 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT + 2) * 8);
4038 /* save argument registers on stack -- if we have to */
4039 if ((m->flags & ACC_STATIC && m->paramcount > (INT_ARG_CNT - 2)) || m->paramcount > (INT_ARG_CNT - 1)) {
4041 s4 paramshiftcnt = (m->flags & ACC_STATIC) ? 2 : 1;
4042 s4 stackparamcnt = (m->paramcount > INT_ARG_CNT) ? m->paramcount - INT_ARG_CNT : 0;
4044 stackframesize = stackparamcnt + paramshiftcnt;
4046 M_LDA(REG_SP, REG_SP, -stackframesize * 8);
4048 /* copy stack arguments into new stack frame -- if any */
4049 for (i = 0; i < stackparamcnt; i++) {
4050 M_LLD(REG_ITMP1, REG_SP, (stackparamcnt + 1 + i) * 8);
4051 M_LST(REG_ITMP1, REG_SP, (paramshiftcnt + i) * 8);
4054 if (m->flags & ACC_STATIC) {
4055 if (IS_FLT_DBL_TYPE(m->paramtypes[5])) {
4056 M_DST(rd->argfltregs[5], REG_SP, 1 * 8);
4058 M_LST(rd->argintregs[5], REG_SP, 1 * 8);
4061 if (IS_FLT_DBL_TYPE(m->paramtypes[4])) {
4062 M_DST(rd->argfltregs[4], REG_SP, 0 * 8);
4064 M_LST(rd->argintregs[4], REG_SP, 0 * 8);
4068 if (IS_FLT_DBL_TYPE(m->paramtypes[5])) {
4069 M_DST(rd->argfltregs[5], REG_SP, 0 * 8);
4071 M_LST(rd->argintregs[5], REG_SP, 0 * 8);
4076 if (m->flags & ACC_STATIC) {
4077 M_MOV(rd->argintregs[3], rd->argintregs[5]);
4078 M_MOV(rd->argintregs[2], rd->argintregs[4]);
4079 M_MOV(rd->argintregs[1], rd->argintregs[3]);
4080 M_MOV(rd->argintregs[0], rd->argintregs[2]);
4081 M_FMOV(rd->argfltregs[3], rd->argfltregs[5]);
4082 M_FMOV(rd->argfltregs[2], rd->argfltregs[4]);
4083 M_FMOV(rd->argfltregs[1], rd->argfltregs[3]);
4084 M_FMOV(rd->argfltregs[0], rd->argfltregs[2]);
4086 /* put class into second argument register */
4087 M_ALD(rd->argintregs[1], REG_PV, -8 * 8);
4090 M_MOV(rd->argintregs[4], rd->argintregs[5]);
4091 M_MOV(rd->argintregs[3], rd->argintregs[4]);
4092 M_MOV(rd->argintregs[2], rd->argintregs[3]);
4093 M_MOV(rd->argintregs[1], rd->argintregs[2]);
4094 M_MOV(rd->argintregs[0], rd->argintregs[1]);
4095 M_FMOV(rd->argfltregs[4], rd->argfltregs[5]);
4096 M_FMOV(rd->argfltregs[3], rd->argfltregs[4]);
4097 M_FMOV(rd->argfltregs[2], rd->argfltregs[3]);
4098 M_FMOV(rd->argfltregs[1], rd->argfltregs[2]);
4099 M_FMOV(rd->argfltregs[0], rd->argfltregs[1]);
4102 /* put env into first argument register */
4103 M_ALD(rd->argintregs[0], REG_PV, -4 * 8);
4105 M_ALD(REG_PV, REG_PV, -1 * 8); /* load adress of native method */
4106 M_JSR(REG_RA, REG_PV); /* call native method */
4107 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4108 M_LDA(REG_PV, REG_RA, disp); /* recompute pv from ra */
4110 /* remove stackframe if there is one */
4111 if (stackframesize) {
4112 M_LDA(REG_SP, REG_SP, stackframesize * 8);
4115 /* 13 instructions */
4117 M_LDA(REG_SP, REG_SP, -2 * 8);
4118 M_ALD(rd->argintregs[0], REG_PV, -6 * 8); /* load method adress */
4119 M_LST(REG_RESULT, REG_SP, 0 * 8);
4120 M_DST(REG_FRESULT, REG_SP, 1 * 8);
4121 M_MOV(REG_RESULT, rd->argintregs[1]);
4122 M_FMOV(REG_FRESULT, rd->argfltregs[2]);
4123 M_FMOV(REG_FRESULT, rd->argfltregs[3]);
4124 M_ALD(REG_PV, REG_PV, -7 * 8); /* builtin_displaymethodstop */
4125 M_JSR(REG_RA, REG_PV);
4126 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4127 M_LDA(REG_PV, REG_RA, disp);
4128 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4129 M_DLD(REG_FRESULT, REG_SP, 1 * 8);
4130 M_LDA(REG_SP, REG_SP, 2 * 8);
4133 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4134 if (IS_FLT_DBL_TYPE(m->returntype))
4135 M_DST(REG_FRESULT, REG_SP, 1 * 8);
4137 M_AST(REG_RESULT, REG_SP, 1 * 8);
4138 M_ALD(REG_PV, REG_PV, -2 * 8); /* builtin_get_exceptionptrptr */
4139 M_JSR(REG_RA, REG_PV);
4140 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4141 M_LDA(REG_PV, REG_RA, disp);
4142 M_MOV(REG_RESULT, REG_ITMP3);
4143 if (IS_FLT_DBL_TYPE(m->returntype))
4144 M_DLD(REG_FRESULT, REG_SP, 1 * 8);
4146 M_ALD(REG_RESULT, REG_SP, 1 * 8);
4148 M_ALD(REG_ITMP3, REG_PV, -2 * 8); /* get address of exceptionptr */
4150 M_ALD(REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
4151 M_BNEZ(REG_ITMP1, 3); /* if no exception then return */
4153 M_ALD(REG_RA, REG_SP, 0 * 8); /* load return address */
4154 M_LDA(REG_SP, REG_SP, NATIVESTUB_STACK * 8); /* remove stackframe */
4155 M_RET(REG_ZERO, REG_RA); /* return to caller */
4157 M_AST(REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
4159 M_ALD(REG_RA, REG_SP, 0 * 8); /* load return address */
4160 M_LDA(REG_SP, REG_SP, NATIVESTUB_STACK * 8); /* remove stackframe */
4161 M_LDA(REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
4162 M_ALD(REG_ITMP3, REG_PV, -3 * 8); /* load asm exception handler address */
4163 M_JMP(REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
4165 /* generate put/getstatic stub call code */
4172 /* there can only be one clinit ref entry */
4173 cref = cd->clinitrefs;
4176 /* Get machine code which is patched back in later. The call is */
4177 /* 1 instruction word long. */
4178 xcodeptr = (s4 *) (cd->mcodebase + cref->branchpos);
4179 *(cs-10) = (u4) *xcodeptr;
4181 /* patch in the call to call the following code (done at compile */
4184 tmpmcodeptr = mcodeptr; /* save current mcodeptr */
4185 mcodeptr = xcodeptr; /* set mcodeptr to patch position */
4187 M_BSR(REG_RA, tmpmcodeptr - (xcodeptr + 1));
4189 mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
4191 /* move class pointer into REG_ITMP2 */
4192 M_ALD(REG_ITMP1, REG_PV, -8 * 8); /* class */
4194 /* move machine code into REG_ITMP3 */
4195 M_ILD(REG_ITMP3, REG_PV, -10 * 8); /* machine code */
4196 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
4197 M_IST(REG_ITMP3, REG_SP, 0);
4199 M_ALD(REG_ITMP2, REG_PV, -9 * 8); /* asm_check_clinit */
4200 M_JMP(REG_ZERO, REG_ITMP2);
4205 dolog_plain("stubsize: %d (for %d params)\n", (int) (mcodeptr - (s4*) s), m->paramcount);
4208 #if defined(STATISTICS)
4210 count_nstub_len += NATIVESTUB_SIZE * 8;
4213 /* release dump area */
4215 dump_release(dumpsize);
4217 return (u1 *) (s + NATIVESTUB_OFFSET);
4221 /* function: removenativestub **************************************************
4223 removes a previously created native-stub from memory
4225 *******************************************************************************/
4227 void removenativestub(u1 *stub)
4229 CFREE((u8 *) stub - NATIVESTUBOFFSET, NATIVESTUBSIZE * 8);
4234 * These are local overrides for various environment variables in Emacs.
4235 * Please do not remove this and leave it at the end of the file, where
4236 * Emacs will automagically detect them.
4237 * ---------------------------------------------------------------------
4240 * indent-tabs-mode: t