Coverage for /Syzygy/block_graph/basic_block_assembler_unittest.cc

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

Coverage information generated Tue Jun 25 13:56:24 2013.