1 /***************************** alpha/ngen.c ************************************
3 Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
5 See file COPYRIGHT for information on usage and disclaimer of warranties
7 Contains the codegenerator for an Alpha processor.
8 This module generates Alpha machine code for a sequence of
9 pseudo commands (ICMDs).
11 Authors: Andreas Krall EMAIL: cacao@complang.tuwien.ac.at
12 Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at
14 Last Change: 1998/08/10
16 *******************************************************************************/
20 /*******************************************************************************
22 Datatypes and Register Allocations:
23 -----------------------------------
25 On 64-bit-machines (like the Alpha) all operands are stored in the
26 registers in a 64-bit form, even when the correspondig JavaVM
27 operands only need 32 bits.
28 This is done by a canonical representation:
30 32-bit integers are allways stored as sign-extended 64-bit values
31 (this approach is directly supported by the Alpha architecture and
32 is very easy to implement).
34 32-bit-floats are stored in a 64-bit doubleprecision register by
35 simply expanding the exponent and mantissa with zeroes.
36 (also supported by the architecture)
41 The calling conventions and the layout of the stack is
42 explained in detail in the documention file: calling.doc
44 *******************************************************************************/
47 /*********** additional functions and macros to generate code *****************/
49 #define BlockPtrOfPC(pc) block+block_index[pc]
52 #define COUNT_SPILLS count_spills++
58 /* gen_nullptr_check(objreg) */
60 #ifdef SOFTNULLPTRCHECK
61 #define gen_nullptr_check(objreg) \
64 mcode_addxnullrefs(mcodeptr);\
67 #define gen_nullptr_check(objreg)
71 /* MCODECHECK(icnt) */
73 #define MCODECHECK(icnt) \
74 if((mcodeptr+(icnt))>mcodeend)mcodeptr=mcode_increase((u1*)mcodeptr)
77 generates an integer-move from register a to b.
78 if a and b are the same int-register, no code will be generated.
81 #define M_INTMOVE(a,b) if(a!=b){M_OR(a,a,b,0);}
85 generates a floating-point-move from register a to b.
86 if a and b are the same float-register, no code will be generated
89 #define M_FLTMOVE(a,b) if(a!=b){M_FMOV(a,b);}
93 this function generates code to fetch data from a pseudo-register
95 If the pseudo-register has actually been assigned to a real
96 register, no code will be emitted, since following operations
97 can use this register directly.
99 v: pseudoregister to be fetched from
100 tempregnum: temporary register to be used if v is actually spilled to ram
102 return: the register number, where the operand can be found after
103 fetching (this wil be either tempregnum or the register
104 number allready given to v)
107 #define var_to_reg_int(regnr,v,tempnr) { \
108 if ((v)->flags & INMEMORY) \
109 {COUNT_SPILLS;M_LLD(tempnr,REG_SP,8*(v)->regoff);regnr=tempnr;} \
110 else regnr=(v)->regoff; \
114 #define var_to_reg_flt(regnr,v,tempnr) { \
115 if ((v)->flags & INMEMORY) \
116 {COUNT_SPILLS;M_DLD(tempnr,REG_SP,8*(v)->regoff);regnr=tempnr;} \
117 else regnr=(v)->regoff; \
122 This function determines a register, to which the result of an
123 operation should go, when it is ultimatively intended to store the result
125 If v is assigned to an actual register, this register will be
127 Otherwise (when v is spilled) this function returns tempregnum.
128 If not already done, regoff and flags are set in the stack location.
131 static int reg_of_var(stackptr v, int tempregnum)
135 switch (v->varkind) {
137 if (!(v->flags & INMEMORY))
141 var = &(interfaces[v->varnum][v->type]);
142 v->regoff = var->regoff;
143 if (!(var->flags & INMEMORY))
147 var = &(locals[v->varnum][v->type]);
148 v->regoff = var->regoff;
149 if (!(var->flags & INMEMORY))
153 v->regoff = v->varnum;
154 if (IS_FLT_DBL_TYPE(v->type)) {
155 if (v->varnum < fltreg_argnum) {
156 v->regoff = argfltregs[v->varnum];
157 return(argfltregs[v->varnum]);
161 if (v->varnum < intreg_argnum) {
162 v->regoff = argintregs[v->varnum];
163 return(argintregs[v->varnum]);
165 v->regoff -= intreg_argnum;
168 v->flags |= INMEMORY;
173 /* store_reg_to_var_xxx:
174 This function generates the code to store the result of an operation
175 back into a spilled pseudo-variable.
176 If the pseudo-variable has not been spilled in the first place, this
177 function will generate nothing.
179 v ............ Pseudovariable
180 tempregnum ... Number of the temporary registers as returned by
184 #define store_reg_to_var_int(sptr, tempregnum) { \
185 if ((sptr)->flags & INMEMORY) { \
187 M_LST(tempregnum, REG_SP, 8 * (sptr)->regoff); \
191 #define store_reg_to_var_flt(sptr, tempregnum) { \
192 if ((sptr)->flags & INMEMORY) { \
194 M_DST(tempregnum, REG_SP, 8 * (sptr)->regoff); \
199 void asm_signal_exception(void *xptr, void *sigctx);
201 void catch_NullPointerException(int sig, int code, void *sigctx)
205 /* Reset signal handler - necessary for SysV, does no harm for BSD */
207 signal(sig, (void*) catch_NullPointerException);
209 sigaddset(&nsig, sig);
210 sigprocmask(SIG_UNBLOCK, &nsig, 0);
211 asm_signal_exception(proto_java_lang_NullPointerException, sigctx);
216 void init_exceptions(void)
223 extern unsigned long ieee_get_fp_control();
224 extern void ieee_set_fp_control(unsigned long fp_control);
226 void init_exceptions(void)
228 /* initialise floating point control */
229 ieee_set_fp_control(ieee_get_fp_control()
230 & ~IEEE_TRAP_ENABLE_INV
231 & ~IEEE_TRAP_ENABLE_DZE
232 /* & ~IEEE_TRAP_ENABLE_UNF */
233 & ~IEEE_TRAP_ENABLE_OVF);
236 /* Catch signal we need to convert to exceptions */
239 signal(SIGSEGV, (void*) catch_NullPointerException);
242 signal(SIGBUS, (void*) catch_NullPointerException);
247 /*************************** function gen_mcode ********************************
249 generates machine code
251 *******************************************************************************/
253 #define MethodPointer -8
254 #define FrameSize -12
259 #define ExTableSize -32
260 #define ExTableStart -32
262 #define ExEntrySize -32
265 #define ExHandlerPC -24
266 #define ExCatchType -32
268 static void gen_mcode()
270 int len, s1, s2, s3, d, bbs;
281 savedregs_num = (isleafmethod) ? 0 : 1; /* space to save the RA */
283 /* space to save used callee saved registers */
285 savedregs_num += (savintregcnt - maxsavintreguse);
286 savedregs_num += (savfltregcnt - maxsavfltreguse);
288 parentargs_base = maxmemuse + savedregs_num;
291 if (checksync && (method->flags & ACC_SYNCHRONIZED))
295 /* create method header */
297 (void) dseg_addaddress(method); /* MethodPointer */
298 (void) dseg_adds4(parentargs_base * 8); /* FrameSize */
301 if (checksync && (method->flags & ACC_SYNCHRONIZED))
302 (void) dseg_adds4((maxmemuse + 1) * 8); /* IsSync */
305 (void) dseg_adds4(0); /* IsSync */
307 (void) dseg_adds4(isleafmethod); /* IsLeaf */
308 (void) dseg_adds4(savintregcnt - maxsavintreguse); /* IntSave */
309 (void) dseg_adds4(savfltregcnt - maxsavfltreguse); /* FltSave */
310 (void) dseg_adds4(exceptiontablelength); /* ExTableSize */
312 for (len = 0; len < exceptiontablelength; len++) {
313 dseg_addtarget(BlockPtrOfPC(extable[len].startpc));
314 dseg_addtarget(BlockPtrOfPC(extable[len].endpc));
315 dseg_addtarget(BlockPtrOfPC(extable[len].handlerpc));
316 (void) dseg_addaddress(extable[len].catchtype);
319 /* initialise mcode variables */
321 mcodeptr = (s4*) mcodebase;
322 mcodeend = (s4*) (mcodebase + mcodesize);
325 /* create stack frame (if necessary) */
328 {M_LDA (REG_SP, REG_SP, -parentargs_base * 8);}
330 /* save return address and used callee saved registers */
334 {p--; M_LST (REG_RA, REG_SP, 8*p);}
335 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
336 {p--; M_LST (savintregs[r], REG_SP, 8 * p);}
337 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
338 {p--; M_DST (savfltregs[r], REG_SP, 8 * p);}
340 /* save monitorenter argument */
343 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
344 if (method->flags & ACC_STATIC) {
345 p = dseg_addaddress (class);
346 M_LLD(REG_ITMP1, REG_PV, p);
347 M_LST(REG_ITMP1, REG_SP, 8 * maxmemuse);
350 M_LST (argintregs[0], REG_SP, 8 * maxmemuse);
355 if (runverbose && isleafmethod) {
356 M_LDA (REG_SP, REG_SP, -(8*8));
357 M_LST(REG_RA, REG_SP, 1*8);
358 M_LST(argintregs[0], REG_SP, 2*8);
359 M_LST(argintregs[1], REG_SP, 3*8);
360 M_LST(argintregs[2], REG_SP, 4*8);
361 M_LST(argintregs[3], REG_SP, 5*8);
362 M_LST(argintregs[4], REG_SP, 6*8);
363 M_LST(argintregs[5], REG_SP, 7*8);
364 p = dseg_addaddress (method);
365 M_LLD(REG_ITMP1, REG_PV, p);
366 M_LST(REG_ITMP1, REG_SP, 0);
367 p = dseg_addaddress ((void*) (builtin_trace_args));
368 M_LLD(REG_PV, REG_PV, p);
369 M_JSR(REG_RA, REG_PV);
370 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
371 M_LLD(REG_RA, REG_SP, 1*8);
372 M_LLD(argintregs[0], REG_SP, 2*8);
373 M_LLD(argintregs[1], REG_SP, 3*8);
374 M_LLD(argintregs[2], REG_SP, 4*8);
375 M_LLD(argintregs[3], REG_SP, 5*8);
376 M_LLD(argintregs[4], REG_SP, 6*8);
377 M_LLD(argintregs[5], REG_SP, 7*8);
378 M_LDA (REG_SP, REG_SP, 8*8);
381 /* take arguments out of register or stack frame */
383 for (p = 0, l = 0; p < mparamcount; p++) {
385 var = &(locals[l][t]);
387 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
392 if (IS_INT_LNG_TYPE(t)) { /* integer args */
393 if (p < INT_ARG_CNT) { /* register arguments */
394 if (!(var->flags & INMEMORY)) /* reg arg -> register */
395 {M_INTMOVE (argintregs[p], r);}
396 else /* reg arg -> spilled */
397 M_LST (argintregs[p], REG_SP, 8 * r);
399 else { /* stack arguments */
400 pa = p - INT_ARG_CNT;
401 if (!(var->flags & INMEMORY)) /* stack arg -> register */
402 M_LLD (r, REG_SP, 8 * (parentargs_base + pa));
403 else { /* stack arg -> spilled */
404 M_LLD (REG_ITMP1, REG_SP, 8 * (parentargs_base + pa));
405 M_LST (REG_ITMP1, REG_SP, 8 * r);
409 else { /* floating args */
410 if (p < FLT_ARG_CNT) { /* register arguments */
411 if (!(var->flags & INMEMORY)) /* reg arg -> register */
412 {M_FLTMOVE (argfltregs[p], r);}
413 else /* reg arg -> spilled */
414 M_DST (argfltregs[p], REG_SP, 8 * r);
416 else { /* stack arguments */
417 pa = p - FLT_ARG_CNT;
418 if (!(var->flags & INMEMORY)) /* stack-arg -> register */
419 M_DLD (r, REG_SP, 8 * (parentargs_base + pa) );
420 else { /* stack-arg -> spilled */
421 M_DLD (REG_FTMP1, REG_SP, 8 * (parentargs_base + pa));
422 M_DST (REG_FTMP1, REG_SP, 8 * r);
428 if (runverbose && !isleafmethod) {
429 M_LDA (REG_SP, REG_SP, -8);
430 p = dseg_addaddress (method);
431 M_LLD(REG_ITMP1, REG_PV, p);
432 M_LST(REG_ITMP1, REG_SP, 0);
433 p = dseg_addaddress ((void*) (builtin_trace_args));
434 M_LLD(REG_PV, REG_PV, p);
435 M_JSR(REG_RA, REG_PV);
436 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
437 M_LDA(REG_SP, REG_SP, 8);
441 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
442 p = dseg_addaddress ((void*) (builtin_monitorenter));
443 M_LLD(REG_PV, REG_PV, p);
444 M_LLD(argintregs[0], REG_SP, 8 * maxmemuse);
445 M_JSR(REG_RA, REG_PV);
446 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
451 /* end of header generation */
453 for (bbs = block_count, bptr = block; --bbs >= 0; bptr++) {
454 bptr -> mpc = (int)((u1*) mcodeptr - mcodebase);
456 /* branch resolving */
460 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
461 gen_resolvebranch((u1*) mcodebase + brefs->branchpos,
462 brefs->branchpos, bptr->mpc);
468 while (src != NULL) {
470 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
471 d = reg_of_var(src, REG_ITMP1);
472 M_INTMOVE(REG_ITMP1, d);
473 store_reg_to_var_int(src, d);
476 d = reg_of_var(src, REG_IFTMP);
477 if ((src->varkind != STACKVAR)) {
479 if (IS_FLT_DBL_TYPE(s2)) {
480 if (!(interfaces[len][s2].flags & INMEMORY)) {
481 s1 = interfaces[len][s2].regoff;
485 M_DLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
487 store_reg_to_var_flt(src, d);
490 if (!(interfaces[len][s2].flags & INMEMORY)) {
491 s1 = interfaces[len][s2].regoff;
495 M_LLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
497 store_reg_to_var_int(src, d);
505 len = bptr[1].ipc - s1;
506 for (iptr = &instr[s1];
508 src = iptr->dst, len--, iptr++) {
516 case ICMD_NULLCHECKPOP:
517 var_to_reg_int(s1, src, REG_ITMP1);
518 gen_nullptr_check(s1);
521 /*********************** constant operations **************************/
524 d = reg_of_var(iptr->dst, REG_ITMP1);
525 if ( (iptr->val.i >= -32768) && (iptr->val.i <= 32767) ) {
526 M_LDA(d, REG_ZERO, iptr->val.i);
529 a = dseg_adds4 (iptr->val.i);
532 store_reg_to_var_int(iptr->dst, d);
536 d = reg_of_var(iptr->dst, REG_ITMP1);
537 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767) ) {
538 M_LDA(d, REG_ZERO, iptr->val.l);
541 a = dseg_adds8 (iptr->val.l);
544 store_reg_to_var_int(iptr->dst, d);
548 d = reg_of_var (iptr->dst, REG_FTMP1);
549 a = dseg_addfloat (iptr->val.f);
551 store_reg_to_var_flt (iptr->dst, d);
555 d = reg_of_var (iptr->dst, REG_FTMP1);
556 a = dseg_adddouble (iptr->val.d);
558 store_reg_to_var_flt (iptr->dst, d);
563 d = reg_of_var(iptr->dst, REG_ITMP1);
565 a = dseg_addaddress (iptr->val.a);
569 M_INTMOVE(REG_ZERO, d);
571 store_reg_to_var_int(iptr->dst, d);
574 /********************** load/store operations *************************/
579 d = reg_of_var(iptr->dst, REG_ITMP1);
580 if ((iptr->dst->varkind == LOCALVAR) &&
581 (iptr->dst->varnum == iptr->op1))
583 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
584 if (var->flags & INMEMORY)
585 M_LLD(d, REG_SP, 8 * var->regoff);
587 {M_INTMOVE(var->regoff,d);}
588 store_reg_to_var_int(iptr->dst, d);
593 d = reg_of_var(iptr->dst, REG_FTMP1);
594 if ((iptr->dst->varkind == LOCALVAR) &&
595 (iptr->dst->varnum == iptr->op1))
597 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
598 if (var->flags & INMEMORY)
599 M_DLD(d, REG_SP, 8 * var->regoff);
601 {M_FLTMOVE(var->regoff,d);}
602 store_reg_to_var_flt(iptr->dst, d);
609 if ((src->varkind == LOCALVAR) &&
610 (src->varnum == iptr->op1))
612 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
613 if (var->flags & INMEMORY) {
614 var_to_reg_int(s1, src, REG_ITMP1);
615 M_LST(s1, REG_SP, 8 * var->regoff);
618 var_to_reg_int(s1, src, var->regoff);
619 M_INTMOVE(s1, var->regoff);
625 if ((src->varkind == LOCALVAR) &&
626 (src->varnum == iptr->op1))
628 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
629 if (var->flags & INMEMORY) {
630 var_to_reg_flt(s1, src, REG_FTMP1);
631 M_DST(s1, REG_SP, 8 * var->regoff);
634 var_to_reg_flt(s1, src, var->regoff);
635 M_FLTMOVE(s1, var->regoff);
640 /******************* pop/dup/swap operations **************************/
646 #define M_COPY(from,to) \
647 d = reg_of_var(to, REG_IFTMP); \
648 if ((from->regoff != to->regoff) || \
649 ((from->flags ^ to->flags) & INMEMORY)) { \
650 if (IS_FLT_DBL_TYPE(from->type)) { \
651 var_to_reg_flt(s1, from, d); \
653 store_reg_to_var_flt(to, d); \
656 var_to_reg_int(s1, from, d); \
658 store_reg_to_var_int(to, d); \
663 M_COPY(src, iptr->dst);
667 M_COPY(src, iptr->dst->prev->prev);
669 M_COPY(src, iptr->dst);
670 M_COPY(src->prev, iptr->dst->prev);
674 M_COPY(src->prev, iptr->dst->prev->prev->prev);
676 M_COPY(src, iptr->dst);
677 M_COPY(src->prev, iptr->dst->prev);
678 M_COPY(src->prev->prev, iptr->dst->prev->prev);
679 M_COPY(src, iptr->dst->prev->prev->prev);
683 M_COPY(src, iptr->dst);
684 M_COPY(src->prev, iptr->dst->prev);
685 M_COPY(src->prev->prev, iptr->dst->prev->prev);
686 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
687 M_COPY(src, iptr->dst->prev->prev->prev->prev);
688 M_COPY(src->prev, iptr->dst->prev->prev->prev->prev->prev);
692 M_COPY(src, iptr->dst->prev);
693 M_COPY(src->prev, iptr->dst);
697 /********************* integer operations *****************************/
700 var_to_reg_int(s1, src, REG_ITMP1);
701 d = reg_of_var(iptr->dst, REG_ITMP3);
702 M_ISUB(REG_ZERO, s1, d, 0);
703 store_reg_to_var_int(iptr->dst, d);
707 var_to_reg_int(s1, src, REG_ITMP1);
708 d = reg_of_var(iptr->dst, REG_ITMP3);
709 M_LSUB(REG_ZERO, s1, d, 0);
710 store_reg_to_var_int(iptr->dst, d);
714 var_to_reg_int(s1, src, REG_ITMP1);
715 d = reg_of_var(iptr->dst, REG_ITMP3);
717 store_reg_to_var_int(iptr->dst, d);
721 var_to_reg_int(s1, src, REG_ITMP1);
722 d = reg_of_var(iptr->dst, REG_ITMP3);
723 M_IADD(s1, REG_ZERO, d , 0);
724 store_reg_to_var_int(iptr->dst, d);
728 var_to_reg_int(s1, src, REG_ITMP1);
729 d = reg_of_var(iptr->dst, REG_ITMP3);
730 if (has_ext_instr_set) {
737 store_reg_to_var_int(iptr->dst, d);
741 var_to_reg_int(s1, src, REG_ITMP1);
742 d = reg_of_var(iptr->dst, REG_ITMP3);
743 M_ZAPNOT(s1, 0x03, d, 1);
744 store_reg_to_var_int(iptr->dst, d);
748 var_to_reg_int(s1, src, REG_ITMP1);
749 d = reg_of_var(iptr->dst, REG_ITMP3);
750 if (has_ext_instr_set) {
754 M_SLL( s1, 48, d, 1);
757 store_reg_to_var_int(iptr->dst, d);
760 #define ICONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
761 else{a=dseg_adds4(c);M_ILD(r,REG_PV,a);}
763 #define LCONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
764 else{a=dseg_adds8(c);M_LLD(r,REG_PV,a);}
768 var_to_reg_int(s1, src->prev, REG_ITMP1);
769 var_to_reg_int(s2, src, REG_ITMP2);
770 d = reg_of_var(iptr->dst, REG_ITMP3);
771 M_IADD(s1, s2, d, 0);
772 store_reg_to_var_int(iptr->dst, d);
775 var_to_reg_int(s1, src, REG_ITMP1);
776 d = reg_of_var(iptr->dst, REG_ITMP3);
777 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
778 M_IADD(s1, iptr->val.i, d, 1);
781 ICONST(REG_ITMP2, iptr->val.i);
782 M_IADD(s1, REG_ITMP2, d, 0);
784 store_reg_to_var_int(iptr->dst, d);
787 var_to_reg_int(s1, src->prev, REG_ITMP1);
788 var_to_reg_int(s2, src, REG_ITMP2);
789 d = reg_of_var(iptr->dst, REG_ITMP3);
790 M_LADD(s1, s2, d, 0);
791 store_reg_to_var_int(iptr->dst, d);
794 var_to_reg_int(s1, src, REG_ITMP1);
795 d = reg_of_var(iptr->dst, REG_ITMP3);
796 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
797 M_LADD(s1, iptr->val.l, d, 1);
800 LCONST(REG_ITMP2, iptr->val.l);
801 M_LADD(s1, REG_ITMP2, d, 0);
803 store_reg_to_var_int(iptr->dst, d);
807 var_to_reg_int(s1, src->prev, REG_ITMP1);
808 var_to_reg_int(s2, src, REG_ITMP2);
809 d = reg_of_var(iptr->dst, REG_ITMP3);
810 M_ISUB(s1, s2, d, 0);
811 store_reg_to_var_int(iptr->dst, d);
814 var_to_reg_int(s1, src, REG_ITMP1);
815 d = reg_of_var(iptr->dst, REG_ITMP3);
816 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
817 M_ISUB(s1, iptr->val.i, d, 1);
820 ICONST(REG_ITMP2, iptr->val.i);
821 M_ISUB(s1, REG_ITMP2, d, 0);
823 store_reg_to_var_int(iptr->dst, d);
826 var_to_reg_int(s1, src->prev, REG_ITMP1);
827 var_to_reg_int(s2, src, REG_ITMP2);
828 d = reg_of_var(iptr->dst, REG_ITMP3);
829 M_LSUB(s1, s2, d, 0);
830 store_reg_to_var_int(iptr->dst, d);
833 var_to_reg_int(s1, src, REG_ITMP1);
834 d = reg_of_var(iptr->dst, REG_ITMP3);
835 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
836 M_LSUB(s1, iptr->val.l, d, 1);
839 LCONST(REG_ITMP2, iptr->val.l);
840 M_LSUB(s1, REG_ITMP2, d, 0);
842 store_reg_to_var_int(iptr->dst, d);
846 var_to_reg_int(s1, src->prev, REG_ITMP1);
847 var_to_reg_int(s2, src, REG_ITMP2);
848 d = reg_of_var(iptr->dst, REG_ITMP3);
849 M_IMUL(s1, s2, d, 0);
850 store_reg_to_var_int(iptr->dst, d);
853 var_to_reg_int(s1, src, REG_ITMP1);
854 d = reg_of_var(iptr->dst, REG_ITMP3);
855 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
856 M_IMUL(s1, iptr->val.i, d, 1);
859 ICONST(REG_ITMP2, iptr->val.i);
860 M_IMUL(s1, REG_ITMP2, d, 0);
862 store_reg_to_var_int(iptr->dst, d);
865 var_to_reg_int(s1, src->prev, REG_ITMP1);
866 var_to_reg_int(s2, src, REG_ITMP2);
867 d = reg_of_var(iptr->dst, REG_ITMP3);
868 M_LMUL (s1, s2, d, 0);
869 store_reg_to_var_int(iptr->dst, d);
872 var_to_reg_int(s1, src, REG_ITMP1);
873 d = reg_of_var(iptr->dst, REG_ITMP3);
874 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
875 M_LMUL(s1, iptr->val.l, d, 1);
878 LCONST(REG_ITMP2, iptr->val.l);
879 M_LMUL(s1, REG_ITMP2, d, 0);
881 store_reg_to_var_int(iptr->dst, d);
886 var_to_reg_int(s1, src->prev, REG_ITMP1);
887 var_to_reg_int(s2, src, REG_ITMP2);
888 d = reg_of_var(iptr->dst, REG_ITMP3);
889 M_AND(s2, 0x1f, REG_ITMP3, 1);
890 M_SLL(s1, REG_ITMP3, d, 0);
891 M_IADD(d, REG_ZERO, d, 0);
892 store_reg_to_var_int(iptr->dst, d);
895 var_to_reg_int(s1, src, REG_ITMP1);
896 d = reg_of_var(iptr->dst, REG_ITMP3);
897 M_SLL(s1, iptr->val.i & 0x1f, d, 1);
898 M_IADD(d, REG_ZERO, d, 0);
899 store_reg_to_var_int(iptr->dst, d);
903 var_to_reg_int(s1, src->prev, REG_ITMP1);
904 var_to_reg_int(s2, src, REG_ITMP2);
905 d = reg_of_var(iptr->dst, REG_ITMP3);
906 M_AND(s2, 0x1f, REG_ITMP3, 1);
907 M_SRA(s1, REG_ITMP3, d, 0);
908 store_reg_to_var_int(iptr->dst, d);
911 var_to_reg_int(s1, src, REG_ITMP1);
912 d = reg_of_var(iptr->dst, REG_ITMP3);
913 M_SRA(s1, iptr->val.i & 0x1f, d, 1);
914 store_reg_to_var_int(iptr->dst, d);
918 var_to_reg_int(s1, src->prev, REG_ITMP1);
919 var_to_reg_int(s2, src, REG_ITMP2);
920 d = reg_of_var(iptr->dst, REG_ITMP3);
921 M_AND (s2, 0x1f, REG_ITMP2, 1);
922 M_ZAPNOT(s1, 0x0f, d, 1);
923 M_SRL ( d, REG_ITMP2, d, 0);
924 M_IADD ( d, REG_ZERO, d, 0);
925 store_reg_to_var_int(iptr->dst, d);
927 case ICMD_IUSHRCONST:
928 var_to_reg_int(s1, src, REG_ITMP1);
929 d = reg_of_var(iptr->dst, REG_ITMP3);
930 M_ZAPNOT(s1, 0x0f, d, 1);
931 M_SRL(d, iptr->val.i & 0x1f, d, 1);
932 M_IADD(d, REG_ZERO, d, 0);
933 store_reg_to_var_int(iptr->dst, d);
937 var_to_reg_int(s1, src->prev, REG_ITMP1);
938 var_to_reg_int(s2, src, REG_ITMP2);
939 d = reg_of_var(iptr->dst, REG_ITMP3);
941 store_reg_to_var_int(iptr->dst, d);
944 var_to_reg_int(s1, src, REG_ITMP1);
945 d = reg_of_var(iptr->dst, REG_ITMP3);
946 M_SLL(s1, iptr->val.l & 0x3f, d, 1);
947 store_reg_to_var_int(iptr->dst, d);
951 var_to_reg_int(s1, src->prev, REG_ITMP1);
952 var_to_reg_int(s2, src, REG_ITMP2);
953 d = reg_of_var(iptr->dst, REG_ITMP3);
955 store_reg_to_var_int(iptr->dst, d);
958 var_to_reg_int(s1, src, REG_ITMP1);
959 d = reg_of_var(iptr->dst, REG_ITMP3);
960 M_SRA(s1, iptr->val.l & 0x3f, d, 1);
961 store_reg_to_var_int(iptr->dst, d);
965 var_to_reg_int(s1, src->prev, REG_ITMP1);
966 var_to_reg_int(s2, src, REG_ITMP2);
967 d = reg_of_var(iptr->dst, REG_ITMP3);
969 store_reg_to_var_int(iptr->dst, d);
971 case ICMD_LUSHRCONST:
972 var_to_reg_int(s1, src, REG_ITMP1);
973 d = reg_of_var(iptr->dst, REG_ITMP3);
974 M_SRL(s1, iptr->val.l & 0x3f, d, 1);
975 store_reg_to_var_int(iptr->dst, d);
980 var_to_reg_int(s1, src->prev, REG_ITMP1);
981 var_to_reg_int(s2, src, REG_ITMP2);
982 d = reg_of_var(iptr->dst, REG_ITMP3);
984 store_reg_to_var_int(iptr->dst, d);
987 var_to_reg_int(s1, src, REG_ITMP1);
988 d = reg_of_var(iptr->dst, REG_ITMP3);
989 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
990 M_AND(s1, iptr->val.i, d, 1);
993 ICONST(REG_ITMP2, iptr->val.i);
994 M_AND(s1, REG_ITMP2, d, 0);
996 store_reg_to_var_int(iptr->dst, d);
999 var_to_reg_int(s1, src, REG_ITMP1);
1000 d = reg_of_var(iptr->dst, REG_ITMP3);
1001 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1002 M_AND(s1, iptr->val.l, d, 1);
1005 LCONST(REG_ITMP2, iptr->val.l);
1006 M_AND(s1, REG_ITMP2, d, 0);
1008 store_reg_to_var_int(iptr->dst, d);
1013 var_to_reg_int(s1, src->prev, REG_ITMP1);
1014 var_to_reg_int(s2, src, REG_ITMP2);
1015 d = reg_of_var(iptr->dst, REG_ITMP3);
1017 store_reg_to_var_int(iptr->dst, d);
1020 var_to_reg_int(s1, src, REG_ITMP1);
1021 d = reg_of_var(iptr->dst, REG_ITMP3);
1022 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1023 M_OR(s1, iptr->val.i, d, 1);
1026 ICONST(REG_ITMP2, iptr->val.i);
1027 M_OR(s1, REG_ITMP2, d, 0);
1029 store_reg_to_var_int(iptr->dst, d);
1032 var_to_reg_int(s1, src, REG_ITMP1);
1033 d = reg_of_var(iptr->dst, REG_ITMP3);
1034 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1035 M_OR(s1, iptr->val.l, d, 1);
1038 LCONST(REG_ITMP2, iptr->val.l);
1039 M_OR(s1, REG_ITMP2, d, 0);
1041 store_reg_to_var_int(iptr->dst, d);
1046 var_to_reg_int(s1, src->prev, REG_ITMP1);
1047 var_to_reg_int(s2, src, REG_ITMP2);
1048 d = reg_of_var(iptr->dst, REG_ITMP3);
1049 M_XOR(s1, s2, d, 0);
1050 store_reg_to_var_int(iptr->dst, d);
1052 case ICMD_IXORCONST:
1053 var_to_reg_int(s1, src, REG_ITMP1);
1054 d = reg_of_var(iptr->dst, REG_ITMP3);
1055 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1056 M_XOR(s1, iptr->val.i, d, 1);
1059 ICONST(REG_ITMP2, iptr->val.i);
1060 M_XOR(s1, REG_ITMP2, d, 0);
1062 store_reg_to_var_int(iptr->dst, d);
1064 case ICMD_LXORCONST:
1065 var_to_reg_int(s1, src, REG_ITMP1);
1066 d = reg_of_var(iptr->dst, REG_ITMP3);
1067 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1068 M_XOR(s1, iptr->val.l, d, 1);
1071 LCONST(REG_ITMP2, iptr->val.l);
1072 M_XOR(s1, REG_ITMP2, d, 0);
1074 store_reg_to_var_int(iptr->dst, d);
1079 var_to_reg_int(s1, src->prev, REG_ITMP1);
1080 var_to_reg_int(s2, src, REG_ITMP2);
1081 d = reg_of_var(iptr->dst, REG_ITMP3);
1082 M_CMPLT(s1, s2, REG_ITMP3, 0);
1083 M_CMPLT(s2, s1, REG_ITMP1, 0);
1084 M_LSUB (REG_ITMP1, REG_ITMP3, d, 0);
1085 store_reg_to_var_int(iptr->dst, d);
1090 var = &(locals[iptr->op1][TYPE_INT]);
1091 if (var->flags & INMEMORY) {
1093 M_LLD(s1, REG_SP, 8 * var->regoff);
1097 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1098 M_IADD(s1, iptr->val.i, s1, 1);
1100 else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1101 M_ISUB(s1, (-iptr->val.i), s1, 1);
1104 M_LDA (s1, s1, iptr->val.i);
1105 M_IADD(s1, REG_ZERO, s1, 0);
1107 if (var->flags & INMEMORY)
1108 M_LST(s1, REG_SP, 8 * var->regoff);
1112 /*********************** floating operations **************************/
1115 var_to_reg_flt(s1, src, REG_FTMP1);
1116 d = reg_of_var(iptr->dst, REG_FTMP3);
1118 store_reg_to_var_flt(iptr->dst, d);
1121 var_to_reg_flt(s1, src, REG_FTMP1);
1122 d = reg_of_var(iptr->dst, REG_FTMP3);
1124 store_reg_to_var_flt(iptr->dst, d);
1128 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1129 var_to_reg_flt(s2, src, REG_FTMP2);
1130 d = reg_of_var(iptr->dst, REG_FTMP3);
1138 store_reg_to_var_flt(iptr->dst, d);
1141 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1142 var_to_reg_flt(s2, src, REG_FTMP2);
1143 d = reg_of_var(iptr->dst, REG_FTMP3);
1151 store_reg_to_var_flt(iptr->dst, d);
1155 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1156 var_to_reg_flt(s2, src, REG_FTMP2);
1157 d = reg_of_var(iptr->dst, REG_FTMP3);
1165 store_reg_to_var_flt(iptr->dst, d);
1168 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1169 var_to_reg_flt(s2, src, REG_FTMP2);
1170 d = reg_of_var(iptr->dst, REG_FTMP3);
1178 store_reg_to_var_flt(iptr->dst, d);
1182 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1183 var_to_reg_flt(s2, src, REG_FTMP2);
1184 d = reg_of_var(iptr->dst, REG_FTMP3);
1192 store_reg_to_var_flt(iptr->dst, d);
1195 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1196 var_to_reg_flt(s2, src, REG_FTMP2);
1197 d = reg_of_var(iptr->dst, REG_FTMP3);
1205 store_reg_to_var_flt(iptr->dst, d);
1209 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1210 var_to_reg_flt(s2, src, REG_FTMP2);
1211 d = reg_of_var(iptr->dst, REG_FTMP3);
1219 store_reg_to_var_flt(iptr->dst, d);
1222 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1223 var_to_reg_flt(s2, src, REG_FTMP2);
1224 d = reg_of_var(iptr->dst, REG_FTMP3);
1232 store_reg_to_var_flt(iptr->dst, d);
1236 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1237 var_to_reg_flt(s2, src, REG_FTMP2);
1238 d = reg_of_var(iptr->dst, REG_FTMP3);
1240 M_FDIVS(s1,s2, REG_FTMP3);
1242 M_CVTDL_CS(REG_ZERO, REG_FTMP3, REG_FTMP3); /* round to integer */
1244 M_CVTLF(REG_ZERO, REG_FTMP3, REG_FTMP3);
1245 M_FMULS(REG_FTMP3, s2, REG_FTMP3);
1247 M_FSUBS(s1, REG_FTMP3, d);
1251 M_FDIV(s1,s2, REG_FTMP3);
1252 M_CVTDL_C(REG_ZERO, REG_FTMP3, REG_FTMP3); /* round to integer */
1253 M_CVTLF(REG_ZERO, REG_FTMP3, REG_FTMP3);
1254 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1255 M_FSUB(s1, REG_FTMP3, d);
1257 store_reg_to_var_flt(iptr->dst, d);
1260 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1261 var_to_reg_flt(s2, src, REG_FTMP2);
1262 d = reg_of_var(iptr->dst, REG_FTMP3);
1264 M_DDIVS(s1,s2, REG_FTMP3);
1266 M_CVTDL_CS(REG_ZERO, REG_FTMP3, REG_FTMP3); /* round to integer */
1268 M_CVTLD(REG_ZERO, REG_FTMP3, REG_FTMP3);
1269 M_DMULS(REG_FTMP3, s2, REG_FTMP3);
1271 M_DSUBS(s1, REG_FTMP3, d);
1275 M_DDIV(s1,s2, REG_FTMP3);
1276 M_CVTDL_C(REG_ZERO, REG_FTMP3, REG_FTMP3); /* round to integer */
1277 M_CVTLD(REG_ZERO, REG_FTMP3, REG_FTMP3);
1278 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1279 M_DSUB(s1, REG_FTMP3, d);
1281 store_reg_to_var_flt(iptr->dst, d);
1286 var_to_reg_int(s1, src, REG_ITMP1);
1287 d = reg_of_var(iptr->dst, REG_FTMP3);
1288 a = dseg_adddouble(0.0);
1289 M_LST (s1, REG_PV, a);
1290 M_DLD (d, REG_PV, a);
1291 M_CVTLF(REG_ZERO, d, d);
1292 store_reg_to_var_flt(iptr->dst, d);
1297 var_to_reg_int(s1, src, REG_ITMP1);
1298 d = reg_of_var(iptr->dst, REG_FTMP3);
1299 a = dseg_adddouble(0.0);
1300 M_LST (s1, REG_PV, a);
1301 M_DLD (d, REG_PV, a);
1302 M_CVTLD(REG_ZERO, d, d);
1303 store_reg_to_var_flt(iptr->dst, d);
1308 var_to_reg_flt(s1, src, REG_FTMP1);
1309 d = reg_of_var(iptr->dst, REG_ITMP3);
1310 a = dseg_adddouble(0.0);
1312 M_CVTDL_CS(REG_ZERO, s1, REG_FTMP1);
1314 M_CVTLIS(REG_FTMP1, REG_FTMP2);
1318 M_CVTDL_C(REG_ZERO, s1, REG_FTMP1);
1319 M_CVTLI(REG_FTMP1, REG_FTMP2);
1321 M_DST (REG_FTMP1, REG_PV, a);
1322 M_ILD (d, REG_PV, a);
1323 store_reg_to_var_int(iptr->dst, d);
1328 var_to_reg_flt(s1, src, REG_FTMP1);
1329 d = reg_of_var(iptr->dst, REG_ITMP3);
1330 a = dseg_adddouble(0.0);
1332 M_CVTDL_CS(REG_ZERO, s1, REG_FTMP1);
1336 M_CVTDL_C(REG_ZERO, s1, REG_FTMP1);
1338 M_DST (REG_FTMP1, REG_PV, a);
1339 M_LLD (d, REG_PV, a);
1340 store_reg_to_var_int(iptr->dst, d);
1344 var_to_reg_flt(s1, src, REG_FTMP1);
1345 d = reg_of_var(iptr->dst, REG_FTMP3);
1347 store_reg_to_var_flt(iptr->dst, d);
1351 var_to_reg_flt(s1, src, REG_FTMP1);
1352 d = reg_of_var(iptr->dst, REG_FTMP3);
1354 M_CVTDFS(REG_ZERO, s1, d);
1358 M_CVTDF(REG_ZERO, s1, d);
1360 store_reg_to_var_flt(iptr->dst, d);
1365 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1366 var_to_reg_flt(s2, src, REG_FTMP2);
1367 d = reg_of_var(iptr->dst, REG_ITMP3);
1369 M_LSUB (REG_ZERO, 1, d, 1);
1370 M_FCMPEQS(s1, s2, REG_FTMP3);
1372 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1373 M_OR (REG_ZERO, REG_ZERO, d, 0);
1374 M_FCMPLTS(s2, s1, REG_FTMP3);
1376 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1377 M_LADD (REG_ZERO, 1, d, 1);
1380 M_LSUB (REG_ZERO, 1, d, 1);
1381 M_FCMPEQ(s1, s2, REG_FTMP3);
1382 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1383 M_OR (REG_ZERO, REG_ZERO, d, 0);
1384 M_FCMPLT(s2, s1, REG_FTMP3);
1385 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1386 M_LADD (REG_ZERO, 1, d, 1);
1388 store_reg_to_var_int(iptr->dst, d);
1393 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1394 var_to_reg_flt(s2, src, REG_FTMP2);
1395 d = reg_of_var(iptr->dst, REG_ITMP3);
1397 M_LADD (REG_ZERO, 1, d, 1);
1398 M_FCMPEQS(s1, s2, REG_FTMP3);
1400 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1401 M_OR (REG_ZERO, REG_ZERO, d, 0);
1402 M_FCMPLTS(s1, s2, REG_FTMP3);
1404 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1405 M_LSUB (REG_ZERO, 1, d, 1);
1408 M_LADD (REG_ZERO, 1, d, 1);
1409 M_FCMPEQ(s1, s2, REG_FTMP3);
1410 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1411 M_OR (REG_ZERO, REG_ZERO, d, 0);
1412 M_FCMPLT(s1, s2, REG_FTMP3);
1413 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1414 M_LSUB (REG_ZERO, 1, d, 1);
1416 store_reg_to_var_int(iptr->dst, d);
1420 /********************** memory operations *****************************/
1422 #define gen_bound_check \
1424 M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\
1425 M_CMPULT(s2, REG_ITMP3, REG_ITMP3, 0);\
1426 M_BEQZ(REG_ITMP3, 0);\
1427 mcode_addxboundrefs(mcodeptr);\
1430 case ICMD_ARRAYLENGTH:
1431 var_to_reg_int(s1, src, REG_ITMP1);
1432 d = reg_of_var(iptr->dst, REG_ITMP3);
1433 gen_nullptr_check(s1);
1434 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1435 store_reg_to_var_int(iptr->dst, d);
1439 var_to_reg_int(s1, src->prev, REG_ITMP1);
1440 var_to_reg_int(s2, src, REG_ITMP2);
1441 d = reg_of_var(iptr->dst, REG_ITMP3);
1442 gen_nullptr_check(s1);
1444 M_S8ADDQ(s2, s1, REG_ITMP1, 0);
1445 M_LLD( d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1446 store_reg_to_var_int(iptr->dst, d);
1449 var_to_reg_int(s1, src->prev, REG_ITMP1);
1450 var_to_reg_int(s2, src, REG_ITMP2);
1451 d = reg_of_var(iptr->dst, REG_ITMP3);
1452 gen_nullptr_check(s1);
1454 M_S8ADDQ(s2, s1, REG_ITMP1, 0);
1455 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1456 store_reg_to_var_int(iptr->dst, d);
1459 var_to_reg_int(s1, src->prev, REG_ITMP1);
1460 var_to_reg_int(s2, src, REG_ITMP2);
1461 d = reg_of_var(iptr->dst, REG_ITMP3);
1462 gen_nullptr_check(s1);
1464 M_S4ADDQ(s2, s1, REG_ITMP1, 0);
1465 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1466 store_reg_to_var_int(iptr->dst, d);
1469 var_to_reg_int(s1, src->prev, REG_ITMP1);
1470 var_to_reg_int(s2, src, REG_ITMP2);
1471 d = reg_of_var(iptr->dst, REG_FTMP3);
1472 gen_nullptr_check(s1);
1474 M_S4ADDQ(s2, s1, REG_ITMP1, 0);
1475 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1476 store_reg_to_var_flt(iptr->dst, d);
1479 var_to_reg_int(s1, src->prev, REG_ITMP1);
1480 var_to_reg_int(s2, src, REG_ITMP2);
1481 d = reg_of_var(iptr->dst, REG_FTMP3);
1482 gen_nullptr_check(s1);
1484 M_S8ADDQ(s2, s1, REG_ITMP1, 0);
1485 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1486 store_reg_to_var_flt(iptr->dst, d);
1489 var_to_reg_int(s1, src->prev, REG_ITMP1);
1490 var_to_reg_int(s2, src, REG_ITMP2);
1491 d = reg_of_var(iptr->dst, REG_ITMP3);
1492 gen_nullptr_check(s1);
1494 if (has_ext_instr_set) {
1495 M_LADD(s2, s1, REG_ITMP1, 0);
1496 M_LADD(s2, REG_ITMP1, REG_ITMP1, 0);
1497 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1500 M_LADD (s2, s1, REG_ITMP1, 0);
1501 M_LADD (s2, REG_ITMP1, REG_ITMP1, 0);
1502 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1503 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1504 M_EXTWL(REG_ITMP2, REG_ITMP1, d, 0);
1506 store_reg_to_var_int(iptr->dst, d);
1509 var_to_reg_int(s1, src->prev, REG_ITMP1);
1510 var_to_reg_int(s2, src, REG_ITMP2);
1511 d = reg_of_var(iptr->dst, REG_ITMP3);
1512 gen_nullptr_check(s1);
1514 if (has_ext_instr_set) {
1515 M_LADD(s2, s1, REG_ITMP1, 0);
1516 M_LADD(s2, REG_ITMP1, REG_ITMP1, 0);
1517 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1521 M_LADD(s2, s1, REG_ITMP1, 0);
1522 M_LADD(s2, REG_ITMP1, REG_ITMP1, 0);
1523 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1524 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1525 M_EXTQH(REG_ITMP2, REG_ITMP1, d, 0);
1528 store_reg_to_var_int(iptr->dst, d);
1531 var_to_reg_int(s1, src->prev, REG_ITMP1);
1532 var_to_reg_int(s2, src, REG_ITMP2);
1533 d = reg_of_var(iptr->dst, REG_ITMP3);
1534 gen_nullptr_check(s1);
1536 if (has_ext_instr_set) {
1537 M_LADD (s2, s1, REG_ITMP1, 0);
1538 M_BLDU (d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1542 M_LADD(s2, s1, REG_ITMP1, 0);
1543 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1544 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
1545 M_EXTQH(REG_ITMP2, REG_ITMP1, d, 0);
1548 store_reg_to_var_int(iptr->dst, d);
1552 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1553 var_to_reg_int(s2, src->prev, REG_ITMP2);
1554 gen_nullptr_check(s1);
1556 var_to_reg_int(s3, src, REG_ITMP3);
1557 M_S8ADDQ(s2, s1, REG_ITMP1, 0);
1558 M_LST (s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1561 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1562 var_to_reg_int(s2, src->prev, REG_ITMP2);
1563 gen_nullptr_check(s1);
1565 var_to_reg_int(s3, src, REG_ITMP3);
1566 M_S8ADDQ(s2, s1, REG_ITMP1, 0);
1567 M_LST (s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1570 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1571 var_to_reg_int(s2, src->prev, REG_ITMP2);
1572 gen_nullptr_check(s1);
1574 var_to_reg_int(s3, src, REG_ITMP3);
1575 M_S4ADDQ(s2, s1, REG_ITMP1, 0);
1576 M_IST (s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1579 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1580 var_to_reg_int(s2, src->prev, REG_ITMP2);
1581 gen_nullptr_check(s1);
1583 var_to_reg_flt(s3, src, REG_FTMP3);
1584 M_S4ADDQ(s2, s1, REG_ITMP1, 0);
1585 M_FST (s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1588 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1589 var_to_reg_int(s2, src->prev, REG_ITMP2);
1590 gen_nullptr_check(s1);
1592 var_to_reg_flt(s3, src, REG_FTMP3);
1593 M_S8ADDQ(s2, s1, REG_ITMP1, 0);
1594 M_DST (s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1597 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1598 var_to_reg_int(s2, src->prev, REG_ITMP2);
1599 gen_nullptr_check(s1);
1601 var_to_reg_int(s3, src, REG_ITMP3);
1602 if (has_ext_instr_set) {
1603 M_LADD(s2, s1, REG_ITMP1, 0);
1604 M_LADD(s2, REG_ITMP1, REG_ITMP1, 0);
1605 M_SST (s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1608 M_LADD (s2, s1, REG_ITMP1, 0);
1609 M_LADD (s2, REG_ITMP1, REG_ITMP1, 0);
1610 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1611 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1612 M_INSWL(s3, REG_ITMP1, REG_ITMP3, 0);
1613 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2, 0);
1614 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2, 0);
1615 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1619 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1620 var_to_reg_int(s2, src->prev, REG_ITMP2);
1621 gen_nullptr_check(s1);
1623 var_to_reg_int(s3, src, REG_ITMP3);
1624 if (has_ext_instr_set) {
1625 M_LADD(s2, s1, REG_ITMP1, 0);
1626 M_LADD(s2, REG_ITMP1, REG_ITMP1, 0);
1627 M_SST (s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1630 M_LADD (s2, s1, REG_ITMP1, 0);
1631 M_LADD (s2, REG_ITMP1, REG_ITMP1, 0);
1632 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1633 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1634 M_INSWL(s3, REG_ITMP1, REG_ITMP3, 0);
1635 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2, 0);
1636 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2, 0);
1637 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1641 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1642 var_to_reg_int(s2, src->prev, REG_ITMP2);
1643 gen_nullptr_check(s1);
1645 var_to_reg_int(s3, src, REG_ITMP3);
1646 if (has_ext_instr_set) {
1647 M_LADD(s2, s1, REG_ITMP1, 0);
1648 M_BST (s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1651 M_LADD (s2, s1, REG_ITMP1, 0);
1652 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1653 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1654 M_INSBL(s3, REG_ITMP1, REG_ITMP3, 0);
1655 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2, 0);
1656 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2, 0);
1657 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1662 case ICMD_PUTSTATIC:
1663 a = dseg_addaddress (iptr->val.a);
1664 M_LLD(REG_ITMP1, REG_PV, a);
1665 switch (iptr->op1) {
1667 var_to_reg_int(s2, src, REG_ITMP2);
1668 M_IST(s2, REG_ITMP1, 0);
1672 var_to_reg_int(s2, src, REG_ITMP2);
1673 M_LST(s2, REG_ITMP1, 0);
1676 var_to_reg_flt(s2, src, REG_FTMP2);
1677 M_FST(s2, REG_ITMP1, 0);
1680 var_to_reg_flt(s2, src, REG_FTMP2);
1681 M_DST(s2, REG_ITMP1, 0);
1683 default: panic ("internal error");
1687 case ICMD_GETSTATIC:
1688 a = dseg_addaddress (iptr->val.a);
1689 M_LLD(REG_ITMP1, REG_PV, a);
1690 switch (iptr->op1) {
1692 d = reg_of_var(iptr->dst, REG_ITMP3);
1693 M_ILD(d, REG_ITMP1, 0);
1694 store_reg_to_var_int(iptr->dst, d);
1698 d = reg_of_var(iptr->dst, REG_ITMP3);
1699 M_LLD(d, REG_ITMP1, 0);
1700 store_reg_to_var_int(iptr->dst, d);
1703 d = reg_of_var(iptr->dst, REG_FTMP1);
1704 M_FLD(d, REG_ITMP1, 0);
1705 store_reg_to_var_flt(iptr->dst, d);
1708 d = reg_of_var(iptr->dst, REG_FTMP1);
1709 M_DLD(d, REG_ITMP1, 0);
1710 store_reg_to_var_flt(iptr->dst, d);
1712 default: panic ("internal error");
1718 switch (iptr->op1) {
1720 var_to_reg_int(s1, src->prev, REG_ITMP1);
1721 var_to_reg_int(s2, src, REG_ITMP2);
1722 gen_nullptr_check(s1);
1723 M_IST(s2, s1, iptr->val.i);
1727 var_to_reg_int(s1, src->prev, REG_ITMP1);
1728 var_to_reg_int(s2, src, REG_ITMP2);
1729 gen_nullptr_check(s1);
1730 M_LST(s2, s1, iptr->val.i);
1733 var_to_reg_int(s1, src->prev, REG_ITMP1);
1734 var_to_reg_flt(s2, src, REG_FTMP2);
1735 gen_nullptr_check(s1);
1736 M_FST(s2, s1, iptr->val.i);
1739 var_to_reg_int(s1, src->prev, REG_ITMP1);
1740 var_to_reg_flt(s2, src, REG_FTMP2);
1741 gen_nullptr_check(s1);
1742 M_DST(s2, s1, iptr->val.i);
1744 default: panic ("internal error");
1749 switch (iptr->op1) {
1751 var_to_reg_int(s1, src, REG_ITMP1);
1752 d = reg_of_var(iptr->dst, REG_ITMP3);
1753 gen_nullptr_check(s1);
1754 M_ILD(d, s1, iptr->val.i);
1755 store_reg_to_var_int(iptr->dst, d);
1759 var_to_reg_int(s1, src, REG_ITMP1);
1760 d = reg_of_var(iptr->dst, REG_ITMP3);
1761 gen_nullptr_check(s1);
1762 M_LLD(d, s1, iptr->val.i);
1763 store_reg_to_var_int(iptr->dst, d);
1766 var_to_reg_int(s1, src, REG_ITMP1);
1767 d = reg_of_var(iptr->dst, REG_FTMP1);
1768 gen_nullptr_check(s1);
1769 M_FLD(d, s1, iptr->val.i);
1770 store_reg_to_var_flt(iptr->dst, d);
1773 var_to_reg_int(s1, src, REG_ITMP1);
1774 d = reg_of_var(iptr->dst, REG_FTMP1);
1775 gen_nullptr_check(s1);
1776 M_DLD(d, s1, iptr->val.i);
1777 store_reg_to_var_flt(iptr->dst, d);
1779 default: panic ("internal error");
1784 /********************** branch operations *****************************/
1786 #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}}
1789 var_to_reg_int(s1, src, REG_ITMP1);
1790 M_INTMOVE(s1, REG_ITMP1_XPTR);
1791 a = dseg_addaddress(asm_handle_exception);
1792 M_LLD(REG_ITMP2, REG_PV, a);
1793 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
1799 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
1804 M_BSR(REG_ITMP1, 0);
1805 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
1809 var = &(locals[iptr->op1][TYPE_ADR]);
1810 if (var->flags & INMEMORY) {
1811 M_LLD(REG_ITMP1, REG_SP, 8 * var->regoff);
1812 M_RET(REG_ZERO, REG_ITMP1);
1815 M_RET(REG_ZERO, var->regoff);
1820 var_to_reg_int(s1, src, REG_ITMP1);
1822 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
1824 case ICMD_IFNONNULL:
1825 var_to_reg_int(s1, src, REG_ITMP1);
1827 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
1831 var_to_reg_int(s1, src, REG_ITMP1);
1832 if (iptr->val.i == 0) {
1836 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
1837 M_CMPEQ(s1, iptr->val.i, REG_ITMP1, 1);
1840 ICONST(REG_ITMP2, iptr->val.i);
1841 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1, 0);
1843 M_BNEZ(REG_ITMP1, 0);
1845 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
1848 var_to_reg_int(s1, src, REG_ITMP1);
1849 if (iptr->val.i == 0) {
1853 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
1854 M_CMPLT(s1, iptr->val.i, REG_ITMP1, 1);
1857 ICONST(REG_ITMP2, iptr->val.i);
1858 M_CMPLT(s1, REG_ITMP2, REG_ITMP1, 0);
1860 M_BNEZ(REG_ITMP1, 0);
1862 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
1865 var_to_reg_int(s1, src, REG_ITMP1);
1866 if (iptr->val.i == 0) {
1870 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
1871 M_CMPLE(s1, iptr->val.i, REG_ITMP1, 1);
1874 ICONST(REG_ITMP2, iptr->val.i);
1875 M_CMPLE(s1, REG_ITMP2, REG_ITMP1, 0);
1877 M_BNEZ(REG_ITMP1, 0);
1879 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
1882 var_to_reg_int(s1, src, REG_ITMP1);
1883 if (iptr->val.i == 0) {
1887 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
1888 M_CMPEQ(s1, iptr->val.i, REG_ITMP1, 1);
1891 ICONST(REG_ITMP2, iptr->val.i);
1892 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1, 0);
1894 M_BEQZ(REG_ITMP1, 0);
1896 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
1899 var_to_reg_int(s1, src, REG_ITMP1);
1900 if (iptr->val.i == 0) {
1904 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
1905 M_CMPLE(s1, iptr->val.i, REG_ITMP1, 1);
1908 ICONST(REG_ITMP2, iptr->val.i);
1909 M_CMPLE(s1, REG_ITMP2, REG_ITMP1, 0);
1911 M_BEQZ(REG_ITMP1, 0);
1913 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
1916 var_to_reg_int(s1, src, REG_ITMP1);
1917 if (iptr->val.i == 0) {
1921 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
1922 M_CMPLT(s1, iptr->val.i, REG_ITMP1, 1);
1925 ICONST(REG_ITMP2, iptr->val.i);
1926 M_CMPLT(s1, REG_ITMP2, REG_ITMP1, 0);
1928 M_BEQZ(REG_ITMP1, 0);
1930 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
1934 var_to_reg_int(s1, src, REG_ITMP1);
1935 if (iptr->val.l == 0) {
1939 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
1940 M_CMPEQ(s1, iptr->val.l, REG_ITMP1, 1);
1943 LCONST(REG_ITMP2, iptr->val.l);
1944 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1, 0);
1946 M_BNEZ(REG_ITMP1, 0);
1948 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
1951 var_to_reg_int(s1, src, REG_ITMP1);
1952 if (iptr->val.l == 0) {
1956 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
1957 M_CMPLT(s1, iptr->val.l, REG_ITMP1, 1);
1960 LCONST(REG_ITMP2, iptr->val.l);
1961 M_CMPLT(s1, REG_ITMP2, REG_ITMP1, 0);
1963 M_BNEZ(REG_ITMP1, 0);
1965 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
1968 var_to_reg_int(s1, src, REG_ITMP1);
1969 if (iptr->val.l == 0) {
1973 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
1974 M_CMPLE(s1, iptr->val.l, REG_ITMP1, 1);
1977 LCONST(REG_ITMP2, iptr->val.l);
1978 M_CMPLE(s1, REG_ITMP2, REG_ITMP1, 0);
1980 M_BNEZ(REG_ITMP1, 0);
1982 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
1985 var_to_reg_int(s1, src, REG_ITMP1);
1986 if (iptr->val.l == 0) {
1990 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
1991 M_CMPEQ(s1, iptr->val.l, REG_ITMP1, 1);
1994 LCONST(REG_ITMP2, iptr->val.l);
1995 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1, 0);
1997 M_BEQZ(REG_ITMP1, 0);
1999 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2002 var_to_reg_int(s1, src, REG_ITMP1);
2003 if (iptr->val.l == 0) {
2007 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2008 M_CMPLE(s1, iptr->val.l, REG_ITMP1, 1);
2011 LCONST(REG_ITMP2, iptr->val.l);
2012 M_CMPLE(s1, REG_ITMP2, REG_ITMP1, 0);
2014 M_BEQZ(REG_ITMP1, 0);
2016 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2019 var_to_reg_int(s1, src, REG_ITMP1);
2020 if (iptr->val.l == 0) {
2024 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2025 M_CMPLT(s1, iptr->val.l, REG_ITMP1, 1);
2028 LCONST(REG_ITMP2, iptr->val.l);
2029 M_CMPLT(s1, REG_ITMP2, REG_ITMP1, 0);
2031 M_BEQZ(REG_ITMP1, 0);
2033 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2036 case ICMD_IF_ICMPEQ:
2037 case ICMD_IF_LCMPEQ:
2038 case ICMD_IF_ACMPEQ:
2039 var_to_reg_int(s1, src->prev, REG_ITMP1);
2040 var_to_reg_int(s2, src, REG_ITMP2);
2041 M_CMPEQ(s1, s2, REG_ITMP1, 0);
2042 M_BNEZ(REG_ITMP1, 0);
2043 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2045 case ICMD_IF_ICMPNE:
2046 case ICMD_IF_LCMPNE:
2047 case ICMD_IF_ACMPNE:
2048 var_to_reg_int(s1, src->prev, REG_ITMP1);
2049 var_to_reg_int(s2, src, REG_ITMP2);
2050 M_CMPEQ(s1, s2, REG_ITMP1, 0);
2051 M_BEQZ(REG_ITMP1, 0);
2052 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2054 case ICMD_IF_ICMPLT:
2055 case ICMD_IF_LCMPLT:
2056 var_to_reg_int(s1, src->prev, REG_ITMP1);
2057 var_to_reg_int(s2, src, REG_ITMP2);
2058 M_CMPLT(s1, s2, REG_ITMP1, 0);
2059 M_BNEZ(REG_ITMP1, 0);
2060 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2062 case ICMD_IF_ICMPGT:
2063 case ICMD_IF_LCMPGT:
2064 var_to_reg_int(s1, src->prev, REG_ITMP1);
2065 var_to_reg_int(s2, src, REG_ITMP2);
2066 M_CMPLE(s1, s2, REG_ITMP1, 0);
2067 M_BEQZ(REG_ITMP1, 0);
2068 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2070 case ICMD_IF_ICMPLE:
2071 case ICMD_IF_LCMPLE:
2072 var_to_reg_int(s1, src->prev, REG_ITMP1);
2073 var_to_reg_int(s2, src, REG_ITMP2);
2074 M_CMPLE(s1, s2, REG_ITMP1, 0);
2075 M_BNEZ(REG_ITMP1, 0);
2076 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2078 case ICMD_IF_ICMPGE:
2079 case ICMD_IF_LCMPGE:
2080 var_to_reg_int(s1, src->prev, REG_ITMP1);
2081 var_to_reg_int(s2, src, REG_ITMP2);
2082 M_CMPLT(s1, s2, REG_ITMP1, 0);
2083 M_BEQZ(REG_ITMP1, 0);
2084 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2087 /* branch if the unsigned value of s1 is greater that s2 (note, that s2 has
2090 /* case ICMD_IF_UCMPGE:
2091 var_to_reg_int(s1, src->prev, REG_ITMP1);
2092 var_to_reg_int(s2, src, REG_ITMP2);
2093 M_CMPULE(s2, s1, REG_ITMP1, 0);
2094 M_BNEZ(REG_ITMP1, 0);
2095 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2104 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2105 a = dseg_addaddress ((void*) (builtin_monitorexit));
2106 M_LLD(REG_PV, REG_PV, a);
2107 M_LLD(argintregs[0], REG_SP, 8 * maxmemuse);
2108 M_JSR(REG_RA, REG_PV);
2109 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2112 var_to_reg_int(s1, src, REG_RESULT);
2113 M_INTMOVE(s1, REG_RESULT);
2114 goto nowperformreturn;
2120 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2121 a = dseg_addaddress ((void*) (builtin_monitorexit));
2122 M_LLD(REG_PV, REG_PV, a);
2123 M_LLD(argintregs[0], REG_SP, 8 * maxmemuse);
2124 M_JSR(REG_RA, REG_PV);
2125 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2128 var_to_reg_flt(s1, src, REG_FRESULT);
2129 M_FLTMOVE(s1, REG_FRESULT);
2130 goto nowperformreturn;
2135 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2136 a = dseg_addaddress ((void*) (builtin_monitorexit));
2137 M_LLD(REG_PV, REG_PV, a);
2138 M_LLD(argintregs[0], REG_SP, 8 * maxmemuse);
2139 M_JSR(REG_RA, REG_PV);
2140 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2148 p = parentargs_base;
2150 {p--; M_LLD (REG_RA, REG_SP, 8 * p);}
2151 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
2152 {p--; M_LLD(savintregs[r], REG_SP, 8 * p);}
2153 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
2154 {p--; M_DLD(savfltregs[r], REG_SP, 8 * p);}
2156 if (parentargs_base)
2157 {M_LDA(REG_SP, REG_SP, parentargs_base*8);}
2159 M_LDA (REG_SP, REG_SP, -24);
2160 M_LST(REG_RA, REG_SP, 0);
2161 M_LST(REG_RESULT, REG_SP, 8);
2162 M_DST(REG_FRESULT, REG_SP,16);
2163 a = dseg_addaddress (method);
2164 M_LLD(argintregs[0], REG_PV, a);
2165 M_OR(REG_RESULT, REG_RESULT, argintregs[1], 0);
2166 M_FLTMOVE(REG_FRESULT, argfltregs[2]);
2167 a = dseg_addaddress ((void*) (builtin_displaymethodstop));
2168 M_LLD(REG_PV, REG_PV, a);
2169 M_JSR (REG_RA, REG_PV);
2170 s1 = (int)((u1*) mcodeptr - mcodebase);
2171 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
2174 while (ml<-32768) { ml+=65536; mh--; }
2175 M_LDA (REG_PV, REG_RA, ml );
2176 M_LDAH (REG_PV, REG_PV, mh );
2178 M_DLD(REG_FRESULT, REG_SP,16);
2179 M_LLD(REG_RESULT, REG_SP, 8);
2180 M_LLD(REG_RA, REG_SP, 0);
2181 M_LDA (REG_SP, REG_SP, 24);
2183 M_RET(REG_ZERO, REG_RA);
2189 case ICMD_TABLESWITCH:
2193 s4ptr = iptr->val.a;
2194 l = s4ptr[1]; /* low */
2195 i = s4ptr[2]; /* high */
2197 var_to_reg_int(s1, src, REG_ITMP1);
2199 {M_INTMOVE(s1, REG_ITMP1);}
2201 M_LDA(REG_ITMP1, s1, -l);
2205 M_CMPULE(REG_ITMP1, i - 1, REG_ITMP2, 1);
2207 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
2208 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2, 0);
2210 M_BEQZ(REG_ITMP2, 0);
2211 mcode_addreference(BlockPtrOfPC(s4ptr[0]), mcodeptr);
2213 /* build jump table top down and use address of lowest entry */
2217 dseg_addtarget(BlockPtrOfPC(*--s4ptr));
2221 /* length of dataseg after last dseg_addtarget is used by load */
2223 M_S8ADDQ(REG_ITMP1, REG_PV, REG_ITMP2, 0);
2224 M_LLD(REG_ITMP2, REG_ITMP2, -dseglen);
2225 M_JMP(REG_ZERO, REG_ITMP2);
2230 case ICMD_LOOKUPSWITCH:
2232 s4 i, l, val, *s4ptr;
2234 s4ptr = iptr->val.a;
2235 l = s4ptr[0]; /* default */
2236 i = s4ptr[1]; /* count */
2238 MCODECHECK((i<<2)+8);
2239 var_to_reg_int(s1, src, REG_ITMP1);
2243 if ((val >= 0) && (val <= 255)) {
2244 M_CMPEQ(s1, val, REG_ITMP2, 1);
2247 if ((val >= -32768) && (val <= 32767)) {
2248 M_LDA(REG_ITMP2, REG_ZERO, val);
2251 a = dseg_adds4 (val);
2252 M_ILD(REG_ITMP2, REG_PV, a);
2254 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2, 0);
2256 M_BNEZ(REG_ITMP2, 0);
2257 mcode_addreference(BlockPtrOfPC(s4ptr[1]), mcodeptr);
2261 mcode_addreference(BlockPtrOfPC(l), mcodeptr);
2279 case ICMD_INVOKESTATIC:
2280 case ICMD_INVOKESPECIAL:
2281 case ICMD_INVOKEVIRTUAL:
2282 case ICMD_INVOKEINTERFACE:
2289 MCODECHECK((s3 << 1) + 64);
2291 for (; --s3 >= 0; src = src->prev) {
2292 if (src->varkind == ARGVAR)
2294 if (IS_INT_LNG_TYPE(src->type)) {
2295 if (s3 < INT_ARG_CNT) {
2296 s1 = argintregs[s3];
2297 var_to_reg_int(d, src, s1);
2301 var_to_reg_int(d, src, REG_ITMP1);
2302 M_LST(d, REG_SP, 8 * (s3 - INT_ARG_CNT));
2306 if (s3 < FLT_ARG_CNT) {
2307 s1 = argfltregs[s3];
2308 var_to_reg_flt(d, src, s1);
2312 var_to_reg_flt(d, src, REG_FTMP1);
2313 M_DST(d, REG_SP, 8 * (s3 - FLT_ARG_CNT));
2318 switch (iptr->opc) {
2322 a = dseg_addaddress ((void*) (m));
2324 M_LLD(REG_PV, REG_PV, a); /* Pointer to built-in-function */
2326 goto makeactualcall;
2328 case ICMD_INVOKESTATIC:
2329 case ICMD_INVOKESPECIAL:
2330 a = dseg_addaddress (m->stubroutine);
2332 M_LLD(REG_PV, REG_PV, a ); /* Method-Pointer in r27 */
2335 goto makeactualcall;
2337 case ICMD_INVOKEVIRTUAL:
2339 gen_nullptr_check(argintregs[0]);
2340 M_LLD(REG_METHODPTR, argintregs[0],
2341 OFFSET(java_objectheader, vftbl));
2342 M_LLD(REG_PV, REG_METHODPTR, OFFSET(vftbl, table[0]) +
2343 sizeof(methodptr) * m->vftblindex);
2346 goto makeactualcall;
2348 case ICMD_INVOKEINTERFACE:
2351 gen_nullptr_check(argintregs[0]);
2352 M_LLD(REG_METHODPTR, argintregs[0],
2353 OFFSET(java_objectheader, vftbl));
2354 M_LLD(REG_METHODPTR, REG_METHODPTR,
2355 OFFSET(vftbl, interfacevftbl));
2356 M_LLD(REG_METHODPTR, REG_METHODPTR,
2357 sizeof(methodptr*) * ci->index);
2358 M_LLD(REG_PV, REG_METHODPTR,
2359 sizeof(methodptr) * (m - ci->methods));
2362 goto makeactualcall;
2366 sprintf (logtext, "Unkown ICMD-Command: %d", iptr->opc);
2372 M_JSR (REG_RA, REG_PV);
2373 s1 = (int)((u1*) mcodeptr - mcodebase);
2374 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
2377 while (ml<-32768) { ml+=65536; mh--; }
2378 M_LDA (REG_PV, REG_RA, ml );
2379 M_LDAH (REG_PV, REG_PV, mh );
2382 if (d != TYPE_VOID) {
2383 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
2384 s1 = reg_of_var(iptr->dst, REG_RESULT);
2385 M_INTMOVE(REG_RESULT, s1);
2386 store_reg_to_var_int(iptr->dst, s1);
2389 s1 = reg_of_var(iptr->dst, REG_FRESULT);
2390 M_FLTMOVE(REG_FRESULT, s1);
2391 store_reg_to_var_flt(iptr->dst, s1);
2397 case ICMD_CHECKASIZE:
2398 var_to_reg_int(s1, src, REG_ITMP1);
2400 mcode_addxcheckarefs(mcodeptr);
2403 case ICMD_MULTIANEWARRAY:
2405 /* check for negative sizes and copy sizes to stack if necessary */
2407 MCODECHECK((iptr->op1 << 1) + 64);
2409 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
2410 var_to_reg_int(s2, src, REG_ITMP1);
2412 mcode_addxcheckarefs(mcodeptr);
2414 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
2416 if (src->varkind != ARGVAR) {
2417 M_LST(s2, REG_SP, 8 * (s1 + INT_ARG_CNT));
2421 /* a0 = dimension count */
2423 M_LDA(argintregs[0], REG_ZERO, iptr->op1);
2425 /* a1 = arraydescriptor */
2427 a = dseg_addaddress(iptr->val.a);
2428 M_LLD(argintregs[1], REG_PV, a);
2430 /* a2 = pointer to dimensions = stack pointer */
2432 M_INTMOVE(REG_SP, argintregs[2]);
2434 a = dseg_addaddress((void*) (builtin_nmultianewarray));
2435 M_LLD(REG_PV, REG_PV, a);
2436 M_JSR(REG_RA, REG_PV);
2437 s1 = (int)((u1*) mcodeptr - mcodebase);
2439 M_LDA (REG_PV, REG_RA, -s1);
2441 s4 ml = -s1, mh = 0;
2442 while (ml < -32768) {ml += 65536; mh--;}
2443 M_LDA(REG_PV, REG_RA, ml);
2444 M_LDAH(REG_PV, REG_PV, mh);
2446 s1 = reg_of_var(iptr->dst, REG_RESULT);
2447 M_INTMOVE(REG_RESULT, s1);
2448 store_reg_to_var_int(iptr->dst, s1);
2452 default: sprintf (logtext, "Unknown pseudo command: %d", iptr->opc);
2455 } /* for instruction */
2456 src = bptr->outstack;
2457 len = bptr->outdepth;
2461 if ((src->varkind != STACKVAR)) {
2463 if (IS_FLT_DBL_TYPE(s2)) {
2464 var_to_reg_int(s1, src, REG_ITMP1);
2465 if (!(interfaces[len][s2].flags & INMEMORY)) {
2466 M_FLTMOVE(s1,interfaces[len][s2].regoff);
2469 M_DST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
2473 var_to_reg_flt(s1, src, REG_FTMP1);
2474 if (!(interfaces[len][s2].flags & INMEMORY)) {
2475 M_INTMOVE(s1,interfaces[len][s2].regoff);
2478 M_LST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
2484 } /* for basic block */
2487 s4 *xcodeptr = NULL;
2489 for (; xboundrefs != NULL; xboundrefs = xboundrefs->next) {
2490 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
2491 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
2492 xboundrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
2496 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
2497 xboundrefs->branchpos, (u1*) mcodeptr - mcodebase);
2501 M_LDA(REG_ITMP2_XPC, REG_PV, xboundrefs->branchpos);
2503 if (xcodeptr != NULL) {
2504 M_BR((xcodeptr-mcodeptr)-1);
2507 xcodeptr = mcodeptr;
2509 a = dseg_addaddress(proto_java_lang_ArrayIndexOutOfBoundsException);
2510 M_LLD(REG_ITMP1_XPTR, REG_PV, a);
2512 a = dseg_addaddress(asm_handle_exception);
2513 M_LLD(REG_ITMP3, REG_PV, a);
2515 M_JMP(REG_ZERO, REG_ITMP3);
2521 for (; xcheckarefs != NULL; xcheckarefs = xcheckarefs->next) {
2522 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
2523 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
2524 xcheckarefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
2528 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
2529 xcheckarefs->branchpos, (u1*) mcodeptr - mcodebase);
2533 M_LDA(REG_ITMP2_XPC, REG_PV, xcheckarefs->branchpos);
2535 if (xcodeptr != NULL) {
2536 M_BR((xcodeptr-mcodeptr)-1);
2539 xcodeptr = mcodeptr;
2541 a = dseg_addaddress(proto_java_lang_NegativeArraySizeException);
2542 M_LLD(REG_ITMP1_XPTR, REG_PV, a);
2544 a = dseg_addaddress(asm_handle_exception);
2545 M_LLD(REG_ITMP3, REG_PV, a);
2547 M_JMP(REG_ZERO, REG_ITMP3);
2552 #ifdef SOFTNULLPTRCHECK
2556 for (; xnullrefs != NULL; xnullrefs = xnullrefs->next) {
2557 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
2558 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
2559 xnullrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
2563 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
2564 xnullrefs->branchpos, (u1*) mcodeptr - mcodebase);
2568 M_LDA(REG_ITMP2_XPC, REG_PV, xnullrefs->branchpos - 4);
2570 if (xcodeptr != NULL) {
2571 M_BR((xcodeptr-mcodeptr)-1);
2574 xcodeptr = mcodeptr;
2576 a = dseg_addaddress(proto_java_lang_NullPointerException);
2577 M_LLD(REG_ITMP1_XPTR, REG_PV, a);
2579 a = dseg_addaddress(asm_handle_exception);
2580 M_LLD(REG_ITMP3, REG_PV, a);
2582 M_JMP(REG_ZERO, REG_ITMP3);
2589 mcode_finish((int)((u1*) mcodeptr - mcodebase));
2593 /******** redefinition of code generation macros (compiling into array) *******/
2596 These macros are newly defined to allow code generation into an array.
2597 This is necessary, because the original M_.. macros generate code by
2598 calling 'mcode_adds4' that uses an additional data structure to
2601 For a faster (but less flexible) version to generate code, these
2602 macros directly use the (s4* p) - pointer to put the code directly
2603 in a locally defined array.
2604 This makes sense only for the stub-generation-routines below.
2608 #define M_OP3(op,fu,a,b,c,const) \
2609 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<(16-3*(const)))| \
2610 ((const)<<12)|((fu)<<5)|((c)) )
2612 #define M_FOP3(op,fu,a,b,c) \
2613 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<16)|((fu)<<5)|(c) )
2615 #define M_BRA(op,a,disp) \
2616 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((disp)&0x1fffff) )
2618 #define M_MEM(op,a,b,disp) \
2619 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<16)|((disp)&0xffff) )
2624 /************************ function createcompilerstub **************************
2626 creates a stub routine which calls the compiler
2628 *******************************************************************************/
2630 #define COMPSTUBSIZE 3
2632 u1 *createcompilerstub (methodinfo *m)
2634 u8 *s = CNEW (u8, COMPSTUBSIZE); /* memory to hold the stub */
2635 s4 *p = (s4*) s; /* code generation pointer */
2637 /* code for the stub */
2638 M_LLD (REG_PV, REG_PV, 16); /* load pointer to the compiler */
2639 M_JMP (0, REG_PV); /* jump to the compiler, return address
2640 in reg 0 is used as method pointer */
2641 s[1] = (u8) m; /* literals to be adressed */
2642 s[2] = (u8) asm_call_jit_compiler; /* jump directly via PV from above */
2645 count_cstub_len += COMPSTUBSIZE * 8;
2652 /************************* function removecompilerstub *************************
2654 deletes a compilerstub from memory (simply by freeing it)
2656 *******************************************************************************/
2658 void removecompilerstub (u1 *stub)
2660 CFREE (stub, COMPSTUBSIZE * 8);
2664 /************************ function: removenativestub ***************************
2666 removes a previously created native-stub from memory
2668 *******************************************************************************/
2670 void removenativestub (u1 *stub)
2672 CFREE (stub, NATIVESTUBSIZE * 8);
2678 /********************* Funktion: ncreatenativestub *****************************
2680 creates a stub routine which calls a native method
2682 *******************************************************************************/
2684 #define NATIVESTUBSIZE 11
2686 u1 *ncreatenativestub (functionptr f, methodinfo *m)
2688 u8 *s = CNEW (u8, NATIVESTUBSIZE); /* memory to hold the stub */
2689 s4 *p = (s4*) s; /* code generation pointer */
2691 M_LDA (REG_SP, REG_SP, -8); /* build up stackframe */
2692 M_LST (REG_RA, REG_SP, 0); /* store return address */
2694 M_LLD (REG_PV, REG_PV, 8*8); /* load adress of native method */
2695 M_JSR (REG_RA, REG_PV); /* call native method */
2697 M_LDA (REG_PV, REG_RA, -4*4); /* recompute pv from ra */
2698 M_LLD (REG_ITMP3, REG_PV, 9*8); /* get address of exceptionptr */
2700 M_LLD (REG_RA, REG_SP, 0); /* load return address */
2701 M_LLD (REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
2703 M_LDA (REG_SP, REG_SP, 8); /* remove stackframe */
2704 M_BNEZ (REG_ITMP1, 1); /* if no exception then return */
2706 M_RET (REG_ZERO, REG_RA); /* return to caller */
2708 M_LST (REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
2709 M_LDA (REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
2711 M_LLD (REG_ITMP3, REG_PV,10*8); /* load asm exception handler address */
2712 M_JMP (REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
2715 s[8] = (u8) f; /* address of native method */
2716 s[9] = (u8) (&exceptionptr); /* address of exceptionptr */
2717 s[10]= (u8) (asm_handle_nat_exception); /* addr of asm exception handler */
2720 count_nstub_len += NATIVESTUBSIZE * 8;