LCOV - code coverage report
Current view: top level - vm/jit/x86_64 - codegen.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1257 1364 92.2 %
Date: 2017-07-14 10:03:36 Functions: 6 6 100.0 %

          Line data    Source code
       1             : /* src/vm/jit/x86_64/codegen.cpp - machine code generator for x86_64
       2             : 
       3             :    Copyright (C) 1996-2013
       4             :    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
       5             : 
       6             :    This file is part of CACAO.
       7             : 
       8             :    This program is free software; you can redistribute it and/or
       9             :    modify it under the terms of the GNU General Public License as
      10             :    published by the Free Software Foundation; either version 2, or (at
      11             :    your option) any later version.
      12             : 
      13             :    This program is distributed in the hope that it will be useful, but
      14             :    WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      16             :    General Public License for more details.
      17             : 
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program; if not, write to the Free Software
      20             :    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
      21             :    02110-1301, USA.
      22             : 
      23             : */
      24             : 
      25             : 
      26             : #include "config.h"
      27             : 
      28             : #include <cassert>
      29             : #include <cstdio>
      30             : #include <stdint.h>
      31             : 
      32             : #include "vm/types.hpp"
      33             : #include "vm/os.hpp"
      34             : 
      35             : #include "md-abi.hpp"
      36             : 
      37             : #include "vm/jit/x86_64/codegen.hpp"
      38             : #include "vm/jit/x86_64/emit.hpp"
      39             : 
      40             : #include "mm/memory.hpp"
      41             : 
      42             : #include "native/localref.hpp"
      43             : #include "native/native.hpp"
      44             : 
      45             : #include "threads/lock.hpp"
      46             : 
      47             : #include "vm/descriptor.hpp"
      48             : #include "vm/exceptions.hpp"
      49             : #include "vm/field.hpp"
      50             : #include "vm/global.hpp"
      51             : #include "vm/options.hpp"
      52             : #include "vm/primitive.hpp"
      53             : #include "vm/statistics.hpp"
      54             : #include "vm/vm.hpp"
      55             : 
      56             : #include "vm/jit/abi.hpp"
      57             : #include "vm/jit/asmpart.hpp"
      58             : #include "vm/jit/builtin.hpp"
      59             : #include "vm/jit/code.hpp"
      60             : #include "vm/jit/codegen-common.hpp"
      61             : #include "vm/jit/dseg.hpp"
      62             : #include "vm/jit/emit-common.hpp"
      63             : #include "vm/jit/jit.hpp"
      64             : #include "vm/jit/linenumbertable.hpp"
      65             : #include "vm/jit/methodheader.hpp"
      66             : #include "vm/jit/parse.hpp"
      67             : #include "vm/jit/patcher-common.hpp"
      68             : #include "vm/jit/reg.hpp"
      69             : #include "vm/jit/stacktrace.hpp"
      70             : #include "vm/jit/trap.hpp"
      71             : 
      72             : 
      73             : /**
      74             :  * Generates machine code for the method prolog.
      75             :  */
      76       86399 : void codegen_emit_prolog(jitdata* jd)
      77             : {
      78             :         varinfo*    var;
      79             :         methoddesc* md;
      80             :         int32_t     s1;
      81             :         int32_t     p, t, l;
      82             :         int32_t     varindex;
      83             :         int         i;
      84             : 
      85             :         // Get required compiler data.
      86       86399 :         methodinfo*   m  = jd->m;
      87       86399 :         codegendata*  cd = jd->cd;
      88       86399 :         registerdata* rd = jd->rd;
      89             : 
      90             :         /* create stack frame (if necessary) */
      91             : 
      92       86399 :         if (cd->stackframesize)
      93       76451 :                 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
      94             : 
      95             :         /* save used callee saved registers */
      96             : 
      97       86399 :         p = cd->stackframesize;
      98      286160 :         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
      99      199761 :                 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
     100             :         }
     101       86399 :         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
     102           0 :                 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
     103             :         }
     104             : 
     105             :         /* take arguments out of register or stack frame */
     106             : 
     107       86399 :         md = m->parseddesc;
     108             : 
     109      227649 :         for (p = 0, l = 0; p < md->paramcount; p++) {
     110      141250 :                 t = md->paramtypes[p].type;
     111             : 
     112      141250 :                 varindex = jd->local_map[l * 5 + t];
     113             : 
     114      141250 :                 l++;
     115      141250 :                 if (IS_2_WORD_TYPE(t))    /* increment local counter for 2 word types */
     116         412 :                         l++;
     117             : 
     118      141250 :                 if (varindex == jitdata::UNUSED)
     119        5607 :                         continue;
     120             : 
     121      135643 :                 var = VAR(varindex);
     122             :                 
     123      135643 :                 s1 = md->params[p].regoff;
     124             : 
     125      135643 :                 if (IS_INT_LNG_TYPE(t)) {                    /* integer args          */
     126      134212 :                         if (!md->params[p].inmemory) {           /* register arguments    */
     127      131907 :                                 if (!IS_INMEMORY(var->flags))
     128      126890 :                                         M_INTMOVE(s1, var->vv.regoff);
     129             :                                 else
     130        5017 :                                     M_LST(s1, REG_SP, var->vv.regoff);
     131             :                         }
     132             :                         else {                                 /* stack arguments       */
     133        2305 :                                 if (!IS_INMEMORY(var->flags))
     134             :                                         /* + 8 for return address */
     135           3 :                                         M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1 + 8);
     136             :                                 else
     137        2302 :                                         var->vv.regoff = cd->stackframesize * 8 + s1 + 8;
     138             :                         }
     139             :                 }
     140             :                 else {                                     /* floating args         */
     141             :                         // With SSE, the fst/dld instructions don't actually mean "store a
     142             :                         // float/double to memory", but rather "store the lower 32/64 bits
     143             :                         // of the register to memory". Therefore we get by with treating
     144             :                         // all floating point values the same.
     145        1431 :                         if (!md->params[p].inmemory) {           /* register arguments    */
     146        1383 :                                 if (!IS_INMEMORY(var->flags))
     147          23 :                                         emit_fmove(cd, s1, var->vv.regoff);
     148             :                                 else
     149        1360 :                                         M_DST(s1, REG_SP, var->vv.regoff);
     150             :                         }
     151             :                         else {                                 /* stack arguments       */
     152          48 :                                 if (!IS_INMEMORY(var->flags))
     153           0 :                                         M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1 + 8);
     154             :                                 else
     155          48 :                                         var->vv.regoff = cd->stackframesize * 8 + s1 + 8;
     156             :                         }
     157             :                 }
     158             :         }
     159       86399 : }
     160             : 
     161             : 
     162             : /**
     163             :  * Generates machine code for the method epilog.
     164             :  */
     165      103267 : void codegen_emit_epilog(jitdata* jd)
     166             : {
     167             :         int32_t p;
     168             :         int i;
     169             : 
     170             :         // Get required compiler data.
     171      103267 :         codegendata*  cd = jd->cd;
     172      103267 :         registerdata* rd = jd->rd;
     173             : 
     174      103267 :         p = cd->stackframesize;
     175             : 
     176             :         /* restore saved registers */
     177             : 
     178      357549 :         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
     179      254282 :                 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
     180             :         }
     181      103267 :         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
     182           0 :                 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
     183             :         }
     184             : 
     185             :         /* deallocate stack */
     186             : 
     187      103267 :         if (cd->stackframesize)
     188       91235 :                 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
     189             : 
     190      103267 :         M_RET;
     191      103267 : }
     192             : 
     193             : /**
     194             :  * Generates a memory barrier to be used after volatile writes. It can be
     195             :  * patched out later if the field turns out not to be volatile.
     196             :  */
     197       74865 : void codegen_emit_patchable_barrier(instruction *iptr, codegendata *cd, patchref_t *pr, fieldinfo *fi)
     198             : {
     199       74865 :         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
     200             :                 /* Align on word boundary */
     201        2055 :                 if ((((intptr_t) cd->mcodeptr) & 3) >= 2)
     202         163 :                         emit_nop(cd, 4 - (((intptr_t) cd->mcodeptr) & 3));
     203             :                 /* Displacement for patching out MFENCE */
     204        2055 :                 pr->disp_mb = (cd->mcodeptr - cd->mcodebase - pr->mpc);
     205             :         }
     206       74865 :         if (INSTRUCTION_IS_UNRESOLVED(iptr) || fi->flags & ACC_VOLATILE)
     207        3142 :                 M_MFENCE;
     208       74865 : }
     209             : 
     210             : /**
     211             :  * Ensures that the patched location (an int32_t) is aligned.
     212             :  */
     213        1391 : static void codegen_fixup_alignment(codegendata *cd, patchref_t *pr, u1 *mcodeptr_save)
     214             : {
     215        1391 :         u1 *codeptr = cd->mcodeptr;
     216        1391 :         int disp = PATCH_ALIGNMENT((uintptr_t) cd->mcodeptr, 0, sizeof(int32_t));
     217        1391 :         memmove(mcodeptr_save + disp, mcodeptr_save, cd->mcodeptr - mcodeptr_save);
     218        1391 :         pr->patch_align += cd->mcodeptr - mcodeptr_save + disp;
     219             : 
     220        1391 :         cd->mcodeptr = mcodeptr_save;
     221        1391 :         emit_arbitrary_nop(cd, disp);
     222        1391 :         cd->mcodeptr = codeptr + disp;
     223        1391 : }
     224             : 
     225             : /**
     226             :  * Generates machine code for one ICMD.
     227             :  */
     228     1368799 : void codegen_emit_instruction(jitdata* jd, instruction* iptr)
     229             : {
     230             :         varinfo*            var;
     231             :         varinfo*            dst;
     232             :         builtintable_entry* bte;
     233             :         methodinfo*         lm;             // Local methodinfo for ICMD_INVOKE*.
     234             :         unresolved_method*  um;
     235             :         fieldinfo*          fi;
     236             :         unresolved_field*   uf;
     237             :         patchref_t*         pr;
     238             :         int32_t             fieldtype;
     239             :         int32_t             s1, s2, s3, d;
     240             :         int32_t             disp;
     241     1368799 :         u1*                 mcodeptr_save = NULL;
     242             : 
     243             :         // Get required compiler data.
     244     1368799 :         codegendata*  cd = jd->cd;
     245             : 
     246     1368799 :         switch (iptr->opc) {
     247             : 
     248             :                 /* constant operations ************************************************/
     249             : 
     250             :                 case ICMD_FCONST:     /* ...  ==> ..., constant                       */
     251             : 
     252        4946 :                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
     253        4946 :                         disp = dseg_add_float(cd, iptr->sx.val.f);
     254        4946 :                         emit_movdl_membase_reg(cd, RIP, -((cd->mcodeptr + ((d > 7) ? 9 : 8)) - cd->mcodebase) + disp, d);
     255        4946 :                         emit_store_dst(jd, iptr, d);
     256        4946 :                         break;
     257             :                 
     258             :                 case ICMD_DCONST:     /* ...  ==> ..., constant                       */
     259             : 
     260         233 :                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
     261         233 :                         disp = dseg_add_double(cd, iptr->sx.val.d);
     262         233 :                         emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, d);
     263         233 :                         emit_store_dst(jd, iptr, d);
     264         233 :                         break;
     265             : 
     266             :                 case ICMD_ACONST:     /* ...  ==> ..., constant                       */
     267             : 
     268      165085 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
     269             : 
     270      165085 :                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
     271       32158 :                                 constant_classref *cr = iptr->sx.val.c.ref;
     272       32158 :                                 disp = dseg_add_unique_address(cd, cr);
     273             : 
     274             : /*                              PROFILE_CYCLE_STOP; */
     275             : 
     276             :                                 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
     277       32158 :                                                                           cr, disp);
     278             : 
     279             : /*                              PROFILE_CYCLE_START; */
     280             : 
     281       32158 :                                 M_ALD(d, RIP, disp);
     282             :                         }
     283             :                         else {
     284      132927 :                                 if (iptr->sx.val.anyptr == 0) {
     285       11807 :                                         M_CLR(d);
     286             :                                 }
     287             :                                 else {
     288      121120 :                                         disp = dseg_add_address(cd, iptr->sx.val.anyptr);
     289      121120 :                                         M_ALD(d, RIP, disp);
     290             :                                 }
     291             :                         }
     292      165085 :                         emit_store_dst(jd, iptr, d);
     293      165085 :                         break;
     294             : 
     295             : 
     296             :                 /* integer operations *************************************************/
     297             : 
     298             :                 case ICMD_INEG:       /* ..., value  ==> ..., - value                 */
     299             : 
     300         756 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1); 
     301         756 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
     302         756 :                         M_INTMOVE(s1, d);
     303         756 :                         M_INEG(d);
     304         756 :                         emit_store_dst(jd, iptr, d);
     305         756 :                         break;
     306             : 
     307             :                 case ICMD_LNEG:       /* ..., value  ==> ..., - value                 */
     308             : 
     309          50 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1); 
     310          50 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
     311          50 :                         M_INTMOVE(s1, d);
     312          50 :                         M_LNEG(d);
     313          50 :                         emit_store_dst(jd, iptr, d);
     314          50 :                         break;
     315             : 
     316             :                 case ICMD_I2L:        /* ..., value  ==> ..., value                   */
     317             : 
     318         370 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
     319         370 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
     320         370 :                         M_ISEXT(s1, d);
     321         370 :                         emit_store_dst(jd, iptr, d);
     322         370 :                         break;
     323             : 
     324             :                 case ICMD_L2I:        /* ..., value  ==> ..., value                   */
     325             : 
     326         267 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
     327         267 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
     328         267 :                         M_IMOV(s1, d);
     329         267 :                         emit_store_dst(jd, iptr, d);
     330         267 :                         break;
     331             : 
     332             :                 case ICMD_INT2BYTE:   /* ..., value  ==> ..., value                   */
     333             : 
     334         272 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
     335         272 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
     336         272 :                         M_BSEXT(s1, d);
     337         272 :                         emit_store_dst(jd, iptr, d);
     338         272 :                         break;
     339             : 
     340             :                 case ICMD_INT2CHAR:   /* ..., value  ==> ..., value                   */
     341             : 
     342        1037 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
     343        1037 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
     344        1037 :                         M_CZEXT(s1, d);
     345        1037 :                         emit_store_dst(jd, iptr, d);
     346        1037 :                         break;
     347             : 
     348             :                 case ICMD_INT2SHORT:  /* ..., value  ==> ..., value                   */
     349             : 
     350         144 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
     351         144 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
     352         144 :                         M_SSEXT(s1, d);
     353         144 :                         emit_store_dst(jd, iptr, d);
     354         144 :                         break;
     355             : 
     356             : 
     357             :                 case ICMD_IADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
     358             : 
     359        6032 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
     360        6032 :                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
     361        6032 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
     362        6032 :                         if (s2 == d)
     363         376 :                                 M_IADD(s1, d);
     364             :                         else {
     365        5656 :                                 M_INTMOVE(s1, d);
     366        5656 :                                 M_IADD(s2, d);
     367             :                         }
     368        6032 :                         emit_store_dst(jd, iptr, d);
     369        6032 :                         break;
     370             : 
     371             :                 case ICMD_IINC:
     372             :                 case ICMD_IADDCONST:  /* ..., value  ==> ..., value + constant        */
     373             :                                       /* sx.val.i = constant                             */
     374             : 
     375       19771 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
     376       19771 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
     377             : 
     378             :                         /* Using inc and dec is not faster than add (tested with
     379             :                            sieve). */
     380             : 
     381       19771 :                         M_INTMOVE(s1, d);
     382       19771 :                         M_IADD_IMM(iptr->sx.val.i, d);
     383       19771 :                         emit_store_dst(jd, iptr, d);
     384       19771 :                         break;
     385             : 
     386             :                 case ICMD_LADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
     387             : 
     388         132 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
     389         132 :                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
     390         132 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
     391         132 :                         if (s2 == d)
     392          12 :                                 M_LADD(s1, d);
     393             :                         else {
     394         120 :                                 M_INTMOVE(s1, d);
     395         120 :                                 M_LADD(s2, d);
     396             :                         }
     397         132 :                         emit_store_dst(jd, iptr, d);
     398         132 :                         break;
     399             : 
     400             :                 case ICMD_LADDCONST:  /* ..., value  ==> ..., value + constant        */
     401             :                                       /* sx.val.l = constant                             */
     402             : 
     403         192 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
     404         192 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
     405         192 :                         M_INTMOVE(s1, d);
     406         381 :                         if (IS_IMM32(iptr->sx.val.l))
     407         189 :                                 M_LADD_IMM(iptr->sx.val.l, d);
     408             :                         else {
     409           3 :                                 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
     410           3 :                                 M_LADD(REG_ITMP2, d);
     411             :                         }
     412         192 :                         emit_store_dst(jd, iptr, d);
     413         192 :                         break;
     414             : 
     415             :                 case ICMD_ISUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
     416             : 
     417        3458 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
     418        3458 :                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
     419        3458 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
     420        3458 :                         if (s2 == d) {
     421         749 :                                 M_INTMOVE(s1, REG_ITMP1);
     422         749 :                                 M_ISUB(s2, REG_ITMP1);
     423         749 :                                 M_INTMOVE(REG_ITMP1, d);
     424             :                         } else {
     425        2709 :                                 M_INTMOVE(s1, d);
     426        2709 :                                 M_ISUB(s2, d);
     427             :                         }
     428        3458 :                         emit_store_dst(jd, iptr, d);
     429        3458 :                         break;
     430             : 
     431             :                 case ICMD_ISUBCONST:  /* ..., value  ==> ..., value + constant        */
     432             :                                       /* sx.val.i = constant                             */
     433             : 
     434        4732 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
     435        4732 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
     436        4732 :                         M_INTMOVE(s1, d);
     437        4732 :                         M_ISUB_IMM(iptr->sx.val.i, d);
     438        4732 :                         emit_store_dst(jd, iptr, d);
     439        4732 :                         break;
     440             : 
     441             :                 case ICMD_LSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
     442             : 
     443          59 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
     444          59 :                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
     445          59 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
     446          59 :                         if (s2 == d) {
     447           4 :                                 M_INTMOVE(s1, REG_ITMP1);
     448           4 :                                 M_LSUB(s2, REG_ITMP1);
     449           4 :                                 M_INTMOVE(REG_ITMP1, d);
     450             :                         } else {
     451          55 :                                 M_INTMOVE(s1, d);
     452          55 :                                 M_LSUB(s2, d);
     453             :                         }
     454          59 :                         emit_store_dst(jd, iptr, d);
     455          59 :                         break;
     456             : 
     457             :                 case ICMD_LSUBCONST:  /* ..., value  ==> ..., value - constant        */
     458             :                                       /* sx.val.l = constant                             */
     459             : 
     460          31 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
     461          31 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
     462          31 :                         M_INTMOVE(s1, d);
     463          60 :                         if (IS_IMM32(iptr->sx.val.l))
     464          29 :                                 M_LSUB_IMM(iptr->sx.val.l, d);
     465             :                         else {
     466           2 :                                 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
     467           2 :                                 M_LSUB(REG_ITMP2, d);
     468             :                         }
     469          31 :                         emit_store_dst(jd, iptr, d);
     470          31 :                         break;
     471             : 
     472             :                 case ICMD_IMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
     473             : 
     474         100 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
     475         100 :                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
     476         100 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
     477         100 :                         if (s2 == d)
     478           7 :                                 M_IMUL(s1, d);
     479             :                         else {
     480          93 :                                 M_INTMOVE(s1, d);
     481          93 :                                 M_IMUL(s2, d);
     482             :                         }
     483         100 :                         emit_store_dst(jd, iptr, d);
     484         100 :                         break;
     485             : 
     486             :                 case ICMD_IMULCONST:  /* ..., value  ==> ..., value * constant        */
     487             :                                       /* sx.val.i = constant                             */
     488             : 
     489         866 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
     490         866 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
     491         866 :                         if (iptr->sx.val.i == 2) {
     492         556 :                                 M_INTMOVE(s1, d);
     493         556 :                                 M_ISLL_IMM(1, d);
     494             :                         } else
     495         310 :                                 M_IMUL_IMM(s1, iptr->sx.val.i, d);
     496         866 :                         emit_store_dst(jd, iptr, d);
     497         866 :                         break;
     498             : 
     499             :                 case ICMD_LMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
     500             : 
     501           7 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
     502           7 :                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
     503           7 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
     504           7 :                         if (s2 == d)
     505           4 :                                 M_LMUL(s1, d);
     506             :                         else {
     507           3 :                                 M_INTMOVE(s1, d);
     508           3 :                                 M_LMUL(s2, d);
     509             :                         }
     510           7 :                         emit_store_dst(jd, iptr, d);
     511           7 :                         break;
     512             : 
     513             :                 case ICMD_LMULCONST:  /* ..., value  ==> ..., value * constant        */
     514             :                                       /* sx.val.l = constant                             */
     515             : 
     516          12 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
     517          12 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
     518          22 :                         if (IS_IMM32(iptr->sx.val.l))
     519          10 :                                 M_LMUL_IMM(s1, iptr->sx.val.l, d);
     520             :                         else {
     521           2 :                                 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
     522           2 :                                 M_INTMOVE(s1, d);
     523           2 :                                 M_LMUL(REG_ITMP2, d);
     524             :                         }
     525          12 :                         emit_store_dst(jd, iptr, d);
     526          12 :                         break;
     527             : 
     528             :                 case ICMD_IDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
     529             : 
     530         297 :                         s1 = emit_load_s1(jd, iptr, RAX);
     531         297 :                         s2 = emit_load_s2(jd, iptr, REG_ITMP3);
     532         297 :                         d = codegen_reg_of_dst(jd, iptr, RAX);
     533             : 
     534         297 :                         M_INTMOVE(s1, RAX);
     535         297 :                         M_INTMOVE(s2, REG_ITMP3);
     536         297 :                         emit_arithmetic_check(cd, iptr, REG_ITMP3);
     537             : 
     538         297 :                         M_MOV(RDX, REG_ITMP2);    /* save RDX (it's an argument register) */
     539             : 
     540         297 :                         M_ICMP_IMM(0x80000000, RAX);    /* check as described in jvm spec */
     541         297 :                         M_BNE(4 + 6);
     542         297 :                         M_ICMP_IMM(-1, REG_ITMP3);                             /* 4 bytes */
     543         297 :                         M_BEQ(1 + 3);                                          /* 6 bytes */
     544             : 
     545         297 :                         emit_cltd(cd);                                         /* 1 byte  */
     546         297 :                         emit_idivl_reg(cd, REG_ITMP3);                         /* 3 bytes */
     547             : 
     548         297 :                         M_INTMOVE(RAX, d);
     549         297 :                         emit_store_dst(jd, iptr, d);
     550         297 :                         dst = VAROP(iptr->dst);
     551         297 :                         if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
     552         297 :                                 M_MOV(REG_ITMP2, RDX);                         /* restore RDX */
     553         297 :                         break;
     554             : 
     555             :                 case ICMD_IREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
     556             : 
     557        1588 :                         s1 = emit_load_s1(jd, iptr, RAX);
     558        1588 :                         s2 = emit_load_s2(jd, iptr, REG_ITMP3);
     559        1588 :                         d = codegen_reg_of_dst(jd, iptr, RDX);
     560             : 
     561        1588 :                         M_INTMOVE(s1, RAX);
     562        1588 :                         M_INTMOVE(s2, REG_ITMP3);
     563        1588 :                         emit_arithmetic_check(cd, iptr, REG_ITMP3);
     564             : 
     565        1588 :                         M_MOV(RDX, REG_ITMP2);    /* save RDX (it's an argument register) */
     566             : 
     567        1588 :                         M_ICMP_IMM(0x80000000, RAX);    /* check as described in jvm spec */
     568        1588 :                         M_BNE(3 + 4 + 6);
     569        1588 :                         M_CLR(RDX);                                            /* 3 bytes */
     570        1588 :                         M_ICMP_IMM(-1, REG_ITMP3);                             /* 4 bytes */
     571        1588 :                         M_BEQ(1 + 3);                                          /* 6 bytes */
     572             : 
     573        1588 :                         emit_cltd(cd);                                         /* 1 byte  */
     574        1588 :                         emit_idivl_reg(cd, REG_ITMP3);                         /* 3 byte  */
     575             : 
     576        1588 :                         M_INTMOVE(RDX, d);
     577        1588 :                         emit_store_dst(jd, iptr, d);
     578        1588 :                         dst = VAROP(iptr->dst);
     579        1588 :                         if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
     580         578 :                                 M_MOV(REG_ITMP2, RDX);                         /* restore RDX */
     581        1588 :                         break;
     582             : 
     583             :                 case ICMD_IDIVPOW2:   /* ..., value  ==> ..., value >> constant       */
     584             :                                       /* sx.val.i = constant                             */
     585             : 
     586          51 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
     587          51 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
     588          51 :                         M_INTMOVE(s1, REG_ITMP1);
     589          51 :                         emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
     590          51 :                         emit_leal_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
     591          51 :                         emit_cmovccl_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
     592          51 :                         emit_shiftl_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
     593          51 :                         emit_mov_reg_reg(cd, REG_ITMP1, d);
     594          51 :                         emit_store_dst(jd, iptr, d);
     595          51 :                         break;
     596             : 
     597             :                 case ICMD_IREMPOW2:   /* ..., value  ==> ..., value % constant        */
     598             :                                       /* sx.val.i = constant                             */
     599             : 
     600          31 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
     601          31 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
     602          31 :                         M_INTMOVE(s1, REG_ITMP1);
     603          31 :                         emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
     604          31 :                         emit_leal_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
     605          31 :                         emit_cmovccl_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
     606          31 :                         emit_alul_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
     607          31 :                         emit_alul_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
     608          31 :                         emit_mov_reg_reg(cd, REG_ITMP1, d);
     609          31 :                         emit_store_dst(jd, iptr, d);
     610          31 :                         break;
     611             : 
     612             : 
     613             :                 case ICMD_LDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
     614             : 
     615          31 :                         s1 = emit_load_s1(jd, iptr, RAX);
     616          31 :                         s2 = emit_load_s2(jd, iptr, REG_ITMP3);
     617          31 :                         d = codegen_reg_of_dst(jd, iptr, RAX);
     618             : 
     619          31 :                         M_INTMOVE(s1, RAX);
     620          31 :                         M_INTMOVE(s2, REG_ITMP3);
     621          31 :                         emit_arithmetic_check(cd, iptr, REG_ITMP3);
     622             : 
     623          31 :                         M_MOV(RDX, REG_ITMP2);    /* save RDX (it's an argument register) */
     624             : 
     625             :                         /* check as described in jvm spec */
     626          31 :                         disp = dseg_add_s8(cd, 0x8000000000000000LL);
     627          31 :                         M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, RAX);
     628          31 :                         M_BNE(4 + 6);
     629          31 :                         M_LCMP_IMM(-1, REG_ITMP3);                             /* 4 bytes */
     630          31 :                         M_BEQ(2 + 3);                                          /* 6 bytes */
     631             : 
     632          31 :                         emit_cqto(cd);                                         /* 2 bytes */
     633          31 :                         emit_idiv_reg(cd, REG_ITMP3);                          /* 3 bytes */
     634             : 
     635          31 :                         M_INTMOVE(RAX, d);
     636          31 :                         emit_store_dst(jd, iptr, d);
     637          31 :                         dst = VAROP(iptr->dst);
     638          31 :                         if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
     639          31 :                                 M_MOV(REG_ITMP2, RDX);                         /* restore RDX */
     640          31 :                         break;
     641             : 
     642             :                 case ICMD_LREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
     643             : 
     644          30 :                         s1 = emit_load_s1(jd, iptr, RAX);
     645          30 :                         s2 = emit_load_s2(jd, iptr, REG_ITMP3);
     646          30 :                         d = codegen_reg_of_dst(jd, iptr, RDX);
     647             : 
     648          30 :                         M_INTMOVE(s1, RAX);
     649          30 :                         M_INTMOVE(s2, REG_ITMP3);
     650          30 :                         emit_arithmetic_check(cd, iptr, REG_ITMP3);
     651             : 
     652          30 :                         M_MOV(RDX, REG_ITMP2);    /* save RDX (it's an argument register) */
     653             : 
     654             :                         /* check as described in jvm spec */
     655          30 :                         disp = dseg_add_s8(cd, 0x8000000000000000LL);
     656          30 :                         M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, REG_ITMP1);
     657          30 :                         M_BNE(3 + 4 + 6);
     658          30 :                         M_LXOR(RDX, RDX);                                      /* 3 bytes */
     659          30 :                         M_LCMP_IMM(-1, REG_ITMP3);                             /* 4 bytes */
     660          30 :                         M_BEQ(2 + 3);                                          /* 6 bytes */
     661             : 
     662          30 :                         emit_cqto(cd);                                         /* 2 bytes */
     663          30 :                         emit_idiv_reg(cd, REG_ITMP3);                          /* 3 bytes */
     664             : 
     665          30 :                         M_INTMOVE(RDX, d);
     666          30 :                         emit_store_dst(jd, iptr, d);
     667          30 :                         dst = VAROP(iptr->dst);
     668          30 :                         if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
     669          26 :                                 M_MOV(REG_ITMP2, RDX);                         /* restore RDX */
     670          30 :                         break;
     671             : 
     672             :                 case ICMD_LDIVPOW2:   /* ..., value  ==> ..., value >> constant       */
     673             :                                       /* sx.val.i = constant                             */
     674             : 
     675          30 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
     676          30 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
     677          30 :                         M_INTMOVE(s1, REG_ITMP1);
     678          30 :                         emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
     679          30 :                         emit_lea_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
     680          30 :                         emit_cmovcc_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
     681          30 :                         emit_shift_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
     682          30 :                         emit_mov_reg_reg(cd, REG_ITMP1, d);
     683          30 :                         emit_store_dst(jd, iptr, d);
     684          30 :                         break;
     685             : 
     686             :                 case ICMD_LREMPOW2:   /* ..., value  ==> ..., value % constant        */
     687             :                                       /* sx.val.l = constant                             */
     688             : 
     689          31 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
     690          31 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
     691          31 :                         M_INTMOVE(s1, REG_ITMP1);
     692          31 :                         emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
     693          31 :                         emit_lea_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
     694          31 :                         emit_cmovcc_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
     695          31 :                         emit_alu_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
     696          31 :                         emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
     697          31 :                         emit_mov_reg_reg(cd, REG_ITMP1, d);
     698          31 :                         emit_store_dst(jd, iptr, d);
     699          31 :                         break;
     700             : 
     701             :                 case ICMD_ISHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
     702             : 
     703          96 :                         d = codegen_reg_of_dst(jd, iptr, REG_NULL);
     704          96 :                         emit_ishift(jd, SHIFT_SHL, iptr);
     705          96 :                         break;
     706             : 
     707             :                 case ICMD_ISHLCONST:  /* ..., value  ==> ..., value << constant       */
     708             :                                       /* sx.val.i = constant                             */
     709             : 
     710         499 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
     711         499 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
     712         499 :                         M_INTMOVE(s1, d);
     713         499 :                         M_ISLL_IMM(iptr->sx.val.i, d);
     714         499 :                         emit_store_dst(jd, iptr, d);
     715         499 :                         break;
     716             : 
     717             :                 case ICMD_ISHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
     718             : 
     719         148 :                         d = codegen_reg_of_dst(jd, iptr, REG_NULL);
     720         148 :                         emit_ishift(jd, SHIFT_SAR, iptr);
     721         148 :                         break;
     722             : 
     723             :                 case ICMD_ISHRCONST:  /* ..., value  ==> ..., value >> constant       */
     724             :                                       /* sx.val.i = constant                             */
     725             : 
     726         185 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
     727         185 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
     728         185 :                         M_INTMOVE(s1, d);
     729         185 :                         M_ISRA_IMM(iptr->sx.val.i, d);
     730         185 :                         emit_store_dst(jd, iptr, d);
     731         185 :                         break;
     732             : 
     733             :                 case ICMD_IUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
     734             : 
     735          74 :                         d = codegen_reg_of_dst(jd, iptr, REG_NULL);
     736          74 :                         emit_ishift(jd, SHIFT_SHR, iptr);
     737          74 :                         break;
     738             : 
     739             :                 case ICMD_IUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
     740             :                                       /* sx.val.i = constant                             */
     741             : 
     742         328 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
     743         328 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
     744         328 :                         M_INTMOVE(s1, d);
     745         328 :                         M_ISRL_IMM(iptr->sx.val.i, d);
     746         328 :                         emit_store_dst(jd, iptr, d);
     747         328 :                         break;
     748             : 
     749             :                 case ICMD_LSHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
     750             : 
     751          13 :                         d = codegen_reg_of_dst(jd, iptr, REG_NULL);
     752          13 :                         emit_lshift(jd, SHIFT_SHL, iptr);
     753          13 :                         break;
     754             : 
     755             :         case ICMD_LSHLCONST:  /* ..., value  ==> ..., value << constant       */
     756             :                                           /* sx.val.i = constant                             */
     757             : 
     758          16 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
     759          16 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
     760          16 :                         M_INTMOVE(s1, d);
     761          16 :                         M_LSLL_IMM(iptr->sx.val.i, d);
     762          16 :                         emit_store_dst(jd, iptr, d);
     763          16 :                         break;
     764             : 
     765             :                 case ICMD_LSHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
     766             : 
     767           1 :                         d = codegen_reg_of_dst(jd, iptr, REG_NULL);
     768           1 :                         emit_lshift(jd, SHIFT_SAR, iptr);
     769           1 :                         break;
     770             : 
     771             :                 case ICMD_LSHRCONST:  /* ..., value  ==> ..., value >> constant       */
     772             :                                       /* sx.val.i = constant                             */
     773             : 
     774          25 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
     775          25 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
     776          25 :                         M_INTMOVE(s1, d);
     777          25 :                         M_LSRA_IMM(iptr->sx.val.i, d);
     778          25 :                         emit_store_dst(jd, iptr, d);
     779          25 :                         break;
     780             : 
     781             :                 case ICMD_LUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
     782             : 
     783          17 :                         d = codegen_reg_of_dst(jd, iptr, REG_NULL);
     784          17 :                         emit_lshift(jd, SHIFT_SHR, iptr);
     785          17 :                         break;
     786             : 
     787             :                 case ICMD_LUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
     788             :                                       /* sx.val.l = constant                             */
     789             : 
     790          13 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
     791          13 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
     792          13 :                         M_INTMOVE(s1, d);
     793          13 :                         M_LSRL_IMM(iptr->sx.val.i, d);
     794          13 :                         emit_store_dst(jd, iptr, d);
     795          13 :                         break;
     796             : 
     797             :                 case ICMD_IAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
     798             : 
     799         914 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
     800         914 :                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
     801         914 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
     802         914 :                         if (s2 == d)
     803         282 :                                 M_IAND(s1, d);
     804             :                         else {
     805         632 :                                 M_INTMOVE(s1, d);
     806         632 :                                 M_IAND(s2, d);
     807             :                         }
     808         914 :                         emit_store_dst(jd, iptr, d);
     809         914 :                         break;
     810             : 
     811             :                 case ICMD_IANDCONST:  /* ..., value  ==> ..., value & constant        */
     812             :                                       /* sx.val.i = constant                             */
     813             : 
     814        1231 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
     815        1231 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
     816        1231 :                         M_INTMOVE(s1, d);
     817        1231 :                         M_IAND_IMM(iptr->sx.val.i, d);
     818        1231 :                         emit_store_dst(jd, iptr, d);
     819        1231 :                         break;
     820             : 
     821             :                 case ICMD_LAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
     822             : 
     823          15 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
     824          15 :                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
     825          15 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
     826          15 :                         if (s2 == d)
     827           0 :                                 M_LAND(s1, d);
     828             :                         else {
     829          15 :                                 M_INTMOVE(s1, d);
     830          15 :                                 M_LAND(s2, d);
     831             :                         }
     832          15 :                         emit_store_dst(jd, iptr, d);
     833          15 :                         break;
     834             : 
     835             :                 case ICMD_LANDCONST:  /* ..., value  ==> ..., value & constant        */
     836             :                                       /* sx.val.l = constant                             */
     837             : 
     838          54 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
     839          54 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
     840          54 :                         M_INTMOVE(s1, d);
     841          66 :                         if (IS_IMM32(iptr->sx.val.l))
     842          12 :                                 M_LAND_IMM(iptr->sx.val.l, d);
     843             :                         else {
     844          42 :                                 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
     845          42 :                                 M_LAND(REG_ITMP2, d);
     846             :                         }
     847          54 :                         emit_store_dst(jd, iptr, d);
     848          54 :                         break;
     849             : 
     850             :                 case ICMD_IOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
     851             : 
     852         252 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
     853         252 :                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
     854         252 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
     855         252 :                         if (s2 == d)
     856          36 :                                 M_IOR(s1, d);
     857             :                         else {
     858         216 :                                 M_INTMOVE(s1, d);
     859         216 :                                 M_IOR(s2, d);
     860             :                         }
     861         252 :                         emit_store_dst(jd, iptr, d);
     862         252 :                         break;
     863             : 
     864             :                 case ICMD_IORCONST:   /* ..., value  ==> ..., value | constant        */
     865             :                                       /* sx.val.i = constant                             */
     866             : 
     867         137 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
     868         137 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
     869         137 :                         M_INTMOVE(s1, d);
     870         137 :                         M_IOR_IMM(iptr->sx.val.i, d);
     871         137 :                         emit_store_dst(jd, iptr, d);
     872         137 :                         break;
     873             : 
     874             :                 case ICMD_LOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
     875             : 
     876           9 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
     877           9 :                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
     878           9 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
     879           9 :                         if (s2 == d)
     880           0 :                                 M_LOR(s1, d);
     881             :                         else {
     882           9 :                                 M_INTMOVE(s1, d);
     883           9 :                                 M_LOR(s2, d);
     884             :                         }
     885           9 :                         emit_store_dst(jd, iptr, d);
     886           9 :                         break;
     887             : 
     888             :                 case ICMD_LORCONST:   /* ..., value  ==> ..., value | constant        */
     889             :                                       /* sx.val.l = constant                             */
     890             : 
     891          12 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
     892          12 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
     893          12 :                         M_INTMOVE(s1, d);
     894          22 :                         if (IS_IMM32(iptr->sx.val.l))
     895          10 :                                 M_LOR_IMM(iptr->sx.val.l, d);
     896             :                         else {
     897           2 :                                 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
     898           2 :                                 M_LOR(REG_ITMP2, d);
     899             :                         }
     900          12 :                         emit_store_dst(jd, iptr, d);
     901          12 :                         break;
     902             : 
     903             :                 case ICMD_IXOR:       /* ..., val1, val2  ==> ..., val1 ^ val2        */
     904             : 
     905         637 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
     906         637 :                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
     907         637 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
     908         637 :                         if (s2 == d)
     909         435 :                                 M_IXOR(s1, d);
     910             :                         else {
     911         202 :                                 M_INTMOVE(s1, d);
     912         202 :                                 M_IXOR(s2, d);
     913             :                         }
     914         637 :                         emit_store_dst(jd, iptr, d);
     915         637 :                         break;
     916             : 
     917             :                 case ICMD_IXORCONST:  /* ..., value  ==> ..., value ^ constant        */
     918             :                                       /* sx.val.i = constant                             */
     919             : 
     920          28 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
     921          28 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
     922          28 :                         M_INTMOVE(s1, d);
     923          28 :                         M_IXOR_IMM(iptr->sx.val.i, d);
     924          28 :                         emit_store_dst(jd, iptr, d);
     925          28 :                         break;
     926             : 
     927             :                 case ICMD_LXOR:       /* ..., val1, val2  ==> ..., val1 ^ val2        */
     928             : 
     929           2 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
     930           2 :                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
     931           2 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
     932           2 :                         if (s2 == d)
     933           0 :                                 M_LXOR(s1, d);
     934             :                         else {
     935           2 :                                 M_INTMOVE(s1, d);
     936           2 :                                 M_LXOR(s2, d);
     937             :                         }
     938           2 :                         emit_store_dst(jd, iptr, d);
     939           2 :                         break;
     940             : 
     941             :                 case ICMD_LXORCONST:  /* ..., value  ==> ..., value ^ constant        */
     942             :                                       /* sx.val.l = constant                             */
     943             : 
     944          12 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
     945          12 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
     946          12 :                         M_INTMOVE(s1, d);
     947          22 :                         if (IS_IMM32(iptr->sx.val.l))
     948          10 :                                 M_LXOR_IMM(iptr->sx.val.l, d);
     949             :                         else {
     950           2 :                                 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
     951           2 :                                 M_LXOR(REG_ITMP2, d);
     952             :                         }
     953          12 :                         emit_store_dst(jd, iptr, d);
     954          12 :                         break;
     955             : 
     956             : 
     957             :                 /* floating operations ************************************************/
     958             : 
     959             :                 case ICMD_FNEG:       /* ..., value  ==> ..., - value                 */
     960             : 
     961           0 :                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
     962           0 :                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
     963           0 :                         disp = dseg_add_s4(cd, 0x80000000);
     964           0 :                         emit_fmove(cd, s1, d);
     965           0 :                         emit_movss_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
     966           0 :                         emit_xorps_reg_reg(cd, REG_FTMP2, d);
     967           0 :                         emit_store_dst(jd, iptr, d);
     968           0 :                         break;
     969             : 
     970             :                 case ICMD_DNEG:       /* ..., value  ==> ..., - value                 */
     971             : 
     972           0 :                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
     973           0 :                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
     974           0 :                         disp = dseg_add_s8(cd, 0x8000000000000000);
     975           0 :                         emit_fmove(cd, s1, d);
     976           0 :                         emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
     977           0 :                         emit_xorpd_reg_reg(cd, REG_FTMP2, d);
     978           0 :                         emit_store_dst(jd, iptr, d);
     979           0 :                         break;
     980             : 
     981             :                 case ICMD_FADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
     982             : 
     983        1006 :                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
     984        1006 :                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
     985        1006 :                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
     986        1006 :                         if (s2 == d)
     987           0 :                                 M_FADD(s1, d);
     988             :                         else {
     989        1006 :                                 emit_fmove(cd, s1, d);
     990        1006 :                                 M_FADD(s2, d);
     991             :                         }
     992        1006 :                         emit_store_dst(jd, iptr, d);
     993        1006 :                         break;
     994             : 
     995             :                 case ICMD_DADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
     996             : 
     997           7 :                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
     998           7 :                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
     999           7 :                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
    1000           7 :                         if (s2 == d)
    1001           0 :                                 M_DADD(s1, d);
    1002             :                         else {
    1003           7 :                                 emit_fmove(cd, s1, d);
    1004           7 :                                 M_DADD(s2, d);
    1005             :                         }
    1006           7 :                         emit_store_dst(jd, iptr, d);
    1007           7 :                         break;
    1008             : 
    1009             :                 case ICMD_FSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
    1010             : 
    1011           3 :                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
    1012           3 :                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
    1013           3 :                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
    1014           3 :                         if (s2 == d) {
    1015           0 :                                 emit_fmove(cd, s2, REG_FTMP2);
    1016           0 :                                 s2 = REG_FTMP2;
    1017             :                         }
    1018           3 :                         emit_fmove(cd, s1, d);
    1019           3 :                         M_FSUB(s2, d);
    1020           3 :                         emit_store_dst(jd, iptr, d);
    1021           3 :                         break;
    1022             : 
    1023             :                 case ICMD_DSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
    1024             : 
    1025           5 :                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
    1026           5 :                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
    1027           5 :                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
    1028           5 :                         if (s2 == d) {
    1029           0 :                                 emit_fmove(cd, s2, REG_FTMP2);
    1030           0 :                                 s2 = REG_FTMP2;
    1031             :                         }
    1032           5 :                         emit_fmove(cd, s1, d);
    1033           5 :                         M_DSUB(s2, d);
    1034           5 :                         emit_store_dst(jd, iptr, d);
    1035           5 :                         break;
    1036             : 
    1037             :                 case ICMD_FMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
    1038             : 
    1039         999 :                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
    1040         999 :                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
    1041         999 :                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
    1042         999 :                         if (s2 == d)
    1043           0 :                                 M_FMUL(s1, d);
    1044             :                         else {
    1045         999 :                                 emit_fmove(cd, s1, d);
    1046         999 :                                 M_FMUL(s2, d);
    1047             :                         }
    1048         999 :                         emit_store_dst(jd, iptr, d);
    1049         999 :                         break;
    1050             : 
    1051             :                 case ICMD_DMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
    1052             : 
    1053          10 :                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
    1054          10 :                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
    1055          10 :                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
    1056          10 :                         if (s2 == d)
    1057           0 :                                 M_DMUL(s1, d);
    1058             :                         else {
    1059          10 :                                 emit_fmove(cd, s1, d);
    1060          10 :                                 M_DMUL(s2, d);
    1061             :                         }
    1062          10 :                         emit_store_dst(jd, iptr, d);
    1063          10 :                         break;
    1064             : 
    1065             :                 case ICMD_FDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
    1066             : 
    1067           5 :                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
    1068           5 :                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
    1069           5 :                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
    1070           5 :                         if (s2 == d) {
    1071           0 :                                 emit_fmove(cd, s2, REG_FTMP2);
    1072           0 :                                 s2 = REG_FTMP2;
    1073             :                         }
    1074           5 :                         emit_fmove(cd, s1, d);
    1075           5 :                         M_FDIV(s2, d);
    1076           5 :                         emit_store_dst(jd, iptr, d);
    1077           5 :                         break;
    1078             : 
    1079             :                 case ICMD_DDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
    1080             : 
    1081           7 :                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
    1082           7 :                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
    1083           7 :                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
    1084           7 :                         if (s2 == d) {
    1085           0 :                                 emit_fmove(cd, s2, REG_FTMP2);
    1086           0 :                                 s2 = REG_FTMP2;
    1087             :                         }
    1088           7 :                         emit_fmove(cd, s1, d);
    1089           7 :                         M_DDIV(s2, d);
    1090           7 :                         emit_store_dst(jd, iptr, d);
    1091           7 :                         break;
    1092             : 
    1093             :                 case ICMD_I2F:       /* ..., value  ==> ..., (float) value            */
    1094             : 
    1095        1278 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
    1096        1278 :                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
    1097        1278 :                         M_CVTIF(s1, d);
    1098        1278 :                         emit_store_dst(jd, iptr, d);
    1099        1278 :                         break;
    1100             : 
    1101             :                 case ICMD_I2D:       /* ..., value  ==> ..., (double) value           */
    1102             : 
    1103           8 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
    1104           8 :                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
    1105           8 :                         M_CVTID(s1, d);
    1106           8 :                         emit_store_dst(jd, iptr, d);
    1107           8 :                         break;
    1108             : 
    1109             :                 case ICMD_L2F:       /* ..., value  ==> ..., (float) value            */
    1110             : 
    1111           1 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
    1112           1 :                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
    1113           1 :                         M_CVTLF(s1, d);
    1114           1 :                         emit_store_dst(jd, iptr, d);
    1115           1 :                         break;
    1116             :                         
    1117             :                 case ICMD_L2D:       /* ..., value  ==> ..., (double) value           */
    1118             : 
    1119           3 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
    1120           3 :                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
    1121           3 :                         M_CVTLD(s1, d);
    1122           3 :                         emit_store_dst(jd, iptr, d);
    1123           3 :                         break;
    1124             :                         
    1125             :                 case ICMD_F2I:       /* ..., value  ==> ..., (int) value              */
    1126             : 
    1127           0 :                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
    1128           0 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
    1129           0 :                         M_CVTFI(s1, d);
    1130           0 :                         M_ICMP_IMM(0x80000000, d);                        /* corner cases */
    1131             :                         disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
    1132           0 :                                 ((REG_RESULT == d) ? 0 : 3);
    1133           0 :                         M_BNE(disp);
    1134           0 :                         emit_fmove(cd, s1, REG_FTMP1);
    1135           0 :                         M_MOV_IMM(asm_builtin_f2i, REG_ITMP2);
    1136           0 :                         M_CALL(REG_ITMP2);
    1137           0 :                         M_INTMOVE(REG_RESULT, d);
    1138           0 :                         emit_store_dst(jd, iptr, d);
    1139           0 :                         break;
    1140             : 
    1141             :                 case ICMD_D2I:       /* ..., value  ==> ..., (int) value              */
    1142             : 
    1143           0 :                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
    1144           0 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
    1145           0 :                         M_CVTDI(s1, d);
    1146           0 :                         M_ICMP_IMM(0x80000000, d);                        /* corner cases */
    1147             :                         disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
    1148           0 :                                 ((REG_RESULT == d) ? 0 : 3);
    1149           0 :                         M_BNE(disp);
    1150           0 :                         emit_fmove(cd, s1, REG_FTMP1);
    1151           0 :                         M_MOV_IMM(asm_builtin_d2i, REG_ITMP2);
    1152           0 :                         M_CALL(REG_ITMP2);
    1153           0 :                         M_INTMOVE(REG_RESULT, d);
    1154           0 :                         emit_store_dst(jd, iptr, d);
    1155           0 :                         break;
    1156             : 
    1157             :                 case ICMD_F2L:       /* ..., value  ==> ..., (long) value             */
    1158             : 
    1159           0 :                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
    1160           0 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
    1161           0 :                         M_CVTFL(s1, d);
    1162           0 :                         M_MOV_IMM(0x8000000000000000, REG_ITMP2);
    1163           0 :                         M_LCMP(REG_ITMP2, d);                             /* corner cases */
    1164             :                         disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
    1165           0 :                                 ((REG_RESULT == d) ? 0 : 3);
    1166           0 :                         M_BNE(disp);
    1167           0 :                         emit_fmove(cd, s1, REG_FTMP1);
    1168           0 :                         M_MOV_IMM(asm_builtin_f2l, REG_ITMP2);
    1169           0 :                         M_CALL(REG_ITMP2);
    1170           0 :                         M_INTMOVE(REG_RESULT, d);
    1171           0 :                         emit_store_dst(jd, iptr, d);
    1172           0 :                         break;
    1173             : 
    1174             :                 case ICMD_D2L:       /* ..., value  ==> ..., (long) value             */
    1175             : 
    1176           0 :                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
    1177           0 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
    1178           0 :                         M_CVTDL(s1, d);
    1179           0 :                         M_MOV_IMM(0x8000000000000000, REG_ITMP2);
    1180           0 :                         M_LCMP(REG_ITMP2, d);                             /* corner cases */
    1181             :                         disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
    1182           0 :                                 ((REG_RESULT == d) ? 0 : 3);
    1183           0 :                         M_BNE(disp);
    1184           0 :                         emit_fmove(cd, s1, REG_FTMP1);
    1185           0 :                         M_MOV_IMM(asm_builtin_d2l, REG_ITMP2);
    1186           0 :                         M_CALL(REG_ITMP2);
    1187           0 :                         M_INTMOVE(REG_RESULT, d);
    1188           0 :                         emit_store_dst(jd, iptr, d);
    1189           0 :                         break;
    1190             : 
    1191             :                 case ICMD_F2D:       /* ..., value  ==> ..., (double) value           */
    1192             : 
    1193          19 :                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
    1194          19 :                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
    1195          19 :                         M_CVTFD(s1, d);
    1196          19 :                         emit_store_dst(jd, iptr, d);
    1197          19 :                         break;
    1198             : 
    1199             :                 case ICMD_D2F:       /* ..., value  ==> ..., (float) value            */
    1200             : 
    1201           5 :                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
    1202           5 :                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
    1203           5 :                         M_CVTDF(s1, d);
    1204           5 :                         emit_store_dst(jd, iptr, d);
    1205           5 :                         break;
    1206             : 
    1207             :                 case ICMD_FCMPL:      /* ..., val1, val2  ==> ..., val1 fcmpl val2    */
    1208             :                                           /* == => 0, < => 1, > => -1 */
    1209             : 
    1210        1447 :                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
    1211        1447 :                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
    1212        1447 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
    1213        1447 :                         M_CLR(d);
    1214        1447 :                         M_MOV_IMM(1, REG_ITMP1);
    1215        1447 :                         M_MOV_IMM(-1, REG_ITMP2);
    1216        1447 :                         emit_ucomiss_reg_reg(cd, s1, s2);
    1217        1447 :                         M_CMOVULT(REG_ITMP1, d);
    1218        1447 :                         M_CMOVUGT(REG_ITMP2, d);
    1219        1447 :                         M_CMOVP(REG_ITMP2, d);                   /* treat unordered as GT */
    1220        1447 :                         emit_store_dst(jd, iptr, d);
    1221        1447 :                         break;
    1222             : 
    1223             :                 case ICMD_FCMPG:      /* ..., val1, val2  ==> ..., val1 fcmpg val2    */
    1224             :                                           /* == => 0, < => 1, > => -1 */
    1225             : 
    1226         443 :                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
    1227         443 :                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
    1228         443 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
    1229         443 :                         M_CLR(d);
    1230         443 :                         M_MOV_IMM(1, REG_ITMP1);
    1231         443 :                         M_MOV_IMM(-1, REG_ITMP2);
    1232         443 :                         emit_ucomiss_reg_reg(cd, s1, s2);
    1233         443 :                         M_CMOVULT(REG_ITMP1, d);
    1234         443 :                         M_CMOVUGT(REG_ITMP2, d);
    1235         443 :                         M_CMOVP(REG_ITMP1, d);                   /* treat unordered as LT */
    1236         443 :                         emit_store_dst(jd, iptr, d);
    1237         443 :                         break;
    1238             : 
    1239             :                 case ICMD_DCMPL:      /* ..., val1, val2  ==> ..., val1 fcmpl val2    */
    1240             :                                           /* == => 0, < => 1, > => -1 */
    1241             : 
    1242          43 :                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
    1243          43 :                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
    1244          43 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
    1245          43 :                         M_CLR(d);
    1246          43 :                         M_MOV_IMM(1, REG_ITMP1);
    1247          43 :                         M_MOV_IMM(-1, REG_ITMP2);
    1248          43 :                         emit_ucomisd_reg_reg(cd, s1, s2);
    1249          43 :                         M_CMOVULT(REG_ITMP1, d);
    1250          43 :                         M_CMOVUGT(REG_ITMP2, d);
    1251          43 :                         M_CMOVP(REG_ITMP2, d);                   /* treat unordered as GT */
    1252          43 :                         emit_store_dst(jd, iptr, d);
    1253          43 :                         break;
    1254             : 
    1255             :                 case ICMD_DCMPG:      /* ..., val1, val2  ==> ..., val1 fcmpg val2    */
    1256             :                                           /* == => 0, < => 1, > => -1 */
    1257             : 
    1258          14 :                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
    1259          14 :                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
    1260          14 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
    1261          14 :                         M_CLR(d);
    1262          14 :                         M_MOV_IMM(1, REG_ITMP1);
    1263          14 :                         M_MOV_IMM(-1, REG_ITMP2);
    1264          14 :                         emit_ucomisd_reg_reg(cd, s1, s2);
    1265          14 :                         M_CMOVULT(REG_ITMP1, d);
    1266          14 :                         M_CMOVUGT(REG_ITMP2, d);
    1267          14 :                         M_CMOVP(REG_ITMP1, d);                   /* treat unordered as LT */
    1268          14 :                         emit_store_dst(jd, iptr, d);
    1269          14 :                         break;
    1270             : 
    1271             : 
    1272             :                 /* memory operations **************************************************/
    1273             : 
    1274             :                 case ICMD_BALOAD:     /* ..., arrayref, index  ==> ..., value         */
    1275             : 
    1276         160 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
    1277         160 :                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
    1278         160 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
    1279             :                         /* implicit null-pointer check */
    1280         160 :                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
    1281         160 :                         emit_movsbq_memindex_reg(cd, OFFSET(java_bytearray_t, data[0]), s1, s2, 0, d);
    1282         160 :                         emit_store_dst(jd, iptr, d);
    1283         160 :                         break;
    1284             : 
    1285             :                 case ICMD_CALOAD:     /* ..., arrayref, index  ==> ..., value         */
    1286             : 
    1287        3526 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
    1288        3526 :                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
    1289        3526 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
    1290             :                         /* implicit null-pointer check */
    1291        3526 :                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
    1292        3526 :                         emit_movzwq_memindex_reg(cd, OFFSET(java_chararray_t, data[0]), s1, s2, 1, d);
    1293        3526 :                         emit_store_dst(jd, iptr, d);
    1294        3526 :                         break;                  
    1295             : 
    1296             :                 case ICMD_SALOAD:     /* ..., arrayref, index  ==> ..., value         */
    1297             : 
    1298          55 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
    1299          55 :                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
    1300          55 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
    1301             :                         /* implicit null-pointer check */
    1302          55 :                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
    1303          55 :                         emit_movswq_memindex_reg(cd, OFFSET(java_shortarray_t, data[0]), s1, s2, 1, d);
    1304          55 :                         emit_store_dst(jd, iptr, d);
    1305          55 :                         break;
    1306             : 
    1307             :                 case ICMD_IALOAD:     /* ..., arrayref, index  ==> ..., value         */
    1308             : 
    1309         301 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
    1310         301 :                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
    1311         301 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
    1312             :                         /* implicit null-pointer check */
    1313         301 :                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
    1314         301 :                         emit_movl_memindex_reg(cd, OFFSET(java_intarray_t, data[0]), s1, s2, 2, d);
    1315         301 :                         emit_store_dst(jd, iptr, d);
    1316         301 :                         break;
    1317             : 
    1318             :                 case ICMD_LALOAD:     /* ..., arrayref, index  ==> ..., value         */
    1319             : 
    1320          21 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
    1321          21 :                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
    1322          21 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
    1323             :                         /* implicit null-pointer check */
    1324          21 :                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
    1325          21 :                         emit_mov_memindex_reg(cd, OFFSET(java_longarray_t, data[0]), s1, s2, 3, d);
    1326          21 :                         emit_store_dst(jd, iptr, d);
    1327          21 :                         break;
    1328             : 
    1329             :                 case ICMD_FALOAD:     /* ..., arrayref, index  ==> ..., value         */
    1330             : 
    1331           3 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
    1332           3 :                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
    1333           3 :                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
    1334             :                         /* implicit null-pointer check */
    1335           3 :                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
    1336           3 :                         emit_movss_memindex_reg(cd, OFFSET(java_floatarray_t, data[0]), s1, s2, 2, d);
    1337           3 :                         emit_store_dst(jd, iptr, d);
    1338           3 :                         break;
    1339             : 
    1340             :                 case ICMD_DALOAD:     /* ..., arrayref, index  ==> ..., value         */
    1341             : 
    1342           3 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
    1343           3 :                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
    1344           3 :                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
    1345             :                         /* implicit null-pointer check */
    1346           3 :                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
    1347           3 :                         emit_movsd_memindex_reg(cd, OFFSET(java_doublearray_t, data[0]), s1, s2, 3, d);
    1348           3 :                         emit_store_dst(jd, iptr, d);
    1349           3 :                         break;
    1350             : 
    1351             :                 case ICMD_AALOAD:     /* ..., arrayref, index  ==> ..., value         */
    1352             : 
    1353       21245 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
    1354       21245 :                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
    1355       21245 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
    1356             :                         /* implicit null-pointer check */
    1357       21245 :                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
    1358       21245 :                         emit_mov_memindex_reg(cd, OFFSET(java_objectarray_t, data[0]), s1, s2, 3, d);
    1359       21245 :                         emit_store_dst(jd, iptr, d);
    1360       21245 :                         break;
    1361             : 
    1362             : 
    1363             :                 case ICMD_BASTORE:    /* ..., arrayref, index, value  ==> ...         */
    1364             : 
    1365         360 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
    1366         360 :                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
    1367             :                         /* implicit null-pointer check */
    1368         360 :                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
    1369         360 :                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
    1370         360 :                         emit_movb_reg_memindex(cd, s3, OFFSET(java_bytearray_t, data[0]), s1, s2, 0);
    1371         360 :                         break;
    1372             : 
    1373             :                 case ICMD_CASTORE:    /* ..., arrayref, index, value  ==> ...         */
    1374             : 
    1375        1032 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
    1376        1032 :                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
    1377             :                         /* implicit null-pointer check */
    1378        1032 :                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
    1379        1032 :                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
    1380        1032 :                         emit_movw_reg_memindex(cd, s3, OFFSET(java_chararray_t, data[0]), s1, s2, 1);
    1381        1032 :                         break;
    1382             : 
    1383             :                 case ICMD_SASTORE:    /* ..., arrayref, index, value  ==> ...         */
    1384             : 
    1385          52 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
    1386          52 :                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
    1387             :                         /* implicit null-pointer check */
    1388          52 :                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
    1389          52 :                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
    1390          52 :                         emit_movw_reg_memindex(cd, s3, OFFSET(java_shortarray_t, data[0]), s1, s2, 1);
    1391          52 :                         break;
    1392             : 
    1393             :                 case ICMD_IASTORE:    /* ..., arrayref, index, value  ==> ...         */
    1394             : 
    1395          86 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
    1396          86 :                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
    1397             :                         /* implicit null-pointer check */
    1398          86 :                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
    1399          86 :                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
    1400          86 :                         emit_movl_reg_memindex(cd, s3, OFFSET(java_intarray_t, data[0]), s1, s2, 2);
    1401          86 :                         break;
    1402             : 
    1403             :                 case ICMD_LASTORE:    /* ..., arrayref, index, value  ==> ...         */
    1404             : 
    1405          10 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
    1406          10 :                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
    1407             :                         /* implicit null-pointer check */
    1408          10 :                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
    1409          10 :                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
    1410          10 :                         emit_mov_reg_memindex(cd, s3, OFFSET(java_longarray_t, data[0]), s1, s2, 3);
    1411          10 :                         break;
    1412             : 
    1413             :                 case ICMD_FASTORE:    /* ..., arrayref, index, value  ==> ...         */
    1414             : 
    1415           6 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
    1416           6 :                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
    1417             :                         /* implicit null-pointer check */
    1418           6 :                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
    1419           6 :                         s3 = emit_load_s3(jd, iptr, REG_FTMP3);
    1420           6 :                         emit_movss_reg_memindex(cd, s3, OFFSET(java_floatarray_t, data[0]), s1, s2, 2);
    1421           6 :                         break;
    1422             : 
    1423             :                 case ICMD_DASTORE:    /* ..., arrayref, index, value  ==> ...         */
    1424             : 
    1425           4 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
    1426           4 :                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
    1427             :                         /* implicit null-pointer check */
    1428           4 :                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
    1429           4 :                         s3 = emit_load_s3(jd, iptr, REG_FTMP3);
    1430           4 :                         emit_movsd_reg_memindex(cd, s3, OFFSET(java_doublearray_t, data[0]), s1, s2, 3);
    1431           4 :                         break;
    1432             : 
    1433             :                 case ICMD_AASTORE:    /* ..., arrayref, index, value  ==> ...         */
    1434             : 
    1435       64566 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
    1436       64566 :                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
    1437             :                         /* implicit null-pointer check */
    1438       64566 :                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
    1439       64566 :                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
    1440             : 
    1441       64566 :                         M_MOV(s1, REG_A0);
    1442       64566 :                         M_MOV(s3, REG_A1);
    1443       64566 :                         M_MOV_IMM(BUILTIN_FAST_canstore, REG_ITMP1);
    1444       64566 :                         M_CALL(REG_ITMP1);
    1445       64566 :                         emit_arraystore_check(cd, iptr);
    1446             : 
    1447       64566 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
    1448       64566 :                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
    1449       64566 :                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
    1450       64566 :                         emit_mov_reg_memindex(cd, s3, OFFSET(java_objectarray_t, data[0]), s1, s2, 3);
    1451       64566 :                         break;
    1452             : 
    1453             : 
    1454             :                 case ICMD_BASTORECONST: /* ..., arrayref, index  ==> ...              */
    1455             : 
    1456         725 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
    1457         725 :                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
    1458             :                         /* implicit null-pointer check */
    1459         725 :                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
    1460         725 :                         emit_movb_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_bytearray_t, data[0]), s1, s2, 0);
    1461         725 :                         break;
    1462             : 
    1463             :                 case ICMD_CASTORECONST:   /* ..., arrayref, index  ==> ...            */
    1464             : 
    1465      508614 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
    1466      508614 :                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
    1467             :                         /* implicit null-pointer check */
    1468      508614 :                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
    1469      508614 :                         emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_chararray_t, data[0]), s1, s2, 1);
    1470      508614 :                         break;
    1471             : 
    1472             :                 case ICMD_SASTORECONST:   /* ..., arrayref, index  ==> ...            */
    1473             : 
    1474           4 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
    1475           4 :                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
    1476             :                         /* implicit null-pointer check */
    1477           4 :                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
    1478           4 :                         emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_shortarray_t, data[0]), s1, s2, 1);
    1479           4 :                         break;
    1480             : 
    1481             :                 case ICMD_IASTORECONST: /* ..., arrayref, index  ==> ...              */
    1482             : 
    1483        4735 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
    1484        4735 :                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
    1485             :                         /* implicit null-pointer check */
    1486        4735 :                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
    1487        4735 :                         emit_movl_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_intarray_t, data[0]), s1, s2, 2);
    1488        4735 :                         break;
    1489             : 
    1490             :                 case ICMD_LASTORECONST: /* ..., arrayref, index  ==> ...              */
    1491             : 
    1492           6 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
    1493           6 :                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
    1494             :                         /* implicit null-pointer check */
    1495           6 :                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
    1496             : 
    1497          12 :                         if (IS_IMM32(iptr->sx.s23.s3.constval)) {
    1498           6 :                                 emit_mov_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray_t, data[0]), s1, s2, 3);
    1499             :                         }
    1500             :                         else {
    1501           0 :                                 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray_t, data[0]), s1, s2, 3);
    1502           0 :                                 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval >> 32), OFFSET(java_longarray_t, data[0]) + 4, s1, s2, 3);
    1503             :                         }
    1504           6 :                         break;
    1505             : 
    1506             :                 case ICMD_AASTORECONST: /* ..., arrayref, index  ==> ...              */
    1507             : 
    1508         586 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
    1509         586 :                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
    1510             :                         /* implicit null-pointer check */
    1511         586 :                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
    1512         586 :                         emit_mov_imm_memindex(cd, 0, OFFSET(java_objectarray_t, data[0]), s1, s2, 3);
    1513         586 :                         break;
    1514             : 
    1515             :                 case ICMD_PUTSTATICCONST: /* ...  ==> ...                             */
    1516             :                                           /* val = value (in current instruction)     */
    1517             :                                           /* following NOP)                           */
    1518             : 
    1519         814 :                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
    1520           9 :                                 uf        = iptr->sx.s23.s3.uf;
    1521           9 :                                 fieldtype = uf->fieldref->parseddesc.fd->type;
    1522           9 :                                 disp      = dseg_add_unique_address(cd, uf);
    1523             : 
    1524             : /*                              PROFILE_CYCLE_STOP; */
    1525             : 
    1526           9 :                                 pr = patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
    1527             : 
    1528             : /*                              PROFILE_CYCLE_START; */
    1529             : 
    1530           9 :                                 fi = NULL;              /* Silence compiler warning */
    1531             :                         }
    1532             :                         else {
    1533         805 :                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
    1534         805 :                                 fieldtype = fi->type;
    1535         805 :                                 disp      = dseg_add_address(cd, fi->value);
    1536             : 
    1537         805 :                                 if (!class_is_or_almost_initialized(fi->clazz)) {
    1538             :                                         //PROFILE_CYCLE_STOP;
    1539             : 
    1540             :                                         patcher_add_patch_ref(jd, PATCHER_initialize_class,
    1541           0 :                                                                                   fi->clazz, 0);
    1542             : 
    1543             :                                         //PROFILE_CYCLE_START;
    1544             :                                 }
    1545             : 
    1546         805 :                                 pr = NULL;              /* Silence compiler warning */
    1547             :                         }
    1548             : 
    1549             :                         /* This approach is much faster than moving the field
    1550             :                            address inline into a register. */
    1551             : 
    1552         814 :                         M_ALD(REG_ITMP1, RIP, disp);
    1553             : 
    1554         814 :                         switch (fieldtype) {
    1555             :                         case TYPE_INT:
    1556             :                         case TYPE_FLT:
    1557         514 :                                 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
    1558         514 :                                 break;
    1559             :                         case TYPE_LNG:
    1560             :                         case TYPE_ADR:
    1561             :                         case TYPE_DBL:
    1562         595 :                                 if (IS_IMM32(iptr->sx.s23.s2.constval))
    1563         295 :                                         M_LST_IMM32(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
    1564             :                                 else {
    1565           5 :                                         M_MOV_IMM(iptr->sx.s23.s2.constval, REG_ITMP2);
    1566           5 :                                         M_LST(REG_ITMP2, REG_ITMP1, 0);
    1567             :                                 }
    1568         300 :                                 break;
    1569             :                         default:
    1570           0 :                                 assert(false);
    1571             :                                 break;
    1572             :                         }
    1573         814 :                         codegen_emit_patchable_barrier(iptr, cd, pr, fi);
    1574         814 :                         break;
    1575             : 
    1576             :                 case ICMD_GETFIELD:   /* ...  ==> ..., value                          */
    1577             : 
    1578      100193 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
    1579             : 
    1580      100193 :                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
    1581         677 :                                 uf        = iptr->sx.s23.s3.uf;
    1582         677 :                                 fieldtype = uf->fieldref->parseddesc.fd->type;
    1583         677 :                                 disp      = 0;
    1584             : 
    1585             : /*                              PROFILE_CYCLE_STOP; */
    1586             : 
    1587         677 :                                 pr = patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
    1588         677 :                                 mcodeptr_save = cd->mcodeptr;
    1589             : 
    1590             : /*                              PROFILE_CYCLE_START; */
    1591             : 
    1592         677 :                                 fi = NULL;              /* Silence compiler warning */
    1593             :                         }
    1594             :                         else {
    1595       99516 :                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
    1596       99516 :                                 fieldtype = fi->type;
    1597       99516 :                                 disp      = fi->offset;
    1598             : 
    1599       99516 :                                 pr = 0;
    1600             :                         }
    1601             : 
    1602             :                         /* implicit null-pointer check */
    1603      100193 :                         switch (fieldtype) {
    1604             :                         case TYPE_INT:
    1605       38354 :                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
    1606       38354 :                                 M_ILD32(d, s1, disp);
    1607       38354 :                                 break;
    1608             :                         case TYPE_LNG:
    1609             :                         case TYPE_ADR:
    1610       61364 :                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
    1611       61364 :                                 M_LLD32(d, s1, disp);
    1612       61364 :                                 break;
    1613             :                         case TYPE_FLT:
    1614         454 :                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
    1615         454 :                                 M_FLD32(d, s1, disp);
    1616         454 :                                 break;
    1617             :                         case TYPE_DBL:                          
    1618          21 :                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
    1619          21 :                                 M_DLD32(d, s1, disp);
    1620          21 :                                 break;
    1621             :                         default:
    1622             :                                 // Silence compiler warning.
    1623           0 :                                 d = 0;
    1624             :                         }
    1625      100193 :                         if (pr)
    1626         677 :                                 codegen_fixup_alignment(cd, pr, mcodeptr_save);
    1627      100193 :                         emit_store_dst(jd, iptr, d);
    1628      100193 :                         break;
    1629             : 
    1630             :                 case ICMD_PUTFIELD:   /* ..., objectref, value  ==> ...               */
    1631             : 
    1632       40112 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
    1633       40112 :                         s2 = emit_load_s2(jd, iptr, REG_IFTMP); /* REG_IFTMP == REG_ITMP2 */
    1634             : 
    1635       40112 :                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
    1636         614 :                                 uf        = iptr->sx.s23.s3.uf;
    1637         614 :                                 fieldtype = uf->fieldref->parseddesc.fd->type;
    1638         614 :                                 disp      = 0;
    1639             : 
    1640             : /*                              PROFILE_CYCLE_STOP; */
    1641             : 
    1642         614 :                                 pr = patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
    1643         614 :                                 mcodeptr_save = cd->mcodeptr;
    1644             : 
    1645             : /*                              PROFILE_CYCLE_START; */
    1646             : 
    1647         614 :                                 fi = NULL;              /* Silence compiler warning */
    1648             :                         } 
    1649             :                         else {
    1650       39498 :                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
    1651       39498 :                                 fieldtype = fi->type;
    1652       39498 :                                 disp      = fi->offset;
    1653             : 
    1654       39498 :                                 pr = NULL;              /* Silence compiler warning */
    1655             :                         }
    1656             : 
    1657             :                         /* implicit null-pointer check */
    1658       40112 :                         switch (fieldtype) {
    1659             :                         case TYPE_INT:
    1660       13573 :                                 M_IST32(s2, s1, disp);
    1661       13573 :                                 break;
    1662             :                         case TYPE_LNG:
    1663             :                         case TYPE_ADR:
    1664       25877 :                                 M_LST32(s2, s1, disp);
    1665       25877 :                                 break;
    1666             :                         case TYPE_FLT:
    1667         624 :                                 M_FST32(s2, s1, disp);
    1668         624 :                                 break;
    1669             :                         case TYPE_DBL:
    1670          38 :                                 M_DST32(s2, s1, disp);
    1671             :                                 break;
    1672             :                         }
    1673       40112 :                         if (pr)
    1674         614 :                                 codegen_fixup_alignment(cd, pr, mcodeptr_save);
    1675       40112 :                         codegen_emit_patchable_barrier(iptr, cd, pr, fi);
    1676       40112 :                         break;
    1677             : 
    1678             :                 case ICMD_PUTFIELDCONST:  /* ..., objectref, value  ==> ...           */
    1679             :                                           /* val = value (in current instruction)     */
    1680             :                                           /* following NOP)                           */
    1681             : 
    1682       12129 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
    1683             : 
    1684       12129 :                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
    1685         100 :                                 uf        = iptr->sx.s23.s3.uf;
    1686         100 :                                 fieldtype = uf->fieldref->parseddesc.fd->type;
    1687         100 :                                 disp      = 0;
    1688             : 
    1689             : /*                              PROFILE_CYCLE_STOP; */
    1690             : 
    1691         100 :                                 pr = patcher_add_patch_ref(jd, PATCHER_putfieldconst, uf, 0);
    1692         100 :                                 mcodeptr_save = cd->mcodeptr;
    1693             : 
    1694             : /*                              PROFILE_CYCLE_START; */
    1695             : 
    1696         100 :                                 fi = NULL;              /* Silence compiler warning */
    1697             :                         } 
    1698             :                         else {
    1699       12029 :                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
    1700       12029 :                                 fieldtype = fi->type;
    1701       12029 :                                 disp      = fi->offset;
    1702             : 
    1703       12029 :                                 pr = NULL;              /* Silence compiler warning */
    1704             :                         }
    1705             : 
    1706             :                         /* implicit null-pointer check */
    1707       12129 :                         switch (fieldtype) {
    1708             :                         case TYPE_INT:
    1709             :                         case TYPE_FLT:
    1710        8296 :                                 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
    1711        8296 :                                 break;
    1712             :                         case TYPE_LNG:
    1713             :                         case TYPE_ADR:
    1714             :                         case TYPE_DBL:
    1715             :                                 /* XXX why no check for IS_IMM32? -- probably because of the patcher */
    1716        3833 :                                 M_MOV_IMM(iptr->sx.s23.s2.constval, REG_ITMP2);
    1717        3833 :                                 if (disp)  /* resolved, disp can never be 0 */
    1718        3828 :                                         M_LST(REG_ITMP2, s1, disp);
    1719             :                                 else {     /* unresolved */
    1720           5 :                                         M_LST32(REG_ITMP2, s1, disp);
    1721           5 :                                         pr->patch_align = 4;
    1722             :                                 }
    1723             :                                 break;
    1724             :                         }
    1725       12129 :                         if (pr)
    1726         100 :                                 codegen_fixup_alignment(cd, pr, mcodeptr_save);
    1727       12129 :                         codegen_emit_patchable_barrier(iptr, cd, pr, fi);
    1728       12129 :                         break;
    1729             : 
    1730             : 
    1731             :                 /* branch operations **************************************************/
    1732             : 
    1733             :                 case ICMD_ATHROW:       /* ..., objectref ==> ... (, objectref)       */
    1734             : 
    1735       18423 :                         M_ALD_MEM(REG_METHODPTR, TRAP_THROW);
    1736       18423 :                         break;
    1737             : 
    1738             :                 case ICMD_IF_LEQ:       /* ..., value ==> ...                         */
    1739             :                 case ICMD_IF_LNE:
    1740             :                 case ICMD_IF_LLT:
    1741             :                 case ICMD_IF_LGE:
    1742             :                 case ICMD_IF_LGT:
    1743             :                 case ICMD_IF_LLE:
    1744             : 
    1745         295 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
    1746         560 :                         if (IS_IMM32(iptr->sx.val.l))
    1747         265 :                                 M_LCMP_IMM(iptr->sx.val.l, s1);
    1748             :                         else {
    1749          30 :                                 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
    1750          30 :                                 M_LCMP(REG_ITMP2, s1);
    1751             :                         }
    1752         295 :                         emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_LEQ, BRANCH_OPT_NONE);
    1753         295 :                         break;
    1754             : 
    1755             :                 case ICMD_IF_LCMPEQ:    /* ..., value, value ==> ...                  */
    1756             :                 case ICMD_IF_LCMPNE:
    1757             :                 case ICMD_IF_LCMPLT:
    1758             :                 case ICMD_IF_LCMPGE:
    1759             :                 case ICMD_IF_LCMPGT:
    1760             :                 case ICMD_IF_LCMPLE:
    1761             : 
    1762         124 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
    1763         124 :                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
    1764         124 :                         M_LCMP(s2, s1);
    1765         124 :                         emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_LCMPEQ, BRANCH_OPT_NONE);
    1766         124 :                         break;
    1767             : 
    1768             :                 case ICMD_TABLESWITCH:  /* ..., index ==> ...                         */
    1769             :                         {
    1770             :                                 s4 i, l;
    1771             :                                 branch_target_t *table;
    1772             : 
    1773          72 :                                 table = iptr->dst.table;
    1774             : 
    1775          72 :                                 l = iptr->sx.s23.s2.tablelow;
    1776          72 :                                 i = iptr->sx.s23.s3.tablehigh;
    1777             : 
    1778          72 :                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
    1779          72 :                                 M_INTMOVE(s1, REG_ITMP1);
    1780             : 
    1781          72 :                                 if (l != 0)
    1782          44 :                                         M_ISUB_IMM(l, REG_ITMP1);
    1783             : 
    1784             :                                 /* number of targets */
    1785          72 :                                 i = i - l + 1;
    1786             : 
    1787             :                 /* range check */
    1788             : 
    1789          72 :                                 M_ICMP_IMM(i - 1, REG_ITMP1);
    1790          72 :                                 emit_bugt(cd, table[0].block);
    1791             : 
    1792             :                                 /* build jump table top down and use address of lowest entry */
    1793             : 
    1794          72 :                                 table += i;
    1795             : 
    1796        1218 :                                 while (--i >= 0) {
    1797        1074 :                                         dseg_add_target(cd, table->block);
    1798        1074 :                                         --table;
    1799             :                                 }
    1800             : 
    1801             :                                 /* length of dataseg after last dseg_add_target is used
    1802             :                                    by load */
    1803             : 
    1804          72 :                                 M_MOV_IMM(0, REG_ITMP2);
    1805          72 :                                 dseg_adddata(cd);
    1806          72 :                                 emit_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 3, REG_ITMP1);
    1807          72 :                                 M_JMP(REG_ITMP1);
    1808             :                         }
    1809          72 :                         break;
    1810             : 
    1811             :                 case ICMD_BUILTIN:
    1812       77258 :                         bte = iptr->sx.s23.s3.bte;
    1813       77258 :                         if (bte->stub == NULL) {
    1814        1840 :                                 M_MOV_IMM(bte->fp, REG_ITMP1);
    1815             :                         }
    1816             :                         else {
    1817       75418 :                                 M_MOV_IMM(bte->stub, REG_ITMP1);
    1818             :                         }
    1819       77258 :                         M_CALL(REG_ITMP1);
    1820       77258 :                         break;
    1821             : 
    1822             :                 case ICMD_INVOKESPECIAL:
    1823       98529 :                         emit_nullpointer_check(cd, iptr, REG_A0);
    1824             :                         /* fall through */
    1825             : 
    1826             :                 case ICMD_INVOKESTATIC:
    1827      155417 :                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
    1828       43458 :                                 um = iptr->sx.s23.s3.um;
    1829       43458 :                                 disp = dseg_add_unique_address(cd, um);
    1830             : 
    1831             :                                 patcher_add_patch_ref(jd, PATCHER_invokestatic_special,
    1832       43458 :                                                                           um, disp);
    1833             :                         }
    1834             :                         else {
    1835      111959 :                                 lm = iptr->sx.s23.s3.fmiref->p.method;
    1836      111959 :                                 disp = dseg_add_functionptr(cd, lm->stubroutine);
    1837             :                         }
    1838             : 
    1839      155417 :                         M_ALD(REG_ITMP2, RIP, disp);
    1840      155417 :                         M_CALL(REG_ITMP2);
    1841      155417 :                         break;
    1842             : 
    1843             :                 case ICMD_INVOKEVIRTUAL:
    1844      119224 :                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
    1845       19564 :                                 um = iptr->sx.s23.s3.um;
    1846       19564 :                                 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
    1847       19564 :                                 emit_arbitrary_nop(cd, PATCH_ALIGNMENT((uintptr_t) cd->mcodeptr, 6, sizeof(int32_t)));
    1848             : 
    1849       19564 :                                 s1 = 0;
    1850             :                         }
    1851             :                         else {
    1852       99660 :                                 lm = iptr->sx.s23.s3.fmiref->p.method;
    1853       99660 :                                 s1 = OFFSET(vftbl_t, table[0]) +
    1854      199320 :                                         sizeof(methodptr) * lm->vftblindex;
    1855             :                         }
    1856             : 
    1857             :                         /* implicit null-pointer check */
    1858      119224 :                         M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
    1859      119224 :                         M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
    1860      119224 :                         M_CALL(REG_ITMP3);
    1861      119224 :                         break;
    1862             : 
    1863             :                 case ICMD_INVOKEINTERFACE:
    1864        7503 :                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
    1865        1210 :                                 um = iptr->sx.s23.s3.um;
    1866        1210 :                                 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
    1867        1210 :                                 emit_arbitrary_nop(cd, PATCH_ALIGNMENT((uintptr_t) cd->mcodeptr, 6, sizeof(int32_t)));
    1868             : 
    1869        1210 :                                 s1 = 0;
    1870        1210 :                                 s2 = 0;
    1871             :                         }
    1872             :                         else {
    1873        6293 :                                 lm = iptr->sx.s23.s3.fmiref->p.method;
    1874        6293 :                                 s1 = OFFSET(vftbl_t, interfacetable[0]) -
    1875        6293 :                                         sizeof(methodptr) * lm->clazz->index;
    1876             : 
    1877        6293 :                                 s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
    1878             :                         }
    1879             : 
    1880             :                         /* implicit null-pointer check */
    1881        7503 :                         M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
    1882        7503 :                         M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
    1883        7503 :                         if (INSTRUCTION_IS_UNRESOLVED(iptr))
    1884        1210 :                                 emit_arbitrary_nop(cd, PATCH_ALIGNMENT((uintptr_t) cd->mcodeptr, 3, sizeof(int32_t)));
    1885        7503 :                         M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
    1886        7503 :                         M_CALL(REG_ITMP3);
    1887        7503 :                         break;
    1888             : 
    1889             :                 case ICMD_CHECKCAST:  /* ..., objectref ==> ..., objectref            */
    1890             : 
    1891        9191 :                         if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
    1892             :                                 /* object type cast-check */
    1893             : 
    1894             :                                 classinfo *super;
    1895             :                                 s4         superindex;
    1896             : 
    1897        8232 :                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
    1898        1714 :                                         super      = NULL;
    1899        1714 :                                         superindex = 0;
    1900             :                                 }
    1901             :                                 else {
    1902        6518 :                                         super      = iptr->sx.s23.s3.c.cls;
    1903        6518 :                                         superindex = super->index;
    1904             :                                 }
    1905             : 
    1906        8232 :                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
    1907             : 
    1908             :                                 /* if class is not resolved, check which code to call */
    1909             : 
    1910        8232 :                                 if (super == NULL) {
    1911        1714 :                                         M_TEST(s1);
    1912        1714 :                                         emit_label_beq(cd, BRANCH_LABEL_1);
    1913             : 
    1914             :                                         patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
    1915        1714 :                                                                                   iptr->sx.s23.s3.c.ref, 0);
    1916             : 
    1917        1714 :                                         emit_arbitrary_nop(cd, PATCH_ALIGNMENT((uintptr_t) cd->mcodeptr, 2, sizeof(int32_t)));
    1918             : 
    1919        1714 :                                         M_IMOV_IMM(0, REG_ITMP2);                 /* super->flags */
    1920        1714 :                                         M_IAND_IMM(ACC_INTERFACE, REG_ITMP2);
    1921        1714 :                                         emit_label_beq(cd, BRANCH_LABEL_2);
    1922             :                                 }
    1923             : 
    1924             :                                 /* interface checkcast code */
    1925             : 
    1926        8232 :                                 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
    1927        2093 :                                         if (super != NULL) {
    1928         379 :                                                 M_TEST(s1);
    1929         379 :                                                 emit_label_beq(cd, BRANCH_LABEL_3);
    1930             :                                         }
    1931             : 
    1932        2093 :                                         M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
    1933             : 
    1934        2093 :                                         if (super == NULL) {
    1935             :                                                 patcher_add_patch_ref(jd, PATCHER_checkcast_interface,
    1936             :                                                                                           iptr->sx.s23.s3.c.ref,
    1937        1714 :                                                                                           0);
    1938        1714 :                                                 emit_arbitrary_nop(cd, PATCH_ALIGNMENT((uintptr_t) cd->mcodeptr, 10, sizeof(int32_t)));
    1939             :                                         }
    1940             : 
    1941             :                                         M_ILD32(REG_ITMP3,
    1942        2093 :                                                         REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
    1943        2093 :                                         M_ICMP_IMM32(superindex, REG_ITMP3);
    1944        2093 :                                         emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
    1945             : 
    1946        2093 :                                         if (super == NULL)
    1947        1714 :                                                 emit_arbitrary_nop(cd, PATCH_ALIGNMENT((uintptr_t) cd->mcodeptr, 3, sizeof(int32_t)));
    1948        2093 :                                         M_ALD32(REG_ITMP3, REG_ITMP2, 
    1949             :                                                         OFFSET(vftbl_t, interfacetable[0]) -
    1950        2093 :                                                         superindex * sizeof(methodptr*));
    1951        2093 :                                         M_TEST(REG_ITMP3);
    1952        2093 :                                         emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
    1953             : 
    1954        2093 :                                         if (super == NULL)
    1955        1714 :                                                 emit_label_br(cd, BRANCH_LABEL_4);
    1956             :                                         else
    1957         379 :                                                 emit_label(cd, BRANCH_LABEL_3);
    1958             :                                 }
    1959             : 
    1960             :                                 /* class checkcast code */
    1961             : 
    1962        8232 :                                 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
    1963        7853 :                                         if (super == NULL) {
    1964        1714 :                                                 emit_label(cd, BRANCH_LABEL_2);
    1965             : 
    1966        1714 :                                                 constant_classref *cr = iptr->sx.s23.s3.c.ref;
    1967        1714 :                                                 disp = dseg_add_unique_address(cd, cr);
    1968             : 
    1969             :                                                 patcher_add_patch_ref(jd,
    1970             :                                                                                           PATCHER_resolve_classref_to_vftbl,
    1971        1714 :                                                                                           cr, disp);
    1972             :                                         }
    1973             :                                         else {
    1974        6139 :                                                 M_TEST(s1);
    1975        6139 :                                                 emit_label_beq(cd, BRANCH_LABEL_5);
    1976             : 
    1977        6139 :                                                 disp = dseg_add_address(cd, super->vftbl);
    1978             :                                         }
    1979             : 
    1980        7853 :                                         M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
    1981        7853 :                                         M_ALD(REG_ITMP3, RIP, disp);
    1982             : 
    1983        9709 :                                         if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
    1984        1856 :                                                 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
    1985        1856 :                                                 M_LCMP_MEMINDEX(REG_ITMP2, 0, REG_ITMP1, 0, REG_ITMP3);
    1986        1856 :                                                 emit_label_beq(cd, BRANCH_LABEL_6);  /* good */
    1987             : 
    1988        1856 :                                                 if (super == NULL) {
    1989        1714 :                                                         M_LCMP_IMM(OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]), REG_ITMP1);
    1990        1714 :                                                         emit_label_bne(cd, BRANCH_LABEL_10);  /* throw */
    1991             :                                                 }
    1992             : 
    1993        1856 :                                                 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_depth));
    1994        1856 :                                                 M_ICMP_MEMBASE(REG_ITMP2, OFFSET(vftbl_t, subtype_depth), REG_ITMP1);
    1995        1856 :                                                 emit_label_bgt(cd, BRANCH_LABEL_9);  /* throw */
    1996             : 
    1997        1856 :                                                 M_ALD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow));
    1998        1856 :                                                 M_LCMP_MEMINDEX(REG_ITMP2, -8*DISPLAY_SIZE, REG_ITMP1, 3, REG_ITMP3);
    1999        1856 :                                                 emit_label_beq(cd, BRANCH_LABEL_7);  /* good */
    2000             : 
    2001        1856 :                                                 emit_label(cd, BRANCH_LABEL_9);
    2002        1856 :                                                 if (super == NULL)
    2003        1714 :                                                         emit_label(cd, BRANCH_LABEL_10);
    2004             : 
    2005             :                                                 /* reload s1, might have been destroyed */
    2006        1856 :                                                 emit_load_s1(jd, iptr, REG_ITMP1);
    2007        1856 :                                                 M_ALD_MEM(s1, TRAP_ClassCastException);
    2008             : 
    2009        1856 :                                                 emit_label(cd, BRANCH_LABEL_7);
    2010        1856 :                                                 emit_label(cd, BRANCH_LABEL_6);
    2011             :                                                 /* reload s1, might have been destroyed */
    2012        1856 :                                                 emit_load_s1(jd, iptr, REG_ITMP1);
    2013             :                                         }
    2014             :                                         else {
    2015        5997 :                                                 M_LCMP_MEMBASE(REG_ITMP2, super->vftbl->subtype_offset, REG_ITMP3);
    2016        5997 :                                                 emit_classcast_check(cd, iptr, BRANCH_NE, REG_ITMP3, s1);
    2017             :                                         }
    2018             : 
    2019        7853 :                                         if (super != NULL)
    2020        6139 :                                                 emit_label(cd, BRANCH_LABEL_5);
    2021             :                                 }
    2022             : 
    2023        8232 :                                 if (super == NULL) {
    2024        1714 :                                         emit_label(cd, BRANCH_LABEL_1);
    2025        1714 :                                         emit_label(cd, BRANCH_LABEL_4);
    2026             :                                 }
    2027             : 
    2028        8232 :                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
    2029             :                         }
    2030             :                         else {
    2031             :                                 /* array type cast-check */
    2032             : 
    2033         959 :                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
    2034         959 :                                 M_INTMOVE(s1, REG_A0);
    2035             : 
    2036         959 :                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
    2037         160 :                                         constant_classref *cr = iptr->sx.s23.s3.c.ref;
    2038         160 :                                         disp = dseg_add_unique_address(cd, cr);
    2039             : 
    2040             :                                         patcher_add_patch_ref(jd,
    2041             :                                                                                   PATCHER_resolve_classref_to_classinfo,
    2042         160 :                                                                                   cr, disp);
    2043             :                                 }
    2044             :                                 else {
    2045         799 :                                         disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
    2046             :                                 }
    2047             : 
    2048         959 :                                 M_ALD(REG_A1, RIP, disp);
    2049         959 :                                 M_MOV_IMM(BUILTIN_arraycheckcast, REG_ITMP1);
    2050         959 :                                 M_CALL(REG_ITMP1);
    2051             : 
    2052             :                                 /* s1 may have been destroyed over the function call */
    2053         959 :                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
    2054         959 :                                 M_TEST(REG_RESULT);
    2055         959 :                                 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
    2056             : 
    2057         959 :                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
    2058             :                         }
    2059             : 
    2060        9191 :                         M_INTMOVE(s1, d);
    2061        9191 :                         emit_store_dst(jd, iptr, d);
    2062        9191 :                         break;
    2063             : 
    2064             :                 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
    2065             : 
    2066             :                         {
    2067             :                         classinfo *super;
    2068             :                         s4         superindex;
    2069             : 
    2070        1267 :                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
    2071         272 :                                 super      = NULL;
    2072         272 :                                 superindex = 0;
    2073             :                         }
    2074             :                         else {
    2075         995 :                                 super      = iptr->sx.s23.s3.c.cls;
    2076         995 :                                 superindex = super->index;
    2077             :                         }
    2078             : 
    2079        1267 :                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
    2080        1267 :                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
    2081             : 
    2082        1267 :                         if (s1 == d) {
    2083         145 :                                 M_INTMOVE(s1, REG_ITMP1);
    2084         145 :                                 s1 = REG_ITMP1;
    2085             :                         }
    2086             : 
    2087        1267 :                         M_CLR(d);
    2088             : 
    2089             :                         /* if class is not resolved, check which code to call */
    2090             : 
    2091        1267 :                         if (super == NULL) {
    2092         272 :                                 M_TEST(s1);
    2093         272 :                                 emit_label_beq(cd, BRANCH_LABEL_1);
    2094             : 
    2095             :                                 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
    2096         272 :                                                                           iptr->sx.s23.s3.c.ref, 0);
    2097             : 
    2098         272 :                                 emit_arbitrary_nop(cd, PATCH_ALIGNMENT((uintptr_t) cd->mcodeptr, 2, sizeof(int32_t)));
    2099             : 
    2100         272 :                                 M_IMOV_IMM(0, REG_ITMP3);                     /* super->flags */
    2101         272 :                                 M_IAND_IMM(ACC_INTERFACE, REG_ITMP3);
    2102         272 :                                 emit_label_beq(cd, BRANCH_LABEL_2);
    2103             :                         }
    2104             : 
    2105             :                         /* interface instanceof code */
    2106             : 
    2107        1267 :                         if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
    2108             :                                 int nops;
    2109         425 :                                 if (super != NULL) {
    2110         153 :                                         M_TEST(s1);
    2111         153 :                                         emit_label_beq(cd, BRANCH_LABEL_3);
    2112             :                                 }
    2113             : 
    2114         425 :                                 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
    2115             : 
    2116         425 :                                 if (super == NULL) {
    2117             :                                         patcher_add_patch_ref(jd, PATCHER_instanceof_interface,
    2118         272 :                                                                                   iptr->sx.s23.s3.c.ref, 0);
    2119         272 :                                         emit_arbitrary_nop(cd, PATCH_ALIGNMENT((uintptr_t) cd->mcodeptr, 10, sizeof(int32_t)));
    2120             :                                 }
    2121             : 
    2122             :                                 M_ILD32(REG_ITMP3,
    2123         425 :                                                 REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
    2124         425 :                                 M_ICMP_IMM32(superindex, REG_ITMP3);
    2125             : 
    2126         425 :                                 nops = super == NULL ? PATCH_ALIGNMENT((uintptr_t) (cd->mcodeptr + 6), 3, sizeof(int32_t)) : 0;
    2127             : 
    2128         425 :                                 int a = 3 + 4 /* mov_membase32_reg */ + 3 /* test */ + 4 /* setcc */ + nops;
    2129             : 
    2130         425 :                                 M_BLE(a);
    2131         425 :                                 emit_arbitrary_nop(cd, nops);
    2132         425 :                                 M_ALD32(REG_ITMP1, REG_ITMP1,
    2133             :                                                 OFFSET(vftbl_t, interfacetable[0]) -
    2134         425 :                                                 superindex * sizeof(methodptr*));
    2135         425 :                                 M_TEST(REG_ITMP1);
    2136         425 :                                 M_SETNE(d);
    2137             : 
    2138         425 :                                 if (super == NULL)
    2139         272 :                                         emit_label_br(cd, BRANCH_LABEL_4);
    2140             :                                 else
    2141         153 :                                         emit_label(cd, BRANCH_LABEL_3);
    2142             :                         }
    2143             : 
    2144             :                         /* class instanceof code */
    2145             : 
    2146        1267 :                         if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
    2147        1114 :                                 if (super == NULL) {
    2148         272 :                                         emit_label(cd, BRANCH_LABEL_2);
    2149             : 
    2150         272 :                                         constant_classref *cr = iptr->sx.s23.s3.c.ref;
    2151         272 :                                         disp = dseg_add_unique_address(cd, cr);
    2152             : 
    2153             :                                         patcher_add_patch_ref(jd,
    2154             :                                                                                   PATCHER_resolve_classref_to_vftbl,
    2155         272 :                                                                                   cr, disp);
    2156             :                                 }
    2157             :                                 else {
    2158         842 :                                         M_TEST(s1);
    2159         842 :                                         emit_label_beq(cd, BRANCH_LABEL_5);
    2160             : 
    2161         842 :                                         disp = dseg_add_address(cd, super->vftbl);
    2162             :                                 }
    2163             : 
    2164        1114 :                                 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
    2165        1114 :                                 M_ALD(REG_ITMP3, RIP, disp);
    2166             : 
    2167        1388 :                                 if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
    2168         274 :                                         M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
    2169         274 :                                         M_LCMP_MEMINDEX(REG_ITMP2, 0, REG_ITMP1, 0, REG_ITMP3);
    2170         274 :                                         emit_label_bne(cd, BRANCH_LABEL_8); /* jump over INC/SETE */
    2171         274 :                                         if (d == REG_ITMP2) {
    2172           0 :                                                 M_SETE(d);
    2173           0 :                                                 M_BSEXT(d, d);
    2174             :                                         } else
    2175         274 :                                                 M_LINC(d);
    2176         274 :                                         emit_label_br(cd, BRANCH_LABEL_6);  /* true */
    2177         274 :                                         emit_label(cd, BRANCH_LABEL_8);
    2178             : 
    2179         274 :                                         if (super == NULL) {
    2180         272 :                                                 M_LCMP_IMM(OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]), REG_ITMP1);
    2181         272 :                                                 emit_label_bne(cd, BRANCH_LABEL_10);  /* false */
    2182             :                                         }
    2183             : 
    2184         274 :                                         M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_depth));
    2185         274 :                                         M_ICMP_MEMBASE(REG_ITMP2, OFFSET(vftbl_t, subtype_depth), REG_ITMP1);
    2186         274 :                                         emit_label_bgt(cd, BRANCH_LABEL_9);  /* false */
    2187             : 
    2188         274 :                                         M_ALD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow));
    2189         274 :                                         M_LCMP_MEMINDEX(REG_ITMP2, -8*DISPLAY_SIZE, REG_ITMP1, 3, REG_ITMP3);
    2190         274 :                                         M_SETE(d);
    2191         274 :                                         if (d == REG_ITMP2) {
    2192           0 :                                                 M_BSEXT(d, d);
    2193             : 
    2194           0 :                                                 emit_label_br(cd, BRANCH_LABEL_7); /* jump over M_CLR */
    2195             :                                         }
    2196             : 
    2197         274 :                                         emit_label(cd, BRANCH_LABEL_9);
    2198         274 :                                         if (super == NULL)
    2199         272 :                                                 emit_label(cd, BRANCH_LABEL_10);
    2200         274 :                                         if (d == REG_ITMP2) {
    2201           0 :                                                 M_CLR(d);
    2202             : 
    2203           0 :                                                 emit_label(cd, BRANCH_LABEL_7);
    2204             :                                         }
    2205         274 :                                         emit_label(cd, BRANCH_LABEL_6);
    2206             :                                 }
    2207             :                                 else {
    2208         840 :                                         M_LCMP_MEMBASE(REG_ITMP2, super->vftbl->subtype_offset, REG_ITMP3);
    2209         840 :                                         M_SETE(d);
    2210         840 :                                         if (d == REG_ITMP2)
    2211           0 :                                                 M_BSEXT(d, d);
    2212             :                                 }
    2213             : 
    2214        1114 :                                 if (super != NULL)
    2215         842 :                                         emit_label(cd, BRANCH_LABEL_5);
    2216             :                         }
    2217             : 
    2218        1267 :                         if (super == NULL) {
    2219         272 :                                 emit_label(cd, BRANCH_LABEL_1);
    2220         272 :                                 emit_label(cd, BRANCH_LABEL_4);
    2221             :                         }
    2222             : 
    2223        1267 :                         emit_store_dst(jd, iptr, d);
    2224             :                         }
    2225        1267 :                         break;
    2226             : 
    2227             :                 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref  */
    2228             : 
    2229             :                         /* check for negative sizes and copy sizes to stack if necessary  */
    2230             : 
    2231          15 :                         MCODECHECK((10 * 4 * iptr->s1.argcount) + 5 + 10 * 8);
    2232             : 
    2233          67 :                         for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
    2234             : 
    2235             :                                 /* copy SAVEDVAR sizes to stack */
    2236          37 :                                 var = VAR(iptr->sx.s23.s2.args[s1]);
    2237             : 
    2238             :                                 /* Already Preallocated? */
    2239          37 :                                 if (!(var->flags & PREALLOC)) {
    2240          37 :                                         s2 = emit_load(jd, iptr, var, REG_ITMP1);
    2241          37 :                                         M_LST(s2, REG_SP, s1 * 8);
    2242             :                                 }
    2243             :                         }
    2244             : 
    2245             :                         /* a0 = dimension count */
    2246             : 
    2247          15 :                         M_MOV_IMM(iptr->s1.argcount, REG_A0);
    2248             : 
    2249             :                         /* is a patcher function set? */
    2250             : 
    2251          15 :                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
    2252           2 :                                 constant_classref *cr = iptr->sx.s23.s3.c.ref;
    2253           2 :                                 disp = dseg_add_unique_address(cd, cr);
    2254             : 
    2255             :                                 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
    2256           2 :                                                                           cr, disp);
    2257             :                         }
    2258             :                         else {
    2259          13 :                                 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
    2260             :                         }
    2261             : 
    2262             :                         /* a1 = classinfo */
    2263             : 
    2264          15 :                         M_ALD(REG_A1, RIP, disp);
    2265             : 
    2266             :                         /* a2 = pointer to dimensions = stack pointer */
    2267             : 
    2268          15 :                         M_MOV(REG_SP, REG_A2);
    2269             : 
    2270          15 :                         M_MOV_IMM(BUILTIN_multianewarray, REG_ITMP1);
    2271          15 :                         M_CALL(REG_ITMP1);
    2272             : 
    2273             :                         /* check for exception before result assignment */
    2274             : 
    2275          15 :                         emit_exception_check(cd, iptr);
    2276             : 
    2277          15 :                         s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
    2278          15 :                         M_INTMOVE(REG_RESULT, s1);
    2279          15 :                         emit_store_dst(jd, iptr, s1);
    2280          15 :                         break;
    2281             : 
    2282             :                 default:
    2283           0 :                         vm_abort("Unknown ICMD %d during code generation", iptr->opc);
    2284             :         } /* switch */
    2285     1368799 : }
    2286             : 
    2287             : 
    2288             : /* codegen_emit_stub_native ****************************************************
    2289             : 
    2290             :    Emits a stub routine which calls a native method.
    2291             : 
    2292             : *******************************************************************************/
    2293             : 
    2294       13057 : void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
    2295             : {
    2296             :         methodinfo  *m;
    2297             :         codeinfo    *code;
    2298             :         codegendata *cd;
    2299             :         methoddesc  *md;
    2300             :         int          i, j;
    2301             :         int          s1, s2;
    2302             :         int          disp;
    2303             : 
    2304             :         /* Sanity check. */
    2305             : 
    2306       13057 :         assert(f != NULL);
    2307             : 
    2308             :         /* Get required compiler data. */
    2309             : 
    2310       13057 :         m    = jd->m;
    2311       13057 :         code = jd->code;
    2312       13057 :         cd   = jd->cd;
    2313             : 
    2314             :         /* initialize variables */
    2315             : 
    2316       13057 :         md = m->parseddesc;
    2317             : 
    2318             :         /* calculate stack frame size */
    2319             : 
    2320             :         cd->stackframesize =
    2321             :                 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
    2322             :                 sizeof(localref_table) / SIZEOF_VOID_P +
    2323             :                 md->paramcount +
    2324             :                 (md->returntype.type == TYPE_VOID ? 0 : 1) +
    2325       13057 :                 nmd->memuse;
    2326             : 
    2327       13057 :         ALIGN_ODD(cd->stackframesize);              /* keep stack 16-byte aligned */
    2328             : 
    2329             :         /* create method header */
    2330             : 
    2331       13057 :         (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
    2332       13057 :         (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize       */
    2333       13057 :         (void) dseg_add_unique_s4(cd, 0);                      /* IsLeaf          */
    2334       13057 :         (void) dseg_add_unique_s4(cd, 0);                      /* IntSave         */
    2335       13057 :         (void) dseg_add_unique_s4(cd, 0);                      /* FltSave         */
    2336             : 
    2337             : #if defined(ENABLE_PROFILING)
    2338             :         /* generate native method profiling code */
    2339             : 
    2340             :         if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
    2341             :                 /* count frequency */
    2342             : 
    2343             :                 M_MOV_IMM(code, REG_ITMP3);
    2344             :                 M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
    2345             :         }
    2346             : #endif
    2347             : 
    2348             :         /* generate stub code */
    2349             : 
    2350       13057 :         M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
    2351             : 
    2352             : #if defined(ENABLE_GC_CACAO)
    2353             :         /* Save callee saved integer registers in stackframeinfo (GC may
    2354             :            need to recover them during a collection). */
    2355             : 
    2356             :         disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
    2357             :                 OFFSET(stackframeinfo_t, intregs);
    2358             : 
    2359             :         for (i = 0; i < INT_SAV_CNT; i++)
    2360             :                 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
    2361             : #endif
    2362             : 
    2363             :         /* save integer and float argument registers */
    2364             : 
    2365       29137 :         for (i = 0; i < md->paramcount; i++) {
    2366       16080 :                 if (!md->params[i].inmemory) {
    2367       16026 :                         s1 = md->params[i].regoff;
    2368             : 
    2369       16026 :                         switch (md->paramtypes[i].type) {
    2370             :                         case TYPE_INT:
    2371             :                         case TYPE_LNG:
    2372             :                         case TYPE_ADR:
    2373       15978 :                                 M_LST(s1, REG_SP, i * 8);
    2374       15978 :                                 break;
    2375             :                         case TYPE_FLT:
    2376             :                         case TYPE_DBL:
    2377          48 :                                 M_DST(s1, REG_SP, i * 8);
    2378          48 :                                 break;
    2379             :                         default:
    2380           0 :                                 assert(false);
    2381             :                                 break;
    2382             :                         }
    2383             :                 }
    2384             :         }
    2385             : 
    2386             :         /* create dynamic stack info */
    2387             : 
    2388       13057 :         M_MOV(REG_SP, REG_A0);
    2389       13057 :         emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
    2390       13057 :         M_MOV_IMM(codegen_start_native_call, REG_ITMP1);
    2391       13057 :         M_CALL(REG_ITMP1);
    2392             : 
    2393             :         /* remember class argument */
    2394             : 
    2395       13057 :         if (m->flags & ACC_STATIC)
    2396        5157 :                 M_MOV(REG_RESULT, REG_ITMP2);
    2397             : 
    2398             :         /* restore integer and float argument registers */
    2399             : 
    2400       29137 :         for (i = 0; i < md->paramcount; i++) {
    2401       16080 :                 if (!md->params[i].inmemory) {
    2402       16026 :                         s1 = md->params[i].regoff;
    2403             : 
    2404       16026 :                         switch (md->paramtypes[i].type) {
    2405             :                         case TYPE_INT:
    2406             :                         case TYPE_LNG:
    2407             :                         case TYPE_ADR:
    2408       15978 :                                 M_LLD(s1, REG_SP, i * 8);
    2409       15978 :                                 break;
    2410             :                         case TYPE_FLT:
    2411             :                         case TYPE_DBL:
    2412          48 :                                 M_DLD(s1, REG_SP, i * 8);
    2413          48 :                                 break;
    2414             :                         default:
    2415           0 :                                 assert(false);
    2416             :                                 break;
    2417             :                         }
    2418             :                 }
    2419             :         }
    2420             : 
    2421             :         /* Copy or spill arguments to new locations. */
    2422             : 
    2423       29137 :         for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
    2424       16080 :                 s2 = nmd->params[j].regoff;
    2425             : 
    2426       16080 :                 switch (md->paramtypes[i].type) {
    2427             :                 case TYPE_INT:
    2428             :                 case TYPE_LNG:
    2429             :                 case TYPE_ADR:
    2430       16008 :                         if (!md->params[i].inmemory) {
    2431       15978 :                                 s1 = md->params[i].regoff;
    2432             : 
    2433       15978 :                                 if (!nmd->params[j].inmemory)
    2434       15688 :                                         M_INTMOVE(s1, s2);
    2435             :                                 else
    2436         290 :                                         M_LST(s1, REG_SP, s2);
    2437             :                         }
    2438             :                         else {
    2439          30 :                                 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
    2440          30 :                                 M_LLD(REG_ITMP1, REG_SP, s1);
    2441          30 :                                 M_LST(REG_ITMP1, REG_SP, s2);
    2442             :                         }
    2443       16008 :                         break;
    2444             :                 case TYPE_FLT:
    2445             :                         /* We only copy spilled float arguments, as the float
    2446             :                            argument registers keep unchanged. */
    2447             : 
    2448          31 :                         if (md->params[i].inmemory) {
    2449          12 :                                 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
    2450             : 
    2451          12 :                                 M_FLD(REG_FTMP1, REG_SP, s1);
    2452          12 :                                 M_FST(REG_FTMP1, REG_SP, s2);
    2453             :                         }
    2454          31 :                         break;
    2455             :                 case TYPE_DBL:
    2456          41 :                         if (md->params[i].inmemory) {
    2457          12 :                                 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
    2458          12 :                                 M_DLD(REG_FTMP1, REG_SP, s1);
    2459          12 :                                 M_DST(REG_FTMP1, REG_SP, s2);
    2460             :                         }
    2461          41 :                         break;
    2462             :                 default:
    2463           0 :                         assert(false);
    2464             :                         break;
    2465             :                 }
    2466             :         }
    2467             : 
    2468             :         /* Handle native Java methods. */
    2469             : 
    2470       13057 :         if (m->flags & ACC_NATIVE) {
    2471             :                 /* put class into second argument register */
    2472             : 
    2473       10775 :                 if (m->flags & ACC_STATIC)
    2474        5157 :                         M_MOV(REG_ITMP2, REG_A1);
    2475             : 
    2476             :                 /* put env into first argument register */
    2477             : 
    2478       10775 :                 M_MOV_IMM(VM::get_current()->get_jnienv(), REG_A0);
    2479             :         }
    2480             : 
    2481             :         /* Call the native function. */
    2482             : 
    2483       13057 :         disp = dseg_add_functionptr(cd, f);
    2484       13057 :         M_ALD(REG_ITMP1, RIP, disp);
    2485       13057 :         M_CALL(REG_ITMP1);
    2486             : 
    2487             :         /* save return value */
    2488             : 
    2489       13057 :         switch (md->returntype.type) {
    2490             :         case TYPE_INT:
    2491             :         case TYPE_LNG:
    2492             :         case TYPE_ADR:
    2493       11675 :                 switch (md->returntype.primitivetype) {
    2494             :                 case PRIMITIVETYPE_BOOLEAN:
    2495         494 :                         M_BZEXT(REG_RESULT, REG_RESULT);
    2496         494 :                         break;
    2497             :                 case PRIMITIVETYPE_BYTE:
    2498           0 :                         M_BSEXT(REG_RESULT, REG_RESULT);
    2499           0 :                         break;
    2500             :                 case PRIMITIVETYPE_CHAR:
    2501           0 :                         M_CZEXT(REG_RESULT, REG_RESULT);
    2502           0 :                         break;
    2503             :                 case PRIMITIVETYPE_SHORT:
    2504           0 :                         M_SSEXT(REG_RESULT, REG_RESULT);
    2505             :                         break;
    2506             :                 default:
    2507             :                         break;
    2508             :                 }
    2509       11675 :                 M_LST(REG_RESULT, REG_SP, 0 * 8);
    2510       11675 :                 break;
    2511             :         case TYPE_FLT:
    2512             :         case TYPE_DBL:
    2513           5 :                 M_DST(REG_FRESULT, REG_SP, 0 * 8);
    2514           5 :                 break;
    2515             :         case TYPE_VOID:
    2516        1377 :                 break;
    2517             :         default:
    2518           0 :                 assert(false);
    2519             :                 break;
    2520             :         }
    2521             : 
    2522             :         /* remove native stackframe info */
    2523             : 
    2524       13057 :         M_MOV(REG_SP, REG_A0);
    2525       13057 :         emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
    2526       13057 :         M_MOV_IMM(codegen_finish_native_call, REG_ITMP1);
    2527       13057 :         M_CALL(REG_ITMP1);
    2528       13057 :         M_MOV(REG_RESULT, REG_ITMP3);
    2529             : 
    2530             :         /* restore return value */
    2531             : 
    2532       13057 :         switch (md->returntype.type) {
    2533             :         case TYPE_INT:
    2534             :         case TYPE_LNG:
    2535             :         case TYPE_ADR:
    2536       11675 :                 M_LLD(REG_RESULT, REG_SP, 0 * 8);
    2537       11675 :                 break;
    2538             :         case TYPE_FLT:
    2539             :         case TYPE_DBL:
    2540           5 :                 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
    2541           5 :                 break;
    2542             :         case TYPE_VOID:
    2543        1377 :                 break;
    2544             :         default:
    2545           0 :                 assert(false);
    2546             :                 break;
    2547             :         }
    2548             : 
    2549             : #if defined(ENABLE_GC_CACAO)
    2550             :         /* Restore callee saved integer registers from stackframeinfo (GC
    2551             :            might have modified them during a collection). */
    2552             :         
    2553             :         disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
    2554             :                 OFFSET(stackframeinfo_t, intregs);
    2555             : 
    2556             :         for (i = 0; i < INT_SAV_CNT; i++)
    2557             :                 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
    2558             : #endif
    2559             : 
    2560             :         /* remove stackframe */
    2561             : 
    2562       13057 :         M_AADD_IMM(cd->stackframesize * 8, REG_SP);
    2563             : 
    2564             :         /* test for exception */
    2565             : 
    2566       13057 :         M_TEST(REG_ITMP3);
    2567       13057 :         M_BNE(1);
    2568       13057 :         M_RET;
    2569             : 
    2570             :         /* handle exception */
    2571             : 
    2572       13057 :         M_MOV(REG_ITMP3, REG_ITMP1_XPTR);
    2573       13057 :         M_ALD_MEM(REG_METHODPTR, TRAP_NAT_EXCEPTION);
    2574       13057 : }
    2575             : 
    2576             : 
    2577             : /*
    2578             :  * These are local overrides for various environment variables in Emacs.
    2579             :  * Please do not remove this and leave it at the end of the file, where
    2580             :  * Emacs will automagically detect them.
    2581             :  * ---------------------------------------------------------------------
    2582             :  * Local variables:
    2583             :  * mode: c++
    2584             :  * indent-tabs-mode: t
    2585             :  * c-basic-offset: 4
    2586             :  * tab-width: 4
    2587             :  * End:
    2588             :  * vim:noexpandtab:sw=4:ts=4:
    2589             :  */

Generated by: LCOV version 1.11