6f823f2751d93cfc67d4520e4cec48983f47b4b0
[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 
27 operands only need 32 bits.
28 This is done by a canonical representation:
29
30 32-bit integers are allways stored as sign-extended 64-bit values
31 (this approach is directly supported by the Alpha architecture and
32 is very easy to implement).
33
34 32-bit-floats are stored in a 64-bit doubleprecision register by
35 simply expanding the exponent and mantissa with zeroes.
36 (also supported by the architecture)
37
38
39 Stackframes:
40
41 The calling conventions and the layout of the stack is 
42 explained in detail in the documention file: calling.doc
43
44 *******************************************************************************/
45
46
47 /*********** additional functions and macros to generate code *****************/
48
49 #define BlockPtrOfPC(pc)        block+block_index[pc]
50
51 #ifdef STATISTICS
52 #define COUNT_SPILLS count_spills++
53 #else
54 #define COUNT_SPILLS
55 #endif
56
57
58 /* gen_nullptr_check(objreg) */
59
60 #ifdef SOFTNULLPTRCHECK
61 #define gen_nullptr_check(objreg) \
62         if (checknull) {\
63         M_BEQZ((objreg), 0);\
64         mcode_addxnullrefs(mcodeptr);\
65         }
66 #else
67 #define gen_nullptr_check(objreg)
68 #endif
69
70
71 /* MCODECHECK(icnt) */
72
73 #define MCODECHECK(icnt) \
74         if((mcodeptr+(icnt))>mcodeend)mcodeptr=mcode_increase((u1*)mcodeptr)
75
76 /* M_INTMOVE:
77      generates an integer-move from register a to b.
78      if a and b are the same int-register, no code will be generated.
79 */ 
80
81 #define M_INTMOVE(a,b) if(a!=b){M_OR(a,a,b,0);}
82
83
84 /* M_FLTMOVE:
85     generates a floating-point-move from register a to b.
86     if a and b are the same float-register, no code will be generated
87 */ 
88
89 #define M_FLTMOVE(a,b) if(a!=b){M_FMOV(a,b);}
90
91
92 /* var_to_reg_xxx:
93     this function generates code to fetch data from a pseudo-register
94     into a real register. 
95     If the pseudo-register has actually been assigned to a real 
96     register, no code will be emitted, since following operations
97     can use this register directly.
98     
99     v: pseudoregister to be fetched from
100     tempregnum: temporary register to be used if v is actually spilled to ram
101
102     return: the register number, where the operand can be found after 
103             fetching (this wil be either tempregnum or the register
104             number allready given to v)
105 */
106
107 #define var_to_reg_int(regnr,v,tempnr) { \
108         if ((v)->flags & INMEMORY) \
109                 {COUNT_SPILLS;M_LLD(tempnr,REG_SP,8*(v)->regoff);regnr=tempnr;} \
110         else regnr=(v)->regoff; \
111 }
112
113
114 #define var_to_reg_flt(regnr,v,tempnr) { \
115         if ((v)->flags & INMEMORY) \
116                 {COUNT_SPILLS;M_DLD(tempnr,REG_SP,8*(v)->regoff);regnr=tempnr;} \
117         else regnr=(v)->regoff; \
118 }
119
120
121 /* reg_of_var:
122      This function determines a register, to which the result of an
123      operation should go, when it is ultimatively intended to store the result
124      in pseudoregister v.
125      If v is assigned to an actual register, this register will be
126      returned.
127      Otherwise (when v is spilled) this function returns tempregnum.
128      If not already done, regoff and flags are set in the stack location.
129 */        
130
131 static int reg_of_var(stackptr v, int tempregnum)
132 {
133         varinfo      *var;
134
135         switch (v->varkind) {
136                 case TEMPVAR:
137                         if (!(v->flags & INMEMORY))
138                                 return(v->regoff);
139                         break;
140                 case STACKVAR:
141                         var = &(interfaces[v->varnum][v->type]);
142                         v->regoff = var->regoff;
143                         if (!(var->flags & INMEMORY))
144                                 return(var->regoff);
145                         break;
146                 case LOCALVAR:
147                         var = &(locals[v->varnum][v->type]);
148                         v->regoff = var->regoff;
149                         if (!(var->flags & INMEMORY))
150                                 return(var->regoff);
151                         break;
152                 case ARGVAR:
153                         v->regoff = v->varnum;
154                         if (IS_FLT_DBL_TYPE(v->type)) {
155                                 if (v->varnum < fltreg_argnum) {
156                                         v->regoff = argfltregs[v->varnum];
157                                         return(argfltregs[v->varnum]);
158                                         }
159                                 }
160                         else
161                                 if (v->varnum < intreg_argnum) {
162                                         v->regoff = argintregs[v->varnum];
163                                         return(argintregs[v->varnum]);
164                                         }
165                         v->regoff -= intreg_argnum;
166                         break;
167                 }
168         v->flags |= INMEMORY;
169         return tempregnum;
170 }
171
172
173 /* store_reg_to_var_xxx:
174     This function generates the code to store the result of an operation
175     back into a spilled pseudo-variable.
176     If the pseudo-variable has not been spilled in the first place, this 
177     function will generate nothing.
178     
179     v ............ Pseudovariable
180     tempregnum ... Number of the temporary registers as returned by
181                    reg_of_var.
182 */      
183
184 #define store_reg_to_var_int(sptr, tempregnum) {       \
185         if ((sptr)->flags & INMEMORY) {                    \
186                 COUNT_SPILLS;                                  \
187                 M_LST(tempregnum, REG_SP, 8 * (sptr)->regoff); \
188                 }                                              \
189         }
190
191 #define store_reg_to_var_flt(sptr, tempregnum) {       \
192         if ((sptr)->flags & INMEMORY) {                    \
193                 COUNT_SPILLS;                                  \
194                 M_DST(tempregnum, REG_SP, 8 * (sptr)->regoff); \
195                 }                                              \
196         }
197
198
199 void asm_signal_exception(void *xptr, void *sigctx);
200
201 void catch_NullPointerException(int sig, int code, void *sigctx)
202 {
203         sigset_t nsig;
204
205         /* Reset signal handler - necessary for SysV, does no harm for BSD */
206
207         signal(sig, (void*) catch_NullPointerException);
208         sigemptyset(&nsig);
209         sigaddset(&nsig, sig);
210         sigprocmask(SIG_UNBLOCK, &nsig, NULL);
211         asm_signal_exception(proto_java_lang_NullPointerException, sigctx);
212 }
213
214 #ifdef __osf__
215
216 void init_exceptions(void)
217 {
218
219 #else
220
221 #include <asm/fpu.h>
222
223 extern unsigned long ieee_get_fp_control();
224 extern void ieee_set_fp_control(unsigned long fp_control);
225
226 void init_exceptions(void)
227 {
228 /* initialise floating point control */
229 ieee_set_fp_control(ieee_get_fp_control()
230                     & ~IEEE_TRAP_ENABLE_INV
231                     & ~IEEE_TRAP_ENABLE_DZE
232 /*                  & ~IEEE_TRAP_ENABLE_UNF   */
233                     & ~IEEE_TRAP_ENABLE_OVF);
234 #endif
235
236         /* Catch signal we need to convert to exceptions */
237         if (!checknull) {
238 #if defined(SIGSEGV)
239                 signal(SIGSEGV, (void*) catch_NullPointerException);
240 #endif
241 #if defined(SIGBUS)
242                 signal(SIGBUS, (void*) catch_NullPointerException);
243 #endif
244                 }
245 }
246
247
248 /*************************** function gen_mcode ********************************
249
250         generates machine code
251
252 *******************************************************************************/
253
254 #define         MethodPointer   -8
255 #define         FrameSize       -12
256 #define     IsSync          -16
257 #define     IsLeaf          -20
258 #define     IntSave         -24
259 #define     FltSave         -28
260 #define     ExTableSize     -32
261 #define     ExTableStart    -32
262
263 #define     ExEntrySize     -32
264 #define     ExStartPC       -8
265 #define     ExEndPC         -16
266 #define     ExHandlerPC     -24
267 #define     ExCatchType     -32
268
269 static void gen_mcode()
270 {
271         int  len, s1, s2, s3, d, bbs;
272         s4   a;
273         s4          *mcodeptr;
274         stackptr    src;
275         varinfo     *var;
276         basicblock  *bptr;
277         instruction *iptr;
278
279         {
280         int p, pa, t, l, r;
281
282         savedregs_num = (isleafmethod) ? 0 : 1;           /* space to save the RA */
283
284         /* space to save used callee saved registers */
285
286         savedregs_num += (savintregcnt - maxsavintreguse);
287         savedregs_num += (savfltregcnt - maxsavfltreguse);
288
289         parentargs_base = maxmemuse + savedregs_num;
290
291 #ifdef USE_THREADS
292         if (checksync && (method->flags & ACC_SYNCHRONIZED))
293                 parentargs_base++;
294 #endif
295
296         /* create method header */
297
298         (void) dseg_addaddress(method);                         /* MethodPointer  */
299         (void) dseg_adds4(parentargs_base * 8);                 /* FrameSize      */
300
301 #ifdef USE_THREADS
302         if (checksync && (method->flags & ACC_SYNCHRONIZED))
303                 (void) dseg_adds4((maxmemuse + 1) * 8);             /* IsSync         */
304         else
305 #endif
306                 (void) dseg_adds4(0);                               /* IsSync         */
307                                                
308         (void) dseg_adds4(isleafmethod);                        /* IsLeaf         */
309         (void) dseg_adds4(savintregcnt - maxsavintreguse);      /* IntSave        */
310         (void) dseg_adds4(savfltregcnt - maxsavfltreguse);      /* FltSave        */
311         (void) dseg_adds4(exceptiontablelength);                /* ExTableSize    */
312
313         for (len = 0; len < exceptiontablelength; len++) {
314                 dseg_addtarget(BlockPtrOfPC(extable[len].startpc));
315                 dseg_addtarget(BlockPtrOfPC(extable[len].endpc));
316                 dseg_addtarget(BlockPtrOfPC(extable[len].handlerpc));
317                 (void) dseg_addaddress(extable[len].catchtype);
318                 }
319
320         /* initialise mcode variables */
321         
322         mcodeptr = (s4*) mcodebase;
323         mcodeend = (s4*) (mcodebase + mcodesize);
324         MCODECHECK(128);
325
326         /* create stack frame (if necessary) */
327
328         if (parentargs_base)
329                 {M_LDA (REG_SP, REG_SP, -parentargs_base * 8);}
330
331         /* save return address and used callee saved registers */
332
333         p = parentargs_base;
334         if (!isleafmethod)
335                 {p--;  M_LST (REG_RA, REG_SP, 8*p);}
336         for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
337                 {p--; M_LST (savintregs[r], REG_SP, 8 * p);}
338         for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
339                 {p--; M_DST (savfltregs[r], REG_SP, 8 * p);}
340
341         /* save monitorenter argument */
342
343 #ifdef USE_THREADS
344         if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
345                 if (method->flags & ACC_STATIC) {
346                         p = dseg_addaddress (class);
347                         M_LLD(REG_ITMP1, REG_PV, p);
348                         M_LST(REG_ITMP1, REG_SP, 8 * maxmemuse);
349                         } 
350                 else {
351                         M_LST (argintregs[0], REG_SP, 8 * maxmemuse);
352                         }
353                 }                       
354 #endif
355
356         if (runverbose && isleafmethod) {
357                 M_LDA (REG_SP, REG_SP, -(8*8));
358                 M_LST(REG_RA, REG_SP, 1*8);
359                 M_LST(argintregs[0], REG_SP, 2*8);
360                 M_LST(argintregs[1], REG_SP, 3*8);
361                 M_LST(argintregs[2], REG_SP, 4*8);
362                 M_LST(argintregs[3], REG_SP, 5*8);
363                 M_LST(argintregs[4], REG_SP, 6*8);
364                 M_LST(argintregs[5], REG_SP, 7*8);
365                 p = dseg_addaddress (method);
366                 M_LLD(REG_ITMP1, REG_PV, p);
367                 M_LST(REG_ITMP1, REG_SP, 0);
368                 p = dseg_addaddress ((void*) (builtin_trace_args));
369                 M_LLD(REG_PV, REG_PV, p);
370                 M_JSR(REG_RA, REG_PV);
371                 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
372                 M_LLD(REG_RA, REG_SP, 1*8);
373                 M_LLD(argintregs[0], REG_SP, 2*8);
374                 M_LLD(argintregs[1], REG_SP, 3*8);
375                 M_LLD(argintregs[2], REG_SP, 4*8);
376                 M_LLD(argintregs[3], REG_SP, 5*8);
377                 M_LLD(argintregs[4], REG_SP, 6*8);
378                 M_LLD(argintregs[5], REG_SP, 7*8);
379                 M_LDA (REG_SP, REG_SP, 8*8);
380                 }
381
382         /* take arguments out of register or stack frame */
383
384         for (p = 0, l = 0; p < mparamcount; p++) {
385                 t = mparamtypes[p];
386                 var = &(locals[l][t]);
387                 l++;
388                 if (IS_2_WORD_TYPE(t))    /* increment local counter for 2 word types */
389                         l++;
390                 if (var->type < 0)
391                         continue;
392                 r = var->regoff; 
393                 if (IS_INT_LNG_TYPE(t)) {                    /* integer args          */
394                         if (p < INT_ARG_CNT) {                   /* register arguments    */
395                                 if (!(var->flags & INMEMORY))        /* reg arg -> register   */
396                                         {M_INTMOVE (argintregs[p], r);}
397                                 else                                 /* reg arg -> spilled    */
398                                         M_LST (argintregs[p], REG_SP, 8 * r);
399                                 }
400                         else {                                   /* stack arguments       */
401                                 pa = p - INT_ARG_CNT;
402                                 if (!(var->flags & INMEMORY))        /* stack arg -> register */ 
403                                         M_LLD (r, REG_SP, 8 * (parentargs_base + pa));
404                                 else {                               /* stack arg -> spilled  */
405                                         M_LLD (REG_ITMP1, REG_SP, 8 * (parentargs_base + pa));
406                                         M_LST (REG_ITMP1, REG_SP, 8 * r);
407                                         }
408                                 }
409                         }
410                 else {                                       /* floating args         */   
411                         if (p < FLT_ARG_CNT) {                   /* register arguments    */
412                                 if (!(var->flags & INMEMORY))        /* reg arg -> register   */
413                                         {M_FLTMOVE (argfltregs[p], r);}
414                                 else                                             /* reg arg -> spilled    */
415                                         M_DST (argfltregs[p], REG_SP, 8 * r);
416                                 }
417                         else {                                   /* stack arguments       */
418                                 pa = p - FLT_ARG_CNT;
419                                 if (!(var->flags & INMEMORY))        /* stack-arg -> register */
420                                         M_DLD (r, REG_SP, 8 * (parentargs_base + pa) );
421                                 else {                               /* stack-arg -> spilled  */
422                                         M_DLD (REG_FTMP1, REG_SP, 8 * (parentargs_base + pa));
423                                         M_DST (REG_FTMP1, REG_SP, 8 * r);
424                                         }
425                                 }
426                         }
427                 }  /* end for */
428
429         if (runverbose && !isleafmethod) {
430                 M_LDA (REG_SP, REG_SP, -8);
431                 p = dseg_addaddress (method);
432                 M_LLD(REG_ITMP1, REG_PV, p);
433                 M_LST(REG_ITMP1, REG_SP, 0);
434                 p = dseg_addaddress ((void*) (builtin_trace_args));
435                 M_LLD(REG_PV, REG_PV, p);
436                 M_JSR(REG_RA, REG_PV);
437                 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
438                 M_LDA(REG_SP, REG_SP, 8);
439                 }
440
441 #ifdef USE_THREADS
442         if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
443                 p = dseg_addaddress ((void*) (builtin_monitorenter));
444                 M_LLD(REG_PV, REG_PV, p);
445                 M_LLD(argintregs[0], REG_SP, 8 * maxmemuse);
446                 M_JSR(REG_RA, REG_PV);
447                 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
448                 }                       
449 #endif
450         }
451
452         /* end of header generation */
453
454         for (bbs = block_count, bptr = block; --bbs >= 0; bptr++) {
455                 bptr -> mpc = (int)((u1*) mcodeptr - mcodebase);
456
457                 /* branch resolving */
458
459                 {
460                 branchref *brefs;
461                 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
462                         gen_resolvebranch((u1*) mcodebase + brefs->branchpos, 
463                                           brefs->branchpos, bptr->mpc);
464                         }
465                 }
466                 src = bptr->instack;
467                 len = bptr->indepth;
468                 MCODECHECK(64+len);
469                 while (src != NULL) {
470                         len--;
471                         if ((len == 0) && (bptr->type != BBTYPE_STD)) {
472                                 d = reg_of_var(src, REG_ITMP1);
473                                 M_INTMOVE(REG_ITMP1, d);
474                                 store_reg_to_var_int(src, d);
475                                 }
476                         else {
477                                 d = reg_of_var(src, REG_IFTMP);
478                                 if ((src->varkind != STACKVAR)) {
479                                         s2 = src->type;
480                                         if (IS_FLT_DBL_TYPE(s2)) {
481                                                 if (!(interfaces[len][s2].flags & INMEMORY)) {
482                                                         s1 = interfaces[len][s2].regoff;
483                                                         M_FLTMOVE(s1,d);
484                                                         }
485                                                 else {
486                                                         M_DLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
487                                                         }
488                                                 store_reg_to_var_flt(src, d);
489                                                 }
490                                         else {
491                                                 if (!(interfaces[len][s2].flags & INMEMORY)) {
492                                                         s1 = interfaces[len][s2].regoff;
493                                                         M_INTMOVE(s1,d);
494                                                         }
495                                                 else {
496                                                         M_LLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
497                                                         }
498                                                 store_reg_to_var_int(src, d);
499                                                 }
500                                         }
501                                 }
502                         src = src->prev;
503                         }
504                 s1  = bptr[0].ipc;
505                 src = bptr->instack;
506                 len = bptr[1].ipc - s1;
507                 for (iptr = &instr[s1];
508                     len > 0;
509                     src = iptr->dst, len--, iptr++) {
510
511         MCODECHECK(64);
512         switch (iptr->opc) {
513
514                 case ICMD_NOP:
515                         break;
516
517                 case ICMD_NULLCHECKPOP:
518                         var_to_reg_int(s1, src, REG_ITMP1);
519                         gen_nullptr_check(s1);
520                         break;
521
522                 /*********************** constant operations **************************/
523
524                 case ICMD_ICONST:
525                         d = reg_of_var(iptr->dst, REG_ITMP1);
526                         if ( (iptr->val.i >= -32768) && (iptr->val.i <= 32767) ) {
527                                 M_LDA(d, REG_ZERO, iptr->val.i);
528                                 } 
529                         else {
530                                 a = dseg_adds4 (iptr->val.i);
531                                 M_ILD(d, REG_PV, a);
532                                 }
533                         store_reg_to_var_int(iptr->dst, d);
534                         break;
535
536                 case ICMD_LCONST:
537                         d = reg_of_var(iptr->dst, REG_ITMP1);
538                         if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767) ) {
539                                 M_LDA(d, REG_ZERO, iptr->val.l);
540                                 } 
541                         else {
542                                 a = dseg_adds8 (iptr->val.l);
543                                 M_LLD(d, REG_PV, a);
544                                 }
545                         store_reg_to_var_int(iptr->dst, d);
546                         break;
547
548                 case ICMD_FCONST:
549                         d = reg_of_var (iptr->dst, REG_FTMP1);
550                         a = dseg_addfloat (iptr->val.f);
551                         M_FLD(d, REG_PV, a);
552                         store_reg_to_var_flt (iptr->dst, d);
553                         break;
554                         
555                 case ICMD_DCONST:
556                         d = reg_of_var (iptr->dst, REG_FTMP1);
557                         a = dseg_adddouble (iptr->val.d);
558                         M_DLD(d, REG_PV, a);
559                         store_reg_to_var_flt (iptr->dst, d);
560                         break;
561
562
563                 case ICMD_ACONST:
564                         d = reg_of_var(iptr->dst, REG_ITMP1);
565                         if (iptr->val.a) {
566                                 a = dseg_addaddress (iptr->val.a);
567                                 M_LLD(d, REG_PV, a);
568                                 }
569                         else {
570                                 M_INTMOVE(REG_ZERO, d);
571                                 }
572                         store_reg_to_var_int(iptr->dst, d);
573                         break;
574
575                 /********************** load/store operations *************************/
576
577                 case ICMD_ILOAD:
578                 case ICMD_LLOAD:
579                 case ICMD_ALOAD:
580                         d = reg_of_var(iptr->dst, REG_ITMP1);
581                         if ((iptr->dst->varkind == LOCALVAR) &&
582                             (iptr->dst->varnum == iptr->op1))
583                                 break;
584                         var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
585                         if (var->flags & INMEMORY)
586                                 M_LLD(d, REG_SP, 8 * var->regoff);
587                         else
588                                 {M_INTMOVE(var->regoff,d);}
589                         store_reg_to_var_int(iptr->dst, d);
590                         break;
591
592                 case ICMD_FLOAD:
593                 case ICMD_DLOAD:
594                         d = reg_of_var(iptr->dst, REG_FTMP1);
595                         if ((iptr->dst->varkind == LOCALVAR) &&
596                             (iptr->dst->varnum == iptr->op1))
597                                 break;
598                         var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
599                         if (var->flags & INMEMORY)
600                                 M_DLD(d, REG_SP, 8 * var->regoff);
601                         else
602                                 {M_FLTMOVE(var->regoff,d);}
603                         store_reg_to_var_flt(iptr->dst, d);
604                         break;
605
606
607                 case ICMD_ISTORE:
608                 case ICMD_LSTORE:
609                 case ICMD_ASTORE:
610                         if ((src->varkind == LOCALVAR) &&
611                             (src->varnum == iptr->op1))
612                                 break;
613                         var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
614                         if (var->flags & INMEMORY) {
615                                 var_to_reg_int(s1, src, REG_ITMP1);
616                                 M_LST(s1, REG_SP, 8 * var->regoff);
617                                 }
618                         else {
619                                 var_to_reg_int(s1, src, var->regoff);
620                                 M_INTMOVE(s1, var->regoff);
621                                 }
622                         break;
623
624                 case ICMD_FSTORE:
625                 case ICMD_DSTORE:
626                         if ((src->varkind == LOCALVAR) &&
627                             (src->varnum == iptr->op1))
628                                 break;
629                         var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
630                         if (var->flags & INMEMORY) {
631                                 var_to_reg_flt(s1, src, REG_FTMP1);
632                                 M_DST(s1, REG_SP, 8 * var->regoff);
633                                 }
634                         else {
635                                 var_to_reg_flt(s1, src, var->regoff);
636                                 M_FLTMOVE(s1, var->regoff);
637                                 }
638                         break;
639
640
641                 /******************* pop/dup/swap operations **************************/
642
643                 case ICMD_POP:
644                 case ICMD_POP2:
645                         break;
646
647 #define M_COPY(from,to) \
648                         d = reg_of_var(to, REG_IFTMP); \
649                         if ((from->regoff != to->regoff) || \
650                             ((from->flags ^ to->flags) & INMEMORY)) { \
651                                 if (IS_FLT_DBL_TYPE(from->type)) { \
652                                         var_to_reg_flt(s1, from, d); \
653                                         M_FLTMOVE(s1,d); \
654                                         store_reg_to_var_flt(to, d); \
655                                         }\
656                                 else { \
657                                         var_to_reg_int(s1, from, d); \
658                                         M_INTMOVE(s1,d); \
659                                         store_reg_to_var_int(to, d); \
660                                         }\
661                                 }
662
663                 case ICMD_DUP:
664                         M_COPY(src, iptr->dst);
665                         break;
666
667                 case ICMD_DUP_X1:
668                         M_COPY(src,       iptr->dst->prev->prev);
669                 case ICMD_DUP2:
670                         M_COPY(src,       iptr->dst);
671                         M_COPY(src->prev, iptr->dst->prev);
672                         break;
673
674                 case ICMD_DUP2_X1:
675                         M_COPY(src->prev,       iptr->dst->prev->prev->prev);
676                 case ICMD_DUP_X2:
677                         M_COPY(src,             iptr->dst);
678                         M_COPY(src->prev,       iptr->dst->prev);
679                         M_COPY(src->prev->prev, iptr->dst->prev->prev);
680                         M_COPY(src, iptr->dst->prev->prev->prev);
681                         break;
682
683                 case ICMD_DUP2_X2:
684                         M_COPY(src,                   iptr->dst);
685                         M_COPY(src->prev,             iptr->dst->prev);
686                         M_COPY(src->prev->prev,       iptr->dst->prev->prev);
687                         M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
688                         M_COPY(src,       iptr->dst->prev->prev->prev->prev);
689                         M_COPY(src->prev, iptr->dst->prev->prev->prev->prev->prev);
690                         break;
691
692                 case ICMD_SWAP:
693                         M_COPY(src, iptr->dst->prev);
694                         M_COPY(src->prev, iptr->dst);
695                         break;
696
697
698                 /********************* integer operations *****************************/
699
700                 case ICMD_INEG:
701                         var_to_reg_int(s1, src, REG_ITMP1); 
702                         d = reg_of_var(iptr->dst, REG_ITMP3);
703                         M_ISUB(REG_ZERO, s1, d, 0);
704                         store_reg_to_var_int(iptr->dst, d);
705                         break;
706
707                 case ICMD_LNEG:
708                         var_to_reg_int(s1, src, REG_ITMP1);
709                         d = reg_of_var(iptr->dst, REG_ITMP3);
710                         M_LSUB(REG_ZERO, s1, d, 0);
711                         store_reg_to_var_int(iptr->dst, d);
712                         break;
713
714                 case ICMD_I2L:
715                         var_to_reg_int(s1, src, REG_ITMP1);
716                         d = reg_of_var(iptr->dst, REG_ITMP3);
717                         M_INTMOVE(s1, d);
718                         store_reg_to_var_int(iptr->dst, d);
719                         break;
720
721                 case ICMD_L2I:
722                         var_to_reg_int(s1, src, REG_ITMP1);
723                         d = reg_of_var(iptr->dst, REG_ITMP3);
724                         M_IADD(s1, REG_ZERO, d , 0);
725                         store_reg_to_var_int(iptr->dst, d);
726                         break;
727
728                 case ICMD_INT2BYTE:
729                         var_to_reg_int(s1, src, REG_ITMP1);
730                         d = reg_of_var(iptr->dst, REG_ITMP3);
731                         if (has_ext_instr_set) {
732                                 M_BSEXT(s1, d);
733                                 }
734                         else {
735                                 M_SLL(s1,56, d, 1);
736                                 M_SRA( d,56, d, 1);
737                                 }
738                         store_reg_to_var_int(iptr->dst, d);
739                         break;
740
741                 case ICMD_INT2CHAR:
742                         var_to_reg_int(s1, src, REG_ITMP1);
743                         d = reg_of_var(iptr->dst, REG_ITMP3);
744             M_ZAPNOT(s1, 0x03, d, 1);
745                         store_reg_to_var_int(iptr->dst, d);
746                         break;
747
748                 case ICMD_INT2SHORT:
749                         var_to_reg_int(s1, src, REG_ITMP1);
750                         d = reg_of_var(iptr->dst, REG_ITMP3);
751                         if (has_ext_instr_set) {
752                                 M_SSEXT(s1, d);
753                                 }
754                         else {
755                                 M_SLL( s1, 48, d, 1);
756                                 M_SRA(  d, 48, d, 1);
757                                 }
758                         store_reg_to_var_int(iptr->dst, d);
759                         break;
760
761 #define ICONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
762                     else{a=dseg_adds4(c);M_ILD(r,REG_PV,a);}
763
764 #define LCONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
765                     else{a=dseg_adds8(c);M_LLD(r,REG_PV,a);}
766
767
768                 case ICMD_IADD:
769                         var_to_reg_int(s1, src->prev, REG_ITMP1);
770                         var_to_reg_int(s2, src, REG_ITMP2);
771                         d = reg_of_var(iptr->dst, REG_ITMP3);
772                         M_IADD(s1, s2, d,  0);
773                         store_reg_to_var_int(iptr->dst, d);
774                         break;
775                 case ICMD_IADDCONST:
776                         var_to_reg_int(s1, src, REG_ITMP1);
777                         d = reg_of_var(iptr->dst, REG_ITMP3);
778                         if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
779                                 M_IADD(s1, iptr->val.i, d, 1);
780                                 }
781                         else {
782                                 ICONST(REG_ITMP2, iptr->val.i);
783                                 M_IADD(s1, REG_ITMP2, d, 0);
784                                 }
785                         store_reg_to_var_int(iptr->dst, d);
786                         break;
787                 case ICMD_LADD:
788                         var_to_reg_int(s1, src->prev, REG_ITMP1);
789                         var_to_reg_int(s2, src, REG_ITMP2);
790                         d = reg_of_var(iptr->dst, REG_ITMP3);
791                         M_LADD(s1, s2, d,  0);
792                         store_reg_to_var_int(iptr->dst, d);
793                         break;
794                 case ICMD_LADDCONST:
795                         var_to_reg_int(s1, src, REG_ITMP1);
796                         d = reg_of_var(iptr->dst, REG_ITMP3);
797                         if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
798                                 M_LADD(s1, iptr->val.l, d, 1);
799                                 }
800                         else {
801                                 LCONST(REG_ITMP2, iptr->val.l);
802                                 M_LADD(s1, REG_ITMP2, d, 0);
803                                 }
804                         store_reg_to_var_int(iptr->dst, d);
805                         break;
806
807                 case ICMD_ISUB:
808                         var_to_reg_int(s1, src->prev, REG_ITMP1);
809                         var_to_reg_int(s2, src, REG_ITMP2);
810                         d = reg_of_var(iptr->dst, REG_ITMP3);
811                         M_ISUB(s1, s2, d, 0);
812                         store_reg_to_var_int(iptr->dst, d);
813                         break;
814                 case ICMD_ISUBCONST:
815                         var_to_reg_int(s1, src, REG_ITMP1);
816                         d = reg_of_var(iptr->dst, REG_ITMP3);
817                         if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
818                                 M_ISUB(s1, iptr->val.i, d, 1);
819                                 }
820                         else {
821                                 ICONST(REG_ITMP2, iptr->val.i);
822                                 M_ISUB(s1, REG_ITMP2, d, 0);
823                                 }
824                         store_reg_to_var_int(iptr->dst, d);
825                         break;
826                 case ICMD_LSUB:
827                         var_to_reg_int(s1, src->prev, REG_ITMP1);
828                         var_to_reg_int(s2, src, REG_ITMP2);
829                         d = reg_of_var(iptr->dst, REG_ITMP3);
830                         M_LSUB(s1, s2, d, 0);
831                         store_reg_to_var_int(iptr->dst, d);
832                         break;
833                 case ICMD_LSUBCONST:
834                         var_to_reg_int(s1, src, REG_ITMP1);
835                         d = reg_of_var(iptr->dst, REG_ITMP3);
836                         if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
837                                 M_LSUB(s1, iptr->val.l, d, 1);
838                                 }
839                         else {
840                                 LCONST(REG_ITMP2, iptr->val.l);
841                                 M_LSUB(s1, REG_ITMP2, d, 0);
842                                 }
843                         store_reg_to_var_int(iptr->dst, d);
844                         break;
845
846                 case ICMD_IMUL:
847                         var_to_reg_int(s1, src->prev, REG_ITMP1);
848                         var_to_reg_int(s2, src, REG_ITMP2);
849                         d = reg_of_var(iptr->dst, REG_ITMP3);
850                         M_IMUL(s1, s2, d, 0);
851                         store_reg_to_var_int(iptr->dst, d);
852                         break;
853                 case ICMD_IMULCONST:
854                         var_to_reg_int(s1, src, REG_ITMP1);
855                         d = reg_of_var(iptr->dst, REG_ITMP3);
856                         if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
857                                 M_IMUL(s1, iptr->val.i, d, 1);
858                                 }
859                         else {
860                                 ICONST(REG_ITMP2, iptr->val.i);
861                                 M_IMUL(s1, REG_ITMP2, d, 0);
862                                 }
863                         store_reg_to_var_int(iptr->dst, d);
864                         break;
865                 case ICMD_LMUL:
866                         var_to_reg_int(s1, src->prev, REG_ITMP1);
867                         var_to_reg_int(s2, src, REG_ITMP2);
868                         d = reg_of_var(iptr->dst, REG_ITMP3);
869                         M_LMUL (s1, s2, d, 0);
870                         store_reg_to_var_int(iptr->dst, d);
871                         break;
872                 case ICMD_LMULCONST:
873                         var_to_reg_int(s1, src, REG_ITMP1);
874                         d = reg_of_var(iptr->dst, REG_ITMP3);
875                         if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
876                                 M_LMUL(s1, iptr->val.l, d, 1);
877                                 }
878                         else {
879                                 LCONST(REG_ITMP2, iptr->val.l);
880                                 M_LMUL(s1, REG_ITMP2, d, 0);
881                                 }
882                         store_reg_to_var_int(iptr->dst, d);
883                         break;
884
885                     
886                 case ICMD_ISHL:
887                         var_to_reg_int(s1, src->prev, REG_ITMP1);
888                         var_to_reg_int(s2, src, REG_ITMP2);
889                         d = reg_of_var(iptr->dst, REG_ITMP3);
890                         M_AND(s2, 0x1f, REG_ITMP3, 1);
891                         M_SLL(s1, REG_ITMP3, d, 0);
892                         M_IADD(d, REG_ZERO, d, 0);
893                         store_reg_to_var_int(iptr->dst, d);
894                         break;
895                 case ICMD_ISHLCONST:
896                         var_to_reg_int(s1, src, REG_ITMP1);
897                         d = reg_of_var(iptr->dst, REG_ITMP3);
898                         M_SLL(s1, iptr->val.i & 0x1f, d, 1);
899                         M_IADD(d, REG_ZERO, d, 0);
900                         store_reg_to_var_int(iptr->dst, d);
901                         break;
902
903                 case ICMD_ISHR:
904                         var_to_reg_int(s1, src->prev, REG_ITMP1);
905                         var_to_reg_int(s2, src, REG_ITMP2);
906                         d = reg_of_var(iptr->dst, REG_ITMP3);
907                         M_AND(s2, 0x1f, REG_ITMP3,  1);
908                         M_SRA(s1, REG_ITMP3, d,   0);
909                         store_reg_to_var_int(iptr->dst, d);
910                         break;
911                 case ICMD_ISHRCONST:
912                         var_to_reg_int(s1, src, REG_ITMP1);
913                         d = reg_of_var(iptr->dst, REG_ITMP3);
914                         M_SRA(s1, iptr->val.i & 0x1f, d, 1);
915                         store_reg_to_var_int(iptr->dst, d);
916                         break;
917
918                 case ICMD_IUSHR:
919                         var_to_reg_int(s1, src->prev, REG_ITMP1);
920                         var_to_reg_int(s2, src, REG_ITMP2);
921                         d = reg_of_var(iptr->dst, REG_ITMP3);
922                         M_AND   (s2, 0x1f, REG_ITMP2,  1);
923             M_ZAPNOT(s1, 0x0f, d, 1);
924                         M_SRL   ( d, REG_ITMP2, d, 0);
925                         M_IADD  ( d, REG_ZERO, d, 0);
926                         store_reg_to_var_int(iptr->dst, d);
927                         break;
928                 case ICMD_IUSHRCONST:
929                         var_to_reg_int(s1, src, REG_ITMP1);
930                         d = reg_of_var(iptr->dst, REG_ITMP3);
931             M_ZAPNOT(s1, 0x0f, d, 1);
932                         M_SRL(d, iptr->val.i & 0x1f, d, 1);
933                         M_IADD(d, REG_ZERO, d, 0);
934                         store_reg_to_var_int(iptr->dst, d);
935                         break;
936
937                 case ICMD_LSHL:
938                         var_to_reg_int(s1, src->prev, REG_ITMP1);
939                         var_to_reg_int(s2, src, REG_ITMP2);
940                         d = reg_of_var(iptr->dst, REG_ITMP3);
941                         M_SLL(s1, s2, d, 0);
942                         store_reg_to_var_int(iptr->dst, d);
943                         break;
944                 case ICMD_LSHLCONST:
945                         var_to_reg_int(s1, src, REG_ITMP1);
946                         d = reg_of_var(iptr->dst, REG_ITMP3);
947                         M_SLL(s1, iptr->val.l & 0x3f, d, 1);
948                         store_reg_to_var_int(iptr->dst, d);
949                         break;
950
951                 case ICMD_LSHR:
952                         var_to_reg_int(s1, src->prev, REG_ITMP1);
953                         var_to_reg_int(s2, src, REG_ITMP2);
954                         d = reg_of_var(iptr->dst, REG_ITMP3);
955                         M_SRA(s1, s2, d,  0);
956                         store_reg_to_var_int(iptr->dst, d);
957                         break;
958                 case ICMD_LSHRCONST:
959                         var_to_reg_int(s1, src, REG_ITMP1);
960                         d = reg_of_var(iptr->dst, REG_ITMP3);
961                         M_SRA(s1, iptr->val.l & 0x3f, d, 1);
962                         store_reg_to_var_int(iptr->dst, d);
963                         break;
964
965                 case ICMD_LUSHR:
966                         var_to_reg_int(s1, src->prev, REG_ITMP1);
967                         var_to_reg_int(s2, src, REG_ITMP2);
968                         d = reg_of_var(iptr->dst, REG_ITMP3);
969                         M_SRL(s1, s2, d,  0);
970                         store_reg_to_var_int(iptr->dst, d);
971                         break;
972                 case ICMD_LUSHRCONST:
973                         var_to_reg_int(s1, src, REG_ITMP1);
974                         d = reg_of_var(iptr->dst, REG_ITMP3);
975                         M_SRL(s1, iptr->val.l & 0x3f, d, 1);
976                         store_reg_to_var_int(iptr->dst, d);
977                         break;
978
979                 case ICMD_IAND:
980                 case ICMD_LAND:
981                         var_to_reg_int(s1, src->prev, REG_ITMP1);
982                         var_to_reg_int(s2, src, REG_ITMP2);
983                         d = reg_of_var(iptr->dst, REG_ITMP3);
984                         M_AND(s1, s2, d, 0);
985                         store_reg_to_var_int(iptr->dst, d);
986                         break;
987                 case ICMD_IANDCONST:
988                         var_to_reg_int(s1, src, REG_ITMP1);
989                         d = reg_of_var(iptr->dst, REG_ITMP3);
990                         if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
991                                 M_AND(s1, iptr->val.i, d, 1);
992                                 }
993                         else if (iptr->val.i == 0xffff) {
994                                 M_ZAPNOT(s1, 0x03, d, 1);
995                                 }
996                         else if (iptr->val.i == 0xffffff) {
997                                 M_ZAPNOT(s1, 0x07, d, 1);
998                                 }
999                         else {
1000                                 ICONST(REG_ITMP2, iptr->val.i);
1001                                 M_AND(s1, REG_ITMP2, d, 0);
1002                                 }
1003                         store_reg_to_var_int(iptr->dst, d);
1004                         break;
1005                 case ICMD_IREMPOW2:
1006                         var_to_reg_int(s1, src, REG_ITMP1);
1007                         d = reg_of_var(iptr->dst, REG_ITMP3);
1008                         if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1009                                 M_AND(s1, iptr->val.i, d, 1);
1010                                 M_BGEZ(s1, 3);
1011                                 M_ISUB(REG_ZERO, s1, d, 0);
1012                                 M_AND(d, iptr->val.i, d, 1);
1013                                 }
1014                         else if (iptr->val.i == 0xffff) {
1015                                 M_ZAPNOT(s1, 0x03, d, 1);
1016                                 M_BGEZ(s1, 3);
1017                                 M_ISUB(REG_ZERO, s1, d, 0);
1018                                 M_ZAPNOT(d, 0x03, d, 1);
1019                                 }
1020                         else if (iptr->val.i == 0xffffff) {
1021                                 M_ZAPNOT(s1, 0x07, d, 1);
1022                                 M_BGEZ(s1, 3);
1023                                 M_ISUB(REG_ZERO, s1, d, 0);
1024                                 M_ZAPNOT(d, 0x07, d, 1);
1025                                 }
1026                         else {
1027                                 ICONST(REG_ITMP2, iptr->val.i);
1028                                 M_AND(s1, REG_ITMP2, d, 0);
1029                                 M_BGEZ(s1, 3);
1030                                 M_ISUB(REG_ZERO, s1, d, 0);
1031                                 M_AND(d, REG_ITMP2, d, 0);
1032                                 }
1033                         M_ISUB(REG_ZERO, d, d, 0);
1034                         store_reg_to_var_int(iptr->dst, d);
1035                         break;
1036                 case ICMD_IREM0X10001:
1037                         var_to_reg_int(s1, src, REG_ITMP1);
1038                         d = reg_of_var(iptr->dst, REG_ITMP3);
1039             M_ZAPNOT(s1, 0x03, REG_ITMP2, 1);
1040                         M_SRA(s1, 16, d, 1);
1041                         M_CMPLT(REG_ITMP2, d, REG_ITMP1, 0);
1042                         M_ISUB(REG_ITMP2, d, d, 0);
1043             M_ZAPNOT(d, 0x03, d, 1);
1044                         M_IADD(d, REG_ITMP1, d, 0);
1045                         M_BGEZ(s1, 11);
1046                         M_ISUB(REG_ZERO, s1, REG_ITMP1, 0);
1047             M_ZAPNOT(REG_ITMP1, 0x03, REG_ITMP2, 1);
1048                         M_SRA(REG_ITMP1, 16, d, 1);
1049                         M_CMPLT(REG_ITMP2, d, REG_ITMP1, 0);
1050                         M_ISUB(REG_ITMP2, d, d, 0);
1051             M_ZAPNOT(d, 0x03, d, 1);
1052                         M_IADD(d, REG_ITMP1, d, 0);
1053                         M_ISUB(REG_ZERO, d, d, 0);
1054                         M_SLL(s1, 33, REG_ITMP2, 1);
1055                         M_CMPEQ(REG_ITMP2, REG_ZERO, REG_ITMP2, 0);
1056                         M_ISUB(d, REG_ITMP2, d, 0);
1057                         store_reg_to_var_int(iptr->dst, d);
1058                         break;
1059                 case ICMD_LANDCONST:
1060                         var_to_reg_int(s1, src, REG_ITMP1);
1061                         d = reg_of_var(iptr->dst, REG_ITMP3);
1062                         if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1063                                 M_AND(s1, iptr->val.l, d, 1);
1064                                 }
1065                         else if (iptr->val.l == 0xffffL) {
1066                                 M_ZAPNOT(s1, 0x03, d, 1);
1067                                 }
1068                         else if (iptr->val.l == 0xffffffL) {
1069                                 M_ZAPNOT(s1, 0x07, d, 1);
1070                                 }
1071                         else if (iptr->val.l == 0xffffffffL) {
1072                                 M_ZAPNOT(s1, 0x0f, d, 1);
1073                                 }
1074                         else if (iptr->val.l == 0xffffffffffL) {
1075                                 M_ZAPNOT(s1, 0x1f, d, 1);
1076                                 }
1077                         else if (iptr->val.l == 0xffffffffffffL) {
1078                                 M_ZAPNOT(s1, 0x3f, d, 1);
1079                                 }
1080                         else if (iptr->val.l == 0xffffffffffffffL) {
1081                                 M_ZAPNOT(s1, 0x7f, d, 1);
1082                                 }
1083                         else {
1084                                 LCONST(REG_ITMP2, iptr->val.l);
1085                                 M_AND(s1, REG_ITMP2, d, 0);
1086                                 }
1087                         store_reg_to_var_int(iptr->dst, d);
1088                         break;
1089                 case ICMD_LREMPOW2:
1090                         var_to_reg_int(s1, src, REG_ITMP1);
1091                         d = reg_of_var(iptr->dst, REG_ITMP3);
1092                         if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1093                                 M_AND(s1, iptr->val.l, d, 1);
1094                                 M_BGEZ(s1, 3);
1095                                 M_LSUB(REG_ZERO, s1, d, 0);
1096                                 M_AND(d, iptr->val.l, d, 1);
1097                                 }
1098                         else if (iptr->val.l == 0xffffL) {
1099                                 M_ZAPNOT(s1, 0x03, d, 1);
1100                                 M_BGEZ(s1, 3);
1101                                 M_LSUB(REG_ZERO, s1, d, 0);
1102                                 M_ZAPNOT(d, 0x03, d, 1);
1103                                 }
1104                         else if (iptr->val.l == 0xffffffL) {
1105                                 M_ZAPNOT(s1, 0x07, d, 1);
1106                                 M_BGEZ(s1, 3);
1107                                 M_LSUB(REG_ZERO, s1, d, 0);
1108                                 M_ZAPNOT(d, 0x07, d, 1);
1109                                 }
1110                         else if (iptr->val.l == 0xffffffffL) {
1111                                 M_ZAPNOT(s1, 0x0f, d, 1);
1112                                 M_BGEZ(s1, 3);
1113                                 M_LSUB(REG_ZERO, s1, d, 0);
1114                                 M_ZAPNOT(d, 0x0f, d, 1);
1115                                 }
1116                         else if (iptr->val.l == 0xffffffffffL) {
1117                                 M_ZAPNOT(s1, 0x1f, d, 1);
1118                                 M_BGEZ(s1, 3);
1119                                 M_LSUB(REG_ZERO, s1, d, 0);
1120                                 M_ZAPNOT(d, 0x1f, d, 1);
1121                                 }
1122                         else if (iptr->val.l == 0xffffffffffffL) {
1123                                 M_ZAPNOT(s1, 0x3f, d, 1);
1124                                 M_BGEZ(s1, 3);
1125                                 M_LSUB(REG_ZERO, s1, d, 0);
1126                                 M_ZAPNOT(d, 0x3f, d, 1);
1127                                 }
1128                         else if (iptr->val.l == 0xffffffffffffffL) {
1129                                 M_ZAPNOT(s1, 0x7f, d, 1);
1130                                 M_BGEZ(s1, 3);
1131                                 M_LSUB(REG_ZERO, s1, d, 0);
1132                                 M_ZAPNOT(d, 0x7f, d, 1);
1133                                 }
1134                         else {
1135                                 LCONST(REG_ITMP2, iptr->val.l);
1136                                 M_AND(s1, REG_ITMP2, d, 0);
1137                                 M_BGEZ(s1, 3);
1138                                 M_LSUB(REG_ZERO, s1, d, 0);
1139                                 M_AND(d, REG_ITMP2, d, 0);
1140                                 }
1141                         M_LSUB(REG_ZERO, d, d, 0);
1142                         store_reg_to_var_int(iptr->dst, d);
1143                         break;
1144                 case ICMD_LREM0X10001:
1145                         var_to_reg_int(s1, src, REG_ITMP1);
1146                         d = reg_of_var(iptr->dst, REG_ITMP3);
1147                         M_ZAPNOT(s1, 0x03, REG_ITMP2, 1);
1148                         M_SRA(s1, 16, d, 1);
1149                         M_CMPLT(REG_ITMP2, d, REG_ITMP1, 0);
1150                         M_LSUB(REG_ITMP2, d, d, 0);
1151             M_ZAPNOT(d, 0x03, d, 1);
1152                         M_LADD(d, REG_ITMP1, d, 0);
1153                         M_LDA(REG_ITMP2, REG_ZERO, -1);
1154                         M_SRL(REG_ITMP2, 33, REG_ITMP2, 1);
1155                         M_CMPULT(s1, REG_ITMP2, REG_ITMP2, 0);
1156                         M_BNEZ(REG_ITMP2, 11);
1157                         M_LDA(d, REG_ZERO, -257);
1158                         M_ZAPNOT(d, 0xcd, d, 1);
1159                         M_LSUB(REG_ZERO, s1, REG_ITMP2, 0);
1160                         M_CMOVGE(s1, s1, REG_ITMP2, 0);
1161                         M_UMULH(REG_ITMP2, d, REG_ITMP2, 0);
1162                         M_SRL(REG_ITMP2, 16, REG_ITMP2, 1);
1163                         M_LSUB(REG_ZERO, REG_ITMP2, d, 0);
1164                         M_CMOVGE(s1, REG_ITMP2, d, 0);
1165                         M_SLL(d, 16, REG_ITMP2, 1);
1166                         M_LADD(d, REG_ITMP2, d, 0);
1167                         M_LSUB(s1, d, d, 0);
1168                         store_reg_to_var_int(iptr->dst, d);
1169                         break;
1170
1171                 case ICMD_IOR:
1172                 case ICMD_LOR:
1173                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1174                         var_to_reg_int(s2, src, REG_ITMP2);
1175                         d = reg_of_var(iptr->dst, REG_ITMP3);
1176                         M_OR( s1,s2, d, 0);
1177                         store_reg_to_var_int(iptr->dst, d);
1178                         break;
1179                 case ICMD_IORCONST:
1180                         var_to_reg_int(s1, src, REG_ITMP1);
1181                         d = reg_of_var(iptr->dst, REG_ITMP3);
1182                         if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1183                                 M_OR(s1, iptr->val.i, d, 1);
1184                                 }
1185                         else {
1186                                 ICONST(REG_ITMP2, iptr->val.i);
1187                                 M_OR(s1, REG_ITMP2, d, 0);
1188                                 }
1189                         store_reg_to_var_int(iptr->dst, d);
1190                         break;
1191                 case ICMD_LORCONST:
1192                         var_to_reg_int(s1, src, REG_ITMP1);
1193                         d = reg_of_var(iptr->dst, REG_ITMP3);
1194                         if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1195                                 M_OR(s1, iptr->val.l, d, 1);
1196                                 }
1197                         else {
1198                                 LCONST(REG_ITMP2, iptr->val.l);
1199                                 M_OR(s1, REG_ITMP2, d, 0);
1200                                 }
1201                         store_reg_to_var_int(iptr->dst, d);
1202                         break;
1203
1204                 case ICMD_IXOR:
1205                 case ICMD_LXOR:
1206                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1207                         var_to_reg_int(s2, src, REG_ITMP2);
1208                         d = reg_of_var(iptr->dst, REG_ITMP3);
1209                         M_XOR(s1, s2, d, 0);
1210                         store_reg_to_var_int(iptr->dst, d);
1211                         break;
1212                 case ICMD_IXORCONST:
1213                         var_to_reg_int(s1, src, REG_ITMP1);
1214                         d = reg_of_var(iptr->dst, REG_ITMP3);
1215                         if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1216                                 M_XOR(s1, iptr->val.i, d, 1);
1217                                 }
1218                         else {
1219                                 ICONST(REG_ITMP2, iptr->val.i);
1220                                 M_XOR(s1, REG_ITMP2, d, 0);
1221                                 }
1222                         store_reg_to_var_int(iptr->dst, d);
1223                         break;
1224                 case ICMD_LXORCONST:
1225                         var_to_reg_int(s1, src, REG_ITMP1);
1226                         d = reg_of_var(iptr->dst, REG_ITMP3);
1227                         if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1228                                 M_XOR(s1, iptr->val.l, d, 1);
1229                                 }
1230                         else {
1231                                 LCONST(REG_ITMP2, iptr->val.l);
1232                                 M_XOR(s1, REG_ITMP2, d, 0);
1233                                 }
1234                         store_reg_to_var_int(iptr->dst, d);
1235                         break;
1236
1237
1238                 case ICMD_LCMP:
1239                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1240                         var_to_reg_int(s2, src, REG_ITMP2);
1241                         d = reg_of_var(iptr->dst, REG_ITMP3);
1242                         M_CMPLT(s1, s2, REG_ITMP3, 0);
1243                         M_CMPLT(s2, s1, REG_ITMP1, 0);
1244                         M_LSUB (REG_ITMP1, REG_ITMP3, d, 0);
1245                         store_reg_to_var_int(iptr->dst, d);
1246                         break;
1247
1248
1249                 case ICMD_IINC:
1250                         var = &(locals[iptr->op1][TYPE_INT]);
1251                         if (var->flags & INMEMORY) {
1252                                 s1 = REG_ITMP1;
1253                                 M_LLD(s1, REG_SP, 8 * var->regoff);
1254                                 }
1255                         else
1256                                 s1 = var->regoff;
1257                         if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1258                                 M_IADD(s1, iptr->val.i, s1, 1);
1259                                 }
1260                         else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1261                                 M_ISUB(s1, (-iptr->val.i), s1, 1);
1262                                 }
1263                         else {
1264                                 M_LDA (s1, s1, iptr->val.i);
1265                                 M_IADD(s1, REG_ZERO, s1, 0);
1266                                 }
1267                         if (var->flags & INMEMORY)
1268                                 M_LST(s1, REG_SP, 8 * var->regoff);
1269                         break;
1270
1271
1272                 /*********************** floating operations **************************/
1273
1274                 case ICMD_FNEG:
1275                         var_to_reg_flt(s1, src, REG_FTMP1);
1276                         d = reg_of_var(iptr->dst, REG_FTMP3);
1277                         M_FMOVN(s1, d);
1278                         store_reg_to_var_flt(iptr->dst, d);
1279                         break;
1280                 case ICMD_DNEG:
1281                         var_to_reg_flt(s1, src, REG_FTMP1);
1282                         d = reg_of_var(iptr->dst, REG_FTMP3);
1283                         M_FMOVN(s1, d);
1284                         store_reg_to_var_flt(iptr->dst, d);
1285                         break;
1286
1287                 case ICMD_FADD:
1288                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1289                         var_to_reg_flt(s2, src, REG_FTMP2);
1290                         d = reg_of_var(iptr->dst, REG_FTMP3);
1291                         if (checkfloats) {
1292                                 M_FADDS(s1, s2, d);
1293                                 M_TRAPB;
1294                                 }
1295                         else {
1296                                 M_FADD(s1, s2, d);
1297                                 }
1298                         store_reg_to_var_flt(iptr->dst, d);
1299                         break;
1300                 case ICMD_DADD:
1301                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1302                         var_to_reg_flt(s2, src, REG_FTMP2);
1303                         d = reg_of_var(iptr->dst, REG_FTMP3);
1304                         if (checkfloats) {
1305                                 M_DADDS(s1, s2, d);
1306                                 M_TRAPB;
1307                                 }
1308                         else {
1309                                 M_DADD(s1, s2, d);
1310                                 }
1311                         store_reg_to_var_flt(iptr->dst, d);
1312                         break;
1313
1314                 case ICMD_FSUB:
1315                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1316                         var_to_reg_flt(s2, src, REG_FTMP2);
1317                         d = reg_of_var(iptr->dst, REG_FTMP3);
1318                         if (checkfloats) {
1319                                 M_FSUBS(s1, s2, d);
1320                                 M_TRAPB;
1321                                 }
1322                         else {
1323                                 M_FSUB(s1, s2, d);
1324                                 }
1325                         store_reg_to_var_flt(iptr->dst, d);
1326                         break;
1327                 case ICMD_DSUB:
1328                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1329                         var_to_reg_flt(s2, src, REG_FTMP2);
1330                         d = reg_of_var(iptr->dst, REG_FTMP3);
1331                         if (checkfloats) {
1332                                 M_DSUBS(s1, s2, d);
1333                                 M_TRAPB;
1334                                 }
1335                         else {
1336                                 M_DSUB(s1, s2, d);
1337                                 }
1338                         store_reg_to_var_flt(iptr->dst, d);
1339                         break;
1340
1341                 case ICMD_FMUL:
1342                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1343                         var_to_reg_flt(s2, src, REG_FTMP2);
1344                         d = reg_of_var(iptr->dst, REG_FTMP3);
1345                         if (checkfloats) {
1346                                 M_FMULS(s1, s2, d);
1347                                 M_TRAPB;
1348                                 }
1349                         else {
1350                                 M_FMUL(s1, s2, d);
1351                                 }
1352                         store_reg_to_var_flt(iptr->dst, d);
1353                         break;
1354                 case ICMD_DMUL:
1355                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1356                         var_to_reg_flt(s2, src, REG_FTMP2);
1357                         d = reg_of_var(iptr->dst, REG_FTMP3);
1358                         if (checkfloats) {
1359                                 M_DMULS(s1, s2, d);
1360                                 M_TRAPB;
1361                                 }
1362                         else {
1363                                 M_DMUL(s1, s2, d);
1364                                 }
1365                         store_reg_to_var_flt(iptr->dst, d);
1366                         break;
1367
1368                 case ICMD_FDIV:
1369                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1370                         var_to_reg_flt(s2, src, REG_FTMP2);
1371                         d = reg_of_var(iptr->dst, REG_FTMP3);
1372                         if (checkfloats) {
1373                                 M_FDIVS(s1, s2, d);
1374                                 M_TRAPB;
1375                                 }
1376                         else {
1377                                 M_FDIV(s1, s2, d);
1378                                 }
1379                         store_reg_to_var_flt(iptr->dst, d);
1380                         break;
1381                 case ICMD_DDIV:
1382                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1383                         var_to_reg_flt(s2, src, REG_FTMP2);
1384                         d = reg_of_var(iptr->dst, REG_FTMP3);
1385                         if (checkfloats) {
1386                                 M_DDIVS(s1, s2, d);
1387                                 M_TRAPB;
1388                                 }
1389                         else {
1390                                 M_DDIV(s1, s2, d);
1391                                 }
1392                         store_reg_to_var_flt(iptr->dst, d);
1393                         break;
1394                 
1395                 case ICMD_FREM:
1396                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1397                         var_to_reg_flt(s2, src, REG_FTMP2);
1398                         d = reg_of_var(iptr->dst, REG_FTMP3);
1399                         if (checkfloats) {
1400                                 M_FDIVS(s1,s2, REG_FTMP3);
1401                                 M_TRAPB;
1402                                 M_CVTDL_CS(REG_ZERO, REG_FTMP3, REG_FTMP3); /* round to integer */
1403                                 M_TRAPB;
1404                                 M_CVTLF(REG_ZERO, REG_FTMP3, REG_FTMP3);
1405                                 M_FMULS(REG_FTMP3, s2, REG_FTMP3);
1406                                 M_TRAPB;
1407                                 M_FSUBS(s1, REG_FTMP3, d);
1408                                 M_TRAPB;
1409                                 }
1410                         else {
1411                                 M_FDIV(s1,s2, REG_FTMP3);
1412                                 M_CVTDL_C(REG_ZERO, REG_FTMP3, REG_FTMP3); /* round to integer */
1413                                 M_CVTLF(REG_ZERO, REG_FTMP3, REG_FTMP3);
1414                                 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1415                                 M_FSUB(s1, REG_FTMP3, d);
1416                                 }
1417                         store_reg_to_var_flt(iptr->dst, d);
1418                     break;
1419                 case ICMD_DREM:
1420                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1421                         var_to_reg_flt(s2, src, REG_FTMP2);
1422                         d = reg_of_var(iptr->dst, REG_FTMP3);
1423                         if (checkfloats) {
1424                                 M_DDIVS(s1,s2, REG_FTMP3);
1425                                 M_TRAPB;
1426                                 M_CVTDL_CS(REG_ZERO, REG_FTMP3, REG_FTMP3); /* round to integer */
1427                                 M_TRAPB;
1428                                 M_CVTLD(REG_ZERO, REG_FTMP3, REG_FTMP3);
1429                                 M_DMULS(REG_FTMP3, s2, REG_FTMP3);
1430                                 M_TRAPB;
1431                                 M_DSUBS(s1, REG_FTMP3, d);
1432                                 M_TRAPB;
1433                                 }
1434                         else {
1435                                 M_DDIV(s1,s2, REG_FTMP3);
1436                                 M_CVTDL_C(REG_ZERO, REG_FTMP3, REG_FTMP3); /* round to integer */
1437                                 M_CVTLD(REG_ZERO, REG_FTMP3, REG_FTMP3);
1438                                 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1439                                 M_DSUB(s1, REG_FTMP3, d);
1440                                 }
1441                         store_reg_to_var_flt(iptr->dst, d);
1442                     break;
1443
1444                 case ICMD_I2F:
1445                 case ICMD_L2F:
1446                         var_to_reg_int(s1, src, REG_ITMP1);
1447                         d = reg_of_var(iptr->dst, REG_FTMP3);
1448                         a = dseg_adddouble(0.0);
1449                         M_LST (s1, REG_PV, a);
1450                         M_DLD (d, REG_PV, a);
1451                         M_CVTLF(REG_ZERO, d, d);
1452                         store_reg_to_var_flt(iptr->dst, d);
1453                         break;
1454
1455                 case ICMD_I2D:
1456                 case ICMD_L2D:
1457                         var_to_reg_int(s1, src, REG_ITMP1);
1458                         d = reg_of_var(iptr->dst, REG_FTMP3);
1459                         a = dseg_adddouble(0.0);
1460                         M_LST (s1, REG_PV, a);
1461                         M_DLD (d, REG_PV, a);
1462                         M_CVTLD(REG_ZERO, d, d);
1463                         store_reg_to_var_flt(iptr->dst, d);
1464                         break;
1465                         
1466                 case ICMD_F2I:
1467                 case ICMD_D2I:
1468                         var_to_reg_flt(s1, src, REG_FTMP1);
1469                         d = reg_of_var(iptr->dst, REG_ITMP3);
1470                         a = dseg_adddouble(0.0);
1471                         if (checkfloats) {
1472                                 M_CVTDL_CS(REG_ZERO, s1, REG_FTMP1);
1473                                 M_TRAPB;
1474                                 M_CVTLIS(REG_FTMP1, REG_FTMP2);
1475                                 M_TRAPB;
1476                                 }
1477                         else {
1478                                 M_CVTDL_C(REG_ZERO, s1, REG_FTMP1);
1479                                 M_CVTLI(REG_FTMP1, REG_FTMP2);
1480                                 }
1481                         M_DST (REG_FTMP1, REG_PV, a);
1482                         M_ILD (d, REG_PV, a);
1483                         store_reg_to_var_int(iptr->dst, d);
1484                         break;
1485                 
1486                 case ICMD_F2L:
1487                 case ICMD_D2L:
1488                         var_to_reg_flt(s1, src, REG_FTMP1);
1489                         d = reg_of_var(iptr->dst, REG_ITMP3);
1490                         a = dseg_adddouble(0.0);
1491                         if (checkfloats) {
1492                                 M_CVTDL_CS(REG_ZERO, s1, REG_FTMP1);
1493                                 M_TRAPB;
1494                                 }
1495                         else {
1496                                 M_CVTDL_C(REG_ZERO, s1, REG_FTMP1);
1497                                 }
1498                         M_DST (REG_FTMP1, REG_PV, a);
1499                         M_LLD (d, REG_PV, a);
1500                         store_reg_to_var_int(iptr->dst, d);
1501                         break;
1502
1503                 case ICMD_F2D:
1504                         var_to_reg_flt(s1, src, REG_FTMP1);
1505                         d = reg_of_var(iptr->dst, REG_FTMP3);
1506                         M_FLTMOVE(s1, d);
1507                         store_reg_to_var_flt(iptr->dst, d);
1508                         break;
1509                                         
1510                 case ICMD_D2F:
1511                         var_to_reg_flt(s1, src, REG_FTMP1);
1512                         d = reg_of_var(iptr->dst, REG_FTMP3);
1513                         if (checkfloats) {
1514                                 M_CVTDFS(REG_ZERO, s1, d);
1515                                 M_TRAPB;
1516                                 }
1517                         else {
1518                                 M_CVTDF(REG_ZERO, s1, d);
1519                                 }
1520                         store_reg_to_var_flt(iptr->dst, d);
1521                         break;
1522                 
1523                 case ICMD_FCMPL:
1524                 case ICMD_DCMPL:
1525                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1526                         var_to_reg_flt(s2, src, REG_FTMP2);
1527                         d = reg_of_var(iptr->dst, REG_ITMP3);
1528                         if (checkfloats) {
1529                                 M_LSUB  (REG_ZERO, 1, d, 1);
1530                                 M_FCMPEQS(s1, s2, REG_FTMP3);
1531                                 M_TRAPB;
1532                                 M_FBEQZ (REG_FTMP3, 1);    /* jump over next instructions         */
1533                                 M_OR    (REG_ZERO, REG_ZERO, d, 0);
1534                                 M_FCMPLTS(s2, s1, REG_FTMP3);
1535                                 M_TRAPB;
1536                                 M_FBEQZ (REG_FTMP3, 1);    /* jump over next instruction          */
1537                                 M_LADD  (REG_ZERO, 1, d, 1);
1538                                 }
1539                         else {
1540                                 M_LSUB  (REG_ZERO, 1, d, 1);
1541                                 M_FCMPEQ(s1, s2, REG_FTMP3);
1542                                 M_FBEQZ (REG_FTMP3, 1);    /* jump over next instructions         */
1543                                 M_OR    (REG_ZERO, REG_ZERO, d, 0);
1544                                 M_FCMPLT(s2, s1, REG_FTMP3);
1545                                 M_FBEQZ (REG_FTMP3, 1);    /* jump over next instruction          */
1546                                 M_LADD  (REG_ZERO, 1, d, 1);
1547                                 }
1548                         store_reg_to_var_int(iptr->dst, d);
1549                         break;
1550                         
1551                 case ICMD_FCMPG:
1552                 case ICMD_DCMPG:
1553                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1554                         var_to_reg_flt(s2, src, REG_FTMP2);
1555                         d = reg_of_var(iptr->dst, REG_ITMP3);
1556                         if (checkfloats) {
1557                                 M_LADD  (REG_ZERO, 1, d, 1);
1558                                 M_FCMPEQS(s1, s2, REG_FTMP3);
1559                                 M_TRAPB;
1560                                 M_FBEQZ (REG_FTMP3, 1);    /* jump over next instruction          */
1561                                 M_OR    (REG_ZERO, REG_ZERO, d, 0);
1562                                 M_FCMPLTS(s1, s2, REG_FTMP3);
1563                                 M_TRAPB;
1564                                 M_FBEQZ (REG_FTMP3, 1);    /* jump over next instruction          */
1565                                 M_LSUB  (REG_ZERO, 1, d, 1);
1566                                 }
1567                         else {
1568                                 M_LADD  (REG_ZERO, 1, d, 1);
1569                                 M_FCMPEQ(s1, s2, REG_FTMP3);
1570                                 M_FBEQZ (REG_FTMP3, 1);    /* jump over next instruction          */
1571                                 M_OR    (REG_ZERO, REG_ZERO, d, 0);
1572                                 M_FCMPLT(s1, s2, REG_FTMP3);
1573                                 M_FBEQZ (REG_FTMP3, 1);    /* jump over next instruction          */
1574                                 M_LSUB  (REG_ZERO, 1, d, 1);
1575                                 }
1576                         store_reg_to_var_int(iptr->dst, d);
1577                         break;
1578
1579
1580                 /********************** memory operations *****************************/
1581
1582 #define gen_bound_check \
1583                         if (checkbounds) {\
1584                         M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\
1585                         M_CMPULT(s2, REG_ITMP3, REG_ITMP3, 0);\
1586                         M_BEQZ(REG_ITMP3, 0);\
1587                         mcode_addxboundrefs(mcodeptr);\
1588                         }
1589
1590                 case ICMD_ARRAYLENGTH:
1591                         var_to_reg_int(s1, src, REG_ITMP1);
1592                         d = reg_of_var(iptr->dst, REG_ITMP3);
1593                         gen_nullptr_check(s1);
1594                         M_ILD(d, s1, OFFSET(java_arrayheader, size));
1595                         store_reg_to_var_int(iptr->dst, d);
1596                         break;
1597
1598                 case ICMD_AALOAD:
1599                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1600                         var_to_reg_int(s2, src, REG_ITMP2);
1601                         d = reg_of_var(iptr->dst, REG_ITMP3);
1602                         gen_nullptr_check(s1);
1603                         gen_bound_check;
1604                         M_S8ADDQ(s2, s1, REG_ITMP1, 0);
1605                         M_LLD( d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1606                         store_reg_to_var_int(iptr->dst, d);
1607                         break;
1608                 case ICMD_LALOAD:
1609                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1610                         var_to_reg_int(s2, src, REG_ITMP2);
1611                         d = reg_of_var(iptr->dst, REG_ITMP3);
1612                         gen_nullptr_check(s1);
1613                         gen_bound_check;
1614                         M_S8ADDQ(s2, s1, REG_ITMP1, 0);
1615                         M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1616                         store_reg_to_var_int(iptr->dst, d);
1617                         break;
1618                 case ICMD_IALOAD:
1619                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1620                         var_to_reg_int(s2, src, REG_ITMP2);
1621                         d = reg_of_var(iptr->dst, REG_ITMP3);
1622                         gen_nullptr_check(s1);
1623                         gen_bound_check;
1624                         M_S4ADDQ(s2, s1, REG_ITMP1, 0);
1625                         M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1626                         store_reg_to_var_int(iptr->dst, d);
1627                         break;
1628                 case ICMD_FALOAD:
1629                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1630                         var_to_reg_int(s2, src, REG_ITMP2);
1631                         d = reg_of_var(iptr->dst, REG_FTMP3);
1632                         gen_nullptr_check(s1);
1633                         gen_bound_check;
1634                         M_S4ADDQ(s2, s1, REG_ITMP1, 0);
1635                         M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1636                         store_reg_to_var_flt(iptr->dst, d);
1637                         break;
1638                 case ICMD_DALOAD:
1639                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1640                         var_to_reg_int(s2, src, REG_ITMP2);
1641                         d = reg_of_var(iptr->dst, REG_FTMP3);
1642                         gen_nullptr_check(s1);
1643                         gen_bound_check;
1644                         M_S8ADDQ(s2, s1, REG_ITMP1, 0);
1645                         M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1646                         store_reg_to_var_flt(iptr->dst, d);
1647                         break;
1648                 case ICMD_CALOAD:
1649                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1650                         var_to_reg_int(s2, src, REG_ITMP2);
1651                         d = reg_of_var(iptr->dst, REG_ITMP3);
1652                         gen_nullptr_check(s1);
1653                         gen_bound_check;
1654                         if (has_ext_instr_set) {
1655                                 M_LADD(s2, s1, REG_ITMP1, 0);
1656                                 M_LADD(s2, REG_ITMP1, REG_ITMP1, 0);
1657                                 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1658                                 }
1659                         else {
1660                                 M_LADD (s2, s1, REG_ITMP1,  0);
1661                                 M_LADD (s2, REG_ITMP1, REG_ITMP1, 0);
1662                                 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1663                                 M_LDA  (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1664                                 M_EXTWL(REG_ITMP2, REG_ITMP1, d, 0);
1665                                 }
1666                         store_reg_to_var_int(iptr->dst, d);
1667                         break;                  
1668                 case ICMD_SALOAD:
1669                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1670                         var_to_reg_int(s2, src, REG_ITMP2);
1671                         d = reg_of_var(iptr->dst, REG_ITMP3);
1672                         gen_nullptr_check(s1);
1673                         gen_bound_check;
1674                         if (has_ext_instr_set) {
1675                                 M_LADD(s2, s1, REG_ITMP1, 0);
1676                                 M_LADD(s2, REG_ITMP1, REG_ITMP1, 0);
1677                                 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1678                                 M_SSEXT(d, d);
1679                                 }
1680                         else {
1681                                 M_LADD(s2, s1, REG_ITMP1,  0);
1682                                 M_LADD(s2, REG_ITMP1, REG_ITMP1, 0);
1683                                 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1684                                 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1685                                 M_EXTQH(REG_ITMP2, REG_ITMP1, d, 0);
1686                                 M_SRA(d, 48, d, 1);
1687                                 }
1688                         store_reg_to_var_int(iptr->dst, d);
1689                         break;
1690                 case ICMD_BALOAD:
1691                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1692                         var_to_reg_int(s2, src, REG_ITMP2);
1693                         d = reg_of_var(iptr->dst, REG_ITMP3);
1694                         gen_nullptr_check(s1);
1695                         gen_bound_check;
1696                         if (has_ext_instr_set) {
1697                                 M_LADD   (s2, s1, REG_ITMP1, 0);
1698                                 M_BLDU   (d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1699                                 M_BSEXT  (d, d);
1700                                 }
1701                         else {
1702                                 M_LADD(s2, s1, REG_ITMP1, 0);
1703                                 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1704                                 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
1705                                 M_EXTQH(REG_ITMP2, REG_ITMP1, d, 0);
1706                                 M_SRA(d, 56, d, 1);
1707                                 }
1708                         store_reg_to_var_int(iptr->dst, d);
1709                         break;
1710
1711                 case ICMD_AASTORE:
1712                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1713                         var_to_reg_int(s2, src->prev, REG_ITMP2);
1714                         gen_nullptr_check(s1);
1715                         gen_bound_check;
1716                         var_to_reg_int(s3, src, REG_ITMP3);
1717                         M_S8ADDQ(s2, s1, REG_ITMP1, 0);
1718                         M_LST   (s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1719                         break;
1720                 case ICMD_LASTORE:
1721                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1722                         var_to_reg_int(s2, src->prev, REG_ITMP2);
1723                         gen_nullptr_check(s1);
1724                         gen_bound_check;
1725                         var_to_reg_int(s3, src, REG_ITMP3);
1726                         M_S8ADDQ(s2, s1, REG_ITMP1, 0);
1727                         M_LST   (s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1728                         break;
1729                 case ICMD_IASTORE:
1730                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1731                         var_to_reg_int(s2, src->prev, REG_ITMP2);
1732                         gen_nullptr_check(s1);
1733                         gen_bound_check;
1734                         var_to_reg_int(s3, src, REG_ITMP3);
1735                         M_S4ADDQ(s2, s1, REG_ITMP1, 0);
1736                         M_IST   (s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1737                         break;
1738                 case ICMD_FASTORE:
1739                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1740                         var_to_reg_int(s2, src->prev, REG_ITMP2);
1741                         gen_nullptr_check(s1);
1742                         gen_bound_check;
1743                         var_to_reg_flt(s3, src, REG_FTMP3);
1744                         M_S4ADDQ(s2, s1, REG_ITMP1, 0);
1745                         M_FST   (s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1746                         break;
1747                 case ICMD_DASTORE:
1748                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1749                         var_to_reg_int(s2, src->prev, REG_ITMP2);
1750                         gen_nullptr_check(s1);
1751                         gen_bound_check;
1752                         var_to_reg_flt(s3, src, REG_FTMP3);
1753                         M_S8ADDQ(s2, s1, REG_ITMP1, 0);
1754                         M_DST   (s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1755                         break;
1756                 case ICMD_CASTORE:
1757                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1758                         var_to_reg_int(s2, src->prev, REG_ITMP2);
1759                         gen_nullptr_check(s1);
1760                         gen_bound_check;
1761                         var_to_reg_int(s3, src, REG_ITMP3);
1762                         if (has_ext_instr_set) {
1763                                 M_LADD(s2, s1, REG_ITMP1, 0);
1764                                 M_LADD(s2, REG_ITMP1, REG_ITMP1, 0);
1765                                 M_SST (s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1766                                 }
1767                         else {
1768                                 M_LADD (s2, s1, REG_ITMP1, 0);
1769                                 M_LADD (s2, REG_ITMP1, REG_ITMP1, 0);
1770                                 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1771                                 M_LDA  (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1772                                 M_INSWL(s3, REG_ITMP1, REG_ITMP3, 0);
1773                                 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2, 0);
1774                                 M_OR   (REG_ITMP2, REG_ITMP3, REG_ITMP2, 0);
1775                                 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1776                                 }
1777                         break;
1778                 case ICMD_SASTORE:
1779                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1780                         var_to_reg_int(s2, src->prev, REG_ITMP2);
1781                         gen_nullptr_check(s1);
1782                         gen_bound_check;
1783                         var_to_reg_int(s3, src, REG_ITMP3);
1784                         if (has_ext_instr_set) {
1785                                 M_LADD(s2, s1, REG_ITMP1, 0);
1786                                 M_LADD(s2, REG_ITMP1, REG_ITMP1, 0);
1787                                 M_SST (s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1788                                 }
1789                         else {
1790                                 M_LADD (s2, s1, REG_ITMP1, 0);
1791                                 M_LADD (s2, REG_ITMP1, REG_ITMP1, 0);
1792                                 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1793                                 M_LDA  (REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1794                                 M_INSWL(s3, REG_ITMP1, REG_ITMP3, 0);
1795                                 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2, 0);
1796                                 M_OR   (REG_ITMP2, REG_ITMP3, REG_ITMP2, 0);
1797                                 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1798                                 }
1799                         break;
1800                 case ICMD_BASTORE:
1801                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1802                         var_to_reg_int(s2, src->prev, REG_ITMP2);
1803                         gen_nullptr_check(s1);
1804                         gen_bound_check;
1805                         var_to_reg_int(s3, src, REG_ITMP3);
1806                         if (has_ext_instr_set) {
1807                                 M_LADD(s2, s1, REG_ITMP1, 0);
1808                                 M_BST (s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1809                                 }
1810                         else {
1811                                 M_LADD (s2, s1, REG_ITMP1,  0);
1812                                 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1813                                 M_LDA  (REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1814                                 M_INSBL(s3, REG_ITMP1, REG_ITMP3, 0);
1815                                 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2, 0);
1816                                 M_OR   (REG_ITMP2, REG_ITMP3, REG_ITMP2, 0);
1817                                 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1818                                 }
1819                         break;
1820
1821
1822                 case ICMD_PUTSTATIC:
1823                         a = dseg_addaddress (iptr->val.a);
1824                         M_LLD(REG_ITMP1, REG_PV, a);
1825                         switch (iptr->op1) {
1826                                 case TYPE_INT:
1827                                         var_to_reg_int(s2, src, REG_ITMP2);
1828                                         M_IST(s2, REG_ITMP1, 0);
1829                                         break;
1830                                 case TYPE_LNG:
1831                                 case TYPE_ADR:
1832                                         var_to_reg_int(s2, src, REG_ITMP2);
1833                                         M_LST(s2, REG_ITMP1, 0);
1834                                         break;
1835                                 case TYPE_FLT:
1836                                         var_to_reg_flt(s2, src, REG_FTMP2);
1837                                         M_FST(s2, REG_ITMP1, 0);
1838                                         break;
1839                                 case TYPE_DBL:
1840                                         var_to_reg_flt(s2, src, REG_FTMP2);
1841                                         M_DST(s2, REG_ITMP1, 0);
1842                                         break;
1843                                 default: panic ("internal error");
1844                                 }
1845                         break;
1846
1847                 case ICMD_GETSTATIC:
1848                         a = dseg_addaddress (iptr->val.a);
1849                         M_LLD(REG_ITMP1, REG_PV, a);
1850                         switch (iptr->op1) {
1851                                 case TYPE_INT:
1852                                         d = reg_of_var(iptr->dst, REG_ITMP3);
1853                                         M_ILD(d, REG_ITMP1, 0);
1854                                         store_reg_to_var_int(iptr->dst, d);
1855                                         break;
1856                                 case TYPE_LNG:
1857                                 case TYPE_ADR:
1858                                         d = reg_of_var(iptr->dst, REG_ITMP3);
1859                                         M_LLD(d, REG_ITMP1, 0);
1860                                         store_reg_to_var_int(iptr->dst, d);
1861                                         break;
1862                                 case TYPE_FLT:
1863                                         d = reg_of_var(iptr->dst, REG_FTMP1);
1864                                         M_FLD(d, REG_ITMP1, 0);
1865                                         store_reg_to_var_flt(iptr->dst, d);
1866                                         break;
1867                                 case TYPE_DBL:                          
1868                                         d = reg_of_var(iptr->dst, REG_FTMP1);
1869                                         M_DLD(d, REG_ITMP1, 0);
1870                                         store_reg_to_var_flt(iptr->dst, d);
1871                                         break;
1872                                 default: panic ("internal error");
1873                                 }
1874                         break;
1875
1876
1877                 case ICMD_PUTFIELD:
1878                         switch (iptr->op1) {
1879                                 case TYPE_INT:
1880                                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1881                                         var_to_reg_int(s2, src, REG_ITMP2);
1882                                         gen_nullptr_check(s1);
1883                                         M_IST(s2, s1, iptr->val.i);
1884                                         break;
1885                                 case TYPE_LNG:
1886                                 case TYPE_ADR:
1887                                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1888                                         var_to_reg_int(s2, src, REG_ITMP2);
1889                                         gen_nullptr_check(s1);
1890                                         M_LST(s2, s1, iptr->val.i);
1891                                         break;
1892                                 case TYPE_FLT:
1893                                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1894                                         var_to_reg_flt(s2, src, REG_FTMP2);
1895                                         gen_nullptr_check(s1);
1896                                         M_FST(s2, s1, iptr->val.i);
1897                                         break;
1898                                 case TYPE_DBL:
1899                                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1900                                         var_to_reg_flt(s2, src, REG_FTMP2);
1901                                         gen_nullptr_check(s1);
1902                                         M_DST(s2, s1, iptr->val.i);
1903                                         break;
1904                                 default: panic ("internal error");
1905                                 }
1906                         break;
1907
1908                 case ICMD_GETFIELD:
1909                         switch (iptr->op1) {
1910                                 case TYPE_INT:
1911                                         var_to_reg_int(s1, src, REG_ITMP1);
1912                                         d = reg_of_var(iptr->dst, REG_ITMP3);
1913                                         gen_nullptr_check(s1);
1914                                         M_ILD(d, s1, iptr->val.i);
1915                                         store_reg_to_var_int(iptr->dst, d);
1916                                         break;
1917                                 case TYPE_LNG:
1918                                 case TYPE_ADR:
1919                                         var_to_reg_int(s1, src, REG_ITMP1);
1920                                         d = reg_of_var(iptr->dst, REG_ITMP3);
1921                                         gen_nullptr_check(s1);
1922                                         M_LLD(d, s1, iptr->val.i);
1923                                         store_reg_to_var_int(iptr->dst, d);
1924                                         break;
1925                                 case TYPE_FLT:
1926                                         var_to_reg_int(s1, src, REG_ITMP1);
1927                                         d = reg_of_var(iptr->dst, REG_FTMP1);
1928                                         gen_nullptr_check(s1);
1929                                         M_FLD(d, s1, iptr->val.i);
1930                                         store_reg_to_var_flt(iptr->dst, d);
1931                                         break;
1932                                 case TYPE_DBL:                          
1933                                         var_to_reg_int(s1, src, REG_ITMP1);
1934                                         d = reg_of_var(iptr->dst, REG_FTMP1);
1935                                         gen_nullptr_check(s1);
1936                                         M_DLD(d, s1, iptr->val.i);
1937                                         store_reg_to_var_flt(iptr->dst, d);
1938                                         break;
1939                                 default: panic ("internal error");
1940                                 }
1941                         break;
1942
1943
1944                 /********************** branch operations *****************************/
1945
1946 #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}}
1947
1948                 case ICMD_ATHROW:
1949                         var_to_reg_int(s1, src, REG_ITMP1);
1950                         M_INTMOVE(s1, REG_ITMP1_XPTR);
1951                         a = dseg_addaddress(asm_handle_exception);
1952                         M_LLD(REG_ITMP2, REG_PV, a);
1953                         M_JMP(REG_ITMP2_XPC, REG_ITMP2);
1954                         ALIGNCODENOP;
1955                         break;
1956
1957                 case ICMD_GOTO:
1958                         M_BR(0);
1959                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
1960                         ALIGNCODENOP;
1961                         break;
1962
1963                 case ICMD_JSR:
1964                         M_BSR(REG_ITMP1, 0);
1965                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
1966                         break;
1967                         
1968                 case ICMD_RET:
1969                         var = &(locals[iptr->op1][TYPE_ADR]);
1970                         if (var->flags & INMEMORY) {
1971                                 M_LLD(REG_ITMP1, REG_SP, 8 * var->regoff);
1972                                 M_RET(REG_ZERO, REG_ITMP1);
1973                                 }
1974                         else
1975                                 M_RET(REG_ZERO, var->regoff);
1976                         ALIGNCODENOP;
1977                         break;
1978
1979                 case ICMD_IFNULL:
1980                         var_to_reg_int(s1, src, REG_ITMP1);
1981                         M_BEQZ(s1, 0);
1982                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
1983                         break;
1984                 case ICMD_IFNONNULL:
1985                         var_to_reg_int(s1, src, REG_ITMP1);
1986                         M_BNEZ(s1, 0);
1987                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
1988                         break;
1989
1990                 case ICMD_IFEQ:
1991                         var_to_reg_int(s1, src, REG_ITMP1);
1992                         if (iptr->val.i == 0) {
1993                                 M_BEQZ(s1, 0);
1994                                 }
1995                         else {
1996                                 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
1997                                         M_CMPEQ(s1, iptr->val.i, REG_ITMP1, 1);
1998                                         }
1999                                 else {
2000                                         ICONST(REG_ITMP2, iptr->val.i);
2001                                         M_CMPEQ(s1, REG_ITMP2, REG_ITMP1, 0);
2002                                         }
2003                                 M_BNEZ(REG_ITMP1, 0);
2004                                 }
2005                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2006                         break;
2007                 case ICMD_IFLT:
2008                         var_to_reg_int(s1, src, REG_ITMP1);
2009                         if (iptr->val.i == 0) {
2010                                 M_BLTZ(s1, 0);
2011                                 }
2012                         else {
2013                                 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2014                                         M_CMPLT(s1, iptr->val.i, REG_ITMP1, 1);
2015                                         }
2016                                 else {
2017                                         ICONST(REG_ITMP2, iptr->val.i);
2018                                         M_CMPLT(s1, REG_ITMP2, REG_ITMP1, 0);
2019                                         }
2020                                 M_BNEZ(REG_ITMP1, 0);
2021                                 }
2022                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2023                         break;
2024                 case ICMD_IFLE:
2025                         var_to_reg_int(s1, src, REG_ITMP1);
2026                         if (iptr->val.i == 0) {
2027                                 M_BLEZ(s1, 0);
2028                                 }
2029                         else {
2030                                 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2031                                         M_CMPLE(s1, iptr->val.i, REG_ITMP1, 1);
2032                                         }
2033                                 else {
2034                                         ICONST(REG_ITMP2, iptr->val.i);
2035                                         M_CMPLE(s1, REG_ITMP2, REG_ITMP1, 0);
2036                                         }
2037                                 M_BNEZ(REG_ITMP1, 0);
2038                                 }
2039                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2040                         break;
2041                 case ICMD_IFNE:
2042                         var_to_reg_int(s1, src, REG_ITMP1);
2043                         if (iptr->val.i == 0) {
2044                                 M_BNEZ(s1, 0);
2045                                 }
2046                         else {
2047                                 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2048                                         M_CMPEQ(s1, iptr->val.i, REG_ITMP1, 1);
2049                                         }
2050                                 else {
2051                                         ICONST(REG_ITMP2, iptr->val.i);
2052                                         M_CMPEQ(s1, REG_ITMP2, REG_ITMP1, 0);
2053                                         }
2054                                 M_BEQZ(REG_ITMP1, 0);
2055                                 }
2056                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2057                         break;
2058                 case ICMD_IFGT:
2059                         var_to_reg_int(s1, src, REG_ITMP1);
2060                         if (iptr->val.i == 0) {
2061                                 M_BGTZ(s1, 0);
2062                                 }
2063                         else {
2064                                 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2065                                         M_CMPLE(s1, iptr->val.i, REG_ITMP1, 1);
2066                                         }
2067                                 else {
2068                                         ICONST(REG_ITMP2, iptr->val.i);
2069                                         M_CMPLE(s1, REG_ITMP2, REG_ITMP1, 0);
2070                                         }
2071                                 M_BEQZ(REG_ITMP1, 0);
2072                                 }
2073                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2074                         break;
2075                 case ICMD_IFGE:
2076                         var_to_reg_int(s1, src, REG_ITMP1);
2077                         if (iptr->val.i == 0) {
2078                                 M_BGEZ(s1, 0);
2079                                 }
2080                         else {
2081                                 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2082                                         M_CMPLT(s1, iptr->val.i, REG_ITMP1, 1);
2083                                         }
2084                                 else {
2085                                         ICONST(REG_ITMP2, iptr->val.i);
2086                                         M_CMPLT(s1, REG_ITMP2, REG_ITMP1, 0);
2087                                         }
2088                                 M_BEQZ(REG_ITMP1, 0);
2089                                 }
2090                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2091                         break;
2092
2093                 case ICMD_IF_LEQ:
2094                         var_to_reg_int(s1, src, REG_ITMP1);
2095                         if (iptr->val.l == 0) {
2096                                 M_BEQZ(s1, 0);
2097                                 }
2098                         else {
2099                                 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2100                                         M_CMPEQ(s1, iptr->val.l, REG_ITMP1, 1);
2101                                         }
2102                                 else {
2103                                         LCONST(REG_ITMP2, iptr->val.l);
2104                                         M_CMPEQ(s1, REG_ITMP2, REG_ITMP1, 0);
2105                                         }
2106                                 M_BNEZ(REG_ITMP1, 0);
2107                                 }
2108                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2109                         break;
2110                 case ICMD_IF_LLT:
2111                         var_to_reg_int(s1, src, REG_ITMP1);
2112                         if (iptr->val.l == 0) {
2113                                 M_BLTZ(s1, 0);
2114                                 }
2115                         else {
2116                                 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2117                                         M_CMPLT(s1, iptr->val.l, REG_ITMP1, 1);
2118                                         }
2119                                 else {
2120                                         LCONST(REG_ITMP2, iptr->val.l);
2121                                         M_CMPLT(s1, REG_ITMP2, REG_ITMP1, 0);
2122                                         }
2123                                 M_BNEZ(REG_ITMP1, 0);
2124                                 }
2125                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2126                         break;
2127                 case ICMD_IF_LLE:
2128                         var_to_reg_int(s1, src, REG_ITMP1);
2129                         if (iptr->val.l == 0) {
2130                                 M_BLEZ(s1, 0);
2131                                 }
2132                         else {
2133                                 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2134                                         M_CMPLE(s1, iptr->val.l, REG_ITMP1, 1);
2135                                         }
2136                                 else {
2137                                         LCONST(REG_ITMP2, iptr->val.l);
2138                                         M_CMPLE(s1, REG_ITMP2, REG_ITMP1, 0);
2139                                         }
2140                                 M_BNEZ(REG_ITMP1, 0);
2141                                 }
2142                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2143                         break;
2144                 case ICMD_IF_LNE:
2145                         var_to_reg_int(s1, src, REG_ITMP1);
2146                         if (iptr->val.l == 0) {
2147                                 M_BNEZ(s1, 0);
2148                                 }
2149                         else {
2150                                 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2151                                         M_CMPEQ(s1, iptr->val.l, REG_ITMP1, 1);
2152                                         }
2153                                 else {
2154                                         LCONST(REG_ITMP2, iptr->val.l);
2155                                         M_CMPEQ(s1, REG_ITMP2, REG_ITMP1, 0);
2156                                         }
2157                                 M_BEQZ(REG_ITMP1, 0);
2158                                 }
2159                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2160                         break;
2161                 case ICMD_IF_LGT:
2162                         var_to_reg_int(s1, src, REG_ITMP1);
2163                         if (iptr->val.l == 0) {
2164                                 M_BGTZ(s1, 0);
2165                                 }
2166                         else {
2167                                 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2168                                         M_CMPLE(s1, iptr->val.l, REG_ITMP1, 1);
2169                                         }
2170                                 else {
2171                                         LCONST(REG_ITMP2, iptr->val.l);
2172                                         M_CMPLE(s1, REG_ITMP2, REG_ITMP1, 0);
2173                                         }
2174                                 M_BEQZ(REG_ITMP1, 0);
2175                                 }
2176                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2177                         break;
2178                 case ICMD_IF_LGE:
2179                         var_to_reg_int(s1, src, REG_ITMP1);
2180                         if (iptr->val.l == 0) {
2181                                 M_BGEZ(s1, 0);
2182                                 }
2183                         else {
2184                                 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2185                                         M_CMPLT(s1, iptr->val.l, REG_ITMP1, 1);
2186                                         }
2187                                 else {
2188                                         LCONST(REG_ITMP2, iptr->val.l);
2189                                         M_CMPLT(s1, REG_ITMP2, REG_ITMP1, 0);
2190                                         }
2191                                 M_BEQZ(REG_ITMP1, 0);
2192                                 }
2193                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2194                         break;
2195
2196                 case ICMD_IF_ICMPEQ:
2197                 case ICMD_IF_LCMPEQ:
2198                 case ICMD_IF_ACMPEQ:
2199                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2200                         var_to_reg_int(s2, src, REG_ITMP2);
2201                         M_CMPEQ(s1, s2, REG_ITMP1, 0);
2202                         M_BNEZ(REG_ITMP1, 0);
2203                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2204                         break;
2205                 case ICMD_IF_ICMPNE:
2206                 case ICMD_IF_LCMPNE:
2207                 case ICMD_IF_ACMPNE:
2208                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2209                         var_to_reg_int(s2, src, REG_ITMP2);
2210                         M_CMPEQ(s1, s2, REG_ITMP1, 0);
2211                         M_BEQZ(REG_ITMP1, 0);
2212                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2213                         break;
2214                 case ICMD_IF_ICMPLT:
2215                 case ICMD_IF_LCMPLT:
2216                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2217                         var_to_reg_int(s2, src, REG_ITMP2);
2218                         M_CMPLT(s1, s2, REG_ITMP1, 0);
2219                         M_BNEZ(REG_ITMP1, 0);
2220                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2221                         break;
2222                 case ICMD_IF_ICMPGT:
2223                 case ICMD_IF_LCMPGT:
2224                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2225                         var_to_reg_int(s2, src, REG_ITMP2);
2226                         M_CMPLE(s1, s2, REG_ITMP1, 0);
2227                         M_BEQZ(REG_ITMP1, 0);
2228                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2229                         break;
2230                 case ICMD_IF_ICMPLE:
2231                 case ICMD_IF_LCMPLE:
2232                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2233                         var_to_reg_int(s2, src, REG_ITMP2);
2234                         M_CMPLE(s1, s2, REG_ITMP1, 0);
2235                         M_BNEZ(REG_ITMP1, 0);
2236                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2237                         break;
2238                 case ICMD_IF_ICMPGE:
2239                 case ICMD_IF_LCMPGE:
2240                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2241                         var_to_reg_int(s2, src, REG_ITMP2);
2242                         M_CMPLT(s1, s2, REG_ITMP1,  0);
2243                         M_BEQZ(REG_ITMP1, 0);
2244                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2245                         break;
2246
2247 /*   branch if the unsigned value of s1 is greater that s2 (note, that s2 has
2248          to be >= 0) */
2249
2250 /*              case ICMD_IF_UCMPGE: 
2251                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2252                         var_to_reg_int(s2, src, REG_ITMP2);
2253                         M_CMPULE(s2, s1, REG_ITMP1, 0);
2254                         M_BNEZ(REG_ITMP1, 0);
2255                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2256             break;
2257 */
2258
2259                 case ICMD_IRETURN:
2260                 case ICMD_LRETURN:
2261                 case ICMD_ARETURN:
2262
2263 #ifdef USE_THREADS
2264                         if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2265                                 a = dseg_addaddress ((void*) (builtin_monitorexit));
2266                                 M_LLD(REG_PV, REG_PV, a);
2267                                 M_LLD(argintregs[0], REG_SP, 8 * maxmemuse);
2268                                 M_JSR(REG_RA, REG_PV);
2269                                 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2270                                 }                       
2271 #endif
2272                         var_to_reg_int(s1, src, REG_RESULT);
2273                         M_INTMOVE(s1, REG_RESULT);
2274                         goto nowperformreturn;
2275
2276                 case ICMD_FRETURN:
2277                 case ICMD_DRETURN:
2278
2279 #ifdef USE_THREADS
2280                         if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2281                                 a = dseg_addaddress ((void*) (builtin_monitorexit));
2282                                 M_LLD(REG_PV, REG_PV, a);
2283                                 M_LLD(argintregs[0], REG_SP, 8 * maxmemuse);
2284                                 M_JSR(REG_RA, REG_PV);
2285                                 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2286                                 }                       
2287 #endif
2288                         var_to_reg_flt(s1, src, REG_FRESULT);
2289                         M_FLTMOVE(s1, REG_FRESULT);
2290                         goto nowperformreturn;
2291
2292                 case ICMD_RETURN:
2293
2294 #ifdef USE_THREADS
2295                         if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2296                                 a = dseg_addaddress ((void*) (builtin_monitorexit));
2297                                 M_LLD(REG_PV, REG_PV, a);
2298                                 M_LLD(argintregs[0], REG_SP, 8 * maxmemuse);
2299                                 M_JSR(REG_RA, REG_PV);
2300                                 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2301                                 }                       
2302 #endif
2303
2304 nowperformreturn:
2305                         {
2306                         int r, p;
2307                         
2308                         p = parentargs_base;
2309                         if (!isleafmethod)
2310                                 {p--;  M_LLD (REG_RA, REG_SP, 8 * p);}
2311                         for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
2312                                         {p--; M_LLD(savintregs[r], REG_SP, 8 * p);}
2313                         for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
2314                                         {p--; M_DLD(savfltregs[r], REG_SP, 8 * p);}
2315
2316                         if (parentargs_base)
2317                                 {M_LDA(REG_SP, REG_SP, parentargs_base*8);}
2318                         if (runverbose) {
2319                                 M_LDA (REG_SP, REG_SP, -24);
2320                                 M_LST(REG_RA, REG_SP, 0);
2321                                 M_LST(REG_RESULT, REG_SP, 8);
2322                                 M_DST(REG_FRESULT, REG_SP,16);
2323                                 a = dseg_addaddress (method);
2324                                 M_LLD(argintregs[0], REG_PV, a);
2325                                 M_OR(REG_RESULT, REG_RESULT, argintregs[1], 0);
2326                                 M_FLTMOVE(REG_FRESULT, argfltregs[2]);
2327                                 a = dseg_addaddress ((void*) (builtin_displaymethodstop));
2328                                 M_LLD(REG_PV, REG_PV, a);
2329                                 M_JSR (REG_RA, REG_PV);
2330                                 s1 = (int)((u1*) mcodeptr - mcodebase);
2331                                 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
2332                                 else {
2333                                         s4 ml=-s1, mh=0;
2334                                         while (ml<-32768) { ml+=65536; mh--; }
2335                                         M_LDA (REG_PV, REG_RA, ml );
2336                                         M_LDAH (REG_PV, REG_PV, mh );
2337                                         }
2338                                 M_DLD(REG_FRESULT, REG_SP,16);
2339                                 M_LLD(REG_RESULT, REG_SP, 8);
2340                                 M_LLD(REG_RA, REG_SP, 0);
2341                                 M_LDA (REG_SP, REG_SP, 24);
2342                                 }
2343                         M_RET(REG_ZERO, REG_RA);
2344                         ALIGNCODENOP;
2345                         }
2346                         break;
2347
2348
2349                 case ICMD_TABLESWITCH:
2350                         {
2351                         s4 i, l, *s4ptr;
2352
2353                         s4ptr = iptr->val.a;
2354                         l = s4ptr[1];                          /* low     */
2355                         i = s4ptr[2];                          /* high    */
2356                         
2357                         var_to_reg_int(s1, src, REG_ITMP1);
2358                         if (l == 0)
2359                                 {M_INTMOVE(s1, REG_ITMP1);}
2360                         else
2361                                 M_LDA(REG_ITMP1, s1, -l);
2362                         i = i - l + 1;
2363
2364                         if (i <= 256)
2365                                 M_CMPULE(REG_ITMP1, i - 1, REG_ITMP2, 1);
2366                         else {
2367                                 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
2368                                 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2, 0);
2369                                 }
2370                         M_BEQZ(REG_ITMP2, 0);
2371                         mcode_addreference(BlockPtrOfPC(s4ptr[0]), mcodeptr);
2372
2373                         /* build jump table top down and use address of lowest entry */
2374
2375                         s4ptr += 3 + i;
2376                         while (--i >= 0) {
2377                                 dseg_addtarget(BlockPtrOfPC(*--s4ptr));
2378                                 }
2379                         }
2380
2381                         /* length of dataseg after last dseg_addtarget is used by load */
2382
2383                         M_S8ADDQ(REG_ITMP1, REG_PV, REG_ITMP2, 0);
2384                         M_LLD(REG_ITMP2, REG_ITMP2, -dseglen);
2385                         M_JMP(REG_ZERO, REG_ITMP2);
2386                         ALIGNCODENOP;
2387                         break;
2388
2389
2390                 case ICMD_LOOKUPSWITCH:
2391                         {
2392                         s4 i, l, val, *s4ptr;
2393
2394                         s4ptr = iptr->val.a;
2395                         l = s4ptr[0];                          /* default  */
2396                         i = s4ptr[1];                          /* count    */
2397                         
2398                         MCODECHECK((i<<2)+8);
2399                         var_to_reg_int(s1, src, REG_ITMP1);
2400                         while (--i >= 0) {
2401                                 s4ptr += 2;
2402                                 val = s4ptr[0];
2403                                 if ((val >= 0) && (val <= 255)) {
2404                                         M_CMPEQ(s1, val, REG_ITMP2, 1);
2405                                         }
2406                                 else {
2407                                         if ((val >= -32768) && (val <= 32767)) {
2408                                                 M_LDA(REG_ITMP2, REG_ZERO, val);
2409                                                 } 
2410                                         else {
2411                                                 a = dseg_adds4 (val);
2412                                                 M_ILD(REG_ITMP2, REG_PV, a);
2413                                                 }
2414                                         M_CMPEQ(s1, REG_ITMP2, REG_ITMP2, 0);
2415                                         }
2416                                 M_BNEZ(REG_ITMP2, 0);
2417                                 mcode_addreference(BlockPtrOfPC(s4ptr[1]), mcodeptr);
2418                                 }
2419
2420                         M_BR(0);
2421                         mcode_addreference(BlockPtrOfPC(l), mcodeptr);
2422                         ALIGNCODENOP;
2423                         break;
2424                         }
2425
2426
2427                 case ICMD_BUILTIN3:
2428                         s3 = 3;
2429                         goto gen_method;
2430
2431                 case ICMD_BUILTIN2:
2432                         s3 = 2;
2433                         goto gen_method;
2434
2435                 case ICMD_BUILTIN1:
2436                         s3 = 1;
2437                         goto gen_method;
2438
2439                 case ICMD_INVOKESTATIC:
2440                 case ICMD_INVOKESPECIAL:
2441                 case ICMD_INVOKEVIRTUAL:
2442                 case ICMD_INVOKEINTERFACE:
2443                         s3 = iptr->op1;
2444
2445 gen_method: {
2446                         methodinfo   *m;
2447                         classinfo    *ci;
2448
2449                         MCODECHECK((s3 << 1) + 64);
2450
2451                         for (; --s3 >= 0; src = src->prev) {
2452                                 if (src->varkind == ARGVAR)
2453                                         continue;
2454                                 if (IS_INT_LNG_TYPE(src->type)) {
2455                                         if (s3 < INT_ARG_CNT) {
2456                                                 s1 = argintregs[s3];
2457                                                 var_to_reg_int(d, src, s1);
2458                                                 M_INTMOVE(d, s1);
2459                                                 }
2460                                         else  {
2461                                                 var_to_reg_int(d, src, REG_ITMP1);
2462                                                 M_LST(d, REG_SP, 8 * (s3 - INT_ARG_CNT));
2463                                                 }
2464                                         }
2465                                 else
2466                                         if (s3 < FLT_ARG_CNT) {
2467                                                 s1 = argfltregs[s3];
2468                                                 var_to_reg_flt(d, src, s1);
2469                                                 M_FLTMOVE(d, s1);
2470                                                 }
2471                                         else {
2472                                                 var_to_reg_flt(d, src, REG_FTMP1);
2473                                                 M_DST(d, REG_SP, 8 * (s3 - FLT_ARG_CNT));
2474                                                 }
2475                                 } /* end of for */
2476
2477                         m = iptr->val.a;
2478                         switch (iptr->opc) {
2479                                 case ICMD_BUILTIN3:
2480                                 case ICMD_BUILTIN2:
2481                                 case ICMD_BUILTIN1:
2482                                         a = dseg_addaddress ((void*) (m));
2483
2484                                         M_LLD(REG_PV, REG_PV, a); /* Pointer to built-in-function */
2485                                         d = iptr->op1;
2486                                         goto makeactualcall;
2487
2488                                 case ICMD_INVOKESTATIC:
2489                                 case ICMD_INVOKESPECIAL:
2490                                         a = dseg_addaddress (m->stubroutine);
2491
2492                                         M_LLD(REG_PV, REG_PV, a );       /* Method-Pointer in r27 */
2493
2494                                         d = m->returntype;
2495                                         goto makeactualcall;
2496
2497                                 case ICMD_INVOKEVIRTUAL:
2498
2499                                         gen_nullptr_check(argintregs[0]);
2500                                         M_LLD(REG_METHODPTR, argintregs[0],
2501                                                                  OFFSET(java_objectheader, vftbl));
2502                                         M_LLD(REG_PV, REG_METHODPTR, OFFSET(vftbl, table[0]) +
2503                                                                 sizeof(methodptr) * m->vftblindex);
2504
2505                                         d = m->returntype;
2506                                         goto makeactualcall;
2507
2508                                 case ICMD_INVOKEINTERFACE:
2509                                         ci = m->class;
2510                                         
2511                                         gen_nullptr_check(argintregs[0]);
2512                                         M_LLD(REG_METHODPTR, argintregs[0],
2513                                                                  OFFSET(java_objectheader, vftbl));    
2514                                         M_LLD(REG_METHODPTR, REG_METHODPTR,
2515                                                                     OFFSET(vftbl, interfacevftbl));
2516                                         M_LLD(REG_METHODPTR, REG_METHODPTR,
2517                                                                    sizeof(methodptr*) * ci->index);
2518                                         M_LLD(REG_PV, REG_METHODPTR,
2519                                                             sizeof(methodptr) * (m - ci->methods));
2520
2521                                         d = m->returntype;
2522                                         goto makeactualcall;
2523
2524                                 default:
2525                                         d = 0;
2526                                         sprintf (logtext, "Unkown ICMD-Command: %d", iptr->opc);
2527                                         error ();
2528                                 }
2529
2530 makeactualcall:
2531
2532                         M_JSR (REG_RA, REG_PV);
2533                         s1 = (int)((u1*) mcodeptr - mcodebase);
2534                         if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
2535                         else {
2536                                 s4 ml=-s1, mh=0;
2537                                 while (ml<-32768) { ml+=65536; mh--; }
2538                                 M_LDA (REG_PV, REG_RA, ml );
2539                                 M_LDAH (REG_PV, REG_PV, mh );
2540                                 }
2541
2542                         if (d != TYPE_VOID) {
2543                                 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
2544                                         s1 = reg_of_var(iptr->dst, REG_RESULT);
2545                                         M_INTMOVE(REG_RESULT, s1);
2546                                         store_reg_to_var_int(iptr->dst, s1);
2547                                         }
2548                                 else {
2549                                         s1 = reg_of_var(iptr->dst, REG_FRESULT);
2550                                         M_FLTMOVE(REG_FRESULT, s1);
2551                                         store_reg_to_var_flt(iptr->dst, s1);
2552                                         }
2553                                 }
2554                         }
2555                         break;
2556
2557                 case ICMD_CHECKASIZE:
2558                         var_to_reg_int(s1, src, REG_ITMP1);
2559                         M_BLTZ(s1, 0);
2560                         mcode_addxcheckarefs(mcodeptr);
2561                         break;
2562
2563                 case ICMD_MULTIANEWARRAY:
2564
2565                         /* check for negative sizes and copy sizes to stack if necessary  */
2566
2567                         MCODECHECK((iptr->op1 << 1) + 64);
2568
2569                         for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
2570                                 var_to_reg_int(s2, src, REG_ITMP1);
2571                                 M_BLTZ(s2, 0);
2572                                 mcode_addxcheckarefs(mcodeptr);
2573
2574                                 /* copy sizes to stack (argument numbers >= INT_ARG_CNT)      */
2575
2576                                 if (src->varkind != ARGVAR) {
2577                                         M_LST(s2, REG_SP, 8 * (s1 + INT_ARG_CNT));
2578                                         }
2579                                 }
2580
2581                         /* a0 = dimension count */
2582
2583                         M_LDA(argintregs[0], REG_ZERO, iptr->op1);
2584
2585                         /* a1 = arraydescriptor */
2586
2587                         a = dseg_addaddress(iptr->val.a);
2588                         M_LLD(argintregs[1], REG_PV, a);
2589
2590                         /* a2 = pointer to dimensions = stack pointer */
2591
2592                         M_INTMOVE(REG_SP, argintregs[2]);
2593
2594                         a = dseg_addaddress((void*) (builtin_nmultianewarray));
2595                         M_LLD(REG_PV, REG_PV, a);
2596                         M_JSR(REG_RA, REG_PV);
2597                         s1 = (int)((u1*) mcodeptr - mcodebase);
2598                         if (s1 <= 32768)
2599                                 M_LDA (REG_PV, REG_RA, -s1);
2600                         else {
2601                                 s4 ml = -s1, mh = 0;
2602                                 while (ml < -32768) {ml += 65536; mh--;}
2603                                 M_LDA(REG_PV, REG_RA, ml);
2604                                 M_LDAH(REG_PV, REG_PV, mh);
2605                                 }
2606                         s1 = reg_of_var(iptr->dst, REG_RESULT);
2607                         M_INTMOVE(REG_RESULT, s1);
2608                         store_reg_to_var_int(iptr->dst, s1);
2609                         break;
2610
2611
2612                 default: sprintf (logtext, "Unknown pseudo command: %d", iptr->opc);
2613                          error();
2614         } /* switch */
2615         } /* for instruction */
2616         src = bptr->outstack;
2617         len = bptr->outdepth;
2618         MCODECHECK(64+len);
2619         while (src) {
2620                 len--;
2621                 if ((src->varkind != STACKVAR)) {
2622                         s2 = src->type;
2623                         if (IS_FLT_DBL_TYPE(s2)) {
2624                                 var_to_reg_int(s1, src, REG_ITMP1);
2625                                 if (!(interfaces[len][s2].flags & INMEMORY)) {
2626                                         M_FLTMOVE(s1,interfaces[len][s2].regoff);
2627                                         }
2628                                 else {
2629                                         M_DST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
2630                                         }
2631                                 }
2632                         else {
2633                                 var_to_reg_flt(s1, src, REG_FTMP1);
2634                                 if (!(interfaces[len][s2].flags & INMEMORY)) {
2635                                         M_INTMOVE(s1,interfaces[len][s2].regoff);
2636                                         }
2637                                 else {
2638                                         M_LST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
2639                                         }
2640                                 }
2641                         }
2642                 src = src->prev;
2643                 }
2644         } /* for basic block */
2645
2646         bptr -> mpc = (int)((u1*) mcodeptr - mcodebase);
2647
2648         {
2649         s4 *xcodeptr = NULL;
2650         
2651         for (; xboundrefs != NULL; xboundrefs = xboundrefs->next) {
2652                 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
2653                         gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos, 
2654                                 xboundrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
2655                         continue;
2656                         }
2657
2658                 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos, 
2659                                   xboundrefs->branchpos, (u1*) mcodeptr - mcodebase);
2660
2661                 MCODECHECK(8);
2662
2663                 M_LDA(REG_ITMP2_XPC, REG_PV, xboundrefs->branchpos);
2664
2665                 if (xcodeptr != NULL) {
2666                         M_BR((xcodeptr-mcodeptr)-1);
2667                         }
2668                 else {
2669                         xcodeptr = mcodeptr;
2670
2671                         a = dseg_addaddress(proto_java_lang_ArrayIndexOutOfBoundsException);
2672                         M_LLD(REG_ITMP1_XPTR, REG_PV, a);
2673
2674                         a = dseg_addaddress(asm_handle_exception);
2675                         M_LLD(REG_ITMP3, REG_PV, a);
2676
2677                         M_JMP(REG_ZERO, REG_ITMP3);
2678                         }
2679                 }
2680
2681         xcodeptr = NULL;
2682         
2683         for (; xcheckarefs != NULL; xcheckarefs = xcheckarefs->next) {
2684                 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
2685                         gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos, 
2686                                 xcheckarefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
2687                         continue;
2688                         }
2689
2690                 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos, 
2691                                   xcheckarefs->branchpos, (u1*) mcodeptr - mcodebase);
2692
2693                 MCODECHECK(8);
2694
2695                 M_LDA(REG_ITMP2_XPC, REG_PV, xcheckarefs->branchpos);
2696
2697                 if (xcodeptr != NULL) {
2698                         M_BR((xcodeptr-mcodeptr)-1);
2699                         }
2700                 else {
2701                         xcodeptr = mcodeptr;
2702
2703                         a = dseg_addaddress(proto_java_lang_NegativeArraySizeException);
2704                         M_LLD(REG_ITMP1_XPTR, REG_PV, a);
2705
2706                         a = dseg_addaddress(asm_handle_exception);
2707                         M_LLD(REG_ITMP3, REG_PV, a);
2708
2709                         M_JMP(REG_ZERO, REG_ITMP3);
2710                         }
2711                 }
2712
2713
2714 #ifdef SOFTNULLPTRCHECK
2715
2716         xcodeptr = NULL;
2717
2718         for (; xnullrefs != NULL; xnullrefs = xnullrefs->next) {
2719                 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
2720                         gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos, 
2721                                 xnullrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
2722                         continue;
2723                         }
2724
2725                 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos, 
2726                                   xnullrefs->branchpos, (u1*) mcodeptr - mcodebase);
2727
2728                 MCODECHECK(8);
2729
2730                 M_LDA(REG_ITMP2_XPC, REG_PV, xnullrefs->branchpos - 4);
2731
2732                 if (xcodeptr != NULL) {
2733                         M_BR((xcodeptr-mcodeptr)-1);
2734                         }
2735                 else {
2736                         xcodeptr = mcodeptr;
2737
2738                         a = dseg_addaddress(proto_java_lang_NullPointerException);
2739                         M_LLD(REG_ITMP1_XPTR, REG_PV, a);
2740
2741                         a = dseg_addaddress(asm_handle_exception);
2742                         M_LLD(REG_ITMP3, REG_PV, a);
2743
2744                         M_JMP(REG_ZERO, REG_ITMP3);
2745                         }
2746                 }
2747
2748 #endif
2749         }
2750
2751         mcode_finish((int)((u1*) mcodeptr - mcodebase));
2752 }
2753
2754
2755 /******** redefinition of code generation macros (compiling into array) *******/
2756
2757 /* 
2758 These macros are newly defined to allow code generation into an array.
2759 This is necessary, because the original M_.. macros generate code by
2760 calling 'mcode_adds4' that uses an additional data structure to
2761 receive the code.
2762
2763 For a faster (but less flexible) version to generate code, these
2764 macros directly use the (s4* p) - pointer to put the code directly
2765 in a locally defined array.
2766 This makes sense only for the stub-generation-routines below.
2767 */
2768
2769 #undef M_OP3
2770 #define M_OP3(op,fu,a,b,c,const) \
2771         *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<(16-3*(const)))| \
2772         ((const)<<12)|((fu)<<5)|((c)) )
2773 #undef M_FOP3
2774 #define M_FOP3(op,fu,a,b,c) \
2775         *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<16)|((fu)<<5)|(c) )
2776 #undef M_BRA
2777 #define M_BRA(op,a,disp) \
2778         *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((disp)&0x1fffff) )
2779 #undef M_MEM
2780 #define M_MEM(op,a,b,disp) \
2781         *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<16)|((disp)&0xffff) )
2782
2783
2784 #if 0
2785
2786 /************************ function createcompilerstub **************************
2787
2788         creates a stub routine which calls the compiler
2789         
2790 *******************************************************************************/
2791
2792 #define COMPSTUBSIZE 3
2793
2794 u1 *createcompilerstub (methodinfo *m)
2795 {
2796         u8 *s = CNEW (u8, COMPSTUBSIZE);    /* memory to hold the stub            */
2797         s4 *p = (s4*) s;                    /* code generation pointer            */
2798         
2799                                             /* code for the stub                  */
2800         M_LLD (REG_PV, REG_PV, 16);         /* load pointer to the compiler       */
2801         M_JMP (0, REG_PV);                  /* jump to the compiler, return address
2802                                                in reg 0 is used as method pointer */
2803         s[1] = (u8) m;                      /* literals to be adressed            */  
2804         s[2] = (u8) asm_call_jit_compiler;  /* jump directly via PV from above    */
2805
2806 #ifdef STATISTICS
2807         count_cstub_len += COMPSTUBSIZE * 8;
2808 #endif
2809
2810         return (u1*) s;
2811 }
2812
2813
2814 /************************* function removecompilerstub *************************
2815
2816      deletes a compilerstub from memory  (simply by freeing it)
2817
2818 *******************************************************************************/
2819
2820 void removecompilerstub (u1 *stub) 
2821 {
2822         CFREE (stub, COMPSTUBSIZE * 8);
2823 }
2824
2825
2826 /************************ function: removenativestub ***************************
2827
2828     removes a previously created native-stub from memory
2829     
2830 *******************************************************************************/
2831
2832 void removenativestub (u1 *stub)
2833 {
2834         CFREE (stub, NATIVESTUBSIZE * 8);
2835 }
2836
2837 #endif /* 0 */
2838
2839
2840 /********************* Funktion: ncreatenativestub *****************************
2841
2842         creates a stub routine which calls a native method
2843         
2844 *******************************************************************************/
2845
2846 #define NATIVESTUBSIZE 11
2847
2848 u1 *ncreatenativestub (functionptr f, methodinfo *m)
2849 {
2850         u8 *s = CNEW (u8, NATIVESTUBSIZE);  /* memory to hold the stub            */
2851         s4 *p = (s4*) s;                    /* code generation pointer            */
2852
2853         M_LDA  (REG_SP, REG_SP, -8);        /* build up stackframe                */
2854         M_LST  (REG_RA, REG_SP, 0);         /* store return address               */
2855
2856         M_LLD  (REG_PV, REG_PV, 8*8);       /* load adress of native method       */
2857         M_JSR  (REG_RA, REG_PV);            /* call native method                 */
2858
2859         M_LDA  (REG_PV, REG_RA, -4*4);      /* recompute pv from ra               */
2860         M_LLD  (REG_ITMP3, REG_PV, 9*8);    /* get address of exceptionptr        */
2861
2862         M_LLD  (REG_RA, REG_SP, 0);         /* load return address                */
2863         M_LLD  (REG_ITMP1, REG_ITMP3, 0);   /* load exception into reg. itmp1     */
2864
2865         M_LDA  (REG_SP, REG_SP, 8);         /* remove stackframe                  */
2866         M_BNEZ (REG_ITMP1, 1);              /* if no exception then return        */
2867
2868         M_RET  (REG_ZERO, REG_RA);          /* return to caller                   */
2869         
2870         M_LST  (REG_ZERO, REG_ITMP3, 0);    /* store NULL into exceptionptr       */
2871         M_LDA  (REG_ITMP2, REG_RA, -4);     /* move fault address into reg. itmp2 */
2872
2873         M_LLD  (REG_ITMP3, REG_PV,10*8);    /* load asm exception handler address */
2874         M_JMP  (REG_ZERO, REG_ITMP3);       /* jump to asm exception handler      */
2875
2876
2877         s[8] = (u8) f;                      /* address of native method           */
2878         s[9] = (u8) (&exceptionptr);        /* address of exceptionptr            */
2879         s[10]= (u8) (asm_handle_nat_exception); /* addr of asm exception handler  */
2880
2881 #ifdef STATISTICS
2882         count_nstub_len += NATIVESTUBSIZE * 8;
2883 #endif
2884
2885         return (u1*) s;
2886 }
2887