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 1641 2004-12-01 13:13:31Z christian $
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"
47 #include "vm/jit/lsra.h"
49 #include "vm/jit/parse.h"
50 #include "vm/jit/reg.h"
51 #include "vm/jit/alpha/codegen.h"
52 #include "vm/jit/alpha/arch.h"
53 #include "vm/jit/alpha/types.h"
56 /* *****************************************************************************
58 Datatypes and Register Allocations:
59 -----------------------------------
61 On 64-bit-machines (like the Alpha) all operands are stored in the
62 registers in a 64-bit form, even when the correspondig JavaVM operands
63 only need 32 bits. This is done by a canonical representation:
65 32-bit integers are allways stored as sign-extended 64-bit values (this
66 approach is directly supported by the Alpha architecture and is very easy
69 32-bit-floats are stored in a 64-bit doubleprecision register by simply
70 expanding the exponent and mantissa with zeroes. (also supported by the
76 The calling conventions and the layout of the stack is explained in detail
77 in the documention file: calling.doc
79 *******************************************************************************/
82 /* register descripton - array ************************************************/
84 /* #define REG_RES 0 reserved register for OS or code generator */
85 /* #define REG_RET 1 return value register */
86 /* #define REG_EXC 2 exception value register (only old jit) */
87 /* #define REG_SAV 3 (callee) saved register */
88 /* #define REG_TMP 4 scratch temporary register (caller saved) */
89 /* #define REG_ARG 5 argument register (caller saved) */
91 /* #define REG_END -1 last entry in tables */
94 REG_RET, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
95 REG_TMP, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
96 REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_TMP, REG_TMP,
97 REG_TMP, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES,
100 /* for use of reserved registers, see comment above */
102 int nregdescfloat[] = {
103 REG_RET, REG_TMP, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
104 REG_SAV, REG_SAV, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
105 REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_TMP, REG_TMP,
106 REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_RES, REG_RES, REG_RES, REG_RES,
110 /* Include independent code generation stuff -- include after register */
111 /* descriptions to avoid extern definitions. */
113 #include "vm/jit/codegen.inc"
114 #include "vm/jit/reg.inc"
116 #include "vm/jit/lsra.inc"
120 /* NullPointerException handlers and exception handling initialisation */
122 typedef struct sigctx_struct {
123 long sc_onstack; /* sigstack state to restore */
124 long sc_mask; /* signal mask to restore */
125 long sc_pc; /* pc at time of signal */
126 long sc_ps; /* psl to retore */
127 long sc_regs[32]; /* processor regs 0 to 31 */
128 long sc_ownedfp; /* fp has been used */
129 long sc_fpregs[32]; /* fp regs 0 to 31 */
130 unsigned long sc_fpcr; /* floating point control register */
131 unsigned long sc_fp_control; /* software fpcr */
133 unsigned long sc_reserved1, sc_reserved2;
134 unsigned long sc_ssize;
136 unsigned long sc_traparg_a0;
137 unsigned long sc_traparg_a1;
138 unsigned long sc_traparg_a2;
139 unsigned long sc_fp_trap_pc;
140 unsigned long sc_fp_trigger_sum;
141 unsigned long sc_fp_trigger_inst;
142 unsigned long sc_retcode[2];
146 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
147 void thread_restartcriticalsection(ucontext_t *uc)
150 if ((critical = thread_checkcritical((void*) uc->uc_mcontext.sc_pc)) != NULL)
151 uc->uc_mcontext.sc_pc = (u8) critical;
155 /* NullPointerException signal handler for hardware null pointer check */
157 void catch_NullPointerException(int sig, int code, sigctx_struct *sigctx)
162 java_objectheader *xptr;
164 /* Reset signal handler - necessary for SysV, does no harm for BSD */
166 instr = *((int*)(sigctx->sc_pc));
167 faultaddr = sigctx->sc_regs[(instr >> 16) & 0x1f];
169 if (faultaddr == 0) {
170 /* reinstall handler */
171 signal(sig, (functionptr) catch_NullPointerException);
173 sigaddset(&nsig, sig);
174 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
176 xptr = new_nullpointerexception();
178 sigctx->sc_regs[REG_ITMP1_XPTR] = (u8) xptr;
179 sigctx->sc_regs[REG_ITMP2_XPC] = sigctx->sc_pc;
180 sigctx->sc_pc = (u8) asm_handle_exception;
184 faultaddr += (long) ((instr << 16) >> 16);
185 fprintf(stderr, "faulting address: 0x%016lx\n", faultaddr);
186 panic("Stack overflow");
193 void init_exceptions(void)
198 /* Linux on Digital Alpha needs an initialisation of the ieee floating point
199 control for IEEE compliant arithmetic (option -mieee of GCC). Under
200 Digital Unix this is done automatically.
205 extern unsigned long ieee_get_fp_control();
206 extern void ieee_set_fp_control(unsigned long fp_control);
208 void init_exceptions(void)
210 /* initialize floating point control */
212 ieee_set_fp_control(ieee_get_fp_control()
213 & ~IEEE_TRAP_ENABLE_INV
214 & ~IEEE_TRAP_ENABLE_DZE
215 /* & ~IEEE_TRAP_ENABLE_UNF we dont want underflow */
216 & ~IEEE_TRAP_ENABLE_OVF);
219 /* install signal handlers we need to convert to exceptions */
223 signal(SIGSEGV, (functionptr) catch_NullPointerException);
227 signal(SIGBUS, (functionptr) catch_NullPointerException);
233 /* function gen_mcode **********************************************************
235 generates machine code
237 *******************************************************************************/
239 void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
241 s4 len, s1, s2, s3, d;
255 savedregs_num = (m->isleafmethod) ? 0 : 1; /* space to save the RA */
257 /* space to save used callee saved registers */
259 savedregs_num += (rd->savintregcnt - rd->maxsavintreguse);
260 savedregs_num += (rd->savfltregcnt - rd->maxsavfltreguse);
262 parentargs_base = rd->maxmemuse + savedregs_num;
264 #if defined(USE_THREADS) /* space to save argument of monitor_enter */
266 if (checksync && (m->flags & ACC_SYNCHRONIZED))
271 /* create method header */
273 (void) dseg_addaddress(cd, m); /* MethodPointer */
274 (void) dseg_adds4(cd, parentargs_base * 8); /* FrameSize */
276 #if defined(USE_THREADS)
278 /* IsSync contains the offset relative to the stack pointer for the
279 argument of monitor_exit used in the exception handler. Since the
280 offset could be zero and give a wrong meaning of the flag it is
284 if (checksync && (m->flags & ACC_SYNCHRONIZED))
285 (void) dseg_adds4(cd, (rd->maxmemuse + 1) * 8); /* IsSync */
290 (void) dseg_adds4(cd, 0); /* IsSync */
292 (void) dseg_adds4(cd, m->isleafmethod); /* IsLeaf */
293 (void) dseg_adds4(cd, rd->savintregcnt - rd->maxsavintreguse);/* IntSave */
294 (void) dseg_adds4(cd, rd->savfltregcnt - rd->maxsavfltreguse);/* FltSave */
296 dseg_addlinenumbertablesize(cd);
298 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
300 /* create exception table */
302 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
303 dseg_addtarget(cd, ex->start);
304 dseg_addtarget(cd, ex->end);
305 dseg_addtarget(cd, ex->handler);
306 (void) dseg_addaddress(cd, ex->catchtype);
309 /* initialize mcode variables */
311 mcodeptr = (s4 *) cd->mcodebase;
312 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
313 MCODECHECK(128 + m->paramcount);
315 /* create stack frame (if necessary) */
317 if (parentargs_base) {
318 M_LDA(REG_SP, REG_SP, -parentargs_base * 8);
321 /* save return address and used callee saved registers */
324 if (!m->isleafmethod) {
325 p--; M_AST(REG_RA, REG_SP, p * 8);
327 for (i = rd->savintregcnt - 1; i >= rd->maxsavintreguse; i--) {
328 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
330 for (i = rd->savfltregcnt - 1; i >= rd->maxsavfltreguse; i--) {
331 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
334 /* save monitorenter argument */
336 #if defined(USE_THREADS)
337 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
338 if (m->flags & ACC_STATIC) {
339 p = dseg_addaddress(cd, m->class);
340 M_ALD(REG_ITMP1, REG_PV, p);
341 M_AST(REG_ITMP1, REG_SP, rd->maxmemuse * 8);
344 M_AST(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
349 /* copy argument registers to stack and call trace function with pointer
350 to arguments on stack.
355 M_LDA(REG_SP, REG_SP, -((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
356 M_AST(REG_RA, REG_SP, 1 * 8);
358 /* save integer argument registers */
359 for (p = 0; /* p < m->paramcount && */ p < INT_ARG_CNT; p++) {
360 M_LST(rd->argintregs[p], REG_SP, (2 + p) * 8);
363 /* save and copy float arguments into integer registers */
364 for (p = 0; /* p < m->paramcount && */ p < FLT_ARG_CNT; p++) {
365 t = m->paramtypes[p];
367 if (IS_FLT_DBL_TYPE(t)) {
368 if (IS_2_WORD_TYPE(t)) {
369 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
372 M_FST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
375 M_LLD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
378 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
382 p = dseg_addaddress(cd, m);
383 M_ALD(REG_ITMP1, REG_PV, p);
384 M_AST(REG_ITMP1, REG_SP, 0 * 8);
385 p = dseg_addaddress(cd, (void *) builtin_trace_args);
386 M_ALD(REG_PV, REG_PV, p);
387 M_JSR(REG_RA, REG_PV);
388 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
389 M_LDA(REG_PV, REG_RA, disp);
390 M_ALD(REG_RA, REG_SP, 1 * 8);
392 for (p = 0; /* p < mparamcount && */ p < INT_ARG_CNT; p++) {
393 M_LLD(rd->argintregs[p], REG_SP, (2 + p) * 8);
396 for (p = 0; /* p < mparamcount && */ p < FLT_ARG_CNT; p++) {
397 t = m->paramtypes[p];
399 if (IS_FLT_DBL_TYPE(t)) {
400 if (IS_2_WORD_TYPE(t)) {
401 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
404 M_FLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
408 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
412 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT + 2) * 8);
415 /* take arguments out of register or stack frame */
417 for (p = 0, l = 0; p < m->paramcount; p++) {
418 t = m->paramtypes[p];
419 var = &(rd->locals[l][t]);
421 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
425 if (IS_INT_LNG_TYPE(t)) { /* integer args */
426 if (p < INT_ARG_CNT) { /* register arguments */
427 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
428 M_INTMOVE(rd->argintregs[p], var->regoff);
429 } else { /* reg arg -> spilled */
430 M_LST(rd->argintregs[p], REG_SP, 8 * var->regoff);
433 } else { /* stack arguments */
434 pa = p - INT_ARG_CNT;
435 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
436 M_LLD(var->regoff, REG_SP, 8 * (parentargs_base + pa));
438 } else { /* stack arg -> spilled */
439 M_LLD(REG_ITMP1, REG_SP, 8 * (parentargs_base + pa));
440 M_LST(REG_ITMP1, REG_SP, 8 * var->regoff);
444 } else { /* floating args */
445 if (p < FLT_ARG_CNT) { /* register arguments */
446 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
447 M_FLTMOVE(rd->argfltregs[p], var->regoff);
449 } else { /* reg arg -> spilled */
450 M_DST(rd->argfltregs[p], REG_SP, 8 * var->regoff);
453 } else { /* stack arguments */
454 pa = p - FLT_ARG_CNT;
455 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
456 M_DLD(var->regoff, REG_SP, 8 * (parentargs_base + pa) );
458 } else { /* stack-arg -> spilled */
459 M_DLD(REG_FTMP1, REG_SP, 8 * (parentargs_base + pa));
460 M_DST(REG_FTMP1, REG_SP, 8 * var->regoff);
466 /* call monitorenter function */
468 #if defined(USE_THREADS)
469 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
471 s8 func_enter = (m->flags & ACC_STATIC) ?
472 (s8) builtin_staticmonitorenter : (s8) builtin_monitorenter;
473 p = dseg_addaddress(cd, (void*) func_enter);
474 M_ALD(REG_PV, REG_PV, p);
475 M_ALD(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
476 M_JSR(REG_RA, REG_PV);
477 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
478 M_LDA(REG_PV, REG_RA, disp);
483 /* end of header generation */
485 /* walk through all basic blocks */
486 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
488 bptr->mpc = (s4) ((u1 *) mcodeptr - cd->mcodebase);
490 if (bptr->flags >= BBREACHED) {
492 /* branch resolving */
496 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
497 gen_resolvebranch((u1*) cd->mcodebase + brefs->branchpos,
498 brefs->branchpos, bptr->mpc);
502 /* copy interface registers to their destination */
509 while (src != NULL) {
511 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
512 /* d = reg_of_var(m, src, REG_ITMP1); */
513 if (!(src->flags & INMEMORY))
517 M_INTMOVE(REG_ITMP1, d);
518 store_reg_to_var_int(src, d);
524 while (src != NULL) {
526 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
527 d = reg_of_var(rd, src, REG_ITMP1);
528 M_INTMOVE(REG_ITMP1, d);
529 store_reg_to_var_int(src, d);
532 d = reg_of_var(rd, src, REG_IFTMP);
533 if ((src->varkind != STACKVAR)) {
535 if (IS_FLT_DBL_TYPE(s2)) {
536 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
537 s1 = rd->interfaces[len][s2].regoff;
541 M_DLD(d, REG_SP, 8 * rd->interfaces[len][s2].regoff);
543 store_reg_to_var_flt(src, d);
546 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
547 s1 = rd->interfaces[len][s2].regoff;
551 M_LLD(d, REG_SP, 8 * rd->interfaces[len][s2].regoff);
553 store_reg_to_var_int(src, d);
563 /* walk through all instructions */
567 for (iptr = bptr->iinstr;
569 src = iptr->dst, len--, iptr++) {
571 MCODECHECK(64); /* an instruction usually needs < 64 words */
574 case ICMD_NOP: /* ... ==> ... */
577 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
579 var_to_reg_int(s1, src, REG_ITMP1);
581 codegen_addxnullrefs(cd, mcodeptr);
584 /* constant operations ************************************************/
586 case ICMD_ICONST: /* ... ==> ..., constant */
587 /* op1 = 0, val.i = constant */
589 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
590 ICONST(d, iptr->val.i);
591 store_reg_to_var_int(iptr->dst, d);
594 case ICMD_LCONST: /* ... ==> ..., constant */
595 /* op1 = 0, val.l = constant */
597 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
598 LCONST(d, iptr->val.l);
599 store_reg_to_var_int(iptr->dst, d);
602 case ICMD_FCONST: /* ... ==> ..., constant */
603 /* op1 = 0, val.f = constant */
605 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
606 a = dseg_addfloat(cd, iptr->val.f);
608 store_reg_to_var_flt(iptr->dst, d);
611 case ICMD_DCONST: /* ... ==> ..., constant */
612 /* op1 = 0, val.d = constant */
614 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
615 a = dseg_adddouble(cd, iptr->val.d);
617 store_reg_to_var_flt(iptr->dst, d);
620 case ICMD_ACONST: /* ... ==> ..., constant */
621 /* op1 = 0, val.a = constant */
623 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
625 a = dseg_addaddress(cd, iptr->val.a);
628 M_INTMOVE(REG_ZERO, d);
630 store_reg_to_var_int(iptr->dst, d);
634 /* load/store operations **********************************************/
636 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
637 case ICMD_LLOAD: /* op1 = local variable */
640 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
641 if ((iptr->dst->varkind == LOCALVAR) &&
642 (iptr->dst->varnum == iptr->op1))
644 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
645 if (var->flags & INMEMORY)
646 M_LLD(d, REG_SP, 8 * var->regoff);
648 {M_INTMOVE(var->regoff,d);}
649 store_reg_to_var_int(iptr->dst, d);
652 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
653 case ICMD_DLOAD: /* op1 = local variable */
655 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
656 if ((iptr->dst->varkind == LOCALVAR) &&
657 (iptr->dst->varnum == iptr->op1))
659 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
660 if (var->flags & INMEMORY)
661 M_DLD(d, REG_SP, 8 * var->regoff);
663 {M_FLTMOVE(var->regoff,d);}
664 store_reg_to_var_flt(iptr->dst, d);
668 case ICMD_ISTORE: /* ..., value ==> ... */
669 case ICMD_LSTORE: /* op1 = local variable */
672 if ((src->varkind == LOCALVAR) &&
673 (src->varnum == iptr->op1))
675 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
676 if (var->flags & INMEMORY) {
677 var_to_reg_int(s1, src, REG_ITMP1);
678 M_LST(s1, REG_SP, 8 * var->regoff);
681 var_to_reg_int(s1, src, var->regoff);
682 M_INTMOVE(s1, var->regoff);
686 case ICMD_FSTORE: /* ..., value ==> ... */
687 case ICMD_DSTORE: /* op1 = local variable */
689 if ((src->varkind == LOCALVAR) &&
690 (src->varnum == iptr->op1))
692 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
693 if (var->flags & INMEMORY) {
694 var_to_reg_flt(s1, src, REG_FTMP1);
695 M_DST(s1, REG_SP, 8 * var->regoff);
698 var_to_reg_flt(s1, src, var->regoff);
699 M_FLTMOVE(s1, var->regoff);
704 /* pop/dup/swap operations ********************************************/
706 /* attention: double and longs are only one entry in CACAO ICMDs */
708 case ICMD_POP: /* ..., value ==> ... */
709 case ICMD_POP2: /* ..., value, value ==> ... */
712 case ICMD_DUP: /* ..., a ==> ..., a, a */
713 M_COPY(src, iptr->dst);
716 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
718 M_COPY(src, iptr->dst);
719 M_COPY(src->prev, iptr->dst->prev);
720 M_COPY(iptr->dst, iptr->dst->prev->prev);
723 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
725 M_COPY(src, iptr->dst);
726 M_COPY(src->prev, iptr->dst->prev);
727 M_COPY(src->prev->prev, iptr->dst->prev->prev);
728 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
731 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
733 M_COPY(src, iptr->dst);
734 M_COPY(src->prev, iptr->dst->prev);
737 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
739 M_COPY(src, iptr->dst);
740 M_COPY(src->prev, iptr->dst->prev);
741 M_COPY(src->prev->prev, iptr->dst->prev->prev);
742 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
743 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev);
746 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
748 M_COPY(src, iptr->dst);
749 M_COPY(src->prev, iptr->dst->prev);
750 M_COPY(src->prev->prev, iptr->dst->prev->prev);
751 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
752 M_COPY(iptr->dst, iptr->dst->prev->prev->prev->prev);
753 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev->prev);
756 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
758 M_COPY(src, iptr->dst->prev);
759 M_COPY(src->prev, iptr->dst);
763 /* integer operations *************************************************/
765 case ICMD_INEG: /* ..., value ==> ..., - value */
767 var_to_reg_int(s1, src, REG_ITMP1);
768 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
769 M_ISUB(REG_ZERO, s1, d);
770 store_reg_to_var_int(iptr->dst, d);
773 case ICMD_LNEG: /* ..., value ==> ..., - value */
775 var_to_reg_int(s1, src, REG_ITMP1);
776 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
777 M_LSUB(REG_ZERO, s1, d);
778 store_reg_to_var_int(iptr->dst, d);
781 case ICMD_I2L: /* ..., value ==> ..., value */
783 var_to_reg_int(s1, src, REG_ITMP1);
784 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
786 store_reg_to_var_int(iptr->dst, d);
789 case ICMD_L2I: /* ..., value ==> ..., value */
791 var_to_reg_int(s1, src, REG_ITMP1);
792 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
793 M_IADD(s1, REG_ZERO, d );
794 store_reg_to_var_int(iptr->dst, d);
797 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
799 var_to_reg_int(s1, src, REG_ITMP1);
800 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
801 if (has_ext_instr_set) {
805 M_SLL_IMM(s1, 56, d);
806 M_SRA_IMM( d, 56, d);
808 store_reg_to_var_int(iptr->dst, d);
811 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
813 var_to_reg_int(s1, src, REG_ITMP1);
814 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
816 store_reg_to_var_int(iptr->dst, d);
819 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
821 var_to_reg_int(s1, src, REG_ITMP1);
822 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
823 if (has_ext_instr_set) {
827 M_SLL_IMM(s1, 48, d);
828 M_SRA_IMM( d, 48, d);
830 store_reg_to_var_int(iptr->dst, d);
834 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
836 var_to_reg_int(s1, src->prev, REG_ITMP1);
837 var_to_reg_int(s2, src, REG_ITMP2);
838 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
840 store_reg_to_var_int(iptr->dst, d);
843 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
844 /* val.i = constant */
846 var_to_reg_int(s1, src, REG_ITMP1);
847 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
848 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
849 M_IADD_IMM(s1, iptr->val.i, d);
852 ICONST(REG_ITMP2, iptr->val.i);
853 M_IADD(s1, REG_ITMP2, d);
855 store_reg_to_var_int(iptr->dst, d);
858 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
860 var_to_reg_int(s1, src->prev, REG_ITMP1);
861 var_to_reg_int(s2, src, REG_ITMP2);
862 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
864 store_reg_to_var_int(iptr->dst, d);
867 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
868 /* val.l = constant */
870 var_to_reg_int(s1, src, REG_ITMP1);
871 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
872 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
873 M_LADD_IMM(s1, iptr->val.l, d);
876 LCONST(REG_ITMP2, iptr->val.l);
877 M_LADD(s1, REG_ITMP2, d);
879 store_reg_to_var_int(iptr->dst, d);
882 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
884 var_to_reg_int(s1, src->prev, REG_ITMP1);
885 var_to_reg_int(s2, src, REG_ITMP2);
886 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
888 store_reg_to_var_int(iptr->dst, d);
891 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
892 /* val.i = constant */
894 var_to_reg_int(s1, src, REG_ITMP1);
895 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
896 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
897 M_ISUB_IMM(s1, iptr->val.i, d);
900 ICONST(REG_ITMP2, iptr->val.i);
901 M_ISUB(s1, REG_ITMP2, d);
903 store_reg_to_var_int(iptr->dst, d);
906 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
908 var_to_reg_int(s1, src->prev, REG_ITMP1);
909 var_to_reg_int(s2, src, REG_ITMP2);
910 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
912 store_reg_to_var_int(iptr->dst, d);
915 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
916 /* val.l = constant */
918 var_to_reg_int(s1, src, REG_ITMP1);
919 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
920 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
921 M_LSUB_IMM(s1, iptr->val.l, d);
924 LCONST(REG_ITMP2, iptr->val.l);
925 M_LSUB(s1, REG_ITMP2, d);
927 store_reg_to_var_int(iptr->dst, d);
930 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
932 var_to_reg_int(s1, src->prev, REG_ITMP1);
933 var_to_reg_int(s2, src, REG_ITMP2);
934 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
936 store_reg_to_var_int(iptr->dst, d);
939 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
940 /* val.i = constant */
942 var_to_reg_int(s1, src, REG_ITMP1);
943 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
944 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
945 M_IMUL_IMM(s1, iptr->val.i, d);
948 ICONST(REG_ITMP2, iptr->val.i);
949 M_IMUL(s1, REG_ITMP2, d);
951 store_reg_to_var_int(iptr->dst, d);
954 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
956 var_to_reg_int(s1, src->prev, REG_ITMP1);
957 var_to_reg_int(s2, src, REG_ITMP2);
958 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
960 store_reg_to_var_int(iptr->dst, d);
963 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
964 /* val.l = constant */
966 var_to_reg_int(s1, src, REG_ITMP1);
967 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
968 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
969 M_LMUL_IMM(s1, iptr->val.l, d);
972 LCONST(REG_ITMP2, iptr->val.l);
973 M_LMUL(s1, REG_ITMP2, d);
975 store_reg_to_var_int(iptr->dst, d);
978 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
979 case ICMD_LDIVPOW2: /* val.i = constant */
981 var_to_reg_int(s1, src, REG_ITMP1);
982 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
983 if (iptr->val.i <= 15) {
984 M_LDA(REG_ITMP2, s1, (1 << iptr->val.i) -1);
985 M_CMOVGE(s1, s1, REG_ITMP2);
988 M_SRA_IMM(s1, 63, REG_ITMP2);
989 M_SRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
990 M_LADD(s1, REG_ITMP2, REG_ITMP2);
992 M_SRA_IMM(REG_ITMP2, iptr->val.i, d);
993 store_reg_to_var_int(iptr->dst, d);
996 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
998 var_to_reg_int(s1, src->prev, REG_ITMP1);
999 var_to_reg_int(s2, src, REG_ITMP2);
1000 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1001 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1002 M_SLL(s1, REG_ITMP3, d);
1003 M_IADD(d, REG_ZERO, d);
1004 store_reg_to_var_int(iptr->dst, d);
1007 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1008 /* val.i = constant */
1010 var_to_reg_int(s1, src, REG_ITMP1);
1011 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1012 M_SLL_IMM(s1, iptr->val.i & 0x1f, d);
1013 M_IADD(d, REG_ZERO, d);
1014 store_reg_to_var_int(iptr->dst, d);
1017 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1019 var_to_reg_int(s1, src->prev, REG_ITMP1);
1020 var_to_reg_int(s2, src, REG_ITMP2);
1021 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1022 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1023 M_SRA(s1, REG_ITMP3, d);
1024 store_reg_to_var_int(iptr->dst, d);
1027 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1028 /* val.i = constant */
1030 var_to_reg_int(s1, src, REG_ITMP1);
1031 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1032 M_SRA_IMM(s1, iptr->val.i & 0x1f, d);
1033 store_reg_to_var_int(iptr->dst, d);
1036 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1038 var_to_reg_int(s1, src->prev, REG_ITMP1);
1039 var_to_reg_int(s2, src, REG_ITMP2);
1040 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1041 M_AND_IMM(s2, 0x1f, REG_ITMP2);
1043 M_SRL(d, REG_ITMP2, d);
1044 M_IADD(d, REG_ZERO, d);
1045 store_reg_to_var_int(iptr->dst, d);
1048 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1049 /* val.i = constant */
1051 var_to_reg_int(s1, src, REG_ITMP1);
1052 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1054 M_SRL_IMM(d, iptr->val.i & 0x1f, d);
1055 M_IADD(d, REG_ZERO, d);
1056 store_reg_to_var_int(iptr->dst, d);
1059 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1061 var_to_reg_int(s1, src->prev, REG_ITMP1);
1062 var_to_reg_int(s2, src, REG_ITMP2);
1063 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1065 store_reg_to_var_int(iptr->dst, d);
1068 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1069 /* val.i = constant */
1071 var_to_reg_int(s1, src, REG_ITMP1);
1072 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1073 M_SLL_IMM(s1, iptr->val.i & 0x3f, d);
1074 store_reg_to_var_int(iptr->dst, d);
1077 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1079 var_to_reg_int(s1, src->prev, REG_ITMP1);
1080 var_to_reg_int(s2, src, REG_ITMP2);
1081 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1083 store_reg_to_var_int(iptr->dst, d);
1086 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1087 /* val.i = constant */
1089 var_to_reg_int(s1, src, REG_ITMP1);
1090 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1091 M_SRA_IMM(s1, iptr->val.i & 0x3f, d);
1092 store_reg_to_var_int(iptr->dst, d);
1095 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1097 var_to_reg_int(s1, src->prev, REG_ITMP1);
1098 var_to_reg_int(s2, src, REG_ITMP2);
1099 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1101 store_reg_to_var_int(iptr->dst, d);
1104 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1105 /* val.i = constant */
1107 var_to_reg_int(s1, src, REG_ITMP1);
1108 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1109 M_SRL_IMM(s1, iptr->val.i & 0x3f, d);
1110 store_reg_to_var_int(iptr->dst, d);
1113 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1116 var_to_reg_int(s1, src->prev, REG_ITMP1);
1117 var_to_reg_int(s2, src, REG_ITMP2);
1118 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1120 store_reg_to_var_int(iptr->dst, d);
1123 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1124 /* val.i = constant */
1126 var_to_reg_int(s1, src, REG_ITMP1);
1127 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1128 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1129 M_AND_IMM(s1, iptr->val.i, d);
1131 else if (iptr->val.i == 0xffff) {
1134 else if (iptr->val.i == 0xffffff) {
1135 M_ZAPNOT_IMM(s1, 0x07, d);
1138 ICONST(REG_ITMP2, iptr->val.i);
1139 M_AND(s1, REG_ITMP2, d);
1141 store_reg_to_var_int(iptr->dst, d);
1144 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1145 /* val.i = constant */
1147 var_to_reg_int(s1, src, REG_ITMP1);
1148 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1150 M_MOV(s1, REG_ITMP1);
1153 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1154 M_AND_IMM(s1, iptr->val.i, d);
1156 M_ISUB(REG_ZERO, s1, d);
1157 M_AND_IMM(d, iptr->val.i, d);
1159 else if (iptr->val.i == 0xffff) {
1162 M_ISUB(REG_ZERO, s1, d);
1165 else if (iptr->val.i == 0xffffff) {
1166 M_ZAPNOT_IMM(s1, 0x07, d);
1168 M_ISUB(REG_ZERO, s1, d);
1169 M_ZAPNOT_IMM(d, 0x07, d);
1172 ICONST(REG_ITMP2, iptr->val.i);
1173 M_AND(s1, REG_ITMP2, d);
1175 M_ISUB(REG_ZERO, s1, d);
1176 M_AND(d, REG_ITMP2, d);
1178 M_ISUB(REG_ZERO, d, d);
1179 store_reg_to_var_int(iptr->dst, d);
1182 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1183 /* val.l = constant */
1185 var_to_reg_int(s1, src, REG_ITMP1);
1186 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1187 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1188 M_AND_IMM(s1, iptr->val.l, d);
1190 else if (iptr->val.l == 0xffffL) {
1193 else if (iptr->val.l == 0xffffffL) {
1194 M_ZAPNOT_IMM(s1, 0x07, d);
1196 else if (iptr->val.l == 0xffffffffL) {
1199 else if (iptr->val.l == 0xffffffffffL) {
1200 M_ZAPNOT_IMM(s1, 0x1f, d);
1202 else if (iptr->val.l == 0xffffffffffffL) {
1203 M_ZAPNOT_IMM(s1, 0x3f, d);
1205 else if (iptr->val.l == 0xffffffffffffffL) {
1206 M_ZAPNOT_IMM(s1, 0x7f, d);
1209 LCONST(REG_ITMP2, iptr->val.l);
1210 M_AND(s1, REG_ITMP2, d);
1212 store_reg_to_var_int(iptr->dst, d);
1215 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1216 /* val.l = constant */
1218 var_to_reg_int(s1, src, REG_ITMP1);
1219 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1221 M_MOV(s1, REG_ITMP1);
1224 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1225 M_AND_IMM(s1, iptr->val.l, d);
1227 M_LSUB(REG_ZERO, s1, d);
1228 M_AND_IMM(d, iptr->val.l, d);
1230 else if (iptr->val.l == 0xffffL) {
1233 M_LSUB(REG_ZERO, s1, d);
1236 else if (iptr->val.l == 0xffffffL) {
1237 M_ZAPNOT_IMM(s1, 0x07, d);
1239 M_LSUB(REG_ZERO, s1, d);
1240 M_ZAPNOT_IMM(d, 0x07, d);
1242 else if (iptr->val.l == 0xffffffffL) {
1245 M_LSUB(REG_ZERO, s1, d);
1248 else if (iptr->val.l == 0xffffffffffL) {
1249 M_ZAPNOT_IMM(s1, 0x1f, d);
1251 M_LSUB(REG_ZERO, s1, d);
1252 M_ZAPNOT_IMM(d, 0x1f, d);
1254 else if (iptr->val.l == 0xffffffffffffL) {
1255 M_ZAPNOT_IMM(s1, 0x3f, d);
1257 M_LSUB(REG_ZERO, s1, d);
1258 M_ZAPNOT_IMM(d, 0x3f, d);
1260 else if (iptr->val.l == 0xffffffffffffffL) {
1261 M_ZAPNOT_IMM(s1, 0x7f, d);
1263 M_LSUB(REG_ZERO, s1, d);
1264 M_ZAPNOT_IMM(d, 0x7f, d);
1267 LCONST(REG_ITMP2, iptr->val.l);
1268 M_AND(s1, REG_ITMP2, d);
1270 M_LSUB(REG_ZERO, s1, d);
1271 M_AND(d, REG_ITMP2, d);
1273 M_LSUB(REG_ZERO, d, d);
1274 store_reg_to_var_int(iptr->dst, d);
1277 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1280 var_to_reg_int(s1, src->prev, REG_ITMP1);
1281 var_to_reg_int(s2, src, REG_ITMP2);
1282 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1284 store_reg_to_var_int(iptr->dst, d);
1287 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1288 /* val.i = constant */
1290 var_to_reg_int(s1, src, REG_ITMP1);
1291 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1292 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1293 M_OR_IMM(s1, iptr->val.i, d);
1296 ICONST(REG_ITMP2, iptr->val.i);
1297 M_OR(s1, REG_ITMP2, d);
1299 store_reg_to_var_int(iptr->dst, d);
1302 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1303 /* val.l = constant */
1305 var_to_reg_int(s1, src, REG_ITMP1);
1306 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1307 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1308 M_OR_IMM(s1, iptr->val.l, d);
1311 LCONST(REG_ITMP2, iptr->val.l);
1312 M_OR(s1, REG_ITMP2, d);
1314 store_reg_to_var_int(iptr->dst, d);
1317 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1320 var_to_reg_int(s1, src->prev, REG_ITMP1);
1321 var_to_reg_int(s2, src, REG_ITMP2);
1322 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1324 store_reg_to_var_int(iptr->dst, d);
1327 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1328 /* val.i = constant */
1330 var_to_reg_int(s1, src, REG_ITMP1);
1331 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1332 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1333 M_XOR_IMM(s1, iptr->val.i, d);
1336 ICONST(REG_ITMP2, iptr->val.i);
1337 M_XOR(s1, REG_ITMP2, d);
1339 store_reg_to_var_int(iptr->dst, d);
1342 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1343 /* val.l = constant */
1345 var_to_reg_int(s1, src, REG_ITMP1);
1346 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1347 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1348 M_XOR_IMM(s1, iptr->val.l, d);
1351 LCONST(REG_ITMP2, iptr->val.l);
1352 M_XOR(s1, REG_ITMP2, d);
1354 store_reg_to_var_int(iptr->dst, d);
1358 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1360 var_to_reg_int(s1, src->prev, REG_ITMP1);
1361 var_to_reg_int(s2, src, REG_ITMP2);
1362 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1363 M_CMPLT(s1, s2, REG_ITMP3);
1364 M_CMPLT(s2, s1, REG_ITMP1);
1365 M_LSUB (REG_ITMP1, REG_ITMP3, d);
1366 store_reg_to_var_int(iptr->dst, d);
1370 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1371 /* op1 = variable, val.i = constant */
1373 var = &(rd->locals[iptr->op1][TYPE_INT]);
1374 if (var->flags & INMEMORY) {
1376 M_LLD(s1, REG_SP, 8 * var->regoff);
1380 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1381 M_IADD_IMM(s1, iptr->val.i, s1);
1383 else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1384 M_ISUB_IMM(s1, (-iptr->val.i), s1);
1387 M_LDA (s1, s1, iptr->val.i);
1388 M_IADD(s1, REG_ZERO, s1);
1390 if (var->flags & INMEMORY)
1391 M_LST(s1, REG_SP, 8 * var->regoff);
1395 /* floating operations ************************************************/
1397 case ICMD_FNEG: /* ..., 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_DNEG: /* ..., value ==> ..., - value */
1407 var_to_reg_flt(s1, src, REG_FTMP1);
1408 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1410 store_reg_to_var_flt(iptr->dst, d);
1413 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1415 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1416 var_to_reg_flt(s2, src, REG_FTMP2);
1417 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1422 if (d == s1 || d == s2) {
1423 M_FADDS(s1, s2, REG_FTMP3);
1425 M_FMOV(REG_FTMP3, d);
1432 store_reg_to_var_flt(iptr->dst, d);
1435 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1437 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1438 var_to_reg_flt(s2, src, REG_FTMP2);
1439 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1444 if (d == s1 || d == s2) {
1445 M_DADDS(s1, s2, REG_FTMP3);
1447 M_FMOV(REG_FTMP3, d);
1454 store_reg_to_var_flt(iptr->dst, d);
1457 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1459 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1460 var_to_reg_flt(s2, src, REG_FTMP2);
1461 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1466 if (d == s1 || d == s2) {
1467 M_FSUBS(s1, s2, REG_FTMP3);
1469 M_FMOV(REG_FTMP3, d);
1476 store_reg_to_var_flt(iptr->dst, d);
1479 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1481 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1482 var_to_reg_flt(s2, src, REG_FTMP2);
1483 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1488 if (d == s1 || d == s2) {
1489 M_DSUBS(s1, s2, REG_FTMP3);
1491 M_FMOV(REG_FTMP3, d);
1498 store_reg_to_var_flt(iptr->dst, d);
1501 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1503 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1504 var_to_reg_flt(s2, src, REG_FTMP2);
1505 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1510 if (d == s1 || d == s2) {
1511 M_FMULS(s1, s2, REG_FTMP3);
1513 M_FMOV(REG_FTMP3, d);
1520 store_reg_to_var_flt(iptr->dst, d);
1523 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1525 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1526 var_to_reg_flt(s2, src, REG_FTMP2);
1527 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1532 if (d == s1 || d == s2) {
1533 M_DMULS(s1, s2, REG_FTMP3);
1535 M_FMOV(REG_FTMP3, d);
1542 store_reg_to_var_flt(iptr->dst, d);
1545 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1547 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1548 var_to_reg_flt(s2, src, REG_FTMP2);
1549 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1554 if (d == s1 || d == s2) {
1555 M_FDIVS(s1, s2, REG_FTMP3);
1557 M_FMOV(REG_FTMP3, d);
1564 store_reg_to_var_flt(iptr->dst, d);
1567 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1569 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1570 var_to_reg_flt(s2, src, REG_FTMP2);
1571 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1576 if (d == s1 || d == s2) {
1577 M_DDIVS(s1, s2, REG_FTMP3);
1579 M_FMOV(REG_FTMP3, d);
1586 store_reg_to_var_flt(iptr->dst, d);
1589 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1591 var_to_reg_int(s1, src, REG_ITMP1);
1592 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1593 a = dseg_adddouble(cd, 0.0);
1594 M_LST (s1, REG_PV, a);
1595 M_DLD (d, REG_PV, a);
1597 store_reg_to_var_flt(iptr->dst, d);
1600 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1602 var_to_reg_int(s1, src, REG_ITMP1);
1603 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1604 a = dseg_adddouble(cd, 0.0);
1605 M_LST (s1, REG_PV, a);
1606 M_DLD (d, REG_PV, a);
1608 store_reg_to_var_flt(iptr->dst, d);
1611 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1613 var_to_reg_flt(s1, src, REG_FTMP1);
1614 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1615 a = dseg_adddouble(cd, 0.0);
1616 M_CVTDL_C(s1, REG_FTMP2);
1617 M_CVTLI(REG_FTMP2, REG_FTMP3);
1618 M_DST (REG_FTMP3, REG_PV, a);
1619 M_ILD (d, REG_PV, a);
1620 store_reg_to_var_int(iptr->dst, d);
1623 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1625 var_to_reg_flt(s1, src, REG_FTMP1);
1626 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1627 a = dseg_adddouble(cd, 0.0);
1628 M_CVTDL_C(s1, REG_FTMP2);
1629 M_DST (REG_FTMP2, REG_PV, a);
1630 M_LLD (d, REG_PV, a);
1631 store_reg_to_var_int(iptr->dst, d);
1634 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1636 var_to_reg_flt(s1, src, REG_FTMP1);
1637 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1640 store_reg_to_var_flt(iptr->dst, d);
1643 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1645 var_to_reg_flt(s1, src, REG_FTMP1);
1646 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1654 store_reg_to_var_flt(iptr->dst, d);
1657 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1659 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1660 var_to_reg_flt(s2, src, REG_FTMP2);
1661 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1663 M_LSUB_IMM(REG_ZERO, 1, d);
1664 M_FCMPEQ(s1, s2, REG_FTMP3);
1665 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1667 M_FCMPLT(s2, s1, REG_FTMP3);
1668 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1669 M_LADD_IMM(REG_ZERO, 1, d);
1672 M_LSUB_IMM(REG_ZERO, 1, d);
1673 M_FCMPEQS(s1, s2, REG_FTMP3);
1675 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1677 M_FCMPLTS(s2, s1, REG_FTMP3);
1679 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1680 M_LADD_IMM(REG_ZERO, 1, d);
1682 store_reg_to_var_int(iptr->dst, d);
1685 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1687 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1688 var_to_reg_flt(s2, src, REG_FTMP2);
1689 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1691 M_LADD_IMM(REG_ZERO, 1, d);
1692 M_FCMPEQ(s1, s2, REG_FTMP3);
1693 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1695 M_FCMPLT(s1, s2, REG_FTMP3);
1696 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1697 M_LSUB_IMM(REG_ZERO, 1, d);
1700 M_LADD_IMM(REG_ZERO, 1, d);
1701 M_FCMPEQS(s1, s2, REG_FTMP3);
1703 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1705 M_FCMPLTS(s1, s2, REG_FTMP3);
1707 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1708 M_LSUB_IMM(REG_ZERO, 1, d);
1710 store_reg_to_var_int(iptr->dst, d);
1714 /* memory operations **************************************************/
1716 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1718 var_to_reg_int(s1, src, REG_ITMP1);
1719 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1720 gen_nullptr_check(s1);
1721 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1722 store_reg_to_var_int(iptr->dst, d);
1725 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1727 var_to_reg_int(s1, src->prev, REG_ITMP1);
1728 var_to_reg_int(s2, src, REG_ITMP2);
1729 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1730 if (iptr->op1 == 0) {
1731 gen_nullptr_check(s1);
1734 M_SAADDQ(s2, s1, REG_ITMP1);
1735 M_ALD( d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1736 store_reg_to_var_int(iptr->dst, d);
1739 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1741 var_to_reg_int(s1, src->prev, REG_ITMP1);
1742 var_to_reg_int(s2, src, REG_ITMP2);
1743 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1744 if (iptr->op1 == 0) {
1745 gen_nullptr_check(s1);
1748 M_S8ADDQ(s2, s1, REG_ITMP1);
1749 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1750 store_reg_to_var_int(iptr->dst, d);
1753 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1755 var_to_reg_int(s1, src->prev, REG_ITMP1);
1756 var_to_reg_int(s2, src, REG_ITMP2);
1757 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1758 if (iptr->op1 == 0) {
1759 gen_nullptr_check(s1);
1763 M_S4ADDQ(s2, s1, REG_ITMP1);
1764 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1765 store_reg_to_var_int(iptr->dst, d);
1768 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1770 var_to_reg_int(s1, src->prev, REG_ITMP1);
1771 var_to_reg_int(s2, src, REG_ITMP2);
1772 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1773 if (iptr->op1 == 0) {
1774 gen_nullptr_check(s1);
1777 M_S4ADDQ(s2, s1, REG_ITMP1);
1778 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1779 store_reg_to_var_flt(iptr->dst, d);
1782 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1784 var_to_reg_int(s1, src->prev, REG_ITMP1);
1785 var_to_reg_int(s2, src, REG_ITMP2);
1786 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1787 if (iptr->op1 == 0) {
1788 gen_nullptr_check(s1);
1791 M_S8ADDQ(s2, s1, REG_ITMP1);
1792 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1793 store_reg_to_var_flt(iptr->dst, d);
1796 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1798 var_to_reg_int(s1, src->prev, REG_ITMP1);
1799 var_to_reg_int(s2, src, REG_ITMP2);
1800 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1801 if (iptr->op1 == 0) {
1802 gen_nullptr_check(s1);
1805 if (has_ext_instr_set) {
1806 M_LADD(s2, s1, REG_ITMP1);
1807 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1808 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1811 M_LADD (s2, s1, REG_ITMP1);
1812 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1813 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1814 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1815 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
1817 store_reg_to_var_int(iptr->dst, d);
1820 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1822 var_to_reg_int(s1, src->prev, REG_ITMP1);
1823 var_to_reg_int(s2, src, REG_ITMP2);
1824 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1825 if (iptr->op1 == 0) {
1826 gen_nullptr_check(s1);
1829 if (has_ext_instr_set) {
1830 M_LADD(s2, s1, REG_ITMP1);
1831 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1832 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1836 M_LADD(s2, s1, REG_ITMP1);
1837 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1838 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1839 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1840 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1841 M_SRA_IMM(d, 48, d);
1843 store_reg_to_var_int(iptr->dst, d);
1846 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1848 var_to_reg_int(s1, src->prev, REG_ITMP1);
1849 var_to_reg_int(s2, src, REG_ITMP2);
1850 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1851 if (iptr->op1 == 0) {
1852 gen_nullptr_check(s1);
1855 if (has_ext_instr_set) {
1856 M_LADD (s2, s1, REG_ITMP1);
1857 M_BLDU (d, REG_ITMP1, OFFSET (java_bytearray, data[0]));
1861 M_LADD(s2, s1, REG_ITMP1);
1862 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1863 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
1864 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1865 M_SRA_IMM(d, 56, d);
1867 store_reg_to_var_int(iptr->dst, d);
1871 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1873 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1874 var_to_reg_int(s2, src->prev, REG_ITMP2);
1875 if (iptr->op1 == 0) {
1876 gen_nullptr_check(s1);
1879 var_to_reg_int(s3, src, REG_ITMP3);
1880 M_SAADDQ(s2, s1, REG_ITMP1);
1881 M_AST (s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1884 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1886 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1887 var_to_reg_int(s2, src->prev, REG_ITMP2);
1888 if (iptr->op1 == 0) {
1889 gen_nullptr_check(s1);
1892 var_to_reg_int(s3, src, REG_ITMP3);
1893 M_S8ADDQ(s2, s1, REG_ITMP1);
1894 M_LST (s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1897 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1899 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1900 var_to_reg_int(s2, src->prev, REG_ITMP2);
1901 if (iptr->op1 == 0) {
1902 gen_nullptr_check(s1);
1906 var_to_reg_int(s3, src, REG_ITMP3);
1907 M_S4ADDQ(s2, s1, REG_ITMP1);
1908 M_IST (s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1911 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1913 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1914 var_to_reg_int(s2, src->prev, REG_ITMP2);
1915 if (iptr->op1 == 0) {
1916 gen_nullptr_check(s1);
1919 var_to_reg_flt(s3, src, REG_FTMP3);
1920 M_S4ADDQ(s2, s1, REG_ITMP1);
1921 M_FST (s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1924 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1926 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1927 var_to_reg_int(s2, src->prev, REG_ITMP2);
1928 if (iptr->op1 == 0) {
1929 gen_nullptr_check(s1);
1932 var_to_reg_flt(s3, src, REG_FTMP3);
1933 M_S8ADDQ(s2, s1, REG_ITMP1);
1934 M_DST (s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1937 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1939 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1940 var_to_reg_int(s2, src->prev, REG_ITMP2);
1941 if (iptr->op1 == 0) {
1942 gen_nullptr_check(s1);
1945 var_to_reg_int(s3, src, REG_ITMP3);
1946 if (has_ext_instr_set) {
1947 M_LADD(s2, s1, REG_ITMP1);
1948 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1949 M_SST (s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1952 M_LADD (s2, s1, REG_ITMP1);
1953 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1954 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1955 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1956 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1957 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1958 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
1959 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1963 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1965 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1966 var_to_reg_int(s2, src->prev, REG_ITMP2);
1967 if (iptr->op1 == 0) {
1968 gen_nullptr_check(s1);
1971 var_to_reg_int(s3, src, REG_ITMP3);
1972 if (has_ext_instr_set) {
1973 M_LADD(s2, s1, REG_ITMP1);
1974 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1975 M_SST (s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1978 M_LADD (s2, s1, REG_ITMP1);
1979 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1980 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1981 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1982 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1983 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1984 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
1985 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1989 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1991 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1992 var_to_reg_int(s2, src->prev, REG_ITMP2);
1993 if (iptr->op1 == 0) {
1994 gen_nullptr_check(s1);
1997 var_to_reg_int(s3, src, REG_ITMP3);
1998 if (has_ext_instr_set) {
1999 M_LADD(s2, s1, REG_ITMP1);
2000 M_BST (s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2003 M_LADD (s2, s1, REG_ITMP1);
2004 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2005 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2006 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
2007 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2008 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2009 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2014 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
2016 var_to_reg_int(s1, src->prev, REG_ITMP1);
2017 var_to_reg_int(s2, src, REG_ITMP2);
2018 if (iptr->op1 == 0) {
2019 gen_nullptr_check(s1);
2022 M_S4ADDQ(s2, s1, REG_ITMP1);
2023 M_IST(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
2026 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
2028 var_to_reg_int(s1, src->prev, REG_ITMP1);
2029 var_to_reg_int(s2, src, REG_ITMP2);
2030 if (iptr->op1 == 0) {
2031 gen_nullptr_check(s1);
2034 M_S8ADDQ(s2, s1, REG_ITMP1);
2035 M_LST(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
2038 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
2040 var_to_reg_int(s1, src->prev, REG_ITMP1);
2041 var_to_reg_int(s2, src, REG_ITMP2);
2042 if (iptr->op1 == 0) {
2043 gen_nullptr_check(s1);
2046 M_SAADDQ(s2, s1, REG_ITMP1);
2047 M_AST(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
2050 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
2052 var_to_reg_int(s1, src->prev, REG_ITMP1);
2053 var_to_reg_int(s2, src, REG_ITMP2);
2054 if (iptr->op1 == 0) {
2055 gen_nullptr_check(s1);
2058 if (has_ext_instr_set) {
2059 M_LADD(s2, s1, REG_ITMP1);
2060 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2063 M_LADD(s2, s1, REG_ITMP1);
2064 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2065 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2066 M_INSBL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2067 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2068 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2069 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2073 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
2075 var_to_reg_int(s1, src->prev, REG_ITMP1);
2076 var_to_reg_int(s2, src, REG_ITMP2);
2077 if (iptr->op1 == 0) {
2078 gen_nullptr_check(s1);
2081 if (has_ext_instr_set) {
2082 M_LADD(s2, s1, REG_ITMP1);
2083 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2084 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
2087 M_LADD(s2, s1, REG_ITMP1);
2088 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2089 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2090 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2091 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2092 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2093 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2094 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2098 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
2100 var_to_reg_int(s1, src->prev, REG_ITMP1);
2101 var_to_reg_int(s2, src, REG_ITMP2);
2102 if (iptr->op1 == 0) {
2103 gen_nullptr_check(s1);
2106 if (has_ext_instr_set) {
2107 M_LADD(s2, s1, REG_ITMP1);
2108 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2109 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2112 M_LADD(s2, s1, REG_ITMP1);
2113 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2114 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2115 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2116 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2117 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2118 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2119 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2124 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2125 /* op1 = type, val.a = field address */
2127 /* If the static fields' class is not yet initialized, we do it */
2128 /* now. The call code is generated later. */
2129 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
2130 codegen_addclinitref(cd, mcodeptr, ((fieldinfo *) iptr->val.a)->class);
2132 /* This is just for debugging purposes. Is very difficult to */
2133 /* read patched code. Here we patch the following 2 nop's */
2134 /* so that the real code keeps untouched. */
2135 if (showdisassemble) {
2140 a = dseg_addaddress(cd, &(((fieldinfo *)(iptr->val.a))->value));
2141 M_ALD(REG_ITMP1, REG_PV, a);
2142 switch (iptr->op1) {
2144 var_to_reg_int(s2, src, REG_ITMP2);
2145 M_IST(s2, REG_ITMP1, 0);
2148 var_to_reg_int(s2, src, REG_ITMP2);
2149 M_LST(s2, REG_ITMP1, 0);
2152 var_to_reg_int(s2, src, REG_ITMP2);
2153 M_AST(s2, REG_ITMP1, 0);
2156 var_to_reg_flt(s2, src, REG_FTMP2);
2157 M_FST(s2, REG_ITMP1, 0);
2160 var_to_reg_flt(s2, src, REG_FTMP2);
2161 M_DST(s2, REG_ITMP1, 0);
2163 default: panic ("internal error");
2167 case ICMD_GETSTATIC: /* ... ==> ..., value */
2168 /* op1 = type, val.a = field address */
2170 /* if class isn't yet initialized, do it */
2171 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
2172 codegen_addclinitref(cd, mcodeptr, ((fieldinfo *) iptr->val.a)->class);
2174 /* This is just for debugging purposes. Is very difficult to */
2175 /* read patched code. Here we patch the following 2 nop's */
2176 /* so that the real code keeps untouched. */
2177 if (showdisassemble) {
2182 a = dseg_addaddress(cd, &(((fieldinfo *) iptr->val.a)->value));
2183 M_ALD(REG_ITMP1, REG_PV, a);
2184 switch (iptr->op1) {
2186 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2187 M_ILD(d, REG_ITMP1, 0);
2188 store_reg_to_var_int(iptr->dst, d);
2191 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2192 M_LLD(d, REG_ITMP1, 0);
2193 store_reg_to_var_int(iptr->dst, d);
2196 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2197 M_ALD(d, REG_ITMP1, 0);
2198 store_reg_to_var_int(iptr->dst, d);
2201 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2202 M_FLD(d, REG_ITMP1, 0);
2203 store_reg_to_var_flt(iptr->dst, d);
2206 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2207 M_DLD(d, REG_ITMP1, 0);
2208 store_reg_to_var_flt(iptr->dst, d);
2210 default: panic ("internal error");
2215 case ICMD_PUTFIELD: /* ..., value ==> ... */
2216 /* op1 = type, val.i = field offset */
2218 a = ((fieldinfo *) iptr->val.a)->offset;
2219 switch (iptr->op1) {
2221 var_to_reg_int(s1, src->prev, REG_ITMP1);
2222 var_to_reg_int(s2, src, REG_ITMP2);
2223 gen_nullptr_check(s1);
2227 var_to_reg_int(s1, src->prev, REG_ITMP1);
2228 var_to_reg_int(s2, src, REG_ITMP2);
2229 gen_nullptr_check(s1);
2233 var_to_reg_int(s1, src->prev, REG_ITMP1);
2234 var_to_reg_int(s2, src, REG_ITMP2);
2235 gen_nullptr_check(s1);
2239 var_to_reg_int(s1, src->prev, REG_ITMP1);
2240 var_to_reg_flt(s2, src, REG_FTMP2);
2241 gen_nullptr_check(s1);
2245 var_to_reg_int(s1, src->prev, REG_ITMP1);
2246 var_to_reg_flt(s2, src, REG_FTMP2);
2247 gen_nullptr_check(s1);
2250 default: panic ("internal error");
2254 case ICMD_GETFIELD: /* ... ==> ..., value */
2255 /* op1 = type, val.i = field offset */
2257 a = ((fieldinfo *)(iptr->val.a))->offset;
2258 switch (iptr->op1) {
2260 var_to_reg_int(s1, src, REG_ITMP1);
2261 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2262 gen_nullptr_check(s1);
2264 store_reg_to_var_int(iptr->dst, d);
2267 var_to_reg_int(s1, src, REG_ITMP1);
2268 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2269 gen_nullptr_check(s1);
2271 store_reg_to_var_int(iptr->dst, d);
2274 var_to_reg_int(s1, src, REG_ITMP1);
2275 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2276 gen_nullptr_check(s1);
2278 store_reg_to_var_int(iptr->dst, d);
2281 var_to_reg_int(s1, src, REG_ITMP1);
2282 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2283 gen_nullptr_check(s1);
2285 store_reg_to_var_flt(iptr->dst, d);
2288 var_to_reg_int(s1, src, REG_ITMP1);
2289 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2290 gen_nullptr_check(s1);
2292 store_reg_to_var_flt(iptr->dst, d);
2294 default: panic ("internal error");
2299 /* branch operations **************************************************/
2301 #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}}
2303 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2305 var_to_reg_int(s1, src, REG_ITMP1);
2306 M_INTMOVE(s1, REG_ITMP1_XPTR);
2307 a = dseg_addaddress(cd, asm_handle_exception);
2308 M_ALD(REG_ITMP2, REG_PV, a);
2309 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2310 M_NOP; /* nop ensures that XPC is less than the end */
2311 /* of basic block */
2315 case ICMD_GOTO: /* ... ==> ... */
2316 /* op1 = target JavaVM pc */
2318 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2322 case ICMD_JSR: /* ... ==> ... */
2323 /* op1 = target JavaVM pc */
2325 M_BSR(REG_ITMP1, 0);
2326 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2329 case ICMD_RET: /* ... ==> ... */
2330 /* op1 = local variable */
2332 var = &(rd->locals[iptr->op1][TYPE_ADR]);
2333 if (var->flags & INMEMORY) {
2334 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2335 M_RET(REG_ZERO, REG_ITMP1);
2338 M_RET(REG_ZERO, var->regoff);
2342 case ICMD_IFNULL: /* ..., 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_IFNONNULL: /* ..., value ==> ... */
2351 /* op1 = target JavaVM pc */
2353 var_to_reg_int(s1, src, REG_ITMP1);
2355 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2358 case ICMD_IFEQ: /* ..., value ==> ... */
2359 /* op1 = target JavaVM pc, val.i = constant */
2361 var_to_reg_int(s1, src, REG_ITMP1);
2362 if (iptr->val.i == 0) {
2366 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2367 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2370 ICONST(REG_ITMP2, iptr->val.i);
2371 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2373 M_BNEZ(REG_ITMP1, 0);
2375 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2378 case ICMD_IFLT: /* ..., value ==> ... */
2379 /* op1 = target JavaVM pc, val.i = constant */
2381 var_to_reg_int(s1, src, REG_ITMP1);
2382 if (iptr->val.i == 0) {
2386 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2387 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2390 ICONST(REG_ITMP2, iptr->val.i);
2391 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2393 M_BNEZ(REG_ITMP1, 0);
2395 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2398 case ICMD_IFLE: /* ..., value ==> ... */
2399 /* op1 = target JavaVM pc, val.i = constant */
2401 var_to_reg_int(s1, src, REG_ITMP1);
2402 if (iptr->val.i == 0) {
2406 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2407 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2410 ICONST(REG_ITMP2, iptr->val.i);
2411 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2413 M_BNEZ(REG_ITMP1, 0);
2415 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2418 case ICMD_IFNE: /* ..., value ==> ... */
2419 /* op1 = target JavaVM pc, val.i = constant */
2421 var_to_reg_int(s1, src, REG_ITMP1);
2422 if (iptr->val.i == 0) {
2426 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2427 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2430 ICONST(REG_ITMP2, iptr->val.i);
2431 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2433 M_BEQZ(REG_ITMP1, 0);
2435 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2438 case ICMD_IFGT: /* ..., value ==> ... */
2439 /* op1 = target JavaVM pc, val.i = constant */
2441 var_to_reg_int(s1, src, REG_ITMP1);
2442 if (iptr->val.i == 0) {
2446 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2447 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2450 ICONST(REG_ITMP2, iptr->val.i);
2451 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2453 M_BEQZ(REG_ITMP1, 0);
2455 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2458 case ICMD_IFGE: /* ..., value ==> ... */
2459 /* op1 = target JavaVM pc, val.i = constant */
2461 var_to_reg_int(s1, src, REG_ITMP1);
2462 if (iptr->val.i == 0) {
2466 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2467 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2470 ICONST(REG_ITMP2, iptr->val.i);
2471 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2473 M_BEQZ(REG_ITMP1, 0);
2475 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2478 case ICMD_IF_LEQ: /* ..., value ==> ... */
2479 /* op1 = target JavaVM pc, val.l = constant */
2481 var_to_reg_int(s1, src, REG_ITMP1);
2482 if (iptr->val.l == 0) {
2486 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2487 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2490 LCONST(REG_ITMP2, iptr->val.l);
2491 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2493 M_BNEZ(REG_ITMP1, 0);
2495 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2498 case ICMD_IF_LLT: /* ..., value ==> ... */
2499 /* op1 = target JavaVM pc, val.l = constant */
2501 var_to_reg_int(s1, src, REG_ITMP1);
2502 if (iptr->val.l == 0) {
2506 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2507 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2510 LCONST(REG_ITMP2, iptr->val.l);
2511 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2513 M_BNEZ(REG_ITMP1, 0);
2515 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2518 case ICMD_IF_LLE: /* ..., value ==> ... */
2519 /* op1 = target JavaVM pc, val.l = constant */
2521 var_to_reg_int(s1, src, REG_ITMP1);
2522 if (iptr->val.l == 0) {
2526 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2527 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2530 LCONST(REG_ITMP2, iptr->val.l);
2531 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2533 M_BNEZ(REG_ITMP1, 0);
2535 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2538 case ICMD_IF_LNE: /* ..., value ==> ... */
2539 /* op1 = target JavaVM pc, val.l = constant */
2541 var_to_reg_int(s1, src, REG_ITMP1);
2542 if (iptr->val.l == 0) {
2546 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2547 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2550 LCONST(REG_ITMP2, iptr->val.l);
2551 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2553 M_BEQZ(REG_ITMP1, 0);
2555 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2558 case ICMD_IF_LGT: /* ..., value ==> ... */
2559 /* op1 = target JavaVM pc, val.l = constant */
2561 var_to_reg_int(s1, src, REG_ITMP1);
2562 if (iptr->val.l == 0) {
2566 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2567 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2570 LCONST(REG_ITMP2, iptr->val.l);
2571 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2573 M_BEQZ(REG_ITMP1, 0);
2575 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2578 case ICMD_IF_LGE: /* ..., value ==> ... */
2579 /* op1 = target JavaVM pc, val.l = constant */
2581 var_to_reg_int(s1, src, REG_ITMP1);
2582 if (iptr->val.l == 0) {
2586 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2587 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2590 LCONST(REG_ITMP2, iptr->val.l);
2591 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2593 M_BEQZ(REG_ITMP1, 0);
2595 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2598 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2599 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2600 case ICMD_IF_ACMPEQ:
2602 var_to_reg_int(s1, src->prev, REG_ITMP1);
2603 var_to_reg_int(s2, src, REG_ITMP2);
2604 M_CMPEQ(s1, s2, REG_ITMP1);
2605 M_BNEZ(REG_ITMP1, 0);
2606 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2609 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2610 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2611 case ICMD_IF_ACMPNE:
2613 var_to_reg_int(s1, src->prev, REG_ITMP1);
2614 var_to_reg_int(s2, src, REG_ITMP2);
2615 M_CMPEQ(s1, s2, REG_ITMP1);
2616 M_BEQZ(REG_ITMP1, 0);
2617 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2620 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2621 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2623 var_to_reg_int(s1, src->prev, REG_ITMP1);
2624 var_to_reg_int(s2, src, REG_ITMP2);
2625 M_CMPLT(s1, s2, REG_ITMP1);
2626 M_BNEZ(REG_ITMP1, 0);
2627 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2630 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2631 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2633 var_to_reg_int(s1, src->prev, REG_ITMP1);
2634 var_to_reg_int(s2, src, REG_ITMP2);
2635 M_CMPLE(s1, s2, REG_ITMP1);
2636 M_BEQZ(REG_ITMP1, 0);
2637 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2640 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2641 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2643 var_to_reg_int(s1, src->prev, REG_ITMP1);
2644 var_to_reg_int(s2, src, REG_ITMP2);
2645 M_CMPLE(s1, s2, REG_ITMP1);
2646 M_BNEZ(REG_ITMP1, 0);
2647 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2650 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2651 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2653 var_to_reg_int(s1, src->prev, REG_ITMP1);
2654 var_to_reg_int(s2, src, REG_ITMP2);
2655 M_CMPLT(s1, s2, REG_ITMP1);
2656 M_BEQZ(REG_ITMP1, 0);
2657 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2660 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2662 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2665 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2666 /* val.i = constant */
2668 var_to_reg_int(s1, src, REG_ITMP1);
2669 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2671 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2672 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2673 M_CMPEQ(s1, REG_ZERO, d);
2674 store_reg_to_var_int(iptr->dst, d);
2677 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2678 M_CMPEQ(s1, REG_ZERO, d);
2680 store_reg_to_var_int(iptr->dst, d);
2684 M_MOV(s1, REG_ITMP1);
2687 ICONST(d, iptr[1].val.i);
2689 if ((s3 >= 0) && (s3 <= 255)) {
2690 M_CMOVEQ_IMM(s1, s3, d);
2693 ICONST(REG_ITMP2, s3);
2694 M_CMOVEQ(s1, REG_ITMP2, d);
2696 store_reg_to_var_int(iptr->dst, d);
2699 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2700 /* val.i = constant */
2702 var_to_reg_int(s1, src, REG_ITMP1);
2703 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2705 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2706 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2707 M_CMPEQ(s1, REG_ZERO, d);
2708 store_reg_to_var_int(iptr->dst, d);
2711 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2712 M_CMPEQ(s1, REG_ZERO, d);
2714 store_reg_to_var_int(iptr->dst, d);
2718 M_MOV(s1, REG_ITMP1);
2721 ICONST(d, iptr[1].val.i);
2723 if ((s3 >= 0) && (s3 <= 255)) {
2724 M_CMOVNE_IMM(s1, s3, d);
2727 ICONST(REG_ITMP2, s3);
2728 M_CMOVNE(s1, REG_ITMP2, d);
2730 store_reg_to_var_int(iptr->dst, d);
2733 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2734 /* val.i = constant */
2736 var_to_reg_int(s1, src, REG_ITMP1);
2737 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2739 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2740 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2741 M_CMPLT(s1, REG_ZERO, d);
2742 store_reg_to_var_int(iptr->dst, d);
2745 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2746 M_CMPLE(REG_ZERO, s1, d);
2747 store_reg_to_var_int(iptr->dst, d);
2751 M_MOV(s1, REG_ITMP1);
2754 ICONST(d, iptr[1].val.i);
2756 if ((s3 >= 0) && (s3 <= 255)) {
2757 M_CMOVLT_IMM(s1, s3, d);
2760 ICONST(REG_ITMP2, s3);
2761 M_CMOVLT(s1, REG_ITMP2, d);
2763 store_reg_to_var_int(iptr->dst, d);
2766 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2767 /* val.i = constant */
2769 var_to_reg_int(s1, src, REG_ITMP1);
2770 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2772 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2773 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2774 M_CMPLE(REG_ZERO, s1, d);
2775 store_reg_to_var_int(iptr->dst, d);
2778 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2779 M_CMPLT(s1, REG_ZERO, d);
2780 store_reg_to_var_int(iptr->dst, d);
2784 M_MOV(s1, REG_ITMP1);
2787 ICONST(d, iptr[1].val.i);
2789 if ((s3 >= 0) && (s3 <= 255)) {
2790 M_CMOVGE_IMM(s1, s3, d);
2793 ICONST(REG_ITMP2, s3);
2794 M_CMOVGE(s1, REG_ITMP2, d);
2796 store_reg_to_var_int(iptr->dst, d);
2799 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2800 /* val.i = constant */
2802 var_to_reg_int(s1, src, REG_ITMP1);
2803 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2805 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2806 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2807 M_CMPLT(REG_ZERO, s1, d);
2808 store_reg_to_var_int(iptr->dst, d);
2811 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2812 M_CMPLE(s1, REG_ZERO, d);
2813 store_reg_to_var_int(iptr->dst, d);
2817 M_MOV(s1, REG_ITMP1);
2820 ICONST(d, iptr[1].val.i);
2822 if ((s3 >= 0) && (s3 <= 255)) {
2823 M_CMOVGT_IMM(s1, s3, d);
2826 ICONST(REG_ITMP2, s3);
2827 M_CMOVGT(s1, REG_ITMP2, d);
2829 store_reg_to_var_int(iptr->dst, d);
2832 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2833 /* val.i = constant */
2835 var_to_reg_int(s1, src, REG_ITMP1);
2836 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2838 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2839 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2840 M_CMPLE(s1, REG_ZERO, d);
2841 store_reg_to_var_int(iptr->dst, d);
2844 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2845 M_CMPLT(REG_ZERO, s1, d);
2846 store_reg_to_var_int(iptr->dst, d);
2850 M_MOV(s1, REG_ITMP1);
2853 ICONST(d, iptr[1].val.i);
2855 if ((s3 >= 0) && (s3 <= 255)) {
2856 M_CMOVLE_IMM(s1, s3, d);
2859 ICONST(REG_ITMP2, s3);
2860 M_CMOVLE(s1, REG_ITMP2, d);
2862 store_reg_to_var_int(iptr->dst, d);
2866 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2870 var_to_reg_int(s1, src, REG_RESULT);
2871 M_INTMOVE(s1, REG_RESULT);
2873 #if defined(USE_THREADS)
2874 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2876 a = dseg_addaddress(cd, (void *) (builtin_monitorexit));
2877 M_ALD(REG_PV, REG_PV, a);
2878 M_ALD(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
2879 M_LST(REG_RESULT, REG_SP, rd->maxmemuse * 8);
2880 M_JSR(REG_RA, REG_PV);
2881 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
2882 M_LDA(REG_PV, REG_RA, disp);
2883 M_LLD(REG_RESULT, REG_SP, rd->maxmemuse * 8);
2887 goto nowperformreturn;
2889 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2892 var_to_reg_flt(s1, src, REG_FRESULT);
2893 M_FLTMOVE(s1, REG_FRESULT);
2895 #if defined(USE_THREADS)
2896 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2898 a = dseg_addaddress(cd, (void *) (builtin_monitorexit));
2899 M_ALD(REG_PV, REG_PV, a);
2900 M_ALD(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
2901 M_DST(REG_FRESULT, REG_SP, rd->maxmemuse * 8);
2902 M_JSR(REG_RA, REG_PV);
2903 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
2904 M_LDA(REG_PV, REG_RA, disp);
2905 M_DLD(REG_FRESULT, REG_SP, rd->maxmemuse * 8);
2909 goto nowperformreturn;
2911 case ICMD_RETURN: /* ... ==> ... */
2913 #if defined(USE_THREADS)
2914 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2916 a = dseg_addaddress(cd, (void *) (builtin_monitorexit));
2917 M_ALD(REG_PV, REG_PV, a);
2918 M_ALD(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
2919 M_JSR(REG_RA, REG_PV);
2920 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
2921 M_LDA(REG_PV, REG_RA, disp);
2929 p = parentargs_base;
2931 /* restore return address */
2933 if (!m->isleafmethod) {
2934 p--; M_LLD(REG_RA, REG_SP, p * 8);
2937 /* restore saved registers */
2939 for (i = rd->savintregcnt - 1; i >= rd->maxsavintreguse; i--) {
2940 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2942 for (i = rd->savfltregcnt - 1; i >= rd->maxsavfltreguse; i--) {
2943 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2946 /* deallocate stack */
2948 if (parentargs_base) {
2949 M_LDA(REG_SP, REG_SP, parentargs_base * 8);
2952 /* call trace function */
2955 M_LDA(REG_SP, REG_SP, -3 * 8);
2956 M_AST(REG_RA, REG_SP, 0 * 8);
2957 M_LST(REG_RESULT, REG_SP, 1 * 8);
2958 M_DST(REG_FRESULT, REG_SP, 2 * 8);
2959 a = dseg_addaddress(cd, m);
2960 M_ALD(rd->argintregs[0], REG_PV, a);
2961 M_MOV(REG_RESULT, rd->argintregs[1]);
2962 M_FLTMOVE(REG_FRESULT, rd->argfltregs[2]);
2963 M_FLTMOVE(REG_FRESULT, rd->argfltregs[3]);
2964 a = dseg_addaddress(cd, (void *) builtin_displaymethodstop);
2965 M_ALD(REG_PV, REG_PV, a);
2966 M_JSR(REG_RA, REG_PV);
2967 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
2968 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
2970 s4 ml = -s1, mh = 0;
2971 while (ml < -32768) { ml += 65536; mh--; }
2972 M_LDA(REG_PV, REG_RA, ml);
2973 M_LDAH(REG_PV, REG_PV, mh);
2975 M_DLD(REG_FRESULT, REG_SP, 2 * 8);
2976 M_LLD(REG_RESULT, REG_SP, 1 * 8);
2977 M_ALD(REG_RA, REG_SP, 0 * 8);
2978 M_LDA(REG_SP, REG_SP, 3 * 8);
2981 M_RET(REG_ZERO, REG_RA);
2987 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2992 tptr = (void **) iptr->target;
2994 s4ptr = iptr->val.a;
2995 l = s4ptr[1]; /* low */
2996 i = s4ptr[2]; /* high */
2998 var_to_reg_int(s1, src, REG_ITMP1);
3000 {M_INTMOVE(s1, REG_ITMP1);}
3001 else if (l <= 32768) {
3002 M_LDA(REG_ITMP1, s1, -l);
3005 ICONST(REG_ITMP2, l);
3006 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
3013 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
3015 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
3016 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3018 M_BEQZ(REG_ITMP2, 0);
3021 /* codegen_addreference(cd, BlockPtrOfPC(s4ptr[0]), mcodeptr); */
3022 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3024 /* build jump table top down and use address of lowest entry */
3026 /* s4ptr += 3 + i; */
3030 /* dseg_addtarget(cd, BlockPtrOfPC(*--s4ptr)); */
3031 dseg_addtarget(cd, (basicblock *) tptr[0]);
3036 /* length of dataseg after last dseg_addtarget is used by load */
3038 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
3039 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
3040 M_JMP(REG_ZERO, REG_ITMP2);
3045 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3047 s4 i, l, val, *s4ptr;
3050 tptr = (void **) iptr->target;
3052 s4ptr = iptr->val.a;
3053 l = s4ptr[0]; /* default */
3054 i = s4ptr[1]; /* count */
3056 MCODECHECK((i<<2)+8);
3057 var_to_reg_int(s1, src, REG_ITMP1);
3063 if ((val >= 0) && (val <= 255)) {
3064 M_CMPEQ_IMM(s1, val, REG_ITMP2);
3067 if ((val >= -32768) && (val <= 32767)) {
3068 M_LDA(REG_ITMP2, REG_ZERO, val);
3071 a = dseg_adds4(cd, val);
3072 M_ILD(REG_ITMP2, REG_PV, a);
3074 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
3076 M_BNEZ(REG_ITMP2, 0);
3077 /* codegen_addreference(cd, BlockPtrOfPC(s4ptr[1]), mcodeptr); */
3078 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3082 /* codegen_addreference(cd, BlockPtrOfPC(l), mcodeptr); */
3084 tptr = (void **) iptr->target;
3085 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3092 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
3093 /* op1 = return type, val.a = function pointer*/
3097 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
3098 /* op1 = return type, val.a = function pointer*/
3102 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
3103 /* op1 = return type, val.a = function pointer*/
3107 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3108 /* op1 = arg count, val.a = method pointer */
3110 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3111 /* op1 = arg count, val.a = method pointer */
3113 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3114 /* op1 = arg count, val.a = method pointer */
3116 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
3117 /* op1 = arg count, val.a = method pointer */
3124 MCODECHECK((s3 << 1) + 64);
3126 /* copy arguments to registers or stack location */
3128 for (; --s3 >= 0; src = src->prev) {
3129 if (src->varkind == ARGVAR)
3131 if (IS_INT_LNG_TYPE(src->type)) {
3132 if (s3 < INT_ARG_CNT) {
3133 s1 = rd->argintregs[s3];
3134 var_to_reg_int(d, src, s1);
3138 var_to_reg_int(d, src, REG_ITMP1);
3139 M_LST(d, REG_SP, 8 * (s3 - INT_ARG_CNT));
3143 if (s3 < FLT_ARG_CNT) {
3144 s1 = rd->argfltregs[s3];
3145 var_to_reg_flt(d, src, s1);
3149 var_to_reg_flt(d, src, REG_FTMP1);
3150 M_DST(d, REG_SP, 8 * (s3 - FLT_ARG_CNT));
3156 switch (iptr->opc) {
3160 a = dseg_addaddress(cd, (void *) lm);
3163 M_ALD(REG_PV, REG_PV, a); /* Pointer to built-in-function */
3166 case ICMD_INVOKESTATIC:
3167 case ICMD_INVOKESPECIAL:
3168 a = dseg_addaddress(cd, lm->stubroutine);
3171 M_ALD(REG_PV, REG_PV, a); /* method pointer in r27 */
3174 case ICMD_INVOKEVIRTUAL:
3177 gen_nullptr_check(rd->argintregs[0]);
3178 M_ALD(REG_METHODPTR, rd->argintregs[0],
3179 OFFSET(java_objectheader, vftbl));
3180 M_ALD(REG_PV, REG_METHODPTR, OFFSET(vftbl_t, table[0]) +
3181 sizeof(methodptr) * lm->vftblindex);
3184 case ICMD_INVOKEINTERFACE:
3187 gen_nullptr_check(rd->argintregs[0]);
3188 M_ALD(REG_METHODPTR, rd->argintregs[0],
3189 OFFSET(java_objectheader, vftbl));
3190 M_ALD(REG_METHODPTR, REG_METHODPTR,
3191 OFFSET(vftbl_t, interfacetable[0]) -
3192 sizeof(methodptr*) * lm->class->index);
3193 M_ALD(REG_PV, REG_METHODPTR,
3194 sizeof(methodptr) * (lm - lm->class->methods));
3198 M_JSR(REG_RA, REG_PV);
3202 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3203 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3205 s4 ml = -s1, mh = 0;
3206 while (ml < -32768) { ml += 65536; mh--; }
3207 M_LDA(REG_PV, REG_RA, ml);
3208 M_LDAH(REG_PV, REG_PV, mh);
3211 /* d contains return type */
3213 if (d != TYPE_VOID) {
3214 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3215 s1 = reg_of_var(rd, iptr->dst, REG_RESULT);
3216 M_INTMOVE(REG_RESULT, s1);
3217 store_reg_to_var_int(iptr->dst, s1);
3220 s1 = reg_of_var(rd, iptr->dst, REG_FRESULT);
3221 M_FLTMOVE(REG_FRESULT, s1);
3222 store_reg_to_var_flt(iptr->dst, s1);
3229 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3231 /* op1: 0 == array, 1 == class */
3232 /* val.a: (classinfo*) superclass */
3234 /* superclass is an interface:
3236 * return (sub != NULL) &&
3237 * (sub->vftbl->interfacetablelength > super->index) &&
3238 * (sub->vftbl->interfacetable[-super->index] != NULL);
3240 * superclass is a class:
3242 * return ((sub != NULL) && (0
3243 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3244 * super->vftbl->diffvall));
3248 classinfo *super = (classinfo*) iptr->val.a;
3250 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3251 codegen_threadcritrestart(cd, (u1 *) mcodeptr - cd->mcodebase);
3253 var_to_reg_int(s1, src, REG_ITMP1);
3254 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
3256 M_MOV(s1, REG_ITMP1);
3260 if (iptr->op1) { /* class/interface */
3261 if (super->flags & ACC_INTERFACE) { /* interface */
3263 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3264 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3265 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3266 M_BLEZ(REG_ITMP2, 2);
3267 M_ALD(REG_ITMP1, REG_ITMP1,
3268 OFFSET(vftbl_t, interfacetable[0]) -
3269 super->index * sizeof(methodptr*));
3270 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3274 s2 = super->vftbl->diffval;
3275 M_BEQZ(s1, 4 + (s2 > 255));
3276 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3277 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3278 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3280 M_CMPULE_IMM(REG_ITMP1, s2, d);
3282 M_LDA(REG_ITMP2, REG_ZERO, s2);
3283 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3287 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3288 a = dseg_addaddress(cd, (void*) super->vftbl);
3289 M_ALD(REG_ITMP2, REG_PV, a);
3290 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3291 codegen_threadcritstart(cd, (u1 *) mcodeptr - cd->mcodebase);
3293 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3294 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3295 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3296 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3297 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3299 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3300 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3304 panic ("internal error: no inlined array instanceof");
3306 store_reg_to_var_int(iptr->dst, d);
3309 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3311 /* op1: 0 == array, 1 == class */
3312 /* val.a: (classinfo*) superclass */
3314 /* superclass is an interface:
3316 * OK if ((sub == NULL) ||
3317 * (sub->vftbl->interfacetablelength > super->index) &&
3318 * (sub->vftbl->interfacetable[-super->index] != NULL));
3320 * superclass is a class:
3322 * OK if ((sub == NULL) || (0
3323 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3324 * super->vftbl->diffvall));
3328 classinfo *super = (classinfo *) iptr->val.a;
3330 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3331 codegen_threadcritrestart(cd, (u1 *) mcodeptr - cd->mcodebase);
3333 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
3334 var_to_reg_int(s1, src, d);
3335 if (iptr->op1) { /* class/interface */
3336 if (super->flags & ACC_INTERFACE) { /* interface */
3338 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3339 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3340 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3341 M_BLEZ(REG_ITMP2, 0);
3342 codegen_addxcastrefs(cd, mcodeptr);
3343 M_ALD(REG_ITMP2, REG_ITMP1,
3344 OFFSET(vftbl_t, interfacetable[0]) -
3345 super->index * sizeof(methodptr*));
3346 M_BEQZ(REG_ITMP2, 0);
3347 codegen_addxcastrefs(cd, mcodeptr);
3351 s2 = super->vftbl->diffval;
3352 M_BEQZ(s1, 4 + (s2 != 0) + (s2 > 255));
3353 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3354 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3355 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3357 M_BNEZ(REG_ITMP1, 0);
3359 else if (s2 <= 255) {
3360 M_CMPULE_IMM(REG_ITMP1, s2, REG_ITMP2);
3361 M_BEQZ(REG_ITMP2, 0);
3364 M_LDA(REG_ITMP2, REG_ZERO, s2);
3365 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3366 M_BEQZ(REG_ITMP2, 0);
3369 M_BEQZ(s1, 8 + (d == REG_ITMP3));
3370 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3371 a = dseg_addaddress(cd, (void *) super->vftbl);
3372 M_ALD(REG_ITMP2, REG_PV, a);
3373 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3374 codegen_threadcritstart(cd, (u1 *) mcodeptr - cd->mcodebase);
3376 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3377 if (d != REG_ITMP3) {
3378 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3379 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3380 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3381 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3383 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3386 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3387 M_ISUB(REG_ITMP1, REG_ITMP2, REG_ITMP1);
3388 M_ALD(REG_ITMP2, REG_PV, a);
3389 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3390 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3391 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3394 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3395 M_BEQZ(REG_ITMP2, 0);
3396 codegen_addxcastrefs(cd, mcodeptr);
3400 panic ("internal error: no inlined array checkcast");
3403 store_reg_to_var_int(iptr->dst, d);
3406 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
3408 var_to_reg_int(s1, src, REG_ITMP1);
3410 codegen_addxcheckarefs(cd, mcodeptr);
3413 case ICMD_CHECKEXCEPTION: /* ... ==> ... */
3415 M_BEQZ(REG_RESULT, 0);
3416 codegen_addxexceptionrefs(cd, mcodeptr);
3419 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3420 /* op1 = dimension, val.a = array descriptor */
3422 /* check for negative sizes and copy sizes to stack if necessary */
3424 MCODECHECK((iptr->op1 << 1) + 64);
3426 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3427 var_to_reg_int(s2, src, REG_ITMP1);
3429 codegen_addxcheckarefs(cd, mcodeptr);
3431 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
3433 if (src->varkind != ARGVAR) {
3434 M_LST(s2, REG_SP, 8 * (s1 + INT_ARG_CNT));
3438 /* a0 = dimension count */
3440 ICONST(rd->argintregs[0], iptr->op1);
3442 /* a1 = arraydescriptor */
3444 a = dseg_addaddress(cd, iptr->val.a);
3445 M_ALD(rd->argintregs[1], REG_PV, a);
3447 /* a2 = pointer to dimensions = stack pointer */
3449 M_INTMOVE(REG_SP, rd->argintregs[2]);
3451 a = dseg_addaddress(cd, (void *) builtin_nmultianewarray);
3452 M_ALD(REG_PV, REG_PV, a);
3453 M_JSR(REG_RA, REG_PV);
3454 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3456 M_LDA(REG_PV, REG_RA, -s1);
3458 s4 ml = -s1, mh = 0;
3459 while (ml < -32768) { ml += 65536; mh--; }
3460 M_LDA(REG_PV, REG_RA, ml);
3461 M_LDAH(REG_PV, REG_PV, mh);
3463 s1 = reg_of_var(rd, iptr->dst, REG_RESULT);
3464 M_INTMOVE(REG_RESULT, s1);
3465 store_reg_to_var_int(iptr->dst, s1);
3468 case ICMD_INLINE_START:
3469 case ICMD_INLINE_END:
3472 default: error ("Unknown pseudo command: %d", iptr->opc);
3478 } /* for instruction */
3480 /* copy values to interface registers */
3482 src = bptr->outstack;
3483 len = bptr->outdepth;
3490 if ((src->varkind != STACKVAR)) {
3492 if (IS_FLT_DBL_TYPE(s2)) {
3493 var_to_reg_flt(s1, src, REG_FTMP1);
3494 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3495 M_FLTMOVE(s1,rd->interfaces[len][s2].regoff);
3498 M_DST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3502 var_to_reg_int(s1, src, REG_ITMP1);
3503 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3504 M_INTMOVE(s1,rd->interfaces[len][s2].regoff);
3507 M_LST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3513 } /* if (bptr -> flags >= BBREACHED) */
3514 } /* for basic block */
3517 /* generate bound check stubs */
3519 s4 *xcodeptr = NULL;
3522 for (bref = cd->xboundrefs; bref != NULL; bref = bref->next) {
3523 gen_resolvebranch((u1*) cd->mcodebase + bref->branchpos,
3525 (u1*) mcodeptr - cd->mcodebase);
3529 /* move index register into REG_ITMP1 */
3530 M_MOV(bref->reg, REG_ITMP1);
3531 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3533 if (xcodeptr != NULL) {
3534 M_BR(xcodeptr - mcodeptr - 1);
3537 xcodeptr = mcodeptr;
3539 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3540 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3542 a = dseg_addaddress(cd, string_java_lang_ArrayIndexOutOfBoundsException);
3543 M_ALD(rd->argintregs[0], REG_PV, a);
3544 M_MOV(REG_ITMP1, rd->argintregs[1]);
3546 a = dseg_addaddress(cd, new_exception_int);
3547 M_ALD(REG_PV, REG_PV, a);
3548 M_JSR(REG_RA, REG_PV);
3551 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3552 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3554 s4 ml = -s1, mh = 0;
3555 while (ml < -32768) { ml += 65536; mh--; }
3556 M_LDA(REG_PV, REG_RA, ml);
3557 M_LDAH(REG_PV, REG_PV, mh);
3560 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3562 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3563 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3565 a = dseg_addaddress(cd, asm_handle_exception);
3566 M_ALD(REG_ITMP3, REG_PV, a);
3568 M_JMP(REG_ZERO, REG_ITMP3);
3572 /* generate negative array size check stubs */
3576 for (bref = cd->xcheckarefs; bref != NULL; bref = bref->next) {
3577 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3578 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3580 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3584 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3586 (u1 *) mcodeptr - cd->mcodebase);
3590 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3592 if (xcodeptr != NULL) {
3593 M_BR(xcodeptr - mcodeptr - 1);
3596 xcodeptr = mcodeptr;
3598 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3599 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3601 a = dseg_addaddress(cd, string_java_lang_NegativeArraySizeException);
3602 M_ALD(rd->argintregs[0], REG_PV, a);
3604 a = dseg_addaddress(cd, new_exception);
3605 M_ALD(REG_PV, REG_PV, a);
3606 M_JSR(REG_RA, REG_PV);
3609 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3610 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3612 s4 ml = -s1, mh = 0;
3613 while (ml < -32768) { ml += 65536; mh--; }
3614 M_LDA(REG_PV, REG_RA, ml);
3615 M_LDAH(REG_PV, REG_PV, mh);
3618 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3620 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3621 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3623 a = dseg_addaddress(cd, asm_handle_exception);
3624 M_ALD(REG_ITMP3, REG_PV, a);
3626 M_JMP(REG_ZERO, REG_ITMP3);
3630 /* generate cast check stubs */
3634 for (bref = cd->xcastrefs; bref != NULL; bref = bref->next) {
3635 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3636 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3638 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3642 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3644 (u1 *) mcodeptr - cd->mcodebase);
3648 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3650 if (xcodeptr != NULL) {
3651 M_BR(xcodeptr - mcodeptr - 1);
3654 xcodeptr = mcodeptr;
3656 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3657 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3659 a = dseg_addaddress(cd, string_java_lang_ClassCastException);
3660 M_ALD(rd->argintregs[0], REG_PV, a);
3662 a = dseg_addaddress(cd, new_exception);
3663 M_ALD(REG_PV, REG_PV, a);
3664 M_JSR(REG_RA, REG_PV);
3667 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3668 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3670 s4 ml = -s1, mh = 0;
3671 while (ml < -32768) { ml += 65536; mh--; }
3672 M_LDA(REG_PV, REG_RA, ml);
3673 M_LDAH(REG_PV, REG_PV, mh);
3676 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3678 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3679 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3681 a = dseg_addaddress(cd, asm_handle_exception);
3682 M_ALD(REG_ITMP3, REG_PV, a);
3684 M_JMP(REG_ZERO, REG_ITMP3);
3688 /* generate exception check stubs */
3692 for (bref = cd->xexceptionrefs; bref != NULL; bref = bref->next) {
3693 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3694 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3696 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3700 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3702 (u1 *) mcodeptr - cd->mcodebase);
3706 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3708 if (xcodeptr != NULL) {
3709 M_BR(xcodeptr - mcodeptr - 1);
3712 xcodeptr = mcodeptr;
3714 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3715 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3716 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3718 a = dseg_addaddress(cd, &builtin_get_exceptionptrptr);
3719 M_ALD(REG_PV, REG_PV, a);
3720 M_JSR(REG_RA, REG_PV);
3723 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3724 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3726 s4 ml = -s1, mh = 0;
3727 while (ml < -32768) { ml += 65536; mh--; }
3728 M_LDA(REG_PV, REG_RA, ml);
3729 M_LDAH(REG_PV, REG_PV, mh);
3732 M_ALD(REG_ITMP1_XPTR, REG_RESULT, 0);
3733 M_AST(REG_ZERO, REG_RESULT, 0);
3735 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3736 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3738 a = dseg_addaddress(cd, &_exceptionptr);
3739 M_ALD(REG_ITMP3, REG_PV, a);
3740 M_ALD(REG_ITMP1_XPTR, REG_ITMP3, 0);
3741 M_AST(REG_ZERO, REG_ITMP3, 0);
3744 a = dseg_addaddress(cd, asm_handle_exception);
3745 M_ALD(REG_ITMP3, REG_PV, a);
3747 M_JMP(REG_ZERO, REG_ITMP3);
3751 /* generate null pointer check stubs */
3755 for (bref = cd->xnullrefs; bref != NULL; bref = bref->next) {
3756 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3757 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3759 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3763 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3765 (u1 *) mcodeptr - cd->mcodebase);
3769 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3771 if (xcodeptr != NULL) {
3772 M_BR(xcodeptr - mcodeptr - 1);
3775 xcodeptr = mcodeptr;
3777 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3778 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3780 a = dseg_addaddress(cd, string_java_lang_NullPointerException);
3781 M_ALD(rd->argintregs[0], REG_PV, a);
3783 a = dseg_addaddress(cd, new_exception);
3784 M_ALD(REG_PV, REG_PV, a);
3785 M_JSR(REG_RA, REG_PV);
3788 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3789 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3791 s4 ml = -s1, mh = 0;
3792 while (ml < -32768) { ml += 65536; mh--; }
3793 M_LDA(REG_PV, REG_RA, ml);
3794 M_LDAH(REG_PV, REG_PV, mh);
3797 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3799 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3800 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3802 a = dseg_addaddress(cd, asm_handle_exception);
3803 M_ALD(REG_ITMP3, REG_PV, a);
3805 M_JMP(REG_ZERO, REG_ITMP3);
3809 /* generate put/getstatic stub call code */
3816 for (cref = cd->clinitrefs; cref != NULL; cref = cref->next) {
3817 /* Get machine code which is patched back in later. The call is */
3818 /* 1 instruction word long. */
3819 xcodeptr = (s4 *) (cd->mcodebase + cref->branchpos);
3822 /* patch in the call to call the following code (done at compile */
3825 tmpmcodeptr = mcodeptr; /* save current mcodeptr */
3826 mcodeptr = xcodeptr; /* set mcodeptr to patch position */
3828 M_BSR(REG_RA, tmpmcodeptr - (xcodeptr + 1));
3830 mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
3834 /* move class pointer into REG_ITMP2 */
3835 a = dseg_addaddress(cd, cref->class);
3836 M_ALD(REG_ITMP1, REG_PV, a);
3838 /* move machine code onto stack */
3839 a = dseg_adds4(cd, mcode);
3840 M_ILD(REG_ITMP3, REG_PV, a);
3841 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3842 M_IST(REG_ITMP3, REG_SP, 0);
3844 a = dseg_addaddress(cd, asm_check_clinit);
3845 M_ALD(REG_ITMP2, REG_PV, a);
3846 M_JMP(REG_ZERO, REG_ITMP2);
3851 codegen_finish(m, cd, (s4) ((u1 *) mcodeptr - cd->mcodebase));
3855 /* function createcompilerstub *************************************************
3857 creates a stub routine which calls the compiler
3859 *******************************************************************************/
3861 #define COMPSTUBSIZE 3
3863 u1 *createcompilerstub(methodinfo *m)
3865 u8 *s = CNEW(u8, COMPSTUBSIZE); /* memory to hold the stub */
3866 s4 *mcodeptr = (s4 *) s; /* code generation pointer */
3868 /* code for the stub */
3869 M_ALD(REG_PV, REG_PV, 16); /* load pointer to the compiler */
3870 M_JMP(0, REG_PV); /* jump to the compiler, return address
3871 in reg 0 is used as method pointer */
3872 s[1] = (u8) m; /* literals to be adressed */
3873 s[2] = (u8) asm_call_jit_compiler; /* jump directly via PV from above */
3875 #if defined(STATISTICS)
3877 count_cstub_len += COMPSTUBSIZE * 8;
3884 /* function removecompilerstub *************************************************
3886 deletes a compilerstub from memory (simply by freeing it)
3888 *******************************************************************************/
3890 void removecompilerstub(u1 *stub)
3892 CFREE(stub, COMPSTUBSIZE * 8);
3896 /* function: createnativestub **************************************************
3898 creates a stub routine which calls a native method
3900 *******************************************************************************/
3902 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3903 #define NATIVESTUB_STACK 2
3904 #define NATIVESTUB_THREAD_EXTRA 6
3906 #define NATIVESTUB_STACK 1
3907 #define NATIVESTUB_THREAD_EXTRA 1
3910 #define NATIVESTUB_SIZE (44 + NATIVESTUB_THREAD_EXTRA - 1)
3911 #define NATIVESTUB_STATIC_SIZE 4
3912 #define NATIVESTUB_VERBOSE_SIZE (39 + 13)
3913 #define NATIVESTUB_OFFSET 10
3915 u1 *createnativestub(functionptr f, methodinfo *m)
3917 u8 *s; /* memory pointer to hold the stub */
3919 s4 *mcodeptr; /* code generation pointer */
3920 s4 stackframesize = 0; /* size of stackframe if needed */
3925 t_inlining_globals *id;
3928 /* mark start of dump memory area */
3930 dumpsize = dump_size();
3932 /* setup registers before using it */
3934 cd = DNEW(codegendata);
3935 rd = DNEW(registerdata);
3936 id = DNEW(t_inlining_globals);
3938 inlining_setup(m, id);
3939 reg_setup(m, rd, id);
3941 descriptor2types(m); /* set paramcount and paramtypes */
3943 stubsize = NATIVESTUB_SIZE; /* calculate nativestub size */
3945 if ((m->flags & ACC_STATIC) && !m->class->initialized)
3946 stubsize += NATIVESTUB_STATIC_SIZE;
3949 stubsize += NATIVESTUB_VERBOSE_SIZE;
3951 s = CNEW(u8, stubsize); /* memory to hold the stub */
3952 cs = s + NATIVESTUB_OFFSET;
3953 mcodeptr = (s4 *) cs; /* code generation pointer */
3955 /* set some required varibles which are normally set by codegen_setup */
3956 cd->mcodebase = (u1 *) mcodeptr;
3957 cd->clinitrefs = NULL;
3959 *(cs-1) = (u8) f; /* address of native method */
3960 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3961 *(cs-2) = (u8) &builtin_get_exceptionptrptr;
3963 *(cs-2) = (u8) (&_exceptionptr); /* address of exceptionptr */
3965 *(cs-3) = (u8) asm_handle_nat_exception; /* addr of asm exception handler*/
3966 *(cs-4) = (u8) (&env); /* addr of jni_environement */
3967 *(cs-5) = (u8) builtin_trace_args;
3969 *(cs-7) = (u8) builtin_displaymethodstop;
3970 *(cs-8) = (u8) m->class;
3971 *(cs-9) = (u8) asm_check_clinit;
3972 *(cs-10) = (u8) NULL; /* filled with machine code */
3974 M_LDA(REG_SP, REG_SP, -NATIVESTUB_STACK * 8); /* build up stackframe */
3975 M_AST(REG_RA, REG_SP, 0 * 8); /* store return address */
3977 /* if function is static, check for initialized */
3979 if (m->flags & ACC_STATIC) {
3980 /* if class isn't yet initialized, do it */
3981 if (!m->class->initialized) {
3982 codegen_addclinitref(cd, mcodeptr, m->class);
3986 /* max. 39 instructions */
3990 M_LDA(REG_SP, REG_SP, -((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
3991 M_AST(REG_RA, REG_SP, 1 * 8);
3993 /* save integer argument registers */
3994 for (p = 0; p < m->paramcount && p < INT_ARG_CNT; p++) {
3995 M_LST(rd->argintregs[p], REG_SP, (2 + p) * 8);
3998 /* save and copy float arguments into integer registers */
3999 for (p = 0; p < m->paramcount && p < FLT_ARG_CNT; p++) {
4000 t = m->paramtypes[p];
4002 if (IS_FLT_DBL_TYPE(t)) {
4003 if (IS_2_WORD_TYPE(t)) {
4004 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4005 M_LLD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4008 M_FST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4009 M_ILD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4013 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4017 M_ALD(REG_ITMP1, REG_PV, -6 * 8);
4018 M_AST(REG_ITMP1, REG_SP, 0 * 8);
4019 M_ALD(REG_PV, REG_PV, -5 * 8);
4020 M_JSR(REG_RA, REG_PV);
4021 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4022 M_LDA(REG_PV, REG_RA, disp);
4024 for (p = 0; p < m->paramcount && p < INT_ARG_CNT; p++) {
4025 M_LLD(rd->argintregs[p], REG_SP, (2 + p) * 8);
4028 for (p = 0; p < m->paramcount && p < FLT_ARG_CNT; p++) {
4029 t = m->paramtypes[p];
4031 if (IS_FLT_DBL_TYPE(t)) {
4032 if (IS_2_WORD_TYPE(t)) {
4033 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4036 M_FLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4040 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4044 M_ALD(REG_RA, REG_SP, 1 * 8);
4045 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT + 2) * 8);
4048 /* save argument registers on stack -- if we have to */
4049 if ((m->flags & ACC_STATIC && m->paramcount > (INT_ARG_CNT - 2)) || m->paramcount > (INT_ARG_CNT - 1)) {
4051 s4 paramshiftcnt = (m->flags & ACC_STATIC) ? 2 : 1;
4052 s4 stackparamcnt = (m->paramcount > INT_ARG_CNT) ? m->paramcount - INT_ARG_CNT : 0;
4054 stackframesize = stackparamcnt + paramshiftcnt;
4056 M_LDA(REG_SP, REG_SP, -stackframesize * 8);
4058 /* copy stack arguments into new stack frame -- if any */
4059 for (i = 0; i < stackparamcnt; i++) {
4060 M_LLD(REG_ITMP1, REG_SP, (stackparamcnt + 1 + i) * 8);
4061 M_LST(REG_ITMP1, REG_SP, (paramshiftcnt + i) * 8);
4064 if (m->flags & ACC_STATIC) {
4065 if (IS_FLT_DBL_TYPE(m->paramtypes[5])) {
4066 M_DST(rd->argfltregs[5], REG_SP, 1 * 8);
4068 M_LST(rd->argintregs[5], REG_SP, 1 * 8);
4071 if (IS_FLT_DBL_TYPE(m->paramtypes[4])) {
4072 M_DST(rd->argfltregs[4], REG_SP, 0 * 8);
4074 M_LST(rd->argintregs[4], REG_SP, 0 * 8);
4078 if (IS_FLT_DBL_TYPE(m->paramtypes[5])) {
4079 M_DST(rd->argfltregs[5], REG_SP, 0 * 8);
4081 M_LST(rd->argintregs[5], REG_SP, 0 * 8);
4086 if (m->flags & ACC_STATIC) {
4087 M_MOV(rd->argintregs[3], rd->argintregs[5]);
4088 M_MOV(rd->argintregs[2], rd->argintregs[4]);
4089 M_MOV(rd->argintregs[1], rd->argintregs[3]);
4090 M_MOV(rd->argintregs[0], rd->argintregs[2]);
4091 M_FMOV(rd->argfltregs[3], rd->argfltregs[5]);
4092 M_FMOV(rd->argfltregs[2], rd->argfltregs[4]);
4093 M_FMOV(rd->argfltregs[1], rd->argfltregs[3]);
4094 M_FMOV(rd->argfltregs[0], rd->argfltregs[2]);
4096 /* put class into second argument register */
4097 M_ALD(rd->argintregs[1], REG_PV, -8 * 8);
4100 M_MOV(rd->argintregs[4], rd->argintregs[5]);
4101 M_MOV(rd->argintregs[3], rd->argintregs[4]);
4102 M_MOV(rd->argintregs[2], rd->argintregs[3]);
4103 M_MOV(rd->argintregs[1], rd->argintregs[2]);
4104 M_MOV(rd->argintregs[0], rd->argintregs[1]);
4105 M_FMOV(rd->argfltregs[4], rd->argfltregs[5]);
4106 M_FMOV(rd->argfltregs[3], rd->argfltregs[4]);
4107 M_FMOV(rd->argfltregs[2], rd->argfltregs[3]);
4108 M_FMOV(rd->argfltregs[1], rd->argfltregs[2]);
4109 M_FMOV(rd->argfltregs[0], rd->argfltregs[1]);
4112 /* put env into first argument register */
4113 M_ALD(rd->argintregs[0], REG_PV, -4 * 8);
4115 M_ALD(REG_PV, REG_PV, -1 * 8); /* load adress of native method */
4116 M_JSR(REG_RA, REG_PV); /* call native method */
4117 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4118 M_LDA(REG_PV, REG_RA, disp); /* recompute pv from ra */
4120 /* remove stackframe if there is one */
4121 if (stackframesize) {
4122 M_LDA(REG_SP, REG_SP, stackframesize * 8);
4125 /* 13 instructions */
4127 M_LDA(REG_SP, REG_SP, -2 * 8);
4128 M_ALD(rd->argintregs[0], REG_PV, -6 * 8); /* load method adress */
4129 M_LST(REG_RESULT, REG_SP, 0 * 8);
4130 M_DST(REG_FRESULT, REG_SP, 1 * 8);
4131 M_MOV(REG_RESULT, rd->argintregs[1]);
4132 M_FMOV(REG_FRESULT, rd->argfltregs[2]);
4133 M_FMOV(REG_FRESULT, rd->argfltregs[3]);
4134 M_ALD(REG_PV, REG_PV, -7 * 8); /* builtin_displaymethodstop */
4135 M_JSR(REG_RA, REG_PV);
4136 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4137 M_LDA(REG_PV, REG_RA, disp);
4138 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4139 M_DLD(REG_FRESULT, REG_SP, 1 * 8);
4140 M_LDA(REG_SP, REG_SP, 2 * 8);
4143 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4144 if (IS_FLT_DBL_TYPE(m->returntype))
4145 M_DST(REG_FRESULT, REG_SP, 1 * 8);
4147 M_AST(REG_RESULT, REG_SP, 1 * 8);
4148 M_ALD(REG_PV, REG_PV, -2 * 8); /* builtin_get_exceptionptrptr */
4149 M_JSR(REG_RA, REG_PV);
4150 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4151 M_LDA(REG_PV, REG_RA, disp);
4152 M_MOV(REG_RESULT, REG_ITMP3);
4153 if (IS_FLT_DBL_TYPE(m->returntype))
4154 M_DLD(REG_FRESULT, REG_SP, 1 * 8);
4156 M_ALD(REG_RESULT, REG_SP, 1 * 8);
4158 M_ALD(REG_ITMP3, REG_PV, -2 * 8); /* get address of exceptionptr */
4160 M_ALD(REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
4161 M_BNEZ(REG_ITMP1, 3); /* if no exception then return */
4163 M_ALD(REG_RA, REG_SP, 0 * 8); /* load return address */
4164 M_LDA(REG_SP, REG_SP, NATIVESTUB_STACK * 8); /* remove stackframe */
4165 M_RET(REG_ZERO, REG_RA); /* return to caller */
4167 M_AST(REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
4169 M_ALD(REG_RA, REG_SP, 0 * 8); /* load return address */
4170 M_LDA(REG_SP, REG_SP, NATIVESTUB_STACK * 8); /* remove stackframe */
4171 M_LDA(REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
4172 M_ALD(REG_ITMP3, REG_PV, -3 * 8); /* load asm exception handler address */
4173 M_JMP(REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
4175 /* generate put/getstatic stub call code */
4182 /* there can only be one clinit ref entry */
4183 cref = cd->clinitrefs;
4186 /* Get machine code which is patched back in later. The call is */
4187 /* 1 instruction word long. */
4188 xcodeptr = (s4 *) (cd->mcodebase + cref->branchpos);
4189 *(cs-10) = (u4) *xcodeptr;
4191 /* patch in the call to call the following code (done at compile */
4194 tmpmcodeptr = mcodeptr; /* save current mcodeptr */
4195 mcodeptr = xcodeptr; /* set mcodeptr to patch position */
4197 M_BSR(REG_RA, tmpmcodeptr - (xcodeptr + 1));
4199 mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
4201 /* move class pointer into REG_ITMP2 */
4202 M_ALD(REG_ITMP1, REG_PV, -8 * 8); /* class */
4204 /* move machine code into REG_ITMP3 */
4205 M_ILD(REG_ITMP3, REG_PV, -10 * 8); /* machine code */
4206 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
4207 M_IST(REG_ITMP3, REG_SP, 0);
4209 M_ALD(REG_ITMP2, REG_PV, -9 * 8); /* asm_check_clinit */
4210 M_JMP(REG_ZERO, REG_ITMP2);
4215 dolog_plain("stubsize: %d (for %d params)\n", (int) (mcodeptr - (s4*) s), m->paramcount);
4218 #if defined(STATISTICS)
4220 count_nstub_len += NATIVESTUB_SIZE * 8;
4223 /* release dump area */
4225 dump_release(dumpsize);
4227 return (u1 *) (s + NATIVESTUB_OFFSET);
4231 /* function: removenativestub **************************************************
4233 removes a previously created native-stub from memory
4235 *******************************************************************************/
4237 void removenativestub(u1 *stub)
4239 CFREE((u8 *) stub - NATIVESTUBOFFSET, NATIVESTUBSIZE * 8);
4244 * These are local overrides for various environment variables in Emacs.
4245 * Please do not remove this and leave it at the end of the file, where
4246 * Emacs will automagically detect them.
4247 * ---------------------------------------------------------------------
4250 * indent-tabs-mode: t