basic block struct changed
[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                 if (bptr->flags >= BBREACHED) {
458
459                 /* branch resolving */
460
461                 {
462                 branchref *brefs;
463                 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
464                         gen_resolvebranch((u1*) mcodebase + brefs->branchpos, 
465                                           brefs->branchpos, bptr->mpc);
466                         }
467                 }
468                 src = bptr->instack;
469                 len = bptr->indepth;
470                 MCODECHECK(64+len);
471                 while (src != NULL) {
472                         len--;
473                         if ((len == 0) && (bptr->type != BBTYPE_STD)) {
474                                 d = reg_of_var(src, REG_ITMP1);
475                                 M_INTMOVE(REG_ITMP1, d);
476                                 store_reg_to_var_int(src, d);
477                                 }
478                         else {
479                                 d = reg_of_var(src, REG_IFTMP);
480                                 if ((src->varkind != STACKVAR)) {
481                                         s2 = src->type;
482                                         if (IS_FLT_DBL_TYPE(s2)) {
483                                                 if (!(interfaces[len][s2].flags & INMEMORY)) {
484                                                         s1 = interfaces[len][s2].regoff;
485                                                         M_FLTMOVE(s1,d);
486                                                         }
487                                                 else {
488                                                         M_DLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
489                                                         }
490                                                 store_reg_to_var_flt(src, d);
491                                                 }
492                                         else {
493                                                 if (!(interfaces[len][s2].flags & INMEMORY)) {
494                                                         s1 = interfaces[len][s2].regoff;
495                                                         M_INTMOVE(s1,d);
496                                                         }
497                                                 else {
498                                                         M_LLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
499                                                         }
500                                                 store_reg_to_var_int(src, d);
501                                                 }
502                                         }
503                                 }
504                         src = src->prev;
505                         }
506                 src = bptr->instack;
507                 len = bptr->icount;
508                 for (iptr = bptr->iinstr;
509                     len > 0;
510                     src = iptr->dst, len--, iptr++) {
511
512         MCODECHECK(64);
513         switch (iptr->opc) {
514
515                 case ICMD_NOP:
516                         break;
517
518                 case ICMD_NULLCHECKPOP:
519                         var_to_reg_int(s1, src, REG_ITMP1);
520                         gen_nullptr_check(s1);
521                         break;
522
523                 /* constant operations ************************************************/
524
525                 case ICMD_ICONST:
526                         d = reg_of_var(iptr->dst, REG_ITMP1);
527                         if ( (iptr->val.i >= -32768) && (iptr->val.i <= 32767) ) {
528                                 M_LDA(d, REG_ZERO, iptr->val.i);
529                                 } 
530                         else {
531                                 a = dseg_adds4 (iptr->val.i);
532                                 M_ILD(d, REG_PV, a);
533                                 }
534                         store_reg_to_var_int(iptr->dst, d);
535                         break;
536
537                 case ICMD_LCONST:
538                         d = reg_of_var(iptr->dst, REG_ITMP1);
539                         if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767) ) {
540                                 M_LDA(d, REG_ZERO, iptr->val.l);
541                                 } 
542                         else {
543                                 a = dseg_adds8 (iptr->val.l);
544                                 M_LLD(d, REG_PV, a);
545                                 }
546                         store_reg_to_var_int(iptr->dst, d);
547                         break;
548
549                 case ICMD_FCONST:
550                         d = reg_of_var (iptr->dst, REG_FTMP1);
551                         a = dseg_addfloat (iptr->val.f);
552                         M_FLD(d, REG_PV, a);
553                         store_reg_to_var_flt (iptr->dst, d);
554                         break;
555                         
556                 case ICMD_DCONST:
557                         d = reg_of_var (iptr->dst, REG_FTMP1);
558                         a = dseg_adddouble (iptr->val.d);
559                         M_DLD(d, REG_PV, a);
560                         store_reg_to_var_flt (iptr->dst, d);
561                         break;
562
563
564                 case ICMD_ACONST:
565                         d = reg_of_var(iptr->dst, REG_ITMP1);
566                         if (iptr->val.a) {
567                                 a = dseg_addaddress (iptr->val.a);
568                                 M_LLD(d, REG_PV, a);
569                                 }
570                         else {
571                                 M_INTMOVE(REG_ZERO, d);
572                                 }
573                         store_reg_to_var_int(iptr->dst, d);
574                         break;
575
576                 /* load/store operations **********************************************/
577
578                 case ICMD_ILOAD:
579                 case ICMD_LLOAD:
580                 case ICMD_ALOAD:
581                         d = reg_of_var(iptr->dst, REG_ITMP1);
582                         if ((iptr->dst->varkind == LOCALVAR) &&
583                             (iptr->dst->varnum == iptr->op1))
584                                 break;
585                         var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
586                         if (var->flags & INMEMORY)
587                                 M_LLD(d, REG_SP, 8 * var->regoff);
588                         else
589                                 {M_INTMOVE(var->regoff,d);}
590                         store_reg_to_var_int(iptr->dst, d);
591                         break;
592
593                 case ICMD_FLOAD:
594                 case ICMD_DLOAD:
595                         d = reg_of_var(iptr->dst, REG_FTMP1);
596                         if ((iptr->dst->varkind == LOCALVAR) &&
597                             (iptr->dst->varnum == iptr->op1))
598                                 break;
599                         var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
600                         if (var->flags & INMEMORY)
601                                 M_DLD(d, REG_SP, 8 * var->regoff);
602                         else
603                                 {M_FLTMOVE(var->regoff,d);}
604                         store_reg_to_var_flt(iptr->dst, d);
605                         break;
606
607
608                 case ICMD_ISTORE:
609                 case ICMD_LSTORE:
610                 case ICMD_ASTORE:
611                         if ((src->varkind == LOCALVAR) &&
612                             (src->varnum == iptr->op1))
613                                 break;
614                         var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
615                         if (var->flags & INMEMORY) {
616                                 var_to_reg_int(s1, src, REG_ITMP1);
617                                 M_LST(s1, REG_SP, 8 * var->regoff);
618                                 }
619                         else {
620                                 var_to_reg_int(s1, src, var->regoff);
621                                 M_INTMOVE(s1, var->regoff);
622                                 }
623                         break;
624
625                 case ICMD_FSTORE:
626                 case ICMD_DSTORE:
627                         if ((src->varkind == LOCALVAR) &&
628                             (src->varnum == iptr->op1))
629                                 break;
630                         var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
631                         if (var->flags & INMEMORY) {
632                                 var_to_reg_flt(s1, src, REG_FTMP1);
633                                 M_DST(s1, REG_SP, 8 * var->regoff);
634                                 }
635                         else {
636                                 var_to_reg_flt(s1, src, var->regoff);
637                                 M_FLTMOVE(s1, var->regoff);
638                                 }
639                         break;
640
641
642                 /* pop/dup/swap operations ********************************************/
643
644                 case ICMD_POP:
645                 case ICMD_POP2:
646                         break;
647
648 #define M_COPY(from,to) \
649                         d = reg_of_var(to, REG_IFTMP); \
650                         if ((from->regoff != to->regoff) || \
651                             ((from->flags ^ to->flags) & INMEMORY)) { \
652                                 if (IS_FLT_DBL_TYPE(from->type)) { \
653                                         var_to_reg_flt(s1, from, d); \
654                                         M_FLTMOVE(s1,d); \
655                                         store_reg_to_var_flt(to, d); \
656                                         }\
657                                 else { \
658                                         var_to_reg_int(s1, from, d); \
659                                         M_INTMOVE(s1,d); \
660                                         store_reg_to_var_int(to, d); \
661                                         }\
662                                 }
663
664                 case ICMD_DUP:
665                         M_COPY(src, iptr->dst);
666                         break;
667
668                 case ICMD_DUP_X1:
669                         M_COPY(src,       iptr->dst->prev->prev);
670                 case ICMD_DUP2:
671                         M_COPY(src,       iptr->dst);
672                         M_COPY(src->prev, iptr->dst->prev);
673                         break;
674
675                 case ICMD_DUP2_X1:
676                         M_COPY(src->prev,       iptr->dst->prev->prev->prev);
677                 case ICMD_DUP_X2:
678                         M_COPY(src,             iptr->dst);
679                         M_COPY(src->prev,       iptr->dst->prev);
680                         M_COPY(src->prev->prev, iptr->dst->prev->prev);
681                         M_COPY(src, iptr->dst->prev->prev->prev);
682                         break;
683
684                 case ICMD_DUP2_X2:
685                         M_COPY(src,                   iptr->dst);
686                         M_COPY(src->prev,             iptr->dst->prev);
687                         M_COPY(src->prev->prev,       iptr->dst->prev->prev);
688                         M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
689                         M_COPY(src,       iptr->dst->prev->prev->prev->prev);
690                         M_COPY(src->prev, iptr->dst->prev->prev->prev->prev->prev);
691                         break;
692
693                 case ICMD_SWAP:
694                         M_COPY(src, iptr->dst->prev);
695                         M_COPY(src->prev, iptr->dst);
696                         break;
697
698
699                 /* integer operations *************************************************/
700
701                 case ICMD_INEG:
702                         var_to_reg_int(s1, src, REG_ITMP1); 
703                         d = reg_of_var(iptr->dst, REG_ITMP3);
704                         M_ISUB(REG_ZERO, s1, d, 0);
705                         store_reg_to_var_int(iptr->dst, d);
706                         break;
707
708                 case ICMD_LNEG:
709                         var_to_reg_int(s1, src, REG_ITMP1);
710                         d = reg_of_var(iptr->dst, REG_ITMP3);
711                         M_LSUB(REG_ZERO, s1, d, 0);
712                         store_reg_to_var_int(iptr->dst, d);
713                         break;
714
715                 case ICMD_I2L:
716                         var_to_reg_int(s1, src, REG_ITMP1);
717                         d = reg_of_var(iptr->dst, REG_ITMP3);
718                         M_INTMOVE(s1, d);
719                         store_reg_to_var_int(iptr->dst, d);
720                         break;
721
722                 case ICMD_L2I:
723                         var_to_reg_int(s1, src, REG_ITMP1);
724                         d = reg_of_var(iptr->dst, REG_ITMP3);
725                         M_IADD(s1, REG_ZERO, d , 0);
726                         store_reg_to_var_int(iptr->dst, d);
727                         break;
728
729                 case ICMD_INT2BYTE:
730                         var_to_reg_int(s1, src, REG_ITMP1);
731                         d = reg_of_var(iptr->dst, REG_ITMP3);
732                         if (has_ext_instr_set) {
733                                 M_BSEXT(s1, d);
734                                 }
735                         else {
736                                 M_SLL(s1,56, d, 1);
737                                 M_SRA( d,56, d, 1);
738                                 }
739                         store_reg_to_var_int(iptr->dst, d);
740                         break;
741
742                 case ICMD_INT2CHAR:
743                         var_to_reg_int(s1, src, REG_ITMP1);
744                         d = reg_of_var(iptr->dst, REG_ITMP3);
745             M_ZAPNOT(s1, 0x03, d, 1);
746                         store_reg_to_var_int(iptr->dst, d);
747                         break;
748
749                 case ICMD_INT2SHORT:
750                         var_to_reg_int(s1, src, REG_ITMP1);
751                         d = reg_of_var(iptr->dst, REG_ITMP3);
752                         if (has_ext_instr_set) {
753                                 M_SSEXT(s1, d);
754                                 }
755                         else {
756                                 M_SLL( s1, 48, d, 1);
757                                 M_SRA(  d, 48, d, 1);
758                                 }
759                         store_reg_to_var_int(iptr->dst, d);
760                         break;
761
762 #define ICONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
763                     else{a=dseg_adds4(c);M_ILD(r,REG_PV,a);}
764
765 #define LCONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LDA(r,REG_ZERO,c);} \
766                     else{a=dseg_adds8(c);M_LLD(r,REG_PV,a);}
767
768
769                 case ICMD_IADD:
770                         var_to_reg_int(s1, src->prev, REG_ITMP1);
771                         var_to_reg_int(s2, src, REG_ITMP2);
772                         d = reg_of_var(iptr->dst, REG_ITMP3);
773                         M_IADD(s1, s2, d,  0);
774                         store_reg_to_var_int(iptr->dst, d);
775                         break;
776                 case ICMD_IADDCONST:
777                         var_to_reg_int(s1, src, REG_ITMP1);
778                         d = reg_of_var(iptr->dst, REG_ITMP3);
779                         if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
780                                 M_IADD(s1, iptr->val.i, d, 1);
781                                 }
782                         else {
783                                 ICONST(REG_ITMP2, iptr->val.i);
784                                 M_IADD(s1, REG_ITMP2, d, 0);
785                                 }
786                         store_reg_to_var_int(iptr->dst, d);
787                         break;
788                 case ICMD_LADD:
789                         var_to_reg_int(s1, src->prev, REG_ITMP1);
790                         var_to_reg_int(s2, src, REG_ITMP2);
791                         d = reg_of_var(iptr->dst, REG_ITMP3);
792                         M_LADD(s1, s2, d,  0);
793                         store_reg_to_var_int(iptr->dst, d);
794                         break;
795                 case ICMD_LADDCONST:
796                         var_to_reg_int(s1, src, REG_ITMP1);
797                         d = reg_of_var(iptr->dst, REG_ITMP3);
798                         if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
799                                 M_LADD(s1, iptr->val.l, d, 1);
800                                 }
801                         else {
802                                 LCONST(REG_ITMP2, iptr->val.l);
803                                 M_LADD(s1, REG_ITMP2, d, 0);
804                                 }
805                         store_reg_to_var_int(iptr->dst, d);
806                         break;
807
808                 case ICMD_ISUB:
809                         var_to_reg_int(s1, src->prev, REG_ITMP1);
810                         var_to_reg_int(s2, src, REG_ITMP2);
811                         d = reg_of_var(iptr->dst, REG_ITMP3);
812                         M_ISUB(s1, s2, d, 0);
813                         store_reg_to_var_int(iptr->dst, d);
814                         break;
815                 case ICMD_ISUBCONST:
816                         var_to_reg_int(s1, src, REG_ITMP1);
817                         d = reg_of_var(iptr->dst, REG_ITMP3);
818                         if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
819                                 M_ISUB(s1, iptr->val.i, d, 1);
820                                 }
821                         else {
822                                 ICONST(REG_ITMP2, iptr->val.i);
823                                 M_ISUB(s1, REG_ITMP2, d, 0);
824                                 }
825                         store_reg_to_var_int(iptr->dst, d);
826                         break;
827                 case ICMD_LSUB:
828                         var_to_reg_int(s1, src->prev, REG_ITMP1);
829                         var_to_reg_int(s2, src, REG_ITMP2);
830                         d = reg_of_var(iptr->dst, REG_ITMP3);
831                         M_LSUB(s1, s2, d, 0);
832                         store_reg_to_var_int(iptr->dst, d);
833                         break;
834                 case ICMD_LSUBCONST:
835                         var_to_reg_int(s1, src, REG_ITMP1);
836                         d = reg_of_var(iptr->dst, REG_ITMP3);
837                         if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
838                                 M_LSUB(s1, iptr->val.l, d, 1);
839                                 }
840                         else {
841                                 LCONST(REG_ITMP2, iptr->val.l);
842                                 M_LSUB(s1, REG_ITMP2, d, 0);
843                                 }
844                         store_reg_to_var_int(iptr->dst, d);
845                         break;
846
847                 case ICMD_IMUL:
848                         var_to_reg_int(s1, src->prev, REG_ITMP1);
849                         var_to_reg_int(s2, src, REG_ITMP2);
850                         d = reg_of_var(iptr->dst, REG_ITMP3);
851                         M_IMUL(s1, s2, d, 0);
852                         store_reg_to_var_int(iptr->dst, d);
853                         break;
854                 case ICMD_IMULCONST:
855                         var_to_reg_int(s1, src, REG_ITMP1);
856                         d = reg_of_var(iptr->dst, REG_ITMP3);
857                         if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
858                                 M_IMUL(s1, iptr->val.i, d, 1);
859                                 }
860                         else {
861                                 ICONST(REG_ITMP2, iptr->val.i);
862                                 M_IMUL(s1, REG_ITMP2, d, 0);
863                                 }
864                         store_reg_to_var_int(iptr->dst, d);
865                         break;
866                 case ICMD_LMUL:
867                         var_to_reg_int(s1, src->prev, REG_ITMP1);
868                         var_to_reg_int(s2, src, REG_ITMP2);
869                         d = reg_of_var(iptr->dst, REG_ITMP3);
870                         M_LMUL (s1, s2, d, 0);
871                         store_reg_to_var_int(iptr->dst, d);
872                         break;
873                 case ICMD_LMULCONST:
874                         var_to_reg_int(s1, src, REG_ITMP1);
875                         d = reg_of_var(iptr->dst, REG_ITMP3);
876                         if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
877                                 M_LMUL(s1, iptr->val.l, d, 1);
878                                 }
879                         else {
880                                 LCONST(REG_ITMP2, iptr->val.l);
881                                 M_LMUL(s1, REG_ITMP2, d, 0);
882                                 }
883                         store_reg_to_var_int(iptr->dst, d);
884                         break;
885                 case ICMD_IDIVPOW2:
886                 case ICMD_LDIVPOW2:
887                         var_to_reg_int(s1, src, REG_ITMP1);
888                         d = reg_of_var(iptr->dst, REG_ITMP3);
889                         if (iptr->val.i <= 15) {
890                                 M_LDA(REG_ITMP2, s1, (1 << iptr->val.i) -1);
891                                 M_CMOVGE(s1, s1, REG_ITMP2, 0);
892                                 }
893                         else {
894                                 M_SRA(s1, 63, REG_ITMP2, 1);
895                                 M_SRL(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2, 1);
896                                 M_LADD(s1, REG_ITMP2, REG_ITMP2, 0);
897                                 }
898                         M_SRA(REG_ITMP2, iptr->val.i, d, 1);
899                         store_reg_to_var_int(iptr->dst, d);
900                         break;
901
902                     
903                 case ICMD_ISHL:
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_SLL(s1, REG_ITMP3, d, 0);
909                         M_IADD(d, REG_ZERO, d, 0);
910                         store_reg_to_var_int(iptr->dst, d);
911                         break;
912                 case ICMD_ISHLCONST:
913                         var_to_reg_int(s1, src, REG_ITMP1);
914                         d = reg_of_var(iptr->dst, REG_ITMP3);
915                         M_SLL(s1, iptr->val.i & 0x1f, d, 1);
916                         M_IADD(d, REG_ZERO, d, 0);
917                         store_reg_to_var_int(iptr->dst, d);
918                         break;
919
920                 case ICMD_ISHR:
921                         var_to_reg_int(s1, src->prev, REG_ITMP1);
922                         var_to_reg_int(s2, src, REG_ITMP2);
923                         d = reg_of_var(iptr->dst, REG_ITMP3);
924                         M_AND(s2, 0x1f, REG_ITMP3,  1);
925                         M_SRA(s1, REG_ITMP3, d,   0);
926                         store_reg_to_var_int(iptr->dst, d);
927                         break;
928                 case ICMD_ISHRCONST:
929                         var_to_reg_int(s1, src, REG_ITMP1);
930                         d = reg_of_var(iptr->dst, REG_ITMP3);
931                         M_SRA(s1, iptr->val.i & 0x1f, d, 1);
932                         store_reg_to_var_int(iptr->dst, d);
933                         break;
934
935                 case ICMD_IUSHR:
936                         var_to_reg_int(s1, src->prev, REG_ITMP1);
937                         var_to_reg_int(s2, src, REG_ITMP2);
938                         d = reg_of_var(iptr->dst, REG_ITMP3);
939                         M_AND   (s2, 0x1f, REG_ITMP2,  1);
940             M_ZAPNOT(s1, 0x0f, d, 1);
941                         M_SRL   ( d, REG_ITMP2, d, 0);
942                         M_IADD  ( d, REG_ZERO, d, 0);
943                         store_reg_to_var_int(iptr->dst, d);
944                         break;
945                 case ICMD_IUSHRCONST:
946                         var_to_reg_int(s1, src, REG_ITMP1);
947                         d = reg_of_var(iptr->dst, REG_ITMP3);
948             M_ZAPNOT(s1, 0x0f, d, 1);
949                         M_SRL(d, iptr->val.i & 0x1f, d, 1);
950                         M_IADD(d, REG_ZERO, d, 0);
951                         store_reg_to_var_int(iptr->dst, d);
952                         break;
953
954                 case ICMD_LSHL:
955                         var_to_reg_int(s1, src->prev, REG_ITMP1);
956                         var_to_reg_int(s2, src, REG_ITMP2);
957                         d = reg_of_var(iptr->dst, REG_ITMP3);
958                         M_SLL(s1, s2, d, 0);
959                         store_reg_to_var_int(iptr->dst, d);
960                         break;
961                 case ICMD_LSHLCONST:
962                         var_to_reg_int(s1, src, REG_ITMP1);
963                         d = reg_of_var(iptr->dst, REG_ITMP3);
964                         M_SLL(s1, iptr->val.l & 0x3f, d, 1);
965                         store_reg_to_var_int(iptr->dst, d);
966                         break;
967
968                 case ICMD_LSHR:
969                         var_to_reg_int(s1, src->prev, REG_ITMP1);
970                         var_to_reg_int(s2, src, REG_ITMP2);
971                         d = reg_of_var(iptr->dst, REG_ITMP3);
972                         M_SRA(s1, s2, d,  0);
973                         store_reg_to_var_int(iptr->dst, d);
974                         break;
975                 case ICMD_LSHRCONST:
976                         var_to_reg_int(s1, src, REG_ITMP1);
977                         d = reg_of_var(iptr->dst, REG_ITMP3);
978                         M_SRA(s1, iptr->val.l & 0x3f, d, 1);
979                         store_reg_to_var_int(iptr->dst, d);
980                         break;
981
982                 case ICMD_LUSHR:
983                         var_to_reg_int(s1, src->prev, REG_ITMP1);
984                         var_to_reg_int(s2, src, REG_ITMP2);
985                         d = reg_of_var(iptr->dst, REG_ITMP3);
986                         M_SRL(s1, s2, d,  0);
987                         store_reg_to_var_int(iptr->dst, d);
988                         break;
989                 case ICMD_LUSHRCONST:
990                         var_to_reg_int(s1, src, REG_ITMP1);
991                         d = reg_of_var(iptr->dst, REG_ITMP3);
992                         M_SRL(s1, iptr->val.l & 0x3f, d, 1);
993                         store_reg_to_var_int(iptr->dst, d);
994                         break;
995
996                 case ICMD_IAND:
997                 case ICMD_LAND:
998                         var_to_reg_int(s1, src->prev, REG_ITMP1);
999                         var_to_reg_int(s2, src, REG_ITMP2);
1000                         d = reg_of_var(iptr->dst, REG_ITMP3);
1001                         M_AND(s1, s2, d, 0);
1002                         store_reg_to_var_int(iptr->dst, d);
1003                         break;
1004                 case ICMD_IANDCONST:
1005                         var_to_reg_int(s1, src, REG_ITMP1);
1006                         d = reg_of_var(iptr->dst, REG_ITMP3);
1007                         if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1008                                 M_AND(s1, iptr->val.i, d, 1);
1009                                 }
1010                         else if (iptr->val.i == 0xffff) {
1011                                 M_ZAPNOT(s1, 0x03, d, 1);
1012                                 }
1013                         else if (iptr->val.i == 0xffffff) {
1014                                 M_ZAPNOT(s1, 0x07, d, 1);
1015                                 }
1016                         else {
1017                                 ICONST(REG_ITMP2, iptr->val.i);
1018                                 M_AND(s1, REG_ITMP2, d, 0);
1019                                 }
1020                         store_reg_to_var_int(iptr->dst, d);
1021                         break;
1022                 case ICMD_IREMPOW2:
1023                         var_to_reg_int(s1, src, REG_ITMP1);
1024                         d = reg_of_var(iptr->dst, REG_ITMP3);
1025                         if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1026                                 M_AND(s1, iptr->val.i, d, 1);
1027                                 M_BGEZ(s1, 3);
1028                                 M_ISUB(REG_ZERO, s1, d, 0);
1029                                 M_AND(d, iptr->val.i, d, 1);
1030                                 }
1031                         else if (iptr->val.i == 0xffff) {
1032                                 M_ZAPNOT(s1, 0x03, d, 1);
1033                                 M_BGEZ(s1, 3);
1034                                 M_ISUB(REG_ZERO, s1, d, 0);
1035                                 M_ZAPNOT(d, 0x03, d, 1);
1036                                 }
1037                         else if (iptr->val.i == 0xffffff) {
1038                                 M_ZAPNOT(s1, 0x07, d, 1);
1039                                 M_BGEZ(s1, 3);
1040                                 M_ISUB(REG_ZERO, s1, d, 0);
1041                                 M_ZAPNOT(d, 0x07, d, 1);
1042                                 }
1043                         else {
1044                                 ICONST(REG_ITMP2, iptr->val.i);
1045                                 M_AND(s1, REG_ITMP2, d, 0);
1046                                 M_BGEZ(s1, 3);
1047                                 M_ISUB(REG_ZERO, s1, d, 0);
1048                                 M_AND(d, REG_ITMP2, d, 0);
1049                                 }
1050                         M_ISUB(REG_ZERO, d, d, 0);
1051                         store_reg_to_var_int(iptr->dst, d);
1052                         break;
1053                 case ICMD_IREM0X10001:
1054                 
1055 /*          i % 0x100001
1056                         b = i & 0xffff;
1057                         a = i >> 16;
1058                         a = ((b - a) & 0xffff) + (b < a);
1059 */
1060                         var_to_reg_int(s1, src, REG_ITMP1);
1061                         d = reg_of_var(iptr->dst, REG_ITMP3);
1062             M_ZAPNOT(s1, 0x03, REG_ITMP2, 1);
1063                         M_SRA(s1, 16, d, 1);
1064                         M_CMPLT(REG_ITMP2, d, REG_ITMP1, 0);
1065                         M_ISUB(REG_ITMP2, d, d, 0);
1066             M_ZAPNOT(d, 0x03, d, 1);
1067                         M_IADD(d, REG_ITMP1, d, 0);
1068                         M_BGEZ(s1, 11);
1069                         M_ISUB(REG_ZERO, s1, REG_ITMP1, 0);
1070             M_ZAPNOT(REG_ITMP1, 0x03, REG_ITMP2, 1);
1071                         M_SRA(REG_ITMP1, 16, d, 1);
1072                         M_CMPLT(REG_ITMP2, d, REG_ITMP1, 0);
1073                         M_ISUB(REG_ITMP2, d, d, 0);
1074             M_ZAPNOT(d, 0x03, d, 1);
1075                         M_IADD(d, REG_ITMP1, d, 0);
1076                         M_ISUB(REG_ZERO, d, d, 0);
1077                         M_SLL(s1, 33, REG_ITMP2, 1);
1078                         M_CMPEQ(REG_ITMP2, REG_ZERO, REG_ITMP2, 0);
1079                         M_ISUB(d, REG_ITMP2, d, 0);
1080                         store_reg_to_var_int(iptr->dst, d);
1081                         break;
1082                 case ICMD_LANDCONST:
1083                         var_to_reg_int(s1, src, REG_ITMP1);
1084                         d = reg_of_var(iptr->dst, REG_ITMP3);
1085                         if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1086                                 M_AND(s1, iptr->val.l, d, 1);
1087                                 }
1088                         else if (iptr->val.l == 0xffffL) {
1089                                 M_ZAPNOT(s1, 0x03, d, 1);
1090                                 }
1091                         else if (iptr->val.l == 0xffffffL) {
1092                                 M_ZAPNOT(s1, 0x07, d, 1);
1093                                 }
1094                         else if (iptr->val.l == 0xffffffffL) {
1095                                 M_ZAPNOT(s1, 0x0f, d, 1);
1096                                 }
1097                         else if (iptr->val.l == 0xffffffffffL) {
1098                                 M_ZAPNOT(s1, 0x1f, d, 1);
1099                                 }
1100                         else if (iptr->val.l == 0xffffffffffffL) {
1101                                 M_ZAPNOT(s1, 0x3f, d, 1);
1102                                 }
1103                         else if (iptr->val.l == 0xffffffffffffffL) {
1104                                 M_ZAPNOT(s1, 0x7f, d, 1);
1105                                 }
1106                         else {
1107                                 LCONST(REG_ITMP2, iptr->val.l);
1108                                 M_AND(s1, REG_ITMP2, d, 0);
1109                                 }
1110                         store_reg_to_var_int(iptr->dst, d);
1111                         break;
1112                 case ICMD_LREMPOW2:
1113                         var_to_reg_int(s1, src, REG_ITMP1);
1114                         d = reg_of_var(iptr->dst, REG_ITMP3);
1115                         if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1116                                 M_AND(s1, iptr->val.l, d, 1);
1117                                 M_BGEZ(s1, 3);
1118                                 M_LSUB(REG_ZERO, s1, d, 0);
1119                                 M_AND(d, iptr->val.l, d, 1);
1120                                 }
1121                         else if (iptr->val.l == 0xffffL) {
1122                                 M_ZAPNOT(s1, 0x03, d, 1);
1123                                 M_BGEZ(s1, 3);
1124                                 M_LSUB(REG_ZERO, s1, d, 0);
1125                                 M_ZAPNOT(d, 0x03, d, 1);
1126                                 }
1127                         else if (iptr->val.l == 0xffffffL) {
1128                                 M_ZAPNOT(s1, 0x07, d, 1);
1129                                 M_BGEZ(s1, 3);
1130                                 M_LSUB(REG_ZERO, s1, d, 0);
1131                                 M_ZAPNOT(d, 0x07, d, 1);
1132                                 }
1133                         else if (iptr->val.l == 0xffffffffL) {
1134                                 M_ZAPNOT(s1, 0x0f, d, 1);
1135                                 M_BGEZ(s1, 3);
1136                                 M_LSUB(REG_ZERO, s1, d, 0);
1137                                 M_ZAPNOT(d, 0x0f, d, 1);
1138                                 }
1139                         else if (iptr->val.l == 0xffffffffffL) {
1140                                 M_ZAPNOT(s1, 0x1f, d, 1);
1141                                 M_BGEZ(s1, 3);
1142                                 M_LSUB(REG_ZERO, s1, d, 0);
1143                                 M_ZAPNOT(d, 0x1f, d, 1);
1144                                 }
1145                         else if (iptr->val.l == 0xffffffffffffL) {
1146                                 M_ZAPNOT(s1, 0x3f, d, 1);
1147                                 M_BGEZ(s1, 3);
1148                                 M_LSUB(REG_ZERO, s1, d, 0);
1149                                 M_ZAPNOT(d, 0x3f, d, 1);
1150                                 }
1151                         else if (iptr->val.l == 0xffffffffffffffL) {
1152                                 M_ZAPNOT(s1, 0x7f, d, 1);
1153                                 M_BGEZ(s1, 3);
1154                                 M_LSUB(REG_ZERO, s1, d, 0);
1155                                 M_ZAPNOT(d, 0x7f, d, 1);
1156                                 }
1157                         else {
1158                                 LCONST(REG_ITMP2, iptr->val.l);
1159                                 M_AND(s1, REG_ITMP2, d, 0);
1160                                 M_BGEZ(s1, 3);
1161                                 M_LSUB(REG_ZERO, s1, d, 0);
1162                                 M_AND(d, REG_ITMP2, d, 0);
1163                                 }
1164                         M_LSUB(REG_ZERO, d, d, 0);
1165                         store_reg_to_var_int(iptr->dst, d);
1166                         break;
1167                 case ICMD_LREM0X10001:
1168                         var_to_reg_int(s1, src, REG_ITMP1);
1169                         d = reg_of_var(iptr->dst, REG_ITMP3);
1170                         M_ZAPNOT(s1, 0x03, REG_ITMP2, 1);
1171                         M_SRA(s1, 16, d, 1);
1172                         M_CMPLT(REG_ITMP2, d, REG_ITMP1, 0);
1173                         M_LSUB(REG_ITMP2, d, d, 0);
1174             M_ZAPNOT(d, 0x03, d, 1);
1175                         M_LADD(d, REG_ITMP1, d, 0);
1176                         M_LDA(REG_ITMP2, REG_ZERO, -1);
1177                         M_SRL(REG_ITMP2, 33, REG_ITMP2, 1);
1178                         M_CMPULT(s1, REG_ITMP2, REG_ITMP2, 0);
1179                         M_BNEZ(REG_ITMP2, 11);
1180                         M_LDA(d, REG_ZERO, -257);
1181                         M_ZAPNOT(d, 0xcd, d, 1);
1182                         M_LSUB(REG_ZERO, s1, REG_ITMP2, 0);
1183                         M_CMOVGE(s1, s1, REG_ITMP2, 0);
1184                         M_UMULH(REG_ITMP2, d, REG_ITMP2, 0);
1185                         M_SRL(REG_ITMP2, 16, REG_ITMP2, 1);
1186                         M_LSUB(REG_ZERO, REG_ITMP2, d, 0);
1187                         M_CMOVGE(s1, REG_ITMP2, d, 0);
1188                         M_SLL(d, 16, REG_ITMP2, 1);
1189                         M_LADD(d, REG_ITMP2, d, 0);
1190                         M_LSUB(s1, d, d, 0);
1191                         store_reg_to_var_int(iptr->dst, d);
1192                         break;
1193
1194                 case ICMD_IOR:
1195                 case ICMD_LOR:
1196                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1197                         var_to_reg_int(s2, src, REG_ITMP2);
1198                         d = reg_of_var(iptr->dst, REG_ITMP3);
1199                         M_OR( s1,s2, d, 0);
1200                         store_reg_to_var_int(iptr->dst, d);
1201                         break;
1202                 case ICMD_IORCONST:
1203                         var_to_reg_int(s1, src, REG_ITMP1);
1204                         d = reg_of_var(iptr->dst, REG_ITMP3);
1205                         if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1206                                 M_OR(s1, iptr->val.i, d, 1);
1207                                 }
1208                         else {
1209                                 ICONST(REG_ITMP2, iptr->val.i);
1210                                 M_OR(s1, REG_ITMP2, d, 0);
1211                                 }
1212                         store_reg_to_var_int(iptr->dst, d);
1213                         break;
1214                 case ICMD_LORCONST:
1215                         var_to_reg_int(s1, src, REG_ITMP1);
1216                         d = reg_of_var(iptr->dst, REG_ITMP3);
1217                         if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1218                                 M_OR(s1, iptr->val.l, d, 1);
1219                                 }
1220                         else {
1221                                 LCONST(REG_ITMP2, iptr->val.l);
1222                                 M_OR(s1, REG_ITMP2, d, 0);
1223                                 }
1224                         store_reg_to_var_int(iptr->dst, d);
1225                         break;
1226
1227                 case ICMD_IXOR:
1228                 case ICMD_LXOR:
1229                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1230                         var_to_reg_int(s2, src, REG_ITMP2);
1231                         d = reg_of_var(iptr->dst, REG_ITMP3);
1232                         M_XOR(s1, s2, d, 0);
1233                         store_reg_to_var_int(iptr->dst, d);
1234                         break;
1235                 case ICMD_IXORCONST:
1236                         var_to_reg_int(s1, src, REG_ITMP1);
1237                         d = reg_of_var(iptr->dst, REG_ITMP3);
1238                         if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1239                                 M_XOR(s1, iptr->val.i, d, 1);
1240                                 }
1241                         else {
1242                                 ICONST(REG_ITMP2, iptr->val.i);
1243                                 M_XOR(s1, REG_ITMP2, d, 0);
1244                                 }
1245                         store_reg_to_var_int(iptr->dst, d);
1246                         break;
1247                 case ICMD_LXORCONST:
1248                         var_to_reg_int(s1, src, REG_ITMP1);
1249                         d = reg_of_var(iptr->dst, REG_ITMP3);
1250                         if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1251                                 M_XOR(s1, iptr->val.l, d, 1);
1252                                 }
1253                         else {
1254                                 LCONST(REG_ITMP2, iptr->val.l);
1255                                 M_XOR(s1, REG_ITMP2, d, 0);
1256                                 }
1257                         store_reg_to_var_int(iptr->dst, d);
1258                         break;
1259
1260
1261                 case ICMD_LCMP:
1262                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1263                         var_to_reg_int(s2, src, REG_ITMP2);
1264                         d = reg_of_var(iptr->dst, REG_ITMP3);
1265                         M_CMPLT(s1, s2, REG_ITMP3, 0);
1266                         M_CMPLT(s2, s1, REG_ITMP1, 0);
1267                         M_LSUB (REG_ITMP1, REG_ITMP3, d, 0);
1268                         store_reg_to_var_int(iptr->dst, d);
1269                         break;
1270
1271
1272                 case ICMD_IINC:
1273                         var = &(locals[iptr->op1][TYPE_INT]);
1274                         if (var->flags & INMEMORY) {
1275                                 s1 = REG_ITMP1;
1276                                 M_LLD(s1, REG_SP, 8 * var->regoff);
1277                                 }
1278                         else
1279                                 s1 = var->regoff;
1280                         if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1281                                 M_IADD(s1, iptr->val.i, s1, 1);
1282                                 }
1283                         else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1284                                 M_ISUB(s1, (-iptr->val.i), s1, 1);
1285                                 }
1286                         else {
1287                                 M_LDA (s1, s1, iptr->val.i);
1288                                 M_IADD(s1, REG_ZERO, s1, 0);
1289                                 }
1290                         if (var->flags & INMEMORY)
1291                                 M_LST(s1, REG_SP, 8 * var->regoff);
1292                         break;
1293
1294
1295                 /* floating operations ************************************************/
1296
1297                 case ICMD_FNEG:
1298                         var_to_reg_flt(s1, src, REG_FTMP1);
1299                         d = reg_of_var(iptr->dst, REG_FTMP3);
1300                         M_FMOVN(s1, d);
1301                         store_reg_to_var_flt(iptr->dst, d);
1302                         break;
1303                 case ICMD_DNEG:
1304                         var_to_reg_flt(s1, src, REG_FTMP1);
1305                         d = reg_of_var(iptr->dst, REG_FTMP3);
1306                         M_FMOVN(s1, d);
1307                         store_reg_to_var_flt(iptr->dst, d);
1308                         break;
1309
1310                 case ICMD_FADD:
1311                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1312                         var_to_reg_flt(s2, src, REG_FTMP2);
1313                         d = reg_of_var(iptr->dst, REG_FTMP3);
1314                         if (checkfloats) {
1315                                 M_FADDS(s1, s2, d);
1316                                 M_TRAPB;
1317                                 }
1318                         else {
1319                                 M_FADD(s1, s2, d);
1320                                 }
1321                         store_reg_to_var_flt(iptr->dst, d);
1322                         break;
1323                 case ICMD_DADD:
1324                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1325                         var_to_reg_flt(s2, src, REG_FTMP2);
1326                         d = reg_of_var(iptr->dst, REG_FTMP3);
1327                         if (checkfloats) {
1328                                 M_DADDS(s1, s2, d);
1329                                 M_TRAPB;
1330                                 }
1331                         else {
1332                                 M_DADD(s1, s2, d);
1333                                 }
1334                         store_reg_to_var_flt(iptr->dst, d);
1335                         break;
1336
1337                 case ICMD_FSUB:
1338                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1339                         var_to_reg_flt(s2, src, REG_FTMP2);
1340                         d = reg_of_var(iptr->dst, REG_FTMP3);
1341                         if (checkfloats) {
1342                                 M_FSUBS(s1, s2, d);
1343                                 M_TRAPB;
1344                                 }
1345                         else {
1346                                 M_FSUB(s1, s2, d);
1347                                 }
1348                         store_reg_to_var_flt(iptr->dst, d);
1349                         break;
1350                 case ICMD_DSUB:
1351                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1352                         var_to_reg_flt(s2, src, REG_FTMP2);
1353                         d = reg_of_var(iptr->dst, REG_FTMP3);
1354                         if (checkfloats) {
1355                                 M_DSUBS(s1, s2, d);
1356                                 M_TRAPB;
1357                                 }
1358                         else {
1359                                 M_DSUB(s1, s2, d);
1360                                 }
1361                         store_reg_to_var_flt(iptr->dst, d);
1362                         break;
1363
1364                 case ICMD_FMUL:
1365                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1366                         var_to_reg_flt(s2, src, REG_FTMP2);
1367                         d = reg_of_var(iptr->dst, REG_FTMP3);
1368                         if (checkfloats) {
1369                                 M_FMULS(s1, s2, d);
1370                                 M_TRAPB;
1371                                 }
1372                         else {
1373                                 M_FMUL(s1, s2, d);
1374                                 }
1375                         store_reg_to_var_flt(iptr->dst, d);
1376                         break;
1377                 case ICMD_DMUL:
1378                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1379                         var_to_reg_flt(s2, src, REG_FTMP2);
1380                         d = reg_of_var(iptr->dst, REG_FTMP3);
1381                         if (checkfloats) {
1382                                 M_DMULS(s1, s2, d);
1383                                 M_TRAPB;
1384                                 }
1385                         else {
1386                                 M_DMUL(s1, s2, d);
1387                                 }
1388                         store_reg_to_var_flt(iptr->dst, d);
1389                         break;
1390
1391                 case ICMD_FDIV:
1392                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1393                         var_to_reg_flt(s2, src, REG_FTMP2);
1394                         d = reg_of_var(iptr->dst, REG_FTMP3);
1395                         if (checkfloats) {
1396                                 M_FDIVS(s1, s2, d);
1397                                 M_TRAPB;
1398                                 }
1399                         else {
1400                                 M_FDIV(s1, s2, d);
1401                                 }
1402                         store_reg_to_var_flt(iptr->dst, d);
1403                         break;
1404                 case ICMD_DDIV:
1405                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1406                         var_to_reg_flt(s2, src, REG_FTMP2);
1407                         d = reg_of_var(iptr->dst, REG_FTMP3);
1408                         if (checkfloats) {
1409                                 M_DDIVS(s1, s2, d);
1410                                 M_TRAPB;
1411                                 }
1412                         else {
1413                                 M_DDIV(s1, s2, d);
1414                                 }
1415                         store_reg_to_var_flt(iptr->dst, d);
1416                         break;
1417                 
1418                 case ICMD_FREM:
1419                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1420                         var_to_reg_flt(s2, src, REG_FTMP2);
1421                         d = reg_of_var(iptr->dst, REG_FTMP3);
1422                         if (checkfloats) {
1423                                 M_FDIVS(s1,s2, REG_FTMP3);
1424                                 M_TRAPB;
1425                                 M_CVTDL_CS(REG_ZERO, REG_FTMP3, REG_FTMP3); /* round to integer */
1426                                 M_TRAPB;
1427                                 M_CVTLF(REG_ZERO, REG_FTMP3, REG_FTMP3);
1428                                 M_FMULS(REG_FTMP3, s2, REG_FTMP3);
1429                                 M_TRAPB;
1430                                 M_FSUBS(s1, REG_FTMP3, d);
1431                                 M_TRAPB;
1432                                 }
1433                         else {
1434                                 M_FDIV(s1,s2, REG_FTMP3);
1435                                 M_CVTDL_C(REG_ZERO, REG_FTMP3, REG_FTMP3); /* round to integer */
1436                                 M_CVTLF(REG_ZERO, REG_FTMP3, REG_FTMP3);
1437                                 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1438                                 M_FSUB(s1, REG_FTMP3, d);
1439                                 }
1440                         store_reg_to_var_flt(iptr->dst, d);
1441                     break;
1442                 case ICMD_DREM:
1443                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1444                         var_to_reg_flt(s2, src, REG_FTMP2);
1445                         d = reg_of_var(iptr->dst, REG_FTMP3);
1446                         if (checkfloats) {
1447                                 M_DDIVS(s1,s2, REG_FTMP3);
1448                                 M_TRAPB;
1449                                 M_CVTDL_CS(REG_ZERO, REG_FTMP3, REG_FTMP3); /* round to integer */
1450                                 M_TRAPB;
1451                                 M_CVTLD(REG_ZERO, REG_FTMP3, REG_FTMP3);
1452                                 M_DMULS(REG_FTMP3, s2, REG_FTMP3);
1453                                 M_TRAPB;
1454                                 M_DSUBS(s1, REG_FTMP3, d);
1455                                 M_TRAPB;
1456                                 }
1457                         else {
1458                                 M_DDIV(s1,s2, REG_FTMP3);
1459                                 M_CVTDL_C(REG_ZERO, REG_FTMP3, REG_FTMP3); /* round to integer */
1460                                 M_CVTLD(REG_ZERO, REG_FTMP3, REG_FTMP3);
1461                                 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1462                                 M_DSUB(s1, REG_FTMP3, d);
1463                                 }
1464                         store_reg_to_var_flt(iptr->dst, d);
1465                     break;
1466
1467                 case ICMD_I2F:
1468                 case ICMD_L2F:
1469                         var_to_reg_int(s1, src, REG_ITMP1);
1470                         d = reg_of_var(iptr->dst, REG_FTMP3);
1471                         a = dseg_adddouble(0.0);
1472                         M_LST (s1, REG_PV, a);
1473                         M_DLD (d, REG_PV, a);
1474                         M_CVTLF(REG_ZERO, d, d);
1475                         store_reg_to_var_flt(iptr->dst, d);
1476                         break;
1477
1478                 case ICMD_I2D:
1479                 case ICMD_L2D:
1480                         var_to_reg_int(s1, src, REG_ITMP1);
1481                         d = reg_of_var(iptr->dst, REG_FTMP3);
1482                         a = dseg_adddouble(0.0);
1483                         M_LST (s1, REG_PV, a);
1484                         M_DLD (d, REG_PV, a);
1485                         M_CVTLD(REG_ZERO, d, d);
1486                         store_reg_to_var_flt(iptr->dst, d);
1487                         break;
1488                         
1489                 case ICMD_F2I:
1490                 case ICMD_D2I:
1491                         var_to_reg_flt(s1, src, REG_FTMP1);
1492                         d = reg_of_var(iptr->dst, REG_ITMP3);
1493                         a = dseg_adddouble(0.0);
1494                         if (checkfloats) {
1495                                 M_CVTDL_CS(REG_ZERO, s1, REG_FTMP1);
1496                                 M_TRAPB;
1497                                 M_CVTLIS(REG_FTMP1, REG_FTMP2);
1498                                 M_TRAPB;
1499                                 }
1500                         else {
1501                                 M_CVTDL_C(REG_ZERO, s1, REG_FTMP1);
1502                                 M_CVTLI(REG_FTMP1, REG_FTMP2);
1503                                 }
1504                         M_DST (REG_FTMP1, REG_PV, a);
1505                         M_ILD (d, REG_PV, a);
1506                         store_reg_to_var_int(iptr->dst, d);
1507                         break;
1508                 
1509                 case ICMD_F2L:
1510                 case ICMD_D2L:
1511                         var_to_reg_flt(s1, src, REG_FTMP1);
1512                         d = reg_of_var(iptr->dst, REG_ITMP3);
1513                         a = dseg_adddouble(0.0);
1514                         if (checkfloats) {
1515                                 M_CVTDL_CS(REG_ZERO, s1, REG_FTMP1);
1516                                 M_TRAPB;
1517                                 }
1518                         else {
1519                                 M_CVTDL_C(REG_ZERO, s1, REG_FTMP1);
1520                                 }
1521                         M_DST (REG_FTMP1, REG_PV, a);
1522                         M_LLD (d, REG_PV, a);
1523                         store_reg_to_var_int(iptr->dst, d);
1524                         break;
1525
1526                 case ICMD_F2D:
1527                         var_to_reg_flt(s1, src, REG_FTMP1);
1528                         d = reg_of_var(iptr->dst, REG_FTMP3);
1529                         M_FLTMOVE(s1, d);
1530                         store_reg_to_var_flt(iptr->dst, d);
1531                         break;
1532                                         
1533                 case ICMD_D2F:
1534                         var_to_reg_flt(s1, src, REG_FTMP1);
1535                         d = reg_of_var(iptr->dst, REG_FTMP3);
1536                         if (checkfloats) {
1537                                 M_CVTDFS(REG_ZERO, s1, d);
1538                                 M_TRAPB;
1539                                 }
1540                         else {
1541                                 M_CVTDF(REG_ZERO, s1, d);
1542                                 }
1543                         store_reg_to_var_flt(iptr->dst, d);
1544                         break;
1545                 
1546                 case ICMD_FCMPL:
1547                 case ICMD_DCMPL:
1548                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1549                         var_to_reg_flt(s2, src, REG_FTMP2);
1550                         d = reg_of_var(iptr->dst, REG_ITMP3);
1551                         if (checkfloats) {
1552                                 M_LSUB  (REG_ZERO, 1, d, 1);
1553                                 M_FCMPEQS(s1, s2, REG_FTMP3);
1554                                 M_TRAPB;
1555                                 M_FBEQZ (REG_FTMP3, 1);    /* jump over next instructions         */
1556                                 M_OR    (REG_ZERO, REG_ZERO, d, 0);
1557                                 M_FCMPLTS(s2, s1, REG_FTMP3);
1558                                 M_TRAPB;
1559                                 M_FBEQZ (REG_FTMP3, 1);    /* jump over next instruction          */
1560                                 M_LADD  (REG_ZERO, 1, d, 1);
1561                                 }
1562                         else {
1563                                 M_LSUB  (REG_ZERO, 1, d, 1);
1564                                 M_FCMPEQ(s1, s2, REG_FTMP3);
1565                                 M_FBEQZ (REG_FTMP3, 1);    /* jump over next instructions         */
1566                                 M_OR    (REG_ZERO, REG_ZERO, d, 0);
1567                                 M_FCMPLT(s2, s1, REG_FTMP3);
1568                                 M_FBEQZ (REG_FTMP3, 1);    /* jump over next instruction          */
1569                                 M_LADD  (REG_ZERO, 1, d, 1);
1570                                 }
1571                         store_reg_to_var_int(iptr->dst, d);
1572                         break;
1573                         
1574                 case ICMD_FCMPG:
1575                 case ICMD_DCMPG:
1576                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1577                         var_to_reg_flt(s2, src, REG_FTMP2);
1578                         d = reg_of_var(iptr->dst, REG_ITMP3);
1579                         if (checkfloats) {
1580                                 M_LADD  (REG_ZERO, 1, d, 1);
1581                                 M_FCMPEQS(s1, s2, REG_FTMP3);
1582                                 M_TRAPB;
1583                                 M_FBEQZ (REG_FTMP3, 1);    /* jump over next instruction          */
1584                                 M_OR    (REG_ZERO, REG_ZERO, d, 0);
1585                                 M_FCMPLTS(s1, s2, REG_FTMP3);
1586                                 M_TRAPB;
1587                                 M_FBEQZ (REG_FTMP3, 1);    /* jump over next instruction          */
1588                                 M_LSUB  (REG_ZERO, 1, d, 1);
1589                                 }
1590                         else {
1591                                 M_LADD  (REG_ZERO, 1, d, 1);
1592                                 M_FCMPEQ(s1, s2, REG_FTMP3);
1593                                 M_FBEQZ (REG_FTMP3, 1);    /* jump over next instruction          */
1594                                 M_OR    (REG_ZERO, REG_ZERO, d, 0);
1595                                 M_FCMPLT(s1, s2, REG_FTMP3);
1596                                 M_FBEQZ (REG_FTMP3, 1);    /* jump over next instruction          */
1597                                 M_LSUB  (REG_ZERO, 1, d, 1);
1598                                 }
1599                         store_reg_to_var_int(iptr->dst, d);
1600                         break;
1601
1602
1603                 /* memory operations **************************************************/
1604
1605 #define gen_bound_check \
1606                         if (checkbounds) {\
1607                         M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\
1608                         M_CMPULT(s2, REG_ITMP3, REG_ITMP3, 0);\
1609                         M_BEQZ(REG_ITMP3, 0);\
1610                         mcode_addxboundrefs(mcodeptr);\
1611                         }
1612
1613                 case ICMD_ARRAYLENGTH:
1614                         var_to_reg_int(s1, src, REG_ITMP1);
1615                         d = reg_of_var(iptr->dst, REG_ITMP3);
1616                         gen_nullptr_check(s1);
1617                         M_ILD(d, s1, OFFSET(java_arrayheader, size));
1618                         store_reg_to_var_int(iptr->dst, d);
1619                         break;
1620
1621                 case ICMD_AALOAD:
1622                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1623                         var_to_reg_int(s2, src, REG_ITMP2);
1624                         d = reg_of_var(iptr->dst, REG_ITMP3);
1625                         gen_nullptr_check(s1);
1626                         gen_bound_check;
1627                         M_S8ADDQ(s2, s1, REG_ITMP1, 0);
1628                         M_LLD( d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1629                         store_reg_to_var_int(iptr->dst, d);
1630                         break;
1631                 case ICMD_LALOAD:
1632                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1633                         var_to_reg_int(s2, src, REG_ITMP2);
1634                         d = reg_of_var(iptr->dst, REG_ITMP3);
1635                         gen_nullptr_check(s1);
1636                         gen_bound_check;
1637                         M_S8ADDQ(s2, s1, REG_ITMP1, 0);
1638                         M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1639                         store_reg_to_var_int(iptr->dst, d);
1640                         break;
1641                 case ICMD_IALOAD:
1642                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1643                         var_to_reg_int(s2, src, REG_ITMP2);
1644                         d = reg_of_var(iptr->dst, REG_ITMP3);
1645                         gen_nullptr_check(s1);
1646                         gen_bound_check;
1647                         M_S4ADDQ(s2, s1, REG_ITMP1, 0);
1648                         M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1649                         store_reg_to_var_int(iptr->dst, d);
1650                         break;
1651                 case ICMD_FALOAD:
1652                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1653                         var_to_reg_int(s2, src, REG_ITMP2);
1654                         d = reg_of_var(iptr->dst, REG_FTMP3);
1655                         gen_nullptr_check(s1);
1656                         gen_bound_check;
1657                         M_S4ADDQ(s2, s1, REG_ITMP1, 0);
1658                         M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1659                         store_reg_to_var_flt(iptr->dst, d);
1660                         break;
1661                 case ICMD_DALOAD:
1662                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1663                         var_to_reg_int(s2, src, REG_ITMP2);
1664                         d = reg_of_var(iptr->dst, REG_FTMP3);
1665                         gen_nullptr_check(s1);
1666                         gen_bound_check;
1667                         M_S8ADDQ(s2, s1, REG_ITMP1, 0);
1668                         M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1669                         store_reg_to_var_flt(iptr->dst, d);
1670                         break;
1671                 case ICMD_CALOAD:
1672                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1673                         var_to_reg_int(s2, src, REG_ITMP2);
1674                         d = reg_of_var(iptr->dst, REG_ITMP3);
1675                         gen_nullptr_check(s1);
1676                         gen_bound_check;
1677                         if (has_ext_instr_set) {
1678                                 M_LADD(s2, s1, REG_ITMP1, 0);
1679                                 M_LADD(s2, REG_ITMP1, REG_ITMP1, 0);
1680                                 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1681                                 }
1682                         else {
1683                                 M_LADD (s2, s1, REG_ITMP1,  0);
1684                                 M_LADD (s2, REG_ITMP1, REG_ITMP1, 0);
1685                                 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1686                                 M_LDA  (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1687                                 M_EXTWL(REG_ITMP2, REG_ITMP1, d, 0);
1688                                 }
1689                         store_reg_to_var_int(iptr->dst, d);
1690                         break;                  
1691                 case ICMD_SALOAD:
1692                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1693                         var_to_reg_int(s2, src, REG_ITMP2);
1694                         d = reg_of_var(iptr->dst, REG_ITMP3);
1695                         gen_nullptr_check(s1);
1696                         gen_bound_check;
1697                         if (has_ext_instr_set) {
1698                                 M_LADD(s2, s1, REG_ITMP1, 0);
1699                                 M_LADD(s2, REG_ITMP1, REG_ITMP1, 0);
1700                                 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1701                                 M_SSEXT(d, d);
1702                                 }
1703                         else {
1704                                 M_LADD(s2, s1, REG_ITMP1,  0);
1705                                 M_LADD(s2, REG_ITMP1, REG_ITMP1, 0);
1706                                 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1707                                 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1708                                 M_EXTQH(REG_ITMP2, REG_ITMP1, d, 0);
1709                                 M_SRA(d, 48, d, 1);
1710                                 }
1711                         store_reg_to_var_int(iptr->dst, d);
1712                         break;
1713                 case ICMD_BALOAD:
1714                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1715                         var_to_reg_int(s2, src, REG_ITMP2);
1716                         d = reg_of_var(iptr->dst, REG_ITMP3);
1717                         gen_nullptr_check(s1);
1718                         gen_bound_check;
1719                         if (has_ext_instr_set) {
1720                                 M_LADD   (s2, s1, REG_ITMP1, 0);
1721                                 M_BLDU   (d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1722                                 M_BSEXT  (d, d);
1723                                 }
1724                         else {
1725                                 M_LADD(s2, s1, REG_ITMP1, 0);
1726                                 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1727                                 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
1728                                 M_EXTQH(REG_ITMP2, REG_ITMP1, d, 0);
1729                                 M_SRA(d, 56, d, 1);
1730                                 }
1731                         store_reg_to_var_int(iptr->dst, d);
1732                         break;
1733
1734                 case ICMD_AASTORE:
1735                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1736                         var_to_reg_int(s2, src->prev, REG_ITMP2);
1737                         gen_nullptr_check(s1);
1738                         gen_bound_check;
1739                         var_to_reg_int(s3, src, REG_ITMP3);
1740                         M_S8ADDQ(s2, s1, REG_ITMP1, 0);
1741                         M_LST   (s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1742                         break;
1743                 case ICMD_LASTORE:
1744                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1745                         var_to_reg_int(s2, src->prev, REG_ITMP2);
1746                         gen_nullptr_check(s1);
1747                         gen_bound_check;
1748                         var_to_reg_int(s3, src, REG_ITMP3);
1749                         M_S8ADDQ(s2, s1, REG_ITMP1, 0);
1750                         M_LST   (s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1751                         break;
1752                 case ICMD_IASTORE:
1753                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1754                         var_to_reg_int(s2, src->prev, REG_ITMP2);
1755                         gen_nullptr_check(s1);
1756                         gen_bound_check;
1757                         var_to_reg_int(s3, src, REG_ITMP3);
1758                         M_S4ADDQ(s2, s1, REG_ITMP1, 0);
1759                         M_IST   (s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1760                         break;
1761                 case ICMD_FASTORE:
1762                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1763                         var_to_reg_int(s2, src->prev, REG_ITMP2);
1764                         gen_nullptr_check(s1);
1765                         gen_bound_check;
1766                         var_to_reg_flt(s3, src, REG_FTMP3);
1767                         M_S4ADDQ(s2, s1, REG_ITMP1, 0);
1768                         M_FST   (s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1769                         break;
1770                 case ICMD_DASTORE:
1771                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1772                         var_to_reg_int(s2, src->prev, REG_ITMP2);
1773                         gen_nullptr_check(s1);
1774                         gen_bound_check;
1775                         var_to_reg_flt(s3, src, REG_FTMP3);
1776                         M_S8ADDQ(s2, s1, REG_ITMP1, 0);
1777                         M_DST   (s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1778                         break;
1779                 case ICMD_CASTORE:
1780                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1781                         var_to_reg_int(s2, src->prev, REG_ITMP2);
1782                         gen_nullptr_check(s1);
1783                         gen_bound_check;
1784                         var_to_reg_int(s3, src, REG_ITMP3);
1785                         if (has_ext_instr_set) {
1786                                 M_LADD(s2, s1, REG_ITMP1, 0);
1787                                 M_LADD(s2, REG_ITMP1, REG_ITMP1, 0);
1788                                 M_SST (s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1789                                 }
1790                         else {
1791                                 M_LADD (s2, s1, REG_ITMP1, 0);
1792                                 M_LADD (s2, REG_ITMP1, REG_ITMP1, 0);
1793                                 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1794                                 M_LDA  (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1795                                 M_INSWL(s3, REG_ITMP1, REG_ITMP3, 0);
1796                                 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2, 0);
1797                                 M_OR   (REG_ITMP2, REG_ITMP3, REG_ITMP2, 0);
1798                                 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1799                                 }
1800                         break;
1801                 case ICMD_SASTORE:
1802                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1803                         var_to_reg_int(s2, src->prev, REG_ITMP2);
1804                         gen_nullptr_check(s1);
1805                         gen_bound_check;
1806                         var_to_reg_int(s3, src, REG_ITMP3);
1807                         if (has_ext_instr_set) {
1808                                 M_LADD(s2, s1, REG_ITMP1, 0);
1809                                 M_LADD(s2, REG_ITMP1, REG_ITMP1, 0);
1810                                 M_SST (s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1811                                 }
1812                         else {
1813                                 M_LADD (s2, s1, REG_ITMP1, 0);
1814                                 M_LADD (s2, REG_ITMP1, REG_ITMP1, 0);
1815                                 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1816                                 M_LDA  (REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1817                                 M_INSWL(s3, REG_ITMP1, REG_ITMP3, 0);
1818                                 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2, 0);
1819                                 M_OR   (REG_ITMP2, REG_ITMP3, REG_ITMP2, 0);
1820                                 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1821                                 }
1822                         break;
1823                 case ICMD_BASTORE:
1824                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1825                         var_to_reg_int(s2, src->prev, REG_ITMP2);
1826                         gen_nullptr_check(s1);
1827                         gen_bound_check;
1828                         var_to_reg_int(s3, src, REG_ITMP3);
1829                         if (has_ext_instr_set) {
1830                                 M_LADD(s2, s1, REG_ITMP1, 0);
1831                                 M_BST (s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1832                                 }
1833                         else {
1834                                 M_LADD (s2, s1, REG_ITMP1,  0);
1835                                 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1836                                 M_LDA  (REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1837                                 M_INSBL(s3, REG_ITMP1, REG_ITMP3, 0);
1838                                 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2, 0);
1839                                 M_OR   (REG_ITMP2, REG_ITMP3, REG_ITMP2, 0);
1840                                 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1841                                 }
1842                         break;
1843
1844
1845                 case ICMD_PUTSTATIC:
1846                         a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value));
1847                         M_LLD(REG_ITMP1, REG_PV, a);
1848                         switch (iptr->op1) {
1849                                 case TYPE_INT:
1850                                         var_to_reg_int(s2, src, REG_ITMP2);
1851                                         M_IST(s2, REG_ITMP1, 0);
1852                                         break;
1853                                 case TYPE_LNG:
1854                                 case TYPE_ADR:
1855                                         var_to_reg_int(s2, src, REG_ITMP2);
1856                                         M_LST(s2, REG_ITMP1, 0);
1857                                         break;
1858                                 case TYPE_FLT:
1859                                         var_to_reg_flt(s2, src, REG_FTMP2);
1860                                         M_FST(s2, REG_ITMP1, 0);
1861                                         break;
1862                                 case TYPE_DBL:
1863                                         var_to_reg_flt(s2, src, REG_FTMP2);
1864                                         M_DST(s2, REG_ITMP1, 0);
1865                                         break;
1866                                 default: panic ("internal error");
1867                                 }
1868                         break;
1869
1870                 case ICMD_GETSTATIC:
1871                         a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value));
1872                         M_LLD(REG_ITMP1, REG_PV, a);
1873                         switch (iptr->op1) {
1874                                 case TYPE_INT:
1875                                         d = reg_of_var(iptr->dst, REG_ITMP3);
1876                                         M_ILD(d, REG_ITMP1, 0);
1877                                         store_reg_to_var_int(iptr->dst, d);
1878                                         break;
1879                                 case TYPE_LNG:
1880                                 case TYPE_ADR:
1881                                         d = reg_of_var(iptr->dst, REG_ITMP3);
1882                                         M_LLD(d, REG_ITMP1, 0);
1883                                         store_reg_to_var_int(iptr->dst, d);
1884                                         break;
1885                                 case TYPE_FLT:
1886                                         d = reg_of_var(iptr->dst, REG_FTMP1);
1887                                         M_FLD(d, REG_ITMP1, 0);
1888                                         store_reg_to_var_flt(iptr->dst, d);
1889                                         break;
1890                                 case TYPE_DBL:                          
1891                                         d = reg_of_var(iptr->dst, REG_FTMP1);
1892                                         M_DLD(d, REG_ITMP1, 0);
1893                                         store_reg_to_var_flt(iptr->dst, d);
1894                                         break;
1895                                 default: panic ("internal error");
1896                                 }
1897                         break;
1898
1899
1900                 case ICMD_PUTFIELD:
1901                         a = ((fieldinfo *)(iptr->val.a))->offset;
1902                         switch (iptr->op1) {
1903                                 case TYPE_INT:
1904                                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1905                                         var_to_reg_int(s2, src, REG_ITMP2);
1906                                         gen_nullptr_check(s1);
1907                                         M_IST(s2, s1, a);
1908                                         break;
1909                                 case TYPE_LNG:
1910                                 case TYPE_ADR:
1911                                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1912                                         var_to_reg_int(s2, src, REG_ITMP2);
1913                                         gen_nullptr_check(s1);
1914                                         M_LST(s2, s1, a);
1915                                         break;
1916                                 case TYPE_FLT:
1917                                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1918                                         var_to_reg_flt(s2, src, REG_FTMP2);
1919                                         gen_nullptr_check(s1);
1920                                         M_FST(s2, s1, a);
1921                                         break;
1922                                 case TYPE_DBL:
1923                                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1924                                         var_to_reg_flt(s2, src, REG_FTMP2);
1925                                         gen_nullptr_check(s1);
1926                                         M_DST(s2, s1, a);
1927                                         break;
1928                                 default: panic ("internal error");
1929                                 }
1930                         break;
1931
1932                 case ICMD_GETFIELD:
1933                         a = ((fieldinfo *)(iptr->val.a))->offset;
1934                         switch (iptr->op1) {
1935                                 case TYPE_INT:
1936                                         var_to_reg_int(s1, src, REG_ITMP1);
1937                                         d = reg_of_var(iptr->dst, REG_ITMP3);
1938                                         gen_nullptr_check(s1);
1939                                         M_ILD(d, s1, a);
1940                                         store_reg_to_var_int(iptr->dst, d);
1941                                         break;
1942                                 case TYPE_LNG:
1943                                 case TYPE_ADR:
1944                                         var_to_reg_int(s1, src, REG_ITMP1);
1945                                         d = reg_of_var(iptr->dst, REG_ITMP3);
1946                                         gen_nullptr_check(s1);
1947                                         M_LLD(d, s1, a);
1948                                         store_reg_to_var_int(iptr->dst, d);
1949                                         break;
1950                                 case TYPE_FLT:
1951                                         var_to_reg_int(s1, src, REG_ITMP1);
1952                                         d = reg_of_var(iptr->dst, REG_FTMP1);
1953                                         gen_nullptr_check(s1);
1954                                         M_FLD(d, s1, a);
1955                                         store_reg_to_var_flt(iptr->dst, d);
1956                                         break;
1957                                 case TYPE_DBL:                          
1958                                         var_to_reg_int(s1, src, REG_ITMP1);
1959                                         d = reg_of_var(iptr->dst, REG_FTMP1);
1960                                         gen_nullptr_check(s1);
1961                                         M_DLD(d, s1, a);
1962                                         store_reg_to_var_flt(iptr->dst, d);
1963                                         break;
1964                                 default: panic ("internal error");
1965                                 }
1966                         break;
1967
1968
1969                 /* branch operations **************************************************/
1970
1971 #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}}
1972
1973                 case ICMD_ATHROW:
1974                         var_to_reg_int(s1, src, REG_ITMP1);
1975                         M_INTMOVE(s1, REG_ITMP1_XPTR);
1976                         a = dseg_addaddress(asm_handle_exception);
1977                         M_LLD(REG_ITMP2, REG_PV, a);
1978                         M_JMP(REG_ITMP2_XPC, REG_ITMP2);
1979                         ALIGNCODENOP;
1980                         break;
1981
1982                 case ICMD_GOTO:
1983                         M_BR(0);
1984                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
1985                         ALIGNCODENOP;
1986                         break;
1987
1988                 case ICMD_JSR:
1989                         M_BSR(REG_ITMP1, 0);
1990                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
1991                         break;
1992                         
1993                 case ICMD_RET:
1994                         var = &(locals[iptr->op1][TYPE_ADR]);
1995                         if (var->flags & INMEMORY) {
1996                                 M_LLD(REG_ITMP1, REG_SP, 8 * var->regoff);
1997                                 M_RET(REG_ZERO, REG_ITMP1);
1998                                 }
1999                         else
2000                                 M_RET(REG_ZERO, var->regoff);
2001                         ALIGNCODENOP;
2002                         break;
2003
2004                 case ICMD_IFNULL:
2005                         var_to_reg_int(s1, src, REG_ITMP1);
2006                         M_BEQZ(s1, 0);
2007                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2008                         break;
2009                 case ICMD_IFNONNULL:
2010                         var_to_reg_int(s1, src, REG_ITMP1);
2011                         M_BNEZ(s1, 0);
2012                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2013                         break;
2014
2015                 case ICMD_IFEQ:
2016                         var_to_reg_int(s1, src, REG_ITMP1);
2017                         if (iptr->val.i == 0) {
2018                                 M_BEQZ(s1, 0);
2019                                 }
2020                         else {
2021                                 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2022                                         M_CMPEQ(s1, iptr->val.i, REG_ITMP1, 1);
2023                                         }
2024                                 else {
2025                                         ICONST(REG_ITMP2, iptr->val.i);
2026                                         M_CMPEQ(s1, REG_ITMP2, REG_ITMP1, 0);
2027                                         }
2028                                 M_BNEZ(REG_ITMP1, 0);
2029                                 }
2030                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2031                         break;
2032                 case ICMD_IFLT:
2033                         var_to_reg_int(s1, src, REG_ITMP1);
2034                         if (iptr->val.i == 0) {
2035                                 M_BLTZ(s1, 0);
2036                                 }
2037                         else {
2038                                 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2039                                         M_CMPLT(s1, iptr->val.i, REG_ITMP1, 1);
2040                                         }
2041                                 else {
2042                                         ICONST(REG_ITMP2, iptr->val.i);
2043                                         M_CMPLT(s1, REG_ITMP2, REG_ITMP1, 0);
2044                                         }
2045                                 M_BNEZ(REG_ITMP1, 0);
2046                                 }
2047                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2048                         break;
2049                 case ICMD_IFLE:
2050                         var_to_reg_int(s1, src, REG_ITMP1);
2051                         if (iptr->val.i == 0) {
2052                                 M_BLEZ(s1, 0);
2053                                 }
2054                         else {
2055                                 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2056                                         M_CMPLE(s1, iptr->val.i, REG_ITMP1, 1);
2057                                         }
2058                                 else {
2059                                         ICONST(REG_ITMP2, iptr->val.i);
2060                                         M_CMPLE(s1, REG_ITMP2, REG_ITMP1, 0);
2061                                         }
2062                                 M_BNEZ(REG_ITMP1, 0);
2063                                 }
2064                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2065                         break;
2066                 case ICMD_IFNE:
2067                         var_to_reg_int(s1, src, REG_ITMP1);
2068                         if (iptr->val.i == 0) {
2069                                 M_BNEZ(s1, 0);
2070                                 }
2071                         else {
2072                                 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2073                                         M_CMPEQ(s1, iptr->val.i, REG_ITMP1, 1);
2074                                         }
2075                                 else {
2076                                         ICONST(REG_ITMP2, iptr->val.i);
2077                                         M_CMPEQ(s1, REG_ITMP2, REG_ITMP1, 0);
2078                                         }
2079                                 M_BEQZ(REG_ITMP1, 0);
2080                                 }
2081                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2082                         break;
2083                 case ICMD_IFGT:
2084                         var_to_reg_int(s1, src, REG_ITMP1);
2085                         if (iptr->val.i == 0) {
2086                                 M_BGTZ(s1, 0);
2087                                 }
2088                         else {
2089                                 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2090                                         M_CMPLE(s1, iptr->val.i, REG_ITMP1, 1);
2091                                         }
2092                                 else {
2093                                         ICONST(REG_ITMP2, iptr->val.i);
2094                                         M_CMPLE(s1, REG_ITMP2, REG_ITMP1, 0);
2095                                         }
2096                                 M_BEQZ(REG_ITMP1, 0);
2097                                 }
2098                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2099                         break;
2100                 case ICMD_IFGE:
2101                         var_to_reg_int(s1, src, REG_ITMP1);
2102                         if (iptr->val.i == 0) {
2103                                 M_BGEZ(s1, 0);
2104                                 }
2105                         else {
2106                                 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2107                                         M_CMPLT(s1, iptr->val.i, REG_ITMP1, 1);
2108                                         }
2109                                 else {
2110                                         ICONST(REG_ITMP2, iptr->val.i);
2111                                         M_CMPLT(s1, REG_ITMP2, REG_ITMP1, 0);
2112                                         }
2113                                 M_BEQZ(REG_ITMP1, 0);
2114                                 }
2115                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2116                         break;
2117
2118                 case ICMD_IF_LEQ:
2119                         var_to_reg_int(s1, src, REG_ITMP1);
2120                         if (iptr->val.l == 0) {
2121                                 M_BEQZ(s1, 0);
2122                                 }
2123                         else {
2124                                 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2125                                         M_CMPEQ(s1, iptr->val.l, REG_ITMP1, 1);
2126                                         }
2127                                 else {
2128                                         LCONST(REG_ITMP2, iptr->val.l);
2129                                         M_CMPEQ(s1, REG_ITMP2, REG_ITMP1, 0);
2130                                         }
2131                                 M_BNEZ(REG_ITMP1, 0);
2132                                 }
2133                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2134                         break;
2135                 case ICMD_IF_LLT:
2136                         var_to_reg_int(s1, src, REG_ITMP1);
2137                         if (iptr->val.l == 0) {
2138                                 M_BLTZ(s1, 0);
2139                                 }
2140                         else {
2141                                 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2142                                         M_CMPLT(s1, iptr->val.l, REG_ITMP1, 1);
2143                                         }
2144                                 else {
2145                                         LCONST(REG_ITMP2, iptr->val.l);
2146                                         M_CMPLT(s1, REG_ITMP2, REG_ITMP1, 0);
2147                                         }
2148                                 M_BNEZ(REG_ITMP1, 0);
2149                                 }
2150                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2151                         break;
2152                 case ICMD_IF_LLE:
2153                         var_to_reg_int(s1, src, REG_ITMP1);
2154                         if (iptr->val.l == 0) {
2155                                 M_BLEZ(s1, 0);
2156                                 }
2157                         else {
2158                                 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2159                                         M_CMPLE(s1, iptr->val.l, REG_ITMP1, 1);
2160                                         }
2161                                 else {
2162                                         LCONST(REG_ITMP2, iptr->val.l);
2163                                         M_CMPLE(s1, REG_ITMP2, REG_ITMP1, 0);
2164                                         }
2165                                 M_BNEZ(REG_ITMP1, 0);
2166                                 }
2167                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2168                         break;
2169                 case ICMD_IF_LNE:
2170                         var_to_reg_int(s1, src, REG_ITMP1);
2171                         if (iptr->val.l == 0) {
2172                                 M_BNEZ(s1, 0);
2173                                 }
2174                         else {
2175                                 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2176                                         M_CMPEQ(s1, iptr->val.l, REG_ITMP1, 1);
2177                                         }
2178                                 else {
2179                                         LCONST(REG_ITMP2, iptr->val.l);
2180                                         M_CMPEQ(s1, REG_ITMP2, REG_ITMP1, 0);
2181                                         }
2182                                 M_BEQZ(REG_ITMP1, 0);
2183                                 }
2184                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2185                         break;
2186                 case ICMD_IF_LGT:
2187                         var_to_reg_int(s1, src, REG_ITMP1);
2188                         if (iptr->val.l == 0) {
2189                                 M_BGTZ(s1, 0);
2190                                 }
2191                         else {
2192                                 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2193                                         M_CMPLE(s1, iptr->val.l, REG_ITMP1, 1);
2194                                         }
2195                                 else {
2196                                         LCONST(REG_ITMP2, iptr->val.l);
2197                                         M_CMPLE(s1, REG_ITMP2, REG_ITMP1, 0);
2198                                         }
2199                                 M_BEQZ(REG_ITMP1, 0);
2200                                 }
2201                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2202                         break;
2203                 case ICMD_IF_LGE:
2204                         var_to_reg_int(s1, src, REG_ITMP1);
2205                         if (iptr->val.l == 0) {
2206                                 M_BGEZ(s1, 0);
2207                                 }
2208                         else {
2209                                 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2210                                         M_CMPLT(s1, iptr->val.l, REG_ITMP1, 1);
2211                                         }
2212                                 else {
2213                                         LCONST(REG_ITMP2, iptr->val.l);
2214                                         M_CMPLT(s1, REG_ITMP2, REG_ITMP1, 0);
2215                                         }
2216                                 M_BEQZ(REG_ITMP1, 0);
2217                                 }
2218                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2219                         break;
2220
2221                 case ICMD_IF_ICMPEQ:
2222                 case ICMD_IF_LCMPEQ:
2223                 case ICMD_IF_ACMPEQ:
2224                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2225                         var_to_reg_int(s2, src, REG_ITMP2);
2226                         M_CMPEQ(s1, s2, REG_ITMP1, 0);
2227                         M_BNEZ(REG_ITMP1, 0);
2228                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2229                         break;
2230                 case ICMD_IF_ICMPNE:
2231                 case ICMD_IF_LCMPNE:
2232                 case ICMD_IF_ACMPNE:
2233                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2234                         var_to_reg_int(s2, src, REG_ITMP2);
2235                         M_CMPEQ(s1, s2, REG_ITMP1, 0);
2236                         M_BEQZ(REG_ITMP1, 0);
2237                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2238                         break;
2239                 case ICMD_IF_ICMPLT:
2240                 case ICMD_IF_LCMPLT:
2241                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2242                         var_to_reg_int(s2, src, REG_ITMP2);
2243                         M_CMPLT(s1, s2, REG_ITMP1, 0);
2244                         M_BNEZ(REG_ITMP1, 0);
2245                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2246                         break;
2247                 case ICMD_IF_ICMPGT:
2248                 case ICMD_IF_LCMPGT:
2249                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2250                         var_to_reg_int(s2, src, REG_ITMP2);
2251                         M_CMPLE(s1, s2, REG_ITMP1, 0);
2252                         M_BEQZ(REG_ITMP1, 0);
2253                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2254                         break;
2255                 case ICMD_IF_ICMPLE:
2256                 case ICMD_IF_LCMPLE:
2257                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2258                         var_to_reg_int(s2, src, REG_ITMP2);
2259                         M_CMPLE(s1, s2, REG_ITMP1, 0);
2260                         M_BNEZ(REG_ITMP1, 0);
2261                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2262                         break;
2263                 case ICMD_IF_ICMPGE:
2264                 case ICMD_IF_LCMPGE:
2265                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2266                         var_to_reg_int(s2, src, REG_ITMP2);
2267                         M_CMPLT(s1, s2, REG_ITMP1,  0);
2268                         M_BEQZ(REG_ITMP1, 0);
2269                         mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2270                         break;
2271
2272                 case ICMD_ELSE_ICONST:
2273                         break;
2274                 case ICMD_IFEQ_ICONST:
2275                         var_to_reg_int(s1, src, REG_ITMP1);
2276                         d = reg_of_var(iptr->dst, REG_ITMP3);
2277                         a = iptr->val.i;
2278                         if (iptr[1].opc == ICMD_ELSE_ICONST) {
2279                                 if ((a == 1) && (iptr[1].val.i == 0)) {
2280                                         M_CMPEQ(s1, REG_ZERO, d,  0);
2281                                         store_reg_to_var_int(iptr->dst, d);
2282                                         break;
2283                                         }
2284                                 if ((a == 0) && (iptr[1].val.i == 1)) {
2285                                         M_CMPEQ(s1, REG_ZERO, d,  0);
2286                                         M_XOR(d, 1, d, 1);
2287                                         store_reg_to_var_int(iptr->dst, d);
2288                                         break;
2289                                         }
2290                                 if (s1 == d) {
2291                                         M_OR(s1, s1 , REG_ITMP1, 0);
2292                                         s1 = REG_ITMP1;
2293                                         }
2294                                 ICONST(d, iptr[1].val.i);
2295                                 }
2296                         if ((a >= 0) && (a <= 255)) {
2297                                 M_CMOVEQ(s1, a, d, 1);
2298                                 }
2299                         else {
2300                                 ICONST(REG_ITMP2, a);
2301                                 M_CMOVEQ(s1, REG_ITMP2, d, 0);
2302                                 }
2303                         store_reg_to_var_int(iptr->dst, d);
2304                         break;
2305                 case ICMD_IFNE_ICONST:
2306                         var_to_reg_int(s1, src, REG_ITMP1);
2307                         d = reg_of_var(iptr->dst, REG_ITMP3);
2308                         a = iptr->val.i;
2309                         if (iptr[1].opc == ICMD_ELSE_ICONST) {
2310                                 if ((a == 0) && (iptr[1].val.i == 1)) {
2311                                         M_CMPEQ(s1, REG_ZERO, d,  0);
2312                                         store_reg_to_var_int(iptr->dst, d);
2313                                         break;
2314                                         }
2315                                 if ((a == 1) && (iptr[1].val.i == 0)) {
2316                                         M_CMPEQ(s1, REG_ZERO, d,  0);
2317                                         M_XOR(d, 1, d, 1);
2318                                         store_reg_to_var_int(iptr->dst, d);
2319                                         break;
2320                                         }
2321                                 if (s1 == d) {
2322                                         M_OR(s1, s1 , REG_ITMP1, 0);
2323                                         s1 = REG_ITMP1;
2324                                         }
2325                                 ICONST(d, iptr[1].val.i);
2326                                 }
2327                         if ((a >= 0) && (a <= 255)) {
2328                                 M_CMOVNE(s1, a, d, 1);
2329                                 }
2330                         else {
2331                                 ICONST(REG_ITMP2, a);
2332                                 M_CMOVNE(s1, REG_ITMP2, d, 0);
2333                                 }
2334                         store_reg_to_var_int(iptr->dst, d);
2335                         break;
2336                 case ICMD_IFLT_ICONST:
2337                         var_to_reg_int(s1, src, REG_ITMP1);
2338                         d = reg_of_var(iptr->dst, REG_ITMP3);
2339                         a = iptr->val.i;
2340                         if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2341                                 if ((a == 1) && (iptr[1].val.i == 0)) {
2342                                         M_CMPLT(s1, REG_ZERO, d,  0);
2343                                         store_reg_to_var_int(iptr->dst, d);
2344                                         break;
2345                                         }
2346                                 if ((a == 0) && (iptr[1].val.i == 1)) {
2347                                         M_CMPLE(REG_ZERO, s1, d,  0);
2348                                         store_reg_to_var_int(iptr->dst, d);
2349                                         break;
2350                                         }
2351                                 if (s1 == d) {
2352                                         M_OR(s1, s1 , REG_ITMP1, 0);
2353                                         s1 = REG_ITMP1;
2354                                         }
2355                                 ICONST(d, iptr[1].val.i);
2356                                 }
2357                         if ((a >= 0) && (a <= 255)) {
2358                                 M_CMOVLT(s1, a, d, 1);
2359                                 }
2360                         else {
2361                                 ICONST(REG_ITMP2, a);
2362                                 M_CMOVLT(s1, REG_ITMP2, d, 0);
2363                                 }
2364                         store_reg_to_var_int(iptr->dst, d);
2365                         break;
2366                 case ICMD_IFGE_ICONST:
2367                         var_to_reg_int(s1, src, REG_ITMP1);
2368                         d = reg_of_var(iptr->dst, REG_ITMP3);
2369                         a = iptr->val.i;
2370                         if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2371                                 if ((a == 1) && (iptr[1].val.i == 0)) {
2372                                         M_CMPLE(REG_ZERO, s1, d,  0);
2373                                         store_reg_to_var_int(iptr->dst, d);
2374                                         break;
2375                                         }
2376                                 if ((a == 0) && (iptr[1].val.i == 1)) {
2377                                         M_CMPLT(s1, REG_ZERO, d,  0);
2378                                         store_reg_to_var_int(iptr->dst, d);
2379                                         break;
2380                                         }
2381                                 if (s1 == d) {
2382                                         M_OR(s1, s1 , REG_ITMP1, 0);
2383                                         s1 = REG_ITMP1;
2384                                         }
2385                                 ICONST(d, iptr[1].val.i);
2386                                 }
2387                         if ((a >= 0) && (a <= 255)) {
2388                                 M_CMOVGE(s1, a, d, 1);
2389                                 }
2390                         else {
2391                                 ICONST(REG_ITMP2, a);
2392                                 M_CMOVGE(s1, REG_ITMP2, d, 0);
2393                                 }
2394                         store_reg_to_var_int(iptr->dst, d);
2395                         break;
2396                 case ICMD_IFGT_ICONST:
2397                         var_to_reg_int(s1, src, REG_ITMP1);
2398                         d = reg_of_var(iptr->dst, REG_ITMP3);
2399                         a = iptr->val.i;
2400                         if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2401                                 if ((a == 1) && (iptr[1].val.i == 0)) {
2402                                         M_CMPLT(REG_ZERO, s1, d,  0);
2403                                         store_reg_to_var_int(iptr->dst, d);
2404                                         break;
2405                                         }
2406                                 if ((a == 0) && (iptr[1].val.i == 1)) {
2407                                         M_CMPLE(s1, REG_ZERO, d,  0);
2408                                         store_reg_to_var_int(iptr->dst, d);
2409                                         break;
2410                                         }
2411                                 if (s1 == d) {
2412                                         M_OR(s1, s1 , REG_ITMP1, 0);
2413                                         s1 = REG_ITMP1;
2414                                         }
2415                                 ICONST(d, iptr[1].val.i);
2416                                 }
2417                         if ((a >= 0) && (a <= 255)) {
2418                                 M_CMOVGT(s1, a, d, 1);
2419                                 }
2420                         else {
2421                                 ICONST(REG_ITMP2, a);
2422                                 M_CMOVGT(s1, REG_ITMP2, d, 0);
2423                                 }
2424                         store_reg_to_var_int(iptr->dst, d);
2425                         break;
2426                 case ICMD_IFLE_ICONST:
2427                         var_to_reg_int(s1, src, REG_ITMP1);
2428                         d = reg_of_var(iptr->dst, REG_ITMP3);
2429                         a = iptr->val.i;
2430                         if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2431                                 if ((a == 1) && (iptr[1].val.i == 0)) {
2432                                         M_CMPLE(s1, REG_ZERO, d,  0);
2433                                         store_reg_to_var_int(iptr->dst, d);
2434                                         break;
2435                                         }
2436                                 if ((a == 0) && (iptr[1].val.i == 1)) {
2437                                         M_CMPLT(REG_ZERO, s1, d,  0);
2438                                         store_reg_to_var_int(iptr->dst, d);
2439                                         break;
2440                                         }
2441                                 if (s1 == d) {
2442                                         M_OR(s1, s1 , REG_ITMP1, 0);
2443                                         s1 = REG_ITMP1;
2444                                         }
2445                                 ICONST(d, iptr[1].val.i);
2446                                 }
2447                         if ((a >= 0) && (a <= 255)) {
2448                                 M_CMOVLE(s1, a, d, 1);
2449                                 }
2450                         else {
2451                                 ICONST(REG_ITMP2, a);
2452                                 M_CMOVLE(s1, REG_ITMP2, d, 0);
2453                                 }
2454                         store_reg_to_var_int(iptr->dst, d);
2455                         break;
2456
2457
2458                 case ICMD_IRETURN:
2459                 case ICMD_LRETURN:
2460                 case ICMD_ARETURN:
2461
2462 #ifdef USE_THREADS
2463                         if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2464                                 a = dseg_addaddress ((void*) (builtin_monitorexit));
2465                                 M_LLD(REG_PV, REG_PV, a);
2466                                 M_LLD(argintregs[0], REG_SP, 8 * maxmemuse);
2467                                 M_JSR(REG_RA, REG_PV);
2468                                 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2469                                 }                       
2470 #endif
2471                         var_to_reg_int(s1, src, REG_RESULT);
2472                         M_INTMOVE(s1, REG_RESULT);
2473                         goto nowperformreturn;
2474
2475                 case ICMD_FRETURN:
2476                 case ICMD_DRETURN:
2477
2478 #ifdef USE_THREADS
2479                         if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2480                                 a = dseg_addaddress ((void*) (builtin_monitorexit));
2481                                 M_LLD(REG_PV, REG_PV, a);
2482                                 M_LLD(argintregs[0], REG_SP, 8 * maxmemuse);
2483                                 M_JSR(REG_RA, REG_PV);
2484                                 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2485                                 }                       
2486 #endif
2487                         var_to_reg_flt(s1, src, REG_FRESULT);
2488                         M_FLTMOVE(s1, REG_FRESULT);
2489                         goto nowperformreturn;
2490
2491                 case ICMD_RETURN:
2492
2493 #ifdef USE_THREADS
2494                         if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2495                                 a = dseg_addaddress ((void*) (builtin_monitorexit));
2496                                 M_LLD(REG_PV, REG_PV, a);
2497                                 M_LLD(argintregs[0], REG_SP, 8 * maxmemuse);
2498                                 M_JSR(REG_RA, REG_PV);
2499                                 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
2500                                 }                       
2501 #endif
2502
2503 nowperformreturn:
2504                         {
2505                         int r, p;
2506                         
2507                         p = parentargs_base;
2508                         if (!isleafmethod)
2509                                 {p--;  M_LLD (REG_RA, REG_SP, 8 * p);}
2510                         for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
2511                                         {p--; M_LLD(savintregs[r], REG_SP, 8 * p);}
2512                         for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
2513                                         {p--; M_DLD(savfltregs[r], REG_SP, 8 * p);}
2514
2515                         if (parentargs_base)
2516                                 {M_LDA(REG_SP, REG_SP, parentargs_base*8);}
2517                         if (runverbose) {
2518                                 M_LDA (REG_SP, REG_SP, -24);
2519                                 M_LST(REG_RA, REG_SP, 0);
2520                                 M_LST(REG_RESULT, REG_SP, 8);
2521                                 M_DST(REG_FRESULT, REG_SP,16);
2522                                 a = dseg_addaddress (method);
2523                                 M_LLD(argintregs[0], REG_PV, a);
2524                                 M_OR(REG_RESULT, REG_RESULT, argintregs[1], 0);
2525                                 M_FLTMOVE(REG_FRESULT, argfltregs[2]);
2526                                 a = dseg_addaddress ((void*) (builtin_displaymethodstop));
2527                                 M_LLD(REG_PV, REG_PV, a);
2528                                 M_JSR (REG_RA, REG_PV);
2529                                 s1 = (int)((u1*) mcodeptr - mcodebase);
2530                                 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
2531                                 else {
2532                                         s4 ml=-s1, mh=0;
2533                                         while (ml<-32768) { ml+=65536; mh--; }
2534                                         M_LDA (REG_PV, REG_RA, ml );
2535                                         M_LDAH (REG_PV, REG_PV, mh );
2536                                         }
2537                                 M_DLD(REG_FRESULT, REG_SP,16);
2538                                 M_LLD(REG_RESULT, REG_SP, 8);
2539                                 M_LLD(REG_RA, REG_SP, 0);
2540                                 M_LDA (REG_SP, REG_SP, 24);
2541                                 }
2542                         M_RET(REG_ZERO, REG_RA);
2543                         ALIGNCODENOP;
2544                         }
2545                         break;
2546
2547
2548                 case ICMD_TABLESWITCH:
2549                         {
2550                         s4 i, l, *s4ptr;
2551
2552                         s4ptr = iptr->val.a;
2553                         l = s4ptr[1];                          /* low     */
2554                         i = s4ptr[2];                          /* high    */
2555                         
2556                         var_to_reg_int(s1, src, REG_ITMP1);
2557                         if (l == 0)
2558                                 {M_INTMOVE(s1, REG_ITMP1);}
2559                         else
2560                                 M_LDA(REG_ITMP1, s1, -l);
2561                         i = i - l + 1;
2562
2563                         if (i <= 256)
2564                                 M_CMPULE(REG_ITMP1, i - 1, REG_ITMP2, 1);
2565                         else {
2566                                 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
2567                                 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2, 0);
2568                                 }
2569                         M_BEQZ(REG_ITMP2, 0);
2570                         mcode_addreference(BlockPtrOfPC(s4ptr[0]), mcodeptr);
2571
2572                         /* build jump table top down and use address of lowest entry */
2573
2574                         s4ptr += 3 + i;
2575                         while (--i >= 0) {
2576                                 dseg_addtarget(BlockPtrOfPC(*--s4ptr));
2577                                 }
2578                         }
2579
2580                         /* length of dataseg after last dseg_addtarget is used by load */
2581
2582                         M_S8ADDQ(REG_ITMP1, REG_PV, REG_ITMP2, 0);
2583                         M_LLD(REG_ITMP2, REG_ITMP2, -dseglen);
2584                         M_JMP(REG_ZERO, REG_ITMP2);
2585                         ALIGNCODENOP;
2586                         break;
2587
2588
2589                 case ICMD_LOOKUPSWITCH:
2590                         {
2591                         s4 i, l, val, *s4ptr;
2592
2593                         s4ptr = iptr->val.a;
2594                         l = s4ptr[0];                          /* default  */
2595                         i = s4ptr[1];                          /* count    */
2596                         
2597                         MCODECHECK((i<<2)+8);
2598                         var_to_reg_int(s1, src, REG_ITMP1);
2599                         while (--i >= 0) {
2600                                 s4ptr += 2;
2601                                 val = s4ptr[0];
2602                                 if ((val >= 0) && (val <= 255)) {
2603                                         M_CMPEQ(s1, val, REG_ITMP2, 1);
2604                                         }
2605                                 else {
2606                                         if ((val >= -32768) && (val <= 32767)) {
2607                                                 M_LDA(REG_ITMP2, REG_ZERO, val);
2608                                                 } 
2609                                         else {
2610                                                 a = dseg_adds4 (val);
2611                                                 M_ILD(REG_ITMP2, REG_PV, a);
2612                                                 }
2613                                         M_CMPEQ(s1, REG_ITMP2, REG_ITMP2, 0);
2614                                         }
2615                                 M_BNEZ(REG_ITMP2, 0);
2616                                 mcode_addreference(BlockPtrOfPC(s4ptr[1]), mcodeptr);
2617                                 }
2618
2619                         M_BR(0);
2620                         mcode_addreference(BlockPtrOfPC(l), mcodeptr);
2621                         ALIGNCODENOP;
2622                         break;
2623                         }
2624
2625
2626                 case ICMD_BUILTIN3:
2627                         s3 = 3;
2628                         goto gen_method;
2629
2630                 case ICMD_BUILTIN2:
2631                         s3 = 2;
2632                         goto gen_method;
2633
2634                 case ICMD_BUILTIN1:
2635                         s3 = 1;
2636                         goto gen_method;
2637
2638                 case ICMD_INVOKESTATIC:
2639                 case ICMD_INVOKESPECIAL:
2640                 case ICMD_INVOKEVIRTUAL:
2641                 case ICMD_INVOKEINTERFACE:
2642                         s3 = iptr->op1;
2643
2644 gen_method: {
2645                         methodinfo   *m;
2646                         classinfo    *ci;
2647
2648                         MCODECHECK((s3 << 1) + 64);
2649
2650                         for (; --s3 >= 0; src = src->prev) {
2651                                 if (src->varkind == ARGVAR)
2652                                         continue;
2653                                 if (IS_INT_LNG_TYPE(src->type)) {
2654                                         if (s3 < INT_ARG_CNT) {
2655                                                 s1 = argintregs[s3];
2656                                                 var_to_reg_int(d, src, s1);
2657                                                 M_INTMOVE(d, s1);
2658                                                 }
2659                                         else  {
2660                                                 var_to_reg_int(d, src, REG_ITMP1);
2661                                                 M_LST(d, REG_SP, 8 * (s3 - INT_ARG_CNT));
2662                                                 }
2663                                         }
2664                                 else
2665                                         if (s3 < FLT_ARG_CNT) {
2666                                                 s1 = argfltregs[s3];
2667                                                 var_to_reg_flt(d, src, s1);
2668                                                 M_FLTMOVE(d, s1);
2669                                                 }
2670                                         else {
2671                                                 var_to_reg_flt(d, src, REG_FTMP1);
2672                                                 M_DST(d, REG_SP, 8 * (s3 - FLT_ARG_CNT));
2673                                                 }
2674                                 } /* end of for */
2675
2676                         m = iptr->val.a;
2677                         switch (iptr->opc) {
2678                                 case ICMD_BUILTIN3:
2679                                 case ICMD_BUILTIN2:
2680                                 case ICMD_BUILTIN1:
2681                                         a = dseg_addaddress ((void*) (m));
2682
2683                                         M_LLD(REG_PV, REG_PV, a); /* Pointer to built-in-function */
2684                                         d = iptr->op1;
2685                                         goto makeactualcall;
2686
2687                                 case ICMD_INVOKESTATIC:
2688                                 case ICMD_INVOKESPECIAL:
2689                                         a = dseg_addaddress (m->stubroutine);
2690
2691                                         M_LLD(REG_PV, REG_PV, a );       /* Method-Pointer in r27 */
2692
2693                                         d = m->returntype;
2694                                         goto makeactualcall;
2695
2696                                 case ICMD_INVOKEVIRTUAL:
2697
2698                                         gen_nullptr_check(argintregs[0]);
2699                                         M_LLD(REG_METHODPTR, argintregs[0],
2700                                                                  OFFSET(java_objectheader, vftbl));
2701                                         M_LLD(REG_PV, REG_METHODPTR, OFFSET(vftbl, table[0]) +
2702                                                                 sizeof(methodptr) * m->vftblindex);
2703
2704                                         d = m->returntype;
2705                                         goto makeactualcall;
2706
2707                                 case ICMD_INVOKEINTERFACE:
2708                                         ci = m->class;
2709                                         
2710                                         gen_nullptr_check(argintregs[0]);
2711                                         M_LLD(REG_METHODPTR, argintregs[0],
2712                                                                  OFFSET(java_objectheader, vftbl));    
2713                                         M_LLD(REG_METHODPTR, REG_METHODPTR,
2714                                               OFFSET(vftbl, interfacetable[0]) -
2715                                               sizeof(methodptr*) * ci->index);
2716                                         M_LLD(REG_PV, REG_METHODPTR,
2717                                                             sizeof(methodptr) * (m - ci->methods));
2718
2719                                         d = m->returntype;
2720                                         goto makeactualcall;
2721
2722                                 default:
2723                                         d = 0;
2724                                         sprintf (logtext, "Unkown ICMD-Command: %d", iptr->opc);
2725                                         error ();
2726                                 }
2727
2728 makeactualcall:
2729
2730                         M_JSR (REG_RA, REG_PV);
2731                         s1 = (int)((u1*) mcodeptr - mcodebase);
2732                         if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
2733                         else {
2734                                 s4 ml=-s1, mh=0;
2735                                 while (ml<-32768) { ml+=65536; mh--; }
2736                                 M_LDA (REG_PV, REG_RA, ml );
2737                                 M_LDAH (REG_PV, REG_PV, mh );
2738                                 }
2739
2740                         if (d != TYPE_VOID) {
2741                                 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
2742                                         s1 = reg_of_var(iptr->dst, REG_RESULT);
2743                                         M_INTMOVE(REG_RESULT, s1);
2744                                         store_reg_to_var_int(iptr->dst, s1);
2745                                         }
2746                                 else {
2747                                         s1 = reg_of_var(iptr->dst, REG_FRESULT);
2748                                         M_FLTMOVE(REG_FRESULT, s1);
2749                                         store_reg_to_var_flt(iptr->dst, s1);
2750                                         }
2751                                 }
2752                         }
2753                         break;
2754
2755
2756                 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
2757
2758                                       /* op1:   0 == array, 1 == class                */
2759                                       /* val.a: (classinfo*) superclass               */
2760
2761 /*          superclass is an interface:
2762  *
2763  *          return (sub != NULL) &&
2764  *                 (sub->vftbl->interfacetablelength > super->index) &&
2765  *                 (sub->vftbl->interfacetable[-super->index] != NULL);
2766  *
2767  *          superclass is a class:
2768  *
2769  *          return ((sub != NULL) && (0
2770  *                  <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2771  *                  super->vftbl->diffvall));
2772  */
2773
2774                         {
2775                         classinfo *super = (classinfo*) iptr->val.a;
2776                         
2777                         var_to_reg_int(s1, src, REG_ITMP1);
2778                         d = reg_of_var(iptr->dst, REG_ITMP3);
2779                         if (s1 == d) {
2780                                 M_MOV(s1, REG_ITMP1);
2781                                 s1 = REG_ITMP1;
2782                                 }
2783                         M_CLR(d);
2784                         if (iptr->op1) {                               /* class/interface */
2785                                 if (super->flags & ACC_INTERFACE) {        /* interface       */
2786                                         M_BEQZ(s1, 6);
2787                                         M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2788                                         M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
2789                                         M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
2790                                         M_BLEZ(REG_ITMP2, 2);
2791                                         M_ALD(REG_ITMP1, REG_ITMP1,
2792                                               OFFSET(vftbl, interfacetable[0]) -
2793                                               super->index * sizeof(methodptr*));
2794                                         M_CMPULT(REG_ZERO, REG_ITMP1, d, 0);   /* REG_ITMP1 != 0  */
2795                                         }
2796                                 else {                                     /* class           */
2797                                         s2 = super->vftbl->diffval;
2798                                         M_BEQZ(s1, 4 + (s2 > 255));
2799                                         M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2800                                         M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
2801                                         M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
2802                                         if (s2 <= 255)
2803                                                 M_CMPULE(REG_ITMP1, s2, d, 1);
2804                                         else {
2805                                                 M_LDA(REG_ITMP2, REG_ZERO, s2);
2806                                                 M_CMPULE(REG_ITMP1, REG_ITMP2, d, 0);
2807                                                 }
2808                                         }
2809                                 }
2810                         else
2811                                 panic ("internal error: no inlined array instanceof");
2812                         }
2813                         store_reg_to_var_int(iptr->dst, d);
2814                         break;
2815
2816                 case ICMD_CHECKCAST:  /* ..., objectref ==> ..., objectref            */
2817
2818                                       /* op1:   0 == array, 1 == class                */
2819                                       /* val.a: (classinfo*) superclass               */
2820
2821 /*          superclass is an interface:
2822  *
2823  *          OK if ((sub == NULL) ||
2824  *                 (sub->vftbl->interfacetablelength > super->index) &&
2825  *                 (sub->vftbl->interfacetable[-super->index] != NULL));
2826  *
2827  *          superclass is a class:
2828  *
2829  *          OK if ((sub == NULL) || (0
2830  *                 <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2831  *                 super->vftbl->diffvall));
2832  */
2833
2834                         {
2835                         classinfo *super = (classinfo*) iptr->val.a;
2836                         
2837                         d = reg_of_var(iptr->dst, REG_ITMP3);
2838                         var_to_reg_int(s1, src, d);
2839                         if (iptr->op1) {                               /* class/interface */
2840                                 if (super->flags & ACC_INTERFACE) {        /* interface       */
2841                                         M_BEQZ(s1, 6);
2842                                         M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2843                                         M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
2844                                         M_LDA(REG_ITMP2, REG_ITMP2, - super->index);
2845                                         M_BLEZ(REG_ITMP2, 0);
2846                                         mcode_addxcastrefs(mcodeptr);
2847                                         M_ALD(REG_ITMP2, REG_ITMP1,
2848                                               OFFSET(vftbl, interfacetable[0]) -
2849                                               super->index * sizeof(methodptr*));
2850                                         M_BEQZ(REG_ITMP2, 0);
2851                                         mcode_addxcastrefs(mcodeptr);
2852                                         }
2853                                 else {                                     /* class           */
2854                                         s2 = super->vftbl->diffval;
2855                                         M_BEQZ(s1, 4 + (s2 != 0) + (s2 > 255));
2856                                         M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2857                                         M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
2858                                         M_LDA(REG_ITMP1, REG_ITMP1, - super->vftbl->baseval);
2859                                         if (s2 == 0) {
2860                                                 M_BNEZ(REG_ITMP1, 0);
2861                                                 }
2862                                         else if (s2 <= 255) {
2863                                                 M_CMPULE(REG_ITMP1, s2, REG_ITMP2, 1);
2864                                                 M_BEQZ(REG_ITMP2, 0);
2865                                                 }
2866                                         else {
2867                                                 M_LDA(REG_ITMP2, REG_ZERO, s2);
2868                                                 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2, 0);
2869                                                 M_BEQZ(REG_ITMP2, 0);
2870                                                 }
2871                                         mcode_addxcastrefs(mcodeptr);
2872                                         }
2873                                 }
2874                         else
2875                                 panic ("internal error: no inlined array checkcast");
2876                         }
2877                         M_INTMOVE(s1, d);
2878                         store_reg_to_var_int(iptr->dst, d);
2879                         break;
2880
2881                 case ICMD_CHECKASIZE:
2882                         var_to_reg_int(s1, src, REG_ITMP1);
2883                         M_BLTZ(s1, 0);
2884                         mcode_addxcheckarefs(mcodeptr);
2885                         break;
2886
2887                 case ICMD_MULTIANEWARRAY:
2888
2889                         /* check for negative sizes and copy sizes to stack if necessary  */
2890
2891                         MCODECHECK((iptr->op1 << 1) + 64);
2892
2893                         for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
2894                                 var_to_reg_int(s2, src, REG_ITMP1);
2895                                 M_BLTZ(s2, 0);
2896                                 mcode_addxcheckarefs(mcodeptr);
2897
2898                                 /* copy sizes to stack (argument numbers >= INT_ARG_CNT)      */
2899
2900                                 if (src->varkind != ARGVAR) {
2901                                         M_LST(s2, REG_SP, 8 * (s1 + INT_ARG_CNT));
2902                                         }
2903                                 }
2904
2905                         /* a0 = dimension count */
2906
2907                         M_LDA(argintregs[0], REG_ZERO, iptr->op1);
2908
2909                         /* a1 = arraydescriptor */
2910
2911                         a = dseg_addaddress(iptr->val.a);
2912                         M_LLD(argintregs[1], REG_PV, a);
2913
2914                         /* a2 = pointer to dimensions = stack pointer */
2915
2916                         M_INTMOVE(REG_SP, argintregs[2]);
2917
2918                         a = dseg_addaddress((void*) (builtin_nmultianewarray));
2919                         M_LLD(REG_PV, REG_PV, a);
2920                         M_JSR(REG_RA, REG_PV);
2921                         s1 = (int)((u1*) mcodeptr - mcodebase);
2922                         if (s1 <= 32768)
2923                                 M_LDA (REG_PV, REG_RA, -s1);
2924                         else {
2925                                 s4 ml = -s1, mh = 0;
2926                                 while (ml < -32768) {ml += 65536; mh--;}
2927                                 M_LDA(REG_PV, REG_RA, ml);
2928                                 M_LDAH(REG_PV, REG_PV, mh);
2929                                 }
2930                         s1 = reg_of_var(iptr->dst, REG_RESULT);
2931                         M_INTMOVE(REG_RESULT, s1);
2932                         store_reg_to_var_int(iptr->dst, s1);
2933                         break;
2934
2935
2936                 default: sprintf (logtext, "Unknown pseudo command: %d", iptr->opc);
2937                          error();
2938         } /* switch */
2939         } /* for instruction */
2940         src = bptr->outstack;
2941         len = bptr->outdepth;
2942         MCODECHECK(64+len);
2943         while (src) {
2944                 len--;
2945                 if ((src->varkind != STACKVAR)) {
2946                         s2 = src->type;
2947                         if (IS_FLT_DBL_TYPE(s2)) {
2948                                 var_to_reg_flt(s1, src, REG_FTMP1);
2949                                 if (!(interfaces[len][s2].flags & INMEMORY)) {
2950                                         M_FLTMOVE(s1,interfaces[len][s2].regoff);
2951                                         }
2952                                 else {
2953                                         M_DST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
2954                                         }
2955                                 }
2956                         else {
2957                                 var_to_reg_int(s1, src, REG_ITMP1);
2958                                 if (!(interfaces[len][s2].flags & INMEMORY)) {
2959                                         M_INTMOVE(s1,interfaces[len][s2].regoff);
2960                                         }
2961                                 else {
2962                                         M_LST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
2963                                         }
2964                                 }
2965                         }
2966                 src = src->prev;
2967                 }
2968         } /* if (bptr -> flags >= BBREACHED) */
2969         } /* for basic block */
2970
2971         bptr -> mpc = (int)((u1*) mcodeptr - mcodebase);
2972
2973         {
2974         s4 *xcodeptr = NULL;
2975         
2976         for (; xboundrefs != NULL; xboundrefs = xboundrefs->next) {
2977                 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
2978                         gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos, 
2979                                 xboundrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
2980                         continue;
2981                         }
2982
2983                 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos, 
2984                                   xboundrefs->branchpos, (u1*) mcodeptr - mcodebase);
2985
2986                 MCODECHECK(8);
2987
2988                 M_LDA(REG_ITMP2_XPC, REG_PV, xboundrefs->branchpos);
2989
2990                 if (xcodeptr != NULL) {
2991                         M_BR((xcodeptr-mcodeptr)-1);
2992                         }
2993                 else {
2994                         xcodeptr = mcodeptr;
2995
2996                         a = dseg_addaddress(proto_java_lang_ArrayIndexOutOfBoundsException);
2997                         M_LLD(REG_ITMP1_XPTR, REG_PV, a);
2998
2999                         a = dseg_addaddress(asm_handle_exception);
3000                         M_LLD(REG_ITMP3, REG_PV, a);
3001
3002                         M_JMP(REG_ZERO, REG_ITMP3);
3003                         }
3004                 }
3005
3006         xcodeptr = NULL;
3007         
3008         for (; xcheckarefs != NULL; xcheckarefs = xcheckarefs->next) {
3009                 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3010                         gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos, 
3011                                 xcheckarefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3012                         continue;
3013                         }
3014
3015                 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos, 
3016                                   xcheckarefs->branchpos, (u1*) mcodeptr - mcodebase);
3017
3018                 MCODECHECK(8);
3019
3020                 M_LDA(REG_ITMP2_XPC, REG_PV, xcheckarefs->branchpos);
3021
3022                 if (xcodeptr != NULL) {
3023                         M_BR((xcodeptr-mcodeptr)-1);
3024                         }
3025                 else {
3026                         xcodeptr = mcodeptr;
3027
3028                         a = dseg_addaddress(proto_java_lang_NegativeArraySizeException);
3029                         M_LLD(REG_ITMP1_XPTR, REG_PV, a);
3030
3031                         a = dseg_addaddress(asm_handle_exception);
3032                         M_LLD(REG_ITMP3, REG_PV, a);
3033
3034                         M_JMP(REG_ZERO, REG_ITMP3);
3035                         }
3036                 }
3037
3038         xcodeptr = NULL;
3039         
3040         for (; xcastrefs != NULL; xcastrefs = xcastrefs->next) {
3041                 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3042                         gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos, 
3043                                 xcastrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3044                         continue;
3045                         }
3046
3047                 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos, 
3048                                   xcastrefs->branchpos, (u1*) mcodeptr - mcodebase);
3049
3050                 MCODECHECK(8);
3051
3052                 M_LDA(REG_ITMP2_XPC, REG_PV, xcastrefs->branchpos);
3053
3054                 if (xcodeptr != NULL) {
3055                         M_BR((xcodeptr-mcodeptr)-1);
3056                         }
3057                 else {
3058                         xcodeptr = mcodeptr;
3059
3060                         a = dseg_addaddress(proto_java_lang_ClassCastException);
3061                         M_LLD(REG_ITMP1_XPTR, REG_PV, a);
3062
3063                         a = dseg_addaddress(asm_handle_exception);
3064                         M_LLD(REG_ITMP3, REG_PV, a);
3065
3066                         M_JMP(REG_ZERO, REG_ITMP3);
3067                         }
3068                 }
3069
3070
3071 #ifdef SOFTNULLPTRCHECK
3072
3073         xcodeptr = NULL;
3074
3075         for (; xnullrefs != NULL; xnullrefs = xnullrefs->next) {
3076                 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3077                         gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos, 
3078                                 xnullrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3079                         continue;
3080                         }
3081
3082                 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos, 
3083                                   xnullrefs->branchpos, (u1*) mcodeptr - mcodebase);
3084
3085                 MCODECHECK(8);
3086
3087                 M_LDA(REG_ITMP2_XPC, REG_PV, xnullrefs->branchpos - 4);
3088
3089                 if (xcodeptr != NULL) {
3090                         M_BR((xcodeptr-mcodeptr)-1);
3091                         }
3092                 else {
3093                         xcodeptr = mcodeptr;
3094
3095                         a = dseg_addaddress(proto_java_lang_NullPointerException);
3096                         M_LLD(REG_ITMP1_XPTR, REG_PV, a);
3097
3098                         a = dseg_addaddress(asm_handle_exception);
3099                         M_LLD(REG_ITMP3, REG_PV, a);
3100
3101                         M_JMP(REG_ZERO, REG_ITMP3);
3102                         }
3103                 }
3104
3105 #endif
3106         }
3107
3108         mcode_finish((int)((u1*) mcodeptr - mcodebase));
3109 }
3110
3111
3112 /* redefinition of code generation macros (compiling into array) **************/
3113
3114 /* 
3115 These macros are newly defined to allow code generation into an array.
3116 This is necessary, because the original M_.. macros generate code by
3117 calling 'mcode_adds4' that uses an additional data structure to
3118 receive the code.
3119
3120 For a faster (but less flexible) version to generate code, these
3121 macros directly use the (s4* p) - pointer to put the code directly
3122 in a locally defined array.
3123 This makes sense only for the stub-generation-routines below.
3124 */
3125
3126 #undef M_OP3
3127 #define M_OP3(op,fu,a,b,c,const) \
3128         *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<(16-3*(const)))| \
3129         ((const)<<12)|((fu)<<5)|((c)) )
3130 #undef M_FOP3
3131 #define M_FOP3(op,fu,a,b,c) \
3132         *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<16)|((fu)<<5)|(c) )
3133 #undef M_BRA
3134 #define M_BRA(op,a,disp) \
3135         *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((disp)&0x1fffff) )
3136 #undef M_MEM
3137 #define M_MEM(op,a,b,disp) \
3138         *(p++) = ( (((s4)(op))<<26)|((a)<<21)|((b)<<16)|((disp)&0xffff) )
3139
3140
3141 #if 0
3142
3143 /* function createcompilerstub *************************************************
3144
3145         creates a stub routine which calls the compiler
3146         
3147 *******************************************************************************/
3148
3149 #define COMPSTUBSIZE 3
3150
3151 u1 *createcompilerstub (methodinfo *m)
3152 {
3153         u8 *s = CNEW (u8, COMPSTUBSIZE);    /* memory to hold the stub            */
3154         s4 *p = (s4*) s;                    /* code generation pointer            */
3155         
3156                                             /* code for the stub                  */
3157         M_LLD (REG_PV, REG_PV, 16);         /* load pointer to the compiler       */
3158         M_JMP (0, REG_PV);                  /* jump to the compiler, return address
3159                                                in reg 0 is used as method pointer */
3160         s[1] = (u8) m;                      /* literals to be adressed            */  
3161         s[2] = (u8) asm_call_jit_compiler;  /* jump directly via PV from above    */
3162
3163 #ifdef STATISTICS
3164         count_cstub_len += COMPSTUBSIZE * 8;
3165 #endif
3166
3167         return (u1*) s;
3168 }
3169
3170
3171 /* function removecompilerstub *************************************************
3172
3173      deletes a compilerstub from memory  (simply by freeing it)
3174
3175 *******************************************************************************/
3176
3177 void removecompilerstub (u1 *stub) 
3178 {
3179         CFREE (stub, COMPSTUBSIZE * 8);
3180 }
3181
3182
3183 /* function: removenativestub **************************************************
3184
3185     removes a previously created native-stub from memory
3186     
3187 *******************************************************************************/
3188
3189 void removenativestub (u1 *stub)
3190 {
3191         CFREE (stub, NATIVESTUBSIZE * 8);
3192 }
3193
3194 #endif /* 0 */
3195
3196
3197 /* function: ncreatenativestub *************************************************
3198
3199         creates a stub routine which calls a native method
3200         
3201 *******************************************************************************/
3202
3203 #define NATIVESTUBSIZE 11
3204
3205 u1 *ncreatenativestub (functionptr f, methodinfo *m)
3206 {
3207         u8 *s = CNEW (u8, NATIVESTUBSIZE);  /* memory to hold the stub            */
3208         s4 *p = (s4*) s;                    /* code generation pointer            */
3209
3210         M_LDA  (REG_SP, REG_SP, -8);        /* build up stackframe                */
3211         M_LST  (REG_RA, REG_SP, 0);         /* store return address               */
3212
3213         M_LLD  (REG_PV, REG_PV, 8*8);       /* load adress of native method       */
3214         M_JSR  (REG_RA, REG_PV);            /* call native method                 */
3215
3216         M_LDA  (REG_PV, REG_RA, -4*4);      /* recompute pv from ra               */
3217         M_LLD  (REG_ITMP3, REG_PV, 9*8);    /* get address of exceptionptr        */
3218
3219         M_LLD  (REG_RA, REG_SP, 0);         /* load return address                */
3220         M_LLD  (REG_ITMP1, REG_ITMP3, 0);   /* load exception into reg. itmp1     */
3221
3222         M_LDA  (REG_SP, REG_SP, 8);         /* remove stackframe                  */
3223         M_BNEZ (REG_ITMP1, 1);              /* if no exception then return        */
3224
3225         M_RET  (REG_ZERO, REG_RA);          /* return to caller                   */
3226         
3227         M_LST  (REG_ZERO, REG_ITMP3, 0);    /* store NULL into exceptionptr       */
3228         M_LDA  (REG_ITMP2, REG_RA, -4);     /* move fault address into reg. itmp2 */
3229
3230         M_LLD  (REG_ITMP3, REG_PV,10*8);    /* load asm exception handler address */
3231         M_JMP  (REG_ZERO, REG_ITMP3);       /* jump to asm exception handler      */
3232
3233
3234         s[8] = (u8) f;                      /* address of native method           */
3235         s[9] = (u8) (&exceptionptr);        /* address of exceptionptr            */
3236         s[10]= (u8) (asm_handle_nat_exception); /* addr of asm exception handler  */
3237
3238 #ifdef STATISTICS
3239         count_nstub_len += NATIVESTUBSIZE * 8;
3240 #endif
3241
3242         return (u1*) s;
3243 }
3244
3245
3246 /*
3247  * These are local overrides for various environment variables in Emacs.
3248  * Please do not remove this and leave it at the end of the file, where
3249  * Emacs will automagically detect them.
3250  * ---------------------------------------------------------------------
3251  * Local variables:
3252  * mode: c
3253  * indent-tabs-mode: t
3254  * c-basic-offset: 4
3255  * tab-width: 4
3256  * End:
3257  */