Coverage for /Syzygy/core/assembler.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
99.1%6446500.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    :  namespace core {
  20    :  
  21    :  namespace {
  22    :  
  23    :  enum Mod {
  24    :    kReg1Ind = 0,  // Register indirect mode.
  25    :    kReg1ByteDisp = 1,  // Register + byte displacement.
  26    :    kReg1WordDisp = 2,  // Register + word displacement.
  27    :    kReg1 = 3,  // Register itself.
  28    :  };
  29    :  
  30    :  // The code that AL/AX/EAX/RAX registers all map to. There are special encodings
  31    :  // for arithmetic instructions with this register as the destination.
  32  E :  static const RegisterCode kAccumulatorCode = Register::Code(kRegisterEax);
  33    :  
  34    :  const uint8 kTwoByteOpCodePrefix = 0x0F;
  35    :  // Prefix group 2 (segment selection).
  36    :  const uint8 kFsSegmentPrefix = 0x64;
  37    :  // Prefix group 3 (operand size override).
  38    :  const uint8 kOperandSizePrefix = 0x66;
  39    :  
  40    :  // Some opcodes that are used repeatedly.
  41    :  const uint8 kNopOpCode = 0x1F;
  42    :  
  43    :  // Returns true if @p operand is a displacement only - e.g.
  44    :  // specifies neither a base, nor an index register.
  45  E :  bool IsDisplacementOnly(const OperandImpl& operand) {
  46    :    return operand.displacement().size() != kSizeNone &&
  47    :        operand.base() == kRegisterNone &&
  48  E :        operand.index() == kRegisterNone;
  49  E :  }
  50    :  
  51    :  }  // namespace
  52    :  
  53    :  const size_t AssemblerImpl::kShortBranchOpcodeSize = 1;
  54    :  const size_t AssemblerImpl::kShortBranchSize = kShortBranchOpcodeSize + 1;
  55    :  
  56    :  const size_t AssemblerImpl::kLongBranchOpcodeSize = 2;
  57    :  const size_t AssemblerImpl::kLongBranchSize = kLongBranchOpcodeSize + 4;
  58    :  
  59    :  const size_t AssemblerImpl::kShortJumpOpcodeSize = 1;
  60    :  const size_t AssemblerImpl::kShortJumpSize = kShortJumpOpcodeSize + 1;
  61    :  
  62    :  const size_t AssemblerImpl::kLongJumpOpcodeSize = 1;
  63    :  const size_t AssemblerImpl::kLongJumpSize = kLongJumpOpcodeSize + 4;
  64    :  
  65    :  OperandImpl::OperandImpl(const Register32& base)
  66    :      : base_(base.id()),
  67    :        index_(kRegisterNone),
  68  E :        scale_(kTimes1) {
  69  E :  }
  70    :  
  71    :  OperandImpl::OperandImpl(const Register32& base,
  72    :                           const DisplacementImpl& displacement)
  73    :      : base_(base.id()),
  74    :        index_(kRegisterNone),
  75    :        scale_(kTimes1),
  76  E :        displacement_(displacement) {
  77    :    // There must be a base register.
  78  E :    DCHECK_NE(kRegisterNone, base_);
  79  E :  }
  80    :  
  81    :  OperandImpl::OperandImpl(const DisplacementImpl& displacement)
  82    :      : base_(kRegisterNone),
  83    :        index_(kRegisterNone),
  84    :        scale_(kTimes1),
  85  E :        displacement_(displacement) {
  86  E :    DCHECK_NE(kSizeNone, displacement.size());
  87  E :  }
  88    :  
  89    :  OperandImpl::OperandImpl(const Register32& base,
  90    :                           const Register32& index,
  91    :                           ScaleFactor scale,
  92    :                           const DisplacementImpl& displacement)
  93    :      : base_(base.id()),
  94    :        index_(index.id()),
  95    :        scale_(scale),
  96  E :        displacement_(displacement) {
  97    :    // ESP cannot be used as an index register.
  98  E :    DCHECK_NE(kRegisterEsp, index.id());
  99  E :    DCHECK_NE(kSizeNone, displacement.size());
 100  E :  }
 101    :  
 102    :  OperandImpl::OperandImpl(const Register32& base,
 103    :                           const Register32& index,
 104    :                           ScaleFactor scale)
 105    :      : base_(base.id()),
 106    :        index_(index.id()),
 107  E :        scale_(scale) {
 108    :    // ESP cannot be used as an index register.
 109  E :    DCHECK_NE(kRegisterEsp, index.id());
 110  E :    DCHECK_EQ(kSizeNone, displacement_.size());
 111  E :  }
 112    :  
 113    :  OperandImpl::OperandImpl(const Register32& index,
 114    :                           ScaleFactor scale,
 115    :                           const DisplacementImpl& displacement)
 116    :      : base_(kRegisterNone),
 117    :        index_(index.id()),
 118    :        scale_(scale),
 119  E :        displacement_(displacement) {
 120    :    // ESP cannot be used as an index register.
 121  E :    DCHECK_NE(kRegisterEsp, index.id());
 122  E :    DCHECK_NE(kSizeNone, displacement.size());
 123  E :  }
 124    :  
 125    :  OperandImpl::OperandImpl(RegisterId base,
 126    :                           RegisterId index,
 127    :                           ScaleFactor scale,
 128    :                           const DisplacementImpl& displacement)
 129    :      : base_(base),
 130    :        index_(index),
 131    :        scale_(scale),
 132  E :        displacement_(displacement) {
 133  E :  }
 134    :  
 135    :  ValueImpl::ValueImpl()
 136  E :      : value_(0), reference_(NULL), size_(kSizeNone) {
 137  E :  }
 138    :  
 139    :  ValueImpl::ValueImpl(uint32 value, ValueSize size)
 140  E :      : value_(value), reference_(NULL), size_(size) {
 141  E :  }
 142    :  
 143    :  ValueImpl::ValueImpl(uint32 value,
 144    :                       ValueSize size,
 145    :                       const void* value_ref)
 146  E :      : value_(value), reference_(value_ref), size_(size) {
 147    :    // We can't have a 16-bit value *and* a reference, as there are no
 148    :    // addressing modes that accept 16-bit input.
 149  E :    DCHECK(value_ref == NULL || size != kSize16Bit);
 150  E :  }
 151    :  
 152  E :  bool ValueImpl::operator==(const ValueImpl& rhs) const {
 153    :    return value_ == rhs.value_ &&
 154    :        reference_ == rhs.reference_ &&
 155  E :        size_ == rhs.size_;
 156  E :  }
 157    :  
 158    :  // This class is used to buffer a single instruction during it's creation.
 159    :  // TODO(siggi): Add a small state machine in debug mode to ensure the
 160    :  //     correct order of invocation to opcode/modrm etc.
 161    :  class AssemblerImpl::InstructionBuffer {
 162    :   public:
 163    :    explicit InstructionBuffer(AssemblerImpl* assm);
 164    :    ~InstructionBuffer();
 165    :  
 166    :    // @name Accessors.
 167    :    // @{
 168  E :    size_t len() const { return len_; }
 169  E :    const uint8* buf() const { return buf_; }
 170  E :    size_t num_references() const { return num_references_; }
 171  E :    const size_t *reference_offsets() const { return reference_offsets_; }
 172  E :    const void*const* references() const { return references_; }
 173    :    // @}
 174    :  
 175    :    // Emits operand size prefix (0x66) bytes.
 176    :    // @param count The number of operand size prefix bytes to emit.
 177    :    void EmitOperandSizePrefix(size_t count);
 178    :    // Emit an opcode byte.
 179    :    void EmitOpCodeByte(uint8 opcode);
 180    :    // Emit a ModR/M byte with an opcode extension.
 181    :    void EmitModRMByte(Mod mod, uint8 op, RegisterId reg1);
 182    :    // Emit a ModR/M byte with a destination register.
 183    :    void EmitModRMByte(Mod mod, RegisterId reg2, RegisterId reg1);
 184    :    // Emit a SIB byte.
 185    :    void EmitScaleIndexBaseByte(ScaleFactor scale,
 186    :                                RegisterId index,
 187    :                                RegisterId base);
 188    :    // Emit an operand.
 189    :    void EmitOperand(uint8 reg_op, const OperandImpl& op);
 190    :  
 191    :    // Emit an 8-bit displacement, with optional reference info.
 192    :    void Emit8BitDisplacement(const DisplacementImpl& disp);
 193    :  
 194    :    // Emit a 32-bit displacement with optional reference info.
 195    :    void Emit32BitDisplacement(const DisplacementImpl& disp);
 196    :  
 197    :    // Emit an 8-bit PC-relative value.
 198    :    void Emit8BitPCRelative(uint32 location, const ValueImpl& disp);
 199    :  
 200    :    // Emit a 32-bit PC-relative value.
 201    :    void Emit32BitPCRelative(uint32 location, const ValueImpl& disp);
 202    :  
 203    :    // Emit a 16-bit immediate value.
 204    :    void Emit16BitValue(uint16 value);
 205    :  
 206    :    // Emit an arithmetic instruction with various encoding.
 207    :    void EmitArithmeticInstruction(
 208    :        uint8 op, const Register& dst, const Register& src);
 209    :    void EmitArithmeticInstruction(
 210    :        uint8 op, const Register& dst, const OperandImpl& src);
 211    :    void EmitArithmeticInstruction(
 212    :        uint8 op, const OperandImpl& dst, const Register32& src);
 213    :    void EmitArithmeticInstructionToRegister32(uint8 op_eax, uint8 op_8,
 214    :        uint8 op_32, uint8 sub_op, const Register32& dst,
 215    :        const ImmediateImpl& src);
 216    :    void EmitArithmeticInstructionToRegister8(uint8 op_eax, uint8 op_8,
 217    :        uint8 sub_op, const Register8& dst, const ImmediateImpl& src);
 218    :    void EmitArithmeticInstructionToOperand(uint8 op_8, uint8 op_32, uint8 sub_op,
 219    :        const OperandImpl& dst, const ImmediateImpl& src);
 220    :  
 221    :    // Emit an XCHG instruction.
 222    :    void EmitXchg(ValueSize size, RegisterId dst, RegisterId src);
 223    :  
 224    :    // Add reference at current location.
 225    :    void AddReference(const void* reference);
 226    :  
 227    :   protected:
 228    :    void EmitByte(uint8 byte);
 229    :  
 230    :    AssemblerImpl* asm_;
 231    :    size_t num_references_;
 232    :    const void* (references_)[2];
 233    :    size_t reference_offsets_[2];
 234    :    size_t len_;
 235    :    uint8 buf_[kMaxInstructionLength];
 236    :  };
 237    :  
 238    :  AssemblerImpl::InstructionBuffer::InstructionBuffer(AssemblerImpl* assm)
 239  E :      : asm_(assm), len_(0), num_references_(0) {
 240  E :    DCHECK(assm != NULL);
 241    :  #ifndef NDEBUG
 242    :    // Initialize the buffer in debug mode for easier debugging.
 243  E :    ::memset(buf_, 0xCC, sizeof(buf_));
 244    :  #endif
 245  E :  }
 246    :  
 247  E :  AssemblerImpl::InstructionBuffer::~InstructionBuffer() {
 248  E :    asm_->Output(*this);
 249  E :  }
 250    :  
 251  E :  void AssemblerImpl::InstructionBuffer::EmitOperandSizePrefix(size_t count) {
 252  E :    for (size_t i = 0; i < count; ++i)
 253  E :      EmitByte(kOperandSizePrefix);
 254  E :  }
 255    :  
 256  E :  void AssemblerImpl::InstructionBuffer::EmitOpCodeByte(uint8 opcode) {
 257  E :    EmitByte(opcode);
 258  E :  }
 259    :  
 260    :  void AssemblerImpl::InstructionBuffer::EmitModRMByte(
 261  E :      Mod mod, uint8 reg_op, RegisterId reg1) {
 262  E :    DCHECK_LE(reg_op, 8);
 263  E :    DCHECK_NE(kRegisterNone, reg1);
 264  E :    EmitByte((mod << 6) | (reg_op << 3) | Register::Code(reg1));
 265  E :  }
 266    :  
 267    :  void AssemblerImpl::InstructionBuffer::EmitModRMByte(
 268  E :      Mod mod, RegisterId reg2, RegisterId reg1) {
 269  E :    DCHECK_NE(kRegisterNone, reg2);
 270  E :    DCHECK_NE(kRegisterNone, reg1);
 271  E :    EmitModRMByte(mod, Register::Code(reg2), reg1);
 272  E :  }
 273    :  
 274    :  void AssemblerImpl::InstructionBuffer::EmitScaleIndexBaseByte(
 275  E :      ScaleFactor scale, RegisterId index, RegisterId base) {
 276  E :    DCHECK_NE(kRegisterNone, index);
 277  E :    DCHECK_NE(kRegisterNone, base);
 278    :  
 279  E :    EmitByte((scale << 6) | (Register::Code(index) << 3) | Register::Code(base));
 280  E :  }
 281    :  
 282    :  void AssemblerImpl::InstructionBuffer::EmitOperand(
 283  E :      uint8 reg_op, const OperandImpl& op) {
 284  E :    DCHECK_GE(8, reg_op);
 285    :  
 286    :    // The op operand can encode any one of the following things:
 287    :    // An indirect register access [EAX].
 288    :    // An indirect 32-bit displacement only [0xDEADBEEF].
 289    :    // An indirect base register + 32/8-bit displacement [EAX+0xDEADBEEF].
 290    :    // An indirect base + index register*scale [EAX+ECX*4].
 291    :    // An indirect base + index register*scale + 32/8-bit displacement
 292    :    //   [EAX+ECX*4+0xDEADBEEF].
 293    :    // To complicate things, there are certain combinations that can't be encoded
 294    :    // canonically. The mode [ESP] or [ESP+disp] can never be encoded in a
 295    :    // ModR/M byte alone, as ESP in the ModR/M byte for any of the indirect modes
 296    :    // is overloaded to select the SIB representation.
 297    :    // Likewise [EBP] is overloaded to encode the [disp32] case.
 298    :    // See e.g. http://ref.x86asm.net/geek32-abc.html#modrm_byte_32 for a nice
 299    :    // overview table of the ModR/M byte encoding.
 300    :  
 301    :    // ESP can never be used as an index register on X86.
 302  E :    DCHECK_NE(kRegisterEsp, op.index());
 303    :  
 304    :    // Is there an index register?
 305  E :    if (op.index() == kRegisterNone) {
 306  E :      DCHECK_EQ(kTimes1, op.scale());
 307    :  
 308    :      // No index register, is there a base register?
 309  E :      if (op.base() == kRegisterNone) {
 310    :        // No base register, this is a displacement only.
 311  E :        DCHECK_NE(kSizeNone, op.displacement().size());
 312  E :        DCHECK_EQ(kTimes1, op.scale());
 313    :  
 314    :        // The [disp32] mode is encoded by overloading [EBP].
 315  E :        EmitModRMByte(kReg1Ind, reg_op, kRegisterEbp);
 316  E :        Emit32BitDisplacement(op.displacement());
 317  E :      } else {
 318    :        // Base register only, is it ESP?
 319  E :        if (op.base() == kRegisterEsp) {
 320    :          // The [ESP] and [ESP+disp] cases cannot be encoded without a SIB byte.
 321  E :          if (op.displacement().size() == kSizeNone) {
 322  E :            EmitModRMByte(kReg1Ind, reg_op, kRegisterEsp);
 323  E :            EmitScaleIndexBaseByte(kTimes1, kRegisterEsp, kRegisterEsp);
 324  E :          } else if (op.displacement().size() == kSize8Bit) {
 325  E :            EmitModRMByte(kReg1ByteDisp, reg_op, kRegisterEsp);
 326  E :            EmitScaleIndexBaseByte(kTimes1, kRegisterEsp, kRegisterEsp);
 327  E :            Emit8BitDisplacement(op.displacement());
 328  E :          } else {
 329  E :            DCHECK_EQ(kSize32Bit, op.displacement().size());
 330  E :            EmitModRMByte(kReg1WordDisp, reg_op, kRegisterEsp);
 331  E :            EmitScaleIndexBaseByte(kTimes1, kRegisterEsp, kRegisterEsp);
 332  E :            Emit32BitDisplacement(op.displacement());
 333  E :          }
 334  E :        } else if (op.displacement().size() == kSizeNone) {
 335  E :          if (op.base() == kRegisterEbp) {
 336    :            // The [EBP] case cannot be encoded canonically, there always must
 337    :            // be a (zero) displacement.
 338  E :            EmitModRMByte(kReg1ByteDisp, reg_op, op.base());
 339  E :            Emit8BitDisplacement(DisplacementImpl(0, kSize8Bit, NULL));
 340  E :          } else {
 341  E :            EmitModRMByte(kReg1Ind, reg_op, op.base());
 342  E :          }
 343  E :        } else if (op.displacement().size() == kSize8Bit) {
 344    :          // It's [base+disp8], or possibly [EBP].
 345  E :          EmitModRMByte(kReg1ByteDisp, reg_op, op.base());
 346  E :          Emit8BitDisplacement(op.displacement());
 347  E :        } else {
 348  E :          DCHECK_EQ(kSize32Bit, op.displacement().size());
 349    :          // It's [base+disp32].
 350  E :          EmitModRMByte(kReg1WordDisp, reg_op, op.base());
 351  E :          Emit32BitDisplacement(op.displacement());
 352    :        }
 353  E :      }
 354  E :    } else if (op.base() == kRegisterNone) {
 355    :      // Index, no base.
 356  E :      DCHECK_NE(kRegisterNone, op.index());
 357  E :      DCHECK_EQ(kRegisterNone, op.base());
 358    :  
 359    :      // This mode always has a 32 bit displacement.
 360  E :      EmitModRMByte(kReg1Ind, reg_op, kRegisterEsp);
 361  E :      EmitScaleIndexBaseByte(op.scale(), op.index(), kRegisterEbp);
 362  E :      Emit32BitDisplacement(op.displacement());
 363  E :    } else {
 364    :      // Index and base case.
 365  E :      DCHECK_NE(kRegisterNone, op.index());
 366  E :      DCHECK_NE(kRegisterNone, op.base());
 367    :  
 368    :      // Is there a displacement?
 369  E :      if (op.displacement().size() == kSizeNone) {
 370  E :        EmitModRMByte(kReg1Ind, reg_op, kRegisterEsp);
 371  E :        EmitScaleIndexBaseByte(op.scale(), op.index(), op.base());
 372  E :      } else if (op.displacement().size() == kSize8Bit) {
 373  E :        EmitModRMByte(kReg1ByteDisp, reg_op, kRegisterEsp);
 374  E :        EmitScaleIndexBaseByte(op.scale(), op.index(), op.base());
 375  E :        Emit8BitDisplacement(op.displacement());
 376  E :      } else {
 377  E :        DCHECK_EQ(kSize32Bit, op.displacement().size());
 378  E :        EmitModRMByte(kReg1WordDisp, reg_op, kRegisterEsp);
 379  E :        EmitScaleIndexBaseByte(op.scale(), op.index(), op.base());
 380  E :        Emit32BitDisplacement(op.displacement());
 381    :      }
 382    :    }
 383  E :  }
 384    :  
 385    :  void AssemblerImpl::InstructionBuffer::Emit8BitDisplacement(
 386  E :      const DisplacementImpl& disp) {
 387  E :    DCHECK(disp.size() == kSize8Bit);
 388    :  
 389  E :    AddReference(disp.reference());
 390    :  
 391  E :    EmitByte(disp.value());
 392  E :  }
 393    :  
 394    :  void AssemblerImpl::InstructionBuffer::Emit32BitDisplacement(
 395  E :      const DisplacementImpl& disp) {
 396  E :    AddReference(disp.reference());
 397    :  
 398  E :    uint32 value = disp.value();
 399  E :    EmitByte(value);
 400  E :    EmitByte(value >> 8);
 401  E :    EmitByte(value >> 16);
 402  E :    EmitByte(value >> 24);
 403  E :  }
 404    :  
 405    :  void AssemblerImpl::InstructionBuffer::Emit8BitPCRelative(
 406  E :      uint32 location, const ValueImpl& value) {
 407  E :    DCHECK_EQ(kSize8Bit, value.size());
 408    :  
 409  E :    AddReference(value.reference());
 410    :  
 411    :    // Turn the absolute value into a value relative to the address of
 412    :    // the end of the emitted constant.
 413  E :    int32 relative_value = value.value() - (location + len_ + 1);
 414  E :    DCHECK_LE(std::numeric_limits<int8>::min(), relative_value);
 415  E :    DCHECK_GE(std::numeric_limits<int8>::max(), relative_value);
 416  E :    EmitByte(relative_value);
 417  E :  }
 418    :  
 419    :  void AssemblerImpl::InstructionBuffer::Emit32BitPCRelative(
 420  E :      uint32 location, const ValueImpl& value) {
 421  E :    DCHECK_EQ(kSize32Bit, value.size());
 422    :  
 423  E :    AddReference(value.reference());
 424    :  
 425    :    // Turn the absolute value into a value relative to the address of
 426    :    // the end of the emitted constant.
 427  E :    uint32 relative_value = value.value() - (location + len_ + 4);
 428  E :    EmitByte(relative_value);
 429  E :    EmitByte(relative_value >> 8);
 430  E :    EmitByte(relative_value >> 16);
 431  E :    EmitByte(relative_value >> 24);
 432  E :  }
 433    :  
 434  E :  void AssemblerImpl::InstructionBuffer::Emit16BitValue(uint16 value) {
 435  E :    EmitByte(value);
 436  E :    EmitByte(value >> 8);
 437  E :  }
 438    :  
 439    :  void AssemblerImpl::InstructionBuffer::EmitArithmeticInstruction(
 440  E :      uint8 op, const Register& dst, const Register& src) {
 441  E :    DCHECK_EQ(dst.size(), src.size());
 442  E :    EmitOpCodeByte(op);
 443  E :    EmitModRMByte(kReg1, dst.id(), src.id());
 444  E :  }
 445    :  
 446    :  void AssemblerImpl::InstructionBuffer::EmitArithmeticInstruction(
 447  E :      uint8 op, const Register& dst, const OperandImpl& src) {
 448  E :    EmitOpCodeByte(op);
 449  E :    EmitOperand(dst.code(), src);
 450  E :  }
 451    :  
 452    :  void AssemblerImpl::InstructionBuffer::EmitArithmeticInstruction(
 453  E :      uint8 op, const OperandImpl& dst, const Register32& src) {
 454  E :    EmitOpCodeByte(op);
 455  E :    EmitOperand(src.code(), dst);
 456  E :  }
 457    :  
 458    :  void AssemblerImpl::InstructionBuffer::EmitArithmeticInstructionToRegister32(
 459    :      uint8 op_eax, uint8 op_8, uint8 op_32, uint8 sub_op,
 460  E :      const Register32& dst, const ImmediateImpl& src) {
 461  E :    if (dst.id() == kRegisterEax && src.size() == kSize32Bit) {
 462    :      // Special encoding for EAX.
 463  E :      EmitOpCodeByte(op_eax);
 464  E :      Emit32BitDisplacement(src);
 465  E :    } else if (src.size() == kSize8Bit) {
 466  E :      EmitOpCodeByte(op_8);
 467  E :      EmitModRMByte(kReg1, sub_op, dst.id());
 468  E :      Emit8BitDisplacement(src);
 469  E :    } else {
 470  E :      EmitOpCodeByte(op_32);
 471  E :      EmitModRMByte(kReg1, sub_op, dst.id());
 472  E :      Emit32BitDisplacement(src);
 473    :    }
 474  E :  }
 475    :  
 476    :  void AssemblerImpl::InstructionBuffer::EmitArithmeticInstructionToRegister8(
 477    :      uint8 op_eax, uint8 op_8, uint8 sub_op,
 478  E :      const Register8& dst, const ImmediateImpl& src) {
 479  E :    DCHECK(src.size() == kSize8Bit);
 480  E :    if (dst.code() == kAccumulatorCode) {
 481    :      // Special encoding for AL/AX/EAX.
 482  E :      EmitOpCodeByte(op_eax);
 483  E :    } else {
 484  E :      EmitOpCodeByte(op_8);
 485  E :      EmitModRMByte(kReg1, sub_op, dst.id());
 486    :    }
 487  E :    Emit8BitDisplacement(src);
 488  E :  }
 489    :  
 490    :  void AssemblerImpl::InstructionBuffer::EmitArithmeticInstructionToOperand(
 491    :      uint8 op_8, uint8 op_32, uint8 sub_op,
 492  E :      const OperandImpl& dst, const ImmediateImpl& src) {
 493  E :    if (src.size() == kSize8Bit) {
 494  E :      EmitOpCodeByte(op_8);
 495  E :      EmitOperand(sub_op, dst);
 496  E :      Emit8BitDisplacement(src);
 497  E :    } else {
 498  E :      EmitOpCodeByte(op_32);
 499  E :      EmitOperand(sub_op, dst);
 500  E :      Emit32BitDisplacement(src);
 501    :    }
 502  E :  }
 503    :  
 504    :  void AssemblerImpl::InstructionBuffer::EmitXchg(
 505  E :      ValueSize size, RegisterId dst, RegisterId src) {
 506    :    // Encoding for 8-bit registers.
 507  E :    if (size == kSize8Bit) {
 508  E :      EmitOpCodeByte(0x86);
 509  E :      EmitModRMByte(kReg1, src, dst);
 510  E :    } else {
 511    :      // 16-bit encodings are identical to 32-bit encodings, simply with
 512    :      // a operand size override prefix.
 513  E :      if (size == kSize16Bit)
 514  E :        EmitOperandSizePrefix(1);
 515    :  
 516    :      // If either register is EAX/AX there's a 1-byte encoding.
 517  E :      RegisterCode dst_code = Register::Code(dst);
 518  E :      RegisterCode src_code = Register::Code(src);
 519  E :      if (src_code == kAccumulatorCode || dst_code == kAccumulatorCode) {
 520  E :        RegisterCode other_register = dst_code;
 521  E :        if (dst_code == kAccumulatorCode)
 522  E :          other_register = src_code;
 523  E :        EmitOpCodeByte(0x90 | other_register);
 524  E :      } else {
 525    :        // Otherwise we use a 2-byte encoding with a ModR/M byte.
 526  E :        EmitOpCodeByte(0x87);
 527  E :        EmitModRMByte(kReg1, src, dst);
 528    :      }
 529    :    }
 530  E :  }
 531    :  
 532  E :  void AssemblerImpl::InstructionBuffer::AddReference(const void* reference) {
 533  E :    if (reference == NULL)
 534  E :      return;
 535    :  
 536  E :    DCHECK_GT(arraysize(references_), num_references_);
 537  E :    reference_offsets_[num_references_] = len();
 538  E :    references_[num_references_] = reference;
 539  E :    ++num_references_;
 540  E :  }
 541    :  
 542  E :  void AssemblerImpl::InstructionBuffer::EmitByte(uint8 byte) {
 543  E :    DCHECK_GT(sizeof(buf_), len_);
 544  E :    buf_[len_++] = byte;
 545  E :  }
 546    :  
 547    :  AssemblerImpl::AssemblerImpl(uint32 location, InstructionSerializer* serializer)
 548  E :      : location_(location), serializer_(serializer) {
 549  E :    DCHECK(serializer != NULL);
 550  E :  }
 551    :  
 552  E :  void AssemblerImpl::nop(size_t size) {
 553    :    // These are NOP sequences suggested by the Intel Architecture
 554    :    // Software Developer's manual, page 4-8.
 555    :    //
 556    :    //  1: 0x90
 557    :    //  2: 0x66 0x90
 558    :    //  3: 0x66 0x66 0x90
 559    :    //  4: 0x0F 0x1F 0x40 0x00
 560    :    //  5: 0x0F 0x1F 0x44 0x00 0x00
 561    :    //  6: 0x66 0x0F 0x1F 0x44 0x00 0x00
 562    :    //  7: 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00
 563    :    //  8: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
 564    :    //  9: 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
 565    :    // 10: 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
 566    :    // 11: 0x66 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
 567    :    //
 568    :    // It is further suggested not to put consecutive XCHG NOPs with prefixes,
 569    :    // but rather to mix them with 0x1F NOPs or XCHG NOPs without prefixes. The
 570    :    // basic nops without any operand prefixes (0x66) have been implemented as
 571    :    // helper functions nop1, nop4, nop5, nop7 and nop8. This implementation of
 572    :    // NOP sequences has been inspired by Oracle's HotSpot JVM JIT assembler
 573    :    // (http://openjdk.java.net/groups/hotspot/).
 574    :  
 575    :    // Eat up the NOPs in chunks of 15 bytes.
 576  E :    while (size >= 15) {
 577  E :      nop8(3);  // 11-byte non-XCHG NOP.
 578  E :      nop1(3);  // 4-byte prefixed XCHG NOP.
 579  E :      size -= 15;
 580  E :    }
 581  E :    DCHECK_GE(14u, size);
 582    :  
 583    :    // Handle the last chunk of bytes.
 584  E :    size_t prefix_count = 0;
 585  E :    switch (size) {
 586    :      // Handle 12- to 14-byte NOPs.
 587    :      case 14:
 588  E :        ++prefix_count;
 589    :      case 13:
 590  E :        ++prefix_count;
 591    :      case 12:
 592  E :        nop8(prefix_count);  // 8- to 10-byte non-XCHG NOP.
 593  E :        nop1(3);  // 4-byte prefixed XCHG NOP.
 594  E :        return;
 595    :  
 596    :      // Handle 8- to 11-byte NOPs.
 597    :      case 11:
 598  E :        ++prefix_count;
 599    :      case 10:
 600  E :        ++prefix_count;
 601    :      case 9:
 602  E :        ++prefix_count;
 603    :      case 8:
 604  E :        nop8(prefix_count);  // 8- to 11-byte non-XCHG NOP.
 605  E :        return;
 606    :  
 607    :      // Handle 7-byte NOPs.
 608    :      case 7:
 609  E :        nop7(prefix_count);  // 7-byte non-XCHG NOP.
 610  E :        return;
 611    :  
 612    :      // Handle 5- to 6-byte NOPs.
 613    :      case 6:
 614  E :        ++prefix_count;
 615    :      case 5:
 616  E :        nop5(prefix_count);  // 5- to 6-byte non-XCHG NOP.
 617  E :        return;
 618    :  
 619    :      // Handle 4-byte NOPs.
 620    :      case 4:
 621  E :        nop4(prefix_count);  // 4-byte non-XCHG NOP.
 622  E :        return;
 623    :  
 624    :      // Handle 1- to 3-byte NOPs.
 625    :      case 3:
 626  E :        ++prefix_count;
 627    :      case 2:
 628  E :        ++prefix_count;
 629    :      case 1:
 630  E :        nop1(prefix_count);  // 1- to 3-byte XCHG NOP.
 631    :        return;
 632    :  
 633    :      case 0:
 634    :        // Nothing to do!
 635    :        break;
 636    :    }
 637    :    return;
 638  E :  }
 639    :  
 640  E :  void AssemblerImpl::call(const ImmediateImpl& dst) {
 641  E :    InstructionBuffer instr(this);
 642    :  
 643  E :    instr.EmitOpCodeByte(0xE8);
 644  E :    instr.Emit32BitPCRelative(location_, dst);
 645  E :  }
 646    :  
 647  E :  void AssemblerImpl::call(const OperandImpl& dst) {
 648  E :    InstructionBuffer instr(this);
 649    :  
 650  E :    instr.EmitOpCodeByte(0xFF);
 651  E :    instr.EmitOperand(0x2, dst);
 652  E :  }
 653    :  
 654  E :  void AssemblerImpl::j(ConditionCode cc, const ImmediateImpl& dst) {
 655  E :    DCHECK_LE(kMinConditionCode, cc);
 656  E :    DCHECK_GE(kMaxConditionCode, cc);
 657    :  
 658  E :    InstructionBuffer instr(this);
 659  E :    if (dst.size() == kSize32Bit) {
 660  E :      instr.EmitOpCodeByte(kTwoByteOpCodePrefix);
 661  E :      instr.EmitOpCodeByte(0x80 | cc);
 662  E :      instr.Emit32BitPCRelative(location_, dst);
 663  E :    } else {
 664  E :      DCHECK_EQ(kSize8Bit, dst.size());
 665  E :      instr.EmitOpCodeByte(0x70 | cc);
 666  E :      instr.Emit8BitPCRelative(location_, dst);
 667    :    }
 668  E :  }
 669    :  
 670  E :  void AssemblerImpl::jecxz(const ImmediateImpl& dst) {
 671  E :    DCHECK_EQ(kSize8Bit, dst.size());
 672  E :    InstructionBuffer instr(this);
 673  E :    instr.EmitOpCodeByte(0xE3);
 674  E :    instr.Emit8BitPCRelative(location_, dst);
 675  E :  }
 676    :  
 677  E :  void AssemblerImpl::jmp(const ImmediateImpl& dst) {
 678  E :    InstructionBuffer instr(this);
 679    :  
 680  E :    if (dst.size() == kSize32Bit) {
 681  E :      instr.EmitOpCodeByte(0xE9);
 682  E :      instr.Emit32BitPCRelative(location_, dst);
 683  E :    } else {
 684  E :      DCHECK_EQ(kSize8Bit, dst.size());
 685  E :      instr.EmitOpCodeByte(0xEB);
 686  E :      instr.Emit8BitPCRelative(location_, dst);
 687    :    }
 688  E :  }
 689    :  
 690  E :  void AssemblerImpl::jmp(const OperandImpl& dst) {
 691  E :    InstructionBuffer instr(this);
 692    :  
 693  E :    instr.EmitOpCodeByte(0xFF);
 694  E :    instr.EmitOperand(0x4, dst);
 695  E :  }
 696    :  
 697  E :  void AssemblerImpl::l(LoopCode lc, const ImmediateImpl& dst) {
 698  E :    DCHECK_EQ(kSize8Bit, dst.size());
 699  E :    DCHECK_LE(0, lc);
 700  E :    DCHECK_GE(2, lc);
 701  E :    InstructionBuffer instr(this);
 702    :  
 703  E :    instr.EmitOpCodeByte(0xE0 | lc);
 704  E :    instr.Emit8BitPCRelative(location_, dst);
 705  E :  }
 706    :  
 707  E :  void AssemblerImpl::ret() {
 708  E :    InstructionBuffer instr(this);
 709    :  
 710  E :    instr.EmitOpCodeByte(0xC3);
 711  E :  }
 712    :  
 713  E :  void AssemblerImpl::ret(uint16 n) {
 714  E :    InstructionBuffer instr(this);
 715    :  
 716  E :    instr.EmitOpCodeByte(0xC2);
 717  E :    instr.Emit16BitValue(n);
 718  E :  }
 719    :  
 720  E :  void AssemblerImpl::set(ConditionCode cc, const Register32& dst) {
 721  E :    DCHECK_LE(kMinConditionCode, cc);
 722  E :    DCHECK_GE(kMaxConditionCode, cc);
 723    :  
 724  E :    InstructionBuffer instr(this);
 725  E :    instr.EmitOpCodeByte(kTwoByteOpCodePrefix);
 726  E :    instr.EmitOpCodeByte(0x90 | cc);
 727    :  
 728    :    // AMD64 Architecture Programmers Manual Volume 3: General-Purpose and System
 729    :    // Instructions: The reg field in the ModR/M byte is unused.
 730  E :    const Register32& unused = core::eax;
 731  E :    instr.EmitModRMByte(kReg1, unused.id(), dst.id());
 732  E :  }
 733    :  
 734  E :  void AssemblerImpl::mov_b(const OperandImpl& dst, const ImmediateImpl& src) {
 735  E :    InstructionBuffer instr(this);
 736    :  
 737  E :    instr.EmitOpCodeByte(0xC6);
 738  E :    instr.EmitOperand(0, dst);
 739  E :    instr.Emit8BitDisplacement(src);
 740  E :  }
 741    :  
 742  E :  void AssemblerImpl::movzx_b(const Register32& dst, const OperandImpl& src) {
 743  E :    InstructionBuffer instr(this);
 744  E :    instr.EmitOpCodeByte(kTwoByteOpCodePrefix);
 745  E :    instr.EmitOpCodeByte(0xB6);
 746  E :    instr.EmitOperand(dst.code(), src);
 747  E :  }
 748    :  
 749  E :  void AssemblerImpl::mov(const Register32& dst, const Register32& src) {
 750  E :    InstructionBuffer instr(this);
 751    :  
 752  E :    instr.EmitOpCodeByte(0x8B);
 753  E :    instr.EmitModRMByte(kReg1, dst.id(), src.id());
 754  E :  }
 755    :  
 756  E :  void AssemblerImpl::mov(const Register32& dst, const OperandImpl& src) {
 757  E :    InstructionBuffer instr(this);
 758    :  
 759  E :    if (dst.id() == kRegisterEax && IsDisplacementOnly(src)) {
 760    :      // Special encoding for indirect displacement only to EAX.
 761  E :      instr.EmitOpCodeByte(0xA1);
 762  E :      instr.Emit32BitDisplacement(src.displacement());
 763  E :    } else {
 764  E :      instr.EmitOpCodeByte(0x8B);
 765  E :      instr.EmitOperand(dst.code(), src);
 766    :    }
 767  E :  }
 768    :  
 769  E :  void AssemblerImpl::mov(const OperandImpl& dst, const Register32& src) {
 770  E :    InstructionBuffer instr(this);
 771    :  
 772  E :    if (src.id() == kRegisterEax && IsDisplacementOnly(dst)) {
 773    :      // Special encoding for indirect displacement only from EAX.
 774  E :      instr.EmitOpCodeByte(0xA3);
 775  E :      instr.Emit32BitDisplacement(dst.displacement());
 776  E :    } else {
 777  E :      instr.EmitOpCodeByte(0x89);
 778  E :      instr.EmitOperand(src.code(), dst);
 779    :    }
 780  E :  }
 781    :  
 782  E :  void AssemblerImpl::mov(const Register32& dst, const ValueImpl& src) {
 783  E :    DCHECK_NE(kSizeNone, src.size());
 784  E :    InstructionBuffer instr(this);
 785    :  
 786  E :    instr.EmitOpCodeByte(0xB8 | dst.code());
 787  E :    instr.Emit32BitDisplacement(src);
 788  E :  }
 789    :  
 790  E :  void AssemblerImpl::mov(const OperandImpl& dst, const ImmediateImpl& src) {
 791  E :    InstructionBuffer instr(this);
 792    :  
 793  E :    instr.EmitOpCodeByte(0xC7);
 794  E :    instr.EmitOperand(0, dst);
 795  E :    instr.Emit32BitDisplacement(src);
 796  E :  }
 797    :  
 798  E :  void AssemblerImpl::mov_fs(const Register32& dst, const OperandImpl& src) {
 799  E :    InstructionBuffer instr(this);
 800  E :    instr.EmitOpCodeByte(kFsSegmentPrefix);
 801    :  
 802  E :    if (dst.id() == kRegisterEax && IsDisplacementOnly(src)) {
 803    :      // Special encoding for indirect displacement only to EAX.
 804  i :      instr.EmitOpCodeByte(0xA1);
 805  i :      instr.Emit32BitDisplacement(src.displacement());
 806  i :    } else {
 807  E :      instr.EmitOpCodeByte(0x8B);
 808  E :      instr.EmitOperand(dst.code(), src);
 809    :    }
 810  E :  }
 811    :  
 812  E :  void AssemblerImpl::mov_fs(const OperandImpl& dst, const Register32& src) {
 813  E :    InstructionBuffer instr(this);
 814  E :    instr.EmitOpCodeByte(kFsSegmentPrefix);
 815    :  
 816  E :    if (src.id() == kRegisterEax && IsDisplacementOnly(dst)) {
 817    :      // Special encoding for indirect displacement only from EAX.
 818  i :      instr.EmitOpCodeByte(0xA3);
 819  i :      instr.Emit32BitDisplacement(dst.displacement());
 820  i :    } else {
 821  E :      instr.EmitOpCodeByte(0x89);
 822  E :      instr.EmitOperand(src.code(), dst);
 823    :    }
 824  E :  }
 825    :  
 826  E :  void AssemblerImpl::lea(const Register32& dst, const OperandImpl& src) {
 827  E :    InstructionBuffer instr(this);
 828    :  
 829  E :    instr.EmitOpCodeByte(0x8D);
 830  E :    instr.EmitOperand(dst.code(), src);
 831  E :  }
 832    :  
 833  E :  void AssemblerImpl::push(const Register32& src) {
 834  E :    InstructionBuffer instr(this);
 835    :  
 836  E :    instr.EmitOpCodeByte(0x50 | src.code());
 837  E :  }
 838    :  
 839  E :  void AssemblerImpl::push(const ImmediateImpl& src) {
 840  E :    DCHECK_EQ(kSize32Bit, src.size());
 841  E :    InstructionBuffer instr(this);
 842    :  
 843  E :    instr.EmitOpCodeByte(0x68);
 844  E :    instr.Emit32BitDisplacement(src);
 845  E :  }
 846    :  
 847  E :  void AssemblerImpl::push(const OperandImpl& dst) {
 848  E :    InstructionBuffer instr(this);
 849    :  
 850  E :    instr.EmitOpCodeByte(0xFF);
 851  E :    instr.EmitOperand(0x6, dst);
 852  E :  }
 853    :  
 854  E :  void AssemblerImpl::pop(const Register32& src) {
 855  E :    InstructionBuffer instr(this);
 856    :  
 857  E :    instr.EmitOpCodeByte(0x58 | src.code());
 858  E :  }
 859    :  
 860  E :  void AssemblerImpl::pop(const OperandImpl& dst) {
 861  E :    InstructionBuffer instr(this);
 862    :  
 863  E :    instr.EmitOpCodeByte(0x8F);
 864  E :    instr.EmitOperand(0, dst);
 865  E :  }
 866    :  
 867  E :  void AssemblerImpl::pushfd() {
 868  E :    InstructionBuffer instr(this);
 869  E :    instr.EmitOpCodeByte(0x9C);
 870  E :  }
 871    :  
 872  E :  void AssemblerImpl::popfd() {
 873  E :    InstructionBuffer instr(this);
 874  E :    instr.EmitOpCodeByte(0x9D);
 875  E :  }
 876    :  
 877  E :  void AssemblerImpl::lahf() {
 878  E :    InstructionBuffer instr(this);
 879  E :    instr.EmitOpCodeByte(0x9F);
 880  E :  }
 881    :  
 882  E :  void AssemblerImpl::sahf() {
 883  E :    InstructionBuffer instr(this);
 884  E :    instr.EmitOpCodeByte(0x9E);
 885  E :  }
 886    :  
 887  E :  void AssemblerImpl::test(const Register8& dst, const Register8& src) {
 888  E :    InstructionBuffer instr(this);
 889  E :    instr.EmitArithmeticInstruction(0x84, dst, src);
 890  E :  }
 891    :  
 892  E :  void AssemblerImpl::test(const Register8& dst, const ImmediateImpl& src) {
 893  E :    InstructionBuffer instr(this);
 894  E :    instr.EmitArithmeticInstructionToRegister8(0xA8, 0xF6, 0, dst, src);
 895  E :  }
 896    :  
 897  E :  void AssemblerImpl::test(const Register32& dst, const Register32& src) {
 898  E :    InstructionBuffer instr(this);
 899  E :    instr.EmitArithmeticInstruction(0x85, dst, src);
 900  E :  }
 901    :  
 902  E :  void AssemblerImpl::test(const Register32& dst, const OperandImpl& src) {
 903    :    // Use commutative property for a smaller encoding.
 904  E :    test(src, dst);
 905  E :  }
 906    :  
 907  E :  void AssemblerImpl::test(const OperandImpl& dst, const Register32& src) {
 908  E :    InstructionBuffer instr(this);
 909  E :    instr.EmitArithmeticInstruction(0x85, dst, src);
 910  E :  }
 911    :  
 912  E :  void AssemblerImpl::test(const Register32& dst, const ImmediateImpl& src) {
 913  E :    if (src.size() == kSize8Bit) {
 914    :      // note: There is no encoding for a 8-bit immediate with 32-bit register.
 915  E :      test(dst, ImmediateImpl(src.value(), kSize32Bit));
 916  E :    } else {
 917  E :      InstructionBuffer instr(this);
 918  E :      instr.EmitArithmeticInstructionToRegister32(0xA9, 0xF7, 0xF7, 0, dst, src);
 919  E :    }
 920  E :  }
 921    :  
 922  E :  void AssemblerImpl::test(const OperandImpl& dst, const ImmediateImpl& src) {
 923  E :    if (src.size() == kSize8Bit) {
 924    :      // note: There is no encoding for a 8-bit immediate with 32-bit register.
 925  E :      test(dst, ImmediateImpl(src.value(), kSize32Bit));
 926  E :    } else {
 927  E :      InstructionBuffer instr(this);
 928  E :      instr.EmitArithmeticInstructionToOperand(0xF7, 0xF7, 0, dst, src);
 929  E :    }
 930  E :  }
 931    :  
 932  E :  void AssemblerImpl::cmp(const Register8& dst, const Register8& src) {
 933  E :    InstructionBuffer instr(this);
 934  E :    instr.EmitArithmeticInstruction(0x3A, dst, src);
 935  E :  }
 936    :  
 937  E :  void AssemblerImpl::cmp(const Register8& dst, const ImmediateImpl& src) {
 938  E :    InstructionBuffer instr(this);
 939  E :    instr.EmitArithmeticInstructionToRegister8(0x3C, 0x80, 7, dst, src);
 940  E :  }
 941    :  
 942  E :  void AssemblerImpl::cmp(const Register32& dst, const Register32& src) {
 943  E :    InstructionBuffer instr(this);
 944  E :    instr.EmitArithmeticInstruction(0x3B, dst, src);
 945  E :  }
 946    :  
 947  E :  void AssemblerImpl::cmp(const Register32& dst, const OperandImpl& src) {
 948  E :    InstructionBuffer instr(this);
 949  E :    instr.EmitArithmeticInstruction(0x3B, dst, src);
 950  E :  }
 951    :  
 952  E :  void AssemblerImpl::cmp(const OperandImpl& dst, const Register32& src) {
 953  E :    InstructionBuffer instr(this);
 954  E :    instr.EmitArithmeticInstruction(0x39, dst, src);
 955  E :  }
 956    :  
 957  E :  void AssemblerImpl::cmp(const Register32& dst, const ImmediateImpl& src) {
 958  E :    InstructionBuffer instr(this);
 959  E :    instr.EmitArithmeticInstructionToRegister32(0x3D, 0x83, 0x81, 7, dst, src);
 960  E :  }
 961    :  
 962  E :  void AssemblerImpl::cmp(const OperandImpl& dst, const ImmediateImpl& src) {
 963  E :    InstructionBuffer instr(this);
 964  E :    instr.EmitArithmeticInstructionToOperand(0x83, 0x81, 7, dst, src);
 965  E :  }
 966    :  
 967  E :  void AssemblerImpl::add(const Register8& dst, const Register8& src) {
 968  E :    InstructionBuffer instr(this);
 969  E :    instr.EmitArithmeticInstruction(0x02, dst, src);
 970  E :  }
 971    :  
 972  E :  void AssemblerImpl::add(const Register8& dst, const ImmediateImpl& src) {
 973  E :    InstructionBuffer instr(this);
 974  E :    instr.EmitArithmeticInstructionToRegister8(0x04, 0x80, 0, dst, src);
 975  E :  }
 976    :  
 977  E :  void AssemblerImpl::add(const Register32& dst, const Register32& src) {
 978  E :    InstructionBuffer instr(this);
 979  E :    instr.EmitArithmeticInstruction(0x03, dst, src);
 980  E :  }
 981    :  
 982  E :  void AssemblerImpl::add(const Register32& dst, const OperandImpl& src) {
 983  E :    InstructionBuffer instr(this);
 984  E :    instr.EmitArithmeticInstruction(0x03, dst, src);
 985  E :  }
 986    :  
 987  E :  void AssemblerImpl::add(const OperandImpl& dst, const Register32& src) {
 988  E :    InstructionBuffer instr(this);
 989  E :    instr.EmitArithmeticInstruction(0x01, dst, src);
 990  E :  }
 991    :  
 992  E :  void AssemblerImpl::add(const Register32& dst, const ImmediateImpl& src) {
 993  E :    InstructionBuffer instr(this);
 994  E :    instr.EmitArithmeticInstructionToRegister32(0x05, 0x83, 0x81, 0, dst, src);
 995  E :  }
 996    :  
 997  E :  void AssemblerImpl::add(const OperandImpl& dst, const ImmediateImpl& src) {
 998  E :    InstructionBuffer instr(this);
 999  E :    instr.EmitArithmeticInstructionToOperand(0x83, 0x81, 0, dst, src);
1000  E :  }
1001    :  
1002  E :  void AssemblerImpl::sub(const Register8& dst, const Register8& src) {
1003  E :    InstructionBuffer instr(this);
1004  E :    instr.EmitArithmeticInstruction(0x2A, dst, src);
1005  E :  }
1006    :  
1007  E :  void AssemblerImpl::sub(const Register8& dst, const ImmediateImpl& src) {
1008  E :    InstructionBuffer instr(this);
1009  E :    instr.EmitArithmeticInstructionToRegister8(0x2C, 0x80, 5, dst, src);
1010  E :  }
1011    :  
1012  E :  void AssemblerImpl::sub(const Register32& dst, const Register32& src) {
1013  E :    InstructionBuffer instr(this);
1014  E :    instr.EmitArithmeticInstruction(0x2B, dst, src);
1015  E :  }
1016    :  
1017  E :  void AssemblerImpl::sub(const Register32& dst, const OperandImpl& src) {
1018  E :    InstructionBuffer instr(this);
1019  E :    instr.EmitArithmeticInstruction(0x2B, dst, src);
1020  E :  }
1021    :  
1022  E :  void AssemblerImpl::sub(const OperandImpl&  dst, const Register32& src) {
1023  E :    InstructionBuffer instr(this);
1024  E :    instr.EmitArithmeticInstruction(0x29, dst, src);
1025  E :  }
1026    :  
1027  E :  void AssemblerImpl::sub(const Register32& dst, const ImmediateImpl& src) {
1028  E :    InstructionBuffer instr(this);
1029  E :    instr.EmitArithmeticInstructionToRegister32(0x2D, 0x83, 0x81, 5, dst, src);
1030  E :  }
1031    :  
1032  E :  void AssemblerImpl::sub(const OperandImpl&  dst, const ImmediateImpl& src) {
1033  E :    InstructionBuffer instr(this);
1034  E :    instr.EmitArithmeticInstructionToOperand(0x83, 0x81, 5, dst, src);
1035  E :  }
1036    :  
1037  E :  void AssemblerImpl::shl(const Register32& dst, const ImmediateImpl& src) {
1038  E :    InstructionBuffer instr(this);
1039  E :    if (src.value() == 1) {
1040  E :      instr.EmitOpCodeByte(0xD1);
1041  E :      instr.EmitModRMByte(kReg1, 4, dst.id());
1042  E :    } else {
1043  E :      instr.EmitOpCodeByte(0xC1);
1044  E :      instr.EmitModRMByte(kReg1, 4, dst.id());
1045  E :      instr.Emit8BitDisplacement(src);
1046    :    }
1047  E :  }
1048    :  
1049  E :  void AssemblerImpl::shr(const Register32& dst, const ImmediateImpl& src) {
1050  E :    InstructionBuffer instr(this);
1051  E :    if (src.value() == 1) {
1052  E :      instr.EmitOpCodeByte(0xD1);
1053  E :      instr.EmitModRMByte(kReg1, 5, dst.id());
1054  E :    } else {
1055  E :      instr.EmitOpCodeByte(0xC1);
1056  E :      instr.EmitModRMByte(kReg1, 5, dst.id());
1057  E :      instr.Emit8BitDisplacement(src);
1058    :    }
1059  E :  }
1060    :  
1061  E :  void AssemblerImpl::xchg(const Register32& dst, const Register32& src) {
1062  E :    InstructionBuffer instr(this);
1063  E :    instr.EmitXchg(kSize32Bit, dst.id(), src.id());
1064  E :  }
1065    :  
1066  E :  void AssemblerImpl::xchg(const Register16& dst, const Register16& src) {
1067  E :    InstructionBuffer instr(this);
1068  E :    instr.EmitXchg(kSize16Bit, dst.id(), src.id());
1069  E :  }
1070    :  
1071  E :  void AssemblerImpl::xchg(const Register8& dst, const Register8& src) {
1072  E :    InstructionBuffer instr(this);
1073  E :    instr.EmitXchg(kSize8Bit, dst.id(), src.id());
1074  E :  }
1075    :  
1076  E :  void AssemblerImpl::nop1(size_t prefix_count) {
1077  E :    InstructionBuffer instr(this);
1078  E :    instr.EmitOperandSizePrefix(prefix_count);
1079  E :    instr.EmitXchg(kSize32Bit, kRegisterEax, kRegisterEax);
1080  E :  }
1081    :  
1082  E :  void AssemblerImpl::nop4(size_t prefix_count) {
1083  E :    InstructionBuffer instr(this);
1084  E :    instr.EmitOperandSizePrefix(prefix_count);
1085    :    // 4 bytes: NOP DWORD PTR [EAX + 0] 8-bit offset
1086  E :    instr.EmitOpCodeByte(kTwoByteOpCodePrefix);
1087  E :    instr.EmitOpCodeByte(kNopOpCode);
1088  E :    instr.EmitModRMByte(kReg1ByteDisp, 0, kRegisterEax);
1089  E :    instr.Emit8BitDisplacement(DisplacementImpl(0, kSize8Bit));
1090  E :  }
1091    :  
1092  E :  void AssemblerImpl::nop5(size_t prefix_count) {
1093  E :    InstructionBuffer instr(this);
1094  E :    instr.EmitOperandSizePrefix(prefix_count);
1095    :    // 5 bytes: NOP DWORD PTR [EAX + EAX * 1 + 0] 8-bit offset
1096  E :    instr.EmitOpCodeByte(kTwoByteOpCodePrefix);
1097  E :    instr.EmitOpCodeByte(kNopOpCode);
1098    :    // esp in the ModR/M byte indicates SIB to follow.
1099  E :    instr.EmitModRMByte(kReg1ByteDisp, 0, kRegisterEsp);
1100  E :    instr.EmitScaleIndexBaseByte(kTimes1, kRegisterEax, kRegisterEax);
1101  E :    instr.Emit8BitDisplacement(DisplacementImpl(0, kSize8Bit));
1102  E :  }
1103    :  
1104  E :  void AssemblerImpl::nop7(size_t prefix_count) {
1105  E :    InstructionBuffer instr(this);
1106  E :    instr.EmitOperandSizePrefix(prefix_count);
1107    :    // 7 bytes: NOP DWORD PTR [EAX + 0] 32-bit offset
1108  E :    instr.EmitOpCodeByte(kTwoByteOpCodePrefix);
1109  E :    instr.EmitOpCodeByte(kNopOpCode);
1110  E :    instr.EmitModRMByte(kReg1WordDisp, 0, kRegisterEax);
1111  E :    instr.Emit32BitDisplacement(DisplacementImpl(0, kSize32Bit));
1112  E :  }
1113    :  
1114  E :  void AssemblerImpl::nop8(size_t prefix_count) {
1115  E :    InstructionBuffer instr(this);
1116  E :    instr.EmitOperandSizePrefix(prefix_count);
1117    :    // 8 bytes: NOP DWORD PTR [EAX + EAX * 1 + 0] 32-bit offset
1118  E :    instr.EmitOpCodeByte(kTwoByteOpCodePrefix);
1119  E :    instr.EmitOpCodeByte(kNopOpCode);
1120    :    // esp in the ModR/M byte indicates SIB to follow.
1121  E :    instr.EmitModRMByte(kReg1WordDisp, 0, kRegisterEsp);
1122  E :    instr.EmitScaleIndexBaseByte(kTimes1, kRegisterEax, kRegisterEax);
1123  E :    instr.Emit32BitDisplacement(DisplacementImpl(0, kSize32Bit));
1124  E :  }
1125    :  
1126  E :  void AssemblerImpl::Output(const InstructionBuffer& instr) {
1127    :    serializer_->AppendInstruction(location_,
1128    :                                   instr.buf(),
1129    :                                   instr.len(),
1130    :                                   instr.reference_offsets(),
1131    :                                   instr.references(),
1132  E :                                   instr.num_references());
1133    :  
1134  E :    location_ += instr.len();
1135  E :  }
1136    :  
1137    :  }  // namespace core

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