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