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