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