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