~bkerensa/ubuntu/raring/valgrind/merge-from-deb

« back to all changes in this revision

Viewing changes to VEX/priv/host-x86/isel.c

  • Committer: Bazaar Package Importer
  • Author(s): Andrés Roldán
  • Date: 2008-06-13 02:31:40 UTC
  • mto: (1.4.1 upstream) (2.2.1 squeeze)
  • mto: This revision was merged to the branch mainline in revision 24.
  • Revision ID: james.westby@ubuntu.com-20080613023140-iwk33rz9rhvfkr96
Import upstream version 3.3.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
10
10
   This file is part of LibVEX, a library for dynamic binary
11
11
   instrumentation and translation.
12
12
 
13
 
   Copyright (C) 2004-2006 OpenWorks LLP.  All rights reserved.
 
13
   Copyright (C) 2004-2007 OpenWorks LLP.  All rights reserved.
14
14
 
15
15
   This library is made available under a dual licensing scheme.
16
16
 
113
113
   return IRExpr_Binder(binder);
114
114
}
115
115
 
 
116
static Bool isZeroU8 ( IRExpr* e )
 
117
{
 
118
   return e->tag == Iex_Const
 
119
          && e->Iex.Const.con->tag == Ico_U8
 
120
          && e->Iex.Const.con->Ico.U8 == 0;
 
121
}
 
122
 
 
123
static Bool isZeroU32 ( IRExpr* e )
 
124
{
 
125
   return e->tag == Iex_Const
 
126
          && e->Iex.Const.con->tag == Ico_U32
 
127
          && e->Iex.Const.con->Ico.U32 == 0;
 
128
}
 
129
 
 
130
static Bool isZeroU64 ( IRExpr* e )
 
131
{
 
132
   return e->tag == Iex_Const
 
133
          && e->Iex.Const.con->tag == Ico_U64
 
134
          && e->Iex.Const.con->Ico.U64 == 0ULL;
 
135
}
116
136
 
117
137
 
118
138
/*---------------------------------------------------------*/
362
382
Bool mightRequireFixedRegs ( IRExpr* e )
363
383
{
364
384
   switch (e->tag) {
365
 
      case Iex_Tmp: case Iex_Const: case Iex_Get: 
 
385
      case Iex_RdTmp: case Iex_Const: case Iex_Get: 
366
386
         return False;
367
387
      default:
368
388
         return True;
565
585
   offset. */
566
586
 
567
587
static
568
 
X86AMode* genGuestArrayOffset ( ISelEnv* env, IRArray* descr, 
 
588
X86AMode* genGuestArrayOffset ( ISelEnv* env, IRRegArray* descr, 
569
589
                                IRExpr* off, Int bias )
570
590
{
571
591
   HReg tmp, roff;
724
744
static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e )
725
745
{
726
746
   MatchInfo mi;
727
 
   DECLARE_PATTERN(p_32to1_then_1Uto8);
728
747
 
729
748
   IRType ty = typeOfIRExpr(env->type_env,e);
730
749
   vassert(ty == Ity_I32 || ty == Ity_I16 || ty == Ity_I8);
732
751
   switch (e->tag) {
733
752
 
734
753
   /* --------- TEMP --------- */
735
 
   case Iex_Tmp: {
736
 
      return lookupIRTemp(env, e->Iex.Tmp.tmp);
 
754
   case Iex_RdTmp: {
 
755
      return lookupIRTemp(env, e->Iex.RdTmp.tmp);
737
756
   }
738
757
 
739
758
   /* --------- LOAD --------- */
793
812
      X86AluOp   aluOp;
794
813
      X86ShiftOp shOp;
795
814
 
 
815
      /* Pattern: Sub32(0,x) */
 
816
      if (e->Iex.Binop.op == Iop_Sub32 && isZeroU32(e->Iex.Binop.arg1)) {
 
817
         HReg dst = newVRegI(env);
 
818
         HReg reg = iselIntExpr_R(env, e->Iex.Binop.arg2);
 
819
         addInstr(env, mk_iMOVsd_RR(reg,dst));
 
820
         addInstr(env, X86Instr_Unary32(Xun_NEG,dst));
 
821
         return dst;
 
822
      }
 
823
 
796
824
      /* Is it an addition or logical style op? */
797
825
      switch (e->Iex.Binop.op) {
798
826
         case Iop_Add8: case Iop_Add16: case Iop_Add32:
1005
1033
 
1006
1034
   /* --------- UNARY OP --------- */
1007
1035
   case Iex_Unop: {
 
1036
 
1008
1037
      /* 1Uto8(32to1(expr32)) */
1009
 
      DEFINE_PATTERN(p_32to1_then_1Uto8,
1010
 
                     unop(Iop_1Uto8,unop(Iop_32to1,bind(0))));
1011
 
      if (matchIRExpr(&mi,p_32to1_then_1Uto8,e)) {
1012
 
         IRExpr* expr32 = mi.bindee[0];
1013
 
         HReg dst = newVRegI(env);
1014
 
         HReg src = iselIntExpr_R(env, expr32);
1015
 
         addInstr(env, mk_iMOVsd_RR(src,dst) );
1016
 
         addInstr(env, X86Instr_Alu32R(Xalu_AND,
1017
 
                                       X86RMI_Imm(1), dst));
1018
 
         return dst;
 
1038
      if (e->Iex.Unop.op == Iop_1Uto8) { 
 
1039
         DECLARE_PATTERN(p_32to1_then_1Uto8);
 
1040
         DEFINE_PATTERN(p_32to1_then_1Uto8,
 
1041
                        unop(Iop_1Uto8,unop(Iop_32to1,bind(0))));
 
1042
         if (matchIRExpr(&mi,p_32to1_then_1Uto8,e)) {
 
1043
            IRExpr* expr32 = mi.bindee[0];
 
1044
            HReg dst = newVRegI(env);
 
1045
            HReg src = iselIntExpr_R(env, expr32);
 
1046
            addInstr(env, mk_iMOVsd_RR(src,dst) );
 
1047
            addInstr(env, X86Instr_Alu32R(Xalu_AND,
 
1048
                                          X86RMI_Imm(1), dst));
 
1049
            return dst;
 
1050
         }
 
1051
      }
 
1052
 
 
1053
      /* 8Uto32(LDle(expr32)) */
 
1054
      if (e->Iex.Unop.op == Iop_8Uto32) {
 
1055
         DECLARE_PATTERN(p_LDle8_then_8Uto32);
 
1056
         DEFINE_PATTERN(p_LDle8_then_8Uto32,
 
1057
                        unop(Iop_8Uto32,
 
1058
                             IRExpr_Load(Iend_LE,Ity_I8,bind(0))) );
 
1059
         if (matchIRExpr(&mi,p_LDle8_then_8Uto32,e)) {
 
1060
            HReg dst = newVRegI(env);
 
1061
            X86AMode* amode = iselIntExpr_AMode ( env, mi.bindee[0] );
 
1062
            addInstr(env, X86Instr_LoadEX(1,False,amode,dst));
 
1063
            return dst;
 
1064
         }
 
1065
      }
 
1066
 
 
1067
      /* 8Sto32(LDle(expr32)) */
 
1068
      if (e->Iex.Unop.op == Iop_8Sto32) {
 
1069
         DECLARE_PATTERN(p_LDle8_then_8Sto32);
 
1070
         DEFINE_PATTERN(p_LDle8_then_8Sto32,
 
1071
                        unop(Iop_8Sto32,
 
1072
                             IRExpr_Load(Iend_LE,Ity_I8,bind(0))) );
 
1073
         if (matchIRExpr(&mi,p_LDle8_then_8Sto32,e)) {
 
1074
            HReg dst = newVRegI(env);
 
1075
            X86AMode* amode = iselIntExpr_AMode ( env, mi.bindee[0] );
 
1076
            addInstr(env, X86Instr_LoadEX(1,True,amode,dst));
 
1077
            return dst;
 
1078
         }
1019
1079
      }
1020
1080
 
1021
1081
      /* 16Uto32(LDle(expr32)) */
1022
 
      {
 
1082
      if (e->Iex.Unop.op == Iop_16Uto32) {
1023
1083
         DECLARE_PATTERN(p_LDle16_then_16Uto32);
1024
1084
         DEFINE_PATTERN(p_LDle16_then_16Uto32,
1025
1085
                        unop(Iop_16Uto32,
1032
1092
         }
1033
1093
      }
1034
1094
 
 
1095
      /* 8Uto32(GET:I8) */
 
1096
      if (e->Iex.Unop.op == Iop_8Uto32) {
 
1097
         if (e->Iex.Unop.arg->tag == Iex_Get) {
 
1098
            HReg      dst;
 
1099
            X86AMode* amode;
 
1100
            vassert(e->Iex.Unop.arg->Iex.Get.ty == Ity_I8);
 
1101
            dst = newVRegI(env);
 
1102
            amode = X86AMode_IR(e->Iex.Unop.arg->Iex.Get.offset,
 
1103
                                hregX86_EBP());
 
1104
            addInstr(env, X86Instr_LoadEX(1,False,amode,dst));
 
1105
            return dst;
 
1106
         }
 
1107
      }
 
1108
 
 
1109
      /* 16to32(GET:I16) */
 
1110
      if (e->Iex.Unop.op == Iop_16Uto32) {
 
1111
         if (e->Iex.Unop.arg->tag == Iex_Get) {
 
1112
            HReg      dst;
 
1113
            X86AMode* amode;
 
1114
            vassert(e->Iex.Unop.arg->Iex.Get.ty == Ity_I16);
 
1115
            dst = newVRegI(env);
 
1116
            amode = X86AMode_IR(e->Iex.Unop.arg->Iex.Get.offset,
 
1117
                                hregX86_EBP());
 
1118
            addInstr(env, X86Instr_LoadEX(2,False,amode,dst));
 
1119
            return dst;
 
1120
         }
 
1121
      }
 
1122
 
1035
1123
      switch (e->Iex.Unop.op) {
1036
1124
         case Iop_8Uto16:
1037
1125
         case Iop_8Uto32:
1122
1210
                                          X86RMI_Reg(tmp), dst));
1123
1211
            return dst;
1124
1212
         }
1125
 
         case Iop_Neg8:
1126
 
         case Iop_Neg16:
1127
 
         case Iop_Neg32: {
 
1213
 
 
1214
         case Iop_CmpwNEZ32: {
1128
1215
            HReg dst = newVRegI(env);
1129
 
            HReg reg = iselIntExpr_R(env, e->Iex.Unop.arg);
1130
 
            addInstr(env, mk_iMOVsd_RR(reg,dst));
 
1216
            HReg src = iselIntExpr_R(env, e->Iex.Unop.arg);
 
1217
            addInstr(env, mk_iMOVsd_RR(src,dst));
1131
1218
            addInstr(env, X86Instr_Unary32(Xun_NEG,dst));
 
1219
            addInstr(env, X86Instr_Alu32R(Xalu_OR,
 
1220
                                          X86RMI_Reg(src), dst));
 
1221
            addInstr(env, X86Instr_Sh32(Xsh_SAR, 31, dst));
 
1222
            return dst;
 
1223
         }
 
1224
         case Iop_Left8:
 
1225
         case Iop_Left16:
 
1226
         case Iop_Left32: {
 
1227
            HReg dst = newVRegI(env);
 
1228
            HReg src = iselIntExpr_R(env, e->Iex.Unop.arg);
 
1229
            addInstr(env, mk_iMOVsd_RR(src, dst));
 
1230
            addInstr(env, X86Instr_Unary32(Xun_NEG, dst));
 
1231
            addInstr(env, X86Instr_Alu32R(Xalu_OR, X86RMI_Reg(src), dst));
1132
1232
            return dst;
1133
1233
         }
1134
1234
 
1143
1243
            return dst;
1144
1244
         }
1145
1245
 
 
1246
         /* ReinterpF32asI32(e) */
 
1247
         /* Given an IEEE754 single, produce an I32 with the same bit
 
1248
            pattern.  Keep stack 8-aligned even though only using 4
 
1249
            bytes. */
 
1250
         case Iop_ReinterpF32asI32: {
 
1251
            HReg rf   = iselFltExpr(env, e->Iex.Unop.arg);
 
1252
            HReg dst  = newVRegI(env);
 
1253
            X86AMode* zero_esp = X86AMode_IR(0, hregX86_ESP());
 
1254
            /* paranoia */
 
1255
            set_FPU_rounding_default(env);
 
1256
            /* subl $8, %esp */
 
1257
            sub_from_esp(env, 8);
 
1258
            /* gstF %rf, 0(%esp) */
 
1259
            addInstr(env,
 
1260
                     X86Instr_FpLdSt(False/*store*/, 4, rf, zero_esp));
 
1261
            /* movl 0(%esp), %dst */
 
1262
            addInstr(env, 
 
1263
                     X86Instr_Alu32R(Xalu_MOV, X86RMI_Mem(zero_esp), dst));
 
1264
            /* addl $8, %esp */
 
1265
            add_to_esp(env, 8);
 
1266
            return dst;
 
1267
         }
 
1268
 
1146
1269
         case Iop_16to8:
1147
1270
         case Iop_32to8:
1148
1271
         case Iop_32to16:
1225
1348
   case Iex_Mux0X: {
1226
1349
     if ((ty == Ity_I32 || ty == Ity_I16 || ty == Ity_I8)
1227
1350
         && typeOfIRExpr(env->type_env,e->Iex.Mux0X.cond) == Ity_I8) {
1228
 
        HReg r8;
1229
 
        HReg rX   = iselIntExpr_R(env, e->Iex.Mux0X.exprX);
1230
 
        X86RM* r0 = iselIntExpr_RM(env, e->Iex.Mux0X.expr0);
1231
 
        HReg dst = newVRegI(env);
 
1351
        X86RM* r8;
 
1352
        HReg   rX  = iselIntExpr_R(env, e->Iex.Mux0X.exprX);
 
1353
        X86RM* r0  = iselIntExpr_RM(env, e->Iex.Mux0X.expr0);
 
1354
        HReg   dst = newVRegI(env);
1232
1355
        addInstr(env, mk_iMOVsd_RR(rX,dst));
1233
 
        r8 = iselIntExpr_R(env, e->Iex.Mux0X.cond);
 
1356
        r8 = iselIntExpr_RM(env, e->Iex.Mux0X.cond);
1234
1357
        addInstr(env, X86Instr_Test32(0xFF, r8));
1235
1358
        addInstr(env, X86Instr_CMov32(Xcc_Z,r0,dst));
1236
1359
        return dst;
1292
1415
   IRType ty = typeOfIRExpr(env->type_env,e);
1293
1416
   vassert(ty == Ity_I32);
1294
1417
 
 
1418
   /* Add32( Add32(expr1, Shl32(expr2, simm)), imm32 ) */
 
1419
   if (e->tag == Iex_Binop
 
1420
       && e->Iex.Binop.op == Iop_Add32
 
1421
       && e->Iex.Binop.arg2->tag == Iex_Const
 
1422
       && e->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U32
 
1423
       && e->Iex.Binop.arg1->tag == Iex_Binop
 
1424
       && e->Iex.Binop.arg1->Iex.Binop.op == Iop_Add32
 
1425
       && e->Iex.Binop.arg1->Iex.Binop.arg2->tag == Iex_Binop
 
1426
       && e->Iex.Binop.arg1->Iex.Binop.arg2->Iex.Binop.op == Iop_Shl32
 
1427
       && e->Iex.Binop.arg1
 
1428
           ->Iex.Binop.arg2->Iex.Binop.arg2->tag == Iex_Const
 
1429
       && e->Iex.Binop.arg1
 
1430
           ->Iex.Binop.arg2->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U8) {
 
1431
      UInt shift = e->Iex.Binop.arg1
 
1432
                    ->Iex.Binop.arg2->Iex.Binop.arg2->Iex.Const.con->Ico.U8;
 
1433
      UInt imm32 = e->Iex.Binop.arg2->Iex.Const.con->Ico.U32;
 
1434
      if (shift == 1 || shift == 2 || shift == 3) {
 
1435
         HReg r1 = iselIntExpr_R(env, e->Iex.Binop.arg1->Iex.Binop.arg1);
 
1436
         HReg r2 = iselIntExpr_R(env, e->Iex.Binop.arg1
 
1437
                                       ->Iex.Binop.arg2->Iex.Binop.arg1 );
 
1438
         return X86AMode_IRRS(imm32, r1, r2, shift);
 
1439
      }
 
1440
   }
 
1441
 
1295
1442
   /* Add32(expr1, Shl32(expr2, imm)) */
1296
1443
   if (e->tag == Iex_Binop
1297
1444
       && e->Iex.Binop.op == Iop_Add32
1494
1641
static X86CondCode iselCondCode_wrk ( ISelEnv* env, IRExpr* e )
1495
1642
{
1496
1643
   MatchInfo mi;
1497
 
   DECLARE_PATTERN(p_32to1);
1498
 
   DECLARE_PATTERN(p_1Uto32_then_32to1);
1499
 
   DECLARE_PATTERN(p_1Sto32_then_32to1);
1500
1644
 
1501
1645
   vassert(e);
1502
1646
   vassert(typeOfIRExpr(env->type_env,e) == Ity_I1);
1503
1647
 
1504
1648
   /* var */
1505
 
   if (e->tag == Iex_Tmp) {
1506
 
      HReg r32 = lookupIRTemp(env, e->Iex.Tmp.tmp);
 
1649
   if (e->tag == Iex_RdTmp) {
 
1650
      HReg r32 = lookupIRTemp(env, e->Iex.RdTmp.tmp);
1507
1651
      /* Test32 doesn't modify r32; so this is OK. */
1508
 
      addInstr(env, X86Instr_Test32(1,r32));
 
1652
      addInstr(env, X86Instr_Test32(1,X86RM_Reg(r32)));
1509
1653
      return Xcc_NZ;
1510
1654
   }
1511
1655
 
1529
1673
 
1530
1674
   /* --- patterns rooted at: 32to1 --- */
1531
1675
 
1532
 
   /* 32to1(1Uto32(e)) ==> e */
1533
 
   DEFINE_PATTERN(p_1Uto32_then_32to1,
1534
 
                  unop(Iop_32to1,unop(Iop_1Uto32,bind(0))));
1535
 
   if (matchIRExpr(&mi,p_1Uto32_then_32to1,e)) {
1536
 
      IRExpr* expr1 = mi.bindee[0];
1537
 
      return iselCondCode(env, expr1);
1538
 
   }
1539
 
 
1540
 
   /* 32to1(1Sto32(e)) ==> e */
1541
 
   DEFINE_PATTERN(p_1Sto32_then_32to1,
1542
 
                  unop(Iop_32to1,unop(Iop_1Sto32,bind(0))));
1543
 
   if (matchIRExpr(&mi,p_1Sto32_then_32to1,e)) {
1544
 
      IRExpr* expr1 = mi.bindee[0];
1545
 
      return iselCondCode(env, expr1);
1546
 
   }
1547
 
 
1548
 
   /* 32to1(expr32) */
1549
 
   DEFINE_PATTERN(p_32to1, 
1550
 
                  unop(Iop_32to1,bind(0))
1551
 
   );
1552
 
   if (matchIRExpr(&mi,p_32to1,e)) {
1553
 
      HReg r = iselIntExpr_R(env, mi.bindee[0]);
1554
 
      addInstr(env, X86Instr_Test32(1,r));
 
1676
   if (e->tag == Iex_Unop
 
1677
       && e->Iex.Unop.op == Iop_32to1) {
 
1678
      X86RM* rm = iselIntExpr_RM(env, e->Iex.Unop.arg);
 
1679
      addInstr(env, X86Instr_Test32(1,rm));
1555
1680
      return Xcc_NZ;
1556
1681
   }
1557
1682
 
1560
1685
   /* CmpNEZ8(x) */
1561
1686
   if (e->tag == Iex_Unop 
1562
1687
       && e->Iex.Unop.op == Iop_CmpNEZ8) {
1563
 
      HReg r = iselIntExpr_R(env, e->Iex.Unop.arg);
1564
 
      addInstr(env, X86Instr_Test32(0xFF,r));
 
1688
      X86RM* rm = iselIntExpr_RM(env, e->Iex.Unop.arg);
 
1689
      addInstr(env, X86Instr_Test32(0xFF,rm));
1565
1690
      return Xcc_NZ;
1566
1691
   }
1567
1692
 
1570
1695
   /* CmpNEZ16(x) */
1571
1696
   if (e->tag == Iex_Unop 
1572
1697
       && e->Iex.Unop.op == Iop_CmpNEZ16) {
1573
 
      HReg r = iselIntExpr_R(env, e->Iex.Unop.arg);
1574
 
      addInstr(env, X86Instr_Test32(0xFFFF,r));
 
1698
      X86RM* rm = iselIntExpr_RM(env, e->Iex.Unop.arg);
 
1699
      addInstr(env, X86Instr_Test32(0xFFFF,rm));
1575
1700
      return Xcc_NZ;
1576
1701
   }
1577
1702
 
1578
1703
   /* --- patterns rooted at: CmpNEZ32 --- */
1579
1704
 
1580
 
   /* CmpNEZ32(1Sto32(b)) ==> b */
1581
 
   {
1582
 
      DECLARE_PATTERN(p_CmpNEZ32_1Sto32);
1583
 
      DEFINE_PATTERN(p_CmpNEZ32_1Sto32,
1584
 
                     unop(Iop_CmpNEZ32, unop(Iop_1Sto32,bind(0))));
1585
 
      if (matchIRExpr(&mi, p_CmpNEZ32_1Sto32, e)) {
1586
 
         return iselCondCode(env, mi.bindee[0]);
1587
 
      }
1588
 
   }
1589
 
 
1590
1705
   /* CmpNEZ32(And32(x,y)) */
1591
1706
   {
1592
1707
      DECLARE_PATTERN(p_CmpNEZ32_And32);
1617
1732
      }
1618
1733
   }
1619
1734
 
 
1735
   /* CmpNEZ32(GET(..):I32) */
 
1736
   if (e->tag == Iex_Unop 
 
1737
       && e->Iex.Unop.op == Iop_CmpNEZ32
 
1738
       && e->Iex.Unop.arg->tag == Iex_Get) {
 
1739
      X86AMode* am = X86AMode_IR(e->Iex.Unop.arg->Iex.Get.offset, 
 
1740
                                 hregX86_EBP());
 
1741
      addInstr(env, X86Instr_Alu32M(Xalu_CMP, X86RI_Imm(0), am));
 
1742
      return Xcc_NZ;
 
1743
   }
 
1744
 
1620
1745
   /* CmpNEZ32(x) */
1621
1746
   if (e->tag == Iex_Unop 
1622
1747
       && e->Iex.Unop.op == Iop_CmpNEZ32) {
1628
1753
 
1629
1754
   /* --- patterns rooted at: CmpNEZ64 --- */
1630
1755
 
1631
 
   /* CmpNEZ64(1Sto64(b)) ==> b */
1632
 
   {
1633
 
      DECLARE_PATTERN(p_CmpNEZ64_1Sto64);
1634
 
      DEFINE_PATTERN(
1635
 
         p_CmpNEZ64_1Sto64,
1636
 
         unop(Iop_CmpNEZ64, unop(Iop_1Sto64,bind(0))));
1637
 
      if (matchIRExpr(&mi, p_CmpNEZ64_1Sto64, e)) {
1638
 
         return iselCondCode(env, mi.bindee[0]);
1639
 
      }
1640
 
   }
1641
 
 
1642
1756
   /* CmpNEZ64(Or64(x,y)) */
1643
1757
   {
1644
1758
      DECLARE_PATTERN(p_CmpNEZ64_Or64);
1674
1788
   if (e->tag == Iex_Binop 
1675
1789
       && (e->Iex.Binop.op == Iop_CmpEQ8
1676
1790
           || e->Iex.Binop.op == Iop_CmpNE8)) {
1677
 
      HReg    r1   = iselIntExpr_R(env, e->Iex.Binop.arg1);
1678
 
      X86RMI* rmi2 = iselIntExpr_RMI(env, e->Iex.Binop.arg2);
1679
 
      HReg    r    = newVRegI(env);
1680
 
      addInstr(env, mk_iMOVsd_RR(r1,r));
1681
 
      addInstr(env, X86Instr_Alu32R(Xalu_XOR,rmi2,r));
1682
 
      addInstr(env, X86Instr_Test32(0xFF,r));
1683
 
      switch (e->Iex.Binop.op) {
1684
 
         case Iop_CmpEQ8:  return Xcc_Z;
1685
 
         case Iop_CmpNE8:  return Xcc_NZ;
1686
 
         default: vpanic("iselCondCode(x86): CmpXX8");
 
1791
      if (isZeroU8(e->Iex.Binop.arg2)) {
 
1792
         HReg    r1   = iselIntExpr_R(env, e->Iex.Binop.arg1);
 
1793
         addInstr(env, X86Instr_Test32(0xFF,X86RM_Reg(r1)));
 
1794
         switch (e->Iex.Binop.op) {
 
1795
            case Iop_CmpEQ8:  return Xcc_Z;
 
1796
            case Iop_CmpNE8:  return Xcc_NZ;
 
1797
            default: vpanic("iselCondCode(x86): CmpXX8(expr,0:I8)");
 
1798
         }
 
1799
      } else {
 
1800
         HReg    r1   = iselIntExpr_R(env, e->Iex.Binop.arg1);
 
1801
         X86RMI* rmi2 = iselIntExpr_RMI(env, e->Iex.Binop.arg2);
 
1802
         HReg    r    = newVRegI(env);
 
1803
         addInstr(env, mk_iMOVsd_RR(r1,r));
 
1804
         addInstr(env, X86Instr_Alu32R(Xalu_XOR,rmi2,r));
 
1805
         addInstr(env, X86Instr_Test32(0xFF,X86RM_Reg(r)));
 
1806
         switch (e->Iex.Binop.op) {
 
1807
            case Iop_CmpEQ8:  return Xcc_Z;
 
1808
            case Iop_CmpNE8:  return Xcc_NZ;
 
1809
            default: vpanic("iselCondCode(x86): CmpXX8(expr,expr)");
 
1810
         }
1687
1811
      }
1688
1812
   }
1689
1813
 
1696
1820
      HReg    r    = newVRegI(env);
1697
1821
      addInstr(env, mk_iMOVsd_RR(r1,r));
1698
1822
      addInstr(env, X86Instr_Alu32R(Xalu_XOR,rmi2,r));
1699
 
      addInstr(env, X86Instr_Test32(0xFFFF,r));
 
1823
      addInstr(env, X86Instr_Test32(0xFFFF,X86RM_Reg(r)));
1700
1824
      switch (e->Iex.Binop.op) {
1701
1825
         case Iop_CmpEQ16:  return Xcc_Z;
1702
1826
         case Iop_CmpNE16:  return Xcc_NZ;
1776
1900
/* DO NOT CALL THIS DIRECTLY ! */
1777
1901
static void iselInt64Expr_wrk ( HReg* rHi, HReg* rLo, ISelEnv* env, IRExpr* e )
1778
1902
{
 
1903
   MatchInfo mi;
1779
1904
   HWord fn = 0; /* helper fn for most SIMD64 stuff */
1780
1905
   vassert(e);
1781
1906
   vassert(typeOfIRExpr(env->type_env,e) == Ity_I64);
1803
1928
   }
1804
1929
 
1805
1930
   /* read 64-bit IRTemp */
1806
 
   if (e->tag == Iex_Tmp) {
1807
 
      lookupIRTemp64( rHi, rLo, env, e->Iex.Tmp.tmp);
 
1931
   if (e->tag == Iex_RdTmp) {
 
1932
      lookupIRTemp64( rHi, rLo, env, e->Iex.RdTmp.tmp);
1808
1933
      return;
1809
1934
   }
1810
1935
 
1852
1977
      return;
1853
1978
   }
1854
1979
 
1855
 
   /* 64-bit Mux0X */
 
1980
   /* 64-bit Mux0X: Mux0X(g, expr, 0:I64) */
 
1981
   if (e->tag == Iex_Mux0X && isZeroU64(e->Iex.Mux0X.exprX)) {
 
1982
      X86RM* r8;
 
1983
      HReg e0Lo, e0Hi;
 
1984
      HReg tLo = newVRegI(env);
 
1985
      HReg tHi = newVRegI(env);
 
1986
      X86AMode* zero_esp = X86AMode_IR(0, hregX86_ESP());
 
1987
      iselInt64Expr(&e0Hi, &e0Lo, env, e->Iex.Mux0X.expr0);
 
1988
      r8 = iselIntExpr_RM(env, e->Iex.Mux0X.cond);
 
1989
      addInstr(env, mk_iMOVsd_RR( e0Hi, tHi ) );
 
1990
      addInstr(env, mk_iMOVsd_RR( e0Lo, tLo ) );
 
1991
      addInstr(env, X86Instr_Push(X86RMI_Imm(0)));
 
1992
      addInstr(env, X86Instr_Test32(0xFF, r8));
 
1993
      addInstr(env, X86Instr_CMov32(Xcc_NZ,X86RM_Mem(zero_esp),tHi));
 
1994
      addInstr(env, X86Instr_CMov32(Xcc_NZ,X86RM_Mem(zero_esp),tLo));
 
1995
      add_to_esp(env, 4);
 
1996
      *rHi = tHi;
 
1997
      *rLo = tLo;
 
1998
      return;
 
1999
   }
 
2000
   /* 64-bit Mux0X: Mux0X(g, 0:I64, expr) */
 
2001
   if (e->tag == Iex_Mux0X && isZeroU64(e->Iex.Mux0X.expr0)) {
 
2002
      X86RM* r8;
 
2003
      HReg e0Lo, e0Hi;
 
2004
      HReg tLo = newVRegI(env);
 
2005
      HReg tHi = newVRegI(env);
 
2006
      X86AMode* zero_esp = X86AMode_IR(0, hregX86_ESP());
 
2007
      iselInt64Expr(&e0Hi, &e0Lo, env, e->Iex.Mux0X.exprX);
 
2008
      r8 = iselIntExpr_RM(env, e->Iex.Mux0X.cond);
 
2009
      addInstr(env, mk_iMOVsd_RR( e0Hi, tHi ) );
 
2010
      addInstr(env, mk_iMOVsd_RR( e0Lo, tLo ) );
 
2011
      addInstr(env, X86Instr_Push(X86RMI_Imm(0)));
 
2012
      addInstr(env, X86Instr_Test32(0xFF, r8));
 
2013
      addInstr(env, X86Instr_CMov32(Xcc_Z,X86RM_Mem(zero_esp),tHi));
 
2014
      addInstr(env, X86Instr_CMov32(Xcc_Z,X86RM_Mem(zero_esp),tLo));
 
2015
      add_to_esp(env, 4);
 
2016
      *rHi = tHi;
 
2017
      *rLo = tLo;
 
2018
      return;
 
2019
   }
 
2020
 
 
2021
   /* 64-bit Mux0X: Mux0X(g, expr, expr) */
1856
2022
   if (e->tag == Iex_Mux0X) {
1857
 
      HReg e0Lo, e0Hi, eXLo, eXHi, r8;
 
2023
      X86RM* r8;
 
2024
      HReg e0Lo, e0Hi, eXLo, eXHi;
1858
2025
      HReg tLo = newVRegI(env);
1859
2026
      HReg tHi = newVRegI(env);
1860
2027
      iselInt64Expr(&e0Hi, &e0Lo, env, e->Iex.Mux0X.expr0);
1861
2028
      iselInt64Expr(&eXHi, &eXLo, env, e->Iex.Mux0X.exprX);
1862
2029
      addInstr(env, mk_iMOVsd_RR(eXHi, tHi));
1863
2030
      addInstr(env, mk_iMOVsd_RR(eXLo, tLo));
1864
 
      r8 = iselIntExpr_R(env, e->Iex.Mux0X.cond);
 
2031
      r8 = iselIntExpr_RM(env, e->Iex.Mux0X.cond);
1865
2032
      addInstr(env, X86Instr_Test32(0xFF, r8));
1866
2033
      /* This assumes the first cmov32 doesn't trash the condition
1867
2034
         codes, so they are still available for the second cmov32 */
1928
2095
                          : e->Iex.Binop.op==Iop_And64 ? Xalu_AND
1929
2096
                          : Xalu_XOR;
1930
2097
            iselInt64Expr(&xHi, &xLo, env, e->Iex.Binop.arg1);
 
2098
            iselInt64Expr(&yHi, &yLo, env, e->Iex.Binop.arg2);
1931
2099
            addInstr(env, mk_iMOVsd_RR(xHi, tHi));
1932
 
            addInstr(env, mk_iMOVsd_RR(xLo, tLo));
1933
 
            iselInt64Expr(&yHi, &yLo, env, e->Iex.Binop.arg2);
1934
2100
            addInstr(env, X86Instr_Alu32R(op, X86RMI_Reg(yHi), tHi));
 
2101
            addInstr(env, mk_iMOVsd_RR(xLo, tLo));
1935
2102
            addInstr(env, X86Instr_Alu32R(op, X86RMI_Reg(yLo), tLo));
1936
2103
            *rHi = tHi;
1937
2104
            *rLo = tLo;
1940
2107
 
1941
2108
         /* Add64/Sub64 */
1942
2109
         case Iop_Add64:
 
2110
            if (e->Iex.Binop.arg2->tag == Iex_Const) {
 
2111
               /* special case Add64(e, const) */
 
2112
               ULong w64 = e->Iex.Binop.arg2->Iex.Const.con->Ico.U64;
 
2113
               UInt  wHi = toUInt(w64 >> 32);
 
2114
               UInt  wLo = toUInt(w64);
 
2115
               HReg  tLo = newVRegI(env);
 
2116
               HReg  tHi = newVRegI(env);
 
2117
               HReg  xLo, xHi;
 
2118
               vassert(e->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U64);
 
2119
               iselInt64Expr(&xHi, &xLo, env, e->Iex.Binop.arg1);
 
2120
               addInstr(env, mk_iMOVsd_RR(xHi, tHi));
 
2121
               addInstr(env, mk_iMOVsd_RR(xLo, tLo));
 
2122
               addInstr(env, X86Instr_Alu32R(Xalu_ADD, X86RMI_Imm(wLo), tLo));
 
2123
               addInstr(env, X86Instr_Alu32R(Xalu_ADC, X86RMI_Imm(wHi), tHi));
 
2124
               *rHi = tHi;
 
2125
               *rLo = tLo;
 
2126
               return;
 
2127
            }
 
2128
            /* else fall through to the generic case */
1943
2129
         case Iop_Sub64: {
1944
2130
            HReg xLo, xHi, yLo, yHi;
1945
2131
            HReg tLo = newVRegI(env);
2000
2186
               and those regs are legitimately modifiable. */
2001
2187
            addInstr(env, X86Instr_Sh3232(Xsh_SHL, 0/*%cl*/, tLo, tHi));
2002
2188
            addInstr(env, X86Instr_Sh32(Xsh_SHL, 0/*%cl*/, tLo));
2003
 
            addInstr(env, X86Instr_Test32(32, hregX86_ECX()));
 
2189
            addInstr(env, X86Instr_Test32(32, X86RM_Reg(hregX86_ECX())));
2004
2190
            addInstr(env, X86Instr_CMov32(Xcc_NZ, X86RM_Reg(tLo), tHi));
2005
2191
            addInstr(env, X86Instr_Alu32R(Xalu_MOV, X86RMI_Imm(0), tTemp));
2006
2192
            addInstr(env, X86Instr_CMov32(Xcc_NZ, X86RM_Reg(tTemp), tLo));
2042
2228
               and those regs are legitimately modifiable. */
2043
2229
            addInstr(env, X86Instr_Sh3232(Xsh_SHR, 0/*%cl*/, tHi, tLo));
2044
2230
            addInstr(env, X86Instr_Sh32(Xsh_SHR, 0/*%cl*/, tHi));
2045
 
            addInstr(env, X86Instr_Test32(32, hregX86_ECX()));
 
2231
            addInstr(env, X86Instr_Test32(32, X86RM_Reg(hregX86_ECX())));
2046
2232
            addInstr(env, X86Instr_CMov32(Xcc_NZ, X86RM_Reg(tHi), tLo));
2047
2233
            addInstr(env, X86Instr_Alu32R(Xalu_MOV, X86RMI_Imm(0), tTemp));
2048
2234
            addInstr(env, X86Instr_CMov32(Xcc_NZ, X86RM_Reg(tTemp), tHi));
2138
2324
            fn = (HWord)h_generic_calc_InterleaveHI32x2; goto binnish;
2139
2325
         case Iop_InterleaveLO32x2:
2140
2326
            fn = (HWord)h_generic_calc_InterleaveLO32x2; goto binnish;
 
2327
         case Iop_CatOddLanes16x4:
 
2328
            fn = (HWord)h_generic_calc_CatOddLanes16x4; goto binnish;
 
2329
         case Iop_CatEvenLanes16x4:
 
2330
            fn = (HWord)h_generic_calc_CatEvenLanes16x4; goto binnish;
 
2331
         case Iop_Perm8x8:
 
2332
            fn = (HWord)h_generic_calc_Perm8x8; goto binnish;
2141
2333
 
2142
2334
         case Iop_Max8Ux8:
2143
2335
            fn = (HWord)h_generic_calc_Max8Ux8; goto binnish;
2150
2342
 
2151
2343
         case Iop_Mul16x4:
2152
2344
            fn = (HWord)h_generic_calc_Mul16x4; goto binnish;
 
2345
         case Iop_Mul32x2:
 
2346
            fn = (HWord)h_generic_calc_Mul32x2; goto binnish;
2153
2347
         case Iop_MulHi16Sx4:
2154
2348
            fn = (HWord)h_generic_calc_MulHi16Sx4; goto binnish;
2155
2349
         case Iop_MulHi16Ux4:
2215
2409
            fn = (HWord)h_generic_calc_ShlN32x2; goto shifty;
2216
2410
         case Iop_ShlN16x4:
2217
2411
            fn = (HWord)h_generic_calc_ShlN16x4; goto shifty;
 
2412
         case Iop_ShlN8x8:
 
2413
            fn = (HWord)h_generic_calc_ShlN8x8;  goto shifty;
2218
2414
         case Iop_ShrN32x2:
2219
2415
            fn = (HWord)h_generic_calc_ShrN32x2; goto shifty;
2220
2416
         case Iop_ShrN16x4:
2223
2419
            fn = (HWord)h_generic_calc_SarN32x2; goto shifty;
2224
2420
         case Iop_SarN16x4:
2225
2421
            fn = (HWord)h_generic_calc_SarN16x4; goto shifty;
 
2422
         case Iop_SarN8x8:
 
2423
            fn = (HWord)h_generic_calc_SarN8x8;  goto shifty;
2226
2424
         shifty: {
2227
2425
            /* Note: the following assumes all helpers are of
2228
2426
               signature 
2332
2530
            return;
2333
2531
         }
2334
2532
 
2335
 
         /* Neg64(e) */
2336
 
         case Iop_Neg64: {
 
2533
         /* Left64(e) */
 
2534
         case Iop_Left64: {
2337
2535
            HReg yLo, yHi;
2338
2536
            HReg tLo = newVRegI(env);
2339
2537
            HReg tHi = newVRegI(env);
2345
2543
            /* tHi = 0 - yHi - carry */
2346
2544
            addInstr(env, X86Instr_Alu32R(Xalu_MOV, X86RMI_Imm(0), tHi));
2347
2545
            addInstr(env, X86Instr_Alu32R(Xalu_SBB, X86RMI_Reg(yHi), tHi));
 
2546
            /* So now we have tHi:tLo = -arg.  To finish off, or 'arg'
 
2547
               back in, so as to give the final result 
 
2548
               tHi:tLo = arg | -arg. */
 
2549
            addInstr(env, X86Instr_Alu32R(Xalu_OR, X86RMI_Reg(yLo), tLo));
 
2550
            addInstr(env, X86Instr_Alu32R(Xalu_OR, X86RMI_Reg(yHi), tHi));
2348
2551
            *rHi = tHi;
2349
2552
            *rLo = tLo;
2350
2553
            return;
2351
2554
         }
2352
2555
 
 
2556
         /* --- patterns rooted at: CmpwNEZ64 --- */
 
2557
 
 
2558
         /* CmpwNEZ64(e) */
 
2559
         case Iop_CmpwNEZ64: {
 
2560
 
 
2561
         DECLARE_PATTERN(p_CmpwNEZ64_Or64);
 
2562
         DEFINE_PATTERN(p_CmpwNEZ64_Or64,
 
2563
                        unop(Iop_CmpwNEZ64,binop(Iop_Or64,bind(0),bind(1))));
 
2564
         if (matchIRExpr(&mi, p_CmpwNEZ64_Or64, e)) {
 
2565
            /* CmpwNEZ64(Or64(x,y)) */
 
2566
            HReg xHi,xLo,yHi,yLo;
 
2567
            HReg xBoth = newVRegI(env);
 
2568
            HReg merged = newVRegI(env);
 
2569
            HReg tmp2 = newVRegI(env);
 
2570
 
 
2571
            iselInt64Expr(&xHi,&xLo, env, mi.bindee[0]);
 
2572
            addInstr(env, mk_iMOVsd_RR(xHi,xBoth));
 
2573
            addInstr(env, X86Instr_Alu32R(Xalu_OR,
 
2574
                                          X86RMI_Reg(xLo),xBoth));
 
2575
 
 
2576
            iselInt64Expr(&yHi,&yLo, env, mi.bindee[1]);
 
2577
            addInstr(env, mk_iMOVsd_RR(yHi,merged));
 
2578
            addInstr(env, X86Instr_Alu32R(Xalu_OR,
 
2579
                                          X86RMI_Reg(yLo),merged));
 
2580
            addInstr(env, X86Instr_Alu32R(Xalu_OR,
 
2581
                                             X86RMI_Reg(xBoth),merged));
 
2582
 
 
2583
            /* tmp2 = (merged | -merged) >>s 31 */
 
2584
            addInstr(env, mk_iMOVsd_RR(merged,tmp2));
 
2585
            addInstr(env, X86Instr_Unary32(Xun_NEG,tmp2));
 
2586
            addInstr(env, X86Instr_Alu32R(Xalu_OR,
 
2587
                                          X86RMI_Reg(merged), tmp2));
 
2588
            addInstr(env, X86Instr_Sh32(Xsh_SAR, 31, tmp2));
 
2589
            *rHi = tmp2;
 
2590
            *rLo = tmp2;
 
2591
            return;
 
2592
         } else {
 
2593
            /* CmpwNEZ64(e) */
 
2594
            HReg srcLo, srcHi;
 
2595
            HReg tmp1  = newVRegI(env);
 
2596
            HReg tmp2  = newVRegI(env);
 
2597
            /* srcHi:srcLo = arg */
 
2598
            iselInt64Expr(&srcHi, &srcLo, env, e->Iex.Unop.arg);
 
2599
            /* tmp1 = srcHi | srcLo */
 
2600
            addInstr(env, mk_iMOVsd_RR(srcHi,tmp1));
 
2601
            addInstr(env, X86Instr_Alu32R(Xalu_OR,
 
2602
                                          X86RMI_Reg(srcLo), tmp1));
 
2603
            /* tmp2 = (tmp1 | -tmp1) >>s 31 */
 
2604
            addInstr(env, mk_iMOVsd_RR(tmp1,tmp2));
 
2605
            addInstr(env, X86Instr_Unary32(Xun_NEG,tmp2));
 
2606
            addInstr(env, X86Instr_Alu32R(Xalu_OR,
 
2607
                                          X86RMI_Reg(tmp1), tmp2));
 
2608
            addInstr(env, X86Instr_Sh32(Xsh_SAR, 31, tmp2));
 
2609
            *rHi = tmp2;
 
2610
            *rLo = tmp2;
 
2611
            return;
 
2612
         }
 
2613
         }
 
2614
 
2353
2615
         /* ReinterpF64asI64(e) */
2354
2616
         /* Given an IEEE754 double, produce an I64 with the same bit
2355
2617
            pattern. */
2456
2718
   IRType ty = typeOfIRExpr(env->type_env,e);
2457
2719
   vassert(ty == Ity_F32);
2458
2720
 
2459
 
   if (e->tag == Iex_Tmp) {
2460
 
      return lookupIRTemp(env, e->Iex.Tmp.tmp);
 
2721
   if (e->tag == Iex_RdTmp) {
 
2722
      return lookupIRTemp(env, e->Iex.RdTmp.tmp);
2461
2723
   }
2462
2724
 
2463
2725
   if (e->tag == Iex_Load && e->Iex.Load.end == Iend_LE) {
2555
2817
   vassert(e);
2556
2818
   vassert(ty == Ity_F64);
2557
2819
 
2558
 
   if (e->tag == Iex_Tmp) {
2559
 
      return lookupIRTemp(env, e->Iex.Tmp.tmp);
 
2820
   if (e->tag == Iex_RdTmp) {
 
2821
      return lookupIRTemp(env, e->Iex.RdTmp.tmp);
2560
2822
   }
2561
2823
 
2562
2824
   if (e->tag == Iex_Const) {
2763
3025
   if (e->tag == Iex_Mux0X) {
2764
3026
     if (ty == Ity_F64
2765
3027
         && typeOfIRExpr(env->type_env,e->Iex.Mux0X.cond) == Ity_I8) {
2766
 
        HReg r8  = iselIntExpr_R(env, e->Iex.Mux0X.cond);
 
3028
        X86RM* r8 = iselIntExpr_RM(env, e->Iex.Mux0X.cond);
2767
3029
        HReg rX  = iselDblExpr(env, e->Iex.Mux0X.exprX);
2768
3030
        HReg r0  = iselDblExpr(env, e->Iex.Mux0X.expr0);
2769
3031
        HReg dst = newVRegF(env);
2821
3083
 
2822
3084
   REQUIRE_SSE1;
2823
3085
 
2824
 
   if (e->tag == Iex_Tmp) {
2825
 
      return lookupIRTemp(env, e->Iex.Tmp.tmp);
 
3086
   if (e->tag == Iex_RdTmp) {
 
3087
      return lookupIRTemp(env, e->Iex.RdTmp.tmp);
2826
3088
   }
2827
3089
 
2828
3090
   if (e->tag == Iex_Get) {
3284
3546
   } /* if (e->tag == Iex_Binop) */
3285
3547
 
3286
3548
   if (e->tag == Iex_Mux0X) {
3287
 
      HReg r8  = iselIntExpr_R(env, e->Iex.Mux0X.cond);
 
3549
      X86RM* r8 = iselIntExpr_RM(env, e->Iex.Mux0X.cond);
3288
3550
      HReg rX  = iselVecExpr(env, e->Iex.Mux0X.exprX);
3289
3551
      HReg r0  = iselVecExpr(env, e->Iex.Mux0X.expr0);
3290
3552
      HReg dst = newVRegV(env);
3322
3584
 
3323
3585
   /* --------- STORE --------- */
3324
3586
   case Ist_Store: {
3325
 
      X86AMode* am;
3326
3587
      IRType    tya = typeOfIRExpr(env->type_env, stmt->Ist.Store.addr);
3327
3588
      IRType    tyd = typeOfIRExpr(env->type_env, stmt->Ist.Store.data);
3328
3589
      IREndness end = stmt->Ist.Store.end;
3330
3591
      if (tya != Ity_I32 || end != Iend_LE) 
3331
3592
         goto stmt_fail;
3332
3593
 
3333
 
      am = iselIntExpr_AMode(env, stmt->Ist.Store.addr);
3334
3594
      if (tyd == Ity_I32) {
 
3595
         X86AMode* am = iselIntExpr_AMode(env, stmt->Ist.Store.addr);
3335
3596
         X86RI* ri = iselIntExpr_RI(env, stmt->Ist.Store.data);
3336
3597
         addInstr(env, X86Instr_Alu32M(Xalu_MOV,ri,am));
3337
3598
         return;
3338
3599
      }
3339
3600
      if (tyd == Ity_I8 || tyd == Ity_I16) {
 
3601
         X86AMode* am = iselIntExpr_AMode(env, stmt->Ist.Store.addr);
3340
3602
         HReg r = iselIntExpr_R(env, stmt->Ist.Store.data);
3341
3603
         addInstr(env, X86Instr_Store( toUChar(tyd==Ity_I8 ? 1 : 2),
3342
3604
                                       r,am ));
3343
3605
         return;
3344
3606
      }
3345
3607
      if (tyd == Ity_F64) {
 
3608
         X86AMode* am = iselIntExpr_AMode(env, stmt->Ist.Store.addr);
3346
3609
         HReg r = iselDblExpr(env, stmt->Ist.Store.data);
3347
3610
         addInstr(env, X86Instr_FpLdSt(False/*store*/, 8, r, am));
3348
3611
         return;
3349
3612
      }
3350
3613
      if (tyd == Ity_F32) {
 
3614
         X86AMode* am = iselIntExpr_AMode(env, stmt->Ist.Store.addr);
3351
3615
         HReg r = iselFltExpr(env, stmt->Ist.Store.data);
3352
3616
         addInstr(env, X86Instr_FpLdSt(False/*store*/, 4, r, am));
3353
3617
         return;
3363
3627
         return;
3364
3628
      }
3365
3629
      if (tyd == Ity_V128) {
 
3630
         X86AMode* am = iselIntExpr_AMode(env, stmt->Ist.Store.addr);
3366
3631
         HReg r = iselVecExpr(env, stmt->Ist.Store.data);
3367
3632
         addInstr(env, X86Instr_SseLdSt(False/*store*/, r, am));
3368
3633
         return;
3461
3726
   }
3462
3727
 
3463
3728
   /* --------- TMP --------- */
3464
 
   case Ist_Tmp: {
3465
 
      IRTemp tmp = stmt->Ist.Tmp.tmp;
 
3729
   case Ist_WrTmp: {
 
3730
      IRTemp tmp = stmt->Ist.WrTmp.tmp;
3466
3731
      IRType ty = typeOfIRTemp(env->type_env, tmp);
 
3732
 
 
3733
      /* optimisation: if stmt->Ist.WrTmp.data is Add32(..,..),
 
3734
         compute it into an AMode and then use LEA.  This usually
 
3735
         produces fewer instructions, often because (for memcheck
 
3736
         created IR) we get t = address-expression, (t is later used
 
3737
         twice) and so doing this naturally turns address-expression
 
3738
         back into an X86 amode. */
 
3739
      if (ty == Ity_I32 
 
3740
          && stmt->Ist.WrTmp.data->tag == Iex_Binop
 
3741
          && stmt->Ist.WrTmp.data->Iex.Binop.op == Iop_Add32) {
 
3742
         X86AMode* am = iselIntExpr_AMode(env, stmt->Ist.WrTmp.data);
 
3743
         HReg dst = lookupIRTemp(env, tmp);
 
3744
         if (am->tag == Xam_IR && am->Xam.IR.imm == 0) {
 
3745
            /* Hmm, iselIntExpr_AMode wimped out and just computed the
 
3746
               value into a register.  Just emit a normal reg-reg move
 
3747
               so reg-alloc can coalesce it away in the usual way. */
 
3748
            HReg src = am->Xam.IR.reg;
 
3749
            addInstr(env, X86Instr_Alu32R(Xalu_MOV, X86RMI_Reg(src), dst));
 
3750
         } else {
 
3751
            addInstr(env, X86Instr_Lea32(am,dst));
 
3752
         }
 
3753
         return;
 
3754
      }
 
3755
 
3467
3756
      if (ty == Ity_I32 || ty == Ity_I16 || ty == Ity_I8) {
3468
 
         X86RMI* rmi = iselIntExpr_RMI(env, stmt->Ist.Tmp.data);
 
3757
         X86RMI* rmi = iselIntExpr_RMI(env, stmt->Ist.WrTmp.data);
3469
3758
         HReg dst = lookupIRTemp(env, tmp);
3470
3759
         addInstr(env, X86Instr_Alu32R(Xalu_MOV,rmi,dst));
3471
3760
         return;
3472
3761
      }
3473
3762
      if (ty == Ity_I64) {
3474
3763
         HReg rHi, rLo, dstHi, dstLo;
3475
 
         iselInt64Expr(&rHi,&rLo, env, stmt->Ist.Tmp.data);
 
3764
         iselInt64Expr(&rHi,&rLo, env, stmt->Ist.WrTmp.data);
3476
3765
         lookupIRTemp64( &dstHi, &dstLo, env, tmp);
3477
3766
         addInstr(env, mk_iMOVsd_RR(rHi,dstHi) );
3478
3767
         addInstr(env, mk_iMOVsd_RR(rLo,dstLo) );
3479
3768
         return;
3480
3769
      }
3481
3770
      if (ty == Ity_I1) {
3482
 
         X86CondCode cond = iselCondCode(env, stmt->Ist.Tmp.data);
 
3771
         X86CondCode cond = iselCondCode(env, stmt->Ist.WrTmp.data);
3483
3772
         HReg dst = lookupIRTemp(env, tmp);
3484
3773
         addInstr(env, X86Instr_Set32(cond, dst));
3485
3774
         return;
3486
3775
      }
3487
3776
      if (ty == Ity_F64) {
3488
3777
         HReg dst = lookupIRTemp(env, tmp);
3489
 
         HReg src = iselDblExpr(env, stmt->Ist.Tmp.data);
 
3778
         HReg src = iselDblExpr(env, stmt->Ist.WrTmp.data);
3490
3779
         addInstr(env, X86Instr_FpUnary(Xfp_MOV,src,dst));
3491
3780
         return;
3492
3781
      }
3493
3782
      if (ty == Ity_F32) {
3494
3783
         HReg dst = lookupIRTemp(env, tmp);
3495
 
         HReg src = iselFltExpr(env, stmt->Ist.Tmp.data);
 
3784
         HReg src = iselFltExpr(env, stmt->Ist.WrTmp.data);
3496
3785
         addInstr(env, X86Instr_FpUnary(Xfp_MOV,src,dst));
3497
3786
         return;
3498
3787
      }
3499
3788
      if (ty == Ity_V128) {
3500
3789
         HReg dst = lookupIRTemp(env, tmp);
3501
 
         HReg src = iselVecExpr(env, stmt->Ist.Tmp.data);
 
3790
         HReg src = iselVecExpr(env, stmt->Ist.WrTmp.data);
3502
3791
         addInstr(env, mk_vMOVsd_RR(src,dst));
3503
3792
         return;
3504
3793
      }
3545
3834
   }
3546
3835
 
3547
3836
   /* --------- MEM FENCE --------- */
3548
 
   case Ist_MFence:
3549
 
      addInstr(env, X86Instr_MFence(env->hwcaps));
3550
 
      return;
 
3837
   case Ist_MBE:
 
3838
      switch (stmt->Ist.MBE.event) {
 
3839
         case Imbe_Fence:
 
3840
            addInstr(env, X86Instr_MFence(env->hwcaps));
 
3841
            return;
 
3842
         case Imbe_BusLock:
 
3843
         case Imbe_BusUnlock:
 
3844
            return;
 
3845
         default:
 
3846
            break;
 
3847
      }
 
3848
      break;
3551
3849
 
3552
3850
   /* --------- INSTR MARK --------- */
3553
3851
   /* Doesn't generate any executable code ... */
3602
3900
/*--- Insn selector top-level                           ---*/
3603
3901
/*---------------------------------------------------------*/
3604
3902
 
3605
 
/* Translate an entire BB to x86 code. */
 
3903
/* Translate an entire SB to x86 code. */
3606
3904
 
3607
 
HInstrArray* iselBB_X86 ( IRBB* bb, VexArch arch_host,
3608
 
                                    VexArchInfo* archinfo_host )
 
3905
HInstrArray* iselSB_X86 ( IRSB* bb, VexArch      arch_host,
 
3906
                                    VexArchInfo* archinfo_host,
 
3907
                                    VexAbiInfo*  vbi/*UNUSED*/ )
3609
3908
{
3610
3909
   Int      i, j;
3611
3910
   HReg     hreg, hregHI;