* Merged in new trap code (twisti-branch).
[cacao.git] / src / vm / jit / x86_64 / codegen.c
1 /* src/vm/jit/x86_64/codegen.c - machine code generator for x86_64
2
3    Copyright (C) 1996-2005, 2006, 2007 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 */
26
27
28 #include "config.h"
29
30 #include <assert.h>
31 #include <stdio.h>
32 #include <stdint.h>
33
34 #include "vm/types.h"
35
36 #include "md-abi.h"
37
38 #include "vm/jit/x86_64/arch.h"
39 #include "vm/jit/x86_64/codegen.h"
40 #include "vm/jit/x86_64/emit.h"
41
42 #include "mm/memory.h"
43
44 #include "native/jni.h"
45 #include "native/localref.h"
46 #include "native/native.h"
47
48 #include "threads/lock-common.h"
49
50 #include "vm/builtin.h"
51 #include "vm/exceptions.h"
52 #include "vm/global.h"
53 #include "vm/stringlocal.h"
54 #include "vm/vm.h"
55
56 #include "vm/jit/abi.h"
57 #include "vm/jit/asmpart.h"
58 #include "vm/jit/code.h"
59 #include "vm/jit/codegen-common.h"
60 #include "vm/jit/dseg.h"
61 #include "vm/jit/emit-common.h"
62 #include "vm/jit/jit.h"
63 #include "vm/jit/linenumbertable.h"
64 #include "vm/jit/methodheader.h"
65 #include "vm/jit/parse.h"
66 #include "vm/jit/patcher-common.h"
67 #include "vm/jit/reg.h"
68 #include "vm/jit/replace.h"
69 #include "vm/jit/stacktrace.h"
70 #include "vm/jit/trap.h"
71
72 #if defined(ENABLE_LSRA)
73 # include "vm/jit/allocator/lsra.h"
74 #endif
75
76 #include "vmcore/loader.h"
77 #include "vmcore/options.h"
78 #include "vmcore/statistics.h"
79
80
81 /* codegen_emit ****************************************************************
82
83    Generates machine code.
84
85 *******************************************************************************/
86
87 bool codegen_emit(jitdata *jd)
88 {
89         methodinfo         *m;
90         codeinfo           *code;
91         codegendata        *cd;
92         registerdata       *rd;
93         s4                  len, s1, s2, s3, d, disp;
94         u2                  currentline;
95         ptrint              a;
96         varinfo            *var, *dst;
97         basicblock         *bptr;
98         instruction        *iptr;
99         constant_classref  *cr;
100         unresolved_class   *uc;
101         methodinfo         *lm;             /* local methodinfo for ICMD_INVOKE*  */
102         unresolved_method  *um;
103         builtintable_entry *bte;
104         methoddesc         *md;
105         fieldinfo          *fi;
106         unresolved_field   *uf;
107         s4                  fieldtype;
108         s4                 varindex;
109
110         /* get required compiler data */
111
112         m    = jd->m;
113         code = jd->code;
114         cd   = jd->cd;
115         rd   = jd->rd;
116
117         /* prevent compiler warnings */
118
119         d   = 0;
120         lm  = NULL;
121         um  = NULL;
122         bte = NULL;
123
124         {
125         s4 i, p, t, l;
126         s4 savedregs_num;
127
128         savedregs_num = 0;
129
130         /* space to save used callee saved registers */
131
132         savedregs_num += (INT_SAV_CNT - rd->savintreguse);
133         savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
134
135         cd->stackframesize = rd->memuse + savedregs_num;
136
137 #if defined(ENABLE_THREADS)
138         /* space to save argument of monitor_enter */
139
140         if (checksync && code_is_synchronized(code))
141                 cd->stackframesize++;
142 #endif
143
144         /* Keep stack of non-leaf functions 16-byte aligned for calls into
145            native code e.g. libc or jni (alignment problems with
146            movaps). */
147
148         if (!code_is_leafmethod(code) || opt_verbosecall)
149                 cd->stackframesize |= 0x1;
150
151         /* create method header */
152
153         (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
154         (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize       */
155
156         code->synchronizedoffset = rd->memuse * 8;
157
158         if (code_is_leafmethod(code))
159                 (void) dseg_add_unique_s4(cd, 1);                  /* IsLeaf          */
160         else
161                 (void) dseg_add_unique_s4(cd, 0);                  /* IsLeaf          */
162
163         (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
164         (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
165
166 #if defined(ENABLE_PROFILING)
167         /* generate method profiling code */
168
169         if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
170                 /* count frequency */
171
172                 M_MOV_IMM(code, REG_ITMP3);
173                 M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
174
175                 PROFILE_CYCLE_START;
176         }
177 #endif
178
179         /* create stack frame (if necessary) */
180
181         if (cd->stackframesize)
182                 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
183
184         /* save used callee saved registers */
185
186         p = cd->stackframesize;
187         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
188                 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
189         }
190         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
191                 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
192         }
193
194         /* take arguments out of register or stack frame */
195
196         md = m->parseddesc;
197
198         for (p = 0, l = 0; p < md->paramcount; p++) {
199                 t = md->paramtypes[p].type;
200
201                 varindex = jd->local_map[l * 5 + t];
202
203                 l++;
204                 if (IS_2_WORD_TYPE(t))    /* increment local counter for 2 word types */
205                         l++;
206
207                 if (varindex == UNUSED)
208                         continue;
209
210                 var = VAR(varindex);
211                 
212                 s1 = md->params[p].regoff;
213
214                 if (IS_INT_LNG_TYPE(t)) {                    /* integer args          */
215                         if (!md->params[p].inmemory) {           /* register arguments    */
216                                 if (!IS_INMEMORY(var->flags))
217                                         M_INTMOVE(s1, var->vv.regoff);
218                                 else
219                                     M_LST(s1, REG_SP, var->vv.regoff);
220                         }
221                         else {                                 /* stack arguments       */
222                                 if (!IS_INMEMORY(var->flags))
223                                         /* + 8 for return address */
224                                         M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1 + 8);
225                                 else
226                                         var->vv.regoff = cd->stackframesize * 8 + s1 + 8;
227                         }
228                 }
229                 else {                                     /* floating args         */
230                         if (!md->params[p].inmemory) {           /* register arguments    */
231                                 if (!IS_INMEMORY(var->flags))
232                                         M_FLTMOVE(s1, var->vv.regoff);
233                                 else
234                                         M_DST(s1, REG_SP, var->vv.regoff);
235                         }
236                         else {                                 /* stack arguments       */
237                                 if (!IS_INMEMORY(var->flags))
238                                         M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1 + 8);
239                                 else
240                                         var->vv.regoff = cd->stackframesize * 8 + s1 + 8;
241                         }
242                 }
243         }
244
245         /* save monitorenter argument */
246
247 #if defined(ENABLE_THREADS)
248         if (checksync && code_is_synchronized(code)) {
249                 /* stack offset for monitor argument */
250
251                 s1 = rd->memuse;
252
253                 if (opt_verbosecall) {
254                         M_LSUB_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
255
256                         for (p = 0; p < INT_ARG_CNT; p++)
257                                 M_LST(abi_registers_integer_argument[p], REG_SP, p * 8);
258
259                         for (p = 0; p < FLT_ARG_CNT; p++)
260                                 M_DST(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
261
262                         s1 += INT_ARG_CNT + FLT_ARG_CNT;
263                 }
264
265                 /* decide which monitor enter function to call */
266
267                 if (m->flags & ACC_STATIC) {
268                         M_MOV_IMM(&m->clazz->object.header, REG_A0);
269                 }
270                 else {
271                         M_TEST(REG_A0);
272                         M_BNE(8);
273                         M_ALD_MEM(REG_A0, TRAP_NullPointerException);
274                 }
275
276                 M_AST(REG_A0, REG_SP, s1 * 8);
277                 M_MOV_IMM(LOCK_monitor_enter, REG_ITMP1);
278                 M_CALL(REG_ITMP1);
279
280                 if (opt_verbosecall) {
281                         for (p = 0; p < INT_ARG_CNT; p++)
282                                 M_LLD(abi_registers_integer_argument[p], REG_SP, p * 8);
283
284                         for (p = 0; p < FLT_ARG_CNT; p++)
285                                 M_DLD(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
286
287                         M_LADD_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
288                 }
289         }
290 #endif
291
292 #if !defined(NDEBUG)
293         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
294                 emit_verbosecall_enter(jd);
295 #endif /* !defined(NDEBUG) */
296
297         }
298
299         /* end of header generation */
300
301         /* create replacement points */
302
303         REPLACEMENT_POINTS_INIT(cd, jd);
304
305         /* walk through all basic blocks */
306
307         for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
308
309                 bptr->mpc = (u4) ((u1 *) cd->mcodeptr - cd->mcodebase);
310
311                 if (bptr->flags >= BBREACHED) {
312
313                 /* branch resolving */
314
315                 codegen_resolve_branchrefs(cd, bptr);
316
317                 /* handle replacement points */
318
319                 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
320
321                 /* copy interface registers to their destination */
322
323                 len = bptr->indepth;
324                 MCODECHECK(512);
325
326 #if defined(ENABLE_PROFILING)
327                 /* generate basicblock profiling code */
328
329                 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
330                         /* count frequency */
331
332                         M_MOV_IMM(code->bbfrequency, REG_ITMP3);
333                         M_IINC_MEMBASE(REG_ITMP3, bptr->nr * 4);
334
335                         /* if this is an exception handler, start profiling again */
336
337                         if (bptr->type == BBTYPE_EXH)
338                                 PROFILE_CYCLE_START;
339                 }
340 #endif
341
342 #if defined(ENABLE_LSRA)
343                 if (opt_lsra) {
344                         while (len) {
345                                 len--;
346                                 src = bptr->invars[len];
347                                 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
348                                         if (bptr->type == BBTYPE_EXH) {
349 /*                                      d = reg_of_var(rd, src, REG_ITMP1); */
350                                                 if (!IS_INMEMORY(src->flags))
351                                                         d= src->vv.regoff;
352                                                 else
353                                                         d=REG_ITMP1;
354                                                 M_INTMOVE(REG_ITMP1, d);
355                                                 emit_store(jd, NULL, src, d);
356                                         }
357                                 }
358                         }
359                         
360                 } else {
361 #endif
362
363                 while (len) {
364                         len--;
365                         var = VAR(bptr->invars[len]);
366                         if ((len ==  bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
367                                 if (bptr->type == BBTYPE_EXH) {
368                                         d = codegen_reg_of_var(0, var, REG_ITMP1);
369                                         M_INTMOVE(REG_ITMP1, d);
370                                         emit_store(jd, NULL, var, d);
371                                 }
372                         } 
373                         else {
374                                 assert((var->flags & INOUT));
375                         }
376                 }
377 #if defined(ENABLE_LSRA)
378                 }
379 #endif
380                 /* walk through all instructions */
381                 
382                 len = bptr->icount;
383                 currentline = 0;
384
385                 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
386                         if (iptr->line != currentline) {
387                                 linenumbertable_list_entry_add(cd, iptr->line);
388                                 currentline = iptr->line;
389                         }
390
391                         MCODECHECK(1024);                         /* 1KB should be enough */
392
393                 switch (iptr->opc) {
394                 case ICMD_NOP:        /* ...  ==> ...                                 */
395                 case ICMD_POP:        /* ..., value  ==> ...                          */
396                 case ICMD_POP2:       /* ..., value, value  ==> ...                   */
397                         break;
398
399                 case ICMD_INLINE_START:
400
401                         REPLACEMENT_POINT_INLINE_START(cd, iptr);
402                         break;
403
404                 case ICMD_INLINE_BODY:
405
406                         REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
407                         linenumbertable_list_entry_add_inline_start(cd, iptr);
408                         linenumbertable_list_entry_add(cd, iptr->line);
409                         break;
410
411                 case ICMD_INLINE_END:
412
413                         linenumbertable_list_entry_add_inline_end(cd, iptr);
414                         linenumbertable_list_entry_add(cd, iptr->line);
415                         break;
416
417                 case ICMD_CHECKNULL:  /* ..., objectref  ==> ..., objectref           */
418
419                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
420                         emit_nullpointer_check(cd, iptr, s1);
421                         break;
422
423                 /* constant operations ************************************************/
424
425                 case ICMD_ICONST:     /* ...  ==> ..., constant                       */
426
427                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
428                         ICONST(d, iptr->sx.val.i);
429                         emit_store_dst(jd, iptr, d);
430                         break;
431
432                 case ICMD_LCONST:     /* ...  ==> ..., constant                       */
433
434                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
435                         LCONST(d, iptr->sx.val.l);
436                         emit_store_dst(jd, iptr, d);
437                         break;
438
439                 case ICMD_FCONST:     /* ...  ==> ..., constant                       */
440
441                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
442                         disp = dseg_add_float(cd, iptr->sx.val.f);
443                         emit_movdl_membase_reg(cd, RIP, -((cd->mcodeptr + ((d > 7) ? 9 : 8)) - cd->mcodebase) + disp, d);
444                         emit_store_dst(jd, iptr, d);
445                         break;
446                 
447                 case ICMD_DCONST:     /* ...  ==> ..., constant                       */
448
449                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
450                         disp = dseg_add_double(cd, iptr->sx.val.d);
451                         emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, d);
452                         emit_store_dst(jd, iptr, d);
453                         break;
454
455                 case ICMD_ACONST:     /* ...  ==> ..., constant                       */
456
457                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
458
459                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
460                                 cr   = iptr->sx.val.c.ref;
461                                 disp = dseg_add_unique_address(cd, cr);
462
463 /*                              PROFILE_CYCLE_STOP; */
464
465                                 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
466                                                                           cr, disp);
467
468 /*                              PROFILE_CYCLE_START; */
469
470                                 M_ALD(d, RIP, disp);
471                         }
472                         else {
473                                 if (iptr->sx.val.anyptr == 0) {
474                                         M_CLR(d);
475                                 }
476                                 else {
477                                         disp = dseg_add_address(cd, iptr->sx.val.anyptr);
478                                         M_ALD(d, RIP, disp);
479                                 }
480                         }
481                         emit_store_dst(jd, iptr, d);
482                         break;
483
484
485                 /* load/store/copy/move operations ************************************/
486
487                 case ICMD_ILOAD:      /* ...  ==> ..., content of local variable      */
488                 case ICMD_ALOAD:      /* s1 = local variable                          */
489                 case ICMD_LLOAD:
490                 case ICMD_FLOAD:  
491                 case ICMD_DLOAD:  
492                 case ICMD_ISTORE:     /* ..., value  ==> ...                          */
493                 case ICMD_LSTORE:
494                 case ICMD_FSTORE:
495                 case ICMD_DSTORE: 
496                 case ICMD_COPY:
497                 case ICMD_MOVE:
498                         
499                         emit_copy(jd, iptr);
500                         break;
501
502                 case ICMD_ASTORE:
503                         if (!(iptr->flags.bits & INS_FLAG_RETADDR))
504                                 emit_copy(jd, iptr);
505                         break;
506
507                 /* integer operations *************************************************/
508
509                 case ICMD_INEG:       /* ..., value  ==> ..., - value                 */
510
511                         s1 = emit_load_s1(jd, iptr, REG_ITMP1); 
512                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
513                         M_INTMOVE(s1, d);
514                         M_INEG(d);
515                         emit_store_dst(jd, iptr, d);
516                         break;
517
518                 case ICMD_LNEG:       /* ..., value  ==> ..., - value                 */
519
520                         s1 = emit_load_s1(jd, iptr, REG_ITMP1); 
521                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
522                         M_INTMOVE(s1, d);
523                         M_LNEG(d);
524                         emit_store_dst(jd, iptr, d);
525                         break;
526
527                 case ICMD_I2L:        /* ..., value  ==> ..., value                   */
528
529                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
530                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
531                         M_ISEXT(s1, d);
532                         emit_store_dst(jd, iptr, d);
533                         break;
534
535                 case ICMD_L2I:        /* ..., value  ==> ..., value                   */
536
537                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
538                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
539                         M_IMOV(s1, d);
540                         emit_store_dst(jd, iptr, d);
541                         break;
542
543                 case ICMD_INT2BYTE:   /* ..., value  ==> ..., value                   */
544
545                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
546                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
547                         M_BSEXT(s1, d);
548                         emit_store_dst(jd, iptr, d);
549                         break;
550
551                 case ICMD_INT2CHAR:   /* ..., value  ==> ..., value                   */
552
553                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
554                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
555                         M_CZEXT(s1, d);
556                         emit_store_dst(jd, iptr, d);
557                         break;
558
559                 case ICMD_INT2SHORT:  /* ..., value  ==> ..., value                   */
560
561                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
562                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
563                         M_SSEXT(s1, d);
564                         emit_store_dst(jd, iptr, d);
565                         break;
566
567
568                 case ICMD_IADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
569
570                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
571                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
572                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
573                         if (s2 == d)
574                                 M_IADD(s1, d);
575                         else {
576                                 M_INTMOVE(s1, d);
577                                 M_IADD(s2, d);
578                         }
579                         emit_store_dst(jd, iptr, d);
580                         break;
581
582                 case ICMD_IINC:
583                 case ICMD_IADDCONST:  /* ..., value  ==> ..., value + constant        */
584                                       /* sx.val.i = constant                             */
585
586                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
587                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
588
589                         /* Using inc and dec is not faster than add (tested with
590                            sieve). */
591
592                         M_INTMOVE(s1, d);
593                         M_IADD_IMM(iptr->sx.val.i, d);
594                         emit_store_dst(jd, iptr, d);
595                         break;
596
597                 case ICMD_LADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
598
599                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
600                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
601                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
602                         if (s2 == d)
603                                 M_LADD(s1, d);
604                         else {
605                                 M_INTMOVE(s1, d);
606                                 M_LADD(s2, d);
607                         }
608                         emit_store_dst(jd, iptr, d);
609                         break;
610
611                 case ICMD_LADDCONST:  /* ..., value  ==> ..., value + constant        */
612                                       /* sx.val.l = constant                             */
613
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                         if (IS_IMM32(iptr->sx.val.l))
618                                 M_LADD_IMM(iptr->sx.val.l, d);
619                         else {
620                                 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
621                                 M_LADD(REG_ITMP2, d);
622                         }
623                         emit_store_dst(jd, iptr, d);
624                         break;
625
626                 case ICMD_ISUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
627
628                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
629                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
630                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
631                         if (s2 == d) {
632                                 M_INTMOVE(s1, REG_ITMP1);
633                                 M_ISUB(s2, REG_ITMP1);
634                                 M_INTMOVE(REG_ITMP1, d);
635                         } else {
636                                 M_INTMOVE(s1, d);
637                                 M_ISUB(s2, d);
638                         }
639                         emit_store_dst(jd, iptr, d);
640                         break;
641
642                 case ICMD_ISUBCONST:  /* ..., value  ==> ..., value + constant        */
643                                       /* sx.val.i = constant                             */
644
645                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
646                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
647                         M_INTMOVE(s1, d);
648                         M_ISUB_IMM(iptr->sx.val.i, d);
649                         emit_store_dst(jd, iptr, d);
650                         break;
651
652                 case ICMD_LSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
653
654                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
655                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
656                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
657                         if (s2 == d) {
658                                 M_INTMOVE(s1, REG_ITMP1);
659                                 M_LSUB(s2, REG_ITMP1);
660                                 M_INTMOVE(REG_ITMP1, d);
661                         } else {
662                                 M_INTMOVE(s1, d);
663                                 M_LSUB(s2, d);
664                         }
665                         emit_store_dst(jd, iptr, d);
666                         break;
667
668                 case ICMD_LSUBCONST:  /* ..., value  ==> ..., value - constant        */
669                                       /* sx.val.l = constant                             */
670
671                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
672                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
673                         M_INTMOVE(s1, d);
674                         if (IS_IMM32(iptr->sx.val.l))
675                                 M_LSUB_IMM(iptr->sx.val.l, d);
676                         else {
677                                 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
678                                 M_LSUB(REG_ITMP2, d);
679                         }
680                         emit_store_dst(jd, iptr, d);
681                         break;
682
683                 case ICMD_IMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
684
685                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
686                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
687                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
688                         if (s2 == d)
689                                 M_IMUL(s1, d);
690                         else {
691                                 M_INTMOVE(s1, d);
692                                 M_IMUL(s2, d);
693                         }
694                         emit_store_dst(jd, iptr, d);
695                         break;
696
697                 case ICMD_IMULCONST:  /* ..., value  ==> ..., value * constant        */
698                                       /* sx.val.i = constant                             */
699
700                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
701                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
702                         if (iptr->sx.val.i == 2) {
703                                 M_INTMOVE(s1, d);
704                                 M_ISLL_IMM(1, d);
705                         } else
706                                 M_IMUL_IMM(s1, iptr->sx.val.i, d);
707                         emit_store_dst(jd, iptr, d);
708                         break;
709
710                 case ICMD_LMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
711
712                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
713                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
714                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
715                         if (s2 == d)
716                                 M_LMUL(s1, d);
717                         else {
718                                 M_INTMOVE(s1, d);
719                                 M_LMUL(s2, d);
720                         }
721                         emit_store_dst(jd, iptr, d);
722                         break;
723
724                 case ICMD_LMULCONST:  /* ..., value  ==> ..., value * constant        */
725                                       /* sx.val.l = constant                             */
726
727                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
728                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
729                         if (IS_IMM32(iptr->sx.val.l))
730                                 M_LMUL_IMM(s1, iptr->sx.val.l, d);
731                         else {
732                                 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
733                                 M_INTMOVE(s1, d);
734                                 M_LMUL(REG_ITMP2, d);
735                         }
736                         emit_store_dst(jd, iptr, d);
737                         break;
738
739                 case ICMD_IDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
740
741                         s1 = emit_load_s1(jd, iptr, RAX);
742                         s2 = emit_load_s2(jd, iptr, REG_ITMP3);
743                         d = codegen_reg_of_dst(jd, iptr, RAX);
744
745                         M_INTMOVE(s1, RAX);
746                         M_INTMOVE(s2, REG_ITMP3);
747                         emit_arithmetic_check(cd, iptr, REG_ITMP3);
748
749                         M_MOV(RDX, REG_ITMP2);    /* save RDX (it's an argument register) */
750
751                         M_ICMP_IMM(0x80000000, RAX);    /* check as described in jvm spec */
752                         M_BNE(4 + 6);
753                         M_ICMP_IMM(-1, REG_ITMP3);                             /* 4 bytes */
754                         M_BEQ(1 + 3);                                          /* 6 bytes */
755
756                         emit_cltd(cd);                                         /* 1 byte  */
757                         emit_idivl_reg(cd, REG_ITMP3);                         /* 3 bytes */
758
759                         M_INTMOVE(RAX, d);
760                         emit_store_dst(jd, iptr, d);
761                         dst = VAROP(iptr->dst);
762                         if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
763                                 M_MOV(REG_ITMP2, RDX);                         /* restore RDX */
764                         break;
765
766                 case ICMD_IREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
767
768                         s1 = emit_load_s1(jd, iptr, RAX);
769                         s2 = emit_load_s2(jd, iptr, REG_ITMP3);
770                         d = codegen_reg_of_dst(jd, iptr, RDX);
771
772                         M_INTMOVE(s1, RAX);
773                         M_INTMOVE(s2, REG_ITMP3);
774                         emit_arithmetic_check(cd, iptr, REG_ITMP3);
775
776                         M_MOV(RDX, REG_ITMP2);    /* save RDX (it's an argument register) */
777
778                         M_ICMP_IMM(0x80000000, RAX);    /* check as described in jvm spec */
779                         M_BNE(3 + 4 + 6);
780                         M_CLR(RDX);                                            /* 3 bytes */
781                         M_ICMP_IMM(-1, REG_ITMP3);                             /* 4 bytes */
782                         M_BEQ(1 + 3);                                          /* 6 bytes */
783
784                         emit_cltd(cd);                                         /* 1 byte  */
785                         emit_idivl_reg(cd, REG_ITMP3);                         /* 3 byte  */
786
787                         M_INTMOVE(RDX, d);
788                         emit_store_dst(jd, iptr, d);
789                         dst = VAROP(iptr->dst);
790                         if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
791                                 M_MOV(REG_ITMP2, RDX);                         /* restore RDX */
792                         break;
793
794                 case ICMD_IDIVPOW2:   /* ..., value  ==> ..., value >> constant       */
795                                       /* sx.val.i = constant                             */
796
797                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
798                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
799                         M_INTMOVE(s1, REG_ITMP1);
800                         emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
801                         emit_leal_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
802                         emit_cmovccl_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
803                         emit_shiftl_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
804                         emit_mov_reg_reg(cd, REG_ITMP1, d);
805                         emit_store_dst(jd, iptr, d);
806                         break;
807
808                 case ICMD_IREMPOW2:   /* ..., value  ==> ..., value % constant        */
809                                       /* sx.val.i = constant                             */
810
811                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
812                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
813                         M_INTMOVE(s1, REG_ITMP1);
814                         emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
815                         emit_leal_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
816                         emit_cmovccl_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
817                         emit_alul_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
818                         emit_alul_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
819                         emit_mov_reg_reg(cd, REG_ITMP1, d);
820                         emit_store_dst(jd, iptr, d);
821                         break;
822
823
824                 case ICMD_LDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
825
826                         s1 = emit_load_s1(jd, iptr, RAX);
827                         s2 = emit_load_s2(jd, iptr, REG_ITMP3);
828                         d = codegen_reg_of_dst(jd, iptr, RAX);
829
830                         M_INTMOVE(s1, RAX);
831                         M_INTMOVE(s2, REG_ITMP3);
832                         emit_arithmetic_check(cd, iptr, REG_ITMP3);
833
834                         M_MOV(RDX, REG_ITMP2);    /* save RDX (it's an argument register) */
835
836                         /* check as described in jvm spec */
837                         disp = dseg_add_s8(cd, 0x8000000000000000LL);
838                         M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, RAX);
839                         M_BNE(4 + 6);
840                         M_LCMP_IMM(-1, REG_ITMP3);                             /* 4 bytes */
841                         M_BEQ(2 + 3);                                          /* 6 bytes */
842
843                         emit_cqto(cd);                                         /* 2 bytes */
844                         emit_idiv_reg(cd, REG_ITMP3);                          /* 3 bytes */
845
846                         M_INTMOVE(RAX, d);
847                         emit_store_dst(jd, iptr, d);
848                         dst = VAROP(iptr->dst);
849                         if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
850                                 M_MOV(REG_ITMP2, RDX);                         /* restore RDX */
851                         break;
852
853                 case ICMD_LREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
854
855                         s1 = emit_load_s1(jd, iptr, RAX);
856                         s2 = emit_load_s2(jd, iptr, REG_ITMP3);
857                         d = codegen_reg_of_dst(jd, iptr, RDX);
858
859                         M_INTMOVE(s1, RAX);
860                         M_INTMOVE(s2, REG_ITMP3);
861                         emit_arithmetic_check(cd, iptr, REG_ITMP3);
862
863                         M_MOV(RDX, REG_ITMP2);    /* save RDX (it's an argument register) */
864
865                         /* check as described in jvm spec */
866                         disp = dseg_add_s8(cd, 0x8000000000000000LL);
867                         M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, REG_ITMP1);
868                         M_BNE(3 + 4 + 6);
869                         M_LXOR(RDX, RDX);                                      /* 3 bytes */
870                         M_LCMP_IMM(-1, REG_ITMP3);                             /* 4 bytes */
871                         M_BEQ(2 + 3);                                          /* 6 bytes */
872
873                         emit_cqto(cd);                                         /* 2 bytes */
874                         emit_idiv_reg(cd, REG_ITMP3);                          /* 3 bytes */
875
876                         M_INTMOVE(RDX, d);
877                         emit_store_dst(jd, iptr, d);
878                         dst = VAROP(iptr->dst);
879                         if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
880                                 M_MOV(REG_ITMP2, RDX);                         /* restore RDX */
881                         break;
882
883                 case ICMD_LDIVPOW2:   /* ..., value  ==> ..., value >> constant       */
884                                       /* sx.val.i = constant                             */
885
886                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
887                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
888                         M_INTMOVE(s1, REG_ITMP1);
889                         emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
890                         emit_lea_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
891                         emit_cmovcc_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
892                         emit_shift_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
893                         emit_mov_reg_reg(cd, REG_ITMP1, d);
894                         emit_store_dst(jd, iptr, d);
895                         break;
896
897                 case ICMD_LREMPOW2:   /* ..., value  ==> ..., value % constant        */
898                                       /* sx.val.l = constant                             */
899
900                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
901                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
902                         M_INTMOVE(s1, REG_ITMP1);
903                         emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
904                         emit_lea_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
905                         emit_cmovcc_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
906                         emit_alu_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
907                         emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
908                         emit_mov_reg_reg(cd, REG_ITMP1, d);
909                         emit_store_dst(jd, iptr, d);
910                         break;
911
912                 case ICMD_ISHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
913
914                         d = codegen_reg_of_dst(jd, iptr, REG_NULL);
915                         emit_ishift(jd, SHIFT_SHL, iptr);
916                         break;
917
918                 case ICMD_ISHLCONST:  /* ..., value  ==> ..., value << constant       */
919                                       /* sx.val.i = constant                             */
920
921                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
922                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
923                         M_INTMOVE(s1, d);
924                         M_ISLL_IMM(iptr->sx.val.i, d);
925                         emit_store_dst(jd, iptr, d);
926                         break;
927
928                 case ICMD_ISHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
929
930                         d = codegen_reg_of_dst(jd, iptr, REG_NULL);
931                         emit_ishift(jd, SHIFT_SAR, iptr);
932                         break;
933
934                 case ICMD_ISHRCONST:  /* ..., value  ==> ..., value >> constant       */
935                                       /* sx.val.i = constant                             */
936
937                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
938                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
939                         M_INTMOVE(s1, d);
940                         M_ISRA_IMM(iptr->sx.val.i, d);
941                         emit_store_dst(jd, iptr, d);
942                         break;
943
944                 case ICMD_IUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
945
946                         d = codegen_reg_of_dst(jd, iptr, REG_NULL);
947                         emit_ishift(jd, SHIFT_SHR, iptr);
948                         break;
949
950                 case ICMD_IUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
951                                       /* sx.val.i = constant                             */
952
953                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
954                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
955                         M_INTMOVE(s1, d);
956                         M_ISRL_IMM(iptr->sx.val.i, d);
957                         emit_store_dst(jd, iptr, d);
958                         break;
959
960                 case ICMD_LSHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
961
962                         d = codegen_reg_of_dst(jd, iptr, REG_NULL);
963                         emit_lshift(jd, SHIFT_SHL, iptr);
964                         break;
965
966         case ICMD_LSHLCONST:  /* ..., value  ==> ..., value << constant       */
967                                           /* sx.val.i = constant                             */
968
969                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
970                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
971                         M_INTMOVE(s1, d);
972                         M_LSLL_IMM(iptr->sx.val.i, d);
973                         emit_store_dst(jd, iptr, d);
974                         break;
975
976                 case ICMD_LSHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
977
978                         d = codegen_reg_of_dst(jd, iptr, REG_NULL);
979                         emit_lshift(jd, SHIFT_SAR, iptr);
980                         break;
981
982                 case ICMD_LSHRCONST:  /* ..., value  ==> ..., value >> constant       */
983                                       /* sx.val.i = constant                             */
984
985                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
986                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
987                         M_INTMOVE(s1, d);
988                         M_LSRA_IMM(iptr->sx.val.i, d);
989                         emit_store_dst(jd, iptr, d);
990                         break;
991
992                 case ICMD_LUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
993
994                         d = codegen_reg_of_dst(jd, iptr, REG_NULL);
995                         emit_lshift(jd, SHIFT_SHR, iptr);
996                         break;
997
998                 case ICMD_LUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
999                                       /* sx.val.l = constant                             */
1000
1001                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1002                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1003                         M_INTMOVE(s1, d);
1004                         M_LSRL_IMM(iptr->sx.val.i, d);
1005                         emit_store_dst(jd, iptr, d);
1006                         break;
1007
1008                 case ICMD_IAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
1009
1010                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1011                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1012                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1013                         if (s2 == d)
1014                                 M_IAND(s1, d);
1015                         else {
1016                                 M_INTMOVE(s1, d);
1017                                 M_IAND(s2, d);
1018                         }
1019                         emit_store_dst(jd, iptr, d);
1020                         break;
1021
1022                 case ICMD_IANDCONST:  /* ..., value  ==> ..., value & constant        */
1023                                       /* sx.val.i = constant                             */
1024
1025                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1026                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1027                         M_INTMOVE(s1, d);
1028                         M_IAND_IMM(iptr->sx.val.i, d);
1029                         emit_store_dst(jd, iptr, d);
1030                         break;
1031
1032                 case ICMD_LAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
1033
1034                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1035                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1036                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1037                         if (s2 == d)
1038                                 M_LAND(s1, d);
1039                         else {
1040                                 M_INTMOVE(s1, d);
1041                                 M_LAND(s2, d);
1042                         }
1043                         emit_store_dst(jd, iptr, d);
1044                         break;
1045
1046                 case ICMD_LANDCONST:  /* ..., value  ==> ..., value & constant        */
1047                                       /* sx.val.l = constant                             */
1048
1049                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1050                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1051                         M_INTMOVE(s1, d);
1052                         if (IS_IMM32(iptr->sx.val.l))
1053                                 M_LAND_IMM(iptr->sx.val.l, d);
1054                         else {
1055                                 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1056                                 M_LAND(REG_ITMP2, d);
1057                         }
1058                         emit_store_dst(jd, iptr, d);
1059                         break;
1060
1061                 case ICMD_IOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
1062
1063                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1064                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1065                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1066                         if (s2 == d)
1067                                 M_IOR(s1, d);
1068                         else {
1069                                 M_INTMOVE(s1, d);
1070                                 M_IOR(s2, d);
1071                         }
1072                         emit_store_dst(jd, iptr, d);
1073                         break;
1074
1075                 case ICMD_IORCONST:   /* ..., value  ==> ..., value | constant        */
1076                                       /* sx.val.i = constant                             */
1077
1078                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1079                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1080                         M_INTMOVE(s1, d);
1081                         M_IOR_IMM(iptr->sx.val.i, d);
1082                         emit_store_dst(jd, iptr, d);
1083                         break;
1084
1085                 case ICMD_LOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
1086
1087                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1088                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1089                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1090                         if (s2 == d)
1091                                 M_LOR(s1, d);
1092                         else {
1093                                 M_INTMOVE(s1, d);
1094                                 M_LOR(s2, d);
1095                         }
1096                         emit_store_dst(jd, iptr, d);
1097                         break;
1098
1099                 case ICMD_LORCONST:   /* ..., value  ==> ..., value | constant        */
1100                                       /* sx.val.l = constant                             */
1101
1102                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1103                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1104                         M_INTMOVE(s1, d);
1105                         if (IS_IMM32(iptr->sx.val.l))
1106                                 M_LOR_IMM(iptr->sx.val.l, d);
1107                         else {
1108                                 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1109                                 M_LOR(REG_ITMP2, d);
1110                         }
1111                         emit_store_dst(jd, iptr, d);
1112                         break;
1113
1114                 case ICMD_IXOR:       /* ..., val1, val2  ==> ..., val1 ^ val2        */
1115
1116                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1117                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1118                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1119                         if (s2 == d)
1120                                 M_IXOR(s1, d);
1121                         else {
1122                                 M_INTMOVE(s1, d);
1123                                 M_IXOR(s2, d);
1124                         }
1125                         emit_store_dst(jd, iptr, d);
1126                         break;
1127
1128                 case ICMD_IXORCONST:  /* ..., value  ==> ..., value ^ constant        */
1129                                       /* sx.val.i = constant                             */
1130
1131                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1132                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1133                         M_INTMOVE(s1, d);
1134                         M_IXOR_IMM(iptr->sx.val.i, d);
1135                         emit_store_dst(jd, iptr, d);
1136                         break;
1137
1138                 case ICMD_LXOR:       /* ..., val1, val2  ==> ..., val1 ^ val2        */
1139
1140                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1141                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1142                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1143                         if (s2 == d)
1144                                 M_LXOR(s1, d);
1145                         else {
1146                                 M_INTMOVE(s1, d);
1147                                 M_LXOR(s2, d);
1148                         }
1149                         emit_store_dst(jd, iptr, d);
1150                         break;
1151
1152                 case ICMD_LXORCONST:  /* ..., value  ==> ..., value ^ constant        */
1153                                       /* sx.val.l = constant                             */
1154
1155                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1156                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1157                         M_INTMOVE(s1, d);
1158                         if (IS_IMM32(iptr->sx.val.l))
1159                                 M_LXOR_IMM(iptr->sx.val.l, d);
1160                         else {
1161                                 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1162                                 M_LXOR(REG_ITMP2, d);
1163                         }
1164                         emit_store_dst(jd, iptr, d);
1165                         break;
1166
1167
1168                 /* floating operations ************************************************/
1169
1170                 case ICMD_FNEG:       /* ..., value  ==> ..., - value                 */
1171
1172                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1173                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1174                         disp = dseg_add_s4(cd, 0x80000000);
1175                         M_FLTMOVE(s1, d);
1176                         emit_movss_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
1177                         emit_xorps_reg_reg(cd, REG_FTMP2, d);
1178                         emit_store_dst(jd, iptr, d);
1179                         break;
1180
1181                 case ICMD_DNEG:       /* ..., value  ==> ..., - value                 */
1182
1183                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1184                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1185                         disp = dseg_add_s8(cd, 0x8000000000000000);
1186                         M_FLTMOVE(s1, d);
1187                         emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
1188                         emit_xorpd_reg_reg(cd, REG_FTMP2, d);
1189                         emit_store_dst(jd, iptr, d);
1190                         break;
1191
1192                 case ICMD_FADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
1193
1194                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1195                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1196                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1197                         if (s2 == d)
1198                                 M_FADD(s1, d);
1199                         else {
1200                                 M_FLTMOVE(s1, d);
1201                                 M_FADD(s2, d);
1202                         }
1203                         emit_store_dst(jd, iptr, d);
1204                         break;
1205
1206                 case ICMD_DADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
1207
1208                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1209                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1210                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1211                         if (s2 == d)
1212                                 M_DADD(s1, d);
1213                         else {
1214                                 M_FLTMOVE(s1, d);
1215                                 M_DADD(s2, d);
1216                         }
1217                         emit_store_dst(jd, iptr, d);
1218                         break;
1219
1220                 case ICMD_FSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
1221
1222                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1223                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1224                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1225                         if (s2 == d) {
1226                                 M_FLTMOVE(s2, REG_FTMP2);
1227                                 s2 = REG_FTMP2;
1228                         }
1229                         M_FLTMOVE(s1, d);
1230                         M_FSUB(s2, d);
1231                         emit_store_dst(jd, iptr, d);
1232                         break;
1233
1234                 case ICMD_DSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
1235
1236                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1237                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1238                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1239                         if (s2 == d) {
1240                                 M_FLTMOVE(s2, REG_FTMP2);
1241                                 s2 = REG_FTMP2;
1242                         }
1243                         M_FLTMOVE(s1, d);
1244                         M_DSUB(s2, d);
1245                         emit_store_dst(jd, iptr, d);
1246                         break;
1247
1248                 case ICMD_FMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
1249
1250                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1251                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1252                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1253                         if (s2 == d)
1254                                 M_FMUL(s1, d);
1255                         else {
1256                                 M_FLTMOVE(s1, d);
1257                                 M_FMUL(s2, d);
1258                         }
1259                         emit_store_dst(jd, iptr, d);
1260                         break;
1261
1262                 case ICMD_DMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
1263
1264                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1265                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1266                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1267                         if (s2 == d)
1268                                 M_DMUL(s1, d);
1269                         else {
1270                                 M_FLTMOVE(s1, d);
1271                                 M_DMUL(s2, d);
1272                         }
1273                         emit_store_dst(jd, iptr, d);
1274                         break;
1275
1276                 case ICMD_FDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1277
1278                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1279                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1280                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1281                         if (s2 == d) {
1282                                 M_FLTMOVE(s2, REG_FTMP2);
1283                                 s2 = REG_FTMP2;
1284                         }
1285                         M_FLTMOVE(s1, d);
1286                         M_FDIV(s2, d);
1287                         emit_store_dst(jd, iptr, d);
1288                         break;
1289
1290                 case ICMD_DDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1291
1292                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1293                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1294                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1295                         if (s2 == d) {
1296                                 M_FLTMOVE(s2, REG_FTMP2);
1297                                 s2 = REG_FTMP2;
1298                         }
1299                         M_FLTMOVE(s1, d);
1300                         M_DDIV(s2, d);
1301                         emit_store_dst(jd, iptr, d);
1302                         break;
1303
1304                 case ICMD_I2F:       /* ..., value  ==> ..., (float) value            */
1305
1306                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1307                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1308                         M_CVTIF(s1, d);
1309                         emit_store_dst(jd, iptr, d);
1310                         break;
1311
1312                 case ICMD_I2D:       /* ..., value  ==> ..., (double) value           */
1313
1314                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1315                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1316                         M_CVTID(s1, d);
1317                         emit_store_dst(jd, iptr, d);
1318                         break;
1319
1320                 case ICMD_L2F:       /* ..., value  ==> ..., (float) value            */
1321
1322                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1323                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1324                         M_CVTLF(s1, d);
1325                         emit_store_dst(jd, iptr, d);
1326                         break;
1327                         
1328                 case ICMD_L2D:       /* ..., value  ==> ..., (double) value           */
1329
1330                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1331                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1332                         M_CVTLD(s1, d);
1333                         emit_store_dst(jd, iptr, d);
1334                         break;
1335                         
1336                 case ICMD_F2I:       /* ..., value  ==> ..., (int) value              */
1337
1338                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1339                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1340                         M_CVTFI(s1, d);
1341                         M_ICMP_IMM(0x80000000, d);                        /* corner cases */
1342                         disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1343                                 ((REG_RESULT == d) ? 0 : 3);
1344                         M_BNE(disp);
1345                         M_FLTMOVE(s1, REG_FTMP1);
1346                         M_MOV_IMM(asm_builtin_f2i, REG_ITMP2);
1347                         M_CALL(REG_ITMP2);
1348                         M_INTMOVE(REG_RESULT, d);
1349                         emit_store_dst(jd, iptr, d);
1350                         break;
1351
1352                 case ICMD_D2I:       /* ..., value  ==> ..., (int) value              */
1353
1354                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1355                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1356                         M_CVTDI(s1, d);
1357                         M_ICMP_IMM(0x80000000, d);                        /* corner cases */
1358                         disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1359                                 ((REG_RESULT == d) ? 0 : 3);
1360                         M_BNE(disp);
1361                         M_FLTMOVE(s1, REG_FTMP1);
1362                         M_MOV_IMM(asm_builtin_d2i, REG_ITMP2);
1363                         M_CALL(REG_ITMP2);
1364                         M_INTMOVE(REG_RESULT, d);
1365                         emit_store_dst(jd, iptr, d);
1366                         break;
1367
1368                 case ICMD_F2L:       /* ..., value  ==> ..., (long) value             */
1369
1370                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1371                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1372                         M_CVTFL(s1, d);
1373                         M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1374                         M_LCMP(REG_ITMP2, d);                             /* corner cases */
1375                         disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1376                                 ((REG_RESULT == d) ? 0 : 3);
1377                         M_BNE(disp);
1378                         M_FLTMOVE(s1, REG_FTMP1);
1379                         M_MOV_IMM(asm_builtin_f2l, REG_ITMP2);
1380                         M_CALL(REG_ITMP2);
1381                         M_INTMOVE(REG_RESULT, d);
1382                         emit_store_dst(jd, iptr, d);
1383                         break;
1384
1385                 case ICMD_D2L:       /* ..., value  ==> ..., (long) value             */
1386
1387                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1388                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1389                         M_CVTDL(s1, d);
1390                         M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1391                         M_LCMP(REG_ITMP2, d);                             /* corner cases */
1392                         disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1393                                 ((REG_RESULT == d) ? 0 : 3);
1394                         M_BNE(disp);
1395                         M_FLTMOVE(s1, REG_FTMP1);
1396                         M_MOV_IMM(asm_builtin_d2l, REG_ITMP2);
1397                         M_CALL(REG_ITMP2);
1398                         M_INTMOVE(REG_RESULT, d);
1399                         emit_store_dst(jd, iptr, d);
1400                         break;
1401
1402                 case ICMD_F2D:       /* ..., value  ==> ..., (double) value           */
1403
1404                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1405                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1406                         M_CVTFD(s1, d);
1407                         emit_store_dst(jd, iptr, d);
1408                         break;
1409
1410                 case ICMD_D2F:       /* ..., value  ==> ..., (float) value            */
1411
1412                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1413                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1414                         M_CVTDF(s1, d);
1415                         emit_store_dst(jd, iptr, d);
1416                         break;
1417
1418                 case ICMD_FCMPL:      /* ..., val1, val2  ==> ..., val1 fcmpl val2    */
1419                                           /* == => 0, < => 1, > => -1 */
1420
1421                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1422                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1423                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1424                         M_CLR(d);
1425                         M_MOV_IMM(1, REG_ITMP1);
1426                         M_MOV_IMM(-1, REG_ITMP2);
1427                         emit_ucomiss_reg_reg(cd, s1, s2);
1428                         M_CMOVULT(REG_ITMP1, d);
1429                         M_CMOVUGT(REG_ITMP2, d);
1430                         M_CMOVP(REG_ITMP2, d);                   /* treat unordered as GT */
1431                         emit_store_dst(jd, iptr, d);
1432                         break;
1433
1434                 case ICMD_FCMPG:      /* ..., val1, val2  ==> ..., val1 fcmpg val2    */
1435                                           /* == => 0, < => 1, > => -1 */
1436
1437                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1438                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1439                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1440                         M_CLR(d);
1441                         M_MOV_IMM(1, REG_ITMP1);
1442                         M_MOV_IMM(-1, REG_ITMP2);
1443                         emit_ucomiss_reg_reg(cd, s1, s2);
1444                         M_CMOVULT(REG_ITMP1, d);
1445                         M_CMOVUGT(REG_ITMP2, d);
1446                         M_CMOVP(REG_ITMP1, d);                   /* treat unordered as LT */
1447                         emit_store_dst(jd, iptr, d);
1448                         break;
1449
1450                 case ICMD_DCMPL:      /* ..., val1, val2  ==> ..., val1 fcmpl val2    */
1451                                           /* == => 0, < => 1, > => -1 */
1452
1453                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1454                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1455                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1456                         M_CLR(d);
1457                         M_MOV_IMM(1, REG_ITMP1);
1458                         M_MOV_IMM(-1, REG_ITMP2);
1459                         emit_ucomisd_reg_reg(cd, s1, s2);
1460                         M_CMOVULT(REG_ITMP1, d);
1461                         M_CMOVUGT(REG_ITMP2, d);
1462                         M_CMOVP(REG_ITMP2, d);                   /* treat unordered as GT */
1463                         emit_store_dst(jd, iptr, d);
1464                         break;
1465
1466                 case ICMD_DCMPG:      /* ..., val1, val2  ==> ..., val1 fcmpg val2    */
1467                                           /* == => 0, < => 1, > => -1 */
1468
1469                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1470                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1471                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1472                         M_CLR(d);
1473                         M_MOV_IMM(1, REG_ITMP1);
1474                         M_MOV_IMM(-1, REG_ITMP2);
1475                         emit_ucomisd_reg_reg(cd, s1, s2);
1476                         M_CMOVULT(REG_ITMP1, d);
1477                         M_CMOVUGT(REG_ITMP2, d);
1478                         M_CMOVP(REG_ITMP1, d);                   /* treat unordered as LT */
1479                         emit_store_dst(jd, iptr, d);
1480                         break;
1481
1482
1483                 /* memory operations **************************************************/
1484
1485                 case ICMD_ARRAYLENGTH: /* ..., arrayref  ==> ..., (int) length        */
1486
1487                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1488                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1489                         /* implicit null-pointer check */
1490                         M_ILD(d, s1, OFFSET(java_array_t, size));
1491                         emit_store_dst(jd, iptr, d);
1492                         break;
1493
1494                 case ICMD_BALOAD:     /* ..., arrayref, index  ==> ..., value         */
1495
1496                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1497                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1498                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1499                         /* implicit null-pointer check */
1500                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1501                         emit_movsbq_memindex_reg(cd, OFFSET(java_bytearray_t, data[0]), s1, s2, 0, d);
1502                         emit_store_dst(jd, iptr, d);
1503                         break;
1504
1505                 case ICMD_CALOAD:     /* ..., arrayref, index  ==> ..., value         */
1506
1507                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1508                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1509                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1510                         /* implicit null-pointer check */
1511                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1512                         emit_movzwq_memindex_reg(cd, OFFSET(java_chararray_t, data[0]), s1, s2, 1, d);
1513                         emit_store_dst(jd, iptr, d);
1514                         break;                  
1515
1516                 case ICMD_SALOAD:     /* ..., arrayref, index  ==> ..., value         */
1517
1518                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1519                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1520                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1521                         /* implicit null-pointer check */
1522                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1523                         emit_movswq_memindex_reg(cd, OFFSET(java_shortarray_t, data[0]), s1, s2, 1, d);
1524                         emit_store_dst(jd, iptr, d);
1525                         break;
1526
1527                 case ICMD_IALOAD:     /* ..., arrayref, index  ==> ..., value         */
1528
1529                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1530                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1531                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1532                         /* implicit null-pointer check */
1533                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1534                         emit_movl_memindex_reg(cd, OFFSET(java_intarray_t, data[0]), s1, s2, 2, d);
1535                         emit_store_dst(jd, iptr, d);
1536                         break;
1537
1538                 case ICMD_LALOAD:     /* ..., arrayref, index  ==> ..., value         */
1539
1540                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1541                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1542                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1543                         /* implicit null-pointer check */
1544                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1545                         emit_mov_memindex_reg(cd, OFFSET(java_longarray_t, data[0]), s1, s2, 3, d);
1546                         emit_store_dst(jd, iptr, d);
1547                         break;
1548
1549                 case ICMD_FALOAD:     /* ..., arrayref, index  ==> ..., value         */
1550
1551                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1552                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1553                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1554                         /* implicit null-pointer check */
1555                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1556                         emit_movss_memindex_reg(cd, OFFSET(java_floatarray_t, data[0]), s1, s2, 2, d);
1557                         emit_store_dst(jd, iptr, d);
1558                         break;
1559
1560                 case ICMD_DALOAD:     /* ..., arrayref, index  ==> ..., value         */
1561
1562                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1563                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1564                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1565                         /* implicit null-pointer check */
1566                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1567                         emit_movsd_memindex_reg(cd, OFFSET(java_doublearray_t, data[0]), s1, s2, 3, d);
1568                         emit_store_dst(jd, iptr, d);
1569                         break;
1570
1571                 case ICMD_AALOAD:     /* ..., arrayref, index  ==> ..., value         */
1572
1573                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1574                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1575                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1576                         /* implicit null-pointer check */
1577                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1578                         emit_mov_memindex_reg(cd, OFFSET(java_objectarray_t, data[0]), s1, s2, 3, d);
1579                         emit_store_dst(jd, iptr, d);
1580                         break;
1581
1582
1583                 case ICMD_BASTORE:    /* ..., arrayref, index, value  ==> ...         */
1584
1585                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1586                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1587                         /* implicit null-pointer check */
1588                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1589                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1590                         emit_movb_reg_memindex(cd, s3, OFFSET(java_bytearray_t, data[0]), s1, s2, 0);
1591                         break;
1592
1593                 case ICMD_CASTORE:    /* ..., arrayref, index, value  ==> ...         */
1594
1595                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1596                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1597                         /* implicit null-pointer check */
1598                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1599                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1600                         emit_movw_reg_memindex(cd, s3, OFFSET(java_chararray_t, data[0]), s1, s2, 1);
1601                         break;
1602
1603                 case ICMD_SASTORE:    /* ..., arrayref, index, value  ==> ...         */
1604
1605                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1606                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1607                         /* implicit null-pointer check */
1608                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1609                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1610                         emit_movw_reg_memindex(cd, s3, OFFSET(java_shortarray_t, data[0]), s1, s2, 1);
1611                         break;
1612
1613                 case ICMD_IASTORE:    /* ..., arrayref, index, value  ==> ...         */
1614
1615                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1616                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1617                         /* implicit null-pointer check */
1618                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1619                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1620                         emit_movl_reg_memindex(cd, s3, OFFSET(java_intarray_t, data[0]), s1, s2, 2);
1621                         break;
1622
1623                 case ICMD_LASTORE:    /* ..., arrayref, index, value  ==> ...         */
1624
1625                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1626                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1627                         /* implicit null-pointer check */
1628                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1629                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1630                         emit_mov_reg_memindex(cd, s3, OFFSET(java_longarray_t, data[0]), s1, s2, 3);
1631                         break;
1632
1633                 case ICMD_FASTORE:    /* ..., arrayref, index, value  ==> ...         */
1634
1635                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1636                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1637                         /* implicit null-pointer check */
1638                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1639                         s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1640                         emit_movss_reg_memindex(cd, s3, OFFSET(java_floatarray_t, data[0]), s1, s2, 2);
1641                         break;
1642
1643                 case ICMD_DASTORE:    /* ..., arrayref, index, value  ==> ...         */
1644
1645                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1646                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1647                         /* implicit null-pointer check */
1648                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1649                         s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1650                         emit_movsd_reg_memindex(cd, s3, OFFSET(java_doublearray_t, data[0]), s1, s2, 3);
1651                         break;
1652
1653                 case ICMD_AASTORE:    /* ..., arrayref, index, value  ==> ...         */
1654
1655                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1656                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1657                         /* implicit null-pointer check */
1658                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1659                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1660
1661                         M_MOV(s1, REG_A0);
1662                         M_MOV(s3, REG_A1);
1663                         M_MOV_IMM(BUILTIN_FAST_canstore, REG_ITMP1);
1664                         M_CALL(REG_ITMP1);
1665                         emit_arraystore_check(cd, iptr);
1666
1667                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1668                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1669                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1670                         emit_mov_reg_memindex(cd, s3, OFFSET(java_objectarray_t, data[0]), s1, s2, 3);
1671                         break;
1672
1673
1674                 case ICMD_BASTORECONST: /* ..., arrayref, index  ==> ...              */
1675
1676                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1677                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1678                         /* implicit null-pointer check */
1679                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1680                         emit_movb_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_bytearray_t, data[0]), s1, s2, 0);
1681                         break;
1682
1683                 case ICMD_CASTORECONST:   /* ..., arrayref, index  ==> ...            */
1684
1685                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1686                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1687                         /* implicit null-pointer check */
1688                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1689                         emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_chararray_t, data[0]), s1, s2, 1);
1690                         break;
1691
1692                 case ICMD_SASTORECONST:   /* ..., arrayref, index  ==> ...            */
1693
1694                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1695                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1696                         /* implicit null-pointer check */
1697                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1698                         emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_shortarray_t, data[0]), s1, s2, 1);
1699                         break;
1700
1701                 case ICMD_IASTORECONST: /* ..., arrayref, index  ==> ...              */
1702
1703                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1704                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1705                         /* implicit null-pointer check */
1706                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1707                         emit_movl_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_intarray_t, data[0]), s1, s2, 2);
1708                         break;
1709
1710                 case ICMD_LASTORECONST: /* ..., arrayref, index  ==> ...              */
1711
1712                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1713                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1714                         /* implicit null-pointer check */
1715                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1716
1717                         if (IS_IMM32(iptr->sx.s23.s3.constval)) {
1718                                 emit_mov_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray_t, data[0]), s1, s2, 3);
1719                         }
1720                         else {
1721                                 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray_t, data[0]), s1, s2, 3);
1722                                 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval >> 32), OFFSET(java_longarray_t, data[0]) + 4, s1, s2, 3);
1723                         }
1724                         break;
1725
1726                 case ICMD_AASTORECONST: /* ..., arrayref, index  ==> ...              */
1727
1728                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1729                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1730                         /* implicit null-pointer check */
1731                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1732                         emit_mov_imm_memindex(cd, 0, OFFSET(java_objectarray_t, data[0]), s1, s2, 3);
1733                         break;
1734
1735
1736                 case ICMD_GETSTATIC:  /* ...  ==> ..., value                          */
1737
1738                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1739                                 uf        = iptr->sx.s23.s3.uf;
1740                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1741                                 disp      = dseg_add_unique_address(cd, uf);
1742
1743 /*                              PROFILE_CYCLE_STOP; */
1744
1745                                 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1746
1747 /*                              PROFILE_CYCLE_START; */
1748                         }
1749                         else {
1750                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1751                                 fieldtype = fi->type;
1752                                 disp      = dseg_add_address(cd, fi->value);
1753
1754                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) {
1755                                         PROFILE_CYCLE_STOP;
1756
1757                                         patcher_add_patch_ref(jd, PATCHER_initialize_class,
1758                                                                                   fi->clazz, 0);
1759
1760                                         PROFILE_CYCLE_START;
1761                                 }
1762                         }
1763
1764                         /* This approach is much faster than moving the field
1765                            address inline into a register. */
1766
1767                         M_ALD(REG_ITMP1, RIP, disp);
1768
1769                         switch (fieldtype) {
1770                         case TYPE_INT:
1771                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1772                                 M_ILD(d, REG_ITMP1, 0);
1773                                 break;
1774                         case TYPE_LNG:
1775                         case TYPE_ADR:
1776                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1777                                 M_LLD(d, REG_ITMP1, 0);
1778                                 break;
1779                         case TYPE_FLT:
1780                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1781                                 M_FLD(d, REG_ITMP1, 0);
1782                                 break;
1783                         case TYPE_DBL:                          
1784                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1785                                 M_DLD(d, REG_ITMP1, 0);
1786                                 break;
1787                         }
1788                         emit_store_dst(jd, iptr, d);
1789                         break;
1790
1791                 case ICMD_PUTSTATIC:  /* ..., value  ==> ...                          */
1792
1793                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1794                                 uf        = iptr->sx.s23.s3.uf;
1795                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1796                                 disp      = dseg_add_unique_address(cd, uf);
1797
1798 /*                              PROFILE_CYCLE_STOP; */
1799
1800                                 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1801
1802 /*                              PROFILE_CYCLE_START; */
1803                         }
1804                         else {
1805                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1806                                 fieldtype = fi->type;
1807                                 disp      = dseg_add_address(cd, fi->value);
1808
1809                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) {
1810                                         PROFILE_CYCLE_STOP;
1811
1812                                         patcher_add_patch_ref(jd, PATCHER_initialize_class,
1813                                                                                   fi->clazz, 0);
1814
1815                                         PROFILE_CYCLE_START;
1816                                 }
1817                         }
1818
1819                         /* This approach is much faster than moving the field
1820                            address inline into a register. */
1821
1822                         M_ALD(REG_ITMP1, RIP, disp);
1823
1824                         switch (fieldtype) {
1825                         case TYPE_INT:
1826                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1827                                 M_IST(s1, REG_ITMP1, 0);
1828                                 break;
1829                         case TYPE_LNG:
1830                         case TYPE_ADR:
1831                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1832                                 M_LST(s1, REG_ITMP1, 0);
1833                                 break;
1834                         case TYPE_FLT:
1835                                 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1836                                 M_FST(s1, REG_ITMP1, 0);
1837                                 break;
1838                         case TYPE_DBL:
1839                                 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1840                                 M_DST(s1, REG_ITMP1, 0);
1841                                 break;
1842                         }
1843                         break;
1844
1845                 case ICMD_PUTSTATICCONST: /* ...  ==> ...                             */
1846                                           /* val = value (in current instruction)     */
1847                                           /* following NOP)                           */
1848
1849                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1850                                 uf        = iptr->sx.s23.s3.uf;
1851                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1852                                 disp      = dseg_add_unique_address(cd, uf);
1853
1854 /*                              PROFILE_CYCLE_STOP; */
1855
1856                                 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1857
1858 /*                              PROFILE_CYCLE_START; */
1859                         }
1860                         else {
1861                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1862                                 fieldtype = fi->type;
1863                                 disp      = dseg_add_address(cd, fi->value);
1864
1865                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) {
1866                                         PROFILE_CYCLE_STOP;
1867
1868                                         patcher_add_patch_ref(jd, PATCHER_initialize_class,
1869                                                                                   fi->clazz, 0);
1870
1871                                         PROFILE_CYCLE_START;
1872                                 }
1873                         }
1874
1875                         /* This approach is much faster than moving the field
1876                            address inline into a register. */
1877
1878                         M_ALD(REG_ITMP1, RIP, disp);
1879
1880                         switch (fieldtype) {
1881                         case TYPE_INT:
1882                         case TYPE_FLT:
1883                                 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1884                                 break;
1885                         case TYPE_LNG:
1886                         case TYPE_ADR:
1887                         case TYPE_DBL:
1888                                 if (IS_IMM32(iptr->sx.s23.s2.constval))
1889                                         M_LST_IMM32(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1890                                 else {
1891                                         M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1892                                         M_IST_IMM(iptr->sx.s23.s2.constval >> 32, REG_ITMP1, 4);
1893                                 }
1894                                 break;
1895                         }
1896                         break;
1897
1898                 case ICMD_GETFIELD:   /* ...  ==> ..., value                          */
1899
1900                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1901
1902                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1903                                 uf        = iptr->sx.s23.s3.uf;
1904                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1905                                 disp      = 0;
1906
1907 /*                              PROFILE_CYCLE_STOP; */
1908
1909                                 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1910
1911 /*                              PROFILE_CYCLE_START; */
1912                         }
1913                         else {
1914                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1915                                 fieldtype = fi->type;
1916                                 disp      = fi->offset;
1917                         }
1918
1919                         /* implicit null-pointer check */
1920                         switch (fieldtype) {
1921                         case TYPE_INT:
1922                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1923                                 M_ILD32(d, s1, disp);
1924                                 break;
1925                         case TYPE_LNG:
1926                         case TYPE_ADR:
1927                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1928                                 M_LLD32(d, s1, disp);
1929                                 break;
1930                         case TYPE_FLT:
1931                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1932                                 M_FLD32(d, s1, disp);
1933                                 break;
1934                         case TYPE_DBL:                          
1935                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1936                                 M_DLD32(d, s1, disp);
1937                                 break;
1938                         }
1939                         emit_store_dst(jd, iptr, d);
1940                         break;
1941
1942                 case ICMD_PUTFIELD:   /* ..., objectref, value  ==> ...               */
1943
1944                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1945                         s2 = emit_load_s2(jd, iptr, REG_IFTMP); /* REG_IFTMP == REG_ITMP2 */
1946
1947                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1948                                 uf        = iptr->sx.s23.s3.uf;
1949                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1950                                 disp      = 0;
1951
1952 /*                              PROFILE_CYCLE_STOP; */
1953
1954                                 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1955
1956 /*                              PROFILE_CYCLE_START; */
1957                         } 
1958                         else {
1959                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1960                                 fieldtype = fi->type;
1961                                 disp      = fi->offset;
1962                         }
1963
1964                         /* implicit null-pointer check */
1965                         switch (fieldtype) {
1966                         case TYPE_INT:
1967                                 M_IST32(s2, s1, disp);
1968                                 break;
1969                         case TYPE_LNG:
1970                         case TYPE_ADR:
1971                                 M_LST32(s2, s1, disp);
1972                                 break;
1973                         case TYPE_FLT:
1974                                 M_FST32(s2, s1, disp);
1975                                 break;
1976                         case TYPE_DBL:
1977                                 M_DST32(s2, s1, disp);
1978                                 break;
1979                         }
1980                         break;
1981
1982                 case ICMD_PUTFIELDCONST:  /* ..., objectref, value  ==> ...           */
1983                                           /* val = value (in current instruction)     */
1984                                           /* following NOP)                           */
1985
1986                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1987
1988                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1989                                 uf        = iptr->sx.s23.s3.uf;
1990                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1991                                 disp      = 0;
1992
1993 /*                              PROFILE_CYCLE_STOP; */
1994
1995                                 patcher_add_patch_ref(jd, PATCHER_putfieldconst, uf, 0);
1996
1997 /*                              PROFILE_CYCLE_START; */
1998                         } 
1999                         else {
2000                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
2001                                 fieldtype = fi->type;
2002                                 disp      = fi->offset;
2003                         }
2004
2005                         /* implicit null-pointer check */
2006                         switch (fieldtype) {
2007                         case TYPE_INT:
2008                         case TYPE_FLT:
2009                                 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2010                                 break;
2011                         case TYPE_LNG:
2012                         case TYPE_ADR:
2013                         case TYPE_DBL:
2014                                 /* XXX why no check for IS_IMM32? */
2015                                 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2016                                 M_IST32_IMM(iptr->sx.s23.s2.constval >> 32, s1, disp + 4);
2017                                 break;
2018                         }
2019                         break;
2020
2021
2022                 /* branch operations **************************************************/
2023
2024                 case ICMD_ATHROW:       /* ..., objectref ==> ... (, objectref)       */
2025
2026                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2027                         M_INTMOVE(s1, REG_ITMP1_XPTR);
2028
2029                         PROFILE_CYCLE_STOP;
2030
2031 #ifdef ENABLE_VERIFIER
2032                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2033                                 uc = iptr->sx.s23.s2.uc;
2034
2035                                 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2036                         }
2037 #endif /* ENABLE_VERIFIER */
2038
2039                         M_CALL_IMM(0);                            /* passing exception pc */
2040                         M_POP(REG_ITMP2_XPC);
2041
2042                         M_MOV_IMM(asm_handle_exception, REG_ITMP3);
2043                         M_JMP(REG_ITMP3);
2044                         break;
2045
2046                 case ICMD_GOTO:         /* ... ==> ...                                */
2047                 case ICMD_RET:
2048
2049                         emit_br(cd, iptr->dst.block);
2050                         ALIGNCODENOP;
2051                         break;
2052
2053                 case ICMD_JSR:          /* ... ==> ...                                */
2054
2055                         emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
2056                         ALIGNCODENOP;
2057                         break;
2058                         
2059                 case ICMD_IFNULL:       /* ..., value ==> ...                         */
2060                 case ICMD_IFNONNULL:
2061
2062                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2063                         M_TEST(s1);
2064                         emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, BRANCH_OPT_NONE);
2065                         break;
2066
2067                 case ICMD_IFEQ:         /* ..., value ==> ...                         */
2068                 case ICMD_IFLT:
2069                 case ICMD_IFLE:
2070                 case ICMD_IFNE:
2071                 case ICMD_IFGT:
2072                 case ICMD_IFGE:
2073
2074                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2075                         M_ICMP_IMM(iptr->sx.val.i, s1);
2076                         emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFEQ, BRANCH_OPT_NONE);
2077                         break;
2078
2079                 case ICMD_IF_LEQ:       /* ..., value ==> ...                         */
2080                 case ICMD_IF_LNE:
2081                 case ICMD_IF_LLT:
2082                 case ICMD_IF_LGE:
2083                 case ICMD_IF_LGT:
2084                 case ICMD_IF_LLE:
2085
2086                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2087                         if (IS_IMM32(iptr->sx.val.l))
2088                                 M_LCMP_IMM(iptr->sx.val.l, s1);
2089                         else {
2090                                 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2091                                 M_LCMP(REG_ITMP2, s1);
2092                         }
2093                         emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_LEQ, BRANCH_OPT_NONE);
2094                         break;
2095
2096                 case ICMD_IF_ICMPEQ:    /* ..., value, value ==> ...                  */
2097                 case ICMD_IF_ICMPNE:
2098                 case ICMD_IF_ICMPLT:
2099                 case ICMD_IF_ICMPGE:
2100                 case ICMD_IF_ICMPGT:
2101                 case ICMD_IF_ICMPLE:
2102
2103                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2104                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2105                         M_ICMP(s2, s1);
2106                         emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ICMPEQ, BRANCH_OPT_NONE);
2107                         break;
2108
2109                 case ICMD_IF_ACMPEQ:    /* ..., value, value ==> ...                  */
2110                 case ICMD_IF_ACMPNE:
2111
2112                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2113                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2114                         M_LCMP(s2, s1);
2115                         emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ACMPEQ, BRANCH_OPT_NONE);
2116                         break;
2117
2118                 case ICMD_IF_LCMPEQ:    /* ..., value, value ==> ...                  */
2119                 case ICMD_IF_LCMPNE:
2120                 case ICMD_IF_LCMPLT:
2121                 case ICMD_IF_LCMPGE:
2122                 case ICMD_IF_LCMPGT:
2123                 case ICMD_IF_LCMPLE:
2124
2125                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2126                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2127                         M_LCMP(s2, s1);
2128                         emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_LCMPEQ, BRANCH_OPT_NONE);
2129                         break;
2130
2131                 case ICMD_IRETURN:      /* ..., retvalue ==> ...                      */
2132                 case ICMD_LRETURN:
2133
2134                         REPLACEMENT_POINT_RETURN(cd, iptr);
2135                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
2136                         M_INTMOVE(s1, REG_RESULT);
2137                         goto nowperformreturn;
2138
2139                 case ICMD_ARETURN:      /* ..., retvalue ==> ...                      */
2140
2141                         REPLACEMENT_POINT_RETURN(cd, iptr);
2142                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
2143                         M_INTMOVE(s1, REG_RESULT);
2144
2145 #ifdef ENABLE_VERIFIER
2146                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2147                                 uc = iptr->sx.s23.s2.uc;
2148
2149                                 PROFILE_CYCLE_STOP;
2150
2151                                 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2152
2153                                 PROFILE_CYCLE_START;
2154                         }
2155 #endif /* ENABLE_VERIFIER */
2156                         goto nowperformreturn;
2157
2158                 case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
2159                 case ICMD_DRETURN:
2160
2161                         REPLACEMENT_POINT_RETURN(cd, iptr);
2162                         s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2163                         M_FLTMOVE(s1, REG_FRESULT);
2164                         goto nowperformreturn;
2165
2166                 case ICMD_RETURN:      /* ...  ==> ...                                */
2167
2168                         REPLACEMENT_POINT_RETURN(cd, iptr);
2169
2170 nowperformreturn:
2171                         {
2172                         s4 i, p;
2173
2174                         p = cd->stackframesize;
2175
2176 #if !defined(NDEBUG)
2177                         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2178                                 emit_verbosecall_exit(jd);
2179 #endif /* !defined(NDEBUG) */
2180
2181 #if defined(ENABLE_THREADS)
2182                         if (checksync && code_is_synchronized(code)) {
2183                                 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2184         
2185                                 /* we need to save the proper return value */
2186                                 switch (iptr->opc) {
2187                                 case ICMD_IRETURN:
2188                                 case ICMD_ARETURN:
2189                                 case ICMD_LRETURN:
2190                                         M_LST(REG_RESULT, REG_SP, rd->memuse * 8);
2191                                         break;
2192                                 case ICMD_FRETURN:
2193                                 case ICMD_DRETURN:
2194                                         M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2195                                         break;
2196                                 }
2197
2198                                 M_MOV_IMM(LOCK_monitor_exit, REG_ITMP1);
2199                                 M_CALL(REG_ITMP1);
2200
2201                                 /* and now restore the proper return value */
2202                                 switch (iptr->opc) {
2203                                 case ICMD_IRETURN:
2204                                 case ICMD_ARETURN:
2205                                 case ICMD_LRETURN:
2206                                         M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2207                                         break;
2208                                 case ICMD_FRETURN:
2209                                 case ICMD_DRETURN:
2210                                         M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2211                                         break;
2212                                 }
2213                         }
2214 #endif
2215
2216                         /* restore saved registers */
2217
2218                         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2219                                 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2220                         }
2221                         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2222                                 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2223                         }
2224
2225                         /* deallocate stack */
2226
2227                         if (cd->stackframesize)
2228                                 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
2229
2230                         /* generate method profiling code */
2231
2232                         PROFILE_CYCLE_STOP;
2233
2234                         M_RET;
2235                         }
2236                         break;
2237
2238
2239                 case ICMD_TABLESWITCH:  /* ..., index ==> ...                         */
2240                         {
2241                                 s4 i, l;
2242                                 branch_target_t *table;
2243
2244                                 table = iptr->dst.table;
2245
2246                                 l = iptr->sx.s23.s2.tablelow;
2247                                 i = iptr->sx.s23.s3.tablehigh;
2248
2249                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2250                                 M_INTMOVE(s1, REG_ITMP1);
2251
2252                                 if (l != 0)
2253                                         M_ISUB_IMM(l, REG_ITMP1);
2254
2255                                 /* number of targets */
2256                                 i = i - l + 1;
2257
2258                 /* range check */
2259
2260                                 M_ICMP_IMM(i - 1, REG_ITMP1);
2261                                 emit_bugt(cd, table[0].block);
2262
2263                                 /* build jump table top down and use address of lowest entry */
2264
2265                                 table += i;
2266
2267                                 while (--i >= 0) {
2268                                         dseg_add_target(cd, table->block);
2269                                         --table;
2270                                 }
2271
2272                                 /* length of dataseg after last dseg_add_target is used
2273                                    by load */
2274
2275                                 M_MOV_IMM(0, REG_ITMP2);
2276                                 dseg_adddata(cd);
2277                                 emit_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 3, REG_ITMP1);
2278                                 M_JMP(REG_ITMP1);
2279                         }
2280                         break;
2281
2282
2283                 case ICMD_LOOKUPSWITCH: /* ..., key ==> ...                           */
2284                         {
2285                                 s4 i;
2286                                 lookup_target_t *lookup;
2287
2288                                 lookup = iptr->dst.lookup;
2289
2290                                 i = iptr->sx.s23.s2.lookupcount;
2291                         
2292                                 MCODECHECK(8 + ((7 + 6) * i) + 5);
2293                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2294
2295                                 while (--i >= 0) {
2296                                         M_ICMP_IMM(lookup->value, s1);
2297                                         emit_beq(cd, lookup->target.block);
2298                                         lookup++;
2299                                 }
2300
2301                                 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2302                                 ALIGNCODENOP;
2303                         }
2304                         break;
2305
2306
2307                 case ICMD_BUILTIN:      /* ..., [arg1, [arg2 ...]] ==> ...            */
2308
2309                         REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr);
2310
2311                         bte = iptr->sx.s23.s3.bte;
2312                         md  = bte->md;
2313                         goto gen_method;
2314
2315                 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ...            */
2316
2317                 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2318                 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer    */
2319                 case ICMD_INVOKEINTERFACE:
2320
2321                         REPLACEMENT_POINT_INVOKE(cd, iptr);
2322
2323                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2324                                 lm = NULL;
2325                                 um = iptr->sx.s23.s3.um;
2326                                 md = um->methodref->parseddesc.md;
2327                         }
2328                         else {
2329                                 lm = iptr->sx.s23.s3.fmiref->p.method;
2330                                 um = NULL;
2331                                 md = lm->parseddesc;
2332                         }
2333
2334 gen_method:
2335                         s3 = md->paramcount;
2336
2337                         MCODECHECK((20 * s3) + 128);
2338
2339                         /* copy arguments to registers or stack location */
2340
2341                         for (s3 = s3 - 1; s3 >= 0; s3--) {
2342                                 var = VAR(iptr->sx.s23.s2.args[s3]);
2343                                 d   = md->params[s3].regoff;
2344
2345                                 /* already preallocated (ARGVAR)? */
2346
2347                                 if (var->flags & PREALLOC)
2348                                         continue;
2349
2350                                 if (IS_INT_LNG_TYPE(var->type)) {
2351                                         if (!md->params[s3].inmemory) {
2352                                                 s1 = emit_load(jd, iptr, var, d);
2353                                                 M_INTMOVE(s1, d);
2354                                         }
2355                                         else {
2356                                                 s1 = emit_load(jd, iptr, var, REG_ITMP1);
2357                                                 M_LST(s1, REG_SP, d);
2358                                         }
2359                                 }
2360                                 else {
2361                                         if (!md->params[s3].inmemory) {
2362                                                 s1 = emit_load(jd, iptr, var, d);
2363                                                 M_FLTMOVE(s1, d);
2364                                         }
2365                                         else {
2366                                                 s1 = emit_load(jd, iptr, var, REG_FTMP1);
2367
2368                                                 if (IS_2_WORD_TYPE(var->type))
2369                                                         M_DST(s1, REG_SP, d);
2370                                                 else
2371                                                         M_FST(s1, REG_SP, d);
2372                                         }
2373                                 }
2374                         }
2375
2376                         /* generate method profiling code */
2377
2378                         PROFILE_CYCLE_STOP;
2379
2380                         switch (iptr->opc) {
2381                         case ICMD_BUILTIN:
2382                                 if (bte->stub == NULL) {
2383                                         M_MOV_IMM(bte->fp, REG_ITMP1);
2384                                 }
2385                                 else {
2386                                         M_MOV_IMM(bte->stub, REG_ITMP1);
2387                                 }
2388                                 M_CALL(REG_ITMP1);
2389                                 break;
2390
2391                         case ICMD_INVOKESPECIAL:
2392                                 emit_nullpointer_check(cd, iptr, REG_A0);
2393                                 /* fall through */
2394
2395                         case ICMD_INVOKESTATIC:
2396                                 if (lm == NULL) {
2397                                         disp = dseg_add_unique_address(cd, um);
2398
2399                                         patcher_add_patch_ref(jd, PATCHER_invokestatic_special,
2400                                                                                   um, disp);
2401                                 }
2402                                 else {
2403                                         disp = dseg_add_functionptr(cd, lm->stubroutine);
2404                                 }
2405
2406                                 M_ALD(REG_ITMP2, RIP, disp);
2407                                 M_CALL(REG_ITMP2);
2408                                 break;
2409
2410                         case ICMD_INVOKEVIRTUAL:
2411                                 if (lm == NULL) {
2412                                         patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
2413
2414                                         s1 = 0;
2415                                 }
2416                                 else {
2417                                         s1 = OFFSET(vftbl_t, table[0]) +
2418                                                 sizeof(methodptr) * lm->vftblindex;
2419                                 }
2420
2421                                 /* implicit null-pointer check */
2422                                 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2423                                 M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
2424                                 M_CALL(REG_ITMP3);
2425                                 break;
2426
2427                         case ICMD_INVOKEINTERFACE:
2428                                 if (lm == NULL) {
2429                                         patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
2430
2431                                         s1 = 0;
2432                                         s2 = 0;
2433                                 }
2434                                 else {
2435                                         s1 = OFFSET(vftbl_t, interfacetable[0]) -
2436                                                 sizeof(methodptr) * lm->clazz->index;
2437
2438                                         s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
2439                                 }
2440
2441                                 /* implicit null-pointer check */
2442                                 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2443                                 M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
2444                                 M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
2445                                 M_CALL(REG_ITMP3);
2446                                 break;
2447                         }
2448
2449                         /* generate method profiling code */
2450
2451                         PROFILE_CYCLE_START;
2452
2453                         /* store size of call code in replacement point */
2454
2455                         REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2456                         REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr);
2457
2458                         /* store return value */
2459
2460                         switch (md->returntype.type) {
2461                         case TYPE_INT:
2462                         case TYPE_LNG:
2463                         case TYPE_ADR:
2464                                 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2465                                 M_INTMOVE(REG_RESULT, s1);
2466                                 emit_store_dst(jd, iptr, s1);
2467                                 break;
2468                         case TYPE_FLT:
2469                         case TYPE_DBL:
2470                                 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2471                                 M_FLTMOVE(REG_FRESULT, s1);
2472                                 emit_store_dst(jd, iptr, s1);
2473                                 break;
2474                         default:
2475                                 /* TYPE_VOID */
2476                                 break;
2477                         }
2478                         break;
2479
2480
2481                 case ICMD_CHECKCAST:  /* ..., objectref ==> ..., objectref            */
2482
2483                         if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2484                                 /* object type cast-check */
2485
2486                                 classinfo *super;
2487                                 s4         superindex;
2488
2489                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2490                                         super      = NULL;
2491                                         superindex = 0;
2492                                 }
2493                                 else {
2494                                         super      = iptr->sx.s23.s3.c.cls;
2495                                         superindex = super->index;
2496                                 }
2497
2498                                 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2499                                         CODEGEN_CRITICAL_SECTION_NEW;
2500
2501                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2502
2503                                 /* if class is not resolved, check which code to call */
2504
2505                                 if (super == NULL) {
2506                                         M_TEST(s1);
2507                                         emit_label_beq(cd, BRANCH_LABEL_1);
2508
2509                                         patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
2510                                                                                   iptr->sx.s23.s3.c.ref, 0);
2511
2512                                         M_IMOV_IMM(0, REG_ITMP2);                 /* super->flags */
2513                                         M_IAND_IMM(ACC_INTERFACE, REG_ITMP2);
2514                                         emit_label_beq(cd, BRANCH_LABEL_2);
2515                                 }
2516
2517                                 /* interface checkcast code */
2518
2519                                 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2520                                         if (super != NULL) {
2521                                                 M_TEST(s1);
2522                                                 emit_label_beq(cd, BRANCH_LABEL_3);
2523                                         }
2524
2525                                         M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2526
2527                                         if (super == NULL) {
2528                                                 patcher_add_patch_ref(jd, PATCHER_checkcast_interface,
2529                                                                                           iptr->sx.s23.s3.c.ref,
2530                                                                                           0);
2531                                         }
2532
2533                                         M_ILD32(REG_ITMP3,
2534                                                         REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
2535                                         M_ICMP_IMM32(superindex, REG_ITMP3);
2536                                         emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2537
2538                                         M_ALD32(REG_ITMP3, REG_ITMP2, 
2539                                                         OFFSET(vftbl_t, interfacetable[0]) -
2540                                                         superindex * sizeof(methodptr*));
2541                                         M_TEST(REG_ITMP3);
2542                                         emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
2543
2544                                         if (super == NULL)
2545                                                 emit_label_br(cd, BRANCH_LABEL_4);
2546                                         else
2547                                                 emit_label(cd, BRANCH_LABEL_3);
2548                                 }
2549
2550                                 /* class checkcast code */
2551
2552                                 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2553                                         if (super == NULL) {
2554                                                 emit_label(cd, BRANCH_LABEL_2);
2555
2556                                                 cr   = iptr->sx.s23.s3.c.ref;
2557                                                 disp = dseg_add_unique_address(cd, cr);
2558
2559                                                 patcher_add_patch_ref(jd,
2560                                                                                           PATCHER_resolve_classref_to_vftbl,
2561                                                                                           cr, disp);
2562                                         }
2563                                         else {
2564                                                 M_TEST(s1);
2565                                                 emit_label_beq(cd, BRANCH_LABEL_5);
2566
2567                                                 disp = dseg_add_address(cd, super->vftbl);
2568                                         }
2569
2570                                         M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2571                                         M_ALD(REG_ITMP3, RIP, disp);
2572
2573                                         CODEGEN_CRITICAL_SECTION_START;
2574
2575                                         M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2576
2577                                         /*                                      if (s1 != REG_ITMP1) { */
2578                                         /*                                              emit_movl_membase_reg(cd, REG_ITMP3, */
2579                                         /*                                                                                              OFFSET(vftbl_t, baseval), */
2580                                         /*                                                                                              REG_ITMP1); */
2581                                         /*                                              emit_movl_membase_reg(cd, REG_ITMP3, */
2582                                         /*                                                                                              OFFSET(vftbl_t, diffval), */
2583                                         /*                                                                                              REG_ITMP3); */
2584                                         /*  #if defined(ENABLE_THREADS) */
2585                                         /*                                              codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
2586                                         /*  #endif */
2587                                         /*                                              emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP1, REG_ITMP2); */
2588
2589                                         /*                                      } else { */
2590
2591                                         M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2592                                         M_ISUB(REG_ITMP3, REG_ITMP2);
2593                                         M_ALD(REG_ITMP3, RIP, disp);
2594                                         M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2595                                         /*                                      } */
2596
2597                                         CODEGEN_CRITICAL_SECTION_END;
2598
2599                                         M_ICMP(REG_ITMP3, REG_ITMP2);
2600                                         emit_classcast_check(cd, iptr, BRANCH_UGT, REG_ITMP3, s1);
2601
2602                                         if (super != NULL)
2603                                                 emit_label(cd, BRANCH_LABEL_5);
2604                                 }
2605
2606                                 if (super == NULL) {
2607                                         emit_label(cd, BRANCH_LABEL_1);
2608                                         emit_label(cd, BRANCH_LABEL_4);
2609                                 }
2610
2611                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
2612                         }
2613                         else {
2614                                 /* array type cast-check */
2615
2616                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2617                                 M_INTMOVE(s1, REG_A0);
2618
2619                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2620                                         cr   = iptr->sx.s23.s3.c.ref;
2621                                         disp = dseg_add_unique_address(cd, cr);
2622
2623                                         patcher_add_patch_ref(jd,
2624                                                                                   PATCHER_resolve_classref_to_classinfo,
2625                                                                                   cr, disp);
2626                                 }
2627                                 else {
2628                                         disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2629                                 }
2630
2631                                 M_ALD(REG_A1, RIP, disp);
2632                                 M_MOV_IMM(BUILTIN_arraycheckcast, REG_ITMP1);
2633                                 M_CALL(REG_ITMP1);
2634
2635                                 /* s1 may have been destroyed over the function call */
2636                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2637                                 M_TEST(REG_RESULT);
2638                                 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2639
2640                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2641                         }
2642
2643                         M_INTMOVE(s1, d);
2644                         emit_store_dst(jd, iptr, d);
2645                         break;
2646
2647                 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
2648
2649                         {
2650                         classinfo *super;
2651                         s4         superindex;
2652
2653                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2654                                 super      = NULL;
2655                                 superindex = 0;
2656                         }
2657                         else {
2658                                 super      = iptr->sx.s23.s3.c.cls;
2659                                 superindex = super->index;
2660                         }
2661
2662                         if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2663                                 CODEGEN_CRITICAL_SECTION_NEW;
2664
2665                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2666                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2667
2668                         if (s1 == d) {
2669                                 M_INTMOVE(s1, REG_ITMP1);
2670                                 s1 = REG_ITMP1;
2671                         }
2672
2673                         M_CLR(d);
2674
2675                         /* if class is not resolved, check which code to call */
2676
2677                         if (super == NULL) {
2678                                 M_TEST(s1);
2679                                 emit_label_beq(cd, BRANCH_LABEL_1);
2680
2681                                 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
2682                                                                           iptr->sx.s23.s3.c.ref, 0);
2683
2684                                 M_IMOV_IMM(0, REG_ITMP3);                     /* super->flags */
2685                                 M_IAND_IMM(ACC_INTERFACE, REG_ITMP3);
2686                                 emit_label_beq(cd, BRANCH_LABEL_2);
2687                         }
2688
2689                         /* interface instanceof code */
2690
2691                         if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2692                                 if (super != NULL) {
2693                                         M_TEST(s1);
2694                                         emit_label_beq(cd, BRANCH_LABEL_3);
2695                                 }
2696
2697                                 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2698
2699                                 if (super == NULL) {
2700                                         patcher_add_patch_ref(jd, PATCHER_instanceof_interface,
2701                                                                                   iptr->sx.s23.s3.c.ref, 0);
2702                                 }
2703
2704                                 M_ILD32(REG_ITMP3,
2705                                                 REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2706                                 M_ICMP_IMM32(superindex, REG_ITMP3);
2707
2708                                 a = 3 + 4 /* mov_membase32_reg */ + 3 /* test */ + 4 /* setcc */;
2709
2710                                 M_BLE(a);
2711                                 M_ALD32(REG_ITMP1, REG_ITMP1,
2712                                                 OFFSET(vftbl_t, interfacetable[0]) -
2713                                                 superindex * sizeof(methodptr*));
2714                                 M_TEST(REG_ITMP1);
2715                                 M_SETNE(d);
2716
2717                                 if (super == NULL)
2718                                         emit_label_br(cd, BRANCH_LABEL_4);
2719                                 else
2720                                         emit_label(cd, BRANCH_LABEL_3);
2721                         }
2722
2723                         /* class instanceof code */
2724
2725                         if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2726                                 if (super == NULL) {
2727                                         emit_label(cd, BRANCH_LABEL_2);
2728
2729                                         cr   = iptr->sx.s23.s3.c.ref;
2730                                         disp = dseg_add_unique_address(cd, cr);
2731
2732                                         patcher_add_patch_ref(jd,
2733                                                                                   PATCHER_resolve_classref_to_vftbl,
2734                                                                                   cr, disp);
2735                                 }
2736                                 else {
2737                                         M_TEST(s1);
2738                                         emit_label_beq(cd, BRANCH_LABEL_5);
2739
2740                                         disp = dseg_add_address(cd, super->vftbl);
2741                                 }
2742
2743                                 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2744                                 M_ALD(REG_ITMP2, RIP, disp);
2745
2746                                 CODEGEN_CRITICAL_SECTION_START;
2747
2748                                 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
2749                                 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, diffval));
2750                                 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2751
2752                                 CODEGEN_CRITICAL_SECTION_END;
2753
2754                                 M_ISUB(REG_ITMP2, REG_ITMP1);
2755                                 M_CLR(d); /* may be REG_ITMP2 */
2756                                 M_ICMP(REG_ITMP3, REG_ITMP1);
2757                                 M_SETULE(d);
2758
2759                                 if (super != NULL)
2760                                         emit_label(cd, BRANCH_LABEL_5);
2761                         }
2762
2763                         if (super == NULL) {
2764                                 emit_label(cd, BRANCH_LABEL_1);
2765                                 emit_label(cd, BRANCH_LABEL_4);
2766                         }
2767
2768                         emit_store_dst(jd, iptr, d);
2769                         }
2770                         break;
2771
2772                 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref  */
2773
2774                         /* check for negative sizes and copy sizes to stack if necessary  */
2775
2776                         MCODECHECK((10 * 4 * iptr->s1.argcount) + 5 + 10 * 8);
2777
2778                         for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2779
2780                                 /* copy SAVEDVAR sizes to stack */
2781                                 var = VAR(iptr->sx.s23.s2.args[s1]);
2782
2783                                 /* Already Preallocated? */
2784                                 if (!(var->flags & PREALLOC)) {
2785                                         s2 = emit_load(jd, iptr, var, REG_ITMP1);
2786                                         M_LST(s2, REG_SP, s1 * 8);
2787                                 }
2788                         }
2789
2790                         /* a0 = dimension count */
2791
2792                         M_MOV_IMM(iptr->s1.argcount, REG_A0);
2793
2794                         /* is a patcher function set? */
2795
2796                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2797                                 cr   = iptr->sx.s23.s3.c.ref;
2798                                 disp = dseg_add_unique_address(cd, cr);
2799
2800                                 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
2801                                                                           cr, disp);
2802                         }
2803                         else {
2804                                 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2805                         }
2806
2807                         /* a1 = classinfo */
2808
2809                         M_ALD(REG_A1, RIP, disp);
2810
2811                         /* a2 = pointer to dimensions = stack pointer */
2812
2813                         M_MOV(REG_SP, REG_A2);
2814
2815                         M_MOV_IMM(BUILTIN_multianewarray, REG_ITMP1);
2816                         M_CALL(REG_ITMP1);
2817
2818                         /* check for exception before result assignment */
2819
2820                         emit_exception_check(cd, iptr);
2821
2822                         s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2823                         M_INTMOVE(REG_RESULT, s1);
2824                         emit_store_dst(jd, iptr, s1);
2825                         break;
2826
2827                 default:
2828                         exceptions_throw_internalerror("Unknown ICMD %d during code generation",
2829                                                                                    iptr->opc);
2830                         return false;
2831         } /* switch */
2832
2833         } /* for instruction */
2834                 
2835         MCODECHECK(512); /* XXX require a lower number? */
2836
2837         /* At the end of a basic block we may have to append some nops,
2838            because the patcher stub calling code might be longer than the
2839            actual instruction. So codepatching does not change the
2840            following block unintentionally. */
2841
2842         if (cd->mcodeptr < cd->lastmcodeptr) {
2843                 while (cd->mcodeptr < cd->lastmcodeptr) {
2844                         M_NOP;
2845                 }
2846         }
2847
2848         } /* if (bptr -> flags >= BBREACHED) */
2849         } /* for basic block */
2850
2851         /* Generate patcher traps. */
2852
2853         emit_patcher_traps(jd);
2854
2855         /* everything's ok */
2856
2857         return true;
2858 }
2859
2860
2861 /* codegen_emit_stub_native ****************************************************
2862
2863    Emits a stub routine which calls a native method.
2864
2865 *******************************************************************************/
2866
2867 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
2868 {
2869         methodinfo  *m;
2870         codeinfo    *code;
2871         codegendata *cd;
2872         methoddesc  *md;
2873         int          i, j;
2874         int          s1, s2;
2875         int          disp;
2876
2877         /* Sanity check. */
2878
2879         assert(f != NULL);
2880
2881         /* Get required compiler data. */
2882
2883         m    = jd->m;
2884         code = jd->code;
2885         cd   = jd->cd;
2886
2887         /* initialize variables */
2888
2889         md = m->parseddesc;
2890
2891         /* calculate stack frame size */
2892
2893         cd->stackframesize =
2894                 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
2895                 sizeof(localref_table) / SIZEOF_VOID_P +
2896                 md->paramcount +
2897                 (md->returntype.type == TYPE_VOID ? 0 : 1) +
2898                 nmd->memuse;
2899
2900         ALIGN_ODD(cd->stackframesize);              /* keep stack 16-byte aligned */
2901
2902         /* create method header */
2903
2904         (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
2905         (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize       */
2906         (void) dseg_add_unique_s4(cd, 0);                      /* IsLeaf          */
2907         (void) dseg_add_unique_s4(cd, 0);                      /* IntSave         */
2908         (void) dseg_add_unique_s4(cd, 0);                      /* FltSave         */
2909
2910 #if defined(ENABLE_PROFILING)
2911         /* generate native method profiling code */
2912
2913         if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
2914                 /* count frequency */
2915
2916                 M_MOV_IMM(code, REG_ITMP3);
2917                 M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
2918         }
2919 #endif
2920
2921         /* generate stub code */
2922
2923         M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
2924
2925 #if defined(ENABLE_GC_CACAO)
2926         /* Save callee saved integer registers in stackframeinfo (GC may
2927            need to recover them during a collection). */
2928
2929         disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
2930                 OFFSET(stackframeinfo_t, intregs);
2931
2932         for (i = 0; i < INT_SAV_CNT; i++)
2933                 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
2934 #endif
2935
2936         /* save integer and float argument registers */
2937
2938         for (i = 0; i < md->paramcount; i++) {
2939                 if (!md->params[i].inmemory) {
2940                         s1 = md->params[i].regoff;
2941
2942                         switch (md->paramtypes[i].type) {
2943                         case TYPE_INT:
2944                         case TYPE_LNG:
2945                         case TYPE_ADR:
2946                                 M_LST(s1, REG_SP, i * 8);
2947                                 break;
2948                         case TYPE_FLT:
2949                         case TYPE_DBL:
2950                                 M_DST(s1, REG_SP, i * 8);
2951                                 break;
2952                         }
2953                 }
2954         }
2955
2956         /* create dynamic stack info */
2957
2958         M_MOV(REG_SP, REG_A0);
2959         emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
2960         M_MOV_IMM(codegen_start_native_call, REG_ITMP1);
2961         M_CALL(REG_ITMP1);
2962
2963         /* remember class argument */
2964
2965         if (m->flags & ACC_STATIC)
2966                 M_MOV(REG_RESULT, REG_ITMP2);
2967
2968         /* restore integer and float argument registers */
2969
2970         for (i = 0; i < md->paramcount; i++) {
2971                 if (!md->params[i].inmemory) {
2972                         s1 = md->params[i].regoff;
2973
2974                         switch (md->paramtypes[i].type) {
2975                         case TYPE_INT:
2976                         case TYPE_LNG:
2977                         case TYPE_ADR:
2978                                 M_LLD(s1, REG_SP, i * 8);
2979                                 break;
2980                         case TYPE_FLT:
2981                         case TYPE_DBL:
2982                                 M_DLD(s1, REG_SP, i * 8);
2983                                 break;
2984                         }
2985                 }
2986         }
2987
2988         /* Copy or spill arguments to new locations. */
2989
2990         for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
2991                 s2 = nmd->params[j].regoff;
2992
2993                 switch (md->paramtypes[i].type) {
2994                 case TYPE_INT:
2995                 case TYPE_LNG:
2996                 case TYPE_ADR:
2997                         if (!md->params[i].inmemory) {
2998                                 s1 = md->params[i].regoff;
2999
3000                                 if (!nmd->params[j].inmemory)
3001                                         M_INTMOVE(s1, s2);
3002                                 else
3003                                         M_LST(s1, REG_SP, s2);
3004                         }
3005                         else {
3006                                 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
3007                                 M_LLD(REG_ITMP1, REG_SP, s1);
3008                                 M_LST(REG_ITMP1, REG_SP, s2);
3009                         }
3010                         break;
3011                 case TYPE_FLT:
3012                         /* We only copy spilled float arguments, as the float
3013                            argument registers keep unchanged. */
3014
3015                         if (md->params[i].inmemory) {
3016                                 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
3017
3018                                 M_FLD(REG_FTMP1, REG_SP, s1);
3019                                 M_FST(REG_FTMP1, REG_SP, s2);
3020                         }
3021                         break;
3022                 case TYPE_DBL:
3023                         if (md->params[i].inmemory) {
3024                                 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
3025                                 M_DLD(REG_FTMP1, REG_SP, s1);
3026                                 M_DST(REG_FTMP1, REG_SP, s2);
3027                         }
3028                         break;
3029                 }
3030         }
3031
3032         /* Handle native Java methods. */
3033
3034         if (m->flags & ACC_NATIVE) {
3035                 /* put class into second argument register */
3036
3037                 if (m->flags & ACC_STATIC)
3038                         M_MOV(REG_ITMP2, REG_A1);
3039
3040                 /* put env into first argument register */
3041
3042                 M_MOV_IMM(_Jv_env, REG_A0);
3043         }
3044
3045         /* Call the native function. */
3046
3047         disp = dseg_add_functionptr(cd, f);
3048         M_ALD(REG_ITMP1, RIP, disp);
3049         M_CALL(REG_ITMP1);
3050
3051         /* save return value */
3052
3053         switch (md->returntype.type) {
3054         case TYPE_INT:
3055         case TYPE_LNG:
3056         case TYPE_ADR:
3057                 M_LST(REG_RESULT, REG_SP, 0 * 8);
3058                 break;
3059         case TYPE_FLT:
3060         case TYPE_DBL:
3061                 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3062                 break;
3063         case TYPE_VOID:
3064                 break;
3065         }
3066
3067         /* remove native stackframe info */
3068
3069         M_MOV(REG_SP, REG_A0);
3070         emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
3071         M_MOV_IMM(codegen_finish_native_call, REG_ITMP1);
3072         M_CALL(REG_ITMP1);
3073         M_MOV(REG_RESULT, REG_ITMP3);
3074
3075         /* restore return value */
3076
3077         switch (md->returntype.type) {
3078         case TYPE_INT:
3079         case TYPE_LNG:
3080         case TYPE_ADR:
3081                 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3082                 break;
3083         case TYPE_FLT:
3084         case TYPE_DBL:
3085                 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3086                 break;
3087         case TYPE_VOID:
3088                 break;
3089         }
3090
3091 #if defined(ENABLE_GC_CACAO)
3092         /* Restore callee saved integer registers from stackframeinfo (GC
3093            might have modified them during a collection). */
3094         
3095         disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
3096                 OFFSET(stackframeinfo_t, intregs);
3097
3098         for (i = 0; i < INT_SAV_CNT; i++)
3099                 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3100 #endif
3101
3102         /* remove stackframe */
3103
3104         M_AADD_IMM(cd->stackframesize * 8, REG_SP);
3105
3106         /* test for exception */
3107
3108         M_TEST(REG_ITMP3);
3109         M_BNE(1);
3110         M_RET;
3111
3112         /* handle exception */
3113
3114         M_MOV(REG_ITMP3, REG_ITMP1_XPTR);
3115         M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);     /* get return address from stack */
3116         M_ASUB_IMM(3, REG_ITMP2_XPC);                                    /* callq */
3117
3118         M_MOV_IMM(asm_handle_nat_exception, REG_ITMP3);
3119         M_JMP(REG_ITMP3);
3120 }
3121
3122
3123 /*
3124  * These are local overrides for various environment variables in Emacs.
3125  * Please do not remove this and leave it at the end of the file, where
3126  * Emacs will automagically detect them.
3127  * ---------------------------------------------------------------------
3128  * Local variables:
3129  * mode: c
3130  * indent-tabs-mode: t
3131  * c-basic-offset: 4
3132  * tab-width: 4
3133  * End:
3134  * vim:noexpandtab:sw=4:ts=4:
3135  */