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