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