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