1 /* jit/mips/codegen.c - machine code generator for mips
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 Contains the codegenerator for an MIPS (R4000 or higher) processor.
32 This module generates MIPS machine code for a sequence of
33 intermediate code commands (ICMDs).
35 $Id: codegen.c 1291 2004-07-09 13:20:56Z twisti $
44 #include "jit/mips/types.h"
54 #include "jit/mips/codegen.h"
56 /* include independent code generation stuff */
57 #include "jit/codegen.inc"
58 #include "jit/reg.inc"
61 /* *****************************************************************************
63 Datatypes and Register Allocations:
64 -----------------------------------
66 On 64-bit-machines (like the MIPS) all operands are stored in the
67 registers in a 64-bit form, even when the correspondig JavaVM operands
68 only need 32 bits. This is done by a canonical representation:
70 32-bit integers are allways stored as sign-extended 64-bit values (this
71 approach is directly supported by the MIPS architecture and is very easy
74 32-bit-floats are stored in a 64-bit double precision register by simply
75 expanding the exponent and mantissa with zeroes. (also supported by the
81 The calling conventions and the layout of the stack is explained in detail
82 in the documention file: calling.doc
84 *******************************************************************************/
87 /* register descripton - array ************************************************/
89 /* #define REG_RES 0 reserved register for OS or code generator */
90 /* #define REG_RET 1 return value register */
91 /* #define REG_EXC 2 exception value register (only old jit) */
92 /* #define REG_SAV 3 (callee) saved register */
93 /* #define REG_TMP 4 scratch temporary register (caller saved) */
94 /* #define REG_ARG 5 argument register (caller saved) */
96 /* #define REG_END -1 last entry in tables */
99 REG_RES, REG_RES, REG_RET, REG_RES, REG_ARG, REG_ARG, REG_ARG, REG_ARG,
100 REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
101 REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
102 REG_TMP, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES,
105 /* for use of reserved registers, see comment above */
107 int nregdescfloat[] = {
108 REG_RET, REG_RES, REG_RES, REG_RES, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
109 REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_ARG, REG_ARG, REG_ARG, REG_ARG,
110 REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
111 REG_SAV, REG_TMP, REG_SAV, REG_TMP, REG_SAV, REG_TMP, REG_SAV, REG_TMP,
114 /* for use of reserved registers, see comment above */
117 /* NullPointerException handlers and exception handling initialisation */
119 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
120 void thread_restartcriticalsection(ucontext_t *uc)
123 if ((critical = thread_checkcritical((void*) uc->uc_mcontext.gregs[CTX_EPC])) != NULL)
124 uc->uc_mcontext.gregs[CTX_EPC] = (u8) critical;
128 /* NullPointerException signal handler for hardware null pointer check */
130 void catch_NullPointerException(int sig, int code, struct sigcontext *sigctx)
135 java_objectheader *xptr;
137 /* Reset signal handler - necessary for SysV, does no harm for BSD */
139 instr = *((int*)(sigctx->sc_pc));
140 faultaddr = sigctx->sc_regs[(instr >> 21) & 0x1f];
142 if (faultaddr == 0) {
144 sigaddset(&nsig, sig);
145 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
147 xptr = new_exception(string_java_lang_NullPointerException);
150 sigctx->sc_regs[REG_ITMP1_XPTR] = (u8) xptr;
151 sigctx->sc_regs[REG_ITMP2_XPC] = sigctx->sc_pc;
152 sigctx->sc_pc = (u8) asm_handle_exception;
155 faultaddr += (long) ((instr << 16) >> 16);
156 fprintf(stderr, "faulting address: 0x%lx at 0x%lx\n", (long) faultaddr, (long) sigctx->sc_pc);
157 panic("Stack overflow");
164 void init_exceptions(void)
167 sigset_t unblockmask;
169 /* The Boehm GC initialization blocks the SIGSEGV signal. So we do a
170 dummy allocation here to ensure that the GC is initialized.
172 heap_allocate(1, 0, NULL);
174 /* install signal handlers we need to convert to exceptions */
176 sigemptyset(&unblockmask);
178 sa.sa_sigaction = catch_NullPointerException;
179 sigemptyset(&sa.sa_mask);
183 sigaction(SIGSEGV, &sa, NULL);
184 sigaddset(&unblockmask, SIGSEGV);
188 sigaction(SIGBUS, &sa, NULL);
189 sigaddset(&unblockmask, SIGBUS);
193 sigprocmask(SIG_UNBLOCK, &unblockmask, NULL);
195 /* Turn off flush-to-zero */
198 n.fc_word = get_fpc_csr();
199 n.fc_struct.flush = 0;
200 set_fpc_csr(n.fc_word);
205 /* function gen_mcode **********************************************************
207 generates machine code
209 *******************************************************************************/
211 void codegen(methodinfo *m)
213 s4 len, s1, s2, s3, d;
228 /* keep code size smaller */
231 savedregs_num = (m->isleafmethod) ? 0 : 1; /* space to save the RA */
233 /* space to save used callee saved registers */
235 savedregs_num += (r->savintregcnt - r->maxsavintreguse);
236 savedregs_num += (r->savfltregcnt - r->maxsavfltreguse);
238 parentargs_base = r->maxmemuse + savedregs_num;
240 #if defined(USE_THREADS) /* space to save argument of monitor_enter */
242 if (checksync && (m->flags & ACC_SYNCHRONIZED))
247 /* adjust frame size for 16 byte alignment */
249 if (parentargs_base & 1)
252 /* create method header */
255 (void) dseg_addaddress(m); /* Filler */
257 (void) dseg_addaddress(m); /* MethodPointer */
258 (void) dseg_adds4(parentargs_base * 8); /* FrameSize */
260 #if defined(USE_THREADS)
262 /* IsSync contains the offset relative to the stack pointer for the
263 argument of monitor_exit used in the exception handler. Since the
264 offset could be zero and give a wrong meaning of the flag it is
268 if (checksync && (m->flags & ACC_SYNCHRONIZED))
269 (void) dseg_adds4((r->maxmemuse + 1) * 8); /* IsSync */
274 (void) dseg_adds4(0); /* IsSync */
276 (void) dseg_adds4(m->isleafmethod); /* IsLeaf */
277 (void) dseg_adds4(r->savintregcnt - r->maxsavintreguse);/* IntSave */
278 (void) dseg_adds4(r->savfltregcnt - r->maxsavfltreguse);/* FltSave */
279 (void) dseg_adds4(m->exceptiontablelength); /* ExTableSize */
281 /* create exception table */
283 for (ex = m->exceptiontable; ex != NULL; ex = ex->down) {
284 dseg_addtarget(ex->start);
285 dseg_addtarget(ex->end);
286 dseg_addtarget(ex->handler);
287 (void) dseg_addaddress(ex->catchtype);
290 /* initialize mcode variables */
292 mcodeptr = (s4 *) mcodebase;
293 mcodeend = (s4 *) (mcodebase + mcodesize);
294 MCODECHECK(128 + m->paramcount);
296 /* create stack frame (if necessary) */
298 if (parentargs_base) {
299 M_LDA(REG_SP, REG_SP, -parentargs_base * 8);
302 /* save return address and used callee saved registers */
305 if (!m->isleafmethod) {
306 p--; M_LST(REG_RA, REG_SP, 8 * p);
308 for (i = r->savintregcnt - 1; i >= r->maxsavintreguse; i--) {
309 p--; M_LST(r->savintregs[i], REG_SP, 8 * p);
311 for (i = r->savfltregcnt - 1; i >= r->maxsavfltreguse; i--) {
312 p--; M_DST(r->savfltregs[i], REG_SP, 8 * p);
315 /* save monitorenter argument */
317 #if defined(USE_THREADS)
318 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
319 if (m->flags & ACC_STATIC) {
320 p = dseg_addaddress(m->class);
321 M_ALD(REG_ITMP1, REG_PV, p);
322 M_AST(REG_ITMP1, REG_SP, r->maxmemuse * 8);
325 M_AST(r->argintregs[0], REG_SP, r->maxmemuse * 8);
330 /* copy argument registers to stack and call trace function with pointer
331 to arguments on stack. ToDo: save floating point registers !!!!!!!!!
335 M_LDA(REG_SP, REG_SP, -(18 * 8));
336 M_LST(REG_RA, REG_SP, 1 * 8);
338 /* save integer argument registers */
339 for (p = 0; p < m->paramcount && p < INT_ARG_CNT; p++) {
340 M_LST(r->argintregs[p], REG_SP, (2 + p) * 8);
343 /* save and copy float arguments into integer registers */
344 for (p = 0; p < m->paramcount && p < FLT_ARG_CNT; p++) {
345 t = m->paramtypes[p];
347 if (IS_FLT_DBL_TYPE(t)) {
348 if (IS_2_WORD_TYPE(t)) {
349 M_DST(r->argfltregs[p], REG_SP, (10 + p) * 8);
350 M_LLD(r->argintregs[p], REG_SP, (10 + p) * 8);
353 M_FST(r->argfltregs[p], REG_SP, (10 + p) * 8);
354 M_ILD(r->argintregs[p], REG_SP, (10 + p) * 8);
358 M_DST(r->argfltregs[p], REG_SP, (10 + p) * 8);
362 p = dseg_addaddress(m);
363 M_ALD(REG_ITMP1, REG_PV, p);
364 M_LST(REG_ITMP1, REG_SP, 0);
365 p = dseg_addaddress((void *) builtin_trace_args);
366 M_ALD(REG_ITMP3, REG_PV, p);
367 M_JSR(REG_RA, REG_ITMP3);
370 M_LLD(REG_RA, REG_SP, 1 * 8);
372 for (p = 0; p < m->paramcount && p < INT_ARG_CNT; p++) {
373 M_LLD(r->argintregs[p], REG_SP, (2 + p) * 8);
376 for (p = 0; p < m->paramcount && p < FLT_ARG_CNT; p++) {
377 t = m->paramtypes[p];
379 if (IS_FLT_DBL_TYPE(t)) {
380 if (IS_2_WORD_TYPE(t)) {
381 M_DLD(r->argfltregs[p], REG_SP, (10 + p) * 8);
384 M_FLD(r->argfltregs[p], REG_SP, (10 + p) * 8);
388 M_DLD(r->argfltregs[p], REG_SP, (10 + p) * 8);
392 M_LDA(REG_SP, REG_SP, 18 * 8);
395 /* take arguments out of register or stack frame */
397 for (p = 0, l = 0; p < m->paramcount; p++) {
398 t = m->paramtypes[p];
399 var = &(r->locals[l][t]);
401 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
405 if (IS_INT_LNG_TYPE(t)) { /* integer args */
406 if (p < INT_ARG_CNT) { /* register arguments */
407 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
408 M_INTMOVE(r->argintregs[p], var->regoff);
409 } else { /* reg arg -> spilled */
410 M_LST(r->argintregs[p], REG_SP, 8 * var->regoff);
413 } else { /* stack arguments */
414 pa = p - INT_ARG_CNT;
415 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
416 M_LLD(var->regoff, REG_SP, 8 * (parentargs_base + pa));
418 } else { /* stack arg -> spilled */
419 M_LLD(REG_ITMP1, REG_SP, 8 * (parentargs_base + pa));
420 M_LST(REG_ITMP1, REG_SP, 8 * var->regoff);
424 } else { /* floating args */
425 if (p < FLT_ARG_CNT) { /* register arguments */
426 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
427 M_TFLTMOVE(var->type, r->argfltregs[p], var->regoff);
429 } else { /* reg arg -> spilled */
430 M_DST(r->argfltregs[p], REG_SP, var->regoff * 8);
433 } else { /* stack arguments */
434 pa = p - FLT_ARG_CNT;
435 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
436 M_DLD(var->regoff, REG_SP, 8 * (parentargs_base + pa));
438 } else { /* stack-arg -> spilled */
439 M_DLD(REG_FTMP1, REG_SP, 8 * (parentargs_base + pa));
440 M_DST(REG_FTMP1, REG_SP, 8 * var->regoff);
446 /* call monitorenter function */
448 #if defined(USE_THREADS)
449 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
451 s8 func_enter = (m->flags & ACC_STATIC) ?
452 (s8) builtin_staticmonitorenter : (s8) builtin_monitorenter;
453 p = dseg_addaddress((void *) func_enter);
454 M_ALD(REG_ITMP3, REG_PV, p);
455 M_JSR(REG_RA, REG_ITMP3);
456 M_ALD(r->argintregs[0], REG_SP, r->maxmemuse * 8);
457 disp = -(s4) ((u1 *) mcodeptr - mcodebase);
458 M_LDA(REG_PV, REG_RA, disp);
463 /* end of header generation */
465 /* walk through all basic blocks */
466 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
468 bptr->mpc = (s4) ((u1 *) mcodeptr - mcodebase);
470 if (bptr->flags >= BBREACHED) {
472 /* branch resolving */
476 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
477 gen_resolvebranch((u1*) mcodebase + brefs->branchpos,
483 /* copy interface registers to their destination */
488 while (src != NULL) {
490 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
491 d = reg_of_var(m, src, REG_ITMP1);
492 M_INTMOVE(REG_ITMP1, d);
493 store_reg_to_var_int(src, d);
496 d = reg_of_var(m, src, REG_IFTMP);
497 if ((src->varkind != STACKVAR)) {
499 if (IS_FLT_DBL_TYPE(s2)) {
500 if (!(r->interfaces[len][s2].flags & INMEMORY)) {
501 s1 = r->interfaces[len][s2].regoff;
502 M_TFLTMOVE(s2, s1, d);
505 M_DLD(d, REG_SP, 8 * r->interfaces[len][s2].regoff);
507 store_reg_to_var_flt(src, d);
510 if (!(r->interfaces[len][s2].flags & INMEMORY)) {
511 s1 = r->interfaces[len][s2].regoff;
515 M_LLD(d, REG_SP, 8 * r->interfaces[len][s2].regoff);
517 store_reg_to_var_int(src, d);
524 /* walk through all instructions */
528 for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
530 MCODECHECK(64); /* an instruction usually needs < 64 words */
533 case ICMD_NOP: /* ... ==> ... */
536 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
538 var_to_reg_int(s1, src, REG_ITMP1);
540 codegen_addxnullrefs(mcodeptr);
544 /* constant operations ************************************************/
546 #define ICONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_IADD_IMM(REG_ZERO,c,r);} \
547 else if(((c)>=0)&&((c)<=0xffff)){M_OR_IMM(REG_ZERO,c,r);} \
548 else{a=dseg_adds4(c);M_ILD(r,REG_PV,a);}
550 #define LCONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LADD_IMM(REG_ZERO,c,r);} \
551 else if(((c)>=0)&&((c)<=0xffff)){M_OR_IMM(REG_ZERO,c,r);} \
552 else{a=dseg_adds8(c);M_LLD(r,REG_PV,a);}
554 case ICMD_ICONST: /* ... ==> ..., constant */
555 /* op1 = 0, val.i = constant */
557 d = reg_of_var(m, iptr->dst, REG_ITMP1);
558 ICONST(d, iptr->val.i);
559 store_reg_to_var_int(iptr->dst, d);
562 case ICMD_LCONST: /* ... ==> ..., constant */
563 /* op1 = 0, val.l = constant */
565 d = reg_of_var(m, iptr->dst, REG_ITMP1);
566 LCONST(d, iptr->val.l);
567 store_reg_to_var_int(iptr->dst, d);
570 case ICMD_FCONST: /* ... ==> ..., constant */
571 /* op1 = 0, val.f = constant */
573 d = reg_of_var(m, iptr->dst, REG_FTMP1);
574 a = dseg_addfloat(iptr->val.f);
576 store_reg_to_var_flt(iptr->dst, d);
579 case ICMD_DCONST: /* ... ==> ..., constant */
580 /* op1 = 0, val.d = constant */
582 d = reg_of_var(m, iptr->dst, REG_FTMP1);
583 a = dseg_adddouble(iptr->val.d);
585 store_reg_to_var_flt (iptr->dst, d);
588 case ICMD_ACONST: /* ... ==> ..., constant */
589 /* op1 = 0, val.a = constant */
591 d = reg_of_var(m, iptr->dst, REG_ITMP1);
593 a = dseg_addaddress(iptr->val.a);
597 M_INTMOVE(REG_ZERO, d);
599 store_reg_to_var_int(iptr->dst, d);
603 /* load/store operations **********************************************/
605 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
606 case ICMD_LLOAD: /* op1 = local variable */
609 d = reg_of_var(m, iptr->dst, REG_ITMP1);
610 if ((iptr->dst->varkind == LOCALVAR) &&
611 (iptr->dst->varnum == iptr->op1))
613 var = &(r->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
614 if (var->flags & INMEMORY) {
615 M_LLD(d, REG_SP, 8 * var->regoff);
617 M_INTMOVE(var->regoff,d);
619 store_reg_to_var_int(iptr->dst, d);
622 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
623 case ICMD_DLOAD: /* op1 = local variable */
625 d = reg_of_var(m, iptr->dst, REG_FTMP1);
626 if ((iptr->dst->varkind == LOCALVAR) &&
627 (iptr->dst->varnum == iptr->op1))
629 var = &(r->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
631 int t2 = ((iptr->opc == ICMD_FLOAD) ? TYPE_FLT : TYPE_DBL);
632 if (var->flags & INMEMORY) {
633 M_CCFLD(var->type, t2, d, REG_SP, 8 * var->regoff);
635 M_CCFLTMOVE(var->type, t2, var->regoff, d);
638 store_reg_to_var_flt(iptr->dst, d);
642 case ICMD_ISTORE: /* ..., value ==> ... */
643 case ICMD_LSTORE: /* op1 = local variable */
646 if ((src->varkind == LOCALVAR) &&
647 (src->varnum == iptr->op1))
649 var = &(r->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
650 if (var->flags & INMEMORY) {
651 var_to_reg_int(s1, src, REG_ITMP1);
652 M_LST(s1, REG_SP, 8 * var->regoff);
655 var_to_reg_int(s1, src, var->regoff);
656 M_INTMOVE(s1, var->regoff);
660 case ICMD_FSTORE: /* ..., value ==> ... */
661 case ICMD_DSTORE: /* op1 = local variable */
663 if ((src->varkind == LOCALVAR) &&
664 (src->varnum == iptr->op1))
666 var = &(r->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
668 int t1 = ((iptr->opc == ICMD_FSTORE) ? TYPE_FLT : TYPE_DBL);
669 if (var->flags & INMEMORY) {
670 var_to_reg_flt(s1, src, REG_FTMP1);
671 M_CCFST(t1, var->type, s1, REG_SP, 8 * var->regoff);
674 var_to_reg_flt(s1, src, var->regoff);
675 M_CCFLTMOVE(t1, var->type, s1, var->regoff);
681 /* pop/dup/swap operations ********************************************/
683 /* attention: double and longs are only one entry in CACAO ICMDs */
685 case ICMD_POP: /* ..., value ==> ... */
686 case ICMD_POP2: /* ..., value, value ==> ... */
689 #define M_COPY(from,to) \
690 d = reg_of_var(m, to, REG_IFTMP); \
691 if ((from->regoff != to->regoff) || \
692 ((from->flags ^ to->flags) & INMEMORY)) { \
693 if (IS_FLT_DBL_TYPE(from->type)) { \
694 var_to_reg_flt(s1, from, d); \
695 M_TFLTMOVE(from->type,s1,d); \
696 store_reg_to_var_flt(to, d); \
699 var_to_reg_int(s1, from, d); \
701 store_reg_to_var_int(to, d); \
705 case ICMD_DUP: /* ..., a ==> ..., a, a */
706 M_COPY(src, iptr->dst);
709 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
711 M_COPY(src, iptr->dst->prev->prev);
713 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
715 M_COPY(src, iptr->dst);
716 M_COPY(src->prev, iptr->dst->prev);
719 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
721 M_COPY(src->prev, iptr->dst->prev->prev->prev);
723 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
725 M_COPY(src, iptr->dst);
726 M_COPY(src->prev, iptr->dst->prev);
727 M_COPY(src->prev->prev, iptr->dst->prev->prev);
728 M_COPY(src, iptr->dst->prev->prev->prev);
731 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
733 M_COPY(src, iptr->dst);
734 M_COPY(src->prev, iptr->dst->prev);
735 M_COPY(src->prev->prev, iptr->dst->prev->prev);
736 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
737 M_COPY(src, iptr->dst->prev->prev->prev->prev);
738 M_COPY(src->prev, iptr->dst->prev->prev->prev->prev->prev);
741 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
743 M_COPY(src, iptr->dst->prev);
744 M_COPY(src->prev, iptr->dst);
748 /* integer operations *************************************************/
750 case ICMD_INEG: /* ..., value ==> ..., - value */
752 var_to_reg_int(s1, src, REG_ITMP1);
753 d = reg_of_var(m, iptr->dst, REG_ITMP3);
754 M_ISUB(REG_ZERO, s1, d);
755 store_reg_to_var_int(iptr->dst, d);
758 case ICMD_LNEG: /* ..., value ==> ..., - value */
760 var_to_reg_int(s1, src, REG_ITMP1);
761 d = reg_of_var(m, iptr->dst, REG_ITMP3);
762 M_LSUB(REG_ZERO, s1, d);
763 store_reg_to_var_int(iptr->dst, d);
766 case ICMD_I2L: /* ..., value ==> ..., value */
768 var_to_reg_int(s1, src, REG_ITMP1);
769 d = reg_of_var(m, iptr->dst, REG_ITMP3);
771 store_reg_to_var_int(iptr->dst, d);
774 case ICMD_L2I: /* ..., value ==> ..., value */
776 var_to_reg_int(s1, src, REG_ITMP1);
777 d = reg_of_var(m, iptr->dst, REG_ITMP3);
778 M_ISLL_IMM(s1, 0, d );
779 store_reg_to_var_int(iptr->dst, d);
782 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
784 var_to_reg_int(s1, src, REG_ITMP1);
785 d = reg_of_var(m, iptr->dst, REG_ITMP3);
786 M_LSLL_IMM(s1, 56, d);
787 M_LSRA_IMM( d, 56, d);
788 store_reg_to_var_int(iptr->dst, d);
791 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
793 var_to_reg_int(s1, src, REG_ITMP1);
794 d = reg_of_var(m, iptr->dst, REG_ITMP3);
796 store_reg_to_var_int(iptr->dst, d);
799 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
801 var_to_reg_int(s1, src, REG_ITMP1);
802 d = reg_of_var(m, iptr->dst, REG_ITMP3);
803 M_LSLL_IMM(s1, 48, d);
804 M_LSRA_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(m, 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(m, iptr->dst, REG_ITMP3);
823 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
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(m, 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(m, iptr->dst, REG_ITMP3);
847 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
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(m, 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(m, iptr->dst, REG_ITMP3);
871 if ((iptr->val.i >= -32767) && (iptr->val.i <= 32768)) {
872 M_IADD_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(m, 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(m, iptr->dst, REG_ITMP3);
895 if ((iptr->val.l >= -32767) && (iptr->val.l <= 32768)) {
896 M_LADD_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(m, iptr->dst, REG_ITMP3);
914 store_reg_to_var_int(iptr->dst, d);
917 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
918 /* val.i = constant */
920 var_to_reg_int(s1, src, REG_ITMP1);
921 d = reg_of_var(m, iptr->dst, REG_ITMP3);
922 ICONST(REG_ITMP2, iptr->val.i);
923 M_IMUL(s1, REG_ITMP2);
927 store_reg_to_var_int(iptr->dst, d);
930 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
932 var_to_reg_int(s1, src->prev, REG_ITMP1);
933 var_to_reg_int(s2, src, REG_ITMP2);
934 d = reg_of_var(m, iptr->dst, REG_ITMP3);
939 store_reg_to_var_int(iptr->dst, d);
942 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
943 /* val.l = constant */
945 var_to_reg_int(s1, src, REG_ITMP1);
946 d = reg_of_var(m, iptr->dst, REG_ITMP3);
947 LCONST(REG_ITMP2, iptr->val.l);
948 M_LMUL(s1, REG_ITMP2);
952 store_reg_to_var_int(iptr->dst, d);
955 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
957 var_to_reg_int(s1, src->prev, REG_ITMP1);
958 var_to_reg_int(s2, src, REG_ITMP2);
959 d = reg_of_var(m, iptr->dst, REG_ITMP3);
964 store_reg_to_var_int(iptr->dst, d);
967 case ICMD_IDIVCONST: /* ..., value ==> ..., value / constant */
968 /* val.i = constant */
970 var_to_reg_int(s1, src, REG_ITMP1);
971 d = reg_of_var(m, iptr->dst, REG_ITMP3);
972 ICONST(REG_ITMP2, iptr->val.i);
973 M_IDIV(s1, REG_ITMP2);
977 store_reg_to_var_int(iptr->dst, d);
980 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
982 var_to_reg_int(s1, src->prev, REG_ITMP1);
983 var_to_reg_int(s2, src, REG_ITMP2);
984 d = reg_of_var(m, iptr->dst, REG_ITMP3);
989 store_reg_to_var_int(iptr->dst, d);
992 case ICMD_LDIVCONST: /* ..., value ==> ..., value / constant */
993 /* val.l = constant */
995 var_to_reg_int(s1, src, REG_ITMP1);
996 d = reg_of_var(m, iptr->dst, REG_ITMP3);
997 LCONST(REG_ITMP2, iptr->val.l);
998 M_LDIV(s1, REG_ITMP2);
1002 store_reg_to_var_int(iptr->dst, d);
1005 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1007 var_to_reg_int(s1, src->prev, REG_ITMP1);
1008 var_to_reg_int(s2, src, REG_ITMP2);
1009 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1014 store_reg_to_var_int(iptr->dst, d);
1017 case ICMD_IREMCONST: /* ..., value ==> ..., value % constant */
1018 /* val.i = constant */
1020 var_to_reg_int(s1, src, REG_ITMP1);
1021 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1022 ICONST(REG_ITMP2, iptr->val.i);
1023 M_IDIV(s1, REG_ITMP2);
1027 store_reg_to_var_int(iptr->dst, d);
1030 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1032 var_to_reg_int(s1, src->prev, REG_ITMP1);
1033 var_to_reg_int(s2, src, REG_ITMP2);
1034 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1039 store_reg_to_var_int(iptr->dst, d);
1042 case ICMD_LREMCONST: /* ..., value ==> ..., value % constant */
1043 /* val.l = constant */
1045 var_to_reg_int(s1, src, REG_ITMP1);
1046 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1047 LCONST(REG_ITMP2, iptr->val.l);
1048 M_LDIV(s1, REG_ITMP2);
1052 store_reg_to_var_int(iptr->dst, d);
1055 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
1056 case ICMD_LDIVPOW2: /* val.i = constant */
1058 var_to_reg_int(s1, src, REG_ITMP1);
1059 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1060 M_LSRA_IMM(s1, 63, REG_ITMP2);
1061 M_LSRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
1062 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1063 M_LSRA_IMM(REG_ITMP2, iptr->val.i, d);
1064 store_reg_to_var_int(iptr->dst, d);
1067 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1069 var_to_reg_int(s1, src->prev, REG_ITMP1);
1070 var_to_reg_int(s2, src, REG_ITMP2);
1071 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1073 store_reg_to_var_int(iptr->dst, d);
1076 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1077 /* val.i = constant */
1079 var_to_reg_int(s1, src, REG_ITMP1);
1080 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1081 M_ISLL_IMM(s1, iptr->val.i, d);
1082 store_reg_to_var_int(iptr->dst, d);
1085 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1087 var_to_reg_int(s1, src->prev, REG_ITMP1);
1088 var_to_reg_int(s2, src, REG_ITMP2);
1089 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1091 store_reg_to_var_int(iptr->dst, d);
1094 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1095 /* val.i = constant */
1097 var_to_reg_int(s1, src, REG_ITMP1);
1098 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1099 M_ISRA_IMM(s1, iptr->val.i, d);
1100 store_reg_to_var_int(iptr->dst, d);
1103 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1105 var_to_reg_int(s1, src->prev, REG_ITMP1);
1106 var_to_reg_int(s2, src, REG_ITMP2);
1107 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1109 store_reg_to_var_int(iptr->dst, d);
1112 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1113 /* val.i = constant */
1115 var_to_reg_int(s1, src, REG_ITMP1);
1116 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1117 M_ISRL_IMM(s1, iptr->val.i, d);
1118 store_reg_to_var_int(iptr->dst, d);
1121 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1123 var_to_reg_int(s1, src->prev, REG_ITMP1);
1124 var_to_reg_int(s2, src, REG_ITMP2);
1125 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1127 store_reg_to_var_int(iptr->dst, d);
1130 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1131 /* val.i = constant */
1133 var_to_reg_int(s1, src, REG_ITMP1);
1134 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1135 M_LSLL_IMM(s1, iptr->val.i, d);
1136 store_reg_to_var_int(iptr->dst, d);
1139 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1141 var_to_reg_int(s1, src->prev, REG_ITMP1);
1142 var_to_reg_int(s2, src, REG_ITMP2);
1143 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1145 store_reg_to_var_int(iptr->dst, d);
1148 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1149 /* val.i = constant */
1151 var_to_reg_int(s1, src, REG_ITMP1);
1152 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1153 M_LSRA_IMM(s1, iptr->val.i, d);
1154 store_reg_to_var_int(iptr->dst, d);
1157 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1159 var_to_reg_int(s1, src->prev, REG_ITMP1);
1160 var_to_reg_int(s2, src, REG_ITMP2);
1161 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1163 store_reg_to_var_int(iptr->dst, d);
1166 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1167 /* val.i = constant */
1169 var_to_reg_int(s1, src, REG_ITMP1);
1170 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1171 M_LSRL_IMM(s1, iptr->val.i, d);
1172 store_reg_to_var_int(iptr->dst, d);
1175 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1178 var_to_reg_int(s1, src->prev, REG_ITMP1);
1179 var_to_reg_int(s2, src, REG_ITMP2);
1180 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1182 store_reg_to_var_int(iptr->dst, d);
1185 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1186 /* val.i = constant */
1188 var_to_reg_int(s1, src, REG_ITMP1);
1189 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1190 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1191 M_AND_IMM(s1, iptr->val.i, d);
1194 ICONST(REG_ITMP2, iptr->val.i);
1195 M_AND(s1, REG_ITMP2, d);
1197 store_reg_to_var_int(iptr->dst, d);
1200 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1201 /* val.i = constant */
1203 var_to_reg_int(s1, src, REG_ITMP1);
1204 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1206 M_MOV(s1, REG_ITMP1);
1209 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1210 M_AND_IMM(s1, iptr->val.i, d);
1213 M_ISUB(REG_ZERO, s1, d);
1214 M_AND_IMM(d, iptr->val.i, d);
1217 ICONST(REG_ITMP2, iptr->val.i);
1218 M_AND(s1, REG_ITMP2, d);
1221 M_ISUB(REG_ZERO, s1, d);
1222 M_AND(d, REG_ITMP2, d);
1224 M_ISUB(REG_ZERO, d, d);
1225 store_reg_to_var_int(iptr->dst, d);
1228 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1229 /* val.l = constant */
1231 var_to_reg_int(s1, src, REG_ITMP1);
1232 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1233 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1234 M_AND_IMM(s1, iptr->val.l, d);
1237 LCONST(REG_ITMP2, iptr->val.l);
1238 M_AND(s1, REG_ITMP2, d);
1240 store_reg_to_var_int(iptr->dst, d);
1243 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1244 /* val.l = constant */
1246 var_to_reg_int(s1, src, REG_ITMP1);
1247 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1249 M_MOV(s1, REG_ITMP1);
1252 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1253 M_AND_IMM(s1, iptr->val.l, d);
1256 M_LSUB(REG_ZERO, s1, d);
1257 M_AND_IMM(d, iptr->val.l, d);
1260 LCONST(REG_ITMP2, iptr->val.l);
1261 M_AND(s1, REG_ITMP2, d);
1264 M_LSUB(REG_ZERO, s1, d);
1265 M_AND(d, REG_ITMP2, d);
1267 M_LSUB(REG_ZERO, d, d);
1268 store_reg_to_var_int(iptr->dst, d);
1271 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1274 var_to_reg_int(s1, src->prev, REG_ITMP1);
1275 var_to_reg_int(s2, src, REG_ITMP2);
1276 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1278 store_reg_to_var_int(iptr->dst, d);
1281 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1282 /* val.i = constant */
1284 var_to_reg_int(s1, src, REG_ITMP1);
1285 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1286 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1287 M_OR_IMM(s1, iptr->val.i, d);
1290 ICONST(REG_ITMP2, iptr->val.i);
1291 M_OR(s1, REG_ITMP2, d);
1293 store_reg_to_var_int(iptr->dst, d);
1296 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1297 /* val.l = constant */
1299 var_to_reg_int(s1, src, REG_ITMP1);
1300 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1301 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1302 M_OR_IMM(s1, iptr->val.l, d);
1305 LCONST(REG_ITMP2, iptr->val.l);
1306 M_OR(s1, REG_ITMP2, d);
1308 store_reg_to_var_int(iptr->dst, d);
1311 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1314 var_to_reg_int(s1, src->prev, REG_ITMP1);
1315 var_to_reg_int(s2, src, REG_ITMP2);
1316 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1318 store_reg_to_var_int(iptr->dst, d);
1321 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1322 /* val.i = constant */
1324 var_to_reg_int(s1, src, REG_ITMP1);
1325 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1326 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1327 M_XOR_IMM(s1, iptr->val.i, d);
1330 ICONST(REG_ITMP2, iptr->val.i);
1331 M_XOR(s1, REG_ITMP2, d);
1333 store_reg_to_var_int(iptr->dst, d);
1336 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1337 /* val.l = constant */
1339 var_to_reg_int(s1, src, REG_ITMP1);
1340 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1341 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1342 M_XOR_IMM(s1, iptr->val.l, d);
1345 LCONST(REG_ITMP2, iptr->val.l);
1346 M_XOR(s1, REG_ITMP2, d);
1348 store_reg_to_var_int(iptr->dst, d);
1352 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1354 var_to_reg_int(s1, src->prev, REG_ITMP1);
1355 var_to_reg_int(s2, src, REG_ITMP2);
1356 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1357 M_CMPLT(s1, s2, REG_ITMP3);
1358 M_CMPLT(s2, s1, REG_ITMP1);
1359 M_LSUB (REG_ITMP1, REG_ITMP3, d);
1360 store_reg_to_var_int(iptr->dst, d);
1364 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1365 /* op1 = variable, val.i = constant */
1367 var = &(r->locals[iptr->op1][TYPE_INT]);
1368 if (var->flags & INMEMORY) {
1370 M_LLD(s1, REG_SP, 8 * var->regoff);
1374 M_IADD_IMM(s1, iptr->val.i, s1);
1375 if (var->flags & INMEMORY)
1376 M_LST(s1, REG_SP, 8 * var->regoff);
1380 /* floating operations ************************************************/
1382 case ICMD_FNEG: /* ..., value ==> ..., - value */
1384 var_to_reg_flt(s1, src, REG_FTMP1);
1385 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1387 store_reg_to_var_flt(iptr->dst, d);
1390 case ICMD_DNEG: /* ..., value ==> ..., - value */
1392 var_to_reg_flt(s1, src, REG_FTMP1);
1393 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1395 store_reg_to_var_flt(iptr->dst, d);
1398 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1400 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1401 var_to_reg_flt(s2, src, REG_FTMP2);
1402 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1404 store_reg_to_var_flt(iptr->dst, d);
1407 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1409 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1410 var_to_reg_flt(s2, src, REG_FTMP2);
1411 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1413 store_reg_to_var_flt(iptr->dst, d);
1416 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1418 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1419 var_to_reg_flt(s2, src, REG_FTMP2);
1420 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1422 store_reg_to_var_flt(iptr->dst, d);
1425 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1427 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1428 var_to_reg_flt(s2, src, REG_FTMP2);
1429 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1431 store_reg_to_var_flt(iptr->dst, d);
1434 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1436 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1437 var_to_reg_flt(s2, src, REG_FTMP2);
1438 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1440 store_reg_to_var_flt(iptr->dst, d);
1443 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1445 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1446 var_to_reg_flt(s2, src, REG_FTMP2);
1447 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1449 store_reg_to_var_flt(iptr->dst, d);
1452 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1454 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1455 var_to_reg_flt(s2, src, REG_FTMP2);
1456 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1458 store_reg_to_var_flt(iptr->dst, d);
1461 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1463 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1464 var_to_reg_flt(s2, src, REG_FTMP2);
1465 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1467 store_reg_to_var_flt(iptr->dst, d);
1470 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1473 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1474 var_to_reg_flt(s2, src, REG_FTMP2);
1475 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1476 M_FDIV(s1,s2, REG_FTMP3);
1477 M_FLOORFL(REG_FTMP3, REG_FTMP3);
1478 M_CVTLF(REG_FTMP3, REG_FTMP3);
1479 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1480 M_FSUB(s1, REG_FTMP3, d);
1481 store_reg_to_var_flt(iptr->dst, d);
1484 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1486 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1487 var_to_reg_flt(s2, src, REG_FTMP2);
1488 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1489 M_DDIV(s1,s2, REG_FTMP3);
1490 M_FLOORDL(REG_FTMP3, REG_FTMP3);
1491 M_CVTLD(REG_FTMP3, REG_FTMP3);
1492 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1493 M_DSUB(s1, REG_FTMP3, d);
1494 store_reg_to_var_flt(iptr->dst, d);
1497 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1499 var_to_reg_int(s1, src, REG_ITMP1);
1500 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1503 store_reg_to_var_flt(iptr->dst, d);
1506 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1508 var_to_reg_int(s1, src, REG_ITMP1);
1509 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1512 store_reg_to_var_flt(iptr->dst, d);
1515 case ICMD_F2I: /* ..., (float) value ==> ..., (int) value */
1517 var_to_reg_flt(s1, src, REG_FTMP1);
1518 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1519 M_TRUNCFI(s1, REG_FTMP1);
1520 M_MOVDI(REG_FTMP1, d);
1522 store_reg_to_var_int(iptr->dst, d);
1525 case ICMD_D2I: /* ..., (double) value ==> ..., (int) value */
1527 var_to_reg_flt(s1, src, REG_FTMP1);
1528 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1529 M_TRUNCDI(s1, REG_FTMP1);
1530 M_MOVDI(REG_FTMP1, d);
1532 store_reg_to_var_int(iptr->dst, d);
1535 case ICMD_F2L: /* ..., (float) value ==> ..., (long) value */
1537 var_to_reg_flt(s1, src, REG_FTMP1);
1538 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1539 M_TRUNCFL(s1, REG_FTMP1);
1540 M_MOVDL(REG_FTMP1, d);
1542 store_reg_to_var_int(iptr->dst, d);
1545 case ICMD_D2L: /* ..., (double) value ==> ..., (long) value */
1547 var_to_reg_flt(s1, src, REG_FTMP1);
1548 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1549 M_TRUNCDL(s1, REG_FTMP1);
1550 M_MOVDL(REG_FTMP1, d);
1552 store_reg_to_var_int(iptr->dst, d);
1555 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1557 var_to_reg_flt(s1, src, REG_FTMP1);
1558 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1560 store_reg_to_var_flt(iptr->dst, d);
1563 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1565 var_to_reg_flt(s1, src, REG_FTMP1);
1566 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1568 store_reg_to_var_flt(iptr->dst, d);
1571 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1573 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1574 var_to_reg_flt(s2, src, REG_FTMP2);
1575 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1578 M_LADD_IMM(REG_ZERO, 1, d);
1582 M_LSUB_IMM(REG_ZERO, 1, d);
1583 M_CMOVT(REG_ZERO, d);
1584 store_reg_to_var_int(iptr->dst, d);
1587 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1589 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1590 var_to_reg_flt(s2, src, REG_FTMP2);
1591 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1594 M_LADD_IMM(REG_ZERO, 1, d);
1598 M_LSUB_IMM(REG_ZERO, 1, d);
1599 M_CMOVT(REG_ZERO, d);
1600 store_reg_to_var_int(iptr->dst, d);
1603 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1605 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1606 var_to_reg_flt(s2, src, REG_FTMP2);
1607 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1610 M_LSUB_IMM(REG_ZERO, 1, d);
1614 M_LADD_IMM(REG_ZERO, 1, d);
1615 M_CMOVT(REG_ZERO, d);
1616 store_reg_to_var_int(iptr->dst, d);
1619 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1621 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1622 var_to_reg_flt(s2, src, REG_FTMP2);
1623 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1626 M_LSUB_IMM(REG_ZERO, 1, d);
1630 M_LADD_IMM(REG_ZERO, 1, d);
1631 M_CMOVT(REG_ZERO, d);
1632 store_reg_to_var_int(iptr->dst, d);
1636 /* memory operations **************************************************/
1638 #define gen_bound_check \
1639 if (checkbounds) { \
1640 M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size)); \
1641 M_CMPULT(s2, REG_ITMP3, REG_ITMP3); \
1642 M_BEQZ(REG_ITMP3, 0); \
1643 codegen_addxboundrefs(mcodeptr, s2); \
1647 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1649 var_to_reg_int(s1, src, REG_ITMP1);
1650 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1651 gen_nullptr_check(s1);
1652 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1653 store_reg_to_var_int(iptr->dst, d);
1656 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1658 var_to_reg_int(s1, src->prev, REG_ITMP1);
1659 var_to_reg_int(s2, src, REG_ITMP2);
1660 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1661 if (iptr->op1 == 0) {
1662 gen_nullptr_check(s1);
1665 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1666 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1667 M_ALD(d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1668 store_reg_to_var_int(iptr->dst, d);
1671 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1673 var_to_reg_int(s1, src->prev, REG_ITMP1);
1674 var_to_reg_int(s2, src, REG_ITMP2);
1675 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1676 if (iptr->op1 == 0) {
1677 gen_nullptr_check(s1);
1680 M_ASLL_IMM(s2, 2, REG_ITMP2);
1681 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1682 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1683 store_reg_to_var_int(iptr->dst, d);
1686 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1688 var_to_reg_int(s1, src->prev, REG_ITMP1);
1689 var_to_reg_int(s2, src, REG_ITMP2);
1690 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1691 if (iptr->op1 == 0) {
1692 gen_nullptr_check(s1);
1695 M_ASLL_IMM(s2, 3, REG_ITMP2);
1696 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1697 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1698 store_reg_to_var_int(iptr->dst, d);
1701 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1703 var_to_reg_int(s1, src->prev, REG_ITMP1);
1704 var_to_reg_int(s2, src, REG_ITMP2);
1705 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1706 if (iptr->op1 == 0) {
1707 gen_nullptr_check(s1);
1710 M_ASLL_IMM(s2, 2, REG_ITMP2);
1711 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1712 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1713 store_reg_to_var_flt(iptr->dst, d);
1716 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1718 var_to_reg_int(s1, src->prev, REG_ITMP1);
1719 var_to_reg_int(s2, src, REG_ITMP2);
1720 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1721 if (iptr->op1 == 0) {
1722 gen_nullptr_check(s1);
1725 M_ASLL_IMM(s2, 3, REG_ITMP2);
1726 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1727 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1728 store_reg_to_var_flt(iptr->dst, d);
1731 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1733 var_to_reg_int(s1, src->prev, REG_ITMP1);
1734 var_to_reg_int(s2, src, REG_ITMP2);
1735 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1736 if (iptr->op1 == 0) {
1737 gen_nullptr_check(s1);
1740 M_AADD(s2, s1, REG_ITMP1);
1741 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1742 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1743 store_reg_to_var_int(iptr->dst, d);
1746 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1748 var_to_reg_int(s1, src->prev, REG_ITMP1);
1749 var_to_reg_int(s2, src, REG_ITMP2);
1750 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1751 if (iptr->op1 == 0) {
1752 gen_nullptr_check(s1);
1755 M_AADD(s2, s1, REG_ITMP1);
1756 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1757 M_SLDS(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1758 store_reg_to_var_int(iptr->dst, d);
1761 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1763 var_to_reg_int(s1, src->prev, REG_ITMP1);
1764 var_to_reg_int(s2, src, REG_ITMP2);
1765 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1766 if (iptr->op1 == 0) {
1767 gen_nullptr_check(s1);
1770 M_AADD(s2, s1, REG_ITMP1);
1771 M_BLDS(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1772 store_reg_to_var_int(iptr->dst, d);
1776 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1778 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1779 var_to_reg_int(s2, src->prev, REG_ITMP2);
1780 if (iptr->op1 == 0) {
1781 gen_nullptr_check(s1);
1784 var_to_reg_int(s3, src, REG_ITMP3);
1785 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1786 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1787 M_AST(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1790 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1792 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1793 var_to_reg_int(s2, src->prev, REG_ITMP2);
1794 if (iptr->op1 == 0) {
1795 gen_nullptr_check(s1);
1798 var_to_reg_int(s3, src, REG_ITMP3);
1799 M_ASLL_IMM(s2, 2, REG_ITMP2);
1800 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1801 M_IST(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1804 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1806 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1807 var_to_reg_int(s2, src->prev, REG_ITMP2);
1808 if (iptr->op1 == 0) {
1809 gen_nullptr_check(s1);
1812 var_to_reg_int(s3, src, REG_ITMP3);
1813 M_ASLL_IMM(s2, 3, REG_ITMP2);
1814 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1815 M_LST(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1818 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1820 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1821 var_to_reg_int(s2, src->prev, REG_ITMP2);
1822 if (iptr->op1 == 0) {
1823 gen_nullptr_check(s1);
1826 var_to_reg_flt(s3, src, REG_FTMP3);
1827 M_ASLL_IMM(s2, 2, REG_ITMP2);
1828 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1829 M_FST(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1832 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1834 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1835 var_to_reg_int(s2, src->prev, REG_ITMP2);
1836 if (iptr->op1 == 0) {
1837 gen_nullptr_check(s1);
1840 var_to_reg_flt(s3, src, REG_FTMP3);
1841 M_ASLL_IMM(s2, 3, REG_ITMP2);
1842 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1843 M_DST(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1846 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1847 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1849 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1850 var_to_reg_int(s2, src->prev, REG_ITMP2);
1851 if (iptr->op1 == 0) {
1852 gen_nullptr_check(s1);
1855 var_to_reg_int(s3, src, REG_ITMP3);
1856 M_AADD(s2, s1, REG_ITMP1);
1857 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1858 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1861 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1863 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1864 var_to_reg_int(s2, src->prev, REG_ITMP2);
1865 if (iptr->op1 == 0) {
1866 gen_nullptr_check(s1);
1869 var_to_reg_int(s3, src, REG_ITMP3);
1870 M_AADD(s2, s1, REG_ITMP1);
1871 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1875 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1876 /* op1 = type, val.a = field address */
1878 /* if class isn't yet initialized, do it */
1879 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
1880 /* call helper function which patches this code */
1881 a = dseg_addaddress(((fieldinfo *) iptr->val.a)->class);
1882 M_ALD(REG_ITMP1, REG_PV, a);
1883 a = dseg_addaddress(asm_check_clinit);
1884 M_ALD(REG_ITMP3, REG_PV, a);
1885 M_JSR(REG_RA, REG_ITMP3);
1889 a = dseg_addaddress(&(((fieldinfo *) iptr->val.a)->value));
1890 M_ALD(REG_ITMP1, REG_PV, a);
1891 switch (iptr->op1) {
1893 var_to_reg_int(s2, src, REG_ITMP2);
1894 M_IST(s2, REG_ITMP1, 0);
1897 var_to_reg_int(s2, src, REG_ITMP2);
1898 M_LST(s2, REG_ITMP1, 0);
1901 var_to_reg_int(s2, src, REG_ITMP2);
1902 M_AST(s2, REG_ITMP1, 0);
1905 var_to_reg_flt(s2, src, REG_FTMP2);
1906 M_FST(s2, REG_ITMP1, 0);
1909 var_to_reg_flt(s2, src, REG_FTMP2);
1910 M_DST(s2, REG_ITMP1, 0);
1912 default: panic ("internal error");
1916 case ICMD_GETSTATIC: /* ... ==> ..., value */
1917 /* op1 = type, val.a = field address */
1919 /* if class isn't yet initialized, do it */
1920 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
1921 /* call helper function which patches this code */
1922 a = dseg_addaddress(((fieldinfo *) iptr->val.a)->class);
1923 M_ALD(REG_ITMP1, REG_PV, a);
1924 a = dseg_addaddress(asm_check_clinit);
1925 M_ALD(REG_ITMP3, REG_PV, a);
1926 M_JSR(REG_RA, REG_ITMP3);
1930 a = dseg_addaddress(&(((fieldinfo *) iptr->val.a)->value));
1931 M_ALD(REG_ITMP1, REG_PV, a);
1932 switch (iptr->op1) {
1934 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1935 M_ILD(d, REG_ITMP1, 0);
1936 store_reg_to_var_int(iptr->dst, d);
1939 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1940 M_LLD(d, REG_ITMP1, 0);
1941 store_reg_to_var_int(iptr->dst, d);
1944 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1945 M_ALD(d, REG_ITMP1, 0);
1946 store_reg_to_var_int(iptr->dst, d);
1949 d = reg_of_var(m, iptr->dst, REG_FTMP1);
1950 M_FLD(d, REG_ITMP1, 0);
1951 store_reg_to_var_flt(iptr->dst, d);
1954 d = reg_of_var(m, iptr->dst, REG_FTMP1);
1955 M_DLD(d, REG_ITMP1, 0);
1956 store_reg_to_var_flt(iptr->dst, d);
1958 default: panic ("internal error");
1963 case ICMD_PUTFIELD: /* ..., value ==> ... */
1964 /* op1 = type, val.i = field offset */
1966 a = ((fieldinfo *)(iptr->val.a))->offset;
1967 switch (iptr->op1) {
1969 var_to_reg_int(s1, src->prev, REG_ITMP1);
1970 var_to_reg_int(s2, src, REG_ITMP2);
1971 gen_nullptr_check(s1);
1975 var_to_reg_int(s1, src->prev, REG_ITMP1);
1976 var_to_reg_int(s2, src, REG_ITMP2);
1977 gen_nullptr_check(s1);
1981 var_to_reg_int(s1, src->prev, REG_ITMP1);
1982 var_to_reg_int(s2, src, REG_ITMP2);
1983 gen_nullptr_check(s1);
1987 var_to_reg_int(s1, src->prev, REG_ITMP1);
1988 var_to_reg_flt(s2, src, REG_FTMP2);
1989 gen_nullptr_check(s1);
1993 var_to_reg_int(s1, src->prev, REG_ITMP1);
1994 var_to_reg_flt(s2, src, REG_FTMP2);
1995 gen_nullptr_check(s1);
1998 default: panic ("internal error");
2002 case ICMD_GETFIELD: /* ... ==> ..., value */
2003 /* op1 = type, val.i = field offset */
2005 a = ((fieldinfo *)(iptr->val.a))->offset;
2006 switch (iptr->op1) {
2008 var_to_reg_int(s1, src, REG_ITMP1);
2009 d = reg_of_var(m, iptr->dst, REG_ITMP3);
2010 gen_nullptr_check(s1);
2012 store_reg_to_var_int(iptr->dst, d);
2015 var_to_reg_int(s1, src, REG_ITMP1);
2016 d = reg_of_var(m, iptr->dst, REG_ITMP3);
2017 gen_nullptr_check(s1);
2019 store_reg_to_var_int(iptr->dst, d);
2022 var_to_reg_int(s1, src, REG_ITMP1);
2023 d = reg_of_var(m, iptr->dst, REG_ITMP3);
2024 gen_nullptr_check(s1);
2026 store_reg_to_var_int(iptr->dst, d);
2029 var_to_reg_int(s1, src, REG_ITMP1);
2030 d = reg_of_var(m, iptr->dst, REG_FTMP1);
2031 gen_nullptr_check(s1);
2033 store_reg_to_var_flt(iptr->dst, d);
2036 var_to_reg_int(s1, src, REG_ITMP1);
2037 d = reg_of_var(m, iptr->dst, REG_FTMP1);
2038 gen_nullptr_check(s1);
2040 store_reg_to_var_flt(iptr->dst, d);
2042 default: panic ("internal error");
2047 /* branch operations **************************************************/
2049 #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}}
2051 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2053 var_to_reg_int(s1, src, REG_ITMP1);
2054 M_INTMOVE(s1, REG_ITMP1_XPTR);
2055 a = dseg_addaddress(asm_handle_exception);
2056 M_ALD(REG_ITMP2, REG_PV, a);
2057 M_JSR(REG_ITMP2_XPC, REG_ITMP2);
2059 M_NOP; /* nop ensures that XPC is less than the end */
2060 /* of basic block */
2064 case ICMD_GOTO: /* ... ==> ... */
2065 /* op1 = target JavaVM pc */
2067 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2072 case ICMD_JSR: /* ... ==> ... */
2073 /* op1 = target JavaVM pc */
2075 dseg_addtarget(BlockPtrOfPC(iptr->op1));
2076 M_ALD(REG_ITMP1, REG_PV, -dseglen);
2077 M_JSR(REG_ITMP1, REG_ITMP1); /* REG_ITMP1 = return address */
2081 case ICMD_RET: /* ... ==> ... */
2082 /* op1 = local variable */
2083 var = &(r->locals[iptr->op1][TYPE_ADR]);
2084 if (var->flags & INMEMORY) {
2085 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2094 case ICMD_IFNULL: /* ..., value ==> ... */
2095 /* op1 = target JavaVM pc */
2097 var_to_reg_int(s1, src, REG_ITMP1);
2099 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2103 case ICMD_IFNONNULL: /* ..., value ==> ... */
2104 /* op1 = target JavaVM pc */
2106 var_to_reg_int(s1, src, REG_ITMP1);
2108 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2112 case ICMD_IFEQ: /* ..., value ==> ... */
2113 /* op1 = target JavaVM pc, val.i = constant */
2115 var_to_reg_int(s1, src, REG_ITMP1);
2116 if (iptr->val.i == 0) {
2120 ICONST(REG_ITMP2, iptr->val.i);
2121 M_BEQ(s1, REG_ITMP2, 0);
2123 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2127 case ICMD_IFLT: /* ..., value ==> ... */
2128 /* op1 = target JavaVM pc, val.i = constant */
2130 var_to_reg_int(s1, src, REG_ITMP1);
2131 if (iptr->val.i == 0) {
2135 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
2136 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2139 ICONST(REG_ITMP2, iptr->val.i);
2140 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2142 M_BNEZ(REG_ITMP1, 0);
2144 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2148 case ICMD_IFLE: /* ..., value ==> ... */
2149 /* op1 = target JavaVM pc, val.i = constant */
2151 var_to_reg_int(s1, src, REG_ITMP1);
2152 if (iptr->val.i == 0) {
2156 if ((iptr->val.i >= -32769) && (iptr->val.i <= 32766)) {
2157 M_CMPLT_IMM(s1, iptr->val.i + 1, REG_ITMP1);
2158 M_BNEZ(REG_ITMP1, 0);
2161 ICONST(REG_ITMP2, iptr->val.i);
2162 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2163 M_BEQZ(REG_ITMP1, 0);
2166 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2170 case ICMD_IFNE: /* ..., value ==> ... */
2171 /* op1 = target JavaVM pc, val.i = constant */
2173 var_to_reg_int(s1, src, REG_ITMP1);
2174 if (iptr->val.i == 0) {
2178 ICONST(REG_ITMP2, iptr->val.i);
2179 M_BNE(s1, REG_ITMP2, 0);
2181 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2185 case ICMD_IFGT: /* ..., value ==> ... */
2186 /* op1 = target JavaVM pc, val.i = constant */
2188 var_to_reg_int(s1, src, REG_ITMP1);
2189 if (iptr->val.i == 0) {
2193 if ((iptr->val.i >= -32769) && (iptr->val.i <= 32766)) {
2194 M_CMPLT_IMM(s1, iptr->val.i + 1, REG_ITMP1);
2195 M_BEQZ(REG_ITMP1, 0);
2198 ICONST(REG_ITMP2, iptr->val.i);
2199 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2200 M_BNEZ(REG_ITMP1, 0);
2203 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2207 case ICMD_IFGE: /* ..., value ==> ... */
2208 /* op1 = target JavaVM pc, val.i = constant */
2210 var_to_reg_int(s1, src, REG_ITMP1);
2211 if (iptr->val.i == 0) {
2215 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
2216 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2219 ICONST(REG_ITMP2, iptr->val.i);
2220 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2222 M_BEQZ(REG_ITMP1, 0);
2224 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2228 case ICMD_IF_LEQ: /* ..., value ==> ... */
2229 /* op1 = target JavaVM pc, val.l = constant */
2231 var_to_reg_int(s1, src, REG_ITMP1);
2232 if (iptr->val.l == 0) {
2236 LCONST(REG_ITMP2, iptr->val.l);
2237 M_BEQ(s1, REG_ITMP2, 0);
2239 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2243 case ICMD_IF_LLT: /* ..., value ==> ... */
2244 /* op1 = target JavaVM pc, val.l = constant */
2246 var_to_reg_int(s1, src, REG_ITMP1);
2247 if (iptr->val.l == 0) {
2251 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2252 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2255 LCONST(REG_ITMP2, iptr->val.l);
2256 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2258 M_BNEZ(REG_ITMP1, 0);
2260 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2264 case ICMD_IF_LLE: /* ..., value ==> ... */
2265 /* op1 = target JavaVM pc, val.l = constant */
2267 var_to_reg_int(s1, src, REG_ITMP1);
2268 if (iptr->val.l == 0) {
2272 if ((iptr->val.l >= -32769) && (iptr->val.l <= 32766)) {
2273 M_CMPLT_IMM(s1, iptr->val.l + 1, REG_ITMP1);
2274 M_BNEZ(REG_ITMP1, 0);
2277 LCONST(REG_ITMP2, iptr->val.l);
2278 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2279 M_BEQZ(REG_ITMP1, 0);
2282 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2286 case ICMD_IF_LNE: /* ..., value ==> ... */
2287 /* op1 = target JavaVM pc, val.l = constant */
2289 var_to_reg_int(s1, src, REG_ITMP1);
2290 if (iptr->val.l == 0) {
2294 LCONST(REG_ITMP2, iptr->val.l);
2295 M_BNE(s1, REG_ITMP2, 0);
2297 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2301 case ICMD_IF_LGT: /* ..., value ==> ... */
2302 /* op1 = target JavaVM pc, val.l = constant */
2304 var_to_reg_int(s1, src, REG_ITMP1);
2305 if (iptr->val.l == 0) {
2309 if ((iptr->val.l >= -32769) && (iptr->val.l <= 32766)) {
2310 M_CMPLT_IMM(s1, iptr->val.l + 1, REG_ITMP1);
2311 M_BEQZ(REG_ITMP1, 0);
2314 LCONST(REG_ITMP2, iptr->val.l);
2315 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2316 M_BNEZ(REG_ITMP1, 0);
2319 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2323 case ICMD_IF_LGE: /* ..., value ==> ... */
2324 /* op1 = target JavaVM pc, val.l = constant */
2326 var_to_reg_int(s1, src, REG_ITMP1);
2327 if (iptr->val.l == 0) {
2331 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2332 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2335 LCONST(REG_ITMP2, iptr->val.l);
2336 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2338 M_BEQZ(REG_ITMP1, 0);
2340 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2344 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2345 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2346 case ICMD_IF_ACMPEQ:
2348 var_to_reg_int(s1, src->prev, REG_ITMP1);
2349 var_to_reg_int(s2, src, REG_ITMP2);
2351 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2355 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2356 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2357 case ICMD_IF_ACMPNE:
2359 var_to_reg_int(s1, src->prev, REG_ITMP1);
2360 var_to_reg_int(s2, src, REG_ITMP2);
2362 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2366 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2367 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2369 var_to_reg_int(s1, src->prev, REG_ITMP1);
2370 var_to_reg_int(s2, src, REG_ITMP2);
2371 M_CMPLT(s1, s2, REG_ITMP1);
2372 M_BNEZ(REG_ITMP1, 0);
2373 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2377 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2378 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2380 var_to_reg_int(s1, src->prev, REG_ITMP1);
2381 var_to_reg_int(s2, src, REG_ITMP2);
2382 M_CMPGT(s1, s2, REG_ITMP1);
2383 M_BNEZ(REG_ITMP1, 0);
2384 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2388 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2389 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2391 var_to_reg_int(s1, src->prev, REG_ITMP1);
2392 var_to_reg_int(s2, src, REG_ITMP2);
2393 M_CMPGT(s1, s2, REG_ITMP1);
2394 M_BEQZ(REG_ITMP1, 0);
2395 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2399 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2400 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2402 var_to_reg_int(s1, src->prev, REG_ITMP1);
2403 var_to_reg_int(s2, src, REG_ITMP2);
2404 M_CMPLT(s1, s2, REG_ITMP1);
2405 M_BEQZ(REG_ITMP1, 0);
2406 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2410 #ifdef CONDITIONAL_LOADCONST
2411 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2413 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2416 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2417 /* val.i = constant */
2419 var_to_reg_int(s1, src, REG_ITMP1);
2420 d = reg_of_var(m, iptr->dst, REG_ITMP3);
2422 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2423 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2424 M_CMPEQ(s1, REG_ZERO, d);
2425 store_reg_to_var_int(iptr->dst, d);
2428 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2429 M_CMPEQ(s1, REG_ZERO, d);
2431 store_reg_to_var_int(iptr->dst, d);
2435 M_MOV(s1, REG_ITMP1);
2438 ICONST(d, iptr[1].val.i);
2440 if ((s3 >= 0) && (s3 <= 255)) {
2441 M_CMOVEQ_IMM(s1, s3, d);
2444 ICONST(REG_ITMP2, s3);
2445 M_CMOVEQ(s1, REG_ITMP2, d);
2447 store_reg_to_var_int(iptr->dst, d);
2450 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2451 /* val.i = constant */
2453 var_to_reg_int(s1, src, REG_ITMP1);
2454 d = reg_of_var(m, iptr->dst, REG_ITMP3);
2456 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2457 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2458 M_CMPEQ(s1, REG_ZERO, d);
2459 store_reg_to_var_int(iptr->dst, d);
2462 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2463 M_CMPEQ(s1, REG_ZERO, d);
2465 store_reg_to_var_int(iptr->dst, d);
2469 M_MOV(s1, REG_ITMP1);
2472 ICONST(d, iptr[1].val.i);
2474 if ((s3 >= 0) && (s3 <= 255)) {
2475 M_CMOVNE_IMM(s1, s3, d);
2478 ICONST(REG_ITMP2, s3);
2479 M_CMOVNE(s1, REG_ITMP2, d);
2481 store_reg_to_var_int(iptr->dst, d);
2484 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2485 /* val.i = constant */
2487 var_to_reg_int(s1, src, REG_ITMP1);
2488 d = reg_of_var(m, iptr->dst, REG_ITMP3);
2490 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2491 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2492 M_CMPLT(s1, REG_ZERO, d);
2493 store_reg_to_var_int(iptr->dst, d);
2496 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2497 M_CMPLE(REG_ZERO, s1, d);
2498 store_reg_to_var_int(iptr->dst, d);
2502 M_MOV(s1, REG_ITMP1);
2505 ICONST(d, iptr[1].val.i);
2507 if ((s3 >= 0) && (s3 <= 255)) {
2508 M_CMOVLT_IMM(s1, s3, d);
2511 ICONST(REG_ITMP2, s3);
2512 M_CMOVLT(s1, REG_ITMP2, d);
2514 store_reg_to_var_int(iptr->dst, d);
2517 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2518 /* val.i = constant */
2520 var_to_reg_int(s1, src, REG_ITMP1);
2521 d = reg_of_var(m, iptr->dst, REG_ITMP3);
2523 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2524 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2525 M_CMPLE(REG_ZERO, s1, d);
2526 store_reg_to_var_int(iptr->dst, d);
2529 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2530 M_CMPLT(s1, REG_ZERO, d);
2531 store_reg_to_var_int(iptr->dst, d);
2535 M_MOV(s1, REG_ITMP1);
2538 ICONST(d, iptr[1].val.i);
2540 if ((s3 >= 0) && (s3 <= 255)) {
2541 M_CMOVGE_IMM(s1, s3, d);
2544 ICONST(REG_ITMP2, s3);
2545 M_CMOVGE(s1, REG_ITMP2, d);
2547 store_reg_to_var_int(iptr->dst, d);
2550 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2551 /* val.i = constant */
2553 var_to_reg_int(s1, src, REG_ITMP1);
2554 d = reg_of_var(m, iptr->dst, REG_ITMP3);
2556 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2557 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2558 M_CMPLT(REG_ZERO, s1, d);
2559 store_reg_to_var_int(iptr->dst, d);
2562 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2563 M_CMPLE(s1, REG_ZERO, d);
2564 store_reg_to_var_int(iptr->dst, d);
2568 M_MOV(s1, REG_ITMP1);
2571 ICONST(d, iptr[1].val.i);
2573 if ((s3 >= 0) && (s3 <= 255)) {
2574 M_CMOVGT_IMM(s1, s3, d);
2577 ICONST(REG_ITMP2, s3);
2578 M_CMOVGT(s1, REG_ITMP2, d);
2580 store_reg_to_var_int(iptr->dst, d);
2583 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2584 /* val.i = constant */
2586 var_to_reg_int(s1, src, REG_ITMP1);
2587 d = reg_of_var(m, iptr->dst, REG_ITMP3);
2589 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2590 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2591 M_CMPLE(s1, REG_ZERO, d);
2592 store_reg_to_var_int(iptr->dst, d);
2595 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2596 M_CMPLT(REG_ZERO, s1, d);
2597 store_reg_to_var_int(iptr->dst, d);
2601 M_MOV(s1, REG_ITMP1);
2604 ICONST(d, iptr[1].val.i);
2606 if ((s3 >= 0) && (s3 <= 255)) {
2607 M_CMOVLE_IMM(s1, s3, d);
2610 ICONST(REG_ITMP2, s3);
2611 M_CMOVLE(s1, REG_ITMP2, d);
2613 store_reg_to_var_int(iptr->dst, d);
2618 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2622 #if defined(USE_THREADS)
2623 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2625 a = dseg_addaddress((void *) builtin_monitorexit);
2626 M_ALD(REG_ITMP3, REG_PV, a);
2627 M_JSR(REG_RA, REG_ITMP3);
2628 M_ALD(r->argintregs[0], REG_SP, r->maxmemuse * 8); /* delay slot */
2629 disp = -(s4) ((u1 *) mcodeptr - mcodebase);
2630 M_LDA(REG_PV, REG_RA, disp);
2633 var_to_reg_int(s1, src, REG_RESULT);
2634 M_INTMOVE(s1, REG_RESULT);
2635 goto nowperformreturn;
2637 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2640 #if defined(USE_THREADS)
2641 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2643 a = dseg_addaddress((void *) builtin_monitorexit);
2644 M_ALD(REG_ITMP3, REG_PV, a);
2645 M_JSR(REG_RA, REG_ITMP3);
2646 M_ALD(r->argintregs[0], REG_SP, r->maxmemuse * 8); /* delay slot */
2647 disp = -(s4) ((u1 *) mcodeptr - mcodebase);
2648 M_LDA(REG_PV, REG_RA, disp);
2651 var_to_reg_flt(s1, src, REG_FRESULT);
2653 int t = ((iptr->opc == ICMD_FRETURN) ? TYPE_FLT : TYPE_DBL);
2654 M_TFLTMOVE(t, s1, REG_FRESULT);
2656 goto nowperformreturn;
2658 case ICMD_RETURN: /* ... ==> ... */
2660 #if defined(USE_THREADS)
2661 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2663 a = dseg_addaddress((void *) builtin_monitorexit);
2664 M_ALD(REG_ITMP3, REG_PV, a);
2665 M_JSR(REG_RA, REG_ITMP3);
2666 M_ALD(r->argintregs[0], REG_SP, r->maxmemuse * 8); /* delay slot */
2667 disp = -(s4) ((u1 *) mcodeptr - mcodebase);
2668 M_LDA(REG_PV, REG_RA, disp);
2676 p = parentargs_base;
2678 /* restore return address */
2680 if (!m->isleafmethod) {
2681 p--; M_LLD(REG_RA, REG_SP, 8 * p);
2684 /* restore saved registers */
2686 for (i = r->savintregcnt - 1; i >= r->maxsavintreguse; i--) {
2687 p--; M_LLD(r->savintregs[i], REG_SP, 8 * p);
2689 for (i = r->savfltregcnt - 1; i >= r->maxsavfltreguse; i--) {
2690 p--; M_DLD(r->savfltregs[i], REG_SP, 8 * p);
2693 /* call trace function */
2696 M_LDA (REG_SP, REG_SP, -24);
2697 M_LST(REG_RA, REG_SP, 0);
2698 M_LST(REG_RESULT, REG_SP, 8);
2699 M_DST(REG_FRESULT, REG_SP,16);
2700 a = dseg_addaddress(m);
2701 M_ALD(r->argintregs[0], REG_PV, a);
2702 M_MOV(REG_RESULT, r->argintregs[1]);
2703 M_FLTMOVE(REG_FRESULT, r->argfltregs[2]);
2704 M_FMOV(REG_FRESULT, r->argfltregs[3]);
2705 a = dseg_addaddress((void *) builtin_displaymethodstop);
2706 M_ALD(REG_ITMP3, REG_PV, a);
2707 M_JSR (REG_RA, REG_ITMP3);
2709 M_DLD(REG_FRESULT, REG_SP,16);
2710 M_LLD(REG_RESULT, REG_SP, 8);
2711 M_LLD(REG_RA, REG_SP, 0);
2712 M_LDA (REG_SP, REG_SP, 24);
2717 /* deallocate stack */
2719 if (parentargs_base) {
2720 M_LDA(REG_SP, REG_SP, parentargs_base * 8);
2731 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2736 tptr = (void **) iptr->target;
2738 s4ptr = iptr->val.a;
2739 l = s4ptr[1]; /* low */
2740 i = s4ptr[2]; /* high */
2742 var_to_reg_int(s1, src, REG_ITMP1);
2744 {M_INTMOVE(s1, REG_ITMP1);}
2745 else if (l <= 32768) {
2746 M_IADD_IMM(s1, -l, REG_ITMP1);
2749 ICONST(REG_ITMP2, l);
2750 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2756 M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
2757 M_BEQZ(REG_ITMP2, 0);
2758 codegen_addreference((basicblock *) tptr[0], mcodeptr);
2759 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1); /* delay slot*/
2761 /* build jump table top down and use address of lowest entry */
2763 /* s4ptr += 3 + i; */
2767 /* dseg_addtarget(BlockPtrOfPC(*--s4ptr)); */
2768 dseg_addtarget((basicblock *) tptr[0]);
2773 /* length of dataseg after last dseg_addtarget is used by load */
2775 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2776 M_ALD(REG_ITMP2, REG_ITMP2, -dseglen);
2783 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2785 s4 i, /*l, */val, *s4ptr;
2788 tptr = (void **) iptr->target;
2790 s4ptr = iptr->val.a;
2791 /*l = s4ptr[0];*/ /* default */
2792 i = s4ptr[1]; /* count */
2794 MCODECHECK((i<<2)+8);
2795 var_to_reg_int(s1, src, REG_ITMP1);
2801 ICONST(REG_ITMP2, val);
2802 M_BEQ(s1, REG_ITMP2, 0);
2803 codegen_addreference((basicblock *) tptr[0], mcodeptr);
2808 tptr = (void **) iptr->target;
2809 codegen_addreference((basicblock *) tptr[0], mcodeptr);
2816 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
2817 /* op1 = return type, val.a = function pointer*/
2821 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
2822 /* op1 = return type, val.a = function pointer*/
2826 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
2827 /* op1 = return type, val.a = function pointer*/
2831 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2832 /* op1 = arg count, val.a = method pointer */
2834 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2835 /* op1 = arg count, val.a = method pointer */
2837 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2838 /* op1 = arg count, val.a = method pointer */
2840 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
2841 /* op1 = arg count, val.a = method pointer */
2848 MCODECHECK((s3 << 1) + 64);
2850 /* copy arguments to registers or stack location */
2852 for (; --s3 >= 0; src = src->prev) {
2853 if (src->varkind == ARGVAR)
2855 if (IS_INT_LNG_TYPE(src->type)) {
2856 if (s3 < INT_ARG_CNT) {
2857 s1 = r->argintregs[s3];
2858 var_to_reg_int(d, src, s1);
2862 var_to_reg_int(d, src, REG_ITMP1);
2863 M_LST(d, REG_SP, 8 * (s3 - INT_ARG_CNT));
2867 if (s3 < FLT_ARG_CNT) {
2868 s1 = r->argfltregs[s3];
2869 var_to_reg_flt(d, src, s1);
2870 M_TFLTMOVE(src->type, d, s1);
2873 var_to_reg_flt(d, src, REG_FTMP1);
2874 M_DST(d, REG_SP, 8 * (s3 - FLT_ARG_CNT));
2880 switch (iptr->opc) {
2884 a = dseg_addaddress((void *) lm);
2885 d = iptr->op1; /* return type */
2887 M_ALD(REG_ITMP3, REG_PV, a); /* built-in-function pointer */
2888 M_JSR(REG_RA, REG_ITMP3);
2890 goto afteractualcall;
2892 case ICMD_INVOKESTATIC:
2893 case ICMD_INVOKESPECIAL:
2894 a = dseg_addaddress(lm->stubroutine);
2897 M_ALD(REG_PV, REG_PV, a); /* method pointer in pv */
2900 case ICMD_INVOKEVIRTUAL:
2903 gen_nullptr_check(r->argintregs[0]);
2904 M_ALD(REG_METHODPTR, r->argintregs[0], OFFSET(java_objectheader, vftbl));
2905 M_ALD(REG_PV, REG_METHODPTR, OFFSET(vftbl, table[0]) + sizeof(methodptr) * lm->vftblindex);
2908 case ICMD_INVOKEINTERFACE:
2911 gen_nullptr_check(r->argintregs[0]);
2912 M_ALD(REG_METHODPTR, r->argintregs[0], OFFSET(java_objectheader, vftbl));
2913 M_ALD(REG_METHODPTR, REG_METHODPTR, OFFSET(vftbl, interfacetable[0]) - sizeof(methodptr*) * lm->class->index);
2914 M_ALD(REG_PV, REG_METHODPTR, sizeof(methodptr) * (lm - lm->class->methods));
2918 M_JSR(REG_RA, REG_PV);
2925 s1 = (s4) ((u1 *) mcodeptr - mcodebase);
2926 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
2928 s4 ml = -s1, mh = 0;
2929 while (ml < -32768) { ml += 65536; mh--; }
2931 M_IADD_IMM(REG_PV, ml, REG_PV);
2932 M_LADD(REG_PV, REG_RA, REG_PV);
2935 /* d contains return type */
2937 if (d != TYPE_VOID) {
2938 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
2939 s1 = reg_of_var(m, iptr->dst, REG_RESULT);
2940 M_INTMOVE(REG_RESULT, s1);
2941 store_reg_to_var_int(iptr->dst, s1);
2944 s1 = reg_of_var(m, iptr->dst, REG_FRESULT);
2945 M_TFLTMOVE(iptr->dst->type, REG_FRESULT, s1);
2946 store_reg_to_var_flt(iptr->dst, s1);
2953 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2955 /* op1: 0 == array, 1 == class */
2956 /* val.a: (classinfo*) superclass */
2958 /* superclass is an interface:
2960 * return (sub != NULL) &&
2961 * (sub->vftbl->interfacetablelength > super->index) &&
2962 * (sub->vftbl->interfacetable[-super->index] != NULL);
2964 * superclass is a class:
2966 * return ((sub != NULL) && (0
2967 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2968 * super->vftbl->diffvall));
2972 classinfo *super = (classinfo*) iptr->val.a;
2974 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
2975 codegen_threadcritrestart((u1*) mcodeptr - mcodebase);
2977 var_to_reg_int(s1, src, REG_ITMP1);
2978 d = reg_of_var(m, iptr->dst, REG_ITMP3);
2980 M_MOV(s1, REG_ITMP1);
2984 if (iptr->op1) { /* class/interface */
2985 if (super->flags & ACC_INTERFACE) { /* interface */
2988 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2989 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
2990 M_IADD_IMM(REG_ITMP2, - super->index, REG_ITMP2);
2991 M_BLEZ(REG_ITMP2, 3);
2993 M_ALD(REG_ITMP1, REG_ITMP1,
2994 OFFSET(vftbl, interfacetable[0]) -
2995 super->index * sizeof(methodptr*));
2996 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3000 s2 = super->vftbl->diffval;
3003 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3004 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3005 M_IADD_IMM(REG_ITMP1, - super->vftbl->baseval, REG_ITMP1);
3006 M_CMPULT_IMM(REG_ITMP1, s2 + 1, d);
3011 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3012 a = dseg_addaddress ((void*) super->vftbl);
3013 M_ALD(REG_ITMP2, REG_PV, a);
3014 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3015 codegen_threadcritstart((u1*) mcodeptr - mcodebase);
3017 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3018 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl, baseval));
3019 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, diffval));
3020 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3021 codegen_threadcritstop((u1*) mcodeptr - mcodebase);
3023 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3024 M_CMPULT(REG_ITMP2, REG_ITMP1, d);
3030 panic ("internal error: no inlined array instanceof");
3032 store_reg_to_var_int(iptr->dst, d);
3035 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3037 /* op1: 0 == array, 1 == class */
3038 /* val.a: (classinfo*) superclass */
3040 /* superclass is an interface:
3042 * OK if ((sub == NULL) ||
3043 * (sub->vftbl->interfacetablelength > super->index) &&
3044 * (sub->vftbl->interfacetable[-super->index] != NULL));
3046 * superclass is a class:
3048 * OK if ((sub == NULL) || (0
3049 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3050 * super->vftbl->diffvall));
3054 classinfo *super = (classinfo*) iptr->val.a;
3056 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3057 codegen_threadcritrestart((u1*) mcodeptr - mcodebase);
3060 d = reg_of_var(m, iptr->dst, REG_ITMP3);
3061 var_to_reg_int(s1, src, d);
3062 if (iptr->op1) { /* class/interface */
3063 if (super->flags & ACC_INTERFACE) { /* interface */
3066 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3067 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3068 M_IADD_IMM(REG_ITMP2, - super->index, REG_ITMP2);
3069 M_BLEZ(REG_ITMP2, 0);
3070 codegen_addxcastrefs(mcodeptr);
3072 M_ALD(REG_ITMP2, REG_ITMP1,
3073 OFFSET(vftbl, interfacetable[0]) -
3074 super->index * sizeof(methodptr*));
3075 M_BEQZ(REG_ITMP2, 0);
3076 codegen_addxcastrefs(mcodeptr);
3082 s2 = super->vftbl->diffval;
3083 M_BEQZ(s1, 6 + (s2 != 0));
3085 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3086 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3087 M_IADD_IMM(REG_ITMP1, - super->vftbl->baseval, REG_ITMP1);
3089 M_BNEZ(REG_ITMP1, 0);
3092 M_CMPULT_IMM(REG_ITMP1, s2 + 1, REG_ITMP2);
3093 M_BEQZ(REG_ITMP2, 0);
3097 M_BEQZ(s1, 10 + (d == REG_ITMP3));
3099 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3100 a = dseg_addaddress ((void*) super->vftbl);
3101 M_ALD(REG_ITMP2, REG_PV, a);
3102 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3103 codegen_threadcritstart((u1*) mcodeptr - mcodebase);
3105 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3106 if (d != REG_ITMP3) {
3107 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl, baseval));
3108 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, diffval));
3109 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3110 codegen_threadcritstop((u1*) mcodeptr - mcodebase);
3112 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3114 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, baseval));
3115 M_ISUB(REG_ITMP1, REG_ITMP2, REG_ITMP1);
3116 M_ALD(REG_ITMP2, REG_PV, a);
3117 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, diffval));
3118 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3119 codegen_threadcritstop((u1*) mcodeptr - mcodebase);
3122 M_CMPULT(REG_ITMP2, REG_ITMP1, REG_ITMP2);
3123 M_BNEZ(REG_ITMP2, 0);
3125 codegen_addxcastrefs(mcodeptr);
3130 panic ("internal error: no inlined array checkcast");
3133 store_reg_to_var_int(iptr->dst, d);
3136 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
3138 var_to_reg_int(s1, src, REG_ITMP1);
3140 codegen_addxcheckarefs(mcodeptr);
3144 case ICMD_CHECKEXCEPTION: /* ... ==> ... */
3146 M_BEQZ(REG_RESULT, 0);
3147 codegen_addxexceptionrefs(mcodeptr);
3151 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3152 /* op1 = dimension, val.a = array descriptor */
3154 /* check for negative sizes and copy sizes to stack if necessary */
3156 MCODECHECK((iptr->op1 << 1) + 64);
3158 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3159 var_to_reg_int(s2, src, REG_ITMP1);
3161 codegen_addxcheckarefs(mcodeptr);
3164 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
3166 if (src->varkind != ARGVAR) {
3167 M_LST(s2, REG_SP, 8 * (s1 + INT_ARG_CNT));
3171 /* a0 = dimension count */
3173 ICONST(r->argintregs[0], iptr->op1);
3175 /* a1 = arraydescriptor */
3177 a = dseg_addaddress(iptr->val.a);
3178 M_ALD(r->argintregs[1], REG_PV, a);
3180 /* a2 = pointer to dimensions = stack pointer */
3182 M_INTMOVE(REG_SP, r->argintregs[2]);
3184 a = dseg_addaddress((void*) builtin_nmultianewarray);
3185 M_ALD(REG_ITMP3, REG_PV, a);
3186 M_JSR(REG_RA, REG_ITMP3);
3188 s1 = (int)((u1*) mcodeptr - mcodebase);
3190 M_LDA (REG_PV, REG_RA, -s1);
3194 s1 = reg_of_var(m, iptr->dst, REG_RESULT);
3195 M_INTMOVE(REG_RESULT, s1);
3196 store_reg_to_var_int(iptr->dst, s1);
3200 default: error ("Unknown pseudo command: %d", iptr->opc);
3206 } /* for instruction */
3208 /* copy values to interface registers */
3210 src = bptr->outstack;
3211 len = bptr->outdepth;
3215 if ((src->varkind != STACKVAR)) {
3217 if (IS_FLT_DBL_TYPE(s2)) {
3218 var_to_reg_flt(s1, src, REG_FTMP1);
3219 if (!(r->interfaces[len][s2].flags & INMEMORY)) {
3220 M_TFLTMOVE(s2, s1, r->interfaces[len][s2].regoff);
3223 M_DST(s1, REG_SP, 8 * r->interfaces[len][s2].regoff);
3227 var_to_reg_int(s1, src, REG_ITMP1);
3228 if (!(r->interfaces[len][s2].flags & INMEMORY)) {
3229 M_INTMOVE(s1, r->interfaces[len][s2].regoff);
3232 M_LST(s1, REG_SP, 8 * r->interfaces[len][s2].regoff);
3238 } /* if (bptr -> flags >= BBREACHED) */
3239 } /* for basic block */
3241 /* bptr -> mpc = (int)((u1*) mcodeptr - mcodebase); */
3244 /* generate bound check stubs */
3246 s4 *xcodeptr = NULL;
3248 for (; xboundrefs != NULL; xboundrefs = xboundrefs->next) {
3249 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
3250 xboundrefs->branchpos,
3251 (u1*) mcodeptr - mcodebase);
3255 M_MOV(xboundrefs->reg, REG_ITMP1);
3256 M_LADD_IMM(REG_PV, xboundrefs->branchpos - 4, REG_ITMP2_XPC);
3258 if (xcodeptr != NULL) {
3259 M_BR(xcodeptr - mcodeptr);
3263 xcodeptr = mcodeptr;
3265 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3266 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3268 a = dseg_addaddress(string_java_lang_ArrayIndexOutOfBoundsException);
3269 M_ALD(r->argintregs[0], REG_PV, a);
3270 M_MOV(REG_ITMP1, r->argintregs[1]);
3272 a = dseg_addaddress(new_exception_int);
3273 M_ALD(REG_ITMP3, REG_PV, a);
3274 M_JSR(REG_RA, REG_ITMP3);
3276 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3278 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3279 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3281 a = dseg_addaddress(asm_handle_exception);
3282 M_ALD(REG_ITMP3, REG_PV, a);
3288 /* generate negative array size check stubs */
3292 for (; xcheckarefs != NULL; xcheckarefs = xcheckarefs->next) {
3293 if ((m->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3294 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3295 xcheckarefs->branchpos,
3296 (u1*) xcodeptr - (u1*) mcodebase - 4);
3300 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3301 xcheckarefs->branchpos,
3302 (u1*) mcodeptr - mcodebase);
3306 M_LADD_IMM(REG_PV, xcheckarefs->branchpos - 4, REG_ITMP2_XPC);
3308 if (xcodeptr != NULL) {
3309 M_BR(xcodeptr - mcodeptr);
3313 xcodeptr = mcodeptr;
3315 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3316 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3318 a = dseg_addaddress(string_java_lang_NegativeArraySizeException);
3319 M_ALD(r->argintregs[0], REG_PV, a);
3321 a = dseg_addaddress(new_exception);
3322 M_ALD(REG_ITMP3, REG_PV, a);
3323 M_JSR(REG_RA, REG_ITMP3);
3325 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3327 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3328 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3330 a = dseg_addaddress(asm_handle_exception);
3331 M_ALD(REG_ITMP3, REG_PV, a);
3337 /* generate cast check stubs */
3341 for (; xcastrefs != NULL; xcastrefs = xcastrefs->next) {
3342 if ((m->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3343 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3344 xcastrefs->branchpos,
3345 (u1*) xcodeptr - (u1*) mcodebase - 4);
3349 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3350 xcastrefs->branchpos,
3351 (u1*) mcodeptr - mcodebase);
3355 M_LADD_IMM(REG_PV, xcastrefs->branchpos - 4, REG_ITMP2_XPC);
3357 if (xcodeptr != NULL) {
3358 M_BR(xcodeptr - mcodeptr);
3362 xcodeptr = mcodeptr;
3364 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3365 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3367 a = dseg_addaddress(string_java_lang_ClassCastException);
3368 M_ALD(r->argintregs[0], REG_PV, a);
3370 a = dseg_addaddress(new_exception);
3371 M_ALD(REG_ITMP3, REG_PV, a);
3372 M_JSR(REG_RA, REG_ITMP3);
3374 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3376 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3377 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3379 a = dseg_addaddress(asm_handle_exception);
3380 M_ALD(REG_ITMP3, REG_PV, a);
3386 /* generate exception check stubs */
3390 for (; xexceptionrefs != NULL; xexceptionrefs = xexceptionrefs->next) {
3391 if ((m->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3392 gen_resolvebranch((u1*) mcodebase + xexceptionrefs->branchpos,
3393 xexceptionrefs->branchpos,
3394 (u1*) xcodeptr - (u1*) mcodebase - 4);
3398 gen_resolvebranch((u1*) mcodebase + xexceptionrefs->branchpos,
3399 xexceptionrefs->branchpos,
3400 (u1*) mcodeptr - mcodebase);
3404 M_LADD_IMM(REG_PV, xexceptionrefs->branchpos - 4, REG_ITMP2_XPC);
3406 if (xcodeptr != NULL) {
3407 M_BR(xcodeptr - mcodeptr);
3411 xcodeptr = mcodeptr;
3413 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3414 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3415 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3417 a = dseg_addaddress(builtin_get_exceptionptrptr);
3418 M_ALD(REG_ITMP3, REG_PV, a);
3419 M_JSR(REG_RA, REG_ITMP3);
3421 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3423 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3424 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3426 a = dseg_addaddress(&_exceptionptr);
3427 M_ALD(REG_ITMP3, REG_PV, a);
3428 M_ALD(REG_ITMP1_XPTR, REG_ITMP3, 0);
3429 M_AST(REG_ZERO, REG_ITMP3, 0);
3432 a = dseg_addaddress(asm_handle_exception);
3433 M_ALD(REG_ITMP3, REG_PV, a);
3439 /* generate null pointer check stubs */
3443 for (; xnullrefs != NULL; xnullrefs = xnullrefs->next) {
3444 if ((m->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3445 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3446 xnullrefs->branchpos,
3447 (u1*) xcodeptr - (u1*) mcodebase - 4);
3451 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3452 xnullrefs->branchpos,
3453 (u1*) mcodeptr - mcodebase);
3457 M_LADD_IMM(REG_PV, xnullrefs->branchpos - 4, REG_ITMP2_XPC);
3459 if (xcodeptr != NULL) {
3460 M_BR(xcodeptr - mcodeptr);
3464 xcodeptr = mcodeptr;
3466 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3467 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3469 a = dseg_addaddress(string_java_lang_NullPointerException);
3470 M_ALD(r->argintregs[0], REG_PV, a);
3472 a = dseg_addaddress(new_exception);
3473 M_ALD(REG_ITMP3, REG_PV, a);
3474 M_JSR(REG_RA, REG_ITMP3);
3476 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3478 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3479 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3481 a = dseg_addaddress(asm_handle_exception);
3482 M_ALD(REG_ITMP3, REG_PV, a);
3489 codegen_finish(m, (s4) ((u1 *) mcodeptr - mcodebase));
3491 docacheflush((void*) m->entrypoint, ((u1*) mcodeptr - mcodebase));
3495 /* function createcompilerstub *************************************************
3497 creates a stub routine which calls the compiler
3499 *******************************************************************************/
3501 #define COMPSTUBSIZE 4
3503 u1 *createcompilerstub(methodinfo *m)
3505 u8 *s = CNEW(u8, COMPSTUBSIZE); /* memory to hold the stub */
3506 s4 *mcodeptr = (s4 *) s; /* code generation pointer */
3508 /* code for the stub */
3509 M_ALD(REG_PV, REG_PV, 24); /* load pointer to the compiler */
3511 M_JSR(REG_ITMP1, REG_PV); /* jump to the compiler, return address
3512 in itmp1 is used as method pointer */
3515 s[2] = (u8) m; /* literals to be adressed */
3516 s[3] = (u8) asm_call_jit_compiler; /* jump directly via PV from above */
3518 (void) docacheflush((void*) s, (char*) mcodeptr - (char*) s);
3521 count_cstub_len += COMPSTUBSIZE * 8;
3528 /* function removecompilerstub *************************************************
3530 deletes a compilerstub from memory (simply by freeing it)
3532 *******************************************************************************/
3534 void removecompilerstub(u1 *stub)
3536 CFREE(stub, COMPSTUBSIZE * 8);
3540 /* function: createnativestub **************************************************
3542 creates a stub routine which calls a native method
3544 *******************************************************************************/
3546 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3547 #define NATIVESTUBSTACK 2
3548 #define NATIVESTUBTHREADEXTRA 5
3550 #define NATIVESTUBSTACK 1
3551 #define NATIVESTUBTHREADEXTRA 1
3554 #define NATIVESTUBSIZE (54 + 4 + NATIVESTUBTHREADEXTRA - 1)
3555 #define NATIVEVERBOSESIZE (50 + 17)
3556 #define NATIVESTUBOFFSET 9
3558 u1 *createnativestub(functionptr f, methodinfo *m)
3560 u8 *s; /* memory to hold the stub */
3562 s4 *mcodeptr; /* code generation pointer */
3563 s4 stackframesize = 0; /* size of stackframe if needed */
3568 /* init registers before using it */
3571 /* keep code size smaller */
3572 r = m->registerdata;
3574 descriptor2types(m); /* set paramcount and paramtypes */
3576 stubsize = runverbose ? NATIVESTUBSIZE + NATIVEVERBOSESIZE : NATIVESTUBSIZE;
3577 s = CNEW(u8, stubsize); /* memory to hold the stub */
3578 cs = s + NATIVESTUBOFFSET;
3579 mcodeptr = (s4 *) (cs); /* code generation pointer */
3581 *(cs-1) = (u8) f; /* address of native method */
3582 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3583 *(cs-2) = (u8) &builtin_get_exceptionptrptr;
3585 *(cs-2) = (u8) (&_exceptionptr); /* address of exceptionptr */
3587 *(cs-3) = (u8) asm_handle_nat_exception;/* addr of asm exception handler */
3588 *(cs-4) = (u8) (&env); /* addr of jni_environement */
3589 *(cs-5) = (u8) builtin_trace_args;
3591 *(cs-7) = (u8) builtin_displaymethodstop;
3592 *(cs-8) = (u8) m->class;
3593 *(cs-9) = (u8) asm_check_clinit;
3595 M_LDA(REG_SP, REG_SP, -NATIVESTUBSTACK * 8); /* build up stackframe */
3596 M_LST(REG_RA, REG_SP, 0); /* store return address */
3598 /* if function is static, check for initialized */
3600 if (m->flags & ACC_STATIC) {
3601 /* if class isn't yet initialized, do it */
3602 if (!m->class->initialized) {
3603 /* call helper function which patches this code */
3604 M_ALD(REG_ITMP1, REG_PV, -8 * 8); /* class */
3605 M_ALD(REG_ITMP3, REG_PV, -9 * 8); /* asm_check_clinit */
3606 M_JSR(REG_RA, REG_ITMP3);
3611 /* max. 50 instructions */
3616 M_LDA(REG_SP, REG_SP, -(18 * 8));
3617 M_AST(REG_RA, REG_SP, 1 * 8);
3619 /* save integer argument registers */
3620 for (p = 0; p < m->paramcount && p < INT_ARG_CNT; p++) {
3621 M_LST(r->argintregs[p], REG_SP, (2 + p) * 8);
3624 /* save and copy float arguments into integer registers */
3625 for (p = 0; p < m->paramcount && p < FLT_ARG_CNT; p++) {
3626 t = m->paramtypes[p];
3628 if (IS_FLT_DBL_TYPE(t)) {
3629 if (IS_2_WORD_TYPE(t)) {
3630 M_DST(r->argfltregs[p], REG_SP, (10 + p) * 8);
3631 M_LLD(r->argintregs[p], REG_SP, (10 + p) * 8);
3634 M_FST(r->argfltregs[p], REG_SP, (10 + p) * 8);
3635 M_ILD(r->argintregs[p], REG_SP, (10 + p) * 8);
3639 M_DST(r->argfltregs[p], REG_SP, (10 + p) * 8);
3643 M_ALD(REG_ITMP1, REG_PV, -6 * 8); /* method address */
3644 M_AST(REG_ITMP1, REG_SP, 0);
3645 M_ALD(REG_ITMP3, REG_PV, -5 * 8); /* builtin_trace_args */
3646 M_JSR(REG_RA, REG_ITMP3);
3648 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
3649 M_LDA(REG_PV, REG_RA, disp);
3651 for (p = 0; p < m->paramcount && p < INT_ARG_CNT; p++) {
3652 M_LLD(r->argintregs[p], REG_SP, (2 + p) * 8);
3655 for (p = 0; p < m->paramcount && p < FLT_ARG_CNT; p++) {
3656 t = m->paramtypes[p];
3658 if (IS_FLT_DBL_TYPE(t)) {
3659 if (IS_2_WORD_TYPE(t)) {
3660 M_DLD(r->argfltregs[p], REG_SP, (10 + p) * 8);
3663 M_FLD(r->argfltregs[p], REG_SP, (10 + p) * 8);
3667 M_DLD(r->argfltregs[p], REG_SP, (10 + p) * 8);
3671 M_ALD(REG_RA, REG_SP, 1 * 8);
3672 M_LDA(REG_SP, REG_SP, 18 * 8);
3675 /* save argument registers on stack -- if we have to */
3676 if ((m->flags & ACC_STATIC && m->paramcount > (INT_ARG_CNT - 2)) || m->paramcount > (INT_ARG_CNT - 1)) {
3678 s4 paramshiftcnt = (m->flags & ACC_STATIC) ? 2 : 1;
3679 s4 stackparamcnt = (m->paramcount > INT_ARG_CNT) ? m->paramcount - INT_ARG_CNT : 0;
3681 stackframesize = stackparamcnt + paramshiftcnt;
3683 M_LDA(REG_SP, REG_SP, -stackframesize * 8);
3685 /* copy stack arguments into new stack frame -- if any */
3686 for (i = 0; i < stackparamcnt; i++) {
3687 M_LLD(REG_ITMP1, REG_SP, (stackparamcnt + 1 + i) * 8);
3688 M_LST(REG_ITMP1, REG_SP, (paramshiftcnt + i) * 8);
3691 if (m->flags & ACC_STATIC) {
3692 if (IS_FLT_DBL_TYPE(m->paramtypes[5])) {
3693 M_DST(r->argfltregs[5], REG_SP, 1 * 8);
3695 M_LST(r->argintregs[5], REG_SP, 1 * 8);
3698 if (IS_FLT_DBL_TYPE(m->paramtypes[4])) {
3699 M_DST(r->argfltregs[4], REG_SP, 0 * 8);
3701 M_LST(r->argintregs[4], REG_SP, 0 * 8);
3705 if (IS_FLT_DBL_TYPE(m->paramtypes[5])) {
3706 M_DST(r->argfltregs[5], REG_SP, 0 * 8);
3708 M_LST(r->argintregs[5], REG_SP, 0 * 8);
3713 if (m->flags & ACC_STATIC) {
3714 M_MOV(r->argintregs[5], r->argintregs[7]);
3716 M_DMFC1(REG_ITMP1, r->argfltregs[5]);
3717 M_DMTC1(REG_ITMP1, r->argfltregs[7]);
3719 M_MOV(r->argintregs[4], r->argintregs[6]);
3721 M_DMFC1(REG_ITMP1, r->argfltregs[4]);
3722 M_DMTC1(REG_ITMP1, r->argfltregs[6]);
3724 M_MOV(r->argintregs[3], r->argintregs[5]);
3725 M_DMFC1(REG_ITMP1, r->argfltregs[3]);
3727 M_MOV(r->argintregs[2], r->argintregs[4]);
3728 M_DMTC1(REG_ITMP1, r->argfltregs[5]);
3730 M_MOV(r->argintregs[1], r->argintregs[3]);
3731 M_DMFC1(REG_ITMP1, r->argfltregs[2]);
3733 M_MOV(r->argintregs[0], r->argintregs[2]);
3734 M_DMTC1(REG_ITMP1, r->argfltregs[4]);
3736 M_DMFC1(REG_ITMP1, r->argfltregs[1]);
3737 M_DMTC1(REG_ITMP1, r->argfltregs[3]);
3739 M_DMFC1(REG_ITMP1, r->argfltregs[0]);
3740 M_DMTC1(REG_ITMP1, r->argfltregs[2]);
3742 M_ALD(r->argintregs[1], REG_PV, -8 * 8);
3745 M_MOV(r->argintregs[6], r->argintregs[7]);
3747 M_DMFC1(REG_ITMP1, r->argfltregs[6]);
3748 M_DMTC1(REG_ITMP1, r->argfltregs[7]);
3750 M_MOV(r->argintregs[5], r->argintregs[6]);
3752 M_DMFC1(REG_ITMP1, r->argfltregs[5]);
3753 M_DMTC1(REG_ITMP1, r->argfltregs[6]);
3755 M_MOV(r->argintregs[4], r->argintregs[5]);
3756 M_DMFC1(REG_ITMP1, r->argfltregs[4]);
3758 M_MOV(r->argintregs[3], r->argintregs[4]);
3759 M_DMTC1(REG_ITMP1, r->argfltregs[5]);
3761 M_MOV(r->argintregs[2], r->argintregs[3]);
3762 M_DMFC1(REG_ITMP1, r->argfltregs[3]);
3764 M_MOV(r->argintregs[1], r->argintregs[2]);
3765 M_DMTC1(REG_ITMP1, r->argfltregs[4]);
3767 M_MOV(r->argintregs[0], r->argintregs[1]);
3768 M_DMFC1(REG_ITMP1, r->argfltregs[2]);
3770 M_DMTC1(REG_ITMP1, r->argfltregs[3]);
3772 M_DMFC1(REG_ITMP1, r->argfltregs[1]);
3773 M_DMFC1(REG_ITMP2, r->argfltregs[0]);
3775 M_DMTC1(REG_ITMP1, r->argfltregs[2]);
3776 M_DMTC1(REG_ITMP2, r->argfltregs[1]);
3779 M_ALD(r->argintregs[0], REG_PV, -4 * 8); /* jni environement */
3780 M_ALD(REG_ITMP3, REG_PV, -1 * 8); /* load adress of native method */
3781 M_JSR(REG_RA, REG_ITMP3); /* call native method */
3782 M_NOP; /* delay slot */
3784 /* remove stackframe if there is one */
3785 if (stackframesize) {
3786 M_LDA(REG_SP, REG_SP, stackframesize * 8);
3789 /* 17 instructions */
3791 M_LDA(REG_SP, REG_SP, -(3 * 8));
3792 M_AST(REG_RA, REG_SP, 0 * 8);
3793 M_LST(REG_RESULT, REG_SP, 1 * 8);
3794 M_DST(REG_FRESULT, REG_SP, 2 * 8);
3795 M_ALD(r->argintregs[0], REG_PV, -6 * 8);
3796 M_MOV(REG_RESULT, r->argintregs[1]);
3797 M_DMFC1(REG_ITMP1, REG_FRESULT);
3798 M_DMTC1(REG_ITMP1, r->argfltregs[2]);
3799 M_DMTC1(REG_ITMP1, r->argfltregs[3]);
3800 M_ALD(REG_ITMP3, REG_PV, -7 * 8);/* builtin_displaymethodstop */
3801 M_JSR(REG_RA, REG_ITMP3);
3803 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
3804 M_LDA(REG_PV, REG_RA, disp);
3805 M_ALD(REG_RA, REG_SP, 0 * 8);
3806 M_LLD(REG_RESULT, REG_SP, 1 * 8);
3807 M_DLD(REG_FRESULT, REG_SP, 2 * 8);
3808 M_LDA(REG_SP, REG_SP, 3 * 8);
3811 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3812 M_ALD(REG_ITMP3, REG_PV, -2 * 8); /* builtin_get_exceptionptrptr */
3813 M_JSR(REG_RA, REG_ITMP3);
3816 if (IS_FLT_DBL_TYPE(m->returntype))
3817 M_DST(REG_FRESULT, REG_SP, 1 * 8);
3819 M_AST(REG_RESULT, REG_SP, 1 * 8);
3820 M_MOV(REG_RESULT, REG_ITMP3);
3821 if (IS_FLT_DBL_TYPE(m->returntype))
3822 M_DLD(REG_FRESULT, REG_SP, 1 * 8);
3824 M_ALD(REG_RESULT, REG_SP, 1 * 8);
3826 M_ALD(REG_ITMP3, REG_PV, -2 * 8); /* get address of exceptionptr */
3829 M_LLD(REG_RA, REG_SP, 0); /* load return address */
3830 M_ALD(REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
3832 M_BNEZ(REG_ITMP1, 2); /* if no exception then return */
3833 M_LDA(REG_SP, REG_SP, NATIVESTUBSTACK * 8);/*remove stackframe, delay slot*/
3835 M_RET(REG_RA); /* return to caller */
3836 M_NOP; /* delay slot */
3838 M_AST(REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
3839 M_ALD(REG_ITMP3, REG_PV, -3 * 8); /* load asm exception handler address */
3841 M_JMP(REG_ITMP3); /* jump to asm exception handler */
3842 M_LDA(REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
3845 (void) docacheflush((void*) cs, (char*) mcodeptr - (char*) cs);
3848 dolog_plain("stubsize: %d (for %d params)\n",
3849 (int) (mcodeptr - (s4*) s), m->paramcount);
3853 count_nstub_len += NATIVESTUBSIZE * 8;
3856 return (u1 *) (s + NATIVESTUBOFFSET);
3860 /* function: removenativestub **************************************************
3862 removes a previously created native-stub from memory
3864 *******************************************************************************/
3866 void removenativestub(u1 *stub)
3868 CFREE((u8*) stub - NATIVESTUBOFFSET, NATIVESTUBSIZE * 8);
3872 void docacheflush(u1 *p, long bytelen)
3874 u1 *e = p + bytelen;
3875 long psize = sysconf(_SC_PAGESIZE);
3876 p -= (long) p & (psize-1);
3877 e += psize - ((((long) e - 1) & (psize-1)) + 1);
3879 mprotect(p, bytelen, PROT_READ|PROT_WRITE|PROT_EXEC);
3884 * These are local overrides for various environment variables in Emacs.
3885 * Please do not remove this and leave it at the end of the file, where
3886 * Emacs will automagically detect them.
3887 * ---------------------------------------------------------------------
3890 * indent-tabs-mode: t