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 1595 2004-11-25 15:49:48Z twisti $
41 #include "jit/alpha/codegen.h"
43 #include "jit/parse.h"
55 /* *****************************************************************************
57 Datatypes and Register Allocations:
58 -----------------------------------
60 On 64-bit-machines (like the Alpha) all operands are stored in the
61 registers in a 64-bit form, even when the correspondig JavaVM operands
62 only need 32 bits. This is done by a canonical representation:
64 32-bit integers are allways stored as sign-extended 64-bit values (this
65 approach is directly supported by the Alpha architecture and is very easy
68 32-bit-floats are stored in a 64-bit doubleprecision register by simply
69 expanding the exponent and mantissa with zeroes. (also supported by the
75 The calling conventions and the layout of the stack is explained in detail
76 in the documention file: calling.doc
78 *******************************************************************************/
81 /* register descripton - array ************************************************/
83 /* #define REG_RES 0 reserved register for OS or code generator */
84 /* #define REG_RET 1 return value register */
85 /* #define REG_EXC 2 exception value register (only old jit) */
86 /* #define REG_SAV 3 (callee) saved register */
87 /* #define REG_TMP 4 scratch temporary register (caller saved) */
88 /* #define REG_ARG 5 argument register (caller saved) */
90 /* #define REG_END -1 last entry in tables */
93 REG_RET, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
94 REG_TMP, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
95 REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_TMP, REG_TMP,
96 REG_TMP, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES,
99 /* for use of reserved registers, see comment above */
101 int nregdescfloat[] = {
102 REG_RET, REG_TMP, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
103 REG_SAV, REG_SAV, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
104 REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_TMP, REG_TMP,
105 REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_RES, REG_RES, REG_RES, REG_RES,
108 /* for use of reserved registers, see comment above */
110 /* include independent code generation stuff -- include after register */
111 /* descriptions to avoid extern definitions */
113 #include "jit/codegen.inc"
114 #include "jit/reg.inc"
115 #include "jit/lsra.inc"
118 /* NullPointerException handlers and exception handling initialisation */
120 typedef struct sigctx_struct {
121 long sc_onstack; /* sigstack state to restore */
122 long sc_mask; /* signal mask to restore */
123 long sc_pc; /* pc at time of signal */
124 long sc_ps; /* psl to retore */
125 long sc_regs[32]; /* processor regs 0 to 31 */
126 long sc_ownedfp; /* fp has been used */
127 long sc_fpregs[32]; /* fp regs 0 to 31 */
128 unsigned long sc_fpcr; /* floating point control register */
129 unsigned long sc_fp_control; /* software fpcr */
131 unsigned long sc_reserved1, sc_reserved2;
132 unsigned long sc_ssize;
134 unsigned long sc_traparg_a0;
135 unsigned long sc_traparg_a1;
136 unsigned long sc_traparg_a2;
137 unsigned long sc_fp_trap_pc;
138 unsigned long sc_fp_trigger_sum;
139 unsigned long sc_fp_trigger_inst;
140 unsigned long sc_retcode[2];
144 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
145 void thread_restartcriticalsection(ucontext_t *uc)
148 if ((critical = thread_checkcritical((void*) uc->uc_mcontext.sc_pc)) != NULL)
149 uc->uc_mcontext.sc_pc = (u8) critical;
153 /* NullPointerException signal handler for hardware null pointer check */
155 void catch_NullPointerException(int sig, int code, sigctx_struct *sigctx)
160 java_objectheader *xptr;
162 /* Reset signal handler - necessary for SysV, does no harm for BSD */
164 instr = *((int*)(sigctx->sc_pc));
165 faultaddr = sigctx->sc_regs[(instr >> 16) & 0x1f];
167 if (faultaddr == 0) {
168 /* reinstall handler */
169 signal(sig, (functionptr) catch_NullPointerException);
171 sigaddset(&nsig, sig);
172 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
174 xptr = new_nullpointerexception();
176 sigctx->sc_regs[REG_ITMP1_XPTR] = (u8) xptr;
177 sigctx->sc_regs[REG_ITMP2_XPC] = sigctx->sc_pc;
178 sigctx->sc_pc = (u8) asm_handle_exception;
182 faultaddr += (long) ((instr << 16) >> 16);
183 fprintf(stderr, "faulting address: 0x%016lx\n", faultaddr);
184 panic("Stack overflow");
191 void init_exceptions(void)
196 /* Linux on Digital Alpha needs an initialisation of the ieee floating point
197 control for IEEE compliant arithmetic (option -mieee of GCC). Under
198 Digital Unix this is done automatically.
203 extern unsigned long ieee_get_fp_control();
204 extern void ieee_set_fp_control(unsigned long fp_control);
206 void init_exceptions(void)
208 /* initialize floating point control */
210 ieee_set_fp_control(ieee_get_fp_control()
211 & ~IEEE_TRAP_ENABLE_INV
212 & ~IEEE_TRAP_ENABLE_DZE
213 /* & ~IEEE_TRAP_ENABLE_UNF we dont want underflow */
214 & ~IEEE_TRAP_ENABLE_OVF);
217 /* install signal handlers we need to convert to exceptions */
221 signal(SIGSEGV, (functionptr) catch_NullPointerException);
225 signal(SIGBUS, (functionptr) catch_NullPointerException);
231 /* function gen_mcode **********************************************************
233 generates machine code
235 *******************************************************************************/
237 void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
239 s4 len, s1, s2, s3, d;
253 savedregs_num = (m->isleafmethod) ? 0 : 1; /* space to save the RA */
255 /* space to save used callee saved registers */
257 savedregs_num += (rd->savintregcnt - rd->maxsavintreguse);
258 savedregs_num += (rd->savfltregcnt - rd->maxsavfltreguse);
260 parentargs_base = rd->maxmemuse + savedregs_num;
262 #if defined(USE_THREADS) /* space to save argument of monitor_enter */
264 if (checksync && (m->flags & ACC_SYNCHRONIZED))
269 /* create method header */
271 (void) dseg_addaddress(cd, m); /* MethodPointer */
272 (void) dseg_adds4(cd, parentargs_base * 8); /* FrameSize */
274 #if defined(USE_THREADS)
276 /* IsSync contains the offset relative to the stack pointer for the
277 argument of monitor_exit used in the exception handler. Since the
278 offset could be zero and give a wrong meaning of the flag it is
282 if (checksync && (m->flags & ACC_SYNCHRONIZED))
283 (void) dseg_adds4(cd, (rd->maxmemuse + 1) * 8); /* IsSync */
288 (void) dseg_adds4(cd, 0); /* IsSync */
290 (void) dseg_adds4(cd, m->isleafmethod); /* IsLeaf */
291 (void) dseg_adds4(cd, rd->savintregcnt - rd->maxsavintreguse);/* IntSave */
292 (void) dseg_adds4(cd, rd->savfltregcnt - rd->maxsavfltreguse);/* FltSave */
294 dseg_addlinenumbertablesize(cd);
296 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
298 /* create exception table */
300 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
301 dseg_addtarget(cd, ex->start);
302 dseg_addtarget(cd, ex->end);
303 dseg_addtarget(cd, ex->handler);
304 (void) dseg_addaddress(cd, ex->catchtype);
307 /* initialize mcode variables */
309 mcodeptr = (s4 *) cd->mcodebase;
310 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
311 MCODECHECK(128 + m->paramcount);
313 /* create stack frame (if necessary) */
315 if (parentargs_base) {
316 M_LDA(REG_SP, REG_SP, -parentargs_base * 8);
319 /* save return address and used callee saved registers */
322 if (!m->isleafmethod) {
323 p--; M_AST(REG_RA, REG_SP, p * 8);
325 for (i = rd->savintregcnt - 1; i >= rd->maxsavintreguse; i--) {
326 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
328 for (i = rd->savfltregcnt - 1; i >= rd->maxsavfltreguse; i--) {
329 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
332 /* save monitorenter argument */
334 #if defined(USE_THREADS)
335 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
336 if (m->flags & ACC_STATIC) {
337 p = dseg_addaddress(cd, m->class);
338 M_ALD(REG_ITMP1, REG_PV, p);
339 M_AST(REG_ITMP1, REG_SP, rd->maxmemuse * 8);
342 M_AST(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
347 /* copy argument registers to stack and call trace function with pointer
348 to arguments on stack.
353 M_LDA(REG_SP, REG_SP, -((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
354 M_AST(REG_RA, REG_SP, 1 * 8);
356 /* save integer argument registers */
357 for (p = 0; /* p < m->paramcount && */ p < INT_ARG_CNT; p++) {
358 M_LST(rd->argintregs[p], REG_SP, (2 + p) * 8);
361 /* save and copy float arguments into integer registers */
362 for (p = 0; /* p < m->paramcount && */ p < FLT_ARG_CNT; p++) {
363 t = m->paramtypes[p];
365 if (IS_FLT_DBL_TYPE(t)) {
366 if (IS_2_WORD_TYPE(t)) {
367 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
370 M_FST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
373 M_LLD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
376 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
380 p = dseg_addaddress(cd, m);
381 M_ALD(REG_ITMP1, REG_PV, p);
382 M_AST(REG_ITMP1, REG_SP, 0 * 8);
383 p = dseg_addaddress(cd, (void *) builtin_trace_args);
384 M_ALD(REG_PV, REG_PV, p);
385 M_JSR(REG_RA, REG_PV);
386 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
387 M_LDA(REG_PV, REG_RA, disp);
388 M_ALD(REG_RA, REG_SP, 1 * 8);
390 for (p = 0; /* p < mparamcount && */ p < INT_ARG_CNT; p++) {
391 M_LLD(rd->argintregs[p], REG_SP, (2 + p) * 8);
394 for (p = 0; /* p < mparamcount && */ p < FLT_ARG_CNT; p++) {
395 t = m->paramtypes[p];
397 if (IS_FLT_DBL_TYPE(t)) {
398 if (IS_2_WORD_TYPE(t)) {
399 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
402 M_FLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
406 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
410 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT + 2) * 8);
413 /* take arguments out of register or stack frame */
415 for (p = 0, l = 0; p < m->paramcount; p++) {
416 t = m->paramtypes[p];
417 var = &(rd->locals[l][t]);
419 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
423 if (IS_INT_LNG_TYPE(t)) { /* integer args */
424 if (p < INT_ARG_CNT) { /* register arguments */
425 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
426 M_INTMOVE(rd->argintregs[p], var->regoff);
427 } else { /* reg arg -> spilled */
428 M_LST(rd->argintregs[p], REG_SP, 8 * var->regoff);
431 } else { /* stack arguments */
432 pa = p - INT_ARG_CNT;
433 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
434 M_LLD(var->regoff, REG_SP, 8 * (parentargs_base + pa));
436 } else { /* stack arg -> spilled */
437 M_LLD(REG_ITMP1, REG_SP, 8 * (parentargs_base + pa));
438 M_LST(REG_ITMP1, REG_SP, 8 * var->regoff);
442 } else { /* floating args */
443 if (p < FLT_ARG_CNT) { /* register arguments */
444 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
445 M_FLTMOVE(rd->argfltregs[p], var->regoff);
447 } else { /* reg arg -> spilled */
448 M_DST(rd->argfltregs[p], REG_SP, 8 * var->regoff);
451 } else { /* stack arguments */
452 pa = p - FLT_ARG_CNT;
453 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
454 M_DLD(var->regoff, REG_SP, 8 * (parentargs_base + pa) );
456 } else { /* stack-arg -> spilled */
457 M_DLD(REG_FTMP1, REG_SP, 8 * (parentargs_base + pa));
458 M_DST(REG_FTMP1, REG_SP, 8 * var->regoff);
464 /* call monitorenter function */
466 #if defined(USE_THREADS)
467 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
469 s8 func_enter = (m->flags & ACC_STATIC) ?
470 (s8) builtin_staticmonitorenter : (s8) builtin_monitorenter;
471 p = dseg_addaddress(cd, (void*) func_enter);
472 M_ALD(REG_PV, REG_PV, p);
473 M_ALD(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
474 M_JSR(REG_RA, REG_PV);
475 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
476 M_LDA(REG_PV, REG_RA, disp);
481 /* end of header generation */
483 /* walk through all basic blocks */
484 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
486 bptr->mpc = (s4) ((u1 *) mcodeptr - cd->mcodebase);
488 if (bptr->flags >= BBREACHED) {
490 /* branch resolving */
494 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
495 gen_resolvebranch((u1*) cd->mcodebase + brefs->branchpos,
496 brefs->branchpos, bptr->mpc);
500 /* copy interface registers to their destination */
506 while (src != NULL) {
508 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
509 /* d = reg_of_var(m, src, REG_ITMP1); */
510 if (!(src->flags & INMEMORY))
514 M_INTMOVE(REG_ITMP1, d);
515 store_reg_to_var_int(src, d);
520 while (src != NULL) {
522 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
523 d = reg_of_var(rd, src, REG_ITMP1);
524 M_INTMOVE(REG_ITMP1, d);
525 store_reg_to_var_int(src, d);
528 d = reg_of_var(rd, src, REG_IFTMP);
529 if ((src->varkind != STACKVAR)) {
531 if (IS_FLT_DBL_TYPE(s2)) {
532 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
533 s1 = rd->interfaces[len][s2].regoff;
537 M_DLD(d, REG_SP, 8 * rd->interfaces[len][s2].regoff);
539 store_reg_to_var_flt(src, d);
542 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
543 s1 = rd->interfaces[len][s2].regoff;
547 M_LLD(d, REG_SP, 8 * rd->interfaces[len][s2].regoff);
549 store_reg_to_var_int(src, d);
557 /* walk through all instructions */
561 for (iptr = bptr->iinstr;
563 src = iptr->dst, len--, iptr++) {
565 MCODECHECK(64); /* an instruction usually needs < 64 words */
568 case ICMD_NOP: /* ... ==> ... */
571 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
573 var_to_reg_int(s1, src, REG_ITMP1);
575 codegen_addxnullrefs(cd, mcodeptr);
578 /* constant operations ************************************************/
580 case ICMD_ICONST: /* ... ==> ..., constant */
581 /* op1 = 0, val.i = constant */
583 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
584 ICONST(d, iptr->val.i);
585 store_reg_to_var_int(iptr->dst, d);
588 case ICMD_LCONST: /* ... ==> ..., constant */
589 /* op1 = 0, val.l = constant */
591 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
592 LCONST(d, iptr->val.l);
593 store_reg_to_var_int(iptr->dst, d);
596 case ICMD_FCONST: /* ... ==> ..., constant */
597 /* op1 = 0, val.f = constant */
599 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
600 a = dseg_addfloat(cd, iptr->val.f);
602 store_reg_to_var_flt(iptr->dst, d);
605 case ICMD_DCONST: /* ... ==> ..., constant */
606 /* op1 = 0, val.d = constant */
608 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
609 a = dseg_adddouble(cd, iptr->val.d);
611 store_reg_to_var_flt(iptr->dst, d);
614 case ICMD_ACONST: /* ... ==> ..., constant */
615 /* op1 = 0, val.a = constant */
617 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
619 a = dseg_addaddress(cd, iptr->val.a);
622 M_INTMOVE(REG_ZERO, d);
624 store_reg_to_var_int(iptr->dst, d);
628 /* load/store operations **********************************************/
630 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
631 case ICMD_LLOAD: /* op1 = local variable */
634 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
635 if ((iptr->dst->varkind == LOCALVAR) &&
636 (iptr->dst->varnum == iptr->op1))
638 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
639 if (var->flags & INMEMORY)
640 M_LLD(d, REG_SP, 8 * var->regoff);
642 {M_INTMOVE(var->regoff,d);}
643 store_reg_to_var_int(iptr->dst, d);
646 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
647 case ICMD_DLOAD: /* op1 = local variable */
649 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
650 if ((iptr->dst->varkind == LOCALVAR) &&
651 (iptr->dst->varnum == iptr->op1))
653 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
654 if (var->flags & INMEMORY)
655 M_DLD(d, REG_SP, 8 * var->regoff);
657 {M_FLTMOVE(var->regoff,d);}
658 store_reg_to_var_flt(iptr->dst, d);
662 case ICMD_ISTORE: /* ..., value ==> ... */
663 case ICMD_LSTORE: /* op1 = local variable */
666 if ((src->varkind == LOCALVAR) &&
667 (src->varnum == iptr->op1))
669 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
670 if (var->flags & INMEMORY) {
671 var_to_reg_int(s1, src, REG_ITMP1);
672 M_LST(s1, REG_SP, 8 * var->regoff);
675 var_to_reg_int(s1, src, var->regoff);
676 M_INTMOVE(s1, var->regoff);
680 case ICMD_FSTORE: /* ..., value ==> ... */
681 case ICMD_DSTORE: /* op1 = local variable */
683 if ((src->varkind == LOCALVAR) &&
684 (src->varnum == iptr->op1))
686 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
687 if (var->flags & INMEMORY) {
688 var_to_reg_flt(s1, src, REG_FTMP1);
689 M_DST(s1, REG_SP, 8 * var->regoff);
692 var_to_reg_flt(s1, src, var->regoff);
693 M_FLTMOVE(s1, var->regoff);
698 /* pop/dup/swap operations ********************************************/
700 /* attention: double and longs are only one entry in CACAO ICMDs */
702 case ICMD_POP: /* ..., value ==> ... */
703 case ICMD_POP2: /* ..., value, value ==> ... */
706 case ICMD_DUP: /* ..., a ==> ..., a, a */
707 M_COPY(src, iptr->dst);
710 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
712 M_COPY(src, iptr->dst);
713 M_COPY(src->prev, iptr->dst->prev);
714 M_COPY(iptr->dst, iptr->dst->prev->prev);
717 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., 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);
725 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
727 M_COPY(src, iptr->dst);
728 M_COPY(src->prev, iptr->dst->prev);
731 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
733 M_COPY(src, iptr->dst);
734 M_COPY(src->prev, iptr->dst->prev);
735 M_COPY(src->prev->prev, iptr->dst->prev->prev);
736 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
737 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev);
740 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
742 M_COPY(src, iptr->dst);
743 M_COPY(src->prev, iptr->dst->prev);
744 M_COPY(src->prev->prev, iptr->dst->prev->prev);
745 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
746 M_COPY(iptr->dst, iptr->dst->prev->prev->prev->prev);
747 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev->prev);
750 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
752 M_COPY(src, iptr->dst->prev);
753 M_COPY(src->prev, iptr->dst);
757 /* integer operations *************************************************/
759 case ICMD_INEG: /* ..., value ==> ..., - value */
761 var_to_reg_int(s1, src, REG_ITMP1);
762 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
763 M_ISUB(REG_ZERO, s1, d);
764 store_reg_to_var_int(iptr->dst, d);
767 case ICMD_LNEG: /* ..., value ==> ..., - value */
769 var_to_reg_int(s1, src, REG_ITMP1);
770 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
771 M_LSUB(REG_ZERO, s1, d);
772 store_reg_to_var_int(iptr->dst, d);
775 case ICMD_I2L: /* ..., value ==> ..., value */
777 var_to_reg_int(s1, src, REG_ITMP1);
778 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
780 store_reg_to_var_int(iptr->dst, d);
783 case ICMD_L2I: /* ..., value ==> ..., value */
785 var_to_reg_int(s1, src, REG_ITMP1);
786 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
787 M_IADD(s1, REG_ZERO, d );
788 store_reg_to_var_int(iptr->dst, d);
791 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
793 var_to_reg_int(s1, src, REG_ITMP1);
794 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
795 if (has_ext_instr_set) {
799 M_SLL_IMM(s1, 56, d);
800 M_SRA_IMM( d, 56, d);
802 store_reg_to_var_int(iptr->dst, d);
805 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
807 var_to_reg_int(s1, src, REG_ITMP1);
808 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
810 store_reg_to_var_int(iptr->dst, d);
813 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
815 var_to_reg_int(s1, src, REG_ITMP1);
816 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
817 if (has_ext_instr_set) {
821 M_SLL_IMM(s1, 48, d);
822 M_SRA_IMM( d, 48, d);
824 store_reg_to_var_int(iptr->dst, d);
828 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
830 var_to_reg_int(s1, src->prev, REG_ITMP1);
831 var_to_reg_int(s2, src, REG_ITMP2);
832 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
834 store_reg_to_var_int(iptr->dst, d);
837 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
838 /* val.i = constant */
840 var_to_reg_int(s1, src, REG_ITMP1);
841 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
842 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
843 M_IADD_IMM(s1, iptr->val.i, d);
846 ICONST(REG_ITMP2, iptr->val.i);
847 M_IADD(s1, REG_ITMP2, d);
849 store_reg_to_var_int(iptr->dst, d);
852 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
854 var_to_reg_int(s1, src->prev, REG_ITMP1);
855 var_to_reg_int(s2, src, REG_ITMP2);
856 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
858 store_reg_to_var_int(iptr->dst, d);
861 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
862 /* val.l = constant */
864 var_to_reg_int(s1, src, REG_ITMP1);
865 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
866 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
867 M_LADD_IMM(s1, iptr->val.l, d);
870 LCONST(REG_ITMP2, iptr->val.l);
871 M_LADD(s1, REG_ITMP2, d);
873 store_reg_to_var_int(iptr->dst, d);
876 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
878 var_to_reg_int(s1, src->prev, REG_ITMP1);
879 var_to_reg_int(s2, src, REG_ITMP2);
880 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
882 store_reg_to_var_int(iptr->dst, d);
885 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
886 /* val.i = constant */
888 var_to_reg_int(s1, src, REG_ITMP1);
889 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
890 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
891 M_ISUB_IMM(s1, iptr->val.i, d);
894 ICONST(REG_ITMP2, iptr->val.i);
895 M_ISUB(s1, REG_ITMP2, d);
897 store_reg_to_var_int(iptr->dst, d);
900 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
902 var_to_reg_int(s1, src->prev, REG_ITMP1);
903 var_to_reg_int(s2, src, REG_ITMP2);
904 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
906 store_reg_to_var_int(iptr->dst, d);
909 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
910 /* val.l = constant */
912 var_to_reg_int(s1, src, REG_ITMP1);
913 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
914 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
915 M_LSUB_IMM(s1, iptr->val.l, d);
918 LCONST(REG_ITMP2, iptr->val.l);
919 M_LSUB(s1, REG_ITMP2, d);
921 store_reg_to_var_int(iptr->dst, d);
924 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
926 var_to_reg_int(s1, src->prev, REG_ITMP1);
927 var_to_reg_int(s2, src, REG_ITMP2);
928 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
930 store_reg_to_var_int(iptr->dst, d);
933 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
934 /* val.i = constant */
936 var_to_reg_int(s1, src, REG_ITMP1);
937 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
938 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
939 M_IMUL_IMM(s1, iptr->val.i, d);
942 ICONST(REG_ITMP2, iptr->val.i);
943 M_IMUL(s1, REG_ITMP2, d);
945 store_reg_to_var_int(iptr->dst, d);
948 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
950 var_to_reg_int(s1, src->prev, REG_ITMP1);
951 var_to_reg_int(s2, src, REG_ITMP2);
952 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
954 store_reg_to_var_int(iptr->dst, d);
957 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
958 /* val.l = constant */
960 var_to_reg_int(s1, src, REG_ITMP1);
961 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
962 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
963 M_LMUL_IMM(s1, iptr->val.l, d);
966 LCONST(REG_ITMP2, iptr->val.l);
967 M_LMUL(s1, REG_ITMP2, d);
969 store_reg_to_var_int(iptr->dst, d);
972 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
973 case ICMD_LDIVPOW2: /* val.i = constant */
975 var_to_reg_int(s1, src, REG_ITMP1);
976 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
977 if (iptr->val.i <= 15) {
978 M_LDA(REG_ITMP2, s1, (1 << iptr->val.i) -1);
979 M_CMOVGE(s1, s1, REG_ITMP2);
982 M_SRA_IMM(s1, 63, REG_ITMP2);
983 M_SRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
984 M_LADD(s1, REG_ITMP2, REG_ITMP2);
986 M_SRA_IMM(REG_ITMP2, iptr->val.i, d);
987 store_reg_to_var_int(iptr->dst, d);
990 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
992 var_to_reg_int(s1, src->prev, REG_ITMP1);
993 var_to_reg_int(s2, src, REG_ITMP2);
994 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
995 M_AND_IMM(s2, 0x1f, REG_ITMP3);
996 M_SLL(s1, REG_ITMP3, d);
997 M_IADD(d, REG_ZERO, d);
998 store_reg_to_var_int(iptr->dst, d);
1001 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1002 /* val.i = constant */
1004 var_to_reg_int(s1, src, REG_ITMP1);
1005 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1006 M_SLL_IMM(s1, iptr->val.i & 0x1f, d);
1007 M_IADD(d, REG_ZERO, d);
1008 store_reg_to_var_int(iptr->dst, d);
1011 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1013 var_to_reg_int(s1, src->prev, REG_ITMP1);
1014 var_to_reg_int(s2, src, REG_ITMP2);
1015 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1016 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1017 M_SRA(s1, REG_ITMP3, d);
1018 store_reg_to_var_int(iptr->dst, d);
1021 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1022 /* val.i = constant */
1024 var_to_reg_int(s1, src, REG_ITMP1);
1025 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1026 M_SRA_IMM(s1, iptr->val.i & 0x1f, d);
1027 store_reg_to_var_int(iptr->dst, d);
1030 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1032 var_to_reg_int(s1, src->prev, REG_ITMP1);
1033 var_to_reg_int(s2, src, REG_ITMP2);
1034 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1035 M_AND_IMM(s2, 0x1f, REG_ITMP2);
1037 M_SRL(d, REG_ITMP2, d);
1038 M_IADD(d, REG_ZERO, d);
1039 store_reg_to_var_int(iptr->dst, d);
1042 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1043 /* val.i = constant */
1045 var_to_reg_int(s1, src, REG_ITMP1);
1046 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1048 M_SRL_IMM(d, iptr->val.i & 0x1f, d);
1049 M_IADD(d, REG_ZERO, d);
1050 store_reg_to_var_int(iptr->dst, d);
1053 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1055 var_to_reg_int(s1, src->prev, REG_ITMP1);
1056 var_to_reg_int(s2, src, REG_ITMP2);
1057 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1059 store_reg_to_var_int(iptr->dst, d);
1062 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1063 /* val.i = constant */
1065 var_to_reg_int(s1, src, REG_ITMP1);
1066 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1067 M_SLL_IMM(s1, iptr->val.i & 0x3f, d);
1068 store_reg_to_var_int(iptr->dst, d);
1071 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1073 var_to_reg_int(s1, src->prev, REG_ITMP1);
1074 var_to_reg_int(s2, src, REG_ITMP2);
1075 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1077 store_reg_to_var_int(iptr->dst, d);
1080 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1081 /* val.i = constant */
1083 var_to_reg_int(s1, src, REG_ITMP1);
1084 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1085 M_SRA_IMM(s1, iptr->val.i & 0x3f, d);
1086 store_reg_to_var_int(iptr->dst, d);
1089 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1091 var_to_reg_int(s1, src->prev, REG_ITMP1);
1092 var_to_reg_int(s2, src, REG_ITMP2);
1093 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1095 store_reg_to_var_int(iptr->dst, d);
1098 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1099 /* val.i = constant */
1101 var_to_reg_int(s1, src, REG_ITMP1);
1102 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1103 M_SRL_IMM(s1, iptr->val.i & 0x3f, d);
1104 store_reg_to_var_int(iptr->dst, d);
1107 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1110 var_to_reg_int(s1, src->prev, REG_ITMP1);
1111 var_to_reg_int(s2, src, REG_ITMP2);
1112 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1114 store_reg_to_var_int(iptr->dst, d);
1117 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1118 /* val.i = constant */
1120 var_to_reg_int(s1, src, REG_ITMP1);
1121 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1122 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1123 M_AND_IMM(s1, iptr->val.i, d);
1125 else if (iptr->val.i == 0xffff) {
1128 else if (iptr->val.i == 0xffffff) {
1129 M_ZAPNOT_IMM(s1, 0x07, d);
1132 ICONST(REG_ITMP2, iptr->val.i);
1133 M_AND(s1, REG_ITMP2, d);
1135 store_reg_to_var_int(iptr->dst, d);
1138 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1139 /* val.i = constant */
1141 var_to_reg_int(s1, src, REG_ITMP1);
1142 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1144 M_MOV(s1, REG_ITMP1);
1147 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1148 M_AND_IMM(s1, iptr->val.i, d);
1150 M_ISUB(REG_ZERO, s1, d);
1151 M_AND_IMM(d, iptr->val.i, d);
1153 else if (iptr->val.i == 0xffff) {
1156 M_ISUB(REG_ZERO, s1, d);
1159 else if (iptr->val.i == 0xffffff) {
1160 M_ZAPNOT_IMM(s1, 0x07, d);
1162 M_ISUB(REG_ZERO, s1, d);
1163 M_ZAPNOT_IMM(d, 0x07, d);
1166 ICONST(REG_ITMP2, iptr->val.i);
1167 M_AND(s1, REG_ITMP2, d);
1169 M_ISUB(REG_ZERO, s1, d);
1170 M_AND(d, REG_ITMP2, d);
1172 M_ISUB(REG_ZERO, d, d);
1173 store_reg_to_var_int(iptr->dst, d);
1176 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1177 /* val.l = constant */
1179 var_to_reg_int(s1, src, REG_ITMP1);
1180 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1181 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1182 M_AND_IMM(s1, iptr->val.l, d);
1184 else if (iptr->val.l == 0xffffL) {
1187 else if (iptr->val.l == 0xffffffL) {
1188 M_ZAPNOT_IMM(s1, 0x07, d);
1190 else if (iptr->val.l == 0xffffffffL) {
1193 else if (iptr->val.l == 0xffffffffffL) {
1194 M_ZAPNOT_IMM(s1, 0x1f, d);
1196 else if (iptr->val.l == 0xffffffffffffL) {
1197 M_ZAPNOT_IMM(s1, 0x3f, d);
1199 else if (iptr->val.l == 0xffffffffffffffL) {
1200 M_ZAPNOT_IMM(s1, 0x7f, d);
1203 LCONST(REG_ITMP2, iptr->val.l);
1204 M_AND(s1, REG_ITMP2, d);
1206 store_reg_to_var_int(iptr->dst, d);
1209 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1210 /* val.l = constant */
1212 var_to_reg_int(s1, src, REG_ITMP1);
1213 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1215 M_MOV(s1, REG_ITMP1);
1218 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1219 M_AND_IMM(s1, iptr->val.l, d);
1221 M_LSUB(REG_ZERO, s1, d);
1222 M_AND_IMM(d, iptr->val.l, d);
1224 else if (iptr->val.l == 0xffffL) {
1227 M_LSUB(REG_ZERO, s1, d);
1230 else if (iptr->val.l == 0xffffffL) {
1231 M_ZAPNOT_IMM(s1, 0x07, d);
1233 M_LSUB(REG_ZERO, s1, d);
1234 M_ZAPNOT_IMM(d, 0x07, d);
1236 else if (iptr->val.l == 0xffffffffL) {
1239 M_LSUB(REG_ZERO, s1, d);
1242 else if (iptr->val.l == 0xffffffffffL) {
1243 M_ZAPNOT_IMM(s1, 0x1f, d);
1245 M_LSUB(REG_ZERO, s1, d);
1246 M_ZAPNOT_IMM(d, 0x1f, d);
1248 else if (iptr->val.l == 0xffffffffffffL) {
1249 M_ZAPNOT_IMM(s1, 0x3f, d);
1251 M_LSUB(REG_ZERO, s1, d);
1252 M_ZAPNOT_IMM(d, 0x3f, d);
1254 else if (iptr->val.l == 0xffffffffffffffL) {
1255 M_ZAPNOT_IMM(s1, 0x7f, d);
1257 M_LSUB(REG_ZERO, s1, d);
1258 M_ZAPNOT_IMM(d, 0x7f, d);
1261 LCONST(REG_ITMP2, iptr->val.l);
1262 M_AND(s1, REG_ITMP2, d);
1264 M_LSUB(REG_ZERO, s1, d);
1265 M_AND(d, REG_ITMP2, d);
1267 M_LSUB(REG_ZERO, d, d);
1268 store_reg_to_var_int(iptr->dst, d);
1271 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1274 var_to_reg_int(s1, src->prev, REG_ITMP1);
1275 var_to_reg_int(s2, src, REG_ITMP2);
1276 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1278 store_reg_to_var_int(iptr->dst, d);
1281 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1282 /* val.i = constant */
1284 var_to_reg_int(s1, src, REG_ITMP1);
1285 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1286 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1287 M_OR_IMM(s1, iptr->val.i, d);
1290 ICONST(REG_ITMP2, iptr->val.i);
1291 M_OR(s1, REG_ITMP2, d);
1293 store_reg_to_var_int(iptr->dst, d);
1296 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1297 /* val.l = constant */
1299 var_to_reg_int(s1, src, REG_ITMP1);
1300 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1301 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1302 M_OR_IMM(s1, iptr->val.l, d);
1305 LCONST(REG_ITMP2, iptr->val.l);
1306 M_OR(s1, REG_ITMP2, d);
1308 store_reg_to_var_int(iptr->dst, d);
1311 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1314 var_to_reg_int(s1, src->prev, REG_ITMP1);
1315 var_to_reg_int(s2, src, REG_ITMP2);
1316 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1318 store_reg_to_var_int(iptr->dst, d);
1321 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1322 /* val.i = constant */
1324 var_to_reg_int(s1, src, REG_ITMP1);
1325 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1326 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1327 M_XOR_IMM(s1, iptr->val.i, d);
1330 ICONST(REG_ITMP2, iptr->val.i);
1331 M_XOR(s1, REG_ITMP2, d);
1333 store_reg_to_var_int(iptr->dst, d);
1336 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1337 /* val.l = constant */
1339 var_to_reg_int(s1, src, REG_ITMP1);
1340 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1341 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1342 M_XOR_IMM(s1, iptr->val.l, d);
1345 LCONST(REG_ITMP2, iptr->val.l);
1346 M_XOR(s1, REG_ITMP2, d);
1348 store_reg_to_var_int(iptr->dst, d);
1352 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1354 var_to_reg_int(s1, src->prev, REG_ITMP1);
1355 var_to_reg_int(s2, src, REG_ITMP2);
1356 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1357 M_CMPLT(s1, s2, REG_ITMP3);
1358 M_CMPLT(s2, s1, REG_ITMP1);
1359 M_LSUB (REG_ITMP1, REG_ITMP3, d);
1360 store_reg_to_var_int(iptr->dst, d);
1364 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1365 /* op1 = variable, val.i = constant */
1367 var = &(rd->locals[iptr->op1][TYPE_INT]);
1368 if (var->flags & INMEMORY) {
1370 M_LLD(s1, REG_SP, 8 * var->regoff);
1374 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1375 M_IADD_IMM(s1, iptr->val.i, s1);
1377 else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1378 M_ISUB_IMM(s1, (-iptr->val.i), s1);
1381 M_LDA (s1, s1, iptr->val.i);
1382 M_IADD(s1, REG_ZERO, s1);
1384 if (var->flags & INMEMORY)
1385 M_LST(s1, REG_SP, 8 * var->regoff);
1389 /* floating operations ************************************************/
1391 case ICMD_FNEG: /* ..., value ==> ..., - value */
1393 var_to_reg_flt(s1, src, REG_FTMP1);
1394 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1396 store_reg_to_var_flt(iptr->dst, d);
1399 case ICMD_DNEG: /* ..., value ==> ..., - value */
1401 var_to_reg_flt(s1, src, REG_FTMP1);
1402 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1404 store_reg_to_var_flt(iptr->dst, d);
1407 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1409 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1410 var_to_reg_flt(s2, src, REG_FTMP2);
1411 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1416 if (d == s1 || d == s2) {
1417 M_FADDS(s1, s2, REG_FTMP3);
1419 M_FMOV(REG_FTMP3, d);
1426 store_reg_to_var_flt(iptr->dst, d);
1429 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1431 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1432 var_to_reg_flt(s2, src, REG_FTMP2);
1433 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1438 if (d == s1 || d == s2) {
1439 M_DADDS(s1, s2, REG_FTMP3);
1441 M_FMOV(REG_FTMP3, d);
1448 store_reg_to_var_flt(iptr->dst, d);
1451 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1453 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1454 var_to_reg_flt(s2, src, REG_FTMP2);
1455 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1460 if (d == s1 || d == s2) {
1461 M_FSUBS(s1, s2, REG_FTMP3);
1463 M_FMOV(REG_FTMP3, d);
1470 store_reg_to_var_flt(iptr->dst, d);
1473 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1475 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1476 var_to_reg_flt(s2, src, REG_FTMP2);
1477 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1482 if (d == s1 || d == s2) {
1483 M_DSUBS(s1, s2, REG_FTMP3);
1485 M_FMOV(REG_FTMP3, d);
1492 store_reg_to_var_flt(iptr->dst, d);
1495 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1497 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1498 var_to_reg_flt(s2, src, REG_FTMP2);
1499 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1504 if (d == s1 || d == s2) {
1505 M_FMULS(s1, s2, REG_FTMP3);
1507 M_FMOV(REG_FTMP3, d);
1514 store_reg_to_var_flt(iptr->dst, d);
1517 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1519 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1520 var_to_reg_flt(s2, src, REG_FTMP2);
1521 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1526 if (d == s1 || d == s2) {
1527 M_DMULS(s1, s2, REG_FTMP3);
1529 M_FMOV(REG_FTMP3, d);
1536 store_reg_to_var_flt(iptr->dst, d);
1539 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1541 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1542 var_to_reg_flt(s2, src, REG_FTMP2);
1543 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1548 if (d == s1 || d == s2) {
1549 M_FDIVS(s1, s2, REG_FTMP3);
1551 M_FMOV(REG_FTMP3, d);
1558 store_reg_to_var_flt(iptr->dst, d);
1561 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1563 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1564 var_to_reg_flt(s2, src, REG_FTMP2);
1565 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1570 if (d == s1 || d == s2) {
1571 M_DDIVS(s1, s2, REG_FTMP3);
1573 M_FMOV(REG_FTMP3, d);
1580 store_reg_to_var_flt(iptr->dst, d);
1583 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1585 var_to_reg_int(s1, src, REG_ITMP1);
1586 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1587 a = dseg_adddouble(cd, 0.0);
1588 M_LST (s1, REG_PV, a);
1589 M_DLD (d, REG_PV, a);
1591 store_reg_to_var_flt(iptr->dst, d);
1594 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1596 var_to_reg_int(s1, src, REG_ITMP1);
1597 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1598 a = dseg_adddouble(cd, 0.0);
1599 M_LST (s1, REG_PV, a);
1600 M_DLD (d, REG_PV, a);
1602 store_reg_to_var_flt(iptr->dst, d);
1605 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1607 var_to_reg_flt(s1, src, REG_FTMP1);
1608 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1609 a = dseg_adddouble(cd, 0.0);
1610 M_CVTDL_C(s1, REG_FTMP2);
1611 M_CVTLI(REG_FTMP2, REG_FTMP3);
1612 M_DST (REG_FTMP3, REG_PV, a);
1613 M_ILD (d, REG_PV, a);
1614 store_reg_to_var_int(iptr->dst, d);
1617 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1619 var_to_reg_flt(s1, src, REG_FTMP1);
1620 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1621 a = dseg_adddouble(cd, 0.0);
1622 M_CVTDL_C(s1, REG_FTMP2);
1623 M_DST (REG_FTMP2, REG_PV, a);
1624 M_LLD (d, REG_PV, a);
1625 store_reg_to_var_int(iptr->dst, d);
1628 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1630 var_to_reg_flt(s1, src, REG_FTMP1);
1631 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1634 store_reg_to_var_flt(iptr->dst, d);
1637 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1639 var_to_reg_flt(s1, src, REG_FTMP1);
1640 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1648 store_reg_to_var_flt(iptr->dst, d);
1651 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1653 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1654 var_to_reg_flt(s2, src, REG_FTMP2);
1655 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1657 M_LSUB_IMM(REG_ZERO, 1, d);
1658 M_FCMPEQ(s1, s2, REG_FTMP3);
1659 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1661 M_FCMPLT(s2, s1, REG_FTMP3);
1662 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1663 M_LADD_IMM(REG_ZERO, 1, d);
1666 M_LSUB_IMM(REG_ZERO, 1, d);
1667 M_FCMPEQS(s1, s2, REG_FTMP3);
1669 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1671 M_FCMPLTS(s2, s1, REG_FTMP3);
1673 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1674 M_LADD_IMM(REG_ZERO, 1, d);
1676 store_reg_to_var_int(iptr->dst, d);
1679 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1681 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1682 var_to_reg_flt(s2, src, REG_FTMP2);
1683 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1685 M_LADD_IMM(REG_ZERO, 1, d);
1686 M_FCMPEQ(s1, s2, REG_FTMP3);
1687 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1689 M_FCMPLT(s1, s2, REG_FTMP3);
1690 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1691 M_LSUB_IMM(REG_ZERO, 1, d);
1694 M_LADD_IMM(REG_ZERO, 1, d);
1695 M_FCMPEQS(s1, s2, REG_FTMP3);
1697 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1699 M_FCMPLTS(s1, s2, REG_FTMP3);
1701 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1702 M_LSUB_IMM(REG_ZERO, 1, d);
1704 store_reg_to_var_int(iptr->dst, d);
1708 /* memory operations **************************************************/
1710 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1712 var_to_reg_int(s1, src, REG_ITMP1);
1713 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1714 gen_nullptr_check(s1);
1715 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1716 store_reg_to_var_int(iptr->dst, d);
1719 case ICMD_AALOAD: /* ..., 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(rd, iptr->dst, REG_ITMP3);
1724 if (iptr->op1 == 0) {
1725 gen_nullptr_check(s1);
1728 M_SAADDQ(s2, s1, REG_ITMP1);
1729 M_ALD( d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1730 store_reg_to_var_int(iptr->dst, d);
1733 case ICMD_LALOAD: /* ..., 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(rd, iptr->dst, REG_ITMP3);
1738 if (iptr->op1 == 0) {
1739 gen_nullptr_check(s1);
1742 M_S8ADDQ(s2, s1, REG_ITMP1);
1743 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1744 store_reg_to_var_int(iptr->dst, d);
1747 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1749 var_to_reg_int(s1, src->prev, REG_ITMP1);
1750 var_to_reg_int(s2, src, REG_ITMP2);
1751 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1752 if (iptr->op1 == 0) {
1753 gen_nullptr_check(s1);
1757 M_S4ADDQ(s2, s1, REG_ITMP1);
1758 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1759 store_reg_to_var_int(iptr->dst, d);
1762 case ICMD_FALOAD: /* ..., 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(rd, iptr->dst, REG_FTMP3);
1767 if (iptr->op1 == 0) {
1768 gen_nullptr_check(s1);
1771 M_S4ADDQ(s2, s1, REG_ITMP1);
1772 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1773 store_reg_to_var_flt(iptr->dst, d);
1776 case ICMD_DALOAD: /* ..., 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(rd, iptr->dst, REG_FTMP3);
1781 if (iptr->op1 == 0) {
1782 gen_nullptr_check(s1);
1785 M_S8ADDQ(s2, s1, REG_ITMP1);
1786 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1787 store_reg_to_var_flt(iptr->dst, d);
1790 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1792 var_to_reg_int(s1, src->prev, REG_ITMP1);
1793 var_to_reg_int(s2, src, REG_ITMP2);
1794 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1795 if (iptr->op1 == 0) {
1796 gen_nullptr_check(s1);
1799 if (has_ext_instr_set) {
1800 M_LADD(s2, s1, REG_ITMP1);
1801 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1802 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1805 M_LADD (s2, s1, REG_ITMP1);
1806 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1807 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1808 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1809 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
1811 store_reg_to_var_int(iptr->dst, d);
1814 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1816 var_to_reg_int(s1, src->prev, REG_ITMP1);
1817 var_to_reg_int(s2, src, REG_ITMP2);
1818 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1819 if (iptr->op1 == 0) {
1820 gen_nullptr_check(s1);
1823 if (has_ext_instr_set) {
1824 M_LADD(s2, s1, REG_ITMP1);
1825 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1826 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1830 M_LADD(s2, s1, REG_ITMP1);
1831 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1832 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1833 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1834 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1835 M_SRA_IMM(d, 48, d);
1837 store_reg_to_var_int(iptr->dst, d);
1840 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1842 var_to_reg_int(s1, src->prev, REG_ITMP1);
1843 var_to_reg_int(s2, src, REG_ITMP2);
1844 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1845 if (iptr->op1 == 0) {
1846 gen_nullptr_check(s1);
1849 if (has_ext_instr_set) {
1850 M_LADD (s2, s1, REG_ITMP1);
1851 M_BLDU (d, REG_ITMP1, OFFSET (java_bytearray, data[0]));
1855 M_LADD(s2, s1, REG_ITMP1);
1856 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1857 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
1858 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1859 M_SRA_IMM(d, 56, d);
1861 store_reg_to_var_int(iptr->dst, d);
1865 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1867 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1868 var_to_reg_int(s2, src->prev, REG_ITMP2);
1869 if (iptr->op1 == 0) {
1870 gen_nullptr_check(s1);
1873 var_to_reg_int(s3, src, REG_ITMP3);
1874 M_SAADDQ(s2, s1, REG_ITMP1);
1875 M_AST (s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1878 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1880 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1881 var_to_reg_int(s2, src->prev, REG_ITMP2);
1882 if (iptr->op1 == 0) {
1883 gen_nullptr_check(s1);
1886 var_to_reg_int(s3, src, REG_ITMP3);
1887 M_S8ADDQ(s2, s1, REG_ITMP1);
1888 M_LST (s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1891 case ICMD_IASTORE: /* ..., 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);
1900 var_to_reg_int(s3, src, REG_ITMP3);
1901 M_S4ADDQ(s2, s1, REG_ITMP1);
1902 M_IST (s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1905 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1907 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1908 var_to_reg_int(s2, src->prev, REG_ITMP2);
1909 if (iptr->op1 == 0) {
1910 gen_nullptr_check(s1);
1913 var_to_reg_flt(s3, src, REG_FTMP3);
1914 M_S4ADDQ(s2, s1, REG_ITMP1);
1915 M_FST (s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1918 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1920 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1921 var_to_reg_int(s2, src->prev, REG_ITMP2);
1922 if (iptr->op1 == 0) {
1923 gen_nullptr_check(s1);
1926 var_to_reg_flt(s3, src, REG_FTMP3);
1927 M_S8ADDQ(s2, s1, REG_ITMP1);
1928 M_DST (s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1931 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1933 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1934 var_to_reg_int(s2, src->prev, REG_ITMP2);
1935 if (iptr->op1 == 0) {
1936 gen_nullptr_check(s1);
1939 var_to_reg_int(s3, src, REG_ITMP3);
1940 if (has_ext_instr_set) {
1941 M_LADD(s2, s1, REG_ITMP1);
1942 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1943 M_SST (s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1946 M_LADD (s2, s1, REG_ITMP1);
1947 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1948 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1949 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1950 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1951 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1952 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
1953 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1957 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1959 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1960 var_to_reg_int(s2, src->prev, REG_ITMP2);
1961 if (iptr->op1 == 0) {
1962 gen_nullptr_check(s1);
1965 var_to_reg_int(s3, src, REG_ITMP3);
1966 if (has_ext_instr_set) {
1967 M_LADD(s2, s1, REG_ITMP1);
1968 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1969 M_SST (s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1972 M_LADD (s2, s1, REG_ITMP1);
1973 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1974 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1975 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1976 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1977 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1978 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
1979 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1983 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1985 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1986 var_to_reg_int(s2, src->prev, REG_ITMP2);
1987 if (iptr->op1 == 0) {
1988 gen_nullptr_check(s1);
1991 var_to_reg_int(s3, src, REG_ITMP3);
1992 if (has_ext_instr_set) {
1993 M_LADD(s2, s1, REG_ITMP1);
1994 M_BST (s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1997 M_LADD (s2, s1, REG_ITMP1);
1998 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1999 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2000 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
2001 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2002 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2003 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2008 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
2010 var_to_reg_int(s1, src->prev, REG_ITMP1);
2011 var_to_reg_int(s2, src, REG_ITMP2);
2012 if (iptr->op1 == 0) {
2013 gen_nullptr_check(s1);
2016 M_S4ADDQ(s2, s1, REG_ITMP1);
2017 M_IST(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
2020 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
2022 var_to_reg_int(s1, src->prev, REG_ITMP1);
2023 var_to_reg_int(s2, src, REG_ITMP2);
2024 if (iptr->op1 == 0) {
2025 gen_nullptr_check(s1);
2028 M_S8ADDQ(s2, s1, REG_ITMP1);
2029 M_LST(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
2032 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
2034 var_to_reg_int(s1, src->prev, REG_ITMP1);
2035 var_to_reg_int(s2, src, REG_ITMP2);
2036 if (iptr->op1 == 0) {
2037 gen_nullptr_check(s1);
2040 M_SAADDQ(s2, s1, REG_ITMP1);
2041 M_AST(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
2044 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
2046 var_to_reg_int(s1, src->prev, REG_ITMP1);
2047 var_to_reg_int(s2, src, REG_ITMP2);
2048 if (iptr->op1 == 0) {
2049 gen_nullptr_check(s1);
2052 if (has_ext_instr_set) {
2053 M_LADD(s2, s1, REG_ITMP1);
2054 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2057 M_LADD(s2, s1, REG_ITMP1);
2058 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2059 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2060 M_INSBL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2061 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2062 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2063 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2067 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
2069 var_to_reg_int(s1, src->prev, REG_ITMP1);
2070 var_to_reg_int(s2, src, REG_ITMP2);
2071 if (iptr->op1 == 0) {
2072 gen_nullptr_check(s1);
2075 if (has_ext_instr_set) {
2076 M_LADD(s2, s1, REG_ITMP1);
2077 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2078 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
2081 M_LADD(s2, s1, REG_ITMP1);
2082 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2083 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2084 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2085 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2086 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2087 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2088 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2092 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
2094 var_to_reg_int(s1, src->prev, REG_ITMP1);
2095 var_to_reg_int(s2, src, REG_ITMP2);
2096 if (iptr->op1 == 0) {
2097 gen_nullptr_check(s1);
2100 if (has_ext_instr_set) {
2101 M_LADD(s2, s1, REG_ITMP1);
2102 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2103 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2106 M_LADD(s2, s1, REG_ITMP1);
2107 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2108 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2109 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2110 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2111 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2112 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2113 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2118 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2119 /* op1 = type, val.a = field address */
2121 /* If the static fields' class is not yet initialized, we do it */
2122 /* now. The call code is generated later. */
2123 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
2124 codegen_addclinitref(cd, mcodeptr, ((fieldinfo *) iptr->val.a)->class);
2126 /* This is just for debugging purposes. Is very difficult to */
2127 /* read patched code. Here we patch the following 2 nop's */
2128 /* so that the real code keeps untouched. */
2129 if (showdisassemble) {
2134 a = dseg_addaddress(cd, &(((fieldinfo *)(iptr->val.a))->value));
2135 M_ALD(REG_ITMP1, REG_PV, a);
2136 switch (iptr->op1) {
2138 var_to_reg_int(s2, src, REG_ITMP2);
2139 M_IST(s2, REG_ITMP1, 0);
2142 var_to_reg_int(s2, src, REG_ITMP2);
2143 M_LST(s2, REG_ITMP1, 0);
2146 var_to_reg_int(s2, src, REG_ITMP2);
2147 M_AST(s2, REG_ITMP1, 0);
2150 var_to_reg_flt(s2, src, REG_FTMP2);
2151 M_FST(s2, REG_ITMP1, 0);
2154 var_to_reg_flt(s2, src, REG_FTMP2);
2155 M_DST(s2, REG_ITMP1, 0);
2157 default: panic ("internal error");
2161 case ICMD_GETSTATIC: /* ... ==> ..., value */
2162 /* op1 = type, val.a = field address */
2164 /* if class isn't yet initialized, do it */
2165 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
2166 codegen_addclinitref(cd, mcodeptr, ((fieldinfo *) iptr->val.a)->class);
2168 /* This is just for debugging purposes. Is very difficult to */
2169 /* read patched code. Here we patch the following 2 nop's */
2170 /* so that the real code keeps untouched. */
2171 if (showdisassemble) {
2176 a = dseg_addaddress(cd, &(((fieldinfo *) iptr->val.a)->value));
2177 M_ALD(REG_ITMP1, REG_PV, a);
2178 switch (iptr->op1) {
2180 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2181 M_ILD(d, REG_ITMP1, 0);
2182 store_reg_to_var_int(iptr->dst, d);
2185 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2186 M_LLD(d, REG_ITMP1, 0);
2187 store_reg_to_var_int(iptr->dst, d);
2190 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2191 M_ALD(d, REG_ITMP1, 0);
2192 store_reg_to_var_int(iptr->dst, d);
2195 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2196 M_FLD(d, REG_ITMP1, 0);
2197 store_reg_to_var_flt(iptr->dst, d);
2200 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2201 M_DLD(d, REG_ITMP1, 0);
2202 store_reg_to_var_flt(iptr->dst, d);
2204 default: panic ("internal error");
2209 case ICMD_PUTFIELD: /* ..., value ==> ... */
2210 /* op1 = type, val.i = field offset */
2212 a = ((fieldinfo *) iptr->val.a)->offset;
2213 switch (iptr->op1) {
2215 var_to_reg_int(s1, src->prev, REG_ITMP1);
2216 var_to_reg_int(s2, src, REG_ITMP2);
2217 gen_nullptr_check(s1);
2221 var_to_reg_int(s1, src->prev, REG_ITMP1);
2222 var_to_reg_int(s2, src, REG_ITMP2);
2223 gen_nullptr_check(s1);
2227 var_to_reg_int(s1, src->prev, REG_ITMP1);
2228 var_to_reg_int(s2, src, REG_ITMP2);
2229 gen_nullptr_check(s1);
2233 var_to_reg_int(s1, src->prev, REG_ITMP1);
2234 var_to_reg_flt(s2, src, REG_FTMP2);
2235 gen_nullptr_check(s1);
2239 var_to_reg_int(s1, src->prev, REG_ITMP1);
2240 var_to_reg_flt(s2, src, REG_FTMP2);
2241 gen_nullptr_check(s1);
2244 default: panic ("internal error");
2248 case ICMD_GETFIELD: /* ... ==> ..., value */
2249 /* op1 = type, val.i = field offset */
2251 a = ((fieldinfo *)(iptr->val.a))->offset;
2252 switch (iptr->op1) {
2254 var_to_reg_int(s1, src, REG_ITMP1);
2255 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2256 gen_nullptr_check(s1);
2258 store_reg_to_var_int(iptr->dst, d);
2261 var_to_reg_int(s1, src, REG_ITMP1);
2262 d = reg_of_var(rd, 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(rd, 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(rd, iptr->dst, REG_FTMP1);
2277 gen_nullptr_check(s1);
2279 store_reg_to_var_flt(iptr->dst, d);
2282 var_to_reg_int(s1, src, REG_ITMP1);
2283 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2284 gen_nullptr_check(s1);
2286 store_reg_to_var_flt(iptr->dst, d);
2288 default: panic ("internal error");
2293 /* branch operations **************************************************/
2295 #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}}
2297 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2299 var_to_reg_int(s1, src, REG_ITMP1);
2300 M_INTMOVE(s1, REG_ITMP1_XPTR);
2301 a = dseg_addaddress(cd, asm_handle_exception);
2302 M_ALD(REG_ITMP2, REG_PV, a);
2303 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2304 M_NOP; /* nop ensures that XPC is less than the end */
2305 /* of basic block */
2309 case ICMD_GOTO: /* ... ==> ... */
2310 /* op1 = target JavaVM pc */
2312 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2316 case ICMD_JSR: /* ... ==> ... */
2317 /* op1 = target JavaVM pc */
2319 M_BSR(REG_ITMP1, 0);
2320 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2323 case ICMD_RET: /* ... ==> ... */
2324 /* op1 = local variable */
2326 var = &(rd->locals[iptr->op1][TYPE_ADR]);
2327 if (var->flags & INMEMORY) {
2328 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2329 M_RET(REG_ZERO, REG_ITMP1);
2332 M_RET(REG_ZERO, var->regoff);
2336 case ICMD_IFNULL: /* ..., value ==> ... */
2337 /* op1 = target JavaVM pc */
2339 var_to_reg_int(s1, src, REG_ITMP1);
2341 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2344 case ICMD_IFNONNULL: /* ..., value ==> ... */
2345 /* op1 = target JavaVM pc */
2347 var_to_reg_int(s1, src, REG_ITMP1);
2349 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2352 case ICMD_IFEQ: /* ..., value ==> ... */
2353 /* op1 = target JavaVM pc, val.i = constant */
2355 var_to_reg_int(s1, src, REG_ITMP1);
2356 if (iptr->val.i == 0) {
2360 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2361 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2364 ICONST(REG_ITMP2, iptr->val.i);
2365 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2367 M_BNEZ(REG_ITMP1, 0);
2369 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2372 case ICMD_IFLT: /* ..., value ==> ... */
2373 /* op1 = target JavaVM pc, val.i = constant */
2375 var_to_reg_int(s1, src, REG_ITMP1);
2376 if (iptr->val.i == 0) {
2380 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2381 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2384 ICONST(REG_ITMP2, iptr->val.i);
2385 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2387 M_BNEZ(REG_ITMP1, 0);
2389 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2392 case ICMD_IFLE: /* ..., value ==> ... */
2393 /* op1 = target JavaVM pc, val.i = constant */
2395 var_to_reg_int(s1, src, REG_ITMP1);
2396 if (iptr->val.i == 0) {
2400 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2401 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2404 ICONST(REG_ITMP2, iptr->val.i);
2405 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2407 M_BNEZ(REG_ITMP1, 0);
2409 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2412 case ICMD_IFNE: /* ..., value ==> ... */
2413 /* op1 = target JavaVM pc, val.i = constant */
2415 var_to_reg_int(s1, src, REG_ITMP1);
2416 if (iptr->val.i == 0) {
2420 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2421 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2424 ICONST(REG_ITMP2, iptr->val.i);
2425 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2427 M_BEQZ(REG_ITMP1, 0);
2429 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2432 case ICMD_IFGT: /* ..., value ==> ... */
2433 /* op1 = target JavaVM pc, val.i = constant */
2435 var_to_reg_int(s1, src, REG_ITMP1);
2436 if (iptr->val.i == 0) {
2440 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2441 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2444 ICONST(REG_ITMP2, iptr->val.i);
2445 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2447 M_BEQZ(REG_ITMP1, 0);
2449 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2452 case ICMD_IFGE: /* ..., value ==> ... */
2453 /* op1 = target JavaVM pc, val.i = constant */
2455 var_to_reg_int(s1, src, REG_ITMP1);
2456 if (iptr->val.i == 0) {
2460 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2461 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2464 ICONST(REG_ITMP2, iptr->val.i);
2465 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2467 M_BEQZ(REG_ITMP1, 0);
2469 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2472 case ICMD_IF_LEQ: /* ..., value ==> ... */
2473 /* op1 = target JavaVM pc, val.l = constant */
2475 var_to_reg_int(s1, src, REG_ITMP1);
2476 if (iptr->val.l == 0) {
2480 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2481 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2484 LCONST(REG_ITMP2, iptr->val.l);
2485 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2487 M_BNEZ(REG_ITMP1, 0);
2489 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2492 case ICMD_IF_LLT: /* ..., value ==> ... */
2493 /* op1 = target JavaVM pc, val.l = constant */
2495 var_to_reg_int(s1, src, REG_ITMP1);
2496 if (iptr->val.l == 0) {
2500 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2501 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2504 LCONST(REG_ITMP2, iptr->val.l);
2505 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2507 M_BNEZ(REG_ITMP1, 0);
2509 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2512 case ICMD_IF_LLE: /* ..., value ==> ... */
2513 /* op1 = target JavaVM pc, val.l = constant */
2515 var_to_reg_int(s1, src, REG_ITMP1);
2516 if (iptr->val.l == 0) {
2520 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2521 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2524 LCONST(REG_ITMP2, iptr->val.l);
2525 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2527 M_BNEZ(REG_ITMP1, 0);
2529 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2532 case ICMD_IF_LNE: /* ..., value ==> ... */
2533 /* op1 = target JavaVM pc, val.l = constant */
2535 var_to_reg_int(s1, src, REG_ITMP1);
2536 if (iptr->val.l == 0) {
2540 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2541 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2544 LCONST(REG_ITMP2, iptr->val.l);
2545 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2547 M_BEQZ(REG_ITMP1, 0);
2549 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2552 case ICMD_IF_LGT: /* ..., value ==> ... */
2553 /* op1 = target JavaVM pc, val.l = constant */
2555 var_to_reg_int(s1, src, REG_ITMP1);
2556 if (iptr->val.l == 0) {
2560 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2561 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2564 LCONST(REG_ITMP2, iptr->val.l);
2565 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2567 M_BEQZ(REG_ITMP1, 0);
2569 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2572 case ICMD_IF_LGE: /* ..., value ==> ... */
2573 /* op1 = target JavaVM pc, val.l = constant */
2575 var_to_reg_int(s1, src, REG_ITMP1);
2576 if (iptr->val.l == 0) {
2580 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2581 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2584 LCONST(REG_ITMP2, iptr->val.l);
2585 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2587 M_BEQZ(REG_ITMP1, 0);
2589 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2592 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2593 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2594 case ICMD_IF_ACMPEQ:
2596 var_to_reg_int(s1, src->prev, REG_ITMP1);
2597 var_to_reg_int(s2, src, REG_ITMP2);
2598 M_CMPEQ(s1, s2, REG_ITMP1);
2599 M_BNEZ(REG_ITMP1, 0);
2600 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2603 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2604 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2605 case ICMD_IF_ACMPNE:
2607 var_to_reg_int(s1, src->prev, REG_ITMP1);
2608 var_to_reg_int(s2, src, REG_ITMP2);
2609 M_CMPEQ(s1, s2, REG_ITMP1);
2610 M_BEQZ(REG_ITMP1, 0);
2611 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2614 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2615 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2617 var_to_reg_int(s1, src->prev, REG_ITMP1);
2618 var_to_reg_int(s2, src, REG_ITMP2);
2619 M_CMPLT(s1, s2, REG_ITMP1);
2620 M_BNEZ(REG_ITMP1, 0);
2621 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2624 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2625 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2627 var_to_reg_int(s1, src->prev, REG_ITMP1);
2628 var_to_reg_int(s2, src, REG_ITMP2);
2629 M_CMPLE(s1, s2, REG_ITMP1);
2630 M_BEQZ(REG_ITMP1, 0);
2631 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2634 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2635 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2637 var_to_reg_int(s1, src->prev, REG_ITMP1);
2638 var_to_reg_int(s2, src, REG_ITMP2);
2639 M_CMPLE(s1, s2, REG_ITMP1);
2640 M_BNEZ(REG_ITMP1, 0);
2641 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2644 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2645 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2647 var_to_reg_int(s1, src->prev, REG_ITMP1);
2648 var_to_reg_int(s2, src, REG_ITMP2);
2649 M_CMPLT(s1, s2, REG_ITMP1);
2650 M_BEQZ(REG_ITMP1, 0);
2651 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2654 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2656 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2659 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2660 /* val.i = constant */
2662 var_to_reg_int(s1, src, REG_ITMP1);
2663 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2665 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2666 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2667 M_CMPEQ(s1, REG_ZERO, d);
2668 store_reg_to_var_int(iptr->dst, d);
2671 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2672 M_CMPEQ(s1, REG_ZERO, d);
2674 store_reg_to_var_int(iptr->dst, d);
2678 M_MOV(s1, REG_ITMP1);
2681 ICONST(d, iptr[1].val.i);
2683 if ((s3 >= 0) && (s3 <= 255)) {
2684 M_CMOVEQ_IMM(s1, s3, d);
2687 ICONST(REG_ITMP2, s3);
2688 M_CMOVEQ(s1, REG_ITMP2, d);
2690 store_reg_to_var_int(iptr->dst, d);
2693 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2694 /* val.i = constant */
2696 var_to_reg_int(s1, src, REG_ITMP1);
2697 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2699 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2700 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2701 M_CMPEQ(s1, REG_ZERO, d);
2702 store_reg_to_var_int(iptr->dst, d);
2705 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2706 M_CMPEQ(s1, REG_ZERO, d);
2708 store_reg_to_var_int(iptr->dst, d);
2712 M_MOV(s1, REG_ITMP1);
2715 ICONST(d, iptr[1].val.i);
2717 if ((s3 >= 0) && (s3 <= 255)) {
2718 M_CMOVNE_IMM(s1, s3, d);
2721 ICONST(REG_ITMP2, s3);
2722 M_CMOVNE(s1, REG_ITMP2, d);
2724 store_reg_to_var_int(iptr->dst, d);
2727 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2728 /* val.i = constant */
2730 var_to_reg_int(s1, src, REG_ITMP1);
2731 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2733 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2734 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2735 M_CMPLT(s1, REG_ZERO, d);
2736 store_reg_to_var_int(iptr->dst, d);
2739 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2740 M_CMPLE(REG_ZERO, s1, d);
2741 store_reg_to_var_int(iptr->dst, d);
2745 M_MOV(s1, REG_ITMP1);
2748 ICONST(d, iptr[1].val.i);
2750 if ((s3 >= 0) && (s3 <= 255)) {
2751 M_CMOVLT_IMM(s1, s3, d);
2754 ICONST(REG_ITMP2, s3);
2755 M_CMOVLT(s1, REG_ITMP2, d);
2757 store_reg_to_var_int(iptr->dst, d);
2760 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2761 /* val.i = constant */
2763 var_to_reg_int(s1, src, REG_ITMP1);
2764 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2766 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2767 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2768 M_CMPLE(REG_ZERO, s1, d);
2769 store_reg_to_var_int(iptr->dst, d);
2772 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2773 M_CMPLT(s1, REG_ZERO, d);
2774 store_reg_to_var_int(iptr->dst, d);
2778 M_MOV(s1, REG_ITMP1);
2781 ICONST(d, iptr[1].val.i);
2783 if ((s3 >= 0) && (s3 <= 255)) {
2784 M_CMOVGE_IMM(s1, s3, d);
2787 ICONST(REG_ITMP2, s3);
2788 M_CMOVGE(s1, REG_ITMP2, d);
2790 store_reg_to_var_int(iptr->dst, d);
2793 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2794 /* val.i = constant */
2796 var_to_reg_int(s1, src, REG_ITMP1);
2797 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2799 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2800 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2801 M_CMPLT(REG_ZERO, s1, d);
2802 store_reg_to_var_int(iptr->dst, d);
2805 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2806 M_CMPLE(s1, REG_ZERO, d);
2807 store_reg_to_var_int(iptr->dst, d);
2811 M_MOV(s1, REG_ITMP1);
2814 ICONST(d, iptr[1].val.i);
2816 if ((s3 >= 0) && (s3 <= 255)) {
2817 M_CMOVGT_IMM(s1, s3, d);
2820 ICONST(REG_ITMP2, s3);
2821 M_CMOVGT(s1, REG_ITMP2, d);
2823 store_reg_to_var_int(iptr->dst, d);
2826 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2827 /* val.i = constant */
2829 var_to_reg_int(s1, src, REG_ITMP1);
2830 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2832 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2833 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2834 M_CMPLE(s1, REG_ZERO, d);
2835 store_reg_to_var_int(iptr->dst, d);
2838 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2839 M_CMPLT(REG_ZERO, s1, d);
2840 store_reg_to_var_int(iptr->dst, d);
2844 M_MOV(s1, REG_ITMP1);
2847 ICONST(d, iptr[1].val.i);
2849 if ((s3 >= 0) && (s3 <= 255)) {
2850 M_CMOVLE_IMM(s1, s3, d);
2853 ICONST(REG_ITMP2, s3);
2854 M_CMOVLE(s1, REG_ITMP2, d);
2856 store_reg_to_var_int(iptr->dst, d);
2860 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2864 var_to_reg_int(s1, src, REG_RESULT);
2865 M_INTMOVE(s1, REG_RESULT);
2867 #if defined(USE_THREADS)
2868 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2870 a = dseg_addaddress(cd, (void *) (builtin_monitorexit));
2871 M_ALD(REG_PV, REG_PV, a);
2872 M_ALD(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
2873 M_LST(REG_RESULT, REG_SP, rd->maxmemuse * 8);
2874 M_JSR(REG_RA, REG_PV);
2875 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
2876 M_LDA(REG_PV, REG_RA, disp);
2877 M_LLD(REG_RESULT, REG_SP, rd->maxmemuse * 8);
2881 goto nowperformreturn;
2883 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2886 var_to_reg_flt(s1, src, REG_FRESULT);
2887 M_FLTMOVE(s1, REG_FRESULT);
2889 #if defined(USE_THREADS)
2890 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2892 a = dseg_addaddress(cd, (void *) (builtin_monitorexit));
2893 M_ALD(REG_PV, REG_PV, a);
2894 M_ALD(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
2895 M_DST(REG_FRESULT, REG_SP, rd->maxmemuse * 8);
2896 M_JSR(REG_RA, REG_PV);
2897 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
2898 M_LDA(REG_PV, REG_RA, disp);
2899 M_DLD(REG_FRESULT, REG_SP, rd->maxmemuse * 8);
2903 goto nowperformreturn;
2905 case ICMD_RETURN: /* ... ==> ... */
2907 #if defined(USE_THREADS)
2908 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2910 a = dseg_addaddress(cd, (void *) (builtin_monitorexit));
2911 M_ALD(REG_PV, REG_PV, a);
2912 M_ALD(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
2913 M_JSR(REG_RA, REG_PV);
2914 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
2915 M_LDA(REG_PV, REG_RA, disp);
2923 p = parentargs_base;
2925 /* restore return address */
2927 if (!m->isleafmethod) {
2928 p--; M_LLD(REG_RA, REG_SP, p * 8);
2931 /* restore saved registers */
2933 for (i = rd->savintregcnt - 1; i >= rd->maxsavintreguse; i--) {
2934 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2936 for (i = rd->savfltregcnt - 1; i >= rd->maxsavfltreguse; i--) {
2937 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2940 /* deallocate stack */
2942 if (parentargs_base) {
2943 M_LDA(REG_SP, REG_SP, parentargs_base * 8);
2946 /* call trace function */
2949 M_LDA(REG_SP, REG_SP, -3 * 8);
2950 M_AST(REG_RA, REG_SP, 0 * 8);
2951 M_LST(REG_RESULT, REG_SP, 1 * 8);
2952 M_DST(REG_FRESULT, REG_SP, 2 * 8);
2953 a = dseg_addaddress(cd, m);
2954 M_ALD(rd->argintregs[0], REG_PV, a);
2955 M_MOV(REG_RESULT, rd->argintregs[1]);
2956 M_FLTMOVE(REG_FRESULT, rd->argfltregs[2]);
2957 M_FLTMOVE(REG_FRESULT, rd->argfltregs[3]);
2958 a = dseg_addaddress(cd, (void *) builtin_displaymethodstop);
2959 M_ALD(REG_PV, REG_PV, a);
2960 M_JSR(REG_RA, REG_PV);
2961 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
2962 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
2964 s4 ml = -s1, mh = 0;
2965 while (ml < -32768) { ml += 65536; mh--; }
2966 M_LDA(REG_PV, REG_RA, ml);
2967 M_LDAH(REG_PV, REG_PV, mh);
2969 M_DLD(REG_FRESULT, REG_SP, 2 * 8);
2970 M_LLD(REG_RESULT, REG_SP, 1 * 8);
2971 M_ALD(REG_RA, REG_SP, 0 * 8);
2972 M_LDA(REG_SP, REG_SP, 3 * 8);
2975 M_RET(REG_ZERO, REG_RA);
2981 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2986 tptr = (void **) iptr->target;
2988 s4ptr = iptr->val.a;
2989 l = s4ptr[1]; /* low */
2990 i = s4ptr[2]; /* high */
2992 var_to_reg_int(s1, src, REG_ITMP1);
2994 {M_INTMOVE(s1, REG_ITMP1);}
2995 else if (l <= 32768) {
2996 M_LDA(REG_ITMP1, s1, -l);
2999 ICONST(REG_ITMP2, l);
3000 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
3007 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
3009 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
3010 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3012 M_BEQZ(REG_ITMP2, 0);
3015 /* codegen_addreference(cd, BlockPtrOfPC(s4ptr[0]), mcodeptr); */
3016 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3018 /* build jump table top down and use address of lowest entry */
3020 /* s4ptr += 3 + i; */
3024 /* dseg_addtarget(cd, BlockPtrOfPC(*--s4ptr)); */
3025 dseg_addtarget(cd, (basicblock *) tptr[0]);
3030 /* length of dataseg after last dseg_addtarget is used by load */
3032 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
3033 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
3034 M_JMP(REG_ZERO, REG_ITMP2);
3039 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3041 s4 i, l, val, *s4ptr;
3044 tptr = (void **) iptr->target;
3046 s4ptr = iptr->val.a;
3047 l = s4ptr[0]; /* default */
3048 i = s4ptr[1]; /* count */
3050 MCODECHECK((i<<2)+8);
3051 var_to_reg_int(s1, src, REG_ITMP1);
3057 if ((val >= 0) && (val <= 255)) {
3058 M_CMPEQ_IMM(s1, val, REG_ITMP2);
3061 if ((val >= -32768) && (val <= 32767)) {
3062 M_LDA(REG_ITMP2, REG_ZERO, val);
3065 a = dseg_adds4(cd, val);
3066 M_ILD(REG_ITMP2, REG_PV, a);
3068 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
3070 M_BNEZ(REG_ITMP2, 0);
3071 /* codegen_addreference(cd, BlockPtrOfPC(s4ptr[1]), mcodeptr); */
3072 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3076 /* codegen_addreference(cd, BlockPtrOfPC(l), mcodeptr); */
3078 tptr = (void **) iptr->target;
3079 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3086 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
3087 /* op1 = return type, val.a = function pointer*/
3091 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
3092 /* op1 = return type, val.a = function pointer*/
3096 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
3097 /* op1 = return type, val.a = function pointer*/
3101 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3102 /* op1 = arg count, val.a = method pointer */
3104 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3105 /* op1 = arg count, val.a = method pointer */
3107 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3108 /* op1 = arg count, val.a = method pointer */
3110 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
3111 /* op1 = arg count, val.a = method pointer */
3118 MCODECHECK((s3 << 1) + 64);
3120 /* copy arguments to registers or stack location */
3122 for (; --s3 >= 0; src = src->prev) {
3123 if (src->varkind == ARGVAR)
3125 if (IS_INT_LNG_TYPE(src->type)) {
3126 if (s3 < INT_ARG_CNT) {
3127 s1 = rd->argintregs[s3];
3128 var_to_reg_int(d, src, s1);
3132 var_to_reg_int(d, src, REG_ITMP1);
3133 M_LST(d, REG_SP, 8 * (s3 - INT_ARG_CNT));
3137 if (s3 < FLT_ARG_CNT) {
3138 s1 = rd->argfltregs[s3];
3139 var_to_reg_flt(d, src, s1);
3143 var_to_reg_flt(d, src, REG_FTMP1);
3144 M_DST(d, REG_SP, 8 * (s3 - FLT_ARG_CNT));
3150 switch (iptr->opc) {
3154 a = dseg_addaddress(cd, (void *) lm);
3157 M_ALD(REG_PV, REG_PV, a); /* Pointer to built-in-function */
3160 case ICMD_INVOKESTATIC:
3161 case ICMD_INVOKESPECIAL:
3162 a = dseg_addaddress(cd, lm->stubroutine);
3165 M_ALD(REG_PV, REG_PV, a); /* method pointer in r27 */
3168 case ICMD_INVOKEVIRTUAL:
3171 gen_nullptr_check(rd->argintregs[0]);
3172 M_ALD(REG_METHODPTR, rd->argintregs[0],
3173 OFFSET(java_objectheader, vftbl));
3174 M_ALD(REG_PV, REG_METHODPTR, OFFSET(vftbl_t, table[0]) +
3175 sizeof(methodptr) * lm->vftblindex);
3178 case ICMD_INVOKEINTERFACE:
3181 gen_nullptr_check(rd->argintregs[0]);
3182 M_ALD(REG_METHODPTR, rd->argintregs[0],
3183 OFFSET(java_objectheader, vftbl));
3184 M_ALD(REG_METHODPTR, REG_METHODPTR,
3185 OFFSET(vftbl_t, interfacetable[0]) -
3186 sizeof(methodptr*) * lm->class->index);
3187 M_ALD(REG_PV, REG_METHODPTR,
3188 sizeof(methodptr) * (lm - lm->class->methods));
3192 M_JSR(REG_RA, REG_PV);
3196 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3197 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3199 s4 ml = -s1, mh = 0;
3200 while (ml < -32768) { ml += 65536; mh--; }
3201 M_LDA(REG_PV, REG_RA, ml);
3202 M_LDAH(REG_PV, REG_PV, mh);
3205 /* d contains return type */
3207 if (d != TYPE_VOID) {
3208 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3209 s1 = reg_of_var(rd, iptr->dst, REG_RESULT);
3210 M_INTMOVE(REG_RESULT, s1);
3211 store_reg_to_var_int(iptr->dst, s1);
3214 s1 = reg_of_var(rd, iptr->dst, REG_FRESULT);
3215 M_FLTMOVE(REG_FRESULT, s1);
3216 store_reg_to_var_flt(iptr->dst, s1);
3223 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3225 /* op1: 0 == array, 1 == class */
3226 /* val.a: (classinfo*) superclass */
3228 /* superclass is an interface:
3230 * return (sub != NULL) &&
3231 * (sub->vftbl->interfacetablelength > super->index) &&
3232 * (sub->vftbl->interfacetable[-super->index] != NULL);
3234 * superclass is a class:
3236 * return ((sub != NULL) && (0
3237 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3238 * super->vftbl->diffvall));
3242 classinfo *super = (classinfo*) iptr->val.a;
3244 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3245 codegen_threadcritrestart(cd, (u1 *) mcodeptr - cd->mcodebase);
3247 var_to_reg_int(s1, src, REG_ITMP1);
3248 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
3250 M_MOV(s1, REG_ITMP1);
3254 if (iptr->op1) { /* class/interface */
3255 if (super->flags & ACC_INTERFACE) { /* interface */
3257 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3258 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3259 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3260 M_BLEZ(REG_ITMP2, 2);
3261 M_ALD(REG_ITMP1, REG_ITMP1,
3262 OFFSET(vftbl_t, interfacetable[0]) -
3263 super->index * sizeof(methodptr*));
3264 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3268 s2 = super->vftbl->diffval;
3269 M_BEQZ(s1, 4 + (s2 > 255));
3270 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3271 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3272 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3274 M_CMPULE_IMM(REG_ITMP1, s2, d);
3276 M_LDA(REG_ITMP2, REG_ZERO, s2);
3277 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3281 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3282 a = dseg_addaddress(cd, (void*) super->vftbl);
3283 M_ALD(REG_ITMP2, REG_PV, a);
3284 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3285 codegen_threadcritstart(cd, (u1 *) mcodeptr - cd->mcodebase);
3287 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3288 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3289 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3290 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3291 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3293 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3294 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3298 panic ("internal error: no inlined array instanceof");
3300 store_reg_to_var_int(iptr->dst, d);
3303 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3305 /* op1: 0 == array, 1 == class */
3306 /* val.a: (classinfo*) superclass */
3308 /* superclass is an interface:
3310 * OK if ((sub == NULL) ||
3311 * (sub->vftbl->interfacetablelength > super->index) &&
3312 * (sub->vftbl->interfacetable[-super->index] != NULL));
3314 * superclass is a class:
3316 * OK if ((sub == NULL) || (0
3317 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3318 * super->vftbl->diffvall));
3322 classinfo *super = (classinfo *) iptr->val.a;
3324 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3325 codegen_threadcritrestart(cd, (u1 *) mcodeptr - cd->mcodebase);
3327 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
3328 var_to_reg_int(s1, src, d);
3329 if (iptr->op1) { /* class/interface */
3330 if (super->flags & ACC_INTERFACE) { /* interface */
3332 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3333 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3334 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3335 M_BLEZ(REG_ITMP2, 0);
3336 codegen_addxcastrefs(cd, mcodeptr);
3337 M_ALD(REG_ITMP2, REG_ITMP1,
3338 OFFSET(vftbl_t, interfacetable[0]) -
3339 super->index * sizeof(methodptr*));
3340 M_BEQZ(REG_ITMP2, 0);
3341 codegen_addxcastrefs(cd, mcodeptr);
3345 s2 = super->vftbl->diffval;
3346 M_BEQZ(s1, 4 + (s2 != 0) + (s2 > 255));
3347 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3348 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3349 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3351 M_BNEZ(REG_ITMP1, 0);
3353 else if (s2 <= 255) {
3354 M_CMPULE_IMM(REG_ITMP1, s2, REG_ITMP2);
3355 M_BEQZ(REG_ITMP2, 0);
3358 M_LDA(REG_ITMP2, REG_ZERO, s2);
3359 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3360 M_BEQZ(REG_ITMP2, 0);
3363 M_BEQZ(s1, 8 + (d == REG_ITMP3));
3364 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3365 a = dseg_addaddress(cd, (void *) super->vftbl);
3366 M_ALD(REG_ITMP2, REG_PV, a);
3367 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3368 codegen_threadcritstart(cd, (u1 *) mcodeptr - cd->mcodebase);
3370 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3371 if (d != REG_ITMP3) {
3372 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3373 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3374 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3375 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3377 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3380 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3381 M_ISUB(REG_ITMP1, REG_ITMP2, REG_ITMP1);
3382 M_ALD(REG_ITMP2, REG_PV, a);
3383 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3384 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3385 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3388 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3389 M_BEQZ(REG_ITMP2, 0);
3390 codegen_addxcastrefs(cd, mcodeptr);
3394 panic ("internal error: no inlined array checkcast");
3397 store_reg_to_var_int(iptr->dst, d);
3400 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
3402 var_to_reg_int(s1, src, REG_ITMP1);
3404 codegen_addxcheckarefs(cd, mcodeptr);
3407 case ICMD_CHECKEXCEPTION: /* ... ==> ... */
3409 M_BEQZ(REG_RESULT, 0);
3410 codegen_addxexceptionrefs(cd, mcodeptr);
3413 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3414 /* op1 = dimension, val.a = array descriptor */
3416 /* check for negative sizes and copy sizes to stack if necessary */
3418 MCODECHECK((iptr->op1 << 1) + 64);
3420 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3421 var_to_reg_int(s2, src, REG_ITMP1);
3423 codegen_addxcheckarefs(cd, mcodeptr);
3425 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
3427 if (src->varkind != ARGVAR) {
3428 M_LST(s2, REG_SP, 8 * (s1 + INT_ARG_CNT));
3432 /* a0 = dimension count */
3434 ICONST(rd->argintregs[0], iptr->op1);
3436 /* a1 = arraydescriptor */
3438 a = dseg_addaddress(cd, iptr->val.a);
3439 M_ALD(rd->argintregs[1], REG_PV, a);
3441 /* a2 = pointer to dimensions = stack pointer */
3443 M_INTMOVE(REG_SP, rd->argintregs[2]);
3445 a = dseg_addaddress(cd, (void *) builtin_nmultianewarray);
3446 M_ALD(REG_PV, REG_PV, a);
3447 M_JSR(REG_RA, REG_PV);
3448 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3450 M_LDA(REG_PV, REG_RA, -s1);
3452 s4 ml = -s1, mh = 0;
3453 while (ml < -32768) { ml += 65536; mh--; }
3454 M_LDA(REG_PV, REG_RA, ml);
3455 M_LDAH(REG_PV, REG_PV, mh);
3457 s1 = reg_of_var(rd, iptr->dst, REG_RESULT);
3458 M_INTMOVE(REG_RESULT, s1);
3459 store_reg_to_var_int(iptr->dst, s1);
3462 case ICMD_INLINE_START:
3463 case ICMD_INLINE_END:
3466 default: error ("Unknown pseudo command: %d", iptr->opc);
3472 } /* for instruction */
3474 /* copy values to interface registers */
3476 src = bptr->outstack;
3477 len = bptr->outdepth;
3482 if ((src->varkind != STACKVAR)) {
3484 if (IS_FLT_DBL_TYPE(s2)) {
3485 var_to_reg_flt(s1, src, REG_FTMP1);
3486 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3487 M_FLTMOVE(s1,rd->interfaces[len][s2].regoff);
3490 M_DST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3494 var_to_reg_int(s1, src, REG_ITMP1);
3495 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3496 M_INTMOVE(s1,rd->interfaces[len][s2].regoff);
3499 M_LST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3505 } /* if (bptr -> flags >= BBREACHED) */
3506 } /* for basic block */
3509 /* generate bound check stubs */
3511 s4 *xcodeptr = NULL;
3514 for (bref = cd->xboundrefs; bref != NULL; bref = bref->next) {
3515 gen_resolvebranch((u1*) cd->mcodebase + bref->branchpos,
3517 (u1*) mcodeptr - cd->mcodebase);
3521 /* move index register into REG_ITMP1 */
3522 M_MOV(bref->reg, REG_ITMP1);
3523 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3525 if (xcodeptr != NULL) {
3526 M_BR(xcodeptr - mcodeptr - 1);
3529 xcodeptr = mcodeptr;
3531 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3532 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3534 a = dseg_addaddress(cd, string_java_lang_ArrayIndexOutOfBoundsException);
3535 M_ALD(rd->argintregs[0], REG_PV, a);
3536 M_MOV(REG_ITMP1, rd->argintregs[1]);
3538 a = dseg_addaddress(cd, new_exception_int);
3539 M_ALD(REG_PV, REG_PV, a);
3540 M_JSR(REG_RA, REG_PV);
3543 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3544 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3546 s4 ml = -s1, mh = 0;
3547 while (ml < -32768) { ml += 65536; mh--; }
3548 M_LDA(REG_PV, REG_RA, ml);
3549 M_LDAH(REG_PV, REG_PV, mh);
3552 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3554 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3555 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3557 a = dseg_addaddress(cd, asm_handle_exception);
3558 M_ALD(REG_ITMP3, REG_PV, a);
3560 M_JMP(REG_ZERO, REG_ITMP3);
3564 /* generate negative array size check stubs */
3568 for (bref = cd->xcheckarefs; bref != NULL; bref = bref->next) {
3569 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3570 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3572 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3576 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3578 (u1 *) mcodeptr - cd->mcodebase);
3582 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3584 if (xcodeptr != NULL) {
3585 M_BR(xcodeptr - mcodeptr - 1);
3588 xcodeptr = mcodeptr;
3590 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3591 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3593 a = dseg_addaddress(cd, string_java_lang_NegativeArraySizeException);
3594 M_ALD(rd->argintregs[0], REG_PV, a);
3596 a = dseg_addaddress(cd, new_exception);
3597 M_ALD(REG_PV, REG_PV, a);
3598 M_JSR(REG_RA, REG_PV);
3601 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3602 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3604 s4 ml = -s1, mh = 0;
3605 while (ml < -32768) { ml += 65536; mh--; }
3606 M_LDA(REG_PV, REG_RA, ml);
3607 M_LDAH(REG_PV, REG_PV, mh);
3610 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3612 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3613 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3615 a = dseg_addaddress(cd, asm_handle_exception);
3616 M_ALD(REG_ITMP3, REG_PV, a);
3618 M_JMP(REG_ZERO, REG_ITMP3);
3622 /* generate cast check stubs */
3626 for (bref = cd->xcastrefs; bref != NULL; bref = bref->next) {
3627 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3628 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3630 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3634 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3636 (u1 *) mcodeptr - cd->mcodebase);
3640 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3642 if (xcodeptr != NULL) {
3643 M_BR(xcodeptr - mcodeptr - 1);
3646 xcodeptr = mcodeptr;
3648 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3649 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3651 a = dseg_addaddress(cd, string_java_lang_ClassCastException);
3652 M_ALD(rd->argintregs[0], REG_PV, a);
3654 a = dseg_addaddress(cd, new_exception);
3655 M_ALD(REG_PV, REG_PV, a);
3656 M_JSR(REG_RA, REG_PV);
3659 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3660 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3662 s4 ml = -s1, mh = 0;
3663 while (ml < -32768) { ml += 65536; mh--; }
3664 M_LDA(REG_PV, REG_RA, ml);
3665 M_LDAH(REG_PV, REG_PV, mh);
3668 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3670 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3671 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3673 a = dseg_addaddress(cd, asm_handle_exception);
3674 M_ALD(REG_ITMP3, REG_PV, a);
3676 M_JMP(REG_ZERO, REG_ITMP3);
3680 /* generate exception check stubs */
3684 for (bref = cd->xexceptionrefs; bref != NULL; bref = bref->next) {
3685 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3686 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3688 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3692 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3694 (u1 *) mcodeptr - cd->mcodebase);
3698 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3700 if (xcodeptr != NULL) {
3701 M_BR(xcodeptr - mcodeptr - 1);
3704 xcodeptr = mcodeptr;
3706 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3707 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3708 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3710 a = dseg_addaddress(cd, &builtin_get_exceptionptrptr);
3711 M_ALD(REG_PV, REG_PV, a);
3712 M_JSR(REG_RA, REG_PV);
3715 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3716 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3718 s4 ml = -s1, mh = 0;
3719 while (ml < -32768) { ml += 65536; mh--; }
3720 M_LDA(REG_PV, REG_RA, ml);
3721 M_LDAH(REG_PV, REG_PV, mh);
3724 M_ALD(REG_ITMP1_XPTR, REG_RESULT, 0);
3725 M_AST(REG_ZERO, REG_RESULT, 0);
3727 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3728 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3730 a = dseg_addaddress(cd, &_exceptionptr);
3731 M_ALD(REG_ITMP3, REG_PV, a);
3732 M_ALD(REG_ITMP1_XPTR, REG_ITMP3, 0);
3733 M_AST(REG_ZERO, REG_ITMP3, 0);
3736 a = dseg_addaddress(cd, asm_handle_exception);
3737 M_ALD(REG_ITMP3, REG_PV, a);
3739 M_JMP(REG_ZERO, REG_ITMP3);
3743 /* generate null pointer check stubs */
3747 for (bref = cd->xnullrefs; bref != NULL; bref = bref->next) {
3748 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3749 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3751 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3755 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3757 (u1 *) mcodeptr - cd->mcodebase);
3761 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3763 if (xcodeptr != NULL) {
3764 M_BR(xcodeptr - mcodeptr - 1);
3767 xcodeptr = mcodeptr;
3769 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3770 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3772 a = dseg_addaddress(cd, string_java_lang_NullPointerException);
3773 M_ALD(rd->argintregs[0], REG_PV, a);
3775 a = dseg_addaddress(cd, new_exception);
3776 M_ALD(REG_PV, REG_PV, a);
3777 M_JSR(REG_RA, REG_PV);
3780 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3781 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3783 s4 ml = -s1, mh = 0;
3784 while (ml < -32768) { ml += 65536; mh--; }
3785 M_LDA(REG_PV, REG_RA, ml);
3786 M_LDAH(REG_PV, REG_PV, mh);
3789 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3791 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3792 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3794 a = dseg_addaddress(cd, asm_handle_exception);
3795 M_ALD(REG_ITMP3, REG_PV, a);
3797 M_JMP(REG_ZERO, REG_ITMP3);
3801 /* generate put/getstatic stub call code */
3808 for (cref = cd->clinitrefs; cref != NULL; cref = cref->next) {
3809 /* Get machine code which is patched back in later. The call is */
3810 /* 1 instruction word long. */
3811 xcodeptr = cd->mcodebase + cref->branchpos;
3814 /* patch in the call to call the following code (done at compile */
3817 tmpmcodeptr = mcodeptr; /* save current mcodeptr */
3818 mcodeptr = xcodeptr; /* set mcodeptr to patch position */
3820 M_BSR(REG_RA, tmpmcodeptr - (xcodeptr + 1));
3822 mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
3826 /* move class pointer into REG_ITMP2 */
3827 a = dseg_addaddress(cd, cref->class);
3828 M_ALD(REG_ITMP1, REG_PV, a);
3830 /* move machine code onto stack */
3831 a = dseg_adds4(cd, mcode);
3832 M_ILD(REG_ITMP3, REG_PV, a);
3833 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3834 M_IST(REG_ITMP3, REG_SP, 0);
3836 a = dseg_addaddress(cd, asm_check_clinit);
3837 M_ALD(REG_ITMP2, REG_PV, a);
3838 M_JMP(REG_ZERO, REG_ITMP2);
3843 codegen_finish(m, cd, (s4) ((u1 *) mcodeptr - cd->mcodebase));
3847 /* function createcompilerstub *************************************************
3849 creates a stub routine which calls the compiler
3851 *******************************************************************************/
3853 #define COMPSTUBSIZE 3
3855 u1 *createcompilerstub(methodinfo *m)
3857 u8 *s = CNEW(u8, COMPSTUBSIZE); /* memory to hold the stub */
3858 s4 *mcodeptr = (s4 *) s; /* code generation pointer */
3860 /* code for the stub */
3861 M_ALD(REG_PV, REG_PV, 16); /* load pointer to the compiler */
3862 M_JMP(0, REG_PV); /* jump to the compiler, return address
3863 in reg 0 is used as method pointer */
3864 s[1] = (u8) m; /* literals to be adressed */
3865 s[2] = (u8) asm_call_jit_compiler; /* jump directly via PV from above */
3867 #if defined(STATISTICS)
3869 count_cstub_len += COMPSTUBSIZE * 8;
3876 /* function removecompilerstub *************************************************
3878 deletes a compilerstub from memory (simply by freeing it)
3880 *******************************************************************************/
3882 void removecompilerstub(u1 *stub)
3884 CFREE(stub, COMPSTUBSIZE * 8);
3888 /* function: createnativestub **************************************************
3890 creates a stub routine which calls a native method
3892 *******************************************************************************/
3894 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3895 #define NATIVESTUB_STACK 2
3896 #define NATIVESTUB_THREAD_EXTRA 6
3898 #define NATIVESTUB_STACK 1
3899 #define NATIVESTUB_THREAD_EXTRA 1
3902 #define NATIVESTUB_SIZE (44 + NATIVESTUB_THREAD_EXTRA - 1)
3903 #define NATIVESTUB_STATIC_SIZE 4
3904 #define NATIVESTUB_VERBOSE_SIZE (39 + 13)
3905 #define NATIVESTUB_OFFSET 10
3907 u1 *createnativestub(functionptr f, methodinfo *m)
3909 u8 *s; /* memory pointer to hold the stub */
3911 s4 *mcodeptr; /* code generation pointer */
3912 s4 stackframesize = 0; /* size of stackframe if needed */
3917 t_inlining_globals *id;
3920 /* mark start of dump memory area */
3922 dumpsize = dump_size();
3924 /* setup registers before using it */
3926 cd = DNEW(codegendata);
3927 rd = DNEW(registerdata);
3928 id = DNEW(t_inlining_globals);
3930 inlining_setup(m, id);
3931 reg_setup(m, rd, id);
3933 descriptor2types(m); /* set paramcount and paramtypes */
3935 stubsize = NATIVESTUB_SIZE; /* calculate nativestub size */
3937 if ((m->flags & ACC_STATIC) && !m->class->initialized)
3938 stubsize += NATIVESTUB_STATIC_SIZE;
3941 stubsize += NATIVESTUB_VERBOSE_SIZE;
3943 s = CNEW(u8, stubsize); /* memory to hold the stub */
3944 cs = s + NATIVESTUB_OFFSET;
3945 mcodeptr = (s4 *) cs; /* code generation pointer */
3947 /* set some required varibles which are normally set by codegen_setup */
3948 cd->mcodebase = mcodeptr;
3949 cd->clinitrefs = NULL;
3951 *(cs-1) = (u8) f; /* address of native method */
3952 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3953 *(cs-2) = (u8) &builtin_get_exceptionptrptr;
3955 *(cs-2) = (u8) (&_exceptionptr); /* address of exceptionptr */
3957 *(cs-3) = (u8) asm_handle_nat_exception; /* addr of asm exception handler*/
3958 *(cs-4) = (u8) (&env); /* addr of jni_environement */
3959 *(cs-5) = (u8) builtin_trace_args;
3961 *(cs-7) = (u8) builtin_displaymethodstop;
3962 *(cs-8) = (u8) m->class;
3963 *(cs-9) = (u8) asm_check_clinit;
3964 *(cs-10) = (u8) NULL; /* filled with machine code */
3966 M_LDA(REG_SP, REG_SP, -NATIVESTUB_STACK * 8); /* build up stackframe */
3967 M_AST(REG_RA, REG_SP, 0 * 8); /* store return address */
3969 /* if function is static, check for initialized */
3971 if (m->flags & ACC_STATIC) {
3972 /* if class isn't yet initialized, do it */
3973 if (!m->class->initialized) {
3974 codegen_addclinitref(cd, mcodeptr, m->class);
3978 /* max. 39 instructions */
3982 M_LDA(REG_SP, REG_SP, -((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
3983 M_AST(REG_RA, REG_SP, 1 * 8);
3985 /* save integer argument registers */
3986 for (p = 0; p < m->paramcount && p < INT_ARG_CNT; p++) {
3987 M_LST(rd->argintregs[p], REG_SP, (2 + p) * 8);
3990 /* save and copy float arguments into integer registers */
3991 for (p = 0; p < m->paramcount && p < FLT_ARG_CNT; p++) {
3992 t = m->paramtypes[p];
3994 if (IS_FLT_DBL_TYPE(t)) {
3995 if (IS_2_WORD_TYPE(t)) {
3996 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
3997 M_LLD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4000 M_FST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4001 M_ILD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4005 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4009 M_ALD(REG_ITMP1, REG_PV, -6 * 8);
4010 M_AST(REG_ITMP1, REG_SP, 0 * 8);
4011 M_ALD(REG_PV, REG_PV, -5 * 8);
4012 M_JSR(REG_RA, REG_PV);
4013 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4014 M_LDA(REG_PV, REG_RA, disp);
4016 for (p = 0; p < m->paramcount && p < INT_ARG_CNT; p++) {
4017 M_LLD(rd->argintregs[p], REG_SP, (2 + p) * 8);
4020 for (p = 0; p < m->paramcount && p < FLT_ARG_CNT; p++) {
4021 t = m->paramtypes[p];
4023 if (IS_FLT_DBL_TYPE(t)) {
4024 if (IS_2_WORD_TYPE(t)) {
4025 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4028 M_FLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4032 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4036 M_ALD(REG_RA, REG_SP, 1 * 8);
4037 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT + 2) * 8);
4040 /* save argument registers on stack -- if we have to */
4041 if ((m->flags & ACC_STATIC && m->paramcount > (INT_ARG_CNT - 2)) || m->paramcount > (INT_ARG_CNT - 1)) {
4043 s4 paramshiftcnt = (m->flags & ACC_STATIC) ? 2 : 1;
4044 s4 stackparamcnt = (m->paramcount > INT_ARG_CNT) ? m->paramcount - INT_ARG_CNT : 0;
4046 stackframesize = stackparamcnt + paramshiftcnt;
4048 M_LDA(REG_SP, REG_SP, -stackframesize * 8);
4050 /* copy stack arguments into new stack frame -- if any */
4051 for (i = 0; i < stackparamcnt; i++) {
4052 M_LLD(REG_ITMP1, REG_SP, (stackparamcnt + 1 + i) * 8);
4053 M_LST(REG_ITMP1, REG_SP, (paramshiftcnt + i) * 8);
4056 if (m->flags & ACC_STATIC) {
4057 if (IS_FLT_DBL_TYPE(m->paramtypes[5])) {
4058 M_DST(rd->argfltregs[5], REG_SP, 1 * 8);
4060 M_LST(rd->argintregs[5], REG_SP, 1 * 8);
4063 if (IS_FLT_DBL_TYPE(m->paramtypes[4])) {
4064 M_DST(rd->argfltregs[4], REG_SP, 0 * 8);
4066 M_LST(rd->argintregs[4], REG_SP, 0 * 8);
4070 if (IS_FLT_DBL_TYPE(m->paramtypes[5])) {
4071 M_DST(rd->argfltregs[5], REG_SP, 0 * 8);
4073 M_LST(rd->argintregs[5], REG_SP, 0 * 8);
4078 if (m->flags & ACC_STATIC) {
4079 M_MOV(rd->argintregs[3], rd->argintregs[5]);
4080 M_MOV(rd->argintregs[2], rd->argintregs[4]);
4081 M_MOV(rd->argintregs[1], rd->argintregs[3]);
4082 M_MOV(rd->argintregs[0], rd->argintregs[2]);
4083 M_FMOV(rd->argfltregs[3], rd->argfltregs[5]);
4084 M_FMOV(rd->argfltregs[2], rd->argfltregs[4]);
4085 M_FMOV(rd->argfltregs[1], rd->argfltregs[3]);
4086 M_FMOV(rd->argfltregs[0], rd->argfltregs[2]);
4088 /* put class into second argument register */
4089 M_ALD(rd->argintregs[1], REG_PV, -8 * 8);
4092 M_MOV(rd->argintregs[4], rd->argintregs[5]);
4093 M_MOV(rd->argintregs[3], rd->argintregs[4]);
4094 M_MOV(rd->argintregs[2], rd->argintregs[3]);
4095 M_MOV(rd->argintregs[1], rd->argintregs[2]);
4096 M_MOV(rd->argintregs[0], rd->argintregs[1]);
4097 M_FMOV(rd->argfltregs[4], rd->argfltregs[5]);
4098 M_FMOV(rd->argfltregs[3], rd->argfltregs[4]);
4099 M_FMOV(rd->argfltregs[2], rd->argfltregs[3]);
4100 M_FMOV(rd->argfltregs[1], rd->argfltregs[2]);
4101 M_FMOV(rd->argfltregs[0], rd->argfltregs[1]);
4104 /* put env into first argument register */
4105 M_ALD(rd->argintregs[0], REG_PV, -4 * 8);
4107 M_ALD(REG_PV, REG_PV, -1 * 8); /* load adress of native method */
4108 M_JSR(REG_RA, REG_PV); /* call native method */
4109 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4110 M_LDA(REG_PV, REG_RA, disp); /* recompute pv from ra */
4112 /* remove stackframe if there is one */
4113 if (stackframesize) {
4114 M_LDA(REG_SP, REG_SP, stackframesize * 8);
4117 /* 13 instructions */
4119 M_LDA(REG_SP, REG_SP, -2 * 8);
4120 M_ALD(rd->argintregs[0], REG_PV, -6 * 8); /* load method adress */
4121 M_LST(REG_RESULT, REG_SP, 0 * 8);
4122 M_DST(REG_FRESULT, REG_SP, 1 * 8);
4123 M_MOV(REG_RESULT, rd->argintregs[1]);
4124 M_FMOV(REG_FRESULT, rd->argfltregs[2]);
4125 M_FMOV(REG_FRESULT, rd->argfltregs[3]);
4126 M_ALD(REG_PV, REG_PV, -7 * 8); /* builtin_displaymethodstop */
4127 M_JSR(REG_RA, REG_PV);
4128 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4129 M_LDA(REG_PV, REG_RA, disp);
4130 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4131 M_DLD(REG_FRESULT, REG_SP, 1 * 8);
4132 M_LDA(REG_SP, REG_SP, 2 * 8);
4135 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4136 if (IS_FLT_DBL_TYPE(m->returntype))
4137 M_DST(REG_FRESULT, REG_SP, 1 * 8);
4139 M_AST(REG_RESULT, REG_SP, 1 * 8);
4140 M_ALD(REG_PV, REG_PV, -2 * 8); /* builtin_get_exceptionptrptr */
4141 M_JSR(REG_RA, REG_PV);
4142 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4143 M_LDA(REG_PV, REG_RA, disp);
4144 M_MOV(REG_RESULT, REG_ITMP3);
4145 if (IS_FLT_DBL_TYPE(m->returntype))
4146 M_DLD(REG_FRESULT, REG_SP, 1 * 8);
4148 M_ALD(REG_RESULT, REG_SP, 1 * 8);
4150 M_ALD(REG_ITMP3, REG_PV, -2 * 8); /* get address of exceptionptr */
4152 M_ALD(REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
4153 M_BNEZ(REG_ITMP1, 3); /* if no exception then return */
4155 M_ALD(REG_RA, REG_SP, 0 * 8); /* load return address */
4156 M_LDA(REG_SP, REG_SP, NATIVESTUB_STACK * 8); /* remove stackframe */
4157 M_RET(REG_ZERO, REG_RA); /* return to caller */
4159 M_AST(REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
4161 M_ALD(REG_RA, REG_SP, 0 * 8); /* load return address */
4162 M_LDA(REG_SP, REG_SP, NATIVESTUB_STACK * 8); /* remove stackframe */
4163 M_LDA(REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
4164 M_ALD(REG_ITMP3, REG_PV, -3 * 8); /* load asm exception handler address */
4165 M_JMP(REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
4167 /* generate put/getstatic stub call code */
4174 /* there can only be one clinit ref entry */
4175 cref = cd->clinitrefs;
4178 /* Get machine code which is patched back in later. The call is */
4179 /* 2 instruction words long. */
4180 xcodeptr = cd->mcodebase + cref->branchpos;
4181 *(cs-10) = (u4) *xcodeptr;
4183 /* patch in the call to call the following code (done at compile */
4186 tmpmcodeptr = mcodeptr; /* save current mcodeptr */
4187 mcodeptr = xcodeptr; /* set mcodeptr to patch position */
4189 M_BSR(REG_RA, tmpmcodeptr - (xcodeptr + 1));
4191 mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
4193 /* move class pointer into REG_ITMP2 */
4194 M_ALD(REG_ITMP1, REG_PV, -8 * 8); /* class */
4196 /* move machine code into REG_ITMP3 */
4197 M_ILD(REG_ITMP3, REG_PV, -10 * 8); /* machine code */
4198 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
4199 M_IST(REG_ITMP3, REG_SP, 0);
4201 M_ALD(REG_ITMP2, REG_PV, -9 * 8); /* asm_check_clinit */
4202 M_JMP(REG_ZERO, REG_ITMP2);
4207 dolog_plain("stubsize: %d (for %d params)\n", (int) (mcodeptr - (s4*) s), m->paramcount);
4210 #if defined(STATISTICS)
4212 count_nstub_len += NATIVESTUB_SIZE * 8;
4215 /* release dump area */
4217 dump_release(dumpsize);
4219 return (u1 *) (s + NATIVESTUB_OFFSET);
4223 /* function: removenativestub **************************************************
4225 removes a previously created native-stub from memory
4227 *******************************************************************************/
4229 void removenativestub(u1 *stub)
4231 CFREE((u8 *) stub - NATIVESTUBOFFSET, NATIVESTUBSIZE * 8);
4236 * These are local overrides for various environment variables in Emacs.
4237 * Please do not remove this and leave it at the end of the file, where
4238 * Emacs will automagically detect them.
4239 * ---------------------------------------------------------------------
4242 * indent-tabs-mode: t