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