Major file restructuring.
[cacao.git] / src / vm / jit / mips / codegen.c
1 /* jit/mips/codegen.c - machine code generator for mips
2
3    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4    Institut f. Computersprachen, TU Wien
5    R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser, M. Probst,
6    S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich,
7    J. Wenninger
8
9    This file is part of CACAO.
10
11    This program is free software; you can redistribute it and/or
12    modify it under the terms of the GNU General Public License as
13    published by the Free Software Foundation; either version 2, or (at
14    your option) any later version.
15
16    This program is distributed in the hope that it will be useful, but
17    WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19    General Public License for more details.
20
21    You should have received a copy of the GNU General Public License
22    along with this program; if not, write to the Free Software
23    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
24    02111-1307, USA.
25
26    Contact: cacao@complang.tuwien.ac.at
27
28    Authors: Andreas Krall
29             Reinhard Grafl
30
31    Contains the codegenerator for an MIPS (R4000 or higher) processor.
32    This module generates MIPS machine code for a sequence of
33    intermediate code commands (ICMDs).
34
35    $Id: codegen.c 564 2003-11-03 15:47:13Z twisti $
36
37 */
38
39
40 #include <stdio.h>
41 #include <signal.h>
42 #include "types.h"
43 #include "codegen.h"
44 #include "jit.h"
45 #include "reg.h"
46 #include "builtin.h"
47 #include "asmpart.h"
48 #include "jni.h"
49 #include "loader.h"
50 #include "tables.h"
51 #include "native.h"
52
53 /* include independent code generation stuff */
54 #include "codegen.inc"
55 #include "reg.inc"
56
57
58 /* *****************************************************************************
59
60 Datatypes and Register Allocations:
61 ----------------------------------- 
62
63 On 64-bit-machines (like the MIPS) all operands are stored in the
64 registers in a 64-bit form, even when the correspondig JavaVM operands
65 only need 32 bits. This is done by a canonical representation:
66
67 32-bit integers are allways stored as sign-extended 64-bit values (this
68 approach is directly supported by the MIPS architecture and is very easy
69 to implement).
70
71 32-bit-floats are stored in a 64-bit double precision register by simply
72 expanding the exponent and mantissa with zeroes. (also supported by the
73 architecture)
74
75
76 Stackframes:
77
78 The calling conventions and the layout of the stack is  explained in detail
79 in the documention file: calling.doc
80
81 *******************************************************************************/
82
83
84 /* additional functions and macros to generate code ***************************/
85
86 /* #define BlockPtrOfPC(pc)        block+block_index[pc] */
87 #define BlockPtrOfPC(pc)  ((basicblock *) iptr->target)
88
89
90 #ifdef STATISTICS
91 #define COUNT_SPILLS count_spills++
92 #else
93 #define COUNT_SPILLS
94 #endif
95
96
97 /* gen_nullptr_check(objreg) */
98
99 #ifdef SOFTNULLPTRCHECK
100 #define gen_nullptr_check(objreg) \
101         if (checknull) {\
102         M_BEQZ((objreg), 0);\
103         codegen_addxnullrefs(mcodeptr);\
104         M_NOP;\
105         }
106 #else
107 #define gen_nullptr_check(objreg)
108 #endif
109
110
111 /* MCODECHECK(icnt) */
112
113 #define MCODECHECK(icnt) \
114         if((mcodeptr+(icnt))>mcodeend)mcodeptr=codegen_increase((u1*)mcodeptr)
115
116 /* M_INTMOVE:
117      generates an integer-move from register a to b.
118      if a and b are the same int-register, no code will be generated.
119 */ 
120
121 #define M_INTMOVE(a,b) if(a!=b){M_MOV(a,b);}
122
123
124 /* M_FLTMOVE:
125     generates a floating-point-move from register a to b.
126     if a and b are the same float-register, no code will be generated
127 */ 
128
129 #define M_FLTMOVE(a,b) {if(a!=b){M_DMOV(a,b);}}
130
131 #define M_TFLTMOVE(t,a,b) \
132         {if(a!=b) \
133                 if ((t)==TYPE_DBL) \
134                     {M_DMOV(a,b);} \
135                 else {M_FMOV(a,b);} \
136         }
137
138 #define M_TFLD(t,a,b,disp) \
139     if ((t)==TYPE_DBL) \
140           {M_DLD(a,b,disp);} \
141     else \
142           {M_FLD(a,b,disp);}
143
144 #define M_TFST(t,a,b,disp) \
145     if ((t)==TYPE_DBL) \
146           {M_DST(a,b,disp);} \
147     else \
148           {M_FST(a,b,disp);}
149
150 #define M_CCFLTMOVE(t1,t2,a,b) \
151         if ((t1)==(t2)) \
152           {M_TFLTMOVE(t1,a,b);} \
153         else \
154           if ((t1)==TYPE_DBL) \
155                 {M_CVTDF(a,b);} \
156           else \
157                 {M_CVTFD(a,b);}
158
159 #define M_CCFLD(t1,t2,a,b,disp) \
160     if ((t1)==(t2)) \
161           {M_DLD(a,b,disp);} \
162         else { \
163           M_DLD(REG_FTMP1,b,disp); \
164           if ((t1)==TYPE_DBL) \
165             {M_CVTDF(REG_FTMP1,a);} \
166           else \
167             {M_CVTFD(REG_FTMP1,a);} \
168         }
169           
170 #define M_CCFST(t1,t2,a,b,disp) \
171     if ((t1)==(t2)) \
172           {M_DST(a,b,disp);} \
173         else { \
174           if ((t1)==TYPE_DBL) \
175             {M_CVTDF(a,REG_FTMP1);} \
176           else \
177             {M_CVTFD(a,REG_FTMP1);} \
178           M_DST(REG_FTMP1,b,disp); \
179         }
180           
181
182 /* var_to_reg_xxx:
183     this function generates code to fetch data from a pseudo-register
184     into a real register. 
185     If the pseudo-register has actually been assigned to a real 
186     register, no code will be emitted, since following operations
187     can use this register directly.
188     
189     v: pseudoregister to be fetched from
190     tempregnum: temporary register to be used if v is actually spilled to ram
191
192     return: the register number, where the operand can be found after 
193             fetching (this wil be either tempregnum or the register
194             number allready given to v)
195 */
196
197 #define var_to_reg_int(regnr,v,tempnr) { \
198         if ((v)->flags & INMEMORY) \
199                 {COUNT_SPILLS;M_LLD(tempnr,REG_SP,8*(v)->regoff);regnr=tempnr;} \
200         else regnr=(v)->regoff; \
201 }
202
203
204 #define var_to_reg_flt(regnr,v,tempnr) { \
205         if ((v)->flags & INMEMORY) \
206                 {COUNT_SPILLS;M_DLD(tempnr,REG_SP,8*(v)->regoff);regnr=tempnr;} \
207         else regnr=(v)->regoff; \
208 }
209
210
211 /* reg_of_var:
212     This function determines a register, to which the result of an operation
213     should go, when it is ultimatively intended to store the result in
214     pseudoregister v.
215     If v is assigned to an actual register, this register will be returned.
216     Otherwise (when v is spilled) this function returns tempregnum.
217     If not already done, regoff and flags are set in the stack location.
218 */        
219
220 static int reg_of_var(stackptr v, int tempregnum)
221 {
222         varinfo      *var;
223
224         switch (v->varkind) {
225                 case TEMPVAR:
226                         if (!(v->flags & INMEMORY))
227                                 return(v->regoff);
228                         break;
229                 case STACKVAR:
230                         var = &(interfaces[v->varnum][v->type]);
231                         v->regoff = var->regoff;
232                         if (!(var->flags & INMEMORY))
233                                 return(var->regoff);
234                         break;
235                 case LOCALVAR:
236                         var = &(locals[v->varnum][v->type]);
237                         v->regoff = var->regoff;
238                         if (!(var->flags & INMEMORY))
239                                 return(var->regoff);
240                         break;
241                 case ARGVAR:
242                         v->regoff = v->varnum;
243                         if (IS_FLT_DBL_TYPE(v->type)) {
244                                 if (v->varnum < fltreg_argnum) {
245                                         v->regoff = argfltregs[v->varnum];
246                                         return(argfltregs[v->varnum]);
247                                         }
248                                 }
249                         else
250                                 if (v->varnum < intreg_argnum) {
251                                         v->regoff = argintregs[v->varnum];
252                                         return(argintregs[v->varnum]);
253                                         }
254                         v->regoff -= intreg_argnum;
255                         break;
256                 }
257         v->flags |= INMEMORY;
258         return tempregnum;
259 }
260
261
262 /* store_reg_to_var_xxx:
263     This function generates the code to store the result of an operation
264     back into a spilled pseudo-variable.
265     If the pseudo-variable has not been spilled in the first place, this 
266     function will generate nothing.
267     
268     v ............ Pseudovariable
269     tempregnum ... Number of the temporary registers as returned by
270                    reg_of_var.
271 */      
272
273 #define store_reg_to_var_int(sptr, tempregnum) {       \
274         if ((sptr)->flags & INMEMORY) {                    \
275                 COUNT_SPILLS;                                  \
276                 M_LST(tempregnum, REG_SP, 8 * (sptr)->regoff); \
277                 }                                              \
278         }
279
280 #define store_reg_to_var_flt(sptr, tempregnum) {       \
281         if ((sptr)->flags & INMEMORY) {                    \
282                 COUNT_SPILLS;                                  \
283                 M_DST(tempregnum, REG_SP, 8 * (sptr)->regoff); \
284                 }                                              \
285         }
286
287
288 void docacheflush(u1 *p, long bytelen, int dummy);
289
290 /* NullPointerException handlers and exception handling initialisation        */
291
292 /* NullPointerException signal handler for hardware null pointer check */
293
294 void catch_NullPointerException(int sig, int code, struct sigcontext *sigctx)
295 {
296         sigset_t nsig;
297         int      instr;
298         long     faultaddr;
299
300         /* Reset signal handler - necessary for SysV, does no harm for BSD */
301
302         instr = *((int*)(sigctx->sc_pc));
303         faultaddr = sigctx->sc_regs[(instr >> 21) & 0x1f];
304
305         if (faultaddr == 0) {
306                 sigemptyset(&nsig);
307                 sigaddset(&nsig, sig);
308                 sigprocmask(SIG_UNBLOCK, &nsig, NULL);           /* unblock signal    */
309                 sigctx->sc_regs[REG_ITMP1_XPTR] =
310                                             (long) proto_java_lang_NullPointerException;
311                 sigctx->sc_regs[REG_ITMP2_XPC] = sigctx->sc_pc;
312                 sigctx->sc_pc = (long) asm_handle_exception;
313                 }
314         else {
315         faultaddr += (long) ((instr << 16) >> 16);
316                 fprintf(stderr, "faulting address: 0x%lx at 0x%lx\n", (long) faultaddr, (long) sigctx->sc_pc);
317                 panic("Stack overflow");
318                 }
319 }
320
321 void createcalljava ();
322
323
324 void init_exceptions(void)
325 {
326         struct sigaction sa;
327         sigset_t unblockmask;
328
329         createcalljava();
330         
331         /* The Boehm GC initialization blocks the SIGSEGV signal. So we do a
332            dummy allocation here to ensure that the GC is initialized.
333         */
334         heap_allocate(1, 0, NULL);
335
336         /* install signal handlers we need to convert to exceptions */
337
338         sigemptyset(&unblockmask);
339         sa.sa_flags = 0;
340         sa.sa_sigaction = catch_NullPointerException;
341         sigemptyset(&sa.sa_mask);
342
343         if (!checknull) {
344
345 #if defined(SIGSEGV)
346                 sigaction(SIGSEGV, &sa, NULL);
347                 sigaddset(&unblockmask, SIGSEGV);
348 #endif
349
350 #if defined(SIGBUS)
351                 sigaction(SIGBUS, &sa, NULL);
352                 sigaddset(&unblockmask, SIGBUS);
353 #endif
354         }
355
356         sigprocmask(SIG_UNBLOCK, &unblockmask, NULL);
357 }
358
359
360 /* function gen_mcode **********************************************************
361
362         generates machine code
363
364 *******************************************************************************/
365
366 #define         MethodPointer   -8
367 #define         FrameSize       -12
368 #define     IsSync          -16
369 #define     IsLeaf          -20
370 #define     IntSave         -24
371 #define     FltSave         -28
372 #define     ExTableSize     -32
373 #define     ExTableStart    -32
374
375 #if POINTERSIZE==8
376 #define     ExEntrySize     -32
377 #define     ExStartPC       -8
378 #define     ExEndPC         -16
379 #define     ExHandlerPC     -24
380 #define     ExCatchType     -32
381 #else
382 #define     ExEntrySize     -16
383 #define     ExStartPC       -4
384 #define     ExEndPC         -8
385 #define     ExHandlerPC     -12
386 #define     ExCatchType     -16
387 #endif
388
389 void codegen()
390 {
391         int  len, s1, s2, s3, d, bbs;
392         s4   a;
393         s4          *mcodeptr;
394         stackptr    src;
395         varinfo     *var;
396         basicblock  *bptr;
397         instruction *iptr;
398         xtable *ex;
399
400         {
401         int p, pa, t, l, r;
402
403         savedregs_num = (isleafmethod) ? 0 : 1;           /* space to save the RA */
404
405         /* space to save used callee saved registers */
406
407         savedregs_num += (savintregcnt - maxsavintreguse);
408         savedregs_num += (savfltregcnt - maxsavfltreguse);
409
410         parentargs_base = maxmemuse + savedregs_num;
411
412 #ifdef USE_THREADS                 /* space to save argument of monitor_enter */
413
414         if (checksync && (method->flags & ACC_SYNCHRONIZED))
415                 parentargs_base++;
416
417 #endif
418
419         /* adjust frame size for 16 byte alignment */
420
421         if (parentargs_base & 1)
422                 parentargs_base++;
423
424         /* create method header */
425
426 #if POINTERSIZE==4
427         (void) dseg_addaddress(method);                         /* Filler         */
428 #endif
429         (void) dseg_addaddress(method);                         /* MethodPointer  */
430         (void) dseg_adds4(parentargs_base * 8);                 /* FrameSize      */
431
432 #ifdef USE_THREADS
433
434         /* IsSync contains the offset relative to the stack pointer for the
435            argument of monitor_exit used in the exception handler. Since the
436            offset could be zero and give a wrong meaning of the flag it is
437            offset by one.
438         */
439
440         if (checksync && (method->flags & ACC_SYNCHRONIZED))
441                 (void) dseg_adds4((maxmemuse + 1) * 8);             /* IsSync         */
442         else
443
444 #endif
445
446         (void) dseg_adds4(0);                                   /* IsSync         */
447                                                
448         (void) dseg_adds4(isleafmethod);                        /* IsLeaf         */
449         (void) dseg_adds4(savintregcnt - maxsavintreguse);      /* IntSave        */
450         (void) dseg_adds4(savfltregcnt - maxsavfltreguse);      /* FltSave        */
451         (void) dseg_adds4(exceptiontablelength);                /* ExTableSize    */
452
453         /* create exception table */
454
455         for (ex = extable; ex != NULL; ex = ex->down) {
456
457 #ifdef LOOP_DEBUG       
458                 if (ex->start != NULL)
459                         printf("adding start - %d - ", ex->start->debug_nr);
460                 else {
461                         printf("PANIC - start is NULL");
462                         exit(-1);
463                 }
464 #endif
465
466                 dseg_addtarget(ex->start);
467
468 #ifdef LOOP_DEBUG                       
469                 if (ex->end != NULL)
470                         printf("adding end - %d - ", ex->end->debug_nr);
471                 else {
472                         printf("PANIC - end is NULL");
473                         exit(-1);
474                 }
475 #endif
476
477                 dseg_addtarget(ex->end);
478
479 #ifdef LOOP_DEBUG               
480                 if (ex->handler != NULL)
481                         printf("adding handler - %d\n", ex->handler->debug_nr);
482                 else {
483                         printf("PANIC - handler is NULL");
484                         exit(-1);
485                 }
486 #endif
487
488                 dseg_addtarget(ex->handler);
489            
490                 (void) dseg_addaddress(ex->catchtype);
491                 }
492         
493         /* initialize mcode variables */
494         
495         mcodeptr = (s4*) mcodebase;
496         mcodeend = (s4*) (mcodebase + mcodesize);
497         MCODECHECK(128 + mparamcount);
498
499         /* create stack frame (if necessary) */
500
501         if (parentargs_base)
502                 {M_LDA (REG_SP, REG_SP, -parentargs_base * 8);}
503
504         /* save return address and used callee saved registers */
505
506         p = parentargs_base;
507         if (!isleafmethod)
508                 {p--;  M_LST (REG_RA, REG_SP, 8*p);}
509         for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
510                 {p--; M_LST (savintregs[r], REG_SP, 8 * p);}
511         for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
512                 {p--; M_DST (savfltregs[r], REG_SP, 8 * p);}
513
514         /* save monitorenter argument */
515
516 #ifdef USE_THREADS
517         if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
518                 if (method->flags & ACC_STATIC) {
519                         p = dseg_addaddress (class);
520                         M_ALD(REG_ITMP1, REG_PV, p);
521                         M_AST(REG_ITMP1, REG_SP, 8 * maxmemuse);
522                         } 
523                 else {
524                         M_AST (argintregs[0], REG_SP, 8 * maxmemuse);
525                         }
526                 }                       
527 #endif
528
529         /* copy argument registers to stack and call trace function with pointer
530            to arguments on stack. ToDo: save floating point registers !!!!!!!!!
531         */
532
533         if (runverbose) {
534                 M_LDA (REG_SP, REG_SP, -(18*8));
535
536                 M_LST(REG_RA,        REG_SP,  1*8);
537
538                 M_LST(argintregs[0], REG_SP,  2*8);
539                 M_LST(argintregs[1], REG_SP,  3*8);
540                 M_LST(argintregs[2], REG_SP,  4*8);
541                 M_LST(argintregs[3], REG_SP,  5*8);
542                 M_LST(argintregs[4], REG_SP,  6*8);
543                 M_LST(argintregs[5], REG_SP,  7*8);
544                 M_LST(argintregs[6], REG_SP,  8*8);
545                 M_LST(argintregs[7], REG_SP,  9*8);
546
547                 M_DST(argfltregs[0], REG_SP, 10*8);
548                 M_DST(argfltregs[1], REG_SP, 11*8);
549                 M_DST(argfltregs[2], REG_SP, 12*8);
550                 M_DST(argfltregs[3], REG_SP, 13*8);
551                 M_DST(argfltregs[4], REG_SP, 14*8);
552                 M_DST(argfltregs[5], REG_SP, 15*8);
553                 M_DST(argfltregs[6], REG_SP, 16*8);
554                 M_DST(argfltregs[7], REG_SP, 17*8);
555
556                 p = dseg_addaddress (method);
557                 M_ALD(REG_ITMP1, REG_PV, p);
558                 M_LST(REG_ITMP1, REG_SP, 0);
559                 p = dseg_addaddress ((void*) (builtin_trace_args));
560                 M_ALD(REG_ITMP3, REG_PV, p);
561                 M_JSR(REG_RA, REG_ITMP3);
562                 M_NOP;
563
564                 M_LLD(REG_RA,        REG_SP,  1*8);
565
566                 M_LLD(argintregs[0], REG_SP,  2*8);
567                 M_LLD(argintregs[1], REG_SP,  3*8);
568                 M_LLD(argintregs[2], REG_SP,  4*8);
569                 M_LLD(argintregs[3], REG_SP,  5*8);
570                 M_LLD(argintregs[4], REG_SP,  6*8);
571                 M_LLD(argintregs[5], REG_SP,  7*8);
572                 M_LLD(argintregs[6], REG_SP,  8*8);
573                 M_LLD(argintregs[7], REG_SP,  9*8);
574
575                 M_DLD(argfltregs[0], REG_SP, 10*8);
576                 M_DLD(argfltregs[1], REG_SP, 11*8);
577                 M_DLD(argfltregs[2], REG_SP, 12*8);
578                 M_DLD(argfltregs[3], REG_SP, 13*8);
579                 M_DLD(argfltregs[4], REG_SP, 14*8);
580                 M_DLD(argfltregs[5], REG_SP, 15*8);
581                 M_DLD(argfltregs[6], REG_SP, 16*8);
582                 M_DLD(argfltregs[7], REG_SP, 17*8);
583
584                 M_LDA (REG_SP, REG_SP, 18*8);
585                 }
586
587         /* take arguments out of register or stack frame */
588
589         for (p = 0, l = 0; p < mparamcount; p++) {
590                 t = mparamtypes[p];
591                 var = &(locals[l][t]);
592                 l++;
593                 if (IS_2_WORD_TYPE(t))    /* increment local counter for 2 word types */
594                         l++;
595                 if (var->type < 0)
596                         continue;
597                 r = var->regoff; 
598                 if (IS_INT_LNG_TYPE(t)) {                    /* integer args          */
599                         if (p < INT_ARG_CNT) {                   /* register arguments    */
600                                 if (!(var->flags & INMEMORY))        /* reg arg -> register   */
601                                         {M_INTMOVE (argintregs[p], r);}
602                                 else                                 /* reg arg -> spilled    */
603                                         M_LST (argintregs[p], REG_SP, 8 * r);
604                                 }
605                         else {                                   /* stack arguments       */
606                                 pa = p - INT_ARG_CNT;
607                                 if (!(var->flags & INMEMORY))        /* stack arg -> register */ 
608                                         M_LLD (r, REG_SP, 8 * (parentargs_base + pa));
609                                 else {                               /* stack arg -> spilled  */
610                                         M_LLD (REG_ITMP1, REG_SP, 8 * (parentargs_base + pa));
611                                         M_LST (REG_ITMP1, REG_SP, 8 * r);
612                                         }
613                                 }
614                         }
615                 else {                                       /* floating args         */   
616                         if (p < FLT_ARG_CNT) {                   /* register arguments    */
617                                 if (!(var->flags & INMEMORY))        /* reg arg -> register   */
618                                         {M_TFLTMOVE (var->type, argfltregs[p], r);}
619                                 else                                             /* reg arg -> spilled    */
620                                         M_DST (argfltregs[p], REG_SP, 8 * r);
621                                 }
622                         else {                                   /* stack arguments       */
623                                 pa = p - FLT_ARG_CNT;
624                                 if (!(var->flags & INMEMORY)) {      /* stack-arg -> register */
625                                         M_DLD (r, REG_SP, 8 * (parentargs_base + pa) );
626                                 } else {                             /* stack-arg -> spilled  */
627                                         M_DLD (REG_FTMP1, REG_SP, 8 * (parentargs_base + pa));
628                                         M_DST (REG_FTMP1, REG_SP, 8 * r);
629                                         }
630                                 }
631                         }
632                 }  /* end for */
633
634         /* call trace function */
635
636 #if 0
637         if (runverbose && !isleafmethod) {
638                 M_LDA (REG_SP, REG_SP, -8);
639                 p = dseg_addaddress (method);
640                 M_ALD(REG_ITMP1, REG_PV, p);
641                 M_AST(REG_ITMP1, REG_SP, 0);
642                 p = dseg_addaddress ((void*) (builtin_trace_args));
643                 M_ALD(REG_ITMP3, REG_PV, p);
644                 M_JSR(REG_RA, REG_ITMP3);
645                 M_NOP;
646                 M_LDA(REG_SP, REG_SP, 8);
647                 }
648 #endif
649
650         /* call monitorenter function */
651
652 #ifdef USE_THREADS
653         if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
654                 int disp;
655                 p = dseg_addaddress ((void*) (builtin_monitorenter));
656                 M_ALD(REG_ITMP3, REG_PV, p);
657                 M_JSR(REG_RA, REG_ITMP3);
658                 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);
659                 disp = -(int)((u1*) mcodeptr - mcodebase);
660                 M_LDA(REG_PV, REG_RA, disp);
661                 }                       
662 #endif
663         }
664
665         /* end of header generation */
666
667         /* walk through all basic blocks */
668         for (/* bbs = block_count, */ bptr = block; /* --bbs >= 0 */ bptr != NULL; bptr = bptr->next) {
669
670                 bptr -> mpc = (int)((u1*) mcodeptr - mcodebase);
671
672                 if (bptr->flags >= BBREACHED) {
673
674                 /* branch resolving */
675
676                 {
677                 branchref *brefs;
678                 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
679                         gen_resolvebranch((u1*) mcodebase + brefs->branchpos, 
680                                           brefs->branchpos, bptr->mpc);
681                         }
682                 }
683
684                 /* copy interface registers to their destination */
685
686                 src = bptr->instack;
687                 len = bptr->indepth;
688                 MCODECHECK(64+len);
689                 while (src != NULL) {
690                         len--;
691                         if ((len == 0) && (bptr->type != BBTYPE_STD)) {
692                                 d = reg_of_var(src, REG_ITMP1);
693                                 M_INTMOVE(REG_ITMP1, d);
694                                 store_reg_to_var_int(src, d);
695                                 }
696                         else {
697                                 d = reg_of_var(src, REG_IFTMP);
698                                 if ((src->varkind != STACKVAR)) {
699                                         s2 = src->type;
700                                         if (IS_FLT_DBL_TYPE(s2)) {
701                                                 if (!(interfaces[len][s2].flags & INMEMORY)) {
702                                                         s1 = interfaces[len][s2].regoff;
703                                                         M_TFLTMOVE(s2,s1,d);
704                                                         }
705                                                 else {
706                                                         M_DLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
707                                                         }
708                                                 store_reg_to_var_flt(src, d);
709                                                 }
710                                         else {
711                                                 if (!(interfaces[len][s2].flags & INMEMORY)) {
712                                                         s1 = interfaces[len][s2].regoff;
713                                                         M_INTMOVE(s1,d);
714                                                         }
715                                                 else {
716                                                         M_LLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
717                                                         }
718                                                 store_reg_to_var_int(src, d);
719                                                 }
720                                         }
721                                 }
722                         src = src->prev;
723                         }
724
725                 /* walk through all instructions */
726                 
727                 src = bptr->instack;
728                 len = bptr->icount;
729                 for (iptr = bptr->iinstr;
730                     len > 0;
731                     src = iptr->dst, len--, iptr++) {
732
733         MCODECHECK(64);           /* an instruction usually needs < 64 words      */
734         switch (iptr->opc) {
735
736                 case ICMD_NOP:        /* ...  ==> ...                                 */
737                         break;
738
739                 case ICMD_NULLCHECKPOP: /* ..., objectref  ==> ...                    */
740
741                         var_to_reg_int(s1, src, REG_ITMP1);
742                         M_BEQZ(s1, 0);
743                         codegen_addxnullrefs(mcodeptr);
744                         M_NOP;
745                         break;
746
747                 /* constant operations ************************************************/
748
749 #define ICONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_IADD_IMM(REG_ZERO,c,r);} \
750                     else if(((c)>=0)&&((c)<=0xffff)){M_OR_IMM(REG_ZERO,c,r);} \
751                     else{a=dseg_adds4(c);M_ILD(r,REG_PV,a);}
752
753 #define LCONST(r,c) if(((c)>=-32768)&&((c)<= 32767)){M_LADD_IMM(REG_ZERO,c,r);} \
754                     else if(((c)>=0)&&((c)<=0xffff)){M_OR_IMM(REG_ZERO,c,r);} \
755                     else{a=dseg_adds8(c);M_LLD(r,REG_PV,a);}
756
757                 case ICMD_ICONST:     /* ...  ==> ..., constant                       */
758                                       /* op1 = 0, val.i = constant                    */
759
760                         d = reg_of_var(iptr->dst, REG_ITMP1);
761                         ICONST(d, iptr->val.i);
762                         store_reg_to_var_int(iptr->dst, d);
763                         break;
764
765                 case ICMD_LCONST:     /* ...  ==> ..., constant                       */
766                                       /* op1 = 0, val.l = constant                    */
767
768                         d = reg_of_var(iptr->dst, REG_ITMP1);
769                         LCONST(d, iptr->val.l);
770                         store_reg_to_var_int(iptr->dst, d);
771                         break;
772
773                 case ICMD_FCONST:     /* ...  ==> ..., constant                       */
774                                       /* op1 = 0, val.f = constant                    */
775
776                         d = reg_of_var (iptr->dst, REG_FTMP1);
777                         a = dseg_addfloat (iptr->val.f);
778                         M_FLD(d, REG_PV, a);
779                         store_reg_to_var_flt (iptr->dst, d);
780                         break;
781                         
782                 case ICMD_DCONST:     /* ...  ==> ..., constant                       */
783                                       /* op1 = 0, val.d = constant                    */
784
785                         d = reg_of_var (iptr->dst, REG_FTMP1);
786                         a = dseg_adddouble (iptr->val.d);
787                         M_DLD(d, REG_PV, a);
788                         store_reg_to_var_flt (iptr->dst, d);
789                         break;
790
791                 case ICMD_ACONST:     /* ...  ==> ..., constant                       */
792                                       /* op1 = 0, val.a = constant                    */
793
794                         d = reg_of_var(iptr->dst, REG_ITMP1);
795                         if (iptr->val.a) {
796                                 a = dseg_addaddress (iptr->val.a);
797                                 M_ALD(d, REG_PV, a);
798                                 }
799                         else {
800                                 M_INTMOVE(REG_ZERO, d);
801                                 }
802                         store_reg_to_var_int(iptr->dst, d);
803                         break;
804
805
806                 /* load/store operations **********************************************/
807
808                 case ICMD_ILOAD:      /* ...  ==> ..., content of local variable      */
809                 case ICMD_LLOAD:      /* op1 = local variable                         */
810                 case ICMD_ALOAD:
811
812                         d = reg_of_var(iptr->dst, REG_ITMP1);
813                         if ((iptr->dst->varkind == LOCALVAR) &&
814                             (iptr->dst->varnum == iptr->op1))
815                                 break;
816                         var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
817                         if (var->flags & INMEMORY)
818                                 M_LLD(d, REG_SP, 8 * var->regoff);
819                         else
820                                 {M_INTMOVE(var->regoff,d);}
821                         store_reg_to_var_int(iptr->dst, d);
822                         break;
823
824                 case ICMD_FLOAD:      /* ...  ==> ..., content of local variable      */
825                 case ICMD_DLOAD:      /* op1 = local variable                         */
826
827                         d = reg_of_var(iptr->dst, REG_FTMP1);
828                         if ((iptr->dst->varkind == LOCALVAR) &&
829                             (iptr->dst->varnum == iptr->op1))
830                                 break;
831                         var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
832                         {
833                                 int t2 = ((iptr->opc == ICMD_FLOAD) ? TYPE_FLT : TYPE_DBL);
834                                 if (var->flags & INMEMORY)
835                                         {M_CCFLD(var->type,t2,d, REG_SP, 8 * var->regoff);}
836                                 else
837                                         {M_CCFLTMOVE(var->type,t2,var->regoff,d);}
838                         }
839                         store_reg_to_var_flt(iptr->dst, d);
840                         break;
841
842
843                 case ICMD_ISTORE:     /* ..., value  ==> ...                          */
844                 case ICMD_LSTORE:     /* op1 = local variable                         */
845                 case ICMD_ASTORE:
846
847                         if ((src->varkind == LOCALVAR) &&
848                             (src->varnum == iptr->op1))
849                                 break;
850                         var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
851                         if (var->flags & INMEMORY) {
852                                 var_to_reg_int(s1, src, REG_ITMP1);
853                                 M_LST(s1, REG_SP, 8 * var->regoff);
854                                 }
855                         else {
856                                 var_to_reg_int(s1, src, var->regoff);
857                                 M_INTMOVE(s1, var->regoff);
858                                 }
859                         break;
860
861                 case ICMD_FSTORE:     /* ..., value  ==> ...                          */
862                 case ICMD_DSTORE:     /* op1 = local variable                         */
863
864                         if ((src->varkind == LOCALVAR) &&
865                             (src->varnum == iptr->op1))
866                                 break;
867                         var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
868                         {
869                                 int t1 = ((iptr->opc == ICMD_FSTORE) ? TYPE_FLT : TYPE_DBL);
870                                 if (var->flags & INMEMORY) {
871                                         var_to_reg_flt(s1, src, REG_FTMP1);
872                                         M_CCFST(t1,var->type,s1, REG_SP, 8 * var->regoff);
873                                         }
874                                 else {
875                                         var_to_reg_flt(s1, src, var->regoff);
876                                         M_CCFLTMOVE(t1,var->type,s1, var->regoff);
877                                         }
878                         }
879                         break;
880
881
882                 /* pop/dup/swap operations ********************************************/
883
884                 /* attention: double and longs are only one entry in CACAO ICMDs      */
885
886                 case ICMD_POP:        /* ..., value  ==> ...                          */
887                 case ICMD_POP2:       /* ..., value, value  ==> ...                   */
888                         break;
889
890 #define M_COPY(from,to) \
891                         d = reg_of_var(to, REG_IFTMP); \
892                         if ((from->regoff != to->regoff) || \
893                             ((from->flags ^ to->flags) & INMEMORY)) { \
894                                 if (IS_FLT_DBL_TYPE(from->type)) { \
895                                         var_to_reg_flt(s1, from, d); \
896                                         M_TFLTMOVE(from->type,s1,d); \
897                                         store_reg_to_var_flt(to, d); \
898                                         }\
899                                 else { \
900                                         var_to_reg_int(s1, from, d); \
901                                         M_INTMOVE(s1,d); \
902                                         store_reg_to_var_int(to, d); \
903                                         }\
904                                 }
905
906                 case ICMD_DUP:        /* ..., a ==> ..., a, a                         */
907                         M_COPY(src, iptr->dst);
908                         break;
909
910                 case ICMD_DUP_X1:     /* ..., a, b ==> ..., b, a, b                   */
911
912                         M_COPY(src,       iptr->dst->prev->prev);
913
914                 case ICMD_DUP2:       /* ..., a, b ==> ..., a, b, a, b                */
915
916                         M_COPY(src,       iptr->dst);
917                         M_COPY(src->prev, iptr->dst->prev);
918                         break;
919
920                 case ICMD_DUP2_X1:    /* ..., a, b, c ==> ..., b, c, a, b, c          */
921
922                         M_COPY(src->prev,       iptr->dst->prev->prev->prev);
923
924                 case ICMD_DUP_X2:     /* ..., a, b, c ==> ..., c, a, b, c             */
925
926                         M_COPY(src,             iptr->dst);
927                         M_COPY(src->prev,       iptr->dst->prev);
928                         M_COPY(src->prev->prev, iptr->dst->prev->prev);
929                         M_COPY(src, iptr->dst->prev->prev->prev);
930                         break;
931
932                 case ICMD_DUP2_X2:    /* ..., a, b, c, d ==> ..., c, d, a, b, c, d    */
933
934                         M_COPY(src,                   iptr->dst);
935                         M_COPY(src->prev,             iptr->dst->prev);
936                         M_COPY(src->prev->prev,       iptr->dst->prev->prev);
937                         M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
938                         M_COPY(src,       iptr->dst->prev->prev->prev->prev);
939                         M_COPY(src->prev, iptr->dst->prev->prev->prev->prev->prev);
940                         break;
941
942                 case ICMD_SWAP:       /* ..., a, b ==> ..., b, a                      */
943
944                         M_COPY(src, iptr->dst->prev);
945                         M_COPY(src->prev, iptr->dst);
946                         break;
947
948
949                 /* integer operations *************************************************/
950
951                 case ICMD_INEG:       /* ..., value  ==> ..., - value                 */
952
953                         var_to_reg_int(s1, src, REG_ITMP1); 
954                         d = reg_of_var(iptr->dst, REG_ITMP3);
955                         M_ISUB(REG_ZERO, s1, d);
956                         store_reg_to_var_int(iptr->dst, d);
957                         break;
958
959                 case ICMD_LNEG:       /* ..., value  ==> ..., - value                 */
960
961                         var_to_reg_int(s1, src, REG_ITMP1);
962                         d = reg_of_var(iptr->dst, REG_ITMP3);
963                         M_LSUB(REG_ZERO, s1, d);
964                         store_reg_to_var_int(iptr->dst, d);
965                         break;
966
967                 case ICMD_I2L:        /* ..., value  ==> ..., value                   */
968
969                         var_to_reg_int(s1, src, REG_ITMP1);
970                         d = reg_of_var(iptr->dst, REG_ITMP3);
971                         M_INTMOVE(s1, d);
972                         store_reg_to_var_int(iptr->dst, d);
973                         break;
974
975                 case ICMD_L2I:        /* ..., value  ==> ..., value                   */
976
977                         var_to_reg_int(s1, src, REG_ITMP1);
978                         d = reg_of_var(iptr->dst, REG_ITMP3);
979                         M_ISLL_IMM(s1, 0, d );
980                         store_reg_to_var_int(iptr->dst, d);
981                         break;
982
983                 case ICMD_INT2BYTE:   /* ..., value  ==> ..., value                   */
984
985                         var_to_reg_int(s1, src, REG_ITMP1);
986                         d = reg_of_var(iptr->dst, REG_ITMP3);
987                         M_LSLL_IMM(s1, 56, d);
988                         M_LSRA_IMM( d, 56, d);
989                         store_reg_to_var_int(iptr->dst, d);
990                         break;
991
992                 case ICMD_INT2CHAR:   /* ..., value  ==> ..., value                   */
993
994                         var_to_reg_int(s1, src, REG_ITMP1);
995                         d = reg_of_var(iptr->dst, REG_ITMP3);
996             M_CZEXT(s1, d);
997                         store_reg_to_var_int(iptr->dst, d);
998                         break;
999
1000                 case ICMD_INT2SHORT:  /* ..., value  ==> ..., value                   */
1001
1002                         var_to_reg_int(s1, src, REG_ITMP1);
1003                         d = reg_of_var(iptr->dst, REG_ITMP3);
1004                         M_LSLL_IMM(s1, 48, d);
1005                         M_LSRA_IMM( d, 48, d);
1006                         store_reg_to_var_int(iptr->dst, d);
1007                         break;
1008
1009
1010                 case ICMD_IADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
1011
1012                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1013                         var_to_reg_int(s2, src, REG_ITMP2);
1014                         d = reg_of_var(iptr->dst, REG_ITMP3);
1015                         M_IADD(s1, s2, d);
1016                         store_reg_to_var_int(iptr->dst, d);
1017                         break;
1018
1019                 case ICMD_IADDCONST:  /* ..., value  ==> ..., value + constant        */
1020                                       /* val.i = constant                             */
1021
1022                         var_to_reg_int(s1, src, REG_ITMP1);
1023                         d = reg_of_var(iptr->dst, REG_ITMP3);
1024                         if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
1025                                 M_IADD_IMM(s1, iptr->val.i, d);
1026                                 }
1027                         else {
1028                                 ICONST(REG_ITMP2, iptr->val.i);
1029                                 M_IADD(s1, REG_ITMP2, d);
1030                                 }
1031                         store_reg_to_var_int(iptr->dst, d);
1032                         break;
1033
1034                 case ICMD_LADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
1035
1036                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1037                         var_to_reg_int(s2, src, REG_ITMP2);
1038                         d = reg_of_var(iptr->dst, REG_ITMP3);
1039                         M_LADD(s1, s2, d);
1040                         store_reg_to_var_int(iptr->dst, d);
1041                         break;
1042
1043                 case ICMD_LADDCONST:  /* ..., value  ==> ..., value + constant        */
1044                                       /* val.l = constant                             */
1045
1046                         var_to_reg_int(s1, src, REG_ITMP1);
1047                         d = reg_of_var(iptr->dst, REG_ITMP3);
1048                         if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
1049                                 M_LADD_IMM(s1, iptr->val.l, d);
1050                                 }
1051                         else {
1052                                 LCONST(REG_ITMP2, iptr->val.l);
1053                                 M_LADD(s1, REG_ITMP2, d);
1054                                 }
1055                         store_reg_to_var_int(iptr->dst, d);
1056                         break;
1057
1058                 case ICMD_ISUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
1059
1060                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1061                         var_to_reg_int(s2, src, REG_ITMP2);
1062                         d = reg_of_var(iptr->dst, REG_ITMP3);
1063                         M_ISUB(s1, s2, d);
1064                         store_reg_to_var_int(iptr->dst, d);
1065                         break;
1066
1067                 case ICMD_ISUBCONST:  /* ..., value  ==> ..., value + constant        */
1068                                       /* val.i = constant                             */
1069
1070                         var_to_reg_int(s1, src, REG_ITMP1);
1071                         d = reg_of_var(iptr->dst, REG_ITMP3);
1072                         if ((iptr->val.i >= -32767) && (iptr->val.i <= 32768)) {
1073                                 M_IADD_IMM(s1, -iptr->val.i, d);
1074                                 }
1075                         else {
1076                                 ICONST(REG_ITMP2, iptr->val.i);
1077                                 M_ISUB(s1, REG_ITMP2, d);
1078                                 }
1079                         store_reg_to_var_int(iptr->dst, d);
1080                         break;
1081
1082                 case ICMD_LSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
1083
1084                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1085                         var_to_reg_int(s2, src, REG_ITMP2);
1086                         d = reg_of_var(iptr->dst, REG_ITMP3);
1087                         M_LSUB(s1, s2, d);
1088                         store_reg_to_var_int(iptr->dst, d);
1089                         break;
1090
1091                 case ICMD_LSUBCONST:  /* ..., value  ==> ..., value - constant        */
1092                                       /* val.l = constant                             */
1093
1094                         var_to_reg_int(s1, src, REG_ITMP1);
1095                         d = reg_of_var(iptr->dst, REG_ITMP3);
1096                         if ((iptr->val.l >= -32767) && (iptr->val.l <= 32768)) {
1097                                 M_LADD_IMM(s1, -iptr->val.l, d);
1098                                 }
1099                         else {
1100                                 LCONST(REG_ITMP2, iptr->val.l);
1101                                 M_LSUB(s1, REG_ITMP2, d);
1102                                 }
1103                         store_reg_to_var_int(iptr->dst, d);
1104                         break;
1105
1106                 case ICMD_IMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
1107
1108                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1109                         var_to_reg_int(s2, src, REG_ITMP2);
1110                         d = reg_of_var(iptr->dst, REG_ITMP3);
1111                         M_IMUL(s1, s2);
1112                         M_MFLO(d);
1113                         M_NOP;
1114                         M_NOP;
1115                         store_reg_to_var_int(iptr->dst, d);
1116                         break;
1117
1118                 case ICMD_IMULCONST:  /* ..., value  ==> ..., value * constant        */
1119                                       /* val.i = constant                             */
1120
1121                         var_to_reg_int(s1, src, REG_ITMP1);
1122                         d = reg_of_var(iptr->dst, REG_ITMP3);
1123                         ICONST(REG_ITMP2, iptr->val.i);
1124                         M_IMUL(s1, REG_ITMP2);
1125                         M_MFLO(d);
1126                         M_NOP;
1127                         M_NOP;
1128                         store_reg_to_var_int(iptr->dst, d);
1129                         break;
1130
1131                 case ICMD_LMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
1132
1133                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1134                         var_to_reg_int(s2, src, REG_ITMP2);
1135                         d = reg_of_var(iptr->dst, REG_ITMP3);
1136                         M_LMUL(s1, s2);
1137                         M_MFLO(d);
1138                         M_NOP;
1139                         M_NOP;
1140                         store_reg_to_var_int(iptr->dst, d);
1141                         break;
1142
1143                 case ICMD_LMULCONST:  /* ..., value  ==> ..., value * constant        */
1144                                       /* val.l = constant                             */
1145
1146                         var_to_reg_int(s1, src, REG_ITMP1);
1147                         d = reg_of_var(iptr->dst, REG_ITMP3);
1148                         LCONST(REG_ITMP2, iptr->val.l);
1149                         M_LMUL(s1, REG_ITMP2);
1150                         M_MFLO(d);
1151                         M_NOP;
1152                         M_NOP;
1153                         store_reg_to_var_int(iptr->dst, d);
1154                         break;
1155
1156                 case ICMD_IDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1157
1158                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1159                         var_to_reg_int(s2, src, REG_ITMP2);
1160                         d = reg_of_var(iptr->dst, REG_ITMP3);
1161                         M_IDIV(s1, s2);
1162                         M_MFLO(d);
1163                         M_NOP;
1164                         M_NOP;
1165                         store_reg_to_var_int(iptr->dst, d);
1166                         break;
1167 #if 0
1168                 case ICMD_IDIVCONST:  /* ..., value  ==> ..., value / constant        */
1169                                       /* val.i = constant                             */
1170
1171                         var_to_reg_int(s1, src, REG_ITMP1);
1172                         d = reg_of_var(iptr->dst, REG_ITMP3);
1173                         ICONST(REG_ITMP2, iptr->val.i);
1174                         M_IDIV(s1, REG_ITMP2);
1175                         M_MFLO(d);
1176                         M_NOP;
1177                         M_NOP;
1178                         store_reg_to_var_int(iptr->dst, d);
1179                         break;
1180 #endif
1181                 case ICMD_LDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1182
1183                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1184                         var_to_reg_int(s2, src, REG_ITMP2);
1185                         d = reg_of_var(iptr->dst, REG_ITMP3);
1186                         M_LDIV(s1, s2);
1187                         M_MFLO(d);
1188                         M_NOP;
1189                         M_NOP;
1190                         store_reg_to_var_int(iptr->dst, d);
1191                         break;
1192 #if 0
1193                 case ICMD_LDIVCONST:  /* ..., value  ==> ..., value / constant        */
1194                                       /* val.l = constant                             */
1195
1196                         var_to_reg_int(s1, src, REG_ITMP1);
1197                         d = reg_of_var(iptr->dst, REG_ITMP3);
1198                         LCONST(REG_ITMP2, iptr->val.l);
1199                         M_LDIV(s1, REG_ITMP2);
1200                         M_MFLO(d);
1201                         M_NOP;
1202                         M_NOP;
1203                         store_reg_to_var_int(iptr->dst, d);
1204                         break;
1205 #endif
1206                 case ICMD_IREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
1207
1208                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1209                         var_to_reg_int(s2, src, REG_ITMP2);
1210                         d = reg_of_var(iptr->dst, REG_ITMP3);
1211                         M_IDIV(s1, s2);
1212                         M_MFHI(d);
1213                         M_NOP;
1214                         M_NOP;
1215                         store_reg_to_var_int(iptr->dst, d);
1216                         break;
1217 #if 0
1218                 case ICMD_IREMCONST:  /* ..., value  ==> ..., value % constant        */
1219                                       /* val.i = constant                             */
1220
1221                         var_to_reg_int(s1, src, REG_ITMP1);
1222                         d = reg_of_var(iptr->dst, REG_ITMP3);
1223                         ICONST(REG_ITMP2, iptr->val.i);
1224                         M_IDIV(s1, REG_ITMP2);
1225                         M_MFHI(d);
1226                         M_NOP;
1227                         M_NOP;
1228                         store_reg_to_var_int(iptr->dst, d);
1229                         break;
1230 #endif
1231                 case ICMD_LREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
1232
1233                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1234                         var_to_reg_int(s2, src, REG_ITMP2);
1235                         d = reg_of_var(iptr->dst, REG_ITMP3);
1236                         M_LDIV(s1, s2);
1237                         M_MFHI(d);
1238                         M_NOP;
1239                         M_NOP;
1240                         store_reg_to_var_int(iptr->dst, d);
1241                         break;
1242 #if 0
1243                 case ICMD_LREMCONST:  /* ..., value  ==> ..., value % constant        */
1244                                       /* val.l = constant                             */
1245
1246                         var_to_reg_int(s1, src, REG_ITMP1);
1247                         d = reg_of_var(iptr->dst, REG_ITMP3);
1248                         LCONST(REG_ITMP2, iptr->val.l);
1249                         M_LDIV(s1, REG_ITMP2);
1250                         M_MFHI(d);
1251                         M_NOP;
1252                         M_NOP;
1253                         store_reg_to_var_int(iptr->dst, d);
1254                         break;
1255 #endif
1256                 case ICMD_IDIVPOW2:   /* ..., value  ==> ..., value << constant       */
1257                 case ICMD_LDIVPOW2:   /* val.i = constant                             */
1258                                       
1259                         var_to_reg_int(s1, src, REG_ITMP1);
1260                         d = reg_of_var(iptr->dst, REG_ITMP3);
1261                         M_LSRA_IMM(s1, 63, REG_ITMP2);
1262                         M_LSRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
1263                         M_LADD(s1, REG_ITMP2, REG_ITMP2);
1264                         M_LSRA_IMM(REG_ITMP2, iptr->val.i, d);
1265                         store_reg_to_var_int(iptr->dst, d);
1266                         break;
1267
1268                 case ICMD_ISHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
1269
1270                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1271                         var_to_reg_int(s2, src, REG_ITMP2);
1272                         d = reg_of_var(iptr->dst, REG_ITMP3);
1273                         M_ISLL(s1, s2, d);
1274                         store_reg_to_var_int(iptr->dst, d);
1275                         break;
1276
1277                 case ICMD_ISHLCONST:  /* ..., value  ==> ..., value << constant       */
1278                                       /* val.i = constant                             */
1279
1280                         var_to_reg_int(s1, src, REG_ITMP1);
1281                         d = reg_of_var(iptr->dst, REG_ITMP3);
1282                         M_ISLL_IMM(s1, iptr->val.i, d);
1283                         store_reg_to_var_int(iptr->dst, d);
1284                         break;
1285
1286                 case ICMD_ISHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
1287
1288                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1289                         var_to_reg_int(s2, src, REG_ITMP2);
1290                         d = reg_of_var(iptr->dst, REG_ITMP3);
1291                         M_ISRA(s1, s2, d);
1292                         store_reg_to_var_int(iptr->dst, d);
1293                         break;
1294
1295                 case ICMD_ISHRCONST:  /* ..., value  ==> ..., value >> constant       */
1296                                       /* val.i = constant                             */
1297
1298                         var_to_reg_int(s1, src, REG_ITMP1);
1299                         d = reg_of_var(iptr->dst, REG_ITMP3);
1300                         M_ISRA_IMM(s1, iptr->val.i, d);
1301                         store_reg_to_var_int(iptr->dst, d);
1302                         break;
1303
1304                 case ICMD_IUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
1305
1306                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1307                         var_to_reg_int(s2, src, REG_ITMP2);
1308                         d = reg_of_var(iptr->dst, REG_ITMP3);
1309                         M_ISRL(s1, s2, d);
1310                         store_reg_to_var_int(iptr->dst, d);
1311                         break;
1312
1313                 case ICMD_IUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
1314                                       /* val.i = constant                             */
1315
1316                         var_to_reg_int(s1, src, REG_ITMP1);
1317                         d = reg_of_var(iptr->dst, REG_ITMP3);
1318                         M_ISRL_IMM(s1, iptr->val.i, d);
1319                         store_reg_to_var_int(iptr->dst, d);
1320                         break;
1321
1322                 case ICMD_LSHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
1323
1324                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1325                         var_to_reg_int(s2, src, REG_ITMP2);
1326                         d = reg_of_var(iptr->dst, REG_ITMP3);
1327                         M_LSLL(s1, s2, d);
1328                         store_reg_to_var_int(iptr->dst, d);
1329                         break;
1330
1331                 case ICMD_LSHLCONST:  /* ..., value  ==> ..., value << constant       */
1332                                       /* val.i = constant                             */
1333
1334                         var_to_reg_int(s1, src, REG_ITMP1);
1335                         d = reg_of_var(iptr->dst, REG_ITMP3);
1336                         M_LSLL_IMM(s1, iptr->val.i, d);
1337                         store_reg_to_var_int(iptr->dst, d);
1338                         break;
1339
1340                 case ICMD_LSHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
1341
1342                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1343                         var_to_reg_int(s2, src, REG_ITMP2);
1344                         d = reg_of_var(iptr->dst, REG_ITMP3);
1345                         M_LSRA(s1, s2, d);
1346                         store_reg_to_var_int(iptr->dst, d);
1347                         break;
1348
1349                 case ICMD_LSHRCONST:  /* ..., value  ==> ..., value >> constant       */
1350                                       /* val.i = constant                             */
1351
1352                         var_to_reg_int(s1, src, REG_ITMP1);
1353                         d = reg_of_var(iptr->dst, REG_ITMP3);
1354                         M_LSRA_IMM(s1, iptr->val.i, d);
1355                         store_reg_to_var_int(iptr->dst, d);
1356                         break;
1357
1358                 case ICMD_LUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
1359
1360                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1361                         var_to_reg_int(s2, src, REG_ITMP2);
1362                         d = reg_of_var(iptr->dst, REG_ITMP3);
1363                         M_LSRL(s1, s2, d);
1364                         store_reg_to_var_int(iptr->dst, d);
1365                         break;
1366
1367                 case ICMD_LUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
1368                                       /* val.i = constant                             */
1369
1370                         var_to_reg_int(s1, src, REG_ITMP1);
1371                         d = reg_of_var(iptr->dst, REG_ITMP3);
1372                         M_LSRL_IMM(s1, iptr->val.i, d);
1373                         store_reg_to_var_int(iptr->dst, d);
1374                         break;
1375
1376                 case ICMD_IAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
1377                 case ICMD_LAND:
1378
1379                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1380                         var_to_reg_int(s2, src, REG_ITMP2);
1381                         d = reg_of_var(iptr->dst, REG_ITMP3);
1382                         M_AND(s1, s2, d);
1383                         store_reg_to_var_int(iptr->dst, d);
1384                         break;
1385
1386                 case ICMD_IANDCONST:  /* ..., value  ==> ..., value & constant        */
1387                                       /* val.i = constant                             */
1388
1389                         var_to_reg_int(s1, src, REG_ITMP1);
1390                         d = reg_of_var(iptr->dst, REG_ITMP3);
1391                         if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1392                                 M_AND_IMM(s1, iptr->val.i, d);
1393                                 }
1394                         else {
1395                                 ICONST(REG_ITMP2, iptr->val.i);
1396                                 M_AND(s1, REG_ITMP2, d);
1397                                 }
1398                         store_reg_to_var_int(iptr->dst, d);
1399                         break;
1400
1401                 case ICMD_IREMPOW2:   /* ..., value  ==> ..., value % constant        */
1402                                       /* val.i = constant                             */
1403
1404                         var_to_reg_int(s1, src, REG_ITMP1);
1405                         d = reg_of_var(iptr->dst, REG_ITMP3);
1406                         if (s1 == d) {
1407                                 M_MOV(s1, REG_ITMP1);
1408                                 s1 = REG_ITMP1;
1409                                 }
1410                         if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1411                                 M_AND_IMM(s1, iptr->val.i, d);
1412                                 M_BGEZ(s1, 4);
1413                                 M_NOP;
1414                                 M_ISUB(REG_ZERO, s1, d);
1415                                 M_AND_IMM(d, iptr->val.i, d);
1416                                 }
1417                         else {
1418                                 ICONST(REG_ITMP2, iptr->val.i);
1419                                 M_AND(s1, REG_ITMP2, d);
1420                                 M_BGEZ(s1, 4);
1421                                 M_NOP;
1422                                 M_ISUB(REG_ZERO, s1, d);
1423                                 M_AND(d, REG_ITMP2, d);
1424                                 }
1425                         M_ISUB(REG_ZERO, d, d);
1426                         store_reg_to_var_int(iptr->dst, d);
1427                         break;
1428
1429                 case ICMD_IREM0X10001:  /* ..., value  ==> ..., value % 0x100001      */
1430                 
1431 /*          b = value & 0xffff;
1432                         a = value >> 16;
1433                         a = ((b - a) & 0xffff) + (b < a);
1434 */
1435                         var_to_reg_int(s1, src, REG_ITMP1);
1436                         d = reg_of_var(iptr->dst, REG_ITMP3);
1437                         if (s1 == d) {
1438                                 M_MOV(s1, REG_ITMP3);
1439                                 s1 = REG_ITMP3;
1440                                 }
1441                         M_BLTZ(s1, 7);
1442             M_CZEXT(s1, REG_ITMP2);                             /* delay slot */
1443                         M_ISRA_IMM(s1, 16, d);
1444                         M_CMPLT(REG_ITMP2, d, REG_ITMP1);
1445                         M_ISUB(REG_ITMP2, d, d);
1446             M_CZEXT(d, d);
1447                         M_BR(7);
1448                         M_IADD(d, REG_ITMP1, d);                            /* delay slot */
1449
1450                         M_LUI(REG_ITMP2, 1);
1451                         M_IADD_IMM(REG_ITMP2, 1, REG_ITMP2);
1452                         M_IDIV(s1, REG_ITMP2);
1453                         M_MFHI(d);
1454                         M_NOP;
1455                         M_NOP;
1456                         store_reg_to_var_int(iptr->dst, d);
1457                         break;
1458
1459                 case ICMD_LANDCONST:  /* ..., value  ==> ..., value & constant        */
1460                                       /* val.l = constant                             */
1461
1462                         var_to_reg_int(s1, src, REG_ITMP1);
1463                         d = reg_of_var(iptr->dst, REG_ITMP3);
1464                         if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1465                                 M_AND_IMM(s1, iptr->val.l, d);
1466                                 }
1467                         else {
1468                                 LCONST(REG_ITMP2, iptr->val.l);
1469                                 M_AND(s1, REG_ITMP2, d);
1470                                 }
1471                         store_reg_to_var_int(iptr->dst, d);
1472                         break;
1473
1474                 case ICMD_LREMPOW2:   /* ..., value  ==> ..., value % constant        */
1475                                       /* val.l = constant                             */
1476
1477                         var_to_reg_int(s1, src, REG_ITMP1);
1478                         d = reg_of_var(iptr->dst, REG_ITMP3);
1479                         if (s1 == d) {
1480                                 M_MOV(s1, REG_ITMP1);
1481                                 s1 = REG_ITMP1;
1482                                 }
1483                         if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1484                                 M_AND_IMM(s1, iptr->val.l, d);
1485                                 M_BGEZ(s1, 4);
1486                                 M_NOP;
1487                                 M_LSUB(REG_ZERO, s1, d);
1488                                 M_AND_IMM(d, iptr->val.l, d);
1489                                 }
1490                         else {
1491                                 LCONST(REG_ITMP2, iptr->val.l);
1492                                 M_AND(s1, REG_ITMP2, d);
1493                                 M_BGEZ(s1, 4);
1494                                 M_NOP;
1495                                 M_LSUB(REG_ZERO, s1, d);
1496                                 M_AND(d, REG_ITMP2, d);
1497                                 }
1498                         M_LSUB(REG_ZERO, d, d);
1499                         store_reg_to_var_int(iptr->dst, d);
1500                         break;
1501
1502                 case ICMD_LREM0X10001:/* ..., value  ==> ..., value % 0x10001         */
1503
1504                         var_to_reg_int(s1, src, REG_ITMP1);
1505                         d = reg_of_var(iptr->dst, REG_ITMP3);
1506                         M_LUI(REG_ITMP2, 1);
1507                         M_LADD_IMM(REG_ITMP2, 1, REG_ITMP2);
1508                         M_LDIV(s1, REG_ITMP2);
1509                         M_MFHI(d);
1510                         M_NOP;
1511                         M_NOP;
1512                         store_reg_to_var_int(iptr->dst, d);
1513                         break;
1514
1515                 case ICMD_IOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
1516                 case ICMD_LOR:
1517
1518                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1519                         var_to_reg_int(s2, src, REG_ITMP2);
1520                         d = reg_of_var(iptr->dst, REG_ITMP3);
1521                         M_OR( s1,s2, d);
1522                         store_reg_to_var_int(iptr->dst, d);
1523                         break;
1524
1525                 case ICMD_IORCONST:   /* ..., value  ==> ..., value | constant        */
1526                                       /* val.i = constant                             */
1527
1528                         var_to_reg_int(s1, src, REG_ITMP1);
1529                         d = reg_of_var(iptr->dst, REG_ITMP3);
1530                         if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1531                                 M_OR_IMM(s1, iptr->val.i, d);
1532                                 }
1533                         else {
1534                                 ICONST(REG_ITMP2, iptr->val.i);
1535                                 M_OR(s1, REG_ITMP2, d);
1536                                 }
1537                         store_reg_to_var_int(iptr->dst, d);
1538                         break;
1539
1540                 case ICMD_LORCONST:   /* ..., value  ==> ..., value | constant        */
1541                                       /* val.l = constant                             */
1542
1543                         var_to_reg_int(s1, src, REG_ITMP1);
1544                         d = reg_of_var(iptr->dst, REG_ITMP3);
1545                         if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1546                                 M_OR_IMM(s1, iptr->val.l, d);
1547                                 }
1548                         else {
1549                                 LCONST(REG_ITMP2, iptr->val.l);
1550                                 M_OR(s1, REG_ITMP2, d);
1551                                 }
1552                         store_reg_to_var_int(iptr->dst, d);
1553                         break;
1554
1555                 case ICMD_IXOR:       /* ..., val1, val2  ==> ..., val1 ^ val2        */
1556                 case ICMD_LXOR:
1557
1558                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1559                         var_to_reg_int(s2, src, REG_ITMP2);
1560                         d = reg_of_var(iptr->dst, REG_ITMP3);
1561                         M_XOR(s1, s2, d);
1562                         store_reg_to_var_int(iptr->dst, d);
1563                         break;
1564
1565                 case ICMD_IXORCONST:  /* ..., value  ==> ..., value ^ constant        */
1566                                       /* val.i = constant                             */
1567
1568                         var_to_reg_int(s1, src, REG_ITMP1);
1569                         d = reg_of_var(iptr->dst, REG_ITMP3);
1570                         if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1571                                 M_XOR_IMM(s1, iptr->val.i, d);
1572                                 }
1573                         else {
1574                                 ICONST(REG_ITMP2, iptr->val.i);
1575                                 M_XOR(s1, REG_ITMP2, d);
1576                                 }
1577                         store_reg_to_var_int(iptr->dst, d);
1578                         break;
1579
1580                 case ICMD_LXORCONST:  /* ..., value  ==> ..., value ^ constant        */
1581                                       /* val.l = constant                             */
1582
1583                         var_to_reg_int(s1, src, REG_ITMP1);
1584                         d = reg_of_var(iptr->dst, REG_ITMP3);
1585                         if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1586                                 M_XOR_IMM(s1, iptr->val.l, d);
1587                                 }
1588                         else {
1589                                 LCONST(REG_ITMP2, iptr->val.l);
1590                                 M_XOR(s1, REG_ITMP2, d);
1591                                 }
1592                         store_reg_to_var_int(iptr->dst, d);
1593                         break;
1594
1595
1596                 case ICMD_LCMP:       /* ..., val1, val2  ==> ..., val1 cmp val2      */
1597
1598                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1599                         var_to_reg_int(s2, src, REG_ITMP2);
1600                         d = reg_of_var(iptr->dst, REG_ITMP3);
1601                         M_CMPLT(s1, s2, REG_ITMP3);
1602                         M_CMPLT(s2, s1, REG_ITMP1);
1603                         M_LSUB (REG_ITMP1, REG_ITMP3, d);
1604                         store_reg_to_var_int(iptr->dst, d);
1605                         break;
1606
1607
1608                 case ICMD_IINC:       /* ..., value  ==> ..., value + constant        */
1609                                       /* op1 = variable, val.i = constant             */
1610
1611                         var = &(locals[iptr->op1][TYPE_INT]);
1612                         if (var->flags & INMEMORY) {
1613                                 s1 = REG_ITMP1;
1614                                 M_LLD(s1, REG_SP, 8 * var->regoff);
1615                                 }
1616                         else
1617                                 s1 = var->regoff;
1618                         M_IADD_IMM(s1, iptr->val.i, s1);
1619                         if (var->flags & INMEMORY)
1620                                 M_LST(s1, REG_SP, 8 * var->regoff);
1621                         break;
1622
1623
1624                 /* floating operations ************************************************/
1625
1626                 case ICMD_FNEG:       /* ..., value  ==> ..., - value                 */
1627
1628                         var_to_reg_flt(s1, src, REG_FTMP1);
1629                         d = reg_of_var(iptr->dst, REG_FTMP3);
1630                         M_FNEG(s1, d);
1631                         store_reg_to_var_flt(iptr->dst, d);
1632                         break;
1633
1634                 case ICMD_DNEG:       /* ..., value  ==> ..., - value                 */
1635
1636                         var_to_reg_flt(s1, src, REG_FTMP1);
1637                         d = reg_of_var(iptr->dst, REG_FTMP3);
1638                         M_DNEG(s1, d);
1639                         store_reg_to_var_flt(iptr->dst, d);
1640                         break;
1641
1642                 case ICMD_FADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
1643
1644                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1645                         var_to_reg_flt(s2, src, REG_FTMP2);
1646                         d = reg_of_var(iptr->dst, REG_FTMP3);
1647                         M_FADD(s1, s2, d);
1648                         store_reg_to_var_flt(iptr->dst, d);
1649                         break;
1650
1651                 case ICMD_DADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
1652
1653                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1654                         var_to_reg_flt(s2, src, REG_FTMP2);
1655                         d = reg_of_var(iptr->dst, REG_FTMP3);
1656                         M_DADD(s1, s2, d);
1657                         store_reg_to_var_flt(iptr->dst, d);
1658                         break;
1659
1660                 case ICMD_FSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
1661
1662                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1663                         var_to_reg_flt(s2, src, REG_FTMP2);
1664                         d = reg_of_var(iptr->dst, REG_FTMP3);
1665                         M_FSUB(s1, s2, d);
1666                         store_reg_to_var_flt(iptr->dst, d);
1667                         break;
1668
1669                 case ICMD_DSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
1670
1671                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1672                         var_to_reg_flt(s2, src, REG_FTMP2);
1673                         d = reg_of_var(iptr->dst, REG_FTMP3);
1674                         M_DSUB(s1, s2, d);
1675                         store_reg_to_var_flt(iptr->dst, d);
1676                         break;
1677
1678                 case ICMD_FMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
1679
1680                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1681                         var_to_reg_flt(s2, src, REG_FTMP2);
1682                         d = reg_of_var(iptr->dst, REG_FTMP3);
1683                         M_FMUL(s1, s2, d);
1684                         store_reg_to_var_flt(iptr->dst, d);
1685                         break;
1686
1687                 case ICMD_DMUL:       /* ..., val1, val2  ==> ..., val1 *** val2        */
1688
1689                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1690                         var_to_reg_flt(s2, src, REG_FTMP2);
1691                         d = reg_of_var(iptr->dst, REG_FTMP3);
1692                         M_DMUL(s1, s2, d);
1693                         store_reg_to_var_flt(iptr->dst, d);
1694                         break;
1695
1696                 case ICMD_FDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1697
1698                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1699                         var_to_reg_flt(s2, src, REG_FTMP2);
1700                         d = reg_of_var(iptr->dst, REG_FTMP3);
1701                         M_FDIV(s1, s2, d);
1702                         store_reg_to_var_flt(iptr->dst, d);
1703                         break;
1704
1705                 case ICMD_DDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1706
1707                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1708                         var_to_reg_flt(s2, src, REG_FTMP2);
1709                         d = reg_of_var(iptr->dst, REG_FTMP3);
1710                         M_DDIV(s1, s2, d);
1711                         store_reg_to_var_flt(iptr->dst, d);
1712                         break;
1713                 
1714                 case ICMD_FREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
1715                         panic("FREM");
1716
1717                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1718                         var_to_reg_flt(s2, src, REG_FTMP2);
1719                         d = reg_of_var(iptr->dst, REG_FTMP3);
1720                         M_FDIV(s1,s2, REG_FTMP3);
1721                         M_FLOORFL(REG_FTMP3, REG_FTMP3);
1722                         M_CVTLF(REG_FTMP3, REG_FTMP3);
1723                         M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1724                         M_FSUB(s1, REG_FTMP3, d);
1725                         store_reg_to_var_flt(iptr->dst, d);
1726                     break;
1727
1728                 case ICMD_DREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
1729
1730                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1731                         var_to_reg_flt(s2, src, REG_FTMP2);
1732                         d = reg_of_var(iptr->dst, REG_FTMP3);
1733                         M_DDIV(s1,s2, REG_FTMP3);
1734                         M_FLOORDL(REG_FTMP3, REG_FTMP3);
1735                         M_CVTLD(REG_FTMP3, REG_FTMP3);
1736                         M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1737                         M_DSUB(s1, REG_FTMP3, d);
1738                         store_reg_to_var_flt(iptr->dst, d);
1739                     break;
1740
1741                 case ICMD_I2F:       /* ..., value  ==> ..., (float) value            */
1742                 case ICMD_L2F:
1743                         var_to_reg_int(s1, src, REG_ITMP1);
1744                         d = reg_of_var(iptr->dst, REG_FTMP3);
1745                         M_MOVLD(s1, d);
1746                         M_CVTLF(d, d);
1747                         store_reg_to_var_flt(iptr->dst, d);
1748                         break;
1749
1750                 case ICMD_I2D:       /* ..., value  ==> ..., (double) value           */
1751                 case ICMD_L2D:
1752                         var_to_reg_int(s1, src, REG_ITMP1);
1753                         d = reg_of_var(iptr->dst, REG_FTMP3);
1754                         M_MOVLD(s1, d);
1755                         M_CVTLD(d, d);
1756                         store_reg_to_var_flt(iptr->dst, d);
1757                         break;
1758                         
1759                 case ICMD_F2I:       /* ..., (float) value  ==> ..., (int) value      */
1760
1761                         var_to_reg_flt(s1, src, REG_FTMP1);
1762                         d = reg_of_var(iptr->dst, REG_ITMP3);
1763                         M_TRUNCFI(s1, REG_FTMP1);
1764                         M_MOVDI(REG_FTMP1, d);
1765                         M_NOP;
1766                         store_reg_to_var_int(iptr->dst, d);
1767                         break;
1768                 
1769                 case ICMD_D2I:       /* ..., (double) value  ==> ..., (int) value     */
1770
1771                         var_to_reg_flt(s1, src, REG_FTMP1);
1772                         d = reg_of_var(iptr->dst, REG_ITMP3);
1773                         M_TRUNCDI(s1, REG_FTMP1);
1774                         M_MOVDI(REG_FTMP1, d);
1775                         M_NOP;
1776                         store_reg_to_var_int(iptr->dst, d);
1777                         break;
1778                 
1779                 case ICMD_F2L:       /* ..., (float) value  ==> ..., (long) value     */
1780
1781                         var_to_reg_flt(s1, src, REG_FTMP1);
1782                         d = reg_of_var(iptr->dst, REG_ITMP3);
1783                         M_TRUNCFL(s1, REG_FTMP1);
1784                         M_MOVDL(REG_FTMP1, d);
1785                         M_NOP;
1786                         store_reg_to_var_int(iptr->dst, d);
1787                         break;
1788
1789                 case ICMD_D2L:       /* ..., (double) value  ==> ..., (long) value    */
1790
1791                         var_to_reg_flt(s1, src, REG_FTMP1);
1792                         d = reg_of_var(iptr->dst, REG_ITMP3);
1793                         M_TRUNCDL(s1, REG_FTMP1);
1794                         M_MOVDL(REG_FTMP1, d);
1795                         M_NOP;
1796                         store_reg_to_var_int(iptr->dst, d);
1797                         break;
1798
1799                 case ICMD_F2D:       /* ..., value  ==> ..., (double) value           */
1800
1801                         var_to_reg_flt(s1, src, REG_FTMP1);
1802                         d = reg_of_var(iptr->dst, REG_FTMP3);
1803                         M_CVTFD(s1, d);
1804                         store_reg_to_var_flt(iptr->dst, d);
1805                         break;
1806                                         
1807                 case ICMD_D2F:       /* ..., value  ==> ..., (double) value           */
1808
1809                         var_to_reg_flt(s1, src, REG_FTMP1);
1810                         d = reg_of_var(iptr->dst, REG_FTMP3);
1811                         M_CVTDF(s1, d);
1812                         store_reg_to_var_flt(iptr->dst, d);
1813                         break;
1814                 
1815                 case ICMD_FCMPL:      /* ..., val1, val2  ==> ..., val1 fcmpl val2    */
1816
1817                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1818                         var_to_reg_flt(s2, src, REG_FTMP2);
1819                         d = reg_of_var(iptr->dst, REG_ITMP3);
1820                         M_FCMPUEQF(s1, s2);
1821                         M_NOP;                             /* compare delay               */
1822                         M_FBF(2);                          /* jump over next instructions */
1823                         M_LSUB_IMM(REG_ZERO, 1, d);        /* delay slot                  */
1824                         M_CLR(d);
1825                         M_FCMPULTF(s2, s1);
1826                         M_NOP;                             /* compare delay               */
1827                         M_FBF(2);                          /* jump over next instruction  */
1828                         M_NOP;
1829                         M_LADD_IMM(REG_ZERO, 1, d);
1830                         store_reg_to_var_int(iptr->dst, d);
1831                         break;
1832                         
1833                 case ICMD_DCMPL:      /* ..., val1, val2  ==> ..., val1 fcmpl val2    */
1834
1835                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1836                         var_to_reg_flt(s2, src, REG_FTMP2);
1837                         d = reg_of_var(iptr->dst, REG_ITMP3);
1838                         M_FCMPUEQD(s1, s2);
1839                         M_NOP;                             /* compare delay               */
1840                         M_FBF(2);                          /* jump over next instructions */
1841                         M_LSUB_IMM(REG_ZERO, 1, d);        /* delay slot                  */
1842                         M_CLR(d);
1843                         M_FCMPULTD(s2, s1);
1844                         M_NOP;                             /* compare delay               */
1845                         M_FBF(2);                          /* jump over next instruction  */
1846                         M_NOP;
1847                         M_LADD_IMM(REG_ZERO, 1, d);
1848                         store_reg_to_var_int(iptr->dst, d);
1849                         break;
1850                         
1851                 case ICMD_FCMPG:      /* ..., val1, val2  ==> ..., val1 fcmpg val2    */
1852
1853                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1854                         var_to_reg_flt(s2, src, REG_FTMP2);
1855                         d = reg_of_var(iptr->dst, REG_ITMP3);
1856                         M_FCMPUEQF(s1, s2);
1857                         M_NOP;                             /* compare delay               */
1858                         M_FBF(2);                          /* jump over next instruction  */
1859                         M_LADD_IMM(REG_ZERO, 1, d);        /* delay slot                  */
1860                         M_CLR(d);
1861                         M_FCMPULTF(s1, s2);
1862                         M_NOP;                             /* compare delay               */
1863                         M_FBF(2);                          /* jump over next instruction  */
1864                         M_NOP;
1865                         M_LSUB_IMM(REG_ZERO, 1, d);
1866                         store_reg_to_var_int(iptr->dst, d);
1867                         break;
1868
1869                 case ICMD_DCMPG:      /* ..., val1, val2  ==> ..., val1 fcmpg val2    */
1870
1871                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1872                         var_to_reg_flt(s2, src, REG_FTMP2);
1873                         d = reg_of_var(iptr->dst, REG_ITMP3);
1874                         M_FCMPUEQD(s1, s2);
1875                         M_NOP;                             /* compare delay               */
1876                         M_FBF(2);                          /* jump over next instruction  */
1877                         M_LADD_IMM(REG_ZERO, 1, d);        /* delay slot                  */
1878                         M_CLR(d);
1879                         M_FCMPULTD(s1, s2);
1880                         M_NOP;                             /* compare delay               */
1881                         M_FBF(2);                          /* jump over next instruction  */
1882                         M_NOP;
1883                         M_LSUB_IMM(REG_ZERO, 1, d);
1884                         store_reg_to_var_int(iptr->dst, d);
1885                         break;
1886
1887
1888                 /* memory operations **************************************************/
1889
1890 #define gen_bound_check \
1891                         if (checkbounds) {\
1892                                 M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\
1893                                 M_CMPULT(s2, REG_ITMP3, REG_ITMP3);\
1894                                 M_BEQZ(REG_ITMP3, 0);\
1895                                 codegen_addxboundrefs(mcodeptr);\
1896                                 M_NOP;\
1897                                 }
1898
1899                 case ICMD_ARRAYLENGTH: /* ..., arrayref  ==> ..., length              */
1900
1901                         var_to_reg_int(s1, src, REG_ITMP1);
1902                         d = reg_of_var(iptr->dst, REG_ITMP3);
1903                         gen_nullptr_check(s1);
1904                         M_ILD(d, s1, OFFSET(java_arrayheader, size));
1905                         store_reg_to_var_int(iptr->dst, d);
1906                         break;
1907
1908                 case ICMD_AALOAD:     /* ..., arrayref, index  ==> ..., value         */
1909
1910                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1911                         var_to_reg_int(s2, src, REG_ITMP2);
1912                         d = reg_of_var(iptr->dst, REG_ITMP3);
1913                         if (iptr->op1 == 0) {
1914                                 gen_nullptr_check(s1);
1915                                 gen_bound_check;
1916                                 }
1917                         M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1918                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1919                         M_ALD(d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1920                         store_reg_to_var_int(iptr->dst, d);
1921                         break;
1922
1923                 case ICMD_IALOAD:     /* ..., arrayref, index  ==> ..., value         */
1924
1925                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1926                         var_to_reg_int(s2, src, REG_ITMP2);
1927                         d = reg_of_var(iptr->dst, REG_ITMP3);
1928                         if (iptr->op1 == 0) {
1929                                 gen_nullptr_check(s1);
1930                                 gen_bound_check;
1931                                 }
1932                         M_ASLL_IMM(s2, 2, REG_ITMP2);
1933                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1934                         M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1935                         store_reg_to_var_int(iptr->dst, d);
1936                         break;
1937
1938                 case ICMD_LALOAD:     /* ..., arrayref, index  ==> ..., value         */
1939
1940                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1941                         var_to_reg_int(s2, src, REG_ITMP2);
1942                         d = reg_of_var(iptr->dst, REG_ITMP3);
1943                         if (iptr->op1 == 0) {
1944                                 gen_nullptr_check(s1);
1945                                 gen_bound_check;
1946                                 }
1947                         M_ASLL_IMM(s2, 3, REG_ITMP2);
1948                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1949                         M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1950                         store_reg_to_var_int(iptr->dst, d);
1951                         break;
1952
1953                 case ICMD_FALOAD:     /* ..., arrayref, index  ==> ..., value         */
1954
1955                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1956                         var_to_reg_int(s2, src, REG_ITMP2);
1957                         d = reg_of_var(iptr->dst, REG_FTMP3);
1958                         if (iptr->op1 == 0) {
1959                                 gen_nullptr_check(s1);
1960                                 gen_bound_check;
1961                                 }
1962                         M_ASLL_IMM(s2, 2, REG_ITMP2);
1963                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1964                         M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1965                         store_reg_to_var_flt(iptr->dst, d);
1966                         break;
1967
1968                 case ICMD_DALOAD:     /* ..., arrayref, index  ==> ..., value         */
1969
1970                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1971                         var_to_reg_int(s2, src, REG_ITMP2);
1972                         d = reg_of_var(iptr->dst, REG_FTMP3);
1973                         if (iptr->op1 == 0) {
1974                                 gen_nullptr_check(s1);
1975                                 gen_bound_check;
1976                                 }
1977                         M_ASLL_IMM(s2, 3, REG_ITMP2);
1978                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1979                         M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1980                         store_reg_to_var_flt(iptr->dst, d);
1981                         break;
1982
1983                 case ICMD_CALOAD:     /* ..., arrayref, index  ==> ..., value         */
1984
1985                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1986                         var_to_reg_int(s2, src, REG_ITMP2);
1987                         d = reg_of_var(iptr->dst, REG_ITMP3);
1988                         if (iptr->op1 == 0) {
1989                                 gen_nullptr_check(s1);
1990                                 gen_bound_check;
1991                                 }
1992                         M_AADD(s2, s1, REG_ITMP1);
1993                         M_AADD(s2, REG_ITMP1, REG_ITMP1);
1994                         M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1995                         store_reg_to_var_int(iptr->dst, d);
1996                         break;                  
1997
1998                 case ICMD_SALOAD:     /* ..., arrayref, index  ==> ..., value         */
1999
2000                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2001                         var_to_reg_int(s2, src, REG_ITMP2);
2002                         d = reg_of_var(iptr->dst, REG_ITMP3);
2003                         if (iptr->op1 == 0) {
2004                                 gen_nullptr_check(s1);
2005                                 gen_bound_check;
2006                                 }
2007                         M_AADD(s2, s1, REG_ITMP1);
2008                         M_AADD(s2, REG_ITMP1, REG_ITMP1);
2009                         M_SLDS(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
2010                         store_reg_to_var_int(iptr->dst, d);
2011                         break;
2012
2013                 case ICMD_BALOAD:     /* ..., arrayref, index  ==> ..., value         */
2014
2015                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2016                         var_to_reg_int(s2, src, REG_ITMP2);
2017                         d = reg_of_var(iptr->dst, REG_ITMP3);
2018                         if (iptr->op1 == 0) {
2019                                 gen_nullptr_check(s1);
2020                                 gen_bound_check;
2021                                 }
2022                         M_AADD(s2, s1, REG_ITMP1);
2023                         M_BLDS(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
2024                         store_reg_to_var_int(iptr->dst, d);
2025                         break;
2026
2027
2028                 case ICMD_AASTORE:    /* ..., arrayref, index, value  ==> ...         */
2029
2030                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2031                         var_to_reg_int(s2, src->prev, REG_ITMP2);
2032                         if (iptr->op1 == 0) {
2033                                 gen_nullptr_check(s1);
2034                                 gen_bound_check;
2035                                 }
2036                         var_to_reg_int(s3, src, REG_ITMP3);
2037                         M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
2038                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
2039                         M_AST(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
2040                         break;
2041
2042                 case ICMD_IASTORE:    /* ..., arrayref, index, value  ==> ...         */
2043
2044                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2045                         var_to_reg_int(s2, src->prev, REG_ITMP2);
2046                         if (iptr->op1 == 0) {
2047                                 gen_nullptr_check(s1);
2048                                 gen_bound_check;
2049                                 }
2050                         var_to_reg_int(s3, src, REG_ITMP3);
2051                         M_ASLL_IMM(s2, 2, REG_ITMP2);
2052                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
2053                         M_IST(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
2054                         break;
2055
2056                 case ICMD_LASTORE:    /* ..., arrayref, index, value  ==> ...         */
2057
2058                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2059                         var_to_reg_int(s2, src->prev, REG_ITMP2);
2060                         if (iptr->op1 == 0) {
2061                                 gen_nullptr_check(s1);
2062                                 gen_bound_check;
2063                                 }
2064                         var_to_reg_int(s3, src, REG_ITMP3);
2065                         M_ASLL_IMM(s2, 3, REG_ITMP2);
2066                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
2067                         M_LST(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
2068                         break;
2069
2070                 case ICMD_FASTORE:    /* ..., arrayref, index, value  ==> ...         */
2071
2072                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2073                         var_to_reg_int(s2, src->prev, REG_ITMP2);
2074                         if (iptr->op1 == 0) {
2075                                 gen_nullptr_check(s1);
2076                                 gen_bound_check;
2077                                 }
2078                         var_to_reg_flt(s3, src, REG_FTMP3);
2079                         M_ASLL_IMM(s2, 2, REG_ITMP2);
2080                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
2081                         M_FST(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
2082                         break;
2083
2084                 case ICMD_DASTORE:    /* ..., arrayref, index, value  ==> ...         */
2085
2086                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2087                         var_to_reg_int(s2, src->prev, REG_ITMP2);
2088                         if (iptr->op1 == 0) {
2089                                 gen_nullptr_check(s1);
2090                                 gen_bound_check;
2091                                 }
2092                         var_to_reg_flt(s3, src, REG_FTMP3);
2093                         M_ASLL_IMM(s2, 3, REG_ITMP2);
2094                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
2095                         M_DST(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
2096                         break;
2097
2098                 case ICMD_CASTORE:    /* ..., arrayref, index, value  ==> ...         */
2099                 case ICMD_SASTORE:    /* ..., arrayref, index, value  ==> ...         */
2100
2101                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2102                         var_to_reg_int(s2, src->prev, REG_ITMP2);
2103                         if (iptr->op1 == 0) {
2104                                 gen_nullptr_check(s1);
2105                                 gen_bound_check;
2106                                 }
2107                         var_to_reg_int(s3, src, REG_ITMP3);
2108                         M_AADD(s2, s1, REG_ITMP1);
2109                         M_AADD(s2, REG_ITMP1, REG_ITMP1);
2110                         M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
2111                         break;
2112
2113                 case ICMD_BASTORE:    /* ..., arrayref, index, value  ==> ...         */
2114
2115                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2116                         var_to_reg_int(s2, src->prev, REG_ITMP2);
2117                         if (iptr->op1 == 0) {
2118                                 gen_nullptr_check(s1);
2119                                 gen_bound_check;
2120                                 }
2121                         var_to_reg_int(s3, src, REG_ITMP3);
2122                         M_AADD(s2, s1, REG_ITMP1);
2123                         M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2124                         break;
2125
2126
2127                 case ICMD_PUTSTATIC:  /* ..., value  ==> ...                          */
2128                                       /* op1 = type, val.a = field address            */
2129
2130                         a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value));
2131                         M_ALD(REG_ITMP1, REG_PV, a);
2132                         switch (iptr->op1) {
2133                                 case TYPE_INT:
2134                                         var_to_reg_int(s2, src, REG_ITMP2);
2135                                         M_IST(s2, REG_ITMP1, 0);
2136                                         break;
2137                                 case TYPE_LNG:
2138                                         var_to_reg_int(s2, src, REG_ITMP2);
2139                                         M_LST(s2, REG_ITMP1, 0);
2140                                         break;
2141                                 case TYPE_ADR:
2142                                         var_to_reg_int(s2, src, REG_ITMP2);
2143                                         M_AST(s2, REG_ITMP1, 0);
2144                                         break;
2145                                 case TYPE_FLT:
2146                                         var_to_reg_flt(s2, src, REG_FTMP2);
2147                                         M_FST(s2, REG_ITMP1, 0);
2148                                         break;
2149                                 case TYPE_DBL:
2150                                         var_to_reg_flt(s2, src, REG_FTMP2);
2151                                         M_DST(s2, REG_ITMP1, 0);
2152                                         break;
2153                                 default: panic ("internal error");
2154                                 }
2155                         break;
2156
2157                 case ICMD_GETSTATIC:  /* ...  ==> ..., value                          */
2158                                       /* op1 = type, val.a = field address            */
2159
2160                         a = dseg_addaddress (&(((fieldinfo *)(iptr->val.a))->value));
2161                         M_ALD(REG_ITMP1, REG_PV, a);
2162                         switch (iptr->op1) {
2163                                 case TYPE_INT:
2164                                         d = reg_of_var(iptr->dst, REG_ITMP3);
2165                                         M_ILD(d, REG_ITMP1, 0);
2166                                         store_reg_to_var_int(iptr->dst, d);
2167                                         break;
2168                                 case TYPE_LNG:
2169                                         d = reg_of_var(iptr->dst, REG_ITMP3);
2170                                         M_LLD(d, REG_ITMP1, 0);
2171                                         store_reg_to_var_int(iptr->dst, d);
2172                                         break;
2173                                 case TYPE_ADR:
2174                                         d = reg_of_var(iptr->dst, REG_ITMP3);
2175                                         M_ALD(d, REG_ITMP1, 0);
2176                                         store_reg_to_var_int(iptr->dst, d);
2177                                         break;
2178                                 case TYPE_FLT:
2179                                         d = reg_of_var(iptr->dst, REG_FTMP1);
2180                                         M_FLD(d, REG_ITMP1, 0);
2181                                         store_reg_to_var_flt(iptr->dst, d);
2182                                         break;
2183                                 case TYPE_DBL:                          
2184                                         d = reg_of_var(iptr->dst, REG_FTMP1);
2185                                         M_DLD(d, REG_ITMP1, 0);
2186                                         store_reg_to_var_flt(iptr->dst, d);
2187                                         break;
2188                                 default: panic ("internal error");
2189                                 }
2190                         break;
2191
2192
2193                 case ICMD_PUTFIELD:   /* ..., value  ==> ...                          */
2194                                       /* op1 = type, val.i = field offset             */
2195
2196                         a = ((fieldinfo *)(iptr->val.a))->offset;
2197                         switch (iptr->op1) {
2198                                 case TYPE_INT:
2199                                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2200                                         var_to_reg_int(s2, src, REG_ITMP2);
2201                                         gen_nullptr_check(s1);
2202                                         M_IST(s2, s1, a);
2203                                         break;
2204                                 case TYPE_LNG:
2205                                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2206                                         var_to_reg_int(s2, src, REG_ITMP2);
2207                                         gen_nullptr_check(s1);
2208                                         M_LST(s2, s1, a);
2209                                         break;
2210                                 case TYPE_ADR:
2211                                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2212                                         var_to_reg_int(s2, src, REG_ITMP2);
2213                                         gen_nullptr_check(s1);
2214                                         M_AST(s2, s1, a);
2215                                         break;
2216                                 case TYPE_FLT:
2217                                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2218                                         var_to_reg_flt(s2, src, REG_FTMP2);
2219                                         gen_nullptr_check(s1);
2220                                         M_FST(s2, s1, a);
2221                                         break;
2222                                 case TYPE_DBL:
2223                                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2224                                         var_to_reg_flt(s2, src, REG_FTMP2);
2225                                         gen_nullptr_check(s1);
2226                                         M_DST(s2, s1, a);
2227                                         break;
2228                                 default: panic ("internal error");
2229                                 }
2230                         break;
2231
2232                 case ICMD_GETFIELD:   /* ...  ==> ..., value                          */
2233                                       /* op1 = type, val.i = field offset             */
2234
2235                         a = ((fieldinfo *)(iptr->val.a))->offset;
2236                         switch (iptr->op1) {
2237                                 case TYPE_INT:
2238                                         var_to_reg_int(s1, src, REG_ITMP1);
2239                                         d = reg_of_var(iptr->dst, REG_ITMP3);
2240                                         gen_nullptr_check(s1);
2241                                         M_ILD(d, s1, a);
2242                                         store_reg_to_var_int(iptr->dst, d);
2243                                         break;
2244                                 case TYPE_LNG:
2245                                         var_to_reg_int(s1, src, REG_ITMP1);
2246                                         d = reg_of_var(iptr->dst, REG_ITMP3);
2247                                         gen_nullptr_check(s1);
2248                                         M_LLD(d, s1, a);
2249                                         store_reg_to_var_int(iptr->dst, d);
2250                                         break;
2251                                 case TYPE_ADR:
2252                                         var_to_reg_int(s1, src, REG_ITMP1);
2253                                         d = reg_of_var(iptr->dst, REG_ITMP3);
2254                                         gen_nullptr_check(s1);
2255                                         M_ALD(d, s1, a);
2256                                         store_reg_to_var_int(iptr->dst, d);
2257                                         break;
2258                                 case TYPE_FLT:
2259                                         var_to_reg_int(s1, src, REG_ITMP1);
2260                                         d = reg_of_var(iptr->dst, REG_FTMP1);
2261                                         gen_nullptr_check(s1);
2262                                         M_FLD(d, s1, a);
2263                                         store_reg_to_var_flt(iptr->dst, d);
2264                                         break;
2265                                 case TYPE_DBL:                          
2266                                         var_to_reg_int(s1, src, REG_ITMP1);
2267                                         d = reg_of_var(iptr->dst, REG_FTMP1);
2268                                         gen_nullptr_check(s1);
2269                                         M_DLD(d, s1, a);
2270                                         store_reg_to_var_flt(iptr->dst, d);
2271                                         break;
2272                                 default: panic ("internal error");
2273                                 }
2274                         break;
2275
2276
2277                 /* branch operations **************************************************/
2278
2279 #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}}
2280
2281                 case ICMD_ATHROW:       /* ..., objectref ==> ... (, objectref)       */
2282
2283                         var_to_reg_int(s1, src, REG_ITMP1);
2284                         M_INTMOVE(s1, REG_ITMP1_XPTR);
2285                         a = dseg_addaddress(asm_handle_exception);
2286                         M_ALD(REG_ITMP2, REG_PV, a);
2287                         M_JSR(REG_ITMP2_XPC, REG_ITMP2);
2288                         M_NOP;
2289                         M_NOP;              /* nop ensures that XPC is less than the end */
2290                                             /* of basic block                            */
2291                         ALIGNCODENOP;
2292                         break;
2293
2294                 case ICMD_GOTO:         /* ... ==> ...                                */
2295                                         /* op1 = target JavaVM pc                     */
2296                         M_BR(0);
2297                         codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2298                         M_NOP;
2299                         ALIGNCODENOP;
2300                         break;
2301
2302                 case ICMD_JSR:          /* ... ==> ...                                */
2303                                         /* op1 = target JavaVM pc                     */
2304
2305                         dseg_addtarget(BlockPtrOfPC(iptr->op1));
2306                         M_ALD(REG_ITMP1, REG_PV, -dseglen);
2307                         M_JSR(REG_ITMP1, REG_ITMP1);        /* REG_ITMP1 = return address */
2308                         M_NOP;
2309                         break;
2310                         
2311                 case ICMD_RET:          /* ... ==> ...                                */
2312                                         /* op1 = local variable                       */
2313                         var = &(locals[iptr->op1][TYPE_ADR]);
2314                         if (var->flags & INMEMORY) {
2315                                 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2316                                 M_RET(REG_ITMP1);
2317                                 }
2318                         else
2319                                 M_RET(var->regoff);
2320                         M_NOP;
2321                         ALIGNCODENOP;
2322                         break;
2323
2324                 case ICMD_IFNULL:       /* ..., value ==> ...                         */
2325                                         /* op1 = target JavaVM pc                     */
2326
2327                         var_to_reg_int(s1, src, REG_ITMP1);
2328                         M_BEQZ(s1, 0);
2329                         codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2330                         M_NOP;
2331                         break;
2332
2333                 case ICMD_IFNONNULL:    /* ..., value ==> ...                         */
2334                                         /* op1 = target JavaVM pc                     */
2335
2336                         var_to_reg_int(s1, src, REG_ITMP1);
2337                         M_BNEZ(s1, 0);
2338                         codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2339                         M_NOP;
2340                         break;
2341
2342                 case ICMD_IFEQ:         /* ..., value ==> ...                         */
2343                                         /* op1 = target JavaVM pc, val.i = constant   */
2344
2345                         var_to_reg_int(s1, src, REG_ITMP1);
2346                         if (iptr->val.i == 0) {
2347                                 M_BEQZ(s1, 0);
2348                                 }
2349                         else {
2350                                 ICONST(REG_ITMP2, iptr->val.i);
2351                                 M_BEQ(s1, REG_ITMP2, 0);
2352                                 }
2353                         codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2354                         M_NOP;
2355                         break;
2356
2357                 case ICMD_IFLT:         /* ..., value ==> ...                         */
2358                                         /* op1 = target JavaVM pc, val.i = constant   */
2359
2360                         var_to_reg_int(s1, src, REG_ITMP1);
2361                         if (iptr->val.i == 0) {
2362                                 M_BLTZ(s1, 0);
2363                                 }
2364                         else {
2365                                 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
2366                                         M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2367                                         }
2368                                 else {
2369                                         ICONST(REG_ITMP2, iptr->val.i);
2370                                         M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2371                                         }
2372                                 M_BNEZ(REG_ITMP1, 0);
2373                                 }
2374                         codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2375                         M_NOP;
2376                         break;
2377
2378                 case ICMD_IFLE:         /* ..., value ==> ...                         */
2379                                         /* op1 = target JavaVM pc, val.i = constant   */
2380
2381                         var_to_reg_int(s1, src, REG_ITMP1);
2382                         if (iptr->val.i == 0) {
2383                                 M_BLEZ(s1, 0);
2384                                 }
2385                         else {
2386                                 if ((iptr->val.i >= -32769) && (iptr->val.i <= 32766)) {
2387                                         M_CMPLT_IMM(s1, iptr->val.i + 1, REG_ITMP1);
2388                                         M_BNEZ(REG_ITMP1, 0);
2389                                         }
2390                                 else {
2391                                         ICONST(REG_ITMP2, iptr->val.i);
2392                                         M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2393                                         M_BEQZ(REG_ITMP1, 0);
2394                                         }
2395                                 }
2396                         codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2397                         M_NOP;
2398                         break;
2399
2400                 case ICMD_IFNE:         /* ..., value ==> ...                         */
2401                                         /* op1 = target JavaVM pc, val.i = constant   */
2402
2403                         var_to_reg_int(s1, src, REG_ITMP1);
2404                         if (iptr->val.i == 0) {
2405                                 M_BNEZ(s1, 0);
2406                                 }
2407                         else {
2408                                 ICONST(REG_ITMP2, iptr->val.i);
2409                                 M_BNE(s1, REG_ITMP2, 0);
2410                                 }
2411                         codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2412                         M_NOP;
2413                         break;
2414
2415                 case ICMD_IFGT:         /* ..., value ==> ...                         */
2416                                         /* op1 = target JavaVM pc, val.i = constant   */
2417
2418                         var_to_reg_int(s1, src, REG_ITMP1);
2419                         if (iptr->val.i == 0) {
2420                                 M_BGTZ(s1, 0);
2421                                 }
2422                         else {
2423                                 if ((iptr->val.i >= -32769) && (iptr->val.i <= 32766)) {
2424                                         M_CMPLT_IMM(s1, iptr->val.i + 1, REG_ITMP1);
2425                                         M_BEQZ(REG_ITMP1, 0);
2426                                         }
2427                                 else {
2428                                         ICONST(REG_ITMP2, iptr->val.i);
2429                                         M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2430                                         M_BNEZ(REG_ITMP1, 0);
2431                                         }
2432                                 }
2433                         codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2434                         M_NOP;
2435                         break;
2436
2437                 case ICMD_IFGE:         /* ..., value ==> ...                         */
2438                                         /* op1 = target JavaVM pc, val.i = constant   */
2439
2440                         var_to_reg_int(s1, src, REG_ITMP1);
2441                         if (iptr->val.i == 0) {
2442                                 M_BGEZ(s1, 0);
2443                                 }
2444                         else {
2445                                 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
2446                                         M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2447                                         }
2448                                 else {
2449                                         ICONST(REG_ITMP2, iptr->val.i);
2450                                         M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2451                                         }
2452                                 M_BEQZ(REG_ITMP1, 0);
2453                                 }
2454                         codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2455                         M_NOP;
2456                         break;
2457
2458                 case ICMD_IF_LEQ:       /* ..., value ==> ...                         */
2459                                         /* op1 = target JavaVM pc, val.l = constant   */
2460
2461                         var_to_reg_int(s1, src, REG_ITMP1);
2462                         if (iptr->val.l == 0) {
2463                                 M_BEQZ(s1, 0);
2464                                 }
2465                         else {
2466                                 LCONST(REG_ITMP2, iptr->val.l);
2467                                 M_BEQ(s1, REG_ITMP2, 0);
2468                                 }
2469                         codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2470                         M_NOP;
2471                         break;
2472
2473                 case ICMD_IF_LLT:       /* ..., value ==> ...                         */
2474                                         /* op1 = target JavaVM pc, val.l = constant   */
2475
2476                         var_to_reg_int(s1, src, REG_ITMP1);
2477                         if (iptr->val.l == 0) {
2478                                 M_BLTZ(s1, 0);
2479                                 }
2480                         else {
2481                                 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2482                                         M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2483                                         }
2484                                 else {
2485                                         LCONST(REG_ITMP2, iptr->val.l);
2486                                         M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2487                                         }
2488                                 M_BNEZ(REG_ITMP1, 0);
2489                                 }
2490                         codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2491                         M_NOP;
2492                         break;
2493
2494                 case ICMD_IF_LLE:       /* ..., value ==> ...                         */
2495                                         /* op1 = target JavaVM pc, val.l = constant   */
2496
2497                         var_to_reg_int(s1, src, REG_ITMP1);
2498                         if (iptr->val.l == 0) {
2499                                 M_BLEZ(s1, 0);
2500                                 }
2501                         else {
2502                                 if ((iptr->val.l >= -32769) && (iptr->val.l <= 32766)) {
2503                                         M_CMPLT_IMM(s1, iptr->val.l + 1, REG_ITMP1);
2504                                         M_BNEZ(REG_ITMP1, 0);
2505                                         }
2506                                 else {
2507                                         LCONST(REG_ITMP2, iptr->val.l);
2508                                         M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2509                                         M_BEQZ(REG_ITMP1, 0);
2510                                         }
2511                                 }
2512                         codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2513                         M_NOP;
2514                         break;
2515
2516                 case ICMD_IF_LNE:       /* ..., value ==> ...                         */
2517                                         /* op1 = target JavaVM pc, val.l = constant   */
2518
2519                         var_to_reg_int(s1, src, REG_ITMP1);
2520                         if (iptr->val.l == 0) {
2521                                 M_BNEZ(s1, 0);
2522                                 }
2523                         else {
2524                                 LCONST(REG_ITMP2, iptr->val.l);
2525                                 M_BNE(s1, REG_ITMP2, 0);
2526                                 }
2527                         codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2528                         M_NOP;
2529                         break;
2530
2531                 case ICMD_IF_LGT:       /* ..., value ==> ...                         */
2532                                         /* op1 = target JavaVM pc, val.l = constant   */
2533
2534                         var_to_reg_int(s1, src, REG_ITMP1);
2535                         if (iptr->val.l == 0) {
2536                                 M_BGTZ(s1, 0);
2537                                 }
2538                         else {
2539                                 if ((iptr->val.l >= -32769) && (iptr->val.l <= 32766)) {
2540                                         M_CMPLT_IMM(s1, iptr->val.l + 1, REG_ITMP1);
2541                                         M_BEQZ(REG_ITMP1, 0);
2542                                         }
2543                                 else {
2544                                         LCONST(REG_ITMP2, iptr->val.l);
2545                                         M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2546                                         M_BNEZ(REG_ITMP1, 0);
2547                                         }
2548                                 }
2549                         codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2550                         M_NOP;
2551                         break;
2552
2553                 case ICMD_IF_LGE:       /* ..., value ==> ...                         */
2554                                         /* op1 = target JavaVM pc, val.l = constant   */
2555
2556                         var_to_reg_int(s1, src, REG_ITMP1);
2557                         if (iptr->val.l == 0) {
2558                                 M_BGEZ(s1, 0);
2559                                 }
2560                         else {
2561                                 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2562                                         M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2563                                         }
2564                                 else {
2565                                         LCONST(REG_ITMP2, iptr->val.l);
2566                                         M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2567                                         }
2568                                 M_BEQZ(REG_ITMP1, 0);
2569                                 }
2570                         codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2571                         M_NOP;
2572                         break;
2573
2574                 case ICMD_IF_ICMPEQ:    /* ..., value, value ==> ...                  */
2575                 case ICMD_IF_LCMPEQ:    /* op1 = target JavaVM pc                     */
2576                 case ICMD_IF_ACMPEQ:
2577
2578                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2579                         var_to_reg_int(s2, src, REG_ITMP2);
2580                         M_BEQ(s1, s2, 0);
2581                         codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2582                         M_NOP;
2583                         break;
2584
2585                 case ICMD_IF_ICMPNE:    /* ..., value, value ==> ...                  */
2586                 case ICMD_IF_LCMPNE:    /* op1 = target JavaVM pc                     */
2587                 case ICMD_IF_ACMPNE:
2588
2589                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2590                         var_to_reg_int(s2, src, REG_ITMP2);
2591                         M_BNE(s1, s2, 0);
2592                         codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2593                         M_NOP;
2594                         break;
2595
2596                 case ICMD_IF_ICMPLT:    /* ..., value, value ==> ...                  */
2597                 case ICMD_IF_LCMPLT:    /* op1 = target JavaVM pc                     */
2598
2599                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2600                         var_to_reg_int(s2, src, REG_ITMP2);
2601                         M_CMPLT(s1, s2, REG_ITMP1);
2602                         M_BNEZ(REG_ITMP1, 0);
2603                         codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2604                         M_NOP;
2605                         break;
2606
2607                 case ICMD_IF_ICMPGT:    /* ..., value, value ==> ...                  */
2608                 case ICMD_IF_LCMPGT:    /* op1 = target JavaVM pc                     */
2609
2610                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2611                         var_to_reg_int(s2, src, REG_ITMP2);
2612                         M_CMPGT(s1, s2, REG_ITMP1);
2613                         M_BNEZ(REG_ITMP1, 0);
2614                         codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2615                         M_NOP;
2616                         break;
2617
2618                 case ICMD_IF_ICMPLE:    /* ..., value, value ==> ...                  */
2619                 case ICMD_IF_LCMPLE:    /* op1 = target JavaVM pc                     */
2620
2621                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2622                         var_to_reg_int(s2, src, REG_ITMP2);
2623                         M_CMPGT(s1, s2, REG_ITMP1);
2624                         M_BEQZ(REG_ITMP1, 0);
2625                         codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2626                         M_NOP;
2627                         break;
2628
2629                 case ICMD_IF_ICMPGE:    /* ..., value, value ==> ...                  */
2630                 case ICMD_IF_LCMPGE:    /* op1 = target JavaVM pc                     */
2631
2632                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2633                         var_to_reg_int(s2, src, REG_ITMP2);
2634                         M_CMPLT(s1, s2, REG_ITMP1);
2635                         M_BEQZ(REG_ITMP1, 0);
2636                         codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
2637                         M_NOP;
2638                         break;
2639
2640 #ifdef CONDITIONAL_LOADCONST
2641                 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST                           */
2642
2643                 case ICMD_ELSE_ICONST:  /* handled by IFxx_ICONST                     */
2644                         break;
2645
2646                 case ICMD_IFEQ_ICONST:  /* ..., value ==> ..., constant               */
2647                                         /* val.i = constant                           */
2648
2649                         var_to_reg_int(s1, src, REG_ITMP1);
2650                         d = reg_of_var(iptr->dst, REG_ITMP3);
2651                         s3 = iptr->val.i;
2652                         if (iptr[1].opc == ICMD_ELSE_ICONST) {
2653                                 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2654                                         M_CMPEQ(s1, REG_ZERO, d);
2655                                         store_reg_to_var_int(iptr->dst, d);
2656                                         break;
2657                                         }
2658                                 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2659                                         M_CMPEQ(s1, REG_ZERO, d);
2660                                         M_XOR_IMM(d, 1, d);
2661                                         store_reg_to_var_int(iptr->dst, d);
2662                                         break;
2663                                         }
2664                                 if (s1 == d) {
2665                                         M_MOV(s1, REG_ITMP1);
2666                                         s1 = REG_ITMP1;
2667                                         }
2668                                 ICONST(d, iptr[1].val.i);
2669                                 }
2670                         if ((s3 >= 0) && (s3 <= 255)) {
2671                                 M_CMOVEQ_IMM(s1, s3, d);
2672                                 }
2673                         else {
2674                                 ICONST(REG_ITMP2, s3);
2675                                 M_CMOVEQ(s1, REG_ITMP2, d);
2676                                 }
2677                         store_reg_to_var_int(iptr->dst, d);
2678                         break;
2679
2680                 case ICMD_IFNE_ICONST:  /* ..., value ==> ..., constant               */
2681                                         /* val.i = constant                           */
2682
2683                         var_to_reg_int(s1, src, REG_ITMP1);
2684                         d = reg_of_var(iptr->dst, REG_ITMP3);
2685                         s3 = iptr->val.i;
2686                         if (iptr[1].opc == ICMD_ELSE_ICONST) {
2687                                 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2688                                         M_CMPEQ(s1, REG_ZERO, d);
2689                                         store_reg_to_var_int(iptr->dst, d);
2690                                         break;
2691                                         }
2692                                 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2693                                         M_CMPEQ(s1, REG_ZERO, d);
2694                                         M_XOR_IMM(d, 1, d);
2695                                         store_reg_to_var_int(iptr->dst, d);
2696                                         break;
2697                                         }
2698                                 if (s1 == d) {
2699                                         M_MOV(s1, REG_ITMP1);
2700                                         s1 = REG_ITMP1;
2701                                         }
2702                                 ICONST(d, iptr[1].val.i);
2703                                 }
2704                         if ((s3 >= 0) && (s3 <= 255)) {
2705                                 M_CMOVNE_IMM(s1, s3, d);
2706                                 }
2707                         else {
2708                                 ICONST(REG_ITMP2, s3);
2709                                 M_CMOVNE(s1, REG_ITMP2, d);
2710                                 }
2711                         store_reg_to_var_int(iptr->dst, d);
2712                         break;
2713
2714                 case ICMD_IFLT_ICONST:  /* ..., value ==> ..., constant               */
2715                                         /* val.i = constant                           */
2716
2717                         var_to_reg_int(s1, src, REG_ITMP1);
2718                         d = reg_of_var(iptr->dst, REG_ITMP3);
2719                         s3 = iptr->val.i;
2720                         if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2721                                 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2722                                         M_CMPLT(s1, REG_ZERO, d);
2723                                         store_reg_to_var_int(iptr->dst, d);
2724                                         break;
2725                                         }
2726                                 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2727                                         M_CMPLE(REG_ZERO, s1, d);
2728                                         store_reg_to_var_int(iptr->dst, d);
2729                                         break;
2730                                         }
2731                                 if (s1 == d) {
2732                                         M_MOV(s1, REG_ITMP1);
2733                                         s1 = REG_ITMP1;
2734                                         }
2735                                 ICONST(d, iptr[1].val.i);
2736                                 }
2737                         if ((s3 >= 0) && (s3 <= 255)) {
2738                                 M_CMOVLT_IMM(s1, s3, d);
2739                                 }
2740                         else {
2741                                 ICONST(REG_ITMP2, s3);
2742                                 M_CMOVLT(s1, REG_ITMP2, d);
2743                                 }
2744                         store_reg_to_var_int(iptr->dst, d);
2745                         break;
2746
2747                 case ICMD_IFGE_ICONST:  /* ..., value ==> ..., constant               */
2748                                         /* val.i = constant                           */
2749
2750                         var_to_reg_int(s1, src, REG_ITMP1);
2751                         d = reg_of_var(iptr->dst, REG_ITMP3);
2752                         s3 = iptr->val.i;
2753                         if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2754                                 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2755                                         M_CMPLE(REG_ZERO, s1, d);
2756                                         store_reg_to_var_int(iptr->dst, d);
2757                                         break;
2758                                         }
2759                                 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2760                                         M_CMPLT(s1, REG_ZERO, d);
2761                                         store_reg_to_var_int(iptr->dst, d);
2762                                         break;
2763                                         }
2764                                 if (s1 == d) {
2765                                         M_MOV(s1, REG_ITMP1);
2766                                         s1 = REG_ITMP1;
2767                                         }
2768                                 ICONST(d, iptr[1].val.i);
2769                                 }
2770                         if ((s3 >= 0) && (s3 <= 255)) {
2771                                 M_CMOVGE_IMM(s1, s3, d);
2772                                 }
2773                         else {
2774                                 ICONST(REG_ITMP2, s3);
2775                                 M_CMOVGE(s1, REG_ITMP2, d);
2776                                 }
2777                         store_reg_to_var_int(iptr->dst, d);
2778                         break;
2779
2780                 case ICMD_IFGT_ICONST:  /* ..., value ==> ..., constant               */
2781                                         /* val.i = constant                           */
2782
2783                         var_to_reg_int(s1, src, REG_ITMP1);
2784                         d = reg_of_var(iptr->dst, REG_ITMP3);
2785                         s3 = iptr->val.i;
2786                         if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2787                                 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2788                                         M_CMPLT(REG_ZERO, s1, d);
2789                                         store_reg_to_var_int(iptr->dst, d);
2790                                         break;
2791                                         }
2792                                 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2793                                         M_CMPLE(s1, REG_ZERO, d);
2794                                         store_reg_to_var_int(iptr->dst, d);
2795                                         break;
2796                                         }
2797                                 if (s1 == d) {
2798                                         M_MOV(s1, REG_ITMP1);
2799                                         s1 = REG_ITMP1;
2800                                         }
2801                                 ICONST(d, iptr[1].val.i);
2802                                 }
2803                         if ((s3 >= 0) && (s3 <= 255)) {
2804                                 M_CMOVGT_IMM(s1, s3, d);
2805                                 }
2806                         else {
2807                                 ICONST(REG_ITMP2, s3);
2808                                 M_CMOVGT(s1, REG_ITMP2, d);
2809                                 }
2810                         store_reg_to_var_int(iptr->dst, d);
2811                         break;
2812
2813                 case ICMD_IFLE_ICONST:  /* ..., value ==> ..., constant               */
2814                                         /* val.i = constant                           */
2815
2816                         var_to_reg_int(s1, src, REG_ITMP1);
2817                         d = reg_of_var(iptr->dst, REG_ITMP3);
2818                         s3 = iptr->val.i;
2819                         if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2820                                 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2821                                         M_CMPLE(s1, REG_ZERO, d);
2822                                         store_reg_to_var_int(iptr->dst, d);
2823                                         break;
2824                                         }
2825                                 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2826                                         M_CMPLT(REG_ZERO, s1, d);
2827                                         store_reg_to_var_int(iptr->dst, d);
2828                                         break;
2829                                         }
2830                                 if (s1 == d) {
2831                                         M_MOV(s1, REG_ITMP1);
2832                                         s1 = REG_ITMP1;
2833                                         }
2834                                 ICONST(d, iptr[1].val.i);
2835                                 }
2836                         if ((s3 >= 0) && (s3 <= 255)) {
2837                                 M_CMOVLE_IMM(s1, s3, d);
2838                                 }
2839                         else {
2840                                 ICONST(REG_ITMP2, s3);
2841                                 M_CMOVLE(s1, REG_ITMP2, d);
2842                                 }
2843                         store_reg_to_var_int(iptr->dst, d);
2844                         break;
2845 #endif
2846
2847
2848                 case ICMD_IRETURN:      /* ..., retvalue ==> ...                      */
2849                 case ICMD_LRETURN:
2850                 case ICMD_ARETURN:
2851
2852 #ifdef USE_THREADS
2853                         if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2854                                 int disp;
2855                                 a = dseg_addaddress ((void*) (builtin_monitorexit));
2856                                 M_ALD(REG_ITMP3, REG_PV, a);
2857                                 M_JSR(REG_RA, REG_ITMP3);
2858                                 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);    /* delay slot */
2859                                 disp = -(int)((u1*) mcodeptr - mcodebase);
2860                                 M_LDA(REG_PV, REG_RA, disp);
2861                                 }                       
2862 #endif
2863                         var_to_reg_int(s1, src, REG_RESULT);
2864                         M_INTMOVE(s1, REG_RESULT);
2865                         goto nowperformreturn;
2866
2867                 case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
2868                 case ICMD_DRETURN:
2869
2870 #ifdef USE_THREADS
2871                         if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2872                                 int disp;
2873                                 a = dseg_addaddress ((void*) (builtin_monitorexit));
2874                                 M_ALD(REG_ITMP3, REG_PV, a);
2875                                 M_JSR(REG_RA, REG_ITMP3);
2876                                 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);    /* delay slot */
2877                                 disp = -(int)((u1*) mcodeptr - mcodebase);
2878                                 M_LDA(REG_PV, REG_RA, disp);
2879                                 }                       
2880 #endif
2881                         var_to_reg_flt(s1, src, REG_FRESULT);
2882                         {
2883                                 int t = ((iptr->opc == ICMD_FRETURN) ? TYPE_FLT : TYPE_DBL);
2884                                 M_TFLTMOVE(t, s1, REG_FRESULT);
2885                         }
2886                         goto nowperformreturn;
2887
2888                 case ICMD_RETURN:      /* ...  ==> ...                                */
2889
2890 #ifdef USE_THREADS
2891                         if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
2892                                 int disp;
2893                                 a = dseg_addaddress ((void*) (builtin_monitorexit));
2894                                 M_ALD(REG_ITMP3, REG_PV, a);
2895                                 M_JSR(REG_RA, REG_ITMP3);
2896                                 M_ALD(argintregs[0], REG_SP, 8 * maxmemuse);    /* delay slot */
2897                                 disp = -(int)((u1*) mcodeptr - mcodebase);
2898                                 M_LDA(REG_PV, REG_RA, disp);
2899                                 }                       
2900 #endif
2901
2902 nowperformreturn:
2903                         {
2904                         int r, p;
2905                         
2906                         p = parentargs_base;
2907                         
2908                         /* restore return address                                         */
2909
2910                         if (!isleafmethod)
2911                                 {p--;  M_LLD (REG_RA, REG_SP, 8 * p);}
2912
2913                         /* restore saved registers                                        */
2914
2915                         for (r = savintregcnt - 1; r >= maxsavintreguse; r--)
2916                                         {p--; M_LLD(savintregs[r], REG_SP, 8 * p);}
2917                         for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--)
2918                                         {p--; M_DLD(savfltregs[r], REG_SP, 8 * p);}
2919
2920                         /* call trace function */
2921
2922                         if (runverbose) {
2923                                 M_LDA (REG_SP, REG_SP, -24);
2924                                 M_LST(REG_RA, REG_SP, 0);
2925                                 M_LST(REG_RESULT, REG_SP, 8);
2926                                 M_DST(REG_FRESULT, REG_SP,16);
2927                                 a = dseg_addaddress (method);
2928                                 M_ALD(argintregs[0], REG_PV, a);
2929                                 M_MOV(REG_RESULT, argintregs[1]);
2930                                 M_FLTMOVE(REG_FRESULT, argfltregs[2]);
2931                                 M_FMOV(REG_FRESULT, argfltregs[3]);
2932                                 a = dseg_addaddress ((void*) (builtin_displaymethodstop));
2933                                 M_ALD(REG_ITMP3, REG_PV, a);
2934                                 M_JSR (REG_RA, REG_ITMP3);
2935                                 M_NOP;
2936                                 M_DLD(REG_FRESULT, REG_SP,16);
2937                                 M_LLD(REG_RESULT, REG_SP, 8);
2938                                 M_LLD(REG_RA, REG_SP, 0);
2939                                 M_LDA (REG_SP, REG_SP, 24);
2940                                 }
2941
2942                         M_RET(REG_RA);
2943
2944                         /* deallocate stack                                               */
2945
2946                         if (parentargs_base)
2947                                 {M_LDA(REG_SP, REG_SP, parentargs_base*8);}
2948                         else
2949                                 {M_NOP;}
2950                         ALIGNCODENOP;
2951                         }
2952                         break;
2953
2954
2955                 case ICMD_TABLESWITCH:  /* ..., index ==> ...                         */
2956                         {
2957                         s4 i, l, *s4ptr;
2958                         void **tptr;
2959
2960                         tptr = (void **) iptr->target;
2961
2962                         s4ptr = iptr->val.a;
2963                         l = s4ptr[1];                          /* low     */
2964                         i = s4ptr[2];                          /* high    */
2965                         
2966                         var_to_reg_int(s1, src, REG_ITMP1);
2967                         if (l == 0)
2968                                 {M_INTMOVE(s1, REG_ITMP1);}
2969                         else if (l <= 32768) {
2970                                 M_IADD_IMM(s1, -l, REG_ITMP1);
2971                                 }
2972                         else {
2973                                 ICONST(REG_ITMP2, l);
2974                                 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2975                                 }
2976                         i = i - l + 1;
2977
2978                         /* range check */
2979
2980                         M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
2981                         M_BEQZ(REG_ITMP2, 0);
2982                         codegen_addreference((basicblock *) tptr[0], mcodeptr);
2983                         M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);      /* delay slot*/
2984
2985                         /* build jump table top down and use address of lowest entry */
2986
2987                         /* s4ptr += 3 + i; */
2988                         tptr += i;
2989
2990                         while (--i >= 0) {
2991                                 /* dseg_addtarget(BlockPtrOfPC(*--s4ptr)); */
2992                                 dseg_addtarget((basicblock *) tptr[0]); 
2993                                 --tptr;
2994                                 }
2995                         }
2996
2997                         /* length of dataseg after last dseg_addtarget is used by load */
2998
2999                         M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
3000                         M_ALD(REG_ITMP2, REG_ITMP2, -dseglen);
3001                         M_JMP(REG_ITMP2);
3002                         M_NOP;
3003                         ALIGNCODENOP;
3004                         break;
3005
3006
3007                 case ICMD_LOOKUPSWITCH: /* ..., key ==> ...                           */
3008                         {
3009                         s4 i, l, val, *s4ptr;
3010                         void **tptr;
3011
3012                         tptr = (void **) iptr->target;
3013
3014                         s4ptr = iptr->val.a;
3015                         l = s4ptr[0];                          /* default  */
3016                         i = s4ptr[1];                          /* count    */
3017                         
3018                         MCODECHECK((i<<2)+8);
3019                         var_to_reg_int(s1, src, REG_ITMP1);
3020                         while (--i >= 0) {
3021                                 s4ptr += 2;
3022                                 ++tptr;
3023
3024                                 val = s4ptr[0];
3025                                 ICONST(REG_ITMP2, val);
3026                                 M_BEQ(s1, REG_ITMP2, 0);
3027                                 codegen_addreference((basicblock *) tptr[0], mcodeptr); 
3028                                 M_NOP;
3029                                 }
3030
3031                         M_BR(0);
3032                         tptr = (void **) iptr->target;
3033                         codegen_addreference((basicblock *) tptr[0], mcodeptr);
3034                         M_NOP;
3035                         ALIGNCODENOP;
3036                         break;
3037                         }
3038
3039
3040                 case ICMD_BUILTIN3:     /* ..., arg1, arg2, arg3 ==> ...              */
3041                                         /* op1 = return type, val.a = function pointer*/
3042                         s3 = 3;
3043                         goto gen_method;
3044
3045                 case ICMD_BUILTIN2:     /* ..., arg1, arg2 ==> ...                    */
3046                                         /* op1 = return type, val.a = function pointer*/
3047                         s3 = 2;
3048                         goto gen_method;
3049
3050                 case ICMD_BUILTIN1:     /* ..., arg1 ==> ...                          */
3051                                         /* op1 = return type, val.a = function pointer*/
3052                         s3 = 1;
3053                         goto gen_method;
3054
3055                 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ...            */
3056                                         /* op1 = arg count, val.a = method pointer    */
3057
3058                 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3059                                         /* op1 = arg count, val.a = method pointer    */
3060
3061                 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3062                                         /* op1 = arg count, val.a = method pointer    */
3063
3064                 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
3065                                         /* op1 = arg count, val.a = method pointer    */
3066
3067                         s3 = iptr->op1;
3068
3069 gen_method: {
3070                         methodinfo   *m;
3071                         classinfo    *ci;
3072
3073                         MCODECHECK((s3 << 1) + 64);
3074
3075                         /* copy arguments to registers or stack location                  */
3076
3077                         for (; --s3 >= 0; src = src->prev) {
3078                                 if (src->varkind == ARGVAR)
3079                                         continue;
3080                                 if (IS_INT_LNG_TYPE(src->type)) {
3081                                         if (s3 < INT_ARG_CNT) {
3082                                                 s1 = argintregs[s3];
3083                                                 var_to_reg_int(d, src, s1);
3084                                                 M_INTMOVE(d, s1);
3085                                                 }
3086                                         else  {
3087                                                 var_to_reg_int(d, src, REG_ITMP1);
3088                                                 M_LST(d, REG_SP, 8 * (s3 - INT_ARG_CNT));
3089                                                 }
3090                                         }
3091                                 else
3092                                         if (s3 < FLT_ARG_CNT) {
3093                                                 s1 = argfltregs[s3];
3094                                                 var_to_reg_flt(d, src, s1);
3095                                                 M_TFLTMOVE(src->type,d, s1);
3096                                                 }
3097                                         else {
3098                                                 var_to_reg_flt(d, src, REG_FTMP1);
3099                                                 M_DST(d, REG_SP, 8 * (s3 - FLT_ARG_CNT));
3100                                                 }
3101                                 } /* end of for */
3102
3103                         m = iptr->val.a;
3104                         switch (iptr->opc) {
3105                                 case ICMD_BUILTIN3:
3106                                 case ICMD_BUILTIN2:
3107                                 case ICMD_BUILTIN1:
3108                                         a = dseg_addaddress ((void*) (m));
3109                                         M_ALD(REG_ITMP3, REG_PV, a); /* built-in-function pointer */
3110                                         M_JSR (REG_RA, REG_ITMP3);
3111                                         M_NOP;
3112                                         d = iptr->op1;                             /* return type */
3113                                         goto afteractualcall;
3114
3115                                 case ICMD_INVOKESTATIC:
3116                                 case ICMD_INVOKESPECIAL:
3117                                         a = dseg_addaddress (m->stubroutine);
3118
3119                                         M_ALD(REG_PV, REG_PV, a );        /* method pointer in pv */
3120
3121                                         d = m->returntype;
3122                                         goto makeactualcall;
3123
3124                                 case ICMD_INVOKEVIRTUAL:
3125
3126                                         gen_nullptr_check(argintregs[0]);
3127                                         M_ALD(REG_METHODPTR, argintregs[0],
3128                                                                  OFFSET(java_objectheader, vftbl));
3129                                         M_ALD(REG_PV, REG_METHODPTR, OFFSET(vftbl, table[0]) +
3130                                                                 sizeof(methodptr) * m->vftblindex);
3131
3132                                         d = m->returntype;
3133                                         goto makeactualcall;
3134
3135                                 case ICMD_INVOKEINTERFACE:
3136                                         ci = m->class;
3137                                         
3138                                         gen_nullptr_check(argintregs[0]);
3139                                         M_ALD(REG_METHODPTR, argintregs[0],
3140                                                                  OFFSET(java_objectheader, vftbl));    
3141                                         M_ALD(REG_METHODPTR, REG_METHODPTR,
3142                                               OFFSET(vftbl, interfacetable[0]) -
3143                                               sizeof(methodptr*) * ci->index);
3144                                         M_ALD(REG_PV, REG_METHODPTR,
3145                                                             sizeof(methodptr) * (m - ci->methods));
3146
3147                                         d = m->returntype;
3148                                         goto makeactualcall;
3149
3150                                 default:
3151                                         d = 0;
3152                                         sprintf (logtext, "Unkown ICMD-Command: %d", iptr->opc);
3153                                         error ();
3154                                 }
3155
3156 makeactualcall:
3157
3158                         M_JSR (REG_RA, REG_PV);
3159                         M_NOP;
3160
3161                         /* recompute pv */
3162
3163 afteractualcall:
3164
3165                         s1 = (int)((u1*) mcodeptr - mcodebase);
3166                         if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
3167                         else {
3168                                         s4 ml=-s1, mh=0;
3169                                         while (ml<-32768) { ml+=65536; mh--; }
3170                                         M_LUI(REG_PV, mh);
3171                                         M_IADD_IMM(REG_PV, ml, REG_PV);
3172                                         M_LADD(REG_PV, REG_RA, REG_PV);
3173                                 }
3174
3175                         /* d contains return type */
3176
3177                         if (d != TYPE_VOID) {
3178                                 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3179                                         s1 = reg_of_var(iptr->dst, REG_RESULT);
3180                                         M_INTMOVE(REG_RESULT, s1);
3181                                         store_reg_to_var_int(iptr->dst, s1);
3182                                         }
3183                                 else {
3184                                         s1 = reg_of_var(iptr->dst, REG_FRESULT);
3185                                         M_TFLTMOVE(iptr->dst->type, REG_FRESULT, s1);
3186                                         store_reg_to_var_flt(iptr->dst, s1);
3187                                         }
3188                                 }
3189                         }
3190                         break;
3191
3192
3193                 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
3194
3195                                       /* op1:   0 == array, 1 == class                */
3196                                       /* val.a: (classinfo*) superclass               */
3197
3198 /*          superclass is an interface:
3199  *
3200  *          return (sub != NULL) &&
3201  *                 (sub->vftbl->interfacetablelength > super->index) &&
3202  *                 (sub->vftbl->interfacetable[-super->index] != NULL);
3203  *
3204  *          superclass is a class:
3205  *
3206  *          return ((sub != NULL) && (0
3207  *                  <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3208  *                  super->vftbl->diffvall));
3209  */
3210
3211                         {
3212                         classinfo *super = (classinfo*) iptr->val.a;
3213                         
3214                         var_to_reg_int(s1, src, REG_ITMP1);
3215                         d = reg_of_var(iptr->dst, REG_ITMP3);
3216                         if (s1 == d) {
3217                                 M_MOV(s1, REG_ITMP1);
3218                                 s1 = REG_ITMP1;
3219                                 }
3220                         M_CLR(d);
3221                         if (iptr->op1) {                               /* class/interface */
3222                                 if (super->flags & ACC_INTERFACE) {        /* interface       */
3223                                         M_BEQZ(s1, 8);
3224                                         M_NOP;
3225                                         M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3226                                         M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3227                                         M_IADD_IMM(REG_ITMP2, - super->index, REG_ITMP2);
3228                                         M_BLEZ(REG_ITMP2, 3);
3229                                         M_NOP;
3230                                         M_ALD(REG_ITMP1, REG_ITMP1,
3231                                               OFFSET(vftbl, interfacetable[0]) -
3232                                               super->index * sizeof(methodptr*));
3233                                         M_CMPULT(REG_ZERO, REG_ITMP1, d);      /* REG_ITMP1 != 0  */
3234                                         }
3235                                 else {                                     /* class           */
3236                                         /*
3237                                         s2 = super->vftbl->diffval;
3238                                         M_BEQZ(s1, 5);
3239                                         M_NOP;
3240                                         M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3241                                         M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3242                                         M_IADD_IMM(REG_ITMP1, - super->vftbl->baseval, REG_ITMP1);
3243                                         M_CMPULT_IMM(REG_ITMP1, s2 + 1, d);
3244                                         */
3245
3246                                         M_BEQZ(s1, 9);
3247                                         M_NOP;
3248                                         M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3249                     a = dseg_addaddress ((void*) super->vftbl);
3250                     M_ALD(REG_ITMP2, REG_PV, a);
3251                     M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3252                     M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl, baseval));
3253                     M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, diffval));
3254                     M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1); 
3255                     M_CMPULT(REG_ITMP2, REG_ITMP1, d);
3256                                         M_XOR_IMM(d, 1, d);
3257
3258                                         }
3259                                 }
3260                         else
3261                                 panic ("internal error: no inlined array instanceof");
3262                         }
3263                         store_reg_to_var_int(iptr->dst, d);
3264                         break;
3265
3266                 case ICMD_CHECKCAST:  /* ..., objectref ==> ..., objectref            */
3267
3268                                       /* op1:   0 == array, 1 == class                */
3269                                       /* val.a: (classinfo*) superclass               */
3270
3271 /*          superclass is an interface:
3272  *
3273  *          OK if ((sub == NULL) ||
3274  *                 (sub->vftbl->interfacetablelength > super->index) &&
3275  *                 (sub->vftbl->interfacetable[-super->index] != NULL));
3276  *
3277  *          superclass is a class:
3278  *
3279  *          OK if ((sub == NULL) || (0
3280  *                 <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3281  *                 super->vftbl->diffvall));
3282  */
3283
3284                         {
3285                         classinfo *super = (classinfo*) iptr->val.a;
3286                         
3287                         d = reg_of_var(iptr->dst, REG_ITMP3);
3288                         var_to_reg_int(s1, src, d);
3289                         if (iptr->op1) {                               /* class/interface */
3290                                 if (super->flags & ACC_INTERFACE) {        /* interface       */
3291                                         M_BEQZ(s1, 9);
3292                                         M_NOP;
3293                                         M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3294                                         M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
3295                                         M_IADD_IMM(REG_ITMP2, - super->index, REG_ITMP2);
3296                                         M_BLEZ(REG_ITMP2, 0);
3297                                         codegen_addxcastrefs(mcodeptr);
3298                                         M_NOP;
3299                                         M_ALD(REG_ITMP2, REG_ITMP1,
3300                                               OFFSET(vftbl, interfacetable[0]) -
3301                                               super->index * sizeof(methodptr*));
3302                                         M_BEQZ(REG_ITMP2, 0);
3303                                         codegen_addxcastrefs(mcodeptr);
3304                                         M_NOP;
3305                                         }
3306                                 else {                                     /* class           */
3307
3308                                         /*
3309                                         s2 = super->vftbl->diffval;
3310                                         M_BEQZ(s1, 6 + (s2 != 0));
3311                                         M_NOP;
3312                                         M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3313                                         M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3314                                         M_IADD_IMM(REG_ITMP1, - super->vftbl->baseval, REG_ITMP1);
3315                                         if (s2 == 0) {
3316                                                 M_BNEZ(REG_ITMP1, 0);
3317                                                 }
3318                                         else{
3319                                                 M_CMPULT_IMM(REG_ITMP1, s2 + 1, REG_ITMP2);
3320                                                 M_BEQZ(REG_ITMP2, 0);
3321                                                 }
3322                                         */
3323
3324                                         M_BEQZ(s1, 10 + (d == REG_ITMP3));
3325                                         M_NOP;
3326                                         M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3327                     a = dseg_addaddress ((void*) super->vftbl);
3328                     M_ALD(REG_ITMP2, REG_PV, a);
3329                     M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl, baseval));
3330                                         if (d != REG_ITMP3) {
3331                                                 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl, baseval));
3332                                                 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, diffval));
3333                                                 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1); 
3334                                         } else {
3335                                                 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, baseval));
3336                                                 M_ISUB(REG_ITMP1, REG_ITMP2, REG_ITMP1); 
3337                                                 M_ALD(REG_ITMP2, REG_PV, a);
3338                                                 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl, diffval));
3339                                         }
3340                     M_CMPULT(REG_ITMP2, REG_ITMP1, REG_ITMP2);
3341                                         M_BNEZ(REG_ITMP2, 0);
3342
3343                                         codegen_addxcastrefs(mcodeptr);
3344                                         M_NOP;
3345                                         }
3346                                 }
3347                         else
3348                                 panic ("internal error: no inlined array checkcast");
3349                         }
3350                         M_INTMOVE(s1, d);
3351                         store_reg_to_var_int(iptr->dst, d);
3352                         break;
3353
3354                 case ICMD_CHECKASIZE:  /* ..., size ==> ..., size                     */
3355
3356                         var_to_reg_int(s1, src, REG_ITMP1);
3357                         M_BLTZ(s1, 0);
3358                         codegen_addxcheckarefs(mcodeptr);
3359                         M_NOP;
3360                         break;
3361
3362                 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref  */
3363                                       /* op1 = dimension, val.a = array descriptor    */
3364
3365                         /* check for negative sizes and copy sizes to stack if necessary  */
3366
3367                         MCODECHECK((iptr->op1 << 1) + 64);
3368
3369                         for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3370                                 var_to_reg_int(s2, src, REG_ITMP1);
3371                                 M_BLTZ(s2, 0);
3372                                 codegen_addxcheckarefs(mcodeptr);
3373                                 M_NOP;
3374
3375                                 /* copy sizes to stack (argument numbers >= INT_ARG_CNT)      */
3376
3377                                 if (src->varkind != ARGVAR) {
3378                                         M_LST(s2, REG_SP, 8 * (s1 + INT_ARG_CNT));
3379                                         }
3380                                 }
3381
3382                         /* a0 = dimension count */
3383
3384                         ICONST(argintregs[0], iptr->op1);
3385
3386                         /* a1 = arraydescriptor */
3387
3388                         a = dseg_addaddress(iptr->val.a);
3389                         M_ALD(argintregs[1], REG_PV, a);
3390
3391                         /* a2 = pointer to dimensions = stack pointer */
3392
3393                         M_INTMOVE(REG_SP, argintregs[2]);
3394
3395                         a = dseg_addaddress((void*) (builtin_nmultianewarray));
3396                         M_ALD(REG_ITMP3, REG_PV, a);
3397                         M_JSR(REG_RA, REG_ITMP3);
3398                         M_NOP;
3399                         s1 = (int)((u1*) mcodeptr - mcodebase);
3400                         if (s1 <= 32768)
3401                                 M_LDA (REG_PV, REG_RA, -s1);
3402                         else {
3403                                 panic("To big");
3404                             }
3405                         s1 = reg_of_var(iptr->dst, REG_RESULT);
3406                         M_INTMOVE(REG_RESULT, s1);
3407                         store_reg_to_var_int(iptr->dst, s1);
3408                         break;
3409
3410
3411                 default: sprintf (logtext, "Unknown pseudo command: %d", iptr->opc);
3412                          error();
3413         
3414    
3415
3416         } /* switch */
3417                 
3418         } /* for instruction */
3419                 
3420         /* copy values to interface registers */
3421
3422         src = bptr->outstack;
3423         len = bptr->outdepth;
3424         MCODECHECK(64+len);
3425         while (src) {
3426                 len--;
3427                 if ((src->varkind != STACKVAR)) {
3428                         s2 = src->type;
3429                         if (IS_FLT_DBL_TYPE(s2)) {
3430                                 var_to_reg_flt(s1, src, REG_FTMP1);
3431                                 if (!(interfaces[len][s2].flags & INMEMORY)) {
3432                                         M_TFLTMOVE(s2,s1,interfaces[len][s2].regoff);
3433                                         }
3434                                 else {
3435                                         M_DST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3436                                         }
3437                                 }
3438                         else {
3439                                 var_to_reg_int(s1, src, REG_ITMP1);
3440                                 if (!(interfaces[len][s2].flags & INMEMORY)) {
3441                                         M_INTMOVE(s1,interfaces[len][s2].regoff);
3442                                         }
3443                                 else {
3444                                         M_LST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
3445                                         }
3446                                 }
3447                         }
3448                 src = src->prev;
3449                 }
3450         } /* if (bptr -> flags >= BBREACHED) */
3451         } /* for basic block */
3452
3453         /* bptr -> mpc = (int)((u1*) mcodeptr - mcodebase); */
3454
3455         {
3456         /* generate bound check stubs */
3457
3458         s4 *xcodeptr = NULL;
3459         
3460         for (; xboundrefs != NULL; xboundrefs = xboundrefs->next) {
3461                 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3462                         gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos, 
3463                                 xboundrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3464                         continue;
3465                         }
3466
3467
3468                 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos, 
3469                                   xboundrefs->branchpos, (u1*) mcodeptr - mcodebase);
3470
3471                 MCODECHECK(8);
3472
3473                 M_LDA(REG_ITMP2_XPC, REG_PV, xboundrefs->branchpos - 4);
3474
3475                 if (xcodeptr != NULL) {
3476                         int disp = xcodeptr-mcodeptr;
3477                         M_BR(disp-1);
3478                         M_NOP;
3479                         }
3480                 else {
3481                         xcodeptr = mcodeptr;
3482
3483                         a = dseg_addaddress(asm_handle_exception);
3484                         M_ALD(REG_ITMP3, REG_PV, a);
3485
3486                         M_JMP(REG_ITMP3);
3487                         a = dseg_addaddress(proto_java_lang_ArrayIndexOutOfBoundsException);
3488                         M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3489                         }
3490                 }
3491
3492         /* generate negative array size check stubs */
3493
3494         xcodeptr = NULL;
3495         
3496         for (; xcheckarefs != NULL; xcheckarefs = xcheckarefs->next) {
3497                 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3498                         gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos, 
3499                                 xcheckarefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3500                         continue;
3501                         }
3502
3503                 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos, 
3504                                   xcheckarefs->branchpos, (u1*) mcodeptr - mcodebase);
3505
3506                 MCODECHECK(8);
3507
3508                 M_LDA(REG_ITMP2_XPC, REG_PV, xcheckarefs->branchpos - 4);
3509
3510                 if (xcodeptr != NULL) {
3511                         int disp = xcodeptr-mcodeptr;
3512                         M_BR(disp-1);
3513                         M_NOP;
3514                         }
3515                 else {
3516                         xcodeptr = mcodeptr;
3517
3518                         a = dseg_addaddress(asm_handle_exception);
3519                         M_ALD(REG_ITMP3, REG_PV, a);
3520
3521                         M_JMP(REG_ITMP3);
3522                         a = dseg_addaddress(proto_java_lang_NegativeArraySizeException);
3523                         M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3524                         }
3525                 }
3526
3527         /* generate cast check stubs */
3528
3529         xcodeptr = NULL;
3530         
3531         for (; xcastrefs != NULL; xcastrefs = xcastrefs->next) {
3532                 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3533                         gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos, 
3534                                 xcastrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3535                         continue;
3536                         }
3537
3538                 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos, 
3539                                   xcastrefs->branchpos, (u1*) mcodeptr - mcodebase);
3540
3541                 MCODECHECK(8);
3542
3543                 M_LDA(REG_ITMP2_XPC, REG_PV, xcastrefs->branchpos - 4);
3544
3545                 if (xcodeptr != NULL) {
3546                         int disp = xcodeptr-mcodeptr;
3547                         M_BR(disp-1);
3548                         M_NOP;
3549                         }
3550                 else {
3551                         xcodeptr = mcodeptr;
3552
3553                         a = dseg_addaddress(asm_handle_exception);
3554                         M_ALD(REG_ITMP3, REG_PV, a);
3555
3556                         M_JMP(REG_ITMP3);
3557                         a = dseg_addaddress(proto_java_lang_ClassCastException);
3558                         M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3559                         }
3560                 }
3561
3562
3563 #ifdef SOFTNULLPTRCHECK
3564
3565         /* generate null pointer check stubs */
3566
3567         xcodeptr = NULL;
3568
3569         for (; xnullrefs != NULL; xnullrefs = xnullrefs->next) {
3570                 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
3571                         gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos, 
3572                                 xnullrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
3573                         continue;
3574                         }
3575
3576                 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos, 
3577                                   xnullrefs->branchpos, (u1*) mcodeptr - mcodebase);
3578
3579                 MCODECHECK(8);
3580
3581                 M_LDA(REG_ITMP2_XPC, REG_PV, xnullrefs->branchpos - 4);
3582
3583                 if (xcodeptr != NULL) {
3584                         int disp = xcodeptr-mcodeptr;
3585                         M_BR(disp-1);
3586                         M_NOP;
3587                         }
3588                 else {
3589                         xcodeptr = mcodeptr;
3590
3591                         a = dseg_addaddress(asm_handle_exception);
3592                         M_ALD(REG_ITMP3, REG_PV, a);
3593
3594                         M_JMP(REG_ITMP3);
3595                         a = dseg_addaddress(proto_java_lang_NullPointerException);
3596                         M_ALD(REG_ITMP1_XPTR, REG_PV, a);
3597                         }
3598                 }
3599
3600 #endif
3601         }
3602
3603         codegen_finish((int)((u1*) mcodeptr - mcodebase));
3604
3605         docacheflush((void*) method->entrypoint,
3606                           ((u1*) mcodeptr - mcodebase), ICACHE);
3607 }
3608
3609
3610 /* redefinition of code generation macros (compiling into array) **************/
3611
3612 /* 
3613 These macros are newly defined to allow code generation into an array.
3614 This is necessary, because the original M_.. macros generate code by
3615 calling 'codegen_adds4' that uses an additional data structure to
3616 receive the code.
3617
3618 For a faster (but less flexible) version to generate code, these
3619 macros directly use the (s4* p) - pointer to put the code directly
3620 in a locally defined array.
3621 This makes sense only for the stub-generation-routines below.
3622 */
3623
3624 #undef M_ITYPE
3625 #define M_ITYPE(op, rs, rt, imm)\
3626   *(p++) = (((op)<<26)|((rs)<<21)|((rt)<<16)|((imm)&0xffff))
3627
3628 #undef M_JTYPE
3629 #define M_JTYPE(op, imm)\
3630   *(p++) = (((op)<<26)|((off)&0x3ffffff))
3631
3632 #undef M_RTYPE
3633 #define M_RTYPE(op, rs, rt, rd, sa, fu)\
3634   *(p++) = (((op)<<26)|((rs)<<21)|((rt)<<16)|((rd)<<11)|((sa)<<6)|(fu))
3635
3636
3637 /* function createcompilerstub *************************************************
3638
3639         creates a stub routine which calls the compiler
3640         
3641 *******************************************************************************/
3642
3643 #define COMPSTUBSIZE 4
3644
3645 u1 *createcompilerstub (methodinfo *m)
3646 {
3647         u8 *s = CNEW (u8, COMPSTUBSIZE);    /* memory to hold the stub            */
3648         s4 *p = (s4*) s;                    /* code generation pointer            */
3649         
3650                                             /* code for the stub                  */
3651         M_ALD(REG_PV, REG_PV, 24);          /* load pointer to the compiler       */
3652         M_NOP;
3653         M_JSR(REG_ITMP1, REG_PV);           /* jump to the compiler, return address
3654                                                in itmp1 is used as method pointer */
3655         M_NOP;
3656
3657         s[2] = (u8) m;                      /* literals to be adressed            */  
3658         s[3] = (u8) asm_call_jit_compiler;  /* jump directly via PV from above    */
3659
3660         (void) docacheflush((void*) s, (char*) p - (char*) s, ICACHE);
3661
3662 #ifdef STATISTICS
3663         count_cstub_len += COMPSTUBSIZE * 8;
3664 #endif
3665
3666         return (u1*) s;
3667 }
3668
3669
3670 /* function removecompilerstub *************************************************
3671
3672      deletes a compilerstub from memory  (simply by freeing it)
3673
3674 *******************************************************************************/
3675
3676 void removecompilerstub (u1 *stub) 
3677 {
3678         CFREE (stub, COMPSTUBSIZE * 8);
3679 }
3680
3681 /* function: createnativestub **************************************************
3682
3683         creates a stub routine which calls a native method
3684
3685 *******************************************************************************/
3686
3687 #define NATIVESTUBSIZE 20
3688
3689 u1 *createnativestub (functionptr f, methodinfo *m)
3690 {
3691         u8 *s = CNEW (u8, NATIVESTUBSIZE);  /* memory to hold the stub            */
3692         s4 *p = (s4*) s;                    /* code generation pointer            */
3693
3694         reg_init();
3695
3696         M_MOV  (argintregs[4], argintregs[5]);
3697         M_DMFC1 (REG_ITMP1, argfltregs[4]);
3698
3699         M_MOV  (argintregs[3], argintregs[4]);
3700         M_DMTC1 (REG_ITMP1, argfltregs[5]);
3701
3702         M_MOV  (argintregs[2], argintregs[3]);
3703         M_DMFC1 (REG_ITMP1, argfltregs[3]);
3704
3705         M_MOV  (argintregs[1], argintregs[2]);
3706         M_DMTC1 (REG_ITMP1, argfltregs[4]);
3707
3708         M_MOV  (argintregs[0], argintregs[1]);
3709         M_DMFC1 (REG_ITMP1, argfltregs[2]);
3710
3711         M_ALD  (argintregs[0], REG_PV, 19*8); /* load adress of jni_environement  */
3712         M_DMTC1 (REG_ITMP1, argfltregs[3]);
3713
3714         M_DMFC1 (REG_ITMP1, argfltregs[1]);
3715         M_DMFC1 (REG_ITMP2, argfltregs[0]);
3716
3717         M_DMTC1 (REG_ITMP1, argfltregs[2]);
3718         M_DMTC1 (REG_ITMP2, argfltregs[1]);
3719
3720         M_ALD  (REG_ITMP3, REG_PV, 16*8);   /* load adress of native method       */
3721         M_LDA  (REG_SP, REG_SP, -8);        /* build up stackframe                */
3722
3723         M_LST  (REG_RA, REG_SP, 0);         /* store return address               */
3724         M_JSR  (REG_RA, REG_ITMP3);         /* call native method                 */
3725
3726         M_NOP;                              /* delay slot                         */
3727         M_ALD  (REG_ITMP3, REG_PV, 17*8);   /* get address of exceptionptr        */
3728
3729         M_LLD  (REG_RA, REG_SP, 0);         /* load return address                */
3730         M_ALD  (REG_ITMP1, REG_ITMP3, 0);   /* load exception into reg. itmp1     */
3731
3732         M_BNEZ (REG_ITMP1, 2);              /* if no exception then return        */
3733         M_LDA  (REG_SP, REG_SP, 8);         /* remove stackframe, delay slot      */
3734
3735         M_RET  (REG_RA);                    /* return to caller                   */
3736         M_NOP;                              /* delay slot                         */
3737         
3738         M_AST  (REG_ZERO, REG_ITMP3, 0);    /* store NULL into exceptionptr       */
3739         M_ALD  (REG_ITMP3, REG_PV,18*8);    /* load asm exception handler address */
3740
3741         M_JMP  (REG_ITMP3);                 /* jump to asm exception handler      */
3742         M_LDA  (REG_ITMP2, REG_RA, -4);     /* move fault address into reg. itmp2 */
3743                                             /* delay slot                         */
3744
3745         s[16] = (u8) f;                     /* address of native method           */
3746         s[17] = (u8) (&exceptionptr);       /* address of exceptionptr            */
3747         s[18]= (u8) (asm_handle_nat_exception); /* addr of asm exception handler  */
3748         s[19] = (u8) (&env);                  /* addr of jni_environement         */
3749
3750         (void) docacheflush((void*) s, (char*) p - (char*) s, ICACHE);
3751
3752 #ifdef STATISTICS
3753         count_nstub_len += NATIVESTUBSIZE * 8;
3754 #endif
3755
3756         return (u1*) s;
3757 }
3758
3759 /* function: removenativestub **************************************************
3760
3761     removes a previously created native-stub from memory
3762     
3763 *******************************************************************************/
3764
3765 void removenativestub (u1 *stub)
3766 {
3767         CFREE (stub, NATIVESTUBSIZE * 8);
3768 }
3769
3770
3771 /* function: createcalljava ****************************************************
3772
3773         creates the asm_calljavamethod (MIPS assembler does not like data in the
3774         text segment). Documentation can be found in asmpart.c.
3775         
3776 *******************************************************************************/
3777
3778 #define REG_FSS0    20
3779 #define REG_FSS1    22
3780 #define REG_FSS2    25
3781 #define REG_FSS3    27
3782 #define REG_FSS4    29
3783 #define REG_FSS5    31
3784
3785 #define CALL_JAVA_MEM_SIZE 60
3786 #define CALL_JAVA_ENTRY    20
3787 #define CALL_JAVA_XHANDLER 55
3788
3789 static s4 calljavamem[CALL_JAVA_MEM_SIZE];
3790
3791 void createcalljava ()
3792 {
3793         s4 *p;
3794         
3795         *((void**)(calljavamem + 0)) = (void*) asm_call_jit_compiler;
3796         *((void**)(calljavamem + 2)) = (void*) builtin_throw_exception;
3797 #if POINTERSIZE==8
3798         *((void**)(calljavamem + 4)) = NULL;
3799         *((void**)(calljavamem + 6)) = (void*) (calljavamem + CALL_JAVA_XHANDLER);
3800         *((void**)(calljavamem + 8)) = (void*) (calljavamem + CALL_JAVA_XHANDLER);
3801         *((void**)(calljavamem +10)) = (void*) (calljavamem + CALL_JAVA_ENTRY);
3802 #else
3803         *((void**)(calljavamem + 8)) = NULL;
3804         *((void**)(calljavamem + 9)) = (void*) (calljavamem + CALL_JAVA_XHANDLER);
3805         *((void**)(calljavamem +10)) = (void*) (calljavamem + CALL_JAVA_XHANDLER);
3806         *((void**)(calljavamem +11)) = (void*) (calljavamem + CALL_JAVA_ENTRY);
3807 #endif
3808         
3809         calljavamem[12] = 1;                /* extable size                       */
3810         calljavamem[13] = 0;                /* fltsave                            */
3811         calljavamem[14] = 0;                /* intsave                            */
3812         calljavamem[15] = 0;                /* isleaf                             */
3813         calljavamem[16] = 0;                /* IsSync                             */
3814         calljavamem[17] = 80;               /* frame size                         */
3815         calljavamem[18] = 0;                /* method pointer (NULL)              */
3816         calljavamem[19] = 0;                /* method pointer (NULL)              */
3817
3818         p = calljavamem + CALL_JAVA_ENTRY;  /* code generation pointer            */
3819
3820 /*  20 */
3821         M_LDA (REG_SP, REG_SP, -10*8);      /* allocate stackframe                */
3822         M_LST (REG_RA, REG_SP, 0);          /* save return address                */
3823
3824         M_BRS(1);                           /* compute current program counter    */
3825         M_LST (REG_PV, REG_SP, 3*8);        /* save procedure vector              */
3826 /*  24 */
3827         M_LDA (REG_PV, REG_RA, -4*4);       /* compute procedure vector           */
3828         M_DST (REG_FSS0, REG_SP, 4*8);      /* save non JavaABI saved flt regs    */
3829
3830         M_DST (REG_FSS1, REG_SP, 5*8);
3831         M_DST (REG_FSS2, REG_SP, 6*8);
3832 /*  28 */
3833         M_DST (REG_FSS3, REG_SP, 7*8);
3834         M_DST (REG_FSS4, REG_SP, 8*8);
3835
3836         M_DST (REG_FSS5, REG_SP, 9*8);
3837         M_LST (REG_ARG_0, REG_SP, 2*8);     /* save method pointer for compiler   */
3838 /*  32 */
3839         M_LDA (REG_ITMP1, REG_SP, 2*8);     /* pass pointer to methodptr via itmp1*/
3840         M_MOV (REG_ARG_1, REG_ARG_0);       /* pass the remaining parameters      */
3841
3842         M_MOV (REG_ARG_2, REG_ARG_1);
3843         M_MOV (REG_ARG_3, REG_ARG_2);
3844 /*  36 */
3845         M_MOV (REG_ARG_4, REG_ARG_3);
3846         M_ALD (REG_METHODPTR, REG_PV, -80); /* address of asm_call_jit_compiler   */
3847
3848         M_AST (REG_METHODPTR, REG_SP, 8);   /* store function address             */
3849         M_MOV (REG_SP, REG_METHODPTR);      /* set method pointer                 */
3850 /*  40 */
3851         M_ALD (REG_PV, REG_METHODPTR, 8);   /* method call as in Java             */
3852         M_JSR (REG_RA, REG_PV);             /* call JIT compiler                  */
3853
3854         M_NOP;                              /* delay slot                         */
3855         M_LDA (REG_PV, REG_RA, -23*4);      /* recompute procedure vector         */
3856
3857 /*  44 */
3858 #if 0
3859         M_CLR (REG_RESULT);                 /* clear return value (exception ptr) */
3860 #else
3861         M_NOP;
3862 #endif
3863 /*  calljava_return: */
3864         M_LLD (REG_RA, REG_SP, 0);          /* restore return address             */
3865
3866         M_LLD (REG_PV, REG_SP, 3*8);        /* restore procedure vector           */
3867         M_DLD (REG_FSS0, REG_SP, 4*8);      /* restore non JavaABI saved flt regs */
3868 /*  48 */
3869         M_DLD (REG_FSS1, REG_SP, 5*8);
3870         M_DLD (REG_FSS2, REG_SP, 6*8);
3871
3872         M_DLD (REG_FSS3, REG_SP, 7*8);
3873         M_DLD (REG_FSS4, REG_SP, 8*8);
3874 /*  52 */
3875         M_DLD (REG_FSS5, REG_SP, 9*8);
3876         M_RET(REG_RA);                      /* return                             */
3877
3878         M_LDA (REG_SP, REG_SP, 10*8);       /* deallocate stackframe (delay slot) */
3879
3880 /*  55 */
3881 /*  calljava_xhandler: */
3882
3883         M_ALD (REG_ITMP3, REG_PV, -72);     /* address of builtin_throw_exception */
3884
3885         M_JSR (REG_RA, REG_ITMP3);          /* call builtin                       */
3886         M_MOV (REG_ITMP1, REG_ARG_0);       /* pass parameter (delay slot)        */
3887 /*  58 */
3888         M_BR(-14);                          /* branch calljava_return             */
3889         M_NOP;                              /* delay slot                         */
3890
3891         (void) cacheflush((void*)(calljavamem + CALL_JAVA_ENTRY),
3892                (CALL_JAVA_MEM_SIZE - CALL_JAVA_ENTRY) * (int) sizeof(s4), ICACHE);
3893 }
3894
3895
3896 typedef java_objectheader* (*asm_fptr)(methodinfo*, void*, void*, void*, void*);
3897
3898 java_objectheader *asm_calljavamethod (methodinfo *m, void *arg1, void *arg2,
3899                                                       void *arg3, void *arg4)
3900 {
3901         java_objectheader *r = ((asm_fptr)(calljavamem + 20))(m, arg1, arg2, arg3, arg4);
3902         return (exceptionptr ? r : NULL);
3903 }
3904
3905 java_objectheader *asm_calljavafunction (methodinfo *m, void *arg1, void *arg2,
3906                                                       void *arg3, void *arg4)
3907 {
3908         return ((asm_fptr)(calljavamem + 20))(m, arg1, arg2, arg3, arg4);
3909 }
3910
3911 void ngen_init()
3912 {
3913         createcalljava();
3914 }
3915
3916 void docacheflush(u1 *p, long bytelen, int dummy)
3917 {
3918         u1 *e = p + bytelen;
3919         long psize = sysconf(_SC_PAGESIZE);
3920         p -= (long) p & (psize-1);
3921         e += psize - ((((long) e - 1) & (psize-1)) + 1);
3922         bytelen = e-p;
3923         mprotect(p, bytelen, PROT_READ|PROT_WRITE|PROT_EXEC);
3924 }
3925
3926
3927 /*
3928  * These are local overrides for various environment variables in Emacs.
3929  * Please do not remove this and leave it at the end of the file, where
3930  * Emacs will automagically detect them.
3931  * ---------------------------------------------------------------------
3932  * Local variables:
3933  * mode: c
3934  * indent-tabs-mode: t
3935  * c-basic-offset: 4
3936  * tab-width: 4
3937  * End:
3938  */