1 /* vm/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 1682 2004-12-05 17:22:27Z stefan $
39 #include "native/native.h"
40 #include "vm/builtin.h"
41 #include "vm/global.h"
42 #include "vm/loader.h"
43 #include "vm/tables.h"
44 #include "vm/jit/asmpart.h"
45 #include "vm/jit/jit.h"
46 #include "vm/jit/parse.h"
47 #include "vm/jit/reg.h"
48 #include "vm/jit/powerpc/arch.h"
49 #include "vm/jit/powerpc/codegen.h"
50 #include "vm/jit/powerpc/types.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 */
64 static int nregdescint[] = {
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 static 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,
81 /* Include independent code generation stuff -- include after register */
82 /* descriptions to avoid extern definitions. */
84 #include "vm/jit/codegen.inc"
85 #include "vm/jit/reg.inc"
87 #include "vm/jit/lsra.inc"
91 void asm_cacheflush(void *, long);
93 /* #include <architecture/ppc/cframe.h> */
95 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
96 void thread_restartcriticalsection(void *u)
98 /* XXX set pc to restart address */
102 #include <mach/message.h>
104 int cacao_catch_Handler(mach_port_t thread)
107 unsigned int crashpc;
109 java_objectheader *xptr;
112 thread_state_flavor_t flavor = PPC_THREAD_STATE;
113 mach_msg_type_number_t thread_state_count = PPC_THREAD_STATE_COUNT;
114 ppc_thread_state_t thread_state;
120 r = thread_get_state(thread, flavor,
121 (natural_t*)&thread_state, &thread_state_count);
122 if (r != KERN_SUCCESS)
123 panic("thread_get_state failed");
125 regs = &thread_state.r0;
126 crashpc = thread_state.srr0;
128 instr = *(s4*) crashpc;
129 reg = (instr >> 16) & 31;
132 xptr = new_nullpointerexception();
134 regs[REG_ITMP2_XPC] = crashpc;
135 regs[REG_ITMP1_XPTR] = (u4) xptr;
136 thread_state.srr0 = (u4) asm_handle_exception;
138 r = thread_set_state(thread, flavor,
139 (natural_t*)&thread_state, thread_state_count);
140 if (r != KERN_SUCCESS)
141 panic("thread_set_state failed");
146 throw_cacao_exception_exit(string_java_lang_InternalError, "Segmentation fault at %p", regs[reg]);
151 void init_exceptions(void)
156 void adjust_argvars(stackptr s, int d, int *fa, int *ia)
162 adjust_argvars(s->prev, d-1, fa, ia);
163 if (s->varkind == ARGVAR)
164 s->varnum = (IS_FLT_DBL_TYPE(s->type)) ? *fa : *ia;
165 *fa += (IS_FLT_DBL_TYPE(s->type) != 0);
166 *ia += (IS_2_WORD_TYPE(s->type)) ? 2 : 1;
170 #define intmaxf(a,b) (((a)<(b)) ? (b) : (a))
172 void preregpass(methodinfo *m, registerdata *rd)
182 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
184 for (iptr = bptr->iinstr, src = bptr->instack;
186 src = iptr->dst, len--, iptr++)
188 if (bptr->flags < BBREACHED)
201 case ICMD_INVOKEVIRTUAL:
202 case ICMD_INVOKESPECIAL:
203 case ICMD_INVOKESTATIC:
204 case ICMD_INVOKEINTERFACE:
209 adjust_argvars(src, s3, &fa, &ia);
212 for (; --s3 >= 0; src = src->prev) {
213 paramsize += IS_2_WORD_TYPE(src->type) ? 2 : 1;
215 rd->ifmemuse = intmaxf(rd->ifmemuse, paramsize);
218 case ICMD_MULTIANEWARRAY:
220 paramsize = rd->intreg_argnum + s3;
221 rd->ifmemuse = intmaxf(rd->ifmemuse, paramsize);
228 rd->maxmemuse = rd->ifmemuse;
232 /* function gen_mcode **********************************************************
234 generates machine code
236 *******************************************************************************/
238 void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
240 s4 len, s1, s2, s3, d;
256 /* space to save used callee saved registers */
258 savedregs_num += (rd->savintregcnt - rd->maxsavintreguse);
259 savedregs_num += 2 * (rd->savfltregcnt - rd->maxsavfltreguse);
261 parentargs_base = rd->maxmemuse + savedregs_num;
263 #ifdef USE_THREADS /* space to save argument of monitor_enter */
265 if (checksync && (m->flags & ACC_SYNCHRONIZED))
270 /* create method header */
272 parentargs_base = (parentargs_base + 3) & ~3;
275 (void) dseg_addaddress(cd, m); /* Filler */
277 (void) dseg_addaddress(cd, m); /* MethodPointer */
278 (void) dseg_adds4(cd, parentargs_base * 4); /* FrameSize */
282 /* IsSync contains the offset relative to the stack pointer for the
283 argument of monitor_exit used in the exception handler. Since the
284 offset could be zero and give a wrong meaning of the flag it is
288 if (checksync && (m->flags & ACC_SYNCHRONIZED))
289 (void) dseg_adds4(cd, (rd->maxmemuse + 1) * 4); /* IsSync */
294 (void) dseg_adds4(cd, 0); /* IsSync */
296 (void) dseg_adds4(cd, m->isleafmethod); /* IsLeaf */
297 (void) dseg_adds4(cd, rd->savintregcnt - rd->maxsavintreguse); /* IntSave */
298 (void) dseg_adds4(cd, rd->savfltregcnt - rd->maxsavfltreguse); /* FltSave */
299 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
301 /* create exception table */
303 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
304 dseg_addtarget(cd, ex->start);
305 dseg_addtarget(cd, ex->end);
306 dseg_addtarget(cd, ex->handler);
307 (void) dseg_addaddress(cd, ex->catchtype);
310 /* initialize mcode variables */
312 mcodeptr = (s4 *) cd->mcodebase;
313 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
314 MCODECHECK(128 + m->paramcount);
316 /* create stack frame (if necessary) */
318 if (!m->isleafmethod) {
320 M_AST(REG_ITMP3, REG_SP, 8);
323 if (parentargs_base) {
324 M_STWU(REG_SP, REG_SP, -parentargs_base * 4);
327 /* save return address and used callee saved registers */
330 for (i = rd->savintregcnt - 1; i >= rd->maxsavintreguse; i--) {
331 p--; M_IST(rd->savintregs[i], REG_SP, 4 * p);
333 for (i = rd->savfltregcnt - 1; i >= rd->maxsavfltreguse; i--) {
334 p-=2; M_DST(rd->savfltregs[i], REG_SP, 4 * p);
337 /* save monitorenter argument */
339 #if defined(USE_THREADS)
340 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
341 if (m->flags & ACC_STATIC) {
342 p = dseg_addaddress(cd, m->class);
343 M_ALD(REG_ITMP1, REG_PV, p);
344 M_AST(REG_ITMP1, REG_SP, 4 * rd->maxmemuse);
347 M_AST(rd->argintregs[0], REG_SP, 4 * rd->maxmemuse);
352 /* copy argument registers to stack and call trace function with pointer
353 to arguments on stack.
362 /* XXX must be a multiple of 16 */
363 M_LDA(REG_SP, REG_SP, -(24 + (INT_ARG_CNT + FLT_ARG_CNT + 1) * 8));
365 M_IST(REG_ITMP3, REG_SP, 24 + (INT_ARG_CNT + FLT_ARG_CNT) * 8);
367 M_CLR(REG_ITMP1); /* clear help register */
369 /* save all arguments into the reserved stack space */
370 for (p = 0; p < m->paramcount && p < TRACE_ARGS_NUM; p++) {
371 t = m->paramtypes[p];
373 if (IS_INT_LNG_TYPE(t)) {
374 /* overlapping u8's are on the stack */
375 if ((p + longargs + dblargs) < (INT_ARG_CNT - IS_2_WORD_TYPE(t))) {
376 s1 = rd->argintregs[p + longargs + dblargs];
378 if (!IS_2_WORD_TYPE(t)) {
379 M_IST(REG_ITMP1, REG_SP, 24 + p * 8);
380 M_IST(s1, REG_SP, 24 + p * 8 + 4);
383 M_IST(s1, REG_SP, 24 + p * 8);
384 M_IST(rd->secondregs[s1], REG_SP, 24 + p * 8 + 4);
389 a = dseg_adds4(cd, 0xdeadbeef);
390 M_ILD(REG_ITMP1, REG_PV, a);
391 M_IST(REG_ITMP1, REG_SP, 24 + p * 8);
392 M_IST(REG_ITMP1, REG_SP, 24 + p * 8 + 4);
396 if ((fltargs + dblargs) < FLT_ARG_CNT) {
397 s1 = rd->argfltregs[fltargs + dblargs];
399 if (!IS_2_WORD_TYPE(t)) {
400 M_IST(REG_ITMP1, REG_SP, 24 + p * 8);
401 M_FST(s1, REG_SP, 24 + p * 8 + 4);
405 M_DST(s1, REG_SP, 24 + p * 8);
410 /* this should not happen */
415 /* TODO: save remaining integer and flaot argument registers */
417 /* load first 4 arguments into integer argument registers */
418 for (p = 0; p < 8; p++) {
419 d = rd->argintregs[p];
420 M_ILD(d, REG_SP, 24 + p * 4);
423 p = dseg_addaddress(cd, m);
424 M_ALD(REG_ITMP1, REG_PV, p);
425 M_AST(REG_ITMP1, REG_SP, 11 * 8); /* 24 (linkage area) + 32 (4 * s8 parameter area regs) + 32 (4 * s8 parameter area stack) = 88 */
426 p = dseg_addaddress(cd, (void *) builtin_trace_args);
427 M_ALD(REG_ITMP2, REG_PV, p);
435 /* restore arguments into the reserved stack space */
436 for (p = 0; p < m->paramcount && p < TRACE_ARGS_NUM; p++) {
437 t = m->paramtypes[p];
439 if (IS_INT_LNG_TYPE(t)) {
440 if ((p + longargs + dblargs) < INT_ARG_CNT) {
441 s1 = rd->argintregs[p + longargs + dblargs];
443 if (!IS_2_WORD_TYPE(t)) {
444 M_ILD(s1, REG_SP, 24 + p * 8 + 4);
447 M_ILD(s1, REG_SP, 24 + p * 8);
448 M_ILD(rd->secondregs[s1], REG_SP, 24 + p * 8 + 4);
454 if ((fltargs + dblargs) < FLT_ARG_CNT) {
455 s1 = rd->argfltregs[fltargs + dblargs];
457 if (!IS_2_WORD_TYPE(t)) {
458 M_FLD(s1, REG_SP, 24 + p * 8 + 4);
462 M_DLD(s1, REG_SP, 24 + p * 8);
469 M_ILD(REG_ITMP3, REG_SP, 24 + (INT_ARG_CNT + FLT_ARG_CNT) * 8);
471 M_LDA(REG_SP, REG_SP, 24 + (INT_ARG_CNT + FLT_ARG_CNT + 1) * 8);
475 /* take arguments out of register or stack frame */
481 for (p = 0, l = 0; p < m->paramcount; p++) {
482 arg = narg; iarg = niarg;
483 t = m->paramtypes[p];
484 var = &(rd->locals[l][t]);
486 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
490 if (IS_INT_LNG_TYPE(t)) { /* integer args */
491 if (iarg < INT_ARG_CNT -
492 (IS_2_WORD_TYPE(t)!=0)) { /* register arguments */
493 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
494 M_TINTMOVE(t, rd->argintregs[iarg], var->regoff);
496 } else { /* reg arg -> spilled */
497 M_IST(rd->argintregs[iarg], REG_SP, 4 * var->regoff);
498 if (IS_2_WORD_TYPE(t))
499 M_IST(rd->secondregs[rd->argintregs[iarg]], REG_SP, 4 * var->regoff + 4);
502 } else { /* stack arguments */
504 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
505 M_ILD(var->regoff, REG_SP, 4 * (parentargs_base + pa));
506 if (IS_2_WORD_TYPE(t))
507 M_ILD(rd->secondregs[var->regoff], REG_SP, 4 * (parentargs_base + pa) + 4);
509 } else { /* stack arg -> spilled */
510 M_ILD(REG_ITMP1, REG_SP, 4 * (parentargs_base + pa));
511 M_IST(REG_ITMP1, REG_SP, 4 * var->regoff);
512 if (IS_2_WORD_TYPE(t)) {
513 M_ILD(REG_ITMP1, REG_SP, 4 * (parentargs_base + pa) + 4);
514 M_IST(REG_ITMP1, REG_SP, 4 * var->regoff + 4);
519 } else { /* floating args */
521 if (arg < FLT_ARG_CNT) { /* register arguments */
522 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
523 M_FLTMOVE(rd->argfltregs[arg], var->regoff);
525 } else { /* reg arg -> spilled */
526 M_DST(rd->argfltregs[arg], REG_SP, 4 * var->regoff);
529 } else { /* stack arguments */
531 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
532 if (IS_2_WORD_TYPE(t)) {
533 M_DLD(var->regoff, REG_SP, 4 * (parentargs_base + pa));
536 M_FLD(var->regoff, REG_SP, 4 * (parentargs_base + pa));
539 } else { /* stack-arg -> spilled */
540 if (IS_2_WORD_TYPE(t)) {
541 M_DLD(REG_FTMP1, REG_SP, 4 * (parentargs_base + pa));
544 M_FLD(REG_FTMP1, REG_SP, 4 * (parentargs_base + pa));
546 M_DST(REG_FTMP1, REG_SP, 4 * var->regoff);
553 /* call monitorenter function */
555 #if defined(USE_THREADS)
556 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
557 s4 func_enter = (m->flags & ACC_STATIC) ?
558 (s4) builtin_staticmonitorenter : (s4) builtin_monitorenter;
559 p = dseg_addaddress(cd, (void *) func_enter);
560 M_ALD(REG_ITMP3, REG_PV, p);
562 M_ALD(rd->argintregs[0], REG_SP, rd->maxmemuse * 4);
568 /* end of header generation */
570 /* walk through all basic blocks */
571 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
573 bptr->mpc = (s4) ((u1 *) mcodeptr - cd->mcodebase);
575 if (bptr->flags >= BBREACHED) {
577 /* branch resolving */
581 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
582 gen_resolvebranch((u1*) cd->mcodebase + brefs->branchpos,
588 /* copy interface registers to their destination */
593 while (src != NULL) {
595 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
596 d = reg_of_var(rd, src, REG_ITMP1);
597 M_INTMOVE(REG_ITMP1, d);
598 store_reg_to_var_int(src, d);
601 d = reg_of_var(rd, src, REG_IFTMP);
602 if ((src->varkind != STACKVAR)) {
604 if (IS_FLT_DBL_TYPE(s2)) {
605 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
606 s1 = rd->interfaces[len][s2].regoff;
610 if (IS_2_WORD_TYPE(s2)) {
611 M_DLD(d, REG_SP, 4 * rd->interfaces[len][s2].regoff);
614 M_FLD(d, REG_SP, 4 * rd->interfaces[len][s2].regoff);
617 store_reg_to_var_flt(src, d);
620 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
621 s1 = rd->interfaces[len][s2].regoff;
625 M_ILD(d, REG_SP, 4 * rd->interfaces[len][s2].regoff);
626 if (IS_2_WORD_TYPE(s2))
627 M_ILD(rd->secondregs[d], REG_SP, 4 * rd->interfaces[len][s2].regoff + 4);
629 store_reg_to_var_int(src, d);
636 /* walk through all instructions */
640 for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
642 MCODECHECK(64); /* an instruction usually needs < 64 words */
645 case ICMD_NOP: /* ... ==> ... */
648 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
650 var_to_reg_int(s1, src, REG_ITMP1);
653 codegen_addxnullrefs(cd, mcodeptr);
656 /* constant operations ************************************************/
658 case ICMD_ICONST: /* ... ==> ..., constant */
659 /* op1 = 0, val.i = constant */
661 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
662 ICONST(d, iptr->val.i);
663 store_reg_to_var_int(iptr->dst, d);
666 case ICMD_LCONST: /* ... ==> ..., constant */
667 /* op1 = 0, val.l = constant */
669 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
670 LCONST(d, iptr->val.l);
671 store_reg_to_var_int(iptr->dst, d);
674 case ICMD_FCONST: /* ... ==> ..., constant */
675 /* op1 = 0, val.f = constant */
677 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
678 a = dseg_addfloat(cd, iptr->val.f);
680 store_reg_to_var_flt(iptr->dst, d);
683 case ICMD_DCONST: /* ... ==> ..., constant */
684 /* op1 = 0, val.d = constant */
686 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
687 a = dseg_adddouble(cd, iptr->val.d);
689 store_reg_to_var_flt(iptr->dst, d);
692 case ICMD_ACONST: /* ... ==> ..., constant */
693 /* op1 = 0, val.a = constant */
695 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
696 ICONST(d, (u4) iptr->val.a);
697 store_reg_to_var_int(iptr->dst, d);
701 /* load/store operations **********************************************/
703 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
704 case ICMD_LLOAD: /* op1 = local variable */
707 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
708 if ((iptr->dst->varkind == LOCALVAR) &&
709 (iptr->dst->varnum == iptr->op1))
711 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
712 if (var->flags & INMEMORY) {
713 M_ILD(d, REG_SP, 4 * var->regoff);
714 if (IS_2_WORD_TYPE(var->type))
715 M_ILD(rd->secondregs[d], REG_SP, 4 * var->regoff + 4);
717 M_TINTMOVE(var->type, var->regoff, d);
719 store_reg_to_var_int(iptr->dst, d);
722 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
723 case ICMD_DLOAD: /* op1 = local variable */
725 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
726 if ((iptr->dst->varkind == LOCALVAR) &&
727 (iptr->dst->varnum == iptr->op1))
729 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
730 if (var->flags & INMEMORY)
731 if (IS_2_WORD_TYPE(var->type))
732 M_DLD(d, REG_SP, 4 * var->regoff);
734 M_FLD(d, REG_SP, 4 * var->regoff);
736 M_FLTMOVE(var->regoff, d);
738 store_reg_to_var_flt(iptr->dst, d);
742 case ICMD_ISTORE: /* ..., value ==> ... */
743 case ICMD_LSTORE: /* op1 = local variable */
746 if ((src->varkind == LOCALVAR) &&
747 (src->varnum == iptr->op1))
749 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
750 if (var->flags & INMEMORY) {
751 var_to_reg_int(s1, src, REG_ITMP1);
752 M_IST(s1, REG_SP, 4 * var->regoff);
753 if (IS_2_WORD_TYPE(var->type))
754 M_IST(rd->secondregs[s1], REG_SP, 4 * var->regoff + 4);
756 var_to_reg_int(s1, src, var->regoff);
757 M_TINTMOVE(var->type, s1, var->regoff);
761 case ICMD_FSTORE: /* ..., value ==> ... */
762 case ICMD_DSTORE: /* op1 = local variable */
764 if ((src->varkind == LOCALVAR) &&
765 (src->varnum == iptr->op1))
767 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
768 if (var->flags & INMEMORY) {
769 var_to_reg_flt(s1, src, REG_FTMP1);
770 if (var->type == TYPE_DBL)
771 M_DST(s1, REG_SP, 4 * var->regoff);
773 M_FST(s1, REG_SP, 4 * var->regoff);
775 var_to_reg_flt(s1, src, var->regoff);
776 M_FLTMOVE(s1, var->regoff);
781 /* pop/dup/swap operations ********************************************/
783 /* attention: double and longs are only one entry in CACAO ICMDs */
785 case ICMD_POP: /* ..., value ==> ... */
786 case ICMD_POP2: /* ..., value, value ==> ... */
789 case ICMD_DUP: /* ..., a ==> ..., a, a */
790 M_COPY(src, iptr->dst);
793 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
795 M_COPY(src, iptr->dst);
796 M_COPY(src->prev, iptr->dst->prev);
797 M_COPY(iptr->dst, iptr->dst->prev->prev);
800 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
802 M_COPY(src, iptr->dst);
803 M_COPY(src->prev, iptr->dst->prev);
804 M_COPY(src->prev->prev, iptr->dst->prev->prev);
805 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
808 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
810 M_COPY(src, iptr->dst);
811 M_COPY(src->prev, iptr->dst->prev);
814 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
816 M_COPY(src, iptr->dst);
817 M_COPY(src->prev, iptr->dst->prev);
818 M_COPY(src->prev->prev, iptr->dst->prev->prev);
819 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
820 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev);
823 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
825 M_COPY(src, iptr->dst);
826 M_COPY(src->prev, iptr->dst->prev);
827 M_COPY(src->prev->prev, iptr->dst->prev->prev);
828 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
829 M_COPY(iptr->dst, iptr->dst->prev->prev->prev->prev);
830 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev->prev);
833 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
835 M_COPY(src, iptr->dst->prev);
836 M_COPY(src->prev, iptr->dst);
840 /* integer operations *************************************************/
842 case ICMD_INEG: /* ..., value ==> ..., - value */
844 var_to_reg_int(s1, src, REG_ITMP1);
845 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
847 store_reg_to_var_int(iptr->dst, d);
850 case ICMD_LNEG: /* ..., value ==> ..., - value */
852 var_to_reg_int(s1, src, REG_ITMP1);
853 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
854 M_SUBFIC(rd->secondregs[s1], 0, rd->secondregs[d]);
856 store_reg_to_var_int(iptr->dst, d);
859 case ICMD_I2L: /* ..., value ==> ..., value */
861 var_to_reg_int(s1, src, REG_ITMP2);
862 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
863 M_INTMOVE(s1, rd->secondregs[d]);
864 M_SRA_IMM(rd->secondregs[d], 31, d);
865 store_reg_to_var_int(iptr->dst, d);
868 case ICMD_L2I: /* ..., value ==> ..., value */
870 var_to_reg_int0(s1, src, REG_ITMP2, 0, 1);
871 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
873 store_reg_to_var_int(iptr->dst, d);
876 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
878 var_to_reg_int(s1, src, REG_ITMP1);
879 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
881 store_reg_to_var_int(iptr->dst, d);
884 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
886 var_to_reg_int(s1, src, REG_ITMP1);
887 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
889 store_reg_to_var_int(iptr->dst, d);
892 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
894 var_to_reg_int(s1, src, REG_ITMP1);
895 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
897 store_reg_to_var_int(iptr->dst, d);
901 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
903 var_to_reg_int(s1, src->prev, REG_ITMP1);
904 var_to_reg_int(s2, src, REG_ITMP2);
905 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
907 store_reg_to_var_int(iptr->dst, d);
910 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
911 /* val.i = constant */
913 var_to_reg_int(s1, src, REG_ITMP1);
914 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
915 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
916 M_IADD_IMM(s1, iptr->val.i, d);
919 ICONST(REG_ITMP2, iptr->val.i);
920 M_IADD(s1, REG_ITMP2, d);
922 store_reg_to_var_int(iptr->dst, d);
925 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
927 var_to_reg_int0(s1, src->prev, REG_ITMP1, 0, 1);
928 var_to_reg_int0(s2, src, REG_ITMP2, 0, 1);
929 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
930 M_ADDC(s1, s2, rd->secondregs[d]);
931 var_to_reg_int0(s1, src->prev, REG_ITMP1, 1, 0);
932 var_to_reg_int0(s2, src, REG_ITMP3, 1, 0);
934 store_reg_to_var_int(iptr->dst, d);
937 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
938 /* val.l = constant */
940 s3 = iptr->val.l & 0xffffffff;
941 var_to_reg_int0(s1, src, REG_ITMP1, 0, 1);
942 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
943 if ((s3 >= -32768) && (s3 <= 32767)) {
944 M_ADDIC(s1, s3, rd->secondregs[d]);
947 ICONST(REG_ITMP2, s3);
948 M_ADDC(s1, REG_ITMP2, rd->secondregs[d]);
950 var_to_reg_int0(s1, src, REG_ITMP1, 1, 0);
951 s3 = iptr->val.l >> 32;
957 ICONST(REG_ITMP3, s3);
958 M_ADDE(s1, REG_ITMP3, d);
960 store_reg_to_var_int(iptr->dst, d);
963 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
965 var_to_reg_int(s1, src->prev, REG_ITMP1);
966 var_to_reg_int(s2, src, REG_ITMP2);
967 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
969 store_reg_to_var_int(iptr->dst, d);
972 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
973 /* val.i = constant */
975 var_to_reg_int(s1, src, REG_ITMP1);
976 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
977 if ((iptr->val.i >= -32767) && (iptr->val.i <= 32768)) {
978 M_IADD_IMM(s1, -iptr->val.i, d);
981 ICONST(REG_ITMP2, -iptr->val.i);
982 M_IADD(s1, REG_ITMP2, d);
984 store_reg_to_var_int(iptr->dst, d);
987 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
989 var_to_reg_int0(s1, src->prev, REG_ITMP1, 0, 1);
990 var_to_reg_int0(s2, src, REG_ITMP2, 0, 1);
991 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
992 M_SUBC(s1, s2, rd->secondregs[d]);
993 var_to_reg_int0(s1, src->prev, REG_ITMP1, 1, 0);
994 var_to_reg_int0(s2, src, REG_ITMP3, 1, 0);
996 store_reg_to_var_int(iptr->dst, d);
999 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
1000 /* val.l = constant */
1002 s3 = (-iptr->val.l) & 0xffffffff;
1003 var_to_reg_int0(s1, src, REG_ITMP1, 0, 1);
1004 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1005 if ((s3 >= -32768) && (s3 <= 32767)) {
1006 M_ADDIC(s1, s3, rd->secondregs[d]);
1009 ICONST(REG_ITMP2, s3);
1010 M_ADDC(s1, REG_ITMP2, rd->secondregs[d]);
1012 var_to_reg_int0(s1, src, REG_ITMP1, 1, 0);
1013 s3 = (-iptr->val.l) >> 32;
1019 ICONST(REG_ITMP3, s3);
1020 M_ADDE(s1, REG_ITMP3, d);
1022 store_reg_to_var_int(iptr->dst, d);
1025 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1026 var_to_reg_int(s1, src->prev, REG_ITMP1);
1027 var_to_reg_int(s2, src, REG_ITMP2);
1028 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1030 store_reg_to_var_int(iptr->dst, d);
1033 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1034 var_to_reg_int(s1, src->prev, REG_ITMP1);
1035 var_to_reg_int(s2, src, REG_ITMP2);
1036 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1040 store_reg_to_var_int(iptr->dst, d);
1043 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1045 var_to_reg_int(s1, src->prev, REG_ITMP1);
1046 var_to_reg_int(s2, src, REG_ITMP2);
1047 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1049 store_reg_to_var_int(iptr->dst, d);
1052 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
1053 /* val.i = constant */
1055 var_to_reg_int(s1, src, REG_ITMP1);
1056 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1057 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
1058 M_IMUL_IMM(s1, iptr->val.i, d);
1061 ICONST(REG_ITMP2, iptr->val.i);
1062 M_IMUL(s1, REG_ITMP2, d);
1064 store_reg_to_var_int(iptr->dst, d);
1067 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
1069 var_to_reg_int(s1, src, REG_ITMP1);
1070 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1071 M_SRA_IMM(s1, iptr->val.i, d);
1073 store_reg_to_var_int(iptr->dst, d);
1076 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1078 var_to_reg_int(s1, src->prev, REG_ITMP1);
1079 var_to_reg_int(s2, src, REG_ITMP2);
1080 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1081 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1082 M_SLL(s1, REG_ITMP3, d);
1083 store_reg_to_var_int(iptr->dst, d);
1086 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1087 /* val.i = constant */
1089 var_to_reg_int(s1, src, REG_ITMP1);
1090 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1091 M_SLL_IMM(s1, iptr->val.i & 0x1f, d);
1092 store_reg_to_var_int(iptr->dst, d);
1095 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1097 var_to_reg_int(s1, src->prev, REG_ITMP1);
1098 var_to_reg_int(s2, src, REG_ITMP2);
1099 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1100 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1101 M_SRA(s1, REG_ITMP3, d);
1102 store_reg_to_var_int(iptr->dst, d);
1105 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1106 /* val.i = constant */
1108 var_to_reg_int(s1, src, REG_ITMP1);
1109 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1110 M_SRA_IMM(s1, iptr->val.i & 0x1f, d);
1111 store_reg_to_var_int(iptr->dst, d);
1114 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1116 var_to_reg_int(s1, src->prev, REG_ITMP1);
1117 var_to_reg_int(s2, src, REG_ITMP2);
1118 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1119 M_AND_IMM(s2, 0x1f, REG_ITMP2);
1120 M_SRL(s1, REG_ITMP2, d);
1121 store_reg_to_var_int(iptr->dst, d);
1124 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1125 /* val.i = constant */
1127 var_to_reg_int(s1, src, REG_ITMP1);
1128 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1129 if (iptr->val.i & 0x1f)
1130 M_SRL_IMM(s1, iptr->val.i & 0x1f, d);
1133 store_reg_to_var_int(iptr->dst, d);
1136 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1138 var_to_reg_int(s1, src->prev, REG_ITMP1);
1139 var_to_reg_int(s2, src, REG_ITMP2);
1140 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1142 store_reg_to_var_int(iptr->dst, d);
1145 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1146 /* val.i = constant */
1148 var_to_reg_int(s1, src, REG_ITMP1);
1149 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1150 if ((iptr->val.i >= 0) && (iptr->val.i <= 65535)) {
1151 M_AND_IMM(s1, iptr->val.i, d);
1154 else if (iptr->val.i == 0xffffff) {
1155 M_RLWINM(s1, 0, 8, 31, d);
1159 ICONST(REG_ITMP2, iptr->val.i);
1160 M_AND(s1, REG_ITMP2, d);
1162 store_reg_to_var_int(iptr->dst, d);
1165 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1167 var_to_reg_int0(s1, src->prev, REG_ITMP1, 0, 1);
1168 var_to_reg_int0(s2, src, REG_ITMP2, 0, 1);
1169 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1170 M_AND(s1, s2, rd->secondregs[d]);
1171 var_to_reg_int0(s1, src->prev, REG_ITMP1, 1, 0);
1172 var_to_reg_int0(s2, src, REG_ITMP3, 1, 0);
1174 store_reg_to_var_int(iptr->dst, d);
1177 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1178 /* val.l = constant */
1180 s3 = iptr->val.l & 0xffffffff;
1181 var_to_reg_int0(s1, src, REG_ITMP1, 0, 1);
1182 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1183 if ((s3 >= 0) && (s3 <= 65535)) {
1184 M_AND_IMM(s1, s3, rd->secondregs[d]);
1187 ICONST(REG_ITMP2, s3);
1188 M_AND(s1, REG_ITMP2, rd->secondregs[d]);
1190 var_to_reg_int0(s1, src, REG_ITMP1, 1, 0);
1191 s3 = iptr->val.l >> 32;
1192 if ((s3 >= 0) && (s3 <= 65535)) {
1193 M_AND_IMM(s1, s3, d);
1196 ICONST(REG_ITMP3, s3);
1197 M_AND(s1, REG_ITMP3, d);
1199 store_reg_to_var_int(iptr->dst, d);
1202 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1203 /* val.i = constant */
1205 var_to_reg_int(s1, src, REG_ITMP1);
1206 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1207 M_MOV(s1, REG_ITMP2);
1209 M_BGE(1 + 2*(iptr->val.i >= 32768));
1210 if (iptr->val.i >= 32768) {
1211 M_ADDIS(REG_ZERO, iptr->val.i>>16, REG_ITMP2);
1212 M_OR_IMM(REG_ITMP2, iptr->val.i, REG_ITMP2);
1213 M_IADD(s1, REG_ITMP2, REG_ITMP2);
1216 M_IADD_IMM(s1, iptr->val.i, REG_ITMP2);
1218 int b=0, m = iptr->val.i;
1221 M_RLWINM(REG_ITMP2, 0, 0, 30-b, REG_ITMP2);
1223 M_ISUB(s1, REG_ITMP2, d);
1224 store_reg_to_var_int(iptr->dst, d);
1227 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1229 var_to_reg_int(s1, src->prev, REG_ITMP1);
1230 var_to_reg_int(s2, src, REG_ITMP2);
1231 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1233 store_reg_to_var_int(iptr->dst, d);
1236 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1237 /* val.i = constant */
1239 var_to_reg_int(s1, src, REG_ITMP1);
1240 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1241 if ((iptr->val.i >= 0) && (iptr->val.i <= 65535)) {
1242 M_OR_IMM(s1, iptr->val.i, d);
1245 ICONST(REG_ITMP2, iptr->val.i);
1246 M_OR(s1, REG_ITMP2, d);
1248 store_reg_to_var_int(iptr->dst, d);
1251 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1253 var_to_reg_int0(s1, src->prev, REG_ITMP1, 0, 1);
1254 var_to_reg_int0(s2, src, REG_ITMP2, 0, 1);
1255 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1256 M_OR(s1, s2, rd->secondregs[d]);
1257 var_to_reg_int0(s1, src->prev, REG_ITMP1, 1, 0);
1258 var_to_reg_int0(s2, src, REG_ITMP3, 1, 0);
1260 store_reg_to_var_int(iptr->dst, d);
1263 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1264 /* val.l = constant */
1266 s3 = iptr->val.l & 0xffffffff;
1267 var_to_reg_int0(s1, src, REG_ITMP1, 0, 1);
1268 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1269 if ((s3 >= 0) && (s3 <= 65535)) {
1270 M_OR_IMM(s1, s3, rd->secondregs[d]);
1273 ICONST(REG_ITMP2, s3);
1274 M_OR(s1, REG_ITMP2, rd->secondregs[d]);
1276 var_to_reg_int0(s1, src, REG_ITMP1, 1, 0);
1277 s3 = iptr->val.l >> 32;
1278 if ((s3 >= 0) && (s3 <= 65535)) {
1279 M_OR_IMM(s1, s3, d);
1282 ICONST(REG_ITMP3, s3);
1283 M_OR(s1, REG_ITMP3, d);
1285 store_reg_to_var_int(iptr->dst, d);
1288 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1290 var_to_reg_int(s1, src->prev, REG_ITMP1);
1291 var_to_reg_int(s2, src, REG_ITMP2);
1292 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1294 store_reg_to_var_int(iptr->dst, d);
1297 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1298 /* val.i = constant */
1300 var_to_reg_int(s1, src, REG_ITMP1);
1301 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1302 if ((iptr->val.i >= 0) && (iptr->val.i <= 65535)) {
1303 M_XOR_IMM(s1, iptr->val.i, d);
1306 ICONST(REG_ITMP2, iptr->val.i);
1307 M_XOR(s1, REG_ITMP2, d);
1309 store_reg_to_var_int(iptr->dst, d);
1312 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1314 var_to_reg_int0(s1, src->prev, REG_ITMP1, 0, 1);
1315 var_to_reg_int0(s2, src, REG_ITMP2, 0, 1);
1316 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1317 M_XOR(s1, s2, rd->secondregs[d]);
1318 var_to_reg_int0(s1, src->prev, REG_ITMP1, 1, 0);
1319 var_to_reg_int0(s2, src, REG_ITMP3, 1, 0);
1321 store_reg_to_var_int(iptr->dst, d);
1324 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1325 /* val.l = constant */
1327 s3 = iptr->val.l & 0xffffffff;
1328 var_to_reg_int0(s1, src, REG_ITMP1, 0, 1);
1329 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1330 if ((s3 >= 0) && (s3 <= 65535)) {
1331 M_XOR_IMM(s1, s3, rd->secondregs[d]);
1334 ICONST(REG_ITMP2, s3);
1335 M_XOR(s1, REG_ITMP2, rd->secondregs[d]);
1337 var_to_reg_int0(s1, src, REG_ITMP1, 1, 0);
1338 s3 = iptr->val.l >> 32;
1339 if ((s3 >= 0) && (s3 <= 65535)) {
1340 M_XOR_IMM(s1, s3, d);
1343 ICONST(REG_ITMP3, s3);
1344 M_XOR(s1, REG_ITMP3, d);
1346 store_reg_to_var_int(iptr->dst, d);
1349 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1351 var_to_reg_int0(s1, src->prev, REG_ITMP3, 1, 0);
1352 var_to_reg_int0(s2, src, REG_ITMP2, 1, 0);
1353 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
1356 (d==s1 || d==s2 || d==rd->secondregs[s1] || d==rd->secondregs[s2]);
1357 int dreg = tempreg ? REG_ITMP1 : d;
1359 M_IADD_IMM(REG_ZERO, 1, dreg);
1364 var_to_reg_int0(s1, src->prev, REG_ITMP3, 0, 1);
1365 var_to_reg_int0(s2, src, REG_ITMP2, 0, 1);
1369 M_IADD_IMM(dreg, -1, dreg);
1370 M_IADD_IMM(dreg, -1, dreg);
1371 gen_resolvebranch(br1, (u1*) br1, (u1*) mcodeptr);
1372 gen_resolvebranch(br1+1, (u1*) (br1+1), (u1*) (mcodeptr-2));
1375 store_reg_to_var_int(iptr->dst, d);
1378 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1379 /* op1 = variable, val.i = constant */
1381 var = &(rd->locals[iptr->op1][TYPE_INT]);
1382 if (var->flags & INMEMORY) {
1384 M_ILD(s1, REG_SP, 4 * var->regoff);
1393 M_ADDIS(s1, m>>16, s1);
1395 M_IADD_IMM(s1, m&0xffff, s1);
1397 if (var->flags & INMEMORY)
1398 M_IST(s1, REG_SP, 4 * var->regoff);
1402 /* floating operations ************************************************/
1404 case ICMD_FNEG: /* ..., value ==> ..., - value */
1406 var_to_reg_flt(s1, src, REG_FTMP1);
1407 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1409 store_reg_to_var_flt(iptr->dst, d);
1412 case ICMD_DNEG: /* ..., value ==> ..., - value */
1414 var_to_reg_flt(s1, src, REG_FTMP1);
1415 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1417 store_reg_to_var_flt(iptr->dst, d);
1420 case ICMD_FADD: /* ..., 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(rd, iptr->dst, REG_FTMP3);
1426 store_reg_to_var_flt(iptr->dst, d);
1429 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1431 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1432 var_to_reg_flt(s2, src, REG_FTMP2);
1433 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1435 store_reg_to_var_flt(iptr->dst, d);
1438 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1440 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1441 var_to_reg_flt(s2, src, REG_FTMP2);
1442 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1444 store_reg_to_var_flt(iptr->dst, d);
1447 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1449 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1450 var_to_reg_flt(s2, src, REG_FTMP2);
1451 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1453 store_reg_to_var_flt(iptr->dst, d);
1456 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1458 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1459 var_to_reg_flt(s2, src, REG_FTMP2);
1460 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1462 store_reg_to_var_flt(iptr->dst, d);
1465 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1467 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1468 var_to_reg_flt(s2, src, REG_FTMP2);
1469 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1471 store_reg_to_var_flt(iptr->dst, d);
1474 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1476 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1477 var_to_reg_flt(s2, src, REG_FTMP2);
1478 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1480 store_reg_to_var_flt(iptr->dst, d);
1483 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1485 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1486 var_to_reg_flt(s2, src, REG_FTMP2);
1487 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1489 store_reg_to_var_flt(iptr->dst, d);
1492 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1494 var_to_reg_flt(s1, src, REG_FTMP1);
1495 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1497 a = dseg_addfloat(cd, 0.0);
1498 M_FLD(REG_FTMP2, REG_PV, a);
1499 M_FCMPU(s1, REG_FTMP2);
1501 a = dseg_adds4(cd, 0);
1502 M_CVTDL_C(s1, REG_FTMP1);
1503 M_LDA (REG_ITMP1, REG_PV, a);
1504 M_STFIWX(REG_FTMP1, 0, REG_ITMP1);
1505 M_ILD (d, REG_PV, a);
1506 store_reg_to_var_int(iptr->dst, d);
1509 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1511 var_to_reg_flt(s1, src, REG_FTMP1);
1512 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1514 store_reg_to_var_flt(iptr->dst, d);
1517 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1519 var_to_reg_flt(s1, src, REG_FTMP1);
1520 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1522 store_reg_to_var_flt(iptr->dst, d);
1525 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1527 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1528 var_to_reg_flt(s2, src, REG_FTMP2);
1529 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1531 M_IADD_IMM(0, -1, d);
1534 M_IADD_IMM(0, 0, d);
1536 M_IADD_IMM(0, 1, d);
1537 store_reg_to_var_int(iptr->dst, d);
1540 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1542 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1543 var_to_reg_flt(s2, src, REG_FTMP2);
1544 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1546 M_IADD_IMM(0, 1, d);
1549 M_IADD_IMM(0, 0, d);
1551 M_IADD_IMM(0, -1, d);
1552 store_reg_to_var_int(iptr->dst, d);
1556 /* memory operations **************************************************/
1558 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1560 var_to_reg_int(s1, src, REG_ITMP1);
1561 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1562 gen_nullptr_check(s1);
1563 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1564 store_reg_to_var_int(iptr->dst, d);
1567 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1569 var_to_reg_int(s1, src->prev, REG_ITMP1);
1570 var_to_reg_int(s2, src, REG_ITMP2);
1571 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1572 if (iptr->op1 == 0) {
1573 gen_nullptr_check(s1);
1576 M_SLL_IMM(s2, 2, REG_ITMP2);
1577 M_IADD_IMM(REG_ITMP2, OFFSET(java_objectarray, data[0]), REG_ITMP2);
1578 M_LWZX(d, s1, REG_ITMP2);
1579 store_reg_to_var_int(iptr->dst, d);
1582 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1584 var_to_reg_int(s1, src->prev, REG_ITMP1);
1585 var_to_reg_int(s2, src, REG_ITMP2);
1586 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1587 if (iptr->op1 == 0) {
1588 gen_nullptr_check(s1);
1591 M_SLL_IMM(s2, 3, REG_ITMP2);
1592 M_IADD(s1, REG_ITMP2, REG_ITMP2);
1593 M_ILD(d, REG_ITMP2, OFFSET(java_longarray, data[0]));
1594 M_ILD(rd->secondregs[d], REG_ITMP2, OFFSET(java_longarray, data[0])+4);
1595 store_reg_to_var_int(iptr->dst, d);
1598 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1600 var_to_reg_int(s1, src->prev, REG_ITMP1);
1601 var_to_reg_int(s2, src, REG_ITMP2);
1602 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1603 if (iptr->op1 == 0) {
1604 gen_nullptr_check(s1);
1607 M_SLL_IMM(s2, 2, REG_ITMP2);
1608 M_IADD_IMM(REG_ITMP2, OFFSET(java_intarray, data[0]), REG_ITMP2);
1609 M_LWZX(d, s1, REG_ITMP2);
1610 store_reg_to_var_int(iptr->dst, d);
1613 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1615 var_to_reg_int(s1, src->prev, REG_ITMP1);
1616 var_to_reg_int(s2, src, REG_ITMP2);
1617 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1618 if (iptr->op1 == 0) {
1619 gen_nullptr_check(s1);
1622 M_SLL_IMM(s2, 2, REG_ITMP2);
1623 M_IADD_IMM(REG_ITMP2, OFFSET(java_floatarray, data[0]), REG_ITMP2);
1624 M_LFSX(d, s1, REG_ITMP2);
1625 store_reg_to_var_flt(iptr->dst, d);
1628 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1630 var_to_reg_int(s1, src->prev, REG_ITMP1);
1631 var_to_reg_int(s2, src, REG_ITMP2);
1632 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1633 if (iptr->op1 == 0) {
1634 gen_nullptr_check(s1);
1637 M_SLL_IMM(s2, 3, REG_ITMP2);
1638 M_IADD_IMM(REG_ITMP2, OFFSET(java_doublearray, data[0]), REG_ITMP2);
1639 M_LFDX(d, s1, REG_ITMP2);
1640 store_reg_to_var_flt(iptr->dst, d);
1643 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1645 var_to_reg_int(s1, src->prev, REG_ITMP1);
1646 var_to_reg_int(s2, src, REG_ITMP2);
1647 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1648 if (iptr->op1 == 0) {
1649 gen_nullptr_check(s1);
1652 M_IADD_IMM(s2, OFFSET(java_chararray, data[0]), REG_ITMP2);
1653 M_LBZX(d, s1, REG_ITMP2);
1655 store_reg_to_var_int(iptr->dst, d);
1658 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1660 var_to_reg_int(s1, src->prev, REG_ITMP1);
1661 var_to_reg_int(s2, src, REG_ITMP2);
1662 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1663 if (iptr->op1 == 0) {
1664 gen_nullptr_check(s1);
1667 M_SLL_IMM(s2, 1, REG_ITMP2);
1668 M_IADD_IMM(REG_ITMP2, OFFSET(java_shortarray, data[0]), REG_ITMP2);
1669 M_LHAX(d, s1, REG_ITMP2);
1670 store_reg_to_var_int(iptr->dst, d);
1673 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1675 var_to_reg_int(s1, src->prev, REG_ITMP1);
1676 var_to_reg_int(s2, src, REG_ITMP2);
1677 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1678 if (iptr->op1 == 0) {
1679 gen_nullptr_check(s1);
1682 M_SLL_IMM(s2, 1, REG_ITMP2);
1683 M_IADD_IMM(REG_ITMP2, OFFSET(java_chararray, data[0]), REG_ITMP2);
1684 M_LHZX(d, s1, REG_ITMP2);
1685 store_reg_to_var_int(iptr->dst, d);
1688 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1690 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1691 var_to_reg_int(s2, src->prev, REG_ITMP2);
1692 if (iptr->op1 == 0) {
1693 gen_nullptr_check(s1);
1696 var_to_reg_int0(s3, src, REG_ITMP3, 1, 0);
1697 M_SLL_IMM(s2, 3, REG_ITMP2);
1698 M_IADD_IMM(REG_ITMP2, OFFSET(java_intarray, data[0]), REG_ITMP2);
1699 M_STWX(s3, s1, REG_ITMP2);
1700 M_IADD_IMM(REG_ITMP2, 4, REG_ITMP2);
1701 var_to_reg_int0(s3, src, REG_ITMP3, 0, 1);
1702 M_STWX(s3, s1, REG_ITMP2);
1705 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1707 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1708 var_to_reg_int(s2, src->prev, REG_ITMP2);
1709 if (iptr->op1 == 0) {
1710 gen_nullptr_check(s1);
1713 var_to_reg_int(s3, src, REG_ITMP3);
1714 M_SLL_IMM(s2, 2, REG_ITMP2);
1715 M_IADD_IMM(REG_ITMP2, OFFSET(java_intarray, data[0]), REG_ITMP2);
1716 M_STWX(s3, s1, REG_ITMP2);
1719 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1721 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1722 var_to_reg_int(s2, src->prev, REG_ITMP2);
1723 if (iptr->op1 == 0) {
1724 gen_nullptr_check(s1);
1727 var_to_reg_flt(s3, src, REG_FTMP3);
1728 M_SLL_IMM(s2, 2, REG_ITMP2);
1729 M_IADD_IMM(REG_ITMP2, OFFSET(java_floatarray, data[0]), REG_ITMP2);
1730 M_STFSX(s3, s1, REG_ITMP2);
1733 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1735 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1736 var_to_reg_int(s2, src->prev, REG_ITMP2);
1737 if (iptr->op1 == 0) {
1738 gen_nullptr_check(s1);
1741 var_to_reg_flt(s3, src, REG_FTMP3);
1742 M_SLL_IMM(s2, 3, REG_ITMP2);
1743 M_IADD_IMM(REG_ITMP2, OFFSET(java_doublearray, data[0]), REG_ITMP2);
1744 M_STFDX(s3, s1, REG_ITMP2);
1747 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1749 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1750 var_to_reg_int(s2, src->prev, REG_ITMP2);
1751 if (iptr->op1 == 0) {
1752 gen_nullptr_check(s1);
1755 var_to_reg_int(s3, src, REG_ITMP3);
1756 M_IADD_IMM(s2, OFFSET(java_bytearray, data[0]), REG_ITMP2);
1757 M_STBX(s3, s1, REG_ITMP2);
1760 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1762 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1763 var_to_reg_int(s2, src->prev, REG_ITMP2);
1764 if (iptr->op1 == 0) {
1765 gen_nullptr_check(s1);
1768 var_to_reg_int(s3, src, REG_ITMP3);
1769 M_SLL_IMM(s2, 1, REG_ITMP2);
1770 M_IADD_IMM(REG_ITMP2, OFFSET(java_shortarray, data[0]), REG_ITMP2);
1771 M_STHX(s3, s1, REG_ITMP2);
1774 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1776 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1777 var_to_reg_int(s2, src->prev, REG_ITMP2);
1778 if (iptr->op1 == 0) {
1779 gen_nullptr_check(s1);
1782 var_to_reg_int(s3, src, REG_ITMP3);
1783 M_SLL_IMM(s2, 1, REG_ITMP2);
1784 M_IADD_IMM(REG_ITMP2, OFFSET(java_chararray, data[0]), REG_ITMP2);
1785 M_STHX(s3, s1, REG_ITMP2);
1788 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1789 /* op1 = type, val.a = field address */
1791 /* if class isn't yet initialized, do it */
1792 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
1793 /* call helper function which patches this code */
1794 a = dseg_addaddress(cd, ((fieldinfo *) iptr->val.a)->class);
1795 M_ALD(REG_ITMP1, REG_PV, a);
1796 a = dseg_addaddress(cd, asm_check_clinit);
1797 M_ALD(REG_PV, REG_PV, a);
1802 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
1804 if (s1 <= 32768) M_LDA(REG_PV, REG_ITMP1, -s1);
1806 s4 ml = -s1, mh = 0;
1807 while (ml < -32768) { ml += 65536; mh--; }
1808 M_LDA(REG_PV, REG_ITMP1, ml);
1809 M_LDAH(REG_PV, REG_PV, mh);
1813 a = dseg_addaddress(cd, &(((fieldinfo *) iptr->val.a)->value));
1814 M_ALD(REG_ITMP1, REG_PV, a);
1815 switch (iptr->op1) {
1817 var_to_reg_int(s2, src, REG_ITMP2);
1818 M_IST(s2, REG_ITMP1, 0);
1821 var_to_reg_int(s2, src, REG_ITMP3);
1822 M_IST(s2, REG_ITMP1, 0);
1823 M_IST(rd->secondregs[s2], REG_ITMP1, 4);
1826 var_to_reg_int(s2, src, REG_ITMP2);
1827 M_AST(s2, REG_ITMP1, 0);
1830 var_to_reg_flt(s2, src, REG_FTMP2);
1831 M_FST(s2, REG_ITMP1, 0);
1834 var_to_reg_flt(s2, src, REG_FTMP2);
1835 M_DST(s2, REG_ITMP1, 0);
1837 default: panic ("internal error");
1841 case ICMD_GETSTATIC: /* ... ==> ..., value */
1842 /* op1 = type, val.a = field address */
1844 /* if class isn't yet initialized, do it */
1845 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
1846 /* call helper function which patches this code */
1847 a = dseg_addaddress(cd, ((fieldinfo *) iptr->val.a)->class);
1848 M_ALD(REG_ITMP1, REG_PV, a);
1849 a = dseg_addaddress(cd, asm_check_clinit);
1850 M_ALD(REG_PV, REG_PV, a);
1855 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
1857 if (s1 <= 32768) M_LDA(REG_PV, REG_ITMP1, -s1);
1859 s4 ml = -s1, mh = 0;
1860 while (ml < -32768) { ml += 65536; mh--; }
1861 M_LDA(REG_PV, REG_ITMP1, ml);
1862 M_LDAH(REG_PV, REG_PV, mh);
1866 a = dseg_addaddress(cd, &(((fieldinfo *) iptr->val.a)->value));
1867 M_ALD(REG_ITMP1, REG_PV, a);
1868 switch (iptr->op1) {
1870 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1871 M_ILD(d, REG_ITMP1, 0);
1872 store_reg_to_var_int(iptr->dst, d);
1875 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1876 M_ILD(d, REG_ITMP1, 0);
1877 M_ILD(rd->secondregs[d], REG_ITMP1, 4);
1878 store_reg_to_var_int(iptr->dst, d);
1881 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1882 M_ALD(d, REG_ITMP1, 0);
1883 store_reg_to_var_int(iptr->dst, d);
1886 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
1887 M_FLD(d, REG_ITMP1, 0);
1888 store_reg_to_var_flt(iptr->dst, d);
1891 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
1892 M_DLD(d, REG_ITMP1, 0);
1893 store_reg_to_var_flt(iptr->dst, d);
1895 default: panic ("internal error");
1900 case ICMD_PUTFIELD: /* ..., value ==> ... */
1901 /* op1 = type, val.i = field offset */
1903 a = ((fieldinfo *)(iptr->val.a))->offset;
1904 switch (iptr->op1) {
1906 var_to_reg_int(s1, src->prev, REG_ITMP1);
1907 var_to_reg_int(s2, src, REG_ITMP2);
1908 gen_nullptr_check(s1);
1912 var_to_reg_int(s1, src->prev, REG_ITMP1);
1913 var_to_reg_int(s2, src, REG_ITMP3);
1914 gen_nullptr_check(s1);
1916 M_IST(rd->secondregs[s2], s1, a+4);
1919 var_to_reg_int(s1, src->prev, REG_ITMP1);
1920 var_to_reg_int(s2, src, REG_ITMP2);
1921 gen_nullptr_check(s1);
1925 var_to_reg_int(s1, src->prev, REG_ITMP1);
1926 var_to_reg_flt(s2, src, REG_FTMP2);
1927 gen_nullptr_check(s1);
1931 var_to_reg_int(s1, src->prev, REG_ITMP1);
1932 var_to_reg_flt(s2, src, REG_FTMP2);
1933 gen_nullptr_check(s1);
1936 default: panic ("internal error");
1940 case ICMD_GETFIELD: /* ... ==> ..., value */
1941 /* op1 = type, val.i = field offset */
1943 a = ((fieldinfo *)(iptr->val.a))->offset;
1944 switch (iptr->op1) {
1946 var_to_reg_int(s1, src, REG_ITMP1);
1947 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1948 gen_nullptr_check(s1);
1950 store_reg_to_var_int(iptr->dst, d);
1953 var_to_reg_int(s1, src, REG_ITMP1);
1954 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1955 gen_nullptr_check(s1);
1957 M_ILD(rd->secondregs[d], s1, a+4);
1958 store_reg_to_var_int(iptr->dst, d);
1961 var_to_reg_int(s1, src, REG_ITMP1);
1962 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1963 gen_nullptr_check(s1);
1965 store_reg_to_var_int(iptr->dst, d);
1968 var_to_reg_int(s1, src, REG_ITMP1);
1969 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
1970 gen_nullptr_check(s1);
1972 store_reg_to_var_flt(iptr->dst, d);
1975 var_to_reg_int(s1, src, REG_ITMP1);
1976 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
1977 gen_nullptr_check(s1);
1979 store_reg_to_var_flt(iptr->dst, d);
1981 default: panic ("internal error");
1986 /* branch operations **************************************************/
1988 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1990 a = dseg_addaddress(cd, asm_handle_exception);
1991 M_ALD(REG_ITMP2, REG_PV, a);
1993 var_to_reg_int(s1, src, REG_ITMP1);
1994 M_INTMOVE(s1, REG_ITMP1_XPTR);
1996 if (m->isleafmethod) M_MFLR(REG_ITMP3); /* save LR */
1997 M_BL(0); /* get current PC */
1998 M_MFLR(REG_ITMP2_XPC);
1999 if (m->isleafmethod) M_MTLR(REG_ITMP3); /* restore LR */
2000 M_RTS; /* jump to CTR */
2005 case ICMD_GOTO: /* ... ==> ... */
2006 /* op1 = target JavaVM pc */
2008 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2012 case ICMD_JSR: /* ... ==> ... */
2013 /* op1 = target JavaVM pc */
2015 if (m->isleafmethod) M_MFLR(REG_ITMP2);
2018 M_IADD_IMM(REG_ITMP1, m->isleafmethod ? 16 : 12, REG_ITMP1);
2019 if (m->isleafmethod) M_MTLR(REG_ITMP2);
2021 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2024 case ICMD_RET: /* ... ==> ... */
2025 /* op1 = local variable */
2027 var = &(rd->locals[iptr->op1][TYPE_ADR]);
2028 if (var->flags & INMEMORY) {
2029 M_ALD(REG_ITMP1, REG_SP, 4 * var->regoff);
2033 M_MTCTR(var->regoff);
2038 case ICMD_IFNULL: /* ..., value ==> ... */
2039 /* op1 = target JavaVM pc */
2041 var_to_reg_int(s1, src, REG_ITMP1);
2044 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2047 case ICMD_IFNONNULL: /* ..., value ==> ... */
2048 /* op1 = target JavaVM pc */
2050 var_to_reg_int(s1, src, REG_ITMP1);
2053 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2061 case ICMD_IFEQ: /* ..., value ==> ... */
2062 /* op1 = target JavaVM pc, val.i = constant */
2064 var_to_reg_int(s1, src, REG_ITMP1);
2065 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
2066 M_CMPI(s1, iptr->val.i);
2069 ICONST(REG_ITMP2, iptr->val.i);
2070 M_CMP(s1, REG_ITMP2);
2093 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2097 case ICMD_IF_LEQ: /* ..., value ==> ... */
2098 /* op1 = target JavaVM pc, val.l = constant */
2100 var_to_reg_int0(s1, src, REG_ITMP1, 0, 1);
2101 var_to_reg_int0(s2, src, REG_ITMP2, 1, 0);
2102 if (iptr->val.l == 0) {
2103 M_OR(s1, s2, REG_ITMP3);
2104 M_CMPI(REG_ITMP3, 0);
2106 } else if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2107 M_CMPI(s2, (u4) (iptr->val.l >> 32));
2109 M_CMPI(s1, (u4) (iptr->val.l & 0xffffffff));
2112 ICONST(REG_ITMP3, (u4) (iptr->val.l >> 32));
2113 M_CMP(s2, REG_ITMP3);
2115 ICONST(REG_ITMP3, (u4) (iptr->val.l & 0xffffffff));
2116 M_CMP(s1, REG_ITMP3)
2119 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2122 case ICMD_IF_LLT: /* ..., value ==> ... */
2123 /* op1 = target JavaVM pc, val.l = constant */
2124 var_to_reg_int0(s1, src, REG_ITMP1, 0, 1);
2125 var_to_reg_int0(s2, src, REG_ITMP2, 1, 0);
2126 /* if (iptr->val.l == 0) { */
2127 /* M_OR(s1, s2, REG_ITMP3); */
2128 /* M_CMPI(REG_ITMP3, 0); */
2131 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2132 M_CMPI(s2, (u4) (iptr->val.l >> 32));
2134 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2136 M_CMPI(s1, (u4) (iptr->val.l & 0xffffffff));
2139 ICONST(REG_ITMP3, (u4) (iptr->val.l >> 32));
2140 M_CMP(s2, REG_ITMP3);
2142 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2144 ICONST(REG_ITMP3, (u4) (iptr->val.l & 0xffffffff));
2145 M_CMP(s1, REG_ITMP3)
2148 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2151 case ICMD_IF_LLE: /* ..., value ==> ... */
2152 /* op1 = target JavaVM pc, val.l = constant */
2154 var_to_reg_int0(s1, src, REG_ITMP1, 0, 1);
2155 var_to_reg_int0(s2, src, REG_ITMP2, 1, 0);
2156 /* if (iptr->val.l == 0) { */
2157 /* M_OR(s1, s2, REG_ITMP3); */
2158 /* M_CMPI(REG_ITMP3, 0); */
2161 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2162 M_CMPI(s2, (u4) (iptr->val.l >> 32));
2164 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2166 M_CMPI(s1, (u4) (iptr->val.l & 0xffffffff));
2169 ICONST(REG_ITMP3, (u4) (iptr->val.l >> 32));
2170 M_CMP(s2, REG_ITMP3);
2172 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2174 ICONST(REG_ITMP3, (u4) (iptr->val.l & 0xffffffff));
2175 M_CMP(s1, REG_ITMP3)
2178 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2181 case ICMD_IF_LNE: /* ..., value ==> ... */
2182 /* op1 = target JavaVM pc, val.l = constant */
2184 var_to_reg_int0(s1, src, REG_ITMP1, 0, 1);
2185 var_to_reg_int0(s2, src, REG_ITMP2, 1, 0);
2186 if (iptr->val.l == 0) {
2187 M_OR(s1, s2, REG_ITMP3);
2188 M_CMPI(REG_ITMP3, 0);
2190 } else if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2191 M_CMPI(s2, (u4) (iptr->val.l >> 32));
2193 M_CMPI(s1, (u4) (iptr->val.l & 0xffffffff));
2196 ICONST(REG_ITMP3, (u4) (iptr->val.l >> 32));
2197 M_CMP(s2, REG_ITMP3);
2199 ICONST(REG_ITMP3, (u4) (iptr->val.l & 0xffffffff));
2200 M_CMP(s1, REG_ITMP3)
2203 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2206 case ICMD_IF_LGT: /* ..., value ==> ... */
2207 /* op1 = target JavaVM pc, val.l = constant */
2209 var_to_reg_int0(s1, src, REG_ITMP1, 0, 1);
2210 var_to_reg_int0(s2, src, REG_ITMP2, 1, 0);
2211 /* if (iptr->val.l == 0) { */
2212 /* M_OR(s1, s2, REG_ITMP3); */
2213 /* M_CMPI(REG_ITMP3, 0); */
2216 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2217 M_CMPI(s2, (u4) (iptr->val.l >> 32));
2219 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2221 M_CMPI(s1, (u4) (iptr->val.l & 0xffffffff));
2224 ICONST(REG_ITMP3, (u4) (iptr->val.l >> 32));
2225 M_CMP(s2, REG_ITMP3);
2227 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2229 ICONST(REG_ITMP3, (u4) (iptr->val.l & 0xffffffff));
2230 M_CMP(s1, REG_ITMP3)
2233 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2236 case ICMD_IF_LGE: /* ..., value ==> ... */
2237 /* op1 = target JavaVM pc, val.l = constant */
2238 var_to_reg_int0(s1, src, REG_ITMP1, 0, 1);
2239 var_to_reg_int0(s2, src, REG_ITMP2, 1, 0);
2240 /* if (iptr->val.l == 0) { */
2241 /* M_OR(s1, s2, REG_ITMP3); */
2242 /* M_CMPI(REG_ITMP3, 0); */
2245 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2246 M_CMPI(s2, (u4) (iptr->val.l >> 32));
2248 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2250 M_CMPI(s1, (u4) (iptr->val.l & 0xffffffff));
2253 ICONST(REG_ITMP3, (u4) (iptr->val.l >> 32));
2254 M_CMP(s2, REG_ITMP3);
2256 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2258 ICONST(REG_ITMP3, (u4) (iptr->val.l & 0xffffffff));
2259 M_CMP(s1, REG_ITMP3)
2262 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2266 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2267 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2268 case ICMD_IF_ACMPEQ:
2270 var_to_reg_int(s1, src->prev, REG_ITMP1);
2271 var_to_reg_int(s2, src, REG_ITMP2);
2274 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2277 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2278 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2279 case ICMD_IF_ACMPNE:
2281 var_to_reg_int(s1, src->prev, REG_ITMP1);
2282 var_to_reg_int(s2, src, REG_ITMP2);
2285 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2288 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2289 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2291 var_to_reg_int(s1, src->prev, REG_ITMP1);
2292 var_to_reg_int(s2, src, REG_ITMP2);
2295 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2298 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2299 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2301 var_to_reg_int(s1, src->prev, REG_ITMP1);
2302 var_to_reg_int(s2, src, REG_ITMP2);
2305 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2308 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2309 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2311 var_to_reg_int(s1, src->prev, REG_ITMP1);
2312 var_to_reg_int(s2, src, REG_ITMP2);
2315 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2318 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2319 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2321 var_to_reg_int(s1, src->prev, REG_ITMP1);
2322 var_to_reg_int(s2, src, REG_ITMP2);
2325 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), mcodeptr);
2328 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2332 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2335 case ICMD_RETURN: /* ... ==> ... */
2337 #if defined(USE_THREADS)
2338 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2339 a = dseg_addaddress(cd, (void *) (builtin_monitorexit));
2340 M_ALD(REG_ITMP3, REG_PV, a);
2342 M_ALD(rd->argintregs[0], REG_SP, rd->maxmemuse * 4);
2346 switch (iptr->opc) {
2350 var_to_reg_int(s1, src, REG_RESULT);
2351 M_TINTMOVE(src->type, s1, REG_RESULT);
2352 goto nowperformreturn;
2356 var_to_reg_flt(s1, src, REG_FRESULT);
2357 M_FLTMOVE(s1, REG_FRESULT);
2358 goto nowperformreturn;
2365 p = parentargs_base;
2367 /* restore return address */
2369 if (!m->isleafmethod) {
2370 M_ALD(REG_ITMP3, REG_SP, 4 * p + 8);
2374 /* restore saved registers */
2376 for (i = rd->savintregcnt - 1; i >= rd->maxsavintreguse; i--) {
2377 p--; M_ILD(rd->savintregs[i], REG_SP, 4 * p);
2379 for (i = rd->savfltregcnt - 1; i >= rd->maxsavfltreguse; i--) {
2380 p -= 2; M_DLD(rd->savfltregs[i], REG_SP, 4 * p);
2383 /* deallocate stack */
2385 if (parentargs_base) {
2386 M_LDA(REG_SP, REG_SP, parentargs_base*4);
2389 /* call trace function */
2393 M_LDA(REG_SP, REG_SP, -10 * 8);
2394 M_DST(REG_FRESULT, REG_SP, 48+0);
2395 M_IST(REG_RESULT, REG_SP, 48+8);
2396 M_AST(REG_ITMP3, REG_SP, 48+12);
2397 M_IST(REG_RESULT2, REG_SP, 48+16);
2398 a = dseg_addaddress(cd, m);
2400 /* keep this order */
2401 switch (iptr->opc) {
2404 M_MOV(REG_RESULT, rd->argintregs[2]);
2405 M_CLR(rd->argintregs[1]);
2409 M_MOV(REG_RESULT2, rd->argintregs[2]);
2410 M_MOV(REG_RESULT, rd->argintregs[1]);
2413 M_ALD(rd->argintregs[0], REG_PV, a);
2415 M_FLTMOVE(REG_FRESULT, rd->argfltregs[0]);
2416 M_FLTMOVE(REG_FRESULT, rd->argfltregs[1]);
2417 a = dseg_addaddress(cd, (void *) builtin_displaymethodstop);
2418 M_ALD(REG_ITMP2, REG_PV, a);
2421 M_DLD(REG_FRESULT, REG_SP, 48+0);
2422 M_ILD(REG_RESULT, REG_SP, 48+8);
2423 M_ALD(REG_ITMP3, REG_SP, 48+12);
2424 M_ILD(REG_RESULT2, REG_SP, 48+16);
2425 M_LDA(REG_SP, REG_SP, 10 * 8);
2435 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2440 tptr = (void **) iptr->target;
2442 s4ptr = iptr->val.a;
2443 l = s4ptr[1]; /* low */
2444 i = s4ptr[2]; /* high */
2446 var_to_reg_int(s1, src, REG_ITMP1);
2448 M_INTMOVE(s1, REG_ITMP1);
2449 } else if (l <= 32768) {
2450 M_LDA(REG_ITMP1, s1, -l);
2452 ICONST(REG_ITMP2, l);
2453 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2459 M_CMPUI(REG_ITMP1, i - 1);
2462 /* codegen_addreference(cd, BlockPtrOfPC(s4ptr[0]), mcodeptr); */
2463 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
2465 /* build jump table top down and use address of lowest entry */
2467 /* s4ptr += 3 + i; */
2471 /* dseg_addtarget(cd, BlockPtrOfPC(*--s4ptr)); */
2472 dseg_addtarget(cd, (basicblock *) tptr[0]);
2477 /* length of dataseg after last dseg_addtarget is used by load */
2479 M_SLL_IMM(REG_ITMP1, 2, REG_ITMP1);
2480 M_IADD(REG_ITMP1, REG_PV, REG_ITMP2);
2481 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2488 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2490 s4 i, l, val, *s4ptr;
2493 tptr = (void **) iptr->target;
2495 s4ptr = iptr->val.a;
2496 l = s4ptr[0]; /* default */
2497 i = s4ptr[1]; /* count */
2499 MCODECHECK((i<<2)+8);
2500 var_to_reg_int(s1, src, REG_ITMP1);
2506 if ((val >= -32768) && (val <= 32767)) {
2510 a = dseg_adds4(cd, val);
2511 M_ILD(REG_ITMP2, REG_PV, a);
2512 M_CMP(s1, REG_ITMP2);
2515 /* codegen_addreference(cd, BlockPtrOfPC(s4ptr[1]), mcodeptr); */
2516 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
2520 /* codegen_addreference(cd, BlockPtrOfPC(l), mcodeptr); */
2522 tptr = (void **) iptr->target;
2523 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
2530 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
2531 /* op1 = return type, val.a = function pointer*/
2535 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
2536 /* op1 = return type, val.a = function pointer*/
2540 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
2541 /* op1 = return type, val.a = function pointer*/
2545 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2546 /* op1 = arg count, val.a = method pointer */
2548 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2549 /* op1 = arg count, val.a = method pointer */
2551 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2552 /* op1 = arg count, val.a = method pointer */
2554 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
2555 /* op1 = arg count, val.a = method pointer */
2563 MCODECHECK((s3 << 1) + 64);
2566 /* copy arguments to registers or stack location */
2568 stackptr srcsave = src;
2572 for (; --s3 >= 0; src = src->prev) {
2573 argsize += IS_2_WORD_TYPE(src->type) ? 2 : 1;
2574 if (IS_FLT_DBL_TYPE(src->type))
2578 for (s3 = s3save, src = srcsave; --s3 >= 0; src = src->prev) {
2579 argsize -= IS_2_WORD_TYPE(src->type) ? 2 : 1;
2580 if (IS_FLT_DBL_TYPE(src->type))
2582 if (src->varkind == ARGVAR)
2584 if (IS_INT_LNG_TYPE(src->type)) {
2585 if (argsize < INT_ARG_CNT) {
2586 s1 = rd->argintregs[argsize];
2587 var_to_reg_int(d, src, s1);
2588 if (argsize < INT_ARG_CNT-1) {
2589 M_TINTMOVE(src->type, d, s1);
2593 if (IS_2_WORD_TYPE(src->type))
2594 M_IST(rd->secondregs[d], REG_SP, 4 * (argsize + 6) + 4);
2598 var_to_reg_int(d, src, REG_ITMP1);
2599 M_IST(d, REG_SP, 4 * (argsize + 6));
2600 if (IS_2_WORD_TYPE(src->type))
2601 M_IST(rd->secondregs[d], REG_SP, 4 * (argsize + 6) + 4);
2605 if (fltcnt < FLT_ARG_CNT) {
2606 s1 = rd->argfltregs[fltcnt];
2607 var_to_reg_flt(d, src, s1);
2611 var_to_reg_flt(d, src, REG_FTMP1);
2612 if (IS_2_WORD_TYPE(src->type))
2613 M_DST(d, REG_SP, 4 * (argsize + 6));
2615 M_FST(d, REG_SP, 4 * (argsize + 6));
2622 switch (iptr->opc) {
2626 a = dseg_addaddress(cd, (void *) lm);
2628 M_ALD(REG_PV, REG_PV, a); /* Pointer to built-in-function */
2630 goto makeactualcall;
2632 case ICMD_INVOKESTATIC:
2633 case ICMD_INVOKESPECIAL:
2634 a = dseg_addaddress(cd, lm->stubroutine);
2636 M_ALD(REG_PV, REG_PV, a); /* method pointer in r27 */
2639 goto makeactualcall;
2641 case ICMD_INVOKEVIRTUAL:
2643 gen_nullptr_check(rd->argintregs[0]);
2644 M_ALD(REG_METHODPTR, rd->argintregs[0],
2645 OFFSET(java_objectheader, vftbl));
2646 M_ALD(REG_PV, REG_METHODPTR, OFFSET(vftbl_t, table[0]) +
2647 sizeof(methodptr) * lm->vftblindex);
2650 goto makeactualcall;
2652 case ICMD_INVOKEINTERFACE:
2655 gen_nullptr_check(rd->argintregs[0]);
2656 M_ALD(REG_METHODPTR, rd->argintregs[0],
2657 OFFSET(java_objectheader, vftbl));
2658 M_ALD(REG_METHODPTR, REG_METHODPTR,
2659 OFFSET(vftbl_t, interfacetable[0]) -
2660 sizeof(methodptr*) * ci->index);
2661 M_ALD(REG_PV, REG_METHODPTR,
2662 sizeof(methodptr) * (lm - ci->methods));
2665 goto makeactualcall;
2669 error ("Unkown ICMD-Command: %d", iptr->opc);
2678 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
2680 if (s1 <= 32768) M_LDA(REG_PV, REG_ITMP1, -s1);
2682 s4 ml = -s1, mh = 0;
2683 while (ml < -32768) { ml += 65536; mh--; }
2684 M_LDA(REG_PV, REG_ITMP1, ml);
2685 M_LDAH(REG_PV, REG_PV, mh);
2688 /* d contains return type */
2690 if (d != TYPE_VOID) {
2691 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
2692 s1 = reg_of_var(rd, iptr->dst, REG_RESULT);
2693 M_TINTMOVE(iptr->dst->type, REG_RESULT, s1);
2694 store_reg_to_var_int(iptr->dst, s1);
2697 s1 = reg_of_var(rd, iptr->dst, REG_FRESULT);
2698 M_FLTMOVE(REG_FRESULT, s1);
2699 store_reg_to_var_flt(iptr->dst, s1);
2706 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2708 /* op1: 0 == array, 1 == class */
2709 /* val.a: (classinfo*) superclass */
2711 /* superclass is an interface:
2713 * return (sub != NULL) &&
2714 * (sub->vftbl->interfacetablelength > super->index) &&
2715 * (sub->vftbl->interfacetable[-super->index] != NULL);
2717 * superclass is a class:
2719 * return ((sub != NULL) && (0
2720 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2721 * super->vftbl->diffvall));
2725 classinfo *super = (classinfo*) iptr->val.a;
2727 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
2728 codegen_threadcritrestart(cd, (u1*) mcodeptr - cd->mcodebase);
2730 var_to_reg_int(s1, src, REG_ITMP1);
2731 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2733 M_MOV(s1, REG_ITMP1);
2737 if (iptr->op1) { /* class/interface */
2739 if (super->flags & ACC_INTERFACE) { /* interface */
2741 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2742 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2743 M_LDATST(REG_ITMP2, REG_ITMP2, - super->index);
2745 M_ALD(REG_ITMP1, REG_ITMP1,
2746 OFFSET(vftbl_t, interfacetable[0]) -
2747 super->index * sizeof(methodptr*));
2751 M_IADD_IMM(REG_ZERO, 1, d);
2755 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2756 a = dseg_addaddress(cd, (void*) super->vftbl);
2757 M_ALD(REG_ITMP2, REG_PV, a);
2758 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
2759 codegen_threadcritstart(cd, (u1*) mcodeptr - cd->mcodebase);
2761 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
2762 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
2763 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
2764 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
2765 codegen_threadcritstop(cd, (u1*) mcodeptr - cd->mcodebase);
2767 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
2768 M_CMPU(REG_ITMP1, REG_ITMP2);
2771 M_IADD_IMM(REG_ZERO, 1, d);
2775 panic ("internal error: no inlined array instanceof");
2777 store_reg_to_var_int(iptr->dst, d);
2780 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2782 /* op1: 0 == array, 1 == class */
2783 /* val.a: (classinfo*) superclass */
2785 /* superclass is an interface:
2787 * OK if ((sub == NULL) ||
2788 * (sub->vftbl->interfacetablelength > super->index) &&
2789 * (sub->vftbl->interfacetable[-super->index] != NULL));
2791 * superclass is a class:
2793 * OK if ((sub == NULL) || (0
2794 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2795 * super->vftbl->diffvall));
2799 classinfo *super = (classinfo*) iptr->val.a;
2801 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
2802 codegen_threadcritrestart(cd, (u1*) mcodeptr - cd->mcodebase);
2804 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
2805 var_to_reg_int(s1, src, d);
2806 if (iptr->op1) { /* class/interface */
2808 if (super->flags & ACC_INTERFACE) { /* interface */
2810 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2811 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
2812 M_LDATST(REG_ITMP3, REG_ITMP3, - super->index);
2814 codegen_addxcastrefs(cd, mcodeptr);
2815 M_ALD(REG_ITMP3, REG_ITMP2,
2816 OFFSET(vftbl_t, interfacetable[0]) -
2817 super->index * sizeof(methodptr*));
2820 codegen_addxcastrefs(cd, mcodeptr);
2823 M_BEQ(8 + (s1 == REG_ITMP1));
2824 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2825 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
2826 codegen_threadcritstart(cd, (u1*) mcodeptr - cd->mcodebase);
2828 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
2829 a = dseg_addaddress(cd, (void*) super->vftbl);
2830 M_ALD(REG_ITMP2, REG_PV, a);
2831 if (d != REG_ITMP1) {
2832 M_ILD(REG_ITMP1, REG_ITMP2, OFFSET(vftbl_t, baseval));
2833 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
2834 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
2835 codegen_threadcritstop(cd, (u1*) mcodeptr - cd->mcodebase);
2837 M_ISUB(REG_ITMP3, REG_ITMP1, REG_ITMP3);
2840 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2841 M_ISUB(REG_ITMP3, REG_ITMP2, REG_ITMP3);
2842 M_ALD(REG_ITMP2, REG_PV, a);
2843 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
2844 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
2845 codegen_threadcritstop(cd, (u1*) mcodeptr - cd->mcodebase);
2848 M_CMPU(REG_ITMP3, REG_ITMP2);
2850 codegen_addxcastrefs(cd, mcodeptr);
2854 panic ("internal error: no inlined array checkcast");
2857 store_reg_to_var_int(iptr->dst, d);
2860 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
2862 var_to_reg_int(s1, src, REG_ITMP1);
2865 codegen_addxcheckarefs(cd, mcodeptr);
2868 case ICMD_CHECKEXCEPTION: /* ... ==> ... */
2870 M_CMPI(REG_RESULT, 0);
2872 codegen_addxexceptionrefs(cd, mcodeptr);
2875 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2876 /* op1 = dimension, val.a = array descriptor */
2878 /* check for negative sizes and copy sizes to stack if necessary */
2880 MCODECHECK((iptr->op1 << 1) + 64);
2882 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
2883 var_to_reg_int(s2, src, REG_ITMP1);
2886 codegen_addxcheckarefs(cd, mcodeptr);
2888 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
2890 if (src->varkind != ARGVAR) {
2891 M_IST(s2, REG_SP, 4 * (s1 + INT_ARG_CNT + 6));
2895 /* a0 = dimension count */
2897 ICONST(rd->argintregs[0], iptr->op1);
2899 /* a1 = arraydescriptor */
2901 a = dseg_addaddress(cd, iptr->val.a);
2902 M_ALD(rd->argintregs[1], REG_PV, a);
2904 /* a2 = pointer to dimensions = stack pointer */
2906 M_LDA(rd->argintregs[2], REG_SP, (INT_ARG_CNT + 6)*4);
2908 a = dseg_addaddress(cd, (void *) builtin_nmultianewarray);
2909 M_ALD(REG_PV, REG_PV, a);
2912 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
2915 M_LDA (REG_PV, REG_ITMP1, -s1);
2917 s4 ml = -s1, mh = 0;
2918 while (ml < -32768) {ml += 65536; mh--;}
2919 M_LDA(REG_PV, REG_ITMP1, ml);
2920 M_LDAH(REG_PV, REG_PV, mh);
2922 s1 = reg_of_var(rd, iptr->dst, REG_RESULT);
2923 M_INTMOVE(REG_RESULT, s1);
2924 store_reg_to_var_int(iptr->dst, s1);
2928 default: error ("Unknown pseudo command: %d", iptr->opc);
2932 } /* for instruction */
2934 /* copy values to interface registers */
2936 src = bptr->outstack;
2937 len = bptr->outdepth;
2938 MCODECHECK(64 + len);
2941 if ((src->varkind != STACKVAR)) {
2943 if (IS_FLT_DBL_TYPE(s2)) {
2944 var_to_reg_flt(s1, src, REG_FTMP1);
2945 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
2946 M_FLTMOVE(s1, rd->interfaces[len][s2].regoff);
2949 M_DST(s1, REG_SP, rd->interfaces[len][s2].regoff * 4);
2953 var_to_reg_int(s1, src, REG_ITMP1);
2954 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
2955 M_TINTMOVE(s2, s1, rd->interfaces[len][s2].regoff);
2958 M_IST(s1, REG_SP, rd->interfaces[len][s2].regoff * 4);
2959 if (IS_2_WORD_TYPE(s2))
2960 M_IST(rd->secondregs[s1], REG_SP, rd->interfaces[len][s2].regoff * 4 + 4);
2966 } /* if (bptr -> flags >= BBREACHED) */
2967 } /* for basic block */
2969 /* bptr -> mpc = (int)((u1*) mcodeptr - mcodebase); */
2972 /* generate bound check stubs */
2974 s4 *xcodeptr = NULL;
2977 for (bref = cd->xboundrefs; bref != NULL; bref = bref->next) {
2978 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
2980 (u1 *) mcodeptr - cd->mcodebase);
2984 /* move index register into REG_ITMP1 */
2985 M_MOV(bref->reg, REG_ITMP1);
2986 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
2988 if (xcodeptr != NULL) {
2989 M_BR(xcodeptr - mcodeptr - 1);
2992 xcodeptr = mcodeptr;
2994 M_IADD_IMM(REG_SP, -1 * 8, REG_SP);
2995 M_IST(REG_ITMP2_XPC, REG_SP, 0 * 8);
2997 M_MOV(REG_ITMP1, rd->argintregs[0]);
2999 a = dseg_addaddress(cd, new_arrayindexoutofboundsexception);
3000 M_ALD(REG_ITMP2, REG_PV, a);
3003 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3005 M_ILD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3006 M_IADD_IMM(REG_SP, 1 * 8, REG_SP);
3008 a = dseg_addaddress(cd, asm_handle_exception);
3009 M_ALD(REG_ITMP3, REG_PV, a);
3016 /* generate negative array size check stubs */
3020 for (bref = cd->xcheckarefs; bref != NULL; bref = bref->next) {
3021 if ((m->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3022 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3024 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3028 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3030 (u1 *) mcodeptr - cd->mcodebase);
3034 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3036 if (xcodeptr != NULL) {
3037 M_BR(xcodeptr - mcodeptr - 1);
3040 xcodeptr = mcodeptr;
3042 M_IADD_IMM(REG_SP, -1 * 8, REG_SP);
3043 M_IST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3045 a = dseg_addaddress(cd, new_negativearraysizeexception);
3046 M_ALD(REG_ITMP2, REG_PV, a);
3049 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3051 M_ILD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3052 M_IADD_IMM(REG_SP, 1 * 8, REG_SP);
3054 a = dseg_addaddress(cd, asm_handle_exception);
3055 M_ALD(REG_ITMP3, REG_PV, a);
3062 /* generate cast check stubs */
3066 for (bref = cd->xcastrefs; bref != NULL; bref = bref->next) {
3067 if ((m->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3068 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3070 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3074 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3076 (u1 *) mcodeptr - cd->mcodebase);
3080 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3082 if (xcodeptr != NULL) {
3083 M_BR(xcodeptr - mcodeptr - 1);
3086 xcodeptr = mcodeptr;
3088 M_IADD_IMM(REG_SP, -1 * 8, REG_SP);
3089 M_IST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3091 a = dseg_addaddress(cd, new_classcastexception);
3092 M_ALD(REG_ITMP2, REG_PV, a);
3095 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3097 M_ILD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3098 M_IADD_IMM(REG_SP, 1 * 8, REG_SP);
3100 a = dseg_addaddress(cd, asm_handle_exception);
3101 M_ALD(REG_ITMP3, REG_PV, a);
3108 /* generate exception check stubs */
3112 for (bref = cd->xexceptionrefs; bref != NULL; bref = bref->next) {
3113 if ((m->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3114 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3116 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3120 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3122 (u1 *) mcodeptr - cd->mcodebase);
3126 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3128 if (xcodeptr != NULL) {
3129 M_BR(xcodeptr - mcodeptr - 1);
3132 xcodeptr = mcodeptr;
3134 /* XXX this cannot work - there is no link area */
3135 M_IADD_IMM(REG_SP, -1 * 8, REG_SP);
3136 M_IST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3138 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3139 a = dseg_addaddress(cd, builtin_get_exceptionptrptr);
3140 M_ALD(REG_ITMP2, REG_PV, a);
3144 /* get the exceptionptr from the ptrprt and clear it */
3145 M_ALD(REG_ITMP1_XPTR, REG_RESULT, 0);
3147 M_AST(REG_ITMP3, REG_RESULT, 0);
3149 a = dseg_addaddress(cd, &_exceptionptr);
3150 M_ALD(REG_ITMP2, REG_PV, a);
3152 M_ALD(REG_ITMP1_XPTR, REG_ITMP2, 0);
3154 M_AST(REG_ITMP3, REG_ITMP2, 0);
3157 M_ILD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3158 M_IADD_IMM(REG_SP, 1 * 8, REG_SP);
3160 a = dseg_addaddress(cd, asm_handle_exception);
3161 M_ALD(REG_ITMP3, REG_PV, a);
3167 /* generate null pointer check stubs */
3171 for (bref = cd->xnullrefs; bref != NULL; bref = bref->next) {
3172 if ((m->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3173 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3175 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3179 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3181 (u1 *) mcodeptr - cd->mcodebase);
3185 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3187 if (xcodeptr != NULL) {
3188 M_BR(xcodeptr - mcodeptr - 1);
3191 xcodeptr = mcodeptr;
3193 M_IADD_IMM(REG_SP, -1 * 8, REG_SP);
3194 M_IST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3196 a = dseg_addaddress(cd, new_nullpointerexception);
3197 M_ALD(REG_ITMP2, REG_PV, a);
3200 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3202 M_ILD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3203 M_IADD_IMM(REG_SP, 1 * 8, REG_SP);
3205 a = dseg_addaddress(cd, asm_handle_exception);
3206 M_ALD(REG_ITMP3, REG_PV, a);
3213 codegen_finish(m, cd, (s4) ((u1 *) mcodeptr - cd->mcodebase));
3215 asm_cacheflush((void *) m->entrypoint, ((u1 *) mcodeptr - cd->mcodebase));
3219 /* function createcompilerstub *************************************************
3221 creates a stub routine which calls the compiler
3223 *******************************************************************************/
3225 #define COMPSTUBSIZE 6
3227 u1 *createcompilerstub(methodinfo *m)
3229 s4 *s = CNEW (s4, COMPSTUBSIZE); /* memory to hold the stub */
3230 s4 *mcodeptr = s; /* code generation pointer */
3232 M_LDA(2, REG_PV, 4*4);
3233 M_ALD(REG_PV, REG_PV, 5*4);
3237 s[4] = (s4) m; /* literals to be adressed */
3238 s[5] = (s4) asm_call_jit_compiler; /* jump directly via PV from above */
3240 asm_cacheflush((void*) s, (u1*) mcodeptr - (u1*) s);
3242 #if defined(STATISTICS)
3244 count_cstub_len += COMPSTUBSIZE * 4;
3251 /* function removecompilerstub *************************************************
3253 deletes a compilerstub from memory (simply by freeing it)
3255 *******************************************************************************/
3257 void removecompilerstub(u1 *stub)
3259 CFREE(stub, COMPSTUBSIZE * 4);
3263 /* function: createnativestub **************************************************
3265 creates a stub routine which calls a native method
3267 *******************************************************************************/
3269 #define NATIVESTUBSIZE 200
3270 #define NATIVESTUBOFFSET 9
3272 u1 *createnativestub(functionptr f, methodinfo *m)
3274 s4 *s; /* memory to hold the stub */
3276 s4 *mcodeptr; /* code generation pointer */
3277 s4 stackframesize = 0; /* size of stackframe if needed */
3280 t_inlining_globals *id;
3283 /* mark start of dump memory area */
3285 dumpsize = dump_size();
3287 /* setup registers before using it */
3289 rd = DNEW(registerdata);
3290 id = DNEW(t_inlining_globals);
3292 inlining_setup(m, id);
3293 reg_setup(m, rd, id);
3295 descriptor2types(m); /* set paramcount and paramtypes */
3297 s = CNEW(s4, NATIVESTUBSIZE);
3298 cs = s + NATIVESTUBOFFSET;
3301 *(cs-1) = (u4) f; /* address of native method */
3302 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3303 *(cs-2) = (u4) builtin_get_exceptionptrptr;
3305 *(cs-2) = (u4) (&_exceptionptr); /* address of exceptionptr */
3307 *(cs-3) = (u4) asm_handle_nat_exception; /* addr of asm exception handler */
3308 *(cs-4) = (u4) (&env); /* addr of jni_environement */
3309 *(cs-5) = (u4) builtin_trace_args;
3311 *(cs-7) = (u4) builtin_displaymethodstop;
3312 *(cs-8) = (u4) m->class;
3313 *(cs-9) = (u4) asm_check_clinit;
3316 M_AST(REG_ITMP1, REG_SP, 8); /* store return address */
3317 M_LDA(REG_SP, REG_SP, -64); /* build up stackframe */
3319 /* if function is static, check for initialized */
3321 if (m->flags & ACC_STATIC) {
3322 /* if class isn't yet initialized, do it */
3323 if (!m->class->initialized) {
3324 /* call helper function which patches this code */
3325 M_ALD(REG_ITMP1, REG_PV, -8 * 4); /* class */
3326 M_ALD(REG_PV, REG_PV, -9 * 4); /* asm_check_clinit */
3329 disp = -(s4) (mcodeptr - cs) * 4;
3331 M_LDA(REG_PV, REG_ITMP1, disp); /* recompute pv from ra */
3341 /* M_MFLR(REG_ITMP3); */
3342 /* XXX must be a multiple of 16 */
3343 M_LDA(REG_SP, REG_SP, -(24 + (INT_ARG_CNT + FLT_ARG_CNT + 1) * 8));
3345 /* M_IST(REG_ITMP3, REG_SP, 24 + (INT_ARG_CNT + FLT_ARG_CNT) * 8); */
3349 /* save all arguments into the reserved stack space */
3350 for (p = 0; p < m->paramcount && p < TRACE_ARGS_NUM; p++) {
3351 t = m->paramtypes[p];
3353 if (IS_INT_LNG_TYPE(t)) {
3354 /* overlapping u8's are on the stack */
3355 if ((p + longargs + dblargs) < (INT_ARG_CNT - IS_2_WORD_TYPE(t))) {
3356 s1 = rd->argintregs[p + longargs + dblargs];
3358 if (!IS_2_WORD_TYPE(t)) {
3359 M_IST(REG_ITMP1, REG_SP, 24 + p * 8);
3360 M_IST(s1, REG_SP, 24 + p * 8 + 4);
3363 M_IST(s1, REG_SP, 24 + p * 8);
3364 M_IST(rd->secondregs[s1], REG_SP, 24 + p * 8 + 4);
3369 /* we do not have a data segment here */
3370 /* a = dseg_adds4(cd, 0xdeadbeef);
3371 M_ILD(REG_ITMP1, REG_PV, a); */
3372 M_LDA(REG_ITMP1, REG_ZERO, -1);
3373 M_IST(REG_ITMP1, REG_SP, 24 + p * 8);
3374 M_IST(REG_ITMP1, REG_SP, 24 + p * 8 + 4);
3378 if ((fltargs + dblargs) < FLT_ARG_CNT) {
3379 s1 = rd->argfltregs[fltargs + dblargs];
3381 if (!IS_2_WORD_TYPE(t)) {
3382 M_IST(REG_ITMP1, REG_SP, 24 + p * 8);
3383 M_FST(s1, REG_SP, 24 + p * 8 + 4);
3387 M_DST(s1, REG_SP, 24 + p * 8);
3392 /* this should not happen */
3397 /* TODO: save remaining integer and flaot argument registers */
3399 /* load first 4 arguments into integer argument registers */
3400 for (p = 0; p < 8; p++) {
3401 d = rd->argintregs[p];
3402 M_ILD(d, REG_SP, 24 + p * 4);
3405 M_ALD(REG_ITMP1, REG_PV, -6 * 4);
3406 M_AST(REG_ITMP1, REG_SP, 11 * 8); /* 24 (linkage area) + 32 (4 * s8 parameter area regs) + 32 (4 * s8 parameter area stack) = 88 */
3407 M_ALD(REG_ITMP2, REG_PV, -5 * 4);
3415 /* restore arguments into the reserved stack space */
3416 for (p = 0; p < m->paramcount && p < TRACE_ARGS_NUM; p++) {
3417 t = m->paramtypes[p];
3419 if (IS_INT_LNG_TYPE(t)) {
3420 if ((p + longargs + dblargs) < INT_ARG_CNT) {
3421 s1 = rd->argintregs[p + longargs + dblargs];
3423 if (!IS_2_WORD_TYPE(t)) {
3424 M_ILD(s1, REG_SP, 24 + p * 8 + 4);
3427 M_ILD(s1, REG_SP, 24 + p * 8);
3428 M_ILD(rd->secondregs[s1], REG_SP, 24 + p * 8 + 4);
3434 if ((fltargs + dblargs) < FLT_ARG_CNT) {
3435 s1 = rd->argfltregs[fltargs + dblargs];
3437 if (!IS_2_WORD_TYPE(t)) {
3438 M_FLD(s1, REG_SP, 24 + p * 8 + 4);
3442 M_DLD(s1, REG_SP, 24 + p * 8);
3449 /* M_ILD(REG_ITMP3, REG_SP, 24 + (INT_ARG_CNT + FLT_ARG_CNT) * 8); */
3451 M_LDA(REG_SP, REG_SP, 24 + (INT_ARG_CNT + FLT_ARG_CNT + 1) * 8);
3452 /* M_MTLR(REG_ITMP3); */
3455 /* save argument registers on stack -- if we have to */
3456 if ((m->flags & ACC_STATIC && m->paramcount > (INT_ARG_CNT - 2)) ||
3457 m->paramcount > (INT_ARG_CNT - 1)) {
3459 s4 paramshiftcnt = (m->flags & ACC_STATIC) ? 2 : 1;
3460 s4 stackparamcnt = (m->paramcount > INT_ARG_CNT) ? m->paramcount - INT_ARG_CNT : 0;
3462 stackframesize = stackparamcnt + paramshiftcnt;
3464 M_LDA(REG_SP, REG_SP, -stackframesize * 8);
3466 panic("nativestub");
3469 if (m->flags & ACC_STATIC) {
3470 M_MOV(rd->argintregs[5], rd->argintregs[7]);
3471 M_MOV(rd->argintregs[4], rd->argintregs[6]);
3472 M_MOV(rd->argintregs[3], rd->argintregs[5]);
3473 M_MOV(rd->argintregs[2], rd->argintregs[4]);
3474 M_MOV(rd->argintregs[1], rd->argintregs[3]);
3475 M_MOV(rd->argintregs[0], rd->argintregs[2]);
3477 /* put class into second argument register */
3478 M_ALD(rd->argintregs[1], REG_PV, -8 * 4);
3481 M_MOV(rd->argintregs[6], rd->argintregs[7]);
3482 M_MOV(rd->argintregs[5], rd->argintregs[6]);
3483 M_MOV(rd->argintregs[4], rd->argintregs[5]);
3484 M_MOV(rd->argintregs[3], rd->argintregs[4]);
3485 M_MOV(rd->argintregs[2], rd->argintregs[3]);
3486 M_MOV(rd->argintregs[1], rd->argintregs[2]);
3487 M_MOV(rd->argintregs[0], rd->argintregs[1]);
3490 /* put env into first argument register */
3491 M_ALD(rd->argintregs[0], REG_PV, -4 * 4);
3493 M_ALD(REG_PV, REG_PV, -1 * 4); /* load adress of native method */
3496 disp = -(s4) (mcodeptr - cs) * 4;
3498 M_LDA(REG_PV, REG_ITMP1, disp); /* recompute pv from ra */
3500 /* remove stackframe if there is one */
3501 if (stackframesize) {
3502 M_LDA(REG_SP, REG_SP, stackframesize * 8);
3505 /* 20 instructions */
3508 M_LDA(REG_SP, REG_SP, -10 * 8);
3509 M_DST(REG_FRESULT, REG_SP, 48+0);
3510 M_IST(REG_RESULT, REG_SP, 48+8);
3511 M_AST(REG_ITMP3, REG_SP, 48+12);
3512 M_IST(REG_RESULT2, REG_SP, 48+16);
3514 /* keep this order */
3515 switch (m->returntype) {
3518 M_MOV(REG_RESULT, rd->argintregs[2]);
3519 M_CLR(rd->argintregs[1]);
3523 M_MOV(REG_RESULT2, rd->argintregs[2]);
3524 M_MOV(REG_RESULT, rd->argintregs[1]);
3527 M_ALD(rd->argintregs[0], REG_PV, -6 * 4);
3529 M_FLTMOVE(REG_FRESULT, rd->argfltregs[0]);
3530 M_FLTMOVE(REG_FRESULT, rd->argfltregs[1]);
3531 M_ALD(REG_ITMP2, REG_PV, -7 * 4);/* builtin_displaymethodstop */
3534 M_DLD(REG_FRESULT, REG_SP, 48+0);
3535 M_ILD(REG_RESULT, REG_SP, 48+8);
3536 M_ALD(REG_ITMP3, REG_SP, 48+12);
3537 M_ILD(REG_RESULT2, REG_SP, 48+16);
3538 M_LDA(REG_SP, REG_SP, 10 * 8);
3542 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3543 if (IS_FLT_DBL_TYPE(m->returntype))
3544 if (IS_2_WORD_TYPE(m->returntype))
3545 M_DST(REG_FRESULT, REG_SP, 56);
3547 M_FST(REG_FRESULT, REG_SP, 56);
3549 M_IST(REG_RESULT, REG_SP, 56);
3550 if (IS_2_WORD_TYPE(m->returntype))
3551 M_IST(REG_RESULT2, REG_SP, 60);
3554 M_ALD(REG_ITMP2, REG_PV, -2 * 4); /* builtin_get_exceptionptrptr */
3557 disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
3559 M_LDA(REG_PV, REG_ITMP1, disp);
3560 M_MOV(REG_RESULT, REG_ITMP2);
3562 if (IS_FLT_DBL_TYPE(m->returntype))
3563 if (IS_2_WORD_TYPE(m->returntype))
3564 M_DLD(REG_FRESULT, REG_SP, 56);
3566 M_FLD(REG_FRESULT, REG_SP, 56);
3568 M_ILD(REG_RESULT, REG_SP, 56);
3569 if (IS_2_WORD_TYPE(m->returntype))
3570 M_ILD(REG_RESULT2, REG_SP, 60);
3573 M_ALD(REG_ITMP2, REG_PV, -2 * 4); /* get address of exceptionptr */
3575 M_ALD(REG_ITMP1, REG_ITMP2, 0); /* load exception into reg. itmp1 */
3577 M_BNE(4); /* if no exception then return */
3579 M_ALD(REG_ITMP1, REG_SP, 64 + 8); /* load return address */
3581 M_LDA(REG_SP, REG_SP, 64); /* remove stackframe */
3586 M_AST(REG_ITMP3, REG_ITMP2, 0); /* store NULL into exceptionptr */
3588 M_ALD(REG_ITMP3, REG_SP, 64 + 8); /* load return address */
3590 M_LDA(REG_SP, REG_SP, 64); /* remove stackframe */
3592 M_LDA(REG_ITMP2, REG_ITMP1, -4); /* move fault address into reg. itmp2 */
3594 M_ALD(REG_ITMP3, REG_PV, -3 * 4); /* load asm exception handler address */
3599 dolog_plain("stubsize: %d (for %d params)\n", (int) (mcodeptr - (s4 *) s), m->paramcount);
3602 asm_cacheflush((void *) s, (u1*) mcodeptr - (u1*) s);
3604 #if defined(STATISTICS)
3606 count_nstub_len += NATIVESTUBSIZE * 4;
3609 /* release dump area */
3611 dump_release(dumpsize);
3613 return (u1*) (s + NATIVESTUBOFFSET);
3617 /* function: removenativestub **************************************************
3619 removes a previously created native-stub from memory
3621 *******************************************************************************/
3623 void removenativestub(u1 *stub)
3625 CFREE((s4 *) stub - NATIVESTUBOFFSET, NATIVESTUBSIZE * 4);
3630 * These are local overrides for various environment variables in Emacs.
3631 * Please do not remove this and leave it at the end of the file, where
3632 * Emacs will automagically detect them.
3633 * ---------------------------------------------------------------------
3636 * indent-tabs-mode: t