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