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