* src/vm/jit/s390/codegen.c (codegen): Fixed ICMD_IF_ACMPNE
[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 7405 2007-02-25 22:34:27Z pm $
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                         OOPS();
2010 #if 0
2011                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2012                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2013                         if (INSTRUCTION_MUST_CHECK(iptr)) {
2014                                 gen_nullptr_check(s1);
2015                                 gen_bound_check;
2016                         }
2017                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2018
2019                         M_MOV(s1, REG_A0);
2020                         M_MOV(s3, REG_A1);
2021                         M_MOV_IMM(BUILTIN_canstore, REG_ITMP1);
2022                         M_CALL(REG_ITMP1);
2023                         M_TEST(REG_RESULT);
2024                         M_BEQ(0);
2025                         codegen_add_arraystoreexception_ref(cd);
2026
2027                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2028                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2029                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2030                         emit_mov_reg_memindex(cd, s3, OFFSET(java_objectarray, data[0]), s1, s2, 3);
2031 #endif
2032                         break;
2033
2034
2035                 case ICMD_BASTORECONST: /* ..., arrayref, index  ==> ...              */
2036                         OOPS();
2037 #if 0
2038                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2039                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2040                         if (INSTRUCTION_MUST_CHECK(iptr)) {
2041                                 gen_nullptr_check(s1);
2042                                 gen_bound_check;
2043                         }
2044                         emit_movb_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_bytearray, data[0]), s1, s2, 0);
2045 #endif
2046                         break;
2047
2048                 case ICMD_CASTORECONST:   /* ..., arrayref, index  ==> ...            */
2049                         OOPS();
2050 #if 0
2051                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2052                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2053                         if (INSTRUCTION_MUST_CHECK(iptr)) {
2054                                 gen_nullptr_check(s1);
2055                                 gen_bound_check;
2056                         }
2057                         emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_chararray, data[0]), s1, s2, 1);
2058 #endif
2059                         break;
2060
2061                 case ICMD_SASTORECONST:   /* ..., arrayref, index  ==> ...            */
2062                         OOPS();
2063 #if 0
2064                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2065                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2066                         if (INSTRUCTION_MUST_CHECK(iptr)) {
2067                                 gen_nullptr_check(s1);
2068                                 gen_bound_check;
2069                         }
2070                         emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_shortarray, data[0]), s1, s2, 1);
2071 #endif
2072                         break;
2073
2074                 case ICMD_IASTORECONST: /* ..., arrayref, index  ==> ...              */
2075                         OOPS();
2076 #if 0
2077                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2078                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2079                         if (INSTRUCTION_MUST_CHECK(iptr)) {
2080                                 gen_nullptr_check(s1);
2081                                 gen_bound_check;
2082                         }
2083                         emit_movl_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_intarray, data[0]), s1, s2, 2);
2084 #endif
2085                         break;
2086
2087                 case ICMD_LASTORECONST: /* ..., arrayref, index  ==> ...              */
2088                         OOPS();
2089 #if 0
2090                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2091                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2092                         if (INSTRUCTION_MUST_CHECK(iptr)) {
2093                                 gen_nullptr_check(s1);
2094                                 gen_bound_check;
2095                         }
2096
2097                         if (IS_IMM32(iptr->sx.s23.s3.constval)) {
2098                                 emit_mov_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray, data[0]), s1, s2, 3);
2099                         } else {
2100                                 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray, data[0]), s1, s2, 3);
2101                                 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval >> 32), OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
2102                         }
2103 #endif
2104                         break;
2105
2106                 case ICMD_AASTORECONST: /* ..., arrayref, index  ==> ...              */
2107                         OOPS();
2108 #if 0
2109                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2110                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2111                         if (INSTRUCTION_MUST_CHECK(iptr)) {
2112                                 gen_nullptr_check(s1);
2113                                 gen_bound_check;
2114                         }
2115                         emit_mov_imm_memindex(cd, 0, OFFSET(java_objectarray, data[0]), s1, s2, 3);
2116 #endif
2117                         break;
2118
2119
2120                 case ICMD_GETSTATIC:  /* ...  ==> ..., value                          */
2121
2122                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2123                                 uf        = iptr->sx.s23.s3.uf;
2124                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2125                                 disp      = dseg_add_unique_address(cd, NULL);
2126
2127 /*                              PROFILE_CYCLE_STOP; */
2128
2129                                 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
2130
2131 /*                              PROFILE_CYCLE_START; */
2132                         }
2133                         else {
2134                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
2135                                 fieldtype = fi->type;
2136                                 disp      = dseg_add_address(cd, &(fi->value));
2137
2138                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2139                                         PROFILE_CYCLE_STOP;
2140
2141                                         codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, 0);
2142
2143                                         PROFILE_CYCLE_START;
2144                                 }
2145                         }
2146
2147                         M_ALD(REG_ITMP1, REG_PV, disp);
2148
2149                         switch (fieldtype) {
2150                         case TYPE_INT:
2151                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2152                                 M_ILD(d, REG_ITMP1, 0);
2153                                 break;
2154                         case TYPE_LNG:
2155                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
2156                                 M_LLD(d, REG_ITMP1, 0);
2157                                 break;
2158                         case TYPE_ADR:
2159                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2160                                 M_ALD(d, REG_ITMP1, 0);
2161                                 break;
2162                         case TYPE_FLT:
2163                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2164                                 M_FLD(d, REG_ITMP1, 0);
2165                                 break;
2166                         case TYPE_DBL:                          
2167                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2168                                 M_DLD(d, REG_ITMP1, 0);
2169                                 break;
2170                         }
2171
2172                         emit_store_dst(jd, iptr, d);
2173
2174                         break;
2175
2176                 case ICMD_PUTSTATIC:  /* ..., value  ==> ...                          */
2177
2178                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2179                                 uf        = iptr->sx.s23.s3.uf;
2180                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2181                                 disp      = dseg_add_unique_address(cd, uf);
2182
2183                                 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
2184                         }
2185                         else {
2186                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
2187                                 fieldtype = fi->type;
2188                                 disp      = dseg_add_address(cd, &(fi->value));
2189
2190                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2191                                         codegen_addpatchref(cd, PATCHER_clinit,
2192                                                                                 fi->class, disp);
2193                         }
2194
2195                         M_ALD(REG_ITMP1, REG_PV, disp);
2196                         switch (fieldtype) {
2197                         case TYPE_INT:
2198                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2199                                 M_IST(s1, REG_ITMP1, 0);
2200                                 break;
2201                         case TYPE_LNG:
2202                                 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
2203                                 M_LST(s1, REG_ITMP1, 0);
2204                                 break;
2205                         case TYPE_ADR:
2206                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2207                                 M_AST(s1, REG_ITMP1, 0);
2208                                 break;
2209                         case TYPE_FLT:
2210                                 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2211                                 M_FST(s1, REG_ITMP1, 0);
2212                                 break;
2213                         case TYPE_DBL:
2214                                 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2215                                 M_DST(s1, REG_ITMP1, 0);
2216                                 break;
2217                         }
2218                         break;
2219
2220                 case ICMD_PUTSTATICCONST: /* ...  ==> ...                             */
2221                                           /* val = value (in current instruction)     */
2222                                           /* following NOP)                           */
2223                         OOPS();
2224 #if 0
2225                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2226                                 uf        = iptr->sx.s23.s3.uf;
2227                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2228                                 disp      = dseg_add_unique_address(cd, uf);
2229
2230                                 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
2231                         }
2232                         else {
2233                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
2234                                 fieldtype = fi->type;
2235                                 disp      = dseg_add_address(cd, &(fi->value));
2236
2237                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2238                                         codegen_add_patch_ref(cd, PATCHER_initialize_class, fi->class,
2239                                                                                   0);
2240                         }
2241                         
2242                         M_ALD(REG_ITMP1, REG_PV, disp);
2243
2244                         switch (fieldtype) {
2245                         case TYPE_INT:
2246                                 M_IST(REG_ZERO, REG_ITMP1, 0);
2247                                 break;
2248                         case TYPE_LNG:
2249                                 M_LST(REG_ZERO, REG_ITMP1, 0);
2250                                 break;
2251                         case TYPE_ADR:
2252                                 M_AST(REG_ZERO, REG_ITMP1, 0);
2253                                 break;
2254                         case TYPE_FLT:
2255                                 M_FST(REG_ZERO, REG_ITMP1, 0);
2256                                 break;
2257                         case TYPE_DBL:
2258                                 M_DST(REG_ZERO, REG_ITMP1, 0);
2259                                 break;
2260                         }
2261 #endif
2262                         break;
2263
2264                 case ICMD_GETFIELD:   /* ...  ==> ..., value                          */
2265
2266                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2267                         emit_nullpointer_check(cd, iptr, s1);
2268
2269                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2270                                 uf        = iptr->sx.s23.s3.uf;
2271                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2272                                 disp      = 0;
2273
2274                                 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
2275                         }
2276                         else {
2277                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
2278                                 fieldtype = fi->type;
2279                                 disp      = fi->offset;
2280                         }
2281
2282                         switch (fieldtype) {
2283                         case TYPE_INT:
2284                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2285                                 M_ILD(d, s1, disp);
2286                                 break;
2287                         case TYPE_LNG:
2288                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
2289                                 if (GET_HIGH_REG(d) == s1) {
2290                                         M_ILD(GET_LOW_REG(d), s1, disp + 4);
2291                                         M_ILD(GET_HIGH_REG(d), s1, disp);
2292                                 }
2293                                 else {
2294                                         M_ILD(GET_HIGH_REG(d), s1, disp);
2295                                         M_ILD(GET_LOW_REG(d), s1, disp + 4);
2296                                 }
2297                                 break;
2298                         case TYPE_ADR:
2299                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2300                                 M_ALD(d, s1, disp);
2301                                 break;
2302                         case TYPE_FLT:
2303                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2304                                 M_FLD(d, s1, disp);
2305                                 break;
2306                         case TYPE_DBL:                          
2307                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2308                                 M_DLD(d, s1, disp);
2309                                 break;
2310                         }
2311                         emit_store_dst(jd, iptr, d);
2312                         break;
2313
2314                 case ICMD_PUTFIELD:   /* ..., objectref, value  ==> ...               */
2315
2316                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2317                         gen_nullptr_check(s1);
2318
2319                         s2 = emit_load_s2(jd, iptr, REG_IFTMP);
2320
2321                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2322                                 uf        = iptr->sx.s23.s3.uf;
2323                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2324                                 disp      = 0;
2325                         } 
2326                         else {
2327                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
2328                                 fieldtype = fi->type;
2329                                 disp      = fi->offset;
2330                         }
2331
2332                         if (IS_INT_LNG_TYPE(fieldtype)) {
2333                                 if (IS_2_WORD_TYPE(fieldtype))
2334                                         s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
2335                                 else
2336                                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2337                         }
2338                         else
2339                                 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
2340
2341                         if (INSTRUCTION_IS_UNRESOLVED(iptr))
2342                                 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
2343
2344                         switch (fieldtype) {
2345                         case TYPE_INT:
2346                                 M_IST(s2, s1, disp);
2347                                 break;
2348                         case TYPE_LNG:
2349                                 /* TODO really order */
2350                                 M_IST(GET_LOW_REG(s2), s1, disp + 4);      /* keep this order */
2351                                 M_IST(GET_HIGH_REG(s2), s1, disp);         /* keep this order */
2352                                 break;
2353                         case TYPE_ADR:
2354                                 M_AST(s2, s1, disp);
2355                                 break;
2356                         case TYPE_FLT:
2357                                 M_FST(s2, s1, disp);
2358                                 break;
2359                         case TYPE_DBL:
2360                                 M_DST(s2, s1, disp);
2361                                 break;
2362                         }
2363                         break;
2364
2365                 case ICMD_PUTFIELDCONST:  /* ..., objectref, value  ==> ...           */
2366                                           /* val = value (in current instruction)     */
2367                                           /* following NOP)                           */
2368                         OOPS();
2369 #if 0
2370                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2371                         gen_nullptr_check(s1);
2372
2373                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2374                                 uf        = iptr->sx.s23.s3.uf;
2375                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2376                                 disp      = 0;
2377
2378 /*                              PROFILE_CYCLE_STOP; */
2379
2380                                 codegen_add_patch_ref(cd, PATCHER_putfieldconst, uf, 0);
2381
2382 /*                              PROFILE_CYCLE_START; */
2383                         } 
2384                         else {
2385                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
2386                                 fieldtype = fi->type;
2387                                 disp      = fi->offset;
2388                         }
2389
2390                         switch (fieldtype) {
2391                         case TYPE_INT:
2392                         case TYPE_FLT:
2393                                 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2394                                 break;
2395                         case TYPE_LNG:
2396                         case TYPE_ADR:
2397                         case TYPE_DBL:
2398                                 /* XXX why no check for IS_IMM32? */
2399                                 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2400                                 M_IST32_IMM(iptr->sx.s23.s2.constval >> 32, s1, disp + 4);
2401                                 break;
2402                         }
2403 #endif
2404                         break;
2405
2406
2407                 /* branch operations **************************************************/
2408
2409                 case ICMD_ATHROW:       /* ..., objectref ==> ... (, objectref)       */
2410
2411                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2412                         M_INTMOVE(s1, REG_ITMP1_XPTR);
2413
2414                         PROFILE_CYCLE_STOP;
2415
2416 #ifdef ENABLE_VERIFIER
2417                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2418                                 uc = iptr->sx.s23.s2.uc;
2419
2420                                 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2421                         }
2422 #endif /* ENABLE_VERIFIER */
2423
2424                         disp = dseg_add_functionptr(cd, asm_handle_exception);
2425                         M_ALD(REG_ITMP2, REG_PV, disp);
2426                         M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2427                         M_NOP;
2428
2429                         break;
2430
2431                 case ICMD_GOTO:         /* ... ==> ...                                */
2432                 case ICMD_RET:          /* ... ==> ...                                */
2433
2434                         M_BR(0);
2435                         codegen_add_branch_ref(cd, iptr->dst.block);
2436
2437                         break;
2438
2439                 case ICMD_JSR:          /* ... ==> ...                                */
2440                         OOPS();
2441 #if 0
2442                         M_JMP_IMM(0);
2443                         codegen_add_branch_ref(cd, iptr->sx.s23.s3.jsrtarget.block);
2444 #endif
2445                         break;
2446                         
2447                 case ICMD_IFNULL:       /* ..., value ==> ...                         */
2448                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2449                         M_TEST(s1);
2450                         M_BEQ(0);
2451                         codegen_add_branch_ref(cd, iptr->dst.block);
2452                         break;
2453
2454                 case ICMD_IFNONNULL:    /* ..., value ==> ...                         */
2455                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2456                         M_TEST(s1);
2457                         M_BNE(0);
2458                         codegen_add_branch_ref(cd, iptr->dst.block);
2459                         break;
2460
2461                 case ICMD_IFEQ:         /* ..., value ==> ...                         */
2462                 case ICMD_IFLT:         /* ..., value ==> ...                         */
2463                 case ICMD_IFLE:         /* ..., value ==> ...                         */
2464                 case ICMD_IFNE:         /* ..., value ==> ...                         */
2465                 case ICMD_IFGT:         /* ..., value ==> ...                         */
2466                 case ICMD_IFGE:         /* ..., value ==> ...                         */
2467                         
2468                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2469
2470                         if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
2471                                 N_CHI(s1, iptr->sx.val.i);
2472                         else {
2473                                 disp = dseg_add_s4(cd, iptr->sx.val.i);
2474                                 N_LHI(REG_ITMP2, disp);
2475                                 N_CL(s1, 0, REG_ITMP2, REG_PV);
2476                         }
2477
2478                         switch (iptr->opc) {
2479                         case ICMD_IFLT:
2480                                 M_BLT(0);
2481                                 break;
2482                         case ICMD_IFLE:
2483                                 M_BLE(0);
2484                                 break;
2485                         case ICMD_IFNE:
2486                                 M_BNE(0);
2487                                 break;
2488                         case ICMD_IFGT:
2489                                 M_BGT(0);
2490                                 break;
2491                         case ICMD_IFGE:
2492                                 M_BGE(0);
2493                                 break;
2494                         case ICMD_IFEQ:
2495                                 M_BEQ(0);
2496                                 break;
2497                         }
2498                         codegen_add_branch_ref(cd, iptr->dst.block);
2499
2500                         break;
2501
2502                 case ICMD_IF_LEQ:       /* ..., value ==> ...                         */
2503                         OOPS();
2504 #if 0
2505                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2506                         if (IS_IMM32(iptr->sx.val.l))
2507                                 M_LCMP_IMM(iptr->sx.val.l, s1);
2508                         else {
2509                                 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2510                                 M_LCMP(REG_ITMP2, s1);
2511                         }
2512                         M_BEQ(0);
2513                         codegen_add_branch_ref(cd, iptr->dst.block);
2514 #endif
2515                         break;
2516
2517                 case ICMD_IF_LLT:       /* ..., value ==> ...                         */
2518                         OOPS();
2519 #if 0
2520
2521                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2522                         if (IS_IMM32(iptr->sx.val.l))
2523                                 M_LCMP_IMM(iptr->sx.val.l, s1);
2524                         else {
2525                                 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2526                                 M_LCMP(REG_ITMP2, s1);
2527                         }
2528                         M_BLT(0);
2529                         codegen_add_branch_ref(cd, iptr->dst.block);
2530 #endif
2531                         break;
2532
2533                 case ICMD_IF_LLE:       /* ..., value ==> ...                         */
2534                         OOPS();
2535 #if 0
2536
2537                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2538                         if (IS_IMM32(iptr->sx.val.l))
2539                                 M_LCMP_IMM(iptr->sx.val.l, s1);
2540                         else {
2541                                 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2542                                 M_LCMP(REG_ITMP2, s1);
2543                         }
2544                         M_BLE(0);
2545                         codegen_add_branch_ref(cd, iptr->dst.block);
2546 #endif
2547                         break;
2548
2549                 case ICMD_IF_LNE:       /* ..., value ==> ...                         */
2550                         OOPS();
2551 #if 0
2552
2553                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2554                         if (IS_IMM32(iptr->sx.val.l))
2555                                 M_LCMP_IMM(iptr->sx.val.l, s1);
2556                         else {
2557                                 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2558                                 M_LCMP(REG_ITMP2, s1);
2559                         }
2560                         M_BNE(0);
2561                         codegen_add_branch_ref(cd, iptr->dst.block);
2562 #endif
2563                         break;
2564
2565                 case ICMD_IF_LGT:       /* ..., value ==> ...                         */
2566                         OOPS();
2567 #if 0
2568
2569                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2570                         if (IS_IMM32(iptr->sx.val.l))
2571                                 M_LCMP_IMM(iptr->sx.val.l, s1);
2572                         else {
2573                                 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2574                                 M_LCMP(REG_ITMP2, s1);
2575                         }
2576                         M_BGT(0);
2577                         codegen_add_branch_ref(cd, iptr->dst.block);
2578 #endif
2579                         break;
2580
2581                 case ICMD_IF_LGE:       /* ..., value ==> ...                         */
2582                         OOPS();
2583 #if 0
2584
2585                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2586                         if (IS_IMM32(iptr->sx.val.l))
2587                                 M_LCMP_IMM(iptr->sx.val.l, s1);
2588                         else {
2589                                 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2590                                 M_LCMP(REG_ITMP2, s1);
2591                         }
2592                         M_BGE(0);
2593                         codegen_add_branch_ref(cd, iptr->dst.block);
2594 #endif
2595                         break;
2596
2597                 case ICMD_IF_ICMPEQ:    /* ..., value, value ==> ...                  */
2598                 case ICMD_IF_ACMPEQ:    /* op1 = target JavaVM pc                     */
2599
2600                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2601                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2602                         M_CMP(s1, s2);
2603                         M_BEQ(0);
2604                         codegen_add_branch_ref(cd, iptr->dst.block);
2605                         break;
2606
2607                 case ICMD_IF_LCMPEQ:    /* ..., value, value ==> ...                  */
2608
2609                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2610                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2611                         M_CMP(s1, s2);
2612                         /* load low-bits before the branch, so we know the distance */
2613                         /* TODO do the loads modify the condition code?
2614                          * lr, l, la, lhi dont
2615                          */
2616                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2617                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2618                         M_BNE(SZ_BRC + SZ_CR + SZ_BRC);
2619                         M_CMP(s1, s2);
2620                         M_BEQ(0);
2621                         codegen_add_branch_ref(cd, iptr->dst.block);
2622                         break;
2623
2624                 case ICMD_IF_ACMPNE:    /* op1 = target JavaVM pc                     */
2625                 case ICMD_IF_ICMPNE:    /* ..., value, value ==> ...                  */
2626
2627                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2628                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2629                         M_ICMP(s2, s1);
2630                         M_BNE(0);
2631                         codegen_add_branch_ref(cd, iptr->dst.block);
2632
2633                         break;
2634
2635                 case ICMD_IF_LCMPNE:    /* ..., value, value ==> ...                  */
2636                         OOPS();
2637 #if 0
2638
2639                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2640                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2641                         M_LCMP(s2, s1);
2642                         M_BNE(0);
2643                         codegen_add_branch_ref(cd, iptr->dst.block);
2644 #endif
2645                         break;
2646
2647                 case ICMD_IF_ICMPLT:    /* ..., value, value ==> ...                  */
2648
2649                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2650                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2651                         M_ICMP(s2, s1);
2652                         M_BLT(0);
2653                         codegen_add_branch_ref(cd, iptr->dst.block);
2654
2655                         break;
2656
2657                 case ICMD_IF_LCMPLT:    /* ..., value, value ==> ...                  */
2658                         OOPS();
2659 #if 0
2660
2661                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2662                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2663                         M_LCMP(s2, s1);
2664                         M_BLT(0);
2665                         codegen_add_branch_ref(cd, iptr->dst.block);
2666 #endif
2667                         break;
2668
2669                 case ICMD_IF_ICMPGT:    /* ..., value, value ==> ...                  */
2670
2671                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2672                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2673                         M_ICMP(s2, s1);
2674                         M_BGT(0);
2675                         codegen_add_branch_ref(cd, iptr->dst.block);
2676
2677                         break;
2678
2679                 case ICMD_IF_LCMPGT:    /* ..., value, value ==> ...                  */
2680
2681                         OOPS();
2682 #if 0
2683                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2684                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2685                         M_LCMP(s2, s1);
2686                         M_BGT(0);
2687                         codegen_add_branch_ref(cd, iptr->dst.block);
2688 #endif
2689                         break;
2690
2691                 case ICMD_IF_ICMPLE:    /* ..., value, value ==> ...                  */
2692
2693                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2694                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2695                         M_ICMP(s2, s1);
2696                         M_BLE(0);
2697                         codegen_add_branch_ref(cd, iptr->dst.block);
2698
2699                         break;
2700
2701                 case ICMD_IF_LCMPLE:    /* ..., value, value ==> ...                  */
2702
2703                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2704                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2705                         M_CMP(s1, s2);
2706                         M_BLT(0);
2707                         codegen_add_branch_ref(cd, iptr->dst.block);
2708                         /* load low-bits before the branch, so we know the distance */
2709                         /* TODO: the loads should not touch the condition code. */
2710                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2711                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2712                         M_BGT(SZ_BRC + SZ_CR + SZ_BRC);
2713                         M_CMP(s1, s2);
2714                         M_BLE(0);
2715                         codegen_add_branch_ref(cd, iptr->dst.block);
2716                         break;
2717
2718                 case ICMD_IF_ICMPGE:    /* ..., value, value ==> ...                  */
2719
2720                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2721                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2722                         M_ICMP(s2, s1);
2723                         M_BGE(0);
2724                         codegen_add_branch_ref(cd, iptr->dst.block);
2725
2726                         break;
2727
2728                 case ICMD_IF_LCMPGE:    /* ..., value, value ==> ...                  */
2729
2730                         OOPS();
2731 #if 0
2732                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2733                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2734                         M_LCMP(s2, s1);
2735                         M_BGE(0);
2736                         codegen_add_branch_ref(cd, iptr->dst.block);
2737 #endif
2738                         break;
2739
2740                 case ICMD_IRETURN:      /* ..., retvalue ==> ...                      */
2741
2742                         REPLACEMENT_POINT_RETURN(cd, iptr);
2743                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
2744                         M_INTMOVE(s1, REG_RESULT);
2745                         goto nowperformreturn;
2746
2747                 case ICMD_ARETURN:      /* ..., retvalue ==> ...                      */
2748
2749                         REPLACEMENT_POINT_RETURN(cd, iptr);
2750                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
2751                         M_INTMOVE(s1, REG_RESULT);
2752
2753 #ifdef ENABLE_VERIFIER
2754                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2755                                 unresolved_class *uc = iptr->sx.s23.s2.uc;
2756
2757                                 codegen_addpatchref(cd, PATCHER_athrow_areturn, uc, 0);
2758                         }
2759 #endif /* ENABLE_VERIFIER */
2760                         goto nowperformreturn;
2761
2762                 case ICMD_LRETURN:      /* ..., retvalue ==> ...                      */
2763
2764                         REPLACEMENT_POINT_RETURN(cd, iptr);
2765                         s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
2766                         M_LNGMOVE(s1, REG_RESULT_PACKED);
2767                         goto nowperformreturn;
2768
2769                 case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
2770                 case ICMD_DRETURN:
2771
2772                         REPLACEMENT_POINT_RETURN(cd, iptr);
2773                         s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2774                         M_FLTMOVE(s1, REG_FRESULT);
2775                         goto nowperformreturn;
2776
2777                 case ICMD_RETURN:      /* ...  ==> ...                                */
2778
2779                         REPLACEMENT_POINT_RETURN(cd, iptr);
2780
2781 nowperformreturn:
2782                         {
2783                         s4 i, p;
2784                         
2785                         p = cd->stackframesize;
2786
2787                         /* call trace function */
2788
2789                         /*emit_verbosecall_exit(jd); TODO */
2790
2791 #if defined(ENABLE_THREADS)
2792                         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2793                                 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2794                                 M_ALD(REG_ITMP3, REG_PV, disp);
2795                                 M_CALL(REG_ITMP3);
2796
2797                                 /* we need to save the proper return value */
2798
2799                                 switch (iptr->opc) {
2800                                 case ICMD_LRETURN:
2801                                         M_IST(REG_RESULT2, REG_SP, rd->memuse * 4 + 8);
2802                                         /* fall through */
2803                                 case ICMD_IRETURN:
2804                                 case ICMD_ARETURN:
2805                                         M_IST(REG_RESULT , REG_SP, rd->memuse * 4 + 4);
2806                                         break;
2807                                 case ICMD_FRETURN:
2808                                         M_FST(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
2809                                         break;
2810                                 case ICMD_DRETURN:
2811                                         M_DST(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
2812                                         break;
2813                                 }
2814
2815                                 M_ALD(REG_A0, REG_SP, rd->memuse * 4);
2816                                 M_JSR;
2817
2818                                 /* and now restore the proper return value */
2819
2820                                 switch (iptr->opc) {
2821                                 case ICMD_LRETURN:
2822                                         M_ILD(REG_RESULT2, REG_SP, rd->memuse * 4 + 8);
2823                                         /* fall through */
2824                                 case ICMD_IRETURN:
2825                                 case ICMD_ARETURN:
2826                                         M_ILD(REG_RESULT , REG_SP, rd->memuse * 4 + 4);
2827                                         break;
2828                                 case ICMD_FRETURN:
2829                                         M_FLD(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
2830                                         break;
2831                                 case ICMD_DRETURN:
2832                                         M_DLD(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
2833                                         break;
2834                                 }
2835                         }
2836 #endif
2837
2838                         /* restore return address                                         */
2839
2840                         p--; M_ALD(REG_RA, REG_SP, p * 4);
2841
2842                         /* restore saved registers                                        */
2843
2844                         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2845                                 p--; M_ILD(rd->savintregs[i], REG_SP, p * 4);
2846                         }
2847                         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2848                                 p -= 2; M_DLD(rd->savfltregs[i], REG_SP, p * 4);
2849                         }
2850
2851                         /* deallocate stack                                               */
2852
2853                         if (cd->stackframesize)
2854                                 M_AADD_IMM(cd->stackframesize * 4, REG_SP);
2855
2856                         M_RET;
2857                         ALIGNCODENOP;
2858                         }
2859                         break;
2860
2861                 case ICMD_TABLESWITCH:  /* ..., index ==> ...                         */
2862                         OOPS();
2863 #if 0
2864                         {
2865                                 s4 i, l;
2866                                 branch_target_t *table;
2867
2868                                 table = iptr->dst.table;
2869
2870                                 l = iptr->sx.s23.s2.tablelow;
2871                                 i = iptr->sx.s23.s3.tablehigh;
2872
2873                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2874                                 M_INTMOVE(s1, REG_ITMP1);
2875
2876                                 if (l != 0)
2877                                         M_ISUB_IMM(l, REG_ITMP1);
2878
2879                                 /* number of targets */
2880                                 i = i - l + 1;
2881
2882                 /* range check */
2883                                 M_ICMP_IMM(i - 1, REG_ITMP1);
2884                                 M_BA(0);
2885
2886                                 codegen_add_branch_ref(cd, table[0].block); /* default target */
2887
2888                                 /* build jump table top down and use address of lowest entry */
2889
2890                                 table += i;
2891
2892                                 while (--i >= 0) {
2893                                         dseg_add_target(cd, table->block);
2894                                         --table;
2895                                 }
2896
2897                                 /* length of dataseg after last dseg_add_target is used
2898                                    by load */
2899
2900                                 M_MOV_IMM(0, REG_ITMP2);
2901                                 dseg_adddata(cd);
2902                                 emit_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 3, REG_ITMP1);
2903                                 M_JMP(REG_ITMP1);
2904                         }
2905 #endif
2906                         break;
2907
2908
2909                 case ICMD_LOOKUPSWITCH: /* ..., key ==> ...                           */
2910                         OOPS();
2911 #if 0
2912                         {
2913                                 s4 i;
2914                                 lookup_target_t *lookup;
2915
2916                                 lookup = iptr->dst.lookup;
2917
2918                                 i = iptr->sx.s23.s2.lookupcount;
2919                         
2920                                 MCODECHECK(8 + ((7 + 6) * i) + 5);
2921                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2922
2923                                 while (--i >= 0) {
2924                                         M_ICMP_IMM(lookup->value, s1);
2925                                         M_BEQ(0);
2926                                         codegen_add_branch_ref(cd, lookup->target.block);
2927                                         lookup++;
2928                                 }
2929
2930                                 M_JMP_IMM(0);
2931                         
2932                                 codegen_add_branch_ref(cd, iptr->sx.s23.s3.lookupdefault.block);
2933                         }
2934 #endif
2935                         break;
2936
2937
2938                 case ICMD_BUILTIN:      /* ..., [arg1, [arg2 ...]] ==> ...            */
2939
2940                         bte = iptr->sx.s23.s3.bte;
2941                         md  = bte->md;
2942                         goto gen_method;
2943
2944                 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ...            */
2945                 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2946                 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer    */
2947                 case ICMD_INVOKEINTERFACE:
2948
2949                         REPLACEMENT_POINT_INVOKE(cd, iptr);
2950
2951                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2952                                 lm = NULL;
2953                                 um = iptr->sx.s23.s3.um;
2954                                 md = um->methodref->parseddesc.md;
2955                         }
2956                         else {
2957                                 lm = iptr->sx.s23.s3.fmiref->p.method;
2958                                 um = NULL;
2959                                 md = lm->parseddesc;
2960                         }
2961
2962 gen_method:
2963                         s3 = md->paramcount;
2964
2965                         MCODECHECK((s3 << 1) + 64);
2966
2967                         /* copy arguments to registers or stack location */
2968
2969                         for (s3 = s3 - 1; s3 >= 0; s3--) {
2970                                 var = VAR(iptr->sx.s23.s2.args[s3]);
2971
2972                                 /* Already Preallocated? */
2973                                 if (var->flags & PREALLOC)
2974                                         continue;
2975
2976                                 if (IS_INT_LNG_TYPE(var->type)) {
2977                                         if (!md->params[s3].inmemory) {
2978                                                 if (IS_2_WORD_TYPE(var->type)) {
2979                                                         s1 = PACK_REGS(
2980                                                                 rd->argintregs[GET_LOW_REG(md->params[s3].regoff)],
2981                                                                 rd->argintregs[GET_HIGH_REG(md->params[s3].regoff)]
2982                                                         );
2983                                                         d = emit_load(jd, iptr, var, s1);
2984                                                         M_LNGMOVE(d, s1);
2985                                                 }
2986                                                 else {
2987                                                         s1 = rd->argintregs[md->params[s3].regoff];
2988                                                         d = emit_load(jd, iptr, var, s1);
2989                                                         M_INTMOVE(d, s1);
2990                                                 }
2991                                         }
2992                                         else {
2993                                                 if (IS_2_WORD_TYPE(var->type)) {
2994                                                         d = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
2995                                                         M_LST(d, REG_SP, md->params[s3].regoff * 4);
2996                                                 }
2997                                                 else {
2998                                                         d = emit_load(jd, iptr, var, REG_ITMP1);
2999                                                         M_IST(d, REG_SP, md->params[s3].regoff * 4);
3000                                                 }
3001                                         }
3002                                 }
3003                                 else {
3004                                         if (!md->params[s3].inmemory) {
3005                                                 s1 = rd->argfltregs[md->params[s3].regoff];
3006                                                 d = emit_load(jd, iptr, var, s1);
3007                                                 M_FLTMOVE(d, s1);
3008                                         }
3009                                         else {
3010                                                 d = emit_load(jd, iptr, var, REG_FTMP1);
3011                                                 if (IS_2_WORD_TYPE(var->type))
3012                                                         M_DST(d, REG_SP, md->params[s3].regoff * 4);
3013                                                 else
3014                                                         M_FST(d, REG_SP, md->params[s3].regoff * 4);
3015                                         }
3016                                 }
3017                         }
3018
3019                         switch (iptr->opc) {
3020                         case ICMD_BUILTIN:
3021                                 disp = dseg_add_functionptr(cd, bte->fp);
3022
3023                                 N_AHI(REG_SP, -96); /* register save are required by C abi */   
3024                                 N_LHI(REG_ITMP1, disp);
3025                                 N_L(REG_PV, 0, REG_ITMP1, REG_PV);
3026                                 break;
3027
3028                         case ICMD_INVOKESPECIAL:
3029                                 emit_nullpointer_check(cd, iptr, REG_A0);
3030                                 M_ILD(REG_ITMP1, REG_A0, 0); /* hardware nullptr   */
3031                                 /* fall through */
3032
3033                         case ICMD_INVOKESTATIC:
3034                                 if (lm == NULL) {
3035                                         disp = dseg_add_unique_address(cd, um);
3036
3037                                         codegen_addpatchref(cd, PATCHER_invokestatic_special,
3038                                                                                 um, disp);
3039                                 }
3040                                 else
3041                                         disp = dseg_add_address(cd, lm->stubroutine);
3042
3043                                 N_LHI(REG_ITMP1, disp);
3044                                 N_L(REG_PV, 0, REG_ITMP1, REG_PV);
3045                                 break;
3046
3047                         case ICMD_INVOKEVIRTUAL:
3048                                 emit_nullpointer_check(cd, iptr, REG_A0);
3049
3050                                 if (lm == NULL) {
3051                                         codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
3052
3053                                         s1 = 0;
3054                                 }
3055                                 else {
3056                                         s1 = OFFSET(vftbl_t, table[0]) +
3057                                                 sizeof(methodptr) * lm->vftblindex;
3058                                 }
3059
3060                                 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
3061                                 M_ALD(REG_PV, REG_METHODPTR, s1);
3062                                 break;
3063
3064                         case ICMD_INVOKEINTERFACE:
3065                                 emit_nullpointer_check(cd, iptr, REG_A0);
3066
3067                                 if (lm == NULL) {
3068                                         codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
3069
3070                                         s1 = 0;
3071                                         s2 = 0;
3072                                 }
3073                                 else {
3074                                         s1 = OFFSET(vftbl_t, interfacetable[0]) -
3075                                                 sizeof(methodptr*) * lm->class->index;
3076
3077                                         s2 = sizeof(methodptr) * (lm - lm->class->methods);
3078                                 }
3079
3080                                 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
3081                                 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3082                                 M_ALD(REG_PV, REG_METHODPTR, s2);
3083                                 break;
3084                         }
3085
3086                         /* generate the actual call */
3087
3088                         M_CALL(REG_PV);
3089                         REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3090                         N_BASR(REG_ITMP1, RN);
3091                         disp = (s4) (cd->mcodeptr - cd->mcodebase);
3092                         M_LDA(REG_PV, REG_ITMP1, -disp);
3093         
3094                         /* post call finalization */
3095
3096                         if (iptr->opc == ICMD_BUILTIN) {
3097                                 N_AHI(REG_SP, 96); /* remove C abi register save area */
3098                         }
3099
3100                         /* actually only used for ICMD_BUILTIN */
3101
3102                         if (INSTRUCTION_MUST_CHECK(iptr)) {
3103                                 M_TEST(REG_RESULT);
3104                                 M_BEQ(0);
3105                                 codegen_add_fillinstacktrace_ref(cd);
3106                         }
3107
3108                         /* store return value */
3109
3110                         d = md->returntype.type;
3111
3112                         if (d != TYPE_VOID) {
3113                                 if (IS_INT_LNG_TYPE(d)) {
3114                                         if (IS_2_WORD_TYPE(d)) {
3115                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
3116                                                 M_LNGMOVE(REG_RESULT_PACKED, s1);
3117                                         }
3118                                         else {
3119                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3120                                                 M_INTMOVE(REG_RESULT, s1);
3121                                         }
3122                                 }
3123                                 else {
3124                                         s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
3125                                         M_FLTMOVE(REG_FRESULT, s1);
3126                                 }
3127                                 emit_store_dst(jd, iptr, s1);
3128                         }
3129
3130                         break;
3131
3132
3133                 case ICMD_CHECKCAST:  /* ..., objectref ==> ..., objectref            */
3134
3135                                       /* val.a: (classinfo*) superclass               */
3136
3137                         /*  superclass is an interface:
3138                          *      
3139                          *  OK if ((sub == NULL) ||
3140                          *         (sub->vftbl->interfacetablelength > super->index) &&
3141                          *         (sub->vftbl->interfacetable[-super->index] != NULL));
3142                          *      
3143                          *  superclass is a class:
3144                          *      
3145                          *  OK if ((sub == NULL) || (0
3146                          *         <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3147                          *         super->vftbl->diffval));
3148                          */
3149
3150                         if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
3151                                 /* object type cast-check */
3152
3153                                 classinfo *super;
3154                                 vftbl_t   *supervftbl;
3155                                 s4         superindex;
3156
3157                                 u1        *class_label_refs[] = { 0 }, *class_label;
3158                                 u1        *exit_label_refs[] = { 0, 0, 0, 0 };
3159
3160                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3161                                         super = NULL;
3162                                         superindex = 0;
3163                                         supervftbl = NULL;
3164                                 }
3165                                 else {
3166                                         super = iptr->sx.s23.s3.c.cls;
3167                                         superindex = super->index;
3168                                         supervftbl = super->vftbl;
3169                                 }
3170
3171 #if defined(ENABLE_THREADS)
3172                                 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3173 #endif
3174                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3175
3176                                 /* if class is not resolved, check which code to call */
3177
3178                                 if (super == NULL) {
3179                                         M_TEST(s1);
3180                                         exit_label_refs[0] = cd->mcodeptr;
3181                                         M_BEQ(0);
3182
3183                                         disp = dseg_add_unique_s4(cd, 0);         /* super->flags */
3184
3185                                         codegen_add_patch_ref(cd, PATCHER_resolve_classref_to_flags,
3186                                                                                   iptr->sx.s23.s3.c.ref,
3187                                                                                   disp);
3188
3189                                         ICONST(REG_ITMP2, ACC_INTERFACE);
3190                                         ICONST(REG_ITMP3, disp); /* TODO negative displacement */
3191                                         N_N(REG_ITMP2, 0, REG_ITMP3, REG_PV);
3192                                         class_label_refs[0] = cd->mcodeptr;
3193                                         M_BEQ(0);
3194                                 }
3195
3196                                 /* interface checkcast code */
3197
3198                                 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3199                                         if (super == NULL) {
3200                                                 codegen_add_patch_ref(cd,
3201                                                                                           PATCHER_checkcast_instanceof_interface,
3202                                                                                           iptr->sx.s23.s3.c.ref,
3203                                                                                           0);
3204                                         } else {
3205                                                 M_TEST(s1);
3206                                                 exit_label_refs[1] = cd->mcodeptr;
3207                                                 M_BEQ(0);
3208                                         }
3209
3210                                         M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3211                                         M_ILD(REG_ITMP3, REG_ITMP2,
3212                                                   OFFSET(vftbl_t, interfacetablelength));
3213                                         M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
3214                                         M_TEST(REG_ITMP3);
3215                                         M_BLE(0);
3216                                         codegen_add_classcastexception_ref(cd, s1);
3217                                         M_ALD(REG_ITMP3, REG_ITMP2,
3218                                                   (s4) (OFFSET(vftbl_t, interfacetable[0]) -
3219                                                                 superindex * sizeof(methodptr*)));
3220                                         M_TEST(REG_ITMP3);
3221                                         M_BEQ(0);
3222                                         codegen_add_classcastexception_ref(cd, s1);
3223
3224                                         if (super == NULL) {
3225                                                 exit_label_refs[2] = cd->mcodeptr;
3226                                                 M_BR(0);
3227                                         }
3228                                 }
3229
3230                                 /* class checkcast code */
3231
3232                                 class_label = cd->mcodeptr;
3233
3234                                 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3235                                         if (super == NULL) {
3236                                                 disp = dseg_add_unique_address(cd, NULL);
3237
3238                                                 codegen_add_patch_ref(cd,
3239                                                                                           PATCHER_resolve_classref_to_vftbl,
3240                                                                                           iptr->sx.s23.s3.c.ref,
3241                                                                                           disp);
3242                                         }
3243                                         else {
3244                                                 disp = dseg_add_address(cd, supervftbl);
3245                                                 M_TEST(s1);
3246                                                 exit_label_refs[3] = cd->mcodeptr;
3247                                                 M_BEQ(0);
3248                                         }
3249
3250                                         M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3251                                         M_ALD(REG_ITMP3, REG_PV, disp);
3252 #if defined(ENABLE_THREADS)
3253                                         codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3254 #endif
3255                                         M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3256                                         /*                              if (s1 != REG_ITMP1) { */
3257                                         /*                                      M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3258                                         /*                                      M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3259                                         /*  #if defined(ENABLE_THREADS) */
3260                                         /*                                      codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase); */
3261                                         /*  #endif */
3262                                         /*                                      M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3263
3264                                         /*                              } else { */
3265                                         M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3266                                         M_ISUB(REG_ITMP2, REG_ITMP3);
3267                                         M_ALD(REG_ITMP3, REG_PV, disp);
3268                                         M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3269 #if defined(ENABLE_THREADS)
3270                                         codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3271 #endif
3272                                         /*                              } */
3273                                         N_CLR(REG_ITMP2, REG_ITMP3); /* Unsigned compare */
3274                                         /* M_CMPULE(REG_ITMP2, REG_ITMP3, REG_ITMP3); itmp3 = (itmp2 <= itmp3) */
3275                                         M_BGT(0); /* Branch if greater then */
3276                                         /* M_BEQZ(REG_ITMP3, 0); branch if (! itmp) -> branch if > */
3277                                         codegen_add_classcastexception_ref(cd, s1);
3278                                 }
3279
3280                                 /* resolve labels by adding the correct displacement */
3281
3282                                 for (s2 = 0; s2 < sizeof(exit_label_refs) / sizeof(exit_label_refs[0]); ++s2) {
3283                                         if (exit_label_refs[s2])
3284                                                 *(u4 *)exit_label_refs[s2] |= (u4)(cd->mcodeptr - exit_label_refs[s2]) / 2;
3285                                 }
3286
3287                                 for (s2 = 0; s2 < sizeof(class_label_refs) / sizeof(class_label_refs[0]); ++s2) {
3288                                         if (class_label_refs[s2])
3289                                                 *(u4 *)class_label_refs[s2] |= (u4)(class_label - class_label_refs[s2]) / 2;
3290                                 }
3291
3292                                 d = codegen_reg_of_dst(jd, iptr, s1);
3293                         }
3294                         else {
3295                                 /* array type cast-check */
3296
3297                                 s1 = emit_load_s1(jd, iptr, REG_A0);
3298                                 M_INTMOVE(s1, REG_A0);
3299
3300                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3301                                         disp = dseg_add_unique_address(cd, NULL);
3302
3303                                         codegen_add_patch_ref(cd,
3304                                                                                   PATCHER_resolve_classref_to_classinfo,
3305                                                                                   iptr->sx.s23.s3.c.ref,
3306                                                                                   disp);
3307                                 }
3308                                 else
3309                                         disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3310
3311                                 M_ALD(REG_A1, REG_PV, disp);
3312                                 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
3313                                 ICONST(REG_ITMP1, disp); /* TODO negative displacement */
3314                                 N_L(REG_PV, 0, REG_ITMP1, REG_PV);
3315                                 M_JSR(REG_RA, REG_PV);
3316                                 N_BASR(REG_ITMP1, RN);
3317                                 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3318                                 M_LDA(REG_PV, REG_ITMP1, -disp);
3319
3320                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3321                                 M_TEST(REG_RESULT);
3322                                 M_BEQ(0);
3323                                 codegen_add_classcastexception_ref(cd, s1);
3324
3325                                 d = codegen_reg_of_dst(jd, iptr, s1);
3326                         }
3327
3328                         M_INTMOVE(s1, d);
3329                         emit_store_dst(jd, iptr, d);
3330                         break;
3331
3332                 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
3333                         OOPS();
3334 #if 0
3335                                       /* val.a: (classinfo*) superclass               */
3336
3337                         /*  superclass is an interface:
3338                          *      
3339                          *  return (sub != NULL) &&
3340                          *         (sub->vftbl->interfacetablelength > super->index) &&
3341                          *         (sub->vftbl->interfacetable[-super->index] != NULL);
3342                          *      
3343                          *  superclass is a class:
3344                          *      
3345                          *  return ((sub != NULL) && (0
3346                          *          <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3347                          *          super->vftbl->diffvall));
3348                          */
3349
3350                         {
3351                         classinfo *super;
3352                         vftbl_t   *supervftbl;
3353                         s4         superindex;
3354
3355                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3356                                 super = NULL;
3357                                 superindex = 0;
3358                                 supervftbl = NULL;
3359
3360                         } else {
3361                                 super = iptr->sx.s23.s3.c.cls;
3362                                 superindex = super->index;
3363                                 supervftbl = super->vftbl;
3364                         }
3365
3366 #if defined(ENABLE_THREADS)
3367                         codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3368 #endif
3369                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3370                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3371                         if (s1 == d) {
3372                                 M_MOV(s1, REG_ITMP1);
3373                                 s1 = REG_ITMP1;
3374                         }
3375
3376                         /* calculate interface instanceof code size */
3377
3378                         s2 = 6;
3379                         if (super == NULL)
3380                                 s2 += (d == REG_ITMP2 ? 1 : 0) + (opt_shownops ? 1 : 0);
3381
3382                         /* calculate class instanceof code size */
3383
3384                         s3 = 7;
3385                         if (super == NULL)
3386                                 s3 += (opt_shownops ? 1 : 0);
3387
3388                         /* if class is not resolved, check which code to call */
3389
3390                         if (super == NULL) {
3391                                 M_CLR(d);
3392                                 M_BEQZ(s1, 4 + (opt_shownops ? 1 : 0) + s2 + 1 + s3);
3393
3394                                 disp = dseg_add_unique_s4(cd, 0);             /* super->flags */
3395
3396                                 codegen_add_patch_ref(cd, PATCHER_resolve_classref_to_flags,
3397                                                                           iptr->sx.s23.s3.c.ref, disp);
3398
3399                                 M_ILD(REG_ITMP3, REG_PV, disp);
3400
3401                                 disp = dseg_add_s4(cd, ACC_INTERFACE);
3402                                 M_ILD(REG_ITMP2, REG_PV, disp);
3403                                 M_AND(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3404                                 M_BEQZ(REG_ITMP3, s2 + 1);
3405                         }
3406
3407                         /* interface instanceof code */
3408
3409                         if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3410                                 if (super == NULL) {
3411                                         /* If d == REG_ITMP2, then it's destroyed in check
3412                                            code above. */
3413                                         if (d == REG_ITMP2)
3414                                                 M_CLR(d);
3415
3416                                         codegen_add_patch_ref(cd,
3417                                                                                   PATCHER_checkcast_instanceof_interface,
3418                                                                                   iptr->sx.s23.s3.c.ref, 0);
3419                                 }
3420                                 else {
3421                                         M_CLR(d);
3422                                         M_BEQZ(s1, s2);
3423                                 }
3424
3425                                 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3426                                 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3427                                 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
3428                                 M_BLEZ(REG_ITMP3, 2);
3429                                 M_ALD(REG_ITMP1, REG_ITMP1,
3430                                           (s4) (OFFSET(vftbl_t, interfacetable[0]) -
3431                                                         superindex * sizeof(methodptr*)));
3432                                 M_CMPULT(REG_ZERO, REG_ITMP1, d);      /* REG_ITMP1 != 0  */
3433
3434                                 if (super == NULL)
3435                                         M_BR(s3);
3436                         }
3437
3438                         /* class instanceof code */
3439
3440                         if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3441                                 if (super == NULL) {
3442                                         disp = dseg_add_unique_address(cd, NULL);
3443
3444                                         codegen_add_patch_ref(cd, PATCHER_resolve_classref_to_vftbl,
3445                                                                                   iptr->sx.s23.s3.c.ref,
3446                                                                                   disp);
3447                                 }
3448                                 else {
3449                                         disp = dseg_add_address(cd, supervftbl);
3450
3451                                         M_CLR(d);
3452                                         M_BEQZ(s1, s3);
3453                                 }
3454
3455                                 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3456                                 M_ALD(REG_ITMP2, REG_PV, disp);
3457 #if defined(ENABLE_THREADS)
3458                                 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3459 #endif
3460                                 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3461                                 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3462                                 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3463 #if defined(ENABLE_THREADS)
3464                                 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3465 #endif
3466                                 M_ISUB(REG_ITMP1, REG_ITMP3);
3467                                 N_CLR(REG_ITMP1, REG_ITMP2);
3468                                 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3469                         }
3470                         emit_store_dst(jd, iptr, d);
3471                         }
3472 #endif
3473                         break;
3474
3475                 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref  */
3476                         OOPS();
3477 #if 0
3478
3479                         /* check for negative sizes and copy sizes to stack if necessary  */
3480
3481                         MCODECHECK((10 * 4 * iptr->s1.argcount) + 5 + 10 * 8);
3482
3483                         for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3484
3485                                 /* copy SAVEDVAR sizes to stack */
3486                                 var = VAR(iptr->sx.s23.s2.args[s1]);
3487
3488                                 /* Already Preallocated? */
3489                                 if (!(var->flags & PREALLOC)) {
3490                                         s2 = emit_load(jd, iptr, var, REG_ITMP1);
3491                                         M_LST(s2, REG_SP, s1 * 8);
3492                                 }
3493                         }
3494
3495                         /* is a patcher function set? */
3496
3497                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3498                                 codegen_add_patch_ref(cd, PATCHER_builtin_multianewarray,
3499                                                                           iptr->sx.s23.s3.c.ref, 0);
3500                         }
3501
3502                         /* a0 = dimension count */
3503
3504                         M_MOV_IMM(iptr->s1.argcount, REG_A0);
3505
3506                         /* a1 = classinfo */
3507
3508                         M_MOV_IMM(iptr->sx.s23.s3.c.cls, REG_A1);
3509
3510                         /* a2 = pointer to dimensions = stack pointer */
3511
3512                         M_MOV(REG_SP, REG_A2);
3513
3514                         M_MOV_IMM(BUILTIN_multianewarray, REG_ITMP1);
3515                         M_CALL(REG_ITMP1);
3516
3517                         /* check for exception before result assignment */
3518
3519                         M_TEST(REG_RESULT);
3520                         M_BEQ(0);
3521                         codegen_add_fillinstacktrace_ref(cd);
3522
3523                         s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3524                         M_INTMOVE(REG_RESULT, s1);
3525                         emit_store_dst(jd, iptr, s1);
3526 #endif
3527                         break;
3528
3529                 default:
3530                         exceptions_throw_internalerror("Unknown ICMD %d", iptr->opc);
3531                         return false;
3532         } /* switch */
3533
3534         } /* for instruction */
3535                 
3536         MCODECHECK(512); /* XXX require a lower number? */
3537
3538         /* At the end of a basic block we may have to append some nops,
3539            because the patcher stub calling code might be longer than the
3540            actual instruction. So codepatching does not change the
3541            following block unintentionally. */
3542
3543         if (cd->mcodeptr < cd->lastmcodeptr) {
3544                 while (cd->mcodeptr < cd->lastmcodeptr) {
3545                         M_NOP;
3546                 }
3547         }
3548
3549         } /* if (bptr -> flags >= BBREACHED) */
3550         } /* for basic block */
3551
3552         dseg_createlinenumbertable(cd);
3553
3554         /* generate stubs */
3555
3556         emit_exception_stubs(jd);
3557         emit_patcher_stubs(jd);
3558 #if 0
3559         emit_replacement_stubs(jd);
3560 #endif
3561
3562         codegen_finish(jd);
3563
3564         /* everything's ok */
3565
3566         return true;
3567 }
3568
3569
3570 /* createcompilerstub **********************************************************
3571
3572    Creates a stub routine which calls the compiler.
3573         
3574 *******************************************************************************/
3575
3576 #define COMPILERSTUB_DATASIZE    (3 * SIZEOF_VOID_P)
3577 #define COMPILERSTUB_CODESIZE    (SZ_AHI + SZ_L + SZ_L + SZ_BCR)
3578
3579 #define COMPILERSTUB_SIZE        (COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE)
3580
3581
3582 u1 *createcompilerstub(methodinfo *m)
3583 {
3584         u1          *s;                     /* memory to hold the stub            */
3585         ptrint      *d;
3586         codeinfo    *code;
3587         codegendata *cd;
3588         s4           dumpsize;
3589
3590         s = CNEW(u1, COMPILERSTUB_SIZE);
3591
3592         /* set data pointer and code pointer */
3593
3594         d = (ptrint *) s;
3595         s = s + COMPILERSTUB_DATASIZE;
3596
3597         /* mark start of dump memory area */
3598
3599         dumpsize = dump_size();
3600
3601         cd = DNEW(codegendata);
3602         cd->mcodeptr = s;
3603
3604         /* Store the codeinfo pointer in the same place as in the
3605            methodheader for compiled methods. */
3606
3607         code = code_codeinfo_new(m);
3608
3609         d[0] = (ptrint) asm_call_jit_compiler;
3610         d[1] = (ptrint) m;
3611         d[2] = (ptrint) code;
3612
3613         /* code for the stub */
3614
3615         /* don't touch ITMP3 as it cointains the return address */
3616
3617         M_ISUB_IMM((3 * 4), REG_PV); /* suppress negative displacements */
3618
3619         M_ILD(REG_ITMP1, REG_PV, 1 * 4); /* methodinfo  */
3620         /* TODO where is methodpointer loaded into itmp2? is it already inside? */
3621         M_ILD(REG_PV, REG_PV, 0 * 4); /* compiler pointer */
3622         N_BR(REG_PV);
3623
3624 #if defined(ENABLE_STATISTICS)
3625         if (opt_stat)
3626                 count_cstub_len += COMPILERSTUB_SIZE;
3627 #endif
3628
3629         /* release dump area */
3630
3631         dump_release(dumpsize);
3632
3633         return s;
3634 }
3635
3636
3637 /* createnativestub ************************************************************
3638
3639    Creates a stub routine which calls a native method.
3640
3641 *******************************************************************************/
3642
3643 /*
3644            arguments on stack                   \
3645 -------------------------------------------------| <- SP on nativestub entry
3646            return address                        |
3647            callee saved int regs (none)          |
3648            callee saved float regs (none)        | stack frame like in cacao
3649            local variable slots (none)           |
3650            arguments for calling methods (none) /
3651 ------------------------------------------------------------------ <- datasp 
3652            stackframe info
3653            locaref table
3654            integer arguments
3655            float arguments
3656 96 - ...   on stack parameters (nmd->memuse slots) \ stack frame like in ABI         
3657 0 - 96     register save area for callee           /
3658 -------------------------------------------------------- <- SP native method
3659                                                             ==
3660                                                             SP after method entry
3661 */
3662
3663 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
3664 {
3665         methodinfo   *m;
3666         codeinfo     *code;
3667         codegendata  *cd;
3668         registerdata *rd;
3669         methoddesc   *md;
3670         s4            nativeparams;
3671         s4            i, j;                 /* count variables                    */
3672         s4            t;
3673         s4            s1, s2;
3674         s4            disp;
3675
3676         /* get required compiler data */
3677
3678         m    = jd->m;
3679         code = jd->code;
3680         cd   = jd->cd;
3681         rd   = jd->rd;
3682
3683         /* initialize variables */
3684
3685         md = m->parseddesc;
3686         nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3687
3688         /* calculate stack frame size */
3689 #if 0
3690         cd->stackframesize =
3691                 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3692                 sizeof(localref_table) / SIZEOF_VOID_P +
3693                 INT_ARG_CNT + FLT_ARG_CNT +
3694                 1 +                       /* functionptr, TODO: store in data segment */
3695                 nmd->memuse;
3696
3697         cd->stackframesize |= 0x1;                  /* keep stack 16-byte aligned */
3698 #endif
3699
3700         cd->stackframesize = 
3701                 1 + /* r14 - return address */ +
3702                 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3703                 sizeof(localref_table) / SIZEOF_VOID_P +
3704                 1 + /* itmp3 */
3705                 (INT_ARG_CNT + FLT_ARG_CNT) * 2 +
3706                 nmd->memuse + /* parameter passing */
3707                 96 / SIZEOF_VOID_P /* required by ABI */;
3708
3709         cd->stackframesize |= 0x1;                  /* keep stack 8-byte aligned */
3710
3711
3712         /* create method header */
3713
3714         (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
3715         (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize       */
3716         (void) dseg_add_unique_s4(cd, 0);                      /* IsSync          */
3717         (void) dseg_add_unique_s4(cd, 0);                      /* IsLeaf          */
3718         (void) dseg_add_unique_s4(cd, 0);                      /* IntSave         */
3719         (void) dseg_add_unique_s4(cd, 0);                      /* FltSave         */
3720         (void) dseg_addlinenumbertablesize(cd);
3721         (void) dseg_add_unique_s4(cd, 0);                      /* ExTableSize     */
3722
3723         /* generate native method profiling code */
3724 #if 0
3725         if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
3726                 /* count frequency */
3727
3728                 M_MOV_IMM(code, REG_ITMP3);
3729                 M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
3730         }
3731 #endif
3732
3733         /* generate stub code */
3734
3735         N_AHI(REG_SP, -(cd->stackframesize * SIZEOF_VOID_P));
3736
3737         /* save return address */
3738
3739         N_ST(R14, (cd->stackframesize - 1) * SIZEOF_VOID_P, RN, REG_SP);
3740
3741 #if 0
3742 #if !defined(NDEBUG)
3743         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3744                 emit_verbosecall_enter(jd);
3745 #endif
3746 #endif
3747
3748         /* get function address (this must happen before the stackframeinfo) */
3749
3750         disp = dseg_add_functionptr(cd, f);
3751
3752 #if !defined(WITH_STATIC_CLASSPATH)
3753         if (f == NULL)
3754                 codegen_add_patch_ref(cd, PATCHER_resolve_native, m, disp);
3755 #endif
3756
3757         M_ILD(REG_ITMP1, REG_PV, disp);
3758
3759         j = 96 + (nmd->memuse * 4);
3760
3761         /* todo some arg registers are not volatile in C-abi terms */
3762
3763         /* save integer and float argument registers */
3764
3765         for (i = 0; i < md->paramcount; i++) {
3766                 if (! md->params[i].inmemory) {
3767                         s1 = md->params[i].regoff;
3768
3769                         if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
3770                                 if (IS_2_WORD_TYPE(t)) {
3771                                         /* todo store multiple */
3772                                         N_ST(rd->argintregs[GET_HIGH_REG(s1)], j, RN, REG_SP);
3773                                         N_ST(rd->argintregs[GET_LOW_REG(s1)], j + 4, RN, REG_SP);
3774                                 } else {
3775                                         N_ST(rd->argintregs[s1], j, RN, REG_SP);
3776                                 }
3777                         } else {
3778                                 if (IS_2_WORD_TYPE(t)) {
3779                                         N_STD(rd->argfltregs[s1], j, RN, REG_SP);
3780                                 } else {
3781                                         N_STE(rd->argfltregs[s1], j, RN, REG_SP);
3782                                 }
3783                         }
3784
3785                         j += 8;
3786                 }
3787         }
3788
3789         N_ST(REG_ITMP1, j, RN, REG_SP);
3790
3791         /* create dynamic stack info */
3792
3793         N_LAE(REG_A0, (cd->stackframesize - 1) * 4, RN, REG_SP); /* datasp */
3794         N_LR(REG_A1, REG_PV); /* pv */
3795         N_LAE(REG_A2, cd->stackframesize * 4, RN, REG_SP); /* old SP */
3796         N_L(REG_A3, (cd->stackframesize - 1) * 4, RN, REG_SP); /* return address */
3797
3798         disp = dseg_add_functionptr(cd, codegen_start_native_call);
3799         M_ILD(REG_ITMP1, REG_PV, disp);
3800
3801         M_CALL(REG_ITMP1); /* call */
3802
3803         /* restore integer and float argument registers */
3804
3805         j = 96 + (nmd->memuse * 4);
3806
3807         for (i = 0; i < md->paramcount; i++) {
3808                 if (! md->params[i].inmemory) {
3809                         s1 = md->params[i].regoff;
3810
3811                         if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
3812                                 if (IS_2_WORD_TYPE(t)) {
3813                                         /* todo load multiple ! */
3814                                         N_L(rd->argintregs[GET_HIGH_REG(s1)], j, RN, REG_SP);
3815                                         N_L(rd->argintregs[GET_LOW_REG(s1)], j + 4, RN, REG_SP);
3816                                 } else {
3817                                         N_L(rd->argintregs[s1], j, RN, REG_SP);
3818                                 }
3819                         } else {
3820                                 if (IS_2_WORD_TYPE(t)) {
3821                                         N_LD(rd->argfltregs[s1], j, RN, REG_SP);
3822                                 } else {
3823                                         N_LE(rd->argfltregs[s1], j, RN, REG_SP);
3824                                 }
3825                         }
3826
3827                         j += 8;
3828                 }
3829         }
3830
3831         N_L(REG_ITMP1, j, RN, REG_SP);
3832
3833         /* copy or spill arguments to new locations */
3834
3835         for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3836                 t = md->paramtypes[i].type;
3837
3838                 if (IS_INT_LNG_TYPE(t)) {
3839
3840                         if (!md->params[i].inmemory) {
3841
3842                                 s1 = rd->argintregs[md->params[i].regoff];
3843
3844                                 if (!nmd->params[j].inmemory) {
3845                                         s2 = rd->argintregs[nmd->params[j].regoff];
3846                                         if (IS_2_WORD_TYPE(t)) {
3847                                                 N_LR(GET_HIGH_REG(s2), GET_HIGH_REG(s1));
3848                                                 N_LR(GET_LOW_REG(s2), GET_LOW_REG(s1));
3849                                         } else {
3850                                                 N_LR(s2, s1);
3851                                         }
3852                                 } else {
3853                                         s2 = nmd->params[j].regoff;
3854                                         if (IS_2_WORD_TYPE(t)) {
3855                                                 N_LM(GET_LOW_REG(s1), GET_HIGH_REG(s1), 96 + (s2 * 4), REG_SP);
3856                                         } else {
3857                                                 N_L(s1, 96 + (s2 * 4), RN, REG_SP);
3858                                         }
3859                                 }
3860
3861                         } else {
3862                                 s1 = md->params[i].regoff + cd->stackframesize + 1;   /* + 1 (RA) */
3863                                 s2 = nmd->params[j].regoff;
3864                                 
3865                                 if (IS_2_WORD_TYPE(t)) {
3866                                         N_MVC(96 + (s2 * 4), 8, REG_SP, s1, REG_SP);
3867                                 } else {
3868                                         N_MVC(96 + (s2 * 4), 4, REG_SP, s1, REG_SP);
3869                                 }
3870                         }
3871
3872                 } else {
3873                         /* We only copy spilled float arguments, as the float argument    */
3874                         /* registers keep unchanged.                                      */
3875
3876                         if (md->params[i].inmemory) {
3877                                 s1 = md->params[i].regoff + cd->stackframesize + 1;   /* + 1 (RA) */
3878                                 s2 = nmd->params[j].regoff;
3879
3880                                 if (IS_2_WORD_TYPE(t)) {
3881                                         N_MVC(96 + (s2 * 4), 8, REG_SP, s1, REG_SP);
3882                                 } else {
3883                                         N_MVC(96 + (s2 * 4), 4, REG_SP, s1, REG_SP);
3884                                 }
3885                         }
3886                 }
3887         }
3888
3889         /* put class into second argument register */
3890
3891         if (m->flags & ACC_STATIC) {
3892                 disp = dseg_add_address(cd, m->class);
3893                 M_ILD(REG_A1, REG_PV, disp);
3894         }
3895
3896         /* put env into first argument register */
3897
3898         disp = dseg_add_address(cd, _Jv_env);
3899         M_ILD(REG_A0, REG_PV, disp);
3900
3901         /* do the native function call */
3902
3903         M_CALL(REG_ITMP1); /* call */
3904
3905         /* save return value */
3906
3907         t = md->returntype.type;
3908
3909         if (t != TYPE_VOID) {
3910                 if (IS_INT_LNG_TYPE(t)) {
3911                         if (IS_2_WORD_TYPE(t)) {
3912                                 N_STM(REG_RESULT, REG_RESULT2, 96, REG_SP);
3913                         } else {
3914                                 N_ST(REG_RESULT, 96, RN, REG_SP);
3915                         }
3916                 } else {
3917                         if (IS_2_WORD_TYPE(t)) {
3918                                 N_STD(REG_FRESULT, 96, RN, REG_SP);
3919                         } else {
3920                                 N_STE(REG_FRESULT, 96, RN, REG_SP);
3921                         }
3922                 }
3923         }
3924
3925 #if 0
3926 #if !defined(NDEBUG)
3927         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3928                 emit_verbosecall_exit(jd);
3929 #endif
3930 #endif
3931
3932         /* remove native stackframe info */
3933
3934         N_LAE(REG_A0, (cd->stackframesize - 1) * 4, RN, REG_SP); /* datasp */
3935         disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3936         M_ILD(REG_ITMP1, REG_PV, disp);
3937         M_CALL(REG_ITMP1);
3938         N_LR(REG_ITMP3, REG_RESULT);
3939
3940         /* restore return value */
3941
3942         if (t != TYPE_VOID) {
3943                 if (IS_INT_LNG_TYPE(t)) {
3944                         if (IS_2_WORD_TYPE(t)) {
3945                                 N_LM(REG_RESULT, REG_RESULT2, 96, REG_SP);
3946                         } else {
3947                                 N_L(REG_RESULT, 96, RN, REG_SP);
3948                         }
3949                 } else {
3950                         if (IS_2_WORD_TYPE(t)) {
3951                                 N_LD(REG_FRESULT, 96, RN, REG_SP);
3952                         } else {
3953                                 N_LE(REG_FRESULT, 96, RN, REG_SP);
3954                         }
3955                 }
3956         }
3957
3958         /* load return address */
3959         
3960         N_L(REG_ITMP2, (cd->stackframesize - 1) * 4, RN, REG_SP);
3961
3962         /* remove stackframe */
3963
3964         N_AHI(REG_SP, cd->stackframesize * 4);
3965
3966         /* test for exception */
3967
3968         N_LTR(REG_ITMP3, REG_ITMP3);
3969         N_BRC(DD_NE, SZ_BRC + SZ_BCR);
3970
3971         /* return */
3972
3973         N_BCR(DD_ANY, REG_ITMP2); 
3974
3975         /* handle exception */
3976
3977         N_LONG_0();
3978
3979 #if 0
3980         M_MOV(REG_ITMP3, REG_ITMP1_XPTR);
3981         M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);     /* get return address from stack */
3982         M_ASUB_IMM(3, REG_ITMP2_XPC);                                    /* callq */
3983
3984         M_MOV_IMM(asm_handle_nat_exception, REG_ITMP3);
3985         M_JMP(REG_ITMP3);
3986
3987 #endif
3988         /* generate patcher stubs */
3989
3990         emit_patcher_stubs(jd);
3991
3992         codegen_finish(jd);
3993
3994         return code->entrypoint;
3995         return NULL;
3996 }
3997
3998
3999
4000 /*
4001  * These are local overrides for various environment variables in Emacs.
4002  * Please do not remove this and leave it at the end of the file, where
4003  * Emacs will automagically detect them.
4004  * ---------------------------------------------------------------------
4005  * Local variables:
4006  * mode: c
4007  * indent-tabs-mode: t
4008  * c-basic-offset: 4
4009  * tab-width: 4
4010  * End:
4011  * vim:noexpandtab:sw=4:ts=4:
4012  */