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