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 1468 2004-11-08 13:29:58Z twisti $
41 #include "jit/alpha/codegen.h"
43 #include "jit/parse.h"
54 /* *****************************************************************************
56 Datatypes and Register Allocations:
57 -----------------------------------
59 On 64-bit-machines (like the Alpha) all operands are stored in the
60 registers in a 64-bit form, even when the correspondig JavaVM operands
61 only need 32 bits. This is done by a canonical representation:
63 32-bit integers are allways stored as sign-extended 64-bit values (this
64 approach is directly supported by the Alpha architecture and is very easy
67 32-bit-floats are stored in a 64-bit doubleprecision register by simply
68 expanding the exponent and mantissa with zeroes. (also supported by the
74 The calling conventions and the layout of the stack is explained in detail
75 in the documention file: calling.doc
77 *******************************************************************************/
80 /* register descripton - array ************************************************/
82 /* #define REG_RES 0 reserved register for OS or code generator */
83 /* #define REG_RET 1 return value register */
84 /* #define REG_EXC 2 exception value register (only old jit) */
85 /* #define REG_SAV 3 (callee) saved register */
86 /* #define REG_TMP 4 scratch temporary register (caller saved) */
87 /* #define REG_ARG 5 argument register (caller saved) */
89 /* #define REG_END -1 last entry in tables */
92 REG_RET, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
93 REG_TMP, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
94 REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_TMP, REG_TMP,
95 REG_TMP, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES,
98 /* for use of reserved registers, see comment above */
100 int nregdescfloat[] = {
101 REG_RET, REG_TMP, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
102 REG_SAV, REG_SAV, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
103 REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_TMP, REG_TMP,
104 REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_RES, REG_RES, REG_RES, REG_RES,
107 /* for use of reserved registers, see comment above */
109 /* include independent code generation stuff -- include after register */
110 /* descriptions to avoid extern definitions */
112 #include "jit/codegen.inc"
113 #include "jit/reg.inc"
116 /* NullPointerException handlers and exception handling initialisation */
118 typedef struct sigctx_struct {
119 long sc_onstack; /* sigstack state to restore */
120 long sc_mask; /* signal mask to restore */
121 long sc_pc; /* pc at time of signal */
122 long sc_ps; /* psl to retore */
123 long sc_regs[32]; /* processor regs 0 to 31 */
124 long sc_ownedfp; /* fp has been used */
125 long sc_fpregs[32]; /* fp regs 0 to 31 */
126 unsigned long sc_fpcr; /* floating point control register */
127 unsigned long sc_fp_control; /* software fpcr */
129 unsigned long sc_reserved1, sc_reserved2;
130 unsigned long sc_ssize;
132 unsigned long sc_traparg_a0;
133 unsigned long sc_traparg_a1;
134 unsigned long sc_traparg_a2;
135 unsigned long sc_fp_trap_pc;
136 unsigned long sc_fp_trigger_sum;
137 unsigned long sc_fp_trigger_inst;
138 unsigned long sc_retcode[2];
142 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
143 void thread_restartcriticalsection(ucontext_t *uc)
146 if ((critical = thread_checkcritical((void*) uc->uc_mcontext.sc_pc)) != NULL)
147 uc->uc_mcontext.sc_pc = (u8) critical;
151 /* NullPointerException signal handler for hardware null pointer check */
153 void catch_NullPointerException(int sig, int code, sigctx_struct *sigctx)
158 java_objectheader *xptr;
160 /* Reset signal handler - necessary for SysV, does no harm for BSD */
162 instr = *((int*)(sigctx->sc_pc));
163 faultaddr = sigctx->sc_regs[(instr >> 16) & 0x1f];
165 if (faultaddr == 0) {
166 signal(sig, (void*) catch_NullPointerException); /* reinstall handler */
168 sigaddset(&nsig, sig);
169 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
171 xptr = new_exception(string_java_lang_NullPointerException);
173 sigctx->sc_regs[REG_ITMP1_XPTR] = (u8) xptr;
174 sigctx->sc_regs[REG_ITMP2_XPC] = sigctx->sc_pc;
175 sigctx->sc_pc = (u8) asm_handle_exception;
179 faultaddr += (long) ((instr << 16) >> 16);
180 fprintf(stderr, "faulting address: 0x%016lx\n", faultaddr);
181 panic("Stack overflow");
188 void init_exceptions(void)
193 /* Linux on Digital Alpha needs an initialisation of the ieee floating point
194 control for IEEE compliant arithmetic (option -mieee of GCC). Under
195 Digital Unix this is done automatically.
200 extern unsigned long ieee_get_fp_control();
201 extern void ieee_set_fp_control(unsigned long fp_control);
203 void init_exceptions(void)
205 /* initialize floating point control */
207 ieee_set_fp_control(ieee_get_fp_control()
208 & ~IEEE_TRAP_ENABLE_INV
209 & ~IEEE_TRAP_ENABLE_DZE
210 /* & ~IEEE_TRAP_ENABLE_UNF we dont want underflow */
211 & ~IEEE_TRAP_ENABLE_OVF);
214 /* install signal handlers we need to convert to exceptions */
218 signal(SIGSEGV, (void*) catch_NullPointerException);
222 signal(SIGBUS, (void*) catch_NullPointerException);
228 /* function gen_mcode **********************************************************
230 generates machine code
232 *******************************************************************************/
234 void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
236 s4 len, s1, s2, s3, d;
250 savedregs_num = (m->isleafmethod) ? 0 : 1; /* space to save the RA */
252 /* space to save used callee saved registers */
254 savedregs_num += (rd->savintregcnt - rd->maxsavintreguse);
255 savedregs_num += (rd->savfltregcnt - rd->maxsavfltreguse);
257 parentargs_base = rd->maxmemuse + savedregs_num;
259 #if defined(USE_THREADS) /* space to save argument of monitor_enter */
261 if (checksync && (m->flags & ACC_SYNCHRONIZED))
266 /* create method header */
268 (void) dseg_addaddress(cd, m); /* MethodPointer */
269 (void) dseg_adds4(cd, parentargs_base * 8); /* FrameSize */
271 #if defined(USE_THREADS)
273 /* IsSync contains the offset relative to the stack pointer for the
274 argument of monitor_exit used in the exception handler. Since the
275 offset could be zero and give a wrong meaning of the flag it is
279 if (checksync && (m->flags & ACC_SYNCHRONIZED))
280 (void) dseg_adds4(cd, (rd->maxmemuse + 1) * 8); /* IsSync */
285 (void) dseg_adds4(cd, 0); /* IsSync */
287 (void) dseg_adds4(cd, m->isleafmethod); /* IsLeaf */
288 (void) dseg_adds4(cd, rd->savintregcnt - rd->maxsavintreguse);/* IntSave */
289 (void) dseg_adds4(cd, rd->savfltregcnt - rd->maxsavfltreguse);/* FltSave */
291 dseg_addlinenumbertablesize(cd);
293 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
295 /* create exception table */
297 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
298 dseg_addtarget(cd, ex->start);
299 dseg_addtarget(cd, ex->end);
300 dseg_addtarget(cd, ex->handler);
301 (void) dseg_addaddress(cd, ex->catchtype);
304 /* initialize mcode variables */
306 mcodeptr = (s4 *) cd->mcodebase;
307 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
308 MCODECHECK(128 + m->paramcount);
310 /* create stack frame (if necessary) */
312 if (parentargs_base) {
313 M_LDA(REG_SP, REG_SP, -parentargs_base * 8);
316 /* save return address and used callee saved registers */
319 if (!m->isleafmethod) {
320 p--; M_AST(REG_RA, REG_SP, p * 8);
322 for (i = rd->savintregcnt - 1; i >= rd->maxsavintreguse; i--) {
323 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
325 for (i = rd->savfltregcnt - 1; i >= rd->maxsavfltreguse; i--) {
326 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
329 /* save monitorenter argument */
331 #if defined(USE_THREADS)
332 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
333 if (m->flags & ACC_STATIC) {
334 p = dseg_addaddress(cd, m->class);
335 M_ALD(REG_ITMP1, REG_PV, p);
336 M_AST(REG_ITMP1, REG_SP, rd->maxmemuse * 8);
339 M_AST(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
344 /* copy argument registers to stack and call trace function with pointer
345 to arguments on stack.
350 M_LDA(REG_SP, REG_SP, -((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
351 M_AST(REG_RA, REG_SP, 1 * 8);
353 /* save integer argument registers */
354 for (p = 0; /* p < m->paramcount && */ p < INT_ARG_CNT; p++) {
355 M_LST(rd->argintregs[p], REG_SP, (2 + p) * 8);
358 /* save and copy float arguments into integer registers */
359 for (p = 0; /* p < m->paramcount && */ p < FLT_ARG_CNT; p++) {
360 t = m->paramtypes[p];
362 if (IS_FLT_DBL_TYPE(t)) {
363 if (IS_2_WORD_TYPE(t)) {
364 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
367 M_FST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
370 M_LLD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
373 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
377 p = dseg_addaddress(cd, m);
378 M_ALD(REG_ITMP1, REG_PV, p);
379 M_AST(REG_ITMP1, REG_SP, 0 * 8);
380 p = dseg_addaddress(cd, (void *) builtin_trace_args);
381 M_ALD(REG_PV, REG_PV, p);
382 M_JSR(REG_RA, REG_PV);
383 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
384 M_LDA(REG_PV, REG_RA, disp);
385 M_ALD(REG_RA, REG_SP, 1 * 8);
387 for (p = 0; /* p < mparamcount && */ p < INT_ARG_CNT; p++) {
388 M_LLD(rd->argintregs[p], REG_SP, (2 + p) * 8);
391 for (p = 0; /* p < mparamcount && */ p < FLT_ARG_CNT; p++) {
392 t = m->paramtypes[p];
394 if (IS_FLT_DBL_TYPE(t)) {
395 if (IS_2_WORD_TYPE(t)) {
396 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
399 M_FLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
403 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
407 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT + 2) * 8);
410 /* take arguments out of register or stack frame */
412 for (p = 0, l = 0; p < m->paramcount; p++) {
413 t = m->paramtypes[p];
414 var = &(rd->locals[l][t]);
416 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
420 if (IS_INT_LNG_TYPE(t)) { /* integer args */
421 if (p < INT_ARG_CNT) { /* register arguments */
422 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
423 M_INTMOVE(rd->argintregs[p], var->regoff);
424 } else { /* reg arg -> spilled */
425 M_LST(rd->argintregs[p], REG_SP, 8 * var->regoff);
428 } else { /* stack arguments */
429 pa = p - INT_ARG_CNT;
430 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
431 M_LLD(var->regoff, REG_SP, 8 * (parentargs_base + pa));
433 } else { /* stack arg -> spilled */
434 M_LLD(REG_ITMP1, REG_SP, 8 * (parentargs_base + pa));
435 M_LST(REG_ITMP1, REG_SP, 8 * var->regoff);
439 } else { /* floating args */
440 if (p < FLT_ARG_CNT) { /* register arguments */
441 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
442 M_FLTMOVE(rd->argfltregs[p], var->regoff);
444 } else { /* reg arg -> spilled */
445 M_DST(rd->argfltregs[p], REG_SP, 8 * var->regoff);
448 } else { /* stack arguments */
449 pa = p - FLT_ARG_CNT;
450 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
451 M_DLD(var->regoff, REG_SP, 8 * (parentargs_base + pa) );
453 } else { /* stack-arg -> spilled */
454 M_DLD(REG_FTMP1, REG_SP, 8 * (parentargs_base + pa));
455 M_DST(REG_FTMP1, REG_SP, 8 * var->regoff);
461 /* call monitorenter function */
463 #if defined(USE_THREADS)
464 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
466 s8 func_enter = (m->flags & ACC_STATIC) ?
467 (s8) builtin_staticmonitorenter : (s8) builtin_monitorenter;
468 p = dseg_addaddress(cd, (void*) func_enter);
469 M_ALD(REG_PV, REG_PV, p);
470 M_ALD(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
471 M_JSR(REG_RA, REG_PV);
472 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
473 M_LDA(REG_PV, REG_RA, disp);
478 /* end of header generation */
480 /* walk through all basic blocks */
481 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
483 bptr->mpc = (s4) ((u1 *) mcodeptr - cd->mcodebase);
485 if (bptr->flags >= BBREACHED) {
487 /* branch resolving */
491 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
492 gen_resolvebranch((u1*) cd->mcodebase + brefs->branchpos,
493 brefs->branchpos, bptr->mpc);
497 /* copy interface registers to their destination */
502 while (src != NULL) {
504 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
505 d = reg_of_var(rd, src, REG_ITMP1);
506 M_INTMOVE(REG_ITMP1, d);
507 store_reg_to_var_int(src, d);
510 d = reg_of_var(rd, src, REG_IFTMP);
511 if ((src->varkind != STACKVAR)) {
513 if (IS_FLT_DBL_TYPE(s2)) {
514 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
515 s1 = rd->interfaces[len][s2].regoff;
519 M_DLD(d, REG_SP, 8 * rd->interfaces[len][s2].regoff);
521 store_reg_to_var_flt(src, d);
524 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
525 s1 = rd->interfaces[len][s2].regoff;
529 M_LLD(d, REG_SP, 8 * rd->interfaces[len][s2].regoff);
531 store_reg_to_var_int(src, d);
538 /* walk through all instructions */
542 for (iptr = bptr->iinstr;
544 src = iptr->dst, len--, iptr++) {
546 MCODECHECK(64); /* an instruction usually needs < 64 words */
549 case ICMD_NOP: /* ... ==> ... */
552 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
554 var_to_reg_int(s1, src, REG_ITMP1);
556 codegen_addxnullrefs(cd, mcodeptr);
559 /* constant operations ************************************************/
561 case ICMD_ICONST: /* ... ==> ..., constant */
562 /* op1 = 0, val.i = constant */
564 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
565 ICONST(d, iptr->val.i);
566 store_reg_to_var_int(iptr->dst, d);
569 case ICMD_LCONST: /* ... ==> ..., constant */
570 /* op1 = 0, val.l = constant */
572 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
573 LCONST(d, iptr->val.l);
574 store_reg_to_var_int(iptr->dst, d);
577 case ICMD_FCONST: /* ... ==> ..., constant */
578 /* op1 = 0, val.f = constant */
580 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
581 a = dseg_addfloat(cd, iptr->val.f);
583 store_reg_to_var_flt(iptr->dst, d);
586 case ICMD_DCONST: /* ... ==> ..., constant */
587 /* op1 = 0, val.d = constant */
589 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
590 a = dseg_adddouble(cd, iptr->val.d);
592 store_reg_to_var_flt(iptr->dst, d);
595 case ICMD_ACONST: /* ... ==> ..., constant */
596 /* op1 = 0, val.a = constant */
598 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
600 a = dseg_addaddress(cd, iptr->val.a);
603 M_INTMOVE(REG_ZERO, d);
605 store_reg_to_var_int(iptr->dst, d);
609 /* load/store operations **********************************************/
611 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
612 case ICMD_LLOAD: /* op1 = local variable */
615 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
616 if ((iptr->dst->varkind == LOCALVAR) &&
617 (iptr->dst->varnum == iptr->op1))
619 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
620 if (var->flags & INMEMORY)
621 M_LLD(d, REG_SP, 8 * var->regoff);
623 {M_INTMOVE(var->regoff,d);}
624 store_reg_to_var_int(iptr->dst, d);
627 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
628 case ICMD_DLOAD: /* op1 = local variable */
630 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
631 if ((iptr->dst->varkind == LOCALVAR) &&
632 (iptr->dst->varnum == iptr->op1))
634 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
635 if (var->flags & INMEMORY)
636 M_DLD(d, REG_SP, 8 * var->regoff);
638 {M_FLTMOVE(var->regoff,d);}
639 store_reg_to_var_flt(iptr->dst, d);
643 case ICMD_ISTORE: /* ..., value ==> ... */
644 case ICMD_LSTORE: /* op1 = local variable */
647 if ((src->varkind == LOCALVAR) &&
648 (src->varnum == iptr->op1))
650 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
651 if (var->flags & INMEMORY) {
652 var_to_reg_int(s1, src, REG_ITMP1);
653 M_LST(s1, REG_SP, 8 * var->regoff);
656 var_to_reg_int(s1, src, var->regoff);
657 M_INTMOVE(s1, var->regoff);
661 case ICMD_FSTORE: /* ..., value ==> ... */
662 case ICMD_DSTORE: /* op1 = local variable */
664 if ((src->varkind == LOCALVAR) &&
665 (src->varnum == iptr->op1))
667 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
668 if (var->flags & INMEMORY) {
669 var_to_reg_flt(s1, src, REG_FTMP1);
670 M_DST(s1, REG_SP, 8 * var->regoff);
673 var_to_reg_flt(s1, src, var->regoff);
674 M_FLTMOVE(s1, var->regoff);
679 /* pop/dup/swap operations ********************************************/
681 /* attention: double and longs are only one entry in CACAO ICMDs */
683 case ICMD_POP: /* ..., value ==> ... */
684 case ICMD_POP2: /* ..., value, value ==> ... */
687 case ICMD_DUP: /* ..., a ==> ..., a, a */
688 M_COPY(src, iptr->dst);
691 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
693 M_COPY(src, iptr->dst);
694 M_COPY(src->prev, iptr->dst->prev);
695 M_COPY(iptr->dst, iptr->dst->prev->prev);
698 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
700 M_COPY(src, iptr->dst);
701 M_COPY(src->prev, iptr->dst->prev);
702 M_COPY(src->prev->prev, iptr->dst->prev->prev);
703 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
706 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
708 M_COPY(src, iptr->dst);
709 M_COPY(src->prev, iptr->dst->prev);
712 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
714 M_COPY(src, iptr->dst);
715 M_COPY(src->prev, iptr->dst->prev);
716 M_COPY(src->prev->prev, iptr->dst->prev->prev);
717 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
718 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev);
721 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
723 M_COPY(src, iptr->dst);
724 M_COPY(src->prev, iptr->dst->prev);
725 M_COPY(src->prev->prev, iptr->dst->prev->prev);
726 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
727 M_COPY(iptr->dst, iptr->dst->prev->prev->prev->prev);
728 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev->prev);
731 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
733 M_COPY(src, iptr->dst->prev);
734 M_COPY(src->prev, iptr->dst);
738 /* integer operations *************************************************/
740 case ICMD_INEG: /* ..., value ==> ..., - value */
742 var_to_reg_int(s1, src, REG_ITMP1);
743 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
744 M_ISUB(REG_ZERO, s1, d);
745 store_reg_to_var_int(iptr->dst, d);
748 case ICMD_LNEG: /* ..., value ==> ..., - value */
750 var_to_reg_int(s1, src, REG_ITMP1);
751 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
752 M_LSUB(REG_ZERO, s1, d);
753 store_reg_to_var_int(iptr->dst, d);
756 case ICMD_I2L: /* ..., value ==> ..., value */
758 var_to_reg_int(s1, src, REG_ITMP1);
759 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
761 store_reg_to_var_int(iptr->dst, d);
764 case ICMD_L2I: /* ..., value ==> ..., value */
766 var_to_reg_int(s1, src, REG_ITMP1);
767 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
768 M_IADD(s1, REG_ZERO, d );
769 store_reg_to_var_int(iptr->dst, d);
772 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
774 var_to_reg_int(s1, src, REG_ITMP1);
775 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
776 if (has_ext_instr_set) {
780 M_SLL_IMM(s1, 56, d);
781 M_SRA_IMM( d, 56, d);
783 store_reg_to_var_int(iptr->dst, d);
786 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
788 var_to_reg_int(s1, src, REG_ITMP1);
789 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
791 store_reg_to_var_int(iptr->dst, d);
794 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
796 var_to_reg_int(s1, src, REG_ITMP1);
797 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
798 if (has_ext_instr_set) {
802 M_SLL_IMM(s1, 48, d);
803 M_SRA_IMM( d, 48, d);
805 store_reg_to_var_int(iptr->dst, d);
809 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
811 var_to_reg_int(s1, src->prev, REG_ITMP1);
812 var_to_reg_int(s2, src, REG_ITMP2);
813 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
815 store_reg_to_var_int(iptr->dst, d);
818 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
819 /* val.i = constant */
821 var_to_reg_int(s1, src, REG_ITMP1);
822 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
823 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
824 M_IADD_IMM(s1, iptr->val.i, d);
827 ICONST(REG_ITMP2, iptr->val.i);
828 M_IADD(s1, REG_ITMP2, d);
830 store_reg_to_var_int(iptr->dst, d);
833 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
835 var_to_reg_int(s1, src->prev, REG_ITMP1);
836 var_to_reg_int(s2, src, REG_ITMP2);
837 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
839 store_reg_to_var_int(iptr->dst, d);
842 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
843 /* val.l = constant */
845 var_to_reg_int(s1, src, REG_ITMP1);
846 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
847 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
848 M_LADD_IMM(s1, iptr->val.l, d);
851 LCONST(REG_ITMP2, iptr->val.l);
852 M_LADD(s1, REG_ITMP2, d);
854 store_reg_to_var_int(iptr->dst, d);
857 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
859 var_to_reg_int(s1, src->prev, REG_ITMP1);
860 var_to_reg_int(s2, src, REG_ITMP2);
861 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
863 store_reg_to_var_int(iptr->dst, d);
866 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
867 /* val.i = constant */
869 var_to_reg_int(s1, src, REG_ITMP1);
870 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
871 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
872 M_ISUB_IMM(s1, iptr->val.i, d);
875 ICONST(REG_ITMP2, iptr->val.i);
876 M_ISUB(s1, REG_ITMP2, d);
878 store_reg_to_var_int(iptr->dst, d);
881 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
883 var_to_reg_int(s1, src->prev, REG_ITMP1);
884 var_to_reg_int(s2, src, REG_ITMP2);
885 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
887 store_reg_to_var_int(iptr->dst, d);
890 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
891 /* val.l = constant */
893 var_to_reg_int(s1, src, REG_ITMP1);
894 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
895 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
896 M_LSUB_IMM(s1, iptr->val.l, d);
899 LCONST(REG_ITMP2, iptr->val.l);
900 M_LSUB(s1, REG_ITMP2, d);
902 store_reg_to_var_int(iptr->dst, d);
905 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
907 var_to_reg_int(s1, src->prev, REG_ITMP1);
908 var_to_reg_int(s2, src, REG_ITMP2);
909 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
911 store_reg_to_var_int(iptr->dst, d);
914 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
915 /* val.i = constant */
917 var_to_reg_int(s1, src, REG_ITMP1);
918 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
919 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
920 M_IMUL_IMM(s1, iptr->val.i, d);
923 ICONST(REG_ITMP2, iptr->val.i);
924 M_IMUL(s1, REG_ITMP2, d);
926 store_reg_to_var_int(iptr->dst, d);
929 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
931 var_to_reg_int(s1, src->prev, REG_ITMP1);
932 var_to_reg_int(s2, src, REG_ITMP2);
933 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
935 store_reg_to_var_int(iptr->dst, d);
938 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
939 /* val.l = constant */
941 var_to_reg_int(s1, src, REG_ITMP1);
942 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
943 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
944 M_LMUL_IMM(s1, iptr->val.l, d);
947 LCONST(REG_ITMP2, iptr->val.l);
948 M_LMUL(s1, REG_ITMP2, d);
950 store_reg_to_var_int(iptr->dst, d);
953 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
954 case ICMD_LDIVPOW2: /* val.i = constant */
956 var_to_reg_int(s1, src, REG_ITMP1);
957 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
958 if (iptr->val.i <= 15) {
959 M_LDA(REG_ITMP2, s1, (1 << iptr->val.i) -1);
960 M_CMOVGE(s1, s1, REG_ITMP2);
963 M_SRA_IMM(s1, 63, REG_ITMP2);
964 M_SRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
965 M_LADD(s1, REG_ITMP2, REG_ITMP2);
967 M_SRA_IMM(REG_ITMP2, iptr->val.i, d);
968 store_reg_to_var_int(iptr->dst, d);
971 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
973 var_to_reg_int(s1, src->prev, REG_ITMP1);
974 var_to_reg_int(s2, src, REG_ITMP2);
975 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
976 M_AND_IMM(s2, 0x1f, REG_ITMP3);
977 M_SLL(s1, REG_ITMP3, d);
978 M_IADD(d, REG_ZERO, d);
979 store_reg_to_var_int(iptr->dst, d);
982 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
983 /* val.i = constant */
985 var_to_reg_int(s1, src, REG_ITMP1);
986 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
987 M_SLL_IMM(s1, iptr->val.i & 0x1f, d);
988 M_IADD(d, REG_ZERO, d);
989 store_reg_to_var_int(iptr->dst, d);
992 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
994 var_to_reg_int(s1, src->prev, REG_ITMP1);
995 var_to_reg_int(s2, src, REG_ITMP2);
996 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
997 M_AND_IMM(s2, 0x1f, REG_ITMP3);
998 M_SRA(s1, REG_ITMP3, d);
999 store_reg_to_var_int(iptr->dst, d);
1002 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1003 /* val.i = constant */
1005 var_to_reg_int(s1, src, REG_ITMP1);
1006 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1007 M_SRA_IMM(s1, iptr->val.i & 0x1f, d);
1008 store_reg_to_var_int(iptr->dst, d);
1011 case ICMD_IUSHR: /* ..., 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_ITMP2);
1018 M_SRL(d, REG_ITMP2, d);
1019 M_IADD(d, REG_ZERO, d);
1020 store_reg_to_var_int(iptr->dst, d);
1023 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1024 /* val.i = constant */
1026 var_to_reg_int(s1, src, REG_ITMP1);
1027 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1029 M_SRL_IMM(d, iptr->val.i & 0x1f, d);
1030 M_IADD(d, REG_ZERO, d);
1031 store_reg_to_var_int(iptr->dst, d);
1034 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1036 var_to_reg_int(s1, src->prev, REG_ITMP1);
1037 var_to_reg_int(s2, src, REG_ITMP2);
1038 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1040 store_reg_to_var_int(iptr->dst, d);
1043 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1044 /* val.i = constant */
1046 var_to_reg_int(s1, src, REG_ITMP1);
1047 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1048 M_SLL_IMM(s1, iptr->val.i & 0x3f, d);
1049 store_reg_to_var_int(iptr->dst, d);
1052 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1054 var_to_reg_int(s1, src->prev, REG_ITMP1);
1055 var_to_reg_int(s2, src, REG_ITMP2);
1056 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1058 store_reg_to_var_int(iptr->dst, d);
1061 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1062 /* val.i = constant */
1064 var_to_reg_int(s1, src, REG_ITMP1);
1065 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1066 M_SRA_IMM(s1, iptr->val.i & 0x3f, d);
1067 store_reg_to_var_int(iptr->dst, d);
1070 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1072 var_to_reg_int(s1, src->prev, REG_ITMP1);
1073 var_to_reg_int(s2, src, REG_ITMP2);
1074 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1076 store_reg_to_var_int(iptr->dst, d);
1079 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1080 /* val.i = constant */
1082 var_to_reg_int(s1, src, REG_ITMP1);
1083 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1084 M_SRL_IMM(s1, iptr->val.i & 0x3f, d);
1085 store_reg_to_var_int(iptr->dst, d);
1088 case ICMD_IAND: /* ..., 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_IANDCONST: /* ..., 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 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1104 M_AND_IMM(s1, iptr->val.i, d);
1106 else if (iptr->val.i == 0xffff) {
1109 else if (iptr->val.i == 0xffffff) {
1110 M_ZAPNOT_IMM(s1, 0x07, d);
1113 ICONST(REG_ITMP2, iptr->val.i);
1114 M_AND(s1, REG_ITMP2, d);
1116 store_reg_to_var_int(iptr->dst, d);
1119 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1120 /* val.i = constant */
1122 var_to_reg_int(s1, src, REG_ITMP1);
1123 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1125 M_MOV(s1, REG_ITMP1);
1128 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1129 M_AND_IMM(s1, iptr->val.i, d);
1131 M_ISUB(REG_ZERO, s1, d);
1132 M_AND_IMM(d, iptr->val.i, d);
1134 else if (iptr->val.i == 0xffff) {
1137 M_ISUB(REG_ZERO, s1, d);
1140 else if (iptr->val.i == 0xffffff) {
1141 M_ZAPNOT_IMM(s1, 0x07, d);
1143 M_ISUB(REG_ZERO, s1, d);
1144 M_ZAPNOT_IMM(d, 0x07, d);
1147 ICONST(REG_ITMP2, iptr->val.i);
1148 M_AND(s1, REG_ITMP2, d);
1150 M_ISUB(REG_ZERO, s1, d);
1151 M_AND(d, REG_ITMP2, d);
1153 M_ISUB(REG_ZERO, d, d);
1154 store_reg_to_var_int(iptr->dst, d);
1157 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1158 /* val.l = constant */
1160 var_to_reg_int(s1, src, REG_ITMP1);
1161 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1162 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1163 M_AND_IMM(s1, iptr->val.l, d);
1165 else if (iptr->val.l == 0xffffL) {
1168 else if (iptr->val.l == 0xffffffL) {
1169 M_ZAPNOT_IMM(s1, 0x07, d);
1171 else if (iptr->val.l == 0xffffffffL) {
1174 else if (iptr->val.l == 0xffffffffffL) {
1175 M_ZAPNOT_IMM(s1, 0x1f, d);
1177 else if (iptr->val.l == 0xffffffffffffL) {
1178 M_ZAPNOT_IMM(s1, 0x3f, d);
1180 else if (iptr->val.l == 0xffffffffffffffL) {
1181 M_ZAPNOT_IMM(s1, 0x7f, d);
1184 LCONST(REG_ITMP2, iptr->val.l);
1185 M_AND(s1, REG_ITMP2, d);
1187 store_reg_to_var_int(iptr->dst, d);
1190 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1191 /* val.l = constant */
1193 var_to_reg_int(s1, src, REG_ITMP1);
1194 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1196 M_MOV(s1, REG_ITMP1);
1199 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1200 M_AND_IMM(s1, iptr->val.l, d);
1202 M_LSUB(REG_ZERO, s1, d);
1203 M_AND_IMM(d, iptr->val.l, d);
1205 else if (iptr->val.l == 0xffffL) {
1208 M_LSUB(REG_ZERO, s1, d);
1211 else if (iptr->val.l == 0xffffffL) {
1212 M_ZAPNOT_IMM(s1, 0x07, d);
1214 M_LSUB(REG_ZERO, s1, d);
1215 M_ZAPNOT_IMM(d, 0x07, d);
1217 else if (iptr->val.l == 0xffffffffL) {
1220 M_LSUB(REG_ZERO, s1, d);
1223 else if (iptr->val.l == 0xffffffffffL) {
1224 M_ZAPNOT_IMM(s1, 0x1f, d);
1226 M_LSUB(REG_ZERO, s1, d);
1227 M_ZAPNOT_IMM(d, 0x1f, d);
1229 else if (iptr->val.l == 0xffffffffffffL) {
1230 M_ZAPNOT_IMM(s1, 0x3f, d);
1232 M_LSUB(REG_ZERO, s1, d);
1233 M_ZAPNOT_IMM(d, 0x3f, d);
1235 else if (iptr->val.l == 0xffffffffffffffL) {
1236 M_ZAPNOT_IMM(s1, 0x7f, d);
1238 M_LSUB(REG_ZERO, s1, d);
1239 M_ZAPNOT_IMM(d, 0x7f, d);
1242 LCONST(REG_ITMP2, iptr->val.l);
1243 M_AND(s1, REG_ITMP2, d);
1245 M_LSUB(REG_ZERO, s1, d);
1246 M_AND(d, REG_ITMP2, d);
1248 M_LSUB(REG_ZERO, d, d);
1249 store_reg_to_var_int(iptr->dst, d);
1252 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1255 var_to_reg_int(s1, src->prev, REG_ITMP1);
1256 var_to_reg_int(s2, src, REG_ITMP2);
1257 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1259 store_reg_to_var_int(iptr->dst, d);
1262 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1263 /* val.i = constant */
1265 var_to_reg_int(s1, src, REG_ITMP1);
1266 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1267 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1268 M_OR_IMM(s1, iptr->val.i, d);
1271 ICONST(REG_ITMP2, iptr->val.i);
1272 M_OR(s1, REG_ITMP2, d);
1274 store_reg_to_var_int(iptr->dst, d);
1277 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1278 /* val.l = constant */
1280 var_to_reg_int(s1, src, REG_ITMP1);
1281 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1282 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1283 M_OR_IMM(s1, iptr->val.l, d);
1286 LCONST(REG_ITMP2, iptr->val.l);
1287 M_OR(s1, REG_ITMP2, d);
1289 store_reg_to_var_int(iptr->dst, d);
1292 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1295 var_to_reg_int(s1, src->prev, REG_ITMP1);
1296 var_to_reg_int(s2, src, REG_ITMP2);
1297 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1299 store_reg_to_var_int(iptr->dst, d);
1302 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1303 /* val.i = constant */
1305 var_to_reg_int(s1, src, REG_ITMP1);
1306 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1307 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1308 M_XOR_IMM(s1, iptr->val.i, d);
1311 ICONST(REG_ITMP2, iptr->val.i);
1312 M_XOR(s1, REG_ITMP2, d);
1314 store_reg_to_var_int(iptr->dst, d);
1317 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1318 /* val.l = constant */
1320 var_to_reg_int(s1, src, REG_ITMP1);
1321 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1322 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1323 M_XOR_IMM(s1, iptr->val.l, d);
1326 LCONST(REG_ITMP2, iptr->val.l);
1327 M_XOR(s1, REG_ITMP2, d);
1329 store_reg_to_var_int(iptr->dst, d);
1333 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1335 var_to_reg_int(s1, src->prev, REG_ITMP1);
1336 var_to_reg_int(s2, src, REG_ITMP2);
1337 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1338 M_CMPLT(s1, s2, REG_ITMP3);
1339 M_CMPLT(s2, s1, REG_ITMP1);
1340 M_LSUB (REG_ITMP1, REG_ITMP3, d);
1341 store_reg_to_var_int(iptr->dst, d);
1345 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1346 /* op1 = variable, val.i = constant */
1348 var = &(rd->locals[iptr->op1][TYPE_INT]);
1349 if (var->flags & INMEMORY) {
1351 M_LLD(s1, REG_SP, 8 * var->regoff);
1355 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1356 M_IADD_IMM(s1, iptr->val.i, s1);
1358 else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1359 M_ISUB_IMM(s1, (-iptr->val.i), s1);
1362 M_LDA (s1, s1, iptr->val.i);
1363 M_IADD(s1, REG_ZERO, s1);
1365 if (var->flags & INMEMORY)
1366 M_LST(s1, REG_SP, 8 * var->regoff);
1370 /* floating operations ************************************************/
1372 case ICMD_FNEG: /* ..., value ==> ..., - value */
1374 var_to_reg_flt(s1, src, REG_FTMP1);
1375 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1377 store_reg_to_var_flt(iptr->dst, d);
1380 case ICMD_DNEG: /* ..., value ==> ..., - value */
1382 var_to_reg_flt(s1, src, REG_FTMP1);
1383 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1385 store_reg_to_var_flt(iptr->dst, d);
1388 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1390 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1391 var_to_reg_flt(s2, src, REG_FTMP2);
1392 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1397 if (d == s1 || d == s2) {
1398 M_FADDS(s1, s2, REG_FTMP3);
1400 M_FMOV(REG_FTMP3, d);
1407 store_reg_to_var_flt(iptr->dst, d);
1410 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1412 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1413 var_to_reg_flt(s2, src, REG_FTMP2);
1414 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1419 if (d == s1 || d == s2) {
1420 M_DADDS(s1, s2, REG_FTMP3);
1422 M_FMOV(REG_FTMP3, d);
1429 store_reg_to_var_flt(iptr->dst, d);
1432 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1434 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1435 var_to_reg_flt(s2, src, REG_FTMP2);
1436 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1441 if (d == s1 || d == s2) {
1442 M_FSUBS(s1, s2, REG_FTMP3);
1444 M_FMOV(REG_FTMP3, d);
1451 store_reg_to_var_flt(iptr->dst, d);
1454 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1456 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1457 var_to_reg_flt(s2, src, REG_FTMP2);
1458 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1463 if (d == s1 || d == s2) {
1464 M_DSUBS(s1, s2, REG_FTMP3);
1466 M_FMOV(REG_FTMP3, d);
1473 store_reg_to_var_flt(iptr->dst, d);
1476 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1478 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1479 var_to_reg_flt(s2, src, REG_FTMP2);
1480 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1485 if (d == s1 || d == s2) {
1486 M_FMULS(s1, s2, REG_FTMP3);
1488 M_FMOV(REG_FTMP3, d);
1495 store_reg_to_var_flt(iptr->dst, d);
1498 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1500 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1501 var_to_reg_flt(s2, src, REG_FTMP2);
1502 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1507 if (d == s1 || d == s2) {
1508 M_DMULS(s1, s2, REG_FTMP3);
1510 M_FMOV(REG_FTMP3, d);
1517 store_reg_to_var_flt(iptr->dst, d);
1520 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1522 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1523 var_to_reg_flt(s2, src, REG_FTMP2);
1524 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1529 if (d == s1 || d == s2) {
1530 M_FDIVS(s1, s2, REG_FTMP3);
1532 M_FMOV(REG_FTMP3, d);
1539 store_reg_to_var_flt(iptr->dst, d);
1542 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1544 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1545 var_to_reg_flt(s2, src, REG_FTMP2);
1546 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1551 if (d == s1 || d == s2) {
1552 M_DDIVS(s1, s2, REG_FTMP3);
1554 M_FMOV(REG_FTMP3, d);
1561 store_reg_to_var_flt(iptr->dst, d);
1564 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1566 var_to_reg_int(s1, src, REG_ITMP1);
1567 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1568 a = dseg_adddouble(cd, 0.0);
1569 M_LST (s1, REG_PV, a);
1570 M_DLD (d, REG_PV, a);
1572 store_reg_to_var_flt(iptr->dst, d);
1575 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1577 var_to_reg_int(s1, src, REG_ITMP1);
1578 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1579 a = dseg_adddouble(cd, 0.0);
1580 M_LST (s1, REG_PV, a);
1581 M_DLD (d, REG_PV, a);
1583 store_reg_to_var_flt(iptr->dst, d);
1586 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1588 var_to_reg_flt(s1, src, REG_FTMP1);
1589 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1590 a = dseg_adddouble(cd, 0.0);
1591 M_CVTDL_C(s1, REG_FTMP2);
1592 M_CVTLI(REG_FTMP2, REG_FTMP3);
1593 M_DST (REG_FTMP3, REG_PV, a);
1594 M_ILD (d, REG_PV, a);
1595 store_reg_to_var_int(iptr->dst, d);
1598 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1600 var_to_reg_flt(s1, src, REG_FTMP1);
1601 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1602 a = dseg_adddouble(cd, 0.0);
1603 M_CVTDL_C(s1, REG_FTMP2);
1604 M_DST (REG_FTMP2, REG_PV, a);
1605 M_LLD (d, REG_PV, a);
1606 store_reg_to_var_int(iptr->dst, d);
1609 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1611 var_to_reg_flt(s1, src, REG_FTMP1);
1612 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1615 store_reg_to_var_flt(iptr->dst, d);
1618 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1620 var_to_reg_flt(s1, src, REG_FTMP1);
1621 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1629 store_reg_to_var_flt(iptr->dst, d);
1632 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1634 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1635 var_to_reg_flt(s2, src, REG_FTMP2);
1636 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1638 M_LSUB_IMM(REG_ZERO, 1, d);
1639 M_FCMPEQ(s1, s2, REG_FTMP3);
1640 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1642 M_FCMPLT(s2, s1, REG_FTMP3);
1643 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1644 M_LADD_IMM(REG_ZERO, 1, d);
1647 M_LSUB_IMM(REG_ZERO, 1, d);
1648 M_FCMPEQS(s1, s2, REG_FTMP3);
1650 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1652 M_FCMPLTS(s2, s1, REG_FTMP3);
1654 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1655 M_LADD_IMM(REG_ZERO, 1, d);
1657 store_reg_to_var_int(iptr->dst, d);
1660 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1662 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1663 var_to_reg_flt(s2, src, REG_FTMP2);
1664 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1666 M_LADD_IMM(REG_ZERO, 1, d);
1667 M_FCMPEQ(s1, s2, REG_FTMP3);
1668 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1670 M_FCMPLT(s1, s2, REG_FTMP3);
1671 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1672 M_LSUB_IMM(REG_ZERO, 1, d);
1675 M_LADD_IMM(REG_ZERO, 1, d);
1676 M_FCMPEQS(s1, s2, REG_FTMP3);
1678 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1680 M_FCMPLTS(s1, s2, REG_FTMP3);
1682 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1683 M_LSUB_IMM(REG_ZERO, 1, d);
1685 store_reg_to_var_int(iptr->dst, d);
1689 /* memory operations **************************************************/
1691 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1693 var_to_reg_int(s1, src, REG_ITMP1);
1694 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1695 gen_nullptr_check(s1);
1696 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1697 store_reg_to_var_int(iptr->dst, d);
1700 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1702 var_to_reg_int(s1, src->prev, REG_ITMP1);
1703 var_to_reg_int(s2, src, REG_ITMP2);
1704 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1705 if (iptr->op1 == 0) {
1706 gen_nullptr_check(s1);
1709 M_SAADDQ(s2, s1, REG_ITMP1);
1710 M_ALD( d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1711 store_reg_to_var_int(iptr->dst, d);
1714 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1716 var_to_reg_int(s1, src->prev, REG_ITMP1);
1717 var_to_reg_int(s2, src, REG_ITMP2);
1718 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1719 if (iptr->op1 == 0) {
1720 gen_nullptr_check(s1);
1723 M_S8ADDQ(s2, s1, REG_ITMP1);
1724 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1725 store_reg_to_var_int(iptr->dst, d);
1728 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1730 var_to_reg_int(s1, src->prev, REG_ITMP1);
1731 var_to_reg_int(s2, src, REG_ITMP2);
1732 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1733 if (iptr->op1 == 0) {
1734 gen_nullptr_check(s1);
1738 M_S4ADDQ(s2, s1, REG_ITMP1);
1739 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1740 store_reg_to_var_int(iptr->dst, d);
1743 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1745 var_to_reg_int(s1, src->prev, REG_ITMP1);
1746 var_to_reg_int(s2, src, REG_ITMP2);
1747 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1748 if (iptr->op1 == 0) {
1749 gen_nullptr_check(s1);
1752 M_S4ADDQ(s2, s1, REG_ITMP1);
1753 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1754 store_reg_to_var_flt(iptr->dst, d);
1757 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1759 var_to_reg_int(s1, src->prev, REG_ITMP1);
1760 var_to_reg_int(s2, src, REG_ITMP2);
1761 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1762 if (iptr->op1 == 0) {
1763 gen_nullptr_check(s1);
1766 M_S8ADDQ(s2, s1, REG_ITMP1);
1767 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1768 store_reg_to_var_flt(iptr->dst, d);
1771 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1773 var_to_reg_int(s1, src->prev, REG_ITMP1);
1774 var_to_reg_int(s2, src, REG_ITMP2);
1775 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1776 if (iptr->op1 == 0) {
1777 gen_nullptr_check(s1);
1780 if (has_ext_instr_set) {
1781 M_LADD(s2, s1, REG_ITMP1);
1782 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1783 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1786 M_LADD (s2, s1, REG_ITMP1);
1787 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1788 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1789 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1790 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
1792 store_reg_to_var_int(iptr->dst, d);
1795 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1797 var_to_reg_int(s1, src->prev, REG_ITMP1);
1798 var_to_reg_int(s2, src, REG_ITMP2);
1799 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1800 if (iptr->op1 == 0) {
1801 gen_nullptr_check(s1);
1804 if (has_ext_instr_set) {
1805 M_LADD(s2, s1, REG_ITMP1);
1806 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1807 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1811 M_LADD(s2, s1, REG_ITMP1);
1812 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1813 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1814 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1815 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1816 M_SRA_IMM(d, 48, d);
1818 store_reg_to_var_int(iptr->dst, d);
1821 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1823 var_to_reg_int(s1, src->prev, REG_ITMP1);
1824 var_to_reg_int(s2, src, REG_ITMP2);
1825 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1826 if (iptr->op1 == 0) {
1827 gen_nullptr_check(s1);
1830 if (has_ext_instr_set) {
1831 M_LADD (s2, s1, REG_ITMP1);
1832 M_BLDU (d, REG_ITMP1, OFFSET (java_bytearray, data[0]));
1836 M_LADD(s2, s1, REG_ITMP1);
1837 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1838 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
1839 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1840 M_SRA_IMM(d, 56, d);
1842 store_reg_to_var_int(iptr->dst, d);
1846 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1848 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1849 var_to_reg_int(s2, src->prev, REG_ITMP2);
1850 if (iptr->op1 == 0) {
1851 gen_nullptr_check(s1);
1854 var_to_reg_int(s3, src, REG_ITMP3);
1855 M_SAADDQ(s2, s1, REG_ITMP1);
1856 M_AST (s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1859 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1861 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1862 var_to_reg_int(s2, src->prev, REG_ITMP2);
1863 if (iptr->op1 == 0) {
1864 gen_nullptr_check(s1);
1867 var_to_reg_int(s3, src, REG_ITMP3);
1868 M_S8ADDQ(s2, s1, REG_ITMP1);
1869 M_LST (s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1872 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1874 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1875 var_to_reg_int(s2, src->prev, REG_ITMP2);
1876 if (iptr->op1 == 0) {
1877 gen_nullptr_check(s1);
1881 var_to_reg_int(s3, src, REG_ITMP3);
1882 M_S4ADDQ(s2, s1, REG_ITMP1);
1883 M_IST (s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1886 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1888 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1889 var_to_reg_int(s2, src->prev, REG_ITMP2);
1890 if (iptr->op1 == 0) {
1891 gen_nullptr_check(s1);
1894 var_to_reg_flt(s3, src, REG_FTMP3);
1895 M_S4ADDQ(s2, s1, REG_ITMP1);
1896 M_FST (s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1899 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1901 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1902 var_to_reg_int(s2, src->prev, REG_ITMP2);
1903 if (iptr->op1 == 0) {
1904 gen_nullptr_check(s1);
1907 var_to_reg_flt(s3, src, REG_FTMP3);
1908 M_S8ADDQ(s2, s1, REG_ITMP1);
1909 M_DST (s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1912 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1914 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1915 var_to_reg_int(s2, src->prev, REG_ITMP2);
1916 if (iptr->op1 == 0) {
1917 gen_nullptr_check(s1);
1920 var_to_reg_int(s3, src, REG_ITMP3);
1921 if (has_ext_instr_set) {
1922 M_LADD(s2, s1, REG_ITMP1);
1923 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1924 M_SST (s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1927 M_LADD (s2, s1, REG_ITMP1);
1928 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1929 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1930 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1931 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1932 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1933 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
1934 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1938 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1940 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1941 var_to_reg_int(s2, src->prev, REG_ITMP2);
1942 if (iptr->op1 == 0) {
1943 gen_nullptr_check(s1);
1946 var_to_reg_int(s3, src, REG_ITMP3);
1947 if (has_ext_instr_set) {
1948 M_LADD(s2, s1, REG_ITMP1);
1949 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1950 M_SST (s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1953 M_LADD (s2, s1, REG_ITMP1);
1954 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1955 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1956 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1957 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1958 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1959 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
1960 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1964 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1966 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1967 var_to_reg_int(s2, src->prev, REG_ITMP2);
1968 if (iptr->op1 == 0) {
1969 gen_nullptr_check(s1);
1972 var_to_reg_int(s3, src, REG_ITMP3);
1973 if (has_ext_instr_set) {
1974 M_LADD(s2, s1, REG_ITMP1);
1975 M_BST (s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1978 M_LADD (s2, s1, REG_ITMP1);
1979 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1980 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1981 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
1982 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1983 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
1984 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1989 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1991 var_to_reg_int(s1, src->prev, REG_ITMP1);
1992 var_to_reg_int(s2, src, REG_ITMP2);
1993 if (iptr->op1 == 0) {
1994 gen_nullptr_check(s1);
1997 M_S4ADDQ(s2, s1, REG_ITMP1);
1998 M_IST(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
2001 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
2003 var_to_reg_int(s1, src->prev, REG_ITMP1);
2004 var_to_reg_int(s2, src, REG_ITMP2);
2005 if (iptr->op1 == 0) {
2006 gen_nullptr_check(s1);
2009 M_S8ADDQ(s2, s1, REG_ITMP1);
2010 M_LST(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
2013 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
2015 var_to_reg_int(s1, src->prev, REG_ITMP1);
2016 var_to_reg_int(s2, src, REG_ITMP2);
2017 if (iptr->op1 == 0) {
2018 gen_nullptr_check(s1);
2021 M_SAADDQ(s2, s1, REG_ITMP1);
2022 M_AST(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
2025 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
2027 var_to_reg_int(s1, src->prev, REG_ITMP1);
2028 var_to_reg_int(s2, src, REG_ITMP2);
2029 if (iptr->op1 == 0) {
2030 gen_nullptr_check(s1);
2033 if (has_ext_instr_set) {
2034 M_LADD(s2, s1, REG_ITMP1);
2035 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2038 M_LADD(s2, s1, REG_ITMP1);
2039 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2040 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2041 M_INSBL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2042 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2043 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2044 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2048 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
2050 var_to_reg_int(s1, src->prev, REG_ITMP1);
2051 var_to_reg_int(s2, src, REG_ITMP2);
2052 if (iptr->op1 == 0) {
2053 gen_nullptr_check(s1);
2056 if (has_ext_instr_set) {
2057 M_LADD(s2, s1, REG_ITMP1);
2058 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2059 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
2062 M_LADD(s2, s1, REG_ITMP1);
2063 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2064 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2065 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2066 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2067 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2068 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2069 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2073 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
2075 var_to_reg_int(s1, src->prev, REG_ITMP1);
2076 var_to_reg_int(s2, src, REG_ITMP2);
2077 if (iptr->op1 == 0) {
2078 gen_nullptr_check(s1);
2081 if (has_ext_instr_set) {
2082 M_LADD(s2, s1, REG_ITMP1);
2083 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2084 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2087 M_LADD(s2, s1, REG_ITMP1);
2088 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2089 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2090 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2091 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2092 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2093 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2094 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2099 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2100 /* op1 = type, val.a = field address */
2102 /* if class isn't yet initialized, do it */
2103 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
2104 /* call helper function which patches this code */
2105 a = dseg_addaddress(cd, ((fieldinfo *) iptr->val.a)->class);
2106 M_ALD(REG_ITMP1, REG_PV, a);
2107 a = dseg_addaddress(cd, asm_check_clinit);
2108 M_ALD(REG_PV, REG_PV, a);
2109 M_JSR(REG_RA, REG_PV);
2112 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
2114 M_LDA(REG_PV, REG_RA, -s1);
2118 s4 ml = -s1, mh = 0;
2119 while (ml < -32768) { ml += 65536; mh--; }
2120 M_LDA(REG_PV, REG_RA, ml);
2121 M_LDAH(REG_PV, REG_PV, mh);
2125 a = dseg_addaddress(cd, &(((fieldinfo *)(iptr->val.a))->value));
2126 M_ALD(REG_ITMP1, REG_PV, a);
2127 switch (iptr->op1) {
2129 var_to_reg_int(s2, src, REG_ITMP2);
2130 M_IST(s2, REG_ITMP1, 0);
2133 var_to_reg_int(s2, src, REG_ITMP2);
2134 M_LST(s2, REG_ITMP1, 0);
2137 var_to_reg_int(s2, src, REG_ITMP2);
2138 M_AST(s2, REG_ITMP1, 0);
2141 var_to_reg_flt(s2, src, REG_FTMP2);
2142 M_FST(s2, REG_ITMP1, 0);
2145 var_to_reg_flt(s2, src, REG_FTMP2);
2146 M_DST(s2, REG_ITMP1, 0);
2148 default: panic ("internal error");
2152 case ICMD_GETSTATIC: /* ... ==> ..., value */
2153 /* op1 = type, val.a = field address */
2155 /* if class isn't yet initialized, do it */
2156 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
2157 /* call helper function which patches this code */
2158 a = dseg_addaddress(cd, ((fieldinfo *) iptr->val.a)->class);
2159 M_ALD(REG_ITMP1, REG_PV, a);
2160 a = dseg_addaddress(cd, asm_check_clinit);
2161 M_ALD(REG_PV, REG_PV, a);
2162 M_JSR(REG_RA, REG_PV);
2165 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
2167 M_LDA(REG_PV, REG_RA, -s1);
2171 s4 ml = -s1, mh = 0;
2172 while (ml < -32768) { ml += 65536; mh--; }
2173 M_LDA(REG_PV, REG_RA, ml);
2174 M_LDAH(REG_PV, REG_PV, mh);
2178 a = dseg_addaddress(cd, &(((fieldinfo *) iptr->val.a)->value));
2179 M_ALD(REG_ITMP1, REG_PV, a);
2180 switch (iptr->op1) {
2182 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2183 M_ILD(d, REG_ITMP1, 0);
2184 store_reg_to_var_int(iptr->dst, d);
2187 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2188 M_LLD(d, REG_ITMP1, 0);
2189 store_reg_to_var_int(iptr->dst, d);
2192 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2193 M_ALD(d, REG_ITMP1, 0);
2194 store_reg_to_var_int(iptr->dst, d);
2197 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2198 M_FLD(d, REG_ITMP1, 0);
2199 store_reg_to_var_flt(iptr->dst, d);
2202 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2203 M_DLD(d, REG_ITMP1, 0);
2204 store_reg_to_var_flt(iptr->dst, d);
2206 default: panic ("internal error");
2211 case ICMD_PUTFIELD: /* ..., value ==> ... */
2212 /* op1 = type, val.i = field offset */
2214 a = ((fieldinfo *) iptr->val.a)->offset;
2215 switch (iptr->op1) {
2217 var_to_reg_int(s1, src->prev, REG_ITMP1);
2218 var_to_reg_int(s2, src, REG_ITMP2);
2219 gen_nullptr_check(s1);
2223 var_to_reg_int(s1, src->prev, REG_ITMP1);
2224 var_to_reg_int(s2, src, REG_ITMP2);
2225 gen_nullptr_check(s1);
2229 var_to_reg_int(s1, src->prev, REG_ITMP1);
2230 var_to_reg_int(s2, src, REG_ITMP2);
2231 gen_nullptr_check(s1);
2235 var_to_reg_int(s1, src->prev, REG_ITMP1);
2236 var_to_reg_flt(s2, src, REG_FTMP2);
2237 gen_nullptr_check(s1);
2241 var_to_reg_int(s1, src->prev, REG_ITMP1);
2242 var_to_reg_flt(s2, src, REG_FTMP2);
2243 gen_nullptr_check(s1);
2246 default: panic ("internal error");
2250 case ICMD_GETFIELD: /* ... ==> ..., value */
2251 /* op1 = type, val.i = field offset */
2253 a = ((fieldinfo *)(iptr->val.a))->offset;
2254 switch (iptr->op1) {
2256 var_to_reg_int(s1, src, REG_ITMP1);
2257 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2258 gen_nullptr_check(s1);
2260 store_reg_to_var_int(iptr->dst, d);
2263 var_to_reg_int(s1, src, REG_ITMP1);
2264 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2265 gen_nullptr_check(s1);
2267 store_reg_to_var_int(iptr->dst, d);
2270 var_to_reg_int(s1, src, REG_ITMP1);
2271 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2272 gen_nullptr_check(s1);
2274 store_reg_to_var_int(iptr->dst, d);
2277 var_to_reg_int(s1, src, REG_ITMP1);
2278 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2279 gen_nullptr_check(s1);
2281 store_reg_to_var_flt(iptr->dst, d);
2284 var_to_reg_int(s1, src, REG_ITMP1);
2285 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2286 gen_nullptr_check(s1);
2288 store_reg_to_var_flt(iptr->dst, d);
2290 default: panic ("internal error");
2295 /* branch operations **************************************************/
2297 #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}}
2299 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2301 var_to_reg_int(s1, src, REG_ITMP1);
2302 M_INTMOVE(s1, REG_ITMP1_XPTR);
2303 a = dseg_addaddress(cd, asm_handle_exception);
2304 M_ALD(REG_ITMP2, REG_PV, a);
2305 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2306 M_NOP; /* nop ensures that XPC is less than the end */
2307 /* of basic block */
2311 case ICMD_GOTO: /* ... ==> ... */
2312 /* op1 = target JavaVM pc */
2314 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2318 case ICMD_JSR: /* ... ==> ... */
2319 /* op1 = target JavaVM pc */
2321 M_BSR(REG_ITMP1, 0);
2322 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2325 case ICMD_RET: /* ... ==> ... */
2326 /* op1 = local variable */
2328 var = &(rd->locals[iptr->op1][TYPE_ADR]);
2329 if (var->flags & INMEMORY) {
2330 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2331 M_RET(REG_ZERO, REG_ITMP1);
2334 M_RET(REG_ZERO, var->regoff);
2338 case ICMD_IFNULL: /* ..., value ==> ... */
2339 /* op1 = target JavaVM pc */
2341 var_to_reg_int(s1, src, REG_ITMP1);
2343 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2346 case ICMD_IFNONNULL: /* ..., value ==> ... */
2347 /* op1 = target JavaVM pc */
2349 var_to_reg_int(s1, src, REG_ITMP1);
2351 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2354 case ICMD_IFEQ: /* ..., value ==> ... */
2355 /* op1 = target JavaVM pc, val.i = constant */
2357 var_to_reg_int(s1, src, REG_ITMP1);
2358 if (iptr->val.i == 0) {
2362 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2363 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2366 ICONST(REG_ITMP2, iptr->val.i);
2367 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2369 M_BNEZ(REG_ITMP1, 0);
2371 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2374 case ICMD_IFLT: /* ..., value ==> ... */
2375 /* op1 = target JavaVM pc, val.i = constant */
2377 var_to_reg_int(s1, src, REG_ITMP1);
2378 if (iptr->val.i == 0) {
2382 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2383 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2386 ICONST(REG_ITMP2, iptr->val.i);
2387 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2389 M_BNEZ(REG_ITMP1, 0);
2391 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2394 case ICMD_IFLE: /* ..., value ==> ... */
2395 /* op1 = target JavaVM pc, val.i = constant */
2397 var_to_reg_int(s1, src, REG_ITMP1);
2398 if (iptr->val.i == 0) {
2402 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2403 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2406 ICONST(REG_ITMP2, iptr->val.i);
2407 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2409 M_BNEZ(REG_ITMP1, 0);
2411 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2414 case ICMD_IFNE: /* ..., value ==> ... */
2415 /* op1 = target JavaVM pc, val.i = constant */
2417 var_to_reg_int(s1, src, REG_ITMP1);
2418 if (iptr->val.i == 0) {
2422 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2423 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2426 ICONST(REG_ITMP2, iptr->val.i);
2427 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2429 M_BEQZ(REG_ITMP1, 0);
2431 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2434 case ICMD_IFGT: /* ..., value ==> ... */
2435 /* op1 = target JavaVM pc, val.i = constant */
2437 var_to_reg_int(s1, src, REG_ITMP1);
2438 if (iptr->val.i == 0) {
2442 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2443 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2446 ICONST(REG_ITMP2, iptr->val.i);
2447 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2449 M_BEQZ(REG_ITMP1, 0);
2451 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2454 case ICMD_IFGE: /* ..., value ==> ... */
2455 /* op1 = target JavaVM pc, val.i = constant */
2457 var_to_reg_int(s1, src, REG_ITMP1);
2458 if (iptr->val.i == 0) {
2462 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2463 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2466 ICONST(REG_ITMP2, iptr->val.i);
2467 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2469 M_BEQZ(REG_ITMP1, 0);
2471 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2474 case ICMD_IF_LEQ: /* ..., value ==> ... */
2475 /* op1 = target JavaVM pc, val.l = constant */
2477 var_to_reg_int(s1, src, REG_ITMP1);
2478 if (iptr->val.l == 0) {
2482 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2483 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2486 LCONST(REG_ITMP2, iptr->val.l);
2487 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2489 M_BNEZ(REG_ITMP1, 0);
2491 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2494 case ICMD_IF_LLT: /* ..., value ==> ... */
2495 /* op1 = target JavaVM pc, val.l = constant */
2497 var_to_reg_int(s1, src, REG_ITMP1);
2498 if (iptr->val.l == 0) {
2502 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2503 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2506 LCONST(REG_ITMP2, iptr->val.l);
2507 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2509 M_BNEZ(REG_ITMP1, 0);
2511 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2514 case ICMD_IF_LLE: /* ..., value ==> ... */
2515 /* op1 = target JavaVM pc, val.l = constant */
2517 var_to_reg_int(s1, src, REG_ITMP1);
2518 if (iptr->val.l == 0) {
2522 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2523 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2526 LCONST(REG_ITMP2, iptr->val.l);
2527 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2529 M_BNEZ(REG_ITMP1, 0);
2531 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2534 case ICMD_IF_LNE: /* ..., value ==> ... */
2535 /* op1 = target JavaVM pc, val.l = constant */
2537 var_to_reg_int(s1, src, REG_ITMP1);
2538 if (iptr->val.l == 0) {
2542 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2543 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2546 LCONST(REG_ITMP2, iptr->val.l);
2547 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2549 M_BEQZ(REG_ITMP1, 0);
2551 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2554 case ICMD_IF_LGT: /* ..., value ==> ... */
2555 /* op1 = target JavaVM pc, val.l = constant */
2557 var_to_reg_int(s1, src, REG_ITMP1);
2558 if (iptr->val.l == 0) {
2562 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2563 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2566 LCONST(REG_ITMP2, iptr->val.l);
2567 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2569 M_BEQZ(REG_ITMP1, 0);
2571 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2574 case ICMD_IF_LGE: /* ..., value ==> ... */
2575 /* op1 = target JavaVM pc, val.l = constant */
2577 var_to_reg_int(s1, src, REG_ITMP1);
2578 if (iptr->val.l == 0) {
2582 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2583 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2586 LCONST(REG_ITMP2, iptr->val.l);
2587 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2589 M_BEQZ(REG_ITMP1, 0);
2591 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2594 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2595 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2596 case ICMD_IF_ACMPEQ:
2598 var_to_reg_int(s1, src->prev, REG_ITMP1);
2599 var_to_reg_int(s2, src, REG_ITMP2);
2600 M_CMPEQ(s1, s2, REG_ITMP1);
2601 M_BNEZ(REG_ITMP1, 0);
2602 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2605 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2606 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2607 case ICMD_IF_ACMPNE:
2609 var_to_reg_int(s1, src->prev, REG_ITMP1);
2610 var_to_reg_int(s2, src, REG_ITMP2);
2611 M_CMPEQ(s1, s2, REG_ITMP1);
2612 M_BEQZ(REG_ITMP1, 0);
2613 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2616 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2617 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2619 var_to_reg_int(s1, src->prev, REG_ITMP1);
2620 var_to_reg_int(s2, src, REG_ITMP2);
2621 M_CMPLT(s1, s2, REG_ITMP1);
2622 M_BNEZ(REG_ITMP1, 0);
2623 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2626 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2627 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2629 var_to_reg_int(s1, src->prev, REG_ITMP1);
2630 var_to_reg_int(s2, src, REG_ITMP2);
2631 M_CMPLE(s1, s2, REG_ITMP1);
2632 M_BEQZ(REG_ITMP1, 0);
2633 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2636 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2637 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2639 var_to_reg_int(s1, src->prev, REG_ITMP1);
2640 var_to_reg_int(s2, src, REG_ITMP2);
2641 M_CMPLE(s1, s2, REG_ITMP1);
2642 M_BNEZ(REG_ITMP1, 0);
2643 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2646 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2647 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2649 var_to_reg_int(s1, src->prev, REG_ITMP1);
2650 var_to_reg_int(s2, src, REG_ITMP2);
2651 M_CMPLT(s1, s2, REG_ITMP1);
2652 M_BEQZ(REG_ITMP1, 0);
2653 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2656 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2658 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2661 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2662 /* val.i = constant */
2664 var_to_reg_int(s1, src, REG_ITMP1);
2665 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2667 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2668 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2669 M_CMPEQ(s1, REG_ZERO, d);
2670 store_reg_to_var_int(iptr->dst, d);
2673 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2674 M_CMPEQ(s1, REG_ZERO, d);
2676 store_reg_to_var_int(iptr->dst, d);
2680 M_MOV(s1, REG_ITMP1);
2683 ICONST(d, iptr[1].val.i);
2685 if ((s3 >= 0) && (s3 <= 255)) {
2686 M_CMOVEQ_IMM(s1, s3, d);
2689 ICONST(REG_ITMP2, s3);
2690 M_CMOVEQ(s1, REG_ITMP2, d);
2692 store_reg_to_var_int(iptr->dst, d);
2695 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2696 /* val.i = constant */
2698 var_to_reg_int(s1, src, REG_ITMP1);
2699 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2701 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2702 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2703 M_CMPEQ(s1, REG_ZERO, d);
2704 store_reg_to_var_int(iptr->dst, d);
2707 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2708 M_CMPEQ(s1, REG_ZERO, d);
2710 store_reg_to_var_int(iptr->dst, d);
2714 M_MOV(s1, REG_ITMP1);
2717 ICONST(d, iptr[1].val.i);
2719 if ((s3 >= 0) && (s3 <= 255)) {
2720 M_CMOVNE_IMM(s1, s3, d);
2723 ICONST(REG_ITMP2, s3);
2724 M_CMOVNE(s1, REG_ITMP2, d);
2726 store_reg_to_var_int(iptr->dst, d);
2729 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2730 /* val.i = constant */
2732 var_to_reg_int(s1, src, REG_ITMP1);
2733 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2735 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2736 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2737 M_CMPLT(s1, REG_ZERO, d);
2738 store_reg_to_var_int(iptr->dst, d);
2741 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2742 M_CMPLE(REG_ZERO, s1, d);
2743 store_reg_to_var_int(iptr->dst, d);
2747 M_MOV(s1, REG_ITMP1);
2750 ICONST(d, iptr[1].val.i);
2752 if ((s3 >= 0) && (s3 <= 255)) {
2753 M_CMOVLT_IMM(s1, s3, d);
2756 ICONST(REG_ITMP2, s3);
2757 M_CMOVLT(s1, REG_ITMP2, d);
2759 store_reg_to_var_int(iptr->dst, d);
2762 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2763 /* val.i = constant */
2765 var_to_reg_int(s1, src, REG_ITMP1);
2766 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2768 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2769 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2770 M_CMPLE(REG_ZERO, s1, d);
2771 store_reg_to_var_int(iptr->dst, d);
2774 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2775 M_CMPLT(s1, REG_ZERO, d);
2776 store_reg_to_var_int(iptr->dst, d);
2780 M_MOV(s1, REG_ITMP1);
2783 ICONST(d, iptr[1].val.i);
2785 if ((s3 >= 0) && (s3 <= 255)) {
2786 M_CMOVGE_IMM(s1, s3, d);
2789 ICONST(REG_ITMP2, s3);
2790 M_CMOVGE(s1, REG_ITMP2, d);
2792 store_reg_to_var_int(iptr->dst, d);
2795 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2796 /* val.i = constant */
2798 var_to_reg_int(s1, src, REG_ITMP1);
2799 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2801 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2802 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2803 M_CMPLT(REG_ZERO, s1, d);
2804 store_reg_to_var_int(iptr->dst, d);
2807 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2808 M_CMPLE(s1, REG_ZERO, d);
2809 store_reg_to_var_int(iptr->dst, d);
2813 M_MOV(s1, REG_ITMP1);
2816 ICONST(d, iptr[1].val.i);
2818 if ((s3 >= 0) && (s3 <= 255)) {
2819 M_CMOVGT_IMM(s1, s3, d);
2822 ICONST(REG_ITMP2, s3);
2823 M_CMOVGT(s1, REG_ITMP2, d);
2825 store_reg_to_var_int(iptr->dst, d);
2828 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2829 /* val.i = constant */
2831 var_to_reg_int(s1, src, REG_ITMP1);
2832 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2834 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2835 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2836 M_CMPLE(s1, REG_ZERO, d);
2837 store_reg_to_var_int(iptr->dst, d);
2840 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2841 M_CMPLT(REG_ZERO, s1, d);
2842 store_reg_to_var_int(iptr->dst, d);
2846 M_MOV(s1, REG_ITMP1);
2849 ICONST(d, iptr[1].val.i);
2851 if ((s3 >= 0) && (s3 <= 255)) {
2852 M_CMOVLE_IMM(s1, s3, d);
2855 ICONST(REG_ITMP2, s3);
2856 M_CMOVLE(s1, REG_ITMP2, d);
2858 store_reg_to_var_int(iptr->dst, d);
2862 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2866 var_to_reg_int(s1, src, REG_RESULT);
2867 M_INTMOVE(s1, REG_RESULT);
2869 #if defined(USE_THREADS)
2870 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2872 a = dseg_addaddress(cd, (void *) (builtin_monitorexit));
2873 M_ALD(REG_PV, REG_PV, a);
2874 M_ALD(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
2875 M_LST(REG_RESULT, REG_SP, rd->maxmemuse * 8);
2876 M_JSR(REG_RA, REG_PV);
2877 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
2878 M_LDA(REG_PV, REG_RA, disp);
2879 M_LLD(REG_RESULT, REG_SP, rd->maxmemuse * 8);
2883 goto nowperformreturn;
2885 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2888 var_to_reg_flt(s1, src, REG_FRESULT);
2889 M_FLTMOVE(s1, REG_FRESULT);
2891 #if defined(USE_THREADS)
2892 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2894 a = dseg_addaddress(cd, (void *) (builtin_monitorexit));
2895 M_ALD(REG_PV, REG_PV, a);
2896 M_ALD(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
2897 M_DST(REG_FRESULT, REG_SP, rd->maxmemuse * 8);
2898 M_JSR(REG_RA, REG_PV);
2899 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
2900 M_LDA(REG_PV, REG_RA, disp);
2901 M_DLD(REG_FRESULT, REG_SP, rd->maxmemuse * 8);
2905 goto nowperformreturn;
2907 case ICMD_RETURN: /* ... ==> ... */
2909 #if defined(USE_THREADS)
2910 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2912 a = dseg_addaddress(cd, (void *) (builtin_monitorexit));
2913 M_ALD(REG_PV, REG_PV, a);
2914 M_ALD(rd->argintregs[0], REG_SP, rd->maxmemuse * 8);
2915 M_JSR(REG_RA, REG_PV);
2916 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
2917 M_LDA(REG_PV, REG_RA, disp);
2925 p = parentargs_base;
2927 /* restore return address */
2929 if (!m->isleafmethod) {
2930 p--; M_LLD(REG_RA, REG_SP, p * 8);
2933 /* restore saved registers */
2935 for (i = rd->savintregcnt - 1; i >= rd->maxsavintreguse; i--) {
2936 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2938 for (i = rd->savfltregcnt - 1; i >= rd->maxsavfltreguse; i--) {
2939 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2942 /* deallocate stack */
2944 if (parentargs_base) {
2945 M_LDA(REG_SP, REG_SP, parentargs_base * 8);
2948 /* call trace function */
2951 M_LDA(REG_SP, REG_SP, -3 * 8);
2952 M_AST(REG_RA, REG_SP, 0 * 8);
2953 M_LST(REG_RESULT, REG_SP, 1 * 8);
2954 M_DST(REG_FRESULT, REG_SP, 2 * 8);
2955 a = dseg_addaddress(cd, m);
2956 M_ALD(rd->argintregs[0], REG_PV, a);
2957 M_MOV(REG_RESULT, rd->argintregs[1]);
2958 M_FLTMOVE(REG_FRESULT, rd->argfltregs[2]);
2959 M_FLTMOVE(REG_FRESULT, rd->argfltregs[3]);
2960 a = dseg_addaddress(cd, (void *) builtin_displaymethodstop);
2961 M_ALD(REG_PV, REG_PV, a);
2962 M_JSR(REG_RA, REG_PV);
2963 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
2964 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
2966 s4 ml = -s1, mh = 0;
2967 while (ml < -32768) { ml += 65536; mh--; }
2968 M_LDA(REG_PV, REG_RA, ml);
2969 M_LDAH(REG_PV, REG_PV, mh);
2971 M_DLD(REG_FRESULT, REG_SP, 2 * 8);
2972 M_LLD(REG_RESULT, REG_SP, 1 * 8);
2973 M_ALD(REG_RA, REG_SP, 0 * 8);
2974 M_LDA(REG_SP, REG_SP, 3 * 8);
2977 M_RET(REG_ZERO, REG_RA);
2983 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2988 tptr = (void **) iptr->target;
2990 s4ptr = iptr->val.a;
2991 l = s4ptr[1]; /* low */
2992 i = s4ptr[2]; /* high */
2994 var_to_reg_int(s1, src, REG_ITMP1);
2996 {M_INTMOVE(s1, REG_ITMP1);}
2997 else if (l <= 32768) {
2998 M_LDA(REG_ITMP1, s1, -l);
3001 ICONST(REG_ITMP2, l);
3002 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
3009 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
3011 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
3012 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3014 M_BEQZ(REG_ITMP2, 0);
3017 /* codegen_addreference(cd, BlockPtrOfPC(s4ptr[0]), mcodeptr); */
3018 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3020 /* build jump table top down and use address of lowest entry */
3022 /* s4ptr += 3 + i; */
3026 /* dseg_addtarget(cd, BlockPtrOfPC(*--s4ptr)); */
3027 dseg_addtarget(cd, (basicblock *) tptr[0]);
3032 /* length of dataseg after last dseg_addtarget is used by load */
3034 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
3035 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
3036 M_JMP(REG_ZERO, REG_ITMP2);
3041 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3043 s4 i, l, val, *s4ptr;
3046 tptr = (void **) iptr->target;
3048 s4ptr = iptr->val.a;
3049 l = s4ptr[0]; /* default */
3050 i = s4ptr[1]; /* count */
3052 MCODECHECK((i<<2)+8);
3053 var_to_reg_int(s1, src, REG_ITMP1);
3059 if ((val >= 0) && (val <= 255)) {
3060 M_CMPEQ_IMM(s1, val, REG_ITMP2);
3063 if ((val >= -32768) && (val <= 32767)) {
3064 M_LDA(REG_ITMP2, REG_ZERO, val);
3067 a = dseg_adds4(cd, val);
3068 M_ILD(REG_ITMP2, REG_PV, a);
3070 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
3072 M_BNEZ(REG_ITMP2, 0);
3073 /* codegen_addreference(cd, BlockPtrOfPC(s4ptr[1]), mcodeptr); */
3074 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3078 /* codegen_addreference(cd, BlockPtrOfPC(l), mcodeptr); */
3080 tptr = (void **) iptr->target;
3081 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3088 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
3089 /* op1 = return type, val.a = function pointer*/
3093 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
3094 /* op1 = return type, val.a = function pointer*/
3098 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
3099 /* op1 = return type, val.a = function pointer*/
3103 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3104 /* op1 = arg count, val.a = method pointer */
3106 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3107 /* op1 = arg count, val.a = method pointer */
3109 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3110 /* op1 = arg count, val.a = method pointer */
3112 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
3113 /* op1 = arg count, val.a = method pointer */
3120 MCODECHECK((s3 << 1) + 64);
3122 /* copy arguments to registers or stack location */
3124 for (; --s3 >= 0; src = src->prev) {
3125 if (src->varkind == ARGVAR)
3127 if (IS_INT_LNG_TYPE(src->type)) {
3128 if (s3 < INT_ARG_CNT) {
3129 s1 = rd->argintregs[s3];
3130 var_to_reg_int(d, src, s1);
3134 var_to_reg_int(d, src, REG_ITMP1);
3135 M_LST(d, REG_SP, 8 * (s3 - INT_ARG_CNT));
3139 if (s3 < FLT_ARG_CNT) {
3140 s1 = rd->argfltregs[s3];
3141 var_to_reg_flt(d, src, s1);
3145 var_to_reg_flt(d, src, REG_FTMP1);
3146 M_DST(d, REG_SP, 8 * (s3 - FLT_ARG_CNT));
3152 switch (iptr->opc) {
3156 a = dseg_addaddress(cd, (void *) lm);
3159 M_ALD(REG_PV, REG_PV, a); /* Pointer to built-in-function */
3162 case ICMD_INVOKESTATIC:
3163 case ICMD_INVOKESPECIAL:
3164 a = dseg_addaddress(cd, lm->stubroutine);
3167 M_ALD(REG_PV, REG_PV, a); /* method pointer in r27 */
3170 case ICMD_INVOKEVIRTUAL:
3173 gen_nullptr_check(rd->argintregs[0]);
3174 M_ALD(REG_METHODPTR, rd->argintregs[0],
3175 OFFSET(java_objectheader, vftbl));
3176 M_ALD(REG_PV, REG_METHODPTR, OFFSET(vftbl_t, table[0]) +
3177 sizeof(methodptr) * lm->vftblindex);
3180 case ICMD_INVOKEINTERFACE:
3183 gen_nullptr_check(rd->argintregs[0]);
3184 M_ALD(REG_METHODPTR, rd->argintregs[0],
3185 OFFSET(java_objectheader, vftbl));
3186 M_ALD(REG_METHODPTR, REG_METHODPTR,
3187 OFFSET(vftbl_t, interfacetable[0]) -
3188 sizeof(methodptr*) * lm->class->index);
3189 M_ALD(REG_PV, REG_METHODPTR,
3190 sizeof(methodptr) * (lm - lm->class->methods));
3194 M_JSR(REG_RA, REG_PV);
3198 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3199 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3201 s4 ml = -s1, mh = 0;
3202 while (ml < -32768) { ml += 65536; mh--; }
3203 M_LDA(REG_PV, REG_RA, ml);
3204 M_LDAH(REG_PV, REG_PV, mh);
3207 /* d contains return type */
3209 if (d != TYPE_VOID) {
3210 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3211 s1 = reg_of_var(rd, iptr->dst, REG_RESULT);
3212 M_INTMOVE(REG_RESULT, s1);
3213 store_reg_to_var_int(iptr->dst, s1);
3216 s1 = reg_of_var(rd, iptr->dst, REG_FRESULT);
3217 M_FLTMOVE(REG_FRESULT, s1);
3218 store_reg_to_var_flt(iptr->dst, s1);
3225 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3227 /* op1: 0 == array, 1 == class */
3228 /* val.a: (classinfo*) superclass */
3230 /* superclass is an interface:
3232 * return (sub != NULL) &&
3233 * (sub->vftbl->interfacetablelength > super->index) &&
3234 * (sub->vftbl->interfacetable[-super->index] != NULL);
3236 * superclass is a class:
3238 * return ((sub != NULL) && (0
3239 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3240 * super->vftbl->diffvall));
3244 classinfo *super = (classinfo*) iptr->val.a;
3246 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3247 codegen_threadcritrestart(cd, (u1 *) mcodeptr - cd->mcodebase);
3249 var_to_reg_int(s1, src, REG_ITMP1);
3250 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
3252 M_MOV(s1, REG_ITMP1);
3256 if (iptr->op1) { /* class/interface */
3257 if (super->flags & ACC_INTERFACE) { /* interface */
3259 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3260 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3261 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3262 M_BLEZ(REG_ITMP2, 2);
3263 M_ALD(REG_ITMP1, REG_ITMP1,
3264 OFFSET(vftbl_t, interfacetable[0]) -
3265 super->index * sizeof(methodptr*));
3266 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3270 s2 = super->vftbl->diffval;
3271 M_BEQZ(s1, 4 + (s2 > 255));
3272 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3273 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3274 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3276 M_CMPULE_IMM(REG_ITMP1, s2, d);
3278 M_LDA(REG_ITMP2, REG_ZERO, s2);
3279 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3283 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3284 a = dseg_addaddress(cd, (void*) super->vftbl);
3285 M_ALD(REG_ITMP2, REG_PV, a);
3286 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3287 codegen_threadcritstart(cd, (u1 *) mcodeptr - cd->mcodebase);
3289 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3290 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3291 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3292 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3293 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3295 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3296 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3300 panic ("internal error: no inlined array instanceof");
3302 store_reg_to_var_int(iptr->dst, d);
3305 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3307 /* op1: 0 == array, 1 == class */
3308 /* val.a: (classinfo*) superclass */
3310 /* superclass is an interface:
3312 * OK if ((sub == NULL) ||
3313 * (sub->vftbl->interfacetablelength > super->index) &&
3314 * (sub->vftbl->interfacetable[-super->index] != NULL));
3316 * superclass is a class:
3318 * OK if ((sub == NULL) || (0
3319 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3320 * super->vftbl->diffvall));
3324 classinfo *super = (classinfo *) iptr->val.a;
3326 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3327 codegen_threadcritrestart(cd, (u1 *) mcodeptr - cd->mcodebase);
3329 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
3330 var_to_reg_int(s1, src, d);
3331 if (iptr->op1) { /* class/interface */
3332 if (super->flags & ACC_INTERFACE) { /* interface */
3334 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3335 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3336 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3337 M_BLEZ(REG_ITMP2, 0);
3338 codegen_addxcastrefs(cd, mcodeptr);
3339 M_ALD(REG_ITMP2, REG_ITMP1,
3340 OFFSET(vftbl_t, interfacetable[0]) -
3341 super->index * sizeof(methodptr*));
3342 M_BEQZ(REG_ITMP2, 0);
3343 codegen_addxcastrefs(cd, mcodeptr);
3347 s2 = super->vftbl->diffval;
3348 M_BEQZ(s1, 4 + (s2 != 0) + (s2 > 255));
3349 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3350 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3351 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3353 M_BNEZ(REG_ITMP1, 0);
3355 else if (s2 <= 255) {
3356 M_CMPULE_IMM(REG_ITMP1, s2, REG_ITMP2);
3357 M_BEQZ(REG_ITMP2, 0);
3360 M_LDA(REG_ITMP2, REG_ZERO, s2);
3361 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3362 M_BEQZ(REG_ITMP2, 0);
3365 M_BEQZ(s1, 8 + (d == REG_ITMP3));
3366 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3367 a = dseg_addaddress(cd, (void *) super->vftbl);
3368 M_ALD(REG_ITMP2, REG_PV, a);
3369 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3370 codegen_threadcritstart(cd, (u1 *) mcodeptr - cd->mcodebase);
3372 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3373 if (d != REG_ITMP3) {
3374 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3375 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3376 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3377 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3379 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3382 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3383 M_ISUB(REG_ITMP1, REG_ITMP2, REG_ITMP1);
3384 M_ALD(REG_ITMP2, REG_PV, a);
3385 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3386 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3387 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3390 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3391 M_BEQZ(REG_ITMP2, 0);
3392 codegen_addxcastrefs(cd, mcodeptr);
3396 panic ("internal error: no inlined array checkcast");
3399 store_reg_to_var_int(iptr->dst, d);
3402 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
3404 var_to_reg_int(s1, src, REG_ITMP1);
3406 codegen_addxcheckarefs(cd, mcodeptr);
3409 case ICMD_CHECKEXCEPTION: /* ... ==> ... */
3411 M_BEQZ(REG_RESULT, 0);
3412 codegen_addxexceptionrefs(cd, mcodeptr);
3415 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3416 /* op1 = dimension, val.a = array descriptor */
3418 /* check for negative sizes and copy sizes to stack if necessary */
3420 MCODECHECK((iptr->op1 << 1) + 64);
3422 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3423 var_to_reg_int(s2, src, REG_ITMP1);
3425 codegen_addxcheckarefs(cd, mcodeptr);
3427 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
3429 if (src->varkind != ARGVAR) {
3430 M_LST(s2, REG_SP, 8 * (s1 + INT_ARG_CNT));
3434 /* a0 = dimension count */
3436 ICONST(rd->argintregs[0], iptr->op1);
3438 /* a1 = arraydescriptor */
3440 a = dseg_addaddress(cd, iptr->val.a);
3441 M_ALD(rd->argintregs[1], REG_PV, a);
3443 /* a2 = pointer to dimensions = stack pointer */
3445 M_INTMOVE(REG_SP, rd->argintregs[2]);
3447 a = dseg_addaddress(cd, (void *) builtin_nmultianewarray);
3448 M_ALD(REG_PV, REG_PV, a);
3449 M_JSR(REG_RA, REG_PV);
3450 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3452 M_LDA(REG_PV, REG_RA, -s1);
3454 s4 ml = -s1, mh = 0;
3455 while (ml < -32768) { ml += 65536; mh--; }
3456 M_LDA(REG_PV, REG_RA, ml);
3457 M_LDAH(REG_PV, REG_PV, mh);
3459 s1 = reg_of_var(rd, iptr->dst, REG_RESULT);
3460 M_INTMOVE(REG_RESULT, s1);
3461 store_reg_to_var_int(iptr->dst, s1);
3465 default: error ("Unknown pseudo command: %d", iptr->opc);
3471 } /* for instruction */
3473 /* copy values to interface registers */
3475 src = bptr->outstack;
3476 len = bptr->outdepth;
3480 if ((src->varkind != STACKVAR)) {
3482 if (IS_FLT_DBL_TYPE(s2)) {
3483 var_to_reg_flt(s1, src, REG_FTMP1);
3484 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3485 M_FLTMOVE(s1,rd->interfaces[len][s2].regoff);
3488 M_DST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3492 var_to_reg_int(s1, src, REG_ITMP1);
3493 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3494 M_INTMOVE(s1,rd->interfaces[len][s2].regoff);
3497 M_LST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3503 } /* if (bptr -> flags >= BBREACHED) */
3504 } /* for basic block */
3507 /* generate bound check stubs */
3509 s4 *xcodeptr = NULL;
3512 for (bref = cd->xboundrefs; bref != NULL; bref = bref->next) {
3513 gen_resolvebranch((u1*) cd->mcodebase + bref->branchpos,
3515 (u1*) mcodeptr - cd->mcodebase);
3519 /* move index register into REG_ITMP1 */
3520 M_MOV(bref->reg, REG_ITMP1);
3521 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3523 if (xcodeptr != NULL) {
3524 M_BR(xcodeptr - mcodeptr - 1);
3527 xcodeptr = mcodeptr;
3529 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3530 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3532 a = dseg_addaddress(cd, string_java_lang_ArrayIndexOutOfBoundsException);
3533 M_ALD(rd->argintregs[0], REG_PV, a);
3534 M_MOV(REG_ITMP1, rd->argintregs[1]);
3536 a = dseg_addaddress(cd, new_exception_int);
3537 M_ALD(REG_PV, REG_PV, a);
3538 M_JSR(REG_RA, REG_PV);
3541 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3542 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3544 s4 ml = -s1, mh = 0;
3545 while (ml < -32768) { ml += 65536; mh--; }
3546 M_LDA(REG_PV, REG_RA, ml);
3547 M_LDAH(REG_PV, REG_PV, mh);
3550 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3552 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3553 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3555 a = dseg_addaddress(cd, asm_handle_exception);
3556 M_ALD(REG_ITMP3, REG_PV, a);
3558 M_JMP(REG_ZERO, REG_ITMP3);
3562 /* generate negative array size check stubs */
3566 for (bref = cd->xcheckarefs; bref != NULL; bref = bref->next) {
3567 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3568 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3570 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3574 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3576 (u1 *) mcodeptr - cd->mcodebase);
3580 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3582 if (xcodeptr != NULL) {
3583 M_BR(xcodeptr - mcodeptr - 1);
3586 xcodeptr = mcodeptr;
3588 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3589 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3591 a = dseg_addaddress(cd, string_java_lang_NegativeArraySizeException);
3592 M_ALD(rd->argintregs[0], REG_PV, a);
3594 a = dseg_addaddress(cd, new_exception);
3595 M_ALD(REG_PV, REG_PV, a);
3596 M_JSR(REG_RA, REG_PV);
3599 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3600 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3602 s4 ml = -s1, mh = 0;
3603 while (ml < -32768) { ml += 65536; mh--; }
3604 M_LDA(REG_PV, REG_RA, ml);
3605 M_LDAH(REG_PV, REG_PV, mh);
3608 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3610 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3611 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3613 a = dseg_addaddress(cd, asm_handle_exception);
3614 M_ALD(REG_ITMP3, REG_PV, a);
3616 M_JMP(REG_ZERO, REG_ITMP3);
3620 /* generate cast check stubs */
3624 for (bref = cd->xcastrefs; bref != NULL; bref = bref->next) {
3625 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3626 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3628 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3632 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3634 (u1 *) mcodeptr - cd->mcodebase);
3638 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3640 if (xcodeptr != NULL) {
3641 M_BR(xcodeptr - mcodeptr - 1);
3644 xcodeptr = mcodeptr;
3646 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3647 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3649 a = dseg_addaddress(cd, string_java_lang_ClassCastException);
3650 M_ALD(rd->argintregs[0], REG_PV, a);
3652 a = dseg_addaddress(cd, new_exception);
3653 M_ALD(REG_PV, REG_PV, a);
3654 M_JSR(REG_RA, REG_PV);
3657 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3658 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3660 s4 ml = -s1, mh = 0;
3661 while (ml < -32768) { ml += 65536; mh--; }
3662 M_LDA(REG_PV, REG_RA, ml);
3663 M_LDAH(REG_PV, REG_PV, mh);
3666 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3668 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3669 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3671 a = dseg_addaddress(cd, asm_handle_exception);
3672 M_ALD(REG_ITMP3, REG_PV, a);
3674 M_JMP(REG_ZERO, REG_ITMP3);
3678 /* generate exception check stubs */
3682 for (bref = cd->xexceptionrefs; bref != NULL; bref = bref->next) {
3683 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3684 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3686 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3690 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3692 (u1 *) mcodeptr - cd->mcodebase);
3696 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3698 if (xcodeptr != NULL) {
3699 M_BR(xcodeptr - mcodeptr - 1);
3702 xcodeptr = mcodeptr;
3704 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3705 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3706 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3708 a = dseg_addaddress(cd, &builtin_get_exceptionptrptr);
3709 M_ALD(REG_PV, REG_PV, a);
3710 M_JSR(REG_RA, REG_PV);
3713 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3714 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3716 s4 ml = -s1, mh = 0;
3717 while (ml < -32768) { ml += 65536; mh--; }
3718 M_LDA(REG_PV, REG_RA, ml);
3719 M_LDAH(REG_PV, REG_PV, mh);
3722 M_ALD(REG_ITMP1_XPTR, REG_RESULT, 0);
3723 M_AST(REG_ZERO, REG_RESULT, 0);
3725 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3726 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3728 a = dseg_addaddress(cd, &_exceptionptr);
3729 M_ALD(REG_ITMP3, REG_PV, a);
3730 M_ALD(REG_ITMP1_XPTR, REG_ITMP3, 0);
3731 M_AST(REG_ZERO, REG_ITMP3, 0);
3734 a = dseg_addaddress(cd, asm_handle_exception);
3735 M_ALD(REG_ITMP3, REG_PV, a);
3737 M_JMP(REG_ZERO, REG_ITMP3);
3741 /* generate null pointer check stubs */
3745 for (bref = cd->xnullrefs; bref != NULL; bref = bref->next) {
3746 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3747 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3749 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3753 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3755 (u1 *) mcodeptr - cd->mcodebase);
3759 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3761 if (xcodeptr != NULL) {
3762 M_BR(xcodeptr - mcodeptr - 1);
3765 xcodeptr = mcodeptr;
3767 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3768 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3770 a = dseg_addaddress(cd, string_java_lang_NullPointerException);
3771 M_ALD(rd->argintregs[0], REG_PV, a);
3773 a = dseg_addaddress(cd, new_exception);
3774 M_ALD(REG_PV, REG_PV, a);
3775 M_JSR(REG_RA, REG_PV);
3778 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3779 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3781 s4 ml = -s1, mh = 0;
3782 while (ml < -32768) { ml += 65536; mh--; }
3783 M_LDA(REG_PV, REG_RA, ml);
3784 M_LDAH(REG_PV, REG_PV, mh);
3787 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3789 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3790 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3792 a = dseg_addaddress(cd, asm_handle_exception);
3793 M_ALD(REG_ITMP3, REG_PV, a);
3795 M_JMP(REG_ZERO, REG_ITMP3);
3800 codegen_finish(m, cd, (s4) ((u1 *) mcodeptr - cd->mcodebase));
3804 /* function createcompilerstub *************************************************
3806 creates a stub routine which calls the compiler
3808 *******************************************************************************/
3810 #define COMPSTUBSIZE 3
3812 u1 *createcompilerstub(methodinfo *m)
3814 u8 *s = CNEW(u8, COMPSTUBSIZE); /* memory to hold the stub */
3815 s4 *mcodeptr = (s4 *) s; /* code generation pointer */
3817 /* code for the stub */
3818 M_ALD(REG_PV, REG_PV, 16); /* load pointer to the compiler */
3819 M_JMP(0, REG_PV); /* jump to the compiler, return address
3820 in reg 0 is used as method pointer */
3821 s[1] = (u8) m; /* literals to be adressed */
3822 s[2] = (u8) asm_call_jit_compiler; /* jump directly via PV from above */
3824 #if defined(STATISTICS)
3826 count_cstub_len += COMPSTUBSIZE * 8;
3833 /* function removecompilerstub *************************************************
3835 deletes a compilerstub from memory (simply by freeing it)
3837 *******************************************************************************/
3839 void removecompilerstub(u1 *stub)
3841 CFREE(stub, COMPSTUBSIZE * 8);
3845 /* function: createnativestub **************************************************
3847 creates a stub routine which calls a native method
3849 *******************************************************************************/
3851 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3852 #define NATIVESTUBSTACK 2
3853 #define NATIVESTUBTHREADEXTRA 6
3855 #define NATIVESTUBSTACK 1
3856 #define NATIVESTUBTHREADEXTRA 1
3859 #define NATIVESTUBSIZE (44 + NATIVESTUBTHREADEXTRA - 1)
3860 #define NATIVESTATICSIZE 5
3861 #define NATIVEVERBOSESIZE (39 + 13)
3862 #define NATIVESTUBOFFSET 9
3864 u1 *createnativestub(functionptr f, methodinfo *m)
3866 u8 *s; /* memory pointer to hold the stub */
3868 s4 *mcodeptr; /* code generation pointer */
3869 s4 stackframesize = 0; /* size of stackframe if needed */
3874 t_inlining_globals *id;
3876 /* mark start of dump memory area */
3878 dumpsize = dump_size();
3880 /* setup registers before using it */
3882 rd = DNEW(registerdata);
3883 id = DNEW(t_inlining_globals);
3885 inlining_setup(m, id);
3886 reg_setup(m, rd, id);
3888 descriptor2types(m); /* set paramcount and paramtypes */
3890 stubsize = NATIVESTUBSIZE; /* calculate nativestub size */
3891 if ((m->flags & ACC_STATIC) && !m->class->initialized)
3892 stubsize += NATIVESTATICSIZE;
3895 stubsize += NATIVEVERBOSESIZE;
3897 s = CNEW(u8, stubsize); /* memory to hold the stub */
3898 cs = s + NATIVESTUBOFFSET;
3899 mcodeptr = (s4 *) (cs); /* code generation pointer */
3901 *(cs-1) = (u8) f; /* address of native method */
3902 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3903 *(cs-2) = (u8) &builtin_get_exceptionptrptr;
3905 *(cs-2) = (u8) (&_exceptionptr); /* address of exceptionptr */
3907 *(cs-3) = (u8) asm_handle_nat_exception; /* addr of asm exception handler */
3908 *(cs-4) = (u8) (&env); /* addr of jni_environement */
3909 *(cs-5) = (u8) builtin_trace_args;
3911 *(cs-7) = (u8) builtin_displaymethodstop;
3912 *(cs-8) = (u8) m->class;
3913 *(cs-9) = (u8) asm_check_clinit;
3915 M_LDA(REG_SP, REG_SP, -NATIVESTUBSTACK * 8); /* build up stackframe */
3916 M_AST(REG_RA, REG_SP, 0 * 8); /* store return address */
3918 /* if function is static, check for initialized */
3920 if (m->flags & ACC_STATIC) {
3921 /* if class isn't yet initialized, do it */
3922 if (!m->class->initialized) {
3923 /* call helper function which patches this code */
3924 M_ALD(REG_ITMP1, REG_PV, -8 * 8); /* class */
3925 M_ALD(REG_PV, REG_PV, -9 * 8); /* asm_check_clinit */
3926 M_JSR(REG_RA, REG_PV);
3927 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
3928 M_LDA(REG_PV, REG_RA, disp);
3929 M_NOP; /* this is essential for code patching */
3933 /* max. 39 instructions */
3937 M_LDA(REG_SP, REG_SP, -((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
3938 M_AST(REG_RA, REG_SP, 1 * 8);
3940 /* save integer argument registers */
3941 for (p = 0; p < m->paramcount && p < INT_ARG_CNT; p++) {
3942 M_LST(rd->argintregs[p], REG_SP, (2 + p) * 8);
3945 /* save and copy float arguments into integer registers */
3946 for (p = 0; p < m->paramcount && p < FLT_ARG_CNT; p++) {
3947 t = m->paramtypes[p];
3949 if (IS_FLT_DBL_TYPE(t)) {
3950 if (IS_2_WORD_TYPE(t)) {
3951 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
3952 M_LLD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
3955 M_FST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
3956 M_ILD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
3960 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
3964 M_ALD(REG_ITMP1, REG_PV, -6 * 8);
3965 M_AST(REG_ITMP1, REG_SP, 0 * 8);
3966 M_ALD(REG_PV, REG_PV, -5 * 8);
3967 M_JSR(REG_RA, REG_PV);
3968 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
3969 M_LDA(REG_PV, REG_RA, disp);
3971 for (p = 0; p < m->paramcount && p < INT_ARG_CNT; p++) {
3972 M_LLD(rd->argintregs[p], REG_SP, (2 + p) * 8);
3975 for (p = 0; p < m->paramcount && p < FLT_ARG_CNT; p++) {
3976 t = m->paramtypes[p];
3978 if (IS_FLT_DBL_TYPE(t)) {
3979 if (IS_2_WORD_TYPE(t)) {
3980 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
3983 M_FLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
3987 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
3991 M_ALD(REG_RA, REG_SP, 1 * 8);
3992 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT + 2) * 8);
3995 /* save argument registers on stack -- if we have to */
3996 if ((m->flags & ACC_STATIC && m->paramcount > (INT_ARG_CNT - 2)) || m->paramcount > (INT_ARG_CNT - 1)) {
3998 s4 paramshiftcnt = (m->flags & ACC_STATIC) ? 2 : 1;
3999 s4 stackparamcnt = (m->paramcount > INT_ARG_CNT) ? m->paramcount - INT_ARG_CNT : 0;
4001 stackframesize = stackparamcnt + paramshiftcnt;
4003 M_LDA(REG_SP, REG_SP, -stackframesize * 8);
4005 /* copy stack arguments into new stack frame -- if any */
4006 for (i = 0; i < stackparamcnt; i++) {
4007 M_LLD(REG_ITMP1, REG_SP, (stackparamcnt + 1 + i) * 8);
4008 M_LST(REG_ITMP1, REG_SP, (paramshiftcnt + i) * 8);
4011 if (m->flags & ACC_STATIC) {
4012 if (IS_FLT_DBL_TYPE(m->paramtypes[5])) {
4013 M_DST(rd->argfltregs[5], REG_SP, 1 * 8);
4015 M_LST(rd->argintregs[5], REG_SP, 1 * 8);
4018 if (IS_FLT_DBL_TYPE(m->paramtypes[4])) {
4019 M_DST(rd->argfltregs[4], REG_SP, 0 * 8);
4021 M_LST(rd->argintregs[4], REG_SP, 0 * 8);
4025 if (IS_FLT_DBL_TYPE(m->paramtypes[5])) {
4026 M_DST(rd->argfltregs[5], REG_SP, 0 * 8);
4028 M_LST(rd->argintregs[5], REG_SP, 0 * 8);
4033 if (m->flags & ACC_STATIC) {
4034 M_MOV(rd->argintregs[3], rd->argintregs[5]);
4035 M_MOV(rd->argintregs[2], rd->argintregs[4]);
4036 M_MOV(rd->argintregs[1], rd->argintregs[3]);
4037 M_MOV(rd->argintregs[0], rd->argintregs[2]);
4038 M_FMOV(rd->argfltregs[3], rd->argfltregs[5]);
4039 M_FMOV(rd->argfltregs[2], rd->argfltregs[4]);
4040 M_FMOV(rd->argfltregs[1], rd->argfltregs[3]);
4041 M_FMOV(rd->argfltregs[0], rd->argfltregs[2]);
4043 /* put class into second argument register */
4044 M_ALD(rd->argintregs[1], REG_PV, -8 * 8);
4047 M_MOV(rd->argintregs[4], rd->argintregs[5]);
4048 M_MOV(rd->argintregs[3], rd->argintregs[4]);
4049 M_MOV(rd->argintregs[2], rd->argintregs[3]);
4050 M_MOV(rd->argintregs[1], rd->argintregs[2]);
4051 M_MOV(rd->argintregs[0], rd->argintregs[1]);
4052 M_FMOV(rd->argfltregs[4], rd->argfltregs[5]);
4053 M_FMOV(rd->argfltregs[3], rd->argfltregs[4]);
4054 M_FMOV(rd->argfltregs[2], rd->argfltregs[3]);
4055 M_FMOV(rd->argfltregs[1], rd->argfltregs[2]);
4056 M_FMOV(rd->argfltregs[0], rd->argfltregs[1]);
4059 /* put env into first argument register */
4060 M_ALD(rd->argintregs[0], REG_PV, -4 * 8);
4062 M_ALD(REG_PV, REG_PV, -1 * 8); /* load adress of native method */
4063 M_JSR(REG_RA, REG_PV); /* call native method */
4064 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4065 M_LDA(REG_PV, REG_RA, disp); /* recompute pv from ra */
4067 /* remove stackframe if there is one */
4068 if (stackframesize) {
4069 M_LDA(REG_SP, REG_SP, stackframesize * 8);
4072 /* 13 instructions */
4074 M_LDA(REG_SP, REG_SP, -2 * 8);
4075 M_ALD(rd->argintregs[0], REG_PV, -6 * 8); /* load method adress */
4076 M_LST(REG_RESULT, REG_SP, 0 * 8);
4077 M_DST(REG_FRESULT, REG_SP, 1 * 8);
4078 M_MOV(REG_RESULT, rd->argintregs[1]);
4079 M_FMOV(REG_FRESULT, rd->argfltregs[2]);
4080 M_FMOV(REG_FRESULT, rd->argfltregs[3]);
4081 M_ALD(REG_PV, REG_PV, -7 * 8); /* builtin_displaymethodstop */
4082 M_JSR(REG_RA, REG_PV);
4083 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4084 M_LDA(REG_PV, REG_RA, disp);
4085 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4086 M_DLD(REG_FRESULT, REG_SP, 1 * 8);
4087 M_LDA(REG_SP, REG_SP, 2 * 8);
4090 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4091 if (IS_FLT_DBL_TYPE(m->returntype))
4092 M_DST(REG_FRESULT, REG_SP, 1 * 8);
4094 M_AST(REG_RESULT, REG_SP, 1 * 8);
4095 M_ALD(REG_PV, REG_PV, -2 * 8); /* builtin_get_exceptionptrptr */
4096 M_JSR(REG_RA, REG_PV);
4097 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4098 M_LDA(REG_PV, REG_RA, disp);
4099 M_MOV(REG_RESULT, REG_ITMP3);
4100 if (IS_FLT_DBL_TYPE(m->returntype))
4101 M_DLD(REG_FRESULT, REG_SP, 1 * 8);
4103 M_ALD(REG_RESULT, REG_SP, 1 * 8);
4105 M_ALD(REG_ITMP3, REG_PV, -2 * 8); /* get address of exceptionptr */
4107 M_ALD(REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
4108 M_BNEZ(REG_ITMP1, 3); /* if no exception then return */
4110 M_ALD(REG_RA, REG_SP, 0 * 8); /* load return address */
4111 M_LDA(REG_SP, REG_SP, NATIVESTUBSTACK * 8); /* remove stackframe */
4112 M_RET(REG_ZERO, REG_RA); /* return to caller */
4114 M_AST(REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
4116 M_ALD(REG_RA, REG_SP, 0 * 8); /* load return address */
4117 M_LDA(REG_SP, REG_SP, NATIVESTUBSTACK * 8); /* remove stackframe */
4118 M_LDA(REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
4119 M_ALD(REG_ITMP3, REG_PV, -3 * 8); /* load asm exception handler address */
4120 M_JMP(REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
4123 dolog_plain("stubsize: %d (for %d params)\n", (int) (mcodeptr - (s4*) s), m->paramcount);
4126 #if defined(STATISTICS)
4128 count_nstub_len += NATIVESTUBSIZE * 8;
4131 /* release dump area */
4133 dump_release(dumpsize);
4135 return (u1 *) (s + NATIVESTUBOFFSET);
4139 /* function: removenativestub **************************************************
4141 removes a previously created native-stub from memory
4143 *******************************************************************************/
4145 void removenativestub(u1 *stub)
4147 CFREE((u8 *) stub - NATIVESTUBOFFSET, NATIVESTUBSIZE * 8);
4152 * These are local overrides for various environment variables in Emacs.
4153 * Please do not remove this and leave it at the end of the file, where
4154 * Emacs will automagically detect them.
4155 * ---------------------------------------------------------------------
4158 * indent-tabs-mode: t