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