57bc1f2004de726abd36cb6a1256912d0ee83853
[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 7300 2007-02-07 22:06:53Z 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 "vm/loader.h"
62 #include "vm/options.h"
63 #include "vm/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
77 #if defined(ENABLE_LSRA)
78 # include "vm/jit/allocator/lsra.h"
79 #endif
80
81 #define OOPS() assert(0);
82
83 #if 0
84 u1 *createcompilerstub(methodinfo *m) {
85         OOPS();
86         u1 *stub = malloc(8);
87         bzero(stub, 8);
88         return stub;
89 }
90 #endif
91
92 #if 0
93 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd) {
94         OOPS();
95         return createcompilerstub(NULL);
96 }
97 #endif
98
99
100
101 /* codegen *********************************************************************
102
103    Generates machine code.
104
105 *******************************************************************************/
106
107
108 bool codegen(jitdata *jd)
109 {
110         methodinfo         *m;
111         codeinfo           *code;
112         codegendata        *cd;
113         registerdata       *rd;
114         s4                  len, s1, s2, s3, d, disp;
115         u2                  currentline;
116         ptrint              a;
117         varinfo            *var, *var1, *var2, *dst;
118         basicblock         *bptr;
119         instruction        *iptr;
120         exception_entry    *ex;
121         constant_classref  *cr;
122         unresolved_class   *uc;
123         methodinfo         *lm;             /* local methodinfo for ICMD_INVOKE*  */
124         unresolved_method  *um;
125         builtintable_entry *bte;
126         methoddesc         *md;
127         fieldinfo          *fi;
128         unresolved_field   *uf;
129         s4                  fieldtype;
130 #if 0
131         rplpoint           *replacementpoint;
132 #endif
133         s4                 varindex;
134
135         /* get required compiler data */
136
137         m    = jd->m;
138         code = jd->code;
139         cd   = jd->cd;
140         rd   = jd->rd;
141
142         /* prevent compiler warnings */
143
144         d   = 0;
145         lm  = NULL;
146         um  = NULL;
147         bte = NULL;
148
149         {
150         s4 i, p, t, l;
151         s4 savedregs_num;
152
153         savedregs_num = 1; /* space to save RA */
154
155         /* space to save used callee saved registers */
156
157         savedregs_num += (INT_SAV_CNT - rd->savintreguse);
158         savedregs_num += (FLT_SAV_CNT - rd->savfltreguse) * 2;
159
160         cd->stackframesize = rd->memuse + savedregs_num;
161
162         /* CAUTION:
163          * As REG_ITMP3 == REG_RA, do not touch REG_ITMP3, until it has been saved.
164          */
165
166 #if defined(ENABLE_THREADS)
167         /* space to save argument of monitor_enter */
168         OOPS(); /* see powerpc  */
169 #if 0
170         if (checksync && (m->flags & ACC_SYNCHRONIZED))
171                 cd->stackframesize++;
172 #endif
173 #endif
174
175         /* Keep stack of non-leaf functions 16-byte aligned for calls into
176            native code e.g. libc or jni (alignment problems with
177            movaps). */
178
179         if (!jd->isleafmethod || opt_verbosecall)
180                 /* TODO really 16 bytes ? */
181                 cd->stackframesize = (cd->stackframesize + 3) & ~3;
182
183         /* create method header */
184
185         (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
186         (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize       */
187
188 #if defined(ENABLE_THREADS)
189         /* IsSync contains the offset relative to the stack pointer for the
190            argument of monitor_exit used in the exception handler. Since the
191            offset could be zero and give a wrong meaning of the flag it is
192            offset by one.
193         */
194
195         if (checksync && (m->flags & ACC_SYNCHRONIZED))
196                 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 4); /* IsSync        */
197         else
198 #endif
199                 (void) dseg_add_unique_s4(cd, 0);                  /* IsSync          */
200                                                
201         (void) dseg_add_unique_s4(cd, jd->isleafmethod);               /* IsLeaf  */
202         (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
203         (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
204
205         (void) dseg_addlinenumbertablesize(cd);
206
207         (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize   */
208
209         /* create exception table */
210
211         for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
212                 dseg_add_target(cd, ex->start);
213                 dseg_add_target(cd, ex->end);
214                 dseg_add_target(cd, ex->handler);
215                 (void) dseg_add_unique_address(cd, ex->catchtype.any);
216         }
217         
218         /* generate method profiling code */
219
220         if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
221                 /* count frequency */
222
223                 M_ALD(REG_ITMP1, REG_PV, CodeinfoPointer);
224                 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(codeinfo, frequency));
225                 M_IADD_IMM(1, REG_ITMP2);
226                 M_IST(REG_ITMP2, REG_ITMP1, OFFSET(codeinfo, frequency));
227
228 /*              PROFILE_CYCLE_START; */
229         }
230
231         /* create stack frame (if necessary) */
232
233         if (cd->stackframesize)
234                 M_ASUB_IMM(cd->stackframesize * 4, REG_SP);
235
236         /* save used callee saved registers and return address */
237
238         p = cd->stackframesize;
239         p--; M_AST(REG_RA, REG_SP, p * 4);
240         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
241                 p--; M_IST(rd->savintregs[i], REG_SP, p * 4);
242         }
243         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
244                 p -= 2; M_DST(rd->savfltregs[i], REG_SP, p * 4);
245         }
246
247         /* take arguments out of register or stack frame */
248
249         md = m->parseddesc;
250
251         for (p = 0, l = 0; p < md->paramcount; p++) {
252                 t = md->paramtypes[p].type;
253                 varindex = jd->local_map[l * 5 + t];
254
255                 l++;
256                 if (IS_2_WORD_TYPE(t))    /* increment local counter for 2 word types */
257                         l++;
258
259                 if (varindex == UNUSED)
260                         continue;
261
262                 var = VAR(varindex);
263
264                 s1 = md->params[p].regoff;
265                 if (IS_INT_LNG_TYPE(t)) {                    /* integer args          */
266                         if (IS_2_WORD_TYPE(t))
267                                 s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
268                                                            rd->argintregs[GET_HIGH_REG(s1)]);
269                         else
270                                 s2 = rd->argintregs[s1];
271                         if (!md->params[p].inmemory) {           /* register arguments    */
272                                 if (!IS_INMEMORY(var->flags)) {      /* reg arg -> register   */
273                                         if (IS_2_WORD_TYPE(t))
274                                                 M_LNGMOVE(s2, var->vv.regoff);
275                                         else
276                                                 M_INTMOVE(s2, var->vv.regoff);
277
278                                 } else {                             /* reg arg -> spilled    */
279                                         if (IS_2_WORD_TYPE(t))
280                                                 M_LST(s2, REG_SP, var->vv.regoff * 4);
281                                         else
282                                                 M_IST(s2, REG_SP, var->vv.regoff * 4);
283                                 }
284
285                         } else {                                 /* stack arguments       */
286                                 if (!IS_INMEMORY(var->flags)) {      /* stack arg -> register */
287                                         if (IS_2_WORD_TYPE(t))
288                                                 M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 4);
289                                         else
290                                                 M_ILD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 4);
291
292                                 } else {                             /* stack arg -> spilled  */
293                                         M_ILD(REG_ITMP1, REG_SP, (cd->stackframesize + s1) * 4);
294                                         M_IST(REG_ITMP1, REG_SP, var->vv.regoff * 4);
295                                         if (IS_2_WORD_TYPE(t)) {
296                                                 M_ILD(REG_ITMP1, REG_SP, (cd->stackframesize + s1) * 4 +4);
297                                                 M_IST(REG_ITMP1, REG_SP, var->vv.regoff * 4 + 4);
298                                         }
299                                 }
300                         }
301
302                 } else {                                     /* floating args         */
303                         if (!md->params[p].inmemory) {           /* register arguments    */
304                                 s2 = rd->argfltregs[s1];
305                                 if (!IS_INMEMORY(var->flags)) {      /* reg arg -> register   */
306                                         M_FLTMOVE(s2, var->vv.regoff);
307
308                                 } else {                                         /* reg arg -> spilled    */
309                                         if (IS_2_WORD_TYPE(t))
310                                                 M_DST(s2, REG_SP, var->vv.regoff * 4);
311                                         else
312                                                 M_FST(s2, REG_SP, var->vv.regoff * 4);
313                                 }
314
315                         } else {                                 /* stack arguments       */
316                                 if (!IS_INMEMORY(var->flags)) {      /* stack-arg -> register */
317                                         if (IS_2_WORD_TYPE(t))
318                                                 M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 4);
319
320                                         else
321                                                 M_FLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 4);
322
323                                 } else {                             /* stack-arg -> spilled  */
324                                         if (IS_2_WORD_TYPE(t)) {
325                                                 M_DLD(REG_FTMP1, REG_SP, (cd->stackframesize + s1) * 4);
326                                                 M_DST(REG_FTMP1, REG_SP, var->vv.regoff * 4);
327                                                 var->vv.regoff = cd->stackframesize + s1;
328
329                                         } else {
330                                                 M_FLD(REG_FTMP1, REG_SP, (cd->stackframesize + s1) * 4);
331                                                 M_FST(REG_FTMP1, REG_SP, var->vv.regoff * 4);
332                                         }
333                                 }
334                         }
335                 }
336         } /* end for */
337
338         /* save monitorenter argument */
339
340 #if defined(ENABLE_THREADS)
341         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
342                 /* stack offset for monitor argument */
343
344                 s1 = rd->memuse;
345
346                 if (opt_verbosecall) {
347                         M_LSUB_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
348
349                         for (p = 0; p < INT_ARG_CNT; p++)
350                                 M_LST(rd->argintregs[p], REG_SP, p * 8);
351
352                         for (p = 0; p < FLT_ARG_CNT; p++)
353                                 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
354
355                         s1 += INT_ARG_CNT + FLT_ARG_CNT;
356                 }
357
358                 /* decide which monitor enter function to call */
359
360                 if (m->flags & ACC_STATIC) {
361                         M_MOV_IMM(&m->class->object.header, REG_A0);
362                 }
363                 else {
364                         M_TEST(REG_A0);
365                         M_BEQ(0);
366                         codegen_add_nullpointerexception_ref(cd);
367                 }
368
369                 M_AST(REG_A0, REG_SP, s1 * 8);
370                 M_MOV_IMM(LOCK_monitor_enter, REG_ITMP1);
371                 M_CALL(REG_ITMP1);
372
373                 if (opt_verbosecall) {
374                         for (p = 0; p < INT_ARG_CNT; p++)
375                                 M_LLD(rd->argintregs[p], REG_SP, p * 8);
376
377                         for (p = 0; p < FLT_ARG_CNT; p++)
378                                 M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
379
380                         M_LADD_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
381                 }
382         }
383 #endif
384
385 #if !defined(NDEBUG)
386         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
387                 emit_verbosecall_enter(jd);
388 #endif /* !defined(NDEBUG) */
389
390         }
391
392         /* end of header generation */
393 #if 0
394         replacementpoint = jd->code->rplpoints;
395 #endif
396
397         /* walk through all basic blocks */
398
399         for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
400
401                 bptr->mpc = (u4) ((u1 *) cd->mcodeptr - cd->mcodebase);
402
403                 if (bptr->flags >= BBREACHED) {
404
405                 /* branch resolving */
406
407                 codegen_resolve_branchrefs(cd, bptr);
408
409                 /* handle replacement points */
410
411 #if 0
412                 if (bptr->bitflags & BBFLAG_REPLACEMENT) {
413                         replacementpoint->pc = (u1*)(ptrint)bptr->mpc; /* will be resolved later */
414                         
415                         replacementpoint++;
416
417                         assert(cd->lastmcodeptr <= cd->mcodeptr);
418                         cd->lastmcodeptr = cd->mcodeptr + 5; /* 5 byte jmp patch */
419                 }
420 #endif
421
422                 /* copy interface registers to their destination */
423
424                 len = bptr->indepth;
425                 MCODECHECK(512);
426
427                 /* generate basicblock profiling code */
428
429                 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
430                         /* count frequency */
431
432                         M_MOV_IMM(code->bbfrequency, REG_ITMP3);
433                         M_IINC_MEMBASE(REG_ITMP3, bptr->nr * 4);
434
435                         /* if this is an exception handler, start profiling again */
436
437                         if (bptr->type == BBTYPE_EXH)
438                                 PROFILE_CYCLE_START;
439                 }
440
441 #if defined(ENABLE_LSRA)
442                 if (opt_lsra) {
443                         while (len) {
444                                 len--;
445                                 src = bptr->invars[len];
446                                 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
447                                         if (bptr->type == BBTYPE_EXH) {
448 /*                                      d = reg_of_var(rd, src, REG_ITMP1); */
449                                                 if (!IS_INMEMORY(src->flags))
450                                                         d= src->vv.regoff;
451                                                 else
452                                                         d=REG_ITMP1;
453                                                 M_INTMOVE(REG_ITMP1, d);
454                                                 emit_store(jd, NULL, src, d);
455                                         }
456                                 }
457                         }
458                         
459                 } else {
460 #endif
461
462                 while (len) {
463                         len--;
464                         var = VAR(bptr->invars[len]);
465                         if ((len ==  bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
466                                 if (bptr->type == BBTYPE_EXH) {
467                                         d = codegen_reg_of_var(0, var, REG_ITMP1);
468                                         M_INTMOVE(REG_ITMP1, d);
469                                         emit_store(jd, NULL, var, d);
470                                 }
471                         } 
472                         else {
473                                 assert((var->flags & INOUT));
474                         }
475                 }
476 #if defined(ENABLE_LSRA)
477                 }
478 #endif
479                 /* walk through all instructions */
480                 
481                 len = bptr->icount;
482                 currentline = 0;
483
484                 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
485                         if (iptr->line != currentline) {
486                                 dseg_addlinenumber(cd, iptr->line);
487                                 currentline = iptr->line;
488                         }
489
490                         MCODECHECK(1024);                         /* 1KB should be enough */
491
492                 switch (iptr->opc) {
493                 case ICMD_NOP:        /* ...  ==> ...                                 */
494                 case ICMD_POP:        /* ..., value  ==> ...                          */
495                 case ICMD_POP2:       /* ..., value, value  ==> ...                   */
496                 case ICMD_INLINE_START: /* internal ICMDs                         */
497                 case ICMD_INLINE_END:
498                         break;
499
500                 case ICMD_CHECKNULL:  /* ..., objectref  ==> ..., objectref           */
501                         OOPS();
502 #if 0
503                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
504                         M_TEST(s1);
505                         M_BEQ(0);
506                         codegen_add_nullpointerexception_ref(cd);
507 #endif
508                         break;
509
510                 /* constant operations ************************************************/
511
512                 case ICMD_ICONST:     /* ...  ==> ..., constant                       */
513                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
514                         ICONST(d, iptr->sx.val.i);
515                         emit_store_dst(jd, iptr, d);
516                         break;
517
518                 case ICMD_LCONST:     /* ...  ==> ..., constant                       */
519                         OOPS();
520 #if 0
521                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
522                         LCONST(d, iptr->sx.val.l);
523                         emit_store_dst(jd, iptr, d);
524 #endif
525                         break;
526
527                 case ICMD_FCONST:     /* ...  ==> ..., constant                       */
528                         OOPS();
529 #if 0
530                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
531                         disp = dseg_add_float(cd, iptr->sx.val.f);
532                         emit_movdl_membase_reg(cd, RIP, -((cd->mcodeptr + ((d > 7) ? 9 : 8)) - cd->mcodebase) + disp, d);
533                         emit_store_dst(jd, iptr, d);
534 #endif
535                         break;
536                 
537                 case ICMD_DCONST:     /* ...  ==> ..., constant                       */
538                         OOPS();
539 #if 0
540                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
541                         disp = dseg_add_double(cd, iptr->sx.val.d);
542                         emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, d);
543                         emit_store_dst(jd, iptr, d);
544 #endif
545                         break;
546
547                 case ICMD_ACONST:     /* ...  ==> ..., constant                       */
548                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
549
550                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
551                                 cr = iptr->sx.val.c.ref;
552                                 disp = dseg_add_unique_address(cd, NULL);
553
554 /*                              PROFILE_CYCLE_STOP; */
555
556                                 codegen_add_patch_ref(cd, PATCHER_aconst, cr, disp);
557
558 /*                              PROFILE_CYCLE_START; */
559
560                                 M_ALD(d, REG_PV, disp);
561                         } else {
562                                 if (iptr->sx.val.anyptr == 0) {
563                                         M_CLR(d);
564                                 } else {
565                                         disp = dseg_add_unique_address(cd, iptr->sx.val.anyptr);
566                                         M_ALD(d, REG_PV, disp);
567                                 }
568                         }
569                         emit_store_dst(jd, iptr, d);
570                         break;
571
572
573                 /* load/store/copy/move operations ************************************/
574
575                 case ICMD_ILOAD:      /* ...  ==> ..., content of local variable      */
576                 case ICMD_ALOAD:      /* s1 = local variable                          */
577                 case ICMD_LLOAD:
578                 case ICMD_FLOAD:  
579                 case ICMD_DLOAD:  
580                 case ICMD_ISTORE:     /* ..., value  ==> ...                          */
581                 case ICMD_LSTORE:
582                 case ICMD_FSTORE:
583                 case ICMD_DSTORE: 
584                 case ICMD_COPY:
585                 case ICMD_MOVE:
586                         emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
587                         break;
588
589                 case ICMD_ASTORE:
590                         if (!(iptr->flags.bits & INS_FLAG_RETADDR))
591                                 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
592                         break;
593
594                 /* integer operations *************************************************/
595
596                 case ICMD_INEG:       /* ..., value  ==> ..., - value                 */
597                         OOPS();
598 #if 0
599                         s1 = emit_load_s1(jd, iptr, REG_ITMP1); 
600                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
601                         M_INTMOVE(s1, d);
602                         M_INEG(d);
603                         emit_store_dst(jd, iptr, d);
604 #endif
605                         break;
606
607                 case ICMD_LNEG:       /* ..., value  ==> ..., - value                 */
608                         OOPS();
609 #if 0
610                         s1 = emit_load_s1(jd, iptr, REG_ITMP1); 
611                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
612                         M_INTMOVE(s1, d);
613                         M_LNEG(d);
614                         emit_store_dst(jd, iptr, d);
615 #endif
616                         break;
617
618                 case ICMD_I2L:        /* ..., value  ==> ..., value                   */
619                         OOPS();
620 #if 0
621                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
622                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
623                         M_ISEXT(s1, d);
624                         emit_store_dst(jd, iptr, d);
625 #endif
626                         break;
627
628                 case ICMD_L2I:        /* ..., value  ==> ..., value                   */
629                         OOPS();
630 #if 0
631                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
632                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
633                         M_IMOV(s1, d);
634                         emit_store_dst(jd, iptr, d);
635 #endif
636                         break;
637
638                 case ICMD_INT2BYTE:   /* ..., value  ==> ..., value                   */
639                         OOPS();
640 #if 0
641                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
642                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
643                         M_BSEXT(s1, d);
644                         emit_store_dst(jd, iptr, d);
645 #endif
646                         break;
647
648                 case ICMD_INT2CHAR:   /* ..., value  ==> ..., value                   */
649                         OOPS();
650 #if 0
651                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
652                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
653                         M_CZEXT(s1, d);
654                         emit_store_dst(jd, iptr, d);
655 #endif
656                         break;
657
658                 case ICMD_INT2SHORT:  /* ..., value  ==> ..., value                   */
659                         OOPS();
660 #if 0
661                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
662                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
663                         M_SSEXT(s1, d);
664                         emit_store_dst(jd, iptr, d);
665 #endif
666                         break;
667
668
669                 case ICMD_IADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
670                         OOPS();
671 #if 0
672                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
673                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
674                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
675                         if (s2 == d)
676                                 M_IADD(s1, d);
677                         else {
678                                 M_INTMOVE(s1, d);
679                                 M_IADD(s2, d);
680                         }
681                         emit_store_dst(jd, iptr, d);
682 #endif
683                         break;
684
685                 case ICMD_IINC:
686                 case ICMD_IADDCONST:  /* ..., value  ==> ..., value + constant        */
687                                       /* sx.val.i = constant                             */
688                         OOPS();
689 #if 0
690                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
691                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
692
693                         /* Using inc and dec is not faster than add (tested with
694                            sieve). */
695
696                         M_INTMOVE(s1, d);
697                         M_IADD_IMM(iptr->sx.val.i, d);
698                         emit_store_dst(jd, iptr, d);
699 #endif
700                         break;
701
702                 case ICMD_LADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
703                         OOPS();
704 #if 0
705                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
706                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
707                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
708                         if (s2 == d)
709                                 M_LADD(s1, d);
710                         else {
711                                 M_INTMOVE(s1, d);
712                                 M_LADD(s2, d);
713                         }
714                         emit_store_dst(jd, iptr, d);
715 #endif
716                         break;
717
718                 case ICMD_LADDCONST:  /* ..., value  ==> ..., value + constant        */
719                                       /* sx.val.l = constant                             */
720                         OOPS();
721 #if 0
722                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
723                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
724                         M_INTMOVE(s1, d);
725                         if (IS_IMM32(iptr->sx.val.l))
726                                 M_LADD_IMM(iptr->sx.val.l, d);
727                         else {
728                                 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
729                                 M_LADD(REG_ITMP2, d);
730                         }
731                         emit_store_dst(jd, iptr, d);
732 #endif
733                         break;
734
735                 case ICMD_ISUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
736                         OOPS();
737 #if 0
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 #endif
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                         OOPS();
1538 #if 0
1539                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1540                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1541                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1542                         if (s2 == d)
1543                                 M_FMUL(s1, d);
1544                         else {
1545                                 M_FLTMOVE(s1, d);
1546                                 M_FMUL(s2, d);
1547                         }
1548                         emit_store_dst(jd, iptr, d);
1549 #endif
1550                         break;
1551
1552                 case ICMD_DMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
1553                         OOPS();
1554 #if 0
1555                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1556                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1557                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1558                         if (s2 == d)
1559                                 M_DMUL(s1, d);
1560                         else {
1561                                 M_FLTMOVE(s1, d);
1562                                 M_DMUL(s2, d);
1563                         }
1564                         emit_store_dst(jd, iptr, d);
1565 #endif
1566                         break;
1567
1568                 case ICMD_FDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1569                         OOPS();
1570 #if 0
1571                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1572                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1573                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1574                         if (s2 == d) {
1575                                 M_FLTMOVE(s2, REG_FTMP2);
1576                                 s2 = REG_FTMP2;
1577                         }
1578                         M_FLTMOVE(s1, d);
1579                         M_FDIV(s2, d);
1580                         emit_store_dst(jd, iptr, d);
1581 #endif
1582                         break;
1583
1584                 case ICMD_DDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1585                         OOPS();
1586 #if 0
1587                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1588                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1589                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1590                         if (s2 == d) {
1591                                 M_FLTMOVE(s2, REG_FTMP2);
1592                                 s2 = REG_FTMP2;
1593                         }
1594                         M_FLTMOVE(s1, d);
1595                         M_DDIV(s2, d);
1596                         emit_store_dst(jd, iptr, d);
1597 #endif
1598                         break;
1599
1600                 case ICMD_I2F:       /* ..., value  ==> ..., (float) value            */
1601                         OOPS();
1602 #if 0
1603                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1604                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1605                         M_CVTIF(s1, d);
1606                         emit_store_dst(jd, iptr, d);
1607 #endif
1608                         break;
1609
1610                 case ICMD_I2D:       /* ..., value  ==> ..., (double) value           */
1611                         OOPS();
1612 #if 0
1613                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1614                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1615                         M_CVTID(s1, d);
1616                         emit_store_dst(jd, iptr, d);
1617 #endif
1618                         break;
1619
1620                 case ICMD_L2F:       /* ..., value  ==> ..., (float) value            */
1621                         OOPS();
1622 #if 0
1623                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1624                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1625                         M_CVTLF(s1, d);
1626                         emit_store_dst(jd, iptr, d);
1627 #endif
1628                         break;
1629                         
1630                 case ICMD_L2D:       /* ..., value  ==> ..., (double) value           */
1631                         OOPS();
1632 #if 0
1633                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1634                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1635                         M_CVTLD(s1, d);
1636                         emit_store_dst(jd, iptr, d);
1637 #endif
1638                         break;
1639                         
1640                 case ICMD_F2I:       /* ..., 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_CVTFI(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_f2i, 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_D2I:       /* ..., value  ==> ..., (int) 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_CVTDI(s1, d);
1664                         M_ICMP_IMM(0x80000000, d);                        /* corner cases */
1665                         disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1666                                 ((REG_RESULT == d) ? 0 : 3);
1667                         M_BNE(disp);
1668                         M_FLTMOVE(s1, REG_FTMP1);
1669                         M_MOV_IMM(asm_builtin_d2i, REG_ITMP2);
1670                         M_CALL(REG_ITMP2);
1671                         M_INTMOVE(REG_RESULT, d);
1672                         emit_store_dst(jd, iptr, d);
1673 #endif
1674                         break;
1675
1676                 case ICMD_F2L:       /* ..., value  ==> ..., (long) value             */
1677                         OOPS();
1678 #if 0
1679                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1680                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1681                         M_CVTFL(s1, d);
1682                         M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1683                         M_LCMP(REG_ITMP2, d);                             /* corner cases */
1684                         disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1685                                 ((REG_RESULT == d) ? 0 : 3);
1686                         M_BNE(disp);
1687                         M_FLTMOVE(s1, REG_FTMP1);
1688                         M_MOV_IMM(asm_builtin_f2l, REG_ITMP2);
1689                         M_CALL(REG_ITMP2);
1690                         M_INTMOVE(REG_RESULT, d);
1691                         emit_store_dst(jd, iptr, d);
1692 #endif
1693                         break;
1694
1695                 case ICMD_D2L:       /* ..., value  ==> ..., (long) value             */
1696                         OOPS();
1697 #if 0
1698                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1699                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1700                         M_CVTDL(s1, d);
1701                         M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1702                         M_LCMP(REG_ITMP2, d);                             /* corner cases */
1703                         disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1704                                 ((REG_RESULT == d) ? 0 : 3);
1705                         M_BNE(disp);
1706                         M_FLTMOVE(s1, REG_FTMP1);
1707                         M_MOV_IMM(asm_builtin_d2l, REG_ITMP2);
1708                         M_CALL(REG_ITMP2);
1709                         M_INTMOVE(REG_RESULT, d);
1710                         emit_store_dst(jd, iptr, d);
1711 #endif
1712                         break;
1713
1714                 case ICMD_F2D:       /* ..., value  ==> ..., (double) value           */
1715                         OOPS();
1716 #if 0
1717                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1718                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1719                         M_CVTFD(s1, d);
1720                         emit_store_dst(jd, iptr, d);
1721 #endif
1722                         break;
1723
1724                 case ICMD_D2F:       /* ..., value  ==> ..., (float) value            */
1725                         OOPS();
1726 #if 0
1727                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1728                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1729                         M_CVTDF(s1, d);
1730                         emit_store_dst(jd, iptr, d);
1731 #endif
1732                         break;
1733
1734                 case ICMD_FCMPL:      /* ..., val1, val2  ==> ..., val1 fcmpl val2    */
1735                                           /* == => 0, < => 1, > => -1 */
1736                         OOPS();
1737 #if 0
1738                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1739                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1740                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1741                         M_CLR(d);
1742                         M_MOV_IMM(1, REG_ITMP1);
1743                         M_MOV_IMM(-1, REG_ITMP2);
1744                         emit_ucomiss_reg_reg(cd, s1, s2);
1745                         M_CMOVB(REG_ITMP1, d);
1746                         M_CMOVA(REG_ITMP2, d);
1747                         M_CMOVP(REG_ITMP2, d);                   /* treat unordered as GT */
1748                         emit_store_dst(jd, iptr, d);
1749 #endif
1750                         break;
1751
1752                 case ICMD_FCMPG:      /* ..., val1, val2  ==> ..., val1 fcmpg val2    */
1753                                           /* == => 0, < => 1, > => -1 */
1754                         OOPS();
1755 #if 0
1756                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1757                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1758                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1759                         M_CLR(d);
1760                         M_MOV_IMM(1, REG_ITMP1);
1761                         M_MOV_IMM(-1, REG_ITMP2);
1762                         emit_ucomiss_reg_reg(cd, s1, s2);
1763                         M_CMOVB(REG_ITMP1, d);
1764                         M_CMOVA(REG_ITMP2, d);
1765                         M_CMOVP(REG_ITMP1, d);                   /* treat unordered as LT */
1766                         emit_store_dst(jd, iptr, d);
1767 #endif
1768                         break;
1769
1770                 case ICMD_DCMPL:      /* ..., val1, val2  ==> ..., val1 fcmpl val2    */
1771                                           /* == => 0, < => 1, > => -1 */
1772                         OOPS();
1773 #if 0
1774                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1775                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1776                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1777                         M_CLR(d);
1778                         M_MOV_IMM(1, REG_ITMP1);
1779                         M_MOV_IMM(-1, REG_ITMP2);
1780                         emit_ucomisd_reg_reg(cd, s1, s2);
1781                         M_CMOVB(REG_ITMP1, d);
1782                         M_CMOVA(REG_ITMP2, d);
1783                         M_CMOVP(REG_ITMP2, d);                   /* treat unordered as GT */
1784                         emit_store_dst(jd, iptr, d);
1785 #endif
1786                         break;
1787
1788                 case ICMD_DCMPG:      /* ..., val1, val2  ==> ..., val1 fcmpg val2    */
1789                                           /* == => 0, < => 1, > => -1 */
1790                         OOPS();
1791 #if 0
1792                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1793                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1794                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1795                         M_CLR(d);
1796                         M_MOV_IMM(1, REG_ITMP1);
1797                         M_MOV_IMM(-1, REG_ITMP2);
1798                         emit_ucomisd_reg_reg(cd, s1, s2);
1799                         M_CMOVB(REG_ITMP1, d);
1800                         M_CMOVA(REG_ITMP2, d);
1801                         M_CMOVP(REG_ITMP1, d);                   /* treat unordered as LT */
1802                         emit_store_dst(jd, iptr, d);
1803 #endif
1804                         break;
1805
1806
1807                 /* memory operations **************************************************/
1808
1809                 case ICMD_ARRAYLENGTH: /* ..., arrayref  ==> ..., (int) length        */
1810                         OOPS();
1811 #if 0
1812                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1813                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1814                         gen_nullptr_check(s1);
1815                         M_ILD(d, s1, OFFSET(java_arrayheader, size));
1816                         emit_store_dst(jd, iptr, d);
1817 #endif
1818                         break;
1819
1820                 case ICMD_BALOAD:     /* ..., arrayref, index  ==> ..., value         */
1821                         OOPS();
1822 #if 0
1823                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1824                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1825                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1826                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1827                                 gen_nullptr_check(s1);
1828                                 gen_bound_check;
1829                         }
1830                         emit_movsbq_memindex_reg(cd, OFFSET(java_bytearray, data[0]), s1, s2, 0, d);
1831                         emit_store_dst(jd, iptr, d);
1832 #endif
1833                         break;
1834
1835                 case ICMD_CALOAD:     /* ..., arrayref, index  ==> ..., value         */
1836                         OOPS();
1837 #if 0
1838                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1839                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1840                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1841                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1842                                 gen_nullptr_check(s1);
1843                                 gen_bound_check;
1844                         }
1845                         emit_movzwq_memindex_reg(cd, OFFSET(java_chararray, data[0]), s1, s2, 1, d);
1846                         emit_store_dst(jd, iptr, d);
1847 #endif
1848                         break;                  
1849
1850                 case ICMD_SALOAD:     /* ..., arrayref, index  ==> ..., value         */
1851                         OOPS();
1852 #if 0
1853                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1854                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1855                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1856                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1857                                 gen_nullptr_check(s1);
1858                                 gen_bound_check;
1859                         }
1860                         emit_movswq_memindex_reg(cd, OFFSET(java_shortarray, data[0]), s1, s2, 1, d);
1861                         emit_store_dst(jd, iptr, d);
1862 #endif
1863                         break;
1864
1865                 case ICMD_IALOAD:     /* ..., arrayref, index  ==> ..., value         */
1866                         OOPS();
1867 #if 0
1868                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1869                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1870                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1871                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1872                                 gen_nullptr_check(s1);
1873                                 gen_bound_check;
1874                         }
1875                         emit_movl_memindex_reg(cd, OFFSET(java_intarray, data[0]), s1, s2, 2, d);
1876                         emit_store_dst(jd, iptr, d);
1877 #endif
1878                         break;
1879
1880                 case ICMD_LALOAD:     /* ..., arrayref, index  ==> ..., value         */
1881                         OOPS();
1882 #if 0
1883                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1884                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1885                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1886                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1887                                 gen_nullptr_check(s1);
1888                                 gen_bound_check;
1889                         }
1890                         emit_mov_memindex_reg(cd, OFFSET(java_longarray, data[0]), s1, s2, 3, d);
1891                         emit_store_dst(jd, iptr, d);
1892 #endif
1893                         break;
1894
1895                 case ICMD_FALOAD:     /* ..., arrayref, index  ==> ..., value         */
1896                         OOPS();
1897 #if 0
1898                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1899                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1900                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1901                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1902                                 gen_nullptr_check(s1);
1903                                 gen_bound_check;
1904                         }
1905                         emit_movss_memindex_reg(cd, OFFSET(java_floatarray, data[0]), s1, s2, 2, d);
1906                         emit_store_dst(jd, iptr, d);
1907 #endif
1908                         break;
1909
1910                 case ICMD_DALOAD:     /* ..., 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                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1916                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1917                                 gen_nullptr_check(s1);
1918                                 gen_bound_check;
1919                         }
1920                         emit_movsd_memindex_reg(cd, OFFSET(java_doublearray, data[0]), s1, s2, 3, d);
1921                         emit_store_dst(jd, iptr, d);
1922 #endif
1923                         break;
1924
1925                 case ICMD_AALOAD:     /* ..., arrayref, index  ==> ..., value         */
1926                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1927                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1928                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1929                         emit_array_checks(cd, iptr, s1, s2);
1930                         M_SAADDQ(s2, s1, REG_ITMP1);
1931                         M_ALD(d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1932                         emit_store_dst(jd, iptr, d);
1933                         break;
1934
1935                 case ICMD_BASTORE:    /* ..., arrayref, index, value  ==> ...         */
1936                         OOPS();
1937 #if 0
1938                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1939                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1940                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1941                                 gen_nullptr_check(s1);
1942                                 gen_bound_check;
1943                         }
1944                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1945                         emit_movb_reg_memindex(cd, s3, OFFSET(java_bytearray, data[0]), s1, s2, 0);
1946 #endif
1947                         break;
1948
1949                 case ICMD_CASTORE:    /* ..., arrayref, index, value  ==> ...         */
1950                         OOPS();
1951 #if 0
1952                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1953                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1954                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1955                                 gen_nullptr_check(s1);
1956                                 gen_bound_check;
1957                         }
1958                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1959                         emit_movw_reg_memindex(cd, s3, OFFSET(java_chararray, data[0]), s1, s2, 1);
1960 #endif
1961                         break;
1962
1963                 case ICMD_SASTORE:    /* ..., arrayref, index, value  ==> ...         */
1964                         OOPS();
1965 #if 0
1966                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1967                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1968                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1969                                 gen_nullptr_check(s1);
1970                                 gen_bound_check;
1971                         }
1972                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1973                         emit_movw_reg_memindex(cd, s3, OFFSET(java_shortarray, data[0]), s1, s2, 1);
1974 #endif
1975                         break;
1976
1977                 case ICMD_IASTORE:    /* ..., arrayref, index, value  ==> ...         */
1978                         OOPS();
1979 #if 0
1980                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1981                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1982                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1983                                 gen_nullptr_check(s1);
1984                                 gen_bound_check;
1985                         }
1986                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1987                         emit_movl_reg_memindex(cd, s3, OFFSET(java_intarray, data[0]), s1, s2, 2);
1988 #endif
1989                         break;
1990
1991                 case ICMD_LASTORE:    /* ..., arrayref, index, value  ==> ...         */
1992                         OOPS();
1993 #if 0
1994                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1995                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1996                         if (INSTRUCTION_MUST_CHECK(iptr)) {
1997                                 gen_nullptr_check(s1);
1998                                 gen_bound_check;
1999                         }
2000                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2001                         emit_mov_reg_memindex(cd, s3, OFFSET(java_longarray, data[0]), s1, s2, 3);
2002 #endif
2003                         break;
2004
2005                 case ICMD_FASTORE:    /* ..., arrayref, index, value  ==> ...         */
2006                         OOPS();
2007 #if 0
2008                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2009                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2010                         if (INSTRUCTION_MUST_CHECK(iptr)) {
2011                                 gen_nullptr_check(s1);
2012                                 gen_bound_check;
2013                         }
2014                         s3 = emit_load_s3(jd, iptr, REG_FTMP3);
2015                         emit_movss_reg_memindex(cd, s3, OFFSET(java_floatarray, data[0]), s1, s2, 2);
2016 #endif
2017                         break;
2018
2019                 case ICMD_DASTORE:    /* ..., arrayref, index, value  ==> ...         */
2020                         OOPS();
2021 #if 0
2022                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2023                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2024                         if (INSTRUCTION_MUST_CHECK(iptr)) {
2025                                 gen_nullptr_check(s1);
2026                                 gen_bound_check;
2027                         }
2028                         s3 = emit_load_s3(jd, iptr, REG_FTMP3);
2029                         emit_movsd_reg_memindex(cd, s3, OFFSET(java_doublearray, data[0]), s1, s2, 3);
2030 #endif
2031                         break;
2032
2033                 case ICMD_AASTORE:    /* ..., arrayref, index, value  ==> ...         */
2034                         OOPS();
2035 #if 0
2036                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2037                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2038                         if (INSTRUCTION_MUST_CHECK(iptr)) {
2039                                 gen_nullptr_check(s1);
2040                                 gen_bound_check;
2041                         }
2042                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2043
2044                         M_MOV(s1, REG_A0);
2045                         M_MOV(s3, REG_A1);
2046                         M_MOV_IMM(BUILTIN_canstore, REG_ITMP1);
2047                         M_CALL(REG_ITMP1);
2048                         M_TEST(REG_RESULT);
2049                         M_BEQ(0);
2050                         codegen_add_arraystoreexception_ref(cd);
2051
2052                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2053                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2054                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2055                         emit_mov_reg_memindex(cd, s3, OFFSET(java_objectarray, data[0]), s1, s2, 3);
2056 #endif
2057                         break;
2058
2059
2060                 case ICMD_BASTORECONST: /* ..., arrayref, index  ==> ...              */
2061                         OOPS();
2062 #if 0
2063                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2064                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2065                         if (INSTRUCTION_MUST_CHECK(iptr)) {
2066                                 gen_nullptr_check(s1);
2067                                 gen_bound_check;
2068                         }
2069                         emit_movb_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_bytearray, data[0]), s1, s2, 0);
2070 #endif
2071                         break;
2072
2073                 case ICMD_CASTORECONST:   /* ..., arrayref, index  ==> ...            */
2074                         OOPS();
2075 #if 0
2076                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2077                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2078                         if (INSTRUCTION_MUST_CHECK(iptr)) {
2079                                 gen_nullptr_check(s1);
2080                                 gen_bound_check;
2081                         }
2082                         emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_chararray, data[0]), s1, s2, 1);
2083 #endif
2084                         break;
2085
2086                 case ICMD_SASTORECONST:   /* ..., arrayref, index  ==> ...            */
2087                         OOPS();
2088 #if 0
2089                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2090                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2091                         if (INSTRUCTION_MUST_CHECK(iptr)) {
2092                                 gen_nullptr_check(s1);
2093                                 gen_bound_check;
2094                         }
2095                         emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_shortarray, data[0]), s1, s2, 1);
2096 #endif
2097                         break;
2098
2099                 case ICMD_IASTORECONST: /* ..., arrayref, index  ==> ...              */
2100                         OOPS();
2101 #if 0
2102                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2103                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2104                         if (INSTRUCTION_MUST_CHECK(iptr)) {
2105                                 gen_nullptr_check(s1);
2106                                 gen_bound_check;
2107                         }
2108                         emit_movl_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_intarray, data[0]), s1, s2, 2);
2109 #endif
2110                         break;
2111
2112                 case ICMD_LASTORECONST: /* ..., arrayref, index  ==> ...              */
2113                         OOPS();
2114 #if 0
2115                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2116                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2117                         if (INSTRUCTION_MUST_CHECK(iptr)) {
2118                                 gen_nullptr_check(s1);
2119                                 gen_bound_check;
2120                         }
2121
2122                         if (IS_IMM32(iptr->sx.s23.s3.constval)) {
2123                                 emit_mov_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray, data[0]), s1, s2, 3);
2124                         } else {
2125                                 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray, data[0]), s1, s2, 3);
2126                                 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval >> 32), OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
2127                         }
2128 #endif
2129                         break;
2130
2131                 case ICMD_AASTORECONST: /* ..., arrayref, index  ==> ...              */
2132                         OOPS();
2133 #if 0
2134                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2135                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2136                         if (INSTRUCTION_MUST_CHECK(iptr)) {
2137                                 gen_nullptr_check(s1);
2138                                 gen_bound_check;
2139                         }
2140                         emit_mov_imm_memindex(cd, 0, OFFSET(java_objectarray, data[0]), s1, s2, 3);
2141 #endif
2142                         break;
2143
2144
2145                 case ICMD_GETSTATIC:  /* ...  ==> ..., value                          */
2146
2147                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2148                                 uf        = iptr->sx.s23.s3.uf;
2149                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2150                                 disp      = dseg_add_unique_address(cd, NULL);
2151
2152 /*                              PROFILE_CYCLE_STOP; */
2153
2154                                 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
2155
2156 /*                              PROFILE_CYCLE_START; */
2157                         }
2158                         else {
2159                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
2160                                 fieldtype = fi->type;
2161                                 disp      = dseg_add_address(cd, &(fi->value));
2162
2163                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2164                                         PROFILE_CYCLE_STOP;
2165
2166                                         codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, 0);
2167
2168                                         PROFILE_CYCLE_START;
2169                                 }
2170                         }
2171
2172                         M_ALD(REG_ITMP1, REG_PV, disp);
2173
2174                         switch (fieldtype) {
2175                         case TYPE_INT:
2176                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2177                                 M_ILD(d, REG_ITMP1, 0);
2178                                 break;
2179                         case TYPE_LNG:
2180                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
2181                                 M_LLD(d, REG_ITMP1, 0);
2182                                 break;
2183                         case TYPE_ADR:
2184                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2185                                 M_ALD(d, REG_ITMP1, 0);
2186                                 break;
2187                         case TYPE_FLT:
2188                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2189                                 M_FLD(d, REG_ITMP1, 0);
2190                                 break;
2191                         case TYPE_DBL:                          
2192                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2193                                 M_DLD(d, REG_ITMP1, 0);
2194                                 break;
2195                         }
2196
2197                         emit_store_dst(jd, iptr, d);
2198
2199                         break;
2200
2201                 case ICMD_PUTSTATIC:  /* ..., value  ==> ...                          */
2202
2203                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2204                                 uf        = iptr->sx.s23.s3.uf;
2205                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2206                                 disp      = dseg_add_unique_address(cd, uf);
2207
2208                                 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
2209                         }
2210                         else {
2211                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
2212                                 fieldtype = fi->type;
2213                                 disp      = dseg_add_address(cd, &(fi->value));
2214
2215                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2216                                         codegen_addpatchref(cd, PATCHER_clinit,
2217                                                                                 fi->class, disp);
2218                         }
2219
2220                         M_ALD(REG_ITMP1, REG_PV, disp);
2221                         switch (fieldtype) {
2222                         case TYPE_INT:
2223                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2224                                 M_IST(s1, REG_ITMP1, 0);
2225                                 break;
2226                         case TYPE_LNG:
2227                                 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
2228                                 M_LST(s1, REG_ITMP1, 0);
2229                                 break;
2230                         case TYPE_ADR:
2231                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2232                                 M_AST(s1, REG_ITMP1, 0);
2233                                 break;
2234                         case TYPE_FLT:
2235                                 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2236                                 M_FST(s1, REG_ITMP1, 0);
2237                                 break;
2238                         case TYPE_DBL:
2239                                 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2240                                 M_DST(s1, REG_ITMP1, 0);
2241                                 break;
2242                         }
2243                         break;
2244
2245                 case ICMD_PUTSTATICCONST: /* ...  ==> ...                             */
2246                                           /* val = value (in current instruction)     */
2247                                           /* following NOP)                           */
2248                         OOPS();
2249 #if 0
2250                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2251                                 uf        = iptr->sx.s23.s3.uf;
2252                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2253                                 disp      = dseg_add_unique_address(cd, NULL);
2254                                 disp      = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
2255
2256                                 /* must be calculated before codegen_add_patch_ref */
2257
2258                                 if (opt_shownops)
2259                                         disp -= PATCHER_CALL_SIZE;
2260
2261
2262 /*                              PROFILE_CYCLE_STOP; */
2263
2264                                 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
2265
2266 /*                              PROFILE_CYCLE_START; */
2267                         }
2268                         else {
2269                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
2270                                 fieldtype = fi->type;
2271                                 disp      = dseg_add_address(cd, &(fi->value));
2272                                 disp      = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
2273
2274                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2275                                         PROFILE_CYCLE_STOP;
2276
2277                                         codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, 0);
2278
2279                                         if (opt_shownops)
2280                                                 disp -= PATCHER_CALL_SIZE;
2281
2282                                         PROFILE_CYCLE_START;
2283                                 }
2284                         }
2285
2286                         /* This approach is much faster than moving the field
2287                            address inline into a register. */
2288
2289                         M_ALD(REG_ITMP1, RIP, disp);
2290
2291                         switch (fieldtype) {
2292                         case TYPE_INT:
2293                         case TYPE_FLT:
2294                                 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
2295                                 break;
2296                         case TYPE_LNG:
2297                         case TYPE_ADR:
2298                         case TYPE_DBL:
2299                                 if (IS_IMM32(iptr->sx.s23.s2.constval))
2300                                         M_LST_IMM32(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
2301                                 else {
2302                                         M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
2303                                         M_IST_IMM(iptr->sx.s23.s2.constval >> 32, REG_ITMP1, 4);
2304                                 }
2305                                 break;
2306                         }
2307 #endif
2308                         break;
2309
2310                 case ICMD_GETFIELD:   /* ...  ==> ..., value                          */
2311                         OOPS();
2312 #if 0
2313                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2314                         gen_nullptr_check(s1);
2315
2316                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2317                                 uf        = iptr->sx.s23.s3.uf;
2318                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2319                                 disp      = 0;
2320
2321 /*                              PROFILE_CYCLE_STOP; */
2322
2323                                 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
2324
2325 /*                              PROFILE_CYCLE_START; */
2326                         }
2327                         else {
2328                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
2329                                 fieldtype = fi->type;
2330                                 disp      = fi->offset;
2331                         }
2332
2333                         switch (fieldtype) {
2334                         case TYPE_INT:
2335                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
2336                                 M_ILD32(d, s1, disp);
2337                                 break;
2338                         case TYPE_LNG:
2339                         case TYPE_ADR:
2340                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
2341                                 M_LLD32(d, s1, disp);
2342                                 break;
2343                         case TYPE_FLT:
2344                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2345                                 M_FLD32(d, s1, disp);
2346                                 break;
2347                         case TYPE_DBL:                          
2348                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2349                                 M_DLD32(d, s1, disp);
2350                                 break;
2351                         }
2352                         emit_store_dst(jd, iptr, d);
2353 #endif
2354                         break;
2355
2356                 case ICMD_PUTFIELD:   /* ..., objectref, value  ==> ...               */
2357                         OOPS();
2358 #if 0
2359                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2360                         gen_nullptr_check(s1);
2361
2362                         s2 = emit_load_s2(jd, iptr, REG_IFTMP);
2363
2364                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2365                                 uf        = iptr->sx.s23.s3.uf;
2366                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2367                                 disp      = 0;
2368
2369 /*                              PROFILE_CYCLE_STOP; */
2370
2371                                 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
2372
2373 /*                              PROFILE_CYCLE_START; */
2374                         } 
2375                         else {
2376                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
2377                                 fieldtype = fi->type;
2378                                 disp      = fi->offset;
2379                         }
2380
2381                         switch (fieldtype) {
2382                         case TYPE_INT:
2383                                 M_IST32(s2, s1, disp);
2384                                 break;
2385                         case TYPE_LNG:
2386                         case TYPE_ADR:
2387                                 M_LST32(s2, s1, disp);
2388                                 break;
2389                         case TYPE_FLT:
2390                                 M_FST32(s2, s1, disp);
2391                                 break;
2392                         case TYPE_DBL:
2393                                 M_DST32(s2, s1, disp);
2394                                 break;
2395                         }
2396 #endif
2397                         break;
2398
2399                 case ICMD_PUTFIELDCONST:  /* ..., objectref, value  ==> ...           */
2400                                           /* val = value (in current instruction)     */
2401                                           /* following NOP)                           */
2402                         OOPS();
2403 #if 0
2404                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2405                         gen_nullptr_check(s1);
2406
2407                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2408                                 uf        = iptr->sx.s23.s3.uf;
2409                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2410                                 disp      = 0;
2411
2412 /*                              PROFILE_CYCLE_STOP; */
2413
2414                                 codegen_add_patch_ref(cd, PATCHER_putfieldconst, uf, 0);
2415
2416 /*                              PROFILE_CYCLE_START; */
2417                         } 
2418                         else {
2419                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
2420                                 fieldtype = fi->type;
2421                                 disp      = fi->offset;
2422                         }
2423
2424                         switch (fieldtype) {
2425                         case TYPE_INT:
2426                         case TYPE_FLT:
2427                                 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2428                                 break;
2429                         case TYPE_LNG:
2430                         case TYPE_ADR:
2431                         case TYPE_DBL:
2432                                 /* XXX why no check for IS_IMM32? */
2433                                 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2434                                 M_IST32_IMM(iptr->sx.s23.s2.constval >> 32, s1, disp + 4);
2435                                 break;
2436                         }
2437 #endif
2438                         break;
2439
2440
2441                 /* branch operations **************************************************/
2442
2443                 case ICMD_ATHROW:       /* ..., objectref ==> ... (, objectref)       */
2444                         OOPS();
2445 #if 0
2446                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2447                         M_INTMOVE(s1, REG_ITMP1_XPTR);
2448
2449                         PROFILE_CYCLE_STOP;
2450
2451 #ifdef ENABLE_VERIFIER
2452                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2453                                 uc = iptr->sx.s23.s2.uc;
2454
2455                                 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2456                         }
2457 #endif /* ENABLE_VERIFIER */
2458
2459                         M_CALL_IMM(0);                            /* passing exception pc */
2460                         M_POP(REG_ITMP2_XPC);
2461
2462                         M_MOV_IMM(asm_handle_exception, REG_ITMP3);
2463                         M_JMP(REG_ITMP3);
2464 #endif
2465                         break;
2466
2467                 case ICMD_GOTO:         /* ... ==> ...                                */
2468                 case ICMD_RET:          /* ... ==> ...                                */
2469
2470                         M_BR(0);
2471                         codegen_add_branch_ref(cd, iptr->dst.block);
2472
2473                         break;
2474
2475                 case ICMD_JSR:          /* ... ==> ...                                */
2476                         OOPS();
2477 #if 0
2478                         M_JMP_IMM(0);
2479                         codegen_add_branch_ref(cd, iptr->sx.s23.s3.jsrtarget.block);
2480 #endif
2481                         break;
2482                         
2483                 case ICMD_IFNULL:       /* ..., value ==> ...                         */
2484                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2485                         M_TEST(s1);
2486                         M_BEQ(0);
2487                         codegen_add_branch_ref(cd, iptr->dst.block);
2488                         break;
2489
2490                 case ICMD_IFNONNULL:    /* ..., value ==> ...                         */
2491                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2492                         M_TEST(s1);
2493                         M_BNE(0);
2494                         codegen_add_branch_ref(cd, iptr->dst.block);
2495                         break;
2496
2497                 case ICMD_IFEQ:         /* ..., value ==> ...                         */
2498                 case ICMD_IFLT:         /* ..., value ==> ...                         */
2499                 case ICMD_IFLE:         /* ..., value ==> ...                         */
2500                 case ICMD_IFNE:         /* ..., value ==> ...                         */
2501                 case ICMD_IFGT:         /* ..., value ==> ...                         */
2502                 case ICMD_IFGE:         /* ..., value ==> ...                         */
2503                         
2504                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2505
2506                         if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
2507                                 N_CHI(s1, iptr->sx.val.i);
2508                         else {
2509                                 disp = dseg_add_s4(cd, iptr->sx.val.i);
2510                                 N_LHI(REG_ITMP2, disp);
2511                                 N_CL(s1, 0, REG_ITMP2, REG_PV);
2512                         }
2513
2514                         switch (iptr->opc) {
2515                         case ICMD_IFLT:
2516                                 M_BLT(0);
2517                                 break;
2518                         case ICMD_IFLE:
2519                                 M_BLE(0);
2520                                 break;
2521                         case ICMD_IFNE:
2522                                 M_BNE(0);
2523                                 break;
2524                         case ICMD_IFGT:
2525                                 M_BGT(0);
2526                                 break;
2527                         case ICMD_IFGE:
2528                                 M_BGE(0);
2529                                 break;
2530                         case ICMD_IFEQ:
2531                                 M_BEQ(0);
2532                                 break;
2533                         }
2534                         codegen_add_branch_ref(cd, iptr->dst.block);
2535
2536                         break;
2537
2538                 case ICMD_IF_LEQ:       /* ..., value ==> ...                         */
2539                         OOPS();
2540 #if 0
2541                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2542                         if (IS_IMM32(iptr->sx.val.l))
2543                                 M_LCMP_IMM(iptr->sx.val.l, s1);
2544                         else {
2545                                 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2546                                 M_LCMP(REG_ITMP2, s1);
2547                         }
2548                         M_BEQ(0);
2549                         codegen_add_branch_ref(cd, iptr->dst.block);
2550 #endif
2551                         break;
2552
2553                 case ICMD_IF_LLT:       /* ..., value ==> ...                         */
2554                         OOPS();
2555 #if 0
2556
2557                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2558                         if (IS_IMM32(iptr->sx.val.l))
2559                                 M_LCMP_IMM(iptr->sx.val.l, s1);
2560                         else {
2561                                 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2562                                 M_LCMP(REG_ITMP2, s1);
2563                         }
2564                         M_BLT(0);
2565                         codegen_add_branch_ref(cd, iptr->dst.block);
2566 #endif
2567                         break;
2568
2569                 case ICMD_IF_LLE:       /* ..., value ==> ...                         */
2570                         OOPS();
2571 #if 0
2572
2573                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2574                         if (IS_IMM32(iptr->sx.val.l))
2575                                 M_LCMP_IMM(iptr->sx.val.l, s1);
2576                         else {
2577                                 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2578                                 M_LCMP(REG_ITMP2, s1);
2579                         }
2580                         M_BLE(0);
2581                         codegen_add_branch_ref(cd, iptr->dst.block);
2582 #endif
2583                         break;
2584
2585                 case ICMD_IF_LNE:       /* ..., value ==> ...                         */
2586                         OOPS();
2587 #if 0
2588
2589                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2590                         if (IS_IMM32(iptr->sx.val.l))
2591                                 M_LCMP_IMM(iptr->sx.val.l, s1);
2592                         else {
2593                                 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2594                                 M_LCMP(REG_ITMP2, s1);
2595                         }
2596                         M_BNE(0);
2597                         codegen_add_branch_ref(cd, iptr->dst.block);
2598 #endif
2599                         break;
2600
2601                 case ICMD_IF_LGT:       /* ..., value ==> ...                         */
2602                         OOPS();
2603 #if 0
2604
2605                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2606                         if (IS_IMM32(iptr->sx.val.l))
2607                                 M_LCMP_IMM(iptr->sx.val.l, s1);
2608                         else {
2609                                 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2610                                 M_LCMP(REG_ITMP2, s1);
2611                         }
2612                         M_BGT(0);
2613                         codegen_add_branch_ref(cd, iptr->dst.block);
2614 #endif
2615                         break;
2616
2617                 case ICMD_IF_LGE:       /* ..., value ==> ...                         */
2618                         OOPS();
2619 #if 0
2620
2621                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2622                         if (IS_IMM32(iptr->sx.val.l))
2623                                 M_LCMP_IMM(iptr->sx.val.l, s1);
2624                         else {
2625                                 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2626                                 M_LCMP(REG_ITMP2, s1);
2627                         }
2628                         M_BGE(0);
2629                         codegen_add_branch_ref(cd, iptr->dst.block);
2630 #endif
2631                         break;
2632
2633                 case ICMD_IF_ICMPEQ:    /* ..., value, value ==> ...                  */
2634                 case ICMD_IF_ACMPEQ:    /* op1 = target JavaVM pc                     */
2635
2636                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2637                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2638                         M_CMP(s1, s2);
2639                         M_BEQ(0);
2640                         codegen_add_branch_ref(cd, iptr->dst.block);
2641                         break;
2642
2643                 case ICMD_IF_LCMPEQ:    /* ..., value, value ==> ...                  */
2644
2645                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2646                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2647                         M_CMP(s1, s2);
2648                         /* load low-bits before the branch, so we know the distance */
2649                         /* TODO do the loads modify the condition code?
2650                          * lr, l, la, lhi dont
2651                          */
2652                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2653                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2654                         M_BNE(SZ_BRC + SZ_CR + SZ_BRC);
2655                         M_CMP(s1, s2);
2656                         M_BEQ(0);
2657                         codegen_add_branch_ref(cd, iptr->dst.block);
2658                         break;
2659
2660                 case ICMD_IF_ICMPNE:    /* ..., value, value ==> ...                  */
2661                         OOPS();
2662 #if 0
2663
2664                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2665                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2666                         M_ICMP(s2, s1);
2667                         M_BNE(0);
2668                         codegen_add_branch_ref(cd, iptr->dst.block);
2669 #endif
2670                         break;
2671
2672                 case ICMD_IF_LCMPNE:    /* ..., value, value ==> ...                  */
2673                 case ICMD_IF_ACMPNE:    /* op1 = target JavaVM pc                     */
2674                         OOPS();
2675 #if 0
2676
2677                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2678                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2679                         M_LCMP(s2, s1);
2680                         M_BNE(0);
2681                         codegen_add_branch_ref(cd, iptr->dst.block);
2682 #endif
2683                         break;
2684
2685                 case ICMD_IF_ICMPLT:    /* ..., value, value ==> ...                  */
2686                         OOPS();
2687 #if 0
2688
2689                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2690                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2691                         M_ICMP(s2, s1);
2692                         M_BLT(0);
2693                         codegen_add_branch_ref(cd, iptr->dst.block);
2694 #endif
2695                         break;
2696
2697                 case ICMD_IF_LCMPLT:    /* ..., value, value ==> ...                  */
2698                         OOPS();
2699 #if 0
2700
2701                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2702                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2703                         M_LCMP(s2, s1);
2704                         M_BLT(0);
2705                         codegen_add_branch_ref(cd, iptr->dst.block);
2706 #endif
2707                         break;
2708
2709                 case ICMD_IF_ICMPGT:    /* ..., value, value ==> ...                  */
2710                         OOPS();
2711 #if 0
2712
2713                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2714                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2715                         M_ICMP(s2, s1);
2716                         M_BGT(0);
2717                         codegen_add_branch_ref(cd, iptr->dst.block);
2718 #endif
2719                         break;
2720
2721                 case ICMD_IF_LCMPGT:    /* ..., value, value ==> ...                  */
2722
2723                         OOPS();
2724 #if 0
2725                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2726                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2727                         M_LCMP(s2, s1);
2728                         M_BGT(0);
2729                         codegen_add_branch_ref(cd, iptr->dst.block);
2730 #endif
2731                         break;
2732
2733                 case ICMD_IF_ICMPLE:    /* ..., value, value ==> ...                  */
2734
2735                         OOPS();
2736 #if 0
2737                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2738                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2739                         M_ICMP(s2, s1);
2740                         M_BLE(0);
2741                         codegen_add_branch_ref(cd, iptr->dst.block);
2742 #endif
2743                         break;
2744
2745                 case ICMD_IF_LCMPLE:    /* ..., value, value ==> ...                  */
2746
2747                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2748                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2749                         M_CMP(s1, s2);
2750                         M_BLT(0);
2751                         codegen_add_branch_ref(cd, iptr->dst.block);
2752                         /* load low-bits before the branch, so we know the distance */
2753                         /* TODO: the loads should not touch the condition code. */
2754                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2755                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2756                         M_BGT(SZ_BRC + SZ_CR + SZ_BRC);
2757                         M_CMP(s1, s2);
2758                         M_BLE(0);
2759                         codegen_add_branch_ref(cd, iptr->dst.block);
2760                         break;
2761
2762                 case ICMD_IF_ICMPGE:    /* ..., value, value ==> ...                  */
2763
2764                         OOPS();
2765 #if 0
2766                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2767                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2768                         M_ICMP(s2, s1);
2769                         M_BGE(0);
2770                         codegen_add_branch_ref(cd, iptr->dst.block);
2771 #endif
2772                         break;
2773
2774                 case ICMD_IF_LCMPGE:    /* ..., value, value ==> ...                  */
2775
2776                         OOPS();
2777 #if 0
2778                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2779                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2780                         M_LCMP(s2, s1);
2781                         M_BGE(0);
2782                         codegen_add_branch_ref(cd, iptr->dst.block);
2783 #endif
2784                         break;
2785
2786                 case ICMD_IRETURN:      /* ..., retvalue ==> ...                      */
2787
2788                         REPLACEMENT_POINT_RETURN(cd, iptr);
2789                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
2790                         M_INTMOVE(s1, REG_RESULT);
2791                         goto nowperformreturn;
2792
2793                 case ICMD_ARETURN:      /* ..., retvalue ==> ...                      */
2794
2795                         REPLACEMENT_POINT_RETURN(cd, iptr);
2796                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
2797                         M_INTMOVE(s1, REG_RESULT);
2798
2799 #ifdef ENABLE_VERIFIER
2800                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2801                                 unresolved_class *uc = iptr->sx.s23.s2.uc;
2802
2803                                 codegen_addpatchref(cd, PATCHER_athrow_areturn, uc, 0);
2804                         }
2805 #endif /* ENABLE_VERIFIER */
2806                         goto nowperformreturn;
2807
2808                 case ICMD_LRETURN:      /* ..., retvalue ==> ...                      */
2809
2810                         REPLACEMENT_POINT_RETURN(cd, iptr);
2811                         s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
2812                         M_LNGMOVE(s1, REG_RESULT_PACKED);
2813                         goto nowperformreturn;
2814
2815                 case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
2816                 case ICMD_DRETURN:
2817
2818                         REPLACEMENT_POINT_RETURN(cd, iptr);
2819                         s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2820                         M_FLTMOVE(s1, REG_FRESULT);
2821                         goto nowperformreturn;
2822
2823                 case ICMD_RETURN:      /* ...  ==> ...                                */
2824
2825                         REPLACEMENT_POINT_RETURN(cd, iptr);
2826
2827 nowperformreturn:
2828                         {
2829                         s4 i, p;
2830                         
2831                         p = cd->stackframesize;
2832
2833                         /* call trace function */
2834
2835                         emit_verbosecall_exit(jd);
2836
2837 #if defined(ENABLE_THREADS)
2838                         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2839                                 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2840                                 M_ALD(REG_ITMP3, REG_PV, disp);
2841                                 M_CALL(REG_ITMP3);
2842
2843                                 /* we need to save the proper return value */
2844
2845                                 switch (iptr->opc) {
2846                                 case ICMD_LRETURN:
2847                                         M_IST(REG_RESULT2, REG_SP, rd->memuse * 4 + 8);
2848                                         /* fall through */
2849                                 case ICMD_IRETURN:
2850                                 case ICMD_ARETURN:
2851                                         M_IST(REG_RESULT , REG_SP, rd->memuse * 4 + 4);
2852                                         break;
2853                                 case ICMD_FRETURN:
2854                                         M_FST(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
2855                                         break;
2856                                 case ICMD_DRETURN:
2857                                         M_DST(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
2858                                         break;
2859                                 }
2860
2861                                 M_ALD(REG_A0, REG_SP, rd->memuse * 4);
2862                                 M_JSR;
2863
2864                                 /* and now restore the proper return value */
2865
2866                                 switch (iptr->opc) {
2867                                 case ICMD_LRETURN:
2868                                         M_ILD(REG_RESULT2, REG_SP, rd->memuse * 4 + 8);
2869                                         /* fall through */
2870                                 case ICMD_IRETURN:
2871                                 case ICMD_ARETURN:
2872                                         M_ILD(REG_RESULT , REG_SP, rd->memuse * 4 + 4);
2873                                         break;
2874                                 case ICMD_FRETURN:
2875                                         M_FLD(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
2876                                         break;
2877                                 case ICMD_DRETURN:
2878                                         M_DLD(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
2879                                         break;
2880                                 }
2881                         }
2882 #endif
2883
2884                         /* restore return address                                         */
2885
2886                         M_ALD(REG_RA, REG_SP, p * 4);
2887
2888                         /* restore saved registers                                        */
2889
2890                         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2891                                 p--; M_ILD(rd->savintregs[i], REG_SP, p * 4);
2892                         }
2893                         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2894                                 p -= 2; M_DLD(rd->savfltregs[i], REG_SP, p * 4);
2895                         }
2896
2897                         /* deallocate stack                                               */
2898
2899                         if (cd->stackframesize)
2900                                 M_AADD_IMM(cd->stackframesize * 4, REG_SP);
2901
2902                         M_RET;
2903                         ALIGNCODENOP;
2904                         }
2905                         break;
2906
2907                 case ICMD_TABLESWITCH:  /* ..., index ==> ...                         */
2908                         OOPS();
2909 #if 0
2910                         {
2911                                 s4 i, l;
2912                                 branch_target_t *table;
2913
2914                                 table = iptr->dst.table;
2915
2916                                 l = iptr->sx.s23.s2.tablelow;
2917                                 i = iptr->sx.s23.s3.tablehigh;
2918
2919                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2920                                 M_INTMOVE(s1, REG_ITMP1);
2921
2922                                 if (l != 0)
2923                                         M_ISUB_IMM(l, REG_ITMP1);
2924
2925                                 /* number of targets */
2926                                 i = i - l + 1;
2927
2928                 /* range check */
2929                                 M_ICMP_IMM(i - 1, REG_ITMP1);
2930                                 M_BA(0);
2931
2932                                 codegen_add_branch_ref(cd, table[0].block); /* default target */
2933
2934                                 /* build jump table top down and use address of lowest entry */
2935
2936                                 table += i;
2937
2938                                 while (--i >= 0) {
2939                                         dseg_add_target(cd, table->block);
2940                                         --table;
2941                                 }
2942
2943                                 /* length of dataseg after last dseg_add_target is used
2944                                    by load */
2945
2946                                 M_MOV_IMM(0, REG_ITMP2);
2947                                 dseg_adddata(cd);
2948                                 emit_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 3, REG_ITMP1);
2949                                 M_JMP(REG_ITMP1);
2950                         }
2951 #endif
2952                         break;
2953
2954
2955                 case ICMD_LOOKUPSWITCH: /* ..., key ==> ...                           */
2956                         OOPS();
2957 #if 0
2958                         {
2959                                 s4 i;
2960                                 lookup_target_t *lookup;
2961
2962                                 lookup = iptr->dst.lookup;
2963
2964                                 i = iptr->sx.s23.s2.lookupcount;
2965                         
2966                                 MCODECHECK(8 + ((7 + 6) * i) + 5);
2967                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2968
2969                                 while (--i >= 0) {
2970                                         M_ICMP_IMM(lookup->value, s1);
2971                                         M_BEQ(0);
2972                                         codegen_add_branch_ref(cd, lookup->target.block);
2973                                         lookup++;
2974                                 }
2975
2976                                 M_JMP_IMM(0);
2977                         
2978                                 codegen_add_branch_ref(cd, iptr->sx.s23.s3.lookupdefault.block);
2979                         }
2980 #endif
2981                         break;
2982
2983
2984                 case ICMD_BUILTIN:      /* ..., [arg1, [arg2 ...]] ==> ...            */
2985
2986                         bte = iptr->sx.s23.s3.bte;
2987                         md  = bte->md;
2988                         goto gen_method;
2989
2990                 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ...            */
2991                 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2992                 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer    */
2993                 case ICMD_INVOKEINTERFACE:
2994
2995                         REPLACEMENT_POINT_INVOKE(cd, iptr);
2996
2997                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2998                                 lm = NULL;
2999                                 um = iptr->sx.s23.s3.um;
3000                                 md = um->methodref->parseddesc.md;
3001                         }
3002                         else {
3003                                 lm = iptr->sx.s23.s3.fmiref->p.method;
3004                                 um = NULL;
3005                                 md = lm->parseddesc;
3006                         }
3007
3008 gen_method:
3009                         s3 = md->paramcount;
3010
3011                         MCODECHECK((s3 << 1) + 64);
3012
3013                         /* copy arguments to registers or stack location */
3014
3015                         for (s3 = s3 - 1; s3 >= 0; s3--) {
3016                                 var = VAR(iptr->sx.s23.s2.args[s3]);
3017
3018                                 /* Already Preallocated? */
3019                                 if (var->flags & PREALLOC)
3020                                         continue;
3021
3022                                 if (IS_INT_LNG_TYPE(var->type)) {
3023                                         if (!md->params[s3].inmemory) {
3024                                                 if (IS_2_WORD_TYPE(var->type)) {
3025                                                         s1 = PACK_REGS(
3026                                                                 rd->argintregs[GET_LOW_REG(md->params[s3].regoff)],
3027                                                                 rd->argintregs[GET_HIGH_REG(md->params[s3].regoff)]
3028                                                         );
3029                                                         d = emit_load(jd, iptr, var, s1);
3030                                                         M_LNGMOVE(d, s1);
3031                                                 }
3032                                                 else {
3033                                                         s1 = rd->argintregs[md->params[s3].regoff];
3034                                                         d = emit_load(jd, iptr, var, s1);
3035                                                         M_INTMOVE(d, s1);
3036                                                 }
3037                                         }
3038                                         else {
3039                                                 if (IS_2_WORD_TYPE(var->type)) {
3040                                                         d = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
3041                                                         M_LST(d, REG_SP, md->params[s3].regoff * 4);
3042                                                 }
3043                                                 else {
3044                                                         d = emit_load(jd, iptr, var, REG_ITMP1);
3045                                                         M_IST(d, REG_SP, md->params[s3].regoff * 4);
3046                                                 }
3047                                         }
3048                                 }
3049                                 else {
3050                                         if (!md->params[s3].inmemory) {
3051                                                 s1 = rd->argfltregs[md->params[s3].regoff];
3052                                                 d = emit_load(jd, iptr, var, s1);
3053                                                 M_FLTMOVE(d, s1);
3054                                         }
3055                                         else {
3056                                                 d = emit_load(jd, iptr, var, REG_FTMP1);
3057                                                 if (IS_2_WORD_TYPE(var->type))
3058                                                         M_DST(d, REG_SP, md->params[s3].regoff * 4);
3059                                                 else
3060                                                         M_FST(d, REG_SP, md->params[s3].regoff * 4);
3061                                         }
3062                                 }
3063                         }
3064
3065                         switch (iptr->opc) {
3066                         case ICMD_BUILTIN:
3067                                 disp = dseg_add_functionptr(cd, bte->fp);
3068
3069                                 N_LHI(REG_ITMP1, disp);
3070                                 N_L(REG_PV, 0, REG_ITMP1, REG_PV);
3071                                 break;
3072
3073                         case ICMD_INVOKESPECIAL:
3074                                 emit_nullpointer_check(cd, iptr, REG_A0);
3075                                 M_ILD(REG_ITMP1, REG_A0, 0); /* hardware nullptr   */
3076                                 /* fall through */
3077
3078                         case ICMD_INVOKESTATIC:
3079                                 if (lm == NULL) {
3080                                         disp = dseg_add_unique_address(cd, um);
3081
3082                                         codegen_addpatchref(cd, PATCHER_invokestatic_special,
3083                                                                                 um, disp);
3084                                 }
3085                                 else
3086                                         disp = dseg_add_address(cd, lm->stubroutine);
3087
3088                                 N_LHI(REG_ITMP1, disp);
3089                                 N_L(REG_PV, 0, REG_ITMP1, REG_PV);
3090                                 break;
3091
3092                         case ICMD_INVOKEVIRTUAL:
3093                                 emit_nullpointer_check(cd, iptr, REG_A0);
3094
3095                                 if (lm == NULL) {
3096                                         codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
3097
3098                                         s1 = 0;
3099                                 }
3100                                 else {
3101                                         s1 = OFFSET(vftbl_t, table[0]) +
3102                                                 sizeof(methodptr) * lm->vftblindex;
3103                                 }
3104
3105                                 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
3106                                 M_ALD(REG_PV, REG_METHODPTR, s1);
3107                                 break;
3108
3109                         case ICMD_INVOKEINTERFACE:
3110                                 emit_nullpointer_check(cd, iptr, REG_A0);
3111
3112                                 if (lm == NULL) {
3113                                         codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
3114
3115                                         s1 = 0;
3116                                         s2 = 0;
3117                                 }
3118                                 else {
3119                                         s1 = OFFSET(vftbl_t, interfacetable[0]) -
3120                                                 sizeof(methodptr*) * lm->class->index;
3121
3122                                         s2 = sizeof(methodptr) * (lm - lm->class->methods);
3123                                 }
3124
3125                                 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
3126                                 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3127                                 M_ALD(REG_PV, REG_METHODPTR, s2);
3128                                 break;
3129                         }
3130
3131                         /* generate the actual call */
3132
3133                         M_CALL(REG_PV);
3134                         REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3135                         N_BASR(REG_ITMP1, RN);
3136                         disp = (s4) (cd->mcodeptr - cd->mcodebase);
3137                         M_LDA(REG_PV, REG_ITMP1, -disp);
3138                         
3139                         /* actually only used for ICMD_BUILTIN */
3140
3141                         if (INSTRUCTION_MUST_CHECK(iptr)) {
3142                                 M_TEST(REG_RESULT);
3143                                 M_BEQ(0);
3144                                 codegen_add_fillinstacktrace_ref(cd);
3145                         }
3146
3147                         /* store return value */
3148
3149                         d = md->returntype.type;
3150
3151                         if (d != TYPE_VOID) {
3152                                 if (IS_INT_LNG_TYPE(d)) {
3153                                         if (IS_2_WORD_TYPE(d)) {
3154                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
3155                                                 M_LNGMOVE(REG_RESULT_PACKED, s1);
3156                                         }
3157                                         else {
3158                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3159                                                 M_INTMOVE(REG_RESULT, s1);
3160                                         }
3161                                 }
3162                                 else {
3163                                         s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
3164                                         M_FLTMOVE(REG_FRESULT, s1);
3165                                 }
3166                                 emit_store_dst(jd, iptr, s1);
3167                         }
3168
3169                         break;
3170
3171
3172                 case ICMD_CHECKCAST:  /* ..., objectref ==> ..., objectref            */
3173                         OOPS();
3174 #if 0
3175
3176                                       /* val.a: (classinfo *) superclass              */
3177
3178                         /*  superclass is an interface:
3179                          *      
3180                          *  OK if ((sub == NULL) ||
3181                          *         (sub->vftbl->interfacetablelength > super->index) &&
3182                          *         (sub->vftbl->interfacetable[-super->index] != NULL));
3183                          *      
3184                          *  superclass is a class:
3185                          *      
3186                          *  OK if ((sub == NULL) || (0
3187                          *         <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3188                          *         super->vftbl->diffval));
3189                          */
3190
3191                         if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
3192                                 /* object type cast-check */
3193
3194                                 classinfo *super;
3195                                 vftbl_t   *supervftbl;
3196                                 s4         superindex;
3197
3198                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3199                                         super = NULL;
3200                                         superindex = 0;
3201                                         supervftbl = NULL;
3202                                 }
3203                                 else {
3204                                         super = iptr->sx.s23.s3.c.cls;
3205                                         superindex = super->index;
3206                                         supervftbl = super->vftbl;
3207                                 }
3208
3209 #if defined(ENABLE_THREADS)
3210                                 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3211 #endif
3212                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3213
3214                                 /* calculate interface checkcast code size */
3215
3216                                 s2 = 3; /* mov_membase_reg */
3217                                 CALCOFFSETBYTES(s2, s1, OFFSET(java_objectheader, vftbl));
3218
3219                                 s2 += 3 + 4 /* movl_membase32_reg */ + 3 + 4 /* sub imm32 */ +
3220                                         3 /* test */ + 6 /* jcc */ + 3 + 4 /* mov_membase32_reg */ +
3221                                         3 /* test */ + 6 /* jcc */;
3222
3223                                 if (super == NULL)
3224                                         s2 += (opt_shownops ? 5 : 0);
3225
3226                                 /* calculate class checkcast code size */
3227
3228                                 s3 = 3; /* mov_membase_reg */
3229                                 CALCOFFSETBYTES(s3, s1, OFFSET(java_objectheader, vftbl));
3230                                 s3 += 10 /* mov_imm_reg */ + 3 + 4 /* movl_membase32_reg */;
3231
3232 #if 0
3233                                 if (s1 != REG_ITMP1) {
3234                                         a += 3;    /* movl_membase_reg - only if REG_ITMP3 == R11 */
3235                                         CALCOFFSETBYTES(a, REG_ITMP3, OFFSET(vftbl_t, baseval));
3236                                         a += 3;    /* movl_membase_reg - only if REG_ITMP3 == R11 */
3237                                         CALCOFFSETBYTES(a, REG_ITMP3, OFFSET(vftbl_t, diffval));
3238                                         a += 3;    /* sub */
3239                                 
3240                                 } else
3241 #endif
3242                                         {
3243                                                 s3 += 3 + 4 /* movl_membase32_reg */ + 3 /* sub */ +
3244                                                         10 /* mov_imm_reg */ + 3 /* movl_membase_reg */;
3245                                                 CALCOFFSETBYTES(s3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3246                                         }
3247                         
3248                                 s3 += 3 /* cmp */ + 6 /* jcc */;
3249
3250                                 if (super == NULL)
3251                                         s3 += (opt_shownops ? 5 : 0);
3252
3253                                 /* if class is not resolved, check which code to call */
3254
3255                                 if (super == NULL) {
3256                                         M_TEST(s1);
3257                                         M_BEQ(6 + (opt_shownops ? 5 : 0) + 7 + 6 + s2 + 5 + s3);
3258
3259                                         codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
3260                                                                                   iptr->sx.s23.s3.c.ref, 0);
3261
3262                                         M_IMOV_IMM(0, REG_ITMP2);                 /* super->flags */
3263                                         M_IAND_IMM(ACC_INTERFACE, REG_ITMP2);
3264                                         M_BEQ(s2 + 5);
3265                                 }
3266
3267                                 /* interface checkcast code */
3268
3269                                 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3270                                         if (super != NULL) {
3271                                                 M_TEST(s1);
3272                                                 M_BEQ(s2);
3273                                         }
3274
3275                                         M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3276
3277                                         if (super == NULL) {
3278                                                 codegen_add_patch_ref(cd,
3279                                                                                           PATCHER_checkcast_instanceof_interface,
3280                                                                                           iptr->sx.s23.s3.c.ref,
3281                                                                                           0);
3282                                         }
3283
3284                                         emit_movl_membase32_reg(cd, REG_ITMP2,
3285                                                                                           OFFSET(vftbl_t, interfacetablelength),
3286                                                                                           REG_ITMP3);
3287                                         /* XXX TWISTI: should this be int arithmetic? */
3288                                         M_LSUB_IMM32(superindex, REG_ITMP3);
3289                                         M_TEST(REG_ITMP3);
3290                                         M_BLE(0);
3291                                         codegen_add_classcastexception_ref(cd, s1);
3292                                         emit_mov_membase32_reg(cd, REG_ITMP2,
3293                                                                                          OFFSET(vftbl_t, interfacetable[0]) -
3294                                                                                          superindex * sizeof(methodptr*),
3295                                                                                          REG_ITMP3);
3296                                         M_TEST(REG_ITMP3);
3297                                         M_BEQ(0);
3298                                         codegen_add_classcastexception_ref(cd, s1);
3299
3300                                         if (super == NULL)
3301                                                 M_JMP_IMM(s3);
3302                                 }
3303
3304                                 /* class checkcast code */
3305
3306                                 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3307                                         if (super != NULL) {
3308                                                 M_TEST(s1);
3309                                                 M_BEQ(s3);
3310                                         }
3311
3312                                         M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3313
3314                                         if (super == NULL) {
3315                                                 codegen_add_patch_ref(cd, PATCHER_checkcast_class,
3316                                                                                           iptr->sx.s23.s3.c.ref,
3317                                                                                           0);
3318                                         }
3319
3320                                         M_MOV_IMM(supervftbl, REG_ITMP3);
3321 #if defined(ENABLE_THREADS)
3322                                         codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3323 #endif
3324                                         emit_movl_membase32_reg(cd, REG_ITMP2,
3325                                                                                           OFFSET(vftbl_t, baseval),
3326                                                                                           REG_ITMP2);
3327                                         /*                                      if (s1 != REG_ITMP1) { */
3328                                         /*                                              emit_movl_membase_reg(cd, REG_ITMP3, */
3329                                         /*                                                                                              OFFSET(vftbl_t, baseval), */
3330                                         /*                                                                                              REG_ITMP1); */
3331                                         /*                                              emit_movl_membase_reg(cd, REG_ITMP3, */
3332                                         /*                                                                                              OFFSET(vftbl_t, diffval), */
3333                                         /*                                                                                              REG_ITMP3); */
3334                                         /*  #if defined(ENABLE_THREADS) */
3335                                         /*                                              codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3336                                         /*  #endif */
3337                                         /*                                              emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP1, REG_ITMP2); */
3338
3339                                         /*                                      } else { */
3340                                         emit_movl_membase32_reg(cd, REG_ITMP3,
3341                                                                                           OFFSET(vftbl_t, baseval),
3342                                                                                           REG_ITMP3);
3343                                         M_LSUB(REG_ITMP3, REG_ITMP2);
3344                                         M_MOV_IMM(supervftbl, REG_ITMP3);
3345                                         M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3346                                         /*                                      } */
3347 #if defined(ENABLE_THREADS)
3348                                         codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3349 #endif
3350                                         M_LCMP(REG_ITMP3, REG_ITMP2);
3351                                         M_BA(0);         /* (u) REG_ITMP1 > (u) REG_ITMP2 -> jump */
3352                                         codegen_add_classcastexception_ref(cd, s1);
3353                                 }
3354
3355                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
3356                         }
3357                         else {
3358                                 /* array type cast-check */
3359
3360                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
3361                                 M_INTMOVE(s1, REG_A0);
3362
3363                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3364                                         codegen_add_patch_ref(cd, PATCHER_builtin_arraycheckcast,
3365                                                                                   iptr->sx.s23.s3.c.ref, 0);
3366                                 }
3367
3368                                 M_MOV_IMM(iptr->sx.s23.s3.c.cls, REG_A1);
3369                                 M_MOV_IMM(BUILTIN_arraycheckcast, REG_ITMP1);
3370                                 M_CALL(REG_ITMP1);
3371
3372                                 /* s1 may have been destroyed over the function call */
3373                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
3374                                 M_TEST(REG_RESULT);
3375                                 M_BEQ(0);
3376                                 codegen_add_classcastexception_ref(cd, s1);
3377
3378                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3379                         }
3380
3381                         M_INTMOVE(s1, d);
3382                         emit_store_dst(jd, iptr, d);
3383 #endif
3384                         break;
3385
3386                 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
3387                         OOPS();
3388 #if 0
3389                                       /* val.a: (classinfo*) superclass               */
3390
3391                         /*  superclass is an interface:
3392                          *      
3393                          *  return (sub != NULL) &&
3394                          *         (sub->vftbl->interfacetablelength > super->index) &&
3395                          *         (sub->vftbl->interfacetable[-super->index] != NULL);
3396                          *      
3397                          *  superclass is a class:
3398                          *      
3399                          *  return ((sub != NULL) && (0
3400                          *          <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3401                          *          super->vftbl->diffvall));
3402                          */
3403
3404                         {
3405                         classinfo *super;
3406                         vftbl_t   *supervftbl;
3407                         s4         superindex;
3408
3409                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3410                                 super = NULL;
3411                                 superindex = 0;
3412                                 supervftbl = NULL;
3413
3414                         } else {
3415                                 super = iptr->sx.s23.s3.c.cls;
3416                                 superindex = super->index;
3417                                 supervftbl = super->vftbl;
3418                         }
3419
3420 #if defined(ENABLE_THREADS)
3421                         codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3422 #endif
3423                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3424                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3425                         if (s1 == d) {
3426                                 M_MOV(s1, REG_ITMP1);
3427                                 s1 = REG_ITMP1;
3428                         }
3429
3430                         /* calculate interface instanceof code size */
3431
3432                         s2 = 6;
3433                         if (super == NULL)
3434                                 s2 += (d == REG_ITMP2 ? 1 : 0) + (opt_shownops ? 1 : 0);
3435
3436                         /* calculate class instanceof code size */
3437
3438                         s3 = 7;
3439                         if (super == NULL)
3440                                 s3 += (opt_shownops ? 1 : 0);
3441
3442                         /* if class is not resolved, check which code to call */
3443
3444                         if (super == NULL) {
3445                                 M_CLR(d);
3446                                 M_BEQZ(s1, 4 + (opt_shownops ? 1 : 0) + s2 + 1 + s3);
3447
3448                                 disp = dseg_add_unique_s4(cd, 0);             /* super->flags */
3449
3450                                 codegen_add_patch_ref(cd, PATCHER_resolve_classref_to_flags,
3451                                                                           iptr->sx.s23.s3.c.ref, disp);
3452
3453                                 M_ILD(REG_ITMP3, REG_PV, disp);
3454
3455                                 disp = dseg_add_s4(cd, ACC_INTERFACE);
3456                                 M_ILD(REG_ITMP2, REG_PV, disp);
3457                                 M_AND(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3458                                 M_BEQZ(REG_ITMP3, s2 + 1);
3459                         }
3460
3461                         /* interface instanceof code */
3462
3463                         if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3464                                 if (super == NULL) {
3465                                         /* If d == REG_ITMP2, then it's destroyed in check
3466                                            code above. */
3467                                         if (d == REG_ITMP2)
3468                                                 M_CLR(d);
3469
3470                                         codegen_add_patch_ref(cd,
3471                                                                                   PATCHER_checkcast_instanceof_interface,
3472                                                                                   iptr->sx.s23.s3.c.ref, 0);
3473                                 }
3474                                 else {
3475                                         M_CLR(d);
3476                                         M_BEQZ(s1, s2);
3477                                 }
3478
3479                                 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3480                                 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3481                                 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
3482                                 M_BLEZ(REG_ITMP3, 2);
3483                                 M_ALD(REG_ITMP1, REG_ITMP1,
3484                                           (s4) (OFFSET(vftbl_t, interfacetable[0]) -
3485                                                         superindex * sizeof(methodptr*)));
3486                                 M_CMPULT(REG_ZERO, REG_ITMP1, d);      /* REG_ITMP1 != 0  */
3487
3488                                 if (super == NULL)
3489                                         M_BR(s3);
3490                         }
3491
3492                         /* class instanceof code */
3493
3494                         if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3495                                 if (super == NULL) {
3496                                         disp = dseg_add_unique_address(cd, NULL);
3497
3498                                         codegen_add_patch_ref(cd, PATCHER_resolve_classref_to_vftbl,
3499                                                                                   iptr->sx.s23.s3.c.ref,
3500                                                                                   disp);
3501                                 }
3502                                 else {
3503                                         disp = dseg_add_address(cd, supervftbl);
3504
3505                                         M_CLR(d);
3506                                         M_BEQZ(s1, s3);
3507                                 }
3508
3509                                 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3510                                 M_ALD(REG_ITMP2, REG_PV, disp);
3511 #if defined(ENABLE_THREADS)
3512                                 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3513 #endif
3514                                 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3515                                 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3516                                 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3517 #if defined(ENABLE_THREADS)
3518                                 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3519 #endif
3520                                 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3521                                 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3522                         }
3523                         emit_store_dst(jd, iptr, d);
3524                         }
3525 #endif
3526                         break;
3527
3528                 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref  */
3529                         OOPS();
3530 #if 0
3531
3532                         /* check for negative sizes and copy sizes to stack if necessary  */
3533
3534                         MCODECHECK((10 * 4 * iptr->s1.argcount) + 5 + 10 * 8);
3535
3536                         for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3537
3538                                 /* copy SAVEDVAR sizes to stack */
3539                                 var = VAR(iptr->sx.s23.s2.args[s1]);
3540
3541                                 /* Already Preallocated? */
3542                                 if (!(var->flags & PREALLOC)) {
3543                                         s2 = emit_load(jd, iptr, var, REG_ITMP1);
3544                                         M_LST(s2, REG_SP, s1 * 8);
3545                                 }
3546                         }
3547
3548                         /* is a patcher function set? */
3549
3550                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3551                                 codegen_add_patch_ref(cd, PATCHER_builtin_multianewarray,
3552                                                                           iptr->sx.s23.s3.c.ref, 0);
3553                         }
3554
3555                         /* a0 = dimension count */
3556
3557                         M_MOV_IMM(iptr->s1.argcount, REG_A0);
3558
3559                         /* a1 = classinfo */
3560
3561                         M_MOV_IMM(iptr->sx.s23.s3.c.cls, REG_A1);
3562
3563                         /* a2 = pointer to dimensions = stack pointer */
3564
3565                         M_MOV(REG_SP, REG_A2);
3566
3567                         M_MOV_IMM(BUILTIN_multianewarray, REG_ITMP1);
3568                         M_CALL(REG_ITMP1);
3569
3570                         /* check for exception before result assignment */
3571
3572                         M_TEST(REG_RESULT);
3573                         M_BEQ(0);
3574                         codegen_add_fillinstacktrace_ref(cd);
3575
3576                         s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3577                         M_INTMOVE(REG_RESULT, s1);
3578                         emit_store_dst(jd, iptr, s1);
3579 #endif
3580                         break;
3581
3582                 default:
3583                         exceptions_throw_internalerror("Unknown ICMD %d", iptr->opc);
3584                         return false;
3585         } /* switch */
3586
3587         } /* for instruction */
3588                 
3589         MCODECHECK(512); /* XXX require a lower number? */
3590
3591         /* At the end of a basic block we may have to append some nops,
3592            because the patcher stub calling code might be longer than the
3593            actual instruction. So codepatching does not change the
3594            following block unintentionally. */
3595
3596         if (cd->mcodeptr < cd->lastmcodeptr) {
3597                 while (cd->mcodeptr < cd->lastmcodeptr) {
3598                         M_NOP;
3599                 }
3600         }
3601
3602         } /* if (bptr -> flags >= BBREACHED) */
3603         } /* for basic block */
3604
3605         dseg_createlinenumbertable(cd);
3606
3607         /* generate stubs */
3608
3609         emit_exception_stubs(jd);
3610         emit_patcher_stubs(jd);
3611 #if 0
3612         emit_replacement_stubs(jd);
3613 #endif
3614
3615         codegen_finish(jd);
3616
3617         /* everything's ok */
3618
3619         return true;
3620 }
3621
3622
3623 /* createcompilerstub **********************************************************
3624
3625    Creates a stub routine which calls the compiler.
3626         
3627 *******************************************************************************/
3628
3629 #define COMPILERSTUB_DATASIZE    (3 * SIZEOF_VOID_P)
3630 #define COMPILERSTUB_CODESIZE    (SZ_BRAS + SZ_AHI + (2 * SZ_L) + SZ_BR)
3631
3632 #define COMPILERSTUB_SIZE        (COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE)
3633
3634
3635 u1 *createcompilerstub(methodinfo *m)
3636 {
3637         u1          *s;                     /* memory to hold the stub            */
3638         ptrint      *d;
3639         codeinfo    *code;
3640         codegendata *cd;
3641         s4           dumpsize;
3642
3643         s = CNEW(u1, COMPILERSTUB_SIZE);
3644
3645         /* set data pointer and code pointer */
3646
3647         d = (ptrint *) s;
3648         s = s + COMPILERSTUB_DATASIZE;
3649
3650         /* mark start of dump memory area */
3651
3652         dumpsize = dump_size();
3653
3654         cd = DNEW(codegendata);
3655         cd->mcodeptr = s;
3656
3657         /* Store the codeinfo pointer in the same place as in the
3658            methodheader for compiled methods. */
3659
3660         code = code_codeinfo_new(m);
3661
3662         d[0] = (ptrint) asm_call_jit_compiler;
3663         d[1] = (ptrint) m;
3664         d[2] = (ptrint) code;
3665
3666         /* code for the stub */
3667
3668         /* don't touch ITMP3 as it cointains the return address */
3669
3670         M_ILD(REG_ITMP1, REG_PV, -2 * 4); /* methodinfo  */
3671         /* TODO where is methodpointer loaded into itmp2? is it already inside? */
3672         M_ILD(REG_PV, REG_PV, -3 * 4); /* compiler pointer */
3673         N_BR(REG_PV);
3674
3675 #if defined(ENABLE_STATISTICS)
3676         if (opt_stat)
3677                 count_cstub_len += COMPILERSTUB_SIZE;
3678 #endif
3679
3680         /* release dump area */
3681
3682         dump_release(dumpsize);
3683
3684         return s;
3685 }
3686
3687
3688 /* createnativestub ************************************************************
3689
3690    Creates a stub routine which calls a native method.
3691
3692 *******************************************************************************/
3693
3694 /*
3695            arguments on stack                   \
3696 -------------------------------------------------| <- SP on nativestub entry
3697            return address                        |
3698            callee saved int regs (none)          |
3699            callee saved float regs (none)        | stack frame like in cacao
3700            local variable slots (none)           |
3701            arguments for calling methods (none) /
3702 ------------------------------------------------------------------ <- datasp 
3703            stackframe info
3704            locaref table
3705            integer arguments
3706            float arguments
3707 96 - ...   on stack parameters (nmd->memuse slots) \ stack frame like in ABI         
3708 0 - 96     register save area for callee           /
3709 -------------------------------------------------------- <- SP native method
3710                                                             ==
3711                                                             SP after method entry
3712 */
3713
3714 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
3715 {
3716         methodinfo   *m;
3717         codeinfo     *code;
3718         codegendata  *cd;
3719         registerdata *rd;
3720         methoddesc   *md;
3721         s4            nativeparams;
3722         s4            i, j;                 /* count variables                    */
3723         s4            t;
3724         s4            s1, s2;
3725         s4            disp;
3726
3727         /* get required compiler data */
3728
3729         m    = jd->m;
3730         code = jd->code;
3731         cd   = jd->cd;
3732         rd   = jd->rd;
3733
3734         /* initialize variables */
3735
3736         md = m->parseddesc;
3737         nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3738
3739         /* calculate stack frame size */
3740 #if 0
3741         cd->stackframesize =
3742                 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3743                 sizeof(localref_table) / SIZEOF_VOID_P +
3744                 INT_ARG_CNT + FLT_ARG_CNT +
3745                 1 +                       /* functionptr, TODO: store in data segment */
3746                 nmd->memuse;
3747
3748         cd->stackframesize |= 0x1;                  /* keep stack 16-byte aligned */
3749 #endif
3750
3751         cd->stackframesize = 
3752                 1 + /* r14 - return address */ +
3753                 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3754                 sizeof(localref_table) / SIZEOF_VOID_P +
3755                 1 + /* itmp3 */
3756                 (INT_ARG_CNT + FLT_ARG_CNT) * 2 +
3757                 nmd->memuse + /* parameter passing */
3758                 96 / SIZEOF_VOID_P /* required by ABI */;
3759
3760
3761         /* create method header */
3762
3763         (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
3764         (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize       */
3765         (void) dseg_add_unique_s4(cd, 0);                      /* IsSync          */
3766         (void) dseg_add_unique_s4(cd, 0);                      /* IsLeaf          */
3767         (void) dseg_add_unique_s4(cd, 0);                      /* IntSave         */
3768         (void) dseg_add_unique_s4(cd, 0);                      /* FltSave         */
3769         (void) dseg_addlinenumbertablesize(cd);
3770         (void) dseg_add_unique_s4(cd, 0);                      /* ExTableSize     */
3771
3772         /* generate native method profiling code */
3773 #if 0
3774         if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
3775                 /* count frequency */
3776
3777                 M_MOV_IMM(code, REG_ITMP3);
3778                 M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
3779         }
3780 #endif
3781
3782         /* generate stub code */
3783
3784         N_AHI(REG_SP, -(cd->stackframesize * SIZEOF_VOID_P));
3785
3786         /* save return address */
3787
3788         N_ST(R14, (cd->stackframesize - 1) * SIZEOF_VOID_P, RN, REG_SP);
3789
3790 #if 0
3791 #if !defined(NDEBUG)
3792         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3793                 emit_verbosecall_enter(jd);
3794 #endif
3795 #endif
3796
3797         /* get function address (this must happen before the stackframeinfo) */
3798
3799 #if !defined(WITH_STATIC_CLASSPATH)
3800         if (f == NULL)
3801                 codegen_add_patch_ref(cd, PATCHER_resolve_native, m, 0);
3802 #endif
3803
3804         disp = dseg_add_functionptr(cd, f);
3805         M_ILD(REG_ITMP1, REG_PV, disp);
3806
3807         j = 96 + (nmd->memuse * 4);
3808
3809         /* todo some arg registers are not volatile in C-abi terms */
3810
3811         /* save integer and float argument registers */
3812
3813         for (i = 0; i < md->paramcount; i++) {
3814                 if (! md->params[i].inmemory) {
3815                         s1 = md->params[i].regoff;
3816
3817                         if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
3818                                 if (IS_2_WORD_TYPE(t)) {
3819                                         /* todo store multiple */
3820                                         N_ST(rd->argintregs[GET_HIGH_REG(s1)], j, RN, REG_SP);
3821                                         N_ST(rd->argintregs[GET_LOW_REG(s1)], j + 4, RN, REG_SP);
3822                                 } else {
3823                                         N_ST(rd->argintregs[s1], j, RN, REG_SP);
3824                                 }
3825                         } else {
3826                                 if (IS_2_WORD_TYPE(t)) {
3827                                         N_STD(rd->argfltregs[s1], j, RN, REG_SP);
3828                                 } else {
3829                                         N_STE(rd->argfltregs[s1], j, RN, REG_SP);
3830                                 }
3831                         }
3832
3833                         j += 8;
3834                 }
3835         }
3836
3837         N_ST(REG_ITMP1, j, RN, REG_SP);
3838
3839         /* create dynamic stack info */
3840
3841         N_LAE(REG_A0, (cd->stackframesize - 1) * 4, RN, REG_SP); /* datasp */
3842         N_LR(REG_A1, REG_PV); /* pv */
3843         N_LAE(REG_A2, cd->stackframesize * 4, RN, REG_SP); /* old SP */
3844         N_L(REG_A3, (cd->stackframesize - 1) * 4, RN, REG_SP); /* return address */
3845
3846         disp = dseg_add_functionptr(cd, codegen_start_native_call);
3847         M_ILD(REG_ITMP1, REG_PV, disp);
3848
3849         M_CALL(REG_ITMP1); /* call */
3850
3851         /* restore integer and float argument registers */
3852
3853         j = 96 + (nmd->memuse * 4);
3854
3855         for (i = 0; i < md->paramcount; i++) {
3856                 if (! md->params[i].inmemory) {
3857                         s1 = md->params[i].regoff;
3858
3859                         if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
3860                                 if (IS_2_WORD_TYPE(t)) {
3861                                         /* todo load multiple ! */
3862                                         N_L(rd->argintregs[GET_HIGH_REG(s1)], j, RN, REG_SP);
3863                                         N_L(rd->argintregs[GET_LOW_REG(s1)], j + 4, RN, REG_SP);
3864                                 } else {
3865                                         N_L(rd->argintregs[s1], j, RN, REG_SP);
3866                                 }
3867                         } else {
3868                                 if (IS_2_WORD_TYPE(t)) {
3869                                         N_LD(rd->argfltregs[s1], j, RN, REG_SP);
3870                                 } else {
3871                                         N_LE(rd->argfltregs[s1], j, RN, REG_SP);
3872                                 }
3873                         }
3874
3875                         j += 8;
3876                 }
3877         }
3878
3879         N_L(REG_ITMP1, j, RN, REG_SP);
3880
3881         /* copy or spill arguments to new locations */
3882
3883         for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3884                 t = md->paramtypes[i].type;
3885
3886                 if (IS_INT_LNG_TYPE(t)) {
3887
3888                         if (!md->params[i].inmemory) {
3889
3890                                 s1 = rd->argintregs[md->params[i].regoff];
3891
3892                                 if (!nmd->params[j].inmemory) {
3893                                         s2 = rd->argintregs[nmd->params[j].regoff];
3894                                         if (IS_2_WORD_TYPE(t)) {
3895                                                 N_LR(GET_HIGH_REG(s2), GET_HIGH_REG(s1));
3896                                                 N_LR(GET_LOW_REG(s2), GET_LOW_REG(s1));
3897                                         } else {
3898                                                 N_LR(s2, s1);
3899                                         }
3900                                 } else {
3901                                         s2 = nmd->params[j].regoff;
3902                                         if (IS_2_WORD_TYPE(t)) {
3903                                                 N_LM(GET_LOW_REG(s1), GET_HIGH_REG(s1), 96 + (s2 * 4), REG_SP);
3904                                         } else {
3905                                                 N_L(s1, 96 + (s2 * 4), RN, REG_SP);
3906                                         }
3907                                 }
3908
3909                         } else {
3910                                 s1 = md->params[i].regoff + cd->stackframesize + 1;   /* + 1 (RA) */
3911                                 s2 = nmd->params[j].regoff;
3912                                 
3913                                 if (IS_2_WORD_TYPE(t)) {
3914                                         N_MVC(96 + (s2 * 4), 8, REG_SP, s1, REG_SP);
3915                                 } else {
3916                                         N_MVC(96 + (s2 * 4), 4, REG_SP, s1, REG_SP);
3917                                 }
3918                         }
3919
3920                 } else {
3921                         /* We only copy spilled float arguments, as the float argument    */
3922                         /* registers keep unchanged.                                      */
3923
3924                         if (md->params[i].inmemory) {
3925                                 s1 = md->params[i].regoff + cd->stackframesize + 1;   /* + 1 (RA) */
3926                                 s2 = nmd->params[j].regoff;
3927
3928                                 if (IS_2_WORD_TYPE(t)) {
3929                                         N_MVC(96 + (s2 * 4), 8, REG_SP, s1, REG_SP);
3930                                 } else {
3931                                         N_MVC(96 + (s2 * 4), 4, REG_SP, s1, REG_SP);
3932                                 }
3933                         }
3934                 }
3935         }
3936
3937         /* put class into second argument register */
3938
3939         if (m->flags & ACC_STATIC) {
3940                 disp = dseg_add_address(cd, m->class);
3941                 M_ILD(REG_A1, REG_PV, disp);
3942         }
3943
3944         /* put env into first argument register */
3945
3946         disp = dseg_add_address(cd, _Jv_env);
3947         M_ILD(REG_A0, REG_PV, disp);
3948
3949         /* do the native function call */
3950
3951         M_CALL(REG_ITMP1); /* call */
3952
3953         /* save return value */
3954
3955         t = md->returntype.type;
3956
3957         if (t != TYPE_VOID) {
3958                 if (IS_INT_LNG_TYPE(t)) {
3959                         if (IS_2_WORD_TYPE(t)) {
3960                                 N_STM(REG_RESULT, REG_RESULT2, 96, REG_SP);
3961                         } else {
3962                                 N_ST(REG_RESULT, 96, RN, REG_SP);
3963                         }
3964                 } else {
3965                         if (IS_2_WORD_TYPE(t)) {
3966                                 N_STD(REG_FRESULT, 96, RN, REG_SP);
3967                         } else {
3968                                 N_STE(REG_FRESULT, 96, RN, REG_SP);
3969                         }
3970                 }
3971         }
3972
3973 #if 0
3974 #if !defined(NDEBUG)
3975         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3976                 emit_verbosecall_exit(jd);
3977 #endif
3978 #endif
3979
3980         /* remove native stackframe info */
3981
3982         N_LAE(REG_A0, cd->stackframesize * 4, RN, REG_SP);
3983         disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3984         M_ILD(REG_ITMP1, REG_PV, disp);
3985         M_CALL(REG_ITMP1);
3986         N_LR(REG_ITMP3, REG_RESULT);
3987
3988         /* restore return value */
3989
3990         if (t != TYPE_VOID) {
3991                 if (IS_INT_LNG_TYPE(t)) {
3992                         if (IS_2_WORD_TYPE(t)) {
3993                                 N_LM(REG_RESULT, REG_RESULT2, 96, REG_SP);
3994                         } else {
3995                                 N_L(REG_RESULT, 96, RN, REG_SP);
3996                         }
3997                 } else {
3998                         if (IS_2_WORD_TYPE(t)) {
3999                                 N_LD(REG_FRESULT, 96, RN, REG_SP);
4000                         } else {
4001                                 N_LE(REG_FRESULT, 96, RN, REG_SP);
4002                         }
4003                 }
4004         }
4005
4006         /* remove stackframe */
4007
4008         N_AHI(REG_SP, cd->stackframesize * 4);
4009
4010         /* test for exception */
4011
4012         N_LTR(REG_ITMP3, REG_ITMP3);
4013         N_BRC(DD_NE, SZ_BRC + SZ_BC);
4014         N_BC(DD_ANY, 0, RN, REG_SP); /* return */
4015
4016         /* handle exception */
4017
4018         N_LONG_0();
4019
4020 #if 0
4021         M_MOV(REG_ITMP3, REG_ITMP1_XPTR);
4022         M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);     /* get return address from stack */
4023         M_ASUB_IMM(3, REG_ITMP2_XPC);                                    /* callq */
4024
4025         M_MOV_IMM(asm_handle_nat_exception, REG_ITMP3);
4026         M_JMP(REG_ITMP3);
4027
4028         /* generate patcher stubs */
4029
4030         emit_patcher_stubs(jd);
4031
4032 #endif
4033         codegen_finish(jd);
4034
4035         return code->entrypoint;
4036         return NULL;
4037 }
4038
4039
4040
4041 /*
4042  * These are local overrides for various environment variables in Emacs.
4043  * Please do not remove this and leave it at the end of the file, where
4044  * Emacs will automagically detect them.
4045  * ---------------------------------------------------------------------
4046  * Local variables:
4047  * mode: c
4048  * indent-tabs-mode: t
4049  * c-basic-offset: 4
4050  * tab-width: 4
4051  * End:
4052  * vim:noexpandtab:sw=4:ts=4:
4053  */