1 /* jit/powerpc/codegen.c - machine code generator for 32-bit powerpc
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 1479 2004-11-11 11:16:46Z twisti $
48 #include "jit/parse.h"
50 #include "jit/powerpc/codegen.h"
53 /* register descripton - array ************************************************/
55 /* #define REG_RES 0 reserved register for OS or code generator */
56 /* #define REG_RET 1 return value register */
57 /* #define REG_EXC 2 exception value register (only old jit) */
58 /* #define REG_SAV 3 (callee) saved register */
59 /* #define REG_TMP 4 scratch temporary register (caller saved) */
60 /* #define REG_ARG 5 argument register (caller saved) */
62 /* #define REG_END -1 last entry in tables */
65 REG_RES, REG_RES, REG_TMP, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG,
66 REG_ARG, REG_ARG, REG_ARG, REG_RES, REG_RES, REG_RES, REG_SAV, REG_SAV,
67 REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
68 REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
71 /* for use of reserved registers, see comment above */
73 int nregdescfloat[] = {
74 REG_RES, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG,
75 REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_SAV, REG_SAV,
76 REG_RES, REG_RES, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
77 REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
80 /* for use of reserved registers, see comment above */
83 /*******************************************************************************
85 include independent code generation stuff -- include after register
86 descriptions to avoid extern definitions
88 *******************************************************************************/
90 #include "jit/codegen.inc"
91 #include "jit/reg.inc"
94 void asm_cacheflush(void *, long);
96 //#include <architecture/ppc/cframe.h>
98 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
99 void thread_restartcriticalsection(void *u)
101 /* XXX set pc to restart address */
105 #include <mach/message.h>
107 int cacao_catch_Handler(mach_port_t thread)
110 unsigned int crashpc;
112 java_objectheader *xptr;
115 thread_state_flavor_t flavor = PPC_THREAD_STATE;
116 mach_msg_type_number_t thread_state_count = PPC_THREAD_STATE_COUNT;
117 ppc_thread_state_t thread_state;
123 r = thread_get_state(thread, flavor,
124 (natural_t*)&thread_state, &thread_state_count);
125 if (r != KERN_SUCCESS)
126 panic("thread_get_state failed");
128 regs = &thread_state.r0;
129 crashpc = thread_state.srr0;
131 instr = *(s4*) crashpc;
132 reg = (instr >> 16) & 31;
135 xptr = new_exception(string_java_lang_NullPointerException);
137 regs[REG_ITMP2_XPC] = crashpc;
138 regs[REG_ITMP1_XPTR] = (u4) xptr;
139 thread_state.srr0 = (u4) asm_handle_exception;
141 r = thread_set_state(thread, flavor,
142 (natural_t*)&thread_state, thread_state_count);
143 if (r != KERN_SUCCESS)
144 panic("thread_set_state failed");
153 void init_exceptions(void)
158 void adjust_argvars(stackptr s, int d, int *fa, int *ia)
164 adjust_argvars(s->prev, d-1, fa, ia);
165 if (s->varkind == ARGVAR)
166 s->varnum = (IS_FLT_DBL_TYPE(s->type)) ? *fa : *ia;
167 *fa += (IS_FLT_DBL_TYPE(s->type) != 0);
168 *ia += (IS_2_WORD_TYPE(s->type)) ? 2 : 1;
172 #define intmaxf(a,b) (((a)<(b)) ? (b) : (a))
174 void preregpass(methodinfo *m, registerdata *rd)
184 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
186 for (iptr = bptr->iinstr, src = bptr->instack;
188 src = iptr->dst, len--, iptr++)
190 if (bptr->flags < BBREACHED)
203 case ICMD_INVOKEVIRTUAL:
204 case ICMD_INVOKESPECIAL:
205 case ICMD_INVOKESTATIC:
206 case ICMD_INVOKEINTERFACE:
211 adjust_argvars(src, s3, &fa, &ia);
214 for (; --s3 >= 0; src = src->prev) {
215 paramsize += IS_2_WORD_TYPE(src->type) ? 2 : 1;
217 rd->ifmemuse = intmaxf(rd->ifmemuse, paramsize);
220 case ICMD_MULTIANEWARRAY:
222 paramsize = rd->intreg_argnum + s3;
223 rd->ifmemuse = intmaxf(rd->ifmemuse, paramsize);
230 rd->maxmemuse = rd->ifmemuse;
234 /* function gen_mcode **********************************************************
236 generates machine code
238 *******************************************************************************/
240 void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
242 s4 len, s1, s2, s3, d;
258 /* space to save used callee saved registers */
260 savedregs_num += (rd->savintregcnt - rd->maxsavintreguse);
261 savedregs_num += 2 * (rd->savfltregcnt - rd->maxsavfltreguse);
263 parentargs_base = rd->maxmemuse + savedregs_num;
265 #ifdef USE_THREADS /* space to save argument of monitor_enter */
267 if (checksync && (m->flags & ACC_SYNCHRONIZED))
272 /* create method header */
274 parentargs_base = (parentargs_base + 3) & ~3;
277 (void) dseg_addaddress(cd, m); /* Filler */
279 (void) dseg_addaddress(cd, m); /* MethodPointer */
280 (void) dseg_adds4(cd, parentargs_base * 4); /* FrameSize */
284 /* IsSync contains the offset relative to the stack pointer for the
285 argument of monitor_exit used in the exception handler. Since the
286 offset could be zero and give a wrong meaning of the flag it is
290 if (checksync && (m->flags & ACC_SYNCHRONIZED))
291 (void) dseg_adds4(cd, (rd->maxmemuse + 1) * 4); /* IsSync */
296 (void) dseg_adds4(cd, 0); /* IsSync */
298 (void) dseg_adds4(cd, m->isleafmethod); /* IsLeaf */
299 (void) dseg_adds4(cd, rd->savintregcnt - rd->maxsavintreguse); /* IntSave */
300 (void) dseg_adds4(cd, rd->savfltregcnt - rd->maxsavfltreguse); /* FltSave */
301 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
303 /* create exception table */
305 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
306 dseg_addtarget(cd, ex->start);
307 dseg_addtarget(cd, ex->end);
308 dseg_addtarget(cd, ex->handler);
309 (void) dseg_addaddress(cd, ex->catchtype);
312 /* initialize mcode variables */
314 mcodeptr = (s4 *) cd->mcodebase;
315 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
316 MCODECHECK(128 + m->paramcount);
318 /* create stack frame (if necessary) */
320 if (!m->isleafmethod) {
322 M_AST(REG_ITMP3, REG_SP, 8);
325 if (parentargs_base) {
326 M_LDA(REG_SP, REG_SP, -parentargs_base * 4);
329 /* save return address and used callee saved registers */
332 for (i = rd->savintregcnt - 1; i >= rd->maxsavintreguse; i--) {
333 p--; M_IST(rd->savintregs[i], REG_SP, 4 * p);
335 for (i = rd->savfltregcnt - 1; i >= rd->maxsavfltreguse; i--) {
336 p-=2; M_DST(rd->savfltregs[i], REG_SP, 4 * p);
339 /* save monitorenter argument */
341 #if defined(USE_THREADS)
342 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
343 if (m->flags & ACC_STATIC) {
344 p = dseg_addaddress(cd, m->class);
345 M_ALD(REG_ITMP1, REG_PV, p);
346 M_AST(REG_ITMP1, REG_SP, 4 * rd->maxmemuse);
349 M_AST(rd->argintregs[0], REG_SP, 4 * rd->maxmemuse);
354 /* copy argument registers to stack and call trace function with pointer
355 to arguments on stack.
364 /* XXX must be a multiple of 16 */
365 M_LDA(REG_SP, REG_SP, -(24 + (INT_ARG_CNT + FLT_ARG_CNT + 1) * 8));
367 M_IST(REG_ITMP3, REG_SP, 24 + (INT_ARG_CNT + FLT_ARG_CNT) * 8);
369 M_CLR(REG_ITMP1); /* clear help register */
371 /* save all arguments into the reserved stack space */
372 for (p = 0; p < m->paramcount && p < TRACE_ARGS_NUM; p++) {
373 t = m->paramtypes[p];
375 if (IS_INT_LNG_TYPE(t)) {
376 /* overlapping u8's are on the stack */
377 if ((p + longargs + dblargs) < (INT_ARG_CNT - IS_2_WORD_TYPE(t))) {
378 s1 = rd->argintregs[p + longargs + dblargs];
380 if (!IS_2_WORD_TYPE(t)) {
381 M_IST(REG_ITMP1, REG_SP, 24 + p * 8);
382 M_IST(s1, REG_SP, 24 + p * 8 + 4);
385 M_IST(s1, REG_SP, 24 + p * 8);
386 M_IST(rd->secondregs[s1], REG_SP, 24 + p * 8 + 4);
391 a = dseg_adds4(cd, 0xdeadbeef);
392 M_ILD(REG_ITMP1, REG_PV, a);
393 M_IST(REG_ITMP1, REG_SP, 24 + p * 8);
394 M_IST(REG_ITMP1, REG_SP, 24 + p * 8 + 4);
398 if ((fltargs + dblargs) < FLT_ARG_CNT) {
399 s1 = rd->argfltregs[fltargs + dblargs];
401 if (!IS_2_WORD_TYPE(t)) {
402 M_IST(REG_ITMP1, REG_SP, 24 + p * 8);
403 M_FST(s1, REG_SP, 24 + p * 8 + 4);
407 M_DST(s1, REG_SP, 24 + p * 8);
412 /* this should not happen */
417 /* TODO: save remaining integer and flaot argument registers */
419 /* load first 4 arguments into integer argument registers */
420 for (p = 0; p < 8; p++) {
421 d = rd->argintregs[p];
422 M_ILD(d, REG_SP, 24 + p * 4);
425 p = dseg_addaddress(cd, m);
426 M_ALD(REG_ITMP1, REG_PV, p);
427 M_AST(REG_ITMP1, REG_SP, 11 * 8); /* 24 (linkage area) + 32 (4 * s8 parameter area regs) + 32 (4 * s8 parameter area stack) = 88 */
428 p = dseg_addaddress(cd, (void *) builtin_trace_args);
429 M_ALD(REG_ITMP2, REG_PV, p);
437 /* restore arguments into the reserved stack space */
438 for (p = 0; p < m->paramcount && p < TRACE_ARGS_NUM; p++) {
439 t = m->paramtypes[p];
441 if (IS_INT_LNG_TYPE(t)) {
442 if ((p + longargs + dblargs) < INT_ARG_CNT) {
443 s1 = rd->argintregs[p + longargs + dblargs];
445 if (!IS_2_WORD_TYPE(t)) {
446 M_ILD(s1, REG_SP, 24 + p * 8 + 4);
449 M_ILD(s1, REG_SP, 24 + p * 8);
450 M_ILD(rd->secondregs[s1], REG_SP, 24 + p * 8 + 4);
456 if ((fltargs + dblargs) < FLT_ARG_CNT) {
457 s1 = rd->argfltregs[fltargs + dblargs];
459 if (!IS_2_WORD_TYPE(t)) {
460 M_FLD(s1, REG_SP, 24 + p * 8 + 4);
464 M_DLD(s1, REG_SP, 24 + p * 8);
471 M_ILD(REG_ITMP3, REG_SP, 24 + (INT_ARG_CNT + FLT_ARG_CNT) * 8);
473 M_LDA(REG_SP, REG_SP, 24 + (INT_ARG_CNT + FLT_ARG_CNT + 1) * 8);
477 /* take arguments out of register or stack frame */
483 for (p = 0, l = 0; p < m->paramcount; p++) {
484 arg = narg; iarg = niarg;
485 t = m->paramtypes[p];
486 var = &(rd->locals[l][t]);
488 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
492 if (IS_INT_LNG_TYPE(t)) { /* integer args */
493 if (iarg < INT_ARG_CNT -
494 (IS_2_WORD_TYPE(t)!=0)) { /* register arguments */
495 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
496 M_TINTMOVE(t, rd->argintregs[iarg], var->regoff);
498 } else { /* reg arg -> spilled */
499 M_IST(rd->argintregs[iarg], REG_SP, 4 * var->regoff);
500 if (IS_2_WORD_TYPE(t))
501 M_IST(rd->secondregs[rd->argintregs[iarg]], REG_SP, 4 * var->regoff + 4);
504 } else { /* stack arguments */
506 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
507 M_ILD(var->regoff, REG_SP, 4 * (parentargs_base + pa));
508 if (IS_2_WORD_TYPE(t))
509 M_ILD(rd->secondregs[var->regoff], REG_SP, 4 * (parentargs_base + pa) + 4);
511 } else { /* stack arg -> spilled */
512 M_ILD(REG_ITMP1, REG_SP, 4 * (parentargs_base + pa));
513 M_IST(REG_ITMP1, REG_SP, 4 * var->regoff);
514 if (IS_2_WORD_TYPE(t)) {
515 M_ILD(REG_ITMP1, REG_SP, 4 * (parentargs_base + pa) + 4);
516 M_IST(REG_ITMP1, REG_SP, 4 * var->regoff + 4);
521 } else { /* floating args */
523 if (arg < FLT_ARG_CNT) { /* register arguments */
524 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
525 M_FLTMOVE(rd->argfltregs[arg], var->regoff);
527 } else { /* reg arg -> spilled */
528 M_DST(rd->argfltregs[arg], REG_SP, 4 * var->regoff);
531 } else { /* stack arguments */
533 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
534 if (IS_2_WORD_TYPE(t)) {
535 M_DLD(var->regoff, REG_SP, 4 * (parentargs_base + pa));
538 M_FLD(var->regoff, REG_SP, 4 * (parentargs_base + pa));
541 } else { /* stack-arg -> spilled */
542 if (IS_2_WORD_TYPE(t)) {
543 M_DLD(REG_FTMP1, REG_SP, 4 * (parentargs_base + pa));
546 M_FLD(REG_FTMP1, REG_SP, 4 * (parentargs_base + pa));
548 M_DST(REG_FTMP1, REG_SP, 4 * var->regoff);
555 /* call monitorenter function */
557 #if defined(USE_THREADS)
558 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
559 s4 func_enter = (m->flags & ACC_STATIC) ?
560 (s4) builtin_staticmonitorenter : (s4) builtin_monitorenter;
561 p = dseg_addaddress(cd, (void *) func_enter);
562 M_ALD(REG_ITMP3, REG_PV, p);
564 M_ALD(rd->argintregs[0], REG_SP, rd->maxmemuse * 4);
570 /* end of header generation */
572 /* walk through all basic blocks */
573 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
575 bptr->mpc = (s4) ((u1 *) mcodeptr - cd->mcodebase);
577 if (bptr->flags >= BBREACHED) {
579 /* branch resolving */
583 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
584 gen_resolvebranch((u1*) cd->mcodebase + brefs->branchpos,
590 /* copy interface registers to their destination */
595 while (src != NULL) {
597 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
598 d = reg_of_var(rd, src, REG_ITMP1);
599 M_INTMOVE(REG_ITMP1, d);
600 store_reg_to_var_int(src, d);
603 d = reg_of_var(rd, src, REG_IFTMP);
604 if ((src->varkind != STACKVAR)) {
606 if (IS_FLT_DBL_TYPE(s2)) {
607 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
608 s1 = rd->interfaces[len][s2].regoff;
612 if (IS_2_WORD_TYPE(s2)) {
613 M_DLD(d, REG_SP, 4 * rd->interfaces[len][s2].regoff);
616 M_FLD(d, REG_SP, 4 * rd->interfaces[len][s2].regoff);
619 store_reg_to_var_flt(src, d);
622 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
623 s1 = rd->interfaces[len][s2].regoff;
627 M_ILD(d, REG_SP, 4 * rd->interfaces[len][s2].regoff);
628 if (IS_2_WORD_TYPE(s2))
629 M_ILD(rd->secondregs[d], REG_SP, 4 * rd->interfaces[len][s2].regoff + 4);
631 store_reg_to_var_int(src, d);
638 /* walk through all instructions */
642 for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
644 MCODECHECK(64); /* an instruction usually needs < 64 words */
647 case ICMD_NOP: /* ... ==> ... */
650 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
652 var_to_reg_int(s1, src, REG_ITMP1);
655 codegen_addxnullrefs(cd, mcodeptr);
658 /* constant operations ************************************************/
660 case ICMD_ICONST: /* ... ==> ..., constant */
661 /* op1 = 0, val.i = constant */
663 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
664 ICONST(d, iptr->val.i);
665 store_reg_to_var_int(iptr->dst, d);
668 case ICMD_LCONST: /* ... ==> ..., constant */
669 /* op1 = 0, val.l = constant */
671 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
672 LCONST(d, iptr->val.l);
673 store_reg_to_var_int(iptr->dst, d);
676 case ICMD_FCONST: /* ... ==> ..., constant */
677 /* op1 = 0, val.f = constant */
679 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
680 a = dseg_addfloat(cd, iptr->val.f);
682 store_reg_to_var_flt(iptr->dst, d);
685 case ICMD_DCONST: /* ... ==> ..., constant */
686 /* op1 = 0, val.d = constant */
688 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
689 a = dseg_adddouble(cd, iptr->val.d);
691 store_reg_to_var_flt(iptr->dst, d);
694 case ICMD_ACONST: /* ... ==> ..., constant */
695 /* op1 = 0, val.a = constant */
697 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
698 ICONST(d, (u4) iptr->val.a);
699 store_reg_to_var_int(iptr->dst, d);
703 /* load/store operations **********************************************/
705 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
706 case ICMD_LLOAD: /* op1 = local variable */
709 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
710 if ((iptr->dst->varkind == LOCALVAR) &&
711 (iptr->dst->varnum == iptr->op1))
713 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
714 if (var->flags & INMEMORY) {
715 M_ILD(d, REG_SP, 4 * var->regoff);
716 if (IS_2_WORD_TYPE(var->type))
717 M_ILD(rd->secondregs[d], REG_SP, 4 * var->regoff + 4);
719 M_TINTMOVE(var->type, var->regoff, d);
721 store_reg_to_var_int(iptr->dst, d);
724 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
725 case ICMD_DLOAD: /* op1 = local variable */
727 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
728 if ((iptr->dst->varkind == LOCALVAR) &&
729 (iptr->dst->varnum == iptr->op1))
731 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
732 if (var->flags & INMEMORY)
733 if (IS_2_WORD_TYPE(var->type))
734 M_DLD(d, REG_SP, 4 * var->regoff);
736 M_FLD(d, REG_SP, 4 * var->regoff);
738 M_FLTMOVE(var->regoff, d);
740 store_reg_to_var_flt(iptr->dst, d);
744 case ICMD_ISTORE: /* ..., value ==> ... */
745 case ICMD_LSTORE: /* op1 = local variable */
748 if ((src->varkind == LOCALVAR) &&
749 (src->varnum == iptr->op1))
751 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
752 if (var->flags & INMEMORY) {
753 var_to_reg_int(s1, src, REG_ITMP1);
754 M_IST(s1, REG_SP, 4 * var->regoff);
755 if (IS_2_WORD_TYPE(var->type))
756 M_IST(rd->secondregs[s1], REG_SP, 4 * var->regoff + 4);
758 var_to_reg_int(s1, src, var->regoff);
759 M_TINTMOVE(var->type, s1, var->regoff);
763 case ICMD_FSTORE: /* ..., value ==> ... */
764 case ICMD_DSTORE: /* op1 = local variable */
766 if ((src->varkind == LOCALVAR) &&
767 (src->varnum == iptr->op1))
769 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
770 if (var->flags & INMEMORY) {
771 var_to_reg_flt(s1, src, REG_FTMP1);
772 if (var->type == TYPE_DBL)
773 M_DST(s1, REG_SP, 4 * var->regoff);
775 M_FST(s1, REG_SP, 4 * var->regoff);
777 var_to_reg_flt(s1, src, var->regoff);
778 M_FLTMOVE(s1, var->regoff);
783 /* pop/dup/swap operations ********************************************/
785 /* attention: double and longs are only one entry in CACAO ICMDs */
787 case ICMD_POP: /* ..., value ==> ... */
788 case ICMD_POP2: /* ..., value, value ==> ... */
791 case ICMD_DUP: /* ..., a ==> ..., a, a */
792 M_COPY(src, iptr->dst);
795 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
797 M_COPY(src, iptr->dst);
798 M_COPY(src->prev, iptr->dst->prev);
799 M_COPY(iptr->dst, iptr->dst->prev->prev);
802 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
804 M_COPY(src, iptr->dst);
805 M_COPY(src->prev, iptr->dst->prev);
806 M_COPY(src->prev->prev, iptr->dst->prev->prev);
807 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
810 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
812 M_COPY(src, iptr->dst);
813 M_COPY(src->prev, iptr->dst->prev);
816 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
818 M_COPY(src, iptr->dst);
819 M_COPY(src->prev, iptr->dst->prev);
820 M_COPY(src->prev->prev, iptr->dst->prev->prev);
821 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
822 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev);
825 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
827 M_COPY(src, iptr->dst);
828 M_COPY(src->prev, iptr->dst->prev);
829 M_COPY(src->prev->prev, iptr->dst->prev->prev);
830 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
831 M_COPY(iptr->dst, iptr->dst->prev->prev->prev->prev);
832 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev->prev);
835 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
837 M_COPY(src, iptr->dst->prev);
838 M_COPY(src->prev, iptr->dst);
842 /* integer operations *************************************************/
844 case ICMD_INEG: /* ..., value ==> ..., - value */
846 var_to_reg_int(s1, src, REG_ITMP1);
847 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
849 store_reg_to_var_int(iptr->dst, d);
852 case ICMD_LNEG: /* ..., value ==> ..., - value */
854 var_to_reg_int(s1, src, REG_ITMP1);
855 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
856 M_SUBFIC(rd->secondregs[s1], 0, rd->secondregs[d]);
858 store_reg_to_var_int(iptr->dst, d);
861 case ICMD_I2L: /* ..., value ==> ..., value */
863 var_to_reg_int(s1, src, REG_ITMP2);
864 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
865 M_INTMOVE(s1, rd->secondregs[d]);
866 M_SRA_IMM(rd->secondregs[d], 31, d);
867 store_reg_to_var_int(iptr->dst, d);
870 case ICMD_L2I: /* ..., value ==> ..., value */
872 var_to_reg_int0(s1, src, REG_ITMP2, 0, 1);
873 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
875 store_reg_to_var_int(iptr->dst, d);
878 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
880 var_to_reg_int(s1, src, REG_ITMP1);
881 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
883 store_reg_to_var_int(iptr->dst, d);
886 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
888 var_to_reg_int(s1, src, REG_ITMP1);
889 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
891 store_reg_to_var_int(iptr->dst, d);
894 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
896 var_to_reg_int(s1, src, REG_ITMP1);
897 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
899 store_reg_to_var_int(iptr->dst, d);
903 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
905 var_to_reg_int(s1, src->prev, REG_ITMP1);
906 var_to_reg_int(s2, src, REG_ITMP2);
907 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
909 store_reg_to_var_int(iptr->dst, d);
912 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
913 /* val.i = constant */
915 var_to_reg_int(s1, src, REG_ITMP1);
916 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
917 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
918 M_IADD_IMM(s1, iptr->val.i, d);
921 ICONST(REG_ITMP2, iptr->val.i);
922 M_IADD(s1, REG_ITMP2, d);
924 store_reg_to_var_int(iptr->dst, d);
927 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
929 var_to_reg_int0(s1, src->prev, REG_ITMP1, 0, 1);
930 var_to_reg_int0(s2, src, REG_ITMP2, 0, 1);
931 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
932 M_ADDC(s1, s2, rd->secondregs[d]);
933 var_to_reg_int0(s1, src->prev, REG_ITMP1, 1, 0);
934 var_to_reg_int0(s2, src, REG_ITMP3, 1, 0);
936 store_reg_to_var_int(iptr->dst, d);
939 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
940 /* val.l = constant */
942 s3 = iptr->val.l & 0xffffffff;
943 var_to_reg_int0(s1, src, REG_ITMP1, 0, 1);
944 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
945 if ((s3 >= -32768) && (s3 <= 32767)) {
946 M_ADDIC(s1, s3, rd->secondregs[d]);
949 ICONST(REG_ITMP2, s3);
950 M_ADDC(s1, REG_ITMP2, rd->secondregs[d]);
952 var_to_reg_int0(s1, src, REG_ITMP1, 1, 0);
953 s3 = iptr->val.l >> 32;
959 ICONST(REG_ITMP3, s3);
960 M_ADDE(s1, REG_ITMP3, d);
962 store_reg_to_var_int(iptr->dst, d);
965 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
967 var_to_reg_int(s1, src->prev, REG_ITMP1);
968 var_to_reg_int(s2, src, REG_ITMP2);
969 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
971 store_reg_to_var_int(iptr->dst, d);
974 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
975 /* val.i = constant */
977 var_to_reg_int(s1, src, REG_ITMP1);
978 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
979 if ((iptr->val.i >= -32767) && (iptr->val.i <= 32768)) {
980 M_IADD_IMM(s1, -iptr->val.i, d);
983 ICONST(REG_ITMP2, -iptr->val.i);
984 M_IADD(s1, REG_ITMP2, d);
986 store_reg_to_var_int(iptr->dst, d);
989 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
991 var_to_reg_int0(s1, src->prev, REG_ITMP1, 0, 1);
992 var_to_reg_int0(s2, src, REG_ITMP2, 0, 1);
993 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
994 M_SUBC(s1, s2, rd->secondregs[d]);
995 var_to_reg_int0(s1, src->prev, REG_ITMP1, 1, 0);
996 var_to_reg_int0(s2, src, REG_ITMP3, 1, 0);
998 store_reg_to_var_int(iptr->dst, d);
1001 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
1002 /* val.l = constant */
1004 s3 = (-iptr->val.l) & 0xffffffff;
1005 var_to_reg_int0(s1, src, REG_ITMP1, 0, 1);
1006 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1007 if ((s3 >= -32768) && (s3 <= 32767)) {
1008 M_ADDIC(s1, s3, rd->secondregs[d]);
1011 ICONST(REG_ITMP2, s3);
1012 M_ADDC(s1, REG_ITMP2, rd->secondregs[d]);
1014 var_to_reg_int0(s1, src, REG_ITMP1, 1, 0);
1015 s3 = (-iptr->val.l) >> 32;
1021 ICONST(REG_ITMP3, s3);
1022 M_ADDE(s1, REG_ITMP3, d);
1024 store_reg_to_var_int(iptr->dst, d);
1027 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1028 var_to_reg_int(s1, src->prev, REG_ITMP1);
1029 var_to_reg_int(s2, src, REG_ITMP2);
1030 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1032 store_reg_to_var_int(iptr->dst, d);
1035 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1036 var_to_reg_int(s1, src->prev, REG_ITMP1);
1037 var_to_reg_int(s2, src, REG_ITMP2);
1038 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1042 store_reg_to_var_int(iptr->dst, d);
1045 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1047 var_to_reg_int(s1, src->prev, REG_ITMP1);
1048 var_to_reg_int(s2, src, REG_ITMP2);
1049 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1051 store_reg_to_var_int(iptr->dst, d);
1054 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
1055 /* val.i = constant */
1057 var_to_reg_int(s1, src, REG_ITMP1);
1058 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1059 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
1060 M_IMUL_IMM(s1, iptr->val.i, d);
1063 ICONST(REG_ITMP2, iptr->val.i);
1064 M_IMUL(s1, REG_ITMP2, d);
1066 store_reg_to_var_int(iptr->dst, d);
1069 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
1071 var_to_reg_int(s1, src, REG_ITMP1);
1072 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1073 M_SRA_IMM(s1, iptr->val.i, d);
1075 store_reg_to_var_int(iptr->dst, d);
1078 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1080 var_to_reg_int(s1, src->prev, REG_ITMP1);
1081 var_to_reg_int(s2, src, REG_ITMP2);
1082 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1083 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1084 M_SLL(s1, REG_ITMP3, d);
1085 store_reg_to_var_int(iptr->dst, d);
1088 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1089 /* val.i = constant */
1091 var_to_reg_int(s1, src, REG_ITMP1);
1092 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1093 M_SLL_IMM(s1, iptr->val.i & 0x1f, d);
1094 store_reg_to_var_int(iptr->dst, d);
1097 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1099 var_to_reg_int(s1, src->prev, REG_ITMP1);
1100 var_to_reg_int(s2, src, REG_ITMP2);
1101 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1102 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1103 M_SRA(s1, REG_ITMP3, d);
1104 store_reg_to_var_int(iptr->dst, d);
1107 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1108 /* val.i = constant */
1110 var_to_reg_int(s1, src, REG_ITMP1);
1111 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1112 M_SRA_IMM(s1, iptr->val.i & 0x1f, d);
1113 store_reg_to_var_int(iptr->dst, d);
1116 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1118 var_to_reg_int(s1, src->prev, REG_ITMP1);
1119 var_to_reg_int(s2, src, REG_ITMP2);
1120 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1121 M_AND_IMM(s2, 0x1f, REG_ITMP2);
1122 M_SRL(s1, REG_ITMP2, d);
1123 store_reg_to_var_int(iptr->dst, d);
1126 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1127 /* val.i = constant */
1129 var_to_reg_int(s1, src, REG_ITMP1);
1130 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1131 if (iptr->val.i & 0x1f)
1132 M_SRL_IMM(s1, iptr->val.i & 0x1f, d);
1135 store_reg_to_var_int(iptr->dst, d);
1138 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1140 var_to_reg_int(s1, src->prev, REG_ITMP1);
1141 var_to_reg_int(s2, src, REG_ITMP2);
1142 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1144 store_reg_to_var_int(iptr->dst, d);
1147 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1148 /* val.i = constant */
1150 var_to_reg_int(s1, src, REG_ITMP1);
1151 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1152 if ((iptr->val.i >= 0) && (iptr->val.i <= 65535)) {
1153 M_AND_IMM(s1, iptr->val.i, d);
1156 else if (iptr->val.i == 0xffffff) {
1157 M_RLWINM(s1, 0, 8, 31, d);
1161 ICONST(REG_ITMP2, iptr->val.i);
1162 M_AND(s1, REG_ITMP2, d);
1164 store_reg_to_var_int(iptr->dst, d);
1167 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1169 var_to_reg_int0(s1, src->prev, REG_ITMP1, 0, 1);
1170 var_to_reg_int0(s2, src, REG_ITMP2, 0, 1);
1171 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1172 M_AND(s1, s2, rd->secondregs[d]);
1173 var_to_reg_int0(s1, src->prev, REG_ITMP1, 1, 0);
1174 var_to_reg_int0(s2, src, REG_ITMP3, 1, 0);
1176 store_reg_to_var_int(iptr->dst, d);
1179 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1180 /* val.l = constant */
1182 s3 = iptr->val.l & 0xffffffff;
1183 var_to_reg_int0(s1, src, REG_ITMP1, 0, 1);
1184 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1185 if ((s3 >= 0) && (s3 <= 65535)) {
1186 M_AND_IMM(s1, s3, rd->secondregs[d]);
1189 ICONST(REG_ITMP2, s3);
1190 M_AND(s1, REG_ITMP2, rd->secondregs[d]);
1192 var_to_reg_int0(s1, src, REG_ITMP1, 1, 0);
1193 s3 = iptr->val.l >> 32;
1194 if ((s3 >= 0) && (s3 <= 65535)) {
1195 M_AND_IMM(s1, s3, d);
1198 ICONST(REG_ITMP3, s3);
1199 M_AND(s1, REG_ITMP3, d);
1201 store_reg_to_var_int(iptr->dst, d);
1204 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1205 /* val.i = constant */
1207 var_to_reg_int(s1, src, REG_ITMP1);
1208 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1209 M_MOV(s1, REG_ITMP2);
1211 M_BGE(1 + 2*(iptr->val.i >= 32768));
1212 if (iptr->val.i >= 32768) {
1213 M_ADDIS(REG_ZERO, iptr->val.i>>16, REG_ITMP2);
1214 M_OR_IMM(REG_ITMP2, iptr->val.i, REG_ITMP2);
1215 M_IADD(s1, REG_ITMP2, REG_ITMP2);
1218 M_IADD_IMM(s1, iptr->val.i, REG_ITMP2);
1220 int b=0, m = iptr->val.i;
1223 M_RLWINM(REG_ITMP2, 0, 0, 30-b, REG_ITMP2);
1225 M_ISUB(s1, REG_ITMP2, d);
1226 store_reg_to_var_int(iptr->dst, d);
1229 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1231 var_to_reg_int(s1, src->prev, REG_ITMP1);
1232 var_to_reg_int(s2, src, REG_ITMP2);
1233 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1235 store_reg_to_var_int(iptr->dst, d);
1238 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1239 /* val.i = constant */
1241 var_to_reg_int(s1, src, REG_ITMP1);
1242 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1243 if ((iptr->val.i >= 0) && (iptr->val.i <= 65535)) {
1244 M_OR_IMM(s1, iptr->val.i, d);
1247 ICONST(REG_ITMP2, iptr->val.i);
1248 M_OR(s1, REG_ITMP2, d);
1250 store_reg_to_var_int(iptr->dst, d);
1253 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1255 var_to_reg_int0(s1, src->prev, REG_ITMP1, 0, 1);
1256 var_to_reg_int0(s2, src, REG_ITMP2, 0, 1);
1257 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1258 M_OR(s1, s2, rd->secondregs[d]);
1259 var_to_reg_int0(s1, src->prev, REG_ITMP1, 1, 0);
1260 var_to_reg_int0(s2, src, REG_ITMP3, 1, 0);
1262 store_reg_to_var_int(iptr->dst, d);
1265 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1266 /* val.l = constant */
1268 s3 = iptr->val.l & 0xffffffff;
1269 var_to_reg_int0(s1, src, REG_ITMP1, 0, 1);
1270 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1271 if ((s3 >= 0) && (s3 <= 65535)) {
1272 M_OR_IMM(s1, s3, rd->secondregs[d]);
1275 ICONST(REG_ITMP2, s3);
1276 M_OR(s1, REG_ITMP2, rd->secondregs[d]);
1278 var_to_reg_int0(s1, src, REG_ITMP1, 1, 0);
1279 s3 = iptr->val.l >> 32;
1280 if ((s3 >= 0) && (s3 <= 65535)) {
1281 M_OR_IMM(s1, s3, d);
1284 ICONST(REG_ITMP3, s3);
1285 M_OR(s1, REG_ITMP3, d);
1287 store_reg_to_var_int(iptr->dst, d);
1290 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1292 var_to_reg_int(s1, src->prev, REG_ITMP1);
1293 var_to_reg_int(s2, src, REG_ITMP2);
1294 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1296 store_reg_to_var_int(iptr->dst, d);
1299 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1300 /* val.i = constant */
1302 var_to_reg_int(s1, src, REG_ITMP1);
1303 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1304 if ((iptr->val.i >= 0) && (iptr->val.i <= 65535)) {
1305 M_XOR_IMM(s1, iptr->val.i, d);
1308 ICONST(REG_ITMP2, iptr->val.i);
1309 M_XOR(s1, REG_ITMP2, d);
1311 store_reg_to_var_int(iptr->dst, d);
1314 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1316 var_to_reg_int0(s1, src->prev, REG_ITMP1, 0, 1);
1317 var_to_reg_int0(s2, src, REG_ITMP2, 0, 1);
1318 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1319 M_XOR(s1, s2, rd->secondregs[d]);
1320 var_to_reg_int0(s1, src->prev, REG_ITMP1, 1, 0);
1321 var_to_reg_int0(s2, src, REG_ITMP3, 1, 0);
1323 store_reg_to_var_int(iptr->dst, d);
1326 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1327 /* val.l = constant */
1329 s3 = iptr->val.l & 0xffffffff;
1330 var_to_reg_int0(s1, src, REG_ITMP1, 0, 1);
1331 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1332 if ((s3 >= 0) && (s3 <= 65535)) {
1333 M_XOR_IMM(s1, s3, rd->secondregs[d]);
1336 ICONST(REG_ITMP2, s3);
1337 M_XOR(s1, REG_ITMP2, rd->secondregs[d]);
1339 var_to_reg_int0(s1, src, REG_ITMP1, 1, 0);
1340 s3 = iptr->val.l >> 32;
1341 if ((s3 >= 0) && (s3 <= 65535)) {
1342 M_XOR_IMM(s1, s3, d);
1345 ICONST(REG_ITMP3, s3);
1346 M_XOR(s1, REG_ITMP3, d);
1348 store_reg_to_var_int(iptr->dst, d);
1351 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1353 var_to_reg_int0(s1, src->prev, REG_ITMP3, 1, 0);
1354 var_to_reg_int0(s2, src, REG_ITMP2, 1, 0);
1355 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
1358 (d==s1 || d==s2 || d==rd->secondregs[s1] || d==rd->secondregs[s2]);
1359 int dreg = tempreg ? REG_ITMP1 : d;
1361 M_IADD_IMM(REG_ZERO, 1, dreg);
1366 var_to_reg_int0(s1, src->prev, REG_ITMP3, 0, 1);
1367 var_to_reg_int0(s2, src, REG_ITMP2, 0, 1);
1371 M_IADD_IMM(dreg, -1, dreg);
1372 M_IADD_IMM(dreg, -1, dreg);
1373 gen_resolvebranch(br1, (u1*) br1, (u1*) mcodeptr);
1374 gen_resolvebranch(br1+1, (u1*) (br1+1), (u1*) (mcodeptr-2));
1377 store_reg_to_var_int(iptr->dst, d);
1380 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1381 /* op1 = variable, val.i = constant */
1383 var = &(rd->locals[iptr->op1][TYPE_INT]);
1384 if (var->flags & INMEMORY) {
1386 M_ILD(s1, REG_SP, 4 * var->regoff);
1395 M_ADDIS(s1, m>>16, s1);
1397 M_IADD_IMM(s1, m&0xffff, s1);
1399 if (var->flags & INMEMORY)
1400 M_IST(s1, REG_SP, 4 * var->regoff);
1404 /* floating operations ************************************************/
1406 case ICMD_FNEG: /* ..., value ==> ..., - value */
1408 var_to_reg_flt(s1, src, REG_FTMP1);
1409 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1411 store_reg_to_var_flt(iptr->dst, d);
1414 case ICMD_DNEG: /* ..., value ==> ..., - value */
1416 var_to_reg_flt(s1, src, REG_FTMP1);
1417 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1419 store_reg_to_var_flt(iptr->dst, d);
1422 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1424 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1425 var_to_reg_flt(s2, src, REG_FTMP2);
1426 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1428 store_reg_to_var_flt(iptr->dst, d);
1431 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1433 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1434 var_to_reg_flt(s2, src, REG_FTMP2);
1435 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1437 store_reg_to_var_flt(iptr->dst, d);
1440 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1442 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1443 var_to_reg_flt(s2, src, REG_FTMP2);
1444 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1446 store_reg_to_var_flt(iptr->dst, d);
1449 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1451 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1452 var_to_reg_flt(s2, src, REG_FTMP2);
1453 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1455 store_reg_to_var_flt(iptr->dst, d);
1458 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1460 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1461 var_to_reg_flt(s2, src, REG_FTMP2);
1462 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1464 store_reg_to_var_flt(iptr->dst, d);
1467 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1469 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1470 var_to_reg_flt(s2, src, REG_FTMP2);
1471 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1473 store_reg_to_var_flt(iptr->dst, d);
1476 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1478 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1479 var_to_reg_flt(s2, src, REG_FTMP2);
1480 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1482 store_reg_to_var_flt(iptr->dst, d);
1485 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1487 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1488 var_to_reg_flt(s2, src, REG_FTMP2);
1489 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1491 store_reg_to_var_flt(iptr->dst, d);
1494 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1496 var_to_reg_flt(s1, src, REG_FTMP1);
1497 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1499 a = dseg_addfloat(cd, 0.0);
1500 M_FLD(REG_FTMP2, REG_PV, a);
1501 M_FCMPU(s1, REG_FTMP2);
1503 a = dseg_adds4(cd, 0);
1504 M_CVTDL_C(s1, REG_FTMP1);
1505 M_LDA (REG_ITMP1, REG_PV, a);
1506 M_STFIWX(REG_FTMP1, 0, REG_ITMP1);
1507 M_ILD (d, REG_PV, a);
1508 store_reg_to_var_int(iptr->dst, d);
1511 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1513 var_to_reg_flt(s1, src, REG_FTMP1);
1514 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1516 store_reg_to_var_flt(iptr->dst, d);
1519 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1521 var_to_reg_flt(s1, src, REG_FTMP1);
1522 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1524 store_reg_to_var_flt(iptr->dst, d);
1527 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1529 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1530 var_to_reg_flt(s2, src, REG_FTMP2);
1531 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1533 M_IADD_IMM(0, -1, d);
1536 M_IADD_IMM(0, 0, d);
1538 M_IADD_IMM(0, 1, d);
1539 store_reg_to_var_int(iptr->dst, d);
1542 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1544 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1545 var_to_reg_flt(s2, src, REG_FTMP2);
1546 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1548 M_IADD_IMM(0, 1, d);
1551 M_IADD_IMM(0, 0, d);
1553 M_IADD_IMM(0, -1, d);
1554 store_reg_to_var_int(iptr->dst, d);
1558 /* memory operations **************************************************/
1560 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1562 var_to_reg_int(s1, src, REG_ITMP1);
1563 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1564 gen_nullptr_check(s1);
1565 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1566 store_reg_to_var_int(iptr->dst, d);
1569 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1571 var_to_reg_int(s1, src->prev, REG_ITMP1);
1572 var_to_reg_int(s2, src, REG_ITMP2);
1573 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1574 if (iptr->op1 == 0) {
1575 gen_nullptr_check(s1);
1578 M_SLL_IMM(s2, 2, REG_ITMP2);
1579 M_IADD_IMM(REG_ITMP2, OFFSET(java_objectarray, data[0]), REG_ITMP2);
1580 M_LWZX(d, s1, REG_ITMP2);
1581 store_reg_to_var_int(iptr->dst, d);
1584 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1586 var_to_reg_int(s1, src->prev, REG_ITMP1);
1587 var_to_reg_int(s2, src, REG_ITMP2);
1588 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1589 if (iptr->op1 == 0) {
1590 gen_nullptr_check(s1);
1593 M_SLL_IMM(s2, 3, REG_ITMP2);
1594 M_IADD(s1, REG_ITMP2, REG_ITMP2);
1595 M_ILD(d, REG_ITMP2, OFFSET(java_longarray, data[0]));
1596 M_ILD(rd->secondregs[d], REG_ITMP2, OFFSET(java_longarray, data[0])+4);
1597 store_reg_to_var_int(iptr->dst, d);
1600 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1602 var_to_reg_int(s1, src->prev, REG_ITMP1);
1603 var_to_reg_int(s2, src, REG_ITMP2);
1604 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1605 if (iptr->op1 == 0) {
1606 gen_nullptr_check(s1);
1609 M_SLL_IMM(s2, 2, REG_ITMP2);
1610 M_IADD_IMM(REG_ITMP2, OFFSET(java_intarray, data[0]), REG_ITMP2);
1611 M_LWZX(d, s1, REG_ITMP2);
1612 store_reg_to_var_int(iptr->dst, d);
1615 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1617 var_to_reg_int(s1, src->prev, REG_ITMP1);
1618 var_to_reg_int(s2, src, REG_ITMP2);
1619 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1620 if (iptr->op1 == 0) {
1621 gen_nullptr_check(s1);
1624 M_SLL_IMM(s2, 2, REG_ITMP2);
1625 M_IADD_IMM(REG_ITMP2, OFFSET(java_floatarray, data[0]), REG_ITMP2);
1626 M_LFSX(d, s1, REG_ITMP2);
1627 store_reg_to_var_flt(iptr->dst, d);
1630 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1632 var_to_reg_int(s1, src->prev, REG_ITMP1);
1633 var_to_reg_int(s2, src, REG_ITMP2);
1634 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1635 if (iptr->op1 == 0) {
1636 gen_nullptr_check(s1);
1639 M_SLL_IMM(s2, 3, REG_ITMP2);
1640 M_IADD_IMM(REG_ITMP2, OFFSET(java_doublearray, data[0]), REG_ITMP2);
1641 M_LFDX(d, s1, REG_ITMP2);
1642 store_reg_to_var_flt(iptr->dst, d);
1645 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1647 var_to_reg_int(s1, src->prev, REG_ITMP1);
1648 var_to_reg_int(s2, src, REG_ITMP2);
1649 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1650 if (iptr->op1 == 0) {
1651 gen_nullptr_check(s1);
1654 M_IADD_IMM(s2, OFFSET(java_chararray, data[0]), REG_ITMP2);
1655 M_LBZX(d, s1, REG_ITMP2);
1657 store_reg_to_var_int(iptr->dst, d);
1660 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1662 var_to_reg_int(s1, src->prev, REG_ITMP1);
1663 var_to_reg_int(s2, src, REG_ITMP2);
1664 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1665 if (iptr->op1 == 0) {
1666 gen_nullptr_check(s1);
1669 M_SLL_IMM(s2, 1, REG_ITMP2);
1670 M_IADD_IMM(REG_ITMP2, OFFSET(java_shortarray, data[0]), REG_ITMP2);
1671 M_LHAX(d, s1, REG_ITMP2);
1672 store_reg_to_var_int(iptr->dst, d);
1675 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1677 var_to_reg_int(s1, src->prev, REG_ITMP1);
1678 var_to_reg_int(s2, src, REG_ITMP2);
1679 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1680 if (iptr->op1 == 0) {
1681 gen_nullptr_check(s1);
1684 M_SLL_IMM(s2, 1, REG_ITMP2);
1685 M_IADD_IMM(REG_ITMP2, OFFSET(java_chararray, data[0]), REG_ITMP2);
1686 M_LHZX(d, s1, REG_ITMP2);
1687 store_reg_to_var_int(iptr->dst, d);
1690 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1692 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1693 var_to_reg_int(s2, src->prev, REG_ITMP2);
1694 if (iptr->op1 == 0) {
1695 gen_nullptr_check(s1);
1698 var_to_reg_int0(s3, src, REG_ITMP3, 1, 0);
1699 M_SLL_IMM(s2, 3, REG_ITMP2);
1700 M_IADD_IMM(REG_ITMP2, OFFSET(java_intarray, data[0]), REG_ITMP2);
1701 M_STWX(s3, s1, REG_ITMP2);
1702 M_IADD_IMM(REG_ITMP2, 4, REG_ITMP2);
1703 var_to_reg_int0(s3, src, REG_ITMP3, 0, 1);
1704 M_STWX(s3, s1, REG_ITMP2);
1707 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1709 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1710 var_to_reg_int(s2, src->prev, REG_ITMP2);
1711 if (iptr->op1 == 0) {
1712 gen_nullptr_check(s1);
1715 var_to_reg_int(s3, src, REG_ITMP3);
1716 M_SLL_IMM(s2, 2, REG_ITMP2);
1717 M_IADD_IMM(REG_ITMP2, OFFSET(java_intarray, data[0]), REG_ITMP2);
1718 M_STWX(s3, s1, REG_ITMP2);
1721 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1723 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1724 var_to_reg_int(s2, src->prev, REG_ITMP2);
1725 if (iptr->op1 == 0) {
1726 gen_nullptr_check(s1);
1729 var_to_reg_flt(s3, src, REG_FTMP3);
1730 M_SLL_IMM(s2, 2, REG_ITMP2);
1731 M_IADD_IMM(REG_ITMP2, OFFSET(java_floatarray, data[0]), REG_ITMP2);
1732 M_STFSX(s3, s1, REG_ITMP2);
1735 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1737 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1738 var_to_reg_int(s2, src->prev, REG_ITMP2);
1739 if (iptr->op1 == 0) {
1740 gen_nullptr_check(s1);
1743 var_to_reg_flt(s3, src, REG_FTMP3);
1744 M_SLL_IMM(s2, 3, REG_ITMP2);
1745 M_IADD_IMM(REG_ITMP2, OFFSET(java_doublearray, data[0]), REG_ITMP2);
1746 M_STFDX(s3, s1, REG_ITMP2);
1749 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1751 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1752 var_to_reg_int(s2, src->prev, REG_ITMP2);
1753 if (iptr->op1 == 0) {
1754 gen_nullptr_check(s1);
1757 var_to_reg_int(s3, src, REG_ITMP3);
1758 M_IADD_IMM(s2, OFFSET(java_bytearray, data[0]), REG_ITMP2);
1759 M_STBX(s3, s1, REG_ITMP2);
1762 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1764 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1765 var_to_reg_int(s2, src->prev, REG_ITMP2);
1766 if (iptr->op1 == 0) {
1767 gen_nullptr_check(s1);
1770 var_to_reg_int(s3, src, REG_ITMP3);
1771 M_SLL_IMM(s2, 1, REG_ITMP2);
1772 M_IADD_IMM(REG_ITMP2, OFFSET(java_shortarray, data[0]), REG_ITMP2);
1773 M_STHX(s3, s1, REG_ITMP2);
1776 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1778 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1779 var_to_reg_int(s2, src->prev, REG_ITMP2);
1780 if (iptr->op1 == 0) {
1781 gen_nullptr_check(s1);
1784 var_to_reg_int(s3, src, REG_ITMP3);
1785 M_SLL_IMM(s2, 1, REG_ITMP2);
1786 M_IADD_IMM(REG_ITMP2, OFFSET(java_chararray, data[0]), REG_ITMP2);
1787 M_STHX(s3, s1, REG_ITMP2);
1790 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1791 /* op1 = type, val.a = field address */
1793 /* if class isn't yet initialized, do it */
1794 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
1795 /* call helper function which patches this code */
1796 a = dseg_addaddress(cd, ((fieldinfo *) iptr->val.a)->class);
1797 M_ALD(REG_ITMP1, REG_PV, a);
1798 a = dseg_addaddress(cd, asm_check_clinit);
1799 M_ALD(REG_PV, REG_PV, a);
1804 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
1806 if (s1 <= 32768) M_LDA(REG_PV, REG_ITMP1, -s1);
1808 s4 ml = -s1, mh = 0;
1809 while (ml < -32768) { ml += 65536; mh--; }
1810 M_LDA(REG_PV, REG_ITMP1, ml);
1811 M_LDAH(REG_PV, REG_PV, mh);
1815 a = dseg_addaddress(cd, &(((fieldinfo *) iptr->val.a)->value));
1816 M_ALD(REG_ITMP1, REG_PV, a);
1817 switch (iptr->op1) {
1819 var_to_reg_int(s2, src, REG_ITMP2);
1820 M_IST(s2, REG_ITMP1, 0);
1823 var_to_reg_int(s2, src, REG_ITMP3);
1824 M_IST(s2, REG_ITMP1, 0);
1825 M_IST(rd->secondregs[s2], REG_ITMP1, 4);
1828 var_to_reg_int(s2, src, REG_ITMP2);
1829 M_AST(s2, REG_ITMP1, 0);
1832 var_to_reg_flt(s2, src, REG_FTMP2);
1833 M_FST(s2, REG_ITMP1, 0);
1836 var_to_reg_flt(s2, src, REG_FTMP2);
1837 M_DST(s2, REG_ITMP1, 0);
1839 default: panic ("internal error");
1843 case ICMD_GETSTATIC: /* ... ==> ..., value */
1844 /* op1 = type, val.a = field address */
1846 /* if class isn't yet initialized, do it */
1847 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
1848 /* call helper function which patches this code */
1849 a = dseg_addaddress(cd, ((fieldinfo *) iptr->val.a)->class);
1850 M_ALD(REG_ITMP1, REG_PV, a);
1851 a = dseg_addaddress(cd, asm_check_clinit);
1852 M_ALD(REG_PV, REG_PV, a);
1857 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
1859 if (s1 <= 32768) M_LDA(REG_PV, REG_ITMP1, -s1);
1861 s4 ml = -s1, mh = 0;
1862 while (ml < -32768) { ml += 65536; mh--; }
1863 M_LDA(REG_PV, REG_ITMP1, ml);
1864 M_LDAH(REG_PV, REG_PV, mh);
1868 a = dseg_addaddress(cd, &(((fieldinfo *) iptr->val.a)->value));
1869 M_ALD(REG_ITMP1, REG_PV, a);
1870 switch (iptr->op1) {
1872 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1873 M_ILD(d, REG_ITMP1, 0);
1874 store_reg_to_var_int(iptr->dst, d);
1877 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1878 M_ILD(d, REG_ITMP1, 0);
1879 M_ILD(rd->secondregs[d], REG_ITMP1, 4);
1880 store_reg_to_var_int(iptr->dst, d);
1883 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1884 M_ALD(d, REG_ITMP1, 0);
1885 store_reg_to_var_int(iptr->dst, d);
1888 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
1889 M_FLD(d, REG_ITMP1, 0);
1890 store_reg_to_var_flt(iptr->dst, d);
1893 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
1894 M_DLD(d, REG_ITMP1, 0);
1895 store_reg_to_var_flt(iptr->dst, d);
1897 default: panic ("internal error");
1902 case ICMD_PUTFIELD: /* ..., value ==> ... */
1903 /* op1 = type, val.i = field offset */
1905 a = ((fieldinfo *)(iptr->val.a))->offset;
1906 switch (iptr->op1) {
1908 var_to_reg_int(s1, src->prev, REG_ITMP1);
1909 var_to_reg_int(s2, src, REG_ITMP2);
1910 gen_nullptr_check(s1);
1914 var_to_reg_int(s1, src->prev, REG_ITMP1);
1915 var_to_reg_int(s2, src, REG_ITMP3);
1916 gen_nullptr_check(s1);
1918 M_IST(rd->secondregs[s2], s1, a+4);
1921 var_to_reg_int(s1, src->prev, REG_ITMP1);
1922 var_to_reg_int(s2, src, REG_ITMP2);
1923 gen_nullptr_check(s1);
1927 var_to_reg_int(s1, src->prev, REG_ITMP1);
1928 var_to_reg_flt(s2, src, REG_FTMP2);
1929 gen_nullptr_check(s1);
1933 var_to_reg_int(s1, src->prev, REG_ITMP1);
1934 var_to_reg_flt(s2, src, REG_FTMP2);
1935 gen_nullptr_check(s1);
1938 default: panic ("internal error");
1942 case ICMD_GETFIELD: /* ... ==> ..., value */
1943 /* op1 = type, val.i = field offset */
1945 a = ((fieldinfo *)(iptr->val.a))->offset;
1946 switch (iptr->op1) {
1948 var_to_reg_int(s1, src, REG_ITMP1);
1949 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1950 gen_nullptr_check(s1);
1952 store_reg_to_var_int(iptr->dst, d);
1955 var_to_reg_int(s1, src, REG_ITMP1);
1956 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1957 gen_nullptr_check(s1);
1959 M_ILD(rd->secondregs[d], s1, a+4);
1960 store_reg_to_var_int(iptr->dst, d);
1963 var_to_reg_int(s1, src, REG_ITMP1);
1964 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1965 gen_nullptr_check(s1);
1967 store_reg_to_var_int(iptr->dst, d);
1970 var_to_reg_int(s1, src, REG_ITMP1);
1971 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
1972 gen_nullptr_check(s1);
1974 store_reg_to_var_flt(iptr->dst, d);
1977 var_to_reg_int(s1, src, REG_ITMP1);
1978 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
1979 gen_nullptr_check(s1);
1981 store_reg_to_var_flt(iptr->dst, d);
1983 default: panic ("internal error");
1988 /* branch operations **************************************************/
1990 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1992 a = dseg_addaddress(cd, asm_handle_exception);
1993 M_ALD(REG_ITMP2, REG_PV, a);
1995 var_to_reg_int(s1, src, REG_ITMP1);
1996 M_INTMOVE(s1, REG_ITMP1_XPTR);
1998 if (m->isleafmethod) M_MFLR(REG_ITMP3); /* save LR */
1999 M_BL(0); /* get current PC */
2000 M_MFLR(REG_ITMP2_XPC);
2001 if (m->isleafmethod) M_MTLR(REG_ITMP3); /* restore LR */
2002 M_RTS; /* jump to CTR */
2007 case ICMD_GOTO: /* ... ==> ... */
2008 /* op1 = target JavaVM pc */
2010 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2014 case ICMD_JSR: /* ... ==> ... */
2015 /* op1 = target JavaVM pc */
2017 if (m->isleafmethod) M_MFLR(REG_ITMP2);
2020 M_IADD_IMM(REG_ITMP1, m->isleafmethod ? 16 : 12, REG_ITMP1);
2021 if (m->isleafmethod) M_MTLR(REG_ITMP2);
2023 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2026 case ICMD_RET: /* ... ==> ... */
2027 /* op1 = local variable */
2029 var = &(rd->locals[iptr->op1][TYPE_ADR]);
2030 if (var->flags & INMEMORY) {
2031 M_ALD(REG_ITMP1, REG_SP, 4 * var->regoff);
2035 M_MTCTR(var->regoff);
2040 case ICMD_IFNULL: /* ..., value ==> ... */
2041 /* op1 = target JavaVM pc */
2043 var_to_reg_int(s1, src, REG_ITMP1);
2046 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2049 case ICMD_IFNONNULL: /* ..., value ==> ... */
2050 /* op1 = target JavaVM pc */
2052 var_to_reg_int(s1, src, REG_ITMP1);
2055 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2063 case ICMD_IFEQ: /* ..., value ==> ... */
2064 /* op1 = target JavaVM pc, val.i = constant */
2066 var_to_reg_int(s1, src, REG_ITMP1);
2067 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
2068 M_CMPI(s1, iptr->val.i);
2071 ICONST(REG_ITMP2, iptr->val.i);
2072 M_CMP(s1, REG_ITMP2);
2095 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2099 case ICMD_IF_LEQ: /* ..., value ==> ... */
2100 /* op1 = target JavaVM pc, val.l = constant */
2102 var_to_reg_int0(s1, src, REG_ITMP1, 0, 1);
2103 var_to_reg_int0(s2, src, REG_ITMP2, 1, 0);
2104 if (iptr->val.l == 0) {
2105 M_OR(s1, s2, REG_ITMP3);
2106 M_CMPI(REG_ITMP3, 0);
2108 } else if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2109 M_CMPI(s2, (u4) (iptr->val.l >> 32));
2111 M_CMPI(s1, (u4) (iptr->val.l & 0xffffffff));
2114 ICONST(REG_ITMP3, (u4) (iptr->val.l >> 32));
2115 M_CMP(s2, REG_ITMP3);
2117 ICONST(REG_ITMP3, (u4) (iptr->val.l & 0xffffffff));
2118 M_CMP(s1, REG_ITMP3)
2121 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2124 case ICMD_IF_LLT: /* ..., value ==> ... */
2125 /* op1 = target JavaVM pc, val.l = constant */
2126 var_to_reg_int0(s1, src, REG_ITMP1, 0, 1);
2127 var_to_reg_int0(s2, src, REG_ITMP2, 1, 0);
2128 /* if (iptr->val.l == 0) { */
2129 /* M_OR(s1, s2, REG_ITMP3); */
2130 /* M_CMPI(REG_ITMP3, 0); */
2133 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2134 M_CMPI(s2, (u4) (iptr->val.l >> 32));
2136 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2138 M_CMPI(s1, (u4) (iptr->val.l & 0xffffffff));
2141 ICONST(REG_ITMP3, (u4) (iptr->val.l >> 32));
2142 M_CMP(s2, REG_ITMP3);
2144 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2146 ICONST(REG_ITMP3, (u4) (iptr->val.l & 0xffffffff));
2147 M_CMP(s1, REG_ITMP3)
2150 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2153 case ICMD_IF_LLE: /* ..., value ==> ... */
2154 /* op1 = target JavaVM pc, val.l = constant */
2156 var_to_reg_int0(s1, src, REG_ITMP1, 0, 1);
2157 var_to_reg_int0(s2, src, REG_ITMP2, 1, 0);
2158 /* if (iptr->val.l == 0) { */
2159 /* M_OR(s1, s2, REG_ITMP3); */
2160 /* M_CMPI(REG_ITMP3, 0); */
2163 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2164 M_CMPI(s2, (u4) (iptr->val.l >> 32));
2166 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2168 M_CMPI(s1, (u4) (iptr->val.l & 0xffffffff));
2171 ICONST(REG_ITMP3, (u4) (iptr->val.l >> 32));
2172 M_CMP(s2, REG_ITMP3);
2174 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2176 ICONST(REG_ITMP3, (u4) (iptr->val.l & 0xffffffff));
2177 M_CMP(s1, REG_ITMP3)
2180 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2183 case ICMD_IF_LNE: /* ..., value ==> ... */
2184 /* op1 = target JavaVM pc, val.l = constant */
2186 var_to_reg_int0(s1, src, REG_ITMP1, 0, 1);
2187 var_to_reg_int0(s2, src, REG_ITMP2, 1, 0);
2188 if (iptr->val.l == 0) {
2189 M_OR(s1, s2, REG_ITMP3);
2190 M_CMPI(REG_ITMP3, 0);
2192 } else if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2193 M_CMPI(s2, (u4) (iptr->val.l >> 32));
2195 M_CMPI(s1, (u4) (iptr->val.l & 0xffffffff));
2198 ICONST(REG_ITMP3, (u4) (iptr->val.l >> 32));
2199 M_CMP(s2, REG_ITMP3);
2201 ICONST(REG_ITMP3, (u4) (iptr->val.l & 0xffffffff));
2202 M_CMP(s1, REG_ITMP3)
2205 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2208 case ICMD_IF_LGT: /* ..., value ==> ... */
2209 /* op1 = target JavaVM pc, val.l = constant */
2211 var_to_reg_int0(s1, src, REG_ITMP1, 0, 1);
2212 var_to_reg_int0(s2, src, REG_ITMP2, 1, 0);
2213 /* if (iptr->val.l == 0) { */
2214 /* M_OR(s1, s2, REG_ITMP3); */
2215 /* M_CMPI(REG_ITMP3, 0); */
2218 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2219 M_CMPI(s2, (u4) (iptr->val.l >> 32));
2221 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2223 M_CMPI(s1, (u4) (iptr->val.l & 0xffffffff));
2226 ICONST(REG_ITMP3, (u4) (iptr->val.l >> 32));
2227 M_CMP(s2, REG_ITMP3);
2229 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2231 ICONST(REG_ITMP3, (u4) (iptr->val.l & 0xffffffff));
2232 M_CMP(s1, REG_ITMP3)
2235 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2238 case ICMD_IF_LGE: /* ..., value ==> ... */
2239 /* op1 = target JavaVM pc, val.l = constant */
2240 var_to_reg_int0(s1, src, REG_ITMP1, 0, 1);
2241 var_to_reg_int0(s2, src, REG_ITMP2, 1, 0);
2242 /* if (iptr->val.l == 0) { */
2243 /* M_OR(s1, s2, REG_ITMP3); */
2244 /* M_CMPI(REG_ITMP3, 0); */
2247 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2248 M_CMPI(s2, (u4) (iptr->val.l >> 32));
2250 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2252 M_CMPI(s1, (u4) (iptr->val.l & 0xffffffff));
2255 ICONST(REG_ITMP3, (u4) (iptr->val.l >> 32));
2256 M_CMP(s2, REG_ITMP3);
2258 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2260 ICONST(REG_ITMP3, (u4) (iptr->val.l & 0xffffffff));
2261 M_CMP(s1, REG_ITMP3)
2264 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2268 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2269 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2270 case ICMD_IF_ACMPEQ:
2272 var_to_reg_int(s1, src->prev, REG_ITMP1);
2273 var_to_reg_int(s2, src, REG_ITMP2);
2276 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2279 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2280 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2281 case ICMD_IF_ACMPNE:
2283 var_to_reg_int(s1, src->prev, REG_ITMP1);
2284 var_to_reg_int(s2, src, REG_ITMP2);
2287 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2290 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2291 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2293 var_to_reg_int(s1, src->prev, REG_ITMP1);
2294 var_to_reg_int(s2, src, REG_ITMP2);
2297 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2300 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2301 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2303 var_to_reg_int(s1, src->prev, REG_ITMP1);
2304 var_to_reg_int(s2, src, REG_ITMP2);
2307 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2310 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2311 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2313 var_to_reg_int(s1, src->prev, REG_ITMP1);
2314 var_to_reg_int(s2, src, REG_ITMP2);
2317 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2320 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2321 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2323 var_to_reg_int(s1, src->prev, REG_ITMP1);
2324 var_to_reg_int(s2, src, REG_ITMP2);
2327 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2330 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2334 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2337 case ICMD_RETURN: /* ... ==> ... */
2339 #if defined(USE_THREADS)
2340 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2341 a = dseg_addaddress(cd, (void *) (builtin_monitorexit));
2342 M_ALD(REG_ITMP3, REG_PV, a);
2344 M_ALD(rd->argintregs[0], REG_SP, rd->maxmemuse * 4);
2348 switch (iptr->opc) {
2352 var_to_reg_int(s1, src, REG_RESULT);
2353 M_TINTMOVE(src->type, s1, REG_RESULT);
2354 goto nowperformreturn;
2358 var_to_reg_flt(s1, src, REG_FRESULT);
2359 M_FLTMOVE(s1, REG_FRESULT);
2360 goto nowperformreturn;
2367 p = parentargs_base;
2369 /* restore return address */
2371 if (!m->isleafmethod) {
2372 M_ALD(REG_ITMP3, REG_SP, 4 * p + 8);
2376 /* restore saved registers */
2378 for (i = rd->savintregcnt - 1; i >= rd->maxsavintreguse; i--) {
2379 p--; M_ILD(rd->savintregs[i], REG_SP, 4 * p);
2381 for (i = rd->savfltregcnt - 1; i >= rd->maxsavfltreguse; i--) {
2382 p -= 2; M_DLD(rd->savfltregs[i], REG_SP, 4 * p);
2385 /* deallocate stack */
2387 if (parentargs_base) {
2388 M_LDA(REG_SP, REG_SP, parentargs_base*4);
2391 /* call trace function */
2395 M_LDA(REG_SP, REG_SP, -10 * 8);
2396 M_DST(REG_FRESULT, REG_SP, 48+0);
2397 M_IST(REG_RESULT, REG_SP, 48+8);
2398 M_AST(REG_ITMP3, REG_SP, 48+12);
2399 M_IST(REG_RESULT2, REG_SP, 48+16);
2400 a = dseg_addaddress(cd, m);
2402 /* keep this order */
2403 switch (iptr->opc) {
2406 M_MOV(REG_RESULT, rd->argintregs[2]);
2407 M_CLR(rd->argintregs[1]);
2411 M_MOV(REG_RESULT2, rd->argintregs[2]);
2412 M_MOV(REG_RESULT, rd->argintregs[1]);
2415 M_ALD(rd->argintregs[0], REG_PV, a);
2417 M_FLTMOVE(REG_FRESULT, rd->argfltregs[0]);
2418 M_FLTMOVE(REG_FRESULT, rd->argfltregs[1]);
2419 a = dseg_addaddress(cd, (void *) builtin_displaymethodstop);
2420 M_ALD(REG_ITMP2, REG_PV, a);
2423 M_DLD(REG_FRESULT, REG_SP, 48+0);
2424 M_ILD(REG_RESULT, REG_SP, 48+8);
2425 M_ALD(REG_ITMP3, REG_SP, 48+12);
2426 M_ILD(REG_RESULT2, REG_SP, 48+16);
2427 M_LDA(REG_SP, REG_SP, 10 * 8);
2437 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2442 tptr = (void **) iptr->target;
2444 s4ptr = iptr->val.a;
2445 l = s4ptr[1]; /* low */
2446 i = s4ptr[2]; /* high */
2448 var_to_reg_int(s1, src, REG_ITMP1);
2450 M_INTMOVE(s1, REG_ITMP1);
2451 } else if (l <= 32768) {
2452 M_LDA(REG_ITMP1, s1, -l);
2454 ICONST(REG_ITMP2, l);
2455 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2461 M_CMPUI(REG_ITMP1, i - 1);
2464 /* codegen_addreference(cd, BlockPtrOfPC(s4ptr[0]), mcodeptr); */
2465 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
2467 /* build jump table top down and use address of lowest entry */
2469 /* s4ptr += 3 + i; */
2473 /* dseg_addtarget(cd, BlockPtrOfPC(*--s4ptr)); */
2474 dseg_addtarget(cd, (basicblock *) tptr[0]);
2479 /* length of dataseg after last dseg_addtarget is used by load */
2481 M_SLL_IMM(REG_ITMP1, 2, REG_ITMP1);
2482 M_IADD(REG_ITMP1, REG_PV, REG_ITMP2);
2483 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2490 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2492 s4 i, l, val, *s4ptr;
2495 tptr = (void **) iptr->target;
2497 s4ptr = iptr->val.a;
2498 l = s4ptr[0]; /* default */
2499 i = s4ptr[1]; /* count */
2501 MCODECHECK((i<<2)+8);
2502 var_to_reg_int(s1, src, REG_ITMP1);
2508 if ((val >= -32768) && (val <= 32767)) {
2512 a = dseg_adds4(cd, val);
2513 M_ILD(REG_ITMP2, REG_PV, a);
2514 M_CMP(s1, REG_ITMP2);
2517 /* codegen_addreference(cd, BlockPtrOfPC(s4ptr[1]), mcodeptr); */
2518 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
2522 /* codegen_addreference(cd, BlockPtrOfPC(l), mcodeptr); */
2524 tptr = (void **) iptr->target;
2525 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
2532 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
2533 /* op1 = return type, val.a = function pointer*/
2537 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
2538 /* op1 = return type, val.a = function pointer*/
2542 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
2543 /* op1 = return type, val.a = function pointer*/
2547 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2548 /* op1 = arg count, val.a = method pointer */
2550 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2551 /* op1 = arg count, val.a = method pointer */
2553 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2554 /* op1 = arg count, val.a = method pointer */
2556 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
2557 /* op1 = arg count, val.a = method pointer */
2565 MCODECHECK((s3 << 1) + 64);
2568 /* copy arguments to registers or stack location */
2570 stackptr srcsave = src;
2574 for (; --s3 >= 0; src = src->prev) {
2575 argsize += IS_2_WORD_TYPE(src->type) ? 2 : 1;
2576 if (IS_FLT_DBL_TYPE(src->type))
2580 for (s3 = s3save, src = srcsave; --s3 >= 0; src = src->prev) {
2581 argsize -= IS_2_WORD_TYPE(src->type) ? 2 : 1;
2582 if (IS_FLT_DBL_TYPE(src->type))
2584 if (src->varkind == ARGVAR)
2586 if (IS_INT_LNG_TYPE(src->type)) {
2587 if (argsize < INT_ARG_CNT) {
2588 s1 = rd->argintregs[argsize];
2589 var_to_reg_int(d, src, s1);
2590 if (argsize < INT_ARG_CNT-1) {
2591 M_TINTMOVE(src->type, d, s1);
2595 if (IS_2_WORD_TYPE(src->type))
2596 M_IST(rd->secondregs[d], REG_SP, 4 * (argsize + 6) + 4);
2600 var_to_reg_int(d, src, REG_ITMP1);
2601 M_IST(d, REG_SP, 4 * (argsize + 6));
2602 if (IS_2_WORD_TYPE(src->type))
2603 M_IST(rd->secondregs[d], REG_SP, 4 * (argsize + 6) + 4);
2607 if (fltcnt < FLT_ARG_CNT) {
2608 s1 = rd->argfltregs[fltcnt];
2609 var_to_reg_flt(d, src, s1);
2613 var_to_reg_flt(d, src, REG_FTMP1);
2614 if (IS_2_WORD_TYPE(src->type))
2615 M_DST(d, REG_SP, 4 * (argsize + 6));
2617 M_FST(d, REG_SP, 4 * (argsize + 6));
2624 switch (iptr->opc) {
2628 a = dseg_addaddress(cd, (void *) lm);
2630 M_ALD(REG_PV, REG_PV, a); /* Pointer to built-in-function */
2632 goto makeactualcall;
2634 case ICMD_INVOKESTATIC:
2635 case ICMD_INVOKESPECIAL:
2636 a = dseg_addaddress(cd, lm->stubroutine);
2638 M_ALD(REG_PV, REG_PV, a); /* method pointer in r27 */
2641 goto makeactualcall;
2643 case ICMD_INVOKEVIRTUAL:
2645 gen_nullptr_check(rd->argintregs[0]);
2646 M_ALD(REG_METHODPTR, rd->argintregs[0],
2647 OFFSET(java_objectheader, vftbl));
2648 M_ALD(REG_PV, REG_METHODPTR, OFFSET(vftbl_t, table[0]) +
2649 sizeof(methodptr) * lm->vftblindex);
2652 goto makeactualcall;
2654 case ICMD_INVOKEINTERFACE:
2657 gen_nullptr_check(rd->argintregs[0]);
2658 M_ALD(REG_METHODPTR, rd->argintregs[0],
2659 OFFSET(java_objectheader, vftbl));
2660 M_ALD(REG_METHODPTR, REG_METHODPTR,
2661 OFFSET(vftbl_t, interfacetable[0]) -
2662 sizeof(methodptr*) * ci->index);
2663 M_ALD(REG_PV, REG_METHODPTR,
2664 sizeof(methodptr) * (lm - ci->methods));
2667 goto makeactualcall;
2671 error ("Unkown ICMD-Command: %d", iptr->opc);
2680 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
2682 if (s1 <= 32768) M_LDA(REG_PV, REG_ITMP1, -s1);
2684 s4 ml = -s1, mh = 0;
2685 while (ml < -32768) { ml += 65536; mh--; }
2686 M_LDA(REG_PV, REG_ITMP1, ml);
2687 M_LDAH(REG_PV, REG_PV, mh);
2690 /* d contains return type */
2692 if (d != TYPE_VOID) {
2693 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
2694 s1 = reg_of_var(rd, iptr->dst, REG_RESULT);
2695 M_TINTMOVE(iptr->dst->type, REG_RESULT, s1);
2696 store_reg_to_var_int(iptr->dst, s1);
2699 s1 = reg_of_var(rd, iptr->dst, REG_FRESULT);
2700 M_FLTMOVE(REG_FRESULT, s1);
2701 store_reg_to_var_flt(iptr->dst, s1);
2708 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2710 /* op1: 0 == array, 1 == class */
2711 /* val.a: (classinfo*) superclass */
2713 /* superclass is an interface:
2715 * return (sub != NULL) &&
2716 * (sub->vftbl->interfacetablelength > super->index) &&
2717 * (sub->vftbl->interfacetable[-super->index] != NULL);
2719 * superclass is a class:
2721 * return ((sub != NULL) && (0
2722 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2723 * super->vftbl->diffvall));
2727 classinfo *super = (classinfo*) iptr->val.a;
2729 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
2730 codegen_threadcritrestart(cd, (u1*) mcodeptr - cd->mcodebase);
2732 var_to_reg_int(s1, src, REG_ITMP1);
2733 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2735 M_MOV(s1, REG_ITMP1);
2739 if (iptr->op1) { /* class/interface */
2741 if (super->flags & ACC_INTERFACE) { /* interface */
2743 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2744 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2745 M_LDATST(REG_ITMP2, REG_ITMP2, - super->index);
2747 M_ALD(REG_ITMP1, REG_ITMP1,
2748 OFFSET(vftbl_t, interfacetable[0]) -
2749 super->index * sizeof(methodptr*));
2753 M_IADD_IMM(REG_ZERO, 1, d);
2757 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2758 a = dseg_addaddress(cd, (void*) super->vftbl);
2759 M_ALD(REG_ITMP2, REG_PV, a);
2760 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
2761 codegen_threadcritstart(cd, (u1*) mcodeptr - cd->mcodebase);
2763 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
2764 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
2765 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
2766 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
2767 codegen_threadcritstop(cd, (u1*) mcodeptr - cd->mcodebase);
2769 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
2770 M_CMPU(REG_ITMP1, REG_ITMP2);
2773 M_IADD_IMM(REG_ZERO, 1, d);
2777 panic ("internal error: no inlined array instanceof");
2779 store_reg_to_var_int(iptr->dst, d);
2782 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2784 /* op1: 0 == array, 1 == class */
2785 /* val.a: (classinfo*) superclass */
2787 /* superclass is an interface:
2789 * OK if ((sub == NULL) ||
2790 * (sub->vftbl->interfacetablelength > super->index) &&
2791 * (sub->vftbl->interfacetable[-super->index] != NULL));
2793 * superclass is a class:
2795 * OK if ((sub == NULL) || (0
2796 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2797 * super->vftbl->diffvall));
2801 classinfo *super = (classinfo*) iptr->val.a;
2803 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
2804 codegen_threadcritrestart(cd, (u1*) mcodeptr - cd->mcodebase);
2806 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
2807 var_to_reg_int(s1, src, d);
2808 if (iptr->op1) { /* class/interface */
2810 if (super->flags & ACC_INTERFACE) { /* interface */
2812 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2813 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
2814 M_LDATST(REG_ITMP3, REG_ITMP3, - super->index);
2816 codegen_addxcastrefs(cd, mcodeptr);
2817 M_ALD(REG_ITMP3, REG_ITMP2,
2818 OFFSET(vftbl_t, interfacetable[0]) -
2819 super->index * sizeof(methodptr*));
2822 codegen_addxcastrefs(cd, mcodeptr);
2825 M_BEQ(8 + (s1 == REG_ITMP1));
2826 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2827 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
2828 codegen_threadcritstart(cd, (u1*) mcodeptr - cd->mcodebase);
2830 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
2831 a = dseg_addaddress(cd, (void*) super->vftbl);
2832 M_ALD(REG_ITMP2, REG_PV, a);
2833 if (d != REG_ITMP1) {
2834 M_ILD(REG_ITMP1, REG_ITMP2, OFFSET(vftbl_t, baseval));
2835 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
2836 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
2837 codegen_threadcritstop(cd, (u1*) mcodeptr - cd->mcodebase);
2839 M_ISUB(REG_ITMP3, REG_ITMP1, REG_ITMP3);
2842 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2843 M_ISUB(REG_ITMP3, REG_ITMP2, REG_ITMP3);
2844 M_ALD(REG_ITMP2, REG_PV, a);
2845 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
2846 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
2847 codegen_threadcritstop(cd, (u1*) mcodeptr - cd->mcodebase);
2850 M_CMPU(REG_ITMP3, REG_ITMP2);
2852 codegen_addxcastrefs(cd, mcodeptr);
2856 panic ("internal error: no inlined array checkcast");
2859 store_reg_to_var_int(iptr->dst, d);
2862 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
2864 var_to_reg_int(s1, src, REG_ITMP1);
2867 codegen_addxcheckarefs(cd, mcodeptr);
2870 case ICMD_CHECKEXCEPTION: /* ... ==> ... */
2872 M_CMPI(REG_RESULT, 0);
2874 codegen_addxexceptionrefs(cd, mcodeptr);
2877 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2878 /* op1 = dimension, val.a = array descriptor */
2880 /* check for negative sizes and copy sizes to stack if necessary */
2882 MCODECHECK((iptr->op1 << 1) + 64);
2884 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
2885 var_to_reg_int(s2, src, REG_ITMP1);
2888 codegen_addxcheckarefs(cd, mcodeptr);
2890 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
2892 if (src->varkind != ARGVAR) {
2893 M_IST(s2, REG_SP, 4 * (s1 + INT_ARG_CNT + 6));
2897 /* a0 = dimension count */
2899 ICONST(rd->argintregs[0], iptr->op1);
2901 /* a1 = arraydescriptor */
2903 a = dseg_addaddress(cd, iptr->val.a);
2904 M_ALD(rd->argintregs[1], REG_PV, a);
2906 /* a2 = pointer to dimensions = stack pointer */
2908 M_LDA(rd->argintregs[2], REG_SP, (INT_ARG_CNT + 6)*4);
2910 a = dseg_addaddress(cd, (void *) builtin_nmultianewarray);
2911 M_ALD(REG_PV, REG_PV, a);
2914 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
2917 M_LDA (REG_PV, REG_ITMP1, -s1);
2919 s4 ml = -s1, mh = 0;
2920 while (ml < -32768) {ml += 65536; mh--;}
2921 M_LDA(REG_PV, REG_ITMP1, ml);
2922 M_LDAH(REG_PV, REG_PV, mh);
2924 s1 = reg_of_var(rd, iptr->dst, REG_RESULT);
2925 M_INTMOVE(REG_RESULT, s1);
2926 store_reg_to_var_int(iptr->dst, s1);
2930 default: error ("Unknown pseudo command: %d", iptr->opc);
2934 } /* for instruction */
2936 /* copy values to interface registers */
2938 src = bptr->outstack;
2939 len = bptr->outdepth;
2940 MCODECHECK(64 + len);
2943 if ((src->varkind != STACKVAR)) {
2945 if (IS_FLT_DBL_TYPE(s2)) {
2946 var_to_reg_flt(s1, src, REG_FTMP1);
2947 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
2948 M_FLTMOVE(s1, rd->interfaces[len][s2].regoff);
2951 M_DST(s1, REG_SP, rd->interfaces[len][s2].regoff * 4);
2955 var_to_reg_int(s1, src, REG_ITMP1);
2956 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
2957 M_TINTMOVE(s2, s1, rd->interfaces[len][s2].regoff);
2960 M_IST(s1, REG_SP, rd->interfaces[len][s2].regoff * 4);
2961 if (IS_2_WORD_TYPE(s2))
2962 M_IST(rd->secondregs[s1], REG_SP, rd->interfaces[len][s2].regoff * 4 + 4);
2968 } /* if (bptr -> flags >= BBREACHED) */
2969 } /* for basic block */
2971 /* bptr -> mpc = (int)((u1*) mcodeptr - mcodebase); */
2974 /* generate bound check stubs */
2976 s4 *xcodeptr = NULL;
2979 for (bref = cd->xboundrefs; bref != NULL; bref = bref->next) {
2980 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
2982 (u1 *) mcodeptr - cd->mcodebase);
2986 /* move index register into REG_ITMP1 */
2987 M_MOV(bref->reg, REG_ITMP1);
2988 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
2990 if (xcodeptr != NULL) {
2991 M_BR(xcodeptr - mcodeptr - 1);
2994 xcodeptr = mcodeptr;
2996 M_IADD_IMM(REG_SP, -1 * 8, REG_SP);
2997 M_IST(REG_ITMP2_XPC, REG_SP, 0 * 8);
2999 a = dseg_addaddress(cd, string_java_lang_ArrayIndexOutOfBoundsException);
3000 M_ALD(rd->argintregs[0], REG_PV, a);
3001 M_MOV(REG_ITMP1, rd->argintregs[1]);
3003 a = dseg_addaddress(cd, new_exception_int);
3004 M_ALD(REG_ITMP2, REG_PV, a);
3007 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3009 M_ILD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3010 M_IADD_IMM(REG_SP, 1 * 8, REG_SP);
3012 a = dseg_addaddress(cd, asm_handle_exception);
3013 M_ALD(REG_ITMP3, REG_PV, a);
3020 /* generate negative array size check stubs */
3024 for (bref = cd->xcheckarefs; bref != NULL; bref = bref->next) {
3025 if ((m->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3026 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3028 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3032 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3034 (u1 *) mcodeptr - cd->mcodebase);
3038 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3040 if (xcodeptr != NULL) {
3041 M_BR(xcodeptr - mcodeptr - 1);
3044 xcodeptr = mcodeptr;
3046 M_IADD_IMM(REG_SP, -1 * 8, REG_SP);
3047 M_IST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3049 a = dseg_addaddress(cd, string_java_lang_NegativeArraySizeException);
3050 M_ALD(rd->argintregs[0], REG_PV, a);
3052 a = dseg_addaddress(cd, new_exception);
3053 M_ALD(REG_ITMP2, REG_PV, a);
3056 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3058 M_ILD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3059 M_IADD_IMM(REG_SP, 1 * 8, REG_SP);
3061 a = dseg_addaddress(cd, asm_handle_exception);
3062 M_ALD(REG_ITMP3, REG_PV, a);
3069 /* generate cast check stubs */
3073 for (bref = cd->xcastrefs; bref != NULL; bref = bref->next) {
3074 if ((m->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3075 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3077 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3081 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3083 (u1 *) mcodeptr - cd->mcodebase);
3087 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3089 if (xcodeptr != NULL) {
3090 M_BR(xcodeptr - mcodeptr - 1);
3093 xcodeptr = mcodeptr;
3095 M_IADD_IMM(REG_SP, -1 * 8, REG_SP);
3096 M_IST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3098 a = dseg_addaddress(cd, string_java_lang_ClassCastException);
3099 M_ALD(rd->argintregs[0], REG_PV, a);
3101 a = dseg_addaddress(cd, new_exception);
3102 M_ALD(REG_ITMP2, REG_PV, a);
3105 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3107 M_ILD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3108 M_IADD_IMM(REG_SP, 1 * 8, REG_SP);
3110 a = dseg_addaddress(cd, asm_handle_exception);
3111 M_ALD(REG_ITMP3, REG_PV, a);
3118 /* generate exception check stubs */
3122 for (bref = cd->xexceptionrefs; bref != NULL; bref = bref->next) {
3123 if ((m->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3124 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3126 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3130 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3132 (u1 *) mcodeptr - cd->mcodebase);
3136 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3138 if (xcodeptr != NULL) {
3139 M_BR(xcodeptr - mcodeptr - 1);
3142 xcodeptr = mcodeptr;
3144 /* XXX this cannot work - there is no link area */
3145 M_IADD_IMM(REG_SP, -1 * 8, REG_SP);
3146 M_IST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3148 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3149 a = dseg_addaddress(cd, builtin_get_exceptionptrptr);
3150 M_ALD(REG_ITMP2, REG_PV, a);
3153 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3155 a = dseg_addaddress(cd, &_exceptionptr);
3156 M_ALD(REG_ITMP2, REG_PV, a);
3158 M_ALD(REG_ITMP1_XPTR, REG_ITMP2, 0);
3160 M_AST(REG_ITMP3, REG_ITMP2, 0);
3163 M_ILD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3164 M_IADD_IMM(REG_SP, 1 * 8, REG_SP);
3166 a = dseg_addaddress(cd, asm_handle_exception);
3167 M_ALD(REG_ITMP3, REG_PV, a);
3173 /* generate null pointer check stubs */
3177 for (bref = cd->xnullrefs; bref != NULL; bref = bref->next) {
3178 if ((m->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3179 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3181 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3185 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3187 (u1 *) mcodeptr - cd->mcodebase);
3191 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3193 if (xcodeptr != NULL) {
3194 M_BR(xcodeptr - mcodeptr - 1);
3197 xcodeptr = mcodeptr;
3199 M_IADD_IMM(REG_SP, -1 * 8, REG_SP);
3200 M_IST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3202 a = dseg_addaddress(cd, string_java_lang_NullPointerException);
3203 M_ALD(rd->argintregs[0], REG_PV, a);
3205 a = dseg_addaddress(cd, new_exception);
3206 M_ALD(REG_ITMP2, REG_PV, a);
3209 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3211 M_ILD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3212 M_IADD_IMM(REG_SP, 1 * 8, REG_SP);
3214 a = dseg_addaddress(cd, asm_handle_exception);
3215 M_ALD(REG_ITMP3, REG_PV, a);
3222 codegen_finish(m, cd, (s4) ((u1 *) mcodeptr - cd->mcodebase));
3224 asm_cacheflush((void *) m->entrypoint, ((u1 *) mcodeptr - cd->mcodebase));
3228 /* function createcompilerstub *************************************************
3230 creates a stub routine which calls the compiler
3232 *******************************************************************************/
3234 #define COMPSTUBSIZE 6
3236 u1 *createcompilerstub(methodinfo *m)
3238 s4 *s = CNEW (s4, COMPSTUBSIZE); /* memory to hold the stub */
3239 s4 *mcodeptr = s; /* code generation pointer */
3241 M_LDA(2, REG_PV, 4*4);
3242 M_ALD(REG_PV, REG_PV, 5*4);
3246 s[4] = (s4) m; /* literals to be adressed */
3247 s[5] = (s4) asm_call_jit_compiler; /* jump directly via PV from above */
3249 asm_cacheflush((void*) s, (u1*) mcodeptr - (u1*) s);
3251 #if defined(STATISTICS)
3253 count_cstub_len += COMPSTUBSIZE * 4;
3260 /* function removecompilerstub *************************************************
3262 deletes a compilerstub from memory (simply by freeing it)
3264 *******************************************************************************/
3266 void removecompilerstub(u1 *stub)
3268 CFREE(stub, COMPSTUBSIZE * 4);
3272 /* function: createnativestub **************************************************
3274 creates a stub routine which calls a native method
3276 *******************************************************************************/
3278 #define NATIVESTUBSIZE 200
3279 #define NATIVESTUBOFFSET 9
3281 u1 *createnativestub(functionptr f, methodinfo *m)
3283 s4 *s; /* memory to hold the stub */
3285 s4 *mcodeptr; /* code generation pointer */
3286 s4 stackframesize = 0; /* size of stackframe if needed */
3289 t_inlining_globals *id;
3292 /* mark start of dump memory area */
3294 dumpsize = dump_size();
3296 /* setup registers before using it */
3298 rd = DNEW(registerdata);
3299 id = DNEW(t_inlining_globals);
3301 inlining_setup(m, id);
3302 reg_setup(m, rd, id);
3304 descriptor2types(m); /* set paramcount and paramtypes */
3306 s = CNEW(s4, NATIVESTUBSIZE);
3307 cs = s + NATIVESTUBOFFSET;
3310 *(cs-1) = (u4) f; /* address of native method */
3311 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3312 *(cs-2) = (u4) builtin_get_exceptionptrptr;
3314 *(cs-2) = (u4) (&_exceptionptr); /* address of exceptionptr */
3316 *(cs-3) = (u4) asm_handle_nat_exception; /* addr of asm exception handler */
3317 *(cs-4) = (u4) (&env); /* addr of jni_environement */
3318 *(cs-5) = (u4) builtin_trace_args;
3320 *(cs-7) = (u4) builtin_displaymethodstop;
3321 *(cs-8) = (u4) m->class;
3322 *(cs-9) = (u4) asm_check_clinit;
3325 M_AST(REG_ITMP1, REG_SP, 8); /* store return address */
3326 M_LDA(REG_SP, REG_SP, -64); /* build up stackframe */
3328 /* if function is static, check for initialized */
3330 if (m->flags & ACC_STATIC) {
3331 /* if class isn't yet initialized, do it */
3332 if (!m->class->initialized) {
3333 /* call helper function which patches this code */
3334 M_ALD(REG_ITMP1, REG_PV, -8 * 4); /* class */
3335 M_ALD(REG_PV, REG_PV, -9 * 4); /* asm_check_clinit */
3338 disp = -(s4) (mcodeptr - cs) * 4;
3340 M_LDA(REG_PV, REG_ITMP1, disp); /* recompute pv from ra */
3350 /* M_MFLR(REG_ITMP3); */
3351 /* XXX must be a multiple of 16 */
3352 M_LDA(REG_SP, REG_SP, -(24 + (INT_ARG_CNT + FLT_ARG_CNT + 1) * 8));
3354 /* M_IST(REG_ITMP3, REG_SP, 24 + (INT_ARG_CNT + FLT_ARG_CNT) * 8); */
3358 /* save all arguments into the reserved stack space */
3359 for (p = 0; p < m->paramcount && p < TRACE_ARGS_NUM; p++) {
3360 t = m->paramtypes[p];
3362 if (IS_INT_LNG_TYPE(t)) {
3363 /* overlapping u8's are on the stack */
3364 if ((p + longargs + dblargs) < (INT_ARG_CNT - IS_2_WORD_TYPE(t))) {
3365 s1 = rd->argintregs[p + longargs + dblargs];
3367 if (!IS_2_WORD_TYPE(t)) {
3368 M_IST(REG_ITMP1, REG_SP, 24 + p * 8);
3369 M_IST(s1, REG_SP, 24 + p * 8 + 4);
3372 M_IST(s1, REG_SP, 24 + p * 8);
3373 M_IST(rd->secondregs[s1], REG_SP, 24 + p * 8 + 4);
3378 /* we do not have a data segment here */
3379 /* a = dseg_adds4(cd, 0xdeadbeef);
3380 M_ILD(REG_ITMP1, REG_PV, a); */
3381 M_LDA(REG_ITMP1, REG_ZERO, -1);
3382 M_IST(REG_ITMP1, REG_SP, 24 + p * 8);
3383 M_IST(REG_ITMP1, REG_SP, 24 + p * 8 + 4);
3387 if ((fltargs + dblargs) < FLT_ARG_CNT) {
3388 s1 = rd->argfltregs[fltargs + dblargs];
3390 if (!IS_2_WORD_TYPE(t)) {
3391 M_IST(REG_ITMP1, REG_SP, 24 + p * 8);
3392 M_FST(s1, REG_SP, 24 + p * 8 + 4);
3396 M_DST(s1, REG_SP, 24 + p * 8);
3401 /* this should not happen */
3406 /* TODO: save remaining integer and flaot argument registers */
3408 /* load first 4 arguments into integer argument registers */
3409 for (p = 0; p < 8; p++) {
3410 d = rd->argintregs[p];
3411 M_ILD(d, REG_SP, 24 + p * 4);
3414 M_ALD(REG_ITMP1, REG_PV, -6 * 4);
3415 M_AST(REG_ITMP1, REG_SP, 11 * 8); /* 24 (linkage area) + 32 (4 * s8 parameter area regs) + 32 (4 * s8 parameter area stack) = 88 */
3416 M_ALD(REG_ITMP2, REG_PV, -5 * 4);
3424 /* restore arguments into the reserved stack space */
3425 for (p = 0; p < m->paramcount && p < TRACE_ARGS_NUM; p++) {
3426 t = m->paramtypes[p];
3428 if (IS_INT_LNG_TYPE(t)) {
3429 if ((p + longargs + dblargs) < INT_ARG_CNT) {
3430 s1 = rd->argintregs[p + longargs + dblargs];
3432 if (!IS_2_WORD_TYPE(t)) {
3433 M_ILD(s1, REG_SP, 24 + p * 8 + 4);
3436 M_ILD(s1, REG_SP, 24 + p * 8);
3437 M_ILD(rd->secondregs[s1], REG_SP, 24 + p * 8 + 4);
3443 if ((fltargs + dblargs) < FLT_ARG_CNT) {
3444 s1 = rd->argfltregs[fltargs + dblargs];
3446 if (!IS_2_WORD_TYPE(t)) {
3447 M_FLD(s1, REG_SP, 24 + p * 8 + 4);
3451 M_DLD(s1, REG_SP, 24 + p * 8);
3458 /* M_ILD(REG_ITMP3, REG_SP, 24 + (INT_ARG_CNT + FLT_ARG_CNT) * 8); */
3460 M_LDA(REG_SP, REG_SP, 24 + (INT_ARG_CNT + FLT_ARG_CNT + 1) * 8);
3461 /* M_MTLR(REG_ITMP3); */
3464 /* save argument registers on stack -- if we have to */
3465 if ((m->flags & ACC_STATIC && m->paramcount > (INT_ARG_CNT - 2)) ||
3466 m->paramcount > (INT_ARG_CNT - 1)) {
3468 s4 paramshiftcnt = (m->flags & ACC_STATIC) ? 2 : 1;
3469 s4 stackparamcnt = (m->paramcount > INT_ARG_CNT) ? m->paramcount - INT_ARG_CNT : 0;
3471 stackframesize = stackparamcnt + paramshiftcnt;
3473 M_LDA(REG_SP, REG_SP, -stackframesize * 8);
3475 panic("nativestub");
3478 if (m->flags & ACC_STATIC) {
3479 M_MOV(rd->argintregs[5], rd->argintregs[7]);
3480 M_MOV(rd->argintregs[4], rd->argintregs[6]);
3481 M_MOV(rd->argintregs[3], rd->argintregs[5]);
3482 M_MOV(rd->argintregs[2], rd->argintregs[4]);
3483 M_MOV(rd->argintregs[1], rd->argintregs[3]);
3484 M_MOV(rd->argintregs[0], rd->argintregs[2]);
3486 /* put class into second argument register */
3487 M_ALD(rd->argintregs[1], REG_PV, -8 * 4);
3490 M_MOV(rd->argintregs[6], rd->argintregs[7]);
3491 M_MOV(rd->argintregs[5], rd->argintregs[6]);
3492 M_MOV(rd->argintregs[4], rd->argintregs[5]);
3493 M_MOV(rd->argintregs[3], rd->argintregs[4]);
3494 M_MOV(rd->argintregs[2], rd->argintregs[3]);
3495 M_MOV(rd->argintregs[1], rd->argintregs[2]);
3496 M_MOV(rd->argintregs[0], rd->argintregs[1]);
3499 /* put env into first argument register */
3500 M_ALD(rd->argintregs[0], REG_PV, -4 * 4);
3502 M_ALD(REG_PV, REG_PV, -1 * 4); /* load adress of native method */
3505 disp = -(s4) (mcodeptr - cs) * 4;
3507 M_LDA(REG_PV, REG_ITMP1, disp); /* recompute pv from ra */
3509 /* remove stackframe if there is one */
3510 if (stackframesize) {
3511 M_LDA(REG_SP, REG_SP, stackframesize * 8);
3514 /* 20 instructions */
3517 M_LDA(REG_SP, REG_SP, -10 * 8);
3518 M_DST(REG_FRESULT, REG_SP, 48+0);
3519 M_IST(REG_RESULT, REG_SP, 48+8);
3520 M_AST(REG_ITMP3, REG_SP, 48+12);
3521 M_IST(REG_RESULT2, REG_SP, 48+16);
3523 /* keep this order */
3524 switch (m->returntype) {
3527 M_MOV(REG_RESULT, rd->argintregs[2]);
3528 M_CLR(rd->argintregs[1]);
3532 M_MOV(REG_RESULT2, rd->argintregs[2]);
3533 M_MOV(REG_RESULT, rd->argintregs[1]);
3536 M_ALD(rd->argintregs[0], REG_PV, -6 * 4);
3538 M_FLTMOVE(REG_FRESULT, rd->argfltregs[0]);
3539 M_FLTMOVE(REG_FRESULT, rd->argfltregs[1]);
3540 M_ALD(REG_ITMP2, REG_PV, -7 * 4);/* builtin_displaymethodstop */
3543 M_DLD(REG_FRESULT, REG_SP, 48+0);
3544 M_ILD(REG_RESULT, REG_SP, 48+8);
3545 M_ALD(REG_ITMP3, REG_SP, 48+12);
3546 M_ILD(REG_RESULT2, REG_SP, 48+16);
3547 M_LDA(REG_SP, REG_SP, 10 * 8);
3551 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3552 if (IS_FLT_DBL_TYPE(m->returntype))
3553 if (IS_2_WORD_TYPE(m->returntype))
3554 M_DST(REG_FRESULT, REG_SP, 56);
3556 M_FST(REG_FRESULT, REG_SP, 56);
3558 M_IST(REG_RESULT, REG_SP, 56);
3559 if (IS_2_WORD_TYPE(m->returntype))
3560 M_IST(REG_RESULT2, REG_SP, 60);
3563 M_ALD(REG_ITMP2, REG_PV, -2 * 4); /* builtin_get_exceptionptrptr */
3566 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
3568 M_LDA(REG_PV, REG_ITMP1, disp);
3569 M_MOV(REG_RESULT, REG_ITMP2);
3571 if (IS_FLT_DBL_TYPE(m->returntype))
3572 if (IS_2_WORD_TYPE(m->returntype))
3573 M_DLD(REG_FRESULT, REG_SP, 56);
3575 M_FLD(REG_FRESULT, REG_SP, 56);
3577 M_ILD(REG_RESULT, REG_SP, 56);
3578 if (IS_2_WORD_TYPE(m->returntype))
3579 M_ILD(REG_RESULT2, REG_SP, 60);
3582 M_ALD(REG_ITMP2, REG_PV, -2 * 4); /* get address of exceptionptr */
3584 M_ALD(REG_ITMP1, REG_ITMP2, 0); /* load exception into reg. itmp1 */
3586 M_BNE(4); /* if no exception then return */
3588 M_ALD(REG_ITMP1, REG_SP, 64 + 8); /* load return address */
3590 M_LDA(REG_SP, REG_SP, 64); /* remove stackframe */
3595 M_AST(REG_ITMP3, REG_ITMP2, 0); /* store NULL into exceptionptr */
3597 M_ALD(REG_ITMP3, REG_SP, 64 + 8); /* load return address */
3599 M_LDA(REG_SP, REG_SP, 64); /* remove stackframe */
3601 M_LDA(REG_ITMP2, REG_ITMP1, -4); /* move fault address into reg. itmp2 */
3603 M_ALD(REG_ITMP3, REG_PV, -3 * 4); /* load asm exception handler address */
3608 dolog_plain("stubsize: %d (for %d params)\n", (int) (mcodeptr - (s4 *) s), m->paramcount);
3611 asm_cacheflush((void *) s, (u1*) mcodeptr - (u1*) s);
3613 #if defined(STATISTICS)
3615 count_nstub_len += NATIVESTUBSIZE * 4;
3618 /* release dump area */
3620 dump_release(dumpsize);
3622 return (u1*) (s + NATIVESTUBOFFSET);
3626 /* function: removenativestub **************************************************
3628 removes a previously created native-stub from memory
3630 *******************************************************************************/
3632 void removenativestub(u1 *stub)
3634 CFREE((s4 *) stub - NATIVESTUBOFFSET, NATIVESTUBSIZE * 4);
3639 * These are local overrides for various environment variables in Emacs.
3640 * Please do not remove this and leave it at the end of the file, where
3641 * Emacs will automagically detect them.
3642 * ---------------------------------------------------------------------
3645 * indent-tabs-mode: t