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, NULL);
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);
248 /*************************** function gen_mcode ********************************
250 generates machine code
252 *******************************************************************************/
254 #define MethodPointer -8
255 #define FrameSize -12
260 #define ExTableSize -32
261 #define ExTableStart -32
263 #define ExEntrySize -32
266 #define ExHandlerPC -24
267 #define ExCatchType -32
269 static void gen_mcode()
271 int len, s1, s2, s3, d, bbs;
282 savedregs_num = (isleafmethod) ? 0 : 1; /* space to save the RA */
284 /* space to save used callee saved registers */
286 savedregs_num += (savintregcnt - maxsavintreguse);
287 savedregs_num += (savfltregcnt - maxsavfltreguse);
289 parentargs_base = maxmemuse + savedregs_num;
292 if (checksync && (method->flags & ACC_SYNCHRONIZED))
296 /* create method header */
298 (void) dseg_addaddress(method); /* MethodPointer */
299 (void) dseg_adds4(parentargs_base * 8); /* FrameSize */
302 if (checksync && (method->flags & ACC_SYNCHRONIZED))
303 (void) dseg_adds4((maxmemuse + 1) * 8); /* IsSync */
306 (void) dseg_adds4(0); /* IsSync */
308 (void) dseg_adds4(isleafmethod); /* IsLeaf */
309 (void) dseg_adds4(savintregcnt - maxsavintreguse); /* IntSave */
310 (void) dseg_adds4(savfltregcnt - maxsavfltreguse); /* FltSave */
311 (void) dseg_adds4(exceptiontablelength); /* ExTableSize */
313 for (len = 0; len < exceptiontablelength; len++) {
314 dseg_addtarget(BlockPtrOfPC(extable[len].startpc));
315 dseg_addtarget(BlockPtrOfPC(extable[len].endpc));
316 dseg_addtarget(BlockPtrOfPC(extable[len].handlerpc));
317 (void) dseg_addaddress(extable[len].catchtype);
320 /* initialise mcode variables */
322 mcodeptr = (s4*) mcodebase;
323 mcodeend = (s4*) (mcodebase + mcodesize);
326 /* create stack frame (if necessary) */
329 {M_LDA (REG_SP, REG_SP, -parentargs_base * 8);}
331 /* save return address and used callee saved registers */
335 {p--; M_LST (REG_RA, REG_SP, 8*p);}
336 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
337 {p--; M_LST (savintregs[r], REG_SP, 8 * p);}
338 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
339 {p--; M_DST (savfltregs[r], REG_SP, 8 * p);}
341 /* save monitorenter argument */
344 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
345 if (method->flags & ACC_STATIC) {
346 p = dseg_addaddress (class);
347 M_LLD(REG_ITMP1, REG_PV, p);
348 M_LST(REG_ITMP1, REG_SP, 8 * maxmemuse);
351 M_LST (argintregs[0], REG_SP, 8 * maxmemuse);
356 if (runverbose && isleafmethod) {
357 M_LDA (REG_SP, REG_SP, -(8*8));
358 M_LST(REG_RA, REG_SP, 1*8);
359 M_LST(argintregs[0], REG_SP, 2*8);
360 M_LST(argintregs[1], REG_SP, 3*8);
361 M_LST(argintregs[2], REG_SP, 4*8);
362 M_LST(argintregs[3], REG_SP, 5*8);
363 M_LST(argintregs[4], REG_SP, 6*8);
364 M_LST(argintregs[5], REG_SP, 7*8);
365 p = dseg_addaddress (method);
366 M_LLD(REG_ITMP1, REG_PV, p);
367 M_LST(REG_ITMP1, REG_SP, 0);
368 p = dseg_addaddress ((void*) (builtin_trace_args));
369 M_LLD(REG_PV, REG_PV, p);
370 M_JSR(REG_RA, REG_PV);
371 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
372 M_LLD(REG_RA, REG_SP, 1*8);
373 M_LLD(argintregs[0], REG_SP, 2*8);
374 M_LLD(argintregs[1], REG_SP, 3*8);
375 M_LLD(argintregs[2], REG_SP, 4*8);
376 M_LLD(argintregs[3], REG_SP, 5*8);
377 M_LLD(argintregs[4], REG_SP, 6*8);
378 M_LLD(argintregs[5], REG_SP, 7*8);
379 M_LDA (REG_SP, REG_SP, 8*8);
382 /* take arguments out of register or stack frame */
384 for (p = 0, l = 0; p < mparamcount; p++) {
386 var = &(locals[l][t]);
388 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
393 if (IS_INT_LNG_TYPE(t)) { /* integer args */
394 if (p < INT_ARG_CNT) { /* register arguments */
395 if (!(var->flags & INMEMORY)) /* reg arg -> register */
396 {M_INTMOVE (argintregs[p], r);}
397 else /* reg arg -> spilled */
398 M_LST (argintregs[p], REG_SP, 8 * r);
400 else { /* stack arguments */
401 pa = p - INT_ARG_CNT;
402 if (!(var->flags & INMEMORY)) /* stack arg -> register */
403 M_LLD (r, REG_SP, 8 * (parentargs_base + pa));
404 else { /* stack arg -> spilled */
405 M_LLD (REG_ITMP1, REG_SP, 8 * (parentargs_base + pa));
406 M_LST (REG_ITMP1, REG_SP, 8 * r);
410 else { /* floating args */
411 if (p < FLT_ARG_CNT) { /* register arguments */
412 if (!(var->flags & INMEMORY)) /* reg arg -> register */
413 {M_FLTMOVE (argfltregs[p], r);}
414 else /* reg arg -> spilled */
415 M_DST (argfltregs[p], REG_SP, 8 * r);
417 else { /* stack arguments */
418 pa = p - FLT_ARG_CNT;
419 if (!(var->flags & INMEMORY)) /* stack-arg -> register */
420 M_DLD (r, REG_SP, 8 * (parentargs_base + pa) );
421 else { /* stack-arg -> spilled */
422 M_DLD (REG_FTMP1, REG_SP, 8 * (parentargs_base + pa));
423 M_DST (REG_FTMP1, REG_SP, 8 * r);
429 if (runverbose && !isleafmethod) {
430 M_LDA (REG_SP, REG_SP, -8);
431 p = dseg_addaddress (method);
432 M_LLD(REG_ITMP1, REG_PV, p);
433 M_LST(REG_ITMP1, REG_SP, 0);
434 p = dseg_addaddress ((void*) (builtin_trace_args));
435 M_LLD(REG_PV, REG_PV, p);
436 M_JSR(REG_RA, REG_PV);
437 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
438 M_LDA(REG_SP, REG_SP, 8);
442 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
443 p = dseg_addaddress ((void*) (builtin_monitorenter));
444 M_LLD(REG_PV, REG_PV, p);
445 M_LLD(argintregs[0], REG_SP, 8 * maxmemuse);
446 M_JSR(REG_RA, REG_PV);
447 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
452 /* end of header generation */
454 for (bbs = block_count, bptr = block; --bbs >= 0; bptr++) {
455 bptr -> mpc = (int)((u1*) mcodeptr - mcodebase);
457 /* branch resolving */
461 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
462 gen_resolvebranch((u1*) mcodebase + brefs->branchpos,
463 brefs->branchpos, bptr->mpc);
469 while (src != NULL) {
471 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
472 d = reg_of_var(src, REG_ITMP1);
473 M_INTMOVE(REG_ITMP1, d);
474 store_reg_to_var_int(src, d);
477 d = reg_of_var(src, REG_IFTMP);
478 if ((src->varkind != STACKVAR)) {
480 if (IS_FLT_DBL_TYPE(s2)) {
481 if (!(interfaces[len][s2].flags & INMEMORY)) {
482 s1 = interfaces[len][s2].regoff;
486 M_DLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
488 store_reg_to_var_flt(src, d);
491 if (!(interfaces[len][s2].flags & INMEMORY)) {
492 s1 = interfaces[len][s2].regoff;
496 M_LLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
498 store_reg_to_var_int(src, d);
506 len = bptr[1].ipc - s1;
507 for (iptr = &instr[s1];
509 src = iptr->dst, len--, iptr++) {
517 case ICMD_NULLCHECKPOP:
518 var_to_reg_int(s1, src, REG_ITMP1);
519 gen_nullptr_check(s1);
522 /*********************** constant operations **************************/
525 d = reg_of_var(iptr->dst, REG_ITMP1);
526 if ( (iptr->val.i >= -32768) && (iptr->val.i <= 32767) ) {
527 M_LDA(d, REG_ZERO, iptr->val.i);
530 a = dseg_adds4 (iptr->val.i);
533 store_reg_to_var_int(iptr->dst, d);
537 d = reg_of_var(iptr->dst, REG_ITMP1);
538 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767) ) {
539 M_LDA(d, REG_ZERO, iptr->val.l);
542 a = dseg_adds8 (iptr->val.l);
545 store_reg_to_var_int(iptr->dst, d);
549 d = reg_of_var (iptr->dst, REG_FTMP1);
550 a = dseg_addfloat (iptr->val.f);
552 store_reg_to_var_flt (iptr->dst, d);
556 d = reg_of_var (iptr->dst, REG_FTMP1);
557 a = dseg_adddouble (iptr->val.d);
559 store_reg_to_var_flt (iptr->dst, d);
564 d = reg_of_var(iptr->dst, REG_ITMP1);
566 a = dseg_addaddress (iptr->val.a);
570 M_INTMOVE(REG_ZERO, d);
572 store_reg_to_var_int(iptr->dst, d);
575 /********************** load/store operations *************************/
580 d = reg_of_var(iptr->dst, REG_ITMP1);
581 if ((iptr->dst->varkind == LOCALVAR) &&
582 (iptr->dst->varnum == iptr->op1))
584 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
585 if (var->flags & INMEMORY)
586 M_LLD(d, REG_SP, 8 * var->regoff);
588 {M_INTMOVE(var->regoff,d);}
589 store_reg_to_var_int(iptr->dst, d);
594 d = reg_of_var(iptr->dst, REG_FTMP1);
595 if ((iptr->dst->varkind == LOCALVAR) &&
596 (iptr->dst->varnum == iptr->op1))
598 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
599 if (var->flags & INMEMORY)
600 M_DLD(d, REG_SP, 8 * var->regoff);
602 {M_FLTMOVE(var->regoff,d);}
603 store_reg_to_var_flt(iptr->dst, d);
610 if ((src->varkind == LOCALVAR) &&
611 (src->varnum == iptr->op1))
613 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
614 if (var->flags & INMEMORY) {
615 var_to_reg_int(s1, src, REG_ITMP1);
616 M_LST(s1, REG_SP, 8 * var->regoff);
619 var_to_reg_int(s1, src, var->regoff);
620 M_INTMOVE(s1, var->regoff);
626 if ((src->varkind == LOCALVAR) &&
627 (src->varnum == iptr->op1))
629 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
630 if (var->flags & INMEMORY) {
631 var_to_reg_flt(s1, src, REG_FTMP1);
632 M_DST(s1, REG_SP, 8 * var->regoff);
635 var_to_reg_flt(s1, src, var->regoff);
636 M_FLTMOVE(s1, var->regoff);
641 /******************* pop/dup/swap operations **************************/
647 #define M_COPY(from,to) \
648 d = reg_of_var(to, REG_IFTMP); \
649 if ((from->regoff != to->regoff) || \
650 ((from->flags ^ to->flags) & INMEMORY)) { \
651 if (IS_FLT_DBL_TYPE(from->type)) { \
652 var_to_reg_flt(s1, from, d); \
654 store_reg_to_var_flt(to, d); \
657 var_to_reg_int(s1, from, d); \
659 store_reg_to_var_int(to, d); \
664 M_COPY(src, iptr->dst);
668 M_COPY(src, iptr->dst->prev->prev);
670 M_COPY(src, iptr->dst);
671 M_COPY(src->prev, iptr->dst->prev);
675 M_COPY(src->prev, iptr->dst->prev->prev->prev);
677 M_COPY(src, iptr->dst);
678 M_COPY(src->prev, iptr->dst->prev);
679 M_COPY(src->prev->prev, iptr->dst->prev->prev);
680 M_COPY(src, iptr->dst->prev->prev->prev);
684 M_COPY(src, iptr->dst);
685 M_COPY(src->prev, iptr->dst->prev);
686 M_COPY(src->prev->prev, iptr->dst->prev->prev);
687 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
688 M_COPY(src, iptr->dst->prev->prev->prev->prev);
689 M_COPY(src->prev, iptr->dst->prev->prev->prev->prev->prev);
693 M_COPY(src, iptr->dst->prev);
694 M_COPY(src->prev, iptr->dst);
698 /********************* integer operations *****************************/
701 var_to_reg_int(s1, src, REG_ITMP1);
702 d = reg_of_var(iptr->dst, REG_ITMP3);
703 M_ISUB(REG_ZERO, s1, d, 0);
704 store_reg_to_var_int(iptr->dst, d);
708 var_to_reg_int(s1, src, REG_ITMP1);
709 d = reg_of_var(iptr->dst, REG_ITMP3);
710 M_LSUB(REG_ZERO, s1, d, 0);
711 store_reg_to_var_int(iptr->dst, d);
715 var_to_reg_int(s1, src, REG_ITMP1);
716 d = reg_of_var(iptr->dst, REG_ITMP3);
718 store_reg_to_var_int(iptr->dst, d);
722 var_to_reg_int(s1, src, REG_ITMP1);
723 d = reg_of_var(iptr->dst, REG_ITMP3);
724 M_IADD(s1, REG_ZERO, d , 0);
725 store_reg_to_var_int(iptr->dst, d);
729 var_to_reg_int(s1, src, REG_ITMP1);
730 d = reg_of_var(iptr->dst, REG_ITMP3);
731 if (has_ext_instr_set) {
738 store_reg_to_var_int(iptr->dst, d);
742 var_to_reg_int(s1, src, REG_ITMP1);
743 d = reg_of_var(iptr->dst, REG_ITMP3);
744 M_ZAPNOT(s1, 0x03, d, 1);
745 store_reg_to_var_int(iptr->dst, d);
749 var_to_reg_int(s1, src, REG_ITMP1);
750 d = reg_of_var(iptr->dst, REG_ITMP3);
751 if (has_ext_instr_set) {
755 M_SLL( s1, 48, d, 1);
758 store_reg_to_var_int(iptr->dst, d);
761 #define ICONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
762 else{a=dseg_adds4(c);M_ILD(r,REG_PV,a);}
764 #define LCONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
765 else{a=dseg_adds8(c);M_LLD(r,REG_PV,a);}
769 var_to_reg_int(s1, src->prev, REG_ITMP1);
770 var_to_reg_int(s2, src, REG_ITMP2);
771 d = reg_of_var(iptr->dst, REG_ITMP3);
772 M_IADD(s1, s2, d, 0);
773 store_reg_to_var_int(iptr->dst, d);
776 var_to_reg_int(s1, src, REG_ITMP1);
777 d = reg_of_var(iptr->dst, REG_ITMP3);
778 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
779 M_IADD(s1, iptr->val.i, d, 1);
782 ICONST(REG_ITMP2, iptr->val.i);
783 M_IADD(s1, REG_ITMP2, d, 0);
785 store_reg_to_var_int(iptr->dst, d);
788 var_to_reg_int(s1, src->prev, REG_ITMP1);
789 var_to_reg_int(s2, src, REG_ITMP2);
790 d = reg_of_var(iptr->dst, REG_ITMP3);
791 M_LADD(s1, s2, d, 0);
792 store_reg_to_var_int(iptr->dst, d);
795 var_to_reg_int(s1, src, REG_ITMP1);
796 d = reg_of_var(iptr->dst, REG_ITMP3);
797 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
798 M_LADD(s1, iptr->val.l, d, 1);
801 LCONST(REG_ITMP2, iptr->val.l);
802 M_LADD(s1, REG_ITMP2, d, 0);
804 store_reg_to_var_int(iptr->dst, d);
808 var_to_reg_int(s1, src->prev, REG_ITMP1);
809 var_to_reg_int(s2, src, REG_ITMP2);
810 d = reg_of_var(iptr->dst, REG_ITMP3);
811 M_ISUB(s1, s2, d, 0);
812 store_reg_to_var_int(iptr->dst, d);
815 var_to_reg_int(s1, src, REG_ITMP1);
816 d = reg_of_var(iptr->dst, REG_ITMP3);
817 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
818 M_ISUB(s1, iptr->val.i, d, 1);
821 ICONST(REG_ITMP2, iptr->val.i);
822 M_ISUB(s1, REG_ITMP2, d, 0);
824 store_reg_to_var_int(iptr->dst, d);
827 var_to_reg_int(s1, src->prev, REG_ITMP1);
828 var_to_reg_int(s2, src, REG_ITMP2);
829 d = reg_of_var(iptr->dst, REG_ITMP3);
830 M_LSUB(s1, s2, d, 0);
831 store_reg_to_var_int(iptr->dst, d);
834 var_to_reg_int(s1, src, REG_ITMP1);
835 d = reg_of_var(iptr->dst, REG_ITMP3);
836 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
837 M_LSUB(s1, iptr->val.l, d, 1);
840 LCONST(REG_ITMP2, iptr->val.l);
841 M_LSUB(s1, REG_ITMP2, d, 0);
843 store_reg_to_var_int(iptr->dst, d);
847 var_to_reg_int(s1, src->prev, REG_ITMP1);
848 var_to_reg_int(s2, src, REG_ITMP2);
849 d = reg_of_var(iptr->dst, REG_ITMP3);
850 M_IMUL(s1, s2, d, 0);
851 store_reg_to_var_int(iptr->dst, d);
854 var_to_reg_int(s1, src, REG_ITMP1);
855 d = reg_of_var(iptr->dst, REG_ITMP3);
856 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
857 M_IMUL(s1, iptr->val.i, d, 1);
860 ICONST(REG_ITMP2, iptr->val.i);
861 M_IMUL(s1, REG_ITMP2, d, 0);
863 store_reg_to_var_int(iptr->dst, d);
866 var_to_reg_int(s1, src->prev, REG_ITMP1);
867 var_to_reg_int(s2, src, REG_ITMP2);
868 d = reg_of_var(iptr->dst, REG_ITMP3);
869 M_LMUL (s1, s2, d, 0);
870 store_reg_to_var_int(iptr->dst, d);
873 var_to_reg_int(s1, src, REG_ITMP1);
874 d = reg_of_var(iptr->dst, REG_ITMP3);
875 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
876 M_LMUL(s1, iptr->val.l, d, 1);
879 LCONST(REG_ITMP2, iptr->val.l);
880 M_LMUL(s1, REG_ITMP2, d, 0);
882 store_reg_to_var_int(iptr->dst, d);
887 var_to_reg_int(s1, src->prev, REG_ITMP1);
888 var_to_reg_int(s2, src, REG_ITMP2);
889 d = reg_of_var(iptr->dst, REG_ITMP3);
890 M_AND(s2, 0x1f, REG_ITMP3, 1);
891 M_SLL(s1, REG_ITMP3, d, 0);
892 M_IADD(d, REG_ZERO, d, 0);
893 store_reg_to_var_int(iptr->dst, d);
896 var_to_reg_int(s1, src, REG_ITMP1);
897 d = reg_of_var(iptr->dst, REG_ITMP3);
898 M_SLL(s1, iptr->val.i & 0x1f, d, 1);
899 M_IADD(d, REG_ZERO, d, 0);
900 store_reg_to_var_int(iptr->dst, d);
904 var_to_reg_int(s1, src->prev, REG_ITMP1);
905 var_to_reg_int(s2, src, REG_ITMP2);
906 d = reg_of_var(iptr->dst, REG_ITMP3);
907 M_AND(s2, 0x1f, REG_ITMP3, 1);
908 M_SRA(s1, REG_ITMP3, d, 0);
909 store_reg_to_var_int(iptr->dst, d);
912 var_to_reg_int(s1, src, REG_ITMP1);
913 d = reg_of_var(iptr->dst, REG_ITMP3);
914 M_SRA(s1, iptr->val.i & 0x1f, d, 1);
915 store_reg_to_var_int(iptr->dst, d);
919 var_to_reg_int(s1, src->prev, REG_ITMP1);
920 var_to_reg_int(s2, src, REG_ITMP2);
921 d = reg_of_var(iptr->dst, REG_ITMP3);
922 M_AND (s2, 0x1f, REG_ITMP2, 1);
923 M_ZAPNOT(s1, 0x0f, d, 1);
924 M_SRL ( d, REG_ITMP2, d, 0);
925 M_IADD ( d, REG_ZERO, d, 0);
926 store_reg_to_var_int(iptr->dst, d);
928 case ICMD_IUSHRCONST:
929 var_to_reg_int(s1, src, REG_ITMP1);
930 d = reg_of_var(iptr->dst, REG_ITMP3);
931 M_ZAPNOT(s1, 0x0f, d, 1);
932 M_SRL(d, iptr->val.i & 0x1f, d, 1);
933 M_IADD(d, REG_ZERO, d, 0);
934 store_reg_to_var_int(iptr->dst, d);
938 var_to_reg_int(s1, src->prev, REG_ITMP1);
939 var_to_reg_int(s2, src, REG_ITMP2);
940 d = reg_of_var(iptr->dst, REG_ITMP3);
942 store_reg_to_var_int(iptr->dst, d);
945 var_to_reg_int(s1, src, REG_ITMP1);
946 d = reg_of_var(iptr->dst, REG_ITMP3);
947 M_SLL(s1, iptr->val.l & 0x3f, d, 1);
948 store_reg_to_var_int(iptr->dst, d);
952 var_to_reg_int(s1, src->prev, REG_ITMP1);
953 var_to_reg_int(s2, src, REG_ITMP2);
954 d = reg_of_var(iptr->dst, REG_ITMP3);
956 store_reg_to_var_int(iptr->dst, d);
959 var_to_reg_int(s1, src, REG_ITMP1);
960 d = reg_of_var(iptr->dst, REG_ITMP3);
961 M_SRA(s1, iptr->val.l & 0x3f, d, 1);
962 store_reg_to_var_int(iptr->dst, d);
966 var_to_reg_int(s1, src->prev, REG_ITMP1);
967 var_to_reg_int(s2, src, REG_ITMP2);
968 d = reg_of_var(iptr->dst, REG_ITMP3);
970 store_reg_to_var_int(iptr->dst, d);
972 case ICMD_LUSHRCONST:
973 var_to_reg_int(s1, src, REG_ITMP1);
974 d = reg_of_var(iptr->dst, REG_ITMP3);
975 M_SRL(s1, iptr->val.l & 0x3f, d, 1);
976 store_reg_to_var_int(iptr->dst, d);
981 var_to_reg_int(s1, src->prev, REG_ITMP1);
982 var_to_reg_int(s2, src, REG_ITMP2);
983 d = reg_of_var(iptr->dst, REG_ITMP3);
985 store_reg_to_var_int(iptr->dst, d);
988 var_to_reg_int(s1, src, REG_ITMP1);
989 d = reg_of_var(iptr->dst, REG_ITMP3);
990 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
991 M_AND(s1, iptr->val.i, d, 1);
993 else if (iptr->val.i == 0xffff) {
994 M_ZAPNOT(s1, 0x03, d, 1);
996 else if (iptr->val.i == 0xffffff) {
997 M_ZAPNOT(s1, 0x07, d, 1);
1000 ICONST(REG_ITMP2, iptr->val.i);
1001 M_AND(s1, REG_ITMP2, d, 0);
1003 store_reg_to_var_int(iptr->dst, d);
1006 var_to_reg_int(s1, src, REG_ITMP1);
1007 d = reg_of_var(iptr->dst, REG_ITMP3);
1008 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1009 M_AND(s1, iptr->val.i, d, 1);
1011 M_ISUB(REG_ZERO, s1, d, 0);
1012 M_AND(d, iptr->val.i, d, 1);
1014 else if (iptr->val.i == 0xffff) {
1015 M_ZAPNOT(s1, 0x03, d, 1);
1017 M_ISUB(REG_ZERO, s1, d, 0);
1018 M_ZAPNOT(d, 0x03, d, 1);
1020 else if (iptr->val.i == 0xffffff) {
1021 M_ZAPNOT(s1, 0x07, d, 1);
1023 M_ISUB(REG_ZERO, s1, d, 0);
1024 M_ZAPNOT(d, 0x07, d, 1);
1027 ICONST(REG_ITMP2, iptr->val.i);
1028 M_AND(s1, REG_ITMP2, d, 0);
1030 M_ISUB(REG_ZERO, s1, d, 0);
1031 M_AND(d, REG_ITMP2, d, 0);
1033 M_ISUB(REG_ZERO, d, d, 0);
1034 store_reg_to_var_int(iptr->dst, d);
1036 case ICMD_IREM0X10001:
1037 var_to_reg_int(s1, src, REG_ITMP1);
1038 d = reg_of_var(iptr->dst, REG_ITMP3);
1039 M_ZAPNOT(s1, 0x03, REG_ITMP2, 1);
1040 M_SRA(s1, 16, d, 1);
1041 M_CMPLT(REG_ITMP2, d, REG_ITMP1, 0);
1042 M_ISUB(REG_ITMP2, d, d, 0);
1043 M_IADD(d, REG_ITMP1, d, 0);
1045 M_ISUB(REG_ZERO, s1, REG_ITMP1, 0);
1046 M_ZAPNOT(REG_ITMP1, 0x03, REG_ITMP2, 1);
1047 M_SRA(REG_ITMP1, 16, d, 1);
1048 M_CMPLT(REG_ITMP2, d, REG_ITMP1, 0);
1049 M_ISUB(REG_ITMP2, d, d, 0);
1050 M_IADD(d, REG_ITMP1, d, 0);
1051 M_ISUB(REG_ZERO, d, d, 0);
1052 M_SLL(s1, 33, REG_ITMP2, 1);
1053 M_CMPEQ(REG_ITMP2, REG_ZERO, REG_ITMP2, 0);
1054 M_ISUB(d, REG_ITMP2, d, 0);
1055 store_reg_to_var_int(iptr->dst, d);
1057 case ICMD_LANDCONST:
1058 var_to_reg_int(s1, src, REG_ITMP1);
1059 d = reg_of_var(iptr->dst, REG_ITMP3);
1060 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1061 M_AND(s1, iptr->val.l, d, 1);
1063 else if (iptr->val.l == 0xffffL) {
1064 M_ZAPNOT(s1, 0x03, d, 1);
1066 else if (iptr->val.l == 0xffffffL) {
1067 M_ZAPNOT(s1, 0x07, d, 1);
1069 else if (iptr->val.l == 0xffffffffL) {
1070 M_ZAPNOT(s1, 0x0f, d, 1);
1072 else if (iptr->val.l == 0xffffffffffL) {
1073 M_ZAPNOT(s1, 0x1f, d, 1);
1075 else if (iptr->val.l == 0xffffffffffffL) {
1076 M_ZAPNOT(s1, 0x3f, d, 1);
1078 else if (iptr->val.l == 0xffffffffffffffL) {
1079 M_ZAPNOT(s1, 0x7f, d, 1);
1082 LCONST(REG_ITMP2, iptr->val.l);
1083 M_AND(s1, REG_ITMP2, d, 0);
1085 store_reg_to_var_int(iptr->dst, d);
1088 var_to_reg_int(s1, src, REG_ITMP1);
1089 d = reg_of_var(iptr->dst, REG_ITMP3);
1090 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1091 M_AND(s1, iptr->val.l, d, 1);
1093 M_LSUB(REG_ZERO, s1, d, 0);
1094 M_AND(d, iptr->val.l, d, 1);
1096 else if (iptr->val.l == 0xffffL) {
1097 M_ZAPNOT(s1, 0x03, d, 1);
1099 M_LSUB(REG_ZERO, s1, d, 0);
1100 M_ZAPNOT(d, 0x03, d, 1);
1102 else if (iptr->val.l == 0xffffffL) {
1103 M_ZAPNOT(s1, 0x07, d, 1);
1105 M_LSUB(REG_ZERO, s1, d, 0);
1106 M_ZAPNOT(d, 0x07, d, 1);
1108 else if (iptr->val.l == 0xffffffffL) {
1109 M_ZAPNOT(s1, 0x0f, d, 1);
1111 M_LSUB(REG_ZERO, s1, d, 0);
1112 M_ZAPNOT(d, 0x0f, d, 1);
1114 else if (iptr->val.l == 0xffffffffffL) {
1115 M_ZAPNOT(s1, 0x1f, d, 1);
1117 M_LSUB(REG_ZERO, s1, d, 0);
1118 M_ZAPNOT(d, 0x1f, d, 1);
1120 else if (iptr->val.l == 0xffffffffffffL) {
1121 M_ZAPNOT(s1, 0x3f, d, 1);
1123 M_LSUB(REG_ZERO, s1, d, 0);
1124 M_ZAPNOT(d, 0x3f, d, 1);
1126 else if (iptr->val.l == 0xffffffffffffffL) {
1127 M_ZAPNOT(s1, 0x7f, d, 1);
1129 M_LSUB(REG_ZERO, s1, d, 0);
1130 M_ZAPNOT(d, 0x7f, d, 1);
1133 LCONST(REG_ITMP2, iptr->val.l);
1134 M_AND(s1, REG_ITMP2, d, 0);
1136 M_LSUB(REG_ZERO, s1, d, 0);
1137 M_AND(d, REG_ITMP2, d, 0);
1139 M_LSUB(REG_ZERO, d, d, 0);
1140 store_reg_to_var_int(iptr->dst, d);
1142 case ICMD_LREM0X10001:
1143 var_to_reg_int(s1, src, REG_ITMP1);
1144 d = reg_of_var(iptr->dst, REG_ITMP3);
1145 M_ZAPNOT(s1, 0x03, REG_ITMP2, 1);
1146 M_SRA(s1, 16, d, 1);
1147 M_CMPLT(REG_ITMP2, d, REG_ITMP1, 0);
1148 M_LSUB(REG_ITMP2, d, d, 0);
1149 M_LADD(d, REG_ITMP1, d, 0);
1150 M_LDA(REG_ITMP2, REG_ZERO, -1);
1151 M_SRL(REG_ITMP2, 33, REG_ITMP2, 1);
1152 M_CMPULT(s1, REG_ITMP2, REG_ITMP2, 0);
1153 M_BNEZ(REG_ITMP2, 11);
1154 M_LDA(d, REG_ZERO, -257);
1155 M_ZAPNOT(d, 0xcd, d, 1);
1156 M_LSUB(REG_ZERO, s1, REG_ITMP2, 0);
1157 M_CMOVGE(s1, s1, REG_ITMP2, 0);
1158 M_UMULH(REG_ITMP2, d, REG_ITMP2, 0);
1159 M_SRL(REG_ITMP2, 16, REG_ITMP2, 1);
1160 M_LSUB(REG_ZERO, REG_ITMP2, d, 0);
1161 M_CMOVGE(s1, REG_ITMP2, d, 0);
1162 M_SLL(d, 16, REG_ITMP2, 1);
1163 M_LADD(d, REG_ITMP2, d, 0);
1164 M_LSUB(s1, d, d, 0);
1165 store_reg_to_var_int(iptr->dst, d);
1170 var_to_reg_int(s1, src->prev, REG_ITMP1);
1171 var_to_reg_int(s2, src, REG_ITMP2);
1172 d = reg_of_var(iptr->dst, REG_ITMP3);
1174 store_reg_to_var_int(iptr->dst, d);
1177 var_to_reg_int(s1, src, REG_ITMP1);
1178 d = reg_of_var(iptr->dst, REG_ITMP3);
1179 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1180 M_OR(s1, iptr->val.i, d, 1);
1183 ICONST(REG_ITMP2, iptr->val.i);
1184 M_OR(s1, REG_ITMP2, d, 0);
1186 store_reg_to_var_int(iptr->dst, d);
1189 var_to_reg_int(s1, src, REG_ITMP1);
1190 d = reg_of_var(iptr->dst, REG_ITMP3);
1191 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1192 M_OR(s1, iptr->val.l, d, 1);
1195 LCONST(REG_ITMP2, iptr->val.l);
1196 M_OR(s1, REG_ITMP2, d, 0);
1198 store_reg_to_var_int(iptr->dst, d);
1203 var_to_reg_int(s1, src->prev, REG_ITMP1);
1204 var_to_reg_int(s2, src, REG_ITMP2);
1205 d = reg_of_var(iptr->dst, REG_ITMP3);
1206 M_XOR(s1, s2, d, 0);
1207 store_reg_to_var_int(iptr->dst, d);
1209 case ICMD_IXORCONST:
1210 var_to_reg_int(s1, src, REG_ITMP1);
1211 d = reg_of_var(iptr->dst, REG_ITMP3);
1212 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1213 M_XOR(s1, iptr->val.i, d, 1);
1216 ICONST(REG_ITMP2, iptr->val.i);
1217 M_XOR(s1, REG_ITMP2, d, 0);
1219 store_reg_to_var_int(iptr->dst, d);
1221 case ICMD_LXORCONST:
1222 var_to_reg_int(s1, src, REG_ITMP1);
1223 d = reg_of_var(iptr->dst, REG_ITMP3);
1224 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1225 M_XOR(s1, iptr->val.l, d, 1);
1228 LCONST(REG_ITMP2, iptr->val.l);
1229 M_XOR(s1, REG_ITMP2, d, 0);
1231 store_reg_to_var_int(iptr->dst, d);
1236 var_to_reg_int(s1, src->prev, REG_ITMP1);
1237 var_to_reg_int(s2, src, REG_ITMP2);
1238 d = reg_of_var(iptr->dst, REG_ITMP3);
1239 M_CMPLT(s1, s2, REG_ITMP3, 0);
1240 M_CMPLT(s2, s1, REG_ITMP1, 0);
1241 M_LSUB (REG_ITMP1, REG_ITMP3, d, 0);
1242 store_reg_to_var_int(iptr->dst, d);
1247 var = &(locals[iptr->op1][TYPE_INT]);
1248 if (var->flags & INMEMORY) {
1250 M_LLD(s1, REG_SP, 8 * var->regoff);
1254 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1255 M_IADD(s1, iptr->val.i, s1, 1);
1257 else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1258 M_ISUB(s1, (-iptr->val.i), s1, 1);
1261 M_LDA (s1, s1, iptr->val.i);
1262 M_IADD(s1, REG_ZERO, s1, 0);
1264 if (var->flags & INMEMORY)
1265 M_LST(s1, REG_SP, 8 * var->regoff);
1269 /*********************** floating operations **************************/
1272 var_to_reg_flt(s1, src, REG_FTMP1);
1273 d = reg_of_var(iptr->dst, REG_FTMP3);
1275 store_reg_to_var_flt(iptr->dst, d);
1278 var_to_reg_flt(s1, src, REG_FTMP1);
1279 d = reg_of_var(iptr->dst, REG_FTMP3);
1281 store_reg_to_var_flt(iptr->dst, d);
1285 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1286 var_to_reg_flt(s2, src, REG_FTMP2);
1287 d = reg_of_var(iptr->dst, REG_FTMP3);
1295 store_reg_to_var_flt(iptr->dst, d);
1298 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1299 var_to_reg_flt(s2, src, REG_FTMP2);
1300 d = reg_of_var(iptr->dst, REG_FTMP3);
1308 store_reg_to_var_flt(iptr->dst, d);
1312 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1313 var_to_reg_flt(s2, src, REG_FTMP2);
1314 d = reg_of_var(iptr->dst, REG_FTMP3);
1322 store_reg_to_var_flt(iptr->dst, d);
1325 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1326 var_to_reg_flt(s2, src, REG_FTMP2);
1327 d = reg_of_var(iptr->dst, REG_FTMP3);
1335 store_reg_to_var_flt(iptr->dst, d);
1339 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1340 var_to_reg_flt(s2, src, REG_FTMP2);
1341 d = reg_of_var(iptr->dst, REG_FTMP3);
1349 store_reg_to_var_flt(iptr->dst, d);
1352 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1353 var_to_reg_flt(s2, src, REG_FTMP2);
1354 d = reg_of_var(iptr->dst, REG_FTMP3);
1362 store_reg_to_var_flt(iptr->dst, d);
1366 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1367 var_to_reg_flt(s2, src, REG_FTMP2);
1368 d = reg_of_var(iptr->dst, REG_FTMP3);
1376 store_reg_to_var_flt(iptr->dst, d);
1379 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1380 var_to_reg_flt(s2, src, REG_FTMP2);
1381 d = reg_of_var(iptr->dst, REG_FTMP3);
1389 store_reg_to_var_flt(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_FTMP3);
1397 M_FDIVS(s1,s2, REG_FTMP3);
1399 M_CVTDL_CS(REG_ZERO, REG_FTMP3, REG_FTMP3); /* round to integer */
1401 M_CVTLF(REG_ZERO, REG_FTMP3, REG_FTMP3);
1402 M_FMULS(REG_FTMP3, s2, REG_FTMP3);
1404 M_FSUBS(s1, REG_FTMP3, d);
1408 M_FDIV(s1,s2, REG_FTMP3);
1409 M_CVTDL_C(REG_ZERO, REG_FTMP3, REG_FTMP3); /* round to integer */
1410 M_CVTLF(REG_ZERO, REG_FTMP3, REG_FTMP3);
1411 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1412 M_FSUB(s1, REG_FTMP3, d);
1414 store_reg_to_var_flt(iptr->dst, d);
1417 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1418 var_to_reg_flt(s2, src, REG_FTMP2);
1419 d = reg_of_var(iptr->dst, REG_FTMP3);
1421 M_DDIVS(s1,s2, REG_FTMP3);
1423 M_CVTDL_CS(REG_ZERO, REG_FTMP3, REG_FTMP3); /* round to integer */
1425 M_CVTLD(REG_ZERO, REG_FTMP3, REG_FTMP3);
1426 M_DMULS(REG_FTMP3, s2, REG_FTMP3);
1428 M_DSUBS(s1, REG_FTMP3, d);
1432 M_DDIV(s1,s2, REG_FTMP3);
1433 M_CVTDL_C(REG_ZERO, REG_FTMP3, REG_FTMP3); /* round to integer */
1434 M_CVTLD(REG_ZERO, REG_FTMP3, REG_FTMP3);
1435 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1436 M_DSUB(s1, REG_FTMP3, d);
1438 store_reg_to_var_flt(iptr->dst, d);
1443 var_to_reg_int(s1, src, REG_ITMP1);
1444 d = reg_of_var(iptr->dst, REG_FTMP3);
1445 a = dseg_adddouble(0.0);
1446 M_LST (s1, REG_PV, a);
1447 M_DLD (d, REG_PV, a);
1448 M_CVTLF(REG_ZERO, d, d);
1449 store_reg_to_var_flt(iptr->dst, d);
1454 var_to_reg_int(s1, src, REG_ITMP1);
1455 d = reg_of_var(iptr->dst, REG_FTMP3);
1456 a = dseg_adddouble(0.0);
1457 M_LST (s1, REG_PV, a);
1458 M_DLD (d, REG_PV, a);
1459 M_CVTLD(REG_ZERO, d, d);
1460 store_reg_to_var_flt(iptr->dst, d);
1465 var_to_reg_flt(s1, src, REG_FTMP1);
1466 d = reg_of_var(iptr->dst, REG_ITMP3);
1467 a = dseg_adddouble(0.0);
1469 M_CVTDL_CS(REG_ZERO, s1, REG_FTMP1);
1471 M_CVTLIS(REG_FTMP1, REG_FTMP2);
1475 M_CVTDL_C(REG_ZERO, s1, REG_FTMP1);
1476 M_CVTLI(REG_FTMP1, REG_FTMP2);
1478 M_DST (REG_FTMP1, REG_PV, a);
1479 M_ILD (d, REG_PV, a);
1480 store_reg_to_var_int(iptr->dst, d);
1485 var_to_reg_flt(s1, src, REG_FTMP1);
1486 d = reg_of_var(iptr->dst, REG_ITMP3);
1487 a = dseg_adddouble(0.0);
1489 M_CVTDL_CS(REG_ZERO, s1, REG_FTMP1);
1493 M_CVTDL_C(REG_ZERO, s1, REG_FTMP1);
1495 M_DST (REG_FTMP1, REG_PV, a);
1496 M_LLD (d, REG_PV, a);
1497 store_reg_to_var_int(iptr->dst, d);
1501 var_to_reg_flt(s1, src, REG_FTMP1);
1502 d = reg_of_var(iptr->dst, REG_FTMP3);
1504 store_reg_to_var_flt(iptr->dst, d);
1508 var_to_reg_flt(s1, src, REG_FTMP1);
1509 d = reg_of_var(iptr->dst, REG_FTMP3);
1511 M_CVTDFS(REG_ZERO, s1, d);
1515 M_CVTDF(REG_ZERO, s1, d);
1517 store_reg_to_var_flt(iptr->dst, d);
1522 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1523 var_to_reg_flt(s2, src, REG_FTMP2);
1524 d = reg_of_var(iptr->dst, REG_ITMP3);
1526 M_LSUB (REG_ZERO, 1, d, 1);
1527 M_FCMPEQS(s1, s2, REG_FTMP3);
1529 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1530 M_OR (REG_ZERO, REG_ZERO, d, 0);
1531 M_FCMPLTS(s2, s1, REG_FTMP3);
1533 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1534 M_LADD (REG_ZERO, 1, d, 1);
1537 M_LSUB (REG_ZERO, 1, d, 1);
1538 M_FCMPEQ(s1, s2, REG_FTMP3);
1539 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1540 M_OR (REG_ZERO, REG_ZERO, d, 0);
1541 M_FCMPLT(s2, s1, REG_FTMP3);
1542 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1543 M_LADD (REG_ZERO, 1, d, 1);
1545 store_reg_to_var_int(iptr->dst, d);
1550 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1551 var_to_reg_flt(s2, src, REG_FTMP2);
1552 d = reg_of_var(iptr->dst, REG_ITMP3);
1554 M_LADD (REG_ZERO, 1, d, 1);
1555 M_FCMPEQS(s1, s2, REG_FTMP3);
1557 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1558 M_OR (REG_ZERO, REG_ZERO, d, 0);
1559 M_FCMPLTS(s1, s2, REG_FTMP3);
1561 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1562 M_LSUB (REG_ZERO, 1, d, 1);
1565 M_LADD (REG_ZERO, 1, d, 1);
1566 M_FCMPEQ(s1, s2, REG_FTMP3);
1567 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1568 M_OR (REG_ZERO, REG_ZERO, d, 0);
1569 M_FCMPLT(s1, s2, REG_FTMP3);
1570 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1571 M_LSUB (REG_ZERO, 1, d, 1);
1573 store_reg_to_var_int(iptr->dst, d);
1577 /********************** memory operations *****************************/
1579 #define gen_bound_check \
1581 M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\
1582 M_CMPULT(s2, REG_ITMP3, REG_ITMP3, 0);\
1583 M_BEQZ(REG_ITMP3, 0);\
1584 mcode_addxboundrefs(mcodeptr);\
1587 case ICMD_ARRAYLENGTH:
1588 var_to_reg_int(s1, src, REG_ITMP1);
1589 d = reg_of_var(iptr->dst, REG_ITMP3);
1590 gen_nullptr_check(s1);
1591 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1592 store_reg_to_var_int(iptr->dst, d);
1596 var_to_reg_int(s1, src->prev, REG_ITMP1);
1597 var_to_reg_int(s2, src, REG_ITMP2);
1598 d = reg_of_var(iptr->dst, REG_ITMP3);
1599 gen_nullptr_check(s1);
1601 M_S8ADDQ(s2, s1, REG_ITMP1, 0);
1602 M_LLD( d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1603 store_reg_to_var_int(iptr->dst, d);
1606 var_to_reg_int(s1, src->prev, REG_ITMP1);
1607 var_to_reg_int(s2, src, REG_ITMP2);
1608 d = reg_of_var(iptr->dst, REG_ITMP3);
1609 gen_nullptr_check(s1);
1611 M_S8ADDQ(s2, s1, REG_ITMP1, 0);
1612 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1613 store_reg_to_var_int(iptr->dst, d);
1616 var_to_reg_int(s1, src->prev, REG_ITMP1);
1617 var_to_reg_int(s2, src, REG_ITMP2);
1618 d = reg_of_var(iptr->dst, REG_ITMP3);
1619 gen_nullptr_check(s1);
1621 M_S4ADDQ(s2, s1, REG_ITMP1, 0);
1622 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1623 store_reg_to_var_int(iptr->dst, d);
1626 var_to_reg_int(s1, src->prev, REG_ITMP1);
1627 var_to_reg_int(s2, src, REG_ITMP2);
1628 d = reg_of_var(iptr->dst, REG_FTMP3);
1629 gen_nullptr_check(s1);
1631 M_S4ADDQ(s2, s1, REG_ITMP1, 0);
1632 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1633 store_reg_to_var_flt(iptr->dst, d);
1636 var_to_reg_int(s1, src->prev, REG_ITMP1);
1637 var_to_reg_int(s2, src, REG_ITMP2);
1638 d = reg_of_var(iptr->dst, REG_FTMP3);
1639 gen_nullptr_check(s1);
1641 M_S8ADDQ(s2, s1, REG_ITMP1, 0);
1642 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1643 store_reg_to_var_flt(iptr->dst, d);
1646 var_to_reg_int(s1, src->prev, REG_ITMP1);
1647 var_to_reg_int(s2, src, REG_ITMP2);
1648 d = reg_of_var(iptr->dst, REG_ITMP3);
1649 gen_nullptr_check(s1);
1651 if (has_ext_instr_set) {
1652 M_LADD(s2, s1, REG_ITMP1, 0);
1653 M_LADD(s2, REG_ITMP1, REG_ITMP1, 0);
1654 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1657 M_LADD (s2, s1, REG_ITMP1, 0);
1658 M_LADD (s2, REG_ITMP1, REG_ITMP1, 0);
1659 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1660 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1661 M_EXTWL(REG_ITMP2, REG_ITMP1, d, 0);
1663 store_reg_to_var_int(iptr->dst, d);
1666 var_to_reg_int(s1, src->prev, REG_ITMP1);
1667 var_to_reg_int(s2, src, REG_ITMP2);
1668 d = reg_of_var(iptr->dst, REG_ITMP3);
1669 gen_nullptr_check(s1);
1671 if (has_ext_instr_set) {
1672 M_LADD(s2, s1, REG_ITMP1, 0);
1673 M_LADD(s2, REG_ITMP1, REG_ITMP1, 0);
1674 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1678 M_LADD(s2, s1, REG_ITMP1, 0);
1679 M_LADD(s2, REG_ITMP1, REG_ITMP1, 0);
1680 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1681 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1682 M_EXTQH(REG_ITMP2, REG_ITMP1, d, 0);
1685 store_reg_to_var_int(iptr->dst, d);
1688 var_to_reg_int(s1, src->prev, REG_ITMP1);
1689 var_to_reg_int(s2, src, REG_ITMP2);
1690 d = reg_of_var(iptr->dst, REG_ITMP3);
1691 gen_nullptr_check(s1);
1693 if (has_ext_instr_set) {
1694 M_LADD (s2, s1, REG_ITMP1, 0);
1695 M_BLDU (d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1699 M_LADD(s2, s1, REG_ITMP1, 0);
1700 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1701 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
1702 M_EXTQH(REG_ITMP2, REG_ITMP1, d, 0);
1705 store_reg_to_var_int(iptr->dst, d);
1709 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1710 var_to_reg_int(s2, src->prev, REG_ITMP2);
1711 gen_nullptr_check(s1);
1713 var_to_reg_int(s3, src, REG_ITMP3);
1714 M_S8ADDQ(s2, s1, REG_ITMP1, 0);
1715 M_LST (s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1718 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1719 var_to_reg_int(s2, src->prev, REG_ITMP2);
1720 gen_nullptr_check(s1);
1722 var_to_reg_int(s3, src, REG_ITMP3);
1723 M_S8ADDQ(s2, s1, REG_ITMP1, 0);
1724 M_LST (s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1727 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1728 var_to_reg_int(s2, src->prev, REG_ITMP2);
1729 gen_nullptr_check(s1);
1731 var_to_reg_int(s3, src, REG_ITMP3);
1732 M_S4ADDQ(s2, s1, REG_ITMP1, 0);
1733 M_IST (s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1736 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1737 var_to_reg_int(s2, src->prev, REG_ITMP2);
1738 gen_nullptr_check(s1);
1740 var_to_reg_flt(s3, src, REG_FTMP3);
1741 M_S4ADDQ(s2, s1, REG_ITMP1, 0);
1742 M_FST (s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1745 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1746 var_to_reg_int(s2, src->prev, REG_ITMP2);
1747 gen_nullptr_check(s1);
1749 var_to_reg_flt(s3, src, REG_FTMP3);
1750 M_S8ADDQ(s2, s1, REG_ITMP1, 0);
1751 M_DST (s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1754 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1755 var_to_reg_int(s2, src->prev, REG_ITMP2);
1756 gen_nullptr_check(s1);
1758 var_to_reg_int(s3, src, REG_ITMP3);
1759 if (has_ext_instr_set) {
1760 M_LADD(s2, s1, REG_ITMP1, 0);
1761 M_LADD(s2, REG_ITMP1, REG_ITMP1, 0);
1762 M_SST (s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1765 M_LADD (s2, s1, REG_ITMP1, 0);
1766 M_LADD (s2, REG_ITMP1, REG_ITMP1, 0);
1767 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1768 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1769 M_INSWL(s3, REG_ITMP1, REG_ITMP3, 0);
1770 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2, 0);
1771 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2, 0);
1772 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1776 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1777 var_to_reg_int(s2, src->prev, REG_ITMP2);
1778 gen_nullptr_check(s1);
1780 var_to_reg_int(s3, src, REG_ITMP3);
1781 if (has_ext_instr_set) {
1782 M_LADD(s2, s1, REG_ITMP1, 0);
1783 M_LADD(s2, REG_ITMP1, REG_ITMP1, 0);
1784 M_SST (s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1787 M_LADD (s2, s1, REG_ITMP1, 0);
1788 M_LADD (s2, REG_ITMP1, REG_ITMP1, 0);
1789 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1790 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1791 M_INSWL(s3, REG_ITMP1, REG_ITMP3, 0);
1792 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2, 0);
1793 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2, 0);
1794 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1798 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1799 var_to_reg_int(s2, src->prev, REG_ITMP2);
1800 gen_nullptr_check(s1);
1802 var_to_reg_int(s3, src, REG_ITMP3);
1803 if (has_ext_instr_set) {
1804 M_LADD(s2, s1, REG_ITMP1, 0);
1805 M_BST (s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1808 M_LADD (s2, s1, REG_ITMP1, 0);
1809 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1810 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1811 M_INSBL(s3, REG_ITMP1, REG_ITMP3, 0);
1812 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2, 0);
1813 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2, 0);
1814 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1819 case ICMD_PUTSTATIC:
1820 a = dseg_addaddress (iptr->val.a);
1821 M_LLD(REG_ITMP1, REG_PV, a);
1822 switch (iptr->op1) {
1824 var_to_reg_int(s2, src, REG_ITMP2);
1825 M_IST(s2, REG_ITMP1, 0);
1829 var_to_reg_int(s2, src, REG_ITMP2);
1830 M_LST(s2, REG_ITMP1, 0);
1833 var_to_reg_flt(s2, src, REG_FTMP2);
1834 M_FST(s2, REG_ITMP1, 0);
1837 var_to_reg_flt(s2, src, REG_FTMP2);
1838 M_DST(s2, REG_ITMP1, 0);
1840 default: panic ("internal error");
1844 case ICMD_GETSTATIC:
1845 a = dseg_addaddress (iptr->val.a);
1846 M_LLD(REG_ITMP1, REG_PV, a);
1847 switch (iptr->op1) {
1849 d = reg_of_var(iptr->dst, REG_ITMP3);
1850 M_ILD(d, REG_ITMP1, 0);
1851 store_reg_to_var_int(iptr->dst, d);
1855 d = reg_of_var(iptr->dst, REG_ITMP3);
1856 M_LLD(d, REG_ITMP1, 0);
1857 store_reg_to_var_int(iptr->dst, d);
1860 d = reg_of_var(iptr->dst, REG_FTMP1);
1861 M_FLD(d, REG_ITMP1, 0);
1862 store_reg_to_var_flt(iptr->dst, d);
1865 d = reg_of_var(iptr->dst, REG_FTMP1);
1866 M_DLD(d, REG_ITMP1, 0);
1867 store_reg_to_var_flt(iptr->dst, d);
1869 default: panic ("internal error");
1875 switch (iptr->op1) {
1877 var_to_reg_int(s1, src->prev, REG_ITMP1);
1878 var_to_reg_int(s2, src, REG_ITMP2);
1879 gen_nullptr_check(s1);
1880 M_IST(s2, s1, iptr->val.i);
1884 var_to_reg_int(s1, src->prev, REG_ITMP1);
1885 var_to_reg_int(s2, src, REG_ITMP2);
1886 gen_nullptr_check(s1);
1887 M_LST(s2, s1, iptr->val.i);
1890 var_to_reg_int(s1, src->prev, REG_ITMP1);
1891 var_to_reg_flt(s2, src, REG_FTMP2);
1892 gen_nullptr_check(s1);
1893 M_FST(s2, s1, iptr->val.i);
1896 var_to_reg_int(s1, src->prev, REG_ITMP1);
1897 var_to_reg_flt(s2, src, REG_FTMP2);
1898 gen_nullptr_check(s1);
1899 M_DST(s2, s1, iptr->val.i);
1901 default: panic ("internal error");
1906 switch (iptr->op1) {
1908 var_to_reg_int(s1, src, REG_ITMP1);
1909 d = reg_of_var(iptr->dst, REG_ITMP3);
1910 gen_nullptr_check(s1);
1911 M_ILD(d, s1, iptr->val.i);
1912 store_reg_to_var_int(iptr->dst, d);
1916 var_to_reg_int(s1, src, REG_ITMP1);
1917 d = reg_of_var(iptr->dst, REG_ITMP3);
1918 gen_nullptr_check(s1);
1919 M_LLD(d, s1, iptr->val.i);
1920 store_reg_to_var_int(iptr->dst, d);
1923 var_to_reg_int(s1, src, REG_ITMP1);
1924 d = reg_of_var(iptr->dst, REG_FTMP1);
1925 gen_nullptr_check(s1);
1926 M_FLD(d, s1, iptr->val.i);
1927 store_reg_to_var_flt(iptr->dst, d);
1930 var_to_reg_int(s1, src, REG_ITMP1);
1931 d = reg_of_var(iptr->dst, REG_FTMP1);
1932 gen_nullptr_check(s1);
1933 M_DLD(d, s1, iptr->val.i);
1934 store_reg_to_var_flt(iptr->dst, d);
1936 default: panic ("internal error");
1941 /********************** branch operations *****************************/
1943 #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}}
1946 var_to_reg_int(s1, src, REG_ITMP1);
1947 M_INTMOVE(s1, REG_ITMP1_XPTR);
1948 a = dseg_addaddress(asm_handle_exception);
1949 M_LLD(REG_ITMP2, REG_PV, a);
1950 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
1956 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
1961 M_BSR(REG_ITMP1, 0);
1962 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
1966 var = &(locals[iptr->op1][TYPE_ADR]);
1967 if (var->flags & INMEMORY) {
1968 M_LLD(REG_ITMP1, REG_SP, 8 * var->regoff);
1969 M_RET(REG_ZERO, REG_ITMP1);
1972 M_RET(REG_ZERO, var->regoff);
1977 var_to_reg_int(s1, src, REG_ITMP1);
1979 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
1981 case ICMD_IFNONNULL:
1982 var_to_reg_int(s1, src, REG_ITMP1);
1984 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
1988 var_to_reg_int(s1, src, REG_ITMP1);
1989 if (iptr->val.i == 0) {
1993 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
1994 M_CMPEQ(s1, iptr->val.i, REG_ITMP1, 1);
1997 ICONST(REG_ITMP2, iptr->val.i);
1998 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1, 0);
2000 M_BNEZ(REG_ITMP1, 0);
2002 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2005 var_to_reg_int(s1, src, REG_ITMP1);
2006 if (iptr->val.i == 0) {
2010 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2011 M_CMPLT(s1, iptr->val.i, REG_ITMP1, 1);
2014 ICONST(REG_ITMP2, iptr->val.i);
2015 M_CMPLT(s1, REG_ITMP2, REG_ITMP1, 0);
2017 M_BNEZ(REG_ITMP1, 0);
2019 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2022 var_to_reg_int(s1, src, REG_ITMP1);
2023 if (iptr->val.i == 0) {
2027 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2028 M_CMPLE(s1, iptr->val.i, REG_ITMP1, 1);
2031 ICONST(REG_ITMP2, iptr->val.i);
2032 M_CMPLE(s1, REG_ITMP2, REG_ITMP1, 0);
2034 M_BNEZ(REG_ITMP1, 0);
2036 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2039 var_to_reg_int(s1, src, REG_ITMP1);
2040 if (iptr->val.i == 0) {
2044 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2045 M_CMPEQ(s1, iptr->val.i, REG_ITMP1, 1);
2048 ICONST(REG_ITMP2, iptr->val.i);
2049 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1, 0);
2051 M_BEQZ(REG_ITMP1, 0);
2053 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2056 var_to_reg_int(s1, src, REG_ITMP1);
2057 if (iptr->val.i == 0) {
2061 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2062 M_CMPLE(s1, iptr->val.i, REG_ITMP1, 1);
2065 ICONST(REG_ITMP2, iptr->val.i);
2066 M_CMPLE(s1, REG_ITMP2, REG_ITMP1, 0);
2068 M_BEQZ(REG_ITMP1, 0);
2070 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2073 var_to_reg_int(s1, src, REG_ITMP1);
2074 if (iptr->val.i == 0) {
2078 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2079 M_CMPLT(s1, iptr->val.i, REG_ITMP1, 1);
2082 ICONST(REG_ITMP2, iptr->val.i);
2083 M_CMPLT(s1, REG_ITMP2, REG_ITMP1, 0);
2085 M_BEQZ(REG_ITMP1, 0);
2087 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2091 var_to_reg_int(s1, src, REG_ITMP1);
2092 if (iptr->val.l == 0) {
2096 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2097 M_CMPEQ(s1, iptr->val.l, REG_ITMP1, 1);
2100 LCONST(REG_ITMP2, iptr->val.l);
2101 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1, 0);
2103 M_BNEZ(REG_ITMP1, 0);
2105 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2108 var_to_reg_int(s1, src, REG_ITMP1);
2109 if (iptr->val.l == 0) {
2113 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2114 M_CMPLT(s1, iptr->val.l, REG_ITMP1, 1);
2117 LCONST(REG_ITMP2, iptr->val.l);
2118 M_CMPLT(s1, REG_ITMP2, REG_ITMP1, 0);
2120 M_BNEZ(REG_ITMP1, 0);
2122 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2125 var_to_reg_int(s1, src, REG_ITMP1);
2126 if (iptr->val.l == 0) {
2130 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2131 M_CMPLE(s1, iptr->val.l, REG_ITMP1, 1);
2134 LCONST(REG_ITMP2, iptr->val.l);
2135 M_CMPLE(s1, REG_ITMP2, REG_ITMP1, 0);
2137 M_BNEZ(REG_ITMP1, 0);
2139 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2142 var_to_reg_int(s1, src, REG_ITMP1);
2143 if (iptr->val.l == 0) {
2147 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2148 M_CMPEQ(s1, iptr->val.l, REG_ITMP1, 1);
2151 LCONST(REG_ITMP2, iptr->val.l);
2152 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1, 0);
2154 M_BEQZ(REG_ITMP1, 0);
2156 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2159 var_to_reg_int(s1, src, REG_ITMP1);
2160 if (iptr->val.l == 0) {
2164 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2165 M_CMPLE(s1, iptr->val.l, REG_ITMP1, 1);
2168 LCONST(REG_ITMP2, iptr->val.l);
2169 M_CMPLE(s1, REG_ITMP2, REG_ITMP1, 0);
2171 M_BEQZ(REG_ITMP1, 0);
2173 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2176 var_to_reg_int(s1, src, REG_ITMP1);
2177 if (iptr->val.l == 0) {
2181 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2182 M_CMPLT(s1, iptr->val.l, REG_ITMP1, 1);
2185 LCONST(REG_ITMP2, iptr->val.l);
2186 M_CMPLT(s1, REG_ITMP2, REG_ITMP1, 0);
2188 M_BEQZ(REG_ITMP1, 0);
2190 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2193 case ICMD_IF_ICMPEQ:
2194 case ICMD_IF_LCMPEQ:
2195 case ICMD_IF_ACMPEQ:
2196 var_to_reg_int(s1, src->prev, REG_ITMP1);
2197 var_to_reg_int(s2, src, REG_ITMP2);
2198 M_CMPEQ(s1, s2, REG_ITMP1, 0);
2199 M_BNEZ(REG_ITMP1, 0);
2200 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2202 case ICMD_IF_ICMPNE:
2203 case ICMD_IF_LCMPNE:
2204 case ICMD_IF_ACMPNE:
2205 var_to_reg_int(s1, src->prev, REG_ITMP1);
2206 var_to_reg_int(s2, src, REG_ITMP2);
2207 M_CMPEQ(s1, s2, REG_ITMP1, 0);
2208 M_BEQZ(REG_ITMP1, 0);
2209 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2211 case ICMD_IF_ICMPLT:
2212 case ICMD_IF_LCMPLT:
2213 var_to_reg_int(s1, src->prev, REG_ITMP1);
2214 var_to_reg_int(s2, src, REG_ITMP2);
2215 M_CMPLT(s1, s2, REG_ITMP1, 0);
2216 M_BNEZ(REG_ITMP1, 0);
2217 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2219 case ICMD_IF_ICMPGT:
2220 case ICMD_IF_LCMPGT:
2221 var_to_reg_int(s1, src->prev, REG_ITMP1);
2222 var_to_reg_int(s2, src, REG_ITMP2);
2223 M_CMPLE(s1, s2, REG_ITMP1, 0);
2224 M_BEQZ(REG_ITMP1, 0);
2225 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2227 case ICMD_IF_ICMPLE:
2228 case ICMD_IF_LCMPLE:
2229 var_to_reg_int(s1, src->prev, REG_ITMP1);
2230 var_to_reg_int(s2, src, REG_ITMP2);
2231 M_CMPLE(s1, s2, REG_ITMP1, 0);
2232 M_BNEZ(REG_ITMP1, 0);
2233 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2235 case ICMD_IF_ICMPGE:
2236 case ICMD_IF_LCMPGE:
2237 var_to_reg_int(s1, src->prev, REG_ITMP1);
2238 var_to_reg_int(s2, src, REG_ITMP2);
2239 M_CMPLT(s1, s2, REG_ITMP1, 0);
2240 M_BEQZ(REG_ITMP1, 0);
2241 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2244 /* branch if the unsigned value of s1 is greater that s2 (note, that s2 has
2247 /* case ICMD_IF_UCMPGE:
2248 var_to_reg_int(s1, src->prev, REG_ITMP1);
2249 var_to_reg_int(s2, src, REG_ITMP2);
2250 M_CMPULE(s2, s1, REG_ITMP1, 0);
2251 M_BNEZ(REG_ITMP1, 0);
2252 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2261 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2262 a = dseg_addaddress ((void*) (builtin_monitorexit));
2263 M_LLD(REG_PV, REG_PV, a);
2264 M_LLD(argintregs[0], REG_SP, 8 * maxmemuse);
2265 M_JSR(REG_RA, REG_PV);
2266 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2269 var_to_reg_int(s1, src, REG_RESULT);
2270 M_INTMOVE(s1, REG_RESULT);
2271 goto nowperformreturn;
2277 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2278 a = dseg_addaddress ((void*) (builtin_monitorexit));
2279 M_LLD(REG_PV, REG_PV, a);
2280 M_LLD(argintregs[0], REG_SP, 8 * maxmemuse);
2281 M_JSR(REG_RA, REG_PV);
2282 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2285 var_to_reg_flt(s1, src, REG_FRESULT);
2286 M_FLTMOVE(s1, REG_FRESULT);
2287 goto nowperformreturn;
2292 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2293 a = dseg_addaddress ((void*) (builtin_monitorexit));
2294 M_LLD(REG_PV, REG_PV, a);
2295 M_LLD(argintregs[0], REG_SP, 8 * maxmemuse);
2296 M_JSR(REG_RA, REG_PV);
2297 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2305 p = parentargs_base;
2307 {p--; M_LLD (REG_RA, REG_SP, 8 * p);}
2308 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
2309 {p--; M_LLD(savintregs[r], REG_SP, 8 * p);}
2310 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
2311 {p--; M_DLD(savfltregs[r], REG_SP, 8 * p);}
2313 if (parentargs_base)
2314 {M_LDA(REG_SP, REG_SP, parentargs_base*8);}
2316 M_LDA (REG_SP, REG_SP, -24);
2317 M_LST(REG_RA, REG_SP, 0);
2318 M_LST(REG_RESULT, REG_SP, 8);
2319 M_DST(REG_FRESULT, REG_SP,16);
2320 a = dseg_addaddress (method);
2321 M_LLD(argintregs[0], REG_PV, a);
2322 M_OR(REG_RESULT, REG_RESULT, argintregs[1], 0);
2323 M_FLTMOVE(REG_FRESULT, argfltregs[2]);
2324 a = dseg_addaddress ((void*) (builtin_displaymethodstop));
2325 M_LLD(REG_PV, REG_PV, a);
2326 M_JSR (REG_RA, REG_PV);
2327 s1 = (int)((u1*) mcodeptr - mcodebase);
2328 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
2331 while (ml<-32768) { ml+=65536; mh--; }
2332 M_LDA (REG_PV, REG_RA, ml );
2333 M_LDAH (REG_PV, REG_PV, mh );
2335 M_DLD(REG_FRESULT, REG_SP,16);
2336 M_LLD(REG_RESULT, REG_SP, 8);
2337 M_LLD(REG_RA, REG_SP, 0);
2338 M_LDA (REG_SP, REG_SP, 24);
2340 M_RET(REG_ZERO, REG_RA);
2346 case ICMD_TABLESWITCH:
2350 s4ptr = iptr->val.a;
2351 l = s4ptr[1]; /* low */
2352 i = s4ptr[2]; /* high */
2354 var_to_reg_int(s1, src, REG_ITMP1);
2356 {M_INTMOVE(s1, REG_ITMP1);}
2358 M_LDA(REG_ITMP1, s1, -l);
2362 M_CMPULE(REG_ITMP1, i - 1, REG_ITMP2, 1);
2364 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
2365 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2, 0);
2367 M_BEQZ(REG_ITMP2, 0);
2368 mcode_addreference(BlockPtrOfPC(s4ptr[0]), mcodeptr);
2370 /* build jump table top down and use address of lowest entry */
2374 dseg_addtarget(BlockPtrOfPC(*--s4ptr));
2378 /* length of dataseg after last dseg_addtarget is used by load */
2380 M_S8ADDQ(REG_ITMP1, REG_PV, REG_ITMP2, 0);
2381 M_LLD(REG_ITMP2, REG_ITMP2, -dseglen);
2382 M_JMP(REG_ZERO, REG_ITMP2);
2387 case ICMD_LOOKUPSWITCH:
2389 s4 i, l, val, *s4ptr;
2391 s4ptr = iptr->val.a;
2392 l = s4ptr[0]; /* default */
2393 i = s4ptr[1]; /* count */
2395 MCODECHECK((i<<2)+8);
2396 var_to_reg_int(s1, src, REG_ITMP1);
2400 if ((val >= 0) && (val <= 255)) {
2401 M_CMPEQ(s1, val, REG_ITMP2, 1);
2404 if ((val >= -32768) && (val <= 32767)) {
2405 M_LDA(REG_ITMP2, REG_ZERO, val);
2408 a = dseg_adds4 (val);
2409 M_ILD(REG_ITMP2, REG_PV, a);
2411 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2, 0);
2413 M_BNEZ(REG_ITMP2, 0);
2414 mcode_addreference(BlockPtrOfPC(s4ptr[1]), mcodeptr);
2418 mcode_addreference(BlockPtrOfPC(l), mcodeptr);
2436 case ICMD_INVOKESTATIC:
2437 case ICMD_INVOKESPECIAL:
2438 case ICMD_INVOKEVIRTUAL:
2439 case ICMD_INVOKEINTERFACE:
2446 MCODECHECK((s3 << 1) + 64);
2448 for (; --s3 >= 0; src = src->prev) {
2449 if (src->varkind == ARGVAR)
2451 if (IS_INT_LNG_TYPE(src->type)) {
2452 if (s3 < INT_ARG_CNT) {
2453 s1 = argintregs[s3];
2454 var_to_reg_int(d, src, s1);
2458 var_to_reg_int(d, src, REG_ITMP1);
2459 M_LST(d, REG_SP, 8 * (s3 - INT_ARG_CNT));
2463 if (s3 < FLT_ARG_CNT) {
2464 s1 = argfltregs[s3];
2465 var_to_reg_flt(d, src, s1);
2469 var_to_reg_flt(d, src, REG_FTMP1);
2470 M_DST(d, REG_SP, 8 * (s3 - FLT_ARG_CNT));
2475 switch (iptr->opc) {
2479 a = dseg_addaddress ((void*) (m));
2481 M_LLD(REG_PV, REG_PV, a); /* Pointer to built-in-function */
2483 goto makeactualcall;
2485 case ICMD_INVOKESTATIC:
2486 case ICMD_INVOKESPECIAL:
2487 a = dseg_addaddress (m->stubroutine);
2489 M_LLD(REG_PV, REG_PV, a ); /* Method-Pointer in r27 */
2492 goto makeactualcall;
2494 case ICMD_INVOKEVIRTUAL:
2496 gen_nullptr_check(argintregs[0]);
2497 M_LLD(REG_METHODPTR, argintregs[0],
2498 OFFSET(java_objectheader, vftbl));
2499 M_LLD(REG_PV, REG_METHODPTR, OFFSET(vftbl, table[0]) +
2500 sizeof(methodptr) * m->vftblindex);
2503 goto makeactualcall;
2505 case ICMD_INVOKEINTERFACE:
2508 gen_nullptr_check(argintregs[0]);
2509 M_LLD(REG_METHODPTR, argintregs[0],
2510 OFFSET(java_objectheader, vftbl));
2511 M_LLD(REG_METHODPTR, REG_METHODPTR,
2512 OFFSET(vftbl, interfacevftbl));
2513 M_LLD(REG_METHODPTR, REG_METHODPTR,
2514 sizeof(methodptr*) * ci->index);
2515 M_LLD(REG_PV, REG_METHODPTR,
2516 sizeof(methodptr) * (m - ci->methods));
2519 goto makeactualcall;
2523 sprintf (logtext, "Unkown ICMD-Command: %d", iptr->opc);
2529 M_JSR (REG_RA, REG_PV);
2530 s1 = (int)((u1*) mcodeptr - mcodebase);
2531 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
2534 while (ml<-32768) { ml+=65536; mh--; }
2535 M_LDA (REG_PV, REG_RA, ml );
2536 M_LDAH (REG_PV, REG_PV, mh );
2539 if (d != TYPE_VOID) {
2540 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
2541 s1 = reg_of_var(iptr->dst, REG_RESULT);
2542 M_INTMOVE(REG_RESULT, s1);
2543 store_reg_to_var_int(iptr->dst, s1);
2546 s1 = reg_of_var(iptr->dst, REG_FRESULT);
2547 M_FLTMOVE(REG_FRESULT, s1);
2548 store_reg_to_var_flt(iptr->dst, s1);
2554 case ICMD_CHECKASIZE:
2555 var_to_reg_int(s1, src, REG_ITMP1);
2557 mcode_addxcheckarefs(mcodeptr);
2560 case ICMD_MULTIANEWARRAY:
2562 /* check for negative sizes and copy sizes to stack if necessary */
2564 MCODECHECK((iptr->op1 << 1) + 64);
2566 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
2567 var_to_reg_int(s2, src, REG_ITMP1);
2569 mcode_addxcheckarefs(mcodeptr);
2571 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
2573 if (src->varkind != ARGVAR) {
2574 M_LST(s2, REG_SP, 8 * (s1 + INT_ARG_CNT));
2578 /* a0 = dimension count */
2580 M_LDA(argintregs[0], REG_ZERO, iptr->op1);
2582 /* a1 = arraydescriptor */
2584 a = dseg_addaddress(iptr->val.a);
2585 M_LLD(argintregs[1], REG_PV, a);
2587 /* a2 = pointer to dimensions = stack pointer */
2589 M_INTMOVE(REG_SP, argintregs[2]);
2591 a = dseg_addaddress((void*) (builtin_nmultianewarray));
2592 M_LLD(REG_PV, REG_PV, a);
2593 M_JSR(REG_RA, REG_PV);
2594 s1 = (int)((u1*) mcodeptr - mcodebase);
2596 M_LDA (REG_PV, REG_RA, -s1);
2598 s4 ml = -s1, mh = 0;
2599 while (ml < -32768) {ml += 65536; mh--;}
2600 M_LDA(REG_PV, REG_RA, ml);
2601 M_LDAH(REG_PV, REG_PV, mh);
2603 s1 = reg_of_var(iptr->dst, REG_RESULT);
2604 M_INTMOVE(REG_RESULT, s1);
2605 store_reg_to_var_int(iptr->dst, s1);
2609 default: sprintf (logtext, "Unknown pseudo command: %d", iptr->opc);
2612 } /* for instruction */
2613 src = bptr->outstack;
2614 len = bptr->outdepth;
2618 if ((src->varkind != STACKVAR)) {
2620 if (IS_FLT_DBL_TYPE(s2)) {
2621 var_to_reg_int(s1, src, REG_ITMP1);
2622 if (!(interfaces[len][s2].flags & INMEMORY)) {
2623 M_FLTMOVE(s1,interfaces[len][s2].regoff);
2626 M_DST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
2630 var_to_reg_flt(s1, src, REG_FTMP1);
2631 if (!(interfaces[len][s2].flags & INMEMORY)) {
2632 M_INTMOVE(s1,interfaces[len][s2].regoff);
2635 M_LST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
2641 } /* for basic block */
2643 bptr -> mpc = (int)((u1*) mcodeptr - mcodebase);
2646 s4 *xcodeptr = NULL;
2648 for (; xboundrefs != NULL; xboundrefs = xboundrefs->next) {
2649 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
2650 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
2651 xboundrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
2655 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
2656 xboundrefs->branchpos, (u1*) mcodeptr - mcodebase);
2660 M_LDA(REG_ITMP2_XPC, REG_PV, xboundrefs->branchpos);
2662 if (xcodeptr != NULL) {
2663 M_BR((xcodeptr-mcodeptr)-1);
2666 xcodeptr = mcodeptr;
2668 a = dseg_addaddress(proto_java_lang_ArrayIndexOutOfBoundsException);
2669 M_LLD(REG_ITMP1_XPTR, REG_PV, a);
2671 a = dseg_addaddress(asm_handle_exception);
2672 M_LLD(REG_ITMP3, REG_PV, a);
2674 M_JMP(REG_ZERO, REG_ITMP3);
2680 for (; xcheckarefs != NULL; xcheckarefs = xcheckarefs->next) {
2681 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
2682 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
2683 xcheckarefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
2687 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
2688 xcheckarefs->branchpos, (u1*) mcodeptr - mcodebase);
2692 M_LDA(REG_ITMP2_XPC, REG_PV, xcheckarefs->branchpos);
2694 if (xcodeptr != NULL) {
2695 M_BR((xcodeptr-mcodeptr)-1);
2698 xcodeptr = mcodeptr;
2700 a = dseg_addaddress(proto_java_lang_NegativeArraySizeException);
2701 M_LLD(REG_ITMP1_XPTR, REG_PV, a);
2703 a = dseg_addaddress(asm_handle_exception);
2704 M_LLD(REG_ITMP3, REG_PV, a);
2706 M_JMP(REG_ZERO, REG_ITMP3);
2711 #ifdef SOFTNULLPTRCHECK
2715 for (; xnullrefs != NULL; xnullrefs = xnullrefs->next) {
2716 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
2717 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
2718 xnullrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
2722 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
2723 xnullrefs->branchpos, (u1*) mcodeptr - mcodebase);
2727 M_LDA(REG_ITMP2_XPC, REG_PV, xnullrefs->branchpos - 4);
2729 if (xcodeptr != NULL) {
2730 M_BR((xcodeptr-mcodeptr)-1);
2733 xcodeptr = mcodeptr;
2735 a = dseg_addaddress(proto_java_lang_NullPointerException);
2736 M_LLD(REG_ITMP1_XPTR, REG_PV, a);
2738 a = dseg_addaddress(asm_handle_exception);
2739 M_LLD(REG_ITMP3, REG_PV, a);
2741 M_JMP(REG_ZERO, REG_ITMP3);
2748 mcode_finish((int)((u1*) mcodeptr - mcodebase));
2752 /******** redefinition of code generation macros (compiling into array) *******/
2755 These macros are newly defined to allow code generation into an array.
2756 This is necessary, because the original M_.. macros generate code by
2757 calling 'mcode_adds4' that uses an additional data structure to
2760 For a faster (but less flexible) version to generate code, these
2761 macros directly use the (s4* p) - pointer to put the code directly
2762 in a locally defined array.
2763 This makes sense only for the stub-generation-routines below.
2767 #define M_OP3(op,fu,a,b,c,const) \
2768 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<(16-3*(const)))| \
2769 ((const)<<12)|((fu)<<5)|((c)) )
2771 #define M_FOP3(op,fu,a,b,c) \
2772 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<16)|((fu)<<5)|(c) )
2774 #define M_BRA(op,a,disp) \
2775 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((disp)&0x1fffff) )
2777 #define M_MEM(op,a,b,disp) \
2778 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<16)|((disp)&0xffff) )
2783 /************************ function createcompilerstub **************************
2785 creates a stub routine which calls the compiler
2787 *******************************************************************************/
2789 #define COMPSTUBSIZE 3
2791 u1 *createcompilerstub (methodinfo *m)
2793 u8 *s = CNEW (u8, COMPSTUBSIZE); /* memory to hold the stub */
2794 s4 *p = (s4*) s; /* code generation pointer */
2796 /* code for the stub */
2797 M_LLD (REG_PV, REG_PV, 16); /* load pointer to the compiler */
2798 M_JMP (0, REG_PV); /* jump to the compiler, return address
2799 in reg 0 is used as method pointer */
2800 s[1] = (u8) m; /* literals to be adressed */
2801 s[2] = (u8) asm_call_jit_compiler; /* jump directly via PV from above */
2804 count_cstub_len += COMPSTUBSIZE * 8;
2811 /************************* function removecompilerstub *************************
2813 deletes a compilerstub from memory (simply by freeing it)
2815 *******************************************************************************/
2817 void removecompilerstub (u1 *stub)
2819 CFREE (stub, COMPSTUBSIZE * 8);
2823 /************************ function: removenativestub ***************************
2825 removes a previously created native-stub from memory
2827 *******************************************************************************/
2829 void removenativestub (u1 *stub)
2831 CFREE (stub, NATIVESTUBSIZE * 8);
2837 /********************* Funktion: ncreatenativestub *****************************
2839 creates a stub routine which calls a native method
2841 *******************************************************************************/
2843 #define NATIVESTUBSIZE 11
2845 u1 *ncreatenativestub (functionptr f, methodinfo *m)
2847 u8 *s = CNEW (u8, NATIVESTUBSIZE); /* memory to hold the stub */
2848 s4 *p = (s4*) s; /* code generation pointer */
2850 M_LDA (REG_SP, REG_SP, -8); /* build up stackframe */
2851 M_LST (REG_RA, REG_SP, 0); /* store return address */
2853 M_LLD (REG_PV, REG_PV, 8*8); /* load adress of native method */
2854 M_JSR (REG_RA, REG_PV); /* call native method */
2856 M_LDA (REG_PV, REG_RA, -4*4); /* recompute pv from ra */
2857 M_LLD (REG_ITMP3, REG_PV, 9*8); /* get address of exceptionptr */
2859 M_LLD (REG_RA, REG_SP, 0); /* load return address */
2860 M_LLD (REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
2862 M_LDA (REG_SP, REG_SP, 8); /* remove stackframe */
2863 M_BNEZ (REG_ITMP1, 1); /* if no exception then return */
2865 M_RET (REG_ZERO, REG_RA); /* return to caller */
2867 M_LST (REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
2868 M_LDA (REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
2870 M_LLD (REG_ITMP3, REG_PV,10*8); /* load asm exception handler address */
2871 M_JMP (REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
2874 s[8] = (u8) f; /* address of native method */
2875 s[9] = (u8) (&exceptionptr); /* address of exceptionptr */
2876 s[10]= (u8) (asm_handle_nat_exception); /* addr of asm exception handler */
2879 count_nstub_len += NATIVESTUBSIZE * 8;