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