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