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