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