0bba6098e1ccae68ea5a1cefe19cb8f3233485aa
[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_IADD(d, REG_ITMP1, d, 0);
1044                         M_BGEZ(s1, 10);
1045                         M_ISUB(REG_ZERO, s1, REG_ITMP1, 0);
1046             M_ZAPNOT(REG_ITMP1, 0x03, REG_ITMP2, 1);
1047                         M_SRA(REG_ITMP1, 16, d, 1);
1048                         M_CMPLT(REG_ITMP2, d, REG_ITMP1, 0);
1049                         M_ISUB(REG_ITMP2, d, d, 0);
1050                         M_IADD(d, REG_ITMP1, d, 0);
1051                         M_ISUB(REG_ZERO, d, d, 0);
1052                         M_SLL(s1, 33, REG_ITMP2, 1);
1053                         M_CMPEQ(REG_ITMP2, REG_ZERO, REG_ITMP2, 0);
1054                         M_ISUB(d, REG_ITMP2, d, 0);
1055                         store_reg_to_var_int(iptr->dst, d);
1056                         break;
1057                 case ICMD_LANDCONST:
1058                         var_to_reg_int(s1, src, REG_ITMP1);
1059                         d = reg_of_var(iptr->dst, REG_ITMP3);
1060                         if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1061                                 M_AND(s1, iptr->val.l, d, 1);
1062                                 }
1063                         else if (iptr->val.l == 0xffffL) {
1064                                 M_ZAPNOT(s1, 0x03, d, 1);
1065                                 }
1066                         else if (iptr->val.l == 0xffffffL) {
1067                                 M_ZAPNOT(s1, 0x07, d, 1);
1068                                 }
1069                         else if (iptr->val.l == 0xffffffffL) {
1070                                 M_ZAPNOT(s1, 0x0f, d, 1);
1071                                 }
1072                         else if (iptr->val.l == 0xffffffffffL) {
1073                                 M_ZAPNOT(s1, 0x1f, d, 1);
1074                                 }
1075                         else if (iptr->val.l == 0xffffffffffffL) {
1076                                 M_ZAPNOT(s1, 0x3f, d, 1);
1077                                 }
1078                         else if (iptr->val.l == 0xffffffffffffffL) {
1079                                 M_ZAPNOT(s1, 0x7f, d, 1);
1080                                 }
1081                         else {
1082                                 LCONST(REG_ITMP2, iptr->val.l);
1083                                 M_AND(s1, REG_ITMP2, d, 0);
1084                                 }
1085                         store_reg_to_var_int(iptr->dst, d);
1086                         break;
1087                 case ICMD_LREMPOW2:
1088                         var_to_reg_int(s1, src, REG_ITMP1);
1089                         d = reg_of_var(iptr->dst, REG_ITMP3);
1090                         if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1091                                 M_AND(s1, iptr->val.l, d, 1);
1092                                 M_BGEZ(s1, 3);
1093                                 M_LSUB(REG_ZERO, s1, d, 0);
1094                                 M_AND(d, iptr->val.l, d, 1);
1095                                 }
1096                         else if (iptr->val.l == 0xffffL) {
1097                                 M_ZAPNOT(s1, 0x03, d, 1);
1098                                 M_BGEZ(s1, 3);
1099                                 M_LSUB(REG_ZERO, s1, d, 0);
1100                                 M_ZAPNOT(d, 0x03, d, 1);
1101                                 }
1102                         else if (iptr->val.l == 0xffffffL) {
1103                                 M_ZAPNOT(s1, 0x07, d, 1);
1104                                 M_BGEZ(s1, 3);
1105                                 M_LSUB(REG_ZERO, s1, d, 0);
1106                                 M_ZAPNOT(d, 0x07, d, 1);
1107                                 }
1108                         else if (iptr->val.l == 0xffffffffL) {
1109                                 M_ZAPNOT(s1, 0x0f, d, 1);
1110                                 M_BGEZ(s1, 3);
1111                                 M_LSUB(REG_ZERO, s1, d, 0);
1112                                 M_ZAPNOT(d, 0x0f, d, 1);
1113                                 }
1114                         else if (iptr->val.l == 0xffffffffffL) {
1115                                 M_ZAPNOT(s1, 0x1f, d, 1);
1116                                 M_BGEZ(s1, 3);
1117                                 M_LSUB(REG_ZERO, s1, d, 0);
1118                                 M_ZAPNOT(d, 0x1f, d, 1);
1119                                 }
1120                         else if (iptr->val.l == 0xffffffffffffL) {
1121                                 M_ZAPNOT(s1, 0x3f, d, 1);
1122                                 M_BGEZ(s1, 3);
1123                                 M_LSUB(REG_ZERO, s1, d, 0);
1124                                 M_ZAPNOT(d, 0x3f, d, 1);
1125                                 }
1126                         else if (iptr->val.l == 0xffffffffffffffL) {
1127                                 M_ZAPNOT(s1, 0x7f, d, 1);
1128                                 M_BGEZ(s1, 3);
1129                                 M_LSUB(REG_ZERO, s1, d, 0);
1130                                 M_ZAPNOT(d, 0x7f, d, 1);
1131                                 }
1132                         else {
1133                                 LCONST(REG_ITMP2, iptr->val.l);
1134                                 M_AND(s1, REG_ITMP2, d, 0);
1135                                 M_BGEZ(s1, 3);
1136                                 M_LSUB(REG_ZERO, s1, d, 0);
1137                                 M_AND(d, REG_ITMP2, d, 0);
1138                                 }
1139                         M_LSUB(REG_ZERO, d, d, 0);
1140                         store_reg_to_var_int(iptr->dst, d);
1141                         break;
1142                 case ICMD_LREM0X10001:
1143                         var_to_reg_int(s1, src, REG_ITMP1);
1144                         d = reg_of_var(iptr->dst, REG_ITMP3);
1145                         M_ZAPNOT(s1, 0x03, REG_ITMP2, 1);
1146                         M_SRA(s1, 16, d, 1);
1147                         M_CMPLT(REG_ITMP2, d, REG_ITMP1, 0);
1148                         M_LSUB(REG_ITMP2, d, d, 0);
1149                         M_LADD(d, REG_ITMP1, d, 0);
1150                         M_LDA(REG_ITMP2, REG_ZERO, -1);
1151                         M_SRL(REG_ITMP2, 33, REG_ITMP2, 1);
1152                         M_CMPULT(s1, REG_ITMP2, REG_ITMP2, 0);
1153                         M_BNEZ(REG_ITMP2, 11);
1154                         M_LDA(d, REG_ZERO, -257);
1155                         M_ZAPNOT(d, 0xcd, d, 1);
1156                         M_LSUB(REG_ZERO, s1, REG_ITMP2, 0);
1157                         M_CMOVGE(s1, s1, REG_ITMP2, 0);
1158                         M_UMULH(REG_ITMP2, d, REG_ITMP2, 0);
1159                         M_SRL(REG_ITMP2, 16, REG_ITMP2, 1);
1160                         M_LSUB(REG_ZERO, REG_ITMP2, d, 0);
1161                         M_CMOVGE(s1, REG_ITMP2, d, 0);
1162                         M_SLL(d, 16, REG_ITMP2, 1);
1163                         M_LADD(d, REG_ITMP2, d, 0);
1164                         M_LSUB(s1, d, d, 0);
1165                         store_reg_to_var_int(iptr->dst, d);
1166                         break;
1167
1168                 case ICMD_IOR:
1169                 case ICMD_LOR:
1170                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1171                         var_to_reg_int(s2, src, REG_ITMP2);
1172                         d = reg_of_var(iptr->dst, REG_ITMP3);
1173                         M_OR( s1,s2, d, 0);
1174                         store_reg_to_var_int(iptr->dst, d);
1175                         break;
1176                 case ICMD_IORCONST:
1177                         var_to_reg_int(s1, src, REG_ITMP1);
1178                         d = reg_of_var(iptr->dst, REG_ITMP3);
1179                         if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1180                                 M_OR(s1, iptr->val.i, d, 1);
1181                                 }
1182                         else {
1183                                 ICONST(REG_ITMP2, iptr->val.i);
1184                                 M_OR(s1, REG_ITMP2, d, 0);
1185                                 }
1186                         store_reg_to_var_int(iptr->dst, d);
1187                         break;
1188                 case ICMD_LORCONST:
1189                         var_to_reg_int(s1, src, REG_ITMP1);
1190                         d = reg_of_var(iptr->dst, REG_ITMP3);
1191                         if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1192                                 M_OR(s1, iptr->val.l, d, 1);
1193                                 }
1194                         else {
1195                                 LCONST(REG_ITMP2, iptr->val.l);
1196                                 M_OR(s1, REG_ITMP2, d, 0);
1197                                 }
1198                         store_reg_to_var_int(iptr->dst, d);
1199                         break;
1200
1201                 case ICMD_IXOR:
1202                 case ICMD_LXOR:
1203                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1204                         var_to_reg_int(s2, src, REG_ITMP2);
1205                         d = reg_of_var(iptr->dst, REG_ITMP3);
1206                         M_XOR(s1, s2, d, 0);
1207                         store_reg_to_var_int(iptr->dst, d);
1208                         break;
1209                 case ICMD_IXORCONST:
1210                         var_to_reg_int(s1, src, REG_ITMP1);
1211                         d = reg_of_var(iptr->dst, REG_ITMP3);
1212                         if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1213                                 M_XOR(s1, iptr->val.i, d, 1);
1214                                 }
1215                         else {
1216                                 ICONST(REG_ITMP2, iptr->val.i);
1217                                 M_XOR(s1, REG_ITMP2, d, 0);
1218                                 }
1219                         store_reg_to_var_int(iptr->dst, d);
1220                         break;
1221                 case ICMD_LXORCONST:
1222                         var_to_reg_int(s1, src, REG_ITMP1);
1223                         d = reg_of_var(iptr->dst, REG_ITMP3);
1224                         if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1225                                 M_XOR(s1, iptr->val.l, d, 1);
1226                                 }
1227                         else {
1228                                 LCONST(REG_ITMP2, iptr->val.l);
1229                                 M_XOR(s1, REG_ITMP2, d, 0);
1230                                 }
1231                         store_reg_to_var_int(iptr->dst, d);
1232                         break;
1233
1234
1235                 case ICMD_LCMP:
1236                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1237                         var_to_reg_int(s2, src, REG_ITMP2);
1238                         d = reg_of_var(iptr->dst, REG_ITMP3);
1239                         M_CMPLT(s1, s2, REG_ITMP3, 0);
1240                         M_CMPLT(s2, s1, REG_ITMP1, 0);
1241                         M_LSUB (REG_ITMP1, REG_ITMP3, d, 0);
1242                         store_reg_to_var_int(iptr->dst, d);
1243                         break;
1244
1245
1246                 case ICMD_IINC:
1247                         var = &(locals[iptr->op1][TYPE_INT]);
1248                         if (var->flags & INMEMORY) {
1249                                 s1 = REG_ITMP1;
1250                                 M_LLD(s1, REG_SP, 8 * var->regoff);
1251                                 }
1252                         else
1253                                 s1 = var->regoff;
1254                         if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1255                                 M_IADD(s1, iptr->val.i, s1, 1);
1256                                 }
1257                         else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1258                                 M_ISUB(s1, (-iptr->val.i), s1, 1);
1259                                 }
1260                         else {
1261                                 M_LDA (s1, s1, iptr->val.i);
1262                                 M_IADD(s1, REG_ZERO, s1, 0);
1263                                 }
1264                         if (var->flags & INMEMORY)
1265                                 M_LST(s1, REG_SP, 8 * var->regoff);
1266                         break;
1267
1268
1269                 /*********************** floating operations **************************/
1270
1271                 case ICMD_FNEG:
1272                         var_to_reg_flt(s1, src, REG_FTMP1);
1273                         d = reg_of_var(iptr->dst, REG_FTMP3);
1274                         M_FMOVN(s1, d);
1275                         store_reg_to_var_flt(iptr->dst, d);
1276                         break;
1277                 case ICMD_DNEG:
1278                         var_to_reg_flt(s1, src, REG_FTMP1);
1279                         d = reg_of_var(iptr->dst, REG_FTMP3);
1280                         M_FMOVN(s1, d);
1281                         store_reg_to_var_flt(iptr->dst, d);
1282                         break;
1283
1284                 case ICMD_FADD:
1285                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1286                         var_to_reg_flt(s2, src, REG_FTMP2);
1287                         d = reg_of_var(iptr->dst, REG_FTMP3);
1288                         if (checkfloats) {
1289                                 M_FADDS(s1, s2, d);
1290                                 M_TRAPB;
1291                                 }
1292                         else {
1293                                 M_FADD(s1, s2, d);
1294                                 }
1295                         store_reg_to_var_flt(iptr->dst, d);
1296                         break;
1297                 case ICMD_DADD:
1298                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1299                         var_to_reg_flt(s2, src, REG_FTMP2);
1300                         d = reg_of_var(iptr->dst, REG_FTMP3);
1301                         if (checkfloats) {
1302                                 M_DADDS(s1, s2, d);
1303                                 M_TRAPB;
1304                                 }
1305                         else {
1306                                 M_DADD(s1, s2, d);
1307                                 }
1308                         store_reg_to_var_flt(iptr->dst, d);
1309                         break;
1310
1311                 case ICMD_FSUB:
1312                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1313                         var_to_reg_flt(s2, src, REG_FTMP2);
1314                         d = reg_of_var(iptr->dst, REG_FTMP3);
1315                         if (checkfloats) {
1316                                 M_FSUBS(s1, s2, d);
1317                                 M_TRAPB;
1318                                 }
1319                         else {
1320                                 M_FSUB(s1, s2, d);
1321                                 }
1322                         store_reg_to_var_flt(iptr->dst, d);
1323                         break;
1324                 case ICMD_DSUB:
1325                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1326                         var_to_reg_flt(s2, src, REG_FTMP2);
1327                         d = reg_of_var(iptr->dst, REG_FTMP3);
1328                         if (checkfloats) {
1329                                 M_DSUBS(s1, s2, d);
1330                                 M_TRAPB;
1331                                 }
1332                         else {
1333                                 M_DSUB(s1, s2, d);
1334                                 }
1335                         store_reg_to_var_flt(iptr->dst, d);
1336                         break;
1337
1338                 case ICMD_FMUL:
1339                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1340                         var_to_reg_flt(s2, src, REG_FTMP2);
1341                         d = reg_of_var(iptr->dst, REG_FTMP3);
1342                         if (checkfloats) {
1343                                 M_FMULS(s1, s2, d);
1344                                 M_TRAPB;
1345                                 }
1346                         else {
1347                                 M_FMUL(s1, s2, d);
1348                                 }
1349                         store_reg_to_var_flt(iptr->dst, d);
1350                         break;
1351                 case ICMD_DMUL:
1352                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1353                         var_to_reg_flt(s2, src, REG_FTMP2);
1354                         d = reg_of_var(iptr->dst, REG_FTMP3);
1355                         if (checkfloats) {
1356                                 M_DMULS(s1, s2, d);
1357                                 M_TRAPB;
1358                                 }
1359                         else {
1360                                 M_DMUL(s1, s2, d);
1361                                 }
1362                         store_reg_to_var_flt(iptr->dst, d);
1363                         break;
1364
1365                 case ICMD_FDIV:
1366                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1367                         var_to_reg_flt(s2, src, REG_FTMP2);
1368                         d = reg_of_var(iptr->dst, REG_FTMP3);
1369                         if (checkfloats) {
1370                                 M_FDIVS(s1, s2, d);
1371                                 M_TRAPB;
1372                                 }
1373                         else {
1374                                 M_FDIV(s1, s2, d);
1375                                 }
1376                         store_reg_to_var_flt(iptr->dst, d);
1377                         break;
1378                 case ICMD_DDIV:
1379                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1380                         var_to_reg_flt(s2, src, REG_FTMP2);
1381                         d = reg_of_var(iptr->dst, REG_FTMP3);
1382                         if (checkfloats) {
1383                                 M_DDIVS(s1, s2, d);
1384                                 M_TRAPB;
1385                                 }
1386                         else {
1387                                 M_DDIV(s1, s2, d);
1388                                 }
1389                         store_reg_to_var_flt(iptr->dst, d);
1390                         break;
1391                 
1392                 case ICMD_FREM:
1393                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1394                         var_to_reg_flt(s2, src, REG_FTMP2);
1395                         d = reg_of_var(iptr->dst, REG_FTMP3);
1396                         if (checkfloats) {
1397                                 M_FDIVS(s1,s2, REG_FTMP3);
1398                                 M_TRAPB;
1399                                 M_CVTDL_CS(REG_ZERO, REG_FTMP3, REG_FTMP3); /* round to integer */
1400                                 M_TRAPB;
1401                                 M_CVTLF(REG_ZERO, REG_FTMP3, REG_FTMP3);
1402                                 M_FMULS(REG_FTMP3, s2, REG_FTMP3);
1403                                 M_TRAPB;
1404                                 M_FSUBS(s1, REG_FTMP3, d);
1405                                 M_TRAPB;
1406                                 }
1407                         else {
1408                                 M_FDIV(s1,s2, REG_FTMP3);
1409                                 M_CVTDL_C(REG_ZERO, REG_FTMP3, REG_FTMP3); /* round to integer */
1410                                 M_CVTLF(REG_ZERO, REG_FTMP3, REG_FTMP3);
1411                                 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1412                                 M_FSUB(s1, REG_FTMP3, d);
1413                                 }
1414                         store_reg_to_var_flt(iptr->dst, d);
1415                     break;
1416                 case ICMD_DREM:
1417                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1418                         var_to_reg_flt(s2, src, REG_FTMP2);
1419                         d = reg_of_var(iptr->dst, REG_FTMP3);
1420                         if (checkfloats) {
1421                                 M_DDIVS(s1,s2, REG_FTMP3);
1422                                 M_TRAPB;
1423                                 M_CVTDL_CS(REG_ZERO, REG_FTMP3, REG_FTMP3); /* round to integer */
1424                                 M_TRAPB;
1425                                 M_CVTLD(REG_ZERO, REG_FTMP3, REG_FTMP3);
1426                                 M_DMULS(REG_FTMP3, s2, REG_FTMP3);
1427                                 M_TRAPB;
1428                                 M_DSUBS(s1, REG_FTMP3, d);
1429                                 M_TRAPB;
1430                                 }
1431                         else {
1432                                 M_DDIV(s1,s2, REG_FTMP3);
1433                                 M_CVTDL_C(REG_ZERO, REG_FTMP3, REG_FTMP3); /* round to integer */
1434                                 M_CVTLD(REG_ZERO, REG_FTMP3, REG_FTMP3);
1435                                 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1436                                 M_DSUB(s1, REG_FTMP3, d);
1437                                 }
1438                         store_reg_to_var_flt(iptr->dst, d);
1439                     break;
1440
1441                 case ICMD_I2F:
1442                 case ICMD_L2F:
1443                         var_to_reg_int(s1, src, REG_ITMP1);
1444                         d = reg_of_var(iptr->dst, REG_FTMP3);
1445                         a = dseg_adddouble(0.0);
1446                         M_LST (s1, REG_PV, a);
1447                         M_DLD (d, REG_PV, a);
1448                         M_CVTLF(REG_ZERO, d, d);
1449                         store_reg_to_var_flt(iptr->dst, d);
1450                         break;
1451
1452                 case ICMD_I2D:
1453                 case ICMD_L2D:
1454                         var_to_reg_int(s1, src, REG_ITMP1);
1455                         d = reg_of_var(iptr->dst, REG_FTMP3);
1456                         a = dseg_adddouble(0.0);
1457                         M_LST (s1, REG_PV, a);
1458                         M_DLD (d, REG_PV, a);
1459                         M_CVTLD(REG_ZERO, d, d);
1460                         store_reg_to_var_flt(iptr->dst, d);
1461                         break;
1462                         
1463                 case ICMD_F2I:
1464                 case ICMD_D2I:
1465                         var_to_reg_flt(s1, src, REG_FTMP1);
1466                         d = reg_of_var(iptr->dst, REG_ITMP3);
1467                         a = dseg_adddouble(0.0);
1468                         if (checkfloats) {
1469                                 M_CVTDL_CS(REG_ZERO, s1, REG_FTMP1);
1470                                 M_TRAPB;
1471                                 M_CVTLIS(REG_FTMP1, REG_FTMP2);
1472                                 M_TRAPB;
1473                                 }
1474                         else {
1475                                 M_CVTDL_C(REG_ZERO, s1, REG_FTMP1);
1476                                 M_CVTLI(REG_FTMP1, REG_FTMP2);
1477                                 }
1478                         M_DST (REG_FTMP1, REG_PV, a);
1479                         M_ILD (d, REG_PV, a);
1480                         store_reg_to_var_int(iptr->dst, d);
1481                         break;
1482                 
1483                 case ICMD_F2L:
1484                 case ICMD_D2L:
1485                         var_to_reg_flt(s1, src, REG_FTMP1);
1486                         d = reg_of_var(iptr->dst, REG_ITMP3);
1487                         a = dseg_adddouble(0.0);
1488                         if (checkfloats) {
1489                                 M_CVTDL_CS(REG_ZERO, s1, REG_FTMP1);
1490                                 M_TRAPB;
1491                                 }
1492                         else {
1493                                 M_CVTDL_C(REG_ZERO, s1, REG_FTMP1);
1494                                 }
1495                         M_DST (REG_FTMP1, REG_PV, a);
1496                         M_LLD (d, REG_PV, a);
1497                         store_reg_to_var_int(iptr->dst, d);
1498                         break;
1499
1500                 case ICMD_F2D:
1501                         var_to_reg_flt(s1, src, REG_FTMP1);
1502                         d = reg_of_var(iptr->dst, REG_FTMP3);
1503                         M_FLTMOVE(s1, d);
1504                         store_reg_to_var_flt(iptr->dst, d);
1505                         break;
1506                                         
1507                 case ICMD_D2F:
1508                         var_to_reg_flt(s1, src, REG_FTMP1);
1509                         d = reg_of_var(iptr->dst, REG_FTMP3);
1510                         if (checkfloats) {
1511                                 M_CVTDFS(REG_ZERO, s1, d);
1512                                 M_TRAPB;
1513                                 }
1514                         else {
1515                                 M_CVTDF(REG_ZERO, s1, d);
1516                                 }
1517                         store_reg_to_var_flt(iptr->dst, d);
1518                         break;
1519                 
1520                 case ICMD_FCMPL:
1521                 case ICMD_DCMPL:
1522                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1523                         var_to_reg_flt(s2, src, REG_FTMP2);
1524                         d = reg_of_var(iptr->dst, REG_ITMP3);
1525                         if (checkfloats) {
1526                                 M_LSUB  (REG_ZERO, 1, d, 1);
1527                                 M_FCMPEQS(s1, s2, REG_FTMP3);
1528                                 M_TRAPB;
1529                                 M_FBEQZ (REG_FTMP3, 1);    /* jump over next instructions         */
1530                                 M_OR    (REG_ZERO, REG_ZERO, d, 0);
1531                                 M_FCMPLTS(s2, s1, REG_FTMP3);
1532                                 M_TRAPB;
1533                                 M_FBEQZ (REG_FTMP3, 1);    /* jump over next instruction          */
1534                                 M_LADD  (REG_ZERO, 1, d, 1);
1535                                 }
1536                         else {
1537                                 M_LSUB  (REG_ZERO, 1, d, 1);
1538                                 M_FCMPEQ(s1, s2, REG_FTMP3);
1539                                 M_FBEQZ (REG_FTMP3, 1);    /* jump over next instructions         */
1540                                 M_OR    (REG_ZERO, REG_ZERO, d, 0);
1541                                 M_FCMPLT(s2, s1, REG_FTMP3);
1542                                 M_FBEQZ (REG_FTMP3, 1);    /* jump over next instruction          */
1543                                 M_LADD  (REG_ZERO, 1, d, 1);
1544                                 }
1545                         store_reg_to_var_int(iptr->dst, d);
1546                         break;
1547                         
1548                 case ICMD_FCMPG:
1549                 case ICMD_DCMPG:
1550                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1551                         var_to_reg_flt(s2, src, REG_FTMP2);
1552                         d = reg_of_var(iptr->dst, REG_ITMP3);
1553                         if (checkfloats) {
1554                                 M_LADD  (REG_ZERO, 1, d, 1);
1555                                 M_FCMPEQS(s1, s2, REG_FTMP3);
1556                                 M_TRAPB;
1557                                 M_FBEQZ (REG_FTMP3, 1);    /* jump over next instruction          */
1558                                 M_OR    (REG_ZERO, REG_ZERO, d, 0);
1559                                 M_FCMPLTS(s1, s2, REG_FTMP3);
1560                                 M_TRAPB;
1561                                 M_FBEQZ (REG_FTMP3, 1);    /* jump over next instruction          */
1562                                 M_LSUB  (REG_ZERO, 1, d, 1);
1563                                 }
1564                         else {
1565                                 M_LADD  (REG_ZERO, 1, d, 1);
1566                                 M_FCMPEQ(s1, s2, REG_FTMP3);
1567                                 M_FBEQZ (REG_FTMP3, 1);    /* jump over next instruction          */
1568                                 M_OR    (REG_ZERO, REG_ZERO, d, 0);
1569                                 M_FCMPLT(s1, s2, REG_FTMP3);
1570                                 M_FBEQZ (REG_FTMP3, 1);    /* jump over next instruction          */
1571                                 M_LSUB  (REG_ZERO, 1, d, 1);
1572                                 }
1573                         store_reg_to_var_int(iptr->dst, d);
1574                         break;
1575
1576
1577                 /********************** memory operations *****************************/
1578
1579 #define gen_bound_check \
1580                         if (checkbounds) {\
1581                         M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\
1582                         M_CMPULT(s2, REG_ITMP3, REG_ITMP3, 0);\
1583                         M_BEQZ(REG_ITMP3, 0);\
1584                         mcode_addxboundrefs(mcodeptr);\
1585                         }
1586
1587                 case ICMD_ARRAYLENGTH:
1588                         var_to_reg_int(s1, src, REG_ITMP1);
1589                         d = reg_of_var(iptr->dst, REG_ITMP3);
1590                         gen_nullptr_check(s1);
1591                         M_ILD(d, s1, OFFSET(java_arrayheader, size));
1592                         store_reg_to_var_int(iptr->dst, d);
1593                         break;
1594
1595                 case ICMD_AALOAD:
1596                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1597                         var_to_reg_int(s2, src, REG_ITMP2);
1598                         d = reg_of_var(iptr->dst, REG_ITMP3);
1599                         gen_nullptr_check(s1);
1600                         gen_bound_check;
1601                         M_S8ADDQ(s2, s1, REG_ITMP1, 0);
1602                         M_LLD( d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1603                         store_reg_to_var_int(iptr->dst, d);
1604                         break;
1605                 case ICMD_LALOAD:
1606                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1607                         var_to_reg_int(s2, src, REG_ITMP2);
1608                         d = reg_of_var(iptr->dst, REG_ITMP3);
1609                         gen_nullptr_check(s1);
1610                         gen_bound_check;
1611                         M_S8ADDQ(s2, s1, REG_ITMP1, 0);
1612                         M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1613                         store_reg_to_var_int(iptr->dst, d);
1614                         break;
1615                 case ICMD_IALOAD:
1616                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1617                         var_to_reg_int(s2, src, REG_ITMP2);
1618                         d = reg_of_var(iptr->dst, REG_ITMP3);
1619                         gen_nullptr_check(s1);
1620                         gen_bound_check;
1621                         M_S4ADDQ(s2, s1, REG_ITMP1, 0);
1622                         M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1623                         store_reg_to_var_int(iptr->dst, d);
1624                         break;
1625                 case ICMD_FALOAD:
1626                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1627                         var_to_reg_int(s2, src, REG_ITMP2);
1628                         d = reg_of_var(iptr->dst, REG_FTMP3);
1629                         gen_nullptr_check(s1);
1630                         gen_bound_check;
1631                         M_S4ADDQ(s2, s1, REG_ITMP1, 0);
1632                         M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1633                         store_reg_to_var_flt(iptr->dst, d);
1634                         break;
1635                 case ICMD_DALOAD:
1636                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1637                         var_to_reg_int(s2, src, REG_ITMP2);
1638                         d = reg_of_var(iptr->dst, REG_FTMP3);
1639                         gen_nullptr_check(s1);
1640                         gen_bound_check;
1641                         M_S8ADDQ(s2, s1, REG_ITMP1, 0);
1642                         M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1643                         store_reg_to_var_flt(iptr->dst, d);
1644                         break;
1645                 case ICMD_CALOAD:
1646                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1647                         var_to_reg_int(s2, src, REG_ITMP2);
1648                         d = reg_of_var(iptr->dst, REG_ITMP3);
1649                         gen_nullptr_check(s1);
1650                         gen_bound_check;
1651                         if (has_ext_instr_set) {
1652                                 M_LADD(s2, s1, REG_ITMP1, 0);
1653                                 M_LADD(s2, REG_ITMP1, REG_ITMP1, 0);
1654                                 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1655                                 }
1656                         else {
1657                                 M_LADD (s2, s1, REG_ITMP1,  0);
1658                                 M_LADD (s2, REG_ITMP1, REG_ITMP1, 0);
1659                                 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1660                                 M_LDA  (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1661                                 M_EXTWL(REG_ITMP2, REG_ITMP1, d, 0);
1662                                 }
1663                         store_reg_to_var_int(iptr->dst, d);
1664                         break;                  
1665                 case ICMD_SALOAD:
1666                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1667                         var_to_reg_int(s2, src, REG_ITMP2);
1668                         d = reg_of_var(iptr->dst, REG_ITMP3);
1669                         gen_nullptr_check(s1);
1670                         gen_bound_check;
1671                         if (has_ext_instr_set) {
1672                                 M_LADD(s2, s1, REG_ITMP1, 0);
1673                                 M_LADD(s2, REG_ITMP1, REG_ITMP1, 0);
1674                                 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1675                                 M_SSEXT(d, d);
1676                                 }
1677                         else {
1678                                 M_LADD(s2, s1, REG_ITMP1,  0);
1679                                 M_LADD(s2, REG_ITMP1, REG_ITMP1, 0);
1680                                 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1681                                 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1682                                 M_EXTQH(REG_ITMP2, REG_ITMP1, d, 0);
1683                                 M_SRA(d, 48, d, 1);
1684                                 }
1685                         store_reg_to_var_int(iptr->dst, d);
1686                         break;
1687                 case ICMD_BALOAD:
1688                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1689                         var_to_reg_int(s2, src, REG_ITMP2);
1690                         d = reg_of_var(iptr->dst, REG_ITMP3);
1691                         gen_nullptr_check(s1);
1692                         gen_bound_check;
1693                         if (has_ext_instr_set) {
1694                                 M_LADD   (s2, s1, REG_ITMP1, 0);
1695                                 M_BLDU   (d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1696                                 M_BSEXT  (d, d);
1697                                 }
1698                         else {
1699                                 M_LADD(s2, s1, REG_ITMP1, 0);
1700                                 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1701                                 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
1702                                 M_EXTQH(REG_ITMP2, REG_ITMP1, d, 0);
1703                                 M_SRA(d, 56, d, 1);
1704                                 }
1705                         store_reg_to_var_int(iptr->dst, d);
1706                         break;
1707
1708                 case ICMD_AASTORE:
1709                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1710                         var_to_reg_int(s2, src->prev, REG_ITMP2);
1711                         gen_nullptr_check(s1);
1712                         gen_bound_check;
1713                         var_to_reg_int(s3, src, REG_ITMP3);
1714                         M_S8ADDQ(s2, s1, REG_ITMP1, 0);
1715                         M_LST   (s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1716                         break;
1717                 case ICMD_LASTORE:
1718                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1719                         var_to_reg_int(s2, src->prev, REG_ITMP2);
1720                         gen_nullptr_check(s1);
1721                         gen_bound_check;
1722                         var_to_reg_int(s3, src, REG_ITMP3);
1723                         M_S8ADDQ(s2, s1, REG_ITMP1, 0);
1724                         M_LST   (s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1725                         break;
1726                 case ICMD_IASTORE:
1727                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1728                         var_to_reg_int(s2, src->prev, REG_ITMP2);
1729                         gen_nullptr_check(s1);
1730                         gen_bound_check;
1731                         var_to_reg_int(s3, src, REG_ITMP3);
1732                         M_S4ADDQ(s2, s1, REG_ITMP1, 0);
1733                         M_IST   (s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1734                         break;
1735                 case ICMD_FASTORE:
1736                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1737                         var_to_reg_int(s2, src->prev, REG_ITMP2);
1738                         gen_nullptr_check(s1);
1739                         gen_bound_check;
1740                         var_to_reg_flt(s3, src, REG_FTMP3);
1741                         M_S4ADDQ(s2, s1, REG_ITMP1, 0);
1742                         M_FST   (s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1743                         break;
1744                 case ICMD_DASTORE:
1745                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1746                         var_to_reg_int(s2, src->prev, REG_ITMP2);
1747                         gen_nullptr_check(s1);
1748                         gen_bound_check;
1749                         var_to_reg_flt(s3, src, REG_FTMP3);
1750                         M_S8ADDQ(s2, s1, REG_ITMP1, 0);
1751                         M_DST   (s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1752                         break;
1753                 case ICMD_CASTORE:
1754                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1755                         var_to_reg_int(s2, src->prev, REG_ITMP2);
1756                         gen_nullptr_check(s1);
1757                         gen_bound_check;
1758                         var_to_reg_int(s3, src, REG_ITMP3);
1759                         if (has_ext_instr_set) {
1760                                 M_LADD(s2, s1, REG_ITMP1, 0);
1761                                 M_LADD(s2, REG_ITMP1, REG_ITMP1, 0);
1762                                 M_SST (s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1763                                 }
1764                         else {
1765                                 M_LADD (s2, s1, REG_ITMP1, 0);
1766                                 M_LADD (s2, REG_ITMP1, REG_ITMP1, 0);
1767                                 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1768                                 M_LDA  (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1769                                 M_INSWL(s3, REG_ITMP1, REG_ITMP3, 0);
1770                                 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2, 0);
1771                                 M_OR   (REG_ITMP2, REG_ITMP3, REG_ITMP2, 0);
1772                                 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1773                                 }
1774                         break;
1775                 case ICMD_SASTORE:
1776                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1777                         var_to_reg_int(s2, src->prev, REG_ITMP2);
1778                         gen_nullptr_check(s1);
1779                         gen_bound_check;
1780                         var_to_reg_int(s3, src, REG_ITMP3);
1781                         if (has_ext_instr_set) {
1782                                 M_LADD(s2, s1, REG_ITMP1, 0);
1783                                 M_LADD(s2, REG_ITMP1, REG_ITMP1, 0);
1784                                 M_SST (s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1785                                 }
1786                         else {
1787                                 M_LADD (s2, s1, REG_ITMP1, 0);
1788                                 M_LADD (s2, REG_ITMP1, REG_ITMP1, 0);
1789                                 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1790                                 M_LDA  (REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1791                                 M_INSWL(s3, REG_ITMP1, REG_ITMP3, 0);
1792                                 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2, 0);
1793                                 M_OR   (REG_ITMP2, REG_ITMP3, REG_ITMP2, 0);
1794                                 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1795                                 }
1796                         break;
1797                 case ICMD_BASTORE:
1798                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1799                         var_to_reg_int(s2, src->prev, REG_ITMP2);
1800                         gen_nullptr_check(s1);
1801                         gen_bound_check;
1802                         var_to_reg_int(s3, src, REG_ITMP3);
1803                         if (has_ext_instr_set) {
1804                                 M_LADD(s2, s1, REG_ITMP1, 0);
1805                                 M_BST (s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1806                                 }
1807                         else {
1808                                 M_LADD (s2, s1, REG_ITMP1,  0);
1809                                 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1810                                 M_LDA  (REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1811                                 M_INSBL(s3, REG_ITMP1, REG_ITMP3, 0);
1812                                 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2, 0);
1813                                 M_OR   (REG_ITMP2, REG_ITMP3, REG_ITMP2, 0);
1814                                 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1815                                 }
1816                         break;
1817
1818
1819                 case ICMD_PUTSTATIC:
1820                         a = dseg_addaddress (iptr->val.a);
1821                         M_LLD(REG_ITMP1, REG_PV, a);
1822                         switch (iptr->op1) {
1823                                 case TYPE_INT:
1824                                         var_to_reg_int(s2, src, REG_ITMP2);
1825                                         M_IST(s2, REG_ITMP1, 0);
1826                                         break;
1827                                 case TYPE_LNG:
1828                                 case TYPE_ADR:
1829                                         var_to_reg_int(s2, src, REG_ITMP2);
1830                                         M_LST(s2, REG_ITMP1, 0);
1831                                         break;
1832                                 case TYPE_FLT:
1833                                         var_to_reg_flt(s2, src, REG_FTMP2);
1834                                         M_FST(s2, REG_ITMP1, 0);
1835                                         break;
1836                                 case TYPE_DBL:
1837                                         var_to_reg_flt(s2, src, REG_FTMP2);
1838                                         M_DST(s2, REG_ITMP1, 0);
1839                                         break;
1840                                 default: panic ("internal error");
1841                                 }
1842                         break;
1843
1844                 case ICMD_GETSTATIC:
1845                         a = dseg_addaddress (iptr->val.a);
1846                         M_LLD(REG_ITMP1, REG_PV, a);
1847                         switch (iptr->op1) {
1848                                 case TYPE_INT:
1849                                         d = reg_of_var(iptr->dst, REG_ITMP3);
1850                                         M_ILD(d, REG_ITMP1, 0);
1851                                         store_reg_to_var_int(iptr->dst, d);
1852                                         break;
1853                                 case TYPE_LNG:
1854                                 case TYPE_ADR:
1855                                         d = reg_of_var(iptr->dst, REG_ITMP3);
1856                                         M_LLD(d, REG_ITMP1, 0);
1857                                         store_reg_to_var_int(iptr->dst, d);
1858                                         break;
1859                                 case TYPE_FLT:
1860                                         d = reg_of_var(iptr->dst, REG_FTMP1);
1861                                         M_FLD(d, REG_ITMP1, 0);
1862                                         store_reg_to_var_flt(iptr->dst, d);
1863                                         break;
1864                                 case TYPE_DBL:                          
1865                                         d = reg_of_var(iptr->dst, REG_FTMP1);
1866                                         M_DLD(d, REG_ITMP1, 0);
1867                                         store_reg_to_var_flt(iptr->dst, d);
1868                                         break;
1869                                 default: panic ("internal error");
1870                                 }
1871                         break;
1872
1873
1874                 case ICMD_PUTFIELD:
1875                         switch (iptr->op1) {
1876                                 case TYPE_INT:
1877                                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1878                                         var_to_reg_int(s2, src, REG_ITMP2);
1879                                         gen_nullptr_check(s1);
1880                                         M_IST(s2, s1, iptr->val.i);
1881                                         break;
1882                                 case TYPE_LNG:
1883                                 case TYPE_ADR:
1884                                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1885                                         var_to_reg_int(s2, src, REG_ITMP2);
1886                                         gen_nullptr_check(s1);
1887                                         M_LST(s2, s1, iptr->val.i);
1888                                         break;
1889                                 case TYPE_FLT:
1890                                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1891                                         var_to_reg_flt(s2, src, REG_FTMP2);
1892                                         gen_nullptr_check(s1);
1893                                         M_FST(s2, s1, iptr->val.i);
1894                                         break;
1895                                 case TYPE_DBL:
1896                                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1897                                         var_to_reg_flt(s2, src, REG_FTMP2);
1898                                         gen_nullptr_check(s1);
1899                                         M_DST(s2, s1, iptr->val.i);
1900                                         break;
1901                                 default: panic ("internal error");
1902                                 }
1903                         break;
1904
1905                 case ICMD_GETFIELD:
1906                         switch (iptr->op1) {
1907                                 case TYPE_INT:
1908                                         var_to_reg_int(s1, src, REG_ITMP1);
1909                                         d = reg_of_var(iptr->dst, REG_ITMP3);
1910                                         gen_nullptr_check(s1);
1911                                         M_ILD(d, s1, iptr->val.i);
1912                                         store_reg_to_var_int(iptr->dst, d);
1913                                         break;
1914                                 case TYPE_LNG:
1915                                 case TYPE_ADR:
1916                                         var_to_reg_int(s1, src, REG_ITMP1);
1917                                         d = reg_of_var(iptr->dst, REG_ITMP3);
1918                                         gen_nullptr_check(s1);
1919                                         M_LLD(d, s1, iptr->val.i);
1920                                         store_reg_to_var_int(iptr->dst, d);
1921                                         break;
1922                                 case TYPE_FLT:
1923                                         var_to_reg_int(s1, src, REG_ITMP1);
1924                                         d = reg_of_var(iptr->dst, REG_FTMP1);
1925                                         gen_nullptr_check(s1);
1926                                         M_FLD(d, s1, iptr->val.i);
1927                                         store_reg_to_var_flt(iptr->dst, d);
1928                                         break;
1929                                 case TYPE_DBL:                          
1930                                         var_to_reg_int(s1, src, REG_ITMP1);
1931                                         d = reg_of_var(iptr->dst, REG_FTMP1);
1932                                         gen_nullptr_check(s1);
1933                                         M_DLD(d, s1, iptr->val.i);
1934                                         store_reg_to_var_flt(iptr->dst, d);
1935                                         break;
1936                                 default: panic ("internal error");
1937                                 }
1938                         break;
1939
1940
1941                 /********************** branch operations *****************************/
1942
1943 #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}}
1944
1945                 case ICMD_ATHROW:
1946                         var_to_reg_int(s1, src, REG_ITMP1);
1947                         M_INTMOVE(s1, REG_ITMP1_XPTR);
1948                         a = dseg_addaddress(asm_handle_exception);
1949                         M_LLD(REG_ITMP2, REG_PV, a);
1950                         M_JMP(REG_ITMP2_XPC, REG_ITMP2);
1951                         ALIGNCODENOP;
1952                         break;
1953
1954                 case ICMD_GOTO:
1955                         M_BR(0);
1956                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
1957                         ALIGNCODENOP;
1958                         break;
1959
1960                 case ICMD_JSR:
1961                         M_BSR(REG_ITMP1, 0);
1962                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
1963                         break;
1964                         
1965                 case ICMD_RET:
1966                         var = &(locals[iptr->op1][TYPE_ADR]);
1967                         if (var->flags & INMEMORY) {
1968                                 M_LLD(REG_ITMP1, REG_SP, 8 * var->regoff);
1969                                 M_RET(REG_ZERO, REG_ITMP1);
1970                                 }
1971                         else
1972                                 M_RET(REG_ZERO, var->regoff);
1973                         ALIGNCODENOP;
1974                         break;
1975
1976                 case ICMD_IFNULL:
1977                         var_to_reg_int(s1, src, REG_ITMP1);
1978                         M_BEQZ(s1, 0);
1979                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
1980                         break;
1981                 case ICMD_IFNONNULL:
1982                         var_to_reg_int(s1, src, REG_ITMP1);
1983                         M_BNEZ(s1, 0);
1984                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
1985                         break;
1986
1987                 case ICMD_IFEQ:
1988                         var_to_reg_int(s1, src, REG_ITMP1);
1989                         if (iptr->val.i == 0) {
1990                                 M_BEQZ(s1, 0);
1991                                 }
1992                         else {
1993                                 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
1994                                         M_CMPEQ(s1, iptr->val.i, REG_ITMP1, 1);
1995                                         }
1996                                 else {
1997                                         ICONST(REG_ITMP2, iptr->val.i);
1998                                         M_CMPEQ(s1, REG_ITMP2, REG_ITMP1, 0);
1999                                         }
2000                                 M_BNEZ(REG_ITMP1, 0);
2001                                 }
2002                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2003                         break;
2004                 case ICMD_IFLT:
2005                         var_to_reg_int(s1, src, REG_ITMP1);
2006                         if (iptr->val.i == 0) {
2007                                 M_BLTZ(s1, 0);
2008                                 }
2009                         else {
2010                                 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2011                                         M_CMPLT(s1, iptr->val.i, REG_ITMP1, 1);
2012                                         }
2013                                 else {
2014                                         ICONST(REG_ITMP2, iptr->val.i);
2015                                         M_CMPLT(s1, REG_ITMP2, REG_ITMP1, 0);
2016                                         }
2017                                 M_BNEZ(REG_ITMP1, 0);
2018                                 }
2019                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2020                         break;
2021                 case ICMD_IFLE:
2022                         var_to_reg_int(s1, src, REG_ITMP1);
2023                         if (iptr->val.i == 0) {
2024                                 M_BLEZ(s1, 0);
2025                                 }
2026                         else {
2027                                 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2028                                         M_CMPLE(s1, iptr->val.i, REG_ITMP1, 1);
2029                                         }
2030                                 else {
2031                                         ICONST(REG_ITMP2, iptr->val.i);
2032                                         M_CMPLE(s1, REG_ITMP2, REG_ITMP1, 0);
2033                                         }
2034                                 M_BNEZ(REG_ITMP1, 0);
2035                                 }
2036                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2037                         break;
2038                 case ICMD_IFNE:
2039                         var_to_reg_int(s1, src, REG_ITMP1);
2040                         if (iptr->val.i == 0) {
2041                                 M_BNEZ(s1, 0);
2042                                 }
2043                         else {
2044                                 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2045                                         M_CMPEQ(s1, iptr->val.i, REG_ITMP1, 1);
2046                                         }
2047                                 else {
2048                                         ICONST(REG_ITMP2, iptr->val.i);
2049                                         M_CMPEQ(s1, REG_ITMP2, REG_ITMP1, 0);
2050                                         }
2051                                 M_BEQZ(REG_ITMP1, 0);
2052                                 }
2053                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2054                         break;
2055                 case ICMD_IFGT:
2056                         var_to_reg_int(s1, src, REG_ITMP1);
2057                         if (iptr->val.i == 0) {
2058                                 M_BGTZ(s1, 0);
2059                                 }
2060                         else {
2061                                 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2062                                         M_CMPLE(s1, iptr->val.i, REG_ITMP1, 1);
2063                                         }
2064                                 else {
2065                                         ICONST(REG_ITMP2, iptr->val.i);
2066                                         M_CMPLE(s1, REG_ITMP2, REG_ITMP1, 0);
2067                                         }
2068                                 M_BEQZ(REG_ITMP1, 0);
2069                                 }
2070                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2071                         break;
2072                 case ICMD_IFGE:
2073                         var_to_reg_int(s1, src, REG_ITMP1);
2074                         if (iptr->val.i == 0) {
2075                                 M_BGEZ(s1, 0);
2076                                 }
2077                         else {
2078                                 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2079                                         M_CMPLT(s1, iptr->val.i, REG_ITMP1, 1);
2080                                         }
2081                                 else {
2082                                         ICONST(REG_ITMP2, iptr->val.i);
2083                                         M_CMPLT(s1, REG_ITMP2, REG_ITMP1, 0);
2084                                         }
2085                                 M_BEQZ(REG_ITMP1, 0);
2086                                 }
2087                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2088                         break;
2089
2090                 case ICMD_IF_LEQ:
2091                         var_to_reg_int(s1, src, REG_ITMP1);
2092                         if (iptr->val.l == 0) {
2093                                 M_BEQZ(s1, 0);
2094                                 }
2095                         else {
2096                                 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2097                                         M_CMPEQ(s1, iptr->val.l, REG_ITMP1, 1);
2098                                         }
2099                                 else {
2100                                         LCONST(REG_ITMP2, iptr->val.l);
2101                                         M_CMPEQ(s1, REG_ITMP2, REG_ITMP1, 0);
2102                                         }
2103                                 M_BNEZ(REG_ITMP1, 0);
2104                                 }
2105                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2106                         break;
2107                 case ICMD_IF_LLT:
2108                         var_to_reg_int(s1, src, REG_ITMP1);
2109                         if (iptr->val.l == 0) {
2110                                 M_BLTZ(s1, 0);
2111                                 }
2112                         else {
2113                                 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2114                                         M_CMPLT(s1, iptr->val.l, REG_ITMP1, 1);
2115                                         }
2116                                 else {
2117                                         LCONST(REG_ITMP2, iptr->val.l);
2118                                         M_CMPLT(s1, REG_ITMP2, REG_ITMP1, 0);
2119                                         }
2120                                 M_BNEZ(REG_ITMP1, 0);
2121                                 }
2122                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2123                         break;
2124                 case ICMD_IF_LLE:
2125                         var_to_reg_int(s1, src, REG_ITMP1);
2126                         if (iptr->val.l == 0) {
2127                                 M_BLEZ(s1, 0);
2128                                 }
2129                         else {
2130                                 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2131                                         M_CMPLE(s1, iptr->val.l, REG_ITMP1, 1);
2132                                         }
2133                                 else {
2134                                         LCONST(REG_ITMP2, iptr->val.l);
2135                                         M_CMPLE(s1, REG_ITMP2, REG_ITMP1, 0);
2136                                         }
2137                                 M_BNEZ(REG_ITMP1, 0);
2138                                 }
2139                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2140                         break;
2141                 case ICMD_IF_LNE:
2142                         var_to_reg_int(s1, src, REG_ITMP1);
2143                         if (iptr->val.l == 0) {
2144                                 M_BNEZ(s1, 0);
2145                                 }
2146                         else {
2147                                 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2148                                         M_CMPEQ(s1, iptr->val.l, REG_ITMP1, 1);
2149                                         }
2150                                 else {
2151                                         LCONST(REG_ITMP2, iptr->val.l);
2152                                         M_CMPEQ(s1, REG_ITMP2, REG_ITMP1, 0);
2153                                         }
2154                                 M_BEQZ(REG_ITMP1, 0);
2155                                 }
2156                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2157                         break;
2158                 case ICMD_IF_LGT:
2159                         var_to_reg_int(s1, src, REG_ITMP1);
2160                         if (iptr->val.l == 0) {
2161                                 M_BGTZ(s1, 0);
2162                                 }
2163                         else {
2164                                 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2165                                         M_CMPLE(s1, iptr->val.l, REG_ITMP1, 1);
2166                                         }
2167                                 else {
2168                                         LCONST(REG_ITMP2, iptr->val.l);
2169                                         M_CMPLE(s1, REG_ITMP2, REG_ITMP1, 0);
2170                                         }
2171                                 M_BEQZ(REG_ITMP1, 0);
2172                                 }
2173                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2174                         break;
2175                 case ICMD_IF_LGE:
2176                         var_to_reg_int(s1, src, REG_ITMP1);
2177                         if (iptr->val.l == 0) {
2178                                 M_BGEZ(s1, 0);
2179                                 }
2180                         else {
2181                                 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2182                                         M_CMPLT(s1, iptr->val.l, REG_ITMP1, 1);
2183                                         }
2184                                 else {
2185                                         LCONST(REG_ITMP2, iptr->val.l);
2186                                         M_CMPLT(s1, REG_ITMP2, REG_ITMP1, 0);
2187                                         }
2188                                 M_BEQZ(REG_ITMP1, 0);
2189                                 }
2190                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2191                         break;
2192
2193                 case ICMD_IF_ICMPEQ:
2194                 case ICMD_IF_LCMPEQ:
2195                 case ICMD_IF_ACMPEQ:
2196                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2197                         var_to_reg_int(s2, src, REG_ITMP2);
2198                         M_CMPEQ(s1, s2, REG_ITMP1, 0);
2199                         M_BNEZ(REG_ITMP1, 0);
2200                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2201                         break;
2202                 case ICMD_IF_ICMPNE:
2203                 case ICMD_IF_LCMPNE:
2204                 case ICMD_IF_ACMPNE:
2205                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2206                         var_to_reg_int(s2, src, REG_ITMP2);
2207                         M_CMPEQ(s1, s2, REG_ITMP1, 0);
2208                         M_BEQZ(REG_ITMP1, 0);
2209                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2210                         break;
2211                 case ICMD_IF_ICMPLT:
2212                 case ICMD_IF_LCMPLT:
2213                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2214                         var_to_reg_int(s2, src, REG_ITMP2);
2215                         M_CMPLT(s1, s2, REG_ITMP1, 0);
2216                         M_BNEZ(REG_ITMP1, 0);
2217                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2218                         break;
2219                 case ICMD_IF_ICMPGT:
2220                 case ICMD_IF_LCMPGT:
2221                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2222                         var_to_reg_int(s2, src, REG_ITMP2);
2223                         M_CMPLE(s1, s2, REG_ITMP1, 0);
2224                         M_BEQZ(REG_ITMP1, 0);
2225                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2226                         break;
2227                 case ICMD_IF_ICMPLE:
2228                 case ICMD_IF_LCMPLE:
2229                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2230                         var_to_reg_int(s2, src, REG_ITMP2);
2231                         M_CMPLE(s1, s2, REG_ITMP1, 0);
2232                         M_BNEZ(REG_ITMP1, 0);
2233                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2234                         break;
2235                 case ICMD_IF_ICMPGE:
2236                 case ICMD_IF_LCMPGE:
2237                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2238                         var_to_reg_int(s2, src, REG_ITMP2);
2239                         M_CMPLT(s1, s2, REG_ITMP1,  0);
2240                         M_BEQZ(REG_ITMP1, 0);
2241                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2242                         break;
2243
2244 /*   branch if the unsigned value of s1 is greater that s2 (note, that s2 has
2245          to be >= 0) */
2246
2247 /*              case ICMD_IF_UCMPGE: 
2248                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2249                         var_to_reg_int(s2, src, REG_ITMP2);
2250                         M_CMPULE(s2, s1, REG_ITMP1, 0);
2251                         M_BNEZ(REG_ITMP1, 0);
2252                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2253             break;
2254 */
2255
2256                 case ICMD_IRETURN:
2257                 case ICMD_LRETURN:
2258                 case ICMD_ARETURN:
2259
2260 #ifdef USE_THREADS
2261                         if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2262                                 a = dseg_addaddress ((void*) (builtin_monitorexit));
2263                                 M_LLD(REG_PV, REG_PV, a);
2264                                 M_LLD(argintregs[0], REG_SP, 8 * maxmemuse);
2265                                 M_JSR(REG_RA, REG_PV);
2266                                 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2267                                 }                       
2268 #endif
2269                         var_to_reg_int(s1, src, REG_RESULT);
2270                         M_INTMOVE(s1, REG_RESULT);
2271                         goto nowperformreturn;
2272
2273                 case ICMD_FRETURN:
2274                 case ICMD_DRETURN:
2275
2276 #ifdef USE_THREADS
2277                         if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2278                                 a = dseg_addaddress ((void*) (builtin_monitorexit));
2279                                 M_LLD(REG_PV, REG_PV, a);
2280                                 M_LLD(argintregs[0], REG_SP, 8 * maxmemuse);
2281                                 M_JSR(REG_RA, REG_PV);
2282                                 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2283                                 }                       
2284 #endif
2285                         var_to_reg_flt(s1, src, REG_FRESULT);
2286                         M_FLTMOVE(s1, REG_FRESULT);
2287                         goto nowperformreturn;
2288
2289                 case ICMD_RETURN:
2290
2291 #ifdef USE_THREADS
2292                         if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2293                                 a = dseg_addaddress ((void*) (builtin_monitorexit));
2294                                 M_LLD(REG_PV, REG_PV, a);
2295                                 M_LLD(argintregs[0], REG_SP, 8 * maxmemuse);
2296                                 M_JSR(REG_RA, REG_PV);
2297                                 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2298                                 }                       
2299 #endif
2300
2301 nowperformreturn:
2302                         {
2303                         int r, p;
2304                         
2305                         p = parentargs_base;
2306                         if (!isleafmethod)
2307                                 {p--;  M_LLD (REG_RA, REG_SP, 8 * p);}
2308                         for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
2309                                         {p--; M_LLD(savintregs[r], REG_SP, 8 * p);}
2310                         for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
2311                                         {p--; M_DLD(savfltregs[r], REG_SP, 8 * p);}
2312
2313                         if (parentargs_base)
2314                                 {M_LDA(REG_SP, REG_SP, parentargs_base*8);}
2315                         if (runverbose) {
2316                                 M_LDA (REG_SP, REG_SP, -24);
2317                                 M_LST(REG_RA, REG_SP, 0);
2318                                 M_LST(REG_RESULT, REG_SP, 8);
2319                                 M_DST(REG_FRESULT, REG_SP,16);
2320                                 a = dseg_addaddress (method);
2321                                 M_LLD(argintregs[0], REG_PV, a);
2322                                 M_OR(REG_RESULT, REG_RESULT, argintregs[1], 0);
2323                                 M_FLTMOVE(REG_FRESULT, argfltregs[2]);
2324                                 a = dseg_addaddress ((void*) (builtin_displaymethodstop));
2325                                 M_LLD(REG_PV, REG_PV, a);
2326                                 M_JSR (REG_RA, REG_PV);
2327                                 s1 = (int)((u1*) mcodeptr - mcodebase);
2328                                 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
2329                                 else {
2330                                         s4 ml=-s1, mh=0;
2331                                         while (ml<-32768) { ml+=65536; mh--; }
2332                                         M_LDA (REG_PV, REG_RA, ml );
2333                                         M_LDAH (REG_PV, REG_PV, mh );
2334                                         }
2335                                 M_DLD(REG_FRESULT, REG_SP,16);
2336                                 M_LLD(REG_RESULT, REG_SP, 8);
2337                                 M_LLD(REG_RA, REG_SP, 0);
2338                                 M_LDA (REG_SP, REG_SP, 24);
2339                                 }
2340                         M_RET(REG_ZERO, REG_RA);
2341                         ALIGNCODENOP;
2342                         }
2343                         break;
2344
2345
2346                 case ICMD_TABLESWITCH:
2347                         {
2348                         s4 i, l, *s4ptr;
2349
2350                         s4ptr = iptr->val.a;
2351                         l = s4ptr[1];                          /* low     */
2352                         i = s4ptr[2];                          /* high    */
2353                         
2354                         var_to_reg_int(s1, src, REG_ITMP1);
2355                         if (l == 0)
2356                                 {M_INTMOVE(s1, REG_ITMP1);}
2357                         else
2358                                 M_LDA(REG_ITMP1, s1, -l);
2359                         i = i - l + 1;
2360
2361                         if (i <= 256)
2362                                 M_CMPULE(REG_ITMP1, i - 1, REG_ITMP2, 1);
2363                         else {
2364                                 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
2365                                 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2, 0);
2366                                 }
2367                         M_BEQZ(REG_ITMP2, 0);
2368                         mcode_addreference(BlockPtrOfPC(s4ptr[0]), mcodeptr);
2369
2370                         /* build jump table top down and use address of lowest entry */
2371
2372                         s4ptr += 3 + i;
2373                         while (--i >= 0) {
2374                                 dseg_addtarget(BlockPtrOfPC(*--s4ptr));
2375                                 }
2376                         }
2377
2378                         /* length of dataseg after last dseg_addtarget is used by load */
2379
2380                         M_S8ADDQ(REG_ITMP1, REG_PV, REG_ITMP2, 0);
2381                         M_LLD(REG_ITMP2, REG_ITMP2, -dseglen);
2382                         M_JMP(REG_ZERO, REG_ITMP2);
2383                         ALIGNCODENOP;
2384                         break;
2385
2386
2387                 case ICMD_LOOKUPSWITCH:
2388                         {
2389                         s4 i, l, val, *s4ptr;
2390
2391                         s4ptr = iptr->val.a;
2392                         l = s4ptr[0];                          /* default  */
2393                         i = s4ptr[1];                          /* count    */
2394                         
2395                         MCODECHECK((i<<2)+8);
2396                         var_to_reg_int(s1, src, REG_ITMP1);
2397                         while (--i >= 0) {
2398                                 s4ptr += 2;
2399                                 val = s4ptr[0];
2400                                 if ((val >= 0) && (val <= 255)) {
2401                                         M_CMPEQ(s1, val, REG_ITMP2, 1);
2402                                         }
2403                                 else {
2404                                         if ((val >= -32768) && (val <= 32767)) {
2405                                                 M_LDA(REG_ITMP2, REG_ZERO, val);
2406                                                 } 
2407                                         else {
2408                                                 a = dseg_adds4 (val);
2409                                                 M_ILD(REG_ITMP2, REG_PV, a);
2410                                                 }
2411                                         M_CMPEQ(s1, REG_ITMP2, REG_ITMP2, 0);
2412                                         }
2413                                 M_BNEZ(REG_ITMP2, 0);
2414                                 mcode_addreference(BlockPtrOfPC(s4ptr[1]), mcodeptr);
2415                                 }
2416
2417                         M_BR(0);
2418                         mcode_addreference(BlockPtrOfPC(l), mcodeptr);
2419                         ALIGNCODENOP;
2420                         break;
2421                         }
2422
2423
2424                 case ICMD_BUILTIN3:
2425                         s3 = 3;
2426                         goto gen_method;
2427
2428                 case ICMD_BUILTIN2:
2429                         s3 = 2;
2430                         goto gen_method;
2431
2432                 case ICMD_BUILTIN1:
2433                         s3 = 1;
2434                         goto gen_method;
2435
2436                 case ICMD_INVOKESTATIC:
2437                 case ICMD_INVOKESPECIAL:
2438                 case ICMD_INVOKEVIRTUAL:
2439                 case ICMD_INVOKEINTERFACE:
2440                         s3 = iptr->op1;
2441
2442 gen_method: {
2443                         methodinfo   *m;
2444                         classinfo    *ci;
2445
2446                         MCODECHECK((s3 << 1) + 64);
2447
2448                         for (; --s3 >= 0; src = src->prev) {
2449                                 if (src->varkind == ARGVAR)
2450                                         continue;
2451                                 if (IS_INT_LNG_TYPE(src->type)) {
2452                                         if (s3 < INT_ARG_CNT) {
2453                                                 s1 = argintregs[s3];
2454                                                 var_to_reg_int(d, src, s1);
2455                                                 M_INTMOVE(d, s1);
2456                                                 }
2457                                         else  {
2458                                                 var_to_reg_int(d, src, REG_ITMP1);
2459                                                 M_LST(d, REG_SP, 8 * (s3 - INT_ARG_CNT));
2460                                                 }
2461                                         }
2462                                 else
2463                                         if (s3 < FLT_ARG_CNT) {
2464                                                 s1 = argfltregs[s3];
2465                                                 var_to_reg_flt(d, src, s1);
2466                                                 M_FLTMOVE(d, s1);
2467                                                 }
2468                                         else {
2469                                                 var_to_reg_flt(d, src, REG_FTMP1);
2470                                                 M_DST(d, REG_SP, 8 * (s3 - FLT_ARG_CNT));
2471                                                 }
2472                                 } /* end of for */
2473
2474                         m = iptr->val.a;
2475                         switch (iptr->opc) {
2476                                 case ICMD_BUILTIN3:
2477                                 case ICMD_BUILTIN2:
2478                                 case ICMD_BUILTIN1:
2479                                         a = dseg_addaddress ((void*) (m));
2480
2481                                         M_LLD(REG_PV, REG_PV, a); /* Pointer to built-in-function */
2482                                         d = iptr->op1;
2483                                         goto makeactualcall;
2484
2485                                 case ICMD_INVOKESTATIC:
2486                                 case ICMD_INVOKESPECIAL:
2487                                         a = dseg_addaddress (m->stubroutine);
2488
2489                                         M_LLD(REG_PV, REG_PV, a );       /* Method-Pointer in r27 */
2490
2491                                         d = m->returntype;
2492                                         goto makeactualcall;
2493
2494                                 case ICMD_INVOKEVIRTUAL:
2495
2496                                         gen_nullptr_check(argintregs[0]);
2497                                         M_LLD(REG_METHODPTR, argintregs[0],
2498                                                                  OFFSET(java_objectheader, vftbl));
2499                                         M_LLD(REG_PV, REG_METHODPTR, OFFSET(vftbl, table[0]) +
2500                                                                 sizeof(methodptr) * m->vftblindex);
2501
2502                                         d = m->returntype;
2503                                         goto makeactualcall;
2504
2505                                 case ICMD_INVOKEINTERFACE:
2506                                         ci = m->class;
2507                                         
2508                                         gen_nullptr_check(argintregs[0]);
2509                                         M_LLD(REG_METHODPTR, argintregs[0],
2510                                                                  OFFSET(java_objectheader, vftbl));    
2511                                         M_LLD(REG_METHODPTR, REG_METHODPTR,
2512                                                                     OFFSET(vftbl, interfacevftbl));
2513                                         M_LLD(REG_METHODPTR, REG_METHODPTR,
2514                                                                    sizeof(methodptr*) * ci->index);
2515                                         M_LLD(REG_PV, REG_METHODPTR,
2516                                                             sizeof(methodptr) * (m - ci->methods));
2517
2518                                         d = m->returntype;
2519                                         goto makeactualcall;
2520
2521                                 default:
2522                                         d = 0;
2523                                         sprintf (logtext, "Unkown ICMD-Command: %d", iptr->opc);
2524                                         error ();
2525                                 }
2526
2527 makeactualcall:
2528
2529                         M_JSR (REG_RA, REG_PV);
2530                         s1 = (int)((u1*) mcodeptr - mcodebase);
2531                         if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
2532                         else {
2533                                 s4 ml=-s1, mh=0;
2534                                 while (ml<-32768) { ml+=65536; mh--; }
2535                                 M_LDA (REG_PV, REG_RA, ml );
2536                                 M_LDAH (REG_PV, REG_PV, mh );
2537                                 }
2538
2539                         if (d != TYPE_VOID) {
2540                                 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
2541                                         s1 = reg_of_var(iptr->dst, REG_RESULT);
2542                                         M_INTMOVE(REG_RESULT, s1);
2543                                         store_reg_to_var_int(iptr->dst, s1);
2544                                         }
2545                                 else {
2546                                         s1 = reg_of_var(iptr->dst, REG_FRESULT);
2547                                         M_FLTMOVE(REG_FRESULT, s1);
2548                                         store_reg_to_var_flt(iptr->dst, s1);
2549                                         }
2550                                 }
2551                         }
2552                         break;
2553
2554                 case ICMD_CHECKASIZE:
2555                         var_to_reg_int(s1, src, REG_ITMP1);
2556                         M_BLTZ(s1, 0);
2557                         mcode_addxcheckarefs(mcodeptr);
2558                         break;
2559
2560                 case ICMD_MULTIANEWARRAY:
2561
2562                         /* check for negative sizes and copy sizes to stack if necessary  */
2563
2564                         MCODECHECK((iptr->op1 << 1) + 64);
2565
2566                         for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
2567                                 var_to_reg_int(s2, src, REG_ITMP1);
2568                                 M_BLTZ(s2, 0);
2569                                 mcode_addxcheckarefs(mcodeptr);
2570
2571                                 /* copy sizes to stack (argument numbers >= INT_ARG_CNT)      */
2572
2573                                 if (src->varkind != ARGVAR) {
2574                                         M_LST(s2, REG_SP, 8 * (s1 + INT_ARG_CNT));
2575                                         }
2576                                 }
2577
2578                         /* a0 = dimension count */
2579
2580                         M_LDA(argintregs[0], REG_ZERO, iptr->op1);
2581
2582                         /* a1 = arraydescriptor */
2583
2584                         a = dseg_addaddress(iptr->val.a);
2585                         M_LLD(argintregs[1], REG_PV, a);
2586
2587                         /* a2 = pointer to dimensions = stack pointer */
2588
2589                         M_INTMOVE(REG_SP, argintregs[2]);
2590
2591                         a = dseg_addaddress((void*) (builtin_nmultianewarray));
2592                         M_LLD(REG_PV, REG_PV, a);
2593                         M_JSR(REG_RA, REG_PV);
2594                         s1 = (int)((u1*) mcodeptr - mcodebase);
2595                         if (s1 <= 32768)
2596                                 M_LDA (REG_PV, REG_RA, -s1);
2597                         else {
2598                                 s4 ml = -s1, mh = 0;
2599                                 while (ml < -32768) {ml += 65536; mh--;}
2600                                 M_LDA(REG_PV, REG_RA, ml);
2601                                 M_LDAH(REG_PV, REG_PV, mh);
2602                                 }
2603                         s1 = reg_of_var(iptr->dst, REG_RESULT);
2604                         M_INTMOVE(REG_RESULT, s1);
2605                         store_reg_to_var_int(iptr->dst, s1);
2606                         break;
2607
2608
2609                 default: sprintf (logtext, "Unknown pseudo command: %d", iptr->opc);
2610                          error();
2611         } /* switch */
2612         } /* for instruction */
2613         src = bptr->outstack;
2614         len = bptr->outdepth;
2615         MCODECHECK(64+len);
2616         while (src) {
2617                 len--;
2618                 if ((src->varkind != STACKVAR)) {
2619                         s2 = src->type;
2620                         if (IS_FLT_DBL_TYPE(s2)) {
2621                                 var_to_reg_int(s1, src, REG_ITMP1);
2622                                 if (!(interfaces[len][s2].flags & INMEMORY)) {
2623                                         M_FLTMOVE(s1,interfaces[len][s2].regoff);
2624                                         }
2625                                 else {
2626                                         M_DST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
2627                                         }
2628                                 }
2629                         else {
2630                                 var_to_reg_flt(s1, src, REG_FTMP1);
2631                                 if (!(interfaces[len][s2].flags & INMEMORY)) {
2632                                         M_INTMOVE(s1,interfaces[len][s2].regoff);
2633                                         }
2634                                 else {
2635                                         M_LST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
2636                                         }
2637                                 }
2638                         }
2639                 src = src->prev;
2640                 }
2641         } /* for basic block */
2642
2643         bptr -> mpc = (int)((u1*) mcodeptr - mcodebase);
2644
2645         {
2646         s4 *xcodeptr = NULL;
2647         
2648         for (; xboundrefs != NULL; xboundrefs = xboundrefs->next) {
2649                 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
2650                         gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos, 
2651                                 xboundrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
2652                         continue;
2653                         }
2654
2655                 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos, 
2656                                   xboundrefs->branchpos, (u1*) mcodeptr - mcodebase);
2657
2658                 MCODECHECK(8);
2659
2660                 M_LDA(REG_ITMP2_XPC, REG_PV, xboundrefs->branchpos);
2661
2662                 if (xcodeptr != NULL) {
2663                         M_BR((xcodeptr-mcodeptr)-1);
2664                         }
2665                 else {
2666                         xcodeptr = mcodeptr;
2667
2668                         a = dseg_addaddress(proto_java_lang_ArrayIndexOutOfBoundsException);
2669                         M_LLD(REG_ITMP1_XPTR, REG_PV, a);
2670
2671                         a = dseg_addaddress(asm_handle_exception);
2672                         M_LLD(REG_ITMP3, REG_PV, a);
2673
2674                         M_JMP(REG_ZERO, REG_ITMP3);
2675                         }
2676                 }
2677
2678         xcodeptr = NULL;
2679         
2680         for (; xcheckarefs != NULL; xcheckarefs = xcheckarefs->next) {
2681                 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
2682                         gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos, 
2683                                 xcheckarefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
2684                         continue;
2685                         }
2686
2687                 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos, 
2688                                   xcheckarefs->branchpos, (u1*) mcodeptr - mcodebase);
2689
2690                 MCODECHECK(8);
2691
2692                 M_LDA(REG_ITMP2_XPC, REG_PV, xcheckarefs->branchpos);
2693
2694                 if (xcodeptr != NULL) {
2695                         M_BR((xcodeptr-mcodeptr)-1);
2696                         }
2697                 else {
2698                         xcodeptr = mcodeptr;
2699
2700                         a = dseg_addaddress(proto_java_lang_NegativeArraySizeException);
2701                         M_LLD(REG_ITMP1_XPTR, REG_PV, a);
2702
2703                         a = dseg_addaddress(asm_handle_exception);
2704                         M_LLD(REG_ITMP3, REG_PV, a);
2705
2706                         M_JMP(REG_ZERO, REG_ITMP3);
2707                         }
2708                 }
2709
2710
2711 #ifdef SOFTNULLPTRCHECK
2712
2713         xcodeptr = NULL;
2714
2715         for (; xnullrefs != NULL; xnullrefs = xnullrefs->next) {
2716                 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
2717                         gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos, 
2718                                 xnullrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
2719                         continue;
2720                         }
2721
2722                 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos, 
2723                                   xnullrefs->branchpos, (u1*) mcodeptr - mcodebase);
2724
2725                 MCODECHECK(8);
2726
2727                 M_LDA(REG_ITMP2_XPC, REG_PV, xnullrefs->branchpos - 4);
2728
2729                 if (xcodeptr != NULL) {
2730                         M_BR((xcodeptr-mcodeptr)-1);
2731                         }
2732                 else {
2733                         xcodeptr = mcodeptr;
2734
2735                         a = dseg_addaddress(proto_java_lang_NullPointerException);
2736                         M_LLD(REG_ITMP1_XPTR, REG_PV, a);
2737
2738                         a = dseg_addaddress(asm_handle_exception);
2739                         M_LLD(REG_ITMP3, REG_PV, a);
2740
2741                         M_JMP(REG_ZERO, REG_ITMP3);
2742                         }
2743                 }
2744
2745 #endif
2746         }
2747
2748         mcode_finish((int)((u1*) mcodeptr - mcodebase));
2749 }
2750
2751
2752 /******** redefinition of code generation macros (compiling into array) *******/
2753
2754 /* 
2755 These macros are newly defined to allow code generation into an array.
2756 This is necessary, because the original M_.. macros generate code by
2757 calling 'mcode_adds4' that uses an additional data structure to
2758 receive the code.
2759
2760 For a faster (but less flexible) version to generate code, these
2761 macros directly use the (s4* p) - pointer to put the code directly
2762 in a locally defined array.
2763 This makes sense only for the stub-generation-routines below.
2764 */
2765
2766 #undef M_OP3
2767 #define M_OP3(op,fu,a,b,c,const) \
2768         *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<(16-3*(const)))| \
2769         ((const)<<12)|((fu)<<5)|((c)) )
2770 #undef M_FOP3
2771 #define M_FOP3(op,fu,a,b,c) \
2772         *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<16)|((fu)<<5)|(c) )
2773 #undef M_BRA
2774 #define M_BRA(op,a,disp) \
2775         *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((disp)&0x1fffff) )
2776 #undef M_MEM
2777 #define M_MEM(op,a,b,disp) \
2778         *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<16)|((disp)&0xffff) )
2779
2780
2781 #if 0
2782
2783 /************************ function createcompilerstub **************************
2784
2785         creates a stub routine which calls the compiler
2786         
2787 *******************************************************************************/
2788
2789 #define COMPSTUBSIZE 3
2790
2791 u1 *createcompilerstub (methodinfo *m)
2792 {
2793         u8 *s = CNEW (u8, COMPSTUBSIZE);    /* memory to hold the stub            */
2794         s4 *p = (s4*) s;                    /* code generation pointer            */
2795         
2796                                             /* code for the stub                  */
2797         M_LLD (REG_PV, REG_PV, 16);         /* load pointer to the compiler       */
2798         M_JMP (0, REG_PV);                  /* jump to the compiler, return address
2799                                                in reg 0 is used as method pointer */
2800         s[1] = (u8) m;                      /* literals to be adressed            */  
2801         s[2] = (u8) asm_call_jit_compiler;  /* jump directly via PV from above    */
2802
2803 #ifdef STATISTICS
2804         count_cstub_len += COMPSTUBSIZE * 8;
2805 #endif
2806
2807         return (u1*) s;
2808 }
2809
2810
2811 /************************* function removecompilerstub *************************
2812
2813      deletes a compilerstub from memory  (simply by freeing it)
2814
2815 *******************************************************************************/
2816
2817 void removecompilerstub (u1 *stub) 
2818 {
2819         CFREE (stub, COMPSTUBSIZE * 8);
2820 }
2821
2822
2823 /************************ function: removenativestub ***************************
2824
2825     removes a previously created native-stub from memory
2826     
2827 *******************************************************************************/
2828
2829 void removenativestub (u1 *stub)
2830 {
2831         CFREE (stub, NATIVESTUBSIZE * 8);
2832 }
2833
2834 #endif /* 0 */
2835
2836
2837 /********************* Funktion: ncreatenativestub *****************************
2838
2839         creates a stub routine which calls a native method
2840         
2841 *******************************************************************************/
2842
2843 #define NATIVESTUBSIZE 11
2844
2845 u1 *ncreatenativestub (functionptr f, methodinfo *m)
2846 {
2847         u8 *s = CNEW (u8, NATIVESTUBSIZE);  /* memory to hold the stub            */
2848         s4 *p = (s4*) s;                    /* code generation pointer            */
2849
2850         M_LDA  (REG_SP, REG_SP, -8);        /* build up stackframe                */
2851         M_LST  (REG_RA, REG_SP, 0);         /* store return address               */
2852
2853         M_LLD  (REG_PV, REG_PV, 8*8);       /* load adress of native method       */
2854         M_JSR  (REG_RA, REG_PV);            /* call native method                 */
2855
2856         M_LDA  (REG_PV, REG_RA, -4*4);      /* recompute pv from ra               */
2857         M_LLD  (REG_ITMP3, REG_PV, 9*8);    /* get address of exceptionptr        */
2858
2859         M_LLD  (REG_RA, REG_SP, 0);         /* load return address                */
2860         M_LLD  (REG_ITMP1, REG_ITMP3, 0);   /* load exception into reg. itmp1     */
2861
2862         M_LDA  (REG_SP, REG_SP, 8);         /* remove stackframe                  */
2863         M_BNEZ (REG_ITMP1, 1);              /* if no exception then return        */
2864
2865         M_RET  (REG_ZERO, REG_RA);          /* return to caller                   */
2866         
2867         M_LST  (REG_ZERO, REG_ITMP3, 0);    /* store NULL into exceptionptr       */
2868         M_LDA  (REG_ITMP2, REG_RA, -4);     /* move fault address into reg. itmp2 */
2869
2870         M_LLD  (REG_ITMP3, REG_PV,10*8);    /* load asm exception handler address */
2871         M_JMP  (REG_ZERO, REG_ITMP3);       /* jump to asm exception handler      */
2872
2873
2874         s[8] = (u8) f;                      /* address of native method           */
2875         s[9] = (u8) (&exceptionptr);        /* address of exceptionptr            */
2876         s[10]= (u8) (asm_handle_nat_exception); /* addr of asm exception handler  */
2877
2878 #ifdef STATISTICS
2879         count_nstub_len += NATIVESTUBSIZE * 8;
2880 #endif
2881
2882         return (u1*) s;
2883 }
2884