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