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