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