Coverage for /Syzygy/block_graph/basic_block_assembler_unittest.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
99.8%4434440.C++test

Line-by-line coverage:

   1    :  // Copyright 2012 Google Inc. All Rights Reserved.
   2    :  //
   3    :  // Licensed under the Apache License, Version 2.0 (the "License");
   4    :  // you may not use this file except in compliance with the License.
   5    :  // You may obtain a copy of the License at
   6    :  //
   7    :  //     http://www.apache.org/licenses/LICENSE-2.0
   8    :  //
   9    :  // Unless required by applicable law or agreed to in writing, software
  10    :  // distributed under the License is distributed on an "AS IS" BASIS,
  11    :  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12    :  // See the License for the specific language governing permissions and
  13    :  // limitations under the License.
  14    :  //
  15    :  #include "syzygy/block_graph/basic_block_assembler.h"
  16    :  
  17    :  #include "gtest/gtest.h"
  18    :  #include "syzygy/block_graph/basic_block_subgraph.h"
  19    :  
  20    :  namespace block_graph {
  21    :  
  22    :  namespace {
  23    :  
  24    :  class BasicBlockAssemblerTest : public testing::Test {
  25    :   public:
  26    :    typedef BlockGraph::RelativeAddress RelativeAddress;
  27    :    typedef BlockGraph::Block::SourceRange SourceRange;
  28    :  
  29    :    BasicBlockAssemblerTest();
  30    :  
  31  E :    void SetUp() OVERRIDE {
  32  E :    }
  33    :  
  34  E :    void TearDown() OVERRIDE {
  35  E :    }
  36    :  
  37    :   protected:
  38    :    struct Ref {
  39    :      size_t offset;
  40    :      BasicBlockReference::ReferredType type;
  41    :      const void* reference;
  42    :    };
  43    :  
  44    :    template <size_t N>
  45  E :    void AssertRefs(const Ref(& refs)[N]) {
  46  E :      ASSERT_EQ(1, instructions_.size());
  47  E :      const Instruction& instr = instructions_.front();
  48    :  
  49  E :      for (size_t i = 0; i < N; ++i) {
  50    :        BasicBlock::BasicBlockReferenceMap::const_iterator it =
  51  E :            instr.references().find(refs[i].offset);
  52  E :        ASSERT_NE(instr.references().end(), it);
  53  E :        ASSERT_EQ(refs[i].type, it->second.referred_type());
  54  E :        switch (refs[i].type) {
  55    :          case BasicBlockReference::REFERRED_TYPE_BLOCK:
  56  E :            ASSERT_EQ(refs[i].reference, it->second.block());
  57  E :            break;
  58    :          case BasicBlockReference::REFERRED_TYPE_BASIC_BLOCK:
  59  E :            ASSERT_EQ(refs[i].reference, it->second.basic_block());
  60  E :            break;
  61    :          default:
  62  i :            ASSERT_TRUE(false);
  63    :        }
  64    :  
  65  E :        ASSERT_EQ(refs[i].type, it->second.referred_type());
  66  E :      }
  67    :  
  68  E :      instructions_.clear();
  69  E :    }
  70    :  
  71  E :    void AssertNoRefs() {
  72  E :      ASSERT_EQ(1, instructions_.size());
  73  E :      ASSERT_EQ(0, instructions_.front().references().size());
  74  E :      instructions_.clear();
  75  E :    }
  76    :  
  77    :    BlockGraph block_graph_;
  78    :    BlockGraph::Block* test_block_;
  79    :    BasicBlockSubGraph subgraph_;
  80    :    BasicCodeBlock* test_bb_;
  81    :    BasicBlock::Instructions instructions_;
  82    :    BasicBlockAssembler asm_;
  83    :  };
  84    :  
  85    :  #define ASSERT_REFS(...) \
  86    :    do { \
  87    :      const Ref refs[] = { __VA_ARGS__ }; \
  88    :      ASSERT_NO_FATAL_FAILURE(AssertRefs(refs)); \
  89    :    } while (0)
  90    :  
  91    :  #define ASSERT_NO_REFS() ASSERT_NO_FATAL_FAILURE(AssertNoRefs())
  92    :  
  93    :  BasicBlockAssemblerTest::BasicBlockAssemblerTest()
  94    :      : test_block_(NULL),
  95    :        test_bb_(NULL),
  96  E :        asm_(instructions_.end(), &instructions_) {
  97  E :    test_block_ = block_graph_.AddBlock(BlockGraph::CODE_BLOCK, 10, "test block");
  98  E :    test_bb_= subgraph_.AddBasicCodeBlock("foo");
  99  E :  }
 100    :  
 101    :  void TestValue(const Value& value,
 102    :                 uint32 expected_value,
 103  E :                 core::ValueSize expected_size) {
 104  E :    EXPECT_EQ(expected_size, value.size());
 105  E :    EXPECT_EQ(expected_value, value.value());
 106    :    EXPECT_EQ(BasicBlockReference::REFERRED_TYPE_UNKNOWN,
 107  E :              value.reference().referred_type());
 108    :  
 109  E :    Value value_copy(value);
 110  E :    EXPECT_EQ(expected_size, value_copy.size());
 111  E :    EXPECT_EQ(expected_value, value_copy.value());
 112    :    EXPECT_EQ(BasicBlockReference::REFERRED_TYPE_UNKNOWN,
 113  E :              value_copy.reference().referred_type());
 114    :  
 115  E :    EXPECT_TRUE(value == value_copy);
 116    :  
 117  E :    Value value_diff(expected_value - 1);
 118  E :    EXPECT_FALSE(value == value_diff);
 119  E :  }
 120    :  
 121  E :  void Test8BitValue(uint32 input_value, uint32 expected_value) {
 122  E :    TestValue(Value(input_value), expected_value, core::kSize8Bit);
 123    :    TestValue(
 124  E :        Value(input_value, core::kSize8Bit), expected_value, core::kSize8Bit);
 125  E :  }
 126    :  
 127  E :  void Test32BitValue(uint32 input_value, uint32 expected_value) {
 128  E :    TestValue(Value(input_value), expected_value, core::kSize32Bit);
 129    :    TestValue(
 130  E :        Value(input_value, core::kSize32Bit), expected_value, core::kSize32Bit);
 131  E :  }
 132    :  
 133    :  typedef BasicBlockAssemblerTest ValueTest;
 134    :  
 135  E :  void TestValueCopy(const Value& input) {
 136    :    // Make sure copy-constructing the value works.
 137  E :    Value copy(input);
 138    :  
 139  E :    ASSERT_EQ(input.value(), copy.value());
 140  E :    ASSERT_EQ(input.size(), copy.size());
 141    :    ASSERT_EQ(input.reference().referred_type(),
 142  E :              copy.reference().referred_type());
 143  E :    ASSERT_EQ(input.reference().block(), copy.reference().block());
 144  E :    ASSERT_EQ(input.reference().basic_block(), copy.reference().basic_block());
 145  E :    ASSERT_EQ(input.reference().offset(), copy.reference().offset());
 146  E :    ASSERT_EQ(input.reference().base(), copy.reference().base());
 147    :  
 148    :    // Make sure assignment operator works.
 149  E :    Value copy2;
 150  E :    copy2 = input;
 151  E :    ASSERT_EQ(input.value(), copy2.value());
 152  E :    ASSERT_EQ(input.size(), copy2.size());
 153    :    ASSERT_EQ(input.reference().referred_type(),
 154  E :              copy2.reference().referred_type());
 155  E :    ASSERT_EQ(input.reference().block(), copy2.reference().block());
 156  E :    ASSERT_EQ(input.reference().basic_block(), copy2.reference().basic_block());
 157  E :    ASSERT_EQ(input.reference().offset(), copy2.reference().offset());
 158  E :    ASSERT_EQ(input.reference().base(), copy2.reference().base());
 159  E :  }
 160    :  
 161    :  }  // namespace
 162    :  
 163  E :  TEST(UntypedReferenceTest, DefaultConstructor) {
 164  E :    UntypedReference r;
 165  E :    EXPECT_EQ(NULL, r.basic_block());
 166  E :    EXPECT_EQ(NULL, r.block());
 167  E :    EXPECT_EQ(0, r.offset());
 168  E :    EXPECT_EQ(0, r.base());
 169  E :    EXPECT_FALSE(r.IsValid());
 170  E :    EXPECT_EQ(BasicBlockReference::REFERRED_TYPE_UNKNOWN, r.referred_type());
 171  E :  }
 172    :  
 173  E :  TEST(UntypedReferenceTest, BasicBlockReferenceToBasicBlockConstructor) {
 174  E :    BasicBlockSubGraph subgraph;
 175  E :    BasicCodeBlock* bcb = subgraph.AddBasicCodeBlock("foo");
 176  E :    BasicBlock* bb = bcb;
 177  E :    BasicBlockReference bbref(BlockGraph::ABSOLUTE_REF, 4, bcb);
 178  E :    UntypedReference r(bbref);
 179  E :    EXPECT_EQ(bb, r.basic_block());
 180  E :    EXPECT_EQ(NULL, r.block());
 181  E :    EXPECT_EQ(0, r.offset());
 182  E :    EXPECT_EQ(0, r.base());
 183  E :    EXPECT_TRUE(r.IsValid());
 184  E :    EXPECT_EQ(BasicBlockReference::REFERRED_TYPE_BASIC_BLOCK, r.referred_type());
 185  E :  }
 186    :  
 187  E :  TEST(UntypedReferenceTest, BasicBlockReferenceToBlockConstructor) {
 188  E :    BlockGraph block_graph;
 189    :    BlockGraph::Block* b =
 190  E :        block_graph.AddBlock(BlockGraph::CODE_BLOCK, 20, "foo");
 191  E :    BasicBlockReference bbref(BlockGraph::ABSOLUTE_REF, 4, b, 4, 10);
 192  E :    UntypedReference r(bbref);
 193  E :    EXPECT_EQ(NULL, r.basic_block());
 194  E :    EXPECT_EQ(b, r.block());
 195  E :    EXPECT_EQ(4, r.offset());
 196  E :    EXPECT_EQ(10, r.base());
 197  E :    EXPECT_TRUE(r.IsValid());
 198  E :    EXPECT_EQ(BasicBlockReference::REFERRED_TYPE_BLOCK, r.referred_type());
 199  E :  }
 200    :  
 201  E :  TEST(UntypedReferenceTest, BasicBlockConstructor) {
 202  E :    BasicBlockSubGraph subgraph;
 203  E :    BasicCodeBlock* bcb = subgraph.AddBasicCodeBlock("foo");
 204  E :    BasicBlock* bb = bcb;
 205  E :    UntypedReference r(bcb);
 206  E :    EXPECT_EQ(bb, r.basic_block());
 207  E :    EXPECT_EQ(NULL, r.block());
 208  E :    EXPECT_EQ(0, r.offset());
 209  E :    EXPECT_EQ(0, r.base());
 210  E :    EXPECT_TRUE(r.IsValid());
 211  E :    EXPECT_EQ(BasicBlockReference::REFERRED_TYPE_BASIC_BLOCK, r.referred_type());
 212  E :  }
 213    :  
 214  E :  TEST(UntypedReferenceTest, BlockConstructor) {
 215  E :    BlockGraph block_graph;
 216    :    BlockGraph::Block* b =
 217  E :        block_graph.AddBlock(BlockGraph::CODE_BLOCK, 0, "dummy");
 218  E :    UntypedReference r(b, 4, 10);
 219  E :    EXPECT_EQ(NULL, r.basic_block());
 220  E :    EXPECT_EQ(b, r.block());
 221  E :    EXPECT_EQ(4, r.offset());
 222  E :    EXPECT_EQ(10, r.base());
 223  E :    EXPECT_TRUE(r.IsValid());
 224  E :    EXPECT_EQ(BasicBlockReference::REFERRED_TYPE_BLOCK, r.referred_type());
 225  E :  }
 226    :  
 227  E :  TEST(UntypedReferenceTest, CopyConstructor) {
 228  E :    BlockGraph block_graph;
 229    :    BlockGraph::Block* b =
 230  E :        block_graph.AddBlock(BlockGraph::CODE_BLOCK, 0, "dummy");
 231  E :    UntypedReference r1(b, 4, 10);
 232    :  
 233  E :    UntypedReference r2(r1);
 234  E :    EXPECT_EQ(r1.basic_block(), r2.basic_block());
 235  E :    EXPECT_EQ(r1.block(), r2.block());
 236  E :    EXPECT_EQ(r1.offset(), r2.offset());
 237  E :    EXPECT_EQ(r1.base(), r2.base());
 238  E :    EXPECT_EQ(r1.IsValid(), r2.IsValid());
 239  E :  }
 240    :  
 241  E :  TEST(UntypedReferenceTest, Comparison) {
 242  E :    BlockGraph block_graph;
 243  E :    BasicBlockSubGraph subgraph;
 244    :    BlockGraph::Block* b =
 245  E :        block_graph.AddBlock(BlockGraph::CODE_BLOCK, 0, "dummy");
 246  E :    UntypedReference r1(b, 4, 10);
 247    :  
 248  E :    UntypedReference r2(b, 0, 0);
 249  E :    EXPECT_FALSE(r1 == r2);
 250    :  
 251  E :    BasicCodeBlock* bcb = subgraph.AddBasicCodeBlock("foo");
 252  E :    BasicBlock* bb = bcb;
 253  E :    UntypedReference r3(bcb);
 254  E :    EXPECT_FALSE(r1 == r3);
 255  E :    EXPECT_FALSE(r2 == r3);
 256    :  
 257  E :    UntypedReference r4(r1);
 258  E :    EXPECT_TRUE(r1 == r4);
 259    :  
 260  E :    UntypedReference r5(r2);
 261  E :    EXPECT_TRUE(r2 == r5);
 262  E :  }
 263    :  
 264  E :  TEST_F(ValueTest, Construction) {
 265    :    {
 266  E :      Value value_empty;
 267  E :      ASSERT_EQ(0, value_empty.value());
 268  E :      ASSERT_EQ(core::kSizeNone, value_empty.size());
 269    :      ASSERT_EQ(BasicBlockReference::REFERRED_TYPE_UNKNOWN,
 270  E :                value_empty.reference().referred_type());
 271    :  
 272  E :      TestValueCopy(value_empty);
 273  E :    }
 274    :  
 275  E :    Test8BitValue(0, 0);
 276  E :    Test8BitValue(127, 127);
 277    :  
 278  E :    Test8BitValue(-128, 0xFFFFFF80);
 279  E :    Test8BitValue(0, 0);
 280  E :    Test8BitValue(127, 0x0000007F);
 281    :  
 282  E :    Test32BitValue(128, 0x00000080);
 283  E :    Test32BitValue(0xCAFEBABE, 0xCAFEBABE);
 284    :  
 285  E :    Test32BitValue(-129, 0xFFFFFF7F);
 286  E :    Test32BitValue(128, 0x000000080);
 287  E :    Test32BitValue(0xBABE, 0xBABE);
 288    :  
 289    :    {
 290  E :      const BlockGraph::Offset kOffs = 10;
 291  E :      Value value_block_ref(test_block_, kOffs);
 292    :  
 293  E :      ASSERT_EQ(0, value_block_ref.value());
 294  E :      ASSERT_EQ(core::kSize32Bit, value_block_ref.size());
 295    :      ASSERT_EQ(BasicBlockReference::REFERRED_TYPE_BLOCK,
 296  E :                value_block_ref.reference().referred_type());
 297  E :      ASSERT_EQ(test_block_, value_block_ref.reference().block());
 298  E :      ASSERT_EQ(kOffs, value_block_ref.reference().offset());
 299  E :      ASSERT_EQ(kOffs, value_block_ref.reference().base());
 300    :  
 301  E :      TestValueCopy(value_block_ref);
 302  E :    }
 303    :  
 304    :    {
 305  E :      Value value_bb_ref(test_bb_);
 306    :  
 307  E :      ASSERT_EQ(0, value_bb_ref.value());
 308  E :      ASSERT_EQ(core::kSize32Bit, value_bb_ref.size());
 309    :      ASSERT_EQ(BasicBlockReference::REFERRED_TYPE_BASIC_BLOCK,
 310  E :                value_bb_ref.reference().referred_type());
 311  E :      ASSERT_EQ(test_bb_, value_bb_ref.reference().basic_block());
 312  E :      ASSERT_EQ(0, value_bb_ref.reference().offset());
 313  E :      ASSERT_EQ(0, value_bb_ref.reference().base());
 314    :  
 315  E :      TestValueCopy(value_bb_ref);
 316  E :    }
 317    :  
 318    :    {
 319    :      // Explicitly specified size and reference info.
 320  E :      UntypedReference ref(test_block_, 1, 2);
 321  E :      Value value_expl_ref(0xBE, core::kSize8Bit, ref);
 322    :  
 323  E :      ASSERT_EQ(0xBE, value_expl_ref.value());
 324  E :      ASSERT_EQ(core::kSize8Bit, value_expl_ref.size());
 325    :      ASSERT_EQ(BasicBlockReference::REFERRED_TYPE_BLOCK,
 326  E :                value_expl_ref.reference().referred_type());
 327  E :      ASSERT_EQ(test_block_, value_expl_ref.reference().block());
 328  E :      ASSERT_EQ(1, value_expl_ref.reference().offset());
 329  E :      ASSERT_EQ(2, value_expl_ref.reference().base());
 330    :  
 331  E :      TestValueCopy(value_expl_ref);
 332  E :    }
 333  E :  }
 334    :  
 335    :  typedef BasicBlockAssemblerTest OperandTest;
 336    :  
 337  E :  void TestOperandCopy(const Operand& input) {
 338  E :    Operand copy(input);
 339    :  
 340  E :    ASSERT_EQ(input.base(), copy.base());
 341  E :    ASSERT_EQ(input.index(), copy.index());
 342  E :    ASSERT_EQ(input.scale(), copy.scale());
 343  E :    ASSERT_EQ(input.displacement().value(), copy.displacement().value());
 344  E :    ASSERT_EQ(input.displacement().size(), copy.displacement().size());
 345  E :    ASSERT_EQ(input.displacement().reference(), copy.displacement().reference());
 346    :  
 347  E :    Operand copy2(core::eax);
 348    :  
 349  E :    copy2 = input;
 350  E :    ASSERT_EQ(input.base(), copy2.base());
 351  E :    ASSERT_EQ(input.index(), copy2.index());
 352  E :    ASSERT_EQ(input.scale(), copy2.scale());
 353  E :    ASSERT_EQ(input.displacement().value(), copy2.displacement().value());
 354  E :    ASSERT_EQ(input.displacement().size(), copy2.displacement().size());
 355  E :    ASSERT_EQ(input.displacement().reference(), copy2.displacement().reference());
 356  E :  }
 357    :  
 358  E :  TEST_F(OperandTest, Construction) {
 359    :    // A register-indirect.
 360  E :    TestOperandCopy(Operand(core::eax));
 361    :  
 362    :    // Register-indirect with displacement.
 363  E :    TestOperandCopy(Operand(core::eax, Displacement(100)));
 364  E :    TestOperandCopy(Operand(core::eax, Displacement(test_block_, 2)));
 365  E :    TestOperandCopy(Operand(core::eax, Displacement(test_bb_)));
 366    :  
 367    :    // Displacement-only mode.
 368  E :    TestOperandCopy(Operand(Displacement(100)));
 369  E :    TestOperandCopy(Operand(Displacement(test_block_, 2)));
 370  E :    TestOperandCopy(Operand(Displacement(test_bb_)));
 371    :  
 372    :    TestOperandCopy(Operand(core::eax,
 373    :                            core::ebp,
 374    :                            core::kTimes2,
 375  E :                            Displacement(100)));
 376    :    TestOperandCopy(Operand(core::eax,
 377    :                            core::ebp,
 378    :                            core::kTimes2,
 379  E :                            Displacement(test_block_, 2)));
 380    :    TestOperandCopy(Operand(core::eax,
 381    :                            core::ebp,
 382    :                            core::kTimes2,
 383  E :                            Displacement(test_bb_)));
 384    :  
 385    :    // The [base + index * scale] mode - no displ.
 386  E :    TestOperandCopy(Operand(core::eax, core::ebp, core::kTimes2));
 387    :  
 388    :    // The [index * scale + displ32] mode - no base.
 389    :    TestOperandCopy(Operand(core::ebp,
 390    :                            core::kTimes2,
 391  E :                            Displacement(100)));
 392    :    TestOperandCopy(Operand(core::ebp,
 393    :                            core::kTimes2,
 394  E :                            Displacement(test_block_, 2)));
 395    :    TestOperandCopy(Operand(core::ebp,
 396    :                            core::kTimes2,
 397  E :                            Displacement(test_bb_)));
 398  E :  }
 399    :  
 400  E :  TEST_F(BasicBlockAssemblerTest, nop) {
 401    :    // We can't use ASSERT_NO_REFS here as nop may generate more than 1
 402    :    // instruction, an exception to the rule of 1 instruction that ASSERT_NO_REFS
 403    :    // enforces.
 404  E :    asm_.nop(0);
 405  E :    ASSERT_EQ(0u, instructions_.size());
 406    :  
 407    :    // Exactly 1 or 2 instructions should be emitted per NOP length from
 408    :    // 1 to 15.
 409  E :    for (size_t i = 1; i <= 15; ++i) {
 410  E :      asm_.nop(i);
 411  E :      ASSERT_LT(0u, instructions_.size());
 412  E :      ASSERT_GE(2u, instructions_.size());
 413    :  
 414    :      // NOP instructions should have no references.
 415    :      for (BasicCodeBlock::Instructions::const_iterator inst_it =
 416  E :               instructions_.begin();
 417  E :           inst_it != instructions_.end();
 418  E :           ++inst_it) {
 419  E :        ASSERT_EQ(0u, inst_it->references().size());
 420  E :      }
 421  E :      instructions_.clear();
 422  E :    }
 423  E :  }
 424    :  
 425  E :  TEST_F(BasicBlockAssemblerTest, call) {
 426  E :    asm_.call(Immediate(test_block_, 0));
 427  E :    ASSERT_REFS(1, BasicBlockReference::REFERRED_TYPE_BLOCK, test_block_);
 428    :  
 429  E :    asm_.call(Operand(Displacement(test_bb_)));
 430  E :    ASSERT_REFS(2, BasicBlockReference::REFERRED_TYPE_BASIC_BLOCK, test_bb_);
 431  E :  }
 432    :  
 433  E :  TEST_F(BasicBlockAssemblerTest, jmp) {
 434  E :    asm_.jmp(Immediate(test_block_, 0));
 435  E :    ASSERT_REFS(1, BasicBlockReference::REFERRED_TYPE_BLOCK, test_block_);
 436    :  
 437  E :    asm_.jmp(Operand(Displacement(test_bb_)));
 438  E :    ASSERT_REFS(2, BasicBlockReference::REFERRED_TYPE_BASIC_BLOCK, test_bb_);
 439  E :  }
 440    :  
 441  E :  TEST_F(BasicBlockAssemblerTest, mov_b) {
 442    :    // mov BYTE PTR [base + index * scale + displ], immediate
 443    :    asm_.mov_b(Operand(core::eax, core::ebx, core::kTimes4,
 444    :                       Displacement(test_block_, 0)),
 445  E :             Immediate(10));
 446  E :    ASSERT_REFS(3, BasicBlockReference::REFERRED_TYPE_BLOCK, test_block_);
 447  E :  }
 448    :  
 449  E :  TEST_F(BasicBlockAssemblerTest, movzx_b) {
 450    :    // movzx eax, BYTE PTR [base + index * scale + displ]
 451    :    asm_.movzx_b(core::eax,
 452    :                 Operand(core::eax, core::ebx, core::kTimes4,
 453  E :                         Displacement(test_block_, 0)));
 454  E :    ASSERT_REFS(4, BasicBlockReference::REFERRED_TYPE_BLOCK, test_block_);
 455  E :  }
 456    :  
 457  E :  TEST_F(BasicBlockAssemblerTest, mov) {
 458    :    // Simple register-register move.
 459  E :    asm_.mov(core::eax, core::ebx);
 460  E :    ASSERT_NO_REFS();
 461    :  
 462    :    // Simple immediate-register move.
 463  E :    asm_.mov(core::eax, Immediate(10));
 464  E :    ASSERT_NO_REFS();
 465    :  
 466    :    // Immediate-with reference to register.
 467  E :    asm_.mov(core::eax, Immediate(test_block_, 0));
 468  E :    ASSERT_REFS(1, BasicBlockReference::REFERRED_TYPE_BLOCK, test_block_);
 469    :  
 470    :    // Torture test; mov [displ], immediate,
 471    :    // both src and dst contain references.
 472  E :    asm_.mov(Operand(Displacement(test_block_, 0)), Immediate(test_bb_));
 473    :    ASSERT_REFS(2, BasicBlockReference::REFERRED_TYPE_BLOCK, test_block_,
 474  E :                6, BasicBlockReference::REFERRED_TYPE_BASIC_BLOCK, test_bb_);
 475    :  
 476    :    // Torture test; mov [base + index * scale + displ], immediate,
 477    :    // both src and dst contain references.
 478    :    asm_.mov(Operand(core::eax, core::ebx, core::kTimes4,
 479    :                     Displacement(test_block_, 0)),
 480  E :             Immediate(test_bb_));
 481    :    ASSERT_REFS(3, BasicBlockReference::REFERRED_TYPE_BLOCK, test_block_,
 482  E :                7, BasicBlockReference::REFERRED_TYPE_BASIC_BLOCK, test_bb_);
 483  E :  }
 484    :  
 485  E :  TEST_F(BasicBlockAssemblerTest, mov_fs) {
 486    :    asm_.mov_fs(Operand(core::eax, core::ebx, core::kTimes4,
 487    :                        Displacement(test_block_, 0)),
 488  E :                core::eax);
 489  E :    ASSERT_REFS(4, BasicBlockReference::REFERRED_TYPE_BLOCK, test_block_);
 490    :  
 491    :    asm_.mov_fs(core::eax,
 492    :                Operand(core::eax, core::ebx, core::kTimes4,
 493  E :                        Displacement(test_block_, 0)));
 494  E :    ASSERT_REFS(4, BasicBlockReference::REFERRED_TYPE_BLOCK, test_block_);
 495  E :  }
 496    :  
 497  E :  TEST_F(BasicBlockAssemblerTest, lea) {
 498  E :    asm_.lea(core::eax, Operand(core::eax));
 499  E :    ASSERT_NO_REFS();
 500    :  
 501    :    asm_.lea(core::eax,
 502    :             Operand(core::eax, core::ebx, core::kTimes4,
 503  E :                     Displacement(test_bb_)));
 504  E :    ASSERT_REFS(3, BasicBlockReference::REFERRED_TYPE_BASIC_BLOCK, test_bb_);
 505  E :  }
 506    :  
 507  E :  TEST_F(BasicBlockAssemblerTest, push) {
 508  E :    asm_.push(core::esp);
 509  E :    ASSERT_NO_REFS();
 510    :  
 511  E :    asm_.push(Immediate(test_block_, 0));
 512  E :    ASSERT_REFS(1, BasicBlockReference::REFERRED_TYPE_BLOCK, test_block_);
 513    :  
 514    :    asm_.push(Operand(core::eax, core::ebx, core::kTimes4,
 515  E :                      Displacement(test_bb_)));
 516  E :    ASSERT_REFS(3, BasicBlockReference::REFERRED_TYPE_BASIC_BLOCK, test_bb_);
 517  E :  }
 518    :  
 519  E :  TEST_F(BasicBlockAssemblerTest, pop) {
 520  E :    asm_.pop(core::ebp);
 521  E :    ASSERT_NO_REFS();
 522    :  
 523    :    asm_.pop(Operand(core::eax, core::ebx, core::kTimes4,
 524  E :                      Displacement(test_bb_)));
 525  E :    ASSERT_REFS(3, BasicBlockReference::REFERRED_TYPE_BASIC_BLOCK, test_bb_);
 526  E :  }
 527    :  
 528  E :  TEST_F(BasicBlockAssemblerTest, pushfd) {
 529  E :    asm_.pushfd();
 530  E :    ASSERT_NO_REFS();
 531  E :  }
 532    :  
 533  E :  TEST_F(BasicBlockAssemblerTest, popfd) {
 534  E :    asm_.popfd();
 535  E :    ASSERT_NO_REFS();
 536  E :  }
 537    :  
 538  E :  TEST_F(BasicBlockAssemblerTest, lahf) {
 539  E :    asm_.lahf();
 540  E :    ASSERT_NO_REFS();
 541  E :  }
 542    :  
 543  E :  TEST_F(BasicBlockAssemblerTest, sahf) {
 544  E :    asm_.sahf();
 545  E :    ASSERT_NO_REFS();
 546  E :  }
 547    :  
 548  E :  TEST_F(BasicBlockAssemblerTest, setxx) {
 549    :    // Simple register-register operation.
 550  E :    asm_.set(core::kParityEven, core::eax);
 551  E :    ASSERT_NO_REFS();
 552    :  
 553  E :    asm_.set(core::kOverflow, core::ebx);
 554  E :    ASSERT_NO_REFS();
 555  E :  }
 556    :  
 557  E :  TEST_F(BasicBlockAssemblerTest, test) {
 558    :    // Simple register-register operation.
 559  E :    asm_.test(core::al, core::bl);
 560  E :    ASSERT_NO_REFS();
 561    :  
 562    :    // Simple immediate-register operation.
 563  E :    asm_.test(core::al, Immediate(10, core::kSize8Bit));
 564  E :    ASSERT_NO_REFS();
 565    :  
 566    :    // Simple register-register operation.
 567  E :    asm_.test(core::eax, core::ebx);
 568  E :    ASSERT_NO_REFS();
 569    :  
 570    :    // Simple immediate-register operation.
 571  E :    asm_.test(core::eax, Immediate(10));
 572  E :    ASSERT_NO_REFS();
 573    :  
 574    :    // Immediate-with reference to register.
 575  E :    asm_.test(core::eax, Immediate(test_block_, 0));
 576  E :    ASSERT_REFS(1, BasicBlockReference::REFERRED_TYPE_BLOCK, test_block_);
 577    :  
 578    :    // Torture test: both src and dst contain references.
 579  E :    asm_.test(Operand(Displacement(test_block_, 0)), Immediate(test_bb_));
 580    :    ASSERT_REFS(2, BasicBlockReference::REFERRED_TYPE_BLOCK, test_block_,
 581  E :                6, BasicBlockReference::REFERRED_TYPE_BASIC_BLOCK, test_bb_);
 582    :  
 583  E :    asm_.test(Operand(Displacement(test_block_, 0)), Immediate(10));
 584  E :    ASSERT_REFS(2, BasicBlockReference::REFERRED_TYPE_BLOCK, test_block_);
 585  E :  }
 586    :  
 587  E :  TEST_F(BasicBlockAssemblerTest, cmp) {
 588    :      // Simple register-register operation.
 589  E :    asm_.cmp(core::al, core::bl);
 590  E :    ASSERT_NO_REFS();
 591    :  
 592    :    // Simple immediate-register operation.
 593  E :    asm_.cmp(core::al, Immediate(10, core::kSize8Bit));
 594  E :    ASSERT_NO_REFS();
 595    :  
 596    :    // Simple register-register operation.
 597  E :    asm_.cmp(core::eax, core::ebx);
 598  E :    ASSERT_NO_REFS();
 599    :  
 600    :    // Simple immediate-register operation.
 601  E :    asm_.cmp(core::eax, Immediate(10));
 602  E :    ASSERT_NO_REFS();
 603    :  
 604    :    // Immediate-with reference to register.
 605  E :    asm_.cmp(core::eax, Immediate(test_block_, 0));
 606  E :    ASSERT_REFS(1, BasicBlockReference::REFERRED_TYPE_BLOCK, test_block_);
 607    :  
 608    :    // Torture test: both src and dst contain references.
 609  E :    asm_.cmp(Operand(Displacement(test_block_, 0)), Immediate(test_bb_));
 610    :    ASSERT_REFS(2, BasicBlockReference::REFERRED_TYPE_BLOCK, test_block_,
 611  E :                6, BasicBlockReference::REFERRED_TYPE_BASIC_BLOCK, test_bb_);
 612    :  
 613  E :    asm_.cmp(Operand(Displacement(test_block_, 0)), Immediate(10));
 614  E :    ASSERT_REFS(2, BasicBlockReference::REFERRED_TYPE_BLOCK, test_block_);
 615  E :  }
 616    :  
 617  E :  TEST_F(BasicBlockAssemblerTest, add) {
 618    :    // Simple register-register operation.
 619  E :    asm_.add(core::al, core::bl);
 620  E :    ASSERT_NO_REFS();
 621    :  
 622    :    // Simple immediate-register operation.
 623  E :    asm_.add(core::al, Immediate(10, core::kSize8Bit));
 624  E :    ASSERT_NO_REFS();
 625    :  
 626    :    // Simple register-register operation.
 627  E :    asm_.add(core::eax, core::ebx);
 628  E :    ASSERT_NO_REFS();
 629    :  
 630    :    // Simple immediate-register operation.
 631  E :    asm_.add(core::eax, Immediate(10));
 632  E :    ASSERT_NO_REFS();
 633    :  
 634    :    // Immediate-with reference to register.
 635  E :    asm_.add(core::eax, Immediate(test_block_, 0));
 636  E :    ASSERT_REFS(1, BasicBlockReference::REFERRED_TYPE_BLOCK, test_block_);
 637    :  
 638    :    // Torture test: both src and dst contain references.
 639  E :    asm_.add(Operand(Displacement(test_block_, 0)), Immediate(test_bb_));
 640    :    ASSERT_REFS(2, BasicBlockReference::REFERRED_TYPE_BLOCK, test_block_,
 641  E :                6, BasicBlockReference::REFERRED_TYPE_BASIC_BLOCK, test_bb_);
 642    :  
 643  E :    asm_.add(Operand(Displacement(test_block_, 0)), Immediate(10));
 644  E :    ASSERT_REFS(2, BasicBlockReference::REFERRED_TYPE_BLOCK, test_block_);
 645  E :  }
 646    :  
 647  E :  TEST_F(BasicBlockAssemblerTest, sub) {
 648    :    // Simple register-register operation.
 649  E :    asm_.sub(core::al, core::bl);
 650  E :    ASSERT_NO_REFS();
 651    :  
 652    :    // Simple immediate-register operation.
 653  E :    asm_.sub(core::al, Immediate(10, core::kSize8Bit));
 654  E :    ASSERT_NO_REFS();
 655    :  
 656    :    // Simple register-register operation.
 657  E :    asm_.sub(core::eax, core::ebx);
 658  E :    ASSERT_NO_REFS();
 659    :  
 660    :    // Simple immediate-register operation.
 661  E :    asm_.sub(core::eax, Immediate(10));
 662  E :    ASSERT_NO_REFS();
 663    :  
 664    :    // Immediate-with reference to register.
 665  E :    asm_.sub(core::eax, Immediate(test_block_, 0));
 666  E :    ASSERT_REFS(1, BasicBlockReference::REFERRED_TYPE_BLOCK, test_block_);
 667    :  
 668    :    // Torture test: both src and dst contain references.
 669  E :    asm_.sub(Operand(Displacement(test_block_, 0)), Immediate(test_bb_));
 670    :    ASSERT_REFS(2, BasicBlockReference::REFERRED_TYPE_BLOCK, test_block_,
 671  E :                6, BasicBlockReference::REFERRED_TYPE_BASIC_BLOCK, test_bb_);
 672    :  
 673  E :    asm_.sub(Operand(Displacement(test_block_, 0)), Immediate(10));
 674  E :    ASSERT_REFS(2, BasicBlockReference::REFERRED_TYPE_BLOCK, test_block_);
 675  E :  }
 676    :  
 677  E :  TEST_F(BasicBlockAssemblerTest, shl) {
 678    :    // Simple immediate-register operation.
 679  E :    asm_.shl(core::eax, Immediate(1));
 680  E :    ASSERT_NO_REFS();
 681  E :  }
 682    :  
 683  E :  TEST_F(BasicBlockAssemblerTest, shr) {
 684    :    // Simple immediate-register operation.
 685  E :    asm_.shr(core::eax, Immediate(1));
 686  E :    ASSERT_NO_REFS();
 687  E :  }
 688    :  
 689  E :  TEST_F(BasicBlockAssemblerTest, ret) {
 690  E :    asm_.ret();
 691  E :    ASSERT_NO_REFS();
 692    :  
 693  E :    asm_.ret(4);
 694  E :    ASSERT_NO_REFS();
 695  E :  }
 696    :  
 697  E :  TEST_F(BasicBlockAssemblerTest, xchg) {
 698  E :    asm_.xchg(core::eax, core::ecx);
 699  E :    ASSERT_NO_REFS();
 700    :  
 701  E :    asm_.xchg(core::esp, core::edx);
 702  E :    ASSERT_NO_REFS();
 703    :  
 704  E :    asm_.xchg(core::ax, core::cx);
 705  E :    ASSERT_NO_REFS();
 706    :  
 707  E :    asm_.xchg(core::sp, core::dx);
 708  E :    ASSERT_NO_REFS();
 709    :  
 710  E :    asm_.xchg(core::al, core::ch);
 711  E :    ASSERT_NO_REFS();
 712    :  
 713  E :    asm_.xchg(core::dh, core::bl);
 714  E :    ASSERT_NO_REFS();
 715  E :  }
 716    :  
 717  E :  TEST_F(BasicBlockAssemblerTest, UndefinedSourceRange) {
 718  E :    ASSERT_EQ(asm_.source_range(), SourceRange());
 719  E :    asm_.call(Immediate(test_block_, 0));
 720  E :    ASSERT_EQ(instructions_.back().source_range(), SourceRange());
 721  E :  }
 722    :  
 723  E :  TEST_F(BasicBlockAssemblerTest, SetSourceRange) {
 724  E :    SourceRange range(RelativeAddress(10), 10);
 725  E :    asm_.set_source_range(range);
 726  E :    asm_.call(Immediate(test_block_, 0));
 727  E :    ASSERT_EQ(instructions_.back().source_range(), range);
 728  E :  }
 729    :  
 730  E :  TEST_F(BasicBlockAssemblerTest, SetMultipleSourceRange) {
 731  E :    SourceRange range1(RelativeAddress(10), 10);
 732  E :    SourceRange range2(RelativeAddress(20), 20);
 733    :  
 734  E :    asm_.set_source_range(range1);
 735  E :    asm_.call(Immediate(test_block_, 0));
 736  E :    ASSERT_EQ(instructions_.back().source_range(), range1);
 737    :  
 738  E :    asm_.set_source_range(range2);
 739  E :    asm_.pop(core::ebp);
 740  E :    ASSERT_EQ(instructions_.back().source_range(), range2);
 741    :  
 742  E :    asm_.ret(4);
 743  E :    ASSERT_EQ(instructions_.back().source_range(), range2);
 744  E :  }
 745    :  
 746    :  }  // namespace block_graph

Coverage information generated Wed Dec 11 11:34:16 2013.