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