Coverage for /Syzygy/block_graph/basic_block_assembler.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
99.3%1401410.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  E :  core::ValueSize ValueSizeFromConstant(uint32 input_value) {
  22    :    // IA32 assembly may/will sign-extend 8-bit literals, so we attempt to encode
  23    :    // in 8 bits only those literals whose value will be unchanged by that
  24    :    // treatment.
  25  E :    input_value |= 0x7F;
  26    :  
  27  E :    if (input_value == 0xFFFFFFFF || input_value == 0x7F)
  28  E :      return core::kSize8Bit;
  29    :  
  30  E :    return core::kSize32Bit;
  31  E :  }
  32    :  
  33    :  core::ValueImpl CopyValue(const BasicBlockReference* ref,
  34  E :                            const core::ValueImpl& value) {
  35    :    return core::ValueImpl(value.value(),
  36    :                           value.size(),
  37  E :                           value.reference() ? ref : NULL);
  38  E :  }
  39    :  
  40    :  }  // namespace
  41    :  
  42  E :  Value::Value() {
  43  E :  }
  44    :  
  45  E :  Value::Value(uint32 value) : value_(value, ValueSizeFromConstant(value)) {
  46  E :  }
  47    :  
  48  E :  Value::Value(uint32 value, core::ValueSize size) : value_(value, size) {
  49  E :  }
  50    :  
  51    :  Value::Value(BasicBlock* bb)
  52    :      : reference_(BlockGraph::ABSOLUTE_REF, sizeof(core::AbsoluteAddress), bb),
  53  E :        value_(0, core::kSize32Bit, &reference_) {
  54  E :  }
  55    :  
  56    :  Value::Value(BlockGraph::Block* block, BlockGraph::Offset offset)
  57    :      : reference_(BlockGraph::ABSOLUTE_REF, sizeof(core::AbsoluteAddress),
  58    :                   block, offset, 0),
  59  E :        value_(0, core::kSize32Bit, &reference_) {
  60  E :  }
  61    :  
  62    :  Value::Value(uint32 value, ValueSize size, const BasicBlockReference& ref)
  63  E :      : reference_(ref), value_(value, size, &reference_) {
  64  E :  }
  65    :  
  66    :  Value::Value(const Value& o)
  67  E :      : reference_(o.reference()), value_(CopyValue(&reference_, o.value_)) {
  68  E :  }
  69    :  
  70    :  Value::Value(const BasicBlockReference& ref, const core::ValueImpl& value)
  71  E :      : reference_(ref), value_(CopyValue(&reference_, value)) {
  72  E :  }
  73    :  
  74  E :  Value::~Value() {
  75    :  #ifndef NDEBUG
  76  E :    if (reference_.IsValid()) {
  77  E :      DCHECK(value_.reference() == &reference_);
  78  E :    } else {
  79  E :      DCHECK(value_.reference() == NULL);
  80    :    }
  81    :  #endif
  82  E :  }
  83    :  
  84  E :  const Value& Value::operator=(const Value& other) {
  85  E :    reference_ = other.reference_;
  86  E :    value_ = CopyValue(&reference_, other.value_);
  87  E :    return *this;
  88  E :  }
  89    :  
  90  E :  bool Value::operator==(const Value& rhs) const {
  91  E :    if (reference_.IsValid())
  92  i :      return reference_ == rhs.reference();
  93  E :    return value_ == rhs.value_;
  94  E :  }
  95    :  
  96  E :  Operand::Operand(core::Register base) : operand_(base) {
  97  E :  }
  98    :  
  99    :  Operand::Operand(core::Register base, const Displacement& displ)
 100    :      : reference_(displ.reference()),
 101  E :        operand_(base, CopyValue(&reference_, displ.value_)) {
 102  E :  }
 103    :  
 104    :  Operand::Operand(const Displacement& displ)
 105    :      : reference_(displ.reference()),
 106  E :        operand_(CopyValue(&reference_, displ.value_)) {
 107  E :  }
 108    :  
 109    :  Operand::Operand(core::Register base,
 110    :                   core::Register index,
 111    :                   core::ScaleFactor scale,
 112    :                   const Displacement& displ)
 113    :      : reference_(displ.reference_),
 114  E :        operand_(base, index, scale, CopyValue(&reference_, displ.value_)) {
 115  E :  }
 116    :  
 117    :  Operand::Operand(core::Register base,
 118    :                   core::Register index,
 119    :                   core::ScaleFactor scale)
 120  E :      : operand_(base, index, scale) {
 121  E :  }
 122    :  
 123    :  Operand::Operand(core::Register index,
 124    :                   core::ScaleFactor scale,
 125    :                   const Displacement& displ)
 126    :      : reference_(displ.reference_),
 127  E :        operand_(index, scale, CopyValue(&reference_, displ.value_)) {
 128  E :  }
 129    :  
 130    :  Operand::Operand(const Operand& o)
 131    :      : reference_(o.reference_),
 132    :        operand_(o.base(), o.index(), o.scale(),
 133  E :                 CopyValue(&reference_, o.operand_.displacement())) {
 134  E :  }
 135    :  
 136  E :  Operand::~Operand() {
 137    :  #ifndef NDEBUG
 138  E :    if (reference_.IsValid()) {
 139  E :      DCHECK(operand_.displacement().reference() == &reference_);
 140  E :    } else {
 141  E :      DCHECK(operand_.displacement().reference() == NULL);
 142    :    }
 143    :  #endif
 144  E :  }
 145    :  
 146  E :  const Operand& Operand::operator=(const Operand& other) {
 147  E :    reference_ = other.reference_;
 148    :    operand_ =
 149    :        core::OperandImpl(other.base(), other.index(), other.scale(),
 150  E :                          CopyValue(&reference_, other.operand_.displacement()));
 151  E :    return *this;
 152  E :  }
 153    :  
 154    :  BasicBlockAssembler::BasicBlockSerializer::BasicBlockSerializer(
 155    :      const Instructions::iterator& where, Instructions* list)
 156  E :          : where_(where), list_(list) {
 157  E :    DCHECK(list != NULL);
 158  E :  }
 159    :  
 160    :  void BasicBlockAssembler::BasicBlockSerializer::AppendInstruction(
 161    :      uint32 location, const uint8* bytes, size_t num_bytes,
 162  E :      const size_t *ref_locations, const void* const* refs, size_t num_refs) {
 163  E :    Instruction instruction;
 164  E :    CHECK(Instruction::FromBuffer(bytes, num_bytes, &instruction));
 165  E :    instruction.set_source_range(source_range_);
 166    :  
 167  E :    Instructions::iterator it = list_->insert(where_, instruction);
 168    :  
 169  E :    for (size_t i = 0; i < num_refs; ++i) {
 170    :      const BasicBlockReference* ref =
 171  E :          reinterpret_cast<const BasicBlockReference*>(refs[i]);
 172  E :      DCHECK(ref != NULL);
 173    :  
 174  E :      it->SetReference(ref_locations[i], *ref);
 175  E :    }
 176  E :  }
 177    :  
 178    :  BasicBlockAssembler::BasicBlockAssembler(const Instructions::iterator& where,
 179    :                                           Instructions* list)
 180  E :      : serializer_(where, list), asm_(0, &serializer_) {
 181  E :  }
 182    :  
 183    :  BasicBlockAssembler::BasicBlockAssembler(uint32 location,
 184    :                                           const Instructions::iterator& where,
 185    :                                           Instructions* list)
 186  E :      : serializer_(where, list), asm_(location, &serializer_) {
 187  E :  }
 188    :  
 189  E :  void BasicBlockAssembler::call(const Immediate& dst) {
 190  E :    asm_.call(dst.value_);
 191  E :  }
 192    :  
 193  E :  void BasicBlockAssembler::call(const Operand& dst) {
 194  E :    asm_.call(dst.operand_);
 195  E :  }
 196    :  
 197  E :  void BasicBlockAssembler::jmp(const Immediate& dst) {
 198  E :    asm_.jmp(dst.value_);
 199  E :  }
 200    :  
 201  E :  void BasicBlockAssembler::jmp(const Operand& dst) {
 202  E :    asm_.jmp(dst.operand_);
 203  E :  }
 204    :  
 205  E :  void BasicBlockAssembler::j(ConditionCode code, const Immediate& dst) {
 206  E :    asm_.j(code, dst.value_);
 207  E :  }
 208    :  
 209  E :  void BasicBlockAssembler::mov_b(const Operand& dst, const Immediate& src) {
 210  E :    asm_.mov_b(dst.operand_, src.value_);
 211  E :  }
 212    :  
 213  E :  void BasicBlockAssembler::mov(Register dst, Register src) {
 214  E :    asm_.mov(dst, src);
 215  E :  }
 216    :  
 217  E :  void BasicBlockAssembler::mov(Register dst, const Operand& src) {
 218  E :    asm_.mov(dst, src.operand_);
 219  E :  }
 220    :  
 221  E :  void BasicBlockAssembler::mov(const Operand& dst, Register src) {
 222  E :    asm_.mov(dst.operand_, src);
 223  E :  }
 224    :  
 225  E :  void BasicBlockAssembler::mov(Register dst, const Immediate& src) {
 226  E :    asm_.mov(dst, src.value_);
 227  E :  }
 228    :  
 229  E :  void BasicBlockAssembler::mov(const Operand& dst, const Immediate& src) {
 230  E :    asm_.mov(dst.operand_, src.value_);
 231  E :  }
 232    :  
 233  E :  void BasicBlockAssembler::lea(Register dst, const Operand& src) {
 234  E :    asm_.lea(dst, src.operand_);
 235  E :  }
 236    :  
 237  E :  void BasicBlockAssembler::push(Register src) {
 238  E :    asm_.push(src);
 239  E :  }
 240    :  
 241  E :  void BasicBlockAssembler::push(const Immediate& src) {
 242  E :    asm_.push(src.value_);
 243  E :  }
 244    :  
 245  E :  void BasicBlockAssembler::push(const Operand& src) {
 246  E :    asm_.push(src.operand_);
 247  E :  }
 248    :  
 249  E :  void BasicBlockAssembler::pop(Register src) {
 250  E :    asm_.pop(src);
 251  E :  }
 252    :  
 253  E :  void BasicBlockAssembler::pop(const Operand& src) {
 254  E :    asm_.pop(src.operand_);
 255  E :  }
 256    :  
 257  E :  void BasicBlockAssembler::ret() {
 258  E :    asm_.ret();
 259  E :  }
 260    :  
 261  E :  void BasicBlockAssembler::ret(uint16 n) {
 262  E :    asm_.ret(n);
 263  E :  }
 264    :  
 265    :  }  // namespace block_graph

Coverage information generated Thu Mar 14 11:53:36 2013.