* src/vm/jit/mips/emit.c (emit_copy): Fixed arguments to
[cacao.git] / src / vm / jit / mips / codegen.c
1 /* src/vm/jit/mips/codegen.c - machine code generator for MIPS
2
3    Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    Contact: cacao@cacaojvm.org
26
27    Authors: Andreas Krall
28             Reinhard Grafl
29
30    Changes: Christian Thalinger
31             Christian Ullrich
32             Edwin Steiner
33
34    Contains the codegenerator for an MIPS (R4000 or higher) processor.
35    This module generates MIPS machine code for a sequence of
36    intermediate code commands (ICMDs).
37
38    $Id: codegen.c 5619 2006-10-01 23:51:23Z edwin $
39
40 */
41
42
43 #include "config.h"
44
45 #include <assert.h>
46 #include <stdio.h>
47
48 #include "vm/types.h"
49
50 #include "md.h"
51 #include "md-abi.h"
52
53 #include "vm/jit/mips/arch.h"
54 #include "vm/jit/mips/codegen.h"
55
56 #include "native/native.h"
57
58 #if defined(ENABLE_THREADS)
59 # include "threads/native/lock.h"
60 #endif
61
62 #include "vm/builtin.h"
63 #include "vm/class.h"
64 #include "vm/exceptions.h"
65 #include "vm/options.h"
66 #include "vm/stringlocal.h"
67 #include "vm/vm.h"
68 #include "vm/jit/asmpart.h"
69 #include "vm/jit/codegen-common.h"
70 #include "vm/jit/dseg.h"
71 #include "vm/jit/emit-common.h"
72 #include "vm/jit/jit.h"
73 #include "vm/jit/patcher.h"
74 #include "vm/jit/reg.h"
75 #include "vm/jit/replace.h"
76
77 #if defined(ENABLE_LSRA)
78 # include "vm/jit/allocator/lsra.h"
79 #endif
80
81
82 /* codegen *********************************************************************
83
84    Generates machine code.
85
86 *******************************************************************************/
87
88 bool codegen(jitdata *jd)
89 {
90         methodinfo         *m;
91         codeinfo           *code;
92         codegendata        *cd;
93         registerdata       *rd;
94         s4                  len, s1, s2, s3, d, disp;
95         varinfo            *var;
96         basicblock         *bptr;
97         instruction        *iptr;
98         exceptiontable     *ex;
99         u2                  currentline;
100         methodinfo         *lm;             /* local methodinfo for ICMD_INVOKE*  */
101         unresolved_method  *um;
102         builtintable_entry *bte;
103         methoddesc         *md;
104         fieldinfo          *fi;
105         unresolved_field   *uf;
106         rplpoint           *replacementpoint;
107         s4                  fieldtype;
108         s4                  varindex;
109
110         /* get required compiler data */
111
112         m    = jd->m;
113         code = jd->code;
114         cd   = jd->cd;
115         rd   = jd->rd;
116
117         {
118         s4 i, p, t, l;
119         s4 savedregs_num;
120
121         savedregs_num = (jd->isleafmethod) ? 0 : 1;       /* space to save the RA */
122
123         /* space to save used callee saved registers */
124
125         savedregs_num += (INT_SAV_CNT - rd->savintreguse);
126         savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
127
128         cd->stackframesize = rd->memuse + savedregs_num;
129
130 #if defined(ENABLE_THREADS)
131         /* space to save argument of monitor_enter */
132
133         if (checksync && (m->flags & ACC_SYNCHRONIZED))
134                 cd->stackframesize++;
135 #endif
136
137         /* keep stack 16-byte aligned */
138
139         if (cd->stackframesize & 1)
140                 cd->stackframesize++;
141
142         /* create method header */
143
144 #if SIZEOF_VOID_P == 4
145         (void) dseg_addaddress(cd, code);                      /* Filler          */
146 #endif
147         (void) dseg_addaddress(cd, code);                      /* CodeinfoPointer */
148         (void) dseg_adds4(cd, cd->stackframesize * 8);         /* FrameSize       */
149
150 #if defined(ENABLE_THREADS)
151         /* IsSync contains the offset relative to the stack pointer for the
152            argument of monitor_exit used in the exception handler. Since the
153            offset could be zero and give a wrong meaning of the flag it is
154            offset by one.
155         */
156
157         if (checksync && (m->flags & ACC_SYNCHRONIZED))
158                 (void) dseg_adds4(cd, (rd->memuse + 1) * 8);       /* IsSync          */
159         else
160 #endif
161                 (void) dseg_adds4(cd, 0);                          /* IsSync          */
162                                                
163         (void) dseg_adds4(cd, jd->isleafmethod);               /* IsLeaf          */
164         (void) dseg_adds4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave         */
165         (void) dseg_adds4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave         */
166         dseg_addlinenumbertablesize(cd);
167         (void) dseg_adds4(cd, cd->exceptiontablelength);       /* ExTableSize     */
168
169         /* create exception table */
170
171         for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
172                 dseg_addtarget(cd, ex->start);
173                 dseg_addtarget(cd, ex->end);
174                 dseg_addtarget(cd, ex->handler);
175                 (void) dseg_addaddress(cd, ex->catchtype.any);
176         }
177         
178         /* create stack frame (if necessary) */
179
180         if (cd->stackframesize)
181                 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8);
182
183         /* save return address and used callee saved registers */
184
185         p = cd->stackframesize;
186         if (!jd->isleafmethod) {
187                 p--; M_AST(REG_RA, REG_SP, p * 8);
188         }
189         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
190                 p--; M_AST(rd->savintregs[i], REG_SP, p * 8);
191         }
192         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
193                 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
194         }
195
196         /* take arguments out of register or stack frame */
197
198         md = m->parseddesc;
199
200         for (p = 0, l = 0; p < md->paramcount; p++) {
201                 t = md->paramtypes[p].type;
202
203                 varindex = jd->local_map[l * 5 + t];
204
205                 l++;
206                 if (IS_2_WORD_TYPE(t))    /* increment local counter for 2 word types */
207                         l++;
208
209                 if (varindex == UNUSED)
210                         continue;
211
212                 var = VAR(varindex);
213
214                 s1 = md->params[p].regoff;
215                 if (IS_INT_LNG_TYPE(t)) {                    /* integer args          */
216                         if (!md->params[p].inmemory) {           /* register arguments    */
217                                 s2 = rd->argintregs[s1];
218                                 if (!(var->flags & INMEMORY)) {      /* reg arg -> register   */
219                                         M_INTMOVE(s2, var->vv.regoff);
220                                 } else {                             /* reg arg -> spilled    */
221                                         M_LST(s2, REG_SP, var->vv.regoff * 8);
222                                 }
223
224                         } else {                                 /* stack arguments       */
225                                 if (!(var->flags & INMEMORY)) {      /* stack arg -> register */
226                                         M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
227                                 } else {                             /* stack arg -> spilled  */
228                                         var->vv.regoff = cd->stackframesize + s1;
229                                 }
230                         }
231
232                 } else {                                     /* floating args         */
233                         if (!md->params[p].inmemory) {           /* register arguments    */
234                                 s2 = rd->argfltregs[s1];
235                                 if (!(var->flags & INMEMORY)) {      /* reg arg -> register   */
236                                         if (IS_2_WORD_TYPE(t))
237                                                 M_DMOV(s2, var->vv.regoff);
238                                         else
239                                                 M_FMOV(s2, var->vv.regoff);
240                                 } else {                                         /* reg arg -> spilled    */
241                                         if (IS_2_WORD_TYPE(t))
242                                                 M_DST(s2, REG_SP, var->vv.regoff * 8);
243                                         else
244                                                 M_FST(s2, REG_SP, var->vv.regoff * 8);
245                                 }
246
247                         } else {                                 /* stack arguments       */
248                                 if (!(var->flags & INMEMORY)) {      /* stack-arg -> register */
249                                         if (IS_2_WORD_TYPE(t))
250                                                 M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
251                                         else
252                                                 M_FLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
253                                 } else                               /* stack-arg -> spilled  */
254                                         var->vv.regoff = cd->stackframesize + s1;
255                         }
256                 }
257         } /* end for */
258
259         /* call monitorenter function */
260
261 #if defined(ENABLE_THREADS)
262         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
263                 /* stack offset for monitor argument */
264
265                 s1 = rd->memuse;
266
267 # if !defined(NDEBUG)
268                 if (opt_verbosecall) {
269                         M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
270
271                         for (p = 0; p < INT_ARG_CNT; p++)
272                                 M_LST(rd->argintregs[p], REG_SP, p * 8);
273
274                         for (p = 0; p < FLT_ARG_CNT; p++)
275                                 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
276
277                         s1 += INT_ARG_CNT + FLT_ARG_CNT;
278                 }
279 # endif
280
281                 /* get correct lock object */
282
283                 if (m->flags & ACC_STATIC) {
284                         p = dseg_addaddress(cd, &m->class->object.header);
285                         M_ALD(REG_A0, REG_PV, p);
286                 }
287                 else {
288                         M_BEQZ(REG_A0, 0);
289                         codegen_add_nullpointerexception_ref(cd);
290                 }
291
292                 p = dseg_addaddress(cd, LOCK_monitor_enter);
293                 M_ALD(REG_ITMP3, REG_PV, p);
294                 M_JSR(REG_RA, REG_ITMP3);
295                 M_AST(REG_A0, REG_SP, s1 * 8);         /* branch delay */
296
297 # if !defined(NDEBUG)
298                 if (opt_verbosecall) {
299                         for (p = 0; p < INT_ARG_CNT; p++)
300                                 M_LLD(rd->argintregs[p], REG_SP, p * 8);
301
302                         for (p = 0; p < FLT_ARG_CNT; p++)
303                                 M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
304
305
306                         M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
307                 }
308 # endif
309         }
310 #endif
311
312 #if !defined(NDEBUG)
313         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
314                 emit_verbosecall_enter(jd);
315 #endif
316
317         }
318
319         /* end of header generation */
320
321         replacementpoint = jd->code->rplpoints;
322
323         /* walk through all basic blocks */
324
325         for (bptr = jd->new_basicblocks; bptr != NULL; bptr = bptr->next) {
326
327                 /* handle replacement points */
328
329 #if 0
330                 if (bptr->bitflags & BBFLAG_REPLACEMENT && bptr->flags >= BBREACHED) {
331
332                         /* 8-byte align pc */
333                         if ((ptrint) cd->mcodeptr & 4) {
334                                 M_NOP;
335                         }
336                         
337                         replacementpoint->pc = (u1*)(ptrint) (cd->mcodeptr - cd->mcodebase);
338                         replacementpoint++;
339
340                         assert(cd->lastmcodeptr <= cd->mcodeptr);
341                         cd->lastmcodeptr = cd->mcodeptr + 2 * 4;       /* br + delay slot */
342                 }
343 #endif
344
345                 /* store relative start of block */
346
347                 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
348
349                 if (bptr->flags >= BBREACHED) {
350
351                         /* branch resolving */
352                         {
353                                 branchref *bref;
354                                 for (bref = bptr->branchrefs; bref != NULL; bref = bref->next) {
355                                         gen_resolvebranch(cd->mcodebase + bref->branchpos, 
356                                                                           bref->branchpos,
357                                                                           bptr->mpc);
358                                 }
359                         }
360
361                 /* copy interface registers to their destination */
362
363                 len = bptr->indepth;
364                 MCODECHECK(64+len);
365 #if defined(ENABLE_LSRA)
366                 if (opt_lsra) {
367                 while (len) {
368                         len--;
369                         src = bptr->invars[len];
370                         if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
371                                         /*                              d = reg_of_var(m, src, REG_ITMP1); */
372                                         if (!(src->flags & INMEMORY))
373                                                 d = src->vv.regoff;
374                                         else
375                                                 d = REG_ITMP1;
376                                         M_INTMOVE(REG_ITMP1, d);
377                                         emit_store(jd, NULL, src, d);
378                                 }
379                         }
380                 } else {
381 #endif
382                 while (len) {
383                         len--;
384                         var = VAR(bptr->invars[len]);
385                         if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
386                                 d = codegen_reg_of_var(0, var, REG_ITMP1);
387                                 M_INTMOVE(REG_ITMP1, d);
388                                 emit_store(jd, NULL, var, d);
389
390                         } else {
391                                 assert((var->flags & OUTVAR));
392                                 d = codegen_reg_of_var(0, var, REG_IFTMP);
393                         }
394                 }
395 #if defined(ENABLE_LSRA)
396                 }
397 #endif
398                 /* walk through all instructions */
399                 
400                 len = bptr->icount;
401                 currentline = 0;
402
403                 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
404                         if (iptr->line != currentline) {
405                                 dseg_addlinenumber(cd, iptr->line);
406                                 currentline = iptr->line;
407                         }
408
409                         MCODECHECK(64);   /* an instruction usually needs < 64 words      */
410
411                         switch (iptr->opc) {
412
413                 case ICMD_NOP:        /* ...  ==> ...                                 */
414                         break;
415
416                 case ICMD_CHECKNULL:  /* ..., objectref  ==> ..., objectref           */
417
418                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
419                         M_BEQZ(s1, 0);
420                         codegen_add_nullpointerexception_ref(cd);
421                         M_NOP;
422                         break;
423
424                 /* constant operations ************************************************/
425
426                 case ICMD_ICONST:     /* ...  ==> ..., constant                       */
427
428                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
429                         ICONST(d, iptr->sx.val.i);
430                         emit_store_dst(jd, iptr, d);
431                         break;
432
433                 case ICMD_LCONST:     /* ...  ==> ..., constant                       */
434
435                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
436                         LCONST(d, iptr->sx.val.l);
437                         emit_store_dst(jd, iptr, d);
438                         break;
439
440                 case ICMD_FCONST:     /* ...  ==> ..., constant                       */
441
442                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
443                         disp = dseg_addfloat(cd, iptr->sx.val.f);
444                         M_FLD(d, REG_PV, disp);
445                         emit_store_dst(jd, iptr, d);
446                         break;
447                         
448                 case ICMD_DCONST:     /* ...  ==> ..., constant                       */
449
450                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
451                         disp = dseg_adddouble(cd, iptr->sx.val.d);
452                         M_DLD(d, REG_PV, disp);
453                         emit_store_dst(jd, iptr, d);
454                         break;
455
456                 case ICMD_ACONST:     /* ...  ==> ..., constant                       */
457
458                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
459
460                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
461                                 disp = dseg_addaddress(cd, NULL);
462
463                                 codegen_addpatchref(cd, PATCHER_aconst,
464                                                                         iptr->sx.val.c.ref,
465                                                                     disp);
466
467                                 if (opt_showdisassemble) {
468                                         M_NOP; M_NOP;
469                                 }
470
471                                 M_ALD(d, REG_PV, disp);
472
473                         } else {
474                                 if (iptr->sx.val.anyptr == NULL) {
475                                         M_INTMOVE(REG_ZERO, d);
476                                 } else {
477                                         disp = dseg_addaddress(cd, iptr->sx.val.anyptr);
478                                         M_ALD(d, REG_PV, disp);
479                                 }
480                         }
481                         emit_store_dst(jd, iptr, d);
482                         break;
483
484
485                 /* load/store/copy/move operations ************************************/
486
487                 case ICMD_ILOAD:      /* ...  ==> ..., content of local variable      */
488                 case ICMD_LLOAD:      /* ...  ==> ..., content of local variable      */
489                 case ICMD_ALOAD:      /* ...  ==> ..., content of local variable      */
490                 case ICMD_FLOAD:      /* ...  ==> ..., content of local variable      */
491                 case ICMD_DLOAD:      /* ...  ==> ..., content of local variable      */
492                 case ICMD_ISTORE:     /* ..., value  ==> ...                          */
493                 case ICMD_LSTORE:     /* ..., value  ==> ...                          */
494                 case ICMD_ASTORE:     /* ..., value  ==> ...                          */
495                 case ICMD_FSTORE:     /* ..., value  ==> ...                          */
496                 case ICMD_DSTORE:     /* ..., value  ==> ...                          */
497                 case ICMD_COPY:
498                 case ICMD_MOVE:
499                 case ICMD_DUP:
500
501                         M_COPY(iptr->s1.varindex, iptr->dst.varindex);
502                         break;
503
504
505                 /* pop/dup/swap operations ********************************************/
506
507                 /* attention: double and longs are only one entry in CACAO ICMDs      */
508
509                 case ICMD_POP:        /* ..., value  ==> ...                          */
510                 case ICMD_POP2:       /* ..., value, value  ==> ...                   */
511                         break;
512
513
514                 /* integer operations *************************************************/
515
516                 case ICMD_INEG:       /* ..., value  ==> ..., - value                 */
517
518                         s1 = emit_load_s1(jd, iptr, REG_ITMP1); 
519                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
520                         M_ISUB(REG_ZERO, s1, d);
521                         emit_store_dst(jd, iptr, d);
522                         break;
523
524                 case ICMD_LNEG:       /* ..., value  ==> ..., - value                 */
525
526                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
527                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
528                         M_LSUB(REG_ZERO, s1, d);
529                         emit_store_dst(jd, iptr, d);
530                         break;
531
532                 case ICMD_I2L:        /* ..., value  ==> ..., value                   */
533
534                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
535                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
536                         M_INTMOVE(s1, d);
537                         emit_store_dst(jd, iptr, d);
538                         break;
539
540                 case ICMD_L2I:        /* ..., value  ==> ..., value                   */
541
542                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
543                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
544                         M_ISLL_IMM(s1, 0, d );
545                         emit_store_dst(jd, iptr, d);
546                         break;
547
548                 case ICMD_INT2BYTE:   /* ..., value  ==> ..., value                   */
549
550                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
551                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
552                         M_LSLL_IMM(s1, 56, d);
553                         M_LSRA_IMM( d, 56, d);
554                         emit_store_dst(jd, iptr, d);
555                         break;
556
557                 case ICMD_INT2CHAR:   /* ..., value  ==> ..., value                   */
558
559                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
560                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
561             M_CZEXT(s1, d);
562                         emit_store_dst(jd, iptr, d);
563                         break;
564
565                 case ICMD_INT2SHORT:  /* ..., value  ==> ..., value                   */
566
567                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
568                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
569                         M_LSLL_IMM(s1, 48, d);
570                         M_LSRA_IMM( d, 48, d);
571                         emit_store_dst(jd, iptr, d);
572                         break;
573
574
575                 case ICMD_IADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
576
577                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
578                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
579                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
580                         M_IADD(s1, s2, d);
581                         emit_store_dst(jd, iptr, d);
582                         break;
583
584                 case ICMD_IADDCONST:  /* ..., value  ==> ..., value + constant        */
585                                       /* sx.val.i = constant                             */
586
587                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
588                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
589                         if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767)) {
590                                 M_IADD_IMM(s1, iptr->sx.val.i, d);
591                         } else {
592                                 ICONST(REG_ITMP2, iptr->sx.val.i);
593                                 M_IADD(s1, REG_ITMP2, d);
594                         }
595                         emit_store_dst(jd, iptr, d);
596                         break;
597
598                 case ICMD_LADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
599
600                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
601                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
602                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
603                         M_LADD(s1, s2, d);
604                         emit_store_dst(jd, iptr, d);
605                         break;
606
607                 case ICMD_LADDCONST:  /* ..., value  ==> ..., value + constant        */
608                                       /* sx.val.l = constant                             */
609
610                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
611                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
612                         if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
613                                 M_LADD_IMM(s1, iptr->sx.val.l, d);
614                         } else {
615                                 LCONST(REG_ITMP2, iptr->sx.val.l);
616                                 M_LADD(s1, REG_ITMP2, d);
617                         }
618                         emit_store_dst(jd, iptr, d);
619                         break;
620
621                 case ICMD_ISUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
622
623                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
624                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
625                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
626                         M_ISUB(s1, s2, d);
627                         emit_store_dst(jd, iptr, d);
628                         break;
629
630                 case ICMD_ISUBCONST:  /* ..., value  ==> ..., value + constant        */
631                                       /* sx.val.i = constant                             */
632
633                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
634                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
635                         if ((iptr->sx.val.i >= -32767) && (iptr->sx.val.i <= 32768)) {
636                                 M_IADD_IMM(s1, -iptr->sx.val.i, d);
637                         } else {
638                                 ICONST(REG_ITMP2, iptr->sx.val.i);
639                                 M_ISUB(s1, REG_ITMP2, d);
640                         }
641                         emit_store_dst(jd, iptr, d);
642                         break;
643
644                 case ICMD_LSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
645
646                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
647                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
648                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
649                         M_LSUB(s1, s2, d);
650                         emit_store_dst(jd, iptr, d);
651                         break;
652
653                 case ICMD_LSUBCONST:  /* ..., value  ==> ..., value - constant        */
654                                       /* sx.val.l = constant                             */
655
656                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
657                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
658                         if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l <= 32768)) {
659                                 M_LADD_IMM(s1, -iptr->sx.val.l, d);
660                         } else {
661                                 LCONST(REG_ITMP2, iptr->sx.val.l);
662                                 M_LSUB(s1, REG_ITMP2, d);
663                         }
664                         emit_store_dst(jd, iptr, d);
665                         break;
666
667                 case ICMD_IMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
668
669                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
670                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
671                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
672                         M_IMUL(s1, s2);
673                         M_MFLO(d);
674                         M_NOP;
675                         M_NOP;
676                         emit_store_dst(jd, iptr, d);
677                         break;
678
679                 case ICMD_IMULCONST:  /* ..., value  ==> ..., value * constant        */
680                                       /* sx.val.i = constant                             */
681
682                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
683                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
684                         ICONST(REG_ITMP2, iptr->sx.val.i);
685                         M_IMUL(s1, REG_ITMP2);
686                         M_MFLO(d);
687                         M_NOP;
688                         M_NOP;
689                         emit_store_dst(jd, iptr, d);
690                         break;
691
692                 case ICMD_LMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
693
694                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
695                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
696                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
697                         M_LMUL(s1, s2);
698                         M_MFLO(d);
699                         M_NOP;
700                         M_NOP;
701                         emit_store_dst(jd, iptr, d);
702                         break;
703
704                 case ICMD_LMULCONST:  /* ..., value  ==> ..., value * constant        */
705                                       /* sx.val.l = constant                             */
706
707                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
708                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
709                         LCONST(REG_ITMP2, iptr->sx.val.l);
710                         M_LMUL(s1, REG_ITMP2);
711                         M_MFLO(d);
712                         M_NOP;
713                         M_NOP;
714                         emit_store_dst(jd, iptr, d);
715                         break;
716
717                 case ICMD_IDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
718
719                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
720                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
721                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
722                         gen_div_check(s2);
723                         M_IDIV(s1, s2);
724                         M_MFLO(d);
725                         M_NOP;
726                         M_NOP;
727                         emit_store_dst(jd, iptr, d);
728                         break;
729
730                 case ICMD_LDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
731
732                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
733                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
734                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
735                         gen_div_check(s2);
736                         M_LDIV(s1, s2);
737                         M_MFLO(d);
738                         M_NOP;
739                         M_NOP;
740                         emit_store_dst(jd, iptr, d);
741                         break;
742
743                 case ICMD_IREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
744
745                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
746                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
747                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
748                         gen_div_check(s2);
749                         M_IDIV(s1, s2);
750                         M_MFHI(d);
751                         M_NOP;
752                         M_NOP;
753                         emit_store_dst(jd, iptr, d);
754                         break;
755
756                 case ICMD_LREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
757
758                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
759                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
760                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
761                         gen_div_check(s2);
762                         M_LDIV(s1, s2);
763                         M_MFHI(d);
764                         M_NOP;
765                         M_NOP;
766                         emit_store_dst(jd, iptr, d);
767                         break;
768
769                 case ICMD_IDIVPOW2:   /* ..., value  ==> ..., value << constant       */
770                 case ICMD_LDIVPOW2:   /* val.i = constant                             */
771                                       
772                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
773                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
774                         M_LSRA_IMM(s1, 63, REG_ITMP2);
775                         M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
776                         M_LADD(s1, REG_ITMP2, REG_ITMP2);
777                         M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
778                         emit_store_dst(jd, iptr, d);
779                         break;
780
781                 case ICMD_IREMPOW2:   /* ..., value  ==> ..., value % constant        */
782                                       /* sx.val.i = constant                          */
783
784                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
785                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
786                         if (s1 == d) {
787                                 M_MOV(s1, REG_ITMP1);
788                                 s1 = REG_ITMP1;
789                         }
790                         if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
791                                 M_AND_IMM(s1, iptr->sx.val.i, d);
792                                 M_BGEZ(s1, 4);
793                                 M_NOP;
794                                 M_ISUB(REG_ZERO, s1, d);
795                                 M_AND_IMM(d, iptr->sx.val.i, d);
796                         }
797                         else {
798                                 ICONST(REG_ITMP2, iptr->sx.val.i);
799                                 M_AND(s1, REG_ITMP2, d);
800                                 M_BGEZ(s1, 4);
801                                 M_NOP;
802                                 M_ISUB(REG_ZERO, s1, d);
803                                 M_AND(d, REG_ITMP2, d);
804                         }
805                         M_ISUB(REG_ZERO, d, d);
806                         emit_store_dst(jd, iptr, d);
807                         break;
808
809                 case ICMD_LREMPOW2:   /* ..., value  ==> ..., value % constant        */
810                                       /* sx.val.l = constant                          */
811
812                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
813                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
814                         if (s1 == d) {
815                                 M_MOV(s1, REG_ITMP1);
816                                 s1 = REG_ITMP1;
817                         }
818                         if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
819                                 M_AND_IMM(s1, iptr->sx.val.l, d);
820                                 M_BGEZ(s1, 4);
821                                 M_NOP;
822                                 M_LSUB(REG_ZERO, s1, d);
823                                 M_AND_IMM(d, iptr->sx.val.l, d);
824                         }
825                         else {
826                                 LCONST(REG_ITMP2, iptr->sx.val.l);
827                                 M_AND(s1, REG_ITMP2, d);
828                                 M_BGEZ(s1, 4);
829                                 M_NOP;
830                                 M_LSUB(REG_ZERO, s1, d);
831                                 M_AND(d, REG_ITMP2, d);
832                         }
833                         M_LSUB(REG_ZERO, d, d);
834                         emit_store_dst(jd, iptr, d);
835                         break;
836
837                 case ICMD_ISHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
838
839                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
840                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
841                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
842                         M_ISLL(s1, s2, d);
843                         emit_store_dst(jd, iptr, d);
844                         break;
845
846                 case ICMD_ISHLCONST:  /* ..., value  ==> ..., value << constant       */
847                                       /* sx.val.i = constant                             */
848
849                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
850                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
851                         M_ISLL_IMM(s1, iptr->sx.val.i, d);
852                         emit_store_dst(jd, iptr, d);
853                         break;
854
855                 case ICMD_ISHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
856
857                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
858                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
859                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
860                         M_ISRA(s1, s2, d);
861                         emit_store_dst(jd, iptr, d);
862                         break;
863
864                 case ICMD_ISHRCONST:  /* ..., value  ==> ..., value >> constant       */
865                                       /* sx.val.i = constant                             */
866
867                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
868                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
869                         M_ISRA_IMM(s1, iptr->sx.val.i, d);
870                         emit_store_dst(jd, iptr, d);
871                         break;
872
873                 case ICMD_IUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
874
875                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
876                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
877                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
878                         M_ISRL(s1, s2, d);
879                         emit_store_dst(jd, iptr, d);
880                         break;
881
882                 case ICMD_IUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
883                                       /* sx.val.i = constant                             */
884
885                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
886                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
887                         M_ISRL_IMM(s1, iptr->sx.val.i, d);
888                         emit_store_dst(jd, iptr, d);
889                         break;
890
891                 case ICMD_LSHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
892
893                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
894                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
895                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
896                         M_LSLL(s1, s2, d);
897                         emit_store_dst(jd, iptr, d);
898                         break;
899
900                 case ICMD_LSHLCONST:  /* ..., value  ==> ..., value << constant       */
901                                       /* sx.val.i = constant                             */
902
903                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
904                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
905                         M_LSLL_IMM(s1, iptr->sx.val.i, d);
906                         emit_store_dst(jd, iptr, d);
907                         break;
908
909                 case ICMD_LSHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
910
911                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
912                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
913                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
914                         M_LSRA(s1, s2, d);
915                         emit_store_dst(jd, iptr, d);
916                         break;
917
918                 case ICMD_LSHRCONST:  /* ..., value  ==> ..., value >> constant       */
919                                       /* sx.val.i = constant                             */
920
921                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
922                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
923                         M_LSRA_IMM(s1, iptr->sx.val.i, d);
924                         emit_store_dst(jd, iptr, d);
925                         break;
926
927                 case ICMD_LUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
928
929                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
930                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
931                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
932                         M_LSRL(s1, s2, d);
933                         emit_store_dst(jd, iptr, d);
934                         break;
935
936                 case ICMD_LUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
937                                       /* sx.val.i = constant                             */
938
939                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
940                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
941                         M_LSRL_IMM(s1, iptr->sx.val.i, d);
942                         emit_store_dst(jd, iptr, d);
943                         break;
944
945                 case ICMD_IAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
946                 case ICMD_LAND:
947
948                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
949                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
950                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
951                         M_AND(s1, s2, d);
952                         emit_store_dst(jd, iptr, d);
953                         break;
954
955                 case ICMD_IANDCONST:  /* ..., value  ==> ..., value & constant        */
956                                       /* sx.val.i = constant                             */
957
958                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
959                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
960                         if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
961                                 M_AND_IMM(s1, iptr->sx.val.i, d);
962                         } else {
963                                 ICONST(REG_ITMP2, iptr->sx.val.i);
964                                 M_AND(s1, REG_ITMP2, d);
965                         }
966                         emit_store_dst(jd, iptr, d);
967                         break;
968
969                 case ICMD_LANDCONST:  /* ..., value  ==> ..., value & constant        */
970                                       /* sx.val.l = constant                             */
971
972                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
973                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
974                         if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
975                                 M_AND_IMM(s1, iptr->sx.val.l, d);
976                         } else {
977                                 LCONST(REG_ITMP2, iptr->sx.val.l);
978                                 M_AND(s1, REG_ITMP2, d);
979                         }
980                         emit_store_dst(jd, iptr, d);
981                         break;
982
983                 case ICMD_IOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
984                 case ICMD_LOR:
985
986                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
987                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
988                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
989                         M_OR(s1,s2, d);
990                         emit_store_dst(jd, iptr, d);
991                         break;
992
993                 case ICMD_IORCONST:   /* ..., value  ==> ..., value | constant        */
994                                       /* sx.val.i = constant                             */
995
996                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
997                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
998                         if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
999                                 M_OR_IMM(s1, iptr->sx.val.i, d);
1000                         } else {
1001                                 ICONST(REG_ITMP2, iptr->sx.val.i);
1002                                 M_OR(s1, REG_ITMP2, d);
1003                         }
1004                         emit_store_dst(jd, iptr, d);
1005                         break;
1006
1007                 case ICMD_LORCONST:   /* ..., value  ==> ..., value | constant        */
1008                                       /* sx.val.l = constant                             */
1009
1010                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1011                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1012                         if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1013                                 M_OR_IMM(s1, iptr->sx.val.l, d);
1014                         } else {
1015                                 LCONST(REG_ITMP2, iptr->sx.val.l);
1016                                 M_OR(s1, REG_ITMP2, d);
1017                         }
1018                         emit_store_dst(jd, iptr, d);
1019                         break;
1020
1021                 case ICMD_IXOR:       /* ..., val1, val2  ==> ..., val1 ^ val2        */
1022                 case ICMD_LXOR:
1023
1024                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1025                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1026                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1027                         M_XOR(s1, s2, d);
1028                         emit_store_dst(jd, iptr, d);
1029                         break;
1030
1031                 case ICMD_IXORCONST:  /* ..., value  ==> ..., value ^ constant        */
1032                                       /* sx.val.i = constant                             */
1033
1034                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1035                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1036                         if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
1037                                 M_XOR_IMM(s1, iptr->sx.val.i, d);
1038                         } else {
1039                                 ICONST(REG_ITMP2, iptr->sx.val.i);
1040                                 M_XOR(s1, REG_ITMP2, d);
1041                         }
1042                         emit_store_dst(jd, iptr, d);
1043                         break;
1044
1045                 case ICMD_LXORCONST:  /* ..., value  ==> ..., value ^ constant        */
1046                                       /* sx.val.l = constant                             */
1047
1048                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1049                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1050                         if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1051                                 M_XOR_IMM(s1, iptr->sx.val.l, d);
1052                         } else {
1053                                 LCONST(REG_ITMP2, iptr->sx.val.l);
1054                                 M_XOR(s1, REG_ITMP2, d);
1055                         }
1056                         emit_store_dst(jd, iptr, d);
1057                         break;
1058
1059
1060                 case ICMD_LCMP:       /* ..., val1, val2  ==> ..., val1 cmp val2      */
1061
1062                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1063                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1064                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1065                         M_CMPLT(s1, s2, REG_ITMP3);
1066                         M_CMPLT(s2, s1, REG_ITMP1);
1067                         M_LSUB(REG_ITMP1, REG_ITMP3, d);
1068                         emit_store_dst(jd, iptr, d);
1069                         break;
1070
1071
1072                 case ICMD_IINC:       /* ..., value  ==> ..., value + constant        */
1073                                       /* s1.localindex = variable, sx.val.i = constant             */
1074
1075                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1076                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1077
1078                         M_IADD_IMM(s1, iptr->sx.val.i, d);
1079
1080                         emit_store_dst(jd, iptr, d);
1081                         break;
1082
1083
1084                 /* floating operations ************************************************/
1085
1086                 case ICMD_FNEG:       /* ..., value  ==> ..., - value                 */
1087
1088                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1089                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1090                         M_FNEG(s1, d);
1091                         emit_store_dst(jd, iptr, d);
1092                         break;
1093
1094                 case ICMD_DNEG:       /* ..., value  ==> ..., - value                 */
1095
1096                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1097                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1098                         M_DNEG(s1, d);
1099                         emit_store_dst(jd, iptr, d);
1100                         break;
1101
1102                 case ICMD_FADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
1103
1104                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1105                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1106                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1107                         M_FADD(s1, s2, d);
1108                         emit_store_dst(jd, iptr, d);
1109                         break;
1110
1111                 case ICMD_DADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
1112
1113                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1114                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1115                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1116                         M_DADD(s1, s2, d);
1117                         emit_store_dst(jd, iptr, d);
1118                         break;
1119
1120                 case ICMD_FSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
1121
1122                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1123                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1124                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1125                         M_FSUB(s1, s2, d);
1126                         emit_store_dst(jd, iptr, d);
1127                         break;
1128
1129                 case ICMD_DSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
1130
1131                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1132                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1133                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1134                         M_DSUB(s1, s2, d);
1135                         emit_store_dst(jd, iptr, d);
1136                         break;
1137
1138                 case ICMD_FMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
1139
1140                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1141                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1142                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1143                         M_FMUL(s1, s2, d);
1144                         emit_store_dst(jd, iptr, d);
1145                         break;
1146
1147                 case ICMD_DMUL:       /* ..., val1, val2  ==> ..., val1 *** val2      */
1148
1149                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1150                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1151                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1152                         M_DMUL(s1, s2, d);
1153                         emit_store_dst(jd, iptr, d);
1154                         break;
1155
1156                 case ICMD_FDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1157
1158                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1159                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1160                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1161                         M_FDIV(s1, s2, d);
1162                         emit_store_dst(jd, iptr, d);
1163                         break;
1164
1165                 case ICMD_DDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1166
1167                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1168                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1169                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1170                         M_DDIV(s1, s2, d);
1171                         emit_store_dst(jd, iptr, d);
1172                         break;
1173
1174 #if 0           
1175                 case ICMD_FREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
1176
1177                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1178                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1179                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1180                         M_FDIV(s1,s2, REG_FTMP3);
1181                         M_FLOORFL(REG_FTMP3, REG_FTMP3);
1182                         M_CVTLF(REG_FTMP3, REG_FTMP3);
1183                         M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1184                         M_FSUB(s1, REG_FTMP3, d);
1185                         emit_store_dst(jd, iptr, d);
1186                     break;
1187
1188                 case ICMD_DREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
1189
1190                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1191                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1192                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1193                         M_DDIV(s1,s2, REG_FTMP3);
1194                         M_FLOORDL(REG_FTMP3, REG_FTMP3);
1195                         M_CVTLD(REG_FTMP3, REG_FTMP3);
1196                         M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1197                         M_DSUB(s1, REG_FTMP3, d);
1198                         emit_store_dst(jd, iptr, d);
1199                     break;
1200 #endif
1201
1202                 case ICMD_I2F:       /* ..., value  ==> ..., (float) value            */
1203                 case ICMD_L2F:
1204                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1205                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1206                         M_MOVLD(s1, d);
1207                         M_CVTLF(d, d);
1208                         emit_store_dst(jd, iptr, d);
1209                         break;
1210
1211                 case ICMD_I2D:       /* ..., value  ==> ..., (double) value           */
1212                 case ICMD_L2D:
1213                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1214                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1215                         M_MOVLD(s1, d);
1216                         M_CVTLD(d, d);
1217                         emit_store_dst(jd, iptr, d);
1218                         break;
1219
1220 #if 0
1221                 /* XXX these do not work correctly */
1222
1223                 case ICMD_F2I:       /* ..., (float) value  ==> ..., (int) value      */
1224
1225                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1226                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1227                         M_TRUNCFI(s1, REG_FTMP1);
1228                         M_MOVDI(REG_FTMP1, d);
1229                         M_NOP;
1230                         emit_store_dst(jd, iptr, d);
1231                         break;
1232                 
1233                 case ICMD_D2I:       /* ..., (double) value  ==> ..., (int) value     */
1234
1235                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1236                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1237                         M_TRUNCDI(s1, REG_FTMP1);
1238                         M_MOVDI(REG_FTMP1, d);
1239                         M_NOP;
1240                         emit_store_dst(jd, iptr, d);
1241                         break;
1242                 
1243                 case ICMD_F2L:       /* ..., (float) value  ==> ..., (long) value     */
1244
1245                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1246                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1247                         M_TRUNCFL(s1, REG_FTMP1);
1248                         M_MOVDL(REG_FTMP1, d);
1249                         M_NOP;
1250                         emit_store_dst(jd, iptr, d);
1251                         break;
1252
1253                 case ICMD_D2L:       /* ..., (double) value  ==> ..., (long) value    */
1254
1255                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1256                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1257                         M_TRUNCDL(s1, REG_FTMP1);
1258                         M_MOVDL(REG_FTMP1, d);
1259                         M_NOP;
1260                         emit_store_dst(jd, iptr, d);
1261                         break;
1262 #endif
1263
1264                 case ICMD_F2D:       /* ..., value  ==> ..., (double) value           */
1265
1266                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1267                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1268                         M_CVTFD(s1, d);
1269                         emit_store_dst(jd, iptr, d);
1270                         break;
1271                                         
1272                 case ICMD_D2F:       /* ..., value  ==> ..., (double) value           */
1273
1274                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1275                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1276                         M_CVTDF(s1, d);
1277                         emit_store_dst(jd, iptr, d);
1278                         break;
1279                 
1280                 case ICMD_FCMPL:      /* ..., val1, val2  ==> ..., val1 fcmpl val2    */
1281
1282                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1283                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1284                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1285                         M_FCMPULEF(s1, s2);
1286                         M_FBT(3);
1287                         M_LADD_IMM(REG_ZERO, 1, d);
1288                         M_BR(4);
1289                         M_NOP;
1290                         M_FCMPEQF(s1, s2);
1291                         M_LSUB_IMM(REG_ZERO, 1, d);
1292                         M_CMOVT(REG_ZERO, d);
1293                         emit_store_dst(jd, iptr, d);
1294                         break;
1295
1296                 case ICMD_DCMPL:      /* ..., val1, val2  ==> ..., val1 fcmpl val2    */
1297
1298                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1299                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1300                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1301                         M_FCMPULED(s1, s2);
1302                         M_FBT(3);
1303                         M_LADD_IMM(REG_ZERO, 1, d);
1304                         M_BR(4);
1305                         M_NOP;
1306                         M_FCMPEQD(s1, s2);
1307                         M_LSUB_IMM(REG_ZERO, 1, d);
1308                         M_CMOVT(REG_ZERO, d);
1309                         emit_store_dst(jd, iptr, d);
1310                         break;
1311                         
1312                 case ICMD_FCMPG:      /* ..., val1, val2  ==> ..., val1 fcmpg val2    */
1313
1314                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1315                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1316                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1317                         M_FCMPOLTF(s1, s2);
1318                         M_FBF(3);
1319                         M_LSUB_IMM(REG_ZERO, 1, d);
1320                         M_BR(4);
1321                         M_NOP;
1322                         M_FCMPEQF(s1, s2);
1323                         M_LADD_IMM(REG_ZERO, 1, d);
1324                         M_CMOVT(REG_ZERO, d);
1325                         emit_store_dst(jd, iptr, d);
1326                         break;
1327
1328                 case ICMD_DCMPG:      /* ..., val1, val2  ==> ..., val1 fcmpg val2    */
1329
1330                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1331                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1332                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1333                         M_FCMPOLTD(s1, s2);
1334                         M_FBF(3);
1335                         M_LSUB_IMM(REG_ZERO, 1, d);
1336                         M_BR(4);
1337                         M_NOP;
1338                         M_FCMPEQD(s1, s2);
1339                         M_LADD_IMM(REG_ZERO, 1, d);
1340                         M_CMOVT(REG_ZERO, d);
1341                         emit_store_dst(jd, iptr, d);
1342                         break;
1343
1344
1345                 /* memory operations **************************************************/
1346
1347                 case ICMD_ARRAYLENGTH: /* ..., arrayref  ==> ..., length              */
1348
1349                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1350                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1351                         gen_nullptr_check(s1);
1352                         M_ILD(d, s1, OFFSET(java_arrayheader, size));
1353                         emit_store_dst(jd, iptr, d);
1354                         break;
1355
1356                 case ICMD_BALOAD:     /* ..., arrayref, index  ==> ..., value         */
1357
1358                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1359                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1360                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1361                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1362                                 gen_nullptr_check(s1);
1363                                 gen_bound_check;
1364                         }
1365                         M_AADD(s2, s1, REG_ITMP3);
1366                         M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray, data[0]));
1367                         emit_store_dst(jd, iptr, d);
1368                         break;
1369
1370                 case ICMD_CALOAD:     /* ..., arrayref, index  ==> ..., value         */
1371
1372                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1373                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1374                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1375                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1376                                 gen_nullptr_check(s1);
1377                                 gen_bound_check;
1378                         }
1379                         M_AADD(s2, s1, REG_ITMP3);
1380                         M_AADD(s2, REG_ITMP3, REG_ITMP3);
1381                         M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1382                         emit_store_dst(jd, iptr, d);
1383                         break;                  
1384
1385                 case ICMD_SALOAD:     /* ..., arrayref, index  ==> ..., value         */
1386
1387                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1388                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1389                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1390                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1391                                 gen_nullptr_check(s1);
1392                                 gen_bound_check;
1393                         }
1394                         M_AADD(s2, s1, REG_ITMP3);
1395                         M_AADD(s2, REG_ITMP3, REG_ITMP3);
1396                         M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray, data[0]));
1397                         emit_store_dst(jd, iptr, d);
1398                         break;
1399
1400                 case ICMD_IALOAD:     /* ..., arrayref, index  ==> ..., value         */
1401
1402                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1403                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1404                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1405                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1406                                 gen_nullptr_check(s1);
1407                                 gen_bound_check;
1408                         }
1409                         M_ASLL_IMM(s2, 2, REG_ITMP3);
1410                         M_AADD(REG_ITMP3, s1, REG_ITMP3);
1411                         M_ILD(d, REG_ITMP3, OFFSET(java_intarray, data[0]));
1412                         emit_store_dst(jd, iptr, d);
1413                         break;
1414
1415                 case ICMD_LALOAD:     /* ..., arrayref, index  ==> ..., value         */
1416
1417                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1418                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1419                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1420                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1421                                 gen_nullptr_check(s1);
1422                                 gen_bound_check;
1423                         }
1424                         M_ASLL_IMM(s2, 3, REG_ITMP3);
1425                         M_AADD(REG_ITMP3, s1, REG_ITMP3);
1426                         M_LLD(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
1427                         emit_store_dst(jd, iptr, d);
1428                         break;
1429
1430                 case ICMD_FALOAD:     /* ..., arrayref, index  ==> ..., value         */
1431
1432                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1433                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1434                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1435                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1436                                 gen_nullptr_check(s1);
1437                                 gen_bound_check;
1438                         }
1439                         M_ASLL_IMM(s2, 2, REG_ITMP3);
1440                         M_AADD(REG_ITMP3, s1, REG_ITMP3);
1441                         M_FLD(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
1442                         emit_store_dst(jd, iptr, d);
1443                         break;
1444
1445                 case ICMD_DALOAD:     /* ..., arrayref, index  ==> ..., value         */
1446
1447                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1448                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1449                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1450                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1451                                 gen_nullptr_check(s1);
1452                                 gen_bound_check;
1453                         }
1454                         M_ASLL_IMM(s2, 3, REG_ITMP3);
1455                         M_AADD(REG_ITMP3, s1, REG_ITMP3);
1456                         M_DLD(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
1457                         emit_store_dst(jd, iptr, d);
1458                         break;
1459
1460                 case ICMD_AALOAD:     /* ..., arrayref, index  ==> ..., value         */
1461
1462                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1463                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1464                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1465                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1466                                 gen_nullptr_check(s1);
1467                                 gen_bound_check;
1468                         }
1469                         M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1470                         M_AADD(REG_ITMP3, s1, REG_ITMP3);
1471                         M_ALD(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
1472                         emit_store_dst(jd, iptr, d);
1473                         break;
1474
1475
1476                 case ICMD_BASTORE:    /* ..., arrayref, index, value  ==> ...         */
1477
1478                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1479                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1480                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1481                                 gen_nullptr_check(s1);
1482                                 gen_bound_check;
1483                         }
1484                         M_AADD(s2, s1, REG_ITMP1);
1485                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1486                         M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1487                         break;
1488
1489                 case ICMD_CASTORE:    /* ..., arrayref, index, value  ==> ...         */
1490                 case ICMD_SASTORE:    /* ..., arrayref, index, value  ==> ...         */
1491
1492                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1493                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1494                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1495                                 gen_nullptr_check(s1);
1496                                 gen_bound_check;
1497                         }
1498                         M_AADD(s2, s1, REG_ITMP1);
1499                         M_AADD(s2, REG_ITMP1, REG_ITMP1);
1500                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1501                         M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1502                         break;
1503
1504                 case ICMD_IASTORE:    /* ..., arrayref, index, value  ==> ...         */
1505
1506                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1507                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1508                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1509                                 gen_nullptr_check(s1);
1510                                 gen_bound_check;
1511                         }
1512                         M_ASLL_IMM(s2, 2, REG_ITMP2);
1513                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1514                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1515                         M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1516                         break;
1517
1518                 case ICMD_LASTORE:    /* ..., arrayref, index, value  ==> ...         */
1519
1520                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1521                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1522                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1523                                 gen_nullptr_check(s1);
1524                                 gen_bound_check;
1525                         }
1526                         M_ASLL_IMM(s2, 3, REG_ITMP2);
1527                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1528                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1529                         M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1530                         break;
1531
1532                 case ICMD_FASTORE:    /* ..., arrayref, index, value  ==> ...         */
1533
1534                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1535                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1536                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1537                                 gen_nullptr_check(s1);
1538                                 gen_bound_check;
1539                         }
1540                         M_ASLL_IMM(s2, 2, REG_ITMP2);
1541                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1542                         s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1543                         M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1544                         break;
1545
1546                 case ICMD_DASTORE:    /* ..., arrayref, index, value  ==> ...         */
1547
1548                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1549                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1550                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1551                                 gen_nullptr_check(s1);
1552                                 gen_bound_check;
1553                         }
1554                         M_ASLL_IMM(s2, 3, REG_ITMP2);
1555                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1556                         s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1557                         M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1558                         break;
1559
1560
1561                 case ICMD_AASTORE:    /* ..., arrayref, index, value  ==> ...         */
1562
1563                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1564                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1565                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1566                                 gen_nullptr_check(s1);
1567                                 gen_bound_check;
1568                         }
1569                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1570
1571                         M_MOV(s1, REG_A0);
1572                         M_MOV(s3, REG_A1);
1573                         disp = dseg_addaddress(cd, BUILTIN_canstore);
1574                         M_ALD(REG_ITMP3, REG_PV, disp);
1575                         M_JSR(REG_RA, REG_ITMP3);
1576                         M_NOP;
1577
1578                         M_BEQZ(REG_RESULT, 0);
1579                         codegen_add_arraystoreexception_ref(cd);
1580                         M_NOP;
1581
1582                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1583                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1584                         M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1585                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1586                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1587                         M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1588                         break;
1589
1590
1591                 case ICMD_BASTORECONST:   /* ..., arrayref, index  ==> ...            */
1592
1593                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1594                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1595                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1596                                 gen_nullptr_check(s1);
1597                                 gen_bound_check;
1598                         }
1599                         M_AADD(s2, s1, REG_ITMP1);
1600                         M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1601                         break;
1602
1603                 case ICMD_CASTORECONST:   /* ..., arrayref, index  ==> ...            */
1604                 case ICMD_SASTORECONST:   /* ..., arrayref, index  ==> ...            */
1605
1606                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1607                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1608                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1609                                 gen_nullptr_check(s1);
1610                                 gen_bound_check;
1611                         }
1612                         M_AADD(s2, s1, REG_ITMP1);
1613                         M_AADD(s2, REG_ITMP1, REG_ITMP1);
1614                         M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1615                         break;
1616
1617                 case ICMD_IASTORECONST:   /* ..., arrayref, index  ==> ...            */
1618
1619                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1620                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1621                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1622                                 gen_nullptr_check(s1);
1623                                 gen_bound_check;
1624                         }
1625                         M_ASLL_IMM(s2, 2, REG_ITMP2);
1626                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1627                         M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1628                         break;
1629
1630                 case ICMD_LASTORECONST:   /* ..., arrayref, index  ==> ...            */
1631
1632                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1633                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1634                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1635                                 gen_nullptr_check(s1);
1636                                 gen_bound_check;
1637                         }
1638                         M_ASLL_IMM(s2, 3, REG_ITMP2);
1639                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1640                         M_LST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1641                         break;
1642
1643                 case ICMD_AASTORECONST:   /* ..., arrayref, index  ==> ...            */
1644
1645                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1646                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1647                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1648                                 gen_nullptr_check(s1);
1649                                 gen_bound_check;
1650                         }
1651                         M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1652                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1653                         M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1654                         break;
1655
1656
1657                 case ICMD_GETSTATIC:  /* ...  ==> ..., value                          */
1658
1659                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1660                                 uf        = iptr->sx.s23.s3.uf;
1661                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1662                                 disp      = dseg_addaddress(cd, NULL);
1663
1664                                 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
1665
1666                                 if (opt_showdisassemble) {
1667                                         M_NOP; M_NOP;
1668                                 }
1669                         }
1670                         else {
1671                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1672                                 fieldtype = fi->type;
1673                                 disp      = dseg_addaddress(cd, &(fi->value));
1674
1675                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1676                                         codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
1677
1678                                         if (opt_showdisassemble) {
1679                                                 M_NOP; M_NOP;
1680                                         }
1681                                 }
1682                         }
1683
1684                         M_ALD(REG_ITMP1, REG_PV, disp);
1685
1686                         switch (fieldtype) {
1687                         case TYPE_INT:
1688                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1689                                 M_ILD_INTERN(d, REG_ITMP1, 0);
1690                                 break;
1691                         case TYPE_LNG:
1692                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1693                                 M_LLD_INTERN(d, REG_ITMP1, 0);
1694                                 break;
1695                         case TYPE_ADR:
1696                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1697                                 M_ALD_INTERN(d, REG_ITMP1, 0);
1698                                 break;
1699                         case TYPE_FLT:
1700                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1701                                 M_FLD_INTERN(d, REG_ITMP1, 0);
1702                                 break;
1703                         case TYPE_DBL:                          
1704                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1705                                 M_DLD_INTERN(d, REG_ITMP1, 0);
1706                                 break;
1707                         }
1708                         emit_store_dst(jd, iptr, d);
1709                         break;
1710
1711                 case ICMD_PUTSTATIC:  /* ..., value  ==> ...                          */
1712
1713                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1714                                 uf        = iptr->sx.s23.s3.uf;
1715                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1716                                 disp      = dseg_addaddress(cd, NULL);
1717
1718                                 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
1719
1720                                 if (opt_showdisassemble) {
1721                                         M_NOP; M_NOP;
1722                                 }
1723                         }
1724                         else {
1725                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1726                                 fieldtype = fi->type;
1727                                 disp      = dseg_addaddress(cd, &(fi->value));
1728
1729                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1730                                         codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
1731
1732                                         if (opt_showdisassemble) {
1733                                                 M_NOP; M_NOP;
1734                                         }
1735                                 }
1736                         }
1737
1738                         M_ALD(REG_ITMP1, REG_PV, disp);
1739
1740                         switch (fieldtype) {
1741                         case TYPE_INT:
1742                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1743                                 M_IST_INTERN(s1, REG_ITMP1, 0);
1744                                 break;
1745                         case TYPE_LNG:
1746                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1747                                 M_LST_INTERN(s1, REG_ITMP1, 0);
1748                                 break;
1749                         case TYPE_ADR:
1750                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1751                                 M_AST_INTERN(s1, REG_ITMP1, 0);
1752                                 break;
1753                         case TYPE_FLT:
1754                                 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1755                                 M_FST_INTERN(s1, REG_ITMP1, 0);
1756                                 break;
1757                         case TYPE_DBL:
1758                                 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1759                                 M_DST_INTERN(s1, REG_ITMP1, 0);
1760                                 break;
1761                         }
1762                         break;
1763
1764                 case ICMD_PUTSTATICCONST: /* ...  ==> ...                             */
1765                                           /* val = value (in current instruction)     */
1766                                           /* following NOP)                           */
1767
1768                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1769                                 uf        = iptr->sx.s23.s3.uf;
1770                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1771                                 disp      = dseg_addaddress(cd, NULL);
1772
1773                                 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
1774
1775                                 if (opt_showdisassemble) {
1776                                         M_NOP; M_NOP;
1777                                 }
1778                         }
1779                         else {
1780                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1781                                 fieldtype = fi->type;
1782                                 disp      = dseg_addaddress(cd, &(fi->value));
1783
1784                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1785                                         codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
1786
1787                                         if (opt_showdisassemble) {
1788                                                 M_NOP; M_NOP;
1789                                         }
1790                                 }
1791                         }
1792
1793                         M_ALD(REG_ITMP1, REG_PV, disp);
1794
1795                         switch (fieldtype) {
1796                         case TYPE_INT:
1797                                 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
1798                                 break;
1799                         case TYPE_LNG:
1800                                 M_LST_INTERN(REG_ZERO, REG_ITMP1, 0);
1801                                 break;
1802                         case TYPE_ADR:
1803                                 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
1804                                 break;
1805                         case TYPE_FLT:
1806                                 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
1807                                 break;
1808                         case TYPE_DBL:
1809                                 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
1810                                 break;
1811                         }
1812                         break;
1813
1814
1815                 case ICMD_GETFIELD:   /* ...  ==> ..., value                          */
1816
1817                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1818                         gen_nullptr_check(s1);
1819
1820                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1821                                 uf        = iptr->sx.s23.s3.uf;
1822                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1823                                 disp      = 0;
1824
1825                                 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
1826
1827                                 if (opt_showdisassemble) {
1828                                         M_NOP; M_NOP;
1829                                 }
1830                         }
1831                         else {
1832                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1833                                 fieldtype = fi->type;
1834                                 disp      = fi->offset;
1835                         }
1836
1837                         switch (fieldtype) {
1838                         case TYPE_INT:
1839                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1840                                 M_ILD(d, s1, disp);
1841                                 break;
1842                         case TYPE_LNG:
1843                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1844                                 M_LLD(d, s1, disp);
1845                                 break;
1846                         case TYPE_ADR:
1847                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1848                                 M_ALD(d, s1, disp);
1849                                 break;
1850                         case TYPE_FLT:
1851                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1852                                 M_FLD(d, s1, disp);
1853                                 break;
1854                         case TYPE_DBL:                          
1855                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1856                                 M_DLD(d, s1, disp);
1857                                 break;
1858                         }
1859                         emit_store_dst(jd, iptr, d);
1860                         break;
1861
1862                 case ICMD_PUTFIELD:   /* ..., objectref, value  ==> ...               */
1863
1864                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1865                         gen_nullptr_check(s1);
1866
1867                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1868                                 uf        = iptr->sx.s23.s3.uf;
1869                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1870                                 disp      = 0;
1871                         }
1872                         else {
1873                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1874                                 fieldtype = fi->type;
1875                                 disp      = fi->offset;
1876                         }
1877
1878                         if (IS_INT_LNG_TYPE(fieldtype))
1879                                 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1880                         else
1881                                 s2 = emit_load_s2(jd, iptr, REG_FTMP1);
1882
1883                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1884                                 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
1885
1886                                 if (opt_showdisassemble) {
1887                                         M_NOP; M_NOP;
1888                                 }
1889                         }
1890
1891                         switch (fieldtype) {
1892                         case TYPE_INT:
1893                                 M_IST(s2, s1, disp);
1894                                 break;
1895                         case TYPE_LNG:
1896                                 M_LST(s2, s1, disp);
1897                                 break;
1898                         case TYPE_ADR:
1899                                 M_AST(s2, s1, disp);
1900                                 break;
1901                         case TYPE_FLT:
1902                                 M_FST(s2, s1, disp);
1903                                 break;
1904                         case TYPE_DBL:
1905                                 M_DST(s2, s1, disp);
1906                                 break;
1907                         }
1908                         break;
1909
1910                 case ICMD_PUTFIELDCONST:  /* ..., objectref  ==> ...                  */
1911
1912                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1913                         gen_nullptr_check(s1);
1914
1915                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1916                                 unresolved_field *uf = iptr->sx.s23.s3.uf;
1917
1918                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1919
1920                                 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
1921
1922                                 if (opt_showdisassemble) {
1923                                         M_NOP; M_NOP;
1924                                 }
1925
1926                                 disp = 0;
1927                         }
1928                         else {
1929                                 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1930                                 fieldtype = fi->type;
1931                                 disp = fi->offset;
1932                         }
1933
1934                         switch (fieldtype) {
1935                         case TYPE_INT:
1936                                 M_IST(REG_ZERO, s1, disp);
1937                                 break;
1938                         case TYPE_LNG:
1939                                 M_LST(REG_ZERO, s1, disp);
1940                                 break;
1941                         case TYPE_ADR:
1942                                 M_AST(REG_ZERO, s1, disp);
1943                                 break;
1944                         case TYPE_FLT:
1945                                 M_FST(REG_ZERO, s1, disp);
1946                                 break;
1947                         case TYPE_DBL:
1948                                 M_DST(REG_ZERO, s1, disp);
1949                                 break;
1950                         }
1951                         break;
1952
1953
1954                 /* branch operations **************************************************/
1955
1956                 case ICMD_ATHROW:       /* ..., objectref ==> ... (, objectref)       */
1957
1958                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1959                         M_INTMOVE(s1, REG_ITMP1_XPTR);
1960                         
1961 #ifdef ENABLE_VERIFIER
1962                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1963                                 codegen_addpatchref(cd, PATCHER_athrow_areturn,
1964                                                                         iptr->sx.s23.s2.uc, 0);
1965
1966                                 if (opt_showdisassemble) {
1967                                         M_NOP; M_NOP;
1968                                 }
1969                         }
1970 #endif /* ENABLE_VERIFIER */
1971
1972                         disp = dseg_addaddress(cd, asm_handle_exception);
1973                         M_ALD(REG_ITMP2, REG_PV, disp);
1974                         M_JSR(REG_ITMP2_XPC, REG_ITMP2);
1975                         M_NOP;
1976                         M_NOP;              /* nop ensures that XPC is less than the end */
1977                                             /* of basic block                            */
1978                         ALIGNCODENOP;
1979                         break;
1980
1981                 case ICMD_GOTO:         /* ... ==> ...                                */
1982                 case ICMD_RET:          /* ... ==> ...                                */
1983
1984                         M_BR(0);
1985                         codegen_addreference(cd, iptr->dst.block);
1986                         M_NOP;
1987                         ALIGNCODENOP;
1988                         break;
1989
1990                 case ICMD_JSR:          /* ... ==> ...                                */
1991
1992                         dseg_addtarget(cd, iptr->sx.s23.s3.jsrtarget.block);
1993                         M_ALD(REG_ITMP1, REG_PV, -(cd->dseglen));
1994                         M_JSR(REG_ITMP1, REG_ITMP1);        /* REG_ITMP1 = return address */
1995                         M_NOP;
1996                         break;
1997                         
1998                 case ICMD_IFNULL:       /* ..., value ==> ...                         */
1999
2000                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2001                         M_BEQZ(s1, 0);
2002                         codegen_addreference(cd, iptr->dst.block);
2003                         M_NOP;
2004                         break;
2005
2006                 case ICMD_IFNONNULL:    /* ..., value ==> ...                         */
2007
2008                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2009                         M_BNEZ(s1, 0);
2010                         codegen_addreference(cd, iptr->dst.block);
2011                         M_NOP;
2012                         break;
2013
2014                 case ICMD_IFEQ:         /* ..., value ==> ...                         */
2015
2016                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2017                         if (iptr->sx.val.i == 0) {
2018                                 M_BEQZ(s1, 0);
2019                         } else {
2020                                 ICONST(REG_ITMP2, iptr->sx.val.i);
2021                                 M_BEQ(s1, REG_ITMP2, 0);
2022                         }
2023                         codegen_addreference(cd, iptr->dst.block);
2024                         M_NOP;
2025                         break;
2026
2027                 case ICMD_IFLT:         /* ..., value ==> ...                         */
2028
2029                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2030                         if (iptr->sx.val.i == 0) {
2031                                 M_BLTZ(s1, 0);
2032                         } else {
2033                                 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767)) {
2034                                         M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2035                                 } else {
2036                                         ICONST(REG_ITMP2, iptr->sx.val.i);
2037                                         M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2038                                 }
2039                                 M_BNEZ(REG_ITMP1, 0);
2040                         }
2041                         codegen_addreference(cd, iptr->dst.block);
2042                         M_NOP;
2043                         break;
2044
2045                 case ICMD_IFLE:         /* ..., value ==> ...                         */
2046
2047                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2048                         if (iptr->sx.val.i == 0) {
2049                                 M_BLEZ(s1, 0);
2050                                 }
2051                         else {
2052                                 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2053                                         M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2054                                         M_BNEZ(REG_ITMP1, 0);
2055                                         }
2056                                 else {
2057                                         ICONST(REG_ITMP2, iptr->sx.val.i);
2058                                         M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2059                                         M_BEQZ(REG_ITMP1, 0);
2060                                         }
2061                                 }
2062                         codegen_addreference(cd, iptr->dst.block);
2063                         M_NOP;
2064                         break;
2065
2066                 case ICMD_IFNE:         /* ..., value ==> ...                         */
2067
2068                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2069                         if (iptr->sx.val.i == 0) {
2070                                 M_BNEZ(s1, 0);
2071                                 }
2072                         else {
2073                                 ICONST(REG_ITMP2, iptr->sx.val.i);
2074                                 M_BNE(s1, REG_ITMP2, 0);
2075                                 }
2076                         codegen_addreference(cd, iptr->dst.block);
2077                         M_NOP;
2078                         break;
2079
2080                 case ICMD_IFGT:         /* ..., value ==> ...                         */
2081
2082                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2083                         if (iptr->sx.val.i == 0) {
2084                                 M_BGTZ(s1, 0);
2085                                 }
2086                         else {
2087                                 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2088                                         M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2089                                         M_BEQZ(REG_ITMP1, 0);
2090                                         }
2091                                 else {
2092                                         ICONST(REG_ITMP2, iptr->sx.val.i);
2093                                         M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2094                                         M_BNEZ(REG_ITMP1, 0);
2095                                         }
2096                                 }
2097                         codegen_addreference(cd, iptr->dst.block);
2098                         M_NOP;
2099                         break;
2100
2101                 case ICMD_IFGE:         /* ..., value ==> ...                         */
2102
2103                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2104                         if (iptr->sx.val.i == 0) {
2105                                 M_BGEZ(s1, 0);
2106                                 }
2107                         else {
2108                                 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767)) {
2109                                         M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2110                                         }
2111                                 else {
2112                                         ICONST(REG_ITMP2, iptr->sx.val.i);
2113                                         M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2114                                         }
2115                                 M_BEQZ(REG_ITMP1, 0);
2116                                 }
2117                         codegen_addreference(cd, iptr->dst.block);
2118                         M_NOP;
2119                         break;
2120
2121                 case ICMD_IF_LEQ:       /* ..., value ==> ...                         */
2122
2123                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2124                         if (iptr->sx.val.l == 0) {
2125                                 M_BEQZ(s1, 0);
2126                                 }
2127                         else {
2128                                 LCONST(REG_ITMP2, iptr->sx.val.l);
2129                                 M_BEQ(s1, REG_ITMP2, 0);
2130                                 }
2131                         codegen_addreference(cd, iptr->dst.block);
2132                         M_NOP;
2133                         break;
2134
2135                 case ICMD_IF_LLT:       /* ..., value ==> ...                         */
2136
2137                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2138                         if (iptr->sx.val.l == 0) {
2139                                 M_BLTZ(s1, 0);
2140                                 }
2141                         else {
2142                                 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
2143                                         M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2144                                         }
2145                                 else {
2146                                         LCONST(REG_ITMP2, iptr->sx.val.l);
2147                                         M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2148                                         }
2149                                 M_BNEZ(REG_ITMP1, 0);
2150                                 }
2151                         codegen_addreference(cd, iptr->dst.block);
2152                         M_NOP;
2153                         break;
2154
2155                 case ICMD_IF_LLE:       /* ..., value ==> ...                         */
2156
2157                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2158                         if (iptr->sx.val.l == 0) {
2159                                 M_BLEZ(s1, 0);
2160                                 }
2161                         else {
2162                                 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2163                                         M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP1);
2164                                         M_BNEZ(REG_ITMP1, 0);
2165                                         }
2166                                 else {
2167                                         LCONST(REG_ITMP2, iptr->sx.val.l);
2168                                         M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2169                                         M_BEQZ(REG_ITMP1, 0);
2170                                         }
2171                                 }
2172                         codegen_addreference(cd, iptr->dst.block);
2173                         M_NOP;
2174                         break;
2175
2176                 case ICMD_IF_LNE:       /* ..., value ==> ...                         */
2177
2178                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2179                         if (iptr->sx.val.l == 0) {
2180                                 M_BNEZ(s1, 0);
2181                                 }
2182                         else {
2183                                 LCONST(REG_ITMP2, iptr->sx.val.l);
2184                                 M_BNE(s1, REG_ITMP2, 0);
2185                                 }
2186                         codegen_addreference(cd, iptr->dst.block);
2187                         M_NOP;
2188                         break;
2189
2190                 case ICMD_IF_LGT:       /* ..., value ==> ...                         */
2191
2192                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2193                         if (iptr->sx.val.l == 0) {
2194                                 M_BGTZ(s1, 0);
2195                                 }
2196                         else {
2197                                 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2198                                         M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP1);
2199                                         M_BEQZ(REG_ITMP1, 0);
2200                                         }
2201                                 else {
2202                                         LCONST(REG_ITMP2, iptr->sx.val.l);
2203                                         M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2204                                         M_BNEZ(REG_ITMP1, 0);
2205                                         }
2206                                 }
2207                         codegen_addreference(cd, iptr->dst.block);
2208                         M_NOP;
2209                         break;
2210
2211                 case ICMD_IF_LGE:       /* ..., value ==> ...                         */
2212
2213                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2214                         if (iptr->sx.val.l == 0) {
2215                                 M_BGEZ(s1, 0);
2216                                 }
2217                         else {
2218                                 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
2219                                         M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2220                                         }
2221                                 else {
2222                                         LCONST(REG_ITMP2, iptr->sx.val.l);
2223                                         M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2224                                         }
2225                                 M_BEQZ(REG_ITMP1, 0);
2226                                 }
2227                         codegen_addreference(cd, iptr->dst.block);
2228                         M_NOP;
2229                         break;
2230
2231                 case ICMD_IF_ICMPEQ:    /* ..., value, value ==> ...                  */
2232                 case ICMD_IF_LCMPEQ:    /* op1 = target JavaVM pc                     */
2233                 case ICMD_IF_ACMPEQ:
2234
2235                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2236                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2237                         M_BEQ(s1, s2, 0);
2238                         codegen_addreference(cd, iptr->dst.block);
2239                         M_NOP;
2240                         break;
2241
2242                 case ICMD_IF_ICMPNE:    /* ..., value, value ==> ...                  */
2243                 case ICMD_IF_LCMPNE:    /* op1 = target JavaVM pc                     */
2244                 case ICMD_IF_ACMPNE:
2245
2246                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2247                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2248                         M_BNE(s1, s2, 0);
2249                         codegen_addreference(cd, iptr->dst.block);
2250                         M_NOP;
2251                         break;
2252
2253                 case ICMD_IF_ICMPLT:    /* ..., value, value ==> ...                  */
2254                 case ICMD_IF_LCMPLT:    /* op1 = target JavaVM pc                     */
2255
2256                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2257                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2258                         M_CMPLT(s1, s2, REG_ITMP1);
2259                         M_BNEZ(REG_ITMP1, 0);
2260                         codegen_addreference(cd, iptr->dst.block);
2261                         M_NOP;
2262                         break;
2263
2264                 case ICMD_IF_ICMPGT:    /* ..., value, value ==> ...                  */
2265                 case ICMD_IF_LCMPGT:    /* op1 = target JavaVM pc                     */
2266
2267                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2268                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2269                         M_CMPGT(s1, s2, REG_ITMP1);
2270                         M_BNEZ(REG_ITMP1, 0);
2271                         codegen_addreference(cd, iptr->dst.block);
2272                         M_NOP;
2273                         break;
2274
2275                 case ICMD_IF_ICMPLE:    /* ..., value, value ==> ...                  */
2276                 case ICMD_IF_LCMPLE:    /* op1 = target JavaVM pc                     */
2277
2278                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2279                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2280                         M_CMPGT(s1, s2, REG_ITMP1);
2281                         M_BEQZ(REG_ITMP1, 0);
2282                         codegen_addreference(cd, iptr->dst.block);
2283                         M_NOP;
2284                         break;
2285
2286                 case ICMD_IF_ICMPGE:    /* ..., value, value ==> ...                  */
2287                 case ICMD_IF_LCMPGE:    /* op1 = target JavaVM pc                     */
2288
2289                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2290                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2291                         M_CMPLT(s1, s2, REG_ITMP1);
2292                         M_BEQZ(REG_ITMP1, 0);
2293                         codegen_addreference(cd, iptr->dst.block);
2294                         M_NOP;
2295                         break;
2296
2297
2298                 case ICMD_IRETURN:      /* ..., retvalue ==> ...                      */
2299                 case ICMD_LRETURN:
2300
2301                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
2302                         M_INTMOVE(s1, REG_RESULT);
2303                         goto nowperformreturn;
2304
2305                 case ICMD_ARETURN:      /* ..., retvalue ==> ...                      */
2306
2307                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
2308                         M_INTMOVE(s1, REG_RESULT);
2309
2310 #ifdef ENABLE_VERIFIER
2311                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2312                                 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2313                                                                         iptr->sx.s23.s2.uc, 0);
2314
2315                                 if (opt_showdisassemble) {
2316                                         M_NOP; M_NOP;
2317                                 }
2318                         }
2319 #endif /* ENABLE_VERIFIER */
2320                         goto nowperformreturn;
2321
2322             case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
2323
2324                         s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2325                         M_FLTMOVE(s1, REG_FRESULT);
2326                         goto nowperformreturn;
2327
2328             case ICMD_DRETURN:      /* ..., retvalue ==> ...                      */
2329
2330                         s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2331                         M_DBLMOVE(s1, REG_FRESULT);
2332                         goto nowperformreturn;
2333
2334                 case ICMD_RETURN:      /* ...  ==> ...                                */
2335
2336 nowperformreturn:
2337                         {
2338                         s4 i, p;
2339                         
2340                         p = cd->stackframesize;
2341
2342 #if !defined(NDEBUG)
2343                         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2344                                 emit_verbosecall_exit(jd);
2345 #endif
2346
2347 #if defined(ENABLE_THREADS)
2348                         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2349                                 disp = dseg_addaddress(cd, LOCK_monitor_exit);
2350                                 M_ALD(REG_ITMP3, REG_PV, disp);
2351
2352                                 /* we need to save the proper return value */
2353
2354                                 switch (iptr->opc) {
2355                                 case ICMD_IRETURN:
2356                                 case ICMD_ARETURN:
2357                                 case ICMD_LRETURN:
2358                                         M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2359                                         M_JSR(REG_RA, REG_ITMP3);
2360                                         M_LST(REG_RESULT, REG_SP, rd->memuse * 8);  /* delay slot */
2361                                         break;
2362                                 case ICMD_FRETURN:
2363                                 case ICMD_DRETURN:
2364                                         M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2365                                         M_JSR(REG_RA, REG_ITMP3);
2366                                         M_DST(REG_FRESULT, REG_SP, rd->memuse * 8); /* delay slot */
2367                                         break;
2368                                 case ICMD_RETURN:
2369                                         M_JSR(REG_RA, REG_ITMP3);
2370                                         M_ALD(REG_A0, REG_SP, rd->memuse * 8); /* delay*/
2371                                         break;
2372                                 }
2373
2374                                 /* and now restore the proper return value */
2375
2376                                 switch (iptr->opc) {
2377                                 case ICMD_IRETURN:
2378                                 case ICMD_ARETURN:
2379                                 case ICMD_LRETURN:
2380                                         M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2381                                         break;
2382                                 case ICMD_FRETURN:
2383                                 case ICMD_DRETURN:
2384                                         M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2385                                         break;
2386                                 }
2387                         }
2388 #endif
2389
2390                         /* restore return address                                         */
2391
2392                         if (!jd->isleafmethod) {
2393                                 p--; M_ALD(REG_RA, REG_SP, p * 8);
2394                         }
2395
2396                         /* restore saved registers                                        */
2397
2398                         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2399                                 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2400                         }
2401                         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2402                                 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2403                         }
2404
2405                         /* deallocate stack and return                                    */
2406
2407                         if (cd->stackframesize) {
2408                                 s4 lo, hi;
2409
2410                                 disp = cd->stackframesize * 8;
2411                                 lo = (short) (disp);
2412                                 hi = (short) (((disp) - lo) >> 16);
2413
2414                                 if (hi == 0) {
2415                                         M_RET(REG_RA);
2416                                         M_LADD_IMM(REG_SP, lo, REG_SP);             /* delay slot */
2417                                 } else {
2418                                         M_LUI(REG_ITMP3,hi);
2419                                         M_LADD_IMM(REG_ITMP3,lo,REG_ITMP3);
2420                                         M_RET(REG_RA);
2421                                         M_LADD(REG_ITMP3,REG_SP,REG_SP);            /* delay slot */
2422                                 }
2423
2424                         } else {
2425                                 M_RET(REG_RA);
2426                                 M_NOP;
2427                         }
2428
2429                         ALIGNCODENOP;
2430                         }
2431                         break;
2432
2433
2434                 case ICMD_TABLESWITCH:  /* ..., index ==> ...                         */
2435                         {
2436                         s4 i, l;
2437                         branch_target_t *table;
2438
2439                         table = iptr->dst.table;
2440
2441                         l = iptr->sx.s23.s2.tablelow;
2442                         i = iptr->sx.s23.s3.tablehigh;
2443
2444                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2445                         if (l == 0)
2446                                 {M_INTMOVE(s1, REG_ITMP1);}
2447                         else if (l <= 32768) {
2448                                 M_IADD_IMM(s1, -l, REG_ITMP1);
2449                                 }
2450                         else {
2451                                 ICONST(REG_ITMP2, l);
2452                                 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2453                                 }
2454
2455                         /* number of targets */
2456                         i = i - l + 1;
2457
2458                         /* range check */
2459
2460                         M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
2461                         M_BEQZ(REG_ITMP2, 0);
2462                         codegen_addreference(cd, table[0].block); /* default target */
2463                         M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);      /* delay slot*/
2464
2465                         /* build jump table top down and use address of lowest entry */
2466
2467                         table += i;
2468
2469                         while (--i >= 0) {
2470                                 dseg_addtarget(cd, table->block); 
2471                                 --table;
2472                                 }
2473                         }
2474
2475                         /* length of dataseg after last dseg_addtarget is used by load */
2476
2477                         M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2478                         M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2479                         M_JMP(REG_ITMP2);
2480                         M_NOP;
2481                         ALIGNCODENOP;
2482                         break;
2483
2484
2485                 case ICMD_LOOKUPSWITCH: /* ..., key ==> ...                           */
2486                         {
2487                         s4 i;
2488                         lookup_target_t *lookup;
2489
2490                         lookup = iptr->dst.lookup;
2491
2492                         i = iptr->sx.s23.s2.lookupcount;
2493                         
2494                         MCODECHECK((i<<2)+8);
2495                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2496
2497                         while (--i >= 0) {
2498                                 ICONST(REG_ITMP2, lookup->value);
2499                                 M_BEQ(s1, REG_ITMP2, 0);
2500                                 codegen_addreference(cd, lookup->target.block); 
2501                                 M_NOP;
2502                                 ++lookup;
2503                         }
2504
2505                         M_BR(0);
2506                         codegen_addreference(cd, iptr->sx.s23.s3.lookupdefault.block);
2507                         M_NOP;
2508                         ALIGNCODENOP;
2509                         break;
2510                         }
2511
2512
2513                 case ICMD_BUILTIN:      /* ..., arg1 ==> ...                          */
2514
2515                         bte = iptr->sx.s23.s3.bte;
2516                         md  = bte->md;
2517                         goto gen_method;
2518
2519                 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ...            */
2520
2521                 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2522                 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer    */
2523                 case ICMD_INVOKEINTERFACE:
2524
2525                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2526                                 lm = NULL;
2527                                 um = iptr->sx.s23.s3.um;
2528                                 md = um->methodref->parseddesc.md;
2529                         }
2530                         else {
2531                                 lm = iptr->sx.s23.s3.fmiref->p.method;
2532                                 um = NULL;
2533                                 md = lm->parseddesc;
2534                         }
2535
2536 gen_method:
2537                         s3 = md->paramcount;
2538
2539                         MCODECHECK((s3 << 1) + 64);
2540
2541                         /* copy arguments to registers or stack location                  */
2542
2543                         for (s3 = s3 - 1; s3 >= 0; s3--) {
2544                                 var = VAR(iptr->sx.s23.s2.args[s3]);
2545
2546                                 if (var->flags & PREALLOC)
2547                                         continue;
2548
2549                                 if (IS_INT_LNG_TYPE(var->type)) {
2550                                         if (!md->params[s3].inmemory) {
2551                                                 s1 = rd->argintregs[md->params[s3].regoff];
2552                                                 d = emit_load(jd, iptr, var, s1);
2553                                                 M_INTMOVE(d, s1);
2554                                         }
2555                                         else  {
2556                                                 d = emit_load(jd, iptr, var, REG_ITMP1);
2557                                                 M_LST(d, REG_SP, md->params[s3].regoff * 8);
2558                                         }
2559                                 }
2560                                 else {
2561                                         if (!md->params[s3].inmemory) {
2562                                                 s1 = rd->argfltregs[md->params[s3].regoff];
2563                                                 d = emit_load(jd, iptr, var, s1);
2564                                                 if (IS_2_WORD_TYPE(var->type))
2565                                                         M_DMOV(d, s1);
2566                                                 else
2567                                                         M_FMOV(d, s1);
2568                                         }
2569                                         else {
2570                                                 d = emit_load(jd, iptr, var, REG_FTMP1);
2571                                                 if (IS_2_WORD_TYPE(var->type))
2572                                                         M_DST(d, REG_SP, md->params[s3].regoff * 8);
2573                                                 else
2574                                                         M_FST(d, REG_SP, md->params[s3].regoff * 8);
2575                                         }
2576                                 }
2577                         }
2578
2579                         switch (iptr->opc) {
2580                         case ICMD_BUILTIN:
2581                                 disp = dseg_addaddress(cd, bte->fp);
2582
2583                                 M_ALD(REG_ITMP3, REG_PV, disp);  /* built-in-function pointer */
2584
2585                                 /* TWISTI: i actually don't know the reason for using
2586                                    REG_ITMP3 here instead of REG_PV. */
2587                                 s1 = REG_ITMP3;
2588                                 break;
2589
2590                         case ICMD_INVOKESPECIAL:
2591                                 M_BEQZ(REG_A0, 0);
2592                                 codegen_add_nullpointerexception_ref(cd);
2593                                 M_NOP;
2594                                 /* fall through */
2595
2596                         case ICMD_INVOKESTATIC:
2597                                 if (lm == NULL) {
2598                                         disp = dseg_addaddress(cd, NULL);
2599
2600                                         codegen_addpatchref(cd, PATCHER_invokestatic_special,
2601                                                                                 um, disp);
2602
2603                                         if (opt_showdisassemble) {
2604                                                 M_NOP; M_NOP;
2605                                         }
2606                                 }
2607                                 else
2608                                         disp = dseg_addaddress(cd, lm->stubroutine);
2609
2610                                 M_ALD(REG_PV, REG_PV, disp);          /* method pointer in pv */
2611                                 s1 = REG_PV;
2612                                 break;
2613
2614                         case ICMD_INVOKEVIRTUAL:
2615                                 gen_nullptr_check(REG_A0);
2616
2617                                 if (lm == NULL) {
2618                                         codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
2619
2620                                         if (opt_showdisassemble) {
2621                                                 M_NOP; M_NOP;
2622                                         }
2623
2624                                         s1 = 0;
2625                                 }
2626                                 else
2627                                         s1 = OFFSET(vftbl_t, table[0]) +
2628                                                 sizeof(methodptr) * lm->vftblindex;
2629
2630                                 M_ALD(REG_METHODPTR, REG_A0,
2631                                           OFFSET(java_objectheader, vftbl));
2632                                 M_ALD(REG_PV, REG_METHODPTR, s1);
2633                                 s1 = REG_PV;
2634                                 break;
2635
2636                         case ICMD_INVOKEINTERFACE:
2637                                 gen_nullptr_check(REG_A0);
2638
2639                                 if (lm == NULL) {
2640                                         codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
2641
2642                                         if (opt_showdisassemble) {
2643                                                 M_NOP; M_NOP;
2644                                         }
2645
2646                                         s1 = 0;
2647                                         s2 = 0;
2648                                 }
2649                                 else {
2650                                         s1 = OFFSET(vftbl_t, interfacetable[0]) -
2651                                                 sizeof(methodptr*) * lm->class->index;
2652
2653                                         s2 = sizeof(methodptr) * (lm - lm->class->methods);
2654                                 }
2655
2656                                 M_ALD(REG_METHODPTR, REG_A0,
2657                                           OFFSET(java_objectheader, vftbl));
2658                                 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2659                                 M_ALD(REG_PV, REG_METHODPTR, s2);
2660                                 s1 = REG_PV;
2661                                 break;
2662                         }
2663
2664                         /* generate the actual call */
2665
2666                         M_JSR(REG_RA, s1);
2667                         M_NOP;
2668                         disp = (s4) (cd->mcodeptr - cd->mcodebase);
2669                         M_LDA(REG_PV, REG_RA, -disp);
2670
2671                         /* actually only used for ICMD_BUILTIN */
2672
2673                         if (INSTRUCTION_MUST_CHECK(iptr)) {
2674                                 M_BEQZ(REG_RESULT, 0);
2675                                 codegen_add_fillinstacktrace_ref(cd);
2676                                 M_NOP;
2677                         }
2678
2679                         /* store return value */
2680
2681                         d = md->returntype.type;
2682
2683                         if (d != TYPE_VOID) {
2684                                 if (IS_INT_LNG_TYPE(d)) {
2685                                         s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2686                                         M_INTMOVE(REG_RESULT, s1);
2687                                 }
2688                                 else {
2689                                         s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2690                                         if (IS_2_WORD_TYPE(d))
2691                                                 M_DMOV(REG_FRESULT, s1);
2692                                         else
2693                                                 M_FMOV(REG_FRESULT, s1);
2694                                 }
2695                                 emit_store_dst(jd, iptr, s1);
2696                         }
2697                         break;
2698
2699
2700                 case ICMD_CHECKCAST:  /* ..., objectref ==> ..., objectref            */
2701                                       /* val.a: (classinfo*) superclass               */
2702
2703                         /*  superclass is an interface:
2704                          *
2705                          *  OK if ((sub == NULL) ||
2706                          *         (sub->vftbl->interfacetablelength > super->index) &&
2707                          *         (sub->vftbl->interfacetable[-super->index] != NULL));
2708                          *
2709                          *  superclass is a class:
2710                          *
2711                          *  OK if ((sub == NULL) || (0
2712                          *         <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2713                          *         super->vftbl->diffvall));
2714                          */
2715
2716                         if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2717                                 classinfo *super;
2718                                 vftbl_t   *supervftbl;
2719                                 s4         superindex;
2720
2721                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2722                                         super = NULL;
2723                                         superindex = 0;
2724                                         supervftbl = NULL;
2725                                 }
2726                                 else {
2727                                         super = iptr->sx.s23.s3.c.cls;
2728                                         superindex = super->index;
2729                                         supervftbl = super->vftbl;
2730                                 }
2731                         
2732 #if defined(ENABLE_THREADS)
2733                                 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2734 #endif
2735
2736                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2737
2738                                 /* calculate interface checkcast code size */
2739
2740                                 s2 = 8;
2741                                 if (super == NULL)
2742                                         s2 += (opt_showdisassemble ? 2 : 0);
2743
2744                                 /* calculate class checkcast code size */
2745
2746                                 s3 = 10 /* 10 + (s1 == REG_ITMP1) */;
2747                                 if (super == NULL)
2748                                         s3 += (opt_showdisassemble ? 2 : 0);
2749
2750                                 /* if class is not resolved, check which code to call */
2751
2752                                 if (super == NULL) {
2753                                         M_BEQZ(s1, 5 + (opt_showdisassemble ? 2 : 0) + s2 + 2 + s3);
2754                                         M_NOP;
2755
2756                                         disp = dseg_adds4(cd, 0);                 /* super->flags */
2757
2758                                         codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
2759                                                                                 iptr->sx.s23.s3.c.ref,
2760                                                                                 disp);
2761
2762                                         if (opt_showdisassemble) {
2763                                                 M_NOP; M_NOP;
2764                                         }
2765
2766                                         /* XXX TWISTI M_ILD can be 2 instructions long (jump offset) */
2767                                         M_ILD(REG_ITMP2, REG_PV, disp);
2768                                         M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
2769                                         M_BEQZ(REG_ITMP2, 1 + s2 + 2);
2770                                         M_NOP;
2771                                 }
2772
2773                                 /* interface checkcast code */
2774
2775                                 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2776                                         if (super != NULL) {
2777                                                 M_BEQZ(s1, 1 + s2);
2778                                                 M_NOP;
2779                                         }
2780                                         else {
2781                                                 codegen_addpatchref(cd,
2782                                                                                         PATCHER_checkcast_instanceof_interface,
2783                                                                                         iptr->sx.s23.s3.c.ref,
2784                                                                                         0);
2785
2786                                                 if (opt_showdisassemble) {
2787                                                         M_NOP; M_NOP;
2788                                                 }
2789                                         }
2790
2791                                         M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2792                                         M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
2793                                         M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
2794                                         M_BLEZ(REG_ITMP3, 0);
2795                                         codegen_add_classcastexception_ref(cd, s1);
2796                                         M_NOP;
2797                                         M_ALD(REG_ITMP3, REG_ITMP2,
2798                                                   OFFSET(vftbl_t, interfacetable[0]) -
2799                                                   superindex * sizeof(methodptr*));
2800                                         M_BEQZ(REG_ITMP3, 0);
2801                                         codegen_add_classcastexception_ref(cd, s1);
2802                                         M_NOP;
2803
2804                                         if (super == NULL) {
2805                                                 M_BR(1 + s3);
2806                                                 M_NOP;
2807                                         }
2808                                 }
2809
2810                                 /* class checkcast code */
2811
2812                                 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2813                                         disp = dseg_addaddress(cd, (void *) supervftbl);
2814
2815                                         if (super != NULL) {
2816                                                 M_BEQZ(s1, 1 + s3);
2817                                                 M_NOP;
2818                                         }
2819                                         else {
2820                                                 codegen_addpatchref(cd,
2821                                                                                         PATCHER_checkcast_instanceof_class,
2822                                                                                         iptr->sx.s23.s3.c.ref,
2823                                                                                         disp);
2824
2825                                                 if (opt_showdisassemble) {
2826                                                         M_NOP; M_NOP;
2827                                                 }
2828                                         }
2829
2830                                         M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2831                                         M_ALD(REG_ITMP3, REG_PV, disp);
2832 #if defined(ENABLE_THREADS)
2833                                         codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
2834 #endif
2835                                         M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2836                                         /*                              if (s1 != REG_ITMP1) { */
2837                                         /*                                      M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
2838                                         /*                                      M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
2839                                         /* #if defined(ENABLE_THREADS) */
2840                                         /*                                      codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
2841                                         /* #endif */
2842                                         /*                                      M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
2843                                         /*                              } else { */
2844                                         M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2845                                         M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2); 
2846                                         M_ALD(REG_ITMP3, REG_PV, disp);
2847                                         M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2848 #if defined(ENABLE_THREADS)
2849                                         codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
2850 #endif
2851                                         /*                              } */
2852                                         M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3);
2853                                         M_BNEZ(REG_ITMP3, 0);
2854                                         codegen_add_classcastexception_ref(cd, s1);
2855                                         M_NOP;
2856                                 }
2857
2858                                 d = codegen_reg_of_dst(jd, iptr, s1);
2859                         }
2860                         else {
2861                                 s1 = emit_load_s1(jd, iptr, REG_A0);
2862                                 M_INTMOVE(s1, REG_A0);
2863
2864                                 disp = dseg_addaddress(cd, iptr->sx.s23.s3.c.cls);
2865
2866                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2867                                         codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast,
2868                                                                                 iptr->sx.s23.s3.c.ref,
2869                                                                                 disp);
2870
2871                                         if (opt_showdisassemble) {
2872                                                 M_NOP; M_NOP;
2873                                         }
2874                                 }
2875
2876                                 M_ALD(REG_A1, REG_PV, disp);
2877                                 disp = dseg_addaddress(cd, BUILTIN_arraycheckcast);
2878                                 M_ALD(REG_ITMP3, REG_PV, disp);
2879                                 M_JSR(REG_RA, REG_ITMP3);
2880                                 M_NOP;
2881
2882                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2883                                 M_BEQZ(REG_RESULT, 0);
2884                                 codegen_add_classcastexception_ref(cd, s1);
2885                                 M_NOP;
2886
2887                                 d = codegen_reg_of_dst(jd, iptr, s1);
2888                         }
2889
2890                         M_INTMOVE(s1, d);
2891                         emit_store_dst(jd, iptr, d);
2892                         break;
2893
2894                 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
2895                                       /* val.a: (classinfo*) superclass               */
2896
2897                         /*  superclass is an interface:
2898                          *
2899                          *  return (sub != NULL) &&
2900                          *         (sub->vftbl->interfacetablelength > super->index) &&
2901                          *         (sub->vftbl->interfacetable[-super->index] != NULL);
2902                          *
2903                          *  superclass is a class:
2904                          *
2905                          *  return ((sub != NULL) && (0
2906                          *          <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2907                          *          super->vftbl->diffvall));
2908                          */
2909
2910                         {
2911                         classinfo *super;
2912                         vftbl_t   *supervftbl;
2913                         s4         superindex;
2914
2915                         super = iptr->sx.s23.s3.c.cls;
2916
2917                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2918                                 super = NULL;
2919                                 superindex = 0;
2920                                 supervftbl = NULL;
2921                         }
2922                         else {
2923                                 super = iptr->sx.s23.s3.c.cls;
2924                                 superindex = super->index;
2925                                 supervftbl = super->vftbl;
2926                         }
2927                         
2928 #if defined(ENABLE_THREADS)
2929                         codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2930 #endif
2931
2932                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2933                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2934                         if (s1 == d) {
2935                                 M_MOV(s1, REG_ITMP1);
2936                                 s1 = REG_ITMP1;
2937                         }
2938
2939                         /* calculate interface instanceof code size */
2940
2941                         s2 = 7;
2942                         if (super == NULL)
2943                                 s2 += (opt_showdisassemble ? 2 : 0);
2944
2945                         /* calculate class instanceof code size */
2946
2947                         s3 = 8;
2948                         if (super == NULL)
2949                                 s3 += (opt_showdisassemble ? 2 : 0);
2950
2951                         M_CLR(d);
2952
2953                         /* if class is not resolved, check which code to call */
2954
2955                         if (super == NULL) {
2956                                 M_BEQZ(s1, 5 + (opt_showdisassemble ? 2 : 0) + s2 + 2 + s3);
2957                                 M_NOP;
2958
2959                                 disp = dseg_adds4(cd, 0);                     /* super->flags */
2960
2961                                 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
2962                                                                         iptr->sx.s23.s3.c.ref, disp);
2963
2964                                 if (opt_showdisassemble) {
2965                                         M_NOP; M_NOP;
2966                                 }
2967
2968                                 /* XXX TWISTI M_ILD can be 2 instructions long (jump offset) */
2969                                 M_ILD(REG_ITMP3, REG_PV, disp);
2970                                 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
2971                                 M_BEQZ(REG_ITMP3, 1 + s2 + 2);
2972                                 M_NOP;
2973                         }
2974
2975                         /* interface instanceof code */
2976
2977                         if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2978                                 if (super != NULL) {
2979                                         M_BEQZ(s1, 1 + s2);
2980                                         M_NOP;
2981                                 }
2982                                 else {
2983                                         codegen_addpatchref(cd,
2984                                                                                 PATCHER_checkcast_instanceof_interface,
2985                                                                                 iptr->sx.s23.s3.c.ref, 0);
2986
2987                                         if (opt_showdisassemble) {
2988                                                 M_NOP; M_NOP;
2989                                         }
2990                                 }
2991
2992                                 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2993                                 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2994                                 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
2995                                 M_BLEZ(REG_ITMP3, 3);
2996                                 M_NOP;
2997                                 M_ALD(REG_ITMP1, REG_ITMP1,
2998                                           OFFSET(vftbl_t, interfacetable[0]) -
2999                                           superindex * sizeof(methodptr*));
3000                                 M_CMPULT(REG_ZERO, REG_ITMP1, d);      /* REG_ITMP1 != 0  */
3001
3002                                 if (super == NULL) {
3003                                         M_BR(1 + s3);
3004                                         M_NOP;
3005                                 }
3006                         }
3007
3008                         /* class instanceof code */
3009
3010                         if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3011                                 disp = dseg_addaddress(cd, supervftbl);
3012
3013                                 if (super != NULL) {
3014                                         M_BEQZ(s1, 1 + s3);
3015                                         M_NOP;
3016                                 }
3017                                 else {
3018                                         codegen_addpatchref(cd, PATCHER_checkcast_instanceof_class,
3019                                                                                 iptr->sx.s23.s3.c.ref,
3020                                                                                 disp);
3021
3022                                         if (opt_showdisassemble) {
3023                                                 M_NOP; M_NOP;
3024                                         }
3025                                 }
3026
3027                                 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3028                                 M_ALD(REG_ITMP2, REG_PV, disp);
3029 #if defined(ENABLE_THREADS)
3030                                 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3031 #endif
3032                                 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3033                                 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3034                                 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3035 #if defined(ENABLE_THREADS)
3036                                 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3037 #endif
3038                                 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1); 
3039                                 M_CMPULT(REG_ITMP2, REG_ITMP1, d);
3040                                 M_XOR_IMM(d, 1, d);
3041                         }
3042                         emit_store_dst(jd, iptr, d);
3043                         }
3044                         break;
3045
3046                 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref  */
3047
3048                         /* check for negative sizes and copy sizes to stack if necessary  */
3049
3050                         MCODECHECK((iptr->s1.argcount << 1) + 64);
3051
3052                         for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3053
3054                                 var = VAR(iptr->sx.s23.s2.args[s1]);
3055
3056                                 /* copy SAVEDVAR sizes to stack */
3057
3058                                 if (!(var->flags & PREALLOC)) {
3059                                         s2 = emit_load(jd, iptr, var, REG_ITMP1);
3060                                         M_LST(s2, REG_SP, s1 * 8);
3061                                 }
3062                         }
3063
3064                         /* a0 = dimension count */
3065
3066                         ICONST(REG_A0, iptr->s1.argcount);
3067
3068                         /* is patcher function set? */
3069
3070                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3071                                 disp = dseg_addaddress(cd, NULL);
3072
3073                                 codegen_addpatchref(cd, PATCHER_builtin_multianewarray,
3074                                                                         iptr->sx.s23.s3.c.ref, disp);
3075
3076                                 if (opt_showdisassemble) {
3077                                         M_NOP; M_NOP;
3078                                 }
3079
3080                         } else {
3081                                 disp = dseg_addaddress(cd, iptr->sx.s23.s3.c.cls);
3082                         }
3083
3084                         /* a1 = arraydescriptor */
3085
3086                         M_ALD(REG_A1, REG_PV, disp);
3087
3088                         /* a2 = pointer to dimensions = stack pointer */
3089
3090                         M_INTMOVE(REG_SP, REG_A2);
3091
3092                         disp = dseg_addaddress(cd, BUILTIN_multianewarray);
3093                         M_ALD(REG_ITMP3, REG_PV, disp);
3094                         M_JSR(REG_RA, REG_ITMP3);
3095                         M_NOP;
3096
3097                         /* check for exception before result assignment */
3098
3099                         M_BEQZ(REG_RESULT, 0);
3100                         codegen_add_fillinstacktrace_ref(cd);
3101                         M_NOP;
3102
3103                         d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3104                         M_INTMOVE(REG_RESULT, d);
3105                         emit_store_dst(jd, iptr, d);
3106                         break;
3107
3108                 default:
3109                         *exceptionptr = new_internalerror("Unknown ICMD %d", iptr->opc);
3110                         return false;
3111         } /* switch */
3112                 
3113         } /* for instruction */
3114                 
3115         MCODECHECK(64); /* XXX require smaller number? */
3116
3117         /* At the end of a basic block we may have to append some nops,
3118            because the patcher stub calling code might be longer than the
3119            actual instruction. So codepatching does not change the
3120            following block unintentionally. */
3121
3122         if (cd->mcodeptr < cd->lastmcodeptr) {
3123                 while (cd->mcodeptr < cd->lastmcodeptr)
3124                         M_NOP;
3125         }
3126
3127         } /* if (bptr -> flags >= BBREACHED) */
3128         } /* for basic block */
3129
3130         dseg_createlinenumbertable(cd);
3131
3132         /* generate exception and patcher stubs */
3133
3134         emit_exception_stubs(jd);
3135         emit_patcher_stubs(jd);
3136
3137 #if 0
3138         emit_replacement_stubs(jd);
3139 #endif
3140
3141         codegen_finish(jd);
3142
3143         /* everything's ok */
3144
3145         return true;
3146 }
3147
3148
3149 /* createcompilerstub **********************************************************
3150
3151    Creates a stub routine which calls the compiler.
3152         
3153 *******************************************************************************/
3154
3155 #define COMPILERSTUB_DATASIZE    3 * SIZEOF_VOID_P
3156 #define COMPILERSTUB_CODESIZE    4 * 4
3157
3158 #define COMPILERSTUB_SIZE        COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
3159
3160
3161 u1 *createcompilerstub(methodinfo *m)
3162 {
3163         u1          *s;                     /* memory to hold the stub            */
3164         ptrint      *d;
3165         codeinfo    *code;
3166         codegendata *cd;
3167         s4           dumpsize;
3168
3169         s = CNEW(u1, COMPILERSTUB_SIZE);
3170
3171         /* set data pointer and code pointer */
3172
3173         d = (ptrint *) s;
3174         s = s + COMPILERSTUB_DATASIZE;
3175
3176         /* mark start of dump memory area */
3177
3178         dumpsize = dump_size();
3179
3180         cd = DNEW(codegendata);
3181         cd->mcodeptr = s;
3182
3183         /* Store the codeinfo pointer in the same place as in the
3184            methodheader for compiled methods. */
3185
3186         code = code_codeinfo_new(m);
3187
3188         d[0] = (ptrint) asm_call_jit_compiler;
3189         d[1] = (ptrint) m;
3190         d[2] = (ptrint) code;
3191
3192         M_ALD_INTERN(REG_ITMP1, REG_PV, -2 * SIZEOF_VOID_P);  /* codeinfo pointer */
3193         M_ALD_INTERN(REG_PV, REG_PV, -3 * SIZEOF_VOID_P);  /* pointer to compiler */
3194         M_JMP(REG_PV);
3195         M_NOP;
3196
3197         md_cacheflush(s, (s4) (cd->mcodeptr - (u1 *) d));
3198
3199 #if defined(ENABLE_STATISTICS)
3200         if (opt_stat)
3201                 count_cstub_len += COMPILERSTUB_SIZE;
3202 #endif
3203
3204         /* release dump area */
3205
3206         dump_release(dumpsize);
3207
3208         return s;
3209 }
3210
3211
3212 /* createnativestub ************************************************************
3213
3214    Creates a stub routine which calls a native method.
3215
3216 *******************************************************************************/
3217
3218 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
3219 {
3220         methodinfo   *m;
3221         codeinfo     *code;
3222         codegendata  *cd;
3223         registerdata *rd;
3224         methoddesc   *md;
3225         s4            nativeparams;
3226         s4            i, j;                 /* count variables                    */
3227         s4            t;
3228         s4            s1, s2, disp;
3229         s4            funcdisp;             /* displacement of the function       */
3230
3231         /* get required compiler data */
3232
3233         m    = jd->m;
3234         code = jd->code;
3235         cd   = jd->cd;
3236         rd   = jd->rd;
3237
3238         /* initialize variables */
3239
3240         md = m->parseddesc;
3241         nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3242
3243         /* calculate stack frame size */
3244
3245         cd->stackframesize =
3246                 1 +                             /* return address                     */
3247                 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3248                 sizeof(localref_table) / SIZEOF_VOID_P +
3249                 md->paramcount +                /* for saving arguments over calls    */
3250                 1 +                             /* for saving return address          */
3251                 nmd->memuse;
3252
3253         /* create method header */
3254
3255 #if SIZEOF_VOID_P == 4
3256         (void) dseg_addaddress(cd, code);                      /* CodeinfoPointer */
3257 #endif
3258         (void) dseg_addaddress(cd, code);                      /* MethodPointer   */
3259         (void) dseg_adds4(cd, cd->stackframesize * 8);         /* FrameSize       */
3260         (void) dseg_adds4(cd, 0);                              /* IsSync          */
3261         (void) dseg_adds4(cd, 0);                              /* IsLeaf          */
3262         (void) dseg_adds4(cd, 0);                              /* IntSave         */
3263         (void) dseg_adds4(cd, 0);                              /* FltSave         */
3264         (void) dseg_addlinenumbertablesize(cd);
3265         (void) dseg_adds4(cd, 0);                              /* ExTableSize     */
3266
3267         /* generate stub code */
3268
3269         M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8); /* build up stackframe    */
3270         M_AST(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* store RA          */
3271
3272 #if !defined(NDEBUG)
3273         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3274                 emit_verbosecall_enter(jd);
3275 #endif
3276
3277         /* get function address (this must happen before the stackframeinfo) */
3278
3279         funcdisp = dseg_addaddress(cd, f);
3280
3281 #if !defined(WITH_STATIC_CLASSPATH)
3282         if (f == NULL) {
3283                 codegen_addpatchref(cd, PATCHER_resolve_native, m, funcdisp);
3284
3285                 if (opt_showdisassemble) {
3286                         M_NOP; M_NOP;
3287                 }
3288         }
3289 #endif
3290
3291         /* save integer and float argument registers */
3292
3293         for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3294                 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
3295                         M_LST(rd->argintregs[i], REG_SP, j * 8);
3296                         j++;
3297                 }
3298         }
3299
3300         for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3301                 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3302                         M_DST(rd->argfltregs[i], REG_SP, j * 8);
3303                         j++;
3304                 }
3305         }
3306
3307         /* prepare data structures for native function call */
3308
3309         M_AADD_IMM(REG_SP, (cd->stackframesize - 1) * 8, REG_A0);
3310         M_MOV(REG_PV, REG_A1);
3311         M_AADD_IMM(REG_SP, cd->stackframesize * 8, REG_A2);
3312         M_ALD(REG_A3, REG_SP, (cd->stackframesize - 1) * 8);
3313         disp = dseg_addaddress(cd, codegen_start_native_call);
3314         M_ALD(REG_ITMP3, REG_PV, disp);
3315         M_JSR(REG_RA, REG_ITMP3);
3316         M_NOP; /* XXX fill me! */
3317
3318         /* restore integer and float argument registers */
3319
3320         for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3321                 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
3322                         M_LLD(rd->argintregs[i], REG_SP, j * 8);
3323                         j++;
3324                 }
3325         }
3326
3327         for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3328                 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3329                         M_DLD(rd->argfltregs[i], REG_SP, j * 8);
3330                         j++;
3331                 }
3332         }
3333
3334         /* copy or spill arguments to new locations */
3335
3336         for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3337                 t = md->paramtypes[i].type;
3338
3339                 if (IS_INT_LNG_TYPE(t)) {
3340                         if (!md->params[i].inmemory) {
3341                                 s1 = rd->argintregs[md->params[i].regoff];
3342
3343                                 if (!nmd->params[j].inmemory) {
3344                                         s2 = rd->argintregs[nmd->params[j].regoff];
3345                                         M_INTMOVE(s1, s2);
3346                                 } else {
3347                                         s2 = nmd->params[j].regoff;
3348                                         M_AST(s1, REG_SP, s2 * 8);
3349                                 }
3350
3351                         } else {
3352                                 s1 = md->params[i].regoff + cd->stackframesize;
3353                                 s2 = nmd->params[j].regoff;
3354                                 M_ALD(REG_ITMP1, REG_SP, s1 * 8);
3355                                 M_AST(REG_ITMP1, REG_SP, s2 * 8);
3356                         }
3357
3358                 } else {
3359                         if (!md->params[i].inmemory) {
3360                                 s1 = rd->argfltregs[md->params[i].regoff];
3361
3362                                 if (!nmd->params[j].inmemory) {
3363                                         s2 = rd->argfltregs[nmd->params[j].regoff];
3364                                         if (IS_2_WORD_TYPE(t))
3365                                                 M_DMOV(s1, s2);
3366                                         else
3367                                                 M_FMOV(s1, s2);
3368
3369                                 } else {
3370                                         s2 = nmd->params[j].regoff;
3371                                         if (IS_2_WORD_TYPE(t))
3372                                                 M_DST(s1, REG_SP, s2 * 8);
3373                                         else
3374                                                 M_FST(s1, REG_SP, s2 * 8);
3375                                 }
3376
3377                         } else {
3378                                 s1 = md->params[i].regoff + cd->stackframesize;
3379                                 s2 = nmd->params[j].regoff;
3380                                 if (IS_2_WORD_TYPE(t)) {
3381                                         M_DLD(REG_FTMP1, REG_SP, s1 * 8);
3382                                         M_DST(REG_FTMP1, REG_SP, s2 * 8);
3383                                 } else {
3384                                         M_FLD(REG_FTMP1, REG_SP, s1 * 8);
3385                                         M_FST(REG_FTMP1, REG_SP, s2 * 8);
3386                                 }
3387                         }
3388                 }
3389         }
3390
3391         /* put class into second argument register */
3392
3393         if (m->flags & ACC_STATIC) {
3394                 disp = dseg_addaddress(cd, m->class);
3395                 M_ALD(REG_A1, REG_PV, disp);
3396         }
3397
3398         /* put env into first argument register */
3399
3400         disp = dseg_addaddress(cd, _Jv_env);
3401         M_ALD(REG_A0, REG_PV, disp);
3402
3403         /* do the native function call */
3404
3405         M_ALD(REG_ITMP3, REG_PV, funcdisp); /* load adress of native method       */
3406         M_JSR(REG_RA, REG_ITMP3);           /* call native method                 */
3407         M_NOP;                              /* delay slot                         */
3408
3409         /* save return value */
3410
3411         if (md->returntype.type != TYPE_VOID) {
3412                 if (IS_INT_LNG_TYPE(md->returntype.type))
3413                         M_LST(REG_RESULT, REG_SP, 0 * 8);
3414                 else
3415                         M_DST(REG_FRESULT, REG_SP, 0 * 8);
3416         }
3417
3418 #if !defined(NDEBUG)
3419         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3420                 emit_verbosecall_exit(jd);
3421 #endif
3422
3423         /* remove native stackframe info */
3424
3425         M_AADD_IMM(REG_SP, (cd->stackframesize - 1) * 8, REG_A0);
3426         disp = dseg_addaddress(cd, codegen_finish_native_call);
3427         M_ALD(REG_ITMP3, REG_PV, disp);
3428         M_JSR(REG_RA, REG_ITMP3);
3429         M_NOP; /* XXX fill me! */
3430         M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3431
3432         /* restore return value */
3433
3434         if (md->returntype.type != TYPE_VOID) {
3435                 if (IS_INT_LNG_TYPE(md->returntype.type))
3436                         M_LLD(REG_RESULT, REG_SP, 0 * 8);
3437                 else
3438                         M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3439         }
3440
3441         M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* load RA           */
3442
3443         /* check for exception */
3444
3445         M_BNEZ(REG_ITMP1_XPTR, 2);          /* if no exception then return        */
3446         M_LDA(REG_SP, REG_SP, cd->stackframesize * 8); /* DELAY SLOT              */
3447
3448         M_RET(REG_RA);                      /* return to caller                   */
3449         M_NOP;                              /* DELAY SLOT                         */
3450
3451         /* handle exception */
3452         
3453         disp = dseg_addaddress(cd, asm_handle_nat_exception);
3454         M_ALD(REG_ITMP3, REG_PV, disp);     /* load asm exception handler address */
3455         M_JMP(REG_ITMP3);                   /* jump to asm exception handler      */
3456         M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address (DELAY)    */
3457
3458         /* generate patcher stubs */
3459
3460         emit_patcher_stubs(jd);
3461
3462         codegen_finish(jd);
3463
3464         return code->entrypoint;
3465 }
3466
3467
3468 /*
3469  * These are local overrides for various environment variables in Emacs.
3470  * Please do not remove this and leave it at the end of the file, where
3471  * Emacs will automagically detect them.
3472  * ---------------------------------------------------------------------
3473  * Local variables:
3474  * mode: c
3475  * indent-tabs-mode: t
3476  * c-basic-offset: 4
3477  * tab-width: 4
3478  * End:
3479  * vim:noexpandtab:sw=4:ts=4:
3480  */