Coverage for /Syzygy/core/assembler.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
100.0%5475470.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/core/assembler.h"
  16    :  
  17    :  #include <limits>
  18    :  
  19    :  #include "base/logging.h"
  20    :  
  21    :  namespace core {
  22    :  
  23  E :  const Register eax(kRegisterEax);
  24  E :  const Register ecx(kRegisterEcx);
  25  E :  const Register edx(kRegisterEdx);
  26  E :  const Register ebx(kRegisterEbx);
  27  E :  const Register esp(kRegisterEsp);
  28  E :  const Register ebp(kRegisterEbp);
  29  E :  const Register esi(kRegisterEsi);
  30  E :  const Register edi(kRegisterEdi);
  31    :  
  32    :  namespace {
  33    :  
  34    :  enum Mod {
  35    :    Reg1Ind = 0,  // Register indirect mode.
  36    :    Reg1ByteDisp = 1,  // Register + byte displacement.
  37    :    Reg1WordDisp = 2,  // Register + word displacement.
  38    :    Reg1 = 3,  // Register + word displacement.
  39    :  };
  40    :  
  41    :  const uint8 kTwoByteOpCodePrefix = 0x0F;
  42    :  const uint8 kFsSegmentPrefix = 0x64;
  43    :  
  44    :  // Returns true if @p operand is a displacement only - e.g.
  45    :  // specifies neither a base, nor an index register.
  46  E :  bool IsDisplacementOnly(const OperandImpl& operand) {
  47    :    return operand.displacement().size() != kSizeNone &&
  48    :        operand.base() == kRegisterNone &&
  49  E :        operand.index() == kRegisterNone;
  50  E :  }
  51    :  
  52    :  }  // namespace
  53    :  
  54    :  const size_t AssemblerImpl::kShortBranchOpcodeSize = 1;
  55    :  const size_t AssemblerImpl::kShortBranchSize = kShortBranchOpcodeSize + 1;
  56    :  
  57    :  const size_t AssemblerImpl::kLongBranchOpcodeSize = 2;
  58    :  const size_t AssemblerImpl::kLongBranchSize = kLongBranchOpcodeSize + 4;
  59    :  
  60    :  const size_t AssemblerImpl::kShortJumpOpcodeSize = 1;
  61    :  const size_t AssemblerImpl::kShortJumpSize = kShortJumpOpcodeSize + 1;
  62    :  
  63    :  const size_t AssemblerImpl::kLongJumpOpcodeSize = 1;
  64    :  const size_t AssemblerImpl::kLongJumpSize = kLongJumpOpcodeSize + 4;
  65    :  
  66    :  OperandImpl::OperandImpl(Register base)
  67    :      : base_(base.code()),
  68    :        index_(kRegisterNone),
  69  E :        scale_(kTimes1) {
  70  E :  }
  71    :  
  72    :  OperandImpl::OperandImpl(Register base,
  73    :                           const DisplacementImpl& displacement)
  74    :      : base_(base.code()),
  75    :        index_(kRegisterNone),
  76    :        scale_(kTimes1),
  77  E :        displacement_(displacement) {
  78    :    // There must be a base register.
  79  E :    DCHECK_NE(kRegisterNone, base_);
  80  E :  }
  81    :  
  82    :  OperandImpl::OperandImpl(const DisplacementImpl& displacement)
  83    :      : base_(kRegisterNone),
  84    :        index_(kRegisterNone),
  85    :        scale_(kTimes1),
  86  E :        displacement_(displacement) {
  87  E :    DCHECK_NE(kSizeNone, displacement.size());
  88  E :  }
  89    :  
  90    :  OperandImpl::OperandImpl(Register base,
  91    :                           Register index,
  92    :                           ScaleFactor scale,
  93    :                           const DisplacementImpl& displacement)
  94    :      : base_(base.code()),
  95    :        index_(index.code()),
  96    :        scale_(scale),
  97  E :        displacement_(displacement) {
  98    :    // ESP cannot be used as an index register.
  99  E :    DCHECK_NE(kRegisterEsp, index.code());
 100  E :    DCHECK_NE(kSizeNone, displacement.size());
 101  E :  }
 102    :  
 103    :  OperandImpl::OperandImpl(Register base,
 104    :                           Register index,
 105    :                           ScaleFactor scale)
 106    :      : base_(base.code()),
 107    :        index_(index.code()),
 108  E :        scale_(scale) {
 109    :    // ESP cannot be used as an index register.
 110  E :    DCHECK_NE(kRegisterEsp, index.code());
 111  E :    DCHECK_EQ(kSizeNone, displacement_.size());
 112  E :  }
 113    :  
 114    :  OperandImpl::OperandImpl(Register index,
 115    :                           ScaleFactor scale,
 116    :                           const DisplacementImpl& displacement)
 117    :      : base_(kRegisterNone),
 118    :        index_(index.code()),
 119    :        scale_(scale),
 120  E :        displacement_(displacement) {
 121    :    // ESP cannot be used as an index register.
 122  E :    DCHECK_NE(kRegisterEsp, index.code());
 123  E :    DCHECK_NE(kSizeNone, displacement.size());
 124  E :  }
 125    :  
 126    :  OperandImpl::OperandImpl(RegisterCode base,
 127    :                           RegisterCode index,
 128    :                           ScaleFactor scale,
 129    :                           const DisplacementImpl& displacement)
 130    :      : base_(base),
 131    :        index_(index),
 132    :        scale_(scale),
 133  E :        displacement_(displacement) {
 134  E :  }
 135    :  
 136    :  ValueImpl::ValueImpl()
 137  E :      : value_(0), reference_(NULL), size_(kSizeNone) {
 138  E :  }
 139    :  
 140    :  ValueImpl::ValueImpl(uint32 value, ValueSize size)
 141  E :      : value_(value), reference_(NULL), size_(size) {
 142  E :  }
 143    :  
 144    :  ValueImpl::ValueImpl(uint32 value,
 145    :                       ValueSize size,
 146    :                       const void* value_ref)
 147  E :      : value_(value), reference_(value_ref), size_(size) {
 148  E :  }
 149    :  
 150  E :  bool ValueImpl::operator==(const ValueImpl& rhs) const {
 151    :    return value_ == rhs.value_ &&
 152    :        reference_ == rhs.reference_ &&
 153  E :        size_ == rhs.size_;
 154  E :  }
 155    :  
 156    :  // This class is used to buffer a single instruction during it's creation.
 157    :  // TODO(siggi): Add a small state machine in debug mode to ensure the
 158    :  //     correct order of invocation to opcode/modrm etc.
 159    :  class AssemblerImpl::InstructionBuffer {
 160    :   public:
 161    :    explicit InstructionBuffer(AssemblerImpl* assm);
 162    :    ~InstructionBuffer();
 163    :  
 164    :    // @name Accessors.
 165    :    // @{
 166  E :    size_t len() const { return len_; }
 167  E :    const uint8* buf() const { return buf_; }
 168  E :    size_t num_references() const { return num_references_; }
 169  E :    const size_t *reference_offsets() const { return reference_offsets_; }
 170  E :    const void*const* references() const { return references_; }
 171    :    // @}
 172    :  
 173    :    // Emit an opcode byte.
 174    :    void EmitOpCodeByte(uint8 opcode);
 175    :    // Emit a ModR/M byte, reg_op is either a register or an opcode
 176    :    // extension, as fits the instruction being generated.
 177    :    void EmitModRMByte(Mod mod, uint8 reg_op, RegisterCode reg1);
 178    :    // Emit a SIB byte.
 179    :    void EmitScaleIndexBaseByte(ScaleFactor scale,
 180    :                                RegisterCode index,
 181    :                                RegisterCode base);
 182    :    // Emit an operand.
 183    :    void EmitOperand(uint8 reg_op, const OperandImpl& op);
 184    :  
 185    :    // Emit an 8-bit displacement, with optional reference info.
 186    :    void Emit8BitDisplacement(const DisplacementImpl& disp);
 187    :  
 188    :    // Emit a 32-bit displacement with optional reference info.
 189    :    void Emit32BitDisplacement(const DisplacementImpl& disp);
 190    :  
 191    :    // Emit an 8-bit PC-relative value.
 192    :    void Emit8BitPCRelative(uint32 location, const ValueImpl& disp);
 193    :  
 194    :    // Emit a 32-bit PC-relative value.
 195    :    void Emit32BitPCRelative(uint32 location, const ValueImpl& disp);
 196    :  
 197    :    // Emit a 16-bit immediate value.
 198    :    void Emit16BitValue(uint16 value);
 199    :  
 200    :    // Emit an arithmetic instruction with various encoding.
 201    :    void EmitArithmeticInstruction(uint8 op, Register dst, Register src);
 202    :    void EmitArithmeticInstruction(
 203    :        uint8 op, Register dst, const OperandImpl& src);
 204    :    void EmitArithmeticInstruction(
 205    :        uint8 op, const OperandImpl& dst, Register src);
 206    :    void EmitArithmeticInstructionToRegister(uint8 op_eax, uint8 op_8,
 207    :        uint8 op_32, uint8 sub_op, Register dst, const ImmediateImpl& src);
 208    :    void EmitArithmeticInstructionToRegister8bit(uint8 op_eax, uint8 op_8,
 209    :        uint8 sub_op, Register dst, const ImmediateImpl& src);
 210    :    void EmitArithmeticInstructionToOperand(uint8 op_8, uint8 op_32, uint8 sub_op,
 211    :        const OperandImpl& dst, const ImmediateImpl& src);
 212    :  
 213    :    // Add reference at current location.
 214    :    void AddReference(const void* reference);
 215    :  
 216    :   protected:
 217    :    void EmitByte(uint8 byte);
 218    :  
 219    :    AssemblerImpl* asm_;
 220    :    size_t num_references_;
 221    :    const void* (references_)[2];
 222    :    size_t reference_offsets_[2];
 223    :    size_t len_;
 224    :    uint8 buf_[kMaxInstructionLength];
 225    :  };
 226    :  
 227    :  AssemblerImpl::InstructionBuffer::InstructionBuffer(AssemblerImpl* assm)
 228  E :      : asm_(assm), len_(0), num_references_(0) {
 229  E :    DCHECK(assm != NULL);
 230    :  #ifndef NDEBUG
 231    :    // Initialize the buffer in debug mode for easier debugging.
 232  E :    ::memset(buf_, 0xCC, sizeof(buf_));
 233    :  #endif
 234  E :  }
 235    :  
 236  E :  AssemblerImpl::InstructionBuffer::~InstructionBuffer() {
 237  E :    asm_->Output(*this);
 238  E :  }
 239    :  
 240  E :  void AssemblerImpl::InstructionBuffer::EmitOpCodeByte(uint8 opcode) {
 241  E :    EmitByte(opcode);
 242  E :  }
 243    :  
 244    :  void AssemblerImpl::InstructionBuffer::EmitModRMByte(
 245  E :      Mod mod, uint8 reg_op, RegisterCode reg1) {
 246  E :    DCHECK_LE(reg_op, 8);
 247  E :    DCHECK_NE(kRegisterNone, reg1);
 248    :  
 249  E :    EmitByte((mod << 6) | (reg_op << 3) | reg1);
 250  E :  }
 251    :  
 252    :  void AssemblerImpl::InstructionBuffer::EmitScaleIndexBaseByte(
 253  E :      ScaleFactor scale, RegisterCode index, RegisterCode base) {
 254  E :    DCHECK_NE(kRegisterNone, index);
 255  E :    DCHECK_NE(kRegisterNone, base);
 256    :  
 257  E :    EmitByte((scale << 6) | (index << 3) | base);
 258  E :  }
 259    :  
 260    :  void AssemblerImpl::InstructionBuffer::EmitOperand(
 261  E :      uint8 reg_op, const OperandImpl& op) {
 262  E :    DCHECK_GE(8, reg_op);
 263    :  
 264    :    // The op operand can encode any one of the following things:
 265    :    // An indirect register access [EAX].
 266    :    // An indirect 32-bit displacement only [0xDEADBEEF].
 267    :    // An indirect base register + 32/8-bit displacement [EAX+0xDEADBEEF].
 268    :    // An indirect base + index register*scale [EAX+ECX*4].
 269    :    // An indirect base + index register*scale + 32/8-bit displacement
 270    :    //   [EAX+ECX*4+0xDEADBEEF].
 271    :    // To complicate things, there are certain combinations that can't be encoded
 272    :    // canonically. The mode [ESP] or [ESP+disp] can never be encoded in a
 273    :    // ModR/M byte alone, as ESP in the ModR/M byte for any of the indirect modes
 274    :    // is overloaded to select the SIB representation.
 275    :    // Likewise [EBP] is overloaded to encode the [disp32] case.
 276    :    // See e.g. http://ref.x86asm.net/geek32-abc.html#modrm_byte_32 for a nice
 277    :    // overview table of the ModR/M byte encoding.
 278    :  
 279    :    // ESP can never be used as an index register on X86.
 280  E :    DCHECK_NE(kRegisterEsp, op.index());
 281    :  
 282    :    // Is there an index register?
 283  E :    if (op.index() == kRegisterNone) {
 284  E :      DCHECK_EQ(kTimes1, op.scale());
 285    :  
 286    :      // No index register, is there a base register?
 287  E :      if (op.base() == kRegisterNone) {
 288    :        // No base register, this is a displacement only.
 289  E :        DCHECK_NE(kSizeNone, op.displacement().size());
 290  E :        DCHECK_EQ(kTimes1, op.scale());
 291    :  
 292    :        // The [disp32] mode is encoded by overloading [EBP].
 293  E :        EmitModRMByte(Reg1Ind, reg_op, kRegisterEbp);
 294  E :        Emit32BitDisplacement(op.displacement());
 295  E :      } else {
 296    :        // Base register only, is it ESP?
 297  E :        if (op.base() == kRegisterEsp) {
 298    :          // The [ESP] and [ESP+disp] cases cannot be encoded without a SIB byte.
 299  E :          if (op.displacement().size() == kSizeNone) {
 300  E :            EmitModRMByte(Reg1Ind, reg_op, kRegisterEsp);
 301  E :            EmitScaleIndexBaseByte(kTimes1, kRegisterEsp, kRegisterEsp);
 302  E :          } else if (op.displacement().size() == kSize8Bit) {
 303  E :            EmitModRMByte(Reg1ByteDisp, reg_op, kRegisterEsp);
 304  E :            EmitScaleIndexBaseByte(kTimes1, kRegisterEsp, kRegisterEsp);
 305  E :            Emit8BitDisplacement(op.displacement());
 306  E :          } else {
 307  E :            DCHECK_EQ(kSize32Bit, op.displacement().size());
 308  E :            EmitModRMByte(Reg1WordDisp, reg_op, kRegisterEsp);
 309  E :            EmitScaleIndexBaseByte(kTimes1, kRegisterEsp, kRegisterEsp);
 310  E :            Emit32BitDisplacement(op.displacement());
 311  E :          }
 312  E :        } else if (op.displacement().size() == kSizeNone) {
 313  E :          if (op.base() == kRegisterEbp) {
 314    :            // The [EBP] case cannot be encoded canonically, there always must
 315    :            // be a (zero) displacement.
 316  E :            EmitModRMByte(Reg1ByteDisp, reg_op, op.base());
 317  E :            Emit8BitDisplacement(DisplacementImpl(0, kSize8Bit, NULL));
 318  E :          } else {
 319  E :            EmitModRMByte(Reg1Ind, reg_op, op.base());
 320  E :          }
 321  E :        } else if (op.displacement().size() == kSize8Bit) {
 322    :          // It's [base+disp8], or possibly [EBP].
 323  E :          EmitModRMByte(Reg1ByteDisp, reg_op, op.base());
 324  E :          Emit8BitDisplacement(op.displacement());
 325  E :        } else {
 326  E :          DCHECK_EQ(kSize32Bit, op.displacement().size());
 327    :          // It's [base+disp32].
 328  E :          EmitModRMByte(Reg1WordDisp, reg_op, op.base());
 329  E :          Emit32BitDisplacement(op.displacement());
 330    :        }
 331  E :      }
 332  E :    } else if (op.base() == kRegisterNone) {
 333    :      // Index, no base.
 334  E :      DCHECK_NE(kRegisterNone, op.index());
 335  E :      DCHECK_EQ(kRegisterNone, op.base());
 336    :  
 337    :      // This mode always has a 32 bit displacement.
 338  E :      EmitModRMByte(Reg1Ind, reg_op, kRegisterEsp);
 339  E :      EmitScaleIndexBaseByte(op.scale(), op.index(), kRegisterEbp);
 340  E :      Emit32BitDisplacement(op.displacement());
 341  E :    } else {
 342    :      // Index and base case.
 343  E :      DCHECK_NE(kRegisterNone, op.index());
 344  E :      DCHECK_NE(kRegisterNone, op.base());
 345    :  
 346    :      // Is there a displacement?
 347  E :      if (op.displacement().size() == kSizeNone) {
 348  E :        EmitModRMByte(Reg1Ind, reg_op, kRegisterEsp);
 349  E :        EmitScaleIndexBaseByte(op.scale(), op.index(), op.base());
 350  E :      } else if (op.displacement().size() == kSize8Bit) {
 351  E :        EmitModRMByte(Reg1ByteDisp, reg_op, kRegisterEsp);
 352  E :        EmitScaleIndexBaseByte(op.scale(), op.index(), op.base());
 353  E :        Emit8BitDisplacement(op.displacement());
 354  E :      } else {
 355  E :        DCHECK_EQ(kSize32Bit, op.displacement().size());
 356  E :        EmitModRMByte(Reg1WordDisp, reg_op, kRegisterEsp);
 357  E :        EmitScaleIndexBaseByte(op.scale(), op.index(), op.base());
 358  E :        Emit32BitDisplacement(op.displacement());
 359    :      }
 360    :    }
 361  E :  }
 362    :  
 363    :  void AssemblerImpl::InstructionBuffer::Emit8BitDisplacement(
 364  E :      const DisplacementImpl& disp) {
 365  E :    DCHECK(disp.size() == kSize8Bit);
 366    :  
 367  E :    AddReference(disp.reference());
 368    :  
 369  E :    EmitByte(disp.value());
 370  E :  }
 371    :  
 372    :  void AssemblerImpl::InstructionBuffer::Emit32BitDisplacement(
 373  E :      const DisplacementImpl& disp) {
 374  E :    AddReference(disp.reference());
 375    :  
 376  E :    uint32 value = disp.value();
 377  E :    EmitByte(value);
 378  E :    EmitByte(value >> 8);
 379  E :    EmitByte(value >> 16);
 380  E :    EmitByte(value >> 24);
 381  E :  }
 382    :  
 383    :  void AssemblerImpl::InstructionBuffer::Emit8BitPCRelative(
 384  E :      uint32 location, const ValueImpl& value) {
 385  E :    DCHECK_EQ(kSize8Bit, value.size());
 386    :  
 387  E :    AddReference(value.reference());
 388    :  
 389    :    // Turn the absolute value into a value relative to the address of
 390    :    // the end of the emitted constant.
 391  E :    int32 relative_value = value.value() - (location + len_ + 1);
 392  E :    DCHECK_LE(std::numeric_limits<int8>::min(), relative_value);
 393  E :    DCHECK_GE(std::numeric_limits<int8>::max(), relative_value);
 394  E :    EmitByte(relative_value);
 395  E :  }
 396    :  
 397    :  void AssemblerImpl::InstructionBuffer::Emit32BitPCRelative(
 398  E :      uint32 location, const ValueImpl& value) {
 399  E :    DCHECK_EQ(kSize32Bit, value.size());
 400    :  
 401  E :    AddReference(value.reference());
 402    :  
 403    :    // Turn the absolute value into a value relative to the address of
 404    :    // the end of the emitted constant.
 405  E :    uint32 relative_value = value.value() - (location + len_ + 4);
 406  E :    EmitByte(relative_value);
 407  E :    EmitByte(relative_value >> 8);
 408  E :    EmitByte(relative_value >> 16);
 409  E :    EmitByte(relative_value >> 24);
 410  E :  }
 411    :  
 412  E :  void AssemblerImpl::InstructionBuffer::Emit16BitValue(uint16 value) {
 413  E :    EmitByte(value);
 414  E :    EmitByte(value >> 8);
 415  E :  }
 416    :  
 417    :  void AssemblerImpl::InstructionBuffer::EmitArithmeticInstruction(
 418  E :      uint8 op, Register dst, Register src) {
 419  E :    EmitOpCodeByte(op);
 420  E :    EmitModRMByte(Reg1, dst.code(), src.code());
 421  E :  }
 422    :  
 423    :  void AssemblerImpl::InstructionBuffer::EmitArithmeticInstruction(
 424  E :      uint8 op, Register dst, const OperandImpl& src) {
 425  E :    EmitOpCodeByte(op);
 426  E :    EmitOperand(dst.code(), src);
 427  E :  }
 428    :  
 429    :  void AssemblerImpl::InstructionBuffer::EmitArithmeticInstruction(
 430  E :      uint8 op, const OperandImpl& dst, Register src) {
 431  E :    EmitOpCodeByte(op);
 432  E :    EmitOperand(src.code(), dst);
 433  E :  }
 434    :  
 435    :  void AssemblerImpl::InstructionBuffer::EmitArithmeticInstructionToRegister(
 436    :      uint8 op_eax, uint8 op_8, uint8 op_32, uint8 sub_op,
 437  E :      Register dst, const ImmediateImpl& src) {
 438  E :    if (dst.code() == kRegisterEax && src.size() == kSize32Bit) {
 439    :      // Special encoding for EAX.
 440  E :      EmitOpCodeByte(op_eax);
 441  E :      Emit32BitDisplacement(src);
 442  E :    } else if (src.size() == kSize8Bit) {
 443  E :      EmitOpCodeByte(op_8);
 444  E :      EmitModRMByte(Reg1, sub_op, dst.code());
 445  E :      Emit8BitDisplacement(src);
 446  E :    } else {
 447  E :      EmitOpCodeByte(op_32);
 448  E :      EmitModRMByte(Reg1, sub_op, dst.code());
 449  E :      Emit32BitDisplacement(src);
 450    :    }
 451  E :  }
 452    :  
 453    :  void AssemblerImpl::InstructionBuffer::EmitArithmeticInstructionToRegister8bit(
 454    :      uint8 op_eax, uint8 op_8, uint8 sub_op,
 455  E :      Register dst, const ImmediateImpl& src) {
 456  E :    DCHECK(src.size() == kSize8Bit);
 457  E :    if (dst.code() == kRegisterEax) {
 458    :      // Special encoding for EAX.
 459  E :      EmitOpCodeByte(op_eax);
 460  E :    } else {
 461  E :      EmitOpCodeByte(op_8);
 462  E :      EmitModRMByte(Reg1, sub_op, dst.code());
 463    :    }
 464  E :    Emit8BitDisplacement(src);
 465  E :  }
 466    :  
 467    :  void AssemblerImpl::InstructionBuffer::EmitArithmeticInstructionToOperand(
 468    :      uint8 op_8, uint8 op_32, uint8 sub_op,
 469  E :      const OperandImpl& dst, const ImmediateImpl& src) {
 470  E :    if (src.size() == kSize8Bit) {
 471  E :      EmitOpCodeByte(op_8);
 472  E :      EmitOperand(sub_op, dst);
 473  E :      Emit8BitDisplacement(src);
 474  E :    } else {
 475  E :      EmitOpCodeByte(op_32);
 476  E :      EmitOperand(sub_op, dst);
 477  E :      Emit32BitDisplacement(src);
 478    :    }
 479  E :  }
 480    :  
 481  E :  void AssemblerImpl::InstructionBuffer::AddReference(const void* reference) {
 482  E :    if (reference == NULL)
 483  E :      return;
 484    :  
 485  E :    DCHECK_GT(arraysize(references_), num_references_);
 486  E :    reference_offsets_[num_references_] = len();
 487  E :    references_[num_references_] = reference;
 488  E :    ++num_references_;
 489  E :  }
 490    :  
 491  E :  void AssemblerImpl::InstructionBuffer::EmitByte(uint8 byte) {
 492  E :    DCHECK_GT(sizeof(buf_), len_);
 493  E :    buf_[len_++] = byte;
 494  E :  }
 495    :  
 496    :  AssemblerImpl::AssemblerImpl(uint32 location, InstructionSerializer* serializer)
 497  E :      : location_(location), serializer_(serializer) {
 498  E :    DCHECK(serializer != NULL);
 499  E :  }
 500    :  
 501  E :  void AssemblerImpl::call(const ImmediateImpl& dst) {
 502  E :    InstructionBuffer instr(this);
 503    :  
 504  E :    instr.EmitOpCodeByte(0xE8);
 505  E :    instr.Emit32BitPCRelative(location_, dst);
 506  E :  }
 507    :  
 508  E :  void AssemblerImpl::call(const OperandImpl& dst) {
 509  E :    InstructionBuffer instr(this);
 510    :  
 511  E :    instr.EmitOpCodeByte(0xFF);
 512  E :    instr.EmitOperand(0x2, dst);
 513  E :  }
 514    :  
 515  E :  void AssemblerImpl::j(ConditionCode cc, const ImmediateImpl& dst) {
 516  E :    DCHECK_LE(kMinConditionCode, cc);
 517  E :    DCHECK_GE(kMaxConditionCode, cc);
 518    :  
 519  E :    InstructionBuffer instr(this);
 520  E :    if (dst.size() == kSize32Bit) {
 521  E :      instr.EmitOpCodeByte(kTwoByteOpCodePrefix);
 522  E :      instr.EmitOpCodeByte(0x80 | cc);
 523  E :      instr.Emit32BitPCRelative(location_, dst);
 524  E :    } else {
 525  E :      DCHECK_EQ(kSize8Bit, dst.size());
 526  E :      instr.EmitOpCodeByte(0x70 | cc);
 527  E :      instr.Emit8BitPCRelative(location_, dst);
 528    :    }
 529  E :  }
 530    :  
 531  E :  void AssemblerImpl::jecxz(const ImmediateImpl& dst) {
 532  E :    DCHECK_EQ(kSize8Bit, dst.size());
 533  E :    InstructionBuffer instr(this);
 534  E :    instr.EmitOpCodeByte(0xE3);
 535  E :    instr.Emit8BitPCRelative(location_, dst);
 536  E :  }
 537    :  
 538  E :  void AssemblerImpl::jmp(const ImmediateImpl& dst) {
 539  E :    InstructionBuffer instr(this);
 540    :  
 541  E :    if (dst.size() == kSize32Bit) {
 542  E :      instr.EmitOpCodeByte(0xE9);
 543  E :      instr.Emit32BitPCRelative(location_, dst);
 544  E :    } else {
 545  E :      DCHECK_EQ(kSize8Bit, dst.size());
 546  E :      instr.EmitOpCodeByte(0xEB);
 547  E :      instr.Emit8BitPCRelative(location_, dst);
 548    :    }
 549  E :  }
 550    :  
 551  E :  void AssemblerImpl::jmp(const OperandImpl& dst) {
 552  E :    InstructionBuffer instr(this);
 553    :  
 554  E :    instr.EmitOpCodeByte(0xFF);
 555  E :    instr.EmitOperand(0x4, dst);
 556  E :  }
 557    :  
 558  E :  void AssemblerImpl::l(LoopCode lc, const ImmediateImpl& dst) {
 559  E :    DCHECK_EQ(kSize8Bit, dst.size());
 560  E :    DCHECK_LE(0, lc);
 561  E :    DCHECK_GE(2, lc);
 562  E :    InstructionBuffer instr(this);
 563    :  
 564  E :    instr.EmitOpCodeByte(0xE0 | lc);
 565  E :    instr.Emit8BitPCRelative(location_, dst);
 566  E :  }
 567    :  
 568  E :  void AssemblerImpl::ret() {
 569  E :    InstructionBuffer instr(this);
 570    :  
 571  E :    instr.EmitOpCodeByte(0xC3);
 572  E :  }
 573    :  
 574  E :  void AssemblerImpl::ret(uint16 n) {
 575  E :    InstructionBuffer instr(this);
 576    :  
 577  E :    instr.EmitOpCodeByte(0xC2);
 578  E :    instr.Emit16BitValue(n);
 579  E :  }
 580    :  
 581  E :  void AssemblerImpl::set(ConditionCode cc, Register dst) {
 582  E :    DCHECK_LE(kMinConditionCode, cc);
 583  E :    DCHECK_GE(kMaxConditionCode, cc);
 584    :  
 585  E :    InstructionBuffer instr(this);
 586  E :    instr.EmitOpCodeByte(kTwoByteOpCodePrefix);
 587  E :    instr.EmitOpCodeByte(0x90 | cc);
 588    :  
 589    :    // AMD64 Architecture Programmers Manual Volume 3: General-Purpose and System
 590    :    // Instructions: The reg field in the ModR/M byte is unused.
 591  E :    Register unused = core::eax;
 592  E :    instr.EmitModRMByte(Reg1, unused.code(), dst.code());
 593  E :  }
 594    :  
 595  E :  void AssemblerImpl::mov_b(const OperandImpl& dst, const ImmediateImpl& src) {
 596  E :    InstructionBuffer instr(this);
 597    :  
 598  E :    instr.EmitOpCodeByte(0xC6);
 599  E :    instr.EmitOperand(0, dst);
 600  E :    instr.Emit8BitDisplacement(src);
 601  E :  }
 602    :  
 603  E :  void AssemblerImpl::movzx_b(Register dst, const OperandImpl& src) {
 604  E :    InstructionBuffer instr(this);
 605  E :    instr.EmitOpCodeByte(kTwoByteOpCodePrefix);
 606  E :    instr.EmitOpCodeByte(0xB6);
 607  E :    instr.EmitOperand(dst.code(), src);
 608  E :  }
 609    :  
 610  E :  void AssemblerImpl::mov(Register dst, Register src) {
 611  E :    InstructionBuffer instr(this);
 612    :  
 613  E :    instr.EmitOpCodeByte(0x8B);
 614  E :    instr.EmitModRMByte(Reg1, dst.code(), src.code());
 615  E :  }
 616    :  
 617  E :  void AssemblerImpl::mov(Register dst, const OperandImpl& src) {
 618  E :    InstructionBuffer instr(this);
 619    :  
 620  E :    if (dst.code() == kRegisterEax && IsDisplacementOnly(src)) {
 621    :      // Special encoding for indirect displacement only to EAX.
 622  E :      instr.EmitOpCodeByte(0xA1);
 623  E :      instr.Emit32BitDisplacement(src.displacement());
 624  E :    } else {
 625  E :      instr.EmitOpCodeByte(0x8B);
 626  E :      instr.EmitOperand(dst.code(), src);
 627    :    }
 628  E :  }
 629    :  
 630  E :  void AssemblerImpl::mov(const OperandImpl& dst, Register src) {
 631  E :    InstructionBuffer instr(this);
 632    :  
 633  E :    if (src.code() == kRegisterEax && IsDisplacementOnly(dst)) {
 634    :      // Special encoding for indirect displacement only from EAX.
 635  E :      instr.EmitOpCodeByte(0xA3);
 636  E :      instr.Emit32BitDisplacement(dst.displacement());
 637  E :    } else {
 638  E :      instr.EmitOpCodeByte(0x89);
 639  E :      instr.EmitOperand(src.code(), dst);
 640    :    }
 641  E :  }
 642    :  
 643  E :  void AssemblerImpl::mov(Register dst, const ValueImpl& src) {
 644  E :    DCHECK_NE(kSizeNone, src.size());
 645  E :    InstructionBuffer instr(this);
 646    :  
 647  E :    instr.EmitOpCodeByte(0xB8 | dst.code());
 648  E :    instr.Emit32BitDisplacement(src);
 649  E :  }
 650    :  
 651  E :  void AssemblerImpl::mov(const OperandImpl& dst, const ImmediateImpl& src) {
 652  E :    InstructionBuffer instr(this);
 653    :  
 654  E :    instr.EmitOpCodeByte(0xC7);
 655  E :    instr.EmitOperand(0, dst);
 656  E :    instr.Emit32BitDisplacement(src);
 657  E :  }
 658    :  
 659  E :  void AssemblerImpl::mov_fs(Register dst, const OperandImpl& src) {
 660  E :    InstructionBuffer instr(this);
 661  E :    instr.EmitOpCodeByte(kFsSegmentPrefix);
 662    :  
 663  E :    if (dst.code() == kRegisterEax && IsDisplacementOnly(src)) {
 664    :      // Special encoding for indirect displacement only to EAX.
 665  E :      instr.EmitOpCodeByte(0xA1);
 666  E :      instr.Emit32BitDisplacement(src.displacement());
 667  E :    } else {
 668  E :      instr.EmitOpCodeByte(0x8B);
 669  E :      instr.EmitOperand(dst.code(), src);
 670    :    }
 671  E :  }
 672    :  
 673  E :  void AssemblerImpl::mov_fs(const OperandImpl& dst, Register src) {
 674  E :    InstructionBuffer instr(this);
 675  E :    instr.EmitOpCodeByte(kFsSegmentPrefix);
 676    :  
 677  E :    if (src.code() == kRegisterEax && IsDisplacementOnly(dst)) {
 678    :      // Special encoding for indirect displacement only from EAX.
 679  E :      instr.EmitOpCodeByte(0xA3);
 680  E :      instr.Emit32BitDisplacement(dst.displacement());
 681  E :    } else {
 682  E :      instr.EmitOpCodeByte(0x89);
 683  E :      instr.EmitOperand(src.code(), dst);
 684    :    }
 685  E :  }
 686    :  
 687  E :  void AssemblerImpl::lea(Register dst, const OperandImpl& src) {
 688  E :    InstructionBuffer instr(this);
 689    :  
 690  E :    instr.EmitOpCodeByte(0x8D);
 691  E :    instr.EmitOperand(dst.code(), src);
 692  E :  }
 693    :  
 694  E :  void AssemblerImpl::push(Register src) {
 695  E :    InstructionBuffer instr(this);
 696    :  
 697  E :    instr.EmitOpCodeByte(0x50 | src.code());
 698  E :  }
 699    :  
 700  E :  void AssemblerImpl::push(const ImmediateImpl& src) {
 701  E :    DCHECK_EQ(kSize32Bit, src.size());
 702  E :    InstructionBuffer instr(this);
 703    :  
 704  E :    instr.EmitOpCodeByte(0x68);
 705  E :    instr.Emit32BitDisplacement(src);
 706  E :  }
 707    :  
 708  E :  void AssemblerImpl::push(const OperandImpl& dst) {
 709  E :    InstructionBuffer instr(this);
 710    :  
 711  E :    instr.EmitOpCodeByte(0xFF);
 712  E :    instr.EmitOperand(0x6, dst);
 713  E :  }
 714    :  
 715  E :  void AssemblerImpl::pop(Register src) {
 716  E :    InstructionBuffer instr(this);
 717    :  
 718  E :    instr.EmitOpCodeByte(0x58 | src.code());
 719  E :  }
 720    :  
 721  E :  void AssemblerImpl::pop(const OperandImpl& dst) {
 722  E :    InstructionBuffer instr(this);
 723    :  
 724  E :    instr.EmitOpCodeByte(0x8F);
 725  E :    instr.EmitOperand(0, dst);
 726  E :  }
 727    :  
 728  E :  void AssemblerImpl::pushfd() {
 729  E :    InstructionBuffer instr(this);
 730  E :    instr.EmitOpCodeByte(0x9C);
 731  E :  }
 732    :  
 733  E :  void AssemblerImpl::popfd() {
 734  E :    InstructionBuffer instr(this);
 735  E :    instr.EmitOpCodeByte(0x9D);
 736  E :  }
 737    :  
 738  E :  void AssemblerImpl::lahf() {
 739  E :    InstructionBuffer instr(this);
 740  E :    instr.EmitOpCodeByte(0x9F);
 741  E :  }
 742    :  
 743  E :  void AssemblerImpl::sahf() {
 744  E :    InstructionBuffer instr(this);
 745  E :    instr.EmitOpCodeByte(0x9E);
 746  E :  }
 747    :  
 748  E :  void AssemblerImpl::test_b(Register dst, Register src) {
 749  E :    InstructionBuffer instr(this);
 750  E :    instr.EmitArithmeticInstruction(0x84, dst, src);
 751  E :  }
 752    :  
 753  E :  void AssemblerImpl::test_b(Register dst, const ImmediateImpl& src) {
 754  E :    InstructionBuffer instr(this);
 755  E :    instr.EmitArithmeticInstructionToRegister8bit(0xA8, 0xF6, 0, dst, src);
 756  E :  }
 757    :  
 758  E :  void AssemblerImpl::test(Register dst, Register src) {
 759  E :    InstructionBuffer instr(this);
 760  E :    instr.EmitArithmeticInstruction(0x85, dst, src);
 761  E :  }
 762    :  
 763  E :  void AssemblerImpl::test(Register dst, const OperandImpl& src) {
 764    :    // Use commutative property for a smaller encoding.
 765  E :    test(src, dst);
 766  E :  }
 767    :  
 768  E :  void AssemblerImpl::test(const OperandImpl& dst, Register src) {
 769  E :    InstructionBuffer instr(this);
 770  E :    instr.EmitArithmeticInstruction(0x85, dst, src);
 771  E :  }
 772    :  
 773  E :  void AssemblerImpl::test(Register dst, const ImmediateImpl& src) {
 774  E :    if (src.size() == kSize8Bit) {
 775    :      // note: There is no encoding for a 8-bit immediate with 32-bit register.
 776  E :      test(dst, ImmediateImpl(src.value(), kSize32Bit));
 777  E :    } else {
 778  E :      InstructionBuffer instr(this);
 779  E :      instr.EmitArithmeticInstructionToRegister(0xA9, 0xF7, 0xF7, 0, dst, src);
 780  E :    }
 781  E :  }
 782    :  
 783  E :  void AssemblerImpl::test(const OperandImpl& dst, const ImmediateImpl& src) {
 784  E :    if (src.size() == kSize8Bit) {
 785    :      // note: There is no encoding for a 8-bit immediate with 32-bit register.
 786  E :      test(dst, ImmediateImpl(src.value(), kSize32Bit));
 787  E :    } else {
 788  E :      InstructionBuffer instr(this);
 789  E :      instr.EmitArithmeticInstructionToOperand(0xF7, 0xF7, 0, dst, src);
 790  E :    }
 791  E :  }
 792    :  
 793  E :  void AssemblerImpl::cmp_b(Register dst, Register src) {
 794  E :    InstructionBuffer instr(this);
 795  E :    instr.EmitArithmeticInstruction(0x3A, dst, src);
 796  E :  }
 797    :  
 798  E :  void AssemblerImpl::cmp_b(Register dst, const ImmediateImpl& src) {
 799  E :    InstructionBuffer instr(this);
 800  E :    instr.EmitArithmeticInstructionToRegister8bit(0x3C, 0x80, 7, dst, src);
 801  E :  }
 802    :  
 803  E :  void AssemblerImpl::cmp(Register dst, Register src) {
 804  E :    InstructionBuffer instr(this);
 805  E :    instr.EmitArithmeticInstruction(0x3B, dst, src);
 806  E :  }
 807    :  
 808  E :  void AssemblerImpl::cmp(Register dst, const OperandImpl& src) {
 809  E :    InstructionBuffer instr(this);
 810  E :    instr.EmitArithmeticInstruction(0x3B, dst, src);
 811  E :  }
 812    :  
 813  E :  void AssemblerImpl::cmp(const OperandImpl& dst, Register src) {
 814  E :    InstructionBuffer instr(this);
 815  E :    instr.EmitArithmeticInstruction(0x39, dst, src);
 816  E :  }
 817    :  
 818  E :  void AssemblerImpl::cmp(Register dst, const ImmediateImpl& src) {
 819  E :    InstructionBuffer instr(this);
 820  E :    instr.EmitArithmeticInstructionToRegister(0x3D, 0x83, 0x81, 7, dst, src);
 821  E :  }
 822    :  
 823  E :  void AssemblerImpl::cmp(const OperandImpl& dst, const ImmediateImpl& src) {
 824  E :    InstructionBuffer instr(this);
 825  E :    instr.EmitArithmeticInstructionToOperand(0x83, 0x81, 7, dst, src);
 826  E :  }
 827    :  
 828  E :  void AssemblerImpl::add_b(Register dst, Register src) {
 829  E :    InstructionBuffer instr(this);
 830  E :    instr.EmitArithmeticInstruction(0x02, dst, src);
 831  E :  }
 832    :  
 833  E :  void AssemblerImpl::add_b(Register dst, const ImmediateImpl& src) {
 834  E :    InstructionBuffer instr(this);
 835  E :    instr.EmitArithmeticInstructionToRegister8bit(0x04, 0x80, 0, dst, src);
 836  E :  }
 837    :  
 838  E :  void AssemblerImpl::add(Register dst, Register src) {
 839  E :    InstructionBuffer instr(this);
 840  E :    instr.EmitArithmeticInstruction(0x03, dst, src);
 841  E :  }
 842    :  
 843  E :  void AssemblerImpl::add(Register dst, const OperandImpl& src) {
 844  E :    InstructionBuffer instr(this);
 845  E :    instr.EmitArithmeticInstruction(0x03, dst, src);
 846  E :  }
 847    :  
 848  E :  void AssemblerImpl::add(const OperandImpl& dst, Register src) {
 849  E :    InstructionBuffer instr(this);
 850  E :    instr.EmitArithmeticInstruction(0x01, dst, src);
 851  E :  }
 852    :  
 853  E :  void AssemblerImpl::add(Register dst, const ImmediateImpl& src) {
 854  E :    InstructionBuffer instr(this);
 855  E :    instr.EmitArithmeticInstructionToRegister(0x05, 0x83, 0x81, 0, dst, src);
 856  E :  }
 857    :  
 858  E :  void AssemblerImpl::add(const OperandImpl& dst, const ImmediateImpl& src) {
 859  E :    InstructionBuffer instr(this);
 860  E :    instr.EmitArithmeticInstructionToOperand(0x83, 0x81, 0, dst, src);
 861  E :  }
 862    :  
 863  E :  void AssemblerImpl::sub_b(Register dst, Register src) {
 864  E :    InstructionBuffer instr(this);
 865  E :    instr.EmitArithmeticInstruction(0x2A, dst, src);
 866  E :  }
 867    :  
 868  E :  void AssemblerImpl::sub_b(Register dst, const ImmediateImpl& src) {
 869  E :    InstructionBuffer instr(this);
 870  E :    instr.EmitArithmeticInstructionToRegister8bit(0x2C, 0x80, 5, dst, src);
 871  E :  }
 872    :  
 873  E :  void AssemblerImpl::sub(Register dst, Register src) {
 874  E :    InstructionBuffer instr(this);
 875  E :    instr.EmitArithmeticInstruction(0x2B, dst, src);
 876  E :  }
 877    :  
 878  E :  void AssemblerImpl::sub(Register dst, const OperandImpl& src) {
 879  E :    InstructionBuffer instr(this);
 880  E :    instr.EmitArithmeticInstruction(0x2B, dst, src);
 881  E :  }
 882    :  
 883  E :  void AssemblerImpl::sub(const OperandImpl&  dst, Register src) {
 884  E :    InstructionBuffer instr(this);
 885  E :    instr.EmitArithmeticInstruction(0x29, dst, src);
 886  E :  }
 887    :  
 888  E :  void AssemblerImpl::sub(Register dst, const ImmediateImpl& src) {
 889  E :    InstructionBuffer instr(this);
 890  E :    instr.EmitArithmeticInstructionToRegister(0x2D, 0x83, 0x81, 5, dst, src);
 891  E :  }
 892    :  
 893  E :  void AssemblerImpl::sub(const OperandImpl&  dst, const ImmediateImpl& src) {
 894  E :    InstructionBuffer instr(this);
 895  E :    instr.EmitArithmeticInstructionToOperand(0x83, 0x81, 5, dst, src);
 896  E :  }
 897    :  
 898  E :  void AssemblerImpl::shl(Register dst, const ImmediateImpl& src) {
 899  E :    InstructionBuffer instr(this);
 900  E :    if (src.value() == 1) {
 901  E :      instr.EmitOpCodeByte(0xD1);
 902  E :      instr.EmitModRMByte(Reg1, 4, dst.code());
 903  E :    } else {
 904  E :      instr.EmitOpCodeByte(0xC1);
 905  E :      instr.EmitModRMByte(Reg1, 4, dst.code());
 906  E :      instr.Emit8BitDisplacement(src);
 907    :    }
 908  E :  }
 909    :  
 910  E :  void AssemblerImpl::shr(Register dst, const ImmediateImpl& src) {
 911  E :    InstructionBuffer instr(this);
 912  E :    if (src.value() == 1) {
 913  E :      instr.EmitOpCodeByte(0xD1);
 914  E :      instr.EmitModRMByte(Reg1, 5, dst.code());
 915  E :    } else {
 916  E :      instr.EmitOpCodeByte(0xC1);
 917  E :      instr.EmitModRMByte(Reg1, 5, dst.code());
 918  E :      instr.Emit8BitDisplacement(src);
 919    :    }
 920  E :  }
 921    :  
 922  E :  void AssemblerImpl::Output(const InstructionBuffer& instr) {
 923    :    serializer_->AppendInstruction(location_,
 924    :                                   instr.buf(),
 925    :                                   instr.len(),
 926    :                                   instr.reference_offsets(),
 927    :                                   instr.references(),
 928  E :                                   instr.num_references());
 929    :  
 930  E :    location_ += instr.len();
 931  E :  }
 932    :  
 933    :  }  // namespace core

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