Coverage for /Syzygy/block_graph/basic_block_assembler_unittest.cc

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

Coverage information generated Thu Jul 04 09:34:53 2013.