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