cleaned up macros
[cacao.git] / alpha / ngen.c
1 /* alpha/ngen.c ****************************************************************
2
3         Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
4
5         See file COPYRIGHT for information on usage and disclaimer of warranties
6
7         Contains the codegenerator for an Alpha processor.
8         This module generates Alpha machine code for a sequence of
9         pseudo commands (ICMDs).
10
11         Authors: Andreas  Krall      EMAIL: cacao@complang.tuwien.ac.at
12                  Reinhard Grafl      EMAIL: cacao@complang.tuwien.ac.at
13
14         Last Change: 1998/08/10
15
16 *******************************************************************************/
17
18
19
20 /* *****************************************************************************
21
22 Datatypes and Register Allocations:
23 ----------------------------------- 
24
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  operands
27 only need 32 bits. This is done by a canonical representation:
28
29 32-bit integers are allways stored as sign-extended 64-bit values (this
30 approach is directly supported by the Alpha architecture and is very easy
31 to implement).
32
33 32-bit-floats are stored in a 64-bit doubleprecision register by simply
34 expanding the exponent and mantissa with zeroes. (also supported by the
35 architecture)
36
37
38 Stackframes:
39
40 The calling conventions and the layout of the stack is  explained in detail
41 in the documention file: calling.doc
42
43 *******************************************************************************/
44
45
46 /* additional functions and macros to generate code ***************************/
47
48 #define BlockPtrOfPC(pc)        block+block_index[pc]
49
50 #ifdef STATISTICS
51 #define COUNT_SPILLS count_spills++
52 #else
53 #define COUNT_SPILLS
54 #endif
55
56
57 /* gen_nullptr_check(objreg) */
58
59 #ifdef SOFTNULLPTRCHECK
60 #define gen_nullptr_check(objreg) \
61         if (checknull) {\
62         M_BEQZ((objreg), 0);\
63         mcode_addxnullrefs(mcodeptr);\
64         }
65 #else
66 #define gen_nullptr_check(objreg)
67 #endif
68
69
70 /* MCODECHECK(icnt) */
71
72 #define MCODECHECK(icnt) \
73         if((mcodeptr+(icnt))>mcodeend)mcodeptr=mcode_increase((u1*)mcodeptr)
74
75 /* M_INTMOVE:
76      generates an integer-move from register a to b.
77      if a and b are the same int-register, no code will be generated.
78 */ 
79
80 #define M_INTMOVE(a,b) if(a!=b){M_MOV(a,b);}
81
82
83 /* M_FLTMOVE:
84     generates a floating-point-move from register a to b.
85     if a and b are the same float-register, no code will be generated
86 */ 
87
88 #define M_FLTMOVE(a,b) if(a!=b){M_FMOV(a,b);}
89
90
91 /* var_to_reg_xxx:
92     this function generates code to fetch data from a pseudo-register
93     into a real register. 
94     If the pseudo-register has actually been assigned to a real 
95     register, no code will be emitted, since following operations
96     can use this register directly.
97     
98     v: pseudoregister to be fetched from
99     tempregnum: temporary register to be used if v is actually spilled to ram
100
101     return: the register number, where the operand can be found after 
102             fetching (this wil be either tempregnum or the register
103             number allready given to v)
104 */
105
106 #define var_to_reg_int(regnr,v,tempnr) { \
107         if ((v)->flags & INMEMORY) \
108                 {COUNT_SPILLS;M_LLD(tempnr,REG_SP,8*(v)->regoff);regnr=tempnr;} \
109         else regnr=(v)->regoff; \
110 }
111
112
113 #define var_to_reg_flt(regnr,v,tempnr) { \
114         if ((v)->flags & INMEMORY) \
115                 {COUNT_SPILLS;M_DLD(tempnr,REG_SP,8*(v)->regoff);regnr=tempnr;} \
116         else regnr=(v)->regoff; \
117 }
118
119
120 /* reg_of_var:
121     This function determines a register, to which the result of an operation
122     should go, when it is ultimatively intended to store the result in
123     pseudoregister v.
124     If v is assigned to an actual register, this register will be returned.
125     Otherwise (when v is spilled) this function returns tempregnum.
126     If not already done, regoff and flags are set in the stack location.
127 */        
128
129 static int reg_of_var(stackptr v, int tempregnum)
130 {
131         varinfo      *var;
132
133         switch (v->varkind) {
134                 case TEMPVAR:
135                         if (!(v->flags & INMEMORY))
136                                 return(v->regoff);
137                         break;
138                 case STACKVAR:
139                         var = &(interfaces[v->varnum][v->type]);
140                         v->regoff = var->regoff;
141                         if (!(var->flags & INMEMORY))
142                                 return(var->regoff);
143                         break;
144                 case LOCALVAR:
145                         var = &(locals[v->varnum][v->type]);
146                         v->regoff = var->regoff;
147                         if (!(var->flags & INMEMORY))
148                                 return(var->regoff);
149                         break;
150                 case ARGVAR:
151                         v->regoff = v->varnum;
152                         if (IS_FLT_DBL_TYPE(v->type)) {
153                                 if (v->varnum < fltreg_argnum) {
154                                         v->regoff = argfltregs[v->varnum];
155                                         return(argfltregs[v->varnum]);
156                                         }
157                                 }
158                         else
159                                 if (v->varnum < intreg_argnum) {
160                                         v->regoff = argintregs[v->varnum];
161                                         return(argintregs[v->varnum]);
162                                         }
163                         v->regoff -= intreg_argnum;
164                         break;
165                 }
166         v->flags |= INMEMORY;
167         return tempregnum;
168 }
169
170
171 /* store_reg_to_var_xxx:
172     This function generates the code to store the result of an operation
173     back into a spilled pseudo-variable.
174     If the pseudo-variable has not been spilled in the first place, this 
175     function will generate nothing.
176     
177     v ............ Pseudovariable
178     tempregnum ... Number of the temporary registers as returned by
179                    reg_of_var.
180 */      
181
182 #define store_reg_to_var_int(sptr, tempregnum) {       \
183         if ((sptr)->flags & INMEMORY) {                    \
184                 COUNT_SPILLS;                                  \
185                 M_LST(tempregnum, REG_SP, 8 * (sptr)->regoff); \
186                 }                                              \
187         }
188
189 #define store_reg_to_var_flt(sptr, tempregnum) {       \
190         if ((sptr)->flags & INMEMORY) {                    \
191                 COUNT_SPILLS;                                  \
192                 M_DST(tempregnum, REG_SP, 8 * (sptr)->regoff); \
193                 }                                              \
194         }
195
196
197 /* NullPointerException handlers and exception handling initialisation        */
198
199 typedef struct sigctx_struct {
200
201         long          sc_onstack;           /* sigstack state to restore          */
202         long          sc_mask;              /* signal mask to restore             */
203         long          sc_pc;                /* pc at time of signal               */
204         long          sc_ps;                /* psl to retore                      */
205         long          sc_regs[32];          /* processor regs 0 to 31             */
206         long          sc_ownedfp;           /* fp has been used                   */
207         long          sc_fpregs[32];        /* fp regs 0 to 31                    */
208         unsigned long sc_fpcr;              /* floating point control register    */
209         unsigned long sc_fp_control;        /* software fpcr                      */
210                                             /* rest is unused                     */
211         unsigned long sc_reserved1, sc_reserved2;
212         unsigned long sc_ssize;
213         char          *sc_sbase;
214         unsigned long sc_traparg_a0;
215         unsigned long sc_traparg_a1;
216         unsigned long sc_traparg_a2;
217         unsigned long sc_fp_trap_pc;
218         unsigned long sc_fp_trigger_sum;
219         unsigned long sc_fp_trigger_inst;
220         unsigned long sc_retcode[2];
221 } sigctx_struct;
222
223
224 /* asm_signal_exception passes exception pointer and the signal context
225         structure (contains the saved registers) to the assembler handler which
226         restores registers and walks through the Java exception tables.
227 */
228
229 void asm_signal_exception(void *xptr, void *sigctx);
230
231
232 /* NullPointerException signal handler for hardware null pointer check */
233
234 void catch_NullPointerException(int sig, int code, sigctx_struct *sigctx)
235 {
236         sigset_t nsig;
237         int      instr;
238         long     faultaddr;
239
240         /* Reset signal handler - necessary for SysV, does no harm for BSD */
241
242         instr = *((int*)(sigctx->sc_pc));
243         faultaddr = sigctx->sc_regs[(instr >> 16) & 0x1f];
244
245         if (faultaddr == 0) {
246                 signal(sig, (void*) catch_NullPointerException); /* reinstall handler */
247                 sigemptyset(&nsig);
248                 sigaddset(&nsig, sig);
249                 sigprocmask(SIG_UNBLOCK, &nsig, NULL);           /* unblock signal    */
250                 asm_signal_exception(proto_java_lang_NullPointerException, sigctx);
251                 }
252         else {
253                 faultaddr += (long) ((instr << 16) >> 16);
254                 fprintf(stderr, "faulting address: 0x%16lx\n", faultaddr);
255                 panic("Stack overflow");
256                 }
257 }
258
259
260 #ifdef __osf__
261
262 void init_exceptions(void)
263 {
264
265 #else /* Linux */
266
267 /* Linux on Digital Alpha needs an initialisation of the ieee floating point
268         control for IEEE compliant arithmetic (option -mieee of GCC). Under
269         Digital Unix this is done automatically.
270 */
271
272 #include <asm/fpu.h>
273
274 extern unsigned long ieee_get_fp_control();
275 extern void ieee_set_fp_control(unsigned long fp_control);
276
277 void init_exceptions(void)
278 {
279 /* initialize floating point control */
280
281 ieee_set_fp_control(ieee_get_fp_control()
282                     & ~IEEE_TRAP_ENABLE_INV
283                     & ~IEEE_TRAP_ENABLE_DZE
284 /*                  & ~IEEE_TRAP_ENABLE_UNF   we dont want underflow */
285                     & ~IEEE_TRAP_ENABLE_OVF);
286 #endif
287
288         /* install signal handlers we need to convert to exceptions */
289
290         if (!checknull) {
291
292 #if defined(SIGSEGV)
293                 signal(SIGSEGV, (void*) catch_NullPointerException);
294 #endif
295
296 #if defined(SIGBUS)
297                 signal(SIGBUS, (void*) catch_NullPointerException);
298 #endif
299                 }
300 }
301
302
303 /* function gen_mcode **********************************************************
304
305         generates machine code
306
307 *******************************************************************************/
308
309 #define         MethodPointer   -8
310 #define         FrameSize       -12
311 #define     IsSync          -16
312 #define     IsLeaf          -20
313 #define     IntSave         -24
314 #define     FltSave         -28
315 #define     ExTableSize     -32
316 #define     ExTableStart    -32
317
318 #define     ExEntrySize     -32
319 #define     ExStartPC       -8
320 #define     ExEndPC         -16
321 #define     ExHandlerPC     -24
322 #define     ExCatchType     -32
323
324 static void gen_mcode()
325 {
326         int  len, s1, s2, s3, d, bbs;
327         s4   a;
328         s4          *mcodeptr;
329         stackptr    src;
330         varinfo     *var;
331         basicblock  *bptr;
332         instruction *iptr;
333
334         {
335         int p, pa, t, l, r;
336
337         savedregs_num = (isleafmethod) ? 0 : 1;           /* space to save the RA */
338
339         /* space to save used callee saved registers */
340
341         savedregs_num += (savintregcnt - maxsavintreguse);
342         savedregs_num += (savfltregcnt - maxsavfltreguse);
343
344         parentargs_base = maxmemuse + savedregs_num;
345
346 #ifdef USE_THREADS                 /* space to save argument of monitor_enter */
347
348         if (checksync && (method->flags & ACC_SYNCHRONIZED))
349                 parentargs_base++;
350
351 #endif
352
353         /* create method header */
354
355         (void) dseg_addaddress(method);                         /* MethodPointer  */
356         (void) dseg_adds4(parentargs_base * 8);                 /* FrameSize      */
357
358 #ifdef USE_THREADS
359
360         /* IsSync contains the offset relative to the stack pointer for the
361            argument of monitor_exit used in the exception handler. Since the
362            offset could be zero and give a wrong meaning of the flag it is
363            offset by one.
364         */
365
366         if (checksync && (method->flags & ACC_SYNCHRONIZED))
367                 (void) dseg_adds4((maxmemuse + 1) * 8);             /* IsSync         */
368         else
369
370 #endif
371
372         (void) dseg_adds4(0);                                   /* IsSync         */
373                                                
374         (void) dseg_adds4(isleafmethod);                        /* IsLeaf         */
375         (void) dseg_adds4(savintregcnt - maxsavintreguse);      /* IntSave        */
376         (void) dseg_adds4(savfltregcnt - maxsavfltreguse);      /* FltSave        */
377         (void) dseg_adds4(exceptiontablelength);                /* ExTableSize    */
378
379         /* create exception table */
380         
381         for (len = 0; len < exceptiontablelength; len++) {
382                 dseg_addtarget(BlockPtrOfPC(extable[len].startpc));
383                 dseg_addtarget(BlockPtrOfPC(extable[len].endpc));
384                 dseg_addtarget(BlockPtrOfPC(extable[len].handlerpc));
385                 (void) dseg_addaddress(extable[len].catchtype);
386                 }
387
388         /* initialize mcode variables */
389         
390         mcodeptr = (s4*) mcodebase;
391         mcodeend = (s4*) (mcodebase + mcodesize);
392         MCODECHECK(128 + mparamcount);
393
394         /* create stack frame (if necessary) */
395
396         if (parentargs_base)
397                 {M_LDA (REG_SP, REG_SP, -parentargs_base * 8);}
398
399         /* save return address and used callee saved registers */
400
401         p = parentargs_base;
402         if (!isleafmethod)
403                 {p--;  M_AST (REG_RA, REG_SP, 8*p);}
404         for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
405                 {p--; M_LST (savintregs[r], REG_SP, 8 * p);}
406         for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
407                 {p--; M_DST (savfltregs[r], REG_SP, 8 * p);}
408
409         /* save monitorenter argument */
410
411 #ifdef USE_THREADS
412         if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
413                 if (method->flags & ACC_STATIC) {
414                         p = dseg_addaddress (class);
415                         M_ALD(REG_ITMP1, REG_PV, p);
416                         M_AST(REG_ITMP1, REG_SP, 8 * maxmemuse);
417                         } 
418                 else {
419                         M_AST (argintregs[0], REG_SP, 8 * maxmemuse);
420                         }
421                 }                       
422 #endif
423
424         /* copy argument registers to stack and call trace function with pointer
425            to arguments on stack. ToDo: save floating point registers !!!!!!!!!
426         */
427
428         if (runverbose && isleafmethod) {
429                 M_LDA (REG_SP, REG_SP, -(14*8));
430                 M_AST(REG_RA, REG_SP, 1*8);
431
432                 M_LST(argintregs[0], REG_SP,  2*8);
433                 M_LST(argintregs[1], REG_SP,  3*8);
434                 M_LST(argintregs[2], REG_SP,  4*8);
435                 M_LST(argintregs[3], REG_SP,  5*8);
436                 M_LST(argintregs[4], REG_SP,  6*8);
437                 M_LST(argintregs[5], REG_SP,  7*8);
438
439                 M_DST(argfltregs[0], REG_SP,  8*8);
440                 M_DST(argfltregs[1], REG_SP,  9*8);
441                 M_DST(argfltregs[2], REG_SP, 10*8);
442                 M_DST(argfltregs[3], REG_SP, 11*8);
443                 M_DST(argfltregs[4], REG_SP, 12*8);
444                 M_DST(argfltregs[5], REG_SP, 13*8);
445
446                 p = dseg_addaddress (method);
447                 M_ALD(REG_ITMP1, REG_PV, p);
448                 M_AST(REG_ITMP1, REG_SP, 0);
449                 p = dseg_addaddress ((void*) (builtin_trace_args));
450                 M_ALD(REG_PV, REG_PV, p);
451                 M_JSR(REG_RA, REG_PV);
452                 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
453                 M_ALD(REG_RA, REG_SP, 1*8);
454
455                 M_LLD(argintregs[0], REG_SP,  2*8);
456                 M_LLD(argintregs[1], REG_SP,  3*8);
457                 M_LLD(argintregs[2], REG_SP,  4*8);
458                 M_LLD(argintregs[3], REG_SP,  5*8);
459                 M_LLD(argintregs[4], REG_SP,  6*8);
460                 M_LLD(argintregs[5], REG_SP,  7*8);
461
462                 M_DLD(argfltregs[0], REG_SP,  8*8);
463                 M_DLD(argfltregs[1], REG_SP,  9*8);
464                 M_DLD(argfltregs[2], REG_SP, 10*8);
465                 M_DLD(argfltregs[3], REG_SP, 11*8);
466                 M_DLD(argfltregs[4], REG_SP, 12*8);
467                 M_DLD(argfltregs[5], REG_SP, 13*8);
468
469                 M_LDA (REG_SP, REG_SP, 14*8);
470                 }
471
472         /* take arguments out of register or stack frame */
473
474         for (p = 0, l = 0; p < mparamcount; p++) {
475                 t = mparamtypes[p];
476                 var = &(locals[l][t]);
477                 l++;
478                 if (IS_2_WORD_TYPE(t))    /* increment local counter for 2 word types */
479                         l++;
480                 if (var->type < 0)
481                         continue;
482                 r = var->regoff; 
483                 if (IS_INT_LNG_TYPE(t)) {                    /* integer args          */
484                         if (p < INT_ARG_CNT) {                   /* register arguments    */
485                                 if (!(var->flags & INMEMORY))        /* reg arg -> register   */
486                                         {M_INTMOVE (argintregs[p], r);}
487                                 else                                 /* reg arg -> spilled    */
488                                         M_LST (argintregs[p], REG_SP, 8 * r);
489                                 }
490                         else {                                   /* stack arguments       */
491                                 pa = p - INT_ARG_CNT;
492                                 if (!(var->flags & INMEMORY))        /* stack arg -> register */ 
493                                         M_LLD (r, REG_SP, 8 * (parentargs_base + pa));
494                                 else {                               /* stack arg -> spilled  */
495                                         M_LLD (REG_ITMP1, REG_SP, 8 * (parentargs_base + pa));
496                                         M_LST (REG_ITMP1, REG_SP, 8 * r);
497                                         }
498                                 }
499                         }
500                 else {                                       /* floating args         */   
501                         if (p < FLT_ARG_CNT) {                   /* register arguments    */
502                                 if (!(var->flags & INMEMORY))        /* reg arg -> register   */
503                                         {M_FLTMOVE (argfltregs[p], r);}
504                                 else                                             /* reg arg -> spilled    */
505                                         M_DST (argfltregs[p], REG_SP, 8 * r);
506                                 }
507                         else {                                   /* stack arguments       */
508                                 pa = p - FLT_ARG_CNT;
509                                 if (!(var->flags & INMEMORY))        /* stack-arg -> register */
510                                         M_DLD (r, REG_SP, 8 * (parentargs_base + pa) );
511                                 else {                               /* stack-arg -> spilled  */
512                                         M_DLD (REG_FTMP1, REG_SP, 8 * (parentargs_base + pa));
513                                         M_DST (REG_FTMP1, REG_SP, 8 * r);
514                                         }
515                                 }
516                         }
517                 }  /* end for */
518
519         /* call trace function */
520
521         if (runverbose && !isleafmethod) {
522                 M_LDA (REG_SP, REG_SP, -8);
523                 p = dseg_addaddress (method);
524                 M_ALD(REG_ITMP1, REG_PV, p);
525                 M_AST(REG_ITMP1, REG_SP, 0);
526                 p = dseg_addaddress ((void*) (builtin_trace_args));
527                 M_ALD(REG_PV, REG_PV, p);
528                 M_JSR(REG_RA, REG_PV);
529                 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
530                 M_LDA(REG_SP, REG_SP, 8);
531                 }
532
533         /* call monitorenter function */
534
535 #ifdef USE_THREADS
536         if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
537                 p = dseg_addaddress ((void*) (builtin_monitorenter));
538                 M_ALD(REG_PV, REG_PV, p);
539                 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
540                 M_JSR(REG_RA, REG_PV);
541                 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
542                 }                       
543 #endif
544         }
545
546         /* end of header generation */
547
548         /* walk through all basic blocks */
549
550         for (bbs = block_count, bptr = block; --bbs >= 0; bptr++) {
551                 bptr -> mpc = (int)((u1*) mcodeptr - mcodebase);
552
553                 if (bptr->flags >= BBREACHED) {
554
555                 /* branch resolving */
556
557                 {
558                 branchref *brefs;
559                 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
560                         gen_resolvebranch((u1*) mcodebase + brefs->branchpos, 
561                                           brefs->branchpos, bptr->mpc);
562                         }
563                 }
564
565                 /* copy interface registers to their destination */
566
567                 src = bptr->instack;
568                 len = bptr->indepth;
569                 MCODECHECK(64+len);
570                 while (src != NULL) {
571                         len--;
572                         if ((len == 0) && (bptr->type != BBTYPE_STD)) {
573                                 d = reg_of_var(src, REG_ITMP1);
574                                 M_INTMOVE(REG_ITMP1, d);
575                                 store_reg_to_var_int(src, d);
576                                 }
577                         else {
578                                 d = reg_of_var(src, REG_IFTMP);
579                                 if ((src->varkind != STACKVAR)) {
580                                         s2 = src->type;
581                                         if (IS_FLT_DBL_TYPE(s2)) {
582                                                 if (!(interfaces[len][s2].flags & INMEMORY)) {
583                                                         s1 = interfaces[len][s2].regoff;
584                                                         M_FLTMOVE(s1,d);
585                                                         }
586                                                 else {
587                                                         M_DLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
588                                                         }
589                                                 store_reg_to_var_flt(src, d);
590                                                 }
591                                         else {
592                                                 if (!(interfaces[len][s2].flags & INMEMORY)) {
593                                                         s1 = interfaces[len][s2].regoff;
594                                                         M_INTMOVE(s1,d);
595                                                         }
596                                                 else {
597                                                         M_LLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
598                                                         }
599                                                 store_reg_to_var_int(src, d);
600                                                 }
601                                         }
602                                 }
603                         src = src->prev;
604                         }
605
606                 /* walk through all instructions */
607
608                 src = bptr->instack;
609                 len = bptr->icount;
610                 for (iptr = bptr->iinstr;
611                     len > 0;
612                     src = iptr->dst, len--, iptr++) {
613
614         MCODECHECK(64);           /* an instruction usually needs < 64 words      */
615         switch (iptr->opc) {
616
617                 case ICMD_NOP:        /* ...  ==> ...                                 */
618                         break;
619
620                 case ICMD_NULLCHECKPOP: /* ..., objectref  ==> ...                    */
621
622                         var_to_reg_int(s1, src, REG_ITMP1);
623                         M_BEQZ(s1, 0);
624                         mcode_addxnullrefs(mcodeptr);
625                         break;
626
627                 /* constant operations ************************************************/
628
629 #define ICONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
630                     else{a=dseg_adds4(c);M_ILD(r,REG_PV,a);}
631
632 #define LCONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
633                     else{a=dseg_adds8(c);M_LLD(r,REG_PV,a);}
634
635                 case ICMD_ICONST:     /* ...  ==> ..., constant                       */
636                                       /* op1 = 0, val.i = constant                    */
637
638                         d = reg_of_var(iptr->dst, REG_ITMP1);
639                         ICONST(d, iptr->val.i);
640                         store_reg_to_var_int(iptr->dst, d);
641                         break;
642
643                 case ICMD_LCONST:     /* ...  ==> ..., constant                       */
644                                       /* op1 = 0, val.l = constant                    */
645
646                         d = reg_of_var(iptr->dst, REG_ITMP1);
647                         LCONST(d, iptr->val.l);
648                         store_reg_to_var_int(iptr->dst, d);
649                         break;
650
651                 case ICMD_FCONST:     /* ...  ==> ..., constant                       */
652                                       /* op1 = 0, val.f = constant                    */
653
654                         d = reg_of_var (iptr->dst, REG_FTMP1);
655                         a = dseg_addfloat (iptr->val.f);
656                         M_FLD(d, REG_PV, a);
657                         store_reg_to_var_flt (iptr->dst, d);
658                         break;
659                         
660                 case ICMD_DCONST:     /* ...  ==> ..., constant                       */
661                                       /* op1 = 0, val.d = constant                    */
662
663                         d = reg_of_var (iptr->dst, REG_FTMP1);
664                         a = dseg_adddouble (iptr->val.d);
665                         M_DLD(d, REG_PV, a);
666                         store_reg_to_var_flt (iptr->dst, d);
667                         break;
668
669                 case ICMD_ACONST:     /* ...  ==> ..., constant                       */
670                                       /* op1 = 0, val.a = constant                    */
671
672                         d = reg_of_var(iptr->dst, REG_ITMP1);
673                         if (iptr->val.a) {
674                                 a = dseg_addaddress (iptr->val.a);
675                                 M_ALD(d, REG_PV, a);
676                                 }
677                         else {
678                                 M_INTMOVE(REG_ZERO, d);
679                                 }
680                         store_reg_to_var_int(iptr->dst, d);
681                         break;
682
683
684                 /* load/store operations **********************************************/
685
686                 case ICMD_ILOAD:      /* ...  ==> ..., content of local variable      */
687                 case ICMD_LLOAD:      /* op1 = local variable                         */
688                 case ICMD_ALOAD:
689
690                         d = reg_of_var(iptr->dst, REG_ITMP1);
691                         if ((iptr->dst->varkind == LOCALVAR) &&
692                             (iptr->dst->varnum == iptr->op1))
693                                 break;
694                         var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
695                         if (var->flags & INMEMORY)
696                                 M_LLD(d, REG_SP, 8 * var->regoff);
697                         else
698                                 {M_INTMOVE(var->regoff,d);}
699                         store_reg_to_var_int(iptr->dst, d);
700                         break;
701
702                 case ICMD_FLOAD:      /* ...  ==> ..., content of local variable      */
703                 case ICMD_DLOAD:      /* op1 = local variable                         */
704
705                         d = reg_of_var(iptr->dst, REG_FTMP1);
706                         if ((iptr->dst->varkind == LOCALVAR) &&
707                             (iptr->dst->varnum == iptr->op1))
708                                 break;
709                         var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
710                         if (var->flags & INMEMORY)
711                                 M_DLD(d, REG_SP, 8 * var->regoff);
712                         else
713                                 {M_FLTMOVE(var->regoff,d);}
714                         store_reg_to_var_flt(iptr->dst, d);
715                         break;
716
717
718                 case ICMD_ISTORE:     /* ..., value  ==> ...                          */
719                 case ICMD_LSTORE:     /* op1 = local variable                         */
720                 case ICMD_ASTORE:
721
722                         if ((src->varkind == LOCALVAR) &&
723                             (src->varnum == iptr->op1))
724                                 break;
725                         var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
726                         if (var->flags & INMEMORY) {
727                                 var_to_reg_int(s1, src, REG_ITMP1);
728                                 M_LST(s1, REG_SP, 8 * var->regoff);
729                                 }
730                         else {
731                                 var_to_reg_int(s1, src, var->regoff);
732                                 M_INTMOVE(s1, var->regoff);
733                                 }
734                         break;
735
736                 case ICMD_FSTORE:     /* ..., value  ==> ...                          */
737                 case ICMD_DSTORE:     /* op1 = local variable                         */
738
739                         if ((src->varkind == LOCALVAR) &&
740                             (src->varnum == iptr->op1))
741                                 break;
742                         var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
743                         if (var->flags & INMEMORY) {
744                                 var_to_reg_flt(s1, src, REG_FTMP1);
745                                 M_DST(s1, REG_SP, 8 * var->regoff);
746                                 }
747                         else {
748                                 var_to_reg_flt(s1, src, var->regoff);
749                                 M_FLTMOVE(s1, var->regoff);
750                                 }
751                         break;
752
753
754                 /* pop/dup/swap operations ********************************************/
755
756                 /* attention: double and longs are only one entry in CACAO ICMDs      */
757
758                 case ICMD_POP:        /* ..., value  ==> ...                          */
759                 case ICMD_POP2:       /* ..., value, value  ==> ...                   */
760                         break;
761
762 #define M_COPY(from,to) \
763                         d = reg_of_var(to, REG_IFTMP); \
764                         if ((from->regoff != to->regoff) || \
765                             ((from->flags ^ to->flags) & INMEMORY)) { \
766                                 if (IS_FLT_DBL_TYPE(from->type)) { \
767                                         var_to_reg_flt(s1, from, d); \
768                                         M_FLTMOVE(s1,d); \
769                                         store_reg_to_var_flt(to, d); \
770                                         }\
771                                 else { \
772                                         var_to_reg_int(s1, from, d); \
773                                         M_INTMOVE(s1,d); \
774                                         store_reg_to_var_int(to, d); \
775                                         }\
776                                 }
777
778                 case ICMD_DUP:        /* ..., a ==> ..., a, a                         */
779                         M_COPY(src, iptr->dst);
780                         break;
781
782                 case ICMD_DUP_X1:     /* ..., a, b ==> ..., b, a, b                   */
783
784                         M_COPY(src,       iptr->dst->prev->prev);
785
786                 case ICMD_DUP2:       /* ..., a, b ==> ..., a, b, a, b                */
787
788                         M_COPY(src,       iptr->dst);
789                         M_COPY(src->prev, iptr->dst->prev);
790                         break;
791
792                 case ICMD_DUP2_X1:    /* ..., a, b, c ==> ..., b, c, a, b, c          */
793
794                         M_COPY(src->prev,       iptr->dst->prev->prev->prev);
795
796                 case ICMD_DUP_X2:     /* ..., a, b, c ==> ..., c, a, b, c             */
797
798                         M_COPY(src,             iptr->dst);
799                         M_COPY(src->prev,       iptr->dst->prev);
800                         M_COPY(src->prev->prev, iptr->dst->prev->prev);
801                         M_COPY(src, iptr->dst->prev->prev->prev);
802                         break;
803
804                 case ICMD_DUP2_X2:    /* ..., a, b, c, d ==> ..., c, d, a, b, c, d    */
805
806                         M_COPY(src,                   iptr->dst);
807                         M_COPY(src->prev,             iptr->dst->prev);
808                         M_COPY(src->prev->prev,       iptr->dst->prev->prev);
809                         M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
810                         M_COPY(src,       iptr->dst->prev->prev->prev->prev);
811                         M_COPY(src->prev, iptr->dst->prev->prev->prev->prev->prev);
812                         break;
813
814                 case ICMD_SWAP:       /* ..., a, b ==> ..., b, a                      */
815
816                         M_COPY(src, iptr->dst->prev);
817                         M_COPY(src->prev, iptr->dst);
818                         break;
819
820
821                 /* integer operations *************************************************/
822
823                 case ICMD_INEG:       /* ..., value  ==> ..., - value                 */
824
825                         var_to_reg_int(s1, src, REG_ITMP1); 
826                         d = reg_of_var(iptr->dst, REG_ITMP3);
827                         M_ISUB(REG_ZERO, s1, d);
828                         store_reg_to_var_int(iptr->dst, d);
829                         break;
830
831                 case ICMD_LNEG:       /* ..., value  ==> ..., - value                 */
832
833                         var_to_reg_int(s1, src, REG_ITMP1);
834                         d = reg_of_var(iptr->dst, REG_ITMP3);
835                         M_LSUB(REG_ZERO, s1, d);
836                         store_reg_to_var_int(iptr->dst, d);
837                         break;
838
839                 case ICMD_I2L:        /* ..., value  ==> ..., value                   */
840
841                         var_to_reg_int(s1, src, REG_ITMP1);
842                         d = reg_of_var(iptr->dst, REG_ITMP3);
843                         M_INTMOVE(s1, d);
844                         store_reg_to_var_int(iptr->dst, d);
845                         break;
846
847                 case ICMD_L2I:        /* ..., value  ==> ..., value                   */
848
849                         var_to_reg_int(s1, src, REG_ITMP1);
850                         d = reg_of_var(iptr->dst, REG_ITMP3);
851                         M_IADD(s1, REG_ZERO, d );
852                         store_reg_to_var_int(iptr->dst, d);
853                         break;
854
855                 case ICMD_INT2BYTE:   /* ..., value  ==> ..., value                   */
856
857                         var_to_reg_int(s1, src, REG_ITMP1);
858                         d = reg_of_var(iptr->dst, REG_ITMP3);
859                         if (has_ext_instr_set) {
860                                 M_BSEXT(s1, d);
861                                 }
862                         else {
863                                 M_SLL_IMM(s1, 56, d);
864                                 M_SRA_IMM( d, 56, d);
865                                 }
866                         store_reg_to_var_int(iptr->dst, d);
867                         break;
868
869                 case ICMD_INT2CHAR:   /* ..., value  ==> ..., value                   */
870
871                         var_to_reg_int(s1, src, REG_ITMP1);
872                         d = reg_of_var(iptr->dst, REG_ITMP3);
873             M_CZEXT(s1, d);
874                         store_reg_to_var_int(iptr->dst, d);
875                         break;
876
877                 case ICMD_INT2SHORT:  /* ..., value  ==> ..., value                   */
878
879                         var_to_reg_int(s1, src, REG_ITMP1);
880                         d = reg_of_var(iptr->dst, REG_ITMP3);
881                         if (has_ext_instr_set) {
882                                 M_SSEXT(s1, d);
883                                 }
884                         else {
885                                 M_SLL_IMM(s1, 48, d);
886                                 M_SRA_IMM( d, 48, d);
887                                 }
888                         store_reg_to_var_int(iptr->dst, d);
889                         break;
890
891
892                 case ICMD_IADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
893
894                         var_to_reg_int(s1, src->prev, REG_ITMP1);
895                         var_to_reg_int(s2, src, REG_ITMP2);
896                         d = reg_of_var(iptr->dst, REG_ITMP3);
897                         M_IADD(s1, s2, d);
898                         store_reg_to_var_int(iptr->dst, d);
899                         break;
900
901                 case ICMD_IADDCONST:  /* ..., value  ==> ..., value + constant        */
902                                       /* val.i = constant                             */
903
904                         var_to_reg_int(s1, src, REG_ITMP1);
905                         d = reg_of_var(iptr->dst, REG_ITMP3);
906                         if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
907                                 M_IADD_IMM(s1, iptr->val.i, d);
908                                 }
909                         else {
910                                 ICONST(REG_ITMP2, iptr->val.i);
911                                 M_IADD(s1, REG_ITMP2, d);
912                                 }
913                         store_reg_to_var_int(iptr->dst, d);
914                         break;
915
916                 case ICMD_LADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
917
918                         var_to_reg_int(s1, src->prev, REG_ITMP1);
919                         var_to_reg_int(s2, src, REG_ITMP2);
920                         d = reg_of_var(iptr->dst, REG_ITMP3);
921                         M_LADD(s1, s2, d);
922                         store_reg_to_var_int(iptr->dst, d);
923                         break;
924
925                 case ICMD_LADDCONST:  /* ..., value  ==> ..., value + constant        */
926                                       /* val.l = constant                             */
927
928                         var_to_reg_int(s1, src, REG_ITMP1);
929                         d = reg_of_var(iptr->dst, REG_ITMP3);
930                         if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
931                                 M_LADD_IMM(s1, iptr->val.l, d);
932                                 }
933                         else {
934                                 LCONST(REG_ITMP2, iptr->val.l);
935                                 M_LADD(s1, REG_ITMP2, d);
936                                 }
937                         store_reg_to_var_int(iptr->dst, d);
938                         break;
939
940                 case ICMD_ISUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
941
942                         var_to_reg_int(s1, src->prev, REG_ITMP1);
943                         var_to_reg_int(s2, src, REG_ITMP2);
944                         d = reg_of_var(iptr->dst, REG_ITMP3);
945                         M_ISUB(s1, s2, d);
946                         store_reg_to_var_int(iptr->dst, d);
947                         break;
948
949                 case ICMD_ISUBCONST:  /* ..., value  ==> ..., value + constant        */
950                                       /* val.i = constant                             */
951
952                         var_to_reg_int(s1, src, REG_ITMP1);
953                         d = reg_of_var(iptr->dst, REG_ITMP3);
954                         if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
955                                 M_ISUB_IMM(s1, iptr->val.i, d);
956                                 }
957                         else {
958                                 ICONST(REG_ITMP2, iptr->val.i);
959                                 M_ISUB(s1, REG_ITMP2, d);
960                                 }
961                         store_reg_to_var_int(iptr->dst, d);
962                         break;
963
964                 case ICMD_LSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
965
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);
969                         M_LSUB(s1, s2, d);
970                         store_reg_to_var_int(iptr->dst, d);
971                         break;
972
973                 case ICMD_LSUBCONST:  /* ..., value  ==> ..., value - constant        */
974                                       /* val.l = constant                             */
975
976                         var_to_reg_int(s1, src, REG_ITMP1);
977                         d = reg_of_var(iptr->dst, REG_ITMP3);
978                         if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
979                                 M_LSUB_IMM(s1, iptr->val.l, d);
980                                 }
981                         else {
982                                 LCONST(REG_ITMP2, iptr->val.l);
983                                 M_LSUB(s1, REG_ITMP2, d);
984                                 }
985                         store_reg_to_var_int(iptr->dst, d);
986                         break;
987
988                 case ICMD_IMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
989
990                         var_to_reg_int(s1, src->prev, REG_ITMP1);
991                         var_to_reg_int(s2, src, REG_ITMP2);
992                         d = reg_of_var(iptr->dst, REG_ITMP3);
993                         M_IMUL(s1, s2, d);
994                         store_reg_to_var_int(iptr->dst, d);
995                         break;
996
997                 case ICMD_IMULCONST:  /* ..., value  ==> ..., value * constant        */
998                                       /* val.i = constant                             */
999
1000                         var_to_reg_int(s1, src, REG_ITMP1);
1001                         d = reg_of_var(iptr->dst, REG_ITMP3);
1002                         if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1003                                 M_IMUL_IMM(s1, iptr->val.i, d);
1004                                 }
1005                         else {
1006                                 ICONST(REG_ITMP2, iptr->val.i);
1007                                 M_IMUL(s1, REG_ITMP2, d);
1008                                 }
1009                         store_reg_to_var_int(iptr->dst, d);
1010                         break;
1011
1012                 case ICMD_LMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
1013
1014                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1015                         var_to_reg_int(s2, src, REG_ITMP2);
1016                         d = reg_of_var(iptr->dst, REG_ITMP3);
1017                         M_LMUL (s1, s2, d);
1018                         store_reg_to_var_int(iptr->dst, d);
1019                         break;
1020
1021                 case ICMD_LMULCONST:  /* ..., value  ==> ..., value * constant        */
1022                                       /* val.l = constant                             */
1023
1024                         var_to_reg_int(s1, src, REG_ITMP1);
1025                         d = reg_of_var(iptr->dst, REG_ITMP3);
1026                         if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1027                                 M_LMUL_IMM(s1, iptr->val.l, d);
1028                                 }
1029                         else {
1030                                 LCONST(REG_ITMP2, iptr->val.l);
1031                                 M_LMUL(s1, REG_ITMP2, d);
1032                                 }
1033                         store_reg_to_var_int(iptr->dst, d);
1034                         break;
1035
1036                 case ICMD_IDIVPOW2:   /* ..., value  ==> ..., value << constant       */
1037                 case ICMD_LDIVPOW2:   /* val.i = constant                             */
1038                                       
1039                         var_to_reg_int(s1, src, REG_ITMP1);
1040                         d = reg_of_var(iptr->dst, REG_ITMP3);
1041                         if (iptr->val.i <= 15) {
1042                                 M_LDA(REG_ITMP2, s1, (1 << iptr->val.i) -1);
1043                                 M_CMOVGE(s1, s1, REG_ITMP2);
1044                                 }
1045                         else {
1046                                 M_SRA_IMM(s1, 63, REG_ITMP2);
1047                                 M_SRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
1048                                 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1049                                 }
1050                         M_SRA_IMM(REG_ITMP2, iptr->val.i, d);
1051                         store_reg_to_var_int(iptr->dst, d);
1052                         break;
1053
1054                 case ICMD_ISHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
1055
1056                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1057                         var_to_reg_int(s2, src, REG_ITMP2);
1058                         d = reg_of_var(iptr->dst, REG_ITMP3);
1059                         M_AND_IMM(s2, 0x1f, REG_ITMP3);
1060                         M_SLL(s1, REG_ITMP3, d);
1061                         M_IADD(d, REG_ZERO, d);
1062                         store_reg_to_var_int(iptr->dst, d);
1063                         break;
1064
1065                 case ICMD_ISHLCONST:  /* ..., value  ==> ..., value << constant       */
1066                                       /* val.i = constant                             */
1067
1068                         var_to_reg_int(s1, src, REG_ITMP1);
1069                         d = reg_of_var(iptr->dst, REG_ITMP3);
1070                         M_SLL_IMM(s1, iptr->val.i & 0x1f, d);
1071                         M_IADD(d, REG_ZERO, d);
1072                         store_reg_to_var_int(iptr->dst, d);
1073                         break;
1074
1075                 case ICMD_ISHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
1076
1077                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1078                         var_to_reg_int(s2, src, REG_ITMP2);
1079                         d = reg_of_var(iptr->dst, REG_ITMP3);
1080                         M_AND_IMM(s2, 0x1f, REG_ITMP3);
1081                         M_SRA(s1, REG_ITMP3, d);
1082                         store_reg_to_var_int(iptr->dst, d);
1083                         break;
1084
1085                 case ICMD_ISHRCONST:  /* ..., value  ==> ..., value >> constant       */
1086                                       /* val.i = constant                             */
1087
1088                         var_to_reg_int(s1, src, REG_ITMP1);
1089                         d = reg_of_var(iptr->dst, REG_ITMP3);
1090                         M_SRA_IMM(s1, iptr->val.i & 0x1f, d);
1091                         store_reg_to_var_int(iptr->dst, d);
1092                         break;
1093
1094                 case ICMD_IUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
1095
1096                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1097                         var_to_reg_int(s2, src, REG_ITMP2);
1098                         d = reg_of_var(iptr->dst, REG_ITMP3);
1099                         M_AND_IMM(s2, 0x1f, REG_ITMP2);
1100             M_IZEXT(s1, d);
1101                         M_SRL(d, REG_ITMP2, d);
1102                         M_IADD(d, REG_ZERO, d);
1103                         store_reg_to_var_int(iptr->dst, d);
1104                         break;
1105
1106                 case ICMD_IUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
1107                                       /* val.i = constant                             */
1108
1109                         var_to_reg_int(s1, src, REG_ITMP1);
1110                         d = reg_of_var(iptr->dst, REG_ITMP3);
1111             M_IZEXT(s1, d);
1112                         M_SRL_IMM(d, iptr->val.i & 0x1f, d);
1113                         M_IADD(d, REG_ZERO, d);
1114                         store_reg_to_var_int(iptr->dst, d);
1115                         break;
1116
1117                 case ICMD_LSHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
1118
1119                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1120                         var_to_reg_int(s2, src, REG_ITMP2);
1121                         d = reg_of_var(iptr->dst, REG_ITMP3);
1122                         M_SLL(s1, s2, d);
1123                         store_reg_to_var_int(iptr->dst, d);
1124                         break;
1125
1126                 case ICMD_LSHLCONST:  /* ..., value  ==> ..., value << constant       */
1127                                       /* val.l = constant                             */
1128
1129                         var_to_reg_int(s1, src, REG_ITMP1);
1130                         d = reg_of_var(iptr->dst, REG_ITMP3);
1131                         M_SLL_IMM(s1, iptr->val.l & 0x3f, d);
1132                         store_reg_to_var_int(iptr->dst, d);
1133                         break;
1134
1135                 case ICMD_LSHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
1136
1137                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1138                         var_to_reg_int(s2, src, REG_ITMP2);
1139                         d = reg_of_var(iptr->dst, REG_ITMP3);
1140                         M_SRA(s1, s2, d);
1141                         store_reg_to_var_int(iptr->dst, d);
1142                         break;
1143
1144                 case ICMD_LSHRCONST:  /* ..., value  ==> ..., value >> constant       */
1145                                       /* val.l = constant                             */
1146
1147                         var_to_reg_int(s1, src, REG_ITMP1);
1148                         d = reg_of_var(iptr->dst, REG_ITMP3);
1149                         M_SRA_IMM(s1, iptr->val.l & 0x3f, d);
1150                         store_reg_to_var_int(iptr->dst, d);
1151                         break;
1152
1153                 case ICMD_LUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
1154
1155                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1156                         var_to_reg_int(s2, src, REG_ITMP2);
1157                         d = reg_of_var(iptr->dst, REG_ITMP3);
1158                         M_SRL(s1, s2, d);
1159                         store_reg_to_var_int(iptr->dst, d);
1160                         break;
1161
1162                 case ICMD_LUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
1163                                       /* val.l = constant                             */
1164
1165                         var_to_reg_int(s1, src, REG_ITMP1);
1166                         d = reg_of_var(iptr->dst, REG_ITMP3);
1167                         M_SRL_IMM(s1, iptr->val.l & 0x3f, d);
1168                         store_reg_to_var_int(iptr->dst, d);
1169                         break;
1170
1171                 case ICMD_IAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
1172                 case ICMD_LAND:
1173
1174                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1175                         var_to_reg_int(s2, src, REG_ITMP2);
1176                         d = reg_of_var(iptr->dst, REG_ITMP3);
1177                         M_AND(s1, s2, d);
1178                         store_reg_to_var_int(iptr->dst, d);
1179                         break;
1180
1181                 case ICMD_IANDCONST:  /* ..., value  ==> ..., value & constant        */
1182                                       /* val.i = constant                             */
1183
1184                         var_to_reg_int(s1, src, REG_ITMP1);
1185                         d = reg_of_var(iptr->dst, REG_ITMP3);
1186                         if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1187                                 M_AND_IMM(s1, iptr->val.i, d);
1188                                 }
1189                         else if (iptr->val.i == 0xffff) {
1190                                 M_CZEXT(s1, d);
1191                                 }
1192                         else if (iptr->val.i == 0xffffff) {
1193                                 M_ZAPNOT_IMM(s1, 0x07, d);
1194                                 }
1195                         else {
1196                                 ICONST(REG_ITMP2, iptr->val.i);
1197                                 M_AND(s1, REG_ITMP2, d);
1198                                 }
1199                         store_reg_to_var_int(iptr->dst, d);
1200                         break;
1201
1202                 case ICMD_IREMPOW2:   /* ..., value  ==> ..., value % constant        */
1203                                       /* val.i = constant                             */
1204
1205                         var_to_reg_int(s1, src, REG_ITMP1);
1206                         d = reg_of_var(iptr->dst, REG_ITMP3);
1207                         if (s1 == d) {
1208                                 M_MOV(s1, REG_ITMP1);
1209                                 s1 = REG_ITMP1;
1210                                 }
1211                         if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1212                                 M_AND_IMM(s1, iptr->val.i, d);
1213                                 M_BGEZ(s1, 3);
1214                                 M_ISUB(REG_ZERO, s1, d);
1215                                 M_AND_IMM(d, iptr->val.i, d);
1216                                 }
1217                         else if (iptr->val.i == 0xffff) {
1218                                 M_CZEXT(s1, d);
1219                                 M_BGEZ(s1, 3);
1220                                 M_ISUB(REG_ZERO, s1, d);
1221                                 M_CZEXT(d, d);
1222                                 }
1223                         else if (iptr->val.i == 0xffffff) {
1224                                 M_ZAPNOT_IMM(s1, 0x07, d);
1225                                 M_BGEZ(s1, 3);
1226                                 M_ISUB(REG_ZERO, s1, d);
1227                                 M_ZAPNOT_IMM(d, 0x07, d);
1228                                 }
1229                         else {
1230                                 ICONST(REG_ITMP2, iptr->val.i);
1231                                 M_AND(s1, REG_ITMP2, d);
1232                                 M_BGEZ(s1, 3);
1233                                 M_ISUB(REG_ZERO, s1, d);
1234                                 M_AND(d, REG_ITMP2, d);
1235                                 }
1236                         M_ISUB(REG_ZERO, d, d);
1237                         store_reg_to_var_int(iptr->dst, d);
1238                         break;
1239
1240                 case ICMD_IREM0X10001:  /* ..., value  ==> ..., value % 0x100001      */
1241                 
1242 /*          b = value & 0xffff;
1243                         a = value >> 16;
1244                         a = ((b - a) & 0xffff) + (b < a);
1245 */
1246                         var_to_reg_int(s1, src, REG_ITMP1);
1247                         d = reg_of_var(iptr->dst, REG_ITMP3);
1248                         if (s1 == d) {
1249                                 M_MOV(s1, REG_ITMP3);
1250                                 s1 = REG_ITMP3;
1251                                 }
1252                         M_BLTZ(s1, 7);
1253             M_CZEXT(s1, REG_ITMP2);
1254                         M_SRA_IMM(s1, 16, d);
1255                         M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1256                         M_ISUB(REG_ITMP2, d, d);
1257             M_CZEXT(d, d);
1258                         M_IADD(d, REG_ITMP1, d);
1259                         M_BR(11 + (s1 == REG_ITMP1));
1260                         M_ISUB(REG_ZERO, s1, REG_ITMP1);
1261             M_CZEXT(REG_ITMP1, REG_ITMP2);
1262                         M_SRA_IMM(REG_ITMP1, 16, d);
1263                         M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1264                         M_ISUB(REG_ITMP2, d, d);
1265             M_CZEXT(d, d);
1266                         M_IADD(d, REG_ITMP1, d);
1267                         M_ISUB(REG_ZERO, d, d);
1268                         if (s1 == REG_ITMP1) {
1269                                 var_to_reg_int(s1, src, REG_ITMP1);
1270                                 }
1271                         M_SLL_IMM(s1, 33, REG_ITMP2);
1272                         M_CMPEQ(REG_ITMP2, REG_ZERO, REG_ITMP2);
1273                         M_ISUB(d, REG_ITMP2, d);
1274                         store_reg_to_var_int(iptr->dst, d);
1275                         break;
1276
1277                 case ICMD_LANDCONST:  /* ..., value  ==> ..., value & constant        */
1278                                       /* val.l = constant                             */
1279
1280                         var_to_reg_int(s1, src, REG_ITMP1);
1281                         d = reg_of_var(iptr->dst, REG_ITMP3);
1282                         if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1283                                 M_AND_IMM(s1, iptr->val.l, d);
1284                                 }
1285                         else if (iptr->val.l == 0xffffL) {
1286                                 M_CZEXT(s1, d);
1287                                 }
1288                         else if (iptr->val.l == 0xffffffL) {
1289                                 M_ZAPNOT_IMM(s1, 0x07, d);
1290                                 }
1291                         else if (iptr->val.l == 0xffffffffL) {
1292                                 M_IZEXT(s1, d);
1293                                 }
1294                         else if (iptr->val.l == 0xffffffffffL) {
1295                                 M_ZAPNOT_IMM(s1, 0x1f, d);
1296                                 }
1297                         else if (iptr->val.l == 0xffffffffffffL) {
1298                                 M_ZAPNOT_IMM(s1, 0x3f, d);
1299                                 }
1300                         else if (iptr->val.l == 0xffffffffffffffL) {
1301                                 M_ZAPNOT_IMM(s1, 0x7f, d);
1302                                 }
1303                         else {
1304                                 LCONST(REG_ITMP2, iptr->val.l);
1305                                 M_AND(s1, REG_ITMP2, d);
1306                                 }
1307                         store_reg_to_var_int(iptr->dst, d);
1308                         break;
1309
1310                 case ICMD_LREMPOW2:   /* ..., value  ==> ..., value % constant        */
1311                                       /* val.l = constant                             */
1312
1313                         var_to_reg_int(s1, src, REG_ITMP1);
1314                         d = reg_of_var(iptr->dst, REG_ITMP3);
1315                         if (s1 == d) {
1316                                 M_MOV(s1, REG_ITMP1);
1317                                 s1 = REG_ITMP1;
1318                                 }
1319                         if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1320                                 M_AND_IMM(s1, iptr->val.l, d);
1321                                 M_BGEZ(s1, 3);
1322                                 M_LSUB(REG_ZERO, s1, d);
1323                                 M_AND_IMM(d, iptr->val.l, d);
1324                                 }
1325                         else if (iptr->val.l == 0xffffL) {
1326                                 M_CZEXT(s1, d);
1327                                 M_BGEZ(s1, 3);
1328                                 M_LSUB(REG_ZERO, s1, d);
1329                                 M_CZEXT(d, d);
1330                                 }
1331                         else if (iptr->val.l == 0xffffffL) {
1332                                 M_ZAPNOT_IMM(s1, 0x07, d);
1333                                 M_BGEZ(s1, 3);
1334                                 M_LSUB(REG_ZERO, s1, d);
1335                                 M_ZAPNOT_IMM(d, 0x07, d);
1336                                 }
1337                         else if (iptr->val.l == 0xffffffffL) {
1338                                 M_IZEXT(s1, d);
1339                                 M_BGEZ(s1, 3);
1340                                 M_LSUB(REG_ZERO, s1, d);
1341                                 M_IZEXT(d, d);
1342                                 }
1343                         else if (iptr->val.l == 0xffffffffffL) {
1344                                 M_ZAPNOT_IMM(s1, 0x1f, d);
1345                                 M_BGEZ(s1, 3);
1346                                 M_LSUB(REG_ZERO, s1, d);
1347                                 M_ZAPNOT_IMM(d, 0x1f, d);
1348                                 }
1349                         else if (iptr->val.l == 0xffffffffffffL) {
1350                                 M_ZAPNOT_IMM(s1, 0x3f, d);
1351                                 M_BGEZ(s1, 3);
1352                                 M_LSUB(REG_ZERO, s1, d);
1353                                 M_ZAPNOT_IMM(d, 0x3f, d);
1354                                 }
1355                         else if (iptr->val.l == 0xffffffffffffffL) {
1356                                 M_ZAPNOT_IMM(s1, 0x7f, d);
1357                                 M_BGEZ(s1, 3);
1358                                 M_LSUB(REG_ZERO, s1, d);
1359                                 M_ZAPNOT_IMM(d, 0x7f, d);
1360                                 }
1361                         else {
1362                                 LCONST(REG_ITMP2, iptr->val.l);
1363                                 M_AND(s1, REG_ITMP2, d);
1364                                 M_BGEZ(s1, 3);
1365                                 M_LSUB(REG_ZERO, s1, d);
1366                                 M_AND(d, REG_ITMP2, d);
1367                                 }
1368                         M_LSUB(REG_ZERO, d, d);
1369                         store_reg_to_var_int(iptr->dst, d);
1370                         break;
1371
1372                 case ICMD_LREM0X10001:/* ..., value  ==> ..., value % 0x10001         */
1373
1374                         var_to_reg_int(s1, src, REG_ITMP1);
1375                         d = reg_of_var(iptr->dst, REG_ITMP3);
1376                         if (s1 == d) {
1377                                 M_MOV(s1, REG_ITMP3);
1378                                 s1 = REG_ITMP3;
1379                                 }
1380                         M_CZEXT(s1, REG_ITMP2);
1381                         M_SRA_IMM(s1, 16, d);
1382                         M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1383                         M_LSUB(REG_ITMP2, d, d);
1384             M_CZEXT(d, d);
1385                         M_LADD(d, REG_ITMP1, d);
1386                         M_LDA(REG_ITMP2, REG_ZERO, -1);
1387                         M_SRL_IMM(REG_ITMP2, 33, REG_ITMP2);
1388                         if (s1 == REG_ITMP1) {
1389                                 var_to_reg_int(s1, src, REG_ITMP1);
1390                                 }
1391                         M_CMPULT(s1, REG_ITMP2, REG_ITMP2);
1392                         M_BNEZ(REG_ITMP2, 11);
1393                         M_LDA(d, REG_ZERO, -257);
1394                         M_ZAPNOT_IMM(d, 0xcd, d);
1395                         M_LSUB(REG_ZERO, s1, REG_ITMP2);
1396                         M_CMOVGE(s1, s1, REG_ITMP2);
1397                         M_UMULH(REG_ITMP2, d, REG_ITMP2);
1398                         M_SRL_IMM(REG_ITMP2, 16, REG_ITMP2);
1399                         M_LSUB(REG_ZERO, REG_ITMP2, d);
1400                         M_CMOVGE(s1, REG_ITMP2, d);
1401                         M_SLL_IMM(d, 16, REG_ITMP2);
1402                         M_LADD(d, REG_ITMP2, d);
1403                         M_LSUB(s1, d, d);
1404                         store_reg_to_var_int(iptr->dst, d);
1405                         break;
1406
1407                 case ICMD_IOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
1408                 case ICMD_LOR:
1409
1410                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1411                         var_to_reg_int(s2, src, REG_ITMP2);
1412                         d = reg_of_var(iptr->dst, REG_ITMP3);
1413                         M_OR( s1,s2, d);
1414                         store_reg_to_var_int(iptr->dst, d);
1415                         break;
1416
1417                 case ICMD_IORCONST:   /* ..., value  ==> ..., value | constant        */
1418                                       /* val.i = constant                             */
1419
1420                         var_to_reg_int(s1, src, REG_ITMP1);
1421                         d = reg_of_var(iptr->dst, REG_ITMP3);
1422                         if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1423                                 M_OR_IMM(s1, iptr->val.i, d);
1424                                 }
1425                         else {
1426                                 ICONST(REG_ITMP2, iptr->val.i);
1427                                 M_OR(s1, REG_ITMP2, d);
1428                                 }
1429                         store_reg_to_var_int(iptr->dst, d);
1430                         break;
1431
1432                 case ICMD_LORCONST:   /* ..., value  ==> ..., value | constant        */
1433                                       /* val.l = constant                             */
1434
1435                         var_to_reg_int(s1, src, REG_ITMP1);
1436                         d = reg_of_var(iptr->dst, REG_ITMP3);
1437                         if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1438                                 M_OR_IMM(s1, iptr->val.l, d);
1439                                 }
1440                         else {
1441                                 LCONST(REG_ITMP2, iptr->val.l);
1442                                 M_OR(s1, REG_ITMP2, d);
1443                                 }
1444                         store_reg_to_var_int(iptr->dst, d);
1445                         break;
1446
1447                 case ICMD_IXOR:       /* ..., val1, val2  ==> ..., val1 ^ val2        */
1448                 case ICMD_LXOR:
1449
1450                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1451                         var_to_reg_int(s2, src, REG_ITMP2);
1452                         d = reg_of_var(iptr->dst, REG_ITMP3);
1453                         M_XOR(s1, s2, d);
1454                         store_reg_to_var_int(iptr->dst, d);
1455                         break;
1456
1457                 case ICMD_IXORCONST:  /* ..., value  ==> ..., value ^ constant        */
1458                                       /* val.i = constant                             */
1459
1460                         var_to_reg_int(s1, src, REG_ITMP1);
1461                         d = reg_of_var(iptr->dst, REG_ITMP3);
1462                         if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1463                                 M_XOR_IMM(s1, iptr->val.i, d);
1464                                 }
1465                         else {
1466                                 ICONST(REG_ITMP2, iptr->val.i);
1467                                 M_XOR(s1, REG_ITMP2, d);
1468                                 }
1469                         store_reg_to_var_int(iptr->dst, d);
1470                         break;
1471
1472                 case ICMD_LXORCONST:  /* ..., value  ==> ..., value ^ constant        */
1473                                       /* val.l = constant                             */
1474
1475                         var_to_reg_int(s1, src, REG_ITMP1);
1476                         d = reg_of_var(iptr->dst, REG_ITMP3);
1477                         if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1478                                 M_XOR_IMM(s1, iptr->val.l, d);
1479                                 }
1480                         else {
1481                                 LCONST(REG_ITMP2, iptr->val.l);
1482                                 M_XOR(s1, REG_ITMP2, d);
1483                                 }
1484                         store_reg_to_var_int(iptr->dst, d);
1485                         break;
1486
1487
1488                 case ICMD_LCMP:       /* ..., val1, val2  ==> ..., val1 cmp val2      */
1489
1490                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1491                         var_to_reg_int(s2, src, REG_ITMP2);
1492                         d = reg_of_var(iptr->dst, REG_ITMP3);
1493                         M_CMPLT(s1, s2, REG_ITMP3);
1494                         M_CMPLT(s2, s1, REG_ITMP1);
1495                         M_LSUB (REG_ITMP1, REG_ITMP3, d);
1496                         store_reg_to_var_int(iptr->dst, d);
1497                         break;
1498
1499
1500                 case ICMD_IINC:       /* ..., value  ==> ..., value + constant        */
1501                                       /* op1 = variable, val.i = constant             */
1502
1503                         var = &(locals[iptr->op1][TYPE_INT]);
1504                         if (var->flags & INMEMORY) {
1505                                 s1 = REG_ITMP1;
1506                                 M_LLD(s1, REG_SP, 8 * var->regoff);
1507                                 }
1508                         else
1509                                 s1 = var->regoff;
1510                         if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1511                                 M_IADD_IMM(s1, iptr->val.i, s1);
1512                                 }
1513                         else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1514                                 M_ISUB_IMM(s1, (-iptr->val.i), s1);
1515                                 }
1516                         else {
1517                                 M_LDA (s1, s1, iptr->val.i);
1518                                 M_IADD(s1, REG_ZERO, s1);
1519                                 }
1520                         if (var->flags & INMEMORY)
1521                                 M_LST(s1, REG_SP, 8 * var->regoff);
1522                         break;
1523
1524
1525                 /* floating operations ************************************************/
1526
1527                 case ICMD_FNEG:       /* ..., value  ==> ..., - value                 */
1528
1529                         var_to_reg_flt(s1, src, REG_FTMP1);
1530                         d = reg_of_var(iptr->dst, REG_FTMP3);
1531                         M_FMOVN(s1, d);
1532                         store_reg_to_var_flt(iptr->dst, d);
1533                         break;
1534
1535                 case ICMD_DNEG:       /* ..., value  ==> ..., - value                 */
1536
1537                         var_to_reg_flt(s1, src, REG_FTMP1);
1538                         d = reg_of_var(iptr->dst, REG_FTMP3);
1539                         M_FMOVN(s1, d);
1540                         store_reg_to_var_flt(iptr->dst, d);
1541                         break;
1542
1543                 case ICMD_FADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
1544
1545                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1546                         var_to_reg_flt(s2, src, REG_FTMP2);
1547                         d = reg_of_var(iptr->dst, REG_FTMP3);
1548                         if (checkfloats) {
1549                                 M_FADDS(s1, s2, d);
1550                                 M_TRAPB;
1551                                 }
1552                         else {
1553                                 M_FADD(s1, s2, d);
1554                                 }
1555                         store_reg_to_var_flt(iptr->dst, d);
1556                         break;
1557
1558                 case ICMD_DADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
1559
1560                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1561                         var_to_reg_flt(s2, src, REG_FTMP2);
1562                         d = reg_of_var(iptr->dst, REG_FTMP3);
1563                         if (checkfloats) {
1564                                 M_DADDS(s1, s2, d);
1565                                 M_TRAPB;
1566                                 }
1567                         else {
1568                                 M_DADD(s1, s2, d);
1569                                 }
1570                         store_reg_to_var_flt(iptr->dst, d);
1571                         break;
1572
1573                 case ICMD_FSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
1574
1575                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1576                         var_to_reg_flt(s2, src, REG_FTMP2);
1577                         d = reg_of_var(iptr->dst, REG_FTMP3);
1578                         if (checkfloats) {
1579                                 M_FSUBS(s1, s2, d);
1580                                 M_TRAPB;
1581                                 }
1582                         else {
1583                                 M_FSUB(s1, s2, d);
1584                                 }
1585                         store_reg_to_var_flt(iptr->dst, d);
1586                         break;
1587
1588                 case ICMD_DSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
1589
1590                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1591                         var_to_reg_flt(s2, src, REG_FTMP2);
1592                         d = reg_of_var(iptr->dst, REG_FTMP3);
1593                         if (checkfloats) {
1594                                 M_DSUBS(s1, s2, d);
1595                                 M_TRAPB;
1596                                 }
1597                         else {
1598                                 M_DSUB(s1, s2, d);
1599                                 }
1600                         store_reg_to_var_flt(iptr->dst, d);
1601                         break;
1602
1603                 case ICMD_FMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
1604
1605                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1606                         var_to_reg_flt(s2, src, REG_FTMP2);
1607                         d = reg_of_var(iptr->dst, REG_FTMP3);
1608                         if (checkfloats) {
1609                                 M_FMULS(s1, s2, d);
1610                                 M_TRAPB;
1611                                 }
1612                         else {
1613                                 M_FMUL(s1, s2, d);
1614                                 }
1615                         store_reg_to_var_flt(iptr->dst, d);
1616                         break;
1617
1618                 case ICMD_DMUL:       /* ..., val1, val2  ==> ..., val1 *** val2        */
1619
1620                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1621                         var_to_reg_flt(s2, src, REG_FTMP2);
1622                         d = reg_of_var(iptr->dst, REG_FTMP3);
1623                         if (checkfloats) {
1624                                 M_DMULS(s1, s2, d);
1625                                 M_TRAPB;
1626                                 }
1627                         else {
1628                                 M_DMUL(s1, s2, d);
1629                                 }
1630                         store_reg_to_var_flt(iptr->dst, d);
1631                         break;
1632
1633                 case ICMD_FDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1634
1635                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1636                         var_to_reg_flt(s2, src, REG_FTMP2);
1637                         d = reg_of_var(iptr->dst, REG_FTMP3);
1638                         if (checkfloats) {
1639                                 M_FDIVS(s1, s2, d);
1640                                 M_TRAPB;
1641                                 }
1642                         else {
1643                                 M_FDIV(s1, s2, d);
1644                                 }
1645                         store_reg_to_var_flt(iptr->dst, d);
1646                         break;
1647
1648                 case ICMD_DDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1649
1650                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1651                         var_to_reg_flt(s2, src, REG_FTMP2);
1652                         d = reg_of_var(iptr->dst, REG_FTMP3);
1653                         if (checkfloats) {
1654                                 M_DDIVS(s1, s2, d);
1655                                 M_TRAPB;
1656                                 }
1657                         else {
1658                                 M_DDIV(s1, s2, d);
1659                                 }
1660                         store_reg_to_var_flt(iptr->dst, d);
1661                         break;
1662                 
1663                 case ICMD_FREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
1664
1665                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1666                         var_to_reg_flt(s2, src, REG_FTMP2);
1667                         d = reg_of_var(iptr->dst, REG_FTMP3);
1668                         if (checkfloats) {
1669                                 M_FDIVS(s1,s2, REG_FTMP3);
1670                                 M_TRAPB;
1671                                 M_CVTDL_CS(REG_FTMP3, REG_FTMP3); /* round to integer */
1672                                 M_TRAPB;
1673                                 M_CVTLF(REG_FTMP3, REG_FTMP3);
1674                                 M_FMULS(REG_FTMP3, s2, REG_FTMP3);
1675                                 M_TRAPB;
1676                                 M_FSUBS(s1, REG_FTMP3, d);
1677                                 M_TRAPB;
1678                                 }
1679                         else {
1680                                 M_FDIV(s1,s2, REG_FTMP3);
1681                                 M_CVTDL_C(REG_FTMP3, REG_FTMP3); /* round to integer */
1682                                 M_CVTLF(REG_FTMP3, REG_FTMP3);
1683                                 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1684                                 M_FSUB(s1, REG_FTMP3, d);
1685                                 }
1686                         store_reg_to_var_flt(iptr->dst, d);
1687                     break;
1688
1689                 case ICMD_DREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
1690
1691                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1692                         var_to_reg_flt(s2, src, REG_FTMP2);
1693                         d = reg_of_var(iptr->dst, REG_FTMP3);
1694                         if (checkfloats) {
1695                                 M_DDIVS(s1,s2, REG_FTMP3);
1696                                 M_TRAPB;
1697                                 M_CVTDL_CS(REG_FTMP3, REG_FTMP3); /* round to integer */
1698                                 M_TRAPB;
1699                                 M_CVTLD(REG_FTMP3, REG_FTMP3);
1700                                 M_DMULS(REG_FTMP3, s2, REG_FTMP3);
1701                                 M_TRAPB;
1702                                 M_DSUBS(s1, REG_FTMP3, d);
1703                                 M_TRAPB;
1704                                 }
1705                         else {
1706                                 M_DDIV(s1,s2, REG_FTMP3);
1707                                 M_CVTDL_C(REG_FTMP3, REG_FTMP3); /* round to integer */
1708                                 M_CVTLD(REG_FTMP3, REG_FTMP3);
1709                                 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1710                                 M_DSUB(s1, REG_FTMP3, d);
1711                                 }
1712                         store_reg_to_var_flt(iptr->dst, d);
1713                     break;
1714
1715                 case ICMD_I2F:       /* ..., value  ==> ..., (float) value            */
1716                 case ICMD_L2F:
1717                         var_to_reg_int(s1, src, REG_ITMP1);
1718                         d = reg_of_var(iptr->dst, REG_FTMP3);
1719                         a = dseg_adddouble(0.0);
1720                         M_LST (s1, REG_PV, a);
1721                         M_DLD (d, REG_PV, a);
1722                         M_CVTLF(d, d);
1723                         store_reg_to_var_flt(iptr->dst, d);
1724                         break;
1725
1726                 case ICMD_I2D:       /* ..., value  ==> ..., (double) value           */
1727                 case ICMD_L2D:
1728                         var_to_reg_int(s1, src, REG_ITMP1);
1729                         d = reg_of_var(iptr->dst, REG_FTMP3);
1730                         a = dseg_adddouble(0.0);
1731                         M_LST (s1, REG_PV, a);
1732                         M_DLD (d, REG_PV, a);
1733                         M_CVTLD(d, d);
1734                         store_reg_to_var_flt(iptr->dst, d);
1735                         break;
1736                         
1737                 case ICMD_F2I:       /* ..., value  ==> ..., (int) value              */
1738                 case ICMD_D2I:
1739                         var_to_reg_flt(s1, src, REG_FTMP1);
1740                         d = reg_of_var(iptr->dst, REG_ITMP3);
1741                         a = dseg_adddouble(0.0);
1742                         if (checkfloats) {
1743                                 M_CVTDL_CS(s1, REG_FTMP1);
1744                                 M_TRAPB;
1745                                 M_CVTLIS(REG_FTMP1, REG_FTMP2);
1746                                 M_TRAPB;
1747                                 }
1748                         else {
1749                                 M_CVTDL_C(s1, REG_FTMP1);
1750                                 M_CVTLI(REG_FTMP1, REG_FTMP2);
1751                                 }
1752                         M_DST (REG_FTMP1, REG_PV, a);
1753                         M_ILD (d, REG_PV, a);
1754                         store_reg_to_var_int(iptr->dst, d);
1755                         break;
1756                 
1757                 case ICMD_F2L:       /* ..., value  ==> ..., (long) value             */
1758                 case ICMD_D2L:
1759                         var_to_reg_flt(s1, src, REG_FTMP1);
1760                         d = reg_of_var(iptr->dst, REG_ITMP3);
1761                         a = dseg_adddouble(0.0);
1762                         if (checkfloats) {
1763                                 M_CVTDL_CS(s1, REG_FTMP1);
1764                                 M_TRAPB;
1765                                 }
1766                         else {
1767                                 M_CVTDL_C(s1, REG_FTMP1);
1768                                 }
1769                         M_DST (REG_FTMP1, REG_PV, a);
1770                         M_LLD (d, REG_PV, a);
1771                         store_reg_to_var_int(iptr->dst, d);
1772                         break;
1773
1774                 case ICMD_F2D:       /* ..., value  ==> ..., (double) value           */
1775
1776                         var_to_reg_flt(s1, src, REG_FTMP1);
1777                         d = reg_of_var(iptr->dst, REG_FTMP3);
1778                         M_FLTMOVE(s1, d);
1779                         store_reg_to_var_flt(iptr->dst, d);
1780                         break;
1781                                         
1782                 case ICMD_D2F:       /* ..., value  ==> ..., (double) value           */
1783
1784                         var_to_reg_flt(s1, src, REG_FTMP1);
1785                         d = reg_of_var(iptr->dst, REG_FTMP3);
1786                         if (checkfloats) {
1787                                 M_CVTDFS(s1, d);
1788                                 M_TRAPB;
1789                                 }
1790                         else {
1791                                 M_CVTDF(s1, d);
1792                                 }
1793                         store_reg_to_var_flt(iptr->dst, d);
1794                         break;
1795                 
1796                 case ICMD_FCMPL:      /* ..., val1, val2  ==> ..., val1 fcmpl val2    */
1797                 case ICMD_DCMPL:
1798                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1799                         var_to_reg_flt(s2, src, REG_FTMP2);
1800                         d = reg_of_var(iptr->dst, REG_ITMP3);
1801                         if (checkfloats) {
1802                                 M_LSUB_IMM(REG_ZERO, 1, d);
1803                                 M_FCMPEQS(s1, s2, REG_FTMP3);
1804                                 M_TRAPB;
1805                                 M_FBEQZ (REG_FTMP3, 1);        /* jump over next instructions */
1806                                 M_CLR   (d);
1807                                 M_FCMPLTS(s2, s1, REG_FTMP3);
1808                                 M_TRAPB;
1809                                 M_FBEQZ (REG_FTMP3, 1);        /* jump over next instruction  */
1810                                 M_LADD_IMM(REG_ZERO, 1, d);
1811                                 }
1812                         else {
1813                                 M_LSUB_IMM(REG_ZERO, 1, d);
1814                                 M_FCMPEQ(s1, s2, REG_FTMP3);
1815                                 M_FBEQZ (REG_FTMP3, 1);        /* jump over next instructions */
1816                                 M_CLR   (d);
1817                                 M_FCMPLT(s2, s1, REG_FTMP3);
1818                                 M_FBEQZ (REG_FTMP3, 1);        /* jump over next instruction  */
1819                                 M_LADD_IMM(REG_ZERO, 1, d);
1820                                 }
1821                         store_reg_to_var_int(iptr->dst, d);
1822                         break;
1823                         
1824                 case ICMD_FCMPG:      /* ..., val1, val2  ==> ..., val1 fcmpg val2    */
1825                 case ICMD_DCMPG:
1826                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1827                         var_to_reg_flt(s2, src, REG_FTMP2);
1828                         d = reg_of_var(iptr->dst, REG_ITMP3);
1829                         if (checkfloats) {
1830                                 M_LADD_IMM(REG_ZERO, 1, d);
1831                                 M_FCMPEQS(s1, s2, REG_FTMP3);
1832                                 M_TRAPB;
1833                                 M_FBEQZ (REG_FTMP3, 1);        /* jump over next instruction  */
1834                                 M_CLR   (d);
1835                                 M_FCMPLTS(s1, s2, REG_FTMP3);
1836                                 M_TRAPB;
1837                                 M_FBEQZ (REG_FTMP3, 1);        /* jump over next instruction  */
1838                                 M_LSUB_IMM(REG_ZERO, 1, d);
1839                                 }
1840                         else {
1841                                 M_LADD_IMM(REG_ZERO, 1, d);
1842                                 M_FCMPEQ(s1, s2, REG_FTMP3);
1843                                 M_FBEQZ (REG_FTMP3, 1);        /* jump over next instruction  */
1844                                 M_CLR   (d);
1845                                 M_FCMPLT(s1, s2, REG_FTMP3);
1846                                 M_FBEQZ (REG_FTMP3, 1);        /* jump over next instruction  */
1847                                 M_LSUB_IMM(REG_ZERO, 1, d);
1848                                 }
1849                         store_reg_to_var_int(iptr->dst, d);
1850                         break;
1851
1852
1853                 /* memory operations **************************************************/
1854
1855 #define gen_bound_check \
1856                         if (checkbounds) {\
1857                                 M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\
1858                                 M_CMPULT(s2, REG_ITMP3, REG_ITMP3);\
1859                                 M_BEQZ(REG_ITMP3, 0);\
1860                                 mcode_addxboundrefs(mcodeptr);\
1861                                 }
1862
1863                 case ICMD_ARRAYLENGTH: /* ..., arrayref  ==> ..., length              */
1864
1865                         var_to_reg_int(s1, src, REG_ITMP1);
1866                         d = reg_of_var(iptr->dst, REG_ITMP3);
1867                         gen_nullptr_check(s1);
1868                         M_ILD(d, s1, OFFSET(java_arrayheader, size));
1869                         store_reg_to_var_int(iptr->dst, d);
1870                         break;
1871
1872                 case ICMD_AALOAD:     /* ..., arrayref, index  ==> ..., value         */
1873
1874                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1875                         var_to_reg_int(s2, src, REG_ITMP2);
1876                         d = reg_of_var(iptr->dst, REG_ITMP3);
1877                         gen_nullptr_check(s1);
1878                         gen_bound_check;
1879                         M_SAADDQ(s2, s1, REG_ITMP1);
1880                         M_ALD( d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1881                         store_reg_to_var_int(iptr->dst, d);
1882                         break;
1883
1884                 case ICMD_LALOAD:     /* ..., arrayref, index  ==> ..., value         */
1885
1886                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1887                         var_to_reg_int(s2, src, REG_ITMP2);
1888                         d = reg_of_var(iptr->dst, REG_ITMP3);
1889                         gen_nullptr_check(s1);
1890                         gen_bound_check;
1891                         M_S8ADDQ(s2, s1, REG_ITMP1);
1892                         M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1893                         store_reg_to_var_int(iptr->dst, d);
1894                         break;
1895
1896                 case ICMD_IALOAD:     /* ..., arrayref, index  ==> ..., value         */
1897
1898                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1899                         var_to_reg_int(s2, src, REG_ITMP2);
1900                         d = reg_of_var(iptr->dst, REG_ITMP3);
1901                         gen_nullptr_check(s1);
1902                         gen_bound_check;
1903                         M_S4ADDQ(s2, s1, REG_ITMP1);
1904                         M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1905                         store_reg_to_var_int(iptr->dst, d);
1906                         break;
1907
1908                 case ICMD_FALOAD:     /* ..., arrayref, index  ==> ..., value         */
1909
1910                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1911                         var_to_reg_int(s2, src, REG_ITMP2);
1912                         d = reg_of_var(iptr->dst, REG_FTMP3);
1913                         gen_nullptr_check(s1);
1914                         gen_bound_check;
1915                         M_S4ADDQ(s2, s1, REG_ITMP1);
1916                         M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1917                         store_reg_to_var_flt(iptr->dst, d);
1918                         break;
1919
1920                 case ICMD_DALOAD:     /* ..., arrayref, index  ==> ..., value         */
1921
1922                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1923                         var_to_reg_int(s2, src, REG_ITMP2);
1924                         d = reg_of_var(iptr->dst, REG_FTMP3);
1925                         gen_nullptr_check(s1);
1926                         gen_bound_check;
1927                         M_S8ADDQ(s2, s1, REG_ITMP1);
1928                         M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1929                         store_reg_to_var_flt(iptr->dst, d);
1930                         break;
1931
1932                 case ICMD_CALOAD:     /* ..., arrayref, index  ==> ..., value         */
1933
1934                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1935                         var_to_reg_int(s2, src, REG_ITMP2);
1936                         d = reg_of_var(iptr->dst, REG_ITMP3);
1937                         gen_nullptr_check(s1);
1938                         gen_bound_check;
1939                         if (has_ext_instr_set) {
1940                                 M_LADD(s2, s1, REG_ITMP1);
1941                                 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1942                                 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1943                                 }
1944                         else {
1945                                 M_LADD (s2, s1, REG_ITMP1);
1946                                 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1947                                 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1948                                 M_LDA  (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1949                                 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
1950                                 }
1951                         store_reg_to_var_int(iptr->dst, d);
1952                         break;                  
1953
1954                 case ICMD_SALOAD:     /* ..., arrayref, index  ==> ..., value         */
1955
1956                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1957                         var_to_reg_int(s2, src, REG_ITMP2);
1958                         d = reg_of_var(iptr->dst, REG_ITMP3);
1959                         gen_nullptr_check(s1);
1960                         gen_bound_check;
1961                         if (has_ext_instr_set) {
1962                                 M_LADD(s2, s1, REG_ITMP1);
1963                                 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1964                                 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1965                                 M_SSEXT(d, d);
1966                                 }
1967                         else {
1968                                 M_LADD(s2, s1, REG_ITMP1);
1969                                 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1970                                 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1971                                 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1972                                 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1973                                 M_SRA_IMM(d, 48, d);
1974                                 }
1975                         store_reg_to_var_int(iptr->dst, d);
1976                         break;
1977
1978                 case ICMD_BALOAD:     /* ..., arrayref, index  ==> ..., value         */
1979
1980                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1981                         var_to_reg_int(s2, src, REG_ITMP2);
1982                         d = reg_of_var(iptr->dst, REG_ITMP3);
1983                         gen_nullptr_check(s1);
1984                         gen_bound_check;
1985                         if (has_ext_instr_set) {
1986                                 M_LADD   (s2, s1, REG_ITMP1);
1987                                 M_BLDU   (d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1988                                 M_BSEXT  (d, d);
1989                                 }
1990                         else {
1991                                 M_LADD(s2, s1, REG_ITMP1);
1992                                 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1993                                 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
1994                                 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1995                                 M_SRA_IMM(d, 56, d);
1996                                 }
1997                         store_reg_to_var_int(iptr->dst, d);
1998                         break;
1999
2000
2001                 case ICMD_AASTORE:    /* ..., arrayref, index, value  ==> ...         */
2002
2003                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2004                         var_to_reg_int(s2, src->prev, REG_ITMP2);
2005                         gen_nullptr_check(s1);
2006                         gen_bound_check;
2007                         var_to_reg_int(s3, src, REG_ITMP3);
2008                         M_SAADDQ(s2, s1, REG_ITMP1);
2009                         M_AST   (s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
2010                         break;
2011
2012                 case ICMD_LASTORE:    /* ..., arrayref, index, value  ==> ...         */
2013
2014                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2015                         var_to_reg_int(s2, src->prev, REG_ITMP2);
2016                         gen_nullptr_check(s1);
2017                         gen_bound_check;
2018                         var_to_reg_int(s3, src, REG_ITMP3);
2019                         M_S8ADDQ(s2, s1, REG_ITMP1);
2020                         M_LST   (s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
2021                         break;
2022
2023                 case ICMD_IASTORE:    /* ..., arrayref, index, value  ==> ...         */
2024
2025                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2026                         var_to_reg_int(s2, src->prev, REG_ITMP2);
2027                         gen_nullptr_check(s1);
2028                         gen_bound_check;
2029                         var_to_reg_int(s3, src, REG_ITMP3);
2030                         M_S4ADDQ(s2, s1, REG_ITMP1);
2031                         M_IST   (s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
2032                         break;
2033
2034                 case ICMD_FASTORE:    /* ..., arrayref, index, value  ==> ...         */
2035
2036                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2037                         var_to_reg_int(s2, src->prev, REG_ITMP2);
2038                         gen_nullptr_check(s1);
2039                         gen_bound_check;
2040                         var_to_reg_flt(s3, src, REG_FTMP3);
2041                         M_S4ADDQ(s2, s1, REG_ITMP1);
2042                         M_FST   (s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
2043                         break;
2044
2045                 case ICMD_DASTORE:    /* ..., arrayref, index, value  ==> ...         */
2046
2047                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2048                         var_to_reg_int(s2, src->prev, REG_ITMP2);
2049                         gen_nullptr_check(s1);
2050                         gen_bound_check;
2051                         var_to_reg_flt(s3, src, REG_FTMP3);
2052                         M_S8ADDQ(s2, s1, REG_ITMP1);
2053                         M_DST   (s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
2054                         break;
2055
2056                 case ICMD_CASTORE:    /* ..., arrayref, index, value  ==> ...         */
2057
2058                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2059                         var_to_reg_int(s2, src->prev, REG_ITMP2);
2060                         gen_nullptr_check(s1);
2061                         gen_bound_check;
2062                         var_to_reg_int(s3, src, REG_ITMP3);
2063                         if (has_ext_instr_set) {
2064                                 M_LADD(s2, s1, REG_ITMP1);
2065                                 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2066                                 M_SST (s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
2067                                 }
2068                         else {
2069                                 M_LADD (s2, s1, REG_ITMP1);
2070                                 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2071                                 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2072                                 M_LDA  (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2073                                 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
2074                                 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2075                                 M_OR   (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2076                                 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2077                                 }
2078                         break;
2079
2080                 case ICMD_SASTORE:    /* ..., arrayref, index, value  ==> ...         */
2081
2082                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2083                         var_to_reg_int(s2, src->prev, REG_ITMP2);
2084                         gen_nullptr_check(s1);
2085                         gen_bound_check;
2086                         var_to_reg_int(s3, src, REG_ITMP3);
2087                         if (has_ext_instr_set) {
2088                                 M_LADD(s2, s1, REG_ITMP1);
2089                                 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2090                                 M_SST (s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2091                                 }
2092                         else {
2093                                 M_LADD (s2, s1, REG_ITMP1);
2094                                 M_LADD (s2, REG_ITMP1, REG_ITMP1);
2095                                 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2096                                 M_LDA  (REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2097                                 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
2098                                 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2099                                 M_OR   (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2100                                 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2101                                 }
2102                         break;
2103
2104                 case ICMD_BASTORE:    /* ..., arrayref, index, value  ==> ...         */
2105
2106                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2107                         var_to_reg_int(s2, src->prev, REG_ITMP2);
2108                         gen_nullptr_check(s1);
2109                         gen_bound_check;
2110                         var_to_reg_int(s3, src, REG_ITMP3);
2111                         if (has_ext_instr_set) {
2112                                 M_LADD(s2, s1, REG_ITMP1);
2113                                 M_BST (s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2114                                 }
2115                         else {
2116                                 M_LADD (s2, s1, REG_ITMP1);
2117                                 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2118                                 M_LDA  (REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2119                                 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
2120                                 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2121                                 M_OR   (REG_ITMP2, REG_ITMP3, REG_ITMP2);
2122                                 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2123                                 }
2124                         break;
2125
2126
2127                 case ICMD_PUTSTATIC:  /* ..., value  ==> ...                          */
2128                                       /* op1 = type, val.a = field address            */
2129
2130                         a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value));
2131                         M_ALD(REG_ITMP1, REG_PV, a);
2132                         switch (iptr->op1) {
2133                                 case TYPE_INT:
2134                                         var_to_reg_int(s2, src, REG_ITMP2);
2135                                         M_IST(s2, REG_ITMP1, 0);
2136                                         break;
2137                                 case TYPE_LNG:
2138                                         var_to_reg_int(s2, src, REG_ITMP2);
2139                                         M_LST(s2, REG_ITMP1, 0);
2140                                         break;
2141                                 case TYPE_ADR:
2142                                         var_to_reg_int(s2, src, REG_ITMP2);
2143                                         M_AST(s2, REG_ITMP1, 0);
2144                                         break;
2145                                 case TYPE_FLT:
2146                                         var_to_reg_flt(s2, src, REG_FTMP2);
2147                                         M_FST(s2, REG_ITMP1, 0);
2148                                         break;
2149                                 case TYPE_DBL:
2150                                         var_to_reg_flt(s2, src, REG_FTMP2);
2151                                         M_DST(s2, REG_ITMP1, 0);
2152                                         break;
2153                                 default: panic ("internal error");
2154                                 }
2155                         break;
2156
2157                 case ICMD_GETSTATIC:  /* ...  ==> ..., value                          */
2158                                       /* op1 = type, val.a = field address            */
2159
2160                         a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value));
2161                         M_ALD(REG_ITMP1, REG_PV, a);
2162                         switch (iptr->op1) {
2163                                 case TYPE_INT:
2164                                         d = reg_of_var(iptr->dst, REG_ITMP3);
2165                                         M_ILD(d, REG_ITMP1, 0);
2166                                         store_reg_to_var_int(iptr->dst, d);
2167                                         break;
2168                                 case TYPE_LNG:
2169                                         d = reg_of_var(iptr->dst, REG_ITMP3);
2170                                         M_LLD(d, REG_ITMP1, 0);
2171                                         store_reg_to_var_int(iptr->dst, d);
2172                                         break;
2173                                 case TYPE_ADR:
2174                                         d = reg_of_var(iptr->dst, REG_ITMP3);
2175                                         M_ALD(d, REG_ITMP1, 0);
2176                                         store_reg_to_var_int(iptr->dst, d);
2177                                         break;
2178                                 case TYPE_FLT:
2179                                         d = reg_of_var(iptr->dst, REG_FTMP1);
2180                                         M_FLD(d, REG_ITMP1, 0);
2181                                         store_reg_to_var_flt(iptr->dst, d);
2182                                         break;
2183                                 case TYPE_DBL:                          
2184                                         d = reg_of_var(iptr->dst, REG_FTMP1);
2185                                         M_DLD(d, REG_ITMP1, 0);
2186                                         store_reg_to_var_flt(iptr->dst, d);
2187                                         break;
2188                                 default: panic ("internal error");
2189                                 }
2190                         break;
2191
2192
2193                 case ICMD_PUTFIELD:   /* ..., value  ==> ...                          */
2194                                       /* op1 = type, val.i = field offset             */
2195
2196                         a = ((fieldinfo *)(iptr->val.a))->offset;
2197                         switch (iptr->op1) {
2198                                 case TYPE_INT:
2199                                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2200                                         var_to_reg_int(s2, src, REG_ITMP2);
2201                                         gen_nullptr_check(s1);
2202                                         M_IST(s2, s1, a);
2203                                         break;
2204                                 case TYPE_LNG:
2205                                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2206                                         var_to_reg_int(s2, src, REG_ITMP2);
2207                                         gen_nullptr_check(s1);
2208                                         M_LST(s2, s1, a);
2209                                         break;
2210                                 case TYPE_ADR:
2211                                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2212                                         var_to_reg_int(s2, src, REG_ITMP2);
2213                                         gen_nullptr_check(s1);
2214                                         M_AST(s2, s1, a);
2215                                         break;
2216                                 case TYPE_FLT:
2217                                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2218                                         var_to_reg_flt(s2, src, REG_FTMP2);
2219                                         gen_nullptr_check(s1);
2220                                         M_FST(s2, s1, a);
2221                                         break;
2222                                 case TYPE_DBL:
2223                                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2224                                         var_to_reg_flt(s2, src, REG_FTMP2);
2225                                         gen_nullptr_check(s1);
2226                                         M_DST(s2, s1, a);
2227                                         break;
2228                                 default: panic ("internal error");
2229                                 }
2230                         break;
2231
2232                 case ICMD_GETFIELD:   /* ...  ==> ..., value                          */
2233                                       /* op1 = type, val.i = field offset             */
2234
2235                         a = ((fieldinfo *)(iptr->val.a))->offset;
2236                         switch (iptr->op1) {
2237                                 case TYPE_INT:
2238                                         var_to_reg_int(s1, src, REG_ITMP1);
2239                                         d = reg_of_var(iptr->dst, REG_ITMP3);
2240                                         gen_nullptr_check(s1);
2241                                         M_ILD(d, s1, a);
2242                                         store_reg_to_var_int(iptr->dst, d);
2243                                         break;
2244                                 case TYPE_LNG:
2245                                         var_to_reg_int(s1, src, REG_ITMP1);
2246                                         d = reg_of_var(iptr->dst, REG_ITMP3);
2247                                         gen_nullptr_check(s1);
2248                                         M_LLD(d, s1, a);
2249                                         store_reg_to_var_int(iptr->dst, d);
2250                                         break;
2251                                 case TYPE_ADR:
2252                                         var_to_reg_int(s1, src, REG_ITMP1);
2253                                         d = reg_of_var(iptr->dst, REG_ITMP3);
2254                                         gen_nullptr_check(s1);
2255                                         M_ALD(d, s1, a);
2256                                         store_reg_to_var_int(iptr->dst, d);
2257                                         break;
2258                                 case TYPE_FLT:
2259                                         var_to_reg_int(s1, src, REG_ITMP1);
2260                                         d = reg_of_var(iptr->dst, REG_FTMP1);
2261                                         gen_nullptr_check(s1);
2262                                         M_FLD(d, s1, a);
2263                                         store_reg_to_var_flt(iptr->dst, d);
2264                                         break;
2265                                 case TYPE_DBL:                          
2266                                         var_to_reg_int(s1, src, REG_ITMP1);
2267                                         d = reg_of_var(iptr->dst, REG_FTMP1);
2268                                         gen_nullptr_check(s1);
2269                                         M_DLD(d, s1, a);
2270                                         store_reg_to_var_flt(iptr->dst, d);
2271                                         break;
2272                                 default: panic ("internal error");
2273                                 }
2274                         break;
2275
2276
2277                 /* branch operations **************************************************/
2278
2279 #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}}
2280
2281                 case ICMD_ATHROW:       /* ..., objectref ==> ... (, objectref)       */
2282
2283                         var_to_reg_int(s1, src, REG_ITMP1);
2284                         M_INTMOVE(s1, REG_ITMP1_XPTR);
2285                         a = dseg_addaddress(asm_handle_exception);
2286                         M_ALD(REG_ITMP2, REG_PV, a);
2287                         M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2288                         ALIGNCODENOP;
2289                         break;
2290
2291                 case ICMD_GOTO:         /* ... ==> ...                                */
2292                                         /* op1 = target JavaVM pc                     */
2293                         M_BR(0);
2294                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2295                         ALIGNCODENOP;
2296                         break;
2297
2298                 case ICMD_JSR:          /* ... ==> ...                                */
2299                                         /* op1 = target JavaVM pc                     */
2300
2301                         M_BSR(REG_ITMP1, 0);
2302                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2303                         break;
2304                         
2305                 case ICMD_RET:          /* ... ==> ...                                */
2306                                         /* op1 = local variable                       */
2307
2308                         var = &(locals[iptr->op1][TYPE_ADR]);
2309                         if (var->flags & INMEMORY) {
2310                                 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2311                                 M_RET(REG_ZERO, REG_ITMP1);
2312                                 }
2313                         else
2314                                 M_RET(REG_ZERO, var->regoff);
2315                         ALIGNCODENOP;
2316                         break;
2317
2318                 case ICMD_IFNULL:       /* ..., value ==> ...                         */
2319                                         /* op1 = target JavaVM pc                     */
2320
2321                         var_to_reg_int(s1, src, REG_ITMP1);
2322                         M_BEQZ(s1, 0);
2323                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2324                         break;
2325
2326                 case ICMD_IFNONNULL:    /* ..., value ==> ...                         */
2327                                         /* op1 = target JavaVM pc                     */
2328
2329                         var_to_reg_int(s1, src, REG_ITMP1);
2330                         M_BNEZ(s1, 0);
2331                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2332                         break;
2333
2334                 case ICMD_IFEQ:         /* ..., value ==> ...                         */
2335                                         /* op1 = target JavaVM pc, val.i = constant   */
2336
2337                         var_to_reg_int(s1, src, REG_ITMP1);
2338                         if (iptr->val.i == 0) {
2339                                 M_BEQZ(s1, 0);
2340                                 }
2341                         else {
2342                                 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2343                                         M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2344                                         }
2345                                 else {
2346                                         ICONST(REG_ITMP2, iptr->val.i);
2347                                         M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2348                                         }
2349                                 M_BNEZ(REG_ITMP1, 0);
2350                                 }
2351                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2352                         break;
2353
2354                 case ICMD_IFLT:         /* ..., value ==> ...                         */
2355                                         /* op1 = target JavaVM pc, val.i = constant   */
2356
2357                         var_to_reg_int(s1, src, REG_ITMP1);
2358                         if (iptr->val.i == 0) {
2359                                 M_BLTZ(s1, 0);
2360                                 }
2361                         else {
2362                                 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2363                                         M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2364                                         }
2365                                 else {
2366                                         ICONST(REG_ITMP2, iptr->val.i);
2367                                         M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2368                                         }
2369                                 M_BNEZ(REG_ITMP1, 0);
2370                                 }
2371                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2372                         break;
2373
2374                 case ICMD_IFLE:         /* ..., value ==> ...                         */
2375                                         /* op1 = target JavaVM pc, val.i = constant   */
2376
2377                         var_to_reg_int(s1, src, REG_ITMP1);
2378                         if (iptr->val.i == 0) {
2379                                 M_BLEZ(s1, 0);
2380                                 }
2381                         else {
2382                                 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2383                                         M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2384                                         }
2385                                 else {
2386                                         ICONST(REG_ITMP2, iptr->val.i);
2387                                         M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2388                                         }
2389                                 M_BNEZ(REG_ITMP1, 0);
2390                                 }
2391                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2392                         break;
2393
2394                 case ICMD_IFNE:         /* ..., value ==> ...                         */
2395                                         /* op1 = target JavaVM pc, val.i = constant   */
2396
2397                         var_to_reg_int(s1, src, REG_ITMP1);
2398                         if (iptr->val.i == 0) {
2399                                 M_BNEZ(s1, 0);
2400                                 }
2401                         else {
2402                                 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2403                                         M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2404                                         }
2405                                 else {
2406                                         ICONST(REG_ITMP2, iptr->val.i);
2407                                         M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2408                                         }
2409                                 M_BEQZ(REG_ITMP1, 0);
2410                                 }
2411                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2412                         break;
2413
2414                 case ICMD_IFGT:         /* ..., value ==> ...                         */
2415                                         /* op1 = target JavaVM pc, val.i = constant   */
2416
2417                         var_to_reg_int(s1, src, REG_ITMP1);
2418                         if (iptr->val.i == 0) {
2419                                 M_BGTZ(s1, 0);
2420                                 }
2421                         else {
2422                                 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2423                                         M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2424                                         }
2425                                 else {
2426                                         ICONST(REG_ITMP2, iptr->val.i);
2427                                         M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2428                                         }
2429                                 M_BEQZ(REG_ITMP1, 0);
2430                                 }
2431                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2432                         break;
2433
2434                 case ICMD_IFGE:         /* ..., value ==> ...                         */
2435                                         /* op1 = target JavaVM pc, val.i = constant   */
2436
2437                         var_to_reg_int(s1, src, REG_ITMP1);
2438                         if (iptr->val.i == 0) {
2439                                 M_BGEZ(s1, 0);
2440                                 }
2441                         else {
2442                                 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2443                                         M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2444                                         }
2445                                 else {
2446                                         ICONST(REG_ITMP2, iptr->val.i);
2447                                         M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2448                                         }
2449                                 M_BEQZ(REG_ITMP1, 0);
2450                                 }
2451                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2452                         break;
2453
2454                 case ICMD_IF_LEQ:       /* ..., value ==> ...                         */
2455                                         /* op1 = target JavaVM pc, val.l = constant   */
2456
2457                         var_to_reg_int(s1, src, REG_ITMP1);
2458                         if (iptr->val.l == 0) {
2459                                 M_BEQZ(s1, 0);
2460                                 }
2461                         else {
2462                                 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2463                                         M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2464                                         }
2465                                 else {
2466                                         LCONST(REG_ITMP2, iptr->val.l);
2467                                         M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2468                                         }
2469                                 M_BNEZ(REG_ITMP1, 0);
2470                                 }
2471                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2472                         break;
2473
2474                 case ICMD_IF_LLT:       /* ..., value ==> ...                         */
2475                                         /* op1 = target JavaVM pc, val.l = constant   */
2476
2477                         var_to_reg_int(s1, src, REG_ITMP1);
2478                         if (iptr->val.l == 0) {
2479                                 M_BLTZ(s1, 0);
2480                                 }
2481                         else {
2482                                 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2483                                         M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2484                                         }
2485                                 else {
2486                                         LCONST(REG_ITMP2, iptr->val.l);
2487                                         M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2488                                         }
2489                                 M_BNEZ(REG_ITMP1, 0);
2490                                 }
2491                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2492                         break;
2493
2494                 case ICMD_IF_LLE:       /* ..., value ==> ...                         */
2495                                         /* op1 = target JavaVM pc, val.l = constant   */
2496
2497                         var_to_reg_int(s1, src, REG_ITMP1);
2498                         if (iptr->val.l == 0) {
2499                                 M_BLEZ(s1, 0);
2500                                 }
2501                         else {
2502                                 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2503                                         M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2504                                         }
2505                                 else {
2506                                         LCONST(REG_ITMP2, iptr->val.l);
2507                                         M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2508                                         }
2509                                 M_BNEZ(REG_ITMP1, 0);
2510                                 }
2511                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2512                         break;
2513
2514                 case ICMD_IF_LNE:       /* ..., value ==> ...                         */
2515                                         /* op1 = target JavaVM pc, val.l = constant   */
2516
2517                         var_to_reg_int(s1, src, REG_ITMP1);
2518                         if (iptr->val.l == 0) {
2519                                 M_BNEZ(s1, 0);
2520                                 }
2521                         else {
2522                                 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2523                                         M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2524                                         }
2525                                 else {
2526                                         LCONST(REG_ITMP2, iptr->val.l);
2527                                         M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2528                                         }
2529                                 M_BEQZ(REG_ITMP1, 0);
2530                                 }
2531                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2532                         break;
2533
2534                 case ICMD_IF_LGT:       /* ..., value ==> ...                         */
2535                                         /* op1 = target JavaVM pc, val.l = constant   */
2536
2537                         var_to_reg_int(s1, src, REG_ITMP1);
2538                         if (iptr->val.l == 0) {
2539                                 M_BGTZ(s1, 0);
2540                                 }
2541                         else {
2542                                 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2543                                         M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2544                                         }
2545                                 else {
2546                                         LCONST(REG_ITMP2, iptr->val.l);
2547                                         M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2548                                         }
2549                                 M_BEQZ(REG_ITMP1, 0);
2550                                 }
2551                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2552                         break;
2553
2554                 case ICMD_IF_LGE:       /* ..., value ==> ...                         */
2555                                         /* op1 = target JavaVM pc, val.l = constant   */
2556
2557                         var_to_reg_int(s1, src, REG_ITMP1);
2558                         if (iptr->val.l == 0) {
2559                                 M_BGEZ(s1, 0);
2560                                 }
2561                         else {
2562                                 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2563                                         M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2564                                         }
2565                                 else {
2566                                         LCONST(REG_ITMP2, iptr->val.l);
2567                                         M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2568                                         }
2569                                 M_BEQZ(REG_ITMP1, 0);
2570                                 }
2571                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2572                         break;
2573
2574                 case ICMD_IF_ICMPEQ:    /* ..., value, value ==> ...                  */
2575                 case ICMD_IF_LCMPEQ:    /* op1 = target JavaVM pc                     */
2576                 case ICMD_IF_ACMPEQ:
2577
2578                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2579                         var_to_reg_int(s2, src, REG_ITMP2);
2580                         M_CMPEQ(s1, s2, REG_ITMP1);
2581                         M_BNEZ(REG_ITMP1, 0);
2582                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2583                         break;
2584
2585                 case ICMD_IF_ICMPNE:    /* ..., value, value ==> ...                  */
2586                 case ICMD_IF_LCMPNE:    /* op1 = target JavaVM pc                     */
2587                 case ICMD_IF_ACMPNE:
2588
2589                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2590                         var_to_reg_int(s2, src, REG_ITMP2);
2591                         M_CMPEQ(s1, s2, REG_ITMP1);
2592                         M_BEQZ(REG_ITMP1, 0);
2593                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2594                         break;
2595
2596                 case ICMD_IF_ICMPLT:    /* ..., value, value ==> ...                  */
2597                 case ICMD_IF_LCMPLT:    /* op1 = target JavaVM pc                     */
2598
2599                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2600                         var_to_reg_int(s2, src, REG_ITMP2);
2601                         M_CMPLT(s1, s2, REG_ITMP1);
2602                         M_BNEZ(REG_ITMP1, 0);
2603                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2604                         break;
2605
2606                 case ICMD_IF_ICMPGT:    /* ..., value, value ==> ...                  */
2607                 case ICMD_IF_LCMPGT:    /* op1 = target JavaVM pc                     */
2608
2609                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2610                         var_to_reg_int(s2, src, REG_ITMP2);
2611                         M_CMPLE(s1, s2, REG_ITMP1);
2612                         M_BEQZ(REG_ITMP1, 0);
2613                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2614                         break;
2615
2616                 case ICMD_IF_ICMPLE:    /* ..., value, value ==> ...                  */
2617                 case ICMD_IF_LCMPLE:    /* op1 = target JavaVM pc                     */
2618
2619                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2620                         var_to_reg_int(s2, src, REG_ITMP2);
2621                         M_CMPLE(s1, s2, REG_ITMP1);
2622                         M_BNEZ(REG_ITMP1, 0);
2623                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2624                         break;
2625
2626                 case ICMD_IF_ICMPGE:    /* ..., value, value ==> ...                  */
2627                 case ICMD_IF_LCMPGE:    /* op1 = target JavaVM pc                     */
2628
2629                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2630                         var_to_reg_int(s2, src, REG_ITMP2);
2631                         M_CMPLT(s1, s2, REG_ITMP1);
2632                         M_BEQZ(REG_ITMP1, 0);
2633                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2634                         break;
2635
2636                 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST                           */
2637
2638                 case ICMD_ELSE_ICONST:  /* handled by IFxx_ICONST                     */
2639                         break;
2640
2641                 case ICMD_IFEQ_ICONST:  /* ..., value ==> ..., constant               */
2642                                         /* val.i = constant                           */
2643
2644                         var_to_reg_int(s1, src, REG_ITMP1);
2645                         d = reg_of_var(iptr->dst, REG_ITMP3);
2646                         a = iptr->val.i;
2647                         if (iptr[1].opc == ICMD_ELSE_ICONST) {
2648                                 if ((a == 1) && (iptr[1].val.i == 0)) {
2649                                         M_CMPEQ(s1, REG_ZERO, d);
2650                                         store_reg_to_var_int(iptr->dst, d);
2651                                         break;
2652                                         }
2653                                 if ((a == 0) && (iptr[1].val.i == 1)) {
2654                                         M_CMPEQ(s1, REG_ZERO, d);
2655                                         M_XOR_IMM(d, 1, d);
2656                                         store_reg_to_var_int(iptr->dst, d);
2657                                         break;
2658                                         }
2659                                 if (s1 == d) {
2660                                         M_MOV(s1, REG_ITMP1);
2661                                         s1 = REG_ITMP1;
2662                                         }
2663                                 ICONST(d, iptr[1].val.i);
2664                                 }
2665                         if ((a >= 0) && (a <= 255)) {
2666                                 M_CMOVEQ_IMM(s1, a, d);
2667                                 }
2668                         else {
2669                                 ICONST(REG_ITMP2, a);
2670                                 M_CMOVEQ(s1, REG_ITMP2, d);
2671                                 }
2672                         store_reg_to_var_int(iptr->dst, d);
2673                         break;
2674
2675                 case ICMD_IFNE_ICONST:  /* ..., value ==> ..., constant               */
2676                                         /* val.i = constant                           */
2677
2678                         var_to_reg_int(s1, src, REG_ITMP1);
2679                         d = reg_of_var(iptr->dst, REG_ITMP3);
2680                         a = iptr->val.i;
2681                         if (iptr[1].opc == ICMD_ELSE_ICONST) {
2682                                 if ((a == 0) && (iptr[1].val.i == 1)) {
2683                                         M_CMPEQ(s1, REG_ZERO, d);
2684                                         store_reg_to_var_int(iptr->dst, d);
2685                                         break;
2686                                         }
2687                                 if ((a == 1) && (iptr[1].val.i == 0)) {
2688                                         M_CMPEQ(s1, REG_ZERO, d);
2689                                         M_XOR_IMM(d, 1, d);
2690                                         store_reg_to_var_int(iptr->dst, d);
2691                                         break;
2692                                         }
2693                                 if (s1 == d) {
2694                                         M_MOV(s1, REG_ITMP1);
2695                                         s1 = REG_ITMP1;
2696                                         }
2697                                 ICONST(d, iptr[1].val.i);
2698                                 }
2699                         if ((a >= 0) && (a <= 255)) {
2700                                 M_CMOVNE_IMM(s1, a, d);
2701                                 }
2702                         else {
2703                                 ICONST(REG_ITMP2, a);
2704                                 M_CMOVNE(s1, REG_ITMP2, d);
2705                                 }
2706                         store_reg_to_var_int(iptr->dst, d);
2707                         break;
2708
2709                 case ICMD_IFLT_ICONST:  /* ..., value ==> ..., constant               */
2710                                         /* val.i = constant                           */
2711
2712                         var_to_reg_int(s1, src, REG_ITMP1);
2713                         d = reg_of_var(iptr->dst, REG_ITMP3);
2714                         a = iptr->val.i;
2715                         if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2716                                 if ((a == 1) && (iptr[1].val.i == 0)) {
2717                                         M_CMPLT(s1, REG_ZERO, d);
2718                                         store_reg_to_var_int(iptr->dst, d);
2719                                         break;
2720                                         }
2721                                 if ((a == 0) && (iptr[1].val.i == 1)) {
2722                                         M_CMPLE(REG_ZERO, s1, d);
2723                                         store_reg_to_var_int(iptr->dst, d);
2724                                         break;
2725                                         }
2726                                 if (s1 == d) {
2727                                         M_MOV(s1, REG_ITMP1);
2728                                         s1 = REG_ITMP1;
2729                                         }
2730                                 ICONST(d, iptr[1].val.i);
2731                                 }
2732                         if ((a >= 0) && (a <= 255)) {
2733                                 M_CMOVLT_IMM(s1, a, d);
2734                                 }
2735                         else {
2736                                 ICONST(REG_ITMP2, a);
2737                                 M_CMOVLT(s1, REG_ITMP2, d);
2738                                 }
2739                         store_reg_to_var_int(iptr->dst, d);
2740                         break;
2741
2742                 case ICMD_IFGE_ICONST:  /* ..., value ==> ..., constant               */
2743                                         /* val.i = constant                           */
2744
2745                         var_to_reg_int(s1, src, REG_ITMP1);
2746                         d = reg_of_var(iptr->dst, REG_ITMP3);
2747                         a = iptr->val.i;
2748                         if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2749                                 if ((a == 1) && (iptr[1].val.i == 0)) {
2750                                         M_CMPLE(REG_ZERO, s1, d);
2751                                         store_reg_to_var_int(iptr->dst, d);
2752                                         break;
2753                                         }
2754                                 if ((a == 0) && (iptr[1].val.i == 1)) {
2755                                         M_CMPLT(s1, REG_ZERO, d);
2756                                         store_reg_to_var_int(iptr->dst, d);
2757                                         break;
2758                                         }
2759                                 if (s1 == d) {
2760                                         M_MOV(s1, REG_ITMP1);
2761                                         s1 = REG_ITMP1;
2762                                         }
2763                                 ICONST(d, iptr[1].val.i);
2764                                 }
2765                         if ((a >= 0) && (a <= 255)) {
2766                                 M_CMOVGE_IMM(s1, a, d);
2767                                 }
2768                         else {
2769                                 ICONST(REG_ITMP2, a);
2770                                 M_CMOVGE(s1, REG_ITMP2, d);
2771                                 }
2772                         store_reg_to_var_int(iptr->dst, d);
2773                         break;
2774
2775                 case ICMD_IFGT_ICONST:  /* ..., value ==> ..., constant               */
2776                                         /* val.i = constant                           */
2777
2778                         var_to_reg_int(s1, src, REG_ITMP1);
2779                         d = reg_of_var(iptr->dst, REG_ITMP3);
2780                         a = iptr->val.i;
2781                         if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2782                                 if ((a == 1) && (iptr[1].val.i == 0)) {
2783                                         M_CMPLT(REG_ZERO, s1, d);
2784                                         store_reg_to_var_int(iptr->dst, d);
2785                                         break;
2786                                         }
2787                                 if ((a == 0) && (iptr[1].val.i == 1)) {
2788                                         M_CMPLE(s1, REG_ZERO, d);
2789                                         store_reg_to_var_int(iptr->dst, d);
2790                                         break;
2791                                         }
2792                                 if (s1 == d) {
2793                                         M_MOV(s1, REG_ITMP1);
2794                                         s1 = REG_ITMP1;
2795                                         }
2796                                 ICONST(d, iptr[1].val.i);
2797                                 }
2798                         if ((a >= 0) && (a <= 255)) {
2799                                 M_CMOVGT_IMM(s1, a, d);
2800                                 }
2801                         else {
2802                                 ICONST(REG_ITMP2, a);
2803                                 M_CMOVGT(s1, REG_ITMP2, d);
2804                                 }
2805                         store_reg_to_var_int(iptr->dst, d);
2806                         break;
2807
2808                 case ICMD_IFLE_ICONST:  /* ..., value ==> ..., constant               */
2809                                         /* val.i = constant                           */
2810
2811                         var_to_reg_int(s1, src, REG_ITMP1);
2812                         d = reg_of_var(iptr->dst, REG_ITMP3);
2813                         a = iptr->val.i;
2814                         if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2815                                 if ((a == 1) && (iptr[1].val.i == 0)) {
2816                                         M_CMPLE(s1, REG_ZERO, d);
2817                                         store_reg_to_var_int(iptr->dst, d);
2818                                         break;
2819                                         }
2820                                 if ((a == 0) && (iptr[1].val.i == 1)) {
2821                                         M_CMPLT(REG_ZERO, s1, d);
2822                                         store_reg_to_var_int(iptr->dst, d);
2823                                         break;
2824                                         }
2825                                 if (s1 == d) {
2826                                         M_MOV(s1, REG_ITMP1);
2827                                         s1 = REG_ITMP1;
2828                                         }
2829                                 ICONST(d, iptr[1].val.i);
2830                                 }
2831                         if ((a >= 0) && (a <= 255)) {
2832                                 M_CMOVLE_IMM(s1, a, d);
2833                                 }
2834                         else {
2835                                 ICONST(REG_ITMP2, a);
2836                                 M_CMOVLE(s1, REG_ITMP2, d);
2837                                 }
2838                         store_reg_to_var_int(iptr->dst, d);
2839                         break;
2840
2841
2842                 case ICMD_IRETURN:      /* ..., retvalue ==> ...                      */
2843                 case ICMD_LRETURN:
2844                 case ICMD_ARETURN:
2845
2846 #ifdef USE_THREADS
2847                         if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2848                                 a = dseg_addaddress ((void*) (builtin_monitorexit));
2849                                 M_ALD(REG_PV, REG_PV, a);
2850                                 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
2851                                 M_JSR(REG_RA, REG_PV);
2852                                 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2853                                 }                       
2854 #endif
2855                         var_to_reg_int(s1, src, REG_RESULT);
2856                         M_INTMOVE(s1, REG_RESULT);
2857                         goto nowperformreturn;
2858
2859                 case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
2860                 case ICMD_DRETURN:
2861
2862 #ifdef USE_THREADS
2863                         if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2864                                 a = dseg_addaddress ((void*) (builtin_monitorexit));
2865                                 M_ALD(REG_PV, REG_PV, a);
2866                                 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
2867                                 M_JSR(REG_RA, REG_PV);
2868                                 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2869                                 }                       
2870 #endif
2871                         var_to_reg_flt(s1, src, REG_FRESULT);
2872                         M_FLTMOVE(s1, REG_FRESULT);
2873                         goto nowperformreturn;
2874
2875                 case ICMD_RETURN:      /* ...  ==> ...                                */
2876
2877 #ifdef USE_THREADS
2878                         if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2879                                 a = dseg_addaddress ((void*) (builtin_monitorexit));
2880                                 M_ALD(REG_PV, REG_PV, a);
2881                                 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
2882                                 M_JSR(REG_RA, REG_PV);
2883                                 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2884                                 }                       
2885 #endif
2886
2887 nowperformreturn:
2888                         {
2889                         int r, p;
2890                         
2891                         p = parentargs_base;
2892                         
2893                         /* restore return address                                         */
2894
2895                         if (!isleafmethod)
2896                                 {p--;  M_LLD (REG_RA, REG_SP, 8 * p);}
2897
2898                         /* restore saved registers                                        */
2899
2900                         for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
2901                                         {p--; M_LLD(savintregs[r], REG_SP, 8 * p);}
2902                         for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
2903                                         {p--; M_DLD(savfltregs[r], REG_SP, 8 * p);}
2904
2905                         /* deallocate stack                                               */
2906
2907                         if (parentargs_base)
2908                                 {M_LDA(REG_SP, REG_SP, parentargs_base*8);}
2909
2910                         /* call trace function */
2911
2912                         if (runverbose) {
2913                                 M_LDA (REG_SP, REG_SP, -24);
2914                                 M_AST(REG_RA, REG_SP, 0);
2915                                 M_LST(REG_RESULT, REG_SP, 8);
2916                                 M_DST(REG_FRESULT, REG_SP,16);
2917                                 a = dseg_addaddress (method);
2918                                 M_ALD(argintregs[0], REG_PV, a);
2919                                 M_MOV(REG_RESULT, argintregs[1]);
2920                                 M_FLTMOVE(REG_FRESULT, argfltregs[2]);
2921                                 a = dseg_addaddress ((void*) (builtin_displaymethodstop));
2922                                 M_ALD(REG_PV, REG_PV, a);
2923                                 M_JSR (REG_RA, REG_PV);
2924                                 s1 = (int)((u1*) mcodeptr - mcodebase);
2925                                 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
2926                                 else {
2927                                         s4 ml=-s1, mh=0;
2928                                         while (ml<-32768) { ml+=65536; mh--; }
2929                                         M_LDA (REG_PV, REG_RA, ml );
2930                                         M_LDAH (REG_PV, REG_PV, mh );
2931                                         }
2932                                 M_DLD(REG_FRESULT, REG_SP,16);
2933                                 M_LLD(REG_RESULT, REG_SP, 8);
2934                                 M_ALD(REG_RA, REG_SP, 0);
2935                                 M_LDA (REG_SP, REG_SP, 24);
2936                                 }
2937
2938                         M_RET(REG_ZERO, REG_RA);
2939                         ALIGNCODENOP;
2940                         }
2941                         break;
2942
2943
2944                 case ICMD_TABLESWITCH:  /* ..., index ==> ...                         */
2945                         {
2946                         s4 i, l, *s4ptr;
2947
2948                         s4ptr = iptr->val.a;
2949                         l = s4ptr[1];                          /* low     */
2950                         i = s4ptr[2];                          /* high    */
2951                         
2952                         var_to_reg_int(s1, src, REG_ITMP1);
2953                         if (l == 0)
2954                                 {M_INTMOVE(s1, REG_ITMP1);}
2955                         else
2956                                 M_LDA(REG_ITMP1, s1, -l);
2957                         i = i - l + 1;
2958
2959                         /* range check */
2960
2961                         if (i <= 256)
2962                                 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
2963                         else {
2964                                 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
2965                                 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
2966                                 }
2967                         M_BEQZ(REG_ITMP2, 0);
2968                         mcode_addreference(BlockPtrOfPC(s4ptr[0]), mcodeptr);
2969
2970                         /* build jump table top down and use address of lowest entry */
2971
2972                         s4ptr += 3 + i;
2973                         while (--i >= 0) {
2974                                 dseg_addtarget(BlockPtrOfPC(*--s4ptr));
2975                                 }
2976                         }
2977
2978                         /* length of dataseg after last dseg_addtarget is used by load */
2979
2980                         M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
2981                         M_ALD(REG_ITMP2, REG_ITMP2, -dseglen);
2982                         M_JMP(REG_ZERO, REG_ITMP2);
2983                         ALIGNCODENOP;
2984                         break;
2985
2986
2987                 case ICMD_LOOKUPSWITCH: /* ..., key ==> ...                           */
2988                         {
2989                         s4 i, l, val, *s4ptr;
2990
2991                         s4ptr = iptr->val.a;
2992                         l = s4ptr[0];                          /* default  */
2993                         i = s4ptr[1];                          /* count    */
2994                         
2995                         MCODECHECK((i<<2)+8);
2996                         var_to_reg_int(s1, src, REG_ITMP1);
2997                         while (--i >= 0) {
2998                                 s4ptr += 2;
2999                                 val = s4ptr[0];
3000                                 if ((val >= 0) && (val <= 255)) {
3001                                         M_CMPEQ_IMM(s1, val, REG_ITMP2);
3002                                         }
3003                                 else {
3004                                         if ((val >= -32768) && (val <= 32767)) {
3005                                                 M_LDA(REG_ITMP2, REG_ZERO, val);
3006                                                 } 
3007                                         else {
3008                                                 a = dseg_adds4 (val);
3009                                                 M_ILD(REG_ITMP2, REG_PV, a);
3010                                                 }
3011                                         M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
3012                                         }
3013                                 M_BNEZ(REG_ITMP2, 0);
3014                                 mcode_addreference(BlockPtrOfPC(s4ptr[1]), mcodeptr);
3015                                 }
3016
3017                         M_BR(0);
3018                         mcode_addreference(BlockPtrOfPC(l), mcodeptr);
3019                         ALIGNCODENOP;
3020                         break;
3021                         }
3022
3023
3024                 case ICMD_BUILTIN3:     /* ..., arg1, arg2, arg3 ==> ...              */
3025                                         /* op1 = return type, val.a = function pointer*/
3026                         s3 = 3;
3027                         goto gen_method;
3028
3029                 case ICMD_BUILTIN2:     /* ..., arg1, arg2 ==> ...                    */
3030                                         /* op1 = return type, val.a = function pointer*/
3031                         s3 = 2;
3032                         goto gen_method;
3033
3034                 case ICMD_BUILTIN1:     /* ..., arg1 ==> ...                          */
3035                                         /* op1 = return type, val.a = function pointer*/
3036                         s3 = 1;
3037                         goto gen_method;
3038
3039                 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ...            */
3040                                         /* op1 = arg count, val.a = method pointer    */
3041
3042                 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3043                                         /* op1 = arg count, val.a = method pointer    */
3044
3045                 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3046                                         /* op1 = arg count, val.a = method pointer    */
3047
3048                 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
3049                                         /* op1 = arg count, val.a = method pointer    */
3050
3051                         s3 = iptr->op1;
3052
3053 gen_method: {
3054                         methodinfo   *m;
3055                         classinfo    *ci;
3056
3057                         MCODECHECK((s3 << 1) + 64);
3058
3059                         /* copy arguments to registers or stack location                  */
3060
3061                         for (; --s3 >= 0; src = src->prev) {
3062                                 if (src->varkind == ARGVAR)
3063                                         continue;
3064                                 if (IS_INT_LNG_TYPE(src->type)) {
3065                                         if (s3 < INT_ARG_CNT) {
3066                                                 s1 = argintregs[s3];
3067                                                 var_to_reg_int(d, src, s1);
3068                                                 M_INTMOVE(d, s1);
3069                                                 }
3070                                         else  {
3071                                                 var_to_reg_int(d, src, REG_ITMP1);
3072                                                 M_LST(d, REG_SP, 8 * (s3 - INT_ARG_CNT));
3073                                                 }
3074                                         }
3075                                 else
3076                                         if (s3 < FLT_ARG_CNT) {
3077                                                 s1 = argfltregs[s3];
3078                                                 var_to_reg_flt(d, src, s1);
3079                                                 M_FLTMOVE(d, s1);
3080                                                 }
3081                                         else {
3082                                                 var_to_reg_flt(d, src, REG_FTMP1);
3083                                                 M_DST(d, REG_SP, 8 * (s3 - FLT_ARG_CNT));
3084                                                 }
3085                                 } /* end of for */
3086
3087                         m = iptr->val.a;
3088                         switch (iptr->opc) {
3089                                 case ICMD_BUILTIN3:
3090                                 case ICMD_BUILTIN2:
3091                                 case ICMD_BUILTIN1:
3092                                         a = dseg_addaddress ((void*) (m));
3093
3094                                         M_ALD(REG_PV, REG_PV, a); /* Pointer to built-in-function */
3095                                         d = iptr->op1;
3096                                         goto makeactualcall;
3097
3098                                 case ICMD_INVOKESTATIC:
3099                                 case ICMD_INVOKESPECIAL:
3100                                         a = dseg_addaddress (m->stubroutine);
3101
3102                                         M_ALD(REG_PV, REG_PV, a );       /* method pointer in r27 */
3103
3104                                         d = m->returntype;
3105                                         goto makeactualcall;
3106
3107                                 case ICMD_INVOKEVIRTUAL:
3108
3109                                         gen_nullptr_check(argintregs[0]);
3110                                         M_ALD(REG_METHODPTR, argintregs[0],
3111                                                                  OFFSET(java_objectheader, vftbl));
3112                                         M_ALD(REG_PV, REG_METHODPTR, OFFSET(vftbl, table[0]) +
3113                                                                 sizeof(methodptr) * m->vftblindex);
3114
3115                                         d = m->returntype;
3116                                         goto makeactualcall;
3117
3118                                 case ICMD_INVOKEINTERFACE:
3119                                         ci = m->class;
3120                                         
3121                                         gen_nullptr_check(argintregs[0]);
3122                                         M_ALD(REG_METHODPTR, argintregs[0],
3123                                                                  OFFSET(java_objectheader, vftbl));    
3124                                         M_ALD(REG_METHODPTR, REG_METHODPTR,
3125                                               OFFSET(vftbl, interfacetable[0]) -
3126                                               sizeof(methodptr*) * ci->index);
3127                                         M_ALD(REG_PV, REG_METHODPTR,
3128                                                             sizeof(methodptr) * (m - ci->methods));
3129
3130                                         d = m->returntype;
3131                                         goto makeactualcall;
3132
3133                                 default:
3134                                         d = 0;
3135                                         sprintf (logtext, "Unkown ICMD-Command: %d", iptr->opc);
3136                                         error ();
3137                                 }
3138
3139 makeactualcall:
3140
3141                         M_JSR (REG_RA, REG_PV);
3142
3143                         /* recompute pv */
3144
3145                         s1 = (int)((u1*) mcodeptr - mcodebase);
3146                         if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
3147                         else {
3148                                 s4 ml=-s1, mh=0;
3149                                 while (ml<-32768) { ml+=65536; mh--; }
3150                                 M_LDA (REG_PV, REG_RA, ml );
3151                                 M_LDAH (REG_PV, REG_PV, mh );
3152                                 }
3153
3154                         /* d contains return type */
3155
3156                         if (d != TYPE_VOID) {
3157                                 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3158                                         s1 = reg_of_var(iptr->dst, REG_RESULT);
3159                                         M_INTMOVE(REG_RESULT, s1);
3160                                         store_reg_to_var_int(iptr->dst, s1);
3161                                         }
3162                                 else {
3163                                         s1 = reg_of_var(iptr->dst, REG_FRESULT);
3164                                         M_FLTMOVE(REG_FRESULT, s1);
3165                                         store_reg_to_var_flt(iptr->dst, s1);
3166                                         }
3167                                 }
3168                         }
3169                         break;
3170
3171
3172                 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
3173
3174                                       /* op1:   0 == array, 1 == class                */
3175                                       /* val.a: (classinfo*) superclass               */
3176
3177 /*          superclass is an interface:
3178  *
3179  *          return (sub != NULL) &&
3180  *                 (sub->vftbl->interfacetablelength > super->index) &&
3181  *                 (sub->vftbl->interfacetable[-super->index] != NULL);
3182  *
3183  *          superclass is a class:
3184  *
3185  *          return ((sub != NULL) && (0
3186  *                  <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3187  *                  super->vftbl->diffvall));
3188  */
3189
3190                         {
3191                         classinfo *super = (classinfo*) iptr->val.a;
3192                         
3193                         var_to_reg_int(s1, src, REG_ITMP1);
3194                         d = reg_of_var(iptr->dst, REG_ITMP3);
3195                         if (s1 == d) {
3196                                 M_MOV(s1, REG_ITMP1);
3197                                 s1 = REG_ITMP1;
3198                                 }
3199                         M_CLR(d);
3200                         if (iptr->op1) {                               /* class/interface */
3201                                 if (super->flags & ACC_INTERFACE) {        /* interface       */
3202                                         M_BEQZ(s1, 6);
3203                                         M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3204                                         M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3205                                         M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3206                                         M_BLEZ(REG_ITMP2, 2);
3207                                         M_ALD(REG_ITMP1, REG_ITMP1,
3208                                               OFFSET(vftbl, interfacetable[0]) -
3209                                               super->index * sizeof(methodptr*));
3210                                         M_CMPULT(REG_ZERO, REG_ITMP1, d);      /* REG_ITMP1 != 0  */
3211                                         }
3212                                 else {                                     /* class           */
3213                                         s2 = super->vftbl->diffval;
3214                                         M_BEQZ(s1, 4 + (s2 > 255));
3215                                         M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3216                                         M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3217                                         M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3218                                         if (s2 <= 255)
3219                                                 M_CMPULE_IMM(REG_ITMP1, s2, d);
3220                                         else {
3221                                                 M_LDA(REG_ITMP2, REG_ZERO, s2);
3222                                                 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3223                                                 }
3224                                         }
3225                                 }
3226                         else
3227                                 panic ("internal error: no inlined array instanceof");
3228                         }
3229                         store_reg_to_var_int(iptr->dst, d);
3230                         break;
3231
3232                 case ICMD_CHECKCAST:  /* ..., objectref ==> ..., objectref            */
3233
3234                                       /* op1:   0 == array, 1 == class                */
3235                                       /* val.a: (classinfo*) superclass               */
3236
3237 /*          superclass is an interface:
3238  *
3239  *          OK if ((sub == NULL) ||
3240  *                 (sub->vftbl->interfacetablelength > super->index) &&
3241  *                 (sub->vftbl->interfacetable[-super->index] != NULL));
3242  *
3243  *          superclass is a class:
3244  *
3245  *          OK if ((sub == NULL) || (0
3246  *                 <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3247  *                 super->vftbl->diffvall));
3248  */
3249
3250                         {
3251                         classinfo *super = (classinfo*) iptr->val.a;
3252                         
3253                         d = reg_of_var(iptr->dst, REG_ITMP3);
3254                         var_to_reg_int(s1, src, d);
3255                         if (iptr->op1) {                               /* class/interface */
3256                                 if (super->flags & ACC_INTERFACE) {        /* interface       */
3257                                         M_BEQZ(s1, 6);
3258                                         M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3259                                         M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3260                                         M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
3261                                         M_BLEZ(REG_ITMP2, 0);
3262                                         mcode_addxcastrefs(mcodeptr);
3263                                         M_ALD(REG_ITMP2, REG_ITMP1,
3264                                               OFFSET(vftbl, interfacetable[0]) -
3265                                               super->index * sizeof(methodptr*));
3266                                         M_BEQZ(REG_ITMP2, 0);
3267                                         mcode_addxcastrefs(mcodeptr);
3268                                         }
3269                                 else {                                     /* class           */
3270                                         s2 = super->vftbl->diffval;
3271                                         M_BEQZ(s1, 4 + (s2 != 0) + (s2 > 255));
3272                                         M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3273                                         M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3274                                         M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
3275                                         if (s2 == 0) {
3276                                                 M_BNEZ(REG_ITMP1, 0);
3277                                                 }
3278                                         else if (s2 <= 255) {
3279                                                 M_CMPULE_IMM(REG_ITMP1, s2, REG_ITMP2);
3280                                                 M_BEQZ(REG_ITMP2, 0);
3281                                                 }
3282                                         else {
3283                                                 M_LDA(REG_ITMP2, REG_ZERO, s2);
3284                                                 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3285                                                 M_BEQZ(REG_ITMP2, 0);
3286                                                 }
3287                                         mcode_addxcastrefs(mcodeptr);
3288                                         }
3289                                 }
3290                         else
3291                                 panic ("internal error: no inlined array checkcast");
3292                         }
3293                         M_INTMOVE(s1, d);
3294                         store_reg_to_var_int(iptr->dst, d);
3295                         break;
3296
3297                 case ICMD_CHECKASIZE:  /* ..., size ==> ..., size                     */
3298
3299                         var_to_reg_int(s1, src, REG_ITMP1);
3300                         M_BLTZ(s1, 0);
3301                         mcode_addxcheckarefs(mcodeptr);
3302                         break;
3303
3304                 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref  */
3305                                       /* op1 = dimension, val.a = array descriptor    */
3306
3307                         /* check for negative sizes and copy sizes to stack if necessary  */
3308
3309                         MCODECHECK((iptr->op1 << 1) + 64);
3310
3311                         for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3312                                 var_to_reg_int(s2, src, REG_ITMP1);
3313                                 M_BLTZ(s2, 0);
3314                                 mcode_addxcheckarefs(mcodeptr);
3315
3316                                 /* copy sizes to stack (argument numbers >= INT_ARG_CNT)      */
3317
3318                                 if (src->varkind != ARGVAR) {
3319                                         M_LST(s2, REG_SP, 8 * (s1 + INT_ARG_CNT));
3320                                         }
3321                                 }
3322
3323                         /* a0 = dimension count */
3324
3325                         M_LDA(argintregs[0], REG_ZERO, iptr->op1);
3326
3327                         /* a1 = arraydescriptor */
3328
3329                         a = dseg_addaddress(iptr->val.a);
3330                         M_ALD(argintregs[1], REG_PV, a);
3331
3332                         /* a2 = pointer to dimensions = stack pointer */
3333
3334                         M_INTMOVE(REG_SP, argintregs[2]);
3335
3336                         a = dseg_addaddress((void*) (builtin_nmultianewarray));
3337                         M_ALD(REG_PV, REG_PV, a);
3338                         M_JSR(REG_RA, REG_PV);
3339                         s1 = (int)((u1*) mcodeptr - mcodebase);
3340                         if (s1 <= 32768)
3341                                 M_LDA (REG_PV, REG_RA, -s1);
3342                         else {
3343                                 s4 ml = -s1, mh = 0;
3344                                 while (ml < -32768) {ml += 65536; mh--;}
3345                                 M_LDA(REG_PV, REG_RA, ml);
3346                                 M_LDAH(REG_PV, REG_PV, mh);
3347                                 }
3348                         s1 = reg_of_var(iptr->dst, REG_RESULT);
3349                         M_INTMOVE(REG_RESULT, s1);
3350                         store_reg_to_var_int(iptr->dst, s1);
3351                         break;
3352
3353
3354                 default: sprintf (logtext, "Unknown pseudo command: %d", iptr->opc);
3355                          error();
3356         } /* switch */
3357         } /* for instruction */
3358
3359         /* copy values to interface registers */
3360
3361         src = bptr->outstack;
3362         len = bptr->outdepth;
3363         MCODECHECK(64+len);
3364         while (src) {
3365                 len--;
3366                 if ((src->varkind != STACKVAR)) {
3367                         s2 = src->type;
3368                         if (IS_FLT_DBL_TYPE(s2)) {
3369                                 var_to_reg_flt(s1, src, REG_FTMP1);
3370                                 if (!(interfaces[len][s2].flags & INMEMORY)) {
3371                                         M_FLTMOVE(s1,interfaces[len][s2].regoff);
3372                                         }
3373                                 else {
3374                                         M_DST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3375                                         }
3376                                 }
3377                         else {
3378                                 var_to_reg_int(s1, src, REG_ITMP1);
3379                                 if (!(interfaces[len][s2].flags & INMEMORY)) {
3380                                         M_INTMOVE(s1,interfaces[len][s2].regoff);
3381                                         }
3382                                 else {
3383                                         M_LST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3384                                         }
3385                                 }
3386                         }
3387                 src = src->prev;
3388                 }
3389         } /* if (bptr -> flags >= BBREACHED) */
3390         } /* for basic block */
3391
3392         bptr -> mpc = (int)((u1*) mcodeptr - mcodebase);
3393
3394         {
3395         /* generate bound check stubs */
3396
3397         s4 *xcodeptr = NULL;
3398         
3399         for (; xboundrefs != NULL; xboundrefs = xboundrefs->next) {
3400                 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3401                         gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos, 
3402                                 xboundrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3403                         continue;
3404                         }
3405
3406                 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos, 
3407                                   xboundrefs->branchpos, (u1*) mcodeptr - mcodebase);
3408
3409                 MCODECHECK(8);
3410
3411                 M_LDA(REG_ITMP2_XPC, REG_PV, xboundrefs->branchpos);
3412
3413                 if (xcodeptr != NULL) {
3414                         M_BR((xcodeptr-mcodeptr)-1);
3415                         }
3416                 else {
3417                         xcodeptr = mcodeptr;
3418
3419                         a = dseg_addaddress(proto_java_lang_ArrayIndexOutOfBoundsException);
3420                         M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3421
3422                         a = dseg_addaddress(asm_handle_exception);
3423                         M_ALD(REG_ITMP3, REG_PV, a);
3424
3425                         M_JMP(REG_ZERO, REG_ITMP3);
3426                         }
3427                 }
3428
3429         /* generate negative array size check stubs */
3430
3431         xcodeptr = NULL;
3432         
3433         for (; xcheckarefs != NULL; xcheckarefs = xcheckarefs->next) {
3434                 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3435                         gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos, 
3436                                 xcheckarefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3437                         continue;
3438                         }
3439
3440                 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos, 
3441                                   xcheckarefs->branchpos, (u1*) mcodeptr - mcodebase);
3442
3443                 MCODECHECK(8);
3444
3445                 M_LDA(REG_ITMP2_XPC, REG_PV, xcheckarefs->branchpos);
3446
3447                 if (xcodeptr != NULL) {
3448                         M_BR((xcodeptr-mcodeptr)-1);
3449                         }
3450                 else {
3451                         xcodeptr = mcodeptr;
3452
3453                         a = dseg_addaddress(proto_java_lang_NegativeArraySizeException);
3454                         M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3455
3456                         a = dseg_addaddress(asm_handle_exception);
3457                         M_ALD(REG_ITMP3, REG_PV, a);
3458
3459                         M_JMP(REG_ZERO, REG_ITMP3);
3460                         }
3461                 }
3462
3463         /* generate cast check stubs */
3464
3465         xcodeptr = NULL;
3466         
3467         for (; xcastrefs != NULL; xcastrefs = xcastrefs->next) {
3468                 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3469                         gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos, 
3470                                 xcastrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3471                         continue;
3472                         }
3473
3474                 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos, 
3475                                   xcastrefs->branchpos, (u1*) mcodeptr - mcodebase);
3476
3477                 MCODECHECK(8);
3478
3479                 M_LDA(REG_ITMP2_XPC, REG_PV, xcastrefs->branchpos);
3480
3481                 if (xcodeptr != NULL) {
3482                         M_BR((xcodeptr-mcodeptr)-1);
3483                         }
3484                 else {
3485                         xcodeptr = mcodeptr;
3486
3487                         a = dseg_addaddress(proto_java_lang_ClassCastException);
3488                         M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3489
3490                         a = dseg_addaddress(asm_handle_exception);
3491                         M_ALD(REG_ITMP3, REG_PV, a);
3492
3493                         M_JMP(REG_ZERO, REG_ITMP3);
3494                         }
3495                 }
3496
3497
3498 #ifdef SOFTNULLPTRCHECK
3499
3500         /* generate null pointer check stubs */
3501
3502         xcodeptr = NULL;
3503
3504         for (; xnullrefs != NULL; xnullrefs = xnullrefs->next) {
3505                 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3506                         gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos, 
3507                                 xnullrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3508                         continue;
3509                         }
3510
3511                 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos, 
3512                                   xnullrefs->branchpos, (u1*) mcodeptr - mcodebase);
3513
3514                 MCODECHECK(8);
3515
3516                 M_LDA(REG_ITMP2_XPC, REG_PV, xnullrefs->branchpos - 4);
3517
3518                 if (xcodeptr != NULL) {
3519                         M_BR((xcodeptr-mcodeptr)-1);
3520                         }
3521                 else {
3522                         xcodeptr = mcodeptr;
3523
3524                         a = dseg_addaddress(proto_java_lang_NullPointerException);
3525                         M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3526
3527                         a = dseg_addaddress(asm_handle_exception);
3528                         M_ALD(REG_ITMP3, REG_PV, a);
3529
3530                         M_JMP(REG_ZERO, REG_ITMP3);
3531                         }
3532                 }
3533
3534 #endif
3535         }
3536
3537         mcode_finish((int)((u1*) mcodeptr - mcodebase));
3538 }
3539
3540
3541 /* redefinition of code generation macros (compiling into array) **************/
3542
3543 /* 
3544 These macros are newly defined to allow code generation into an array.
3545 This is necessary, because the original M_.. macros generate code by
3546 calling 'mcode_adds4' that uses an additional data structure to
3547 receive the code.
3548
3549 For a faster (but less flexible) version to generate code, these
3550 macros directly use the (s4* p) - pointer to put the code directly
3551 in a locally defined array.
3552 This makes sense only for the stub-generation-routines below.
3553 */
3554
3555 #undef M_OP3
3556 #define M_OP3(op,fu,a,b,c,const) \
3557         *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<(16-3*(const)))| \
3558         ((const)<<12)|((fu)<<5)|((c)) )
3559 #undef M_FOP3
3560 #define M_FOP3(op,fu,a,b,c) \
3561         *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<16)|((fu)<<5)|(c) )
3562 #undef M_BRA
3563 #define M_BRA(op,a,disp) \
3564         *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((disp)&0x1fffff) )
3565 #undef M_MEM
3566 #define M_MEM(op,a,b,disp) \
3567         *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<16)|((disp)&0xffff) )
3568
3569
3570 /* function createcompilerstub *************************************************
3571
3572         creates a stub routine which calls the compiler
3573         
3574 *******************************************************************************/
3575
3576 #define COMPSTUBSIZE 3
3577
3578 u1 *createcompilerstub (methodinfo *m)
3579 {
3580         u8 *s = CNEW (u8, COMPSTUBSIZE);    /* memory to hold the stub            */
3581         s4 *p = (s4*) s;                    /* code generation pointer            */
3582         
3583                                             /* code for the stub                  */
3584         M_ALD (REG_PV, REG_PV, 16);         /* load pointer to the compiler       */
3585         M_JMP (0, REG_PV);                  /* jump to the compiler, return address
3586                                                in reg 0 is used as method pointer */
3587         s[1] = (u8) m;                      /* literals to be adressed            */  
3588         s[2] = (u8) asm_call_jit_compiler;  /* jump directly via PV from above    */
3589
3590 #ifdef STATISTICS
3591         count_cstub_len += COMPSTUBSIZE * 8;
3592 #endif
3593
3594         return (u1*) s;
3595 }
3596
3597
3598 /* function removecompilerstub *************************************************
3599
3600      deletes a compilerstub from memory  (simply by freeing it)
3601
3602 *******************************************************************************/
3603
3604 void removecompilerstub (u1 *stub) 
3605 {
3606         CFREE (stub, COMPSTUBSIZE * 8);
3607 }
3608
3609
3610 /* function: createnativestub **************************************************
3611
3612         creates a stub routine which calls a native method
3613         
3614 *******************************************************************************/
3615
3616 #define NATIVESTUBSIZE 11
3617
3618 u1 *createnativestub (functionptr f, methodinfo *m)
3619 {
3620         u8 *s = CNEW (u8, NATIVESTUBSIZE);  /* memory to hold the stub            */
3621         s4 *p = (s4*) s;                    /* code generation pointer            */
3622
3623         M_LDA  (REG_SP, REG_SP, -8);        /* build up stackframe                */
3624         M_AST  (REG_RA, REG_SP, 0);         /* store return address               */
3625
3626         M_ALD  (REG_PV, REG_PV, 8*8);       /* load adress of native method       */
3627         M_JSR  (REG_RA, REG_PV);            /* call native method                 */
3628
3629         M_LDA  (REG_PV, REG_RA, -4*4);      /* recompute pv from ra               */
3630         M_ALD  (REG_ITMP3, REG_PV, 9*8);    /* get address of exceptionptr        */
3631
3632         M_ALD  (REG_RA, REG_SP, 0);         /* load return address                */
3633         M_ALD  (REG_ITMP1, REG_ITMP3, 0);   /* load exception into reg. itmp1     */
3634
3635         M_LDA  (REG_SP, REG_SP, 8);         /* remove stackframe                  */
3636         M_BNEZ (REG_ITMP1, 1);              /* if no exception then return        */
3637
3638         M_RET  (REG_ZERO, REG_RA);          /* return to caller                   */
3639         
3640         M_AST  (REG_ZERO, REG_ITMP3, 0);    /* store NULL into exceptionptr       */
3641         M_LDA  (REG_ITMP2, REG_RA, -4);     /* move fault address into reg. itmp2 */
3642
3643         M_ALD  (REG_ITMP3, REG_PV,10*8);    /* load asm exception handler address */
3644         M_JMP  (REG_ZERO, REG_ITMP3);       /* jump to asm exception handler      */
3645
3646
3647         s[8] = (u8) f;                      /* address of native method           */
3648         s[9] = (u8) (&exceptionptr);        /* address of exceptionptr            */
3649         s[10]= (u8) (asm_handle_nat_exception); /* addr of asm exception handler  */
3650
3651 #ifdef STATISTICS
3652         count_nstub_len += NATIVESTUBSIZE * 8;
3653 #endif
3654
3655         return (u1*) s;
3656 }
3657
3658
3659 /* function: removenativestub **************************************************
3660
3661     removes a previously created native-stub from memory
3662     
3663 *******************************************************************************/
3664
3665 void removenativestub (u1 *stub)
3666 {
3667         CFREE (stub, NATIVESTUBSIZE * 8);
3668 }
3669
3670
3671 /*
3672  * These are local overrides for various environment variables in Emacs.
3673  * Please do not remove this and leave it at the end of the file, where
3674  * Emacs will automagically detect them.
3675  * ---------------------------------------------------------------------
3676  * Local variables:
3677  * mode: c
3678  * indent-tabs-mode: t
3679  * c-basic-offset: 4
3680  * tab-width: 4
3681  * End:
3682  */