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