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