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