1 /* jit/alpha/codegen.c - machine code generator for alpha
3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4 Institut f. Computersprachen, TU Wien
5 R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser, M. Probst,
6 S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich,
9 This file is part of CACAO.
11 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License as
13 published by the Free Software Foundation; either version 2, or (at
14 your option) any later version.
16 This program is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
26 Contact: cacao@complang.tuwien.ac.at
28 Authors: Andreas Krall
31 $Id: codegen.c 1319 2004-07-16 13:45:50Z twisti $
41 #include "jit/alpha/codegen.h"
43 #include "jit/parse.h"
53 /* include independent code generation stuff */
54 #include "jit/codegen.inc"
55 #include "jit/reg.inc"
58 /* *****************************************************************************
60 Datatypes and Register Allocations:
61 -----------------------------------
63 On 64-bit-machines (like the Alpha) all operands are stored in the
64 registers in a 64-bit form, even when the correspondig JavaVM operands
65 only need 32 bits. This is done by a canonical representation:
67 32-bit integers are allways stored as sign-extended 64-bit values (this
68 approach is directly supported by the Alpha architecture and is very easy
71 32-bit-floats are stored in a 64-bit doubleprecision register by simply
72 expanding the exponent and mantissa with zeroes. (also supported by the
78 The calling conventions and the layout of the stack is explained in detail
79 in the documention file: calling.doc
81 *******************************************************************************/
84 /* register descripton - array ************************************************/
86 /* #define REG_RES 0 reserved register for OS or code generator */
87 /* #define REG_RET 1 return value register */
88 /* #define REG_EXC 2 exception value register (only old jit) */
89 /* #define REG_SAV 3 (callee) saved register */
90 /* #define REG_TMP 4 scratch temporary register (caller saved) */
91 /* #define REG_ARG 5 argument register (caller saved) */
93 /* #define REG_END -1 last entry in tables */
96 REG_RET, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
97 REG_TMP, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
98 REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_TMP, REG_TMP,
99 REG_TMP, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES,
102 /* for use of reserved registers, see comment above */
104 int nregdescfloat[] = {
105 REG_RET, REG_TMP, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
106 REG_SAV, REG_SAV, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
107 REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_TMP, REG_TMP,
108 REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_RES, REG_RES, REG_RES, REG_RES,
111 /* for use of reserved registers, see comment above */
114 /* NullPointerException handlers and exception handling initialisation */
116 typedef struct sigctx_struct {
118 long sc_onstack; /* sigstack state to restore */
119 long sc_mask; /* signal mask to restore */
120 long sc_pc; /* pc at time of signal */
121 long sc_ps; /* psl to retore */
122 long sc_regs[32]; /* processor regs 0 to 31 */
123 long sc_ownedfp; /* fp has been used */
124 long sc_fpregs[32]; /* fp regs 0 to 31 */
125 unsigned long sc_fpcr; /* floating point control register */
126 unsigned long sc_fp_control; /* software fpcr */
128 unsigned long sc_reserved1, sc_reserved2;
129 unsigned long sc_ssize;
131 unsigned long sc_traparg_a0;
132 unsigned long sc_traparg_a1;
133 unsigned long sc_traparg_a2;
134 unsigned long sc_fp_trap_pc;
135 unsigned long sc_fp_trigger_sum;
136 unsigned long sc_fp_trigger_inst;
137 unsigned long sc_retcode[2];
141 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
142 void thread_restartcriticalsection(ucontext_t *uc)
145 if ((critical = thread_checkcritical((void*) uc->uc_mcontext.sc_pc)) != NULL)
146 uc->uc_mcontext.sc_pc = (u8) critical;
150 /* NullPointerException signal handler for hardware null pointer check */
152 void catch_NullPointerException(int sig, int code, sigctx_struct *sigctx)
157 java_objectheader *xptr;
159 /* Reset signal handler - necessary for SysV, does no harm for BSD */
161 instr = *((int*)(sigctx->sc_pc));
162 faultaddr = sigctx->sc_regs[(instr >> 16) & 0x1f];
164 if (faultaddr == 0) {
165 signal(sig, (void*) catch_NullPointerException); /* reinstall handler */
167 sigaddset(&nsig, sig);
168 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
170 xptr = new_exception(string_java_lang_NullPointerException);
172 sigctx->sc_regs[REG_ITMP1_XPTR] = (u8) xptr;
173 sigctx->sc_regs[REG_ITMP2_XPC] = sigctx->sc_pc;
174 sigctx->sc_pc = (u8) asm_handle_exception;
178 faultaddr += (long) ((instr << 16) >> 16);
179 fprintf(stderr, "faulting address: 0x%016lx\n", faultaddr);
180 panic("Stack overflow");
187 void init_exceptions(void)
192 /* Linux on Digital Alpha needs an initialisation of the ieee floating point
193 control for IEEE compliant arithmetic (option -mieee of GCC). Under
194 Digital Unix this is done automatically.
199 extern unsigned long ieee_get_fp_control();
200 extern void ieee_set_fp_control(unsigned long fp_control);
202 void init_exceptions(void)
204 /* initialize floating point control */
206 ieee_set_fp_control(ieee_get_fp_control()
207 & ~IEEE_TRAP_ENABLE_INV
208 & ~IEEE_TRAP_ENABLE_DZE
209 /* & ~IEEE_TRAP_ENABLE_UNF we dont want underflow */
210 & ~IEEE_TRAP_ENABLE_OVF);
213 /* install signal handlers we need to convert to exceptions */
217 signal(SIGSEGV, (void*) catch_NullPointerException);
221 signal(SIGBUS, (void*) catch_NullPointerException);
227 /* function gen_mcode **********************************************************
229 generates machine code
231 *******************************************************************************/
233 void codegen(methodinfo *m)
235 s4 len, s1, s2, s3, d;
250 /* keep code size smaller */
253 savedregs_num = (m->isleafmethod) ? 0 : 1; /* space to save the RA */
255 /* space to save used callee saved registers */
257 savedregs_num += (r->savintregcnt - r->maxsavintreguse);
258 savedregs_num += (r->savfltregcnt - r->maxsavfltreguse);
260 parentargs_base = r->maxmemuse + savedregs_num;
262 #if defined(USE_THREADS) /* space to save argument of monitor_enter */
264 if (checksync && (m->flags & ACC_SYNCHRONIZED))
269 /* create method header */
271 (void) dseg_addaddress(m); /* MethodPointer */
272 (void) dseg_adds4(parentargs_base * 8); /* FrameSize */
274 #if defined(USE_THREADS)
276 /* IsSync contains the offset relative to the stack pointer for the
277 argument of monitor_exit used in the exception handler. Since the
278 offset could be zero and give a wrong meaning of the flag it is
282 if (checksync && (m->flags & ACC_SYNCHRONIZED))
283 (void) dseg_adds4((r->maxmemuse + 1) * 8); /* IsSync */
288 (void) dseg_adds4(0); /* IsSync */
290 (void) dseg_adds4(m->isleafmethod); /* IsLeaf */
291 (void) dseg_adds4(r->savintregcnt - r->maxsavintreguse);/* IntSave */
292 (void) dseg_adds4(r->savfltregcnt - r->maxsavfltreguse);/* FltSave */
294 dseg_addlinenumbertablesize();
296 (void) dseg_adds4(m->exceptiontablelength); /* ExTableSize */
298 /* create exception table */
300 for (ex = m->exceptiontable; ex != NULL; ex = ex->down) {
301 dseg_addtarget(ex->start);
302 dseg_addtarget(ex->end);
303 dseg_addtarget(ex->handler);
304 (void) dseg_addaddress(ex->catchtype);
307 /* initialize mcode variables */
309 mcodeptr = (s4*) mcodebase;
310 mcodeend = (s4*) (mcodebase + mcodesize);
311 MCODECHECK(128 + m->paramcount);
313 /* create stack frame (if necessary) */
315 if (parentargs_base) {
316 M_LDA (REG_SP, REG_SP, -parentargs_base * 8);
319 /* save return address and used callee saved registers */
322 if (!m->isleafmethod) {
323 p--; M_AST(REG_RA, REG_SP, p * 8);
325 for (i = r->savintregcnt - 1; i >= r->maxsavintreguse; i--) {
326 p--; M_LST(r->savintregs[i], REG_SP, p * 8);
328 for (i = r->savfltregcnt - 1; i >= r->maxsavfltreguse; i--) {
329 p--; M_DST(r->savfltregs[i], REG_SP, p * 8);
332 /* save monitorenter argument */
334 #if defined(USE_THREADS)
335 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
336 if (m->flags & ACC_STATIC) {
337 p = dseg_addaddress(m->class);
338 M_ALD(REG_ITMP1, REG_PV, p);
339 M_AST(REG_ITMP1, REG_SP, r->maxmemuse * 8);
342 M_AST(r->argintregs[0], REG_SP, r->maxmemuse * 8);
347 /* copy argument registers to stack and call trace function with pointer
348 to arguments on stack.
353 M_LDA(REG_SP, REG_SP, -((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
354 M_AST(REG_RA, REG_SP, 1 * 8);
356 /* save integer argument registers */
357 for (p = 0; /* p < m->paramcount && */ p < INT_ARG_CNT; p++) {
358 M_LST(r->argintregs[p], REG_SP, (2 + p) * 8);
361 /* save and copy float arguments into integer registers */
362 for (p = 0; /* p < m->paramcount && */ p < FLT_ARG_CNT; p++) {
363 t = m->paramtypes[p];
365 if (IS_FLT_DBL_TYPE(t)) {
366 if (IS_2_WORD_TYPE(t)) {
367 M_DST(r->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
370 M_FST(r->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
373 M_LLD(r->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
376 M_DST(r->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
380 p = dseg_addaddress(m);
381 M_ALD(REG_ITMP1, REG_PV, p);
382 M_AST(REG_ITMP1, REG_SP, 0 * 8);
383 p = dseg_addaddress((void *) builtin_trace_args);
384 M_ALD(REG_PV, REG_PV, p);
385 M_JSR(REG_RA, REG_PV);
386 disp = -(s4) ((u1 *) mcodeptr - mcodebase);
387 M_LDA(REG_PV, REG_RA, disp);
388 M_ALD(REG_RA, REG_SP, 1 * 8);
390 for (p = 0; /* p < mparamcount && */ p < INT_ARG_CNT; p++) {
391 M_LLD(r->argintregs[p], REG_SP, (2 + p) * 8);
394 for (p = 0; /* p < mparamcount && */ p < FLT_ARG_CNT; p++) {
395 t = m->paramtypes[p];
397 if (IS_FLT_DBL_TYPE(t)) {
398 if (IS_2_WORD_TYPE(t)) {
399 M_DLD(r->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
402 M_FLD(r->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
406 M_DLD(r->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
410 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT + 2) * 8);
413 /* take arguments out of register or stack frame */
415 for (p = 0, l = 0; p < m->paramcount; p++) {
416 t = m->paramtypes[p];
417 var = &(r->locals[l][t]);
419 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
423 if (IS_INT_LNG_TYPE(t)) { /* integer args */
424 if (p < INT_ARG_CNT) { /* register arguments */
425 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
426 M_INTMOVE(r->argintregs[p], var->regoff);
427 } else { /* reg arg -> spilled */
428 M_LST(r->argintregs[p], REG_SP, 8 * var->regoff);
431 } else { /* stack arguments */
432 pa = p - INT_ARG_CNT;
433 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
434 M_LLD(var->regoff, REG_SP, 8 * (parentargs_base + pa));
436 } else { /* stack arg -> spilled */
437 M_LLD(REG_ITMP1, REG_SP, 8 * (parentargs_base + pa));
438 M_LST(REG_ITMP1, REG_SP, 8 * var->regoff);
442 } else { /* floating args */
443 if (p < FLT_ARG_CNT) { /* register arguments */
444 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
445 M_FLTMOVE(r->argfltregs[p], var->regoff);
447 } else { /* reg arg -> spilled */
448 M_DST(r->argfltregs[p], REG_SP, 8 * var->regoff);
451 } else { /* stack arguments */
452 pa = p - FLT_ARG_CNT;
453 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
454 M_DLD(var->regoff, REG_SP, 8 * (parentargs_base + pa) );
456 } else { /* stack-arg -> spilled */
457 M_DLD(REG_FTMP1, REG_SP, 8 * (parentargs_base + pa));
458 M_DST(REG_FTMP1, REG_SP, 8 * var->regoff);
464 /* call monitorenter function */
466 #if defined(USE_THREADS)
467 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
469 s8 func_enter = (m->flags & ACC_STATIC) ?
470 (s8) builtin_staticmonitorenter : (s8) builtin_monitorenter;
471 p = dseg_addaddress((void*) func_enter);
472 M_ALD(REG_PV, REG_PV, p);
473 M_ALD(r->argintregs[0], REG_SP, r->maxmemuse * 8);
474 M_JSR(REG_RA, REG_PV);
475 disp = -(s4) ((u1 *) mcodeptr - mcodebase);
476 M_LDA(REG_PV, REG_RA, disp);
481 /* end of header generation */
483 /* walk through all basic blocks */
484 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
486 bptr->mpc = (s4) ((u1 *) mcodeptr - mcodebase);
488 if (bptr->flags >= BBREACHED) {
490 /* branch resolving */
494 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
495 gen_resolvebranch((u1*) mcodebase + brefs->branchpos,
496 brefs->branchpos, bptr->mpc);
500 /* copy interface registers to their destination */
505 while (src != NULL) {
507 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
508 d = reg_of_var(m, src, REG_ITMP1);
509 M_INTMOVE(REG_ITMP1, d);
510 store_reg_to_var_int(src, d);
513 d = reg_of_var(m, src, REG_IFTMP);
514 if ((src->varkind != STACKVAR)) {
516 if (IS_FLT_DBL_TYPE(s2)) {
517 if (!(r->interfaces[len][s2].flags & INMEMORY)) {
518 s1 = r->interfaces[len][s2].regoff;
522 M_DLD(d, REG_SP, 8 * r->interfaces[len][s2].regoff);
524 store_reg_to_var_flt(src, d);
527 if (!(r->interfaces[len][s2].flags & INMEMORY)) {
528 s1 = r->interfaces[len][s2].regoff;
532 M_LLD(d, REG_SP, 8 * r->interfaces[len][s2].regoff);
534 store_reg_to_var_int(src, d);
541 /* walk through all instructions */
545 for (iptr = bptr->iinstr;
547 src = iptr->dst, len--, iptr++) {
549 MCODECHECK(64); /* an instruction usually needs < 64 words */
552 case ICMD_NOP: /* ... ==> ... */
555 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
557 var_to_reg_int(s1, src, REG_ITMP1);
559 codegen_addxnullrefs(mcodeptr);
562 /* constant operations ************************************************/
564 #define ICONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
565 else{a=dseg_adds4(c);M_ILD(r,REG_PV,a);}
567 #define LCONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
568 else{a=dseg_adds8(c);M_LLD(r,REG_PV,a);}
570 case ICMD_ICONST: /* ... ==> ..., constant */
571 /* op1 = 0, val.i = constant */
573 d = reg_of_var(m, iptr->dst, REG_ITMP1);
574 ICONST(d, iptr->val.i);
575 store_reg_to_var_int(iptr->dst, d);
578 case ICMD_LCONST: /* ... ==> ..., constant */
579 /* op1 = 0, val.l = constant */
581 d = reg_of_var(m, iptr->dst, REG_ITMP1);
582 LCONST(d, iptr->val.l);
583 store_reg_to_var_int(iptr->dst, d);
586 case ICMD_FCONST: /* ... ==> ..., constant */
587 /* op1 = 0, val.f = constant */
589 d = reg_of_var(m, iptr->dst, REG_FTMP1);
590 a = dseg_addfloat(iptr->val.f);
592 store_reg_to_var_flt(iptr->dst, d);
595 case ICMD_DCONST: /* ... ==> ..., constant */
596 /* op1 = 0, val.d = constant */
598 d = reg_of_var(m, iptr->dst, REG_FTMP1);
599 a = dseg_adddouble(iptr->val.d);
601 store_reg_to_var_flt(iptr->dst, d);
604 case ICMD_ACONST: /* ... ==> ..., constant */
605 /* op1 = 0, val.a = constant */
607 d = reg_of_var(m, iptr->dst, REG_ITMP1);
609 a = dseg_addaddress (iptr->val.a);
613 M_INTMOVE(REG_ZERO, d);
615 store_reg_to_var_int(iptr->dst, d);
619 /* load/store operations **********************************************/
621 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
622 case ICMD_LLOAD: /* op1 = local variable */
625 d = reg_of_var(m, iptr->dst, REG_ITMP1);
626 if ((iptr->dst->varkind == LOCALVAR) &&
627 (iptr->dst->varnum == iptr->op1))
629 var = &(r->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
630 if (var->flags & INMEMORY)
631 M_LLD(d, REG_SP, 8 * var->regoff);
633 {M_INTMOVE(var->regoff,d);}
634 store_reg_to_var_int(iptr->dst, d);
637 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
638 case ICMD_DLOAD: /* op1 = local variable */
640 d = reg_of_var(m, iptr->dst, REG_FTMP1);
641 if ((iptr->dst->varkind == LOCALVAR) &&
642 (iptr->dst->varnum == iptr->op1))
644 var = &(r->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
645 if (var->flags & INMEMORY)
646 M_DLD(d, REG_SP, 8 * var->regoff);
648 {M_FLTMOVE(var->regoff,d);}
649 store_reg_to_var_flt(iptr->dst, d);
653 case ICMD_ISTORE: /* ..., value ==> ... */
654 case ICMD_LSTORE: /* op1 = local variable */
657 if ((src->varkind == LOCALVAR) &&
658 (src->varnum == iptr->op1))
660 var = &(r->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
661 if (var->flags & INMEMORY) {
662 var_to_reg_int(s1, src, REG_ITMP1);
663 M_LST(s1, REG_SP, 8 * var->regoff);
666 var_to_reg_int(s1, src, var->regoff);
667 M_INTMOVE(s1, var->regoff);
671 case ICMD_FSTORE: /* ..., value ==> ... */
672 case ICMD_DSTORE: /* op1 = local variable */
674 if ((src->varkind == LOCALVAR) &&
675 (src->varnum == iptr->op1))
677 var = &(r->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
678 if (var->flags & INMEMORY) {
679 var_to_reg_flt(s1, src, REG_FTMP1);
680 M_DST(s1, REG_SP, 8 * var->regoff);
683 var_to_reg_flt(s1, src, var->regoff);
684 M_FLTMOVE(s1, var->regoff);
689 /* pop/dup/swap operations ********************************************/
691 /* attention: double and longs are only one entry in CACAO ICMDs */
693 case ICMD_POP: /* ..., value ==> ... */
694 case ICMD_POP2: /* ..., value, value ==> ... */
697 case ICMD_DUP: /* ..., a ==> ..., a, a */
698 M_COPY(src, iptr->dst);
701 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
703 M_COPY(src, iptr->dst);
704 M_COPY(src->prev, iptr->dst->prev);
705 M_COPY(iptr->dst, iptr->dst->prev->prev);
708 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
710 M_COPY(src, iptr->dst);
711 M_COPY(src->prev, iptr->dst->prev);
712 M_COPY(src->prev->prev, iptr->dst->prev->prev);
713 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
716 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
718 M_COPY(src, iptr->dst);
719 M_COPY(src->prev, iptr->dst->prev);
722 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
724 M_COPY(src, iptr->dst);
725 M_COPY(src->prev, iptr->dst->prev);
726 M_COPY(src->prev->prev, iptr->dst->prev->prev);
727 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
728 M_COPY(iptr->dst->prev, iptr->dst->prev->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(iptr->dst, iptr->dst->prev->prev->prev->prev);
738 M_COPY(iptr->dst->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_IADD(s1, REG_ZERO, 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 if (has_ext_instr_set) {
790 M_SLL_IMM(s1, 56, d);
791 M_SRA_IMM( d, 56, d);
793 store_reg_to_var_int(iptr->dst, d);
796 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
798 var_to_reg_int(s1, src, REG_ITMP1);
799 d = reg_of_var(m, iptr->dst, REG_ITMP3);
801 store_reg_to_var_int(iptr->dst, d);
804 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
806 var_to_reg_int(s1, src, REG_ITMP1);
807 d = reg_of_var(m, iptr->dst, REG_ITMP3);
808 if (has_ext_instr_set) {
812 M_SLL_IMM(s1, 48, d);
813 M_SRA_IMM( d, 48, d);
815 store_reg_to_var_int(iptr->dst, d);
819 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
821 var_to_reg_int(s1, src->prev, REG_ITMP1);
822 var_to_reg_int(s2, src, REG_ITMP2);
823 d = reg_of_var(m, iptr->dst, REG_ITMP3);
825 store_reg_to_var_int(iptr->dst, d);
828 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
829 /* val.i = constant */
831 var_to_reg_int(s1, src, REG_ITMP1);
832 d = reg_of_var(m, iptr->dst, REG_ITMP3);
833 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
834 M_IADD_IMM(s1, iptr->val.i, d);
837 ICONST(REG_ITMP2, iptr->val.i);
838 M_IADD(s1, REG_ITMP2, d);
840 store_reg_to_var_int(iptr->dst, d);
843 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
845 var_to_reg_int(s1, src->prev, REG_ITMP1);
846 var_to_reg_int(s2, src, REG_ITMP2);
847 d = reg_of_var(m, iptr->dst, REG_ITMP3);
849 store_reg_to_var_int(iptr->dst, d);
852 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
853 /* val.l = constant */
855 var_to_reg_int(s1, src, REG_ITMP1);
856 d = reg_of_var(m, iptr->dst, REG_ITMP3);
857 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
858 M_LADD_IMM(s1, iptr->val.l, d);
861 LCONST(REG_ITMP2, iptr->val.l);
862 M_LADD(s1, REG_ITMP2, d);
864 store_reg_to_var_int(iptr->dst, d);
867 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
869 var_to_reg_int(s1, src->prev, REG_ITMP1);
870 var_to_reg_int(s2, src, REG_ITMP2);
871 d = reg_of_var(m, iptr->dst, REG_ITMP3);
873 store_reg_to_var_int(iptr->dst, d);
876 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
877 /* val.i = constant */
879 var_to_reg_int(s1, src, REG_ITMP1);
880 d = reg_of_var(m, iptr->dst, REG_ITMP3);
881 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
882 M_ISUB_IMM(s1, iptr->val.i, d);
885 ICONST(REG_ITMP2, iptr->val.i);
886 M_ISUB(s1, REG_ITMP2, d);
888 store_reg_to_var_int(iptr->dst, d);
891 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
893 var_to_reg_int(s1, src->prev, REG_ITMP1);
894 var_to_reg_int(s2, src, REG_ITMP2);
895 d = reg_of_var(m, iptr->dst, REG_ITMP3);
897 store_reg_to_var_int(iptr->dst, d);
900 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
901 /* val.l = constant */
903 var_to_reg_int(s1, src, REG_ITMP1);
904 d = reg_of_var(m, iptr->dst, REG_ITMP3);
905 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
906 M_LSUB_IMM(s1, iptr->val.l, d);
909 LCONST(REG_ITMP2, iptr->val.l);
910 M_LSUB(s1, REG_ITMP2, d);
912 store_reg_to_var_int(iptr->dst, d);
915 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
917 var_to_reg_int(s1, src->prev, REG_ITMP1);
918 var_to_reg_int(s2, src, REG_ITMP2);
919 d = reg_of_var(m, iptr->dst, REG_ITMP3);
921 store_reg_to_var_int(iptr->dst, d);
924 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
925 /* val.i = constant */
927 var_to_reg_int(s1, src, REG_ITMP1);
928 d = reg_of_var(m, iptr->dst, REG_ITMP3);
929 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
930 M_IMUL_IMM(s1, iptr->val.i, d);
933 ICONST(REG_ITMP2, iptr->val.i);
934 M_IMUL(s1, REG_ITMP2, d);
936 store_reg_to_var_int(iptr->dst, d);
939 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
941 var_to_reg_int(s1, src->prev, REG_ITMP1);
942 var_to_reg_int(s2, src, REG_ITMP2);
943 d = reg_of_var(m, iptr->dst, REG_ITMP3);
945 store_reg_to_var_int(iptr->dst, d);
948 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
949 /* val.l = constant */
951 var_to_reg_int(s1, src, REG_ITMP1);
952 d = reg_of_var(m, iptr->dst, REG_ITMP3);
953 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
954 M_LMUL_IMM(s1, iptr->val.l, d);
957 LCONST(REG_ITMP2, iptr->val.l);
958 M_LMUL(s1, REG_ITMP2, d);
960 store_reg_to_var_int(iptr->dst, d);
963 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
964 case ICMD_LDIVPOW2: /* val.i = constant */
966 var_to_reg_int(s1, src, REG_ITMP1);
967 d = reg_of_var(m, iptr->dst, REG_ITMP3);
968 if (iptr->val.i <= 15) {
969 M_LDA(REG_ITMP2, s1, (1 << iptr->val.i) -1);
970 M_CMOVGE(s1, s1, REG_ITMP2);
973 M_SRA_IMM(s1, 63, REG_ITMP2);
974 M_SRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
975 M_LADD(s1, REG_ITMP2, REG_ITMP2);
977 M_SRA_IMM(REG_ITMP2, iptr->val.i, d);
978 store_reg_to_var_int(iptr->dst, d);
981 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
983 var_to_reg_int(s1, src->prev, REG_ITMP1);
984 var_to_reg_int(s2, src, REG_ITMP2);
985 d = reg_of_var(m, iptr->dst, REG_ITMP3);
986 M_AND_IMM(s2, 0x1f, REG_ITMP3);
987 M_SLL(s1, REG_ITMP3, d);
988 M_IADD(d, REG_ZERO, d);
989 store_reg_to_var_int(iptr->dst, d);
992 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
993 /* val.i = constant */
995 var_to_reg_int(s1, src, REG_ITMP1);
996 d = reg_of_var(m, iptr->dst, REG_ITMP3);
997 M_SLL_IMM(s1, iptr->val.i & 0x1f, d);
998 M_IADD(d, REG_ZERO, d);
999 store_reg_to_var_int(iptr->dst, d);
1002 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1004 var_to_reg_int(s1, src->prev, REG_ITMP1);
1005 var_to_reg_int(s2, src, REG_ITMP2);
1006 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1007 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1008 M_SRA(s1, REG_ITMP3, d);
1009 store_reg_to_var_int(iptr->dst, d);
1012 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1013 /* val.i = constant */
1015 var_to_reg_int(s1, src, REG_ITMP1);
1016 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1017 M_SRA_IMM(s1, iptr->val.i & 0x1f, d);
1018 store_reg_to_var_int(iptr->dst, d);
1021 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1023 var_to_reg_int(s1, src->prev, REG_ITMP1);
1024 var_to_reg_int(s2, src, REG_ITMP2);
1025 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1026 M_AND_IMM(s2, 0x1f, REG_ITMP2);
1028 M_SRL(d, REG_ITMP2, d);
1029 M_IADD(d, REG_ZERO, d);
1030 store_reg_to_var_int(iptr->dst, d);
1033 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1034 /* val.i = constant */
1036 var_to_reg_int(s1, src, REG_ITMP1);
1037 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1039 M_SRL_IMM(d, iptr->val.i & 0x1f, d);
1040 M_IADD(d, REG_ZERO, d);
1041 store_reg_to_var_int(iptr->dst, d);
1044 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1046 var_to_reg_int(s1, src->prev, REG_ITMP1);
1047 var_to_reg_int(s2, src, REG_ITMP2);
1048 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1050 store_reg_to_var_int(iptr->dst, d);
1053 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1054 /* val.i = constant */
1056 var_to_reg_int(s1, src, REG_ITMP1);
1057 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1058 M_SLL_IMM(s1, iptr->val.i & 0x3f, d);
1059 store_reg_to_var_int(iptr->dst, d);
1062 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1064 var_to_reg_int(s1, src->prev, REG_ITMP1);
1065 var_to_reg_int(s2, src, REG_ITMP2);
1066 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1068 store_reg_to_var_int(iptr->dst, d);
1071 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1072 /* val.i = constant */
1074 var_to_reg_int(s1, src, REG_ITMP1);
1075 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1076 M_SRA_IMM(s1, iptr->val.i & 0x3f, d);
1077 store_reg_to_var_int(iptr->dst, d);
1080 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1082 var_to_reg_int(s1, src->prev, REG_ITMP1);
1083 var_to_reg_int(s2, src, REG_ITMP2);
1084 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1086 store_reg_to_var_int(iptr->dst, d);
1089 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1090 /* val.i = constant */
1092 var_to_reg_int(s1, src, REG_ITMP1);
1093 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1094 M_SRL_IMM(s1, iptr->val.i & 0x3f, d);
1095 store_reg_to_var_int(iptr->dst, d);
1098 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1101 var_to_reg_int(s1, src->prev, REG_ITMP1);
1102 var_to_reg_int(s2, src, REG_ITMP2);
1103 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1105 store_reg_to_var_int(iptr->dst, d);
1108 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1109 /* val.i = constant */
1111 var_to_reg_int(s1, src, REG_ITMP1);
1112 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1113 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1114 M_AND_IMM(s1, iptr->val.i, d);
1116 else if (iptr->val.i == 0xffff) {
1119 else if (iptr->val.i == 0xffffff) {
1120 M_ZAPNOT_IMM(s1, 0x07, d);
1123 ICONST(REG_ITMP2, iptr->val.i);
1124 M_AND(s1, REG_ITMP2, d);
1126 store_reg_to_var_int(iptr->dst, d);
1129 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1130 /* val.i = constant */
1132 var_to_reg_int(s1, src, REG_ITMP1);
1133 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1135 M_MOV(s1, REG_ITMP1);
1138 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1139 M_AND_IMM(s1, iptr->val.i, d);
1141 M_ISUB(REG_ZERO, s1, d);
1142 M_AND_IMM(d, iptr->val.i, d);
1144 else if (iptr->val.i == 0xffff) {
1147 M_ISUB(REG_ZERO, s1, d);
1150 else if (iptr->val.i == 0xffffff) {
1151 M_ZAPNOT_IMM(s1, 0x07, d);
1153 M_ISUB(REG_ZERO, s1, d);
1154 M_ZAPNOT_IMM(d, 0x07, d);
1157 ICONST(REG_ITMP2, iptr->val.i);
1158 M_AND(s1, REG_ITMP2, d);
1160 M_ISUB(REG_ZERO, s1, d);
1161 M_AND(d, REG_ITMP2, d);
1163 M_ISUB(REG_ZERO, d, d);
1164 store_reg_to_var_int(iptr->dst, d);
1167 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1168 /* val.l = constant */
1170 var_to_reg_int(s1, src, REG_ITMP1);
1171 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1172 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1173 M_AND_IMM(s1, iptr->val.l, d);
1175 else if (iptr->val.l == 0xffffL) {
1178 else if (iptr->val.l == 0xffffffL) {
1179 M_ZAPNOT_IMM(s1, 0x07, d);
1181 else if (iptr->val.l == 0xffffffffL) {
1184 else if (iptr->val.l == 0xffffffffffL) {
1185 M_ZAPNOT_IMM(s1, 0x1f, d);
1187 else if (iptr->val.l == 0xffffffffffffL) {
1188 M_ZAPNOT_IMM(s1, 0x3f, d);
1190 else if (iptr->val.l == 0xffffffffffffffL) {
1191 M_ZAPNOT_IMM(s1, 0x7f, d);
1194 LCONST(REG_ITMP2, iptr->val.l);
1195 M_AND(s1, REG_ITMP2, d);
1197 store_reg_to_var_int(iptr->dst, d);
1200 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1201 /* val.l = 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.l >= 0) && (iptr->val.l <= 255)) {
1210 M_AND_IMM(s1, iptr->val.l, d);
1212 M_LSUB(REG_ZERO, s1, d);
1213 M_AND_IMM(d, iptr->val.l, d);
1215 else if (iptr->val.l == 0xffffL) {
1218 M_LSUB(REG_ZERO, s1, d);
1221 else if (iptr->val.l == 0xffffffL) {
1222 M_ZAPNOT_IMM(s1, 0x07, d);
1224 M_LSUB(REG_ZERO, s1, d);
1225 M_ZAPNOT_IMM(d, 0x07, d);
1227 else if (iptr->val.l == 0xffffffffL) {
1230 M_LSUB(REG_ZERO, s1, d);
1233 else if (iptr->val.l == 0xffffffffffL) {
1234 M_ZAPNOT_IMM(s1, 0x1f, d);
1236 M_LSUB(REG_ZERO, s1, d);
1237 M_ZAPNOT_IMM(d, 0x1f, d);
1239 else if (iptr->val.l == 0xffffffffffffL) {
1240 M_ZAPNOT_IMM(s1, 0x3f, d);
1242 M_LSUB(REG_ZERO, s1, d);
1243 M_ZAPNOT_IMM(d, 0x3f, d);
1245 else if (iptr->val.l == 0xffffffffffffffL) {
1246 M_ZAPNOT_IMM(s1, 0x7f, d);
1248 M_LSUB(REG_ZERO, s1, d);
1249 M_ZAPNOT_IMM(d, 0x7f, d);
1252 LCONST(REG_ITMP2, iptr->val.l);
1253 M_AND(s1, REG_ITMP2, d);
1255 M_LSUB(REG_ZERO, s1, d);
1256 M_AND(d, REG_ITMP2, d);
1258 M_LSUB(REG_ZERO, d, d);
1259 store_reg_to_var_int(iptr->dst, d);
1262 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1265 var_to_reg_int(s1, src->prev, REG_ITMP1);
1266 var_to_reg_int(s2, src, REG_ITMP2);
1267 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1269 store_reg_to_var_int(iptr->dst, d);
1272 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1273 /* val.i = constant */
1275 var_to_reg_int(s1, src, REG_ITMP1);
1276 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1277 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1278 M_OR_IMM(s1, iptr->val.i, d);
1281 ICONST(REG_ITMP2, iptr->val.i);
1282 M_OR(s1, REG_ITMP2, d);
1284 store_reg_to_var_int(iptr->dst, d);
1287 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1288 /* val.l = constant */
1290 var_to_reg_int(s1, src, REG_ITMP1);
1291 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1292 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1293 M_OR_IMM(s1, iptr->val.l, d);
1296 LCONST(REG_ITMP2, iptr->val.l);
1297 M_OR(s1, REG_ITMP2, d);
1299 store_reg_to_var_int(iptr->dst, d);
1302 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1305 var_to_reg_int(s1, src->prev, REG_ITMP1);
1306 var_to_reg_int(s2, src, REG_ITMP2);
1307 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1309 store_reg_to_var_int(iptr->dst, d);
1312 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1313 /* val.i = constant */
1315 var_to_reg_int(s1, src, REG_ITMP1);
1316 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1317 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1318 M_XOR_IMM(s1, iptr->val.i, d);
1321 ICONST(REG_ITMP2, iptr->val.i);
1322 M_XOR(s1, REG_ITMP2, d);
1324 store_reg_to_var_int(iptr->dst, d);
1327 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1328 /* val.l = constant */
1330 var_to_reg_int(s1, src, REG_ITMP1);
1331 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1332 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1333 M_XOR_IMM(s1, iptr->val.l, d);
1336 LCONST(REG_ITMP2, iptr->val.l);
1337 M_XOR(s1, REG_ITMP2, d);
1339 store_reg_to_var_int(iptr->dst, d);
1343 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1345 var_to_reg_int(s1, src->prev, REG_ITMP1);
1346 var_to_reg_int(s2, src, REG_ITMP2);
1347 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1348 M_CMPLT(s1, s2, REG_ITMP3);
1349 M_CMPLT(s2, s1, REG_ITMP1);
1350 M_LSUB (REG_ITMP1, REG_ITMP3, d);
1351 store_reg_to_var_int(iptr->dst, d);
1355 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1356 /* op1 = variable, val.i = constant */
1358 var = &(r->locals[iptr->op1][TYPE_INT]);
1359 if (var->flags & INMEMORY) {
1361 M_LLD(s1, REG_SP, 8 * var->regoff);
1365 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1366 M_IADD_IMM(s1, iptr->val.i, s1);
1368 else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1369 M_ISUB_IMM(s1, (-iptr->val.i), s1);
1372 M_LDA (s1, s1, iptr->val.i);
1373 M_IADD(s1, REG_ZERO, 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);
1407 if (d == s1 || d == s2) {
1408 M_FADDS(s1, s2, REG_FTMP3);
1410 M_FMOV(REG_FTMP3, d);
1417 store_reg_to_var_flt(iptr->dst, d);
1420 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1422 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1423 var_to_reg_flt(s2, src, REG_FTMP2);
1424 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1429 if (d == s1 || d == s2) {
1430 M_DADDS(s1, s2, REG_FTMP3);
1432 M_FMOV(REG_FTMP3, d);
1439 store_reg_to_var_flt(iptr->dst, d);
1442 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1444 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1445 var_to_reg_flt(s2, src, REG_FTMP2);
1446 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1451 if (d == s1 || d == s2) {
1452 M_FSUBS(s1, s2, REG_FTMP3);
1454 M_FMOV(REG_FTMP3, d);
1461 store_reg_to_var_flt(iptr->dst, d);
1464 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1466 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1467 var_to_reg_flt(s2, src, REG_FTMP2);
1468 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1473 if (d == s1 || d == s2) {
1474 M_DSUBS(s1, s2, REG_FTMP3);
1476 M_FMOV(REG_FTMP3, d);
1483 store_reg_to_var_flt(iptr->dst, d);
1486 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1488 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1489 var_to_reg_flt(s2, src, REG_FTMP2);
1490 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1495 if (d == s1 || d == s2) {
1496 M_FMULS(s1, s2, REG_FTMP3);
1498 M_FMOV(REG_FTMP3, d);
1505 store_reg_to_var_flt(iptr->dst, d);
1508 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1510 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1511 var_to_reg_flt(s2, src, REG_FTMP2);
1512 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1517 if (d == s1 || d == s2) {
1518 M_DMULS(s1, s2, REG_FTMP3);
1520 M_FMOV(REG_FTMP3, d);
1527 store_reg_to_var_flt(iptr->dst, d);
1530 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1532 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1533 var_to_reg_flt(s2, src, REG_FTMP2);
1534 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1539 if (d == s1 || d == s2) {
1540 M_FDIVS(s1, s2, REG_FTMP3);
1542 M_FMOV(REG_FTMP3, d);
1549 store_reg_to_var_flt(iptr->dst, d);
1552 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1554 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1555 var_to_reg_flt(s2, src, REG_FTMP2);
1556 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1561 if (d == s1 || d == s2) {
1562 M_DDIVS(s1, s2, REG_FTMP3);
1564 M_FMOV(REG_FTMP3, d);
1571 store_reg_to_var_flt(iptr->dst, d);
1574 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1576 var_to_reg_int(s1, src, REG_ITMP1);
1577 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1578 a = dseg_adddouble(0.0);
1579 M_LST (s1, REG_PV, a);
1580 M_DLD (d, REG_PV, a);
1582 store_reg_to_var_flt(iptr->dst, d);
1585 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1587 var_to_reg_int(s1, src, REG_ITMP1);
1588 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1589 a = dseg_adddouble(0.0);
1590 M_LST (s1, REG_PV, a);
1591 M_DLD (d, REG_PV, a);
1593 store_reg_to_var_flt(iptr->dst, d);
1596 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1598 var_to_reg_flt(s1, src, REG_FTMP1);
1599 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1600 a = dseg_adddouble(0.0);
1601 M_CVTDL_C(s1, REG_FTMP2);
1602 M_CVTLI(REG_FTMP2, REG_FTMP3);
1603 M_DST (REG_FTMP3, REG_PV, a);
1604 M_ILD (d, REG_PV, a);
1605 store_reg_to_var_int(iptr->dst, d);
1608 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1610 var_to_reg_flt(s1, src, REG_FTMP1);
1611 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1612 a = dseg_adddouble(0.0);
1613 M_CVTDL_C(s1, REG_FTMP2);
1614 M_DST (REG_FTMP2, REG_PV, a);
1615 M_LLD (d, REG_PV, a);
1616 store_reg_to_var_int(iptr->dst, d);
1619 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1621 var_to_reg_flt(s1, src, REG_FTMP1);
1622 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1625 store_reg_to_var_flt(iptr->dst, d);
1628 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1630 var_to_reg_flt(s1, src, REG_FTMP1);
1631 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1639 store_reg_to_var_flt(iptr->dst, d);
1642 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1644 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1645 var_to_reg_flt(s2, src, REG_FTMP2);
1646 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1648 M_LSUB_IMM(REG_ZERO, 1, d);
1649 M_FCMPEQ(s1, s2, REG_FTMP3);
1650 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1652 M_FCMPLT(s2, s1, REG_FTMP3);
1653 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1654 M_LADD_IMM(REG_ZERO, 1, d);
1657 M_LSUB_IMM(REG_ZERO, 1, d);
1658 M_FCMPEQS(s1, s2, REG_FTMP3);
1660 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1662 M_FCMPLTS(s2, s1, REG_FTMP3);
1664 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1665 M_LADD_IMM(REG_ZERO, 1, d);
1667 store_reg_to_var_int(iptr->dst, d);
1670 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1672 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1673 var_to_reg_flt(s2, src, REG_FTMP2);
1674 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1676 M_LADD_IMM(REG_ZERO, 1, d);
1677 M_FCMPEQ(s1, s2, REG_FTMP3);
1678 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1680 M_FCMPLT(s1, s2, REG_FTMP3);
1681 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1682 M_LSUB_IMM(REG_ZERO, 1, d);
1685 M_LADD_IMM(REG_ZERO, 1, d);
1686 M_FCMPEQS(s1, s2, REG_FTMP3);
1688 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1690 M_FCMPLTS(s1, s2, REG_FTMP3);
1692 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1693 M_LSUB_IMM(REG_ZERO, 1, d);
1695 store_reg_to_var_int(iptr->dst, d);
1699 /* memory operations **************************************************/
1701 #define gen_bound_check \
1702 if (checkbounds) { \
1703 M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\
1704 M_CMPULT(s2, REG_ITMP3, REG_ITMP3);\
1705 M_BEQZ(REG_ITMP3, 0);\
1706 codegen_addxboundrefs(mcodeptr, s2); \
1709 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1711 var_to_reg_int(s1, src, REG_ITMP1);
1712 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1713 gen_nullptr_check(s1);
1714 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1715 store_reg_to_var_int(iptr->dst, d);
1718 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1720 var_to_reg_int(s1, src->prev, REG_ITMP1);
1721 var_to_reg_int(s2, src, REG_ITMP2);
1722 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1723 if (iptr->op1 == 0) {
1724 gen_nullptr_check(s1);
1727 M_SAADDQ(s2, s1, REG_ITMP1);
1728 M_ALD( d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1729 store_reg_to_var_int(iptr->dst, d);
1732 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1734 var_to_reg_int(s1, src->prev, REG_ITMP1);
1735 var_to_reg_int(s2, src, REG_ITMP2);
1736 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1737 if (iptr->op1 == 0) {
1738 gen_nullptr_check(s1);
1741 M_S8ADDQ(s2, s1, REG_ITMP1);
1742 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1743 store_reg_to_var_int(iptr->dst, d);
1746 case ICMD_IALOAD: /* ..., 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);
1756 M_S4ADDQ(s2, s1, REG_ITMP1);
1757 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1758 store_reg_to_var_int(iptr->dst, d);
1761 case ICMD_FALOAD: /* ..., 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_FTMP3);
1766 if (iptr->op1 == 0) {
1767 gen_nullptr_check(s1);
1770 M_S4ADDQ(s2, s1, REG_ITMP1);
1771 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1772 store_reg_to_var_flt(iptr->dst, d);
1775 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1777 var_to_reg_int(s1, src->prev, REG_ITMP1);
1778 var_to_reg_int(s2, src, REG_ITMP2);
1779 d = reg_of_var(m, iptr->dst, REG_FTMP3);
1780 if (iptr->op1 == 0) {
1781 gen_nullptr_check(s1);
1784 M_S8ADDQ(s2, s1, REG_ITMP1);
1785 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1786 store_reg_to_var_flt(iptr->dst, d);
1789 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1791 var_to_reg_int(s1, src->prev, REG_ITMP1);
1792 var_to_reg_int(s2, src, REG_ITMP2);
1793 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1794 if (iptr->op1 == 0) {
1795 gen_nullptr_check(s1);
1798 if (has_ext_instr_set) {
1799 M_LADD(s2, s1, REG_ITMP1);
1800 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1801 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1804 M_LADD (s2, s1, REG_ITMP1);
1805 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1806 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1807 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1808 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
1810 store_reg_to_var_int(iptr->dst, d);
1813 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1815 var_to_reg_int(s1, src->prev, REG_ITMP1);
1816 var_to_reg_int(s2, src, REG_ITMP2);
1817 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1818 if (iptr->op1 == 0) {
1819 gen_nullptr_check(s1);
1822 if (has_ext_instr_set) {
1823 M_LADD(s2, s1, REG_ITMP1);
1824 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1825 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1829 M_LADD(s2, s1, REG_ITMP1);
1830 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1831 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1832 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1833 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1834 M_SRA_IMM(d, 48, d);
1836 store_reg_to_var_int(iptr->dst, d);
1839 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1841 var_to_reg_int(s1, src->prev, REG_ITMP1);
1842 var_to_reg_int(s2, src, REG_ITMP2);
1843 d = reg_of_var(m, iptr->dst, REG_ITMP3);
1844 if (iptr->op1 == 0) {
1845 gen_nullptr_check(s1);
1848 if (has_ext_instr_set) {
1849 M_LADD (s2, s1, REG_ITMP1);
1850 M_BLDU (d, REG_ITMP1, OFFSET (java_bytearray, data[0]));
1854 M_LADD(s2, s1, REG_ITMP1);
1855 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1856 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
1857 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1858 M_SRA_IMM(d, 56, d);
1860 store_reg_to_var_int(iptr->dst, d);
1864 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1866 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1867 var_to_reg_int(s2, src->prev, REG_ITMP2);
1868 if (iptr->op1 == 0) {
1869 gen_nullptr_check(s1);
1872 var_to_reg_int(s3, src, REG_ITMP3);
1873 M_SAADDQ(s2, s1, REG_ITMP1);
1874 M_AST (s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1877 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1879 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1880 var_to_reg_int(s2, src->prev, REG_ITMP2);
1881 if (iptr->op1 == 0) {
1882 gen_nullptr_check(s1);
1885 var_to_reg_int(s3, src, REG_ITMP3);
1886 M_S8ADDQ(s2, s1, REG_ITMP1);
1887 M_LST (s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1890 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1892 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1893 var_to_reg_int(s2, src->prev, REG_ITMP2);
1894 if (iptr->op1 == 0) {
1895 gen_nullptr_check(s1);
1899 var_to_reg_int(s3, src, REG_ITMP3);
1900 M_S4ADDQ(s2, s1, REG_ITMP1);
1901 M_IST (s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1904 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1906 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1907 var_to_reg_int(s2, src->prev, REG_ITMP2);
1908 if (iptr->op1 == 0) {
1909 gen_nullptr_check(s1);
1912 var_to_reg_flt(s3, src, REG_FTMP3);
1913 M_S4ADDQ(s2, s1, REG_ITMP1);
1914 M_FST (s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1917 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1919 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1920 var_to_reg_int(s2, src->prev, REG_ITMP2);
1921 if (iptr->op1 == 0) {
1922 gen_nullptr_check(s1);
1925 var_to_reg_flt(s3, src, REG_FTMP3);
1926 M_S8ADDQ(s2, s1, REG_ITMP1);
1927 M_DST (s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1930 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1932 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1933 var_to_reg_int(s2, src->prev, REG_ITMP2);
1934 if (iptr->op1 == 0) {
1935 gen_nullptr_check(s1);
1938 var_to_reg_int(s3, src, REG_ITMP3);
1939 if (has_ext_instr_set) {
1940 M_LADD(s2, s1, REG_ITMP1);
1941 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1942 M_SST (s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1945 M_LADD (s2, s1, REG_ITMP1);
1946 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1947 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1948 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1949 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1950 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1951 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
1952 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1956 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1958 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1959 var_to_reg_int(s2, src->prev, REG_ITMP2);
1960 if (iptr->op1 == 0) {
1961 gen_nullptr_check(s1);
1964 var_to_reg_int(s3, src, REG_ITMP3);
1965 if (has_ext_instr_set) {
1966 M_LADD(s2, s1, REG_ITMP1);
1967 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1968 M_SST (s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1971 M_LADD (s2, s1, REG_ITMP1);
1972 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1973 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1974 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1975 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1976 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1977 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
1978 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1982 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1984 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1985 var_to_reg_int(s2, src->prev, REG_ITMP2);
1986 if (iptr->op1 == 0) {
1987 gen_nullptr_check(s1);
1990 var_to_reg_int(s3, src, REG_ITMP3);
1991 if (has_ext_instr_set) {
1992 M_LADD(s2, s1, REG_ITMP1);
1993 M_BST (s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1996 M_LADD (s2, s1, REG_ITMP1);
1997 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1998 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1999 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
2000 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2001 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2002 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2007 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
2009 var_to_reg_int(s1, src->prev, REG_ITMP1);
2010 var_to_reg_int(s2, src, REG_ITMP2);
2011 if (iptr->op1 == 0) {
2012 gen_nullptr_check(s1);
2015 M_S4ADDQ(s2, s1, REG_ITMP1);
2016 M_IST(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
2019 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
2021 var_to_reg_int(s1, src->prev, REG_ITMP1);
2022 var_to_reg_int(s2, src, REG_ITMP2);
2023 if (iptr->op1 == 0) {
2024 gen_nullptr_check(s1);
2027 M_S8ADDQ(s2, s1, REG_ITMP1);
2028 M_LST(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
2031 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
2033 var_to_reg_int(s1, src->prev, REG_ITMP1);
2034 var_to_reg_int(s2, src, REG_ITMP2);
2035 if (iptr->op1 == 0) {
2036 gen_nullptr_check(s1);
2039 M_SAADDQ(s2, s1, REG_ITMP1);
2040 M_AST(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
2043 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
2045 var_to_reg_int(s1, src->prev, REG_ITMP1);
2046 var_to_reg_int(s2, src, REG_ITMP2);
2047 if (iptr->op1 == 0) {
2048 gen_nullptr_check(s1);
2051 if (has_ext_instr_set) {
2052 M_LADD(s2, s1, REG_ITMP1);
2053 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2056 M_LADD(s2, s1, REG_ITMP1);
2057 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2058 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2059 M_INSBL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2060 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2061 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2062 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2066 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
2068 var_to_reg_int(s1, src->prev, REG_ITMP1);
2069 var_to_reg_int(s2, src, REG_ITMP2);
2070 if (iptr->op1 == 0) {
2071 gen_nullptr_check(s1);
2074 if (has_ext_instr_set) {
2075 M_LADD(s2, s1, REG_ITMP1);
2076 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2077 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
2080 M_LADD(s2, s1, REG_ITMP1);
2081 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2082 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2083 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2084 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2085 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2086 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2087 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2091 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
2093 var_to_reg_int(s1, src->prev, REG_ITMP1);
2094 var_to_reg_int(s2, src, REG_ITMP2);
2095 if (iptr->op1 == 0) {
2096 gen_nullptr_check(s1);
2099 if (has_ext_instr_set) {
2100 M_LADD(s2, s1, REG_ITMP1);
2101 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2102 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2105 M_LADD(s2, s1, REG_ITMP1);
2106 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2107 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2108 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2109 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2110 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2111 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2112 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2117 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2118 /* op1 = type, val.a = field address */
2120 /* if class isn't yet initialized, do it */
2121 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
2122 /* call helper function which patches this code */
2123 a = dseg_addaddress(((fieldinfo *) iptr->val.a)->class);
2124 M_ALD(REG_ITMP1, REG_PV, a);
2125 a = dseg_addaddress(asm_check_clinit);
2126 M_ALD(REG_PV, REG_PV, a);
2127 M_JSR(REG_RA, REG_PV);
2130 s1 = (int) ((u1*) mcodeptr - mcodebase);
2132 M_LDA(REG_PV, REG_RA, -s1);
2136 s4 ml = -s1, mh = 0;
2137 while (ml < -32768) { ml += 65536; mh--; }
2138 M_LDA(REG_PV, REG_RA, ml);
2139 M_LDAH(REG_PV, REG_PV, mh);
2143 a = dseg_addaddress(&(((fieldinfo *)(iptr->val.a))->value));
2144 M_ALD(REG_ITMP1, REG_PV, a);
2145 switch (iptr->op1) {
2147 var_to_reg_int(s2, src, REG_ITMP2);
2148 M_IST(s2, REG_ITMP1, 0);
2151 var_to_reg_int(s2, src, REG_ITMP2);
2152 M_LST(s2, REG_ITMP1, 0);
2155 var_to_reg_int(s2, src, REG_ITMP2);
2156 M_AST(s2, REG_ITMP1, 0);
2159 var_to_reg_flt(s2, src, REG_FTMP2);
2160 M_FST(s2, REG_ITMP1, 0);
2163 var_to_reg_flt(s2, src, REG_FTMP2);
2164 M_DST(s2, REG_ITMP1, 0);
2166 default: panic ("internal error");
2170 case ICMD_GETSTATIC: /* ... ==> ..., value */
2171 /* op1 = type, val.a = field address */
2173 /* if class isn't yet initialized, do it */
2174 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
2175 /* call helper function which patches this code */
2176 a = dseg_addaddress(((fieldinfo *) iptr->val.a)->class);
2177 M_ALD(REG_ITMP1, REG_PV, a);
2178 a = dseg_addaddress(asm_check_clinit);
2179 M_ALD(REG_PV, REG_PV, a);
2180 M_JSR(REG_RA, REG_PV);
2183 s1 = (int) ((u1*) mcodeptr - mcodebase);
2185 M_LDA(REG_PV, REG_RA, -s1);
2189 s4 ml = -s1, mh = 0;
2190 while (ml < -32768) { ml += 65536; mh--; }
2191 M_LDA(REG_PV, REG_RA, ml);
2192 M_LDAH(REG_PV, REG_PV, mh);
2196 a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value));
2197 M_ALD(REG_ITMP1, REG_PV, a);
2198 switch (iptr->op1) {
2200 d = reg_of_var(m, iptr->dst, REG_ITMP3);
2201 M_ILD(d, REG_ITMP1, 0);
2202 store_reg_to_var_int(iptr->dst, d);
2205 d = reg_of_var(m, iptr->dst, REG_ITMP3);
2206 M_LLD(d, REG_ITMP1, 0);
2207 store_reg_to_var_int(iptr->dst, d);
2210 d = reg_of_var(m, iptr->dst, REG_ITMP3);
2211 M_ALD(d, REG_ITMP1, 0);
2212 store_reg_to_var_int(iptr->dst, d);
2215 d = reg_of_var(m, iptr->dst, REG_FTMP1);
2216 M_FLD(d, REG_ITMP1, 0);
2217 store_reg_to_var_flt(iptr->dst, d);
2220 d = reg_of_var(m, iptr->dst, REG_FTMP1);
2221 M_DLD(d, REG_ITMP1, 0);
2222 store_reg_to_var_flt(iptr->dst, d);
2224 default: panic ("internal error");
2229 case ICMD_PUTFIELD: /* ..., value ==> ... */
2230 /* op1 = type, val.i = field offset */
2232 a = ((fieldinfo *)(iptr->val.a))->offset;
2233 switch (iptr->op1) {
2235 var_to_reg_int(s1, src->prev, REG_ITMP1);
2236 var_to_reg_int(s2, src, REG_ITMP2);
2237 gen_nullptr_check(s1);
2241 var_to_reg_int(s1, src->prev, REG_ITMP1);
2242 var_to_reg_int(s2, src, REG_ITMP2);
2243 gen_nullptr_check(s1);
2247 var_to_reg_int(s1, src->prev, REG_ITMP1);
2248 var_to_reg_int(s2, src, REG_ITMP2);
2249 gen_nullptr_check(s1);
2253 var_to_reg_int(s1, src->prev, REG_ITMP1);
2254 var_to_reg_flt(s2, src, REG_FTMP2);
2255 gen_nullptr_check(s1);
2259 var_to_reg_int(s1, src->prev, REG_ITMP1);
2260 var_to_reg_flt(s2, src, REG_FTMP2);
2261 gen_nullptr_check(s1);
2264 default: panic ("internal error");
2268 case ICMD_GETFIELD: /* ... ==> ..., value */
2269 /* op1 = type, val.i = field offset */
2271 a = ((fieldinfo *)(iptr->val.a))->offset;
2272 switch (iptr->op1) {
2274 var_to_reg_int(s1, src, REG_ITMP1);
2275 d = reg_of_var(m, iptr->dst, REG_ITMP3);
2276 gen_nullptr_check(s1);
2278 store_reg_to_var_int(iptr->dst, d);
2281 var_to_reg_int(s1, src, REG_ITMP1);
2282 d = reg_of_var(m, iptr->dst, REG_ITMP3);
2283 gen_nullptr_check(s1);
2285 store_reg_to_var_int(iptr->dst, d);
2288 var_to_reg_int(s1, src, REG_ITMP1);
2289 d = reg_of_var(m, iptr->dst, REG_ITMP3);
2290 gen_nullptr_check(s1);
2292 store_reg_to_var_int(iptr->dst, d);
2295 var_to_reg_int(s1, src, REG_ITMP1);
2296 d = reg_of_var(m, iptr->dst, REG_FTMP1);
2297 gen_nullptr_check(s1);
2299 store_reg_to_var_flt(iptr->dst, d);
2302 var_to_reg_int(s1, src, REG_ITMP1);
2303 d = reg_of_var(m, iptr->dst, REG_FTMP1);
2304 gen_nullptr_check(s1);
2306 store_reg_to_var_flt(iptr->dst, d);
2308 default: panic ("internal error");
2313 /* branch operations **************************************************/
2315 #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}}
2317 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2319 var_to_reg_int(s1, src, REG_ITMP1);
2320 M_INTMOVE(s1, REG_ITMP1_XPTR);
2321 a = dseg_addaddress(asm_handle_exception);
2322 M_ALD(REG_ITMP2, REG_PV, a);
2323 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2324 M_NOP; /* nop ensures that XPC is less than the end */
2325 /* of basic block */
2329 case ICMD_GOTO: /* ... ==> ... */
2330 /* op1 = target JavaVM pc */
2332 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2336 case ICMD_JSR: /* ... ==> ... */
2337 /* op1 = target JavaVM pc */
2339 M_BSR(REG_ITMP1, 0);
2340 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2343 case ICMD_RET: /* ... ==> ... */
2344 /* op1 = local variable */
2346 var = &(r->locals[iptr->op1][TYPE_ADR]);
2347 if (var->flags & INMEMORY) {
2348 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2349 M_RET(REG_ZERO, REG_ITMP1);
2352 M_RET(REG_ZERO, var->regoff);
2356 case ICMD_IFNULL: /* ..., value ==> ... */
2357 /* op1 = target JavaVM pc */
2359 var_to_reg_int(s1, src, REG_ITMP1);
2361 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2364 case ICMD_IFNONNULL: /* ..., value ==> ... */
2365 /* op1 = target JavaVM pc */
2367 var_to_reg_int(s1, src, REG_ITMP1);
2369 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2372 case ICMD_IFEQ: /* ..., value ==> ... */
2373 /* op1 = target JavaVM pc, val.i = constant */
2375 var_to_reg_int(s1, src, REG_ITMP1);
2376 if (iptr->val.i == 0) {
2380 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2381 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2384 ICONST(REG_ITMP2, iptr->val.i);
2385 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2387 M_BNEZ(REG_ITMP1, 0);
2389 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2392 case ICMD_IFLT: /* ..., value ==> ... */
2393 /* op1 = target JavaVM pc, val.i = constant */
2395 var_to_reg_int(s1, src, REG_ITMP1);
2396 if (iptr->val.i == 0) {
2400 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2401 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2404 ICONST(REG_ITMP2, iptr->val.i);
2405 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2407 M_BNEZ(REG_ITMP1, 0);
2409 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2412 case ICMD_IFLE: /* ..., value ==> ... */
2413 /* op1 = target JavaVM pc, val.i = constant */
2415 var_to_reg_int(s1, src, REG_ITMP1);
2416 if (iptr->val.i == 0) {
2420 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2421 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2424 ICONST(REG_ITMP2, iptr->val.i);
2425 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2427 M_BNEZ(REG_ITMP1, 0);
2429 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2432 case ICMD_IFNE: /* ..., value ==> ... */
2433 /* op1 = target JavaVM pc, val.i = constant */
2435 var_to_reg_int(s1, src, REG_ITMP1);
2436 if (iptr->val.i == 0) {
2440 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2441 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2444 ICONST(REG_ITMP2, iptr->val.i);
2445 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2447 M_BEQZ(REG_ITMP1, 0);
2449 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2452 case ICMD_IFGT: /* ..., value ==> ... */
2453 /* op1 = target JavaVM pc, val.i = constant */
2455 var_to_reg_int(s1, src, REG_ITMP1);
2456 if (iptr->val.i == 0) {
2460 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2461 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2464 ICONST(REG_ITMP2, iptr->val.i);
2465 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2467 M_BEQZ(REG_ITMP1, 0);
2469 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2472 case ICMD_IFGE: /* ..., value ==> ... */
2473 /* op1 = target JavaVM pc, val.i = constant */
2475 var_to_reg_int(s1, src, REG_ITMP1);
2476 if (iptr->val.i == 0) {
2480 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2481 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2484 ICONST(REG_ITMP2, iptr->val.i);
2485 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2487 M_BEQZ(REG_ITMP1, 0);
2489 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2492 case ICMD_IF_LEQ: /* ..., value ==> ... */
2493 /* op1 = target JavaVM pc, val.l = constant */
2495 var_to_reg_int(s1, src, REG_ITMP1);
2496 if (iptr->val.l == 0) {
2500 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2501 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2504 LCONST(REG_ITMP2, iptr->val.l);
2505 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2507 M_BNEZ(REG_ITMP1, 0);
2509 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2512 case ICMD_IF_LLT: /* ..., value ==> ... */
2513 /* op1 = target JavaVM pc, val.l = constant */
2515 var_to_reg_int(s1, src, REG_ITMP1);
2516 if (iptr->val.l == 0) {
2520 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2521 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2524 LCONST(REG_ITMP2, iptr->val.l);
2525 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2527 M_BNEZ(REG_ITMP1, 0);
2529 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2532 case ICMD_IF_LLE: /* ..., value ==> ... */
2533 /* op1 = target JavaVM pc, val.l = constant */
2535 var_to_reg_int(s1, src, REG_ITMP1);
2536 if (iptr->val.l == 0) {
2540 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2541 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2544 LCONST(REG_ITMP2, iptr->val.l);
2545 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2547 M_BNEZ(REG_ITMP1, 0);
2549 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2552 case ICMD_IF_LNE: /* ..., value ==> ... */
2553 /* op1 = target JavaVM pc, val.l = constant */
2555 var_to_reg_int(s1, src, REG_ITMP1);
2556 if (iptr->val.l == 0) {
2560 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2561 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2564 LCONST(REG_ITMP2, iptr->val.l);
2565 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2567 M_BEQZ(REG_ITMP1, 0);
2569 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2572 case ICMD_IF_LGT: /* ..., value ==> ... */
2573 /* op1 = target JavaVM pc, val.l = constant */
2575 var_to_reg_int(s1, src, REG_ITMP1);
2576 if (iptr->val.l == 0) {
2580 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2581 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2584 LCONST(REG_ITMP2, iptr->val.l);
2585 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2587 M_BEQZ(REG_ITMP1, 0);
2589 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2592 case ICMD_IF_LGE: /* ..., value ==> ... */
2593 /* op1 = target JavaVM pc, val.l = constant */
2595 var_to_reg_int(s1, src, REG_ITMP1);
2596 if (iptr->val.l == 0) {
2600 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2601 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2604 LCONST(REG_ITMP2, iptr->val.l);
2605 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2607 M_BEQZ(REG_ITMP1, 0);
2609 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2612 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2613 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2614 case ICMD_IF_ACMPEQ:
2616 var_to_reg_int(s1, src->prev, REG_ITMP1);
2617 var_to_reg_int(s2, src, REG_ITMP2);
2618 M_CMPEQ(s1, s2, REG_ITMP1);
2619 M_BNEZ(REG_ITMP1, 0);
2620 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2623 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2624 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2625 case ICMD_IF_ACMPNE:
2627 var_to_reg_int(s1, src->prev, REG_ITMP1);
2628 var_to_reg_int(s2, src, REG_ITMP2);
2629 M_CMPEQ(s1, s2, REG_ITMP1);
2630 M_BEQZ(REG_ITMP1, 0);
2631 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2634 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2635 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2637 var_to_reg_int(s1, src->prev, REG_ITMP1);
2638 var_to_reg_int(s2, src, REG_ITMP2);
2639 M_CMPLT(s1, s2, REG_ITMP1);
2640 M_BNEZ(REG_ITMP1, 0);
2641 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2644 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2645 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2647 var_to_reg_int(s1, src->prev, REG_ITMP1);
2648 var_to_reg_int(s2, src, REG_ITMP2);
2649 M_CMPLE(s1, s2, REG_ITMP1);
2650 M_BEQZ(REG_ITMP1, 0);
2651 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2654 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2655 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2657 var_to_reg_int(s1, src->prev, REG_ITMP1);
2658 var_to_reg_int(s2, src, REG_ITMP2);
2659 M_CMPLE(s1, s2, REG_ITMP1);
2660 M_BNEZ(REG_ITMP1, 0);
2661 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2664 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2665 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2667 var_to_reg_int(s1, src->prev, REG_ITMP1);
2668 var_to_reg_int(s2, src, REG_ITMP2);
2669 M_CMPLT(s1, s2, REG_ITMP1);
2670 M_BEQZ(REG_ITMP1, 0);
2671 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2674 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2676 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2679 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2680 /* val.i = constant */
2682 var_to_reg_int(s1, src, REG_ITMP1);
2683 d = reg_of_var(m, iptr->dst, REG_ITMP3);
2685 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2686 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2687 M_CMPEQ(s1, REG_ZERO, d);
2688 store_reg_to_var_int(iptr->dst, d);
2691 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2692 M_CMPEQ(s1, REG_ZERO, d);
2694 store_reg_to_var_int(iptr->dst, d);
2698 M_MOV(s1, REG_ITMP1);
2701 ICONST(d, iptr[1].val.i);
2703 if ((s3 >= 0) && (s3 <= 255)) {
2704 M_CMOVEQ_IMM(s1, s3, d);
2707 ICONST(REG_ITMP2, s3);
2708 M_CMOVEQ(s1, REG_ITMP2, d);
2710 store_reg_to_var_int(iptr->dst, d);
2713 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2714 /* val.i = constant */
2716 var_to_reg_int(s1, src, REG_ITMP1);
2717 d = reg_of_var(m, iptr->dst, REG_ITMP3);
2719 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2720 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2721 M_CMPEQ(s1, REG_ZERO, d);
2722 store_reg_to_var_int(iptr->dst, d);
2725 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2726 M_CMPEQ(s1, REG_ZERO, d);
2728 store_reg_to_var_int(iptr->dst, d);
2732 M_MOV(s1, REG_ITMP1);
2735 ICONST(d, iptr[1].val.i);
2737 if ((s3 >= 0) && (s3 <= 255)) {
2738 M_CMOVNE_IMM(s1, s3, d);
2741 ICONST(REG_ITMP2, s3);
2742 M_CMOVNE(s1, REG_ITMP2, d);
2744 store_reg_to_var_int(iptr->dst, d);
2747 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2748 /* val.i = constant */
2750 var_to_reg_int(s1, src, REG_ITMP1);
2751 d = reg_of_var(m, iptr->dst, REG_ITMP3);
2753 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2754 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2755 M_CMPLT(s1, REG_ZERO, d);
2756 store_reg_to_var_int(iptr->dst, d);
2759 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2760 M_CMPLE(REG_ZERO, s1, d);
2761 store_reg_to_var_int(iptr->dst, d);
2765 M_MOV(s1, REG_ITMP1);
2768 ICONST(d, iptr[1].val.i);
2770 if ((s3 >= 0) && (s3 <= 255)) {
2771 M_CMOVLT_IMM(s1, s3, d);
2774 ICONST(REG_ITMP2, s3);
2775 M_CMOVLT(s1, REG_ITMP2, d);
2777 store_reg_to_var_int(iptr->dst, d);
2780 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2781 /* val.i = constant */
2783 var_to_reg_int(s1, src, REG_ITMP1);
2784 d = reg_of_var(m, iptr->dst, REG_ITMP3);
2786 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2787 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2788 M_CMPLE(REG_ZERO, s1, d);
2789 store_reg_to_var_int(iptr->dst, d);
2792 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2793 M_CMPLT(s1, REG_ZERO, d);
2794 store_reg_to_var_int(iptr->dst, d);
2798 M_MOV(s1, REG_ITMP1);
2801 ICONST(d, iptr[1].val.i);
2803 if ((s3 >= 0) && (s3 <= 255)) {
2804 M_CMOVGE_IMM(s1, s3, d);
2807 ICONST(REG_ITMP2, s3);
2808 M_CMOVGE(s1, REG_ITMP2, d);
2810 store_reg_to_var_int(iptr->dst, d);
2813 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2814 /* val.i = constant */
2816 var_to_reg_int(s1, src, REG_ITMP1);
2817 d = reg_of_var(m, iptr->dst, REG_ITMP3);
2819 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2820 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2821 M_CMPLT(REG_ZERO, s1, d);
2822 store_reg_to_var_int(iptr->dst, d);
2825 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2826 M_CMPLE(s1, REG_ZERO, d);
2827 store_reg_to_var_int(iptr->dst, d);
2831 M_MOV(s1, REG_ITMP1);
2834 ICONST(d, iptr[1].val.i);
2836 if ((s3 >= 0) && (s3 <= 255)) {
2837 M_CMOVGT_IMM(s1, s3, d);
2840 ICONST(REG_ITMP2, s3);
2841 M_CMOVGT(s1, REG_ITMP2, d);
2843 store_reg_to_var_int(iptr->dst, d);
2846 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2847 /* val.i = constant */
2849 var_to_reg_int(s1, src, REG_ITMP1);
2850 d = reg_of_var(m, iptr->dst, REG_ITMP3);
2852 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2853 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2854 M_CMPLE(s1, REG_ZERO, d);
2855 store_reg_to_var_int(iptr->dst, d);
2858 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2859 M_CMPLT(REG_ZERO, s1, d);
2860 store_reg_to_var_int(iptr->dst, d);
2864 M_MOV(s1, REG_ITMP1);
2867 ICONST(d, iptr[1].val.i);
2869 if ((s3 >= 0) && (s3 <= 255)) {
2870 M_CMOVLE_IMM(s1, s3, d);
2873 ICONST(REG_ITMP2, s3);
2874 M_CMOVLE(s1, REG_ITMP2, d);
2876 store_reg_to_var_int(iptr->dst, d);
2880 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2884 var_to_reg_int(s1, src, REG_RESULT);
2885 M_INTMOVE(s1, REG_RESULT);
2887 #if defined(USE_THREADS)
2888 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2890 a = dseg_addaddress((void *) (builtin_monitorexit));
2891 M_ALD(REG_PV, REG_PV, a);
2892 M_ALD(r->argintregs[0], REG_SP, r->maxmemuse * 8);
2893 M_LST(REG_RESULT, REG_SP, r->maxmemuse * 8);
2894 M_JSR(REG_RA, REG_PV);
2895 disp = -(s4) ((u1 *) mcodeptr - mcodebase);
2896 M_LDA(REG_PV, REG_RA, disp);
2897 M_LLD(REG_RESULT, REG_SP, r->maxmemuse * 8);
2901 goto nowperformreturn;
2903 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2906 var_to_reg_flt(s1, src, REG_FRESULT);
2907 M_FLTMOVE(s1, REG_FRESULT);
2909 #if defined(USE_THREADS)
2910 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2912 a = dseg_addaddress((void *) (builtin_monitorexit));
2913 M_ALD(REG_PV, REG_PV, a);
2914 M_ALD(r->argintregs[0], REG_SP, r->maxmemuse * 8);
2915 M_DST(REG_FRESULT, REG_SP, r->maxmemuse * 8);
2916 M_JSR(REG_RA, REG_PV);
2917 disp = -(s4) ((u1 *) mcodeptr - mcodebase);
2918 M_LDA(REG_PV, REG_RA, disp);
2919 M_DLD(REG_FRESULT, REG_SP, r->maxmemuse * 8);
2923 goto nowperformreturn;
2925 case ICMD_RETURN: /* ... ==> ... */
2927 #if defined(USE_THREADS)
2928 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2930 a = dseg_addaddress((void *) (builtin_monitorexit));
2931 M_ALD(REG_PV, REG_PV, a);
2932 M_ALD(r->argintregs[0], REG_SP, r->maxmemuse * 8);
2933 M_JSR(REG_RA, REG_PV);
2934 disp = -(s4) ((u1 *) mcodeptr - mcodebase);
2935 M_LDA(REG_PV, REG_RA, disp);
2943 p = parentargs_base;
2945 /* restore return address */
2947 if (!m->isleafmethod) {
2948 p--; M_LLD(REG_RA, REG_SP, p * 8);
2951 /* restore saved registers */
2953 for (i = r->savintregcnt - 1; i >= r->maxsavintreguse; i--) {
2954 p--; M_LLD(r->savintregs[i], REG_SP, p * 8);
2956 for (i = r->savfltregcnt - 1; i >= r->maxsavfltreguse; i--) {
2957 p--; M_DLD(r->savfltregs[i], REG_SP, p * 8);
2960 /* deallocate stack */
2962 if (parentargs_base) {
2963 M_LDA(REG_SP, REG_SP, parentargs_base * 8);
2966 /* call trace function */
2969 M_LDA(REG_SP, REG_SP, -3 * 8);
2970 M_AST(REG_RA, REG_SP, 0 * 8);
2971 M_LST(REG_RESULT, REG_SP, 1 * 8);
2972 M_DST(REG_FRESULT, REG_SP, 2 * 8);
2973 a = dseg_addaddress(m);
2974 M_ALD(r->argintregs[0], REG_PV, a);
2975 M_MOV(REG_RESULT, r->argintregs[1]);
2976 M_FLTMOVE(REG_FRESULT, r->argfltregs[2]);
2977 M_FLTMOVE(REG_FRESULT, r->argfltregs[3]);
2978 a = dseg_addaddress((void *) builtin_displaymethodstop);
2979 M_ALD(REG_PV, REG_PV, a);
2980 M_JSR(REG_RA, REG_PV);
2981 s1 = (s4) ((u1 *) mcodeptr - mcodebase);
2982 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
2984 s4 ml = -s1, mh = 0;
2985 while (ml < -32768) { ml += 65536; mh--; }
2986 M_LDA(REG_PV, REG_RA, ml);
2987 M_LDAH(REG_PV, REG_PV, mh);
2989 M_DLD(REG_FRESULT, REG_SP, 2 * 8);
2990 M_LLD(REG_RESULT, REG_SP, 1 * 8);
2991 M_ALD(REG_RA, REG_SP, 0 * 8);
2992 M_LDA(REG_SP, REG_SP, 3 * 8);
2995 M_RET(REG_ZERO, REG_RA);
3001 case ICMD_TABLESWITCH: /* ..., index ==> ... */
3006 tptr = (void **) iptr->target;
3008 s4ptr = iptr->val.a;
3009 l = s4ptr[1]; /* low */
3010 i = s4ptr[2]; /* high */
3012 var_to_reg_int(s1, src, REG_ITMP1);
3014 {M_INTMOVE(s1, REG_ITMP1);}
3015 else if (l <= 32768) {
3016 M_LDA(REG_ITMP1, s1, -l);
3019 ICONST(REG_ITMP2, l);
3020 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
3027 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
3029 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
3030 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3032 M_BEQZ(REG_ITMP2, 0);
3035 /* codegen_addreference(BlockPtrOfPC(s4ptr[0]), mcodeptr); */
3036 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3038 /* build jump table top down and use address of lowest entry */
3040 /* s4ptr += 3 + i; */
3044 /* dseg_addtarget(BlockPtrOfPC(*--s4ptr)); */
3045 dseg_addtarget((basicblock *) tptr[0]);
3050 /* length of dataseg after last dseg_addtarget is used by load */
3052 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
3053 M_ALD(REG_ITMP2, REG_ITMP2, -dseglen);
3054 M_JMP(REG_ZERO, REG_ITMP2);
3059 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3061 s4 i, l, val, *s4ptr;
3064 tptr = (void **) iptr->target;
3066 s4ptr = iptr->val.a;
3067 l = s4ptr[0]; /* default */
3068 i = s4ptr[1]; /* count */
3070 MCODECHECK((i<<2)+8);
3071 var_to_reg_int(s1, src, REG_ITMP1);
3077 if ((val >= 0) && (val <= 255)) {
3078 M_CMPEQ_IMM(s1, val, REG_ITMP2);
3081 if ((val >= -32768) && (val <= 32767)) {
3082 M_LDA(REG_ITMP2, REG_ZERO, val);
3085 a = dseg_adds4 (val);
3086 M_ILD(REG_ITMP2, REG_PV, a);
3088 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
3090 M_BNEZ(REG_ITMP2, 0);
3091 /* codegen_addreference(BlockPtrOfPC(s4ptr[1]), mcodeptr); */
3092 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3096 /* codegen_addreference(BlockPtrOfPC(l), mcodeptr); */
3098 tptr = (void **) iptr->target;
3099 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3106 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
3107 /* op1 = return type, val.a = function pointer*/
3111 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
3112 /* op1 = return type, val.a = function pointer*/
3116 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
3117 /* op1 = return type, val.a = function pointer*/
3121 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3122 /* op1 = arg count, val.a = method pointer */
3124 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3125 /* op1 = arg count, val.a = method pointer */
3127 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3128 /* op1 = arg count, val.a = method pointer */
3130 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
3131 /* op1 = arg count, val.a = method pointer */
3138 MCODECHECK((s3 << 1) + 64);
3140 /* copy arguments to registers or stack location */
3142 for (; --s3 >= 0; src = src->prev) {
3143 if (src->varkind == ARGVAR)
3145 if (IS_INT_LNG_TYPE(src->type)) {
3146 if (s3 < INT_ARG_CNT) {
3147 s1 = r->argintregs[s3];
3148 var_to_reg_int(d, src, s1);
3152 var_to_reg_int(d, src, REG_ITMP1);
3153 M_LST(d, REG_SP, 8 * (s3 - INT_ARG_CNT));
3157 if (s3 < FLT_ARG_CNT) {
3158 s1 = r->argfltregs[s3];
3159 var_to_reg_flt(d, src, s1);
3163 var_to_reg_flt(d, src, REG_FTMP1);
3164 M_DST(d, REG_SP, 8 * (s3 - FLT_ARG_CNT));
3170 switch (iptr->opc) {
3174 a = dseg_addaddress((void *) lm);
3177 M_ALD(REG_PV, REG_PV, a); /* Pointer to built-in-function */
3180 case ICMD_INVOKESTATIC:
3181 case ICMD_INVOKESPECIAL:
3182 a = dseg_addaddress(lm->stubroutine);
3185 M_ALD(REG_PV, REG_PV, a); /* method pointer in r27 */
3188 case ICMD_INVOKEVIRTUAL:
3191 gen_nullptr_check(r->argintregs[0]);
3192 M_ALD(REG_METHODPTR, r->argintregs[0],
3193 OFFSET(java_objectheader, vftbl));
3194 M_ALD(REG_PV, REG_METHODPTR, OFFSET(vftbl_t, table[0]) +
3195 sizeof(methodptr) * lm->vftblindex);
3198 case ICMD_INVOKEINTERFACE:
3201 gen_nullptr_check(r->argintregs[0]);
3202 M_ALD(REG_METHODPTR, r->argintregs[0],
3203 OFFSET(java_objectheader, vftbl));
3204 M_ALD(REG_METHODPTR, REG_METHODPTR,
3205 OFFSET(vftbl_t, interfacetable[0]) -
3206 sizeof(methodptr*) * lm->class->index);
3207 M_ALD(REG_PV, REG_METHODPTR,
3208 sizeof(methodptr) * (lm - lm->class->methods));
3212 M_JSR(REG_RA, REG_PV);
3216 s1 = (s4) ((u1 *) mcodeptr - mcodebase);
3217 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3219 s4 ml = -s1, mh = 0;
3220 while (ml < -32768) { ml += 65536; mh--; }
3221 M_LDA(REG_PV, REG_RA, ml);
3222 M_LDAH(REG_PV, REG_PV, mh);
3225 /* d contains return type */
3227 if (d != TYPE_VOID) {
3228 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3229 s1 = reg_of_var(m, iptr->dst, REG_RESULT);
3230 M_INTMOVE(REG_RESULT, s1);
3231 store_reg_to_var_int(iptr->dst, s1);
3234 s1 = reg_of_var(m, iptr->dst, REG_FRESULT);
3235 M_FLTMOVE(REG_FRESULT, s1);
3236 store_reg_to_var_flt(iptr->dst, s1);
3243 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3245 /* op1: 0 == array, 1 == class */
3246 /* val.a: (classinfo*) superclass */
3248 /* superclass is an interface:
3250 * return (sub != NULL) &&
3251 * (sub->vftbl->interfacetablelength > super->index) &&
3252 * (sub->vftbl->interfacetable[-super->index] != NULL);
3254 * superclass is a class:
3256 * return ((sub != NULL) && (0
3257 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3258 * super->vftbl->diffvall));
3262 classinfo *super = (classinfo*) iptr->val.a;
3264 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3265 codegen_threadcritrestart((u1*) mcodeptr - mcodebase);
3267 var_to_reg_int(s1, src, REG_ITMP1);
3268 d = reg_of_var(m, iptr->dst, REG_ITMP3);
3270 M_MOV(s1, REG_ITMP1);
3274 if (iptr->op1) { /* class/interface */
3275 if (super->flags & ACC_INTERFACE) { /* interface */
3277 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3278 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3279 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3280 M_BLEZ(REG_ITMP2, 2);
3281 M_ALD(REG_ITMP1, REG_ITMP1,
3282 OFFSET(vftbl_t, interfacetable[0]) -
3283 super->index * sizeof(methodptr*));
3284 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3288 s2 = super->vftbl->diffval;
3289 M_BEQZ(s1, 4 + (s2 > 255));
3290 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3291 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3292 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3294 M_CMPULE_IMM(REG_ITMP1, s2, d);
3296 M_LDA(REG_ITMP2, REG_ZERO, s2);
3297 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3301 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3302 a = dseg_addaddress ((void*) super->vftbl);
3303 M_ALD(REG_ITMP2, REG_PV, a);
3304 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3305 codegen_threadcritstart((u1*) mcodeptr - mcodebase);
3307 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3308 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3309 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3310 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3311 codegen_threadcritstop((u1*) mcodeptr - mcodebase);
3313 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3314 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3318 panic ("internal error: no inlined array instanceof");
3320 store_reg_to_var_int(iptr->dst, d);
3323 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3325 /* op1: 0 == array, 1 == class */
3326 /* val.a: (classinfo*) superclass */
3328 /* superclass is an interface:
3330 * OK if ((sub == NULL) ||
3331 * (sub->vftbl->interfacetablelength > super->index) &&
3332 * (sub->vftbl->interfacetable[-super->index] != NULL));
3334 * superclass is a class:
3336 * OK if ((sub == NULL) || (0
3337 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3338 * super->vftbl->diffvall));
3342 classinfo *super = (classinfo*) iptr->val.a;
3344 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3345 codegen_threadcritrestart((u1*) mcodeptr - mcodebase);
3347 d = reg_of_var(m, iptr->dst, REG_ITMP3);
3348 var_to_reg_int(s1, src, d);
3349 if (iptr->op1) { /* class/interface */
3350 if (super->flags & ACC_INTERFACE) { /* interface */
3352 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3353 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3354 M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3355 M_BLEZ(REG_ITMP2, 0);
3356 codegen_addxcastrefs(mcodeptr);
3357 M_ALD(REG_ITMP2, REG_ITMP1,
3358 OFFSET(vftbl_t, interfacetable[0]) -
3359 super->index * sizeof(methodptr*));
3360 M_BEQZ(REG_ITMP2, 0);
3361 codegen_addxcastrefs(mcodeptr);
3365 s2 = super->vftbl->diffval;
3366 M_BEQZ(s1, 4 + (s2 != 0) + (s2 > 255));
3367 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3368 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3369 M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3371 M_BNEZ(REG_ITMP1, 0);
3373 else if (s2 <= 255) {
3374 M_CMPULE_IMM(REG_ITMP1, s2, REG_ITMP2);
3375 M_BEQZ(REG_ITMP2, 0);
3378 M_LDA(REG_ITMP2, REG_ZERO, s2);
3379 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3380 M_BEQZ(REG_ITMP2, 0);
3383 M_BEQZ(s1, 8 + (d == REG_ITMP3));
3384 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3385 a = dseg_addaddress ((void*) super->vftbl);
3386 M_ALD(REG_ITMP2, REG_PV, a);
3387 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3388 codegen_threadcritstart((u1*) mcodeptr - mcodebase);
3390 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3391 if (d != REG_ITMP3) {
3392 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3393 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3394 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3395 codegen_threadcritstop((u1*) mcodeptr - mcodebase);
3397 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3400 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3401 M_ISUB(REG_ITMP1, REG_ITMP2, REG_ITMP1);
3402 M_ALD(REG_ITMP2, REG_PV, a);
3403 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3404 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3405 codegen_threadcritstop((u1*) mcodeptr - mcodebase);
3408 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3409 M_BEQZ(REG_ITMP2, 0);
3410 codegen_addxcastrefs(mcodeptr);
3414 panic ("internal error: no inlined array checkcast");
3417 store_reg_to_var_int(iptr->dst, d);
3420 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
3422 var_to_reg_int(s1, src, REG_ITMP1);
3424 codegen_addxcheckarefs(mcodeptr);
3427 case ICMD_CHECKEXCEPTION: /* ... ==> ... */
3429 M_BEQZ(REG_RESULT, 0);
3430 codegen_addxexceptionrefs(mcodeptr);
3433 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3434 /* op1 = dimension, val.a = array descriptor */
3436 /* check for negative sizes and copy sizes to stack if necessary */
3438 MCODECHECK((iptr->op1 << 1) + 64);
3440 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3441 var_to_reg_int(s2, src, REG_ITMP1);
3443 codegen_addxcheckarefs(mcodeptr);
3445 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
3447 if (src->varkind != ARGVAR) {
3448 M_LST(s2, REG_SP, 8 * (s1 + INT_ARG_CNT));
3452 /* a0 = dimension count */
3454 ICONST(r->argintregs[0], iptr->op1);
3456 /* a1 = arraydescriptor */
3458 a = dseg_addaddress(iptr->val.a);
3459 M_ALD(r->argintregs[1], REG_PV, a);
3461 /* a2 = pointer to dimensions = stack pointer */
3463 M_INTMOVE(REG_SP, r->argintregs[2]);
3465 a = dseg_addaddress((void *) builtin_nmultianewarray);
3466 M_ALD(REG_PV, REG_PV, a);
3467 M_JSR(REG_RA, REG_PV);
3468 s1 = (s4) ((u1 *) mcodeptr - mcodebase);
3470 M_LDA(REG_PV, REG_RA, -s1);
3472 s4 ml = -s1, mh = 0;
3473 while (ml < -32768) { ml += 65536; mh--; }
3474 M_LDA(REG_PV, REG_RA, ml);
3475 M_LDAH(REG_PV, REG_PV, mh);
3477 s1 = reg_of_var(m, iptr->dst, REG_RESULT);
3478 M_INTMOVE(REG_RESULT, s1);
3479 store_reg_to_var_int(iptr->dst, s1);
3483 default: error ("Unknown pseudo command: %d", iptr->opc);
3489 } /* for instruction */
3491 /* copy values to interface registers */
3493 src = bptr->outstack;
3494 len = bptr->outdepth;
3498 if ((src->varkind != STACKVAR)) {
3500 if (IS_FLT_DBL_TYPE(s2)) {
3501 var_to_reg_flt(s1, src, REG_FTMP1);
3502 if (!(r->interfaces[len][s2].flags & INMEMORY)) {
3503 M_FLTMOVE(s1,r->interfaces[len][s2].regoff);
3506 M_DST(s1, REG_SP, 8 * r->interfaces[len][s2].regoff);
3510 var_to_reg_int(s1, src, REG_ITMP1);
3511 if (!(r->interfaces[len][s2].flags & INMEMORY)) {
3512 M_INTMOVE(s1,r->interfaces[len][s2].regoff);
3515 M_LST(s1, REG_SP, 8 * r->interfaces[len][s2].regoff);
3521 } /* if (bptr -> flags >= BBREACHED) */
3522 } /* for basic block */
3524 /* bptr -> mpc = (int)((u1*) mcodeptr - mcodebase); */
3527 /* generate bound check stubs */
3529 s4 *xcodeptr = NULL;
3531 for (; xboundrefs != NULL; xboundrefs = xboundrefs->next) {
3532 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
3533 xboundrefs->branchpos,
3534 (u1*) mcodeptr - mcodebase);
3538 /* move index register into REG_ITMP1 */
3539 M_MOV(xboundrefs->reg, REG_ITMP1);
3540 M_LDA(REG_ITMP2_XPC, REG_PV, xboundrefs->branchpos - 4);
3542 if (xcodeptr != NULL) {
3543 M_BR(xcodeptr - mcodeptr - 1);
3546 xcodeptr = mcodeptr;
3548 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3549 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3551 a = dseg_addaddress(string_java_lang_ArrayIndexOutOfBoundsException);
3552 M_ALD(r->argintregs[0], REG_PV, a);
3553 M_MOV(REG_ITMP1, r->argintregs[1]);
3555 a = dseg_addaddress(new_exception_int);
3556 M_ALD(REG_PV, REG_PV, a);
3557 M_JSR(REG_RA, REG_PV);
3560 s1 = (s4) ((u1 *) mcodeptr - mcodebase);
3561 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3563 s4 ml = -s1, mh = 0;
3564 while (ml < -32768) { ml += 65536; mh--; }
3565 M_LDA(REG_PV, REG_RA, ml);
3566 M_LDAH(REG_PV, REG_PV, mh);
3569 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3571 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3572 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3574 a = dseg_addaddress(asm_handle_exception);
3575 M_ALD(REG_ITMP3, REG_PV, a);
3577 M_JMP(REG_ZERO, REG_ITMP3);
3581 /* generate negative array size check stubs */
3585 for (; xcheckarefs != NULL; xcheckarefs = xcheckarefs->next) {
3586 if ((m->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3587 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3588 xcheckarefs->branchpos,
3589 (u1*) xcodeptr - (u1*) mcodebase - 4);
3593 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
3594 xcheckarefs->branchpos,
3595 (u1*) mcodeptr - mcodebase);
3599 M_LDA(REG_ITMP2_XPC, REG_PV, xcheckarefs->branchpos - 4);
3601 if (xcodeptr != NULL) {
3602 M_BR(xcodeptr - mcodeptr - 1);
3605 xcodeptr = mcodeptr;
3607 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3608 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3610 a = dseg_addaddress(string_java_lang_NegativeArraySizeException);
3611 M_ALD(r->argintregs[0], REG_PV, a);
3613 a = dseg_addaddress(new_exception);
3614 M_ALD(REG_PV, REG_PV, a);
3615 M_JSR(REG_RA, REG_PV);
3618 s1 = (s4) ((u1 *) mcodeptr - mcodebase);
3619 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3621 s4 ml = -s1, mh = 0;
3622 while (ml < -32768) { ml += 65536; mh--; }
3623 M_LDA(REG_PV, REG_RA, ml);
3624 M_LDAH(REG_PV, REG_PV, mh);
3627 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3629 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3630 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3632 a = dseg_addaddress(asm_handle_exception);
3633 M_ALD(REG_ITMP3, REG_PV, a);
3635 M_JMP(REG_ZERO, REG_ITMP3);
3639 /* generate cast check stubs */
3643 for (; xcastrefs != NULL; xcastrefs = xcastrefs->next) {
3644 if ((m->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3645 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3646 xcastrefs->branchpos,
3647 (u1*) xcodeptr - (u1*) mcodebase - 4);
3651 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
3652 xcastrefs->branchpos,
3653 (u1*) mcodeptr - mcodebase);
3657 M_LDA(REG_ITMP2_XPC, REG_PV, xcastrefs->branchpos - 4);
3659 if (xcodeptr != NULL) {
3660 M_BR(xcodeptr - mcodeptr - 1);
3663 xcodeptr = mcodeptr;
3665 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3666 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3668 a = dseg_addaddress(string_java_lang_ClassCastException);
3669 M_ALD(r->argintregs[0], REG_PV, a);
3671 a = dseg_addaddress(new_exception);
3672 M_ALD(REG_PV, REG_PV, a);
3673 M_JSR(REG_RA, REG_PV);
3676 s1 = (s4) ((u1 *) mcodeptr - mcodebase);
3677 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3679 s4 ml = -s1, mh = 0;
3680 while (ml < -32768) { ml += 65536; mh--; }
3681 M_LDA(REG_PV, REG_RA, ml);
3682 M_LDAH(REG_PV, REG_PV, mh);
3685 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3687 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3688 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3690 a = dseg_addaddress(asm_handle_exception);
3691 M_ALD(REG_ITMP3, REG_PV, a);
3693 M_JMP(REG_ZERO, REG_ITMP3);
3697 /* generate exception check stubs */
3701 for (; xexceptionrefs != NULL; xexceptionrefs = xexceptionrefs->next) {
3702 if ((m->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3703 gen_resolvebranch((u1*) mcodebase + xexceptionrefs->branchpos,
3704 xexceptionrefs->branchpos,
3705 (u1*) xcodeptr - (u1*) mcodebase - 4);
3709 gen_resolvebranch((u1*) mcodebase + xexceptionrefs->branchpos,
3710 xexceptionrefs->branchpos,
3711 (u1*) mcodeptr - mcodebase);
3715 M_LDA(REG_ITMP2_XPC, REG_PV, xexceptionrefs->branchpos - 4);
3717 if (xcodeptr != NULL) {
3718 M_BR(xcodeptr - mcodeptr - 1);
3721 xcodeptr = mcodeptr;
3723 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3724 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3725 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3727 a = dseg_addaddress(&builtin_get_exceptionptrptr);
3728 M_ALD(REG_PV, REG_PV, a);
3729 M_JSR(REG_RA, REG_PV);
3732 s1 = (s4) ((u1 *) mcodeptr - mcodebase);
3733 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3735 s4 ml = -s1, mh = 0;
3736 while (ml < -32768) { ml += 65536; mh--; }
3737 M_LDA(REG_PV, REG_RA, ml);
3738 M_LDAH(REG_PV, REG_PV, mh);
3741 M_ALD(REG_ITMP1_XPTR, REG_RESULT, 0);
3742 M_AST(REG_ZERO, REG_RESULT, 0);
3744 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3745 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3747 a = dseg_addaddress(&_exceptionptr);
3748 M_ALD(REG_ITMP3, REG_PV, a);
3749 M_ALD(REG_ITMP1_XPTR, REG_ITMP3, 0);
3750 M_AST(REG_ZERO, REG_ITMP3, 0);
3753 a = dseg_addaddress(asm_handle_exception);
3754 M_ALD(REG_ITMP3, REG_PV, a);
3756 M_JMP(REG_ZERO, REG_ITMP3);
3760 /* generate null pointer check stubs */
3764 for (; xnullrefs != NULL; xnullrefs = xnullrefs->next) {
3765 if ((m->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3766 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3767 xnullrefs->branchpos,
3768 (u1*) xcodeptr - (u1*) mcodebase - 4);
3772 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
3773 xnullrefs->branchpos,
3774 (u1*) mcodeptr - mcodebase);
3778 M_LDA(REG_ITMP2_XPC, REG_PV, xnullrefs->branchpos - 4);
3780 if (xcodeptr != NULL) {
3781 M_BR(xcodeptr - mcodeptr - 1);
3784 xcodeptr = mcodeptr;
3786 M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
3787 M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3789 a = dseg_addaddress(string_java_lang_NullPointerException);
3790 M_ALD(r->argintregs[0], REG_PV, a);
3792 a = dseg_addaddress(new_exception);
3793 M_ALD(REG_PV, REG_PV, a);
3794 M_JSR(REG_RA, REG_PV);
3797 s1 = (s4) ((u1 *) mcodeptr - mcodebase);
3798 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3800 s4 ml = -s1, mh = 0;
3801 while (ml < -32768) { ml += 65536; mh--; }
3802 M_LDA(REG_PV, REG_RA, ml);
3803 M_LDAH(REG_PV, REG_PV, mh);
3806 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3808 M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3809 M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
3811 a = dseg_addaddress(asm_handle_exception);
3812 M_ALD(REG_ITMP3, REG_PV, a);
3814 M_JMP(REG_ZERO, REG_ITMP3);
3819 codegen_finish(m, (s4) ((u1 *) mcodeptr - mcodebase));
3823 /* function createcompilerstub *************************************************
3825 creates a stub routine which calls the compiler
3827 *******************************************************************************/
3829 #define COMPSTUBSIZE 3
3831 u1 *createcompilerstub(methodinfo *m)
3833 u8 *s = CNEW(u8, COMPSTUBSIZE); /* memory to hold the stub */
3834 s4 *mcodeptr = (s4 *) s; /* code generation pointer */
3836 /* code for the stub */
3837 M_ALD(REG_PV, REG_PV, 16); /* load pointer to the compiler */
3838 M_JMP(0, REG_PV); /* jump to the compiler, return address
3839 in reg 0 is used as method pointer */
3840 s[1] = (u8) m; /* literals to be adressed */
3841 s[2] = (u8) asm_call_jit_compiler; /* jump directly via PV from above */
3843 #if defined(STATISTICS)
3845 count_cstub_len += COMPSTUBSIZE * 8;
3852 /* function removecompilerstub *************************************************
3854 deletes a compilerstub from memory (simply by freeing it)
3856 *******************************************************************************/
3858 void removecompilerstub(u1 *stub)
3860 CFREE(stub, COMPSTUBSIZE * 8);
3864 /* function: createnativestub **************************************************
3866 creates a stub routine which calls a native method
3868 *******************************************************************************/
3870 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3871 #define NATIVESTUBSTACK 2
3872 #define NATIVESTUBTHREADEXTRA 6
3874 #define NATIVESTUBSTACK 1
3875 #define NATIVESTUBTHREADEXTRA 1
3878 #define NATIVESTUBSIZE (44 + NATIVESTUBTHREADEXTRA - 1)
3879 #define NATIVESTATICSIZE 5
3880 #define NATIVEVERBOSESIZE (39 + 13)
3881 #define NATIVESTUBOFFSET 9
3883 u1 *createnativestub(functionptr f, methodinfo *m)
3885 u8 *s; /* memory pointer to hold the stub */
3887 s4 *mcodeptr; /* code generation pointer */
3888 s4 stackframesize = 0; /* size of stackframe if needed */
3893 /* keep code size smaller */
3895 r = m->registerdata;
3897 descriptor2types(m); /* set paramcount and paramtypes */
3899 stubsize = NATIVESTUBSIZE; /* calculate nativestub size */
3900 if ((m->flags & ACC_STATIC) && !m->class->initialized)
3901 stubsize += NATIVESTATICSIZE;
3904 stubsize += NATIVEVERBOSESIZE;
3906 s = CNEW(u8, stubsize); /* memory to hold the stub */
3907 cs = s + NATIVESTUBOFFSET;
3908 mcodeptr = (s4 *) (cs); /* code generation pointer */
3910 *(cs-1) = (u8) f; /* address of native method */
3911 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3912 *(cs-2) = (u8) &builtin_get_exceptionptrptr;
3914 *(cs-2) = (u8) (&_exceptionptr); /* address of exceptionptr */
3916 *(cs-3) = (u8) asm_handle_nat_exception; /* addr of asm exception handler */
3917 *(cs-4) = (u8) (&env); /* addr of jni_environement */
3918 *(cs-5) = (u8) builtin_trace_args;
3920 *(cs-7) = (u8) builtin_displaymethodstop;
3921 *(cs-8) = (u8) m->class;
3922 *(cs-9) = (u8) asm_check_clinit;
3924 M_LDA(REG_SP, REG_SP, -NATIVESTUBSTACK * 8); /* build up stackframe */
3925 M_AST(REG_RA, REG_SP, 0 * 8); /* store return address */
3927 /* if function is static, check for initialized */
3929 if (m->flags & ACC_STATIC) {
3930 /* if class isn't yet initialized, do it */
3931 if (!m->class->initialized) {
3932 /* call helper function which patches this code */
3933 M_ALD(REG_ITMP1, REG_PV, -8 * 8); /* class */
3934 M_ALD(REG_PV, REG_PV, -9 * 8); /* asm_check_clinit */
3935 M_JSR(REG_RA, REG_PV);
3936 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
3937 M_LDA(REG_PV, REG_RA, disp);
3938 M_NOP; /* this is essential for code patching */
3942 /* max. 39 instructions */
3946 M_LDA(REG_SP, REG_SP, -((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
3947 M_AST(REG_RA, REG_SP, 1 * 8);
3949 /* save integer argument registers */
3950 for (p = 0; p < m->paramcount && p < INT_ARG_CNT; p++) {
3951 M_LST(r->argintregs[p], REG_SP, (2 + p) * 8);
3954 /* save and copy float arguments into integer registers */
3955 for (p = 0; p < m->paramcount && p < FLT_ARG_CNT; p++) {
3956 t = m->paramtypes[p];
3958 if (IS_FLT_DBL_TYPE(t)) {
3959 if (IS_2_WORD_TYPE(t)) {
3960 M_DST(r->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
3961 M_LLD(r->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
3964 M_FST(r->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
3965 M_ILD(r->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
3969 M_DST(r->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
3973 M_ALD(REG_ITMP1, REG_PV, -6 * 8);
3974 M_AST(REG_ITMP1, REG_SP, 0 * 8);
3975 M_ALD(REG_PV, REG_PV, -5 * 8);
3976 M_JSR(REG_RA, REG_PV);
3977 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
3978 M_LDA(REG_PV, REG_RA, disp);
3980 for (p = 0; p < m->paramcount && p < INT_ARG_CNT; p++) {
3981 M_LLD(r->argintregs[p], REG_SP, (2 + p) * 8);
3984 for (p = 0; p < m->paramcount && p < FLT_ARG_CNT; p++) {
3985 t = m->paramtypes[p];
3987 if (IS_FLT_DBL_TYPE(t)) {
3988 if (IS_2_WORD_TYPE(t)) {
3989 M_DLD(r->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
3992 M_FLD(r->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
3996 M_DLD(r->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
4000 M_ALD(REG_RA, REG_SP, 1 * 8);
4001 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT + 2) * 8);
4004 /* save argument registers on stack -- if we have to */
4005 if ((m->flags & ACC_STATIC && m->paramcount > (INT_ARG_CNT - 2)) || m->paramcount > (INT_ARG_CNT - 1)) {
4007 s4 paramshiftcnt = (m->flags & ACC_STATIC) ? 2 : 1;
4008 s4 stackparamcnt = (m->paramcount > INT_ARG_CNT) ? m->paramcount - INT_ARG_CNT : 0;
4010 stackframesize = stackparamcnt + paramshiftcnt;
4012 M_LDA(REG_SP, REG_SP, -stackframesize * 8);
4014 /* copy stack arguments into new stack frame -- if any */
4015 for (i = 0; i < stackparamcnt; i++) {
4016 M_LLD(REG_ITMP1, REG_SP, (stackparamcnt + 1 + i) * 8);
4017 M_LST(REG_ITMP1, REG_SP, (paramshiftcnt + i) * 8);
4020 if (m->flags & ACC_STATIC) {
4021 if (IS_FLT_DBL_TYPE(m->paramtypes[5])) {
4022 M_DST(r->argfltregs[5], REG_SP, 1 * 8);
4024 M_LST(r->argintregs[5], REG_SP, 1 * 8);
4027 if (IS_FLT_DBL_TYPE(m->paramtypes[4])) {
4028 M_DST(r->argfltregs[4], REG_SP, 0 * 8);
4030 M_LST(r->argintregs[4], REG_SP, 0 * 8);
4034 if (IS_FLT_DBL_TYPE(m->paramtypes[5])) {
4035 M_DST(r->argfltregs[5], REG_SP, 0 * 8);
4037 M_LST(r->argintregs[5], REG_SP, 0 * 8);
4042 if (m->flags & ACC_STATIC) {
4043 M_MOV(r->argintregs[3], r->argintregs[5]);
4044 M_MOV(r->argintregs[2], r->argintregs[4]);
4045 M_MOV(r->argintregs[1], r->argintregs[3]);
4046 M_MOV(r->argintregs[0], r->argintregs[2]);
4047 M_FMOV(r->argfltregs[3], r->argfltregs[5]);
4048 M_FMOV(r->argfltregs[2], r->argfltregs[4]);
4049 M_FMOV(r->argfltregs[1], r->argfltregs[3]);
4050 M_FMOV(r->argfltregs[0], r->argfltregs[2]);
4052 /* put class into second argument register */
4053 M_ALD(r->argintregs[1], REG_PV, -8 * 8);
4056 M_MOV(r->argintregs[4], r->argintregs[5]);
4057 M_MOV(r->argintregs[3], r->argintregs[4]);
4058 M_MOV(r->argintregs[2], r->argintregs[3]);
4059 M_MOV(r->argintregs[1], r->argintregs[2]);
4060 M_MOV(r->argintregs[0], r->argintregs[1]);
4061 M_FMOV(r->argfltregs[4], r->argfltregs[5]);
4062 M_FMOV(r->argfltregs[3], r->argfltregs[4]);
4063 M_FMOV(r->argfltregs[2], r->argfltregs[3]);
4064 M_FMOV(r->argfltregs[1], r->argfltregs[2]);
4065 M_FMOV(r->argfltregs[0], r->argfltregs[1]);
4068 /* put env into first argument register */
4069 M_ALD(r->argintregs[0], REG_PV, -4 * 8);
4071 M_ALD(REG_PV, REG_PV, -1 * 8); /* load adress of native method */
4072 M_JSR(REG_RA, REG_PV); /* call native method */
4073 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4074 M_LDA(REG_PV, REG_RA, disp); /* recompute pv from ra */
4076 /* remove stackframe if there is one */
4077 if (stackframesize) {
4078 M_LDA(REG_SP, REG_SP, stackframesize * 8);
4081 /* 13 instructions */
4083 M_LDA(REG_SP, REG_SP, -2 * 8);
4084 M_ALD(r->argintregs[0], REG_PV, -6 * 8); /* load method adress */
4085 M_LST(REG_RESULT, REG_SP, 0 * 8);
4086 M_DST(REG_FRESULT, REG_SP, 1 * 8);
4087 M_MOV(REG_RESULT, r->argintregs[1]);
4088 M_FMOV(REG_FRESULT, r->argfltregs[2]);
4089 M_FMOV(REG_FRESULT, r->argfltregs[3]);
4090 M_ALD(REG_PV, REG_PV, -7 * 8); /* builtin_displaymethodstop */
4091 M_JSR(REG_RA, REG_PV);
4092 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4093 M_LDA(REG_PV, REG_RA, disp);
4094 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4095 M_DLD(REG_FRESULT, REG_SP, 1 * 8);
4096 M_LDA(REG_SP, REG_SP, 2 * 8);
4099 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4100 if (IS_FLT_DBL_TYPE(m->returntype))
4101 M_DST(REG_FRESULT, REG_SP, 1 * 8);
4103 M_AST(REG_RESULT, REG_SP, 1 * 8);
4104 M_ALD(REG_PV, REG_PV, -2 * 8); /* builtin_get_exceptionptrptr */
4105 M_JSR(REG_RA, REG_PV);
4106 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
4107 M_LDA(REG_PV, REG_RA, disp);
4108 M_MOV(REG_RESULT, REG_ITMP3);
4109 if (IS_FLT_DBL_TYPE(m->returntype))
4110 M_DLD(REG_FRESULT, REG_SP, 1 * 8);
4112 M_ALD(REG_RESULT, REG_SP, 1 * 8);
4114 M_ALD(REG_ITMP3, REG_PV, -2 * 8); /* get address of exceptionptr */
4116 M_ALD(REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
4117 M_BNEZ(REG_ITMP1, 3); /* if no exception then return */
4119 M_ALD(REG_RA, REG_SP, 0 * 8); /* load return address */
4120 M_LDA(REG_SP, REG_SP, NATIVESTUBSTACK * 8); /* remove stackframe */
4121 M_RET(REG_ZERO, REG_RA); /* return to caller */
4123 M_AST(REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
4125 M_ALD(REG_RA, REG_SP, 0 * 8); /* load return address */
4126 M_LDA(REG_SP, REG_SP, NATIVESTUBSTACK * 8); /* remove stackframe */
4127 M_LDA(REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
4128 M_ALD(REG_ITMP3, REG_PV, -3 * 8); /* load asm exception handler address */
4129 M_JMP(REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
4132 dolog_plain("stubsize: %d (for %d params)\n", (int) (mcodeptr - (s4*) s), m->paramcount);
4135 #if defined(STATISTICS)
4137 count_nstub_len += NATIVESTUBSIZE * 8;
4140 return (u1 *) (s + NATIVESTUBOFFSET);
4144 /* function: removenativestub **************************************************
4146 removes a previously created native-stub from memory
4148 *******************************************************************************/
4150 void removenativestub(u1 *stub)
4152 CFREE((u8 *) stub - NATIVESTUBOFFSET, NATIVESTUBSIZE * 8);
4157 * These are local overrides for various environment variables in Emacs.
4158 * Please do not remove this and leave it at the end of the file, where
4159 * Emacs will automagically detect them.
4160 * ---------------------------------------------------------------------
4163 * indent-tabs-mode: t