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