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_ZAPNOT(d, 0x03, d, 1);
1044 M_IADD(d, REG_ITMP1, d, 0);
1046 M_ISUB(REG_ZERO, s1, REG_ITMP1, 0);
1047 M_ZAPNOT(REG_ITMP1, 0x03, REG_ITMP2, 1);
1048 M_SRA(REG_ITMP1, 16, d, 1);
1049 M_CMPLT(REG_ITMP2, d, REG_ITMP1, 0);
1050 M_ISUB(REG_ITMP2, d, d, 0);
1051 M_ZAPNOT(d, 0x03, d, 1);
1052 M_IADD(d, REG_ITMP1, d, 0);
1053 M_ISUB(REG_ZERO, d, d, 0);
1054 M_SLL(s1, 33, REG_ITMP2, 1);
1055 M_CMPEQ(REG_ITMP2, REG_ZERO, REG_ITMP2, 0);
1056 M_ISUB(d, REG_ITMP2, d, 0);
1057 store_reg_to_var_int(iptr->dst, d);
1059 case ICMD_LANDCONST:
1060 var_to_reg_int(s1, src, REG_ITMP1);
1061 d = reg_of_var(iptr->dst, REG_ITMP3);
1062 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1063 M_AND(s1, iptr->val.l, d, 1);
1065 else if (iptr->val.l == 0xffffL) {
1066 M_ZAPNOT(s1, 0x03, d, 1);
1068 else if (iptr->val.l == 0xffffffL) {
1069 M_ZAPNOT(s1, 0x07, d, 1);
1071 else if (iptr->val.l == 0xffffffffL) {
1072 M_ZAPNOT(s1, 0x0f, d, 1);
1074 else if (iptr->val.l == 0xffffffffffL) {
1075 M_ZAPNOT(s1, 0x1f, d, 1);
1077 else if (iptr->val.l == 0xffffffffffffL) {
1078 M_ZAPNOT(s1, 0x3f, d, 1);
1080 else if (iptr->val.l == 0xffffffffffffffL) {
1081 M_ZAPNOT(s1, 0x7f, d, 1);
1084 LCONST(REG_ITMP2, iptr->val.l);
1085 M_AND(s1, REG_ITMP2, d, 0);
1087 store_reg_to_var_int(iptr->dst, d);
1090 var_to_reg_int(s1, src, REG_ITMP1);
1091 d = reg_of_var(iptr->dst, REG_ITMP3);
1092 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1093 M_AND(s1, iptr->val.l, d, 1);
1095 M_LSUB(REG_ZERO, s1, d, 0);
1096 M_AND(d, iptr->val.l, d, 1);
1098 else if (iptr->val.l == 0xffffL) {
1099 M_ZAPNOT(s1, 0x03, d, 1);
1101 M_LSUB(REG_ZERO, s1, d, 0);
1102 M_ZAPNOT(d, 0x03, d, 1);
1104 else if (iptr->val.l == 0xffffffL) {
1105 M_ZAPNOT(s1, 0x07, d, 1);
1107 M_LSUB(REG_ZERO, s1, d, 0);
1108 M_ZAPNOT(d, 0x07, d, 1);
1110 else if (iptr->val.l == 0xffffffffL) {
1111 M_ZAPNOT(s1, 0x0f, d, 1);
1113 M_LSUB(REG_ZERO, s1, d, 0);
1114 M_ZAPNOT(d, 0x0f, d, 1);
1116 else if (iptr->val.l == 0xffffffffffL) {
1117 M_ZAPNOT(s1, 0x1f, d, 1);
1119 M_LSUB(REG_ZERO, s1, d, 0);
1120 M_ZAPNOT(d, 0x1f, d, 1);
1122 else if (iptr->val.l == 0xffffffffffffL) {
1123 M_ZAPNOT(s1, 0x3f, d, 1);
1125 M_LSUB(REG_ZERO, s1, d, 0);
1126 M_ZAPNOT(d, 0x3f, d, 1);
1128 else if (iptr->val.l == 0xffffffffffffffL) {
1129 M_ZAPNOT(s1, 0x7f, d, 1);
1131 M_LSUB(REG_ZERO, s1, d, 0);
1132 M_ZAPNOT(d, 0x7f, d, 1);
1135 LCONST(REG_ITMP2, iptr->val.l);
1136 M_AND(s1, REG_ITMP2, d, 0);
1138 M_LSUB(REG_ZERO, s1, d, 0);
1139 M_AND(d, REG_ITMP2, d, 0);
1141 M_LSUB(REG_ZERO, d, d, 0);
1142 store_reg_to_var_int(iptr->dst, d);
1144 case ICMD_LREM0X10001:
1145 var_to_reg_int(s1, src, REG_ITMP1);
1146 d = reg_of_var(iptr->dst, REG_ITMP3);
1147 M_ZAPNOT(s1, 0x03, REG_ITMP2, 1);
1148 M_SRA(s1, 16, d, 1);
1149 M_CMPLT(REG_ITMP2, d, REG_ITMP1, 0);
1150 M_LSUB(REG_ITMP2, d, d, 0);
1151 M_ZAPNOT(d, 0x03, d, 1);
1152 M_LADD(d, REG_ITMP1, d, 0);
1153 M_LDA(REG_ITMP2, REG_ZERO, -1);
1154 M_SRL(REG_ITMP2, 33, REG_ITMP2, 1);
1155 M_CMPULT(s1, REG_ITMP2, REG_ITMP2, 0);
1156 M_BNEZ(REG_ITMP2, 11);
1157 M_LDA(d, REG_ZERO, -257);
1158 M_ZAPNOT(d, 0xcd, d, 1);
1159 M_LSUB(REG_ZERO, s1, REG_ITMP2, 0);
1160 M_CMOVGE(s1, s1, REG_ITMP2, 0);
1161 M_UMULH(REG_ITMP2, d, REG_ITMP2, 0);
1162 M_SRL(REG_ITMP2, 16, REG_ITMP2, 1);
1163 M_LSUB(REG_ZERO, REG_ITMP2, d, 0);
1164 M_CMOVGE(s1, REG_ITMP2, d, 0);
1165 M_SLL(d, 16, REG_ITMP2, 1);
1166 M_LADD(d, REG_ITMP2, d, 0);
1167 M_LSUB(s1, d, d, 0);
1168 store_reg_to_var_int(iptr->dst, d);
1173 var_to_reg_int(s1, src->prev, REG_ITMP1);
1174 var_to_reg_int(s2, src, REG_ITMP2);
1175 d = reg_of_var(iptr->dst, REG_ITMP3);
1177 store_reg_to_var_int(iptr->dst, d);
1180 var_to_reg_int(s1, src, REG_ITMP1);
1181 d = reg_of_var(iptr->dst, REG_ITMP3);
1182 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1183 M_OR(s1, iptr->val.i, d, 1);
1186 ICONST(REG_ITMP2, iptr->val.i);
1187 M_OR(s1, REG_ITMP2, d, 0);
1189 store_reg_to_var_int(iptr->dst, d);
1192 var_to_reg_int(s1, src, REG_ITMP1);
1193 d = reg_of_var(iptr->dst, REG_ITMP3);
1194 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1195 M_OR(s1, iptr->val.l, d, 1);
1198 LCONST(REG_ITMP2, iptr->val.l);
1199 M_OR(s1, REG_ITMP2, d, 0);
1201 store_reg_to_var_int(iptr->dst, d);
1206 var_to_reg_int(s1, src->prev, REG_ITMP1);
1207 var_to_reg_int(s2, src, REG_ITMP2);
1208 d = reg_of_var(iptr->dst, REG_ITMP3);
1209 M_XOR(s1, s2, d, 0);
1210 store_reg_to_var_int(iptr->dst, d);
1212 case ICMD_IXORCONST:
1213 var_to_reg_int(s1, src, REG_ITMP1);
1214 d = reg_of_var(iptr->dst, REG_ITMP3);
1215 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1216 M_XOR(s1, iptr->val.i, d, 1);
1219 ICONST(REG_ITMP2, iptr->val.i);
1220 M_XOR(s1, REG_ITMP2, d, 0);
1222 store_reg_to_var_int(iptr->dst, d);
1224 case ICMD_LXORCONST:
1225 var_to_reg_int(s1, src, REG_ITMP1);
1226 d = reg_of_var(iptr->dst, REG_ITMP3);
1227 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1228 M_XOR(s1, iptr->val.l, d, 1);
1231 LCONST(REG_ITMP2, iptr->val.l);
1232 M_XOR(s1, REG_ITMP2, d, 0);
1234 store_reg_to_var_int(iptr->dst, d);
1239 var_to_reg_int(s1, src->prev, REG_ITMP1);
1240 var_to_reg_int(s2, src, REG_ITMP2);
1241 d = reg_of_var(iptr->dst, REG_ITMP3);
1242 M_CMPLT(s1, s2, REG_ITMP3, 0);
1243 M_CMPLT(s2, s1, REG_ITMP1, 0);
1244 M_LSUB (REG_ITMP1, REG_ITMP3, d, 0);
1245 store_reg_to_var_int(iptr->dst, d);
1250 var = &(locals[iptr->op1][TYPE_INT]);
1251 if (var->flags & INMEMORY) {
1253 M_LLD(s1, REG_SP, 8 * var->regoff);
1257 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1258 M_IADD(s1, iptr->val.i, s1, 1);
1260 else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1261 M_ISUB(s1, (-iptr->val.i), s1, 1);
1264 M_LDA (s1, s1, iptr->val.i);
1265 M_IADD(s1, REG_ZERO, s1, 0);
1267 if (var->flags & INMEMORY)
1268 M_LST(s1, REG_SP, 8 * var->regoff);
1272 /*********************** floating operations **************************/
1275 var_to_reg_flt(s1, src, REG_FTMP1);
1276 d = reg_of_var(iptr->dst, REG_FTMP3);
1278 store_reg_to_var_flt(iptr->dst, d);
1281 var_to_reg_flt(s1, src, REG_FTMP1);
1282 d = reg_of_var(iptr->dst, REG_FTMP3);
1284 store_reg_to_var_flt(iptr->dst, d);
1288 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1289 var_to_reg_flt(s2, src, REG_FTMP2);
1290 d = reg_of_var(iptr->dst, REG_FTMP3);
1298 store_reg_to_var_flt(iptr->dst, d);
1301 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1302 var_to_reg_flt(s2, src, REG_FTMP2);
1303 d = reg_of_var(iptr->dst, REG_FTMP3);
1311 store_reg_to_var_flt(iptr->dst, d);
1315 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1316 var_to_reg_flt(s2, src, REG_FTMP2);
1317 d = reg_of_var(iptr->dst, REG_FTMP3);
1325 store_reg_to_var_flt(iptr->dst, d);
1328 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1329 var_to_reg_flt(s2, src, REG_FTMP2);
1330 d = reg_of_var(iptr->dst, REG_FTMP3);
1338 store_reg_to_var_flt(iptr->dst, d);
1342 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1343 var_to_reg_flt(s2, src, REG_FTMP2);
1344 d = reg_of_var(iptr->dst, REG_FTMP3);
1352 store_reg_to_var_flt(iptr->dst, d);
1355 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1356 var_to_reg_flt(s2, src, REG_FTMP2);
1357 d = reg_of_var(iptr->dst, REG_FTMP3);
1365 store_reg_to_var_flt(iptr->dst, d);
1369 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1370 var_to_reg_flt(s2, src, REG_FTMP2);
1371 d = reg_of_var(iptr->dst, REG_FTMP3);
1379 store_reg_to_var_flt(iptr->dst, d);
1382 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1383 var_to_reg_flt(s2, src, REG_FTMP2);
1384 d = reg_of_var(iptr->dst, REG_FTMP3);
1392 store_reg_to_var_flt(iptr->dst, d);
1396 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1397 var_to_reg_flt(s2, src, REG_FTMP2);
1398 d = reg_of_var(iptr->dst, REG_FTMP3);
1400 M_FDIVS(s1,s2, REG_FTMP3);
1402 M_CVTDL_CS(REG_ZERO, REG_FTMP3, REG_FTMP3); /* round to integer */
1404 M_CVTLF(REG_ZERO, REG_FTMP3, REG_FTMP3);
1405 M_FMULS(REG_FTMP3, s2, REG_FTMP3);
1407 M_FSUBS(s1, REG_FTMP3, d);
1411 M_FDIV(s1,s2, REG_FTMP3);
1412 M_CVTDL_C(REG_ZERO, REG_FTMP3, REG_FTMP3); /* round to integer */
1413 M_CVTLF(REG_ZERO, REG_FTMP3, REG_FTMP3);
1414 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1415 M_FSUB(s1, REG_FTMP3, d);
1417 store_reg_to_var_flt(iptr->dst, d);
1420 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1421 var_to_reg_flt(s2, src, REG_FTMP2);
1422 d = reg_of_var(iptr->dst, REG_FTMP3);
1424 M_DDIVS(s1,s2, REG_FTMP3);
1426 M_CVTDL_CS(REG_ZERO, REG_FTMP3, REG_FTMP3); /* round to integer */
1428 M_CVTLD(REG_ZERO, REG_FTMP3, REG_FTMP3);
1429 M_DMULS(REG_FTMP3, s2, REG_FTMP3);
1431 M_DSUBS(s1, REG_FTMP3, d);
1435 M_DDIV(s1,s2, REG_FTMP3);
1436 M_CVTDL_C(REG_ZERO, REG_FTMP3, REG_FTMP3); /* round to integer */
1437 M_CVTLD(REG_ZERO, REG_FTMP3, REG_FTMP3);
1438 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1439 M_DSUB(s1, REG_FTMP3, d);
1441 store_reg_to_var_flt(iptr->dst, d);
1446 var_to_reg_int(s1, src, REG_ITMP1);
1447 d = reg_of_var(iptr->dst, REG_FTMP3);
1448 a = dseg_adddouble(0.0);
1449 M_LST (s1, REG_PV, a);
1450 M_DLD (d, REG_PV, a);
1451 M_CVTLF(REG_ZERO, d, d);
1452 store_reg_to_var_flt(iptr->dst, d);
1457 var_to_reg_int(s1, src, REG_ITMP1);
1458 d = reg_of_var(iptr->dst, REG_FTMP3);
1459 a = dseg_adddouble(0.0);
1460 M_LST (s1, REG_PV, a);
1461 M_DLD (d, REG_PV, a);
1462 M_CVTLD(REG_ZERO, d, d);
1463 store_reg_to_var_flt(iptr->dst, d);
1468 var_to_reg_flt(s1, src, REG_FTMP1);
1469 d = reg_of_var(iptr->dst, REG_ITMP3);
1470 a = dseg_adddouble(0.0);
1472 M_CVTDL_CS(REG_ZERO, s1, REG_FTMP1);
1474 M_CVTLIS(REG_FTMP1, REG_FTMP2);
1478 M_CVTDL_C(REG_ZERO, s1, REG_FTMP1);
1479 M_CVTLI(REG_FTMP1, REG_FTMP2);
1481 M_DST (REG_FTMP1, REG_PV, a);
1482 M_ILD (d, REG_PV, a);
1483 store_reg_to_var_int(iptr->dst, d);
1488 var_to_reg_flt(s1, src, REG_FTMP1);
1489 d = reg_of_var(iptr->dst, REG_ITMP3);
1490 a = dseg_adddouble(0.0);
1492 M_CVTDL_CS(REG_ZERO, s1, REG_FTMP1);
1496 M_CVTDL_C(REG_ZERO, s1, REG_FTMP1);
1498 M_DST (REG_FTMP1, REG_PV, a);
1499 M_LLD (d, REG_PV, a);
1500 store_reg_to_var_int(iptr->dst, d);
1504 var_to_reg_flt(s1, src, REG_FTMP1);
1505 d = reg_of_var(iptr->dst, REG_FTMP3);
1507 store_reg_to_var_flt(iptr->dst, d);
1511 var_to_reg_flt(s1, src, REG_FTMP1);
1512 d = reg_of_var(iptr->dst, REG_FTMP3);
1514 M_CVTDFS(REG_ZERO, s1, d);
1518 M_CVTDF(REG_ZERO, s1, d);
1520 store_reg_to_var_flt(iptr->dst, d);
1525 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1526 var_to_reg_flt(s2, src, REG_FTMP2);
1527 d = reg_of_var(iptr->dst, REG_ITMP3);
1529 M_LSUB (REG_ZERO, 1, d, 1);
1530 M_FCMPEQS(s1, s2, REG_FTMP3);
1532 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1533 M_OR (REG_ZERO, REG_ZERO, d, 0);
1534 M_FCMPLTS(s2, s1, REG_FTMP3);
1536 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1537 M_LADD (REG_ZERO, 1, d, 1);
1540 M_LSUB (REG_ZERO, 1, d, 1);
1541 M_FCMPEQ(s1, s2, REG_FTMP3);
1542 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1543 M_OR (REG_ZERO, REG_ZERO, d, 0);
1544 M_FCMPLT(s2, s1, REG_FTMP3);
1545 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1546 M_LADD (REG_ZERO, 1, d, 1);
1548 store_reg_to_var_int(iptr->dst, d);
1553 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1554 var_to_reg_flt(s2, src, REG_FTMP2);
1555 d = reg_of_var(iptr->dst, REG_ITMP3);
1557 M_LADD (REG_ZERO, 1, d, 1);
1558 M_FCMPEQS(s1, s2, REG_FTMP3);
1560 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1561 M_OR (REG_ZERO, REG_ZERO, d, 0);
1562 M_FCMPLTS(s1, s2, REG_FTMP3);
1564 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1565 M_LSUB (REG_ZERO, 1, d, 1);
1568 M_LADD (REG_ZERO, 1, d, 1);
1569 M_FCMPEQ(s1, s2, REG_FTMP3);
1570 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1571 M_OR (REG_ZERO, REG_ZERO, d, 0);
1572 M_FCMPLT(s1, s2, REG_FTMP3);
1573 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1574 M_LSUB (REG_ZERO, 1, d, 1);
1576 store_reg_to_var_int(iptr->dst, d);
1580 /********************** memory operations *****************************/
1582 #define gen_bound_check \
1584 M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\
1585 M_CMPULT(s2, REG_ITMP3, REG_ITMP3, 0);\
1586 M_BEQZ(REG_ITMP3, 0);\
1587 mcode_addxboundrefs(mcodeptr);\
1590 case ICMD_ARRAYLENGTH:
1591 var_to_reg_int(s1, src, REG_ITMP1);
1592 d = reg_of_var(iptr->dst, REG_ITMP3);
1593 gen_nullptr_check(s1);
1594 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1595 store_reg_to_var_int(iptr->dst, d);
1599 var_to_reg_int(s1, src->prev, REG_ITMP1);
1600 var_to_reg_int(s2, src, REG_ITMP2);
1601 d = reg_of_var(iptr->dst, REG_ITMP3);
1602 gen_nullptr_check(s1);
1604 M_S8ADDQ(s2, s1, REG_ITMP1, 0);
1605 M_LLD( d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1606 store_reg_to_var_int(iptr->dst, d);
1609 var_to_reg_int(s1, src->prev, REG_ITMP1);
1610 var_to_reg_int(s2, src, REG_ITMP2);
1611 d = reg_of_var(iptr->dst, REG_ITMP3);
1612 gen_nullptr_check(s1);
1614 M_S8ADDQ(s2, s1, REG_ITMP1, 0);
1615 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1616 store_reg_to_var_int(iptr->dst, d);
1619 var_to_reg_int(s1, src->prev, REG_ITMP1);
1620 var_to_reg_int(s2, src, REG_ITMP2);
1621 d = reg_of_var(iptr->dst, REG_ITMP3);
1622 gen_nullptr_check(s1);
1624 M_S4ADDQ(s2, s1, REG_ITMP1, 0);
1625 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1626 store_reg_to_var_int(iptr->dst, d);
1629 var_to_reg_int(s1, src->prev, REG_ITMP1);
1630 var_to_reg_int(s2, src, REG_ITMP2);
1631 d = reg_of_var(iptr->dst, REG_FTMP3);
1632 gen_nullptr_check(s1);
1634 M_S4ADDQ(s2, s1, REG_ITMP1, 0);
1635 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1636 store_reg_to_var_flt(iptr->dst, d);
1639 var_to_reg_int(s1, src->prev, REG_ITMP1);
1640 var_to_reg_int(s2, src, REG_ITMP2);
1641 d = reg_of_var(iptr->dst, REG_FTMP3);
1642 gen_nullptr_check(s1);
1644 M_S8ADDQ(s2, s1, REG_ITMP1, 0);
1645 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1646 store_reg_to_var_flt(iptr->dst, d);
1649 var_to_reg_int(s1, src->prev, REG_ITMP1);
1650 var_to_reg_int(s2, src, REG_ITMP2);
1651 d = reg_of_var(iptr->dst, REG_ITMP3);
1652 gen_nullptr_check(s1);
1654 if (has_ext_instr_set) {
1655 M_LADD(s2, s1, REG_ITMP1, 0);
1656 M_LADD(s2, REG_ITMP1, REG_ITMP1, 0);
1657 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1660 M_LADD (s2, s1, REG_ITMP1, 0);
1661 M_LADD (s2, REG_ITMP1, REG_ITMP1, 0);
1662 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1663 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1664 M_EXTWL(REG_ITMP2, REG_ITMP1, d, 0);
1666 store_reg_to_var_int(iptr->dst, d);
1669 var_to_reg_int(s1, src->prev, REG_ITMP1);
1670 var_to_reg_int(s2, src, REG_ITMP2);
1671 d = reg_of_var(iptr->dst, REG_ITMP3);
1672 gen_nullptr_check(s1);
1674 if (has_ext_instr_set) {
1675 M_LADD(s2, s1, REG_ITMP1, 0);
1676 M_LADD(s2, REG_ITMP1, REG_ITMP1, 0);
1677 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1681 M_LADD(s2, s1, REG_ITMP1, 0);
1682 M_LADD(s2, REG_ITMP1, REG_ITMP1, 0);
1683 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1684 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1685 M_EXTQH(REG_ITMP2, REG_ITMP1, d, 0);
1688 store_reg_to_var_int(iptr->dst, d);
1691 var_to_reg_int(s1, src->prev, REG_ITMP1);
1692 var_to_reg_int(s2, src, REG_ITMP2);
1693 d = reg_of_var(iptr->dst, REG_ITMP3);
1694 gen_nullptr_check(s1);
1696 if (has_ext_instr_set) {
1697 M_LADD (s2, s1, REG_ITMP1, 0);
1698 M_BLDU (d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1702 M_LADD(s2, s1, REG_ITMP1, 0);
1703 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1704 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
1705 M_EXTQH(REG_ITMP2, REG_ITMP1, d, 0);
1708 store_reg_to_var_int(iptr->dst, d);
1712 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1713 var_to_reg_int(s2, src->prev, REG_ITMP2);
1714 gen_nullptr_check(s1);
1716 var_to_reg_int(s3, src, REG_ITMP3);
1717 M_S8ADDQ(s2, s1, REG_ITMP1, 0);
1718 M_LST (s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1721 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1722 var_to_reg_int(s2, src->prev, REG_ITMP2);
1723 gen_nullptr_check(s1);
1725 var_to_reg_int(s3, src, REG_ITMP3);
1726 M_S8ADDQ(s2, s1, REG_ITMP1, 0);
1727 M_LST (s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1730 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1731 var_to_reg_int(s2, src->prev, REG_ITMP2);
1732 gen_nullptr_check(s1);
1734 var_to_reg_int(s3, src, REG_ITMP3);
1735 M_S4ADDQ(s2, s1, REG_ITMP1, 0);
1736 M_IST (s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1739 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1740 var_to_reg_int(s2, src->prev, REG_ITMP2);
1741 gen_nullptr_check(s1);
1743 var_to_reg_flt(s3, src, REG_FTMP3);
1744 M_S4ADDQ(s2, s1, REG_ITMP1, 0);
1745 M_FST (s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1748 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1749 var_to_reg_int(s2, src->prev, REG_ITMP2);
1750 gen_nullptr_check(s1);
1752 var_to_reg_flt(s3, src, REG_FTMP3);
1753 M_S8ADDQ(s2, s1, REG_ITMP1, 0);
1754 M_DST (s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1757 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1758 var_to_reg_int(s2, src->prev, REG_ITMP2);
1759 gen_nullptr_check(s1);
1761 var_to_reg_int(s3, src, REG_ITMP3);
1762 if (has_ext_instr_set) {
1763 M_LADD(s2, s1, REG_ITMP1, 0);
1764 M_LADD(s2, REG_ITMP1, REG_ITMP1, 0);
1765 M_SST (s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1768 M_LADD (s2, s1, REG_ITMP1, 0);
1769 M_LADD (s2, REG_ITMP1, REG_ITMP1, 0);
1770 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1771 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1772 M_INSWL(s3, REG_ITMP1, REG_ITMP3, 0);
1773 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2, 0);
1774 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2, 0);
1775 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1779 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1780 var_to_reg_int(s2, src->prev, REG_ITMP2);
1781 gen_nullptr_check(s1);
1783 var_to_reg_int(s3, src, REG_ITMP3);
1784 if (has_ext_instr_set) {
1785 M_LADD(s2, s1, REG_ITMP1, 0);
1786 M_LADD(s2, REG_ITMP1, REG_ITMP1, 0);
1787 M_SST (s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1790 M_LADD (s2, s1, REG_ITMP1, 0);
1791 M_LADD (s2, REG_ITMP1, REG_ITMP1, 0);
1792 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1793 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1794 M_INSWL(s3, REG_ITMP1, REG_ITMP3, 0);
1795 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2, 0);
1796 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2, 0);
1797 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1801 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1802 var_to_reg_int(s2, src->prev, REG_ITMP2);
1803 gen_nullptr_check(s1);
1805 var_to_reg_int(s3, src, REG_ITMP3);
1806 if (has_ext_instr_set) {
1807 M_LADD(s2, s1, REG_ITMP1, 0);
1808 M_BST (s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1811 M_LADD (s2, s1, REG_ITMP1, 0);
1812 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1813 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1814 M_INSBL(s3, REG_ITMP1, REG_ITMP3, 0);
1815 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2, 0);
1816 M_OR (REG_ITMP2, REG_ITMP3, REG_ITMP2, 0);
1817 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1822 case ICMD_PUTSTATIC:
1823 a = dseg_addaddress (iptr->val.a);
1824 M_LLD(REG_ITMP1, REG_PV, a);
1825 switch (iptr->op1) {
1827 var_to_reg_int(s2, src, REG_ITMP2);
1828 M_IST(s2, REG_ITMP1, 0);
1832 var_to_reg_int(s2, src, REG_ITMP2);
1833 M_LST(s2, REG_ITMP1, 0);
1836 var_to_reg_flt(s2, src, REG_FTMP2);
1837 M_FST(s2, REG_ITMP1, 0);
1840 var_to_reg_flt(s2, src, REG_FTMP2);
1841 M_DST(s2, REG_ITMP1, 0);
1843 default: panic ("internal error");
1847 case ICMD_GETSTATIC:
1848 a = dseg_addaddress (iptr->val.a);
1849 M_LLD(REG_ITMP1, REG_PV, a);
1850 switch (iptr->op1) {
1852 d = reg_of_var(iptr->dst, REG_ITMP3);
1853 M_ILD(d, REG_ITMP1, 0);
1854 store_reg_to_var_int(iptr->dst, d);
1858 d = reg_of_var(iptr->dst, REG_ITMP3);
1859 M_LLD(d, REG_ITMP1, 0);
1860 store_reg_to_var_int(iptr->dst, d);
1863 d = reg_of_var(iptr->dst, REG_FTMP1);
1864 M_FLD(d, REG_ITMP1, 0);
1865 store_reg_to_var_flt(iptr->dst, d);
1868 d = reg_of_var(iptr->dst, REG_FTMP1);
1869 M_DLD(d, REG_ITMP1, 0);
1870 store_reg_to_var_flt(iptr->dst, d);
1872 default: panic ("internal error");
1878 switch (iptr->op1) {
1880 var_to_reg_int(s1, src->prev, REG_ITMP1);
1881 var_to_reg_int(s2, src, REG_ITMP2);
1882 gen_nullptr_check(s1);
1883 M_IST(s2, s1, iptr->val.i);
1887 var_to_reg_int(s1, src->prev, REG_ITMP1);
1888 var_to_reg_int(s2, src, REG_ITMP2);
1889 gen_nullptr_check(s1);
1890 M_LST(s2, s1, iptr->val.i);
1893 var_to_reg_int(s1, src->prev, REG_ITMP1);
1894 var_to_reg_flt(s2, src, REG_FTMP2);
1895 gen_nullptr_check(s1);
1896 M_FST(s2, s1, iptr->val.i);
1899 var_to_reg_int(s1, src->prev, REG_ITMP1);
1900 var_to_reg_flt(s2, src, REG_FTMP2);
1901 gen_nullptr_check(s1);
1902 M_DST(s2, s1, iptr->val.i);
1904 default: panic ("internal error");
1909 switch (iptr->op1) {
1911 var_to_reg_int(s1, src, REG_ITMP1);
1912 d = reg_of_var(iptr->dst, REG_ITMP3);
1913 gen_nullptr_check(s1);
1914 M_ILD(d, s1, iptr->val.i);
1915 store_reg_to_var_int(iptr->dst, d);
1919 var_to_reg_int(s1, src, REG_ITMP1);
1920 d = reg_of_var(iptr->dst, REG_ITMP3);
1921 gen_nullptr_check(s1);
1922 M_LLD(d, s1, iptr->val.i);
1923 store_reg_to_var_int(iptr->dst, d);
1926 var_to_reg_int(s1, src, REG_ITMP1);
1927 d = reg_of_var(iptr->dst, REG_FTMP1);
1928 gen_nullptr_check(s1);
1929 M_FLD(d, s1, iptr->val.i);
1930 store_reg_to_var_flt(iptr->dst, d);
1933 var_to_reg_int(s1, src, REG_ITMP1);
1934 d = reg_of_var(iptr->dst, REG_FTMP1);
1935 gen_nullptr_check(s1);
1936 M_DLD(d, s1, iptr->val.i);
1937 store_reg_to_var_flt(iptr->dst, d);
1939 default: panic ("internal error");
1944 /********************** branch operations *****************************/
1946 #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}}
1949 var_to_reg_int(s1, src, REG_ITMP1);
1950 M_INTMOVE(s1, REG_ITMP1_XPTR);
1951 a = dseg_addaddress(asm_handle_exception);
1952 M_LLD(REG_ITMP2, REG_PV, a);
1953 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
1959 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
1964 M_BSR(REG_ITMP1, 0);
1965 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
1969 var = &(locals[iptr->op1][TYPE_ADR]);
1970 if (var->flags & INMEMORY) {
1971 M_LLD(REG_ITMP1, REG_SP, 8 * var->regoff);
1972 M_RET(REG_ZERO, REG_ITMP1);
1975 M_RET(REG_ZERO, var->regoff);
1980 var_to_reg_int(s1, src, REG_ITMP1);
1982 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
1984 case ICMD_IFNONNULL:
1985 var_to_reg_int(s1, src, REG_ITMP1);
1987 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
1991 var_to_reg_int(s1, src, REG_ITMP1);
1992 if (iptr->val.i == 0) {
1996 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
1997 M_CMPEQ(s1, iptr->val.i, REG_ITMP1, 1);
2000 ICONST(REG_ITMP2, iptr->val.i);
2001 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1, 0);
2003 M_BNEZ(REG_ITMP1, 0);
2005 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2008 var_to_reg_int(s1, src, REG_ITMP1);
2009 if (iptr->val.i == 0) {
2013 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2014 M_CMPLT(s1, iptr->val.i, REG_ITMP1, 1);
2017 ICONST(REG_ITMP2, iptr->val.i);
2018 M_CMPLT(s1, REG_ITMP2, REG_ITMP1, 0);
2020 M_BNEZ(REG_ITMP1, 0);
2022 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2025 var_to_reg_int(s1, src, REG_ITMP1);
2026 if (iptr->val.i == 0) {
2030 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2031 M_CMPLE(s1, iptr->val.i, REG_ITMP1, 1);
2034 ICONST(REG_ITMP2, iptr->val.i);
2035 M_CMPLE(s1, REG_ITMP2, REG_ITMP1, 0);
2037 M_BNEZ(REG_ITMP1, 0);
2039 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2042 var_to_reg_int(s1, src, REG_ITMP1);
2043 if (iptr->val.i == 0) {
2047 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2048 M_CMPEQ(s1, iptr->val.i, REG_ITMP1, 1);
2051 ICONST(REG_ITMP2, iptr->val.i);
2052 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1, 0);
2054 M_BEQZ(REG_ITMP1, 0);
2056 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2059 var_to_reg_int(s1, src, REG_ITMP1);
2060 if (iptr->val.i == 0) {
2064 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2065 M_CMPLE(s1, iptr->val.i, REG_ITMP1, 1);
2068 ICONST(REG_ITMP2, iptr->val.i);
2069 M_CMPLE(s1, REG_ITMP2, REG_ITMP1, 0);
2071 M_BEQZ(REG_ITMP1, 0);
2073 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2076 var_to_reg_int(s1, src, REG_ITMP1);
2077 if (iptr->val.i == 0) {
2081 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2082 M_CMPLT(s1, iptr->val.i, REG_ITMP1, 1);
2085 ICONST(REG_ITMP2, iptr->val.i);
2086 M_CMPLT(s1, REG_ITMP2, REG_ITMP1, 0);
2088 M_BEQZ(REG_ITMP1, 0);
2090 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2094 var_to_reg_int(s1, src, REG_ITMP1);
2095 if (iptr->val.l == 0) {
2099 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2100 M_CMPEQ(s1, iptr->val.l, REG_ITMP1, 1);
2103 LCONST(REG_ITMP2, iptr->val.l);
2104 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1, 0);
2106 M_BNEZ(REG_ITMP1, 0);
2108 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2111 var_to_reg_int(s1, src, REG_ITMP1);
2112 if (iptr->val.l == 0) {
2116 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2117 M_CMPLT(s1, iptr->val.l, REG_ITMP1, 1);
2120 LCONST(REG_ITMP2, iptr->val.l);
2121 M_CMPLT(s1, REG_ITMP2, REG_ITMP1, 0);
2123 M_BNEZ(REG_ITMP1, 0);
2125 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2128 var_to_reg_int(s1, src, REG_ITMP1);
2129 if (iptr->val.l == 0) {
2133 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2134 M_CMPLE(s1, iptr->val.l, REG_ITMP1, 1);
2137 LCONST(REG_ITMP2, iptr->val.l);
2138 M_CMPLE(s1, REG_ITMP2, REG_ITMP1, 0);
2140 M_BNEZ(REG_ITMP1, 0);
2142 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2145 var_to_reg_int(s1, src, REG_ITMP1);
2146 if (iptr->val.l == 0) {
2150 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2151 M_CMPEQ(s1, iptr->val.l, REG_ITMP1, 1);
2154 LCONST(REG_ITMP2, iptr->val.l);
2155 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1, 0);
2157 M_BEQZ(REG_ITMP1, 0);
2159 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2162 var_to_reg_int(s1, src, REG_ITMP1);
2163 if (iptr->val.l == 0) {
2167 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2168 M_CMPLE(s1, iptr->val.l, REG_ITMP1, 1);
2171 LCONST(REG_ITMP2, iptr->val.l);
2172 M_CMPLE(s1, REG_ITMP2, REG_ITMP1, 0);
2174 M_BEQZ(REG_ITMP1, 0);
2176 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2179 var_to_reg_int(s1, src, REG_ITMP1);
2180 if (iptr->val.l == 0) {
2184 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2185 M_CMPLT(s1, iptr->val.l, REG_ITMP1, 1);
2188 LCONST(REG_ITMP2, iptr->val.l);
2189 M_CMPLT(s1, REG_ITMP2, REG_ITMP1, 0);
2191 M_BEQZ(REG_ITMP1, 0);
2193 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2196 case ICMD_IF_ICMPEQ:
2197 case ICMD_IF_LCMPEQ:
2198 case ICMD_IF_ACMPEQ:
2199 var_to_reg_int(s1, src->prev, REG_ITMP1);
2200 var_to_reg_int(s2, src, REG_ITMP2);
2201 M_CMPEQ(s1, s2, REG_ITMP1, 0);
2202 M_BNEZ(REG_ITMP1, 0);
2203 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2205 case ICMD_IF_ICMPNE:
2206 case ICMD_IF_LCMPNE:
2207 case ICMD_IF_ACMPNE:
2208 var_to_reg_int(s1, src->prev, REG_ITMP1);
2209 var_to_reg_int(s2, src, REG_ITMP2);
2210 M_CMPEQ(s1, s2, REG_ITMP1, 0);
2211 M_BEQZ(REG_ITMP1, 0);
2212 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2214 case ICMD_IF_ICMPLT:
2215 case ICMD_IF_LCMPLT:
2216 var_to_reg_int(s1, src->prev, REG_ITMP1);
2217 var_to_reg_int(s2, src, REG_ITMP2);
2218 M_CMPLT(s1, s2, REG_ITMP1, 0);
2219 M_BNEZ(REG_ITMP1, 0);
2220 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2222 case ICMD_IF_ICMPGT:
2223 case ICMD_IF_LCMPGT:
2224 var_to_reg_int(s1, src->prev, REG_ITMP1);
2225 var_to_reg_int(s2, src, REG_ITMP2);
2226 M_CMPLE(s1, s2, REG_ITMP1, 0);
2227 M_BEQZ(REG_ITMP1, 0);
2228 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2230 case ICMD_IF_ICMPLE:
2231 case ICMD_IF_LCMPLE:
2232 var_to_reg_int(s1, src->prev, REG_ITMP1);
2233 var_to_reg_int(s2, src, REG_ITMP2);
2234 M_CMPLE(s1, s2, REG_ITMP1, 0);
2235 M_BNEZ(REG_ITMP1, 0);
2236 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2238 case ICMD_IF_ICMPGE:
2239 case ICMD_IF_LCMPGE:
2240 var_to_reg_int(s1, src->prev, REG_ITMP1);
2241 var_to_reg_int(s2, src, REG_ITMP2);
2242 M_CMPLT(s1, s2, REG_ITMP1, 0);
2243 M_BEQZ(REG_ITMP1, 0);
2244 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2247 /* branch if the unsigned value of s1 is greater that s2 (note, that s2 has
2250 /* case ICMD_IF_UCMPGE:
2251 var_to_reg_int(s1, src->prev, REG_ITMP1);
2252 var_to_reg_int(s2, src, REG_ITMP2);
2253 M_CMPULE(s2, s1, REG_ITMP1, 0);
2254 M_BNEZ(REG_ITMP1, 0);
2255 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2264 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2265 a = dseg_addaddress ((void*) (builtin_monitorexit));
2266 M_LLD(REG_PV, REG_PV, a);
2267 M_LLD(argintregs[0], REG_SP, 8 * maxmemuse);
2268 M_JSR(REG_RA, REG_PV);
2269 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2272 var_to_reg_int(s1, src, REG_RESULT);
2273 M_INTMOVE(s1, REG_RESULT);
2274 goto nowperformreturn;
2280 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2281 a = dseg_addaddress ((void*) (builtin_monitorexit));
2282 M_LLD(REG_PV, REG_PV, a);
2283 M_LLD(argintregs[0], REG_SP, 8 * maxmemuse);
2284 M_JSR(REG_RA, REG_PV);
2285 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2288 var_to_reg_flt(s1, src, REG_FRESULT);
2289 M_FLTMOVE(s1, REG_FRESULT);
2290 goto nowperformreturn;
2295 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2296 a = dseg_addaddress ((void*) (builtin_monitorexit));
2297 M_LLD(REG_PV, REG_PV, a);
2298 M_LLD(argintregs[0], REG_SP, 8 * maxmemuse);
2299 M_JSR(REG_RA, REG_PV);
2300 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2308 p = parentargs_base;
2310 {p--; M_LLD (REG_RA, REG_SP, 8 * p);}
2311 for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
2312 {p--; M_LLD(savintregs[r], REG_SP, 8 * p);}
2313 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
2314 {p--; M_DLD(savfltregs[r], REG_SP, 8 * p);}
2316 if (parentargs_base)
2317 {M_LDA(REG_SP, REG_SP, parentargs_base*8);}
2319 M_LDA (REG_SP, REG_SP, -24);
2320 M_LST(REG_RA, REG_SP, 0);
2321 M_LST(REG_RESULT, REG_SP, 8);
2322 M_DST(REG_FRESULT, REG_SP,16);
2323 a = dseg_addaddress (method);
2324 M_LLD(argintregs[0], REG_PV, a);
2325 M_OR(REG_RESULT, REG_RESULT, argintregs[1], 0);
2326 M_FLTMOVE(REG_FRESULT, argfltregs[2]);
2327 a = dseg_addaddress ((void*) (builtin_displaymethodstop));
2328 M_LLD(REG_PV, REG_PV, a);
2329 M_JSR (REG_RA, REG_PV);
2330 s1 = (int)((u1*) mcodeptr - mcodebase);
2331 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
2334 while (ml<-32768) { ml+=65536; mh--; }
2335 M_LDA (REG_PV, REG_RA, ml );
2336 M_LDAH (REG_PV, REG_PV, mh );
2338 M_DLD(REG_FRESULT, REG_SP,16);
2339 M_LLD(REG_RESULT, REG_SP, 8);
2340 M_LLD(REG_RA, REG_SP, 0);
2341 M_LDA (REG_SP, REG_SP, 24);
2343 M_RET(REG_ZERO, REG_RA);
2349 case ICMD_TABLESWITCH:
2353 s4ptr = iptr->val.a;
2354 l = s4ptr[1]; /* low */
2355 i = s4ptr[2]; /* high */
2357 var_to_reg_int(s1, src, REG_ITMP1);
2359 {M_INTMOVE(s1, REG_ITMP1);}
2361 M_LDA(REG_ITMP1, s1, -l);
2365 M_CMPULE(REG_ITMP1, i - 1, REG_ITMP2, 1);
2367 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
2368 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2, 0);
2370 M_BEQZ(REG_ITMP2, 0);
2371 mcode_addreference(BlockPtrOfPC(s4ptr[0]), mcodeptr);
2373 /* build jump table top down and use address of lowest entry */
2377 dseg_addtarget(BlockPtrOfPC(*--s4ptr));
2381 /* length of dataseg after last dseg_addtarget is used by load */
2383 M_S8ADDQ(REG_ITMP1, REG_PV, REG_ITMP2, 0);
2384 M_LLD(REG_ITMP2, REG_ITMP2, -dseglen);
2385 M_JMP(REG_ZERO, REG_ITMP2);
2390 case ICMD_LOOKUPSWITCH:
2392 s4 i, l, val, *s4ptr;
2394 s4ptr = iptr->val.a;
2395 l = s4ptr[0]; /* default */
2396 i = s4ptr[1]; /* count */
2398 MCODECHECK((i<<2)+8);
2399 var_to_reg_int(s1, src, REG_ITMP1);
2403 if ((val >= 0) && (val <= 255)) {
2404 M_CMPEQ(s1, val, REG_ITMP2, 1);
2407 if ((val >= -32768) && (val <= 32767)) {
2408 M_LDA(REG_ITMP2, REG_ZERO, val);
2411 a = dseg_adds4 (val);
2412 M_ILD(REG_ITMP2, REG_PV, a);
2414 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2, 0);
2416 M_BNEZ(REG_ITMP2, 0);
2417 mcode_addreference(BlockPtrOfPC(s4ptr[1]), mcodeptr);
2421 mcode_addreference(BlockPtrOfPC(l), mcodeptr);
2439 case ICMD_INVOKESTATIC:
2440 case ICMD_INVOKESPECIAL:
2441 case ICMD_INVOKEVIRTUAL:
2442 case ICMD_INVOKEINTERFACE:
2449 MCODECHECK((s3 << 1) + 64);
2451 for (; --s3 >= 0; src = src->prev) {
2452 if (src->varkind == ARGVAR)
2454 if (IS_INT_LNG_TYPE(src->type)) {
2455 if (s3 < INT_ARG_CNT) {
2456 s1 = argintregs[s3];
2457 var_to_reg_int(d, src, s1);
2461 var_to_reg_int(d, src, REG_ITMP1);
2462 M_LST(d, REG_SP, 8 * (s3 - INT_ARG_CNT));
2466 if (s3 < FLT_ARG_CNT) {
2467 s1 = argfltregs[s3];
2468 var_to_reg_flt(d, src, s1);
2472 var_to_reg_flt(d, src, REG_FTMP1);
2473 M_DST(d, REG_SP, 8 * (s3 - FLT_ARG_CNT));
2478 switch (iptr->opc) {
2482 a = dseg_addaddress ((void*) (m));
2484 M_LLD(REG_PV, REG_PV, a); /* Pointer to built-in-function */
2486 goto makeactualcall;
2488 case ICMD_INVOKESTATIC:
2489 case ICMD_INVOKESPECIAL:
2490 a = dseg_addaddress (m->stubroutine);
2492 M_LLD(REG_PV, REG_PV, a ); /* Method-Pointer in r27 */
2495 goto makeactualcall;
2497 case ICMD_INVOKEVIRTUAL:
2499 gen_nullptr_check(argintregs[0]);
2500 M_LLD(REG_METHODPTR, argintregs[0],
2501 OFFSET(java_objectheader, vftbl));
2502 M_LLD(REG_PV, REG_METHODPTR, OFFSET(vftbl, table[0]) +
2503 sizeof(methodptr) * m->vftblindex);
2506 goto makeactualcall;
2508 case ICMD_INVOKEINTERFACE:
2511 gen_nullptr_check(argintregs[0]);
2512 M_LLD(REG_METHODPTR, argintregs[0],
2513 OFFSET(java_objectheader, vftbl));
2514 M_LLD(REG_METHODPTR, REG_METHODPTR,
2515 OFFSET(vftbl, interfacevftbl));
2516 M_LLD(REG_METHODPTR, REG_METHODPTR,
2517 sizeof(methodptr*) * ci->index);
2518 M_LLD(REG_PV, REG_METHODPTR,
2519 sizeof(methodptr) * (m - ci->methods));
2522 goto makeactualcall;
2526 sprintf (logtext, "Unkown ICMD-Command: %d", iptr->opc);
2532 M_JSR (REG_RA, REG_PV);
2533 s1 = (int)((u1*) mcodeptr - mcodebase);
2534 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
2537 while (ml<-32768) { ml+=65536; mh--; }
2538 M_LDA (REG_PV, REG_RA, ml );
2539 M_LDAH (REG_PV, REG_PV, mh );
2542 if (d != TYPE_VOID) {
2543 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
2544 s1 = reg_of_var(iptr->dst, REG_RESULT);
2545 M_INTMOVE(REG_RESULT, s1);
2546 store_reg_to_var_int(iptr->dst, s1);
2549 s1 = reg_of_var(iptr->dst, REG_FRESULT);
2550 M_FLTMOVE(REG_FRESULT, s1);
2551 store_reg_to_var_flt(iptr->dst, s1);
2557 case ICMD_CHECKASIZE:
2558 var_to_reg_int(s1, src, REG_ITMP1);
2560 mcode_addxcheckarefs(mcodeptr);
2563 case ICMD_MULTIANEWARRAY:
2565 /* check for negative sizes and copy sizes to stack if necessary */
2567 MCODECHECK((iptr->op1 << 1) + 64);
2569 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
2570 var_to_reg_int(s2, src, REG_ITMP1);
2572 mcode_addxcheckarefs(mcodeptr);
2574 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
2576 if (src->varkind != ARGVAR) {
2577 M_LST(s2, REG_SP, 8 * (s1 + INT_ARG_CNT));
2581 /* a0 = dimension count */
2583 M_LDA(argintregs[0], REG_ZERO, iptr->op1);
2585 /* a1 = arraydescriptor */
2587 a = dseg_addaddress(iptr->val.a);
2588 M_LLD(argintregs[1], REG_PV, a);
2590 /* a2 = pointer to dimensions = stack pointer */
2592 M_INTMOVE(REG_SP, argintregs[2]);
2594 a = dseg_addaddress((void*) (builtin_nmultianewarray));
2595 M_LLD(REG_PV, REG_PV, a);
2596 M_JSR(REG_RA, REG_PV);
2597 s1 = (int)((u1*) mcodeptr - mcodebase);
2599 M_LDA (REG_PV, REG_RA, -s1);
2601 s4 ml = -s1, mh = 0;
2602 while (ml < -32768) {ml += 65536; mh--;}
2603 M_LDA(REG_PV, REG_RA, ml);
2604 M_LDAH(REG_PV, REG_PV, mh);
2606 s1 = reg_of_var(iptr->dst, REG_RESULT);
2607 M_INTMOVE(REG_RESULT, s1);
2608 store_reg_to_var_int(iptr->dst, s1);
2612 default: sprintf (logtext, "Unknown pseudo command: %d", iptr->opc);
2615 } /* for instruction */
2616 src = bptr->outstack;
2617 len = bptr->outdepth;
2621 if ((src->varkind != STACKVAR)) {
2623 if (IS_FLT_DBL_TYPE(s2)) {
2624 var_to_reg_int(s1, src, REG_ITMP1);
2625 if (!(interfaces[len][s2].flags & INMEMORY)) {
2626 M_FLTMOVE(s1,interfaces[len][s2].regoff);
2629 M_DST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
2633 var_to_reg_flt(s1, src, REG_FTMP1);
2634 if (!(interfaces[len][s2].flags & INMEMORY)) {
2635 M_INTMOVE(s1,interfaces[len][s2].regoff);
2638 M_LST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
2644 } /* for basic block */
2646 bptr -> mpc = (int)((u1*) mcodeptr - mcodebase);
2649 s4 *xcodeptr = NULL;
2651 for (; xboundrefs != NULL; xboundrefs = xboundrefs->next) {
2652 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
2653 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
2654 xboundrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
2658 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
2659 xboundrefs->branchpos, (u1*) mcodeptr - mcodebase);
2663 M_LDA(REG_ITMP2_XPC, REG_PV, xboundrefs->branchpos);
2665 if (xcodeptr != NULL) {
2666 M_BR((xcodeptr-mcodeptr)-1);
2669 xcodeptr = mcodeptr;
2671 a = dseg_addaddress(proto_java_lang_ArrayIndexOutOfBoundsException);
2672 M_LLD(REG_ITMP1_XPTR, REG_PV, a);
2674 a = dseg_addaddress(asm_handle_exception);
2675 M_LLD(REG_ITMP3, REG_PV, a);
2677 M_JMP(REG_ZERO, REG_ITMP3);
2683 for (; xcheckarefs != NULL; xcheckarefs = xcheckarefs->next) {
2684 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
2685 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
2686 xcheckarefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
2690 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
2691 xcheckarefs->branchpos, (u1*) mcodeptr - mcodebase);
2695 M_LDA(REG_ITMP2_XPC, REG_PV, xcheckarefs->branchpos);
2697 if (xcodeptr != NULL) {
2698 M_BR((xcodeptr-mcodeptr)-1);
2701 xcodeptr = mcodeptr;
2703 a = dseg_addaddress(proto_java_lang_NegativeArraySizeException);
2704 M_LLD(REG_ITMP1_XPTR, REG_PV, a);
2706 a = dseg_addaddress(asm_handle_exception);
2707 M_LLD(REG_ITMP3, REG_PV, a);
2709 M_JMP(REG_ZERO, REG_ITMP3);
2714 #ifdef SOFTNULLPTRCHECK
2718 for (; xnullrefs != NULL; xnullrefs = xnullrefs->next) {
2719 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
2720 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
2721 xnullrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
2725 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
2726 xnullrefs->branchpos, (u1*) mcodeptr - mcodebase);
2730 M_LDA(REG_ITMP2_XPC, REG_PV, xnullrefs->branchpos - 4);
2732 if (xcodeptr != NULL) {
2733 M_BR((xcodeptr-mcodeptr)-1);
2736 xcodeptr = mcodeptr;
2738 a = dseg_addaddress(proto_java_lang_NullPointerException);
2739 M_LLD(REG_ITMP1_XPTR, REG_PV, a);
2741 a = dseg_addaddress(asm_handle_exception);
2742 M_LLD(REG_ITMP3, REG_PV, a);
2744 M_JMP(REG_ZERO, REG_ITMP3);
2751 mcode_finish((int)((u1*) mcodeptr - mcodebase));
2755 /******** redefinition of code generation macros (compiling into array) *******/
2758 These macros are newly defined to allow code generation into an array.
2759 This is necessary, because the original M_.. macros generate code by
2760 calling 'mcode_adds4' that uses an additional data structure to
2763 For a faster (but less flexible) version to generate code, these
2764 macros directly use the (s4* p) - pointer to put the code directly
2765 in a locally defined array.
2766 This makes sense only for the stub-generation-routines below.
2770 #define M_OP3(op,fu,a,b,c,const) \
2771 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<(16-3*(const)))| \
2772 ((const)<<12)|((fu)<<5)|((c)) )
2774 #define M_FOP3(op,fu,a,b,c) \
2775 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<16)|((fu)<<5)|(c) )
2777 #define M_BRA(op,a,disp) \
2778 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((disp)&0x1fffff) )
2780 #define M_MEM(op,a,b,disp) \
2781 *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<16)|((disp)&0xffff) )
2786 /************************ function createcompilerstub **************************
2788 creates a stub routine which calls the compiler
2790 *******************************************************************************/
2792 #define COMPSTUBSIZE 3
2794 u1 *createcompilerstub (methodinfo *m)
2796 u8 *s = CNEW (u8, COMPSTUBSIZE); /* memory to hold the stub */
2797 s4 *p = (s4*) s; /* code generation pointer */
2799 /* code for the stub */
2800 M_LLD (REG_PV, REG_PV, 16); /* load pointer to the compiler */
2801 M_JMP (0, REG_PV); /* jump to the compiler, return address
2802 in reg 0 is used as method pointer */
2803 s[1] = (u8) m; /* literals to be adressed */
2804 s[2] = (u8) asm_call_jit_compiler; /* jump directly via PV from above */
2807 count_cstub_len += COMPSTUBSIZE * 8;
2814 /************************* function removecompilerstub *************************
2816 deletes a compilerstub from memory (simply by freeing it)
2818 *******************************************************************************/
2820 void removecompilerstub (u1 *stub)
2822 CFREE (stub, COMPSTUBSIZE * 8);
2826 /************************ function: removenativestub ***************************
2828 removes a previously created native-stub from memory
2830 *******************************************************************************/
2832 void removenativestub (u1 *stub)
2834 CFREE (stub, NATIVESTUBSIZE * 8);
2840 /********************* Funktion: ncreatenativestub *****************************
2842 creates a stub routine which calls a native method
2844 *******************************************************************************/
2846 #define NATIVESTUBSIZE 11
2848 u1 *ncreatenativestub (functionptr f, methodinfo *m)
2850 u8 *s = CNEW (u8, NATIVESTUBSIZE); /* memory to hold the stub */
2851 s4 *p = (s4*) s; /* code generation pointer */
2853 M_LDA (REG_SP, REG_SP, -8); /* build up stackframe */
2854 M_LST (REG_RA, REG_SP, 0); /* store return address */
2856 M_LLD (REG_PV, REG_PV, 8*8); /* load adress of native method */
2857 M_JSR (REG_RA, REG_PV); /* call native method */
2859 M_LDA (REG_PV, REG_RA, -4*4); /* recompute pv from ra */
2860 M_LLD (REG_ITMP3, REG_PV, 9*8); /* get address of exceptionptr */
2862 M_LLD (REG_RA, REG_SP, 0); /* load return address */
2863 M_LLD (REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
2865 M_LDA (REG_SP, REG_SP, 8); /* remove stackframe */
2866 M_BNEZ (REG_ITMP1, 1); /* if no exception then return */
2868 M_RET (REG_ZERO, REG_RA); /* return to caller */
2870 M_LST (REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
2871 M_LDA (REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
2873 M_LLD (REG_ITMP3, REG_PV,10*8); /* load asm exception handler address */
2874 M_JMP (REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
2877 s[8] = (u8) f; /* address of native method */
2878 s[9] = (u8) (&exceptionptr); /* address of exceptionptr */
2879 s[10]= (u8) (asm_handle_nat_exception); /* addr of asm exception handler */
2882 count_nstub_len += NATIVESTUBSIZE * 8;