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