1 /* 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 1347 2004-07-21 23:29:39Z twisti $
41 #include "jit/alpha/codegen.h"
43 #include "jit/parse.h"
53 /* include independent code generation stuff */
54 #include "jit/codegen.inc"
55 #include "jit/reg.inc"
58 /* *****************************************************************************
60 Datatypes and Register Allocations:
61 -----------------------------------
63 On 64-bit-machines (like the Alpha) all operands are stored in the
64 registers in a 64-bit form, even when the correspondig JavaVM operands
65 only need 32 bits. This is done by a canonical representation:
67 32-bit integers are allways stored as sign-extended 64-bit values (this
68 approach is directly supported by the Alpha architecture and is very easy
71 32-bit-floats are stored in a 64-bit doubleprecision register by simply
72 expanding the exponent and mantissa with zeroes. (also supported by the
78 The calling conventions and the layout of the stack is explained in detail
79 in the documention file: calling.doc
81 *******************************************************************************/
84 /* register descripton - array ************************************************/
86 /* #define REG_RES 0 reserved register for OS or code generator */
87 /* #define REG_RET 1 return value register */
88 /* #define REG_EXC 2 exception value register (only old jit) */
89 /* #define REG_SAV 3 (callee) saved register */
90 /* #define REG_TMP 4 scratch temporary register (caller saved) */
91 /* #define REG_ARG 5 argument register (caller saved) */
93 /* #define REG_END -1 last entry in tables */
96 REG_RET, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
97 REG_TMP, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
98 REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_TMP, REG_TMP,
99 REG_TMP, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES,
102 /* for use of reserved registers, see comment above */
104 int nregdescfloat[] = {
105 REG_RET, REG_TMP, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
106 REG_SAV, REG_SAV, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
107 REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_TMP, REG_TMP,
108 REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_RES, REG_RES, REG_RES, REG_RES,
111 /* for use of reserved registers, see comment above */
114 /* NullPointerException handlers and exception handling initialisation */
116 typedef struct sigctx_struct {
118 long sc_onstack; /* sigstack state to restore */
119 long sc_mask; /* signal mask to restore */
120 long sc_pc; /* pc at time of signal */
121 long sc_ps; /* psl to retore */
122 long sc_regs[32]; /* processor regs 0 to 31 */
123 long sc_ownedfp; /* fp has been used */
124 long sc_fpregs[32]; /* fp regs 0 to 31 */
125 unsigned long sc_fpcr; /* floating point control register */
126 unsigned long sc_fp_control; /* software fpcr */
128 unsigned long sc_reserved1, sc_reserved2;
129 unsigned long sc_ssize;
131 unsigned long sc_traparg_a0;
132 unsigned long sc_traparg_a1;
133 unsigned long sc_traparg_a2;
134 unsigned long sc_fp_trap_pc;
135 unsigned long sc_fp_trigger_sum;
136 unsigned long sc_fp_trigger_inst;
137 unsigned long sc_retcode[2];
141 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
142 void thread_restartcriticalsection(ucontext_t *uc)
145 if ((critical = thread_checkcritical((void*) uc->uc_mcontext.sc_pc)) != NULL)
146 uc->uc_mcontext.sc_pc = (u8) critical;
150 /* NullPointerException signal handler for hardware null pointer check */
152 void catch_NullPointerException(int sig, int code, sigctx_struct *sigctx)
157 java_objectheader *xptr;
159 /* Reset signal handler - necessary for SysV, does no harm for BSD */
161 instr = *((int*)(sigctx->sc_pc));
162 faultaddr = sigctx->sc_regs[(instr >> 16) & 0x1f];
164 if (faultaddr == 0) {
165 signal(sig, (void*) catch_NullPointerException); /* reinstall handler */
167 sigaddset(&nsig, sig);
168 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
170 xptr = new_exception(string_java_lang_NullPointerException);
172 sigctx->sc_regs[REG_ITMP1_XPTR] = (u8) xptr;
173 sigctx->sc_regs[REG_ITMP2_XPC] = sigctx->sc_pc;
174 sigctx->sc_pc = (u8) asm_handle_exception;
178 faultaddr += (long) ((instr << 16) >> 16);
179 fprintf(stderr, "faulting address: 0x%016lx\n", faultaddr);
180 panic("Stack overflow");
187 void init_exceptions(void)
192 /* Linux on Digital Alpha needs an initialisation of the ieee floating point
193 control for IEEE compliant arithmetic (option -mieee of GCC). Under
194 Digital Unix this is done automatically.
199 extern unsigned long ieee_get_fp_control();
200 extern void ieee_set_fp_control(unsigned long fp_control);
202 void init_exceptions(void)
204 /* initialize floating point control */
206 ieee_set_fp_control(ieee_get_fp_control()
207 & ~IEEE_TRAP_ENABLE_INV
208 & ~IEEE_TRAP_ENABLE_DZE
209 /* & ~IEEE_TRAP_ENABLE_UNF we dont want underflow */
210 & ~IEEE_TRAP_ENABLE_OVF);
213 /* install signal handlers we need to convert to exceptions */
217 signal(SIGSEGV, (void*) catch_NullPointerException);
221 signal(SIGBUS, (void*) catch_NullPointerException);
227 /* function gen_mcode **********************************************************
229 generates machine code
231 *******************************************************************************/
233 void codegen(methodinfo *m)
235 s4 len, s1, s2, s3, d;
247 /* keep code size smaller */
255 savedregs_num = (m->isleafmethod) ? 0 : 1; /* space to save the RA */
257 /* space to save used callee saved registers */
259 savedregs_num += (r->savintregcnt - r->maxsavintreguse);
260 savedregs_num += (r->savfltregcnt - r->maxsavfltreguse);
262 parentargs_base = r->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(m, m); /* MethodPointer */
274 (void) dseg_adds4(m, 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(m, (r->maxmemuse + 1) * 8); /* IsSync */
290 (void) dseg_adds4(m, 0); /* IsSync */
292 (void) dseg_adds4(m, m->isleafmethod); /* IsLeaf */
293 (void) dseg_adds4(m, r->savintregcnt - r->maxsavintreguse);/* IntSave */
294 (void) dseg_adds4(m, r->savfltregcnt - r->maxsavfltreguse);/* FltSave */
296 dseg_addlinenumbertablesize(m);
298 (void) dseg_adds4(m, m->exceptiontablelength); /* ExTableSize */
300 /* create exception table */
302 for (ex = m->exceptiontable; ex != NULL; ex = ex->down) {
303 dseg_addtarget(m, ex->start);
304 dseg_addtarget(m, ex->end);
305 dseg_addtarget(m, ex->handler);
306 (void) dseg_addaddress(m, 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 = r->savintregcnt - 1; i >= r->maxsavintreguse; i--) {
328 p--; M_LST(r->savintregs[i], REG_SP, p * 8);
330 for (i = r->savfltregcnt - 1; i >= r->maxsavfltreguse; i--) {
331 p--; M_DST(r->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(m, m->class);
340 M_ALD(REG_ITMP1, REG_PV, p);
341 M_AST(REG_ITMP1, REG_SP, r->maxmemuse * 8);
344 M_AST(r->argintregs[0], REG_SP, r->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(r->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(r->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
372 M_FST(r->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
375 M_LLD(r->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
378 M_DST(r->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
382 p = dseg_addaddress(m, m);
383 M_ALD(REG_ITMP1, REG_PV, p);
384 M_AST(REG_ITMP1, REG_SP, 0 * 8);
385 p = dseg_addaddress(m, (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(r->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(r->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
404 M_FLD(r->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
408 M_DLD(r->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 = &(r->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(r->argintregs[p], var->regoff);
429 } else { /* reg arg -> spilled */
430 M_LST(r->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(r->argfltregs[p], var->regoff);
449 } else { /* reg arg -> spilled */
450 M_DST(r->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(m, (void*) func_enter);
474 M_ALD(REG_PV, REG_PV, p);
475 M_ALD(r->argintregs[0], REG_SP, r->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 */
507 while (src != NULL) {
509 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
510 d = reg_of_var(m, src, REG_ITMP1);
511 M_INTMOVE(REG_ITMP1, d);
512 store_reg_to_var_int(src, d);
515 d = reg_of_var(m, src, REG_IFTMP);
516 if ((src->varkind != STACKVAR)) {
518 if (IS_FLT_DBL_TYPE(s2)) {
519 if (!(r->interfaces[len][s2].flags & INMEMORY)) {
520 s1 = r->interfaces[len][s2].regoff;
524 M_DLD(d, REG_SP, 8 * r->interfaces[len][s2].regoff);
526 store_reg_to_var_flt(src, d);
529 if (!(r->interfaces[len][s2].flags & INMEMORY)) {
530 s1 = r->interfaces[len][s2].regoff;
534 M_LLD(d, REG_SP, 8 * r->interfaces[len][s2].regoff);
536 store_reg_to_var_int(src, d);
543 /* walk through all instructions */
547 for (iptr = bptr->iinstr;
549 src = iptr->dst, len--, iptr++) {
551 MCODECHECK(64); /* an instruction usually needs < 64 words */
554 case ICMD_NOP: /* ... ==> ... */
557 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
559 var_to_reg_int(s1, src, REG_ITMP1);
561 codegen_addxnullrefs(m, mcodeptr);
564 /* constant operations ************************************************/
566 case ICMD_ICONST: /* ... ==> ..., constant */
567 /* op1 = 0, val.i = constant */
569 d = reg_of_var(m, iptr->dst, REG_ITMP1);
570 ICONST(d, iptr->val.i);
571 store_reg_to_var_int(iptr->dst, d);
574 case ICMD_LCONST: /* ... ==> ..., constant */
575 /* op1 = 0, val.l = constant */
577 d = reg_of_var(m, iptr->dst, REG_ITMP1);
578 LCONST(d, iptr->val.l);
579 store_reg_to_var_int(iptr->dst, d);
582 case ICMD_FCONST: /* ... ==> ..., constant */
583 /* op1 = 0, val.f = constant */
585 d = reg_of_var(m, iptr->dst, REG_FTMP1);
586 a = dseg_addfloat(m, iptr->val.f);
588 store_reg_to_var_flt(iptr->dst, d);
591 case ICMD_DCONST: /* ... ==> ..., constant */
592 /* op1 = 0, val.d = constant */
594 d = reg_of_var(m, iptr->dst, REG_FTMP1);
595 a = dseg_adddouble(m, iptr->val.d);
597 store_reg_to_var_flt(iptr->dst, d);
600 case ICMD_ACONST: /* ... ==> ..., constant */
601 /* op1 = 0, val.a = constant */
603 d = reg_of_var(m, iptr->dst, REG_ITMP1);
605 a = dseg_addaddress(m, iptr->val.a);
608 M_INTMOVE(REG_ZERO, d);
610 store_reg_to_var_int(iptr->dst, d);
614 /* load/store operations **********************************************/
616 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
617 case ICMD_LLOAD: /* op1 = local variable */
620 d = reg_of_var(m, iptr->dst, REG_ITMP1);
621 if ((iptr->dst->varkind == LOCALVAR) &&
622 (iptr->dst->varnum == iptr->op1))
624 var = &(r->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
625 if (var->flags & INMEMORY)
626 M_LLD(d, REG_SP, 8 * var->regoff);
628 {M_INTMOVE(var->regoff,d);}
629 store_reg_to_var_int(iptr->dst, d);
632 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
633 case ICMD_DLOAD: /* op1 = local variable */
635 d = reg_of_var(m, iptr->dst, REG_FTMP1);
636 if ((iptr->dst->varkind == LOCALVAR) &&
637 (iptr->dst->varnum == iptr->op1))
639 var = &(r->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
640 if (var->flags & INMEMORY)
641 M_DLD(d, REG_SP, 8 * var->regoff);
643 {M_FLTMOVE(var->regoff,d);}
644 store_reg_to_var_flt(iptr->dst, d);
648 case ICMD_ISTORE: /* ..., value ==> ... */
649 case ICMD_LSTORE: /* op1 = local variable */
652 if ((src->varkind == LOCALVAR) &&
653 (src->varnum == iptr->op1))
655 var = &(r->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
656 if (var->flags & INMEMORY) {
657 var_to_reg_int(s1, src, REG_ITMP1);
658 M_LST(s1, REG_SP, 8 * var->regoff);
661 var_to_reg_int(s1, src, var->regoff);
662 M_INTMOVE(s1, var->regoff);
666 case ICMD_FSTORE: /* ..., value ==> ... */
667 case ICMD_DSTORE: /* op1 = local variable */
669 if ((src->varkind == LOCALVAR) &&
670 (src->varnum == iptr->op1))
672 var = &(r->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
673 if (var->flags & INMEMORY) {
674 var_to_reg_flt(s1, src, REG_FTMP1);
675 M_DST(s1, REG_SP, 8 * var->regoff);
678 var_to_reg_flt(s1, src, var->regoff);
679 M_FLTMOVE(s1, var->regoff);
684 /* pop/dup/swap operations ********************************************/
686 /* attention: double and longs are only one entry in CACAO ICMDs */
688 case ICMD_POP: /* ..., value ==> ... */
689 case ICMD_POP2: /* ..., value, value ==> ... */
692 case ICMD_DUP: /* ..., a ==> ..., a, a */
693 M_COPY(src, iptr->dst);
696 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
698 M_COPY(src, iptr->dst);
699 M_COPY(src->prev, iptr->dst->prev);
700 M_COPY(iptr->dst, iptr->dst->prev->prev);
703 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
705 M_COPY(src, iptr->dst);
706 M_COPY(src->prev, iptr->dst->prev);
707 M_COPY(src->prev->prev, iptr->dst->prev->prev);
708 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
711 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
713 M_COPY(src, iptr->dst);
714 M_COPY(src->prev, iptr->dst->prev);
717 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
719 M_COPY(src, iptr->dst);
720 M_COPY(src->prev, iptr->dst->prev);
721 M_COPY(src->prev->prev, iptr->dst->prev->prev);
722 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
723 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev);
726 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
728 M_COPY(src, iptr->dst);
729 M_COPY(src->prev, iptr->dst->prev);
730 M_COPY(src->prev->prev, iptr->dst->prev->prev);
731 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
732 M_COPY(iptr->dst, iptr->dst->prev->prev->prev->prev);
733 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev->prev);
736 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
738 M_COPY(src, iptr->dst->prev);
739 M_COPY(src->prev, iptr->dst);
743 /* integer operations *************************************************/
745 case ICMD_INEG: /* ..., value ==> ..., - value */
747 var_to_reg_int(s1, src, REG_ITMP1);
748 d = reg_of_var(m, iptr->dst, REG_ITMP3);
749 M_ISUB(REG_ZERO, s1, d);
750 store_reg_to_var_int(iptr->dst, d);
753 case ICMD_LNEG: /* ..., value ==> ..., - value */
755 var_to_reg_int(s1, src, REG_ITMP1);
756 d = reg_of_var(m, iptr->dst, REG_ITMP3);
757 M_LSUB(REG_ZERO, s1, d);
758 store_reg_to_var_int(iptr->dst, d);
761 case ICMD_I2L: /* ..., value ==> ..., value */
763 var_to_reg_int(s1, src, REG_ITMP1);
764 d = reg_of_var(m, iptr->dst, REG_ITMP3);
766 store_reg_to_var_int(iptr->dst, d);
769 case ICMD_L2I: /* ..., value ==> ..., value */
771 var_to_reg_int(s1, src, REG_ITMP1);
772 d = reg_of_var(m, iptr->dst, REG_ITMP3);
773 M_IADD(s1, REG_ZERO, d );
774 store_reg_to_var_int(iptr->dst, d);
777 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
779 var_to_reg_int(s1, src, REG_ITMP1);
780 d = reg_of_var(m, iptr->dst, REG_ITMP3);
781 if (has_ext_instr_set) {
785 M_SLL_IMM(s1, 56, d);
786 M_SRA_IMM( d, 56, d);
788 store_reg_to_var_int(iptr->dst, d);
791 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
793 var_to_reg_int(s1, src, REG_ITMP1);
794 d = reg_of_var(m, iptr->dst, REG_ITMP3);
796 store_reg_to_var_int(iptr->dst, d);
799 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
801 var_to_reg_int(s1, src, REG_ITMP1);
802 d = reg_of_var(m, iptr->dst, REG_ITMP3);
803 if (has_ext_instr_set) {
807 M_SLL_IMM(s1, 48, d);
808 M_SRA_IMM( d, 48, d);
810 store_reg_to_var_int(iptr->dst, d);
814 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
816 var_to_reg_int(s1, src->prev, REG_ITMP1);
817 var_to_reg_int(s2, src, REG_ITMP2);
818 d = reg_of_var(m, iptr->dst, REG_ITMP3);
820 store_reg_to_var_int(iptr->dst, d);
823 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
824 /* val.i = constant */
826 var_to_reg_int(s1, src, REG_ITMP1);
827 d = reg_of_var(m, iptr->dst, REG_ITMP3);
828 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
829 M_IADD_IMM(s1, iptr->val.i, d);
832 ICONST(REG_ITMP2, iptr->val.i);
833 M_IADD(s1, REG_ITMP2, d);
835 store_reg_to_var_int(iptr->dst, d);
838 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
840 var_to_reg_int(s1, src->prev, REG_ITMP1);
841 var_to_reg_int(s2, src, REG_ITMP2);
842 d = reg_of_var(m, iptr->dst, REG_ITMP3);
844 store_reg_to_var_int(iptr->dst, d);
847 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
848 /* val.l = constant */
850 var_to_reg_int(s1, src, REG_ITMP1);
851 d = reg_of_var(m, iptr->dst, REG_ITMP3);
852 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
853 M_LADD_IMM(s1, iptr->val.l, d);
856 LCONST(REG_ITMP2, iptr->val.l);
857 M_LADD(s1, REG_ITMP2, d);
859 store_reg_to_var_int(iptr->dst, d);
862 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
864 var_to_reg_int(s1, src->prev, REG_ITMP1);
865 var_to_reg_int(s2, src, REG_ITMP2);
866 d = reg_of_var(m, iptr->dst, REG_ITMP3);
868 store_reg_to_var_int(iptr->dst, d);
871 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
872 /* val.i = constant */
874 var_to_reg_int(s1, src, REG_ITMP1);
875 d = reg_of_var(m, iptr->dst, REG_ITMP3);
876 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
877 M_ISUB_IMM(s1, iptr->val.i, d);
880 ICONST(REG_ITMP2, iptr->val.i);
881 M_ISUB(s1, REG_ITMP2, d);
883 store_reg_to_var_int(iptr->dst, d);
886 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
888 var_to_reg_int(s1, src->prev, REG_ITMP1);
889 var_to_reg_int(s2, src, REG_ITMP2);
890 d = reg_of_var(m, iptr->dst, REG_ITMP3);
892 store_reg_to_var_int(iptr->dst, d);
895 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
896 /* val.l = constant */
898 var_to_reg_int(s1, src, REG_ITMP1);
899 d = reg_of_var(m, iptr->dst, REG_ITMP3);
900 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
901 M_LSUB_IMM(s1, iptr->val.l, d);
904 LCONST(REG_ITMP2, iptr->val.l);
905 M_LSUB(s1, REG_ITMP2, d);
907 store_reg_to_var_int(iptr->dst, d);
910 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
912 var_to_reg_int(s1, src->prev, REG_ITMP1);
913 var_to_reg_int(s2, src, REG_ITMP2);
914 d = reg_of_var(m, iptr->dst, REG_ITMP3);
916 store_reg_to_var_int(iptr->dst, d);
919 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
920 /* val.i = constant */
922 var_to_reg_int(s1, src, REG_ITMP1);
923 d = reg_of_var(m, iptr->dst, REG_ITMP3);
924 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
925 M_IMUL_IMM(s1, iptr->val.i, d);
928 ICONST(REG_ITMP2, iptr->val.i);
929 M_IMUL(s1, REG_ITMP2, d);
931 store_reg_to_var_int(iptr->dst, d);
934 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
936 var_to_reg_int(s1, src->prev, REG_ITMP1);
937 var_to_reg_int(s2, src, REG_ITMP2);
938 d = reg_of_var(m, iptr->dst, REG_ITMP3);
940 store_reg_to_var_int(iptr->dst, d);
943 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
944 /* val.l = constant */
946 var_to_reg_int(s1, src, REG_ITMP1);
947 d = reg_of_var(m, iptr->dst, REG_ITMP3);
948 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
949 M_LMUL_IMM(s1, iptr->val.l, d);
952 LCONST(REG_ITMP2, iptr->val.l);
953 M_LMUL(s1, REG_ITMP2, d);
955 store_reg_to_var_int(iptr->dst, d);
958 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
959 case ICMD_LDIVPOW2: /* val.i = constant */
961 var_to_reg_int(s1, src, REG_ITMP1);
962 d = reg_of_var(m, iptr->dst, REG_ITMP3);
963 if (iptr->val.i <= 15) {
964 M_LDA(REG_ITMP2, s1, (1 << iptr->val.i) -1);
965 M_CMOVGE(s1, s1, REG_ITMP2);
968 M_SRA_IMM(s1, 63, REG_ITMP2);
969 M_SRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
970 M_LADD(s1, REG_ITMP2, REG_ITMP2);
972 M_SRA_IMM(REG_ITMP2, iptr->val.i, d);
973 store_reg_to_var_int(iptr->dst, d);
976 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
978 var_to_reg_int(s1, src->prev, REG_ITMP1);
979 var_to_reg_int(s2, src, REG_ITMP2);
980 d = reg_of_var(m, iptr->dst, REG_ITMP3);
981 M_AND_IMM(s2, 0x1f, REG_ITMP3);
982 M_SLL(s1, REG_ITMP3, d);
983 M_IADD(d, REG_ZERO, d);
984 store_reg_to_var_int(iptr->dst, d);
987 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
988 /* val.i = constant */
990 var_to_reg_int(s1, src, REG_ITMP1);
991 d = reg_of_var(m, iptr->dst, REG_ITMP3);
992 M_SLL_IMM(s1, iptr->val.i & 0x1f, d);
993 M_IADD(d, REG_ZERO, d);
994 store_reg_to_var_int(iptr->dst, d);
997 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
999 var_to_reg_int(s1, src->prev, REG_ITMP1);
1000 var_to_reg_int(s2, src, REG_ITMP2);
1001 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1002 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1003 M_SRA(s1, REG_ITMP3, d);
1004 store_reg_to_var_int(iptr->dst, d);
1007 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1008 /* val.i = constant */
1010 var_to_reg_int(s1, src, REG_ITMP1);
1011 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1012 M_SRA_IMM(s1, iptr->val.i & 0x1f, d);
1013 store_reg_to_var_int(iptr->dst, d);
1016 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1018 var_to_reg_int(s1, src->prev, REG_ITMP1);
1019 var_to_reg_int(s2, src, REG_ITMP2);
1020 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1021 M_AND_IMM(s2, 0x1f, REG_ITMP2);
1023 M_SRL(d, REG_ITMP2, d);
1024 M_IADD(d, REG_ZERO, d);
1025 store_reg_to_var_int(iptr->dst, d);
1028 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1029 /* val.i = constant */
1031 var_to_reg_int(s1, src, REG_ITMP1);
1032 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1034 M_SRL_IMM(d, iptr->val.i & 0x1f, d);
1035 M_IADD(d, REG_ZERO, d);
1036 store_reg_to_var_int(iptr->dst, d);
1039 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1041 var_to_reg_int(s1, src->prev, REG_ITMP1);
1042 var_to_reg_int(s2, src, REG_ITMP2);
1043 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1045 store_reg_to_var_int(iptr->dst, d);
1048 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1049 /* val.i = constant */
1051 var_to_reg_int(s1, src, REG_ITMP1);
1052 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1053 M_SLL_IMM(s1, iptr->val.i & 0x3f, d);
1054 store_reg_to_var_int(iptr->dst, d);
1057 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1059 var_to_reg_int(s1, src->prev, REG_ITMP1);
1060 var_to_reg_int(s2, src, REG_ITMP2);
1061 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1063 store_reg_to_var_int(iptr->dst, d);
1066 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1067 /* val.i = constant */
1069 var_to_reg_int(s1, src, REG_ITMP1);
1070 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1071 M_SRA_IMM(s1, iptr->val.i & 0x3f, d);
1072 store_reg_to_var_int(iptr->dst, d);
1075 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1077 var_to_reg_int(s1, src->prev, REG_ITMP1);
1078 var_to_reg_int(s2, src, REG_ITMP2);
1079 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1081 store_reg_to_var_int(iptr->dst, d);
1084 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1085 /* val.i = constant */
1087 var_to_reg_int(s1, src, REG_ITMP1);
1088 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1089 M_SRL_IMM(s1, iptr->val.i & 0x3f, d);
1090 store_reg_to_var_int(iptr->dst, d);
1093 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1096 var_to_reg_int(s1, src->prev, REG_ITMP1);
1097 var_to_reg_int(s2, src, REG_ITMP2);
1098 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1100 store_reg_to_var_int(iptr->dst, d);
1103 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1104 /* val.i = constant */
1106 var_to_reg_int(s1, src, REG_ITMP1);
1107 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1108 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1109 M_AND_IMM(s1, iptr->val.i, d);
1111 else if (iptr->val.i == 0xffff) {
1114 else if (iptr->val.i == 0xffffff) {
1115 M_ZAPNOT_IMM(s1, 0x07, d);
1118 ICONST(REG_ITMP2, iptr->val.i);
1119 M_AND(s1, REG_ITMP2, d);
1121 store_reg_to_var_int(iptr->dst, d);
1124 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1125 /* val.i = constant */
1127 var_to_reg_int(s1, src, REG_ITMP1);
1128 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1130 M_MOV(s1, REG_ITMP1);
1133 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1134 M_AND_IMM(s1, iptr->val.i, d);
1136 M_ISUB(REG_ZERO, s1, d);
1137 M_AND_IMM(d, iptr->val.i, d);
1139 else if (iptr->val.i == 0xffff) {
1142 M_ISUB(REG_ZERO, s1, d);
1145 else if (iptr->val.i == 0xffffff) {
1146 M_ZAPNOT_IMM(s1, 0x07, d);
1148 M_ISUB(REG_ZERO, s1, d);
1149 M_ZAPNOT_IMM(d, 0x07, d);
1152 ICONST(REG_ITMP2, iptr->val.i);
1153 M_AND(s1, REG_ITMP2, d);
1155 M_ISUB(REG_ZERO, s1, d);
1156 M_AND(d, REG_ITMP2, d);
1158 M_ISUB(REG_ZERO, d, d);
1159 store_reg_to_var_int(iptr->dst, d);
1162 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1163 /* val.l = constant */
1165 var_to_reg_int(s1, src, REG_ITMP1);
1166 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1167 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1168 M_AND_IMM(s1, iptr->val.l, d);
1170 else if (iptr->val.l == 0xffffL) {
1173 else if (iptr->val.l == 0xffffffL) {
1174 M_ZAPNOT_IMM(s1, 0x07, d);
1176 else if (iptr->val.l == 0xffffffffL) {
1179 else if (iptr->val.l == 0xffffffffffL) {
1180 M_ZAPNOT_IMM(s1, 0x1f, d);
1182 else if (iptr->val.l == 0xffffffffffffL) {
1183 M_ZAPNOT_IMM(s1, 0x3f, d);
1185 else if (iptr->val.l == 0xffffffffffffffL) {
1186 M_ZAPNOT_IMM(s1, 0x7f, d);
1189 LCONST(REG_ITMP2, iptr->val.l);
1190 M_AND(s1, REG_ITMP2, d);
1192 store_reg_to_var_int(iptr->dst, d);
1195 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1196 /* val.l = constant */
1198 var_to_reg_int(s1, src, REG_ITMP1);
1199 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1201 M_MOV(s1, REG_ITMP1);
1204 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1205 M_AND_IMM(s1, iptr->val.l, d);
1207 M_LSUB(REG_ZERO, s1, d);
1208 M_AND_IMM(d, iptr->val.l, d);
1210 else if (iptr->val.l == 0xffffL) {
1213 M_LSUB(REG_ZERO, s1, d);
1216 else if (iptr->val.l == 0xffffffL) {
1217 M_ZAPNOT_IMM(s1, 0x07, d);
1219 M_LSUB(REG_ZERO, s1, d);
1220 M_ZAPNOT_IMM(d, 0x07, d);
1222 else if (iptr->val.l == 0xffffffffL) {
1225 M_LSUB(REG_ZERO, s1, d);
1228 else if (iptr->val.l == 0xffffffffffL) {
1229 M_ZAPNOT_IMM(s1, 0x1f, d);
1231 M_LSUB(REG_ZERO, s1, d);
1232 M_ZAPNOT_IMM(d, 0x1f, d);
1234 else if (iptr->val.l == 0xffffffffffffL) {
1235 M_ZAPNOT_IMM(s1, 0x3f, d);
1237 M_LSUB(REG_ZERO, s1, d);
1238 M_ZAPNOT_IMM(d, 0x3f, d);
1240 else if (iptr->val.l == 0xffffffffffffffL) {
1241 M_ZAPNOT_IMM(s1, 0x7f, d);
1243 M_LSUB(REG_ZERO, s1, d);
1244 M_ZAPNOT_IMM(d, 0x7f, d);
1247 LCONST(REG_ITMP2, iptr->val.l);
1248 M_AND(s1, REG_ITMP2, d);
1250 M_LSUB(REG_ZERO, s1, d);
1251 M_AND(d, REG_ITMP2, d);
1253 M_LSUB(REG_ZERO, d, d);
1254 store_reg_to_var_int(iptr->dst, d);
1257 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1260 var_to_reg_int(s1, src->prev, REG_ITMP1);
1261 var_to_reg_int(s2, src, REG_ITMP2);
1262 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1264 store_reg_to_var_int(iptr->dst, d);
1267 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1268 /* val.i = constant */
1270 var_to_reg_int(s1, src, REG_ITMP1);
1271 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1272 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1273 M_OR_IMM(s1, iptr->val.i, d);
1276 ICONST(REG_ITMP2, iptr->val.i);
1277 M_OR(s1, REG_ITMP2, d);
1279 store_reg_to_var_int(iptr->dst, d);
1282 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1283 /* val.l = constant */
1285 var_to_reg_int(s1, src, REG_ITMP1);
1286 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1287 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1288 M_OR_IMM(s1, iptr->val.l, d);
1291 LCONST(REG_ITMP2, iptr->val.l);
1292 M_OR(s1, REG_ITMP2, d);
1294 store_reg_to_var_int(iptr->dst, d);
1297 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1300 var_to_reg_int(s1, src->prev, REG_ITMP1);
1301 var_to_reg_int(s2, src, REG_ITMP2);
1302 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1304 store_reg_to_var_int(iptr->dst, d);
1307 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1308 /* val.i = constant */
1310 var_to_reg_int(s1, src, REG_ITMP1);
1311 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1312 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1313 M_XOR_IMM(s1, iptr->val.i, d);
1316 ICONST(REG_ITMP2, iptr->val.i);
1317 M_XOR(s1, REG_ITMP2, d);
1319 store_reg_to_var_int(iptr->dst, d);
1322 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1323 /* val.l = constant */
1325 var_to_reg_int(s1, src, REG_ITMP1);
1326 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1327 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1328 M_XOR_IMM(s1, iptr->val.l, d);
1331 LCONST(REG_ITMP2, iptr->val.l);
1332 M_XOR(s1, REG_ITMP2, d);
1334 store_reg_to_var_int(iptr->dst, d);
1338 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1340 var_to_reg_int(s1, src->prev, REG_ITMP1);
1341 var_to_reg_int(s2, src, REG_ITMP2);
1342 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1343 M_CMPLT(s1, s2, REG_ITMP3);
1344 M_CMPLT(s2, s1, REG_ITMP1);
1345 M_LSUB (REG_ITMP1, REG_ITMP3, d);
1346 store_reg_to_var_int(iptr->dst, d);
1350 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1351 /* op1 = variable, val.i = constant */
1353 var = &(r->locals[iptr->op1][TYPE_INT]);
1354 if (var->flags & INMEMORY) {
1356 M_LLD(s1, REG_SP, 8 * var->regoff);
1360 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1361 M_IADD_IMM(s1, iptr->val.i, s1);
1363 else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1364 M_ISUB_IMM(s1, (-iptr->val.i), s1);
1367 M_LDA (s1, s1, iptr->val.i);
1368 M_IADD(s1, REG_ZERO, s1);
1370 if (var->flags & INMEMORY)
1371 M_LST(s1, REG_SP, 8 * var->regoff);
1375 /* floating operations ************************************************/
1377 case ICMD_FNEG: /* ..., value ==> ..., - value */
1379 var_to_reg_flt(s1, src, REG_FTMP1);
1380 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1382 store_reg_to_var_flt(iptr->dst, d);
1385 case ICMD_DNEG: /* ..., value ==> ..., - value */
1387 var_to_reg_flt(s1, src, REG_FTMP1);
1388 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1390 store_reg_to_var_flt(iptr->dst, d);
1393 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1395 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1396 var_to_reg_flt(s2, src, REG_FTMP2);
1397 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1402 if (d == s1 || d == s2) {
1403 M_FADDS(s1, s2, REG_FTMP3);
1405 M_FMOV(REG_FTMP3, d);
1412 store_reg_to_var_flt(iptr->dst, d);
1415 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1417 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1418 var_to_reg_flt(s2, src, REG_FTMP2);
1419 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1424 if (d == s1 || d == s2) {
1425 M_DADDS(s1, s2, REG_FTMP3);
1427 M_FMOV(REG_FTMP3, d);
1434 store_reg_to_var_flt(iptr->dst, d);
1437 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1439 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1440 var_to_reg_flt(s2, src, REG_FTMP2);
1441 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1446 if (d == s1 || d == s2) {
1447 M_FSUBS(s1, s2, REG_FTMP3);
1449 M_FMOV(REG_FTMP3, d);
1456 store_reg_to_var_flt(iptr->dst, d);
1459 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1461 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1462 var_to_reg_flt(s2, src, REG_FTMP2);
1463 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1468 if (d == s1 || d == s2) {
1469 M_DSUBS(s1, s2, REG_FTMP3);
1471 M_FMOV(REG_FTMP3, d);
1478 store_reg_to_var_flt(iptr->dst, d);
1481 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1483 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1484 var_to_reg_flt(s2, src, REG_FTMP2);
1485 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1490 if (d == s1 || d == s2) {
1491 M_FMULS(s1, s2, REG_FTMP3);
1493 M_FMOV(REG_FTMP3, d);
1500 store_reg_to_var_flt(iptr->dst, d);
1503 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1505 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1506 var_to_reg_flt(s2, src, REG_FTMP2);
1507 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1512 if (d == s1 || d == s2) {
1513 M_DMULS(s1, s2, REG_FTMP3);
1515 M_FMOV(REG_FTMP3, d);
1522 store_reg_to_var_flt(iptr->dst, d);
1525 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1527 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1528 var_to_reg_flt(s2, src, REG_FTMP2);
1529 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1534 if (d == s1 || d == s2) {
1535 M_FDIVS(s1, s2, REG_FTMP3);
1537 M_FMOV(REG_FTMP3, d);
1544 store_reg_to_var_flt(iptr->dst, d);
1547 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1549 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1550 var_to_reg_flt(s2, src, REG_FTMP2);
1551 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1556 if (d == s1 || d == s2) {
1557 M_DDIVS(s1, s2, REG_FTMP3);
1559 M_FMOV(REG_FTMP3, d);
1566 store_reg_to_var_flt(iptr->dst, d);
1569 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1571 var_to_reg_int(s1, src, REG_ITMP1);
1572 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1573 a = dseg_adddouble(m, 0.0);
1574 M_LST (s1, REG_PV, a);
1575 M_DLD (d, REG_PV, a);
1577 store_reg_to_var_flt(iptr->dst, d);
1580 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1582 var_to_reg_int(s1, src, REG_ITMP1);
1583 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1584 a = dseg_adddouble(m, 0.0);
1585 M_LST (s1, REG_PV, a);
1586 M_DLD (d, REG_PV, a);
1588 store_reg_to_var_flt(iptr->dst, d);
1591 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1593 var_to_reg_flt(s1, src, REG_FTMP1);
1594 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1595 a = dseg_adddouble(m, 0.0);
1596 M_CVTDL_C(s1, REG_FTMP2);
1597 M_CVTLI(REG_FTMP2, REG_FTMP3);
1598 M_DST (REG_FTMP3, REG_PV, a);
1599 M_ILD (d, REG_PV, a);
1600 store_reg_to_var_int(iptr->dst, d);
1603 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1605 var_to_reg_flt(s1, src, REG_FTMP1);
1606 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1607 a = dseg_adddouble(m, 0.0);
1608 M_CVTDL_C(s1, REG_FTMP2);
1609 M_DST (REG_FTMP2, REG_PV, a);
1610 M_LLD (d, REG_PV, a);
1611 store_reg_to_var_int(iptr->dst, d);
1614 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1616 var_to_reg_flt(s1, src, REG_FTMP1);
1617 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1620 store_reg_to_var_flt(iptr->dst, d);
1623 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1625 var_to_reg_flt(s1, src, REG_FTMP1);
1626 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1634 store_reg_to_var_flt(iptr->dst, d);
1637 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1639 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1640 var_to_reg_flt(s2, src, REG_FTMP2);
1641 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1643 M_LSUB_IMM(REG_ZERO, 1, d);
1644 M_FCMPEQ(s1, s2, REG_FTMP3);
1645 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1647 M_FCMPLT(s2, s1, REG_FTMP3);
1648 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1649 M_LADD_IMM(REG_ZERO, 1, d);
1652 M_LSUB_IMM(REG_ZERO, 1, d);
1653 M_FCMPEQS(s1, s2, REG_FTMP3);
1655 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1657 M_FCMPLTS(s2, s1, REG_FTMP3);
1659 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1660 M_LADD_IMM(REG_ZERO, 1, d);
1662 store_reg_to_var_int(iptr->dst, d);
1665 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1667 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1668 var_to_reg_flt(s2, src, REG_FTMP2);
1669 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1671 M_LADD_IMM(REG_ZERO, 1, d);
1672 M_FCMPEQ(s1, s2, REG_FTMP3);
1673 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1675 M_FCMPLT(s1, s2, REG_FTMP3);
1676 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1677 M_LSUB_IMM(REG_ZERO, 1, d);
1680 M_LADD_IMM(REG_ZERO, 1, d);
1681 M_FCMPEQS(s1, s2, REG_FTMP3);
1683 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1685 M_FCMPLTS(s1, s2, REG_FTMP3);
1687 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1688 M_LSUB_IMM(REG_ZERO, 1, d);
1690 store_reg_to_var_int(iptr->dst, d);
1694 /* memory operations **************************************************/
1696 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1698 var_to_reg_int(s1, src, REG_ITMP1);
1699 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1700 gen_nullptr_check(s1);
1701 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1702 store_reg_to_var_int(iptr->dst, d);
1705 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1707 var_to_reg_int(s1, src->prev, REG_ITMP1);
1708 var_to_reg_int(s2, src, REG_ITMP2);
1709 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1710 if (iptr->op1 == 0) {
1711 gen_nullptr_check(s1);
1714 M_SAADDQ(s2, s1, REG_ITMP1);
1715 M_ALD( d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1716 store_reg_to_var_int(iptr->dst, d);
1719 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1721 var_to_reg_int(s1, src->prev, REG_ITMP1);
1722 var_to_reg_int(s2, src, REG_ITMP2);
1723 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1724 if (iptr->op1 == 0) {
1725 gen_nullptr_check(s1);
1728 M_S8ADDQ(s2, s1, REG_ITMP1);
1729 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1730 store_reg_to_var_int(iptr->dst, d);
1733 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1735 var_to_reg_int(s1, src->prev, REG_ITMP1);
1736 var_to_reg_int(s2, src, REG_ITMP2);
1737 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1738 if (iptr->op1 == 0) {
1739 gen_nullptr_check(s1);
1743 M_S4ADDQ(s2, s1, REG_ITMP1);
1744 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1745 store_reg_to_var_int(iptr->dst, d);
1748 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1750 var_to_reg_int(s1, src->prev, REG_ITMP1);
1751 var_to_reg_int(s2, src, REG_ITMP2);
1752 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1753 if (iptr->op1 == 0) {
1754 gen_nullptr_check(s1);
1757 M_S4ADDQ(s2, s1, REG_ITMP1);
1758 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1759 store_reg_to_var_flt(iptr->dst, d);
1762 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1764 var_to_reg_int(s1, src->prev, REG_ITMP1);
1765 var_to_reg_int(s2, src, REG_ITMP2);
1766 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1767 if (iptr->op1 == 0) {
1768 gen_nullptr_check(s1);
1771 M_S8ADDQ(s2, s1, REG_ITMP1);
1772 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1773 store_reg_to_var_flt(iptr->dst, d);
1776 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1778 var_to_reg_int(s1, src->prev, REG_ITMP1);
1779 var_to_reg_int(s2, src, REG_ITMP2);
1780 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1781 if (iptr->op1 == 0) {
1782 gen_nullptr_check(s1);
1785 if (has_ext_instr_set) {
1786 M_LADD(s2, s1, REG_ITMP1);
1787 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1788 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1791 M_LADD (s2, s1, REG_ITMP1);
1792 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1793 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1794 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1795 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
1797 store_reg_to_var_int(iptr->dst, d);
1800 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1802 var_to_reg_int(s1, src->prev, REG_ITMP1);
1803 var_to_reg_int(s2, src, REG_ITMP2);
1804 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1805 if (iptr->op1 == 0) {
1806 gen_nullptr_check(s1);
1809 if (has_ext_instr_set) {
1810 M_LADD(s2, s1, REG_ITMP1);
1811 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1812 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1816 M_LADD(s2, s1, REG_ITMP1);
1817 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1818 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1819 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1820 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1821 M_SRA_IMM(d, 48, d);
1823 store_reg_to_var_int(iptr->dst, d);
1826 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1828 var_to_reg_int(s1, src->prev, REG_ITMP1);
1829 var_to_reg_int(s2, src, REG_ITMP2);
1830 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1831 if (iptr->op1 == 0) {
1832 gen_nullptr_check(s1);
1835 if (has_ext_instr_set) {
1836 M_LADD (s2, s1, REG_ITMP1);
1837 M_BLDU (d, REG_ITMP1, OFFSET (java_bytearray, data[0]));
1841 M_LADD(s2, s1, REG_ITMP1);
1842 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1843 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
1844 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1845 M_SRA_IMM(d, 56, d);
1847 store_reg_to_var_int(iptr->dst, d);
1851 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1853 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1854 var_to_reg_int(s2, src->prev, REG_ITMP2);
1855 if (iptr->op1 == 0) {
1856 gen_nullptr_check(s1);
1859 var_to_reg_int(s3, src, REG_ITMP3);
1860 M_SAADDQ(s2, s1, REG_ITMP1);
1861 M_AST (s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1864 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1866 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1867 var_to_reg_int(s2, src->prev, REG_ITMP2);
1868 if (iptr->op1 == 0) {
1869 gen_nullptr_check(s1);
1872 var_to_reg_int(s3, src, REG_ITMP3);
1873 M_S8ADDQ(s2, s1, REG_ITMP1);
1874 M_LST (s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1877 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1879 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1880 var_to_reg_int(s2, src->prev, REG_ITMP2);
1881 if (iptr->op1 == 0) {
1882 gen_nullptr_check(s1);
1886 var_to_reg_int(s3, src, REG_ITMP3);
1887 M_S4ADDQ(s2, s1, REG_ITMP1);
1888 M_IST (s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1891 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1893 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1894 var_to_reg_int(s2, src->prev, REG_ITMP2);
1895 if (iptr->op1 == 0) {
1896 gen_nullptr_check(s1);
1899 var_to_reg_flt(s3, src, REG_FTMP3);
1900 M_S4ADDQ(s2, s1, REG_ITMP1);
1901 M_FST (s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1904 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1906 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1907 var_to_reg_int(s2, src->prev, REG_ITMP2);
1908 if (iptr->op1 == 0) {
1909 gen_nullptr_check(s1);
1912 var_to_reg_flt(s3, src, REG_FTMP3);
1913 M_S8ADDQ(s2, s1, REG_ITMP1);
1914 M_DST (s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1917 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1919 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1920 var_to_reg_int(s2, src->prev, REG_ITMP2);
1921 if (iptr->op1 == 0) {
1922 gen_nullptr_check(s1);
1925 var_to_reg_int(s3, src, REG_ITMP3);
1926 if (has_ext_instr_set) {
1927 M_LADD(s2, s1, REG_ITMP1);
1928 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1929 M_SST (s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1932 M_LADD (s2, s1, REG_ITMP1);
1933 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1934 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1935 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1936 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1937 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1938 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
1939 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1943 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1945 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1946 var_to_reg_int(s2, src->prev, REG_ITMP2);
1947 if (iptr->op1 == 0) {
1948 gen_nullptr_check(s1);
1951 var_to_reg_int(s3, src, REG_ITMP3);
1952 if (has_ext_instr_set) {
1953 M_LADD(s2, s1, REG_ITMP1);
1954 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1955 M_SST (s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1958 M_LADD (s2, s1, REG_ITMP1);
1959 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1960 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1961 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1962 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1963 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1964 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
1965 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1969 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1971 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1972 var_to_reg_int(s2, src->prev, REG_ITMP2);
1973 if (iptr->op1 == 0) {
1974 gen_nullptr_check(s1);
1977 var_to_reg_int(s3, src, REG_ITMP3);
1978 if (has_ext_instr_set) {
1979 M_LADD(s2, s1, REG_ITMP1);
1980 M_BST (s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1983 M_LADD (s2, s1, REG_ITMP1);
1984 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1985 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1986 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
1987 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1988 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
1989 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1994 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1996 var_to_reg_int(s1, src->prev, REG_ITMP1);
1997 var_to_reg_int(s2, src, REG_ITMP2);
1998 if (iptr->op1 == 0) {
1999 gen_nullptr_check(s1);
2002 M_S4ADDQ(s2, s1, REG_ITMP1);
2003 M_IST(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
2006 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
2008 var_to_reg_int(s1, src->prev, REG_ITMP1);
2009 var_to_reg_int(s2, src, REG_ITMP2);
2010 if (iptr->op1 == 0) {
2011 gen_nullptr_check(s1);
2014 M_S8ADDQ(s2, s1, REG_ITMP1);
2015 M_LST(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
2018 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
2020 var_to_reg_int(s1, src->prev, REG_ITMP1);
2021 var_to_reg_int(s2, src, REG_ITMP2);
2022 if (iptr->op1 == 0) {
2023 gen_nullptr_check(s1);
2026 M_SAADDQ(s2, s1, REG_ITMP1);
2027 M_AST(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
2030 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
2032 var_to_reg_int(s1, src->prev, REG_ITMP1);
2033 var_to_reg_int(s2, src, REG_ITMP2);
2034 if (iptr->op1 == 0) {
2035 gen_nullptr_check(s1);
2038 if (has_ext_instr_set) {
2039 M_LADD(s2, s1, REG_ITMP1);
2040 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2043 M_LADD(s2, s1, REG_ITMP1);
2044 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2045 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2046 M_INSBL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2047 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2048 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2049 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2053 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
2055 var_to_reg_int(s1, src->prev, REG_ITMP1);
2056 var_to_reg_int(s2, src, REG_ITMP2);
2057 if (iptr->op1 == 0) {
2058 gen_nullptr_check(s1);
2061 if (has_ext_instr_set) {
2062 M_LADD(s2, s1, REG_ITMP1);
2063 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2064 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
2067 M_LADD(s2, s1, REG_ITMP1);
2068 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2069 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2070 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2071 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2072 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2073 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2074 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2078 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
2080 var_to_reg_int(s1, src->prev, REG_ITMP1);
2081 var_to_reg_int(s2, src, REG_ITMP2);
2082 if (iptr->op1 == 0) {
2083 gen_nullptr_check(s1);
2086 if (has_ext_instr_set) {
2087 M_LADD(s2, s1, REG_ITMP1);
2088 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2089 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2092 M_LADD(s2, s1, REG_ITMP1);
2093 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2094 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2095 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2096 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2097 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2098 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2099 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2104 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2105 /* op1 = type, val.a = field address */
2107 /* if class isn't yet initialized, do it */
2108 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
2109 /* call helper function which patches this code */
2110 a = dseg_addaddress(m, ((fieldinfo *) iptr->val.a)->class);
2111 M_ALD(REG_ITMP1, REG_PV, a);
2112 a = dseg_addaddress(m, asm_check_clinit);
2113 M_ALD(REG_PV, REG_PV, a);
2114 M_JSR(REG_RA, REG_PV);
2117 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
2119 M_LDA(REG_PV, REG_RA, -s1);
2123 s4 ml = -s1, mh = 0;
2124 while (ml < -32768) { ml += 65536; mh--; }
2125 M_LDA(REG_PV, REG_RA, ml);
2126 M_LDAH(REG_PV, REG_PV, mh);
2130 a = dseg_addaddress(m, &(((fieldinfo *)(iptr->val.a))->value));
2131 M_ALD(REG_ITMP1, REG_PV, a);
2132 switch (iptr->op1) {
2134 var_to_reg_int(s2, src, REG_ITMP2);
2135 M_IST(s2, REG_ITMP1, 0);
2138 var_to_reg_int(s2, src, REG_ITMP2);
2139 M_LST(s2, REG_ITMP1, 0);
2142 var_to_reg_int(s2, src, REG_ITMP2);
2143 M_AST(s2, REG_ITMP1, 0);
2146 var_to_reg_flt(s2, src, REG_FTMP2);
2147 M_FST(s2, REG_ITMP1, 0);
2150 var_to_reg_flt(s2, src, REG_FTMP2);
2151 M_DST(s2, REG_ITMP1, 0);
2153 default: panic ("internal error");
2157 case ICMD_GETSTATIC: /* ... ==> ..., value */
2158 /* op1 = type, val.a = field address */
2160 /* if class isn't yet initialized, do it */
2161 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
2162 /* call helper function which patches this code */
2163 a = dseg_addaddress(m, ((fieldinfo *) iptr->val.a)->class);
2164 M_ALD(REG_ITMP1, REG_PV, a);
2165 a = dseg_addaddress(m, asm_check_clinit);
2166 M_ALD(REG_PV, REG_PV, a);
2167 M_JSR(REG_RA, REG_PV);
2170 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
2172 M_LDA(REG_PV, REG_RA, -s1);
2176 s4 ml = -s1, mh = 0;
2177 while (ml < -32768) { ml += 65536; mh--; }
2178 M_LDA(REG_PV, REG_RA, ml);
2179 M_LDAH(REG_PV, REG_PV, mh);
2183 a = dseg_addaddress(m, &(((fieldinfo *) iptr->val.a)->value));
2184 M_ALD(REG_ITMP1, REG_PV, a);
2185 switch (iptr->op1) {
2187 d = reg_of_var(m, iptr->dst, REG_ITMP3);
2188 M_ILD(d, REG_ITMP1, 0);
2189 store_reg_to_var_int(iptr->dst, d);
2192 d = reg_of_var(m, iptr->dst, REG_ITMP3);
2193 M_LLD(d, REG_ITMP1, 0);
2194 store_reg_to_var_int(iptr->dst, d);
2197 d = reg_of_var(m, iptr->dst, REG_ITMP3);
2198 M_ALD(d, REG_ITMP1, 0);
2199 store_reg_to_var_int(iptr->dst, d);
2202 d = reg_of_var(m, iptr->dst, REG_FTMP1);
2203 M_FLD(d, REG_ITMP1, 0);
2204 store_reg_to_var_flt(iptr->dst, d);
2207 d = reg_of_var(m, iptr->dst, REG_FTMP1);
2208 M_DLD(d, REG_ITMP1, 0);
2209 store_reg_to_var_flt(iptr->dst, d);
2211 default: panic ("internal error");
2216 case ICMD_PUTFIELD: /* ..., value ==> ... */
2217 /* op1 = type, val.i = field offset */
2219 a = ((fieldinfo *) iptr->val.a)->offset;
2220 switch (iptr->op1) {
2222 var_to_reg_int(s1, src->prev, REG_ITMP1);
2223 var_to_reg_int(s2, src, REG_ITMP2);
2224 gen_nullptr_check(s1);
2228 var_to_reg_int(s1, src->prev, REG_ITMP1);
2229 var_to_reg_int(s2, src, REG_ITMP2);
2230 gen_nullptr_check(s1);
2234 var_to_reg_int(s1, src->prev, REG_ITMP1);
2235 var_to_reg_int(s2, src, REG_ITMP2);
2236 gen_nullptr_check(s1);
2240 var_to_reg_int(s1, src->prev, REG_ITMP1);
2241 var_to_reg_flt(s2, src, REG_FTMP2);
2242 gen_nullptr_check(s1);
2246 var_to_reg_int(s1, src->prev, REG_ITMP1);
2247 var_to_reg_flt(s2, src, REG_FTMP2);
2248 gen_nullptr_check(s1);
2251 default: panic ("internal error");
2255 case ICMD_GETFIELD: /* ... ==> ..., value */
2256 /* op1 = type, val.i = field offset */
2258 a = ((fieldinfo *)(iptr->val.a))->offset;
2259 switch (iptr->op1) {
2261 var_to_reg_int(s1, src, REG_ITMP1);
2262 d = reg_of_var(m, iptr->dst, REG_ITMP3);
2263 gen_nullptr_check(s1);
2265 store_reg_to_var_int(iptr->dst, d);
2268 var_to_reg_int(s1, src, REG_ITMP1);
2269 d = reg_of_var(m, iptr->dst, REG_ITMP3);
2270 gen_nullptr_check(s1);
2272 store_reg_to_var_int(iptr->dst, d);
2275 var_to_reg_int(s1, src, REG_ITMP1);
2276 d = reg_of_var(m, iptr->dst, REG_ITMP3);
2277 gen_nullptr_check(s1);
2279 store_reg_to_var_int(iptr->dst, d);
2282 var_to_reg_int(s1, src, REG_ITMP1);
2283 d = reg_of_var(m, iptr->dst, REG_FTMP1);
2284 gen_nullptr_check(s1);
2286 store_reg_to_var_flt(iptr->dst, d);
2289 var_to_reg_int(s1, src, REG_ITMP1);
2290 d = reg_of_var(m, iptr->dst, REG_FTMP1);
2291 gen_nullptr_check(s1);
2293 store_reg_to_var_flt(iptr->dst, d);
2295 default: panic ("internal error");
2300 /* branch operations **************************************************/
2302 #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}}
2304 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2306 var_to_reg_int(s1, src, REG_ITMP1);
2307 M_INTMOVE(s1, REG_ITMP1_XPTR);
2308 a = dseg_addaddress(m, asm_handle_exception);
2309 M_ALD(REG_ITMP2, REG_PV, a);
2310 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2311 M_NOP; /* nop ensures that XPC is less than the end */
2312 /* of basic block */
2316 case ICMD_GOTO: /* ... ==> ... */
2317 /* op1 = target JavaVM pc */
2319 codegen_addreference(m, BlockPtrOfPC(iptr->op1), mcodeptr);
2323 case ICMD_JSR: /* ... ==> ... */
2324 /* op1 = target JavaVM pc */
2326 M_BSR(REG_ITMP1, 0);
2327 codegen_addreference(m, BlockPtrOfPC(iptr->op1), mcodeptr);
2330 case ICMD_RET: /* ... ==> ... */
2331 /* op1 = local variable */
2333 var = &(r->locals[iptr->op1][TYPE_ADR]);
2334 if (var->flags & INMEMORY) {
2335 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2336 M_RET(REG_ZERO, REG_ITMP1);
2339 M_RET(REG_ZERO, var->regoff);
2343 case ICMD_IFNULL: /* ..., value ==> ... */
2344 /* op1 = target JavaVM pc */
2346 var_to_reg_int(s1, src, REG_ITMP1);
2348 codegen_addreference(m, BlockPtrOfPC(iptr->op1), mcodeptr);
2351 case ICMD_IFNONNULL: /* ..., value ==> ... */
2352 /* op1 = target JavaVM pc */
2354 var_to_reg_int(s1, src, REG_ITMP1);
2356 codegen_addreference(m, BlockPtrOfPC(iptr->op1), mcodeptr);
2359 case ICMD_IFEQ: /* ..., value ==> ... */
2360 /* op1 = target JavaVM pc, val.i = constant */
2362 var_to_reg_int(s1, src, REG_ITMP1);
2363 if (iptr->val.i == 0) {
2367 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2368 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2371 ICONST(REG_ITMP2, iptr->val.i);
2372 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2374 M_BNEZ(REG_ITMP1, 0);
2376 codegen_addreference(m, BlockPtrOfPC(iptr->op1), mcodeptr);
2379 case ICMD_IFLT: /* ..., value ==> ... */
2380 /* op1 = target JavaVM pc, val.i = constant */
2382 var_to_reg_int(s1, src, REG_ITMP1);
2383 if (iptr->val.i == 0) {
2387 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2388 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2391 ICONST(REG_ITMP2, iptr->val.i);
2392 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2394 M_BNEZ(REG_ITMP1, 0);
2396 codegen_addreference(m, BlockPtrOfPC(iptr->op1), mcodeptr);
2399 case ICMD_IFLE: /* ..., value ==> ... */
2400 /* op1 = target JavaVM pc, val.i = constant */
2402 var_to_reg_int(s1, src, REG_ITMP1);
2403 if (iptr->val.i == 0) {
2407 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2408 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2411 ICONST(REG_ITMP2, iptr->val.i);
2412 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2414 M_BNEZ(REG_ITMP1, 0);
2416 codegen_addreference(m, BlockPtrOfPC(iptr->op1), mcodeptr);
2419 case ICMD_IFNE: /* ..., value ==> ... */
2420 /* op1 = target JavaVM pc, val.i = constant */
2422 var_to_reg_int(s1, src, REG_ITMP1);
2423 if (iptr->val.i == 0) {
2427 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2428 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2431 ICONST(REG_ITMP2, iptr->val.i);
2432 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2434 M_BEQZ(REG_ITMP1, 0);
2436 codegen_addreference(m, BlockPtrOfPC(iptr->op1), mcodeptr);
2439 case ICMD_IFGT: /* ..., value ==> ... */
2440 /* op1 = target JavaVM pc, val.i = constant */
2442 var_to_reg_int(s1, src, REG_ITMP1);
2443 if (iptr->val.i == 0) {
2447 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2448 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2451 ICONST(REG_ITMP2, iptr->val.i);
2452 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2454 M_BEQZ(REG_ITMP1, 0);
2456 codegen_addreference(m, BlockPtrOfPC(iptr->op1), mcodeptr);
2459 case ICMD_IFGE: /* ..., value ==> ... */
2460 /* op1 = target JavaVM pc, val.i = constant */
2462 var_to_reg_int(s1, src, REG_ITMP1);
2463 if (iptr->val.i == 0) {
2467 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2468 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2471 ICONST(REG_ITMP2, iptr->val.i);
2472 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2474 M_BEQZ(REG_ITMP1, 0);
2476 codegen_addreference(m, BlockPtrOfPC(iptr->op1), mcodeptr);
2479 case ICMD_IF_LEQ: /* ..., value ==> ... */
2480 /* op1 = target JavaVM pc, val.l = constant */
2482 var_to_reg_int(s1, src, REG_ITMP1);
2483 if (iptr->val.l == 0) {
2487 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2488 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2491 LCONST(REG_ITMP2, iptr->val.l);
2492 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2494 M_BNEZ(REG_ITMP1, 0);
2496 codegen_addreference(m, BlockPtrOfPC(iptr->op1), mcodeptr);
2499 case ICMD_IF_LLT: /* ..., value ==> ... */
2500 /* op1 = target JavaVM pc, val.l = constant */
2502 var_to_reg_int(s1, src, REG_ITMP1);
2503 if (iptr->val.l == 0) {
2507 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2508 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2511 LCONST(REG_ITMP2, iptr->val.l);
2512 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2514 M_BNEZ(REG_ITMP1, 0);
2516 codegen_addreference(m, BlockPtrOfPC(iptr->op1), mcodeptr);
2519 case ICMD_IF_LLE: /* ..., value ==> ... */
2520 /* op1 = target JavaVM pc, val.l = constant */
2522 var_to_reg_int(s1, src, REG_ITMP1);
2523 if (iptr->val.l == 0) {
2527 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2528 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2531 LCONST(REG_ITMP2, iptr->val.l);
2532 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2534 M_BNEZ(REG_ITMP1, 0);
2536 codegen_addreference(m, BlockPtrOfPC(iptr->op1), mcodeptr);
2539 case ICMD_IF_LNE: /* ..., value ==> ... */
2540 /* op1 = target JavaVM pc, val.l = constant */
2542 var_to_reg_int(s1, src, REG_ITMP1);
2543 if (iptr->val.l == 0) {
2547 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2548 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2551 LCONST(REG_ITMP2, iptr->val.l);
2552 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2554 M_BEQZ(REG_ITMP1, 0);
2556 codegen_addreference(m, BlockPtrOfPC(iptr->op1), mcodeptr);
2559 case ICMD_IF_LGT: /* ..., value ==> ... */
2560 /* op1 = target JavaVM pc, val.l = constant */
2562 var_to_reg_int(s1, src, REG_ITMP1);
2563 if (iptr->val.l == 0) {
2567 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2568 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2571 LCONST(REG_ITMP2, iptr->val.l);
2572 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2574 M_BEQZ(REG_ITMP1, 0);
2576 codegen_addreference(m, BlockPtrOfPC(iptr->op1), mcodeptr);
2579 case ICMD_IF_LGE: /* ..., value ==> ... */
2580 /* op1 = target JavaVM pc, val.l = constant */
2582 var_to_reg_int(s1, src, REG_ITMP1);
2583 if (iptr->val.l == 0) {
2587 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2588 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2591 LCONST(REG_ITMP2, iptr->val.l);
2592 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2594 M_BEQZ(REG_ITMP1, 0);
2596 codegen_addreference(m, BlockPtrOfPC(iptr->op1), mcodeptr);
2599 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2600 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2601 case ICMD_IF_ACMPEQ:
2603 var_to_reg_int(s1, src->prev, REG_ITMP1);
2604 var_to_reg_int(s2, src, REG_ITMP2);
2605 M_CMPEQ(s1, s2, REG_ITMP1);
2606 M_BNEZ(REG_ITMP1, 0);
2607 codegen_addreference(m, BlockPtrOfPC(iptr->op1), mcodeptr);
2610 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2611 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2612 case ICMD_IF_ACMPNE:
2614 var_to_reg_int(s1, src->prev, REG_ITMP1);
2615 var_to_reg_int(s2, src, REG_ITMP2);
2616 M_CMPEQ(s1, s2, REG_ITMP1);
2617 M_BEQZ(REG_ITMP1, 0);
2618 codegen_addreference(m, BlockPtrOfPC(iptr->op1), mcodeptr);
2621 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2622 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2624 var_to_reg_int(s1, src->prev, REG_ITMP1);
2625 var_to_reg_int(s2, src, REG_ITMP2);
2626 M_CMPLT(s1, s2, REG_ITMP1);
2627 M_BNEZ(REG_ITMP1, 0);
2628 codegen_addreference(m, BlockPtrOfPC(iptr->op1), mcodeptr);
2631 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2632 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2634 var_to_reg_int(s1, src->prev, REG_ITMP1);
2635 var_to_reg_int(s2, src, REG_ITMP2);
2636 M_CMPLE(s1, s2, REG_ITMP1);
2637 M_BEQZ(REG_ITMP1, 0);
2638 codegen_addreference(m, BlockPtrOfPC(iptr->op1), mcodeptr);
2641 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2642 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2644 var_to_reg_int(s1, src->prev, REG_ITMP1);
2645 var_to_reg_int(s2, src, REG_ITMP2);
2646 M_CMPLE(s1, s2, REG_ITMP1);
2647 M_BNEZ(REG_ITMP1, 0);
2648 codegen_addreference(m, BlockPtrOfPC(iptr->op1), mcodeptr);
2651 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2652 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2654 var_to_reg_int(s1, src->prev, REG_ITMP1);
2655 var_to_reg_int(s2, src, REG_ITMP2);
2656 M_CMPLT(s1, s2, REG_ITMP1);
2657 M_BEQZ(REG_ITMP1, 0);
2658 codegen_addreference(m, BlockPtrOfPC(iptr->op1), mcodeptr);
2661 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2663 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2666 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2667 /* val.i = constant */
2669 var_to_reg_int(s1, src, REG_ITMP1);
2670 d = reg_of_var(m, iptr->dst, REG_ITMP3);
2672 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2673 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2674 M_CMPEQ(s1, REG_ZERO, d);
2675 store_reg_to_var_int(iptr->dst, d);
2678 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2679 M_CMPEQ(s1, REG_ZERO, d);
2681 store_reg_to_var_int(iptr->dst, d);
2685 M_MOV(s1, REG_ITMP1);
2688 ICONST(d, iptr[1].val.i);
2690 if ((s3 >= 0) && (s3 <= 255)) {
2691 M_CMOVEQ_IMM(s1, s3, d);
2694 ICONST(REG_ITMP2, s3);
2695 M_CMOVEQ(s1, REG_ITMP2, d);
2697 store_reg_to_var_int(iptr->dst, d);
2700 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2701 /* val.i = constant */
2703 var_to_reg_int(s1, src, REG_ITMP1);
2704 d = reg_of_var(m, iptr->dst, REG_ITMP3);
2706 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2707 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2708 M_CMPEQ(s1, REG_ZERO, d);
2709 store_reg_to_var_int(iptr->dst, d);
2712 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2713 M_CMPEQ(s1, REG_ZERO, d);
2715 store_reg_to_var_int(iptr->dst, d);
2719 M_MOV(s1, REG_ITMP1);
2722 ICONST(d, iptr[1].val.i);
2724 if ((s3 >= 0) && (s3 <= 255)) {
2725 M_CMOVNE_IMM(s1, s3, d);
2728 ICONST(REG_ITMP2, s3);
2729 M_CMOVNE(s1, REG_ITMP2, d);
2731 store_reg_to_var_int(iptr->dst, d);
2734 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2735 /* val.i = constant */
2737 var_to_reg_int(s1, src, REG_ITMP1);
2738 d = reg_of_var(m, iptr->dst, REG_ITMP3);
2740 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2741 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2742 M_CMPLT(s1, REG_ZERO, d);
2743 store_reg_to_var_int(iptr->dst, d);
2746 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2747 M_CMPLE(REG_ZERO, s1, d);
2748 store_reg_to_var_int(iptr->dst, d);
2752 M_MOV(s1, REG_ITMP1);
2755 ICONST(d, iptr[1].val.i);
2757 if ((s3 >= 0) && (s3 <= 255)) {
2758 M_CMOVLT_IMM(s1, s3, d);
2761 ICONST(REG_ITMP2, s3);
2762 M_CMOVLT(s1, REG_ITMP2, d);
2764 store_reg_to_var_int(iptr->dst, d);
2767 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2768 /* val.i = constant */
2770 var_to_reg_int(s1, src, REG_ITMP1);
2771 d = reg_of_var(m, iptr->dst, REG_ITMP3);
2773 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2774 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2775 M_CMPLE(REG_ZERO, s1, d);
2776 store_reg_to_var_int(iptr->dst, d);
2779 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2780 M_CMPLT(s1, REG_ZERO, d);
2781 store_reg_to_var_int(iptr->dst, d);
2785 M_MOV(s1, REG_ITMP1);
2788 ICONST(d, iptr[1].val.i);
2790 if ((s3 >= 0) && (s3 <= 255)) {
2791 M_CMOVGE_IMM(s1, s3, d);
2794 ICONST(REG_ITMP2, s3);
2795 M_CMOVGE(s1, REG_ITMP2, d);
2797 store_reg_to_var_int(iptr->dst, d);
2800 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2801 /* val.i = constant */
2803 var_to_reg_int(s1, src, REG_ITMP1);
2804 d = reg_of_var(m, iptr->dst, REG_ITMP3);
2806 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2807 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2808 M_CMPLT(REG_ZERO, s1, d);
2809 store_reg_to_var_int(iptr->dst, d);
2812 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2813 M_CMPLE(s1, REG_ZERO, d);
2814 store_reg_to_var_int(iptr->dst, d);
2818 M_MOV(s1, REG_ITMP1);
2821 ICONST(d, iptr[1].val.i);
2823 if ((s3 >= 0) && (s3 <= 255)) {
2824 M_CMOVGT_IMM(s1, s3, d);
2827 ICONST(REG_ITMP2, s3);
2828 M_CMOVGT(s1, REG_ITMP2, d);
2830 store_reg_to_var_int(iptr->dst, d);
2833 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2834 /* val.i = constant */
2836 var_to_reg_int(s1, src, REG_ITMP1);
2837 d = reg_of_var(m, iptr->dst, REG_ITMP3);
2839 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2840 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2841 M_CMPLE(s1, REG_ZERO, d);
2842 store_reg_to_var_int(iptr->dst, d);
2845 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2846 M_CMPLT(REG_ZERO, s1, d);
2847 store_reg_to_var_int(iptr->dst, d);
2851 M_MOV(s1, REG_ITMP1);
2854 ICONST(d, iptr[1].val.i);
2856 if ((s3 >= 0) && (s3 <= 255)) {
2857 M_CMOVLE_IMM(s1, s3, d);
2860 ICONST(REG_ITMP2, s3);
2861 M_CMOVLE(s1, REG_ITMP2, d);
2863 store_reg_to_var_int(iptr->dst, d);
2867 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2871 var_to_reg_int(s1, src, REG_RESULT);
2872 M_INTMOVE(s1, REG_RESULT);
2874 #if defined(USE_THREADS)
2875 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2877 a = dseg_addaddress(m, (void *) (builtin_monitorexit));
2878 M_ALD(REG_PV, REG_PV, a);
2879 M_ALD(r->argintregs[0], REG_SP, r->maxmemuse * 8);
2880 M_LST(REG_RESULT, REG_SP, r->maxmemuse * 8);
2881 M_JSR(REG_RA, REG_PV);
2882 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
2883 M_LDA(REG_PV, REG_RA, disp);
2884 M_LLD(REG_RESULT, REG_SP, r->maxmemuse * 8);
2888 goto nowperformreturn;
2890 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2893 var_to_reg_flt(s1, src, REG_FRESULT);
2894 M_FLTMOVE(s1, REG_FRESULT);
2896 #if defined(USE_THREADS)
2897 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2899 a = dseg_addaddress(m, (void *) (builtin_monitorexit));
2900 M_ALD(REG_PV, REG_PV, a);
2901 M_ALD(r->argintregs[0], REG_SP, r->maxmemuse * 8);
2902 M_DST(REG_FRESULT, REG_SP, r->maxmemuse * 8);
2903 M_JSR(REG_RA, REG_PV);
2904 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
2905 M_LDA(REG_PV, REG_RA, disp);
2906 M_DLD(REG_FRESULT, REG_SP, r->maxmemuse * 8);
2910 goto nowperformreturn;
2912 case ICMD_RETURN: /* ... ==> ... */
2914 #if defined(USE_THREADS)
2915 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2917 a = dseg_addaddress(m, (void *) (builtin_monitorexit));
2918 M_ALD(REG_PV, REG_PV, a);
2919 M_ALD(r->argintregs[0], REG_SP, r->maxmemuse * 8);
2920 M_JSR(REG_RA, REG_PV);
2921 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
2922 M_LDA(REG_PV, REG_RA, disp);
2930 p = parentargs_base;
2932 /* restore return address */
2934 if (!m->isleafmethod) {
2935 p--; M_LLD(REG_RA, REG_SP, p * 8);
2938 /* restore saved registers */
2940 for (i = r->savintregcnt - 1; i >= r->maxsavintreguse; i--) {
2941 p--; M_LLD(r->savintregs[i], REG_SP, p * 8);
2943 for (i = r->savfltregcnt - 1; i >= r->maxsavfltreguse; i--) {
2944 p--; M_DLD(r->savfltregs[i], REG_SP, p * 8);
2947 /* deallocate stack */
2949 if (parentargs_base) {
2950 M_LDA(REG_SP, REG_SP, parentargs_base * 8);
2953 /* call trace function */
2956 M_LDA(REG_SP, REG_SP, -3 * 8);
2957 M_AST(REG_RA, REG_SP, 0 * 8);
2958 M_LST(REG_RESULT, REG_SP, 1 * 8);
2959 M_DST(REG_FRESULT, REG_SP, 2 * 8);
2960 a = dseg_addaddress(m, m);
2961 M_ALD(r->argintregs[0], REG_PV, a);
2962 M_MOV(REG_RESULT, r->argintregs[1]);
2963 M_FLTMOVE(REG_FRESULT, r->argfltregs[2]);
2964 M_FLTMOVE(REG_FRESULT, r->argfltregs[3]);
2965 a = dseg_addaddress(m, (void *) builtin_displaymethodstop);
2966 M_ALD(REG_PV, REG_PV, a);
2967 M_JSR(REG_RA, REG_PV);
2968 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
2969 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
2971 s4 ml = -s1, mh = 0;
2972 while (ml < -32768) { ml += 65536; mh--; }
2973 M_LDA(REG_PV, REG_RA, ml);
2974 M_LDAH(REG_PV, REG_PV, mh);
2976 M_DLD(REG_FRESULT, REG_SP, 2 * 8);
2977 M_LLD(REG_RESULT, REG_SP, 1 * 8);
2978 M_ALD(REG_RA, REG_SP, 0 * 8);
2979 M_LDA(REG_SP, REG_SP, 3 * 8);
2982 M_RET(REG_ZERO, REG_RA);
2988 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2993 tptr = (void **) iptr->target;
2995 s4ptr = iptr->val.a;
2996 l = s4ptr[1]; /* low */
2997 i = s4ptr[2]; /* high */
2999 var_to_reg_int(s1, src, REG_ITMP1);
3001 {M_INTMOVE(s1, REG_ITMP1);}
3002 else if (l <= 32768) {
3003 M_LDA(REG_ITMP1, s1, -l);
3006 ICONST(REG_ITMP2, l);
3007 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
3014 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
3016 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
3017 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3019 M_BEQZ(REG_ITMP2, 0);
3022 /* codegen_addreference(m, BlockPtrOfPC(s4ptr[0]), mcodeptr); */
3023 codegen_addreference(m, (basicblock *) tptr[0], mcodeptr);
3025 /* build jump table top down and use address of lowest entry */
3027 /* s4ptr += 3 + i; */
3031 /* dseg_addtarget(m, BlockPtrOfPC(*--s4ptr)); */
3032 dseg_addtarget(m, (basicblock *) tptr[0]);
3037 /* length of dataseg after last dseg_addtarget is used by load */
3039 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
3040 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
3041 M_JMP(REG_ZERO, REG_ITMP2);
3046 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3048 s4 i, l, val, *s4ptr;
3051 tptr = (void **) iptr->target;
3053 s4ptr = iptr->val.a;
3054 l = s4ptr[0]; /* default */
3055 i = s4ptr[1]; /* count */
3057 MCODECHECK((i<<2)+8);
3058 var_to_reg_int(s1, src, REG_ITMP1);
3064 if ((val >= 0) && (val <= 255)) {
3065 M_CMPEQ_IMM(s1, val, REG_ITMP2);
3068 if ((val >= -32768) && (val <= 32767)) {
3069 M_LDA(REG_ITMP2, REG_ZERO, val);
3072 a = dseg_adds4(m, val);
3073 M_ILD(REG_ITMP2, REG_PV, a);
3075 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
3077 M_BNEZ(REG_ITMP2, 0);
3078 /* codegen_addreference(m, BlockPtrOfPC(s4ptr[1]), mcodeptr); */
3079 codegen_addreference(m, (basicblock *) tptr[0], mcodeptr);
3083 /* codegen_addreference(m, BlockPtrOfPC(l), mcodeptr); */
3085 tptr = (void **) iptr->target;
3086 codegen_addreference(m, (basicblock *) tptr[0], mcodeptr);
3093 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
3094 /* op1 = return type, val.a = function pointer*/
3098 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
3099 /* op1 = return type, val.a = function pointer*/
3103 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
3104 /* op1 = return type, val.a = function pointer*/
3108 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3109 /* op1 = arg count, val.a = method pointer */
3111 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3112 /* op1 = arg count, val.a = method pointer */
3114 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3115 /* op1 = arg count, val.a = method pointer */
3117 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
3118 /* op1 = arg count, val.a = method pointer */
3125 MCODECHECK((s3 << 1) + 64);
3127 /* copy arguments to registers or stack location */
3129 for (; --s3 >= 0; src = src->prev) {
3130 if (src->varkind == ARGVAR)
3132 if (IS_INT_LNG_TYPE(src->type)) {
3133 if (s3 < INT_ARG_CNT) {
3134 s1 = r->argintregs[s3];
3135 var_to_reg_int(d, src, s1);
3139 var_to_reg_int(d, src, REG_ITMP1);
3140 M_LST(d, REG_SP, 8 * (s3 - INT_ARG_CNT));
3144 if (s3 < FLT_ARG_CNT) {
3145 s1 = r->argfltregs[s3];
3146 var_to_reg_flt(d, src, s1);
3150 var_to_reg_flt(d, src, REG_FTMP1);
3151 M_DST(d, REG_SP, 8 * (s3 - FLT_ARG_CNT));
3157 switch (iptr->opc) {
3161 a = dseg_addaddress(m, (void *) lm);
3164 M_ALD(REG_PV, REG_PV, a); /* Pointer to built-in-function */
3167 case ICMD_INVOKESTATIC:
3168 case ICMD_INVOKESPECIAL:
3169 a = dseg_addaddress(m, lm->stubroutine);
3172 M_ALD(REG_PV, REG_PV, a); /* method pointer in r27 */
3175 case ICMD_INVOKEVIRTUAL:
3178 gen_nullptr_check(r->argintregs[0]);
3179 M_ALD(REG_METHODPTR, r->argintregs[0],
3180 OFFSET(java_objectheader, vftbl));
3181 M_ALD(REG_PV, REG_METHODPTR, OFFSET(vftbl_t, table[0]) +
3182 sizeof(methodptr) * lm->vftblindex);
3185 case ICMD_INVOKEINTERFACE:
3188 gen_nullptr_check(r->argintregs[0]);
3189 M_ALD(REG_METHODPTR, r->argintregs[0],
3190 OFFSET(java_objectheader, vftbl));
3191 M_ALD(REG_METHODPTR, REG_METHODPTR,
3192 OFFSET(vftbl_t, interfacetable[0]) -
3193 sizeof(methodptr*) * lm->class->index);
3194 M_ALD(REG_PV, REG_METHODPTR,
3195 sizeof(methodptr) * (lm - lm->class->methods));
3199 M_JSR(REG_RA, REG_PV);
3203 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3204 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3206 s4 ml = -s1, mh = 0;
3207 while (ml < -32768) { ml += 65536; mh--; }
3208 M_LDA(REG_PV, REG_RA, ml);
3209 M_LDAH(REG_PV, REG_PV, mh);
3212 /* d contains return type */
3214 if (d != TYPE_VOID) {
3215 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3216 s1 = reg_of_var(m, iptr->dst, REG_RESULT);
3217 M_INTMOVE(REG_RESULT, s1);
3218 store_reg_to_var_int(iptr->dst, s1);
3221 s1 = reg_of_var(m, iptr->dst, REG_FRESULT);
3222 M_FLTMOVE(REG_FRESULT, s1);
3223 store_reg_to_var_flt(iptr->dst, s1);
3230 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3232 /* op1: 0 == array, 1 == class */
3233 /* val.a: (classinfo*) superclass */
3235 /* superclass is an interface:
3237 * return (sub != NULL) &&
3238 * (sub->vftbl->interfacetablelength > super->index) &&
3239 * (sub->vftbl->interfacetable[-super->index] != NULL);
3241 * superclass is a class:
3243 * return ((sub != NULL) && (0
3244 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3245 * super->vftbl->diffvall));
3249 classinfo *super = (classinfo*) iptr->val.a;
3251 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3252 codegen_threadcritrestart(m, (u1 *) mcodeptr - cd->mcodebase);
3254 var_to_reg_int(s1, src, REG_ITMP1);
3255 d = reg_of_var(m, iptr->dst, REG_ITMP3);
3257 M_MOV(s1, REG_ITMP1);
3261 if (iptr->op1) { /* class/interface */
3262 if (super->flags & ACC_INTERFACE) { /* interface */
3264 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3265 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3266 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3267 M_BLEZ(REG_ITMP2, 2);
3268 M_ALD(REG_ITMP1, REG_ITMP1,
3269 OFFSET(vftbl_t, interfacetable[0]) -
3270 super->index * sizeof(methodptr*));
3271 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3275 s2 = super->vftbl->diffval;
3276 M_BEQZ(s1, 4 + (s2 > 255));
3277 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3278 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3279 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3281 M_CMPULE_IMM(REG_ITMP1, s2, d);
3283 M_LDA(REG_ITMP2, REG_ZERO, s2);
3284 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3288 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3289 a = dseg_addaddress(m, (void*) super->vftbl);
3290 M_ALD(REG_ITMP2, REG_PV, a);
3291 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3292 codegen_threadcritstart(m, (u1 *) mcodeptr - cd->mcodebase);
3294 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3295 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3296 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3297 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3298 codegen_threadcritstop(m, (u1 *) mcodeptr - cd->mcodebase);
3300 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3301 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3305 panic ("internal error: no inlined array instanceof");
3307 store_reg_to_var_int(iptr->dst, d);
3310 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3312 /* op1: 0 == array, 1 == class */
3313 /* val.a: (classinfo*) superclass */
3315 /* superclass is an interface:
3317 * OK if ((sub == NULL) ||
3318 * (sub->vftbl->interfacetablelength > super->index) &&
3319 * (sub->vftbl->interfacetable[-super->index] != NULL));
3321 * superclass is a class:
3323 * OK if ((sub == NULL) || (0
3324 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3325 * super->vftbl->diffvall));
3329 classinfo *super = (classinfo *) iptr->val.a;
3331 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3332 codegen_threadcritrestart(m, (u1 *) mcodeptr - cd->mcodebase);
3334 d = reg_of_var(m, iptr->dst, REG_ITMP3);
3335 var_to_reg_int(s1, src, d);
3336 if (iptr->op1) { /* class/interface */
3337 if (super->flags & ACC_INTERFACE) { /* interface */
3339 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3340 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3341 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3342 M_BLEZ(REG_ITMP2, 0);
3343 codegen_addxcastrefs(m, mcodeptr);
3344 M_ALD(REG_ITMP2, REG_ITMP1,
3345 OFFSET(vftbl_t, interfacetable[0]) -
3346 super->index * sizeof(methodptr*));
3347 M_BEQZ(REG_ITMP2, 0);
3348 codegen_addxcastrefs(m, mcodeptr);
3352 s2 = super->vftbl->diffval;
3353 M_BEQZ(s1, 4 + (s2 != 0) + (s2 > 255));
3354 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3355 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3356 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3358 M_BNEZ(REG_ITMP1, 0);
3360 else if (s2 <= 255) {
3361 M_CMPULE_IMM(REG_ITMP1, s2, REG_ITMP2);
3362 M_BEQZ(REG_ITMP2, 0);
3365 M_LDA(REG_ITMP2, REG_ZERO, s2);
3366 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3367 M_BEQZ(REG_ITMP2, 0);
3370 M_BEQZ(s1, 8 + (d == REG_ITMP3));
3371 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3372 a = dseg_addaddress(m, (void *) super->vftbl);
3373 M_ALD(REG_ITMP2, REG_PV, a);
3374 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3375 codegen_threadcritstart(m, (u1 *) mcodeptr - cd->mcodebase);
3377 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3378 if (d != REG_ITMP3) {
3379 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3380 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3381 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3382 codegen_threadcritstop(m, (u1 *) mcodeptr - cd->mcodebase);
3384 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3387 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3388 M_ISUB(REG_ITMP1, REG_ITMP2, REG_ITMP1);
3389 M_ALD(REG_ITMP2, REG_PV, a);
3390 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3391 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3392 codegen_threadcritstop(m, (u1 *) mcodeptr - cd->mcodebase);
3395 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3396 M_BEQZ(REG_ITMP2, 0);
3397 codegen_addxcastrefs(m, mcodeptr);
3401 panic ("internal error: no inlined array checkcast");
3404 store_reg_to_var_int(iptr->dst, d);
3407 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
3409 var_to_reg_int(s1, src, REG_ITMP1);
3411 codegen_addxcheckarefs(m, mcodeptr);
3414 case ICMD_CHECKEXCEPTION: /* ... ==> ... */
3416 M_BEQZ(REG_RESULT, 0);
3417 codegen_addxexceptionrefs(m, mcodeptr);
3420 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3421 /* op1 = dimension, val.a = array descriptor */
3423 /* check for negative sizes and copy sizes to stack if necessary */
3425 MCODECHECK((iptr->op1 << 1) + 64);
3427 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3428 var_to_reg_int(s2, src, REG_ITMP1);
3430 codegen_addxcheckarefs(m, mcodeptr);
3432 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
3434 if (src->varkind != ARGVAR) {
3435 M_LST(s2, REG_SP, 8 * (s1 + INT_ARG_CNT));
3439 /* a0 = dimension count */
3441 ICONST(r->argintregs[0], iptr->op1);
3443 /* a1 = arraydescriptor */
3445 a = dseg_addaddress(m, iptr->val.a);
3446 M_ALD(r->argintregs[1], REG_PV, a);
3448 /* a2 = pointer to dimensions = stack pointer */
3450 M_INTMOVE(REG_SP, r->argintregs[2]);
3452 a = dseg_addaddress(m, (void *) builtin_nmultianewarray);
3453 M_ALD(REG_PV, REG_PV, a);
3454 M_JSR(REG_RA, REG_PV);
3455 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3457 M_LDA(REG_PV, REG_RA, -s1);
3459 s4 ml = -s1, mh = 0;
3460 while (ml < -32768) { ml += 65536; mh--; }
3461 M_LDA(REG_PV, REG_RA, ml);
3462 M_LDAH(REG_PV, REG_PV, mh);
3464 s1 = reg_of_var(m, iptr->dst, REG_RESULT);
3465 M_INTMOVE(REG_RESULT, s1);
3466 store_reg_to_var_int(iptr->dst, s1);
3470 default: error ("Unknown pseudo command: %d", iptr->opc);
3476 } /* for instruction */
3478 /* copy values to interface registers */
3480 src = bptr->outstack;
3481 len = bptr->outdepth;
3485 if ((src->varkind != STACKVAR)) {
3487 if (IS_FLT_DBL_TYPE(s2)) {
3488 var_to_reg_flt(s1, src, REG_FTMP1);
3489 if (!(r->interfaces[len][s2].flags & INMEMORY)) {
3490 M_FLTMOVE(s1,r->interfaces[len][s2].regoff);
3493 M_DST(s1, REG_SP, 8 * r->interfaces[len][s2].regoff);
3497 var_to_reg_int(s1, src, REG_ITMP1);
3498 if (!(r->interfaces[len][s2].flags & INMEMORY)) {
3499 M_INTMOVE(s1,r->interfaces[len][s2].regoff);
3502 M_LST(s1, REG_SP, 8 * r->interfaces[len][s2].regoff);
3508 } /* if (bptr -> flags >= BBREACHED) */
3509 } /* for basic block */
3512 /* generate bound check stubs */
3514 s4 *xcodeptr = NULL;
3517 for (bref = cd->xboundrefs; bref != NULL; bref = bref->next) {
3518 gen_resolvebranch((u1*) cd->mcodebase + bref->branchpos,
3520 (u1*) mcodeptr - cd->mcodebase);
3524 /* move index register into REG_ITMP1 */
3525 M_MOV(bref->reg, REG_ITMP1);
3526 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3528 if (xcodeptr != NULL) {
3529 M_BR(xcodeptr - mcodeptr - 1);
3532 xcodeptr = mcodeptr;
3534 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3535 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3537 a = dseg_addaddress(m, string_java_lang_ArrayIndexOutOfBoundsException);
3538 M_ALD(r->argintregs[0], REG_PV, a);
3539 M_MOV(REG_ITMP1, r->argintregs[1]);
3541 a = dseg_addaddress(m, new_exception_int);
3542 M_ALD(REG_PV, REG_PV, a);
3543 M_JSR(REG_RA, REG_PV);
3546 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3547 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3549 s4 ml = -s1, mh = 0;
3550 while (ml < -32768) { ml += 65536; mh--; }
3551 M_LDA(REG_PV, REG_RA, ml);
3552 M_LDAH(REG_PV, REG_PV, mh);
3555 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3557 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3558 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3560 a = dseg_addaddress(m, asm_handle_exception);
3561 M_ALD(REG_ITMP3, REG_PV, a);
3563 M_JMP(REG_ZERO, REG_ITMP3);
3567 /* generate negative array size check stubs */
3571 for (bref = cd->xcheckarefs; bref != NULL; bref = bref->next) {
3572 if ((m->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3573 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3575 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3579 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3581 (u1 *) mcodeptr - cd->mcodebase);
3585 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3587 if (xcodeptr != NULL) {
3588 M_BR(xcodeptr - mcodeptr - 1);
3591 xcodeptr = mcodeptr;
3593 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3594 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3596 a = dseg_addaddress(m, string_java_lang_NegativeArraySizeException);
3597 M_ALD(r->argintregs[0], REG_PV, a);
3599 a = dseg_addaddress(m, new_exception);
3600 M_ALD(REG_PV, REG_PV, a);
3601 M_JSR(REG_RA, REG_PV);
3604 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3605 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3607 s4 ml = -s1, mh = 0;
3608 while (ml < -32768) { ml += 65536; mh--; }
3609 M_LDA(REG_PV, REG_RA, ml);
3610 M_LDAH(REG_PV, REG_PV, mh);
3613 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3615 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3616 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3618 a = dseg_addaddress(m, asm_handle_exception);
3619 M_ALD(REG_ITMP3, REG_PV, a);
3621 M_JMP(REG_ZERO, REG_ITMP3);
3625 /* generate cast check stubs */
3629 for (bref = cd->xcastrefs; bref != NULL; bref = bref->next) {
3630 if ((m->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3631 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3633 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3637 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3639 (u1 *) mcodeptr - cd->mcodebase);
3643 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3645 if (xcodeptr != NULL) {
3646 M_BR(xcodeptr - mcodeptr - 1);
3649 xcodeptr = mcodeptr;
3651 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3652 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3654 a = dseg_addaddress(m, string_java_lang_ClassCastException);
3655 M_ALD(r->argintregs[0], REG_PV, a);
3657 a = dseg_addaddress(m, new_exception);
3658 M_ALD(REG_PV, REG_PV, a);
3659 M_JSR(REG_RA, REG_PV);
3662 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3663 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3665 s4 ml = -s1, mh = 0;
3666 while (ml < -32768) { ml += 65536; mh--; }
3667 M_LDA(REG_PV, REG_RA, ml);
3668 M_LDAH(REG_PV, REG_PV, mh);
3671 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3673 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3674 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3676 a = dseg_addaddress(m, asm_handle_exception);
3677 M_ALD(REG_ITMP3, REG_PV, a);
3679 M_JMP(REG_ZERO, REG_ITMP3);
3683 /* generate exception check stubs */
3687 for (bref = cd->xexceptionrefs; bref != NULL; bref = bref->next) {
3688 if ((m->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3689 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3691 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3695 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3697 (u1 *) mcodeptr - cd->mcodebase);
3701 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3703 if (xcodeptr != NULL) {
3704 M_BR(xcodeptr - mcodeptr - 1);
3707 xcodeptr = mcodeptr;
3709 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3710 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3711 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3713 a = dseg_addaddress(m, &builtin_get_exceptionptrptr);
3714 M_ALD(REG_PV, REG_PV, a);
3715 M_JSR(REG_RA, REG_PV);
3718 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3719 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3721 s4 ml = -s1, mh = 0;
3722 while (ml < -32768) { ml += 65536; mh--; }
3723 M_LDA(REG_PV, REG_RA, ml);
3724 M_LDAH(REG_PV, REG_PV, mh);
3727 M_ALD(REG_ITMP1_XPTR, REG_RESULT, 0);
3728 M_AST(REG_ZERO, REG_RESULT, 0);
3730 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3731 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3733 a = dseg_addaddress(m, &_exceptionptr);
3734 M_ALD(REG_ITMP3, REG_PV, a);
3735 M_ALD(REG_ITMP1_XPTR, REG_ITMP3, 0);
3736 M_AST(REG_ZERO, REG_ITMP3, 0);
3739 a = dseg_addaddress(m, asm_handle_exception);
3740 M_ALD(REG_ITMP3, REG_PV, a);
3742 M_JMP(REG_ZERO, REG_ITMP3);
3746 /* generate null pointer check stubs */
3750 for (bref = cd->xnullrefs; bref != NULL; bref = bref->next) {
3751 if ((m->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3752 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3754 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3758 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3760 (u1 *) mcodeptr - cd->mcodebase);
3764 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3766 if (xcodeptr != NULL) {
3767 M_BR(xcodeptr - mcodeptr - 1);
3770 xcodeptr = mcodeptr;
3772 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3773 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3775 a = dseg_addaddress(m, string_java_lang_NullPointerException);
3776 M_ALD(r->argintregs[0], REG_PV, a);
3778 a = dseg_addaddress(m, new_exception);
3779 M_ALD(REG_PV, REG_PV, a);
3780 M_JSR(REG_RA, REG_PV);
3783 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3784 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3786 s4 ml = -s1, mh = 0;
3787 while (ml < -32768) { ml += 65536; mh--; }
3788 M_LDA(REG_PV, REG_RA, ml);
3789 M_LDAH(REG_PV, REG_PV, mh);
3792 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3794 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3795 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3797 a = dseg_addaddress(m, asm_handle_exception);
3798 M_ALD(REG_ITMP3, REG_PV, a);
3800 M_JMP(REG_ZERO, REG_ITMP3);
3805 codegen_finish(m, (s4) ((u1 *) mcodeptr - cd->mcodebase));
3809 /* function createcompilerstub *************************************************
3811 creates a stub routine which calls the compiler
3813 *******************************************************************************/
3815 #define COMPSTUBSIZE 3
3817 u1 *createcompilerstub(methodinfo *m)
3819 u8 *s = CNEW(u8, COMPSTUBSIZE); /* memory to hold the stub */
3820 s4 *mcodeptr = (s4 *) s; /* code generation pointer */
3822 /* code for the stub */
3823 M_ALD(REG_PV, REG_PV, 16); /* load pointer to the compiler */
3824 M_JMP(0, REG_PV); /* jump to the compiler, return address
3825 in reg 0 is used as method pointer */
3826 s[1] = (u8) m; /* literals to be adressed */
3827 s[2] = (u8) asm_call_jit_compiler; /* jump directly via PV from above */
3829 #if defined(STATISTICS)
3831 count_cstub_len += COMPSTUBSIZE * 8;
3838 /* function removecompilerstub *************************************************
3840 deletes a compilerstub from memory (simply by freeing it)
3842 *******************************************************************************/
3844 void removecompilerstub(u1 *stub)
3846 CFREE(stub, COMPSTUBSIZE * 8);
3850 /* function: createnativestub **************************************************
3852 creates a stub routine which calls a native method
3854 *******************************************************************************/
3856 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3857 #define NATIVESTUBSTACK 2
3858 #define NATIVESTUBTHREADEXTRA 6
3860 #define NATIVESTUBSTACK 1
3861 #define NATIVESTUBTHREADEXTRA 1
3864 #define NATIVESTUBSIZE (44 + NATIVESTUBTHREADEXTRA - 1)
3865 #define NATIVESTATICSIZE 5
3866 #define NATIVEVERBOSESIZE (39 + 13)
3867 #define NATIVESTUBOFFSET 9
3869 u1 *createnativestub(functionptr f, methodinfo *m)
3871 u8 *s; /* memory pointer to hold the stub */
3873 s4 *mcodeptr; /* code generation pointer */
3874 s4 stackframesize = 0; /* size of stackframe if needed */
3879 /* keep code size smaller */
3881 r = m->registerdata;
3883 descriptor2types(m); /* set paramcount and paramtypes */
3885 stubsize = NATIVESTUBSIZE; /* calculate nativestub size */
3886 if ((m->flags & ACC_STATIC) && !m->class->initialized)
3887 stubsize += NATIVESTATICSIZE;
3890 stubsize += NATIVEVERBOSESIZE;
3892 s = CNEW(u8, stubsize); /* memory to hold the stub */
3893 cs = s + NATIVESTUBOFFSET;
3894 mcodeptr = (s4 *) (cs); /* code generation pointer */
3896 *(cs-1) = (u8) f; /* address of native method */
3897 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3898 *(cs-2) = (u8) &builtin_get_exceptionptrptr;
3900 *(cs-2) = (u8) (&_exceptionptr); /* address of exceptionptr */
3902 *(cs-3) = (u8) asm_handle_nat_exception; /* addr of asm exception handler */
3903 *(cs-4) = (u8) (&env); /* addr of jni_environement */
3904 *(cs-5) = (u8) builtin_trace_args;
3906 *(cs-7) = (u8) builtin_displaymethodstop;
3907 *(cs-8) = (u8) m->class;
3908 *(cs-9) = (u8) asm_check_clinit;
3910 M_LDA(REG_SP, REG_SP, -NATIVESTUBSTACK * 8); /* build up stackframe */
3911 M_AST(REG_RA, REG_SP, 0 * 8); /* store return address */
3913 /* if function is static, check for initialized */
3915 if (m->flags & ACC_STATIC) {
3916 /* if class isn't yet initialized, do it */
3917 if (!m->class->initialized) {
3918 /* call helper function which patches this code */
3919 M_ALD(REG_ITMP1, REG_PV, -8 * 8); /* class */
3920 M_ALD(REG_PV, REG_PV, -9 * 8); /* asm_check_clinit */
3921 M_JSR(REG_RA, REG_PV);
3922 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
3923 M_LDA(REG_PV, REG_RA, disp);
3924 M_NOP; /* this is essential for code patching */
3928 /* max. 39 instructions */
3932 M_LDA(REG_SP, REG_SP, -((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
3933 M_AST(REG_RA, REG_SP, 1 * 8);
3935 /* save integer argument registers */
3936 for (p = 0; p < m->paramcount && p < INT_ARG_CNT; p++) {
3937 M_LST(r->argintregs[p], REG_SP, (2 + p) * 8);
3940 /* save and copy float arguments into integer registers */
3941 for (p = 0; p < m->paramcount && p < FLT_ARG_CNT; p++) {
3942 t = m->paramtypes[p];
3944 if (IS_FLT_DBL_TYPE(t)) {
3945 if (IS_2_WORD_TYPE(t)) {
3946 M_DST(r->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
3947 M_LLD(r->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
3950 M_FST(r->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
3951 M_ILD(r->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
3955 M_DST(r->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
3959 M_ALD(REG_ITMP1, REG_PV, -6 * 8);
3960 M_AST(REG_ITMP1, REG_SP, 0 * 8);
3961 M_ALD(REG_PV, REG_PV, -5 * 8);
3962 M_JSR(REG_RA, REG_PV);
3963 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
3964 M_LDA(REG_PV, REG_RA, disp);
3966 for (p = 0; p < m->paramcount && p < INT_ARG_CNT; p++) {
3967 M_LLD(r->argintregs[p], REG_SP, (2 + p) * 8);
3970 for (p = 0; p < m->paramcount && p < FLT_ARG_CNT; p++) {
3971 t = m->paramtypes[p];
3973 if (IS_FLT_DBL_TYPE(t)) {
3974 if (IS_2_WORD_TYPE(t)) {
3975 M_DLD(r->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
3978 M_FLD(r->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
3982 M_DLD(r->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
3986 M_ALD(REG_RA, REG_SP, 1 * 8);
3987 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT + 2) * 8);
3990 /* save argument registers on stack -- if we have to */
3991 if ((m->flags & ACC_STATIC && m->paramcount > (INT_ARG_CNT - 2)) || m->paramcount > (INT_ARG_CNT - 1)) {
3993 s4 paramshiftcnt = (m->flags & ACC_STATIC) ? 2 : 1;
3994 s4 stackparamcnt = (m->paramcount > INT_ARG_CNT) ? m->paramcount - INT_ARG_CNT : 0;
3996 stackframesize = stackparamcnt + paramshiftcnt;
3998 M_LDA(REG_SP, REG_SP, -stackframesize * 8);
4000 /* copy stack arguments into new stack frame -- if any */
4001 for (i = 0; i < stackparamcnt; i++) {
4002 M_LLD(REG_ITMP1, REG_SP, (stackparamcnt + 1 + i) * 8);
4003 M_LST(REG_ITMP1, REG_SP, (paramshiftcnt + i) * 8);
4006 if (m->flags & ACC_STATIC) {
4007 if (IS_FLT_DBL_TYPE(m->paramtypes[5])) {
4008 M_DST(r->argfltregs[5], REG_SP, 1 * 8);
4010 M_LST(r->argintregs[5], REG_SP, 1 * 8);
4013 if (IS_FLT_DBL_TYPE(m->paramtypes[4])) {
4014 M_DST(r->argfltregs[4], REG_SP, 0 * 8);
4016 M_LST(r->argintregs[4], REG_SP, 0 * 8);
4020 if (IS_FLT_DBL_TYPE(m->paramtypes[5])) {
4021 M_DST(r->argfltregs[5], REG_SP, 0 * 8);
4023 M_LST(r->argintregs[5], REG_SP, 0 * 8);
4028 if (m->flags & ACC_STATIC) {
4029 M_MOV(r->argintregs[3], r->argintregs[5]);
4030 M_MOV(r->argintregs[2], r->argintregs[4]);
4031 M_MOV(r->argintregs[1], r->argintregs[3]);
4032 M_MOV(r->argintregs[0], r->argintregs[2]);
4033 M_FMOV(r->argfltregs[3], r->argfltregs[5]);
4034 M_FMOV(r->argfltregs[2], r->argfltregs[4]);
4035 M_FMOV(r->argfltregs[1], r->argfltregs[3]);
4036 M_FMOV(r->argfltregs[0], r->argfltregs[2]);
4038 /* put class into second argument register */
4039 M_ALD(r->argintregs[1], REG_PV, -8 * 8);
4042 M_MOV(r->argintregs[4], r->argintregs[5]);
4043 M_MOV(r->argintregs[3], r->argintregs[4]);
4044 M_MOV(r->argintregs[2], r->argintregs[3]);
4045 M_MOV(r->argintregs[1], r->argintregs[2]);
4046 M_MOV(r->argintregs[0], r->argintregs[1]);
4047 M_FMOV(r->argfltregs[4], r->argfltregs[5]);
4048 M_FMOV(r->argfltregs[3], r->argfltregs[4]);
4049 M_FMOV(r->argfltregs[2], r->argfltregs[3]);
4050 M_FMOV(r->argfltregs[1], r->argfltregs[2]);
4051 M_FMOV(r->argfltregs[0], r->argfltregs[1]);
4054 /* put env into first argument register */
4055 M_ALD(r->argintregs[0], REG_PV, -4 * 8);
4057 M_ALD(REG_PV, REG_PV, -1 * 8); /* load adress of native method */
4058 M_JSR(REG_RA, REG_PV); /* call native method */
4059 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4060 M_LDA(REG_PV, REG_RA, disp); /* recompute pv from ra */
4062 /* remove stackframe if there is one */
4063 if (stackframesize) {
4064 M_LDA(REG_SP, REG_SP, stackframesize * 8);
4067 /* 13 instructions */
4069 M_LDA(REG_SP, REG_SP, -2 * 8);
4070 M_ALD(r->argintregs[0], REG_PV, -6 * 8); /* load method adress */
4071 M_LST(REG_RESULT, REG_SP, 0 * 8);
4072 M_DST(REG_FRESULT, REG_SP, 1 * 8);
4073 M_MOV(REG_RESULT, r->argintregs[1]);
4074 M_FMOV(REG_FRESULT, r->argfltregs[2]);
4075 M_FMOV(REG_FRESULT, r->argfltregs[3]);
4076 M_ALD(REG_PV, REG_PV, -7 * 8); /* builtin_displaymethodstop */
4077 M_JSR(REG_RA, REG_PV);
4078 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4079 M_LDA(REG_PV, REG_RA, disp);
4080 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4081 M_DLD(REG_FRESULT, REG_SP, 1 * 8);
4082 M_LDA(REG_SP, REG_SP, 2 * 8);
4085 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4086 if (IS_FLT_DBL_TYPE(m->returntype))
4087 M_DST(REG_FRESULT, REG_SP, 1 * 8);
4089 M_AST(REG_RESULT, REG_SP, 1 * 8);
4090 M_ALD(REG_PV, REG_PV, -2 * 8); /* builtin_get_exceptionptrptr */
4091 M_JSR(REG_RA, REG_PV);
4092 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4093 M_LDA(REG_PV, REG_RA, disp);
4094 M_MOV(REG_RESULT, REG_ITMP3);
4095 if (IS_FLT_DBL_TYPE(m->returntype))
4096 M_DLD(REG_FRESULT, REG_SP, 1 * 8);
4098 M_ALD(REG_RESULT, REG_SP, 1 * 8);
4100 M_ALD(REG_ITMP3, REG_PV, -2 * 8); /* get address of exceptionptr */
4102 M_ALD(REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
4103 M_BNEZ(REG_ITMP1, 3); /* if no exception then return */
4105 M_ALD(REG_RA, REG_SP, 0 * 8); /* load return address */
4106 M_LDA(REG_SP, REG_SP, NATIVESTUBSTACK * 8); /* remove stackframe */
4107 M_RET(REG_ZERO, REG_RA); /* return to caller */
4109 M_AST(REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
4111 M_ALD(REG_RA, REG_SP, 0 * 8); /* load return address */
4112 M_LDA(REG_SP, REG_SP, NATIVESTUBSTACK * 8); /* remove stackframe */
4113 M_LDA(REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
4114 M_ALD(REG_ITMP3, REG_PV, -3 * 8); /* load asm exception handler address */
4115 M_JMP(REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
4118 dolog_plain("stubsize: %d (for %d params)\n", (int) (mcodeptr - (s4*) s), m->paramcount);
4121 #if defined(STATISTICS)
4123 count_nstub_len += NATIVESTUBSIZE * 8;
4126 return (u1 *) (s + NATIVESTUBOFFSET);
4130 /* function: removenativestub **************************************************
4132 removes a previously created native-stub from memory
4134 *******************************************************************************/
4136 void removenativestub(u1 *stub)
4138 CFREE((u8 *) stub - NATIVESTUBOFFSET, NATIVESTUBSIZE * 8);
4143 * These are local overrides for various environment variables in Emacs.
4144 * Please do not remove this and leave it at the end of the file, where
4145 * Emacs will automagically detect them.
4146 * ---------------------------------------------------------------------
4149 * indent-tabs-mode: t