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