Coverage for /Syzygy/block_graph/basic_block_assembler.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
99.1%3423450.C++source

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    :  namespace block_graph {
  18    :  
  19    :  namespace {
  20    :  
  21    :  typedef core::DisplacementImpl DisplacementImpl;
  22    :  typedef core::OperandImpl OperandImpl;
  23    :  typedef core::ValueImpl ValueImpl;
  24    :  typedef core::ValueSize ValueSize;
  25    :  
  26  E :  ValueSize ValueSizeFromConstant(uint32 input_value) {
  27    :    // IA32 assembly may/will sign-extend 8-bit literals, so we attempt to encode
  28    :    // in 8 bits only those literals whose value will be unchanged by that
  29    :    // treatment.
  30  E :    input_value |= 0x7F;
  31    :  
  32  E :    if (input_value == 0xFFFFFFFF || input_value == 0x7F)
  33  E :      return core::kSize8Bit;
  34    :  
  35  E :    return core::kSize32Bit;
  36  E :  }
  37    :  
  38    :  ValueImpl CopyValue(const UntypedReference* ref,
  39  E :                      const core::ValueImpl& value) {
  40    :    return ValueImpl(value.value(),
  41    :                     value.size(),
  42  E :                     value.reference() ? ref : NULL);
  43  E :  }
  44    :  
  45  E :  size_t ToBytes(core::ValueSize size) {
  46  E :    switch (size) {
  47  E :      case core::kSize8Bit: return 1;
  48  E :      case core::kSize32Bit: return 4;
  49    :    }
  50  i :    NOTREACHED();
  51  i :    return 0;
  52  E :  }
  53    :  
  54    :  // Completes a UntypedReference, converting it to a BasicBlockReference
  55    :  // using the provided type and size information.
  56    :  // @param ref_info The type and size information to use.
  57    :  // @param untyped_ref The untyped reference to be completed.
  58    :  // @returns the equivalent BasicBlockReference.
  59    :  BasicBlockReference CompleteUntypedReference(
  60    :      BlockGraph::ReferenceType type,
  61    :      size_t size,
  62  E :      const UntypedReference& untyped_ref) {
  63  E :    DCHECK(untyped_ref.IsValid());
  64    :  
  65    :    if (untyped_ref.referred_type() ==
  66  E :            BasicBlockReference::REFERRED_TYPE_BLOCK) {
  67  E :      DCHECK(untyped_ref.block() != NULL);
  68    :      return BasicBlockReference(type, size, untyped_ref.block(),
  69  E :                                 untyped_ref.offset(), untyped_ref.base());
  70    :    }
  71    :  
  72    :    DCHECK_EQ(BasicBlockReference::REFERRED_TYPE_BASIC_BLOCK,
  73  E :              untyped_ref.referred_type());
  74  E :    DCHECK(untyped_ref.basic_block() != NULL);
  75  E :    return BasicBlockReference(type, size, untyped_ref.basic_block());
  76  E :  }
  77    :  
  78    :  }  // namespace
  79    :  
  80  E :  Value::Value() {
  81  E :  }
  82    :  
  83  E :  Value::Value(uint32 value) : value_(value, ValueSizeFromConstant(value)) {
  84  E :  }
  85    :  
  86  E :  Value::Value(uint32 value, ValueSize size) : value_(value, size) {
  87  E :  }
  88    :  
  89    :  Value::Value(BasicBlock* bb)
  90    :      : reference_(bb),
  91  E :        value_(0, core::kSize32Bit, &reference_) {
  92  E :  }
  93    :  
  94    :  Value::Value(Block* block, Offset offset)
  95    :      : reference_(block, offset, offset),
  96  E :        value_(0, core::kSize32Bit, &reference_) {
  97  E :  }
  98    :  
  99    :  Value::Value(Block* block, Offset offset, Offset base)
 100    :      : reference_(block, offset, base),
 101  E :        value_(0, core::kSize32Bit, &reference_) {
 102  E :  }
 103    :  
 104    :  Value::Value(uint32 value, ValueSize size, const UntypedReference& ref)
 105  E :      : reference_(ref), value_(value, size, &reference_) {
 106  E :    DCHECK(ref.IsValid());
 107  E :  }
 108    :  
 109    :  Value::Value(const Value& other)
 110    :      : reference_(other.reference()),
 111  E :        value_(CopyValue(&reference_, other.value_)) {
 112  E :  }
 113    :  
 114    :  Value::Value(const UntypedReference& ref, const ValueImpl& value)
 115  E :      : reference_(ref), value_(CopyValue(&reference_, value)) {
 116  E :  }
 117    :  
 118  E :  Value::~Value() {
 119    :  #ifndef NDEBUG
 120  E :    if (reference_.IsValid()) {
 121  E :      DCHECK(value_.reference() == &reference_);
 122  E :    } else {
 123  E :      DCHECK(value_.reference() == NULL);
 124    :    }
 125    :  #endif
 126  E :  }
 127    :  
 128  E :  const Value& Value::operator=(const Value& other) {
 129  E :    reference_ = other.reference_;
 130  E :    value_ = CopyValue(&reference_, other.value_);
 131  E :    return *this;
 132  E :  }
 133    :  
 134  E :  bool Value::operator==(const Value& rhs) const {
 135  E :    if (reference_.IsValid())
 136  i :      return reference_ == rhs.reference();
 137  E :    return value_ == rhs.value_;
 138  E :  }
 139    :  
 140  E :  Operand::Operand(const core::Register32& base) : operand_(base) {
 141  E :  }
 142    :  
 143    :  Operand::Operand(const core::Register32& base, const Displacement& displ)
 144    :      : reference_(displ.reference()),
 145  E :        operand_(base, CopyValue(&reference_, displ.value_)) {
 146  E :  }
 147    :  
 148    :  Operand::Operand(const Displacement& displ)
 149    :      : reference_(displ.reference()),
 150  E :        operand_(CopyValue(&reference_, displ.value_)) {
 151  E :  }
 152    :  
 153    :  Operand::Operand(const core::Register32& base,
 154    :                   const core::Register32& index,
 155    :                   core::ScaleFactor scale,
 156    :                   const Displacement& displ)
 157    :      : reference_(displ.reference_),
 158  E :        operand_(base, index, scale, CopyValue(&reference_, displ.value_)) {
 159  E :  }
 160    :  
 161    :  Operand::Operand(const core::Register32& base,
 162    :                   const core::Register32& index,
 163    :                   core::ScaleFactor scale)
 164  E :      : operand_(base, index, scale) {
 165  E :  }
 166    :  
 167    :  Operand::Operand(const core::Register32& index,
 168    :                   core::ScaleFactor scale,
 169    :                   const Displacement& displ)
 170    :      : reference_(displ.reference_),
 171  E :        operand_(index, scale, CopyValue(&reference_, displ.value_)) {
 172  E :  }
 173    :  
 174    :  Operand::Operand(const Operand& o)
 175    :      : reference_(o.reference_),
 176    :        operand_(o.base(), o.index(), o.scale(),
 177  E :                 CopyValue(&reference_, o.operand_.displacement())) {
 178  E :  }
 179    :  
 180  E :  Operand::~Operand() {
 181    :  #ifndef NDEBUG
 182  E :    if (reference_.IsValid()) {
 183  E :      DCHECK(operand_.displacement().reference() == &reference_);
 184  E :    } else {
 185  E :      DCHECK(operand_.displacement().reference() == NULL);
 186    :    }
 187    :  #endif
 188  E :  }
 189    :  
 190  E :  const Operand& Operand::operator=(const Operand& other) {
 191  E :    reference_ = other.reference_;
 192    :    operand_ =
 193    :        core::OperandImpl(other.base(), other.index(), other.scale(),
 194  E :                          CopyValue(&reference_, other.operand_.displacement()));
 195  E :    return *this;
 196  E :  }
 197    :  
 198    :  BasicBlockAssembler::BasicBlockSerializer::BasicBlockSerializer(
 199    :      const Instructions::iterator& where, Instructions* list)
 200  E :          : where_(where), list_(list), num_ref_infos_(0) {
 201  E :    DCHECK(list != NULL);
 202  E :  }
 203    :  
 204    :  void BasicBlockAssembler::BasicBlockSerializer::AppendInstruction(
 205    :      uint32 location, const uint8* bytes, size_t num_bytes,
 206  E :      const size_t *ref_locations, const void* const* refs, size_t num_refs) {
 207    :    // The number of reference infos we've been provided must match the number of
 208    :    // references we have been given.
 209  E :    DCHECK_EQ(num_ref_infos_, num_refs);
 210    :  
 211  E :    Instruction instruction;
 212  E :    CHECK(Instruction::FromBuffer(bytes, num_bytes, &instruction));
 213  E :    instruction.set_source_range(source_range_);
 214    :  
 215  E :    Instructions::iterator it = list_->insert(where_, instruction);
 216    :  
 217  E :    for (size_t i = 0; i < num_refs; ++i) {
 218    :      const UntypedReference* tref =
 219  E :          reinterpret_cast<const UntypedReference*>(refs[i]);
 220  E :      DCHECK(tref != NULL);
 221    :  
 222    :      BasicBlockReference bbref = CompleteUntypedReference(
 223  E :          ref_infos_[i].type, ref_infos_[i].size, *tref);
 224  E :      DCHECK(bbref.IsValid());
 225  E :      it->SetReference(ref_locations[i], bbref);
 226  E :    }
 227    :  
 228    :    // Clear the reference info for the next instruction.
 229  E :    num_ref_infos_ = 0;
 230  E :  }
 231    :  
 232    :  void BasicBlockAssembler::BasicBlockSerializer::PushReferenceInfo(
 233  E :      BlockGraph::ReferenceType type, core::ValueSize size) {
 234  E :    DCHECK_GT(2u, num_ref_infos_);
 235  E :    ref_infos_[num_ref_infos_].type = type;
 236  E :    ref_infos_[num_ref_infos_].size = ToBytes(size);
 237  E :    ++num_ref_infos_;
 238  E :  }
 239    :  
 240    :  BasicBlockAssembler::BasicBlockAssembler(const Instructions::iterator& where,
 241    :                                           Instructions* list)
 242  E :      : serializer_(where, list), asm_(0, &serializer_) {
 243  E :  }
 244    :  
 245    :  BasicBlockAssembler::BasicBlockAssembler(uint32 location,
 246    :                                           const Instructions::iterator& where,
 247    :                                           Instructions* list)
 248  E :      : serializer_(where, list), asm_(location, &serializer_) {
 249  E :  }
 250    :  
 251  E :  void BasicBlockAssembler::nop(size_t size) {
 252  E :    asm_.nop(size);
 253  E :  }
 254    :  
 255  E :  void BasicBlockAssembler::call(const Immediate& dst) {
 256    :    // In the context of BasicBlockAssembler it only makes sense for calls with
 257    :    // immediate parameters to be backed by a 32-bit reference.
 258  E :    PushMandatoryReferenceInfo(BlockGraph::PC_RELATIVE_REF, dst);
 259  E :    CheckReferenceSize(core::kSize32Bit, dst);
 260  E :    asm_.call(dst.value_);
 261  E :  }
 262    :  
 263  E :  void BasicBlockAssembler::call(const Operand& dst) {
 264    :    // If a call is backed by a reference it must be 32-bit.
 265  E :    PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, dst);
 266  E :    CheckReferenceSize(core::kSize32Bit, dst);
 267  E :    asm_.call(dst.operand_);
 268  E :  }
 269    :  
 270  E :  void BasicBlockAssembler::jmp(const Immediate& dst) {
 271    :    // In the context of BasicBlockAssembler it only makes sense for jumps with
 272    :    // immediate parameters to be backed by a reference.
 273  E :    PushMandatoryReferenceInfo(BlockGraph::PC_RELATIVE_REF, dst);
 274  E :    asm_.jmp(dst.value_);
 275  E :  }
 276    :  
 277  E :  void BasicBlockAssembler::jmp(const Operand& dst) {
 278  E :    PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, dst);
 279  E :    asm_.jmp(dst.operand_);
 280  E :  }
 281    :  
 282  E :  void BasicBlockAssembler::j(ConditionCode code, const Immediate& dst) {
 283    :    // In the context of BasicBlockAssembler it only makes sense for jumps with
 284    :    // immediate parameters to be backed by a reference.
 285  E :    PushMandatoryReferenceInfo(BlockGraph::PC_RELATIVE_REF, dst);
 286  E :    asm_.j(code, dst.value_);
 287  E :  }
 288    :  
 289  E :  void BasicBlockAssembler::set(ConditionCode code, const Register32& dst) {
 290  E :    asm_.set(code, dst);
 291  E :  }
 292    :  
 293  E :  void BasicBlockAssembler::pushfd() {
 294  E :    asm_.pushfd();
 295  E :  }
 296    :  
 297  E :  void BasicBlockAssembler::popfd() {
 298  E :    asm_.popfd();
 299  E :  }
 300    :  
 301  E :  void BasicBlockAssembler::lahf() {
 302  E :    asm_.lahf();
 303  E :  }
 304    :  
 305  E :  void BasicBlockAssembler::sahf() {
 306  E :    asm_.sahf();
 307  E :  }
 308    :  
 309  E :  void BasicBlockAssembler::test(const Register8& dst, const Register8& src) {
 310  E :    asm_.test(dst, src);
 311  E :  }
 312    :  
 313  E :  void BasicBlockAssembler::test(const Register8& dst, const Immediate& src) {
 314  E :    PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
 315  E :    asm_.test(dst, src.value_);
 316  E :  }
 317    :  
 318  E :  void BasicBlockAssembler::test(const Register32& dst, const Register32& src) {
 319  E :    asm_.test(dst, src);
 320  E :  }
 321    :  
 322    :  void BasicBlockAssembler::test(const Register32& dst, const Operand& src) {
 323    :    PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
 324    :    asm_.test(dst, src.operand_);
 325    :  }
 326    :  
 327    :  void BasicBlockAssembler::test(const Operand& dst, const Register32& src) {
 328    :    PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, dst);
 329    :    asm_.test(dst.operand_, src);
 330    :  }
 331    :  
 332  E :  void BasicBlockAssembler::test(const Register32& dst, const Immediate& src) {
 333  E :    PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
 334  E :    asm_.test(dst, src.value_);
 335  E :  }
 336    :  
 337  E :  void BasicBlockAssembler::test(const Operand&  dst, const Immediate& src) {
 338  E :    PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, dst);
 339  E :    PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
 340  E :    asm_.test(dst.operand_, src.value_);
 341  E :  }
 342    :  
 343  E :  void BasicBlockAssembler::cmp(const Register8& dst, const Register8& src) {
 344  E :    asm_.cmp(dst, src);
 345  E :  }
 346    :  
 347  E :  void BasicBlockAssembler::cmp(const Register8& dst, const Immediate& src) {
 348  E :    PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
 349  E :    asm_.cmp(dst, src.value_);
 350  E :  }
 351    :  
 352  E :  void BasicBlockAssembler::cmp(const Register32& dst, const Register32& src) {
 353  E :    asm_.cmp(dst, src);
 354  E :  }
 355    :  
 356    :  void BasicBlockAssembler::cmp(const Register32& dst, const Operand& src) {
 357    :    PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
 358    :    asm_.cmp(dst, src.operand_);
 359    :  }
 360    :  
 361    :  void BasicBlockAssembler::cmp(const Operand& dst, const Register32& src) {
 362    :    PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, dst);
 363    :    asm_.cmp(dst.operand_, src);
 364    :  }
 365    :  
 366  E :  void BasicBlockAssembler::cmp(const Register32& dst, const Immediate& src) {
 367  E :    PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
 368  E :    asm_.cmp(dst, src.value_);
 369  E :  }
 370    :  
 371  E :  void BasicBlockAssembler::cmp(const Operand&  dst, const Immediate& src) {
 372  E :    PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, dst);
 373  E :    PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
 374  E :    asm_.cmp(dst.operand_, src.value_);
 375  E :  }
 376    :  
 377  E :  void BasicBlockAssembler::add(const Register8& dst, const Register8& src) {
 378  E :    asm_.add(dst, src);
 379  E :  }
 380    :  
 381  E :  void BasicBlockAssembler::add(const Register8& dst, const Immediate& src) {
 382  E :    PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
 383  E :    asm_.add(dst, src.value_);
 384  E :  }
 385    :  
 386  E :  void BasicBlockAssembler::add(const Register32& dst, const Register32& src) {
 387  E :    asm_.add(dst, src);
 388  E :  }
 389    :  
 390    :  void BasicBlockAssembler::add(const Register32& dst, const Operand& src) {
 391    :    PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
 392    :    asm_.add(dst, src.operand_);
 393    :  }
 394    :  
 395    :  void BasicBlockAssembler::add(const Operand& dst, const Register32& src) {
 396    :    PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, dst);
 397    :    asm_.add(dst.operand_, src);
 398    :  }
 399    :  
 400  E :  void BasicBlockAssembler::add(const Register32& dst, const Immediate& src) {
 401  E :    PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
 402  E :    asm_.add(dst, src.value_);
 403  E :  }
 404    :  
 405  E :  void BasicBlockAssembler::add(const Operand& dst, const Immediate& src) {
 406  E :    PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, dst);
 407  E :    PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
 408  E :    asm_.add(dst.operand_, src.value_);
 409  E :  }
 410    :  
 411  E :  void BasicBlockAssembler::sub(const Register8& dst, const Register8& src) {
 412  E :    asm_.sub(dst, src);
 413  E :  }
 414    :  
 415  E :  void BasicBlockAssembler::sub(const Register8& dst, const Immediate& src) {
 416  E :    PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
 417  E :    asm_.sub(dst, src.value_);
 418  E :  }
 419    :  
 420  E :  void BasicBlockAssembler::sub(const Register32& dst, const Register32& src) {
 421  E :    asm_.sub(dst, src);
 422  E :  }
 423    :  
 424    :  void BasicBlockAssembler::sub(const Register32& dst, const Operand& src) {
 425    :    PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
 426    :    asm_.sub(dst, src.operand_);
 427    :  }
 428    :  
 429    :  void BasicBlockAssembler::sub(const Operand& dst, const Register32& src) {
 430    :    PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, dst);
 431    :    asm_.sub(dst.operand_, src);
 432    :  }
 433    :  
 434  E :  void BasicBlockAssembler::sub(const Register32& dst, const Immediate& src) {
 435  E :    PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
 436  E :    asm_.sub(dst, src.value_);
 437  E :  }
 438    :  
 439  E :  void BasicBlockAssembler::sub(const Operand& dst, const Immediate& src) {
 440  E :    PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, dst);
 441  E :    PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
 442  E :    asm_.sub(dst.operand_, src.value_);
 443  E :  }
 444    :  
 445  E :  void BasicBlockAssembler::shl(const Register32& dst, const Immediate& src) {
 446  E :    PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
 447  E :    asm_.shl(dst, src.value_);
 448  E :  }
 449    :  
 450  E :  void BasicBlockAssembler::shr(const Register32& dst, const Immediate& src) {
 451  E :    PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
 452  E :    asm_.shr(dst, src.value_);
 453  E :  }
 454    :  
 455  E :  void BasicBlockAssembler::mov_b(const Operand& dst, const Immediate& src) {
 456  E :    PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, dst);
 457  E :    PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
 458  E :    CheckReferenceSize(core::kSize32Bit, dst);
 459  E :    CheckReferenceSize(core::kSize32Bit, src);
 460  E :    asm_.mov_b(dst.operand_, src.value_);
 461  E :  }
 462    :  
 463  E :  void BasicBlockAssembler::movzx_b(const Register32& dst, const Operand& src) {
 464  E :    PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
 465  E :    CheckReferenceSize(core::kSize32Bit, src);
 466  E :    asm_.movzx_b(dst, src.operand_);
 467  E :  }
 468    :  
 469  E :  void BasicBlockAssembler::mov(const Register32& dst, const Register32& src) {
 470  E :    asm_.mov(dst, src);
 471  E :  }
 472    :  
 473  E :  void BasicBlockAssembler::mov(const Register32& dst, const Operand& src) {
 474  E :    PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
 475  E :    CheckReferenceSize(core::kSize32Bit, src);
 476  E :    asm_.mov(dst, src.operand_);
 477  E :  }
 478    :  
 479  E :  void BasicBlockAssembler::mov(const Operand& dst, const Register32& src) {
 480  E :    PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, dst);
 481  E :    CheckReferenceSize(core::kSize32Bit, dst);
 482  E :    asm_.mov(dst.operand_, src);
 483  E :  }
 484    :  
 485  E :  void BasicBlockAssembler::mov(const Register32& dst, const Immediate& src) {
 486  E :    PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
 487  E :    CheckReferenceSize(core::kSize32Bit, src);
 488  E :    asm_.mov(dst, src.value_);
 489  E :  }
 490    :  
 491  E :  void BasicBlockAssembler::mov(const Operand& dst, const Immediate& src) {
 492  E :    PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, dst);
 493  E :    PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
 494  E :    CheckReferenceSize(core::kSize32Bit, dst);
 495  E :    CheckReferenceSize(core::kSize32Bit, src);
 496  E :    asm_.mov(dst.operand_, src.value_);
 497  E :  }
 498    :  
 499  E :  void BasicBlockAssembler::mov_fs(const Register32& dst, const Operand& src) {
 500  E :    PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
 501  E :    CheckReferenceSize(core::kSize32Bit, src);
 502  E :    asm_.mov_fs(dst, src.operand_);
 503  E :  }
 504    :  
 505  E :  void BasicBlockAssembler::mov_fs(const Operand& dst, const Register32& src) {
 506  E :    PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, dst);
 507  E :    CheckReferenceSize(core::kSize32Bit, dst);
 508  E :    asm_.mov_fs(dst.operand_, src);
 509  E :  }
 510    :  
 511  E :  void BasicBlockAssembler::lea(const Register32& dst, const Operand& src) {
 512  E :    PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
 513  E :    CheckReferenceSize(core::kSize32Bit, src);
 514  E :    asm_.lea(dst, src.operand_);
 515  E :  }
 516    :  
 517  E :  void BasicBlockAssembler::push(const Register32& src) {
 518  E :    asm_.push(src);
 519  E :  }
 520    :  
 521  E :  void BasicBlockAssembler::push(const Immediate& src) {
 522  E :    PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
 523  E :    CheckReferenceSize(core::kSize32Bit, src);
 524  E :    asm_.push(src.value_);
 525  E :  }
 526    :  
 527  E :  void BasicBlockAssembler::push(const Operand& src) {
 528  E :    PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
 529  E :    CheckReferenceSize(core::kSize32Bit, src);
 530  E :    asm_.push(src.operand_);
 531  E :  }
 532    :  
 533  E :  void BasicBlockAssembler::pop(const Register32& dst) {
 534  E :    asm_.pop(dst);
 535  E :  }
 536    :  
 537  E :  void BasicBlockAssembler::pop(const Operand& dst) {
 538  E :    PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, dst);
 539  E :    CheckReferenceSize(core::kSize32Bit, dst);
 540  E :    asm_.pop(dst.operand_);
 541  E :  }
 542    :  
 543  E :  void BasicBlockAssembler::ret() {
 544  E :    asm_.ret();
 545  E :  }
 546    :  
 547  E :  void BasicBlockAssembler::ret(uint16 n) {
 548  E :    asm_.ret(n);
 549  E :  }
 550    :  
 551  E :  void BasicBlockAssembler::xchg(const Register32& dst, const Register32& src) {
 552  E :    asm_.xchg(dst, src);
 553  E :  }
 554    :  
 555  E :  void BasicBlockAssembler::xchg(const Register16& dst, const Register16& src) {
 556  E :    asm_.xchg(dst, src);
 557  E :  }
 558    :  
 559  E :  void BasicBlockAssembler::xchg(const Register8& dst, const Register8& src) {
 560  E :    asm_.xchg(dst, src);
 561  E :  }
 562    :  
 563    :  void BasicBlockAssembler::PushMandatoryReferenceInfo(
 564  E :      ReferenceType type, const Immediate& imm) {
 565  E :    DCHECK(imm.value_.reference() != NULL);
 566  E :    serializer_.PushReferenceInfo(type, imm.value_.size());
 567  E :  }
 568    :  
 569    :  void BasicBlockAssembler::PushOptionalReferenceInfo(
 570  E :      ReferenceType type, const Immediate& imm) {
 571  E :    if (imm.value_.reference() == NULL)
 572  E :      return;
 573  E :    serializer_.PushReferenceInfo(type, imm.value_.size());
 574  E :  }
 575    :  
 576    :  void BasicBlockAssembler::PushOptionalReferenceInfo(
 577  E :      ReferenceType type, const Operand& op) {
 578  E :    if (op.operand_.displacement().reference() == NULL)
 579  E :      return;
 580  E :    serializer_.PushReferenceInfo(type, op.operand_.displacement().size());
 581  E :  }
 582    :  
 583    :  void BasicBlockAssembler::CheckReferenceSize(
 584  E :      core::ValueSize size, const Immediate& imm) const {
 585  E :    DCHECK(imm.value_.reference() == NULL || imm.value_.size() == size);
 586  E :  }
 587    :  
 588    :  void BasicBlockAssembler::CheckReferenceSize(
 589  E :      core::ValueSize size, const Operand& op) const {
 590    :    DCHECK(op.operand_.displacement().reference() == NULL ||
 591  E :           op.operand_.displacement().size() == size);
 592  E :  }
 593    :  
 594    :  }  // namespace block_graph

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