Renames the assembler* files.
Renames the assembler* files to IceAssembler*. Fixes whatever breaks.
BUG= https://code.google.com/p/nativeclient/issues/detail?id=4077
R=jvoung@chromium.org
Review URL: https://codereview.chromium.org/1179563004.
diff --git a/Makefile.standalone b/Makefile.standalone
index 82eff15..a641ce1 100644
--- a/Makefile.standalone
+++ b/Makefile.standalone
@@ -163,8 +163,8 @@
SB_LDFLAGS := $(LINKOPTLEVEL) $(LD_EXTRA)
SRCS = \
- assembler.cpp \
- assembler_ia32.cpp \
+ IceAssembler.cpp \
+ IceAssemblerX8632.cpp \
IceBrowserCompileServer.cpp \
IceCfg.cpp \
IceCfgNode.cpp \
diff --git a/src/assembler.cpp b/src/IceAssembler.cpp
similarity index 66%
rename from src/assembler.cpp
rename to src/IceAssembler.cpp
index 931998e..a0500d6 100644
--- a/src/assembler.cpp
+++ b/src/IceAssembler.cpp
@@ -1,4 +1,4 @@
-//===- subzero/src/assembler.cpp - Assembler base class -------------------===//
+//===- subzero/src/IceAssembler.cpp - Assembler base class ----------------===//
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -18,81 +18,81 @@
//
//===----------------------------------------------------------------------===//
//
-// This file implements the Assembler class.
+// This file implements the Assembler base class.
//
//===----------------------------------------------------------------------===//
-#include "assembler.h"
+#include "IceAssembler.h"
#include "IceGlobalContext.h"
#include "IceOperand.h"
namespace Ice {
-static uintptr_t NewContents(Assembler &assembler, intptr_t capacity) {
- uintptr_t result = assembler.AllocateBytes(capacity);
- return result;
+static uintptr_t NewContents(Assembler &Assemblr, intptr_t Capacity) {
+ uintptr_t Result = Assemblr.allocateBytes(Capacity);
+ return Result;
}
AssemblerFixup *AssemblerBuffer::createFixup(FixupKind Kind,
const Constant *Value) {
AssemblerFixup *F =
- new (assembler_.Allocate<AssemblerFixup>()) AssemblerFixup();
+ new (Assemblr.allocate<AssemblerFixup>()) AssemblerFixup();
F->set_position(0);
F->set_kind(Kind);
F->set_value(Value);
- if (!assembler_.getPreliminary())
- fixups_.push_back(F);
+ if (!Assemblr.getPreliminary())
+ Fixups.push_back(F);
return F;
}
#ifndef NDEBUG
AssemblerBuffer::EnsureCapacity::EnsureCapacity(AssemblerBuffer *buffer) {
if (buffer->cursor() >= buffer->limit())
- buffer->ExtendCapacity();
+ buffer->extendCapacity();
// In debug mode, we save the assembler buffer along with the gap
// size before we start emitting to the buffer. This allows us to
// check that any single generated instruction doesn't overflow the
// limit implied by the minimum gap size.
- buffer_ = buffer;
- gap_ = ComputeGap();
+ Buffer = buffer;
+ Gap = computeGap();
// Make sure that extending the capacity leaves a big enough gap
// for any kind of instruction.
- assert(gap_ >= kMinimumGap);
+ assert(Gap >= kMinimumGap);
// Mark the buffer as having ensured the capacity.
- assert(!buffer->HasEnsuredCapacity()); // Cannot nest.
- buffer->has_ensured_capacity_ = true;
+ assert(!buffer->hasEnsuredCapacity()); // Cannot nest.
+ buffer->HasEnsuredCapacity = true;
}
AssemblerBuffer::EnsureCapacity::~EnsureCapacity() {
// Unmark the buffer, so we cannot emit after this.
- buffer_->has_ensured_capacity_ = false;
+ Buffer->HasEnsuredCapacity = false;
// Make sure the generated instruction doesn't take up more
// space than the minimum gap.
- intptr_t delta = gap_ - ComputeGap();
+ intptr_t delta = Gap - computeGap();
assert(delta <= kMinimumGap);
}
#endif // !NDEBUG
-AssemblerBuffer::AssemblerBuffer(Assembler &assembler) : assembler_(assembler) {
+AssemblerBuffer::AssemblerBuffer(Assembler &Asm) : Assemblr(Asm) {
const intptr_t OneKB = 1024;
static const intptr_t kInitialBufferCapacity = 4 * OneKB;
- contents_ = NewContents(assembler_, kInitialBufferCapacity);
- cursor_ = contents_;
- limit_ = ComputeLimit(contents_, kInitialBufferCapacity);
+ Contents = NewContents(Assemblr, kInitialBufferCapacity);
+ Cursor = Contents;
+ Limit = computeLimit(Contents, kInitialBufferCapacity);
#ifndef NDEBUG
- has_ensured_capacity_ = false;
+ HasEnsuredCapacity = false;
#endif // !NDEBUG
// Verify internal state.
- assert(Capacity() == kInitialBufferCapacity);
- assert(Size() == 0);
+ assert(capacity() == kInitialBufferCapacity);
+ assert(size() == 0);
}
AssemblerBuffer::~AssemblerBuffer() {}
-void AssemblerBuffer::ExtendCapacity() {
- intptr_t old_size = Size();
- intptr_t old_capacity = Capacity();
+void AssemblerBuffer::extendCapacity() {
+ intptr_t old_size = size();
+ intptr_t old_capacity = capacity();
const intptr_t OneMB = 1 << 20;
intptr_t new_capacity = std::min(old_capacity * 2, old_capacity + OneMB);
if (new_capacity < old_capacity) {
@@ -101,42 +101,42 @@
}
// Allocate the new data area and copy contents of the old one to it.
- uintptr_t new_contents = NewContents(assembler_, new_capacity);
+ uintptr_t new_contents = NewContents(Assemblr, new_capacity);
memmove(reinterpret_cast<void *>(new_contents),
- reinterpret_cast<void *>(contents_), old_size);
+ reinterpret_cast<void *>(Contents), old_size);
// Compute the relocation delta and switch to the new contents area.
- intptr_t delta = new_contents - contents_;
- contents_ = new_contents;
+ intptr_t delta = new_contents - Contents;
+ Contents = new_contents;
// Update the cursor and recompute the limit.
- cursor_ += delta;
- limit_ = ComputeLimit(new_contents, new_capacity);
+ Cursor += delta;
+ Limit = computeLimit(new_contents, new_capacity);
// Verify internal state.
- assert(Capacity() == new_capacity);
- assert(Size() == old_size);
+ assert(capacity() == new_capacity);
+ assert(size() == old_size);
}
llvm::StringRef Assembler::getBufferView() const {
- return llvm::StringRef(reinterpret_cast<const char *>(buffer_.contents()),
- buffer_.Size());
+ return llvm::StringRef(reinterpret_cast<const char *>(Buffer.contents()),
+ Buffer.size());
}
void Assembler::emitIASBytes(GlobalContext *Ctx) const {
Ostream &Str = Ctx->getStrEmit();
- intptr_t EndPosition = buffer_.Size();
+ intptr_t EndPosition = Buffer.size();
intptr_t CurPosition = 0;
const intptr_t FixupSize = 4;
for (const AssemblerFixup *NextFixup : fixups()) {
intptr_t NextFixupLoc = NextFixup->position();
for (intptr_t i = CurPosition; i < NextFixupLoc; ++i) {
Str << "\t.byte 0x";
- Str.write_hex(buffer_.Load<uint8_t>(i));
+ Str.write_hex(Buffer.load<uint8_t>(i));
Str << "\n";
}
Str << "\t.long ";
- NextFixup->emit(Ctx, buffer_.Load<RelocOffsetT>(NextFixupLoc));
+ NextFixup->emit(Ctx, Buffer.load<RelocOffsetT>(NextFixupLoc));
if (fixupIsPCRel(NextFixup->kind()))
Str << " - .";
Str << "\n";
@@ -146,7 +146,7 @@
// Handle any bytes that are not prefixed by a fixup.
for (intptr_t i = CurPosition; i < EndPosition; ++i) {
Str << "\t.byte 0x";
- Str.write_hex(buffer_.Load<uint8_t>(i));
+ Str.write_hex(Buffer.load<uint8_t>(i));
Str << "\n";
}
}
diff --git a/src/assembler.h b/src/IceAssembler.h
similarity index 68%
rename from src/assembler.h
rename to src/IceAssembler.h
index cf65d94..131b62a 100644
--- a/src/assembler.h
+++ b/src/IceAssembler.h
@@ -1,4 +1,4 @@
-//===- subzero/src/assembler.h - Integrated assembler -----------*- C++ -*-===//
+//===- subzero/src/IceAssembler.h - Integrated assembler --------*- C++ -*-===//
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -20,8 +20,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef SUBZERO_SRC_ASSEMBLER_H
-#define SUBZERO_SRC_ASSEMBLER_H
+#ifndef SUBZERO_SRC_ICEASSEMBLER_H
+#define SUBZERO_SRC_ICEASSEMBLER_H
#include "IceDefs.h"
#include "IceFixups.h"
@@ -38,30 +38,30 @@
~AssemblerBuffer();
// Basic support for emitting, loading, and storing.
- template <typename T> void Emit(T value) {
- assert(HasEnsuredCapacity());
- *reinterpret_cast<T *>(cursor_) = value;
- cursor_ += sizeof(T);
+ template <typename T> void emit(T Value) {
+ assert(hasEnsuredCapacity());
+ *reinterpret_cast<T *>(Cursor) = Value;
+ Cursor += sizeof(T);
}
- template <typename T> T Load(intptr_t position) const {
- assert(position >= 0 &&
- position <= (Size() - static_cast<intptr_t>(sizeof(T))));
- return *reinterpret_cast<T *>(contents_ + position);
+ template <typename T> T load(intptr_t Position) const {
+ assert(Position >= 0 &&
+ Position <= (size() - static_cast<intptr_t>(sizeof(T))));
+ return *reinterpret_cast<T *>(Contents + Position);
}
- template <typename T> void Store(intptr_t position, T value) {
- assert(position >= 0 &&
- position <= (Size() - static_cast<intptr_t>(sizeof(T))));
- *reinterpret_cast<T *>(contents_ + position) = value;
+ template <typename T> void store(intptr_t Position, T Value) {
+ assert(Position >= 0 &&
+ Position <= (size() - static_cast<intptr_t>(sizeof(T))));
+ *reinterpret_cast<T *>(Contents + Position) = Value;
}
// Emit a fixup at the current location.
- void EmitFixup(AssemblerFixup *fixup) { fixup->set_position(Size()); }
+ void emitFixup(AssemblerFixup *Fixup) { Fixup->set_position(size()); }
// Get the size of the emitted code.
- intptr_t Size() const { return cursor_ - contents_; }
- uintptr_t contents() const { return contents_; }
+ intptr_t size() const { return Cursor - Contents; }
+ uintptr_t contents() const { return Contents; }
// To emit an instruction to the assembler buffer, the EnsureCapacity helper
// must be used to guarantee that the underlying data area is big enough to
@@ -77,47 +77,47 @@
EnsureCapacity &operator=(const EnsureCapacity &) = delete;
public:
- explicit EnsureCapacity(AssemblerBuffer *buffer);
+ explicit EnsureCapacity(AssemblerBuffer *Buffer);
~EnsureCapacity();
private:
- AssemblerBuffer *buffer_;
- intptr_t gap_;
+ AssemblerBuffer *Buffer;
+ intptr_t Gap;
- intptr_t ComputeGap() { return buffer_->Capacity() - buffer_->Size(); }
+ intptr_t computeGap() { return Buffer->capacity() - Buffer->size(); }
};
- bool has_ensured_capacity_;
- bool HasEnsuredCapacity() const { return has_ensured_capacity_; }
+ bool HasEnsuredCapacity;
+ bool hasEnsuredCapacity() const { return HasEnsuredCapacity; }
#else // NDEBUG
class EnsureCapacity {
EnsureCapacity(const EnsureCapacity &) = delete;
EnsureCapacity &operator=(const EnsureCapacity &) = delete;
public:
- explicit EnsureCapacity(AssemblerBuffer *buffer) {
- if (buffer->cursor() >= buffer->limit())
- buffer->ExtendCapacity();
+ explicit EnsureCapacity(AssemblerBuffer *Buffer) {
+ if (Buffer->cursor() >= buffer->limit())
+ buffer->extendCapacity();
}
};
// When building the C++ tests, assertion code is enabled. To allow
// asserting that the user of the assembler buffer has ensured the
// capacity needed for emitting, we add a dummy method in non-debug mode.
- bool HasEnsuredCapacity() const { return true; }
+ bool hasEnsuredCapacity() const { return true; }
#endif // NDEBUG
// Returns the position in the instruction stream.
- intptr_t GetPosition() const { return cursor_ - contents_; }
+ intptr_t getPosition() const { return Cursor - Contents; }
// Create and track a fixup in the current function.
AssemblerFixup *createFixup(FixupKind Kind, const Constant *Value);
- const FixupRefList &fixups() const { return fixups_; }
+ const FixupRefList &fixups() const { return Fixups; }
void setSize(intptr_t NewSize) {
- assert(NewSize <= Size());
- cursor_ = contents_ + NewSize;
+ assert(NewSize <= size());
+ Cursor = Contents + NewSize;
}
private:
@@ -126,27 +126,28 @@
// for a single, fast space check per instruction.
static const intptr_t kMinimumGap = 32;
- uintptr_t contents_;
- uintptr_t cursor_;
- uintptr_t limit_;
- Assembler &assembler_;
+ uintptr_t Contents;
+ uintptr_t Cursor;
+ uintptr_t Limit;
+ // The member variable is named Assemblr to avoid hiding the class Assembler.
+ Assembler &Assemblr;
// List of pool-allocated fixups relative to the current function.
- FixupRefList fixups_;
+ FixupRefList Fixups;
- uintptr_t cursor() const { return cursor_; }
- uintptr_t limit() const { return limit_; }
- intptr_t Capacity() const {
- assert(limit_ >= contents_);
- return (limit_ - contents_) + kMinimumGap;
+ uintptr_t cursor() const { return Cursor; }
+ uintptr_t limit() const { return Limit; }
+ intptr_t capacity() const {
+ assert(Limit >= Contents);
+ return (Limit - Contents) + kMinimumGap;
}
// Compute the limit based on the data area and the capacity. See
// description of kMinimumGap for the reasoning behind the value.
- static uintptr_t ComputeLimit(uintptr_t data, intptr_t capacity) {
- return data + capacity - kMinimumGap;
+ static uintptr_t computeLimit(uintptr_t Data, intptr_t Capacity) {
+ return Data + Capacity - kMinimumGap;
}
- void ExtendCapacity();
+ void extendCapacity();
};
class Assembler {
@@ -155,12 +156,12 @@
public:
Assembler()
- : FunctionName(""), IsInternal(false), Preliminary(false),
- buffer_(*this) {}
- virtual ~Assembler() {}
+ : Buffer(*this), FunctionName(""), IsInternal(false),
+ Preliminary(false) {}
+ virtual ~Assembler() = default;
// Allocate a chunk of bytes using the per-Assembler allocator.
- uintptr_t AllocateBytes(size_t bytes) {
+ uintptr_t allocateBytes(size_t bytes) {
// For now, alignment is not related to NaCl bundle alignment, since
// the buffer's GetPosition is relative to the base. So NaCl bundle
// alignment checks can be relative to that base. Later, the buffer
@@ -172,7 +173,7 @@
}
// Allocate data of type T using the per-Assembler allocator.
- template <typename T> T *Allocate() { return Allocator.Allocate<T>(); }
+ template <typename T> T *allocate() { return Allocator.Allocate<T>(); }
// Align the tail end of the function to the required target alignment.
virtual void alignFunction() = 0;
@@ -187,17 +188,17 @@
// Mark the current text location as the start of a CFG node
// (represented by NodeNumber).
- virtual void BindCfgNodeLabel(SizeT NodeNumber) = 0;
+ virtual void bindCfgNodeLabel(SizeT NodeNumber) = 0;
virtual bool fixupIsPCRel(FixupKind Kind) const = 0;
// Return a view of all the bytes of code for the current function.
llvm::StringRef getBufferView() const;
- const FixupRefList &fixups() const { return buffer_.fixups(); }
+ const FixupRefList &fixups() const { return Buffer.fixups(); }
AssemblerFixup *createFixup(FixupKind Kind, const Constant *Value) {
- return buffer_.createFixup(Kind, Value);
+ return Buffer.createFixup(Kind, Value);
}
void emitIASBytes(GlobalContext *Ctx) const;
@@ -205,12 +206,15 @@
void setInternal(bool Internal) { IsInternal = Internal; }
const IceString &getFunctionName() { return FunctionName; }
void setFunctionName(const IceString &NewName) { FunctionName = NewName; }
- intptr_t getBufferSize() const { return buffer_.Size(); }
+ intptr_t getBufferSize() const { return Buffer.size(); }
// Roll back to a (smaller) size.
- void setBufferSize(intptr_t NewSize) { buffer_.setSize(NewSize); }
+ void setBufferSize(intptr_t NewSize) { Buffer.setSize(NewSize); }
void setPreliminary(bool Value) { Preliminary = Value; }
bool getPreliminary() const { return Preliminary; }
+protected:
+ AssemblerBuffer Buffer;
+
private:
ArenaAllocator<32 * 1024> Allocator;
// FunctionName and IsInternal are transferred from the original Cfg
@@ -223,11 +227,8 @@
// final pass where all changes to label bindings, label links, and
// relocation fixups are fully committed (Preliminary=false).
bool Preliminary;
-
-protected:
- AssemblerBuffer buffer_;
};
} // end of namespace Ice
-#endif // SUBZERO_SRC_ASSEMBLER_H_
+#endif // SUBZERO_SRC_ICEASSEMBLER_H_
diff --git a/src/assembler_arm32.h b/src/IceAssemblerARM32.h
similarity index 88%
rename from src/assembler_arm32.h
rename to src/IceAssemblerARM32.h
index 54eadec..a032204 100644
--- a/src/assembler_arm32.h
+++ b/src/IceAssemblerARM32.h
@@ -1,4 +1,4 @@
-//===- subzero/src/assembler_arm32.h - Assembler for ARM32 ------*- C++ -*-===//
+//===- subzero/src/IceAssemblerARM32.h - Assembler for ARM32 ----*- C++ -*-===//
//
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
@@ -19,14 +19,13 @@
//
//===----------------------------------------------------------------------===//
-#ifndef SUBZERO_SRC_ASSEMBLER_ARM32_H
-#define SUBZERO_SRC_ASSEMBLER_ARM32_H
+#ifndef SUBZERO_SRC_ICEASSEMBLERARM32_H
+#define SUBZERO_SRC_ICEASSEMBLERARM32_H
+#include "IceAssembler.h"
#include "IceDefs.h"
#include "IceFixups.h"
-#include "assembler.h"
-
namespace Ice {
namespace ARM32 {
@@ -60,7 +59,7 @@
llvm_unreachable("Not yet implemented.");
}
- void BindCfgNodeLabel(SizeT NodeNumber) override {
+ void bindCfgNodeLabel(SizeT NodeNumber) override {
(void)NodeNumber;
llvm_unreachable("Not yet implemented.");
}
@@ -74,4 +73,4 @@
} // end of namespace ARM32
} // end of namespace Ice
-#endif // SUBZERO_SRC_ASSEMBLER_ARM32_H
+#endif // SUBZERO_SRC_ICEASSEMBLERARM32_H
diff --git a/src/IceAssemblerX8632.cpp b/src/IceAssemblerX8632.cpp
new file mode 100644
index 0000000..a45e7cc
--- /dev/null
+++ b/src/IceAssemblerX8632.cpp
@@ -0,0 +1,2609 @@
+//===- subzero/src/IceAssemblerX8632.cpp - Assembler for x86-32 ----------===//
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// Modified by the Subzero authors.
+//
+//===----------------------------------------------------------------------===//
+//
+// The Subzero Code Generator
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Assembler class for x86-32.
+//
+//===----------------------------------------------------------------------===//
+
+#include "IceAssemblerX8632.h"
+#include "IceCfg.h"
+#include "IceOperand.h"
+
+namespace Ice {
+namespace X8632 {
+
+Address Address::ofConstPool(Assembler *Asm, const Constant *Imm) {
+ AssemblerFixup *Fixup = Asm->createFixup(llvm::ELF::R_386_32, Imm);
+ const RelocOffsetT Offset = 0;
+ return Address::Absolute(Offset, Fixup);
+}
+
+AssemblerX8632::~AssemblerX8632() {
+#ifndef NDEBUG
+ for (const Label *Label : CfgNodeLabels) {
+ Label->FinalCheck();
+ }
+ for (const Label *Label : LocalLabels) {
+ Label->FinalCheck();
+ }
+#endif
+}
+
+void AssemblerX8632::alignFunction() {
+ SizeT Align = 1 << getBundleAlignLog2Bytes();
+ SizeT BytesNeeded = Utils::OffsetToAlignment(Buffer.getPosition(), Align);
+ const SizeT HltSize = 1;
+ while (BytesNeeded > 0) {
+ hlt();
+ BytesNeeded -= HltSize;
+ }
+}
+
+Label *AssemblerX8632::GetOrCreateLabel(SizeT Number, LabelVector &Labels) {
+ Label *L = nullptr;
+ if (Number == Labels.size()) {
+ L = new (this->allocate<Label>()) Label();
+ Labels.push_back(L);
+ return L;
+ }
+ if (Number > Labels.size()) {
+ Labels.resize(Number + 1);
+ }
+ L = Labels[Number];
+ if (!L) {
+ L = new (this->allocate<Label>()) Label();
+ Labels[Number] = L;
+ }
+ return L;
+}
+
+Label *AssemblerX8632::GetOrCreateCfgNodeLabel(SizeT NodeNumber) {
+ return GetOrCreateLabel(NodeNumber, CfgNodeLabels);
+}
+
+Label *AssemblerX8632::GetOrCreateLocalLabel(SizeT Number) {
+ return GetOrCreateLabel(Number, LocalLabels);
+}
+
+void AssemblerX8632::bindCfgNodeLabel(SizeT NodeNumber) {
+ assert(!getPreliminary());
+ Label *L = GetOrCreateCfgNodeLabel(NodeNumber);
+ this->bind(L);
+}
+
+void AssemblerX8632::BindLocalLabel(SizeT Number) {
+ Label *L = GetOrCreateLocalLabel(Number);
+ if (!getPreliminary())
+ this->bind(L);
+}
+
+void AssemblerX8632::call(GPRRegister reg) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0xFF);
+ emitRegisterOperand(2, reg);
+}
+
+void AssemblerX8632::call(const Address &address) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0xFF);
+ emitOperand(2, address);
+}
+
+void AssemblerX8632::call(const ConstantRelocatable *label) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ intptr_t call_start = Buffer.getPosition();
+ emitUint8(0xE8);
+ emitFixup(this->createFixup(llvm::ELF::R_386_PC32, label));
+ emitInt32(-4);
+ assert((Buffer.getPosition() - call_start) == kCallExternalLabelSize);
+ (void)call_start;
+}
+
+void AssemblerX8632::call(const Immediate &abs_address) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ intptr_t call_start = Buffer.getPosition();
+ emitUint8(0xE8);
+ emitFixup(
+ this->createFixup(llvm::ELF::R_386_PC32, AssemblerFixup::NullSymbol));
+ emitInt32(abs_address.value() - 4);
+ assert((Buffer.getPosition() - call_start) == kCallExternalLabelSize);
+ (void)call_start;
+}
+
+void AssemblerX8632::pushl(GPRRegister reg) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x50 + reg);
+}
+
+void AssemblerX8632::popl(GPRRegister reg) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x58 + reg);
+}
+
+void AssemblerX8632::popl(const Address &address) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x8F);
+ emitOperand(0, address);
+}
+
+void AssemblerX8632::pushal() {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x60);
+}
+
+void AssemblerX8632::popal() {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x61);
+}
+
+void AssemblerX8632::setcc(CondX86::BrCond condition, ByteRegister dst) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x0F);
+ emitUint8(0x90 + condition);
+ emitUint8(0xC0 + dst);
+}
+
+void AssemblerX8632::setcc(CondX86::BrCond condition, const Address &address) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x0F);
+ emitUint8(0x90 + condition);
+ emitOperand(0, address);
+}
+
+void AssemblerX8632::mov(Type Ty, GPRRegister dst, const Immediate &imm) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (isByteSizedType(Ty)) {
+ emitUint8(0xB0 + dst);
+ emitUint8(imm.value() & 0xFF);
+ return;
+ }
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ emitUint8(0xB8 + dst);
+ emitImmediate(Ty, imm);
+}
+
+void AssemblerX8632::mov(Type Ty, GPRRegister dst, GPRRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ if (isByteSizedType(Ty)) {
+ emitUint8(0x88);
+ } else {
+ emitUint8(0x89);
+ }
+ emitRegisterOperand(src, dst);
+}
+
+void AssemblerX8632::mov(Type Ty, GPRRegister dst, const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ if (isByteSizedType(Ty)) {
+ emitUint8(0x8A);
+ } else {
+ emitUint8(0x8B);
+ }
+ emitOperand(dst, src);
+}
+
+void AssemblerX8632::mov(Type Ty, const Address &dst, GPRRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ if (isByteSizedType(Ty)) {
+ emitUint8(0x88);
+ } else {
+ emitUint8(0x89);
+ }
+ emitOperand(src, dst);
+}
+
+void AssemblerX8632::mov(Type Ty, const Address &dst, const Immediate &imm) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ if (isByteSizedType(Ty)) {
+ emitUint8(0xC6);
+ emitOperand(0, dst);
+ emitUint8(imm.value() & 0xFF);
+ } else {
+ emitUint8(0xC7);
+ emitOperand(0, dst);
+ emitImmediate(Ty, imm);
+ }
+}
+
+void AssemblerX8632::movzx(Type SrcTy, GPRRegister dst, GPRRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ bool ByteSized = isByteSizedType(SrcTy);
+ assert(ByteSized || SrcTy == IceType_i16);
+ emitUint8(0x0F);
+ emitUint8(ByteSized ? 0xB6 : 0xB7);
+ emitRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::movzx(Type SrcTy, GPRRegister dst, const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ bool ByteSized = isByteSizedType(SrcTy);
+ assert(ByteSized || SrcTy == IceType_i16);
+ emitUint8(0x0F);
+ emitUint8(ByteSized ? 0xB6 : 0xB7);
+ emitOperand(dst, src);
+}
+
+void AssemblerX8632::movsx(Type SrcTy, GPRRegister dst, GPRRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ bool ByteSized = isByteSizedType(SrcTy);
+ assert(ByteSized || SrcTy == IceType_i16);
+ emitUint8(0x0F);
+ emitUint8(ByteSized ? 0xBE : 0xBF);
+ emitRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::movsx(Type SrcTy, GPRRegister dst, const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ bool ByteSized = isByteSizedType(SrcTy);
+ assert(ByteSized || SrcTy == IceType_i16);
+ emitUint8(0x0F);
+ emitUint8(ByteSized ? 0xBE : 0xBF);
+ emitOperand(dst, src);
+}
+
+void AssemblerX8632::lea(Type Ty, GPRRegister dst, const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ assert(Ty == IceType_i16 || Ty == IceType_i32);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ emitUint8(0x8D);
+ emitOperand(dst, src);
+}
+
+void AssemblerX8632::cmov(Type Ty, CondX86::BrCond cond, GPRRegister dst,
+ GPRRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ else
+ assert(Ty == IceType_i32);
+ emitUint8(0x0F);
+ emitUint8(0x40 + cond);
+ emitRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::cmov(Type Ty, CondX86::BrCond cond, GPRRegister dst,
+ const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ else
+ assert(Ty == IceType_i32);
+ emitUint8(0x0F);
+ emitUint8(0x40 + cond);
+ emitOperand(dst, src);
+}
+
+void AssemblerX8632::rep_movsb() {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0xF3);
+ emitUint8(0xA4);
+}
+
+void AssemblerX8632::movss(Type Ty, XmmRegister dst, const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
+ emitUint8(0x0F);
+ emitUint8(0x10);
+ emitOperand(dst, src);
+}
+
+void AssemblerX8632::movss(Type Ty, const Address &dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
+ emitUint8(0x0F);
+ emitUint8(0x11);
+ emitOperand(src, dst);
+}
+
+void AssemblerX8632::movss(Type Ty, XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
+ emitUint8(0x0F);
+ emitUint8(0x11);
+ emitXmmRegisterOperand(src, dst);
+}
+
+void AssemblerX8632::movd(XmmRegister dst, GPRRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0x6E);
+ emitRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::movd(XmmRegister dst, const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0x6E);
+ emitOperand(dst, src);
+}
+
+void AssemblerX8632::movd(GPRRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0x7E);
+ emitRegisterOperand(src, dst);
+}
+
+void AssemblerX8632::movd(const Address &dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0x7E);
+ emitOperand(src, dst);
+}
+
+void AssemblerX8632::movq(XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0xF3);
+ emitUint8(0x0F);
+ emitUint8(0x7E);
+ emitRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::movq(const Address &dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0xD6);
+ emitOperand(src, dst);
+}
+
+void AssemblerX8632::movq(XmmRegister dst, const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0xF3);
+ emitUint8(0x0F);
+ emitUint8(0x7E);
+ emitOperand(dst, src);
+}
+
+void AssemblerX8632::addss(Type Ty, XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
+ emitUint8(0x0F);
+ emitUint8(0x58);
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::addss(Type Ty, XmmRegister dst, const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
+ emitUint8(0x0F);
+ emitUint8(0x58);
+ emitOperand(dst, src);
+}
+
+void AssemblerX8632::subss(Type Ty, XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
+ emitUint8(0x0F);
+ emitUint8(0x5C);
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::subss(Type Ty, XmmRegister dst, const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
+ emitUint8(0x0F);
+ emitUint8(0x5C);
+ emitOperand(dst, src);
+}
+
+void AssemblerX8632::mulss(Type Ty, XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
+ emitUint8(0x0F);
+ emitUint8(0x59);
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::mulss(Type Ty, XmmRegister dst, const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
+ emitUint8(0x0F);
+ emitUint8(0x59);
+ emitOperand(dst, src);
+}
+
+void AssemblerX8632::divss(Type Ty, XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
+ emitUint8(0x0F);
+ emitUint8(0x5E);
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::divss(Type Ty, XmmRegister dst, const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
+ emitUint8(0x0F);
+ emitUint8(0x5E);
+ emitOperand(dst, src);
+}
+
+void AssemblerX8632::fld(Type Ty, const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(isFloat32Asserting32Or64(Ty) ? 0xD9 : 0xDD);
+ emitOperand(0, src);
+}
+
+void AssemblerX8632::fstp(Type Ty, const Address &dst) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(isFloat32Asserting32Or64(Ty) ? 0xD9 : 0xDD);
+ emitOperand(3, dst);
+}
+
+void AssemblerX8632::fstp(X87STRegister st) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0xDD);
+ emitUint8(0xD8 + st);
+}
+
+void AssemblerX8632::movaps(XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x0F);
+ emitUint8(0x28);
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::movups(XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x0F);
+ emitUint8(0x10);
+ emitRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::movups(XmmRegister dst, const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x0F);
+ emitUint8(0x10);
+ emitOperand(dst, src);
+}
+
+void AssemblerX8632::movups(const Address &dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x0F);
+ emitUint8(0x11);
+ emitOperand(src, dst);
+}
+
+void AssemblerX8632::padd(Type Ty, XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ if (isByteSizedArithType(Ty)) {
+ emitUint8(0xFC);
+ } else if (Ty == IceType_i16) {
+ emitUint8(0xFD);
+ } else {
+ emitUint8(0xFE);
+ }
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::padd(Type Ty, XmmRegister dst, const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ if (isByteSizedArithType(Ty)) {
+ emitUint8(0xFC);
+ } else if (Ty == IceType_i16) {
+ emitUint8(0xFD);
+ } else {
+ emitUint8(0xFE);
+ }
+ emitOperand(dst, src);
+}
+
+void AssemblerX8632::pand(Type /* Ty */, XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0xDB);
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::pand(Type /* Ty */, XmmRegister dst, const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0xDB);
+ emitOperand(dst, src);
+}
+
+void AssemblerX8632::pandn(Type /* Ty */, XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0xDF);
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::pandn(Type /* Ty */, XmmRegister dst, const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0xDF);
+ emitOperand(dst, src);
+}
+
+void AssemblerX8632::pmull(Type Ty, XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ if (Ty == IceType_i16) {
+ emitUint8(0xD5);
+ } else {
+ assert(Ty == IceType_i32);
+ emitUint8(0x38);
+ emitUint8(0x40);
+ }
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::pmull(Type Ty, XmmRegister dst, const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ if (Ty == IceType_i16) {
+ emitUint8(0xD5);
+ } else {
+ assert(Ty == IceType_i32);
+ emitUint8(0x38);
+ emitUint8(0x40);
+ }
+ emitOperand(dst, src);
+}
+
+void AssemblerX8632::pmuludq(Type /* Ty */, XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0xF4);
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::pmuludq(Type /* Ty */, XmmRegister dst,
+ const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0xF4);
+ emitOperand(dst, src);
+}
+
+void AssemblerX8632::por(Type /* Ty */, XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0xEB);
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::por(Type /* Ty */, XmmRegister dst, const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0xEB);
+ emitOperand(dst, src);
+}
+
+void AssemblerX8632::psub(Type Ty, XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ if (isByteSizedArithType(Ty)) {
+ emitUint8(0xF8);
+ } else if (Ty == IceType_i16) {
+ emitUint8(0xF9);
+ } else {
+ emitUint8(0xFA);
+ }
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::psub(Type Ty, XmmRegister dst, const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ if (isByteSizedArithType(Ty)) {
+ emitUint8(0xF8);
+ } else if (Ty == IceType_i16) {
+ emitUint8(0xF9);
+ } else {
+ emitUint8(0xFA);
+ }
+ emitOperand(dst, src);
+}
+
+void AssemblerX8632::pxor(Type /* Ty */, XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0xEF);
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::pxor(Type /* Ty */, XmmRegister dst, const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0xEF);
+ emitOperand(dst, src);
+}
+
+void AssemblerX8632::psll(Type Ty, XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ if (Ty == IceType_i16) {
+ emitUint8(0xF1);
+ } else {
+ assert(Ty == IceType_i32);
+ emitUint8(0xF2);
+ }
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::psll(Type Ty, XmmRegister dst, const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ if (Ty == IceType_i16) {
+ emitUint8(0xF1);
+ } else {
+ assert(Ty == IceType_i32);
+ emitUint8(0xF2);
+ }
+ emitOperand(dst, src);
+}
+
+void AssemblerX8632::psll(Type Ty, XmmRegister dst, const Immediate &imm) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ assert(imm.is_int8());
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ if (Ty == IceType_i16) {
+ emitUint8(0x71);
+ } else {
+ assert(Ty == IceType_i32);
+ emitUint8(0x72);
+ }
+ emitRegisterOperand(6, dst);
+ emitUint8(imm.value() & 0xFF);
+}
+
+void AssemblerX8632::psra(Type Ty, XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ if (Ty == IceType_i16) {
+ emitUint8(0xE1);
+ } else {
+ assert(Ty == IceType_i32);
+ emitUint8(0xE2);
+ }
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::psra(Type Ty, XmmRegister dst, const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ if (Ty == IceType_i16) {
+ emitUint8(0xE1);
+ } else {
+ assert(Ty == IceType_i32);
+ emitUint8(0xE2);
+ }
+ emitOperand(dst, src);
+}
+
+void AssemblerX8632::psra(Type Ty, XmmRegister dst, const Immediate &imm) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ assert(imm.is_int8());
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ if (Ty == IceType_i16) {
+ emitUint8(0x71);
+ } else {
+ assert(Ty == IceType_i32);
+ emitUint8(0x72);
+ }
+ emitRegisterOperand(4, dst);
+ emitUint8(imm.value() & 0xFF);
+}
+
+void AssemblerX8632::psrl(Type Ty, XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ if (Ty == IceType_i16) {
+ emitUint8(0xD1);
+ } else if (Ty == IceType_f64) {
+ emitUint8(0xD3);
+ } else {
+ assert(Ty == IceType_i32 || Ty == IceType_f32 || Ty == IceType_v4f32);
+ emitUint8(0xD2);
+ }
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::psrl(Type Ty, XmmRegister dst, const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ if (Ty == IceType_i16) {
+ emitUint8(0xD1);
+ } else if (Ty == IceType_f64) {
+ emitUint8(0xD3);
+ } else {
+ assert(Ty == IceType_i32 || Ty == IceType_f32 || Ty == IceType_v4f32);
+ emitUint8(0xD2);
+ }
+ emitOperand(dst, src);
+}
+
+void AssemblerX8632::psrl(Type Ty, XmmRegister dst, const Immediate &imm) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ assert(imm.is_int8());
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ if (Ty == IceType_i16) {
+ emitUint8(0x71);
+ } else if (Ty == IceType_f64) {
+ emitUint8(0x73);
+ } else {
+ assert(Ty == IceType_i32 || Ty == IceType_f32 || Ty == IceType_v4f32);
+ emitUint8(0x72);
+ }
+ emitRegisterOperand(2, dst);
+ emitUint8(imm.value() & 0xFF);
+}
+
+// {add,sub,mul,div}ps are given a Ty parameter for consistency with
+// {add,sub,mul,div}ss. In the future, when the PNaCl ABI allows
+// addpd, etc., we can use the Ty parameter to decide on adding
+// a 0x66 prefix.
+void AssemblerX8632::addps(Type /* Ty */, XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x0F);
+ emitUint8(0x58);
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::addps(Type /* Ty */, XmmRegister dst, const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x0F);
+ emitUint8(0x58);
+ emitOperand(dst, src);
+}
+
+void AssemblerX8632::subps(Type /* Ty */, XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x0F);
+ emitUint8(0x5C);
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::subps(Type /* Ty */, XmmRegister dst, const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x0F);
+ emitUint8(0x5C);
+ emitOperand(dst, src);
+}
+
+void AssemblerX8632::divps(Type /* Ty */, XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x0F);
+ emitUint8(0x5E);
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::divps(Type /* Ty */, XmmRegister dst, const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x0F);
+ emitUint8(0x5E);
+ emitOperand(dst, src);
+}
+
+void AssemblerX8632::mulps(Type /* Ty */, XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x0F);
+ emitUint8(0x59);
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::mulps(Type /* Ty */, XmmRegister dst, const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x0F);
+ emitUint8(0x59);
+ emitOperand(dst, src);
+}
+
+void AssemblerX8632::minps(XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x0F);
+ emitUint8(0x5D);
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::maxps(XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x0F);
+ emitUint8(0x5F);
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::andps(XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x0F);
+ emitUint8(0x54);
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::andps(XmmRegister dst, const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x0F);
+ emitUint8(0x54);
+ emitOperand(dst, src);
+}
+
+void AssemblerX8632::orps(XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x0F);
+ emitUint8(0x56);
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::blendvps(Type /* Ty */, XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0x38);
+ emitUint8(0x14);
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::blendvps(Type /* Ty */, XmmRegister dst,
+ const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0x38);
+ emitUint8(0x14);
+ emitOperand(dst, src);
+}
+
+void AssemblerX8632::pblendvb(Type /* Ty */, XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0x38);
+ emitUint8(0x10);
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::pblendvb(Type /* Ty */, XmmRegister dst,
+ const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0x38);
+ emitUint8(0x10);
+ emitOperand(dst, src);
+}
+
+void AssemblerX8632::cmpps(XmmRegister dst, XmmRegister src,
+ CondX86::CmppsCond CmpCondition) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x0F);
+ emitUint8(0xC2);
+ emitXmmRegisterOperand(dst, src);
+ emitUint8(CmpCondition);
+}
+
+void AssemblerX8632::cmpps(XmmRegister dst, const Address &src,
+ CondX86::CmppsCond CmpCondition) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x0F);
+ emitUint8(0xC2);
+ emitOperand(dst, src);
+ emitUint8(CmpCondition);
+}
+
+void AssemblerX8632::sqrtps(XmmRegister dst) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x0F);
+ emitUint8(0x51);
+ emitXmmRegisterOperand(dst, dst);
+}
+
+void AssemblerX8632::rsqrtps(XmmRegister dst) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x0F);
+ emitUint8(0x52);
+ emitXmmRegisterOperand(dst, dst);
+}
+
+void AssemblerX8632::reciprocalps(XmmRegister dst) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x0F);
+ emitUint8(0x53);
+ emitXmmRegisterOperand(dst, dst);
+}
+
+void AssemblerX8632::movhlps(XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x0F);
+ emitUint8(0x12);
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::movlhps(XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x0F);
+ emitUint8(0x16);
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::unpcklps(XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x0F);
+ emitUint8(0x14);
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::unpckhps(XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x0F);
+ emitUint8(0x15);
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::unpcklpd(XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0x14);
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::unpckhpd(XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0x15);
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::set1ps(XmmRegister dst, GPRRegister tmp1,
+ const Immediate &imm) {
+ // Load 32-bit immediate value into tmp1.
+ mov(IceType_i32, tmp1, imm);
+ // Move value from tmp1 into dst.
+ movd(dst, tmp1);
+ // Broadcast low lane into other three lanes.
+ shufps(dst, dst, Immediate(0x0));
+}
+
+void AssemblerX8632::shufps(XmmRegister dst, XmmRegister src,
+ const Immediate &imm) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x0F);
+ emitUint8(0xC6);
+ emitXmmRegisterOperand(dst, src);
+ assert(imm.is_uint8());
+ emitUint8(imm.value());
+}
+
+void AssemblerX8632::pshufd(Type /* Ty */, XmmRegister dst, XmmRegister src,
+ const Immediate &imm) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0x70);
+ emitXmmRegisterOperand(dst, src);
+ assert(imm.is_uint8());
+ emitUint8(imm.value());
+}
+
+void AssemblerX8632::pshufd(Type /* Ty */, XmmRegister dst, const Address &src,
+ const Immediate &imm) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0x70);
+ emitOperand(dst, src);
+ assert(imm.is_uint8());
+ emitUint8(imm.value());
+}
+
+void AssemblerX8632::shufps(Type /* Ty */, XmmRegister dst, XmmRegister src,
+ const Immediate &imm) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x0F);
+ emitUint8(0xC6);
+ emitXmmRegisterOperand(dst, src);
+ assert(imm.is_uint8());
+ emitUint8(imm.value());
+}
+
+void AssemblerX8632::shufps(Type /* Ty */, XmmRegister dst, const Address &src,
+ const Immediate &imm) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x0F);
+ emitUint8(0xC6);
+ emitOperand(dst, src);
+ assert(imm.is_uint8());
+ emitUint8(imm.value());
+}
+
+void AssemblerX8632::minpd(XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0x5D);
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::maxpd(XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0x5F);
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::sqrtpd(XmmRegister dst) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0x51);
+ emitXmmRegisterOperand(dst, dst);
+}
+
+void AssemblerX8632::shufpd(XmmRegister dst, XmmRegister src,
+ const Immediate &imm) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0xC6);
+ emitXmmRegisterOperand(dst, src);
+ assert(imm.is_uint8());
+ emitUint8(imm.value());
+}
+
+void AssemblerX8632::cvtdq2ps(Type /* Ignore */, XmmRegister dst,
+ XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x0F);
+ emitUint8(0x5B);
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::cvtdq2ps(Type /* Ignore */, XmmRegister dst,
+ const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x0F);
+ emitUint8(0x5B);
+ emitOperand(dst, src);
+}
+
+void AssemblerX8632::cvttps2dq(Type /* Ignore */, XmmRegister dst,
+ XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0xF3);
+ emitUint8(0x0F);
+ emitUint8(0x5B);
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::cvttps2dq(Type /* Ignore */, XmmRegister dst,
+ const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0xF3);
+ emitUint8(0x0F);
+ emitUint8(0x5B);
+ emitOperand(dst, src);
+}
+
+void AssemblerX8632::cvtsi2ss(Type DestTy, XmmRegister dst, GPRRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(isFloat32Asserting32Or64(DestTy) ? 0xF3 : 0xF2);
+ emitUint8(0x0F);
+ emitUint8(0x2A);
+ emitRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::cvtsi2ss(Type DestTy, XmmRegister dst,
+ const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(isFloat32Asserting32Or64(DestTy) ? 0xF3 : 0xF2);
+ emitUint8(0x0F);
+ emitUint8(0x2A);
+ emitOperand(dst, src);
+}
+
+void AssemblerX8632::cvtfloat2float(Type SrcTy, XmmRegister dst,
+ XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ // ss2sd or sd2ss
+ emitUint8(isFloat32Asserting32Or64(SrcTy) ? 0xF3 : 0xF2);
+ emitUint8(0x0F);
+ emitUint8(0x5A);
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::cvtfloat2float(Type SrcTy, XmmRegister dst,
+ const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(isFloat32Asserting32Or64(SrcTy) ? 0xF3 : 0xF2);
+ emitUint8(0x0F);
+ emitUint8(0x5A);
+ emitOperand(dst, src);
+}
+
+void AssemblerX8632::cvttss2si(Type SrcTy, GPRRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(isFloat32Asserting32Or64(SrcTy) ? 0xF3 : 0xF2);
+ emitUint8(0x0F);
+ emitUint8(0x2C);
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::cvttss2si(Type SrcTy, GPRRegister dst,
+ const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(isFloat32Asserting32Or64(SrcTy) ? 0xF3 : 0xF2);
+ emitUint8(0x0F);
+ emitUint8(0x2C);
+ emitOperand(dst, src);
+}
+
+void AssemblerX8632::ucomiss(Type Ty, XmmRegister a, XmmRegister b) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (Ty == IceType_f64)
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0x2E);
+ emitXmmRegisterOperand(a, b);
+}
+
+void AssemblerX8632::ucomiss(Type Ty, XmmRegister a, const Address &b) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (Ty == IceType_f64)
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0x2E);
+ emitOperand(a, b);
+}
+
+void AssemblerX8632::movmskpd(GPRRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0x50);
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::movmskps(GPRRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x0F);
+ emitUint8(0x50);
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::sqrtss(Type Ty, XmmRegister dst, const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
+ emitUint8(0x0F);
+ emitUint8(0x51);
+ emitOperand(dst, src);
+}
+
+void AssemblerX8632::sqrtss(Type Ty, XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
+ emitUint8(0x0F);
+ emitUint8(0x51);
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::xorpd(XmmRegister dst, const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0x57);
+ emitOperand(dst, src);
+}
+
+void AssemblerX8632::xorpd(XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0x57);
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::orpd(XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0x56);
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::xorps(XmmRegister dst, const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x0F);
+ emitUint8(0x57);
+ emitOperand(dst, src);
+}
+
+void AssemblerX8632::xorps(XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x0F);
+ emitUint8(0x57);
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::andpd(XmmRegister dst, const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0x54);
+ emitOperand(dst, src);
+}
+
+void AssemblerX8632::andpd(XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0x54);
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::insertps(Type Ty, XmmRegister dst, XmmRegister src,
+ const Immediate &imm) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ assert(imm.is_uint8());
+ assert(isVectorFloatingType(Ty));
+ (void)Ty;
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0x3A);
+ emitUint8(0x21);
+ emitXmmRegisterOperand(dst, src);
+ emitUint8(imm.value());
+}
+
+void AssemblerX8632::insertps(Type Ty, XmmRegister dst, const Address &src,
+ const Immediate &imm) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ assert(imm.is_uint8());
+ assert(isVectorFloatingType(Ty));
+ (void)Ty;
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0x3A);
+ emitUint8(0x21);
+ emitOperand(dst, src);
+ emitUint8(imm.value());
+}
+
+void AssemblerX8632::pinsr(Type Ty, XmmRegister dst, GPRRegister src,
+ const Immediate &imm) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ assert(imm.is_uint8());
+ if (Ty == IceType_i16) {
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0xC4);
+ emitXmmRegisterOperand(dst, XmmRegister(src));
+ emitUint8(imm.value());
+ } else {
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0x3A);
+ emitUint8(isByteSizedType(Ty) ? 0x20 : 0x22);
+ emitXmmRegisterOperand(dst, XmmRegister(src));
+ emitUint8(imm.value());
+ }
+}
+
+void AssemblerX8632::pinsr(Type Ty, XmmRegister dst, const Address &src,
+ const Immediate &imm) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ assert(imm.is_uint8());
+ if (Ty == IceType_i16) {
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0xC4);
+ emitOperand(dst, src);
+ emitUint8(imm.value());
+ } else {
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0x3A);
+ emitUint8(isByteSizedType(Ty) ? 0x20 : 0x22);
+ emitOperand(dst, src);
+ emitUint8(imm.value());
+ }
+}
+
+void AssemblerX8632::pextr(Type Ty, GPRRegister dst, XmmRegister src,
+ const Immediate &imm) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ assert(imm.is_uint8());
+ if (Ty == IceType_i16) {
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0xC5);
+ emitXmmRegisterOperand(XmmRegister(dst), src);
+ emitUint8(imm.value());
+ } else {
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0x3A);
+ emitUint8(isByteSizedType(Ty) ? 0x14 : 0x16);
+ // SSE 4.1 versions are "MRI" because dst can be mem, while
+ // pextrw (SSE2) is RMI because dst must be reg.
+ emitXmmRegisterOperand(src, XmmRegister(dst));
+ emitUint8(imm.value());
+ }
+}
+
+void AssemblerX8632::pmovsxdq(XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0x38);
+ emitUint8(0x25);
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::pcmpeq(Type Ty, XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ if (isByteSizedArithType(Ty)) {
+ emitUint8(0x74);
+ } else if (Ty == IceType_i16) {
+ emitUint8(0x75);
+ } else {
+ emitUint8(0x76);
+ }
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::pcmpeq(Type Ty, XmmRegister dst, const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ if (isByteSizedArithType(Ty)) {
+ emitUint8(0x74);
+ } else if (Ty == IceType_i16) {
+ emitUint8(0x75);
+ } else {
+ emitUint8(0x76);
+ }
+ emitOperand(dst, src);
+}
+
+void AssemblerX8632::pcmpgt(Type Ty, XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ if (isByteSizedArithType(Ty)) {
+ emitUint8(0x64);
+ } else if (Ty == IceType_i16) {
+ emitUint8(0x65);
+ } else {
+ emitUint8(0x66);
+ }
+ emitXmmRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::pcmpgt(Type Ty, XmmRegister dst, const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ if (isByteSizedArithType(Ty)) {
+ emitUint8(0x64);
+ } else if (Ty == IceType_i16) {
+ emitUint8(0x65);
+ } else {
+ emitUint8(0x66);
+ }
+ emitOperand(dst, src);
+}
+
+void AssemblerX8632::roundsd(XmmRegister dst, XmmRegister src,
+ RoundingMode mode) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0x3A);
+ emitUint8(0x0B);
+ emitXmmRegisterOperand(dst, src);
+ // Mask precision exeption.
+ emitUint8(static_cast<uint8_t>(mode) | 0x8);
+}
+
+void AssemblerX8632::fnstcw(const Address &dst) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0xD9);
+ emitOperand(7, dst);
+}
+
+void AssemblerX8632::fldcw(const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0xD9);
+ emitOperand(5, src);
+}
+
+void AssemblerX8632::fistpl(const Address &dst) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0xDF);
+ emitOperand(7, dst);
+}
+
+void AssemblerX8632::fistps(const Address &dst) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0xDB);
+ emitOperand(3, dst);
+}
+
+void AssemblerX8632::fildl(const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0xDF);
+ emitOperand(5, src);
+}
+
+void AssemblerX8632::filds(const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0xDB);
+ emitOperand(0, src);
+}
+
+void AssemblerX8632::fincstp() {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0xD9);
+ emitUint8(0xF7);
+}
+
+void AssemblerX8632::cmp(Type Ty, GPRRegister reg, const Immediate &imm) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (isByteSizedType(Ty)) {
+ emitComplexI8(7, Operand(reg), imm);
+ return;
+ }
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ emitComplex(Ty, 7, Operand(reg), imm);
+}
+
+void AssemblerX8632::cmp(Type Ty, GPRRegister reg0, GPRRegister reg1) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ if (isByteSizedType(Ty))
+ emitUint8(0x3A);
+ else
+ emitUint8(0x3B);
+ emitRegisterOperand(reg0, reg1);
+}
+
+void AssemblerX8632::cmp(Type Ty, GPRRegister reg, const Address &address) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ if (isByteSizedType(Ty))
+ emitUint8(0x3A);
+ else
+ emitUint8(0x3B);
+ emitOperand(reg, address);
+}
+
+void AssemblerX8632::cmp(Type Ty, const Address &address, GPRRegister reg) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ if (isByteSizedType(Ty))
+ emitUint8(0x38);
+ else
+ emitUint8(0x39);
+ emitOperand(reg, address);
+}
+
+void AssemblerX8632::cmp(Type Ty, const Address &address,
+ const Immediate &imm) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (isByteSizedType(Ty)) {
+ emitComplexI8(7, address, imm);
+ return;
+ }
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ emitComplex(Ty, 7, address, imm);
+}
+
+void AssemblerX8632::test(Type Ty, GPRRegister reg1, GPRRegister reg2) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ if (isByteSizedType(Ty))
+ emitUint8(0x84);
+ else
+ emitUint8(0x85);
+ emitRegisterOperand(reg1, reg2);
+}
+
+void AssemblerX8632::test(Type Ty, const Address &addr, GPRRegister reg) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ if (isByteSizedType(Ty))
+ emitUint8(0x84);
+ else
+ emitUint8(0x85);
+ emitOperand(reg, addr);
+}
+
+void AssemblerX8632::test(Type Ty, GPRRegister reg,
+ const Immediate &immediate) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ // For registers that have a byte variant (EAX, EBX, ECX, and EDX)
+ // we only test the byte register to keep the encoding short.
+ // This is legal even if the register had high bits set since
+ // this only sets flags registers based on the "AND" of the two operands,
+ // and the immediate had zeros at those high bits.
+ if (immediate.is_uint8() && reg < 4) {
+ // Use zero-extended 8-bit immediate.
+ if (reg == RegX8632::Encoded_Reg_eax) {
+ emitUint8(0xA8);
+ } else {
+ emitUint8(0xF6);
+ emitUint8(0xC0 + reg);
+ }
+ emitUint8(immediate.value() & 0xFF);
+ } else if (reg == RegX8632::Encoded_Reg_eax) {
+ // Use short form if the destination is EAX.
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ emitUint8(0xA9);
+ emitImmediate(Ty, immediate);
+ } else {
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ emitUint8(0xF7);
+ emitRegisterOperand(0, reg);
+ emitImmediate(Ty, immediate);
+ }
+}
+
+void AssemblerX8632::test(Type Ty, const Address &addr,
+ const Immediate &immediate) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ // If the immediate is short, we only test the byte addr to keep the
+ // encoding short.
+ if (immediate.is_uint8()) {
+ // Use zero-extended 8-bit immediate.
+ emitUint8(0xF6);
+ emitOperand(0, addr);
+ emitUint8(immediate.value() & 0xFF);
+ } else {
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ emitUint8(0xF7);
+ emitOperand(0, addr);
+ emitImmediate(Ty, immediate);
+ }
+}
+
+void AssemblerX8632::And(Type Ty, GPRRegister dst, GPRRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ if (isByteSizedType(Ty))
+ emitUint8(0x22);
+ else
+ emitUint8(0x23);
+ emitRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::And(Type Ty, GPRRegister dst, const Address &address) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ if (isByteSizedType(Ty))
+ emitUint8(0x22);
+ else
+ emitUint8(0x23);
+ emitOperand(dst, address);
+}
+
+void AssemblerX8632::And(Type Ty, GPRRegister dst, const Immediate &imm) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (isByteSizedType(Ty)) {
+ emitComplexI8(4, Operand(dst), imm);
+ return;
+ }
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ emitComplex(Ty, 4, Operand(dst), imm);
+}
+
+void AssemblerX8632::Or(Type Ty, GPRRegister dst, GPRRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ if (isByteSizedType(Ty))
+ emitUint8(0x0A);
+ else
+ emitUint8(0x0B);
+ emitRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::Or(Type Ty, GPRRegister dst, const Address &address) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ if (isByteSizedType(Ty))
+ emitUint8(0x0A);
+ else
+ emitUint8(0x0B);
+ emitOperand(dst, address);
+}
+
+void AssemblerX8632::Or(Type Ty, GPRRegister dst, const Immediate &imm) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (isByteSizedType(Ty)) {
+ emitComplexI8(1, Operand(dst), imm);
+ return;
+ }
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ emitComplex(Ty, 1, Operand(dst), imm);
+}
+
+void AssemblerX8632::Xor(Type Ty, GPRRegister dst, GPRRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ if (isByteSizedType(Ty))
+ emitUint8(0x32);
+ else
+ emitUint8(0x33);
+ emitRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::Xor(Type Ty, GPRRegister dst, const Address &address) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ if (isByteSizedType(Ty))
+ emitUint8(0x32);
+ else
+ emitUint8(0x33);
+ emitOperand(dst, address);
+}
+
+void AssemblerX8632::Xor(Type Ty, GPRRegister dst, const Immediate &imm) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (isByteSizedType(Ty)) {
+ emitComplexI8(6, Operand(dst), imm);
+ return;
+ }
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ emitComplex(Ty, 6, Operand(dst), imm);
+}
+
+void AssemblerX8632::add(Type Ty, GPRRegister dst, GPRRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ if (isByteSizedArithType(Ty))
+ emitUint8(0x02);
+ else
+ emitUint8(0x03);
+ emitRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::add(Type Ty, GPRRegister reg, const Address &address) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ if (isByteSizedArithType(Ty))
+ emitUint8(0x02);
+ else
+ emitUint8(0x03);
+ emitOperand(reg, address);
+}
+
+void AssemblerX8632::add(Type Ty, GPRRegister reg, const Immediate &imm) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (isByteSizedArithType(Ty)) {
+ emitComplexI8(0, Operand(reg), imm);
+ return;
+ }
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ emitComplex(Ty, 0, Operand(reg), imm);
+}
+
+void AssemblerX8632::adc(Type Ty, GPRRegister dst, GPRRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ if (isByteSizedArithType(Ty))
+ emitUint8(0x12);
+ else
+ emitUint8(0x13);
+ emitRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::adc(Type Ty, GPRRegister dst, const Address &address) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ if (isByteSizedArithType(Ty))
+ emitUint8(0x12);
+ else
+ emitUint8(0x13);
+ emitOperand(dst, address);
+}
+
+void AssemblerX8632::adc(Type Ty, GPRRegister reg, const Immediate &imm) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (isByteSizedArithType(Ty)) {
+ emitComplexI8(2, Operand(reg), imm);
+ return;
+ }
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ emitComplex(Ty, 2, Operand(reg), imm);
+}
+
+void AssemblerX8632::sub(Type Ty, GPRRegister dst, GPRRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ if (isByteSizedArithType(Ty))
+ emitUint8(0x2A);
+ else
+ emitUint8(0x2B);
+ emitRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::sub(Type Ty, GPRRegister reg, const Address &address) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ if (isByteSizedArithType(Ty))
+ emitUint8(0x2A);
+ else
+ emitUint8(0x2B);
+ emitOperand(reg, address);
+}
+
+void AssemblerX8632::sub(Type Ty, GPRRegister reg, const Immediate &imm) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (isByteSizedArithType(Ty)) {
+ emitComplexI8(5, Operand(reg), imm);
+ return;
+ }
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ emitComplex(Ty, 5, Operand(reg), imm);
+}
+
+void AssemblerX8632::sbb(Type Ty, GPRRegister dst, GPRRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ if (isByteSizedArithType(Ty))
+ emitUint8(0x1A);
+ else
+ emitUint8(0x1B);
+ emitRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::sbb(Type Ty, GPRRegister dst, const Address &address) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ if (isByteSizedArithType(Ty))
+ emitUint8(0x1A);
+ else
+ emitUint8(0x1B);
+ emitOperand(dst, address);
+}
+
+void AssemblerX8632::sbb(Type Ty, GPRRegister reg, const Immediate &imm) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (isByteSizedArithType(Ty)) {
+ emitComplexI8(3, Operand(reg), imm);
+ return;
+ }
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ emitComplex(Ty, 3, Operand(reg), imm);
+}
+
+void AssemblerX8632::cbw() {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitOperandSizeOverride();
+ emitUint8(0x98);
+}
+
+void AssemblerX8632::cwd() {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitOperandSizeOverride();
+ emitUint8(0x99);
+}
+
+void AssemblerX8632::cdq() {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x99);
+}
+
+void AssemblerX8632::div(Type Ty, GPRRegister reg) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ if (isByteSizedArithType(Ty))
+ emitUint8(0xF6);
+ else
+ emitUint8(0xF7);
+ emitRegisterOperand(6, reg);
+}
+
+void AssemblerX8632::div(Type Ty, const Address &addr) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ if (isByteSizedArithType(Ty))
+ emitUint8(0xF6);
+ else
+ emitUint8(0xF7);
+ emitOperand(6, addr);
+}
+
+void AssemblerX8632::idiv(Type Ty, GPRRegister reg) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ if (isByteSizedArithType(Ty))
+ emitUint8(0xF6);
+ else
+ emitUint8(0xF7);
+ emitRegisterOperand(7, reg);
+}
+
+void AssemblerX8632::idiv(Type Ty, const Address &addr) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ if (isByteSizedArithType(Ty))
+ emitUint8(0xF6);
+ else
+ emitUint8(0xF7);
+ emitOperand(7, addr);
+}
+
+void AssemblerX8632::imul(Type Ty, GPRRegister dst, GPRRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ assert(Ty == IceType_i16 || Ty == IceType_i32);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ emitUint8(0x0F);
+ emitUint8(0xAF);
+ emitRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::imul(Type Ty, GPRRegister reg, const Address &address) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ assert(Ty == IceType_i16 || Ty == IceType_i32);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ emitUint8(0x0F);
+ emitUint8(0xAF);
+ emitOperand(reg, address);
+}
+
+void AssemblerX8632::imul(Type Ty, GPRRegister reg, const Immediate &imm) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ assert(Ty == IceType_i16 || Ty == IceType_i32);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ if (imm.is_int8()) {
+ emitUint8(0x6B);
+ emitRegisterOperand(reg, reg);
+ emitUint8(imm.value() & 0xFF);
+ } else {
+ emitUint8(0x69);
+ emitRegisterOperand(reg, reg);
+ emitImmediate(Ty, imm);
+ }
+}
+
+void AssemblerX8632::imul(Type Ty, GPRRegister reg) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ if (isByteSizedArithType(Ty))
+ emitUint8(0xF6);
+ else
+ emitUint8(0xF7);
+ emitRegisterOperand(5, reg);
+}
+
+void AssemblerX8632::imul(Type Ty, const Address &address) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ if (isByteSizedArithType(Ty))
+ emitUint8(0xF6);
+ else
+ emitUint8(0xF7);
+ emitOperand(5, address);
+}
+
+void AssemblerX8632::mul(Type Ty, GPRRegister reg) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ if (isByteSizedArithType(Ty))
+ emitUint8(0xF6);
+ else
+ emitUint8(0xF7);
+ emitRegisterOperand(4, reg);
+}
+
+void AssemblerX8632::mul(Type Ty, const Address &address) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ if (isByteSizedArithType(Ty))
+ emitUint8(0xF6);
+ else
+ emitUint8(0xF7);
+ emitOperand(4, address);
+}
+
+void AssemblerX8632::incl(GPRRegister reg) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x40 + reg);
+}
+
+void AssemblerX8632::incl(const Address &address) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0xFF);
+ emitOperand(0, address);
+}
+
+void AssemblerX8632::decl(GPRRegister reg) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x48 + reg);
+}
+
+void AssemblerX8632::decl(const Address &address) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0xFF);
+ emitOperand(1, address);
+}
+
+void AssemblerX8632::rol(Type Ty, GPRRegister reg, const Immediate &imm) {
+ emitGenericShift(0, Ty, reg, imm);
+}
+
+void AssemblerX8632::rol(Type Ty, GPRRegister operand, GPRRegister shifter) {
+ emitGenericShift(0, Ty, Operand(operand), shifter);
+}
+
+void AssemblerX8632::rol(Type Ty, const Address &operand, GPRRegister shifter) {
+ emitGenericShift(0, Ty, operand, shifter);
+}
+
+void AssemblerX8632::shl(Type Ty, GPRRegister reg, const Immediate &imm) {
+ emitGenericShift(4, Ty, reg, imm);
+}
+
+void AssemblerX8632::shl(Type Ty, GPRRegister operand, GPRRegister shifter) {
+ emitGenericShift(4, Ty, Operand(operand), shifter);
+}
+
+void AssemblerX8632::shl(Type Ty, const Address &operand, GPRRegister shifter) {
+ emitGenericShift(4, Ty, operand, shifter);
+}
+
+void AssemblerX8632::shr(Type Ty, GPRRegister reg, const Immediate &imm) {
+ emitGenericShift(5, Ty, reg, imm);
+}
+
+void AssemblerX8632::shr(Type Ty, GPRRegister operand, GPRRegister shifter) {
+ emitGenericShift(5, Ty, Operand(operand), shifter);
+}
+
+void AssemblerX8632::shr(Type Ty, const Address &operand, GPRRegister shifter) {
+ emitGenericShift(5, Ty, operand, shifter);
+}
+
+void AssemblerX8632::sar(Type Ty, GPRRegister reg, const Immediate &imm) {
+ emitGenericShift(7, Ty, reg, imm);
+}
+
+void AssemblerX8632::sar(Type Ty, GPRRegister operand, GPRRegister shifter) {
+ emitGenericShift(7, Ty, Operand(operand), shifter);
+}
+
+void AssemblerX8632::sar(Type Ty, const Address &address, GPRRegister shifter) {
+ emitGenericShift(7, Ty, address, shifter);
+}
+
+void AssemblerX8632::shld(Type Ty, GPRRegister dst, GPRRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ assert(Ty == IceType_i16 || Ty == IceType_i32);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ emitUint8(0x0F);
+ emitUint8(0xA5);
+ emitRegisterOperand(src, dst);
+}
+
+void AssemblerX8632::shld(Type Ty, GPRRegister dst, GPRRegister src,
+ const Immediate &imm) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ assert(Ty == IceType_i16 || Ty == IceType_i32);
+ assert(imm.is_int8());
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ emitUint8(0x0F);
+ emitUint8(0xA4);
+ emitRegisterOperand(src, dst);
+ emitUint8(imm.value() & 0xFF);
+}
+
+void AssemblerX8632::shld(Type Ty, const Address &operand, GPRRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ assert(Ty == IceType_i16 || Ty == IceType_i32);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ emitUint8(0x0F);
+ emitUint8(0xA5);
+ emitOperand(src, operand);
+}
+
+void AssemblerX8632::shrd(Type Ty, GPRRegister dst, GPRRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ assert(Ty == IceType_i16 || Ty == IceType_i32);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ emitUint8(0x0F);
+ emitUint8(0xAD);
+ emitRegisterOperand(src, dst);
+}
+
+void AssemblerX8632::shrd(Type Ty, GPRRegister dst, GPRRegister src,
+ const Immediate &imm) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ assert(Ty == IceType_i16 || Ty == IceType_i32);
+ assert(imm.is_int8());
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ emitUint8(0x0F);
+ emitUint8(0xAC);
+ emitRegisterOperand(src, dst);
+ emitUint8(imm.value() & 0xFF);
+}
+
+void AssemblerX8632::shrd(Type Ty, const Address &dst, GPRRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ assert(Ty == IceType_i16 || Ty == IceType_i32);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ emitUint8(0x0F);
+ emitUint8(0xAD);
+ emitOperand(src, dst);
+}
+
+void AssemblerX8632::neg(Type Ty, GPRRegister reg) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ if (isByteSizedArithType(Ty))
+ emitUint8(0xF6);
+ else
+ emitUint8(0xF7);
+ emitRegisterOperand(3, reg);
+}
+
+void AssemblerX8632::neg(Type Ty, const Address &addr) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ if (isByteSizedArithType(Ty))
+ emitUint8(0xF6);
+ else
+ emitUint8(0xF7);
+ emitOperand(3, addr);
+}
+
+void AssemblerX8632::notl(GPRRegister reg) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0xF7);
+ emitUint8(0xD0 | reg);
+}
+
+void AssemblerX8632::bswap(Type Ty, GPRRegister reg) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ assert(Ty == IceType_i32);
+ (void)Ty;
+ emitUint8(0x0F);
+ emitUint8(0xC8 | reg);
+}
+
+void AssemblerX8632::bsf(Type Ty, GPRRegister dst, GPRRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ assert(Ty == IceType_i16 || Ty == IceType_i32);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ emitUint8(0x0F);
+ emitUint8(0xBC);
+ emitRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::bsf(Type Ty, GPRRegister dst, const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ assert(Ty == IceType_i16 || Ty == IceType_i32);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ emitUint8(0x0F);
+ emitUint8(0xBC);
+ emitOperand(dst, src);
+}
+
+void AssemblerX8632::bsr(Type Ty, GPRRegister dst, GPRRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ assert(Ty == IceType_i16 || Ty == IceType_i32);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ emitUint8(0x0F);
+ emitUint8(0xBD);
+ emitRegisterOperand(dst, src);
+}
+
+void AssemblerX8632::bsr(Type Ty, GPRRegister dst, const Address &src) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ assert(Ty == IceType_i16 || Ty == IceType_i32);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ emitUint8(0x0F);
+ emitUint8(0xBD);
+ emitOperand(dst, src);
+}
+
+void AssemblerX8632::bt(GPRRegister base, GPRRegister offset) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x0F);
+ emitUint8(0xA3);
+ emitRegisterOperand(offset, base);
+}
+
+void AssemblerX8632::ret() {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0xC3);
+}
+
+void AssemblerX8632::ret(const Immediate &imm) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0xC2);
+ assert(imm.is_uint16());
+ emitUint8(imm.value() & 0xFF);
+ emitUint8((imm.value() >> 8) & 0xFF);
+}
+
+void AssemblerX8632::nop(int size) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ // There are nops up to size 15, but for now just provide up to size 8.
+ assert(0 < size && size <= MAX_NOP_SIZE);
+ switch (size) {
+ case 1:
+ emitUint8(0x90);
+ break;
+ case 2:
+ emitUint8(0x66);
+ emitUint8(0x90);
+ break;
+ case 3:
+ emitUint8(0x0F);
+ emitUint8(0x1F);
+ emitUint8(0x00);
+ break;
+ case 4:
+ emitUint8(0x0F);
+ emitUint8(0x1F);
+ emitUint8(0x40);
+ emitUint8(0x00);
+ break;
+ case 5:
+ emitUint8(0x0F);
+ emitUint8(0x1F);
+ emitUint8(0x44);
+ emitUint8(0x00);
+ emitUint8(0x00);
+ break;
+ case 6:
+ emitUint8(0x66);
+ emitUint8(0x0F);
+ emitUint8(0x1F);
+ emitUint8(0x44);
+ emitUint8(0x00);
+ emitUint8(0x00);
+ break;
+ case 7:
+ emitUint8(0x0F);
+ emitUint8(0x1F);
+ emitUint8(0x80);
+ emitUint8(0x00);
+ emitUint8(0x00);
+ emitUint8(0x00);
+ emitUint8(0x00);
+ break;
+ case 8:
+ emitUint8(0x0F);
+ emitUint8(0x1F);
+ emitUint8(0x84);
+ emitUint8(0x00);
+ emitUint8(0x00);
+ emitUint8(0x00);
+ emitUint8(0x00);
+ emitUint8(0x00);
+ break;
+ default:
+ llvm_unreachable("Unimplemented");
+ }
+}
+
+void AssemblerX8632::int3() {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0xCC);
+}
+
+void AssemblerX8632::hlt() {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0xF4);
+}
+
+void AssemblerX8632::ud2() {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x0F);
+ emitUint8(0x0B);
+}
+
+void AssemblerX8632::j(CondX86::BrCond condition, Label *label, bool near) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (label->IsBound()) {
+ static const int kShortSize = 2;
+ static const int kLongSize = 6;
+ intptr_t offset = label->Position() - Buffer.size();
+ assert(offset <= 0);
+ if (Utils::IsInt(8, offset - kShortSize)) {
+ // TODO(stichnot): Here and in jmp(), we may need to be more
+ // conservative about the backward branch distance if the branch
+ // instruction is within a bundle_lock sequence, because the
+ // distance may increase when padding is added. This isn't an
+ // issue for branches outside a bundle_lock, because if padding
+ // is added, the retry may change it to a long backward branch
+ // without affecting any of the bookkeeping.
+ emitUint8(0x70 + condition);
+ emitUint8((offset - kShortSize) & 0xFF);
+ } else {
+ emitUint8(0x0F);
+ emitUint8(0x80 + condition);
+ emitInt32(offset - kLongSize);
+ }
+ } else if (near) {
+ emitUint8(0x70 + condition);
+ emitNearLabelLink(label);
+ } else {
+ emitUint8(0x0F);
+ emitUint8(0x80 + condition);
+ emitLabelLink(label);
+ }
+}
+
+void AssemblerX8632::j(CondX86::BrCond condition,
+ const ConstantRelocatable *label) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x0F);
+ emitUint8(0x80 + condition);
+ emitFixup(this->createFixup(llvm::ELF::R_386_PC32, label));
+ emitInt32(-4);
+}
+
+void AssemblerX8632::jmp(GPRRegister reg) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0xFF);
+ emitRegisterOperand(4, reg);
+}
+
+void AssemblerX8632::jmp(Label *label, bool near) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (label->IsBound()) {
+ static const int kShortSize = 2;
+ static const int kLongSize = 5;
+ intptr_t offset = label->Position() - Buffer.size();
+ assert(offset <= 0);
+ if (Utils::IsInt(8, offset - kShortSize)) {
+ emitUint8(0xEB);
+ emitUint8((offset - kShortSize) & 0xFF);
+ } else {
+ emitUint8(0xE9);
+ emitInt32(offset - kLongSize);
+ }
+ } else if (near) {
+ emitUint8(0xEB);
+ emitNearLabelLink(label);
+ } else {
+ emitUint8(0xE9);
+ emitLabelLink(label);
+ }
+}
+
+void AssemblerX8632::jmp(const ConstantRelocatable *label) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0xE9);
+ emitFixup(this->createFixup(llvm::ELF::R_386_PC32, label));
+ emitInt32(-4);
+}
+
+void AssemblerX8632::mfence() {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0x0F);
+ emitUint8(0xAE);
+ emitUint8(0xF0);
+}
+
+void AssemblerX8632::lock() {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(0xF0);
+}
+
+void AssemblerX8632::cmpxchg(Type Ty, const Address &address, GPRRegister reg,
+ bool Locked) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ if (Locked)
+ emitUint8(0xF0);
+ emitUint8(0x0F);
+ if (isByteSizedArithType(Ty))
+ emitUint8(0xB0);
+ else
+ emitUint8(0xB1);
+ emitOperand(reg, address);
+}
+
+void AssemblerX8632::cmpxchg8b(const Address &address, bool Locked) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (Locked)
+ emitUint8(0xF0);
+ emitUint8(0x0F);
+ emitUint8(0xC7);
+ emitOperand(1, address);
+}
+
+void AssemblerX8632::xadd(Type Ty, const Address &addr, GPRRegister reg,
+ bool Locked) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ if (Locked)
+ emitUint8(0xF0);
+ emitUint8(0x0F);
+ if (isByteSizedArithType(Ty))
+ emitUint8(0xC0);
+ else
+ emitUint8(0xC1);
+ emitOperand(reg, addr);
+}
+
+void AssemblerX8632::xchg(Type Ty, const Address &addr, GPRRegister reg) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ if (isByteSizedArithType(Ty))
+ emitUint8(0x86);
+ else
+ emitUint8(0x87);
+ emitOperand(reg, addr);
+}
+
+void AssemblerX8632::emitSegmentOverride(uint8_t prefix) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ emitUint8(prefix);
+}
+
+void AssemblerX8632::align(intptr_t alignment, intptr_t offset) {
+ assert(llvm::isPowerOf2_32(alignment));
+ intptr_t pos = offset + Buffer.getPosition();
+ intptr_t mod = pos & (alignment - 1);
+ if (mod == 0) {
+ return;
+ }
+ intptr_t bytes_needed = alignment - mod;
+ while (bytes_needed > MAX_NOP_SIZE) {
+ nop(MAX_NOP_SIZE);
+ bytes_needed -= MAX_NOP_SIZE;
+ }
+ if (bytes_needed) {
+ nop(bytes_needed);
+ }
+ assert(((offset + Buffer.getPosition()) & (alignment - 1)) == 0);
+}
+
+void AssemblerX8632::bind(Label *label) {
+ intptr_t bound = Buffer.size();
+ assert(!label->IsBound()); // Labels can only be bound once.
+ while (label->IsLinked()) {
+ intptr_t position = label->LinkPosition();
+ intptr_t next = Buffer.load<int32_t>(position);
+ Buffer.store<int32_t>(position, bound - (position + 4));
+ label->position_ = next;
+ }
+ while (label->HasNear()) {
+ intptr_t position = label->NearPosition();
+ intptr_t offset = bound - (position + 1);
+ assert(Utils::IsInt(8, offset));
+ Buffer.store<int8_t>(position, offset);
+ }
+ label->BindTo(bound);
+}
+
+void AssemblerX8632::emitOperand(int rm, const Operand &operand) {
+ assert(rm >= 0 && rm < 8);
+ const intptr_t length = operand.length_;
+ assert(length > 0);
+ // Emit the ModRM byte updated with the given RM value.
+ assert((operand.encoding_[0] & 0x38) == 0);
+ emitUint8(operand.encoding_[0] + (rm << 3));
+ if (operand.fixup()) {
+ emitFixup(operand.fixup());
+ }
+ // Emit the rest of the encoded operand.
+ for (intptr_t i = 1; i < length; i++) {
+ emitUint8(operand.encoding_[i]);
+ }
+}
+
+void AssemblerX8632::emitImmediate(Type Ty, const Immediate &imm) {
+ if (Ty == IceType_i16) {
+ assert(!imm.fixup());
+ emitInt16(imm.value());
+ } else {
+ if (imm.fixup()) {
+ emitFixup(imm.fixup());
+ }
+ emitInt32(imm.value());
+ }
+}
+
+void AssemblerX8632::emitComplexI8(int rm, const Operand &operand,
+ const Immediate &immediate) {
+ assert(rm >= 0 && rm < 8);
+ assert(immediate.is_int8());
+ if (operand.IsRegister(RegX8632::Encoded_Reg_eax)) {
+ // Use short form if the destination is al.
+ emitUint8(0x04 + (rm << 3));
+ emitUint8(immediate.value() & 0xFF);
+ } else {
+ // Use sign-extended 8-bit immediate.
+ emitUint8(0x80);
+ emitOperand(rm, operand);
+ emitUint8(immediate.value() & 0xFF);
+ }
+}
+
+void AssemblerX8632::emitComplex(Type Ty, int rm, const Operand &operand,
+ const Immediate &immediate) {
+ assert(rm >= 0 && rm < 8);
+ if (immediate.is_int8()) {
+ // Use sign-extended 8-bit immediate.
+ emitUint8(0x83);
+ emitOperand(rm, operand);
+ emitUint8(immediate.value() & 0xFF);
+ } else if (operand.IsRegister(RegX8632::Encoded_Reg_eax)) {
+ // Use short form if the destination is eax.
+ emitUint8(0x05 + (rm << 3));
+ emitImmediate(Ty, immediate);
+ } else {
+ emitUint8(0x81);
+ emitOperand(rm, operand);
+ emitImmediate(Ty, immediate);
+ }
+}
+
+void AssemblerX8632::emitLabel(Label *label, intptr_t instruction_size) {
+ if (label->IsBound()) {
+ intptr_t offset = label->Position() - Buffer.size();
+ assert(offset <= 0);
+ emitInt32(offset - instruction_size);
+ } else {
+ emitLabelLink(label);
+ }
+}
+
+void AssemblerX8632::emitLabelLink(Label *Label) {
+ assert(!Label->IsBound());
+ intptr_t Position = Buffer.size();
+ emitInt32(Label->position_);
+ if (!getPreliminary())
+ Label->LinkTo(Position);
+}
+
+void AssemblerX8632::emitNearLabelLink(Label *label) {
+ assert(!label->IsBound());
+ intptr_t position = Buffer.size();
+ emitUint8(0);
+ if (!getPreliminary())
+ label->NearLinkTo(position);
+}
+
+void AssemblerX8632::emitGenericShift(int rm, Type Ty, GPRRegister reg,
+ const Immediate &imm) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ assert(imm.is_int8());
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ if (imm.value() == 1) {
+ emitUint8(isByteSizedArithType(Ty) ? 0xD0 : 0xD1);
+ emitOperand(rm, Operand(reg));
+ } else {
+ emitUint8(isByteSizedArithType(Ty) ? 0xC0 : 0xC1);
+ emitOperand(rm, Operand(reg));
+ emitUint8(imm.value() & 0xFF);
+ }
+}
+
+void AssemblerX8632::emitGenericShift(int rm, Type Ty, const Operand &operand,
+ GPRRegister shifter) {
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ assert(shifter == RegX8632::Encoded_Reg_ecx);
+ (void)shifter;
+ if (Ty == IceType_i16)
+ emitOperandSizeOverride();
+ emitUint8(isByteSizedArithType(Ty) ? 0xD2 : 0xD3);
+ emitOperand(rm, operand);
+}
+
+} // end of namespace X8632
+} // end of namespace Ice
diff --git a/src/assembler_ia32.h b/src/IceAssemblerX8632.h
similarity index 93%
rename from src/assembler_ia32.h
rename to src/IceAssemblerX8632.h
index 2a928b0..c67f4ce 100644
--- a/src/assembler_ia32.h
+++ b/src/IceAssemblerX8632.h
@@ -19,9 +19,10 @@
//
//===----------------------------------------------------------------------===//
-#ifndef SUBZERO_SRC_ASSEMBLER_IA32_H
-#define SUBZERO_SRC_ASSEMBLER_IA32_H
+#ifndef SUBZERO_SRC_ICEASSEMBLERX8632_H
+#define SUBZERO_SRC_ICEASSEMBLERX8632_H
+#include "IceAssembler.h"
#include "IceConditionCodesX8632.h"
#include "IceDefs.h"
#include "IceOperand.h"
@@ -29,8 +30,6 @@
#include "IceTypes.h"
#include "IceUtils.h"
-#include "assembler.h"
-
namespace Ice {
using RegX8632::GPRRegister;
@@ -369,7 +368,7 @@
}
Label *GetOrCreateCfgNodeLabel(SizeT NodeNumber);
- void BindCfgNodeLabel(SizeT NodeNumber) override;
+ void bindCfgNodeLabel(SizeT NodeNumber) override;
Label *GetOrCreateLocalLabel(SizeT Number);
void BindLocalLabel(SizeT Number);
@@ -820,35 +819,35 @@
void xadd(Type Ty, const Address &address, GPRRegister reg, bool Locked);
void xchg(Type Ty, const Address &address, GPRRegister reg);
- void EmitSegmentOverride(uint8_t prefix);
+ void emitSegmentOverride(uint8_t prefix);
- intptr_t PreferredLoopAlignment() { return 16; }
- void Align(intptr_t alignment, intptr_t offset);
- void Bind(Label *label);
+ intptr_t preferredLoopAlignment() { return 16; }
+ void align(intptr_t alignment, intptr_t offset);
+ void bind(Label *label);
- intptr_t CodeSize() const { return buffer_.Size(); }
+ intptr_t CodeSize() const { return Buffer.size(); }
private:
- inline void EmitUint8(uint8_t value);
- inline void EmitInt16(int16_t value);
- inline void EmitInt32(int32_t value);
- inline void EmitRegisterOperand(int rm, int reg);
- inline void EmitXmmRegisterOperand(int rm, XmmRegister reg);
- inline void EmitFixup(AssemblerFixup *fixup);
- inline void EmitOperandSizeOverride();
+ inline void emitUint8(uint8_t value);
+ inline void emitInt16(int16_t value);
+ inline void emitInt32(int32_t value);
+ inline void emitRegisterOperand(int rm, int reg);
+ inline void emitXmmRegisterOperand(int rm, XmmRegister reg);
+ inline void emitFixup(AssemblerFixup *fixup);
+ inline void emitOperandSizeOverride();
- void EmitOperand(int rm, const Operand &operand);
- void EmitImmediate(Type ty, const Immediate &imm);
- void EmitComplexI8(int rm, const Operand &operand,
+ void emitOperand(int rm, const Operand &operand);
+ void emitImmediate(Type ty, const Immediate &imm);
+ void emitComplexI8(int rm, const Operand &operand,
const Immediate &immediate);
- void EmitComplex(Type Ty, int rm, const Operand &operand,
+ void emitComplex(Type Ty, int rm, const Operand &operand,
const Immediate &immediate);
- void EmitLabel(Label *label, intptr_t instruction_size);
- void EmitLabelLink(Label *label);
- void EmitNearLabelLink(Label *label);
+ void emitLabel(Label *label, intptr_t instruction_size);
+ void emitLabelLink(Label *label);
+ void emitNearLabelLink(Label *label);
- void EmitGenericShift(int rm, Type Ty, GPRRegister reg, const Immediate &imm);
- void EmitGenericShift(int rm, Type Ty, const Operand &operand,
+ void emitGenericShift(int rm, Type Ty, GPRRegister reg, const Immediate &imm);
+ void emitGenericShift(int rm, Type Ty, const Operand &operand,
GPRRegister shifter);
typedef std::vector<Label *> LabelVector;
@@ -860,34 +859,34 @@
Label *GetOrCreateLabel(SizeT Number, LabelVector &Labels);
};
-inline void AssemblerX8632::EmitUint8(uint8_t value) {
- buffer_.Emit<uint8_t>(value);
+inline void AssemblerX8632::emitUint8(uint8_t value) {
+ Buffer.emit<uint8_t>(value);
}
-inline void AssemblerX8632::EmitInt16(int16_t value) {
- buffer_.Emit<int16_t>(value);
+inline void AssemblerX8632::emitInt16(int16_t value) {
+ Buffer.emit<int16_t>(value);
}
-inline void AssemblerX8632::EmitInt32(int32_t value) {
- buffer_.Emit<int32_t>(value);
+inline void AssemblerX8632::emitInt32(int32_t value) {
+ Buffer.emit<int32_t>(value);
}
-inline void AssemblerX8632::EmitRegisterOperand(int rm, int reg) {
+inline void AssemblerX8632::emitRegisterOperand(int rm, int reg) {
assert(rm >= 0 && rm < 8);
- buffer_.Emit<uint8_t>(0xC0 + (rm << 3) + reg);
+ Buffer.emit<uint8_t>(0xC0 + (rm << 3) + reg);
}
-inline void AssemblerX8632::EmitXmmRegisterOperand(int rm, XmmRegister reg) {
- EmitRegisterOperand(rm, static_cast<GPRRegister>(reg));
+inline void AssemblerX8632::emitXmmRegisterOperand(int rm, XmmRegister reg) {
+ emitRegisterOperand(rm, static_cast<GPRRegister>(reg));
}
-inline void AssemblerX8632::EmitFixup(AssemblerFixup *fixup) {
- buffer_.EmitFixup(fixup);
+inline void AssemblerX8632::emitFixup(AssemblerFixup *fixup) {
+ Buffer.emitFixup(fixup);
}
-inline void AssemblerX8632::EmitOperandSizeOverride() { EmitUint8(0x66); }
+inline void AssemblerX8632::emitOperandSizeOverride() { emitUint8(0x66); }
} // end of namespace X8632
} // end of namespace Ice
-#endif // SUBZERO_SRC_ASSEMBLER_IA32_H
+#endif // SUBZERO_SRC_ICEASSEMBLERX8632_H
diff --git a/src/IceCfg.cpp b/src/IceCfg.cpp
index 5c2f9ad..12de452 100644
--- a/src/IceCfg.cpp
+++ b/src/IceCfg.cpp
@@ -12,7 +12,7 @@
//
//===----------------------------------------------------------------------===//
-#include "assembler.h"
+#include "IceAssembler.h"
#include "IceCfg.h"
#include "IceCfgNode.h"
#include "IceClFlags.h"
diff --git a/src/IceCfg.h b/src/IceCfg.h
index 056812b..c231860 100644
--- a/src/IceCfg.h
+++ b/src/IceCfg.h
@@ -15,7 +15,7 @@
#ifndef SUBZERO_SRC_ICECFG_H
#define SUBZERO_SRC_ICECFG_H
-#include "assembler.h"
+#include "IceAssembler.h"
#include "IceClFlags.h"
#include "IceDefs.h"
#include "IceGlobalContext.h"
diff --git a/src/IceCfgNode.cpp b/src/IceCfgNode.cpp
index 68578b9..dec40e4 100644
--- a/src/IceCfgNode.cpp
+++ b/src/IceCfgNode.cpp
@@ -12,7 +12,7 @@
//
//===----------------------------------------------------------------------===//
-#include "assembler.h"
+#include "IceAssembler.h"
#include "IceCfg.h"
#include "IceCfgNode.h"
#include "IceGlobalInits.h"
@@ -1062,7 +1062,7 @@
// TODO(stichnot): When sandboxing, defer binding the node label
// until just before the first instruction is emitted, to reduce the
// chance that a padding nop is a branch target.
- Asm->BindCfgNodeLabel(getIndex());
+ Asm->bindCfgNodeLabel(getIndex());
for (const Inst &I : Phis) {
if (I.isDeleted())
continue;
diff --git a/src/IceELFObjectWriter.cpp b/src/IceELFObjectWriter.cpp
index 9761dde..9c75482 100644
--- a/src/IceELFObjectWriter.cpp
+++ b/src/IceELFObjectWriter.cpp
@@ -13,7 +13,7 @@
#include "llvm/Support/MathExtras.h"
-#include "assembler.h"
+#include "IceAssembler.h"
#include "IceDefs.h"
#include "IceELFObjectWriter.h"
#include "IceELFSection.h"
diff --git a/src/IceInstARM32.cpp b/src/IceInstARM32.cpp
index c62918b..5131ecc 100644
--- a/src/IceInstARM32.cpp
+++ b/src/IceInstARM32.cpp
@@ -12,7 +12,7 @@
//
//===----------------------------------------------------------------------===//
-#include "assembler_arm32.h"
+#include "IceAssemblerARM32.h"
#include "IceCfg.h"
#include "IceCfgNode.h"
#include "IceInst.h"
diff --git a/src/IceInstX8632.cpp b/src/IceInstX8632.cpp
index 38a9b35..1365d54 100644
--- a/src/IceInstX8632.cpp
+++ b/src/IceInstX8632.cpp
@@ -12,7 +12,7 @@
//
//===----------------------------------------------------------------------===//
-#include "assembler_ia32.h"
+#include "IceAssemblerX8632.h"
#include "IceCfg.h"
#include "IceCfgNode.h"
#include "IceConditionCodesX8632.h"
@@ -2927,7 +2927,7 @@
void OperandX8632Mem::emitSegmentOverride(X8632::AssemblerX8632 *Asm) const {
if (SegmentReg != DefaultSegment) {
assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM);
- Asm->EmitSegmentOverride(InstX8632SegmentPrefixes[SegmentReg]);
+ Asm->emitSegmentOverride(InstX8632SegmentPrefixes[SegmentReg]);
}
}
diff --git a/src/IceInstX8632.h b/src/IceInstX8632.h
index 2e82052..840b21b 100644
--- a/src/IceInstX8632.h
+++ b/src/IceInstX8632.h
@@ -16,7 +16,7 @@
#ifndef SUBZERO_SRC_ICEINSTX8632_H
#define SUBZERO_SRC_ICEINSTX8632_H
-#include "assembler_ia32.h"
+#include "IceAssemblerX8632.h"
#include "IceConditionCodesX8632.h"
#include "IceDefs.h"
#include "IceInst.h"
diff --git a/src/IceTargetLowering.cpp b/src/IceTargetLowering.cpp
index 49c370a..051b00d 100644
--- a/src/IceTargetLowering.cpp
+++ b/src/IceTargetLowering.cpp
@@ -15,8 +15,8 @@
//
//===----------------------------------------------------------------------===//
-#include "assembler_arm32.h"
-#include "assembler_ia32.h"
+#include "IceAssemblerARM32.h"
+#include "IceAssemblerX8632.h"
#include "IceCfg.h" // setError()
#include "IceCfgNode.h"
#include "IceOperand.h"
diff --git a/src/IceTargetLoweringX8632.h b/src/IceTargetLoweringX8632.h
index 5773340..def9dcd 100644
--- a/src/IceTargetLoweringX8632.h
+++ b/src/IceTargetLoweringX8632.h
@@ -18,7 +18,7 @@
#include <unordered_map>
-#include "assembler_ia32.h"
+#include "IceAssemblerX8632.h"
#include "IceDefs.h"
#include "IceInst.h"
#include "IceInstX8632.h"
diff --git a/src/assembler_ia32.cpp b/src/assembler_ia32.cpp
deleted file mode 100644
index edfbc3e..0000000
--- a/src/assembler_ia32.cpp
+++ /dev/null
@@ -1,2609 +0,0 @@
-//===- subzero/src/assembler_ia32.cpp - Assembler for x86-32 -------------===//
-// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-//
-// Modified by the Subzero authors.
-//
-//===----------------------------------------------------------------------===//
-//
-// The Subzero Code Generator
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the Assembler class for x86-32.
-//
-//===----------------------------------------------------------------------===//
-
-#include "assembler_ia32.h"
-#include "IceCfg.h"
-#include "IceOperand.h"
-
-namespace Ice {
-namespace X8632 {
-
-Address Address::ofConstPool(Assembler *Asm, const Constant *Imm) {
- AssemblerFixup *Fixup = Asm->createFixup(llvm::ELF::R_386_32, Imm);
- const RelocOffsetT Offset = 0;
- return Address::Absolute(Offset, Fixup);
-}
-
-AssemblerX8632::~AssemblerX8632() {
-#ifndef NDEBUG
- for (const Label *Label : CfgNodeLabels) {
- Label->FinalCheck();
- }
- for (const Label *Label : LocalLabels) {
- Label->FinalCheck();
- }
-#endif
-}
-
-void AssemblerX8632::alignFunction() {
- SizeT Align = 1 << getBundleAlignLog2Bytes();
- SizeT BytesNeeded = Utils::OffsetToAlignment(buffer_.GetPosition(), Align);
- const SizeT HltSize = 1;
- while (BytesNeeded > 0) {
- hlt();
- BytesNeeded -= HltSize;
- }
-}
-
-Label *AssemblerX8632::GetOrCreateLabel(SizeT Number, LabelVector &Labels) {
- Label *L = nullptr;
- if (Number == Labels.size()) {
- L = new (this->Allocate<Label>()) Label();
- Labels.push_back(L);
- return L;
- }
- if (Number > Labels.size()) {
- Labels.resize(Number + 1);
- }
- L = Labels[Number];
- if (!L) {
- L = new (this->Allocate<Label>()) Label();
- Labels[Number] = L;
- }
- return L;
-}
-
-Label *AssemblerX8632::GetOrCreateCfgNodeLabel(SizeT NodeNumber) {
- return GetOrCreateLabel(NodeNumber, CfgNodeLabels);
-}
-
-Label *AssemblerX8632::GetOrCreateLocalLabel(SizeT Number) {
- return GetOrCreateLabel(Number, LocalLabels);
-}
-
-void AssemblerX8632::BindCfgNodeLabel(SizeT NodeNumber) {
- assert(!getPreliminary());
- Label *L = GetOrCreateCfgNodeLabel(NodeNumber);
- this->Bind(L);
-}
-
-void AssemblerX8632::BindLocalLabel(SizeT Number) {
- Label *L = GetOrCreateLocalLabel(Number);
- if (!getPreliminary())
- this->Bind(L);
-}
-
-void AssemblerX8632::call(GPRRegister reg) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0xFF);
- EmitRegisterOperand(2, reg);
-}
-
-void AssemblerX8632::call(const Address &address) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0xFF);
- EmitOperand(2, address);
-}
-
-void AssemblerX8632::call(const ConstantRelocatable *label) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- intptr_t call_start = buffer_.GetPosition();
- EmitUint8(0xE8);
- EmitFixup(this->createFixup(llvm::ELF::R_386_PC32, label));
- EmitInt32(-4);
- assert((buffer_.GetPosition() - call_start) == kCallExternalLabelSize);
- (void)call_start;
-}
-
-void AssemblerX8632::call(const Immediate &abs_address) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- intptr_t call_start = buffer_.GetPosition();
- EmitUint8(0xE8);
- EmitFixup(
- this->createFixup(llvm::ELF::R_386_PC32, AssemblerFixup::NullSymbol));
- EmitInt32(abs_address.value() - 4);
- assert((buffer_.GetPosition() - call_start) == kCallExternalLabelSize);
- (void)call_start;
-}
-
-void AssemblerX8632::pushl(GPRRegister reg) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x50 + reg);
-}
-
-void AssemblerX8632::popl(GPRRegister reg) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x58 + reg);
-}
-
-void AssemblerX8632::popl(const Address &address) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x8F);
- EmitOperand(0, address);
-}
-
-void AssemblerX8632::pushal() {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x60);
-}
-
-void AssemblerX8632::popal() {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x61);
-}
-
-void AssemblerX8632::setcc(CondX86::BrCond condition, ByteRegister dst) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x0F);
- EmitUint8(0x90 + condition);
- EmitUint8(0xC0 + dst);
-}
-
-void AssemblerX8632::setcc(CondX86::BrCond condition, const Address &address) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x0F);
- EmitUint8(0x90 + condition);
- EmitOperand(0, address);
-}
-
-void AssemblerX8632::mov(Type Ty, GPRRegister dst, const Immediate &imm) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (isByteSizedType(Ty)) {
- EmitUint8(0xB0 + dst);
- EmitUint8(imm.value() & 0xFF);
- return;
- }
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- EmitUint8(0xB8 + dst);
- EmitImmediate(Ty, imm);
-}
-
-void AssemblerX8632::mov(Type Ty, GPRRegister dst, GPRRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- if (isByteSizedType(Ty)) {
- EmitUint8(0x88);
- } else {
- EmitUint8(0x89);
- }
- EmitRegisterOperand(src, dst);
-}
-
-void AssemblerX8632::mov(Type Ty, GPRRegister dst, const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- if (isByteSizedType(Ty)) {
- EmitUint8(0x8A);
- } else {
- EmitUint8(0x8B);
- }
- EmitOperand(dst, src);
-}
-
-void AssemblerX8632::mov(Type Ty, const Address &dst, GPRRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- if (isByteSizedType(Ty)) {
- EmitUint8(0x88);
- } else {
- EmitUint8(0x89);
- }
- EmitOperand(src, dst);
-}
-
-void AssemblerX8632::mov(Type Ty, const Address &dst, const Immediate &imm) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- if (isByteSizedType(Ty)) {
- EmitUint8(0xC6);
- EmitOperand(0, dst);
- EmitUint8(imm.value() & 0xFF);
- } else {
- EmitUint8(0xC7);
- EmitOperand(0, dst);
- EmitImmediate(Ty, imm);
- }
-}
-
-void AssemblerX8632::movzx(Type SrcTy, GPRRegister dst, GPRRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- bool ByteSized = isByteSizedType(SrcTy);
- assert(ByteSized || SrcTy == IceType_i16);
- EmitUint8(0x0F);
- EmitUint8(ByteSized ? 0xB6 : 0xB7);
- EmitRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::movzx(Type SrcTy, GPRRegister dst, const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- bool ByteSized = isByteSizedType(SrcTy);
- assert(ByteSized || SrcTy == IceType_i16);
- EmitUint8(0x0F);
- EmitUint8(ByteSized ? 0xB6 : 0xB7);
- EmitOperand(dst, src);
-}
-
-void AssemblerX8632::movsx(Type SrcTy, GPRRegister dst, GPRRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- bool ByteSized = isByteSizedType(SrcTy);
- assert(ByteSized || SrcTy == IceType_i16);
- EmitUint8(0x0F);
- EmitUint8(ByteSized ? 0xBE : 0xBF);
- EmitRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::movsx(Type SrcTy, GPRRegister dst, const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- bool ByteSized = isByteSizedType(SrcTy);
- assert(ByteSized || SrcTy == IceType_i16);
- EmitUint8(0x0F);
- EmitUint8(ByteSized ? 0xBE : 0xBF);
- EmitOperand(dst, src);
-}
-
-void AssemblerX8632::lea(Type Ty, GPRRegister dst, const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- assert(Ty == IceType_i16 || Ty == IceType_i32);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- EmitUint8(0x8D);
- EmitOperand(dst, src);
-}
-
-void AssemblerX8632::cmov(Type Ty, CondX86::BrCond cond, GPRRegister dst,
- GPRRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- else
- assert(Ty == IceType_i32);
- EmitUint8(0x0F);
- EmitUint8(0x40 + cond);
- EmitRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::cmov(Type Ty, CondX86::BrCond cond, GPRRegister dst,
- const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- else
- assert(Ty == IceType_i32);
- EmitUint8(0x0F);
- EmitUint8(0x40 + cond);
- EmitOperand(dst, src);
-}
-
-void AssemblerX8632::rep_movsb() {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0xF3);
- EmitUint8(0xA4);
-}
-
-void AssemblerX8632::movss(Type Ty, XmmRegister dst, const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
- EmitUint8(0x0F);
- EmitUint8(0x10);
- EmitOperand(dst, src);
-}
-
-void AssemblerX8632::movss(Type Ty, const Address &dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
- EmitUint8(0x0F);
- EmitUint8(0x11);
- EmitOperand(src, dst);
-}
-
-void AssemblerX8632::movss(Type Ty, XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
- EmitUint8(0x0F);
- EmitUint8(0x11);
- EmitXmmRegisterOperand(src, dst);
-}
-
-void AssemblerX8632::movd(XmmRegister dst, GPRRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0x6E);
- EmitRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::movd(XmmRegister dst, const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0x6E);
- EmitOperand(dst, src);
-}
-
-void AssemblerX8632::movd(GPRRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0x7E);
- EmitRegisterOperand(src, dst);
-}
-
-void AssemblerX8632::movd(const Address &dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0x7E);
- EmitOperand(src, dst);
-}
-
-void AssemblerX8632::movq(XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0xF3);
- EmitUint8(0x0F);
- EmitUint8(0x7E);
- EmitRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::movq(const Address &dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0xD6);
- EmitOperand(src, dst);
-}
-
-void AssemblerX8632::movq(XmmRegister dst, const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0xF3);
- EmitUint8(0x0F);
- EmitUint8(0x7E);
- EmitOperand(dst, src);
-}
-
-void AssemblerX8632::addss(Type Ty, XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
- EmitUint8(0x0F);
- EmitUint8(0x58);
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::addss(Type Ty, XmmRegister dst, const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
- EmitUint8(0x0F);
- EmitUint8(0x58);
- EmitOperand(dst, src);
-}
-
-void AssemblerX8632::subss(Type Ty, XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
- EmitUint8(0x0F);
- EmitUint8(0x5C);
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::subss(Type Ty, XmmRegister dst, const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
- EmitUint8(0x0F);
- EmitUint8(0x5C);
- EmitOperand(dst, src);
-}
-
-void AssemblerX8632::mulss(Type Ty, XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
- EmitUint8(0x0F);
- EmitUint8(0x59);
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::mulss(Type Ty, XmmRegister dst, const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
- EmitUint8(0x0F);
- EmitUint8(0x59);
- EmitOperand(dst, src);
-}
-
-void AssemblerX8632::divss(Type Ty, XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
- EmitUint8(0x0F);
- EmitUint8(0x5E);
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::divss(Type Ty, XmmRegister dst, const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
- EmitUint8(0x0F);
- EmitUint8(0x5E);
- EmitOperand(dst, src);
-}
-
-void AssemblerX8632::fld(Type Ty, const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(isFloat32Asserting32Or64(Ty) ? 0xD9 : 0xDD);
- EmitOperand(0, src);
-}
-
-void AssemblerX8632::fstp(Type Ty, const Address &dst) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(isFloat32Asserting32Or64(Ty) ? 0xD9 : 0xDD);
- EmitOperand(3, dst);
-}
-
-void AssemblerX8632::fstp(X87STRegister st) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0xDD);
- EmitUint8(0xD8 + st);
-}
-
-void AssemblerX8632::movaps(XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x0F);
- EmitUint8(0x28);
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::movups(XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x0F);
- EmitUint8(0x10);
- EmitRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::movups(XmmRegister dst, const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x0F);
- EmitUint8(0x10);
- EmitOperand(dst, src);
-}
-
-void AssemblerX8632::movups(const Address &dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x0F);
- EmitUint8(0x11);
- EmitOperand(src, dst);
-}
-
-void AssemblerX8632::padd(Type Ty, XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- if (isByteSizedArithType(Ty)) {
- EmitUint8(0xFC);
- } else if (Ty == IceType_i16) {
- EmitUint8(0xFD);
- } else {
- EmitUint8(0xFE);
- }
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::padd(Type Ty, XmmRegister dst, const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- if (isByteSizedArithType(Ty)) {
- EmitUint8(0xFC);
- } else if (Ty == IceType_i16) {
- EmitUint8(0xFD);
- } else {
- EmitUint8(0xFE);
- }
- EmitOperand(dst, src);
-}
-
-void AssemblerX8632::pand(Type /* Ty */, XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0xDB);
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::pand(Type /* Ty */, XmmRegister dst, const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0xDB);
- EmitOperand(dst, src);
-}
-
-void AssemblerX8632::pandn(Type /* Ty */, XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0xDF);
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::pandn(Type /* Ty */, XmmRegister dst, const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0xDF);
- EmitOperand(dst, src);
-}
-
-void AssemblerX8632::pmull(Type Ty, XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- if (Ty == IceType_i16) {
- EmitUint8(0xD5);
- } else {
- assert(Ty == IceType_i32);
- EmitUint8(0x38);
- EmitUint8(0x40);
- }
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::pmull(Type Ty, XmmRegister dst, const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- if (Ty == IceType_i16) {
- EmitUint8(0xD5);
- } else {
- assert(Ty == IceType_i32);
- EmitUint8(0x38);
- EmitUint8(0x40);
- }
- EmitOperand(dst, src);
-}
-
-void AssemblerX8632::pmuludq(Type /* Ty */, XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0xF4);
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::pmuludq(Type /* Ty */, XmmRegister dst,
- const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0xF4);
- EmitOperand(dst, src);
-}
-
-void AssemblerX8632::por(Type /* Ty */, XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0xEB);
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::por(Type /* Ty */, XmmRegister dst, const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0xEB);
- EmitOperand(dst, src);
-}
-
-void AssemblerX8632::psub(Type Ty, XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- if (isByteSizedArithType(Ty)) {
- EmitUint8(0xF8);
- } else if (Ty == IceType_i16) {
- EmitUint8(0xF9);
- } else {
- EmitUint8(0xFA);
- }
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::psub(Type Ty, XmmRegister dst, const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- if (isByteSizedArithType(Ty)) {
- EmitUint8(0xF8);
- } else if (Ty == IceType_i16) {
- EmitUint8(0xF9);
- } else {
- EmitUint8(0xFA);
- }
- EmitOperand(dst, src);
-}
-
-void AssemblerX8632::pxor(Type /* Ty */, XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0xEF);
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::pxor(Type /* Ty */, XmmRegister dst, const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0xEF);
- EmitOperand(dst, src);
-}
-
-void AssemblerX8632::psll(Type Ty, XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- if (Ty == IceType_i16) {
- EmitUint8(0xF1);
- } else {
- assert(Ty == IceType_i32);
- EmitUint8(0xF2);
- }
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::psll(Type Ty, XmmRegister dst, const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- if (Ty == IceType_i16) {
- EmitUint8(0xF1);
- } else {
- assert(Ty == IceType_i32);
- EmitUint8(0xF2);
- }
- EmitOperand(dst, src);
-}
-
-void AssemblerX8632::psll(Type Ty, XmmRegister dst, const Immediate &imm) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- assert(imm.is_int8());
- EmitUint8(0x66);
- EmitUint8(0x0F);
- if (Ty == IceType_i16) {
- EmitUint8(0x71);
- } else {
- assert(Ty == IceType_i32);
- EmitUint8(0x72);
- }
- EmitRegisterOperand(6, dst);
- EmitUint8(imm.value() & 0xFF);
-}
-
-void AssemblerX8632::psra(Type Ty, XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- if (Ty == IceType_i16) {
- EmitUint8(0xE1);
- } else {
- assert(Ty == IceType_i32);
- EmitUint8(0xE2);
- }
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::psra(Type Ty, XmmRegister dst, const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- if (Ty == IceType_i16) {
- EmitUint8(0xE1);
- } else {
- assert(Ty == IceType_i32);
- EmitUint8(0xE2);
- }
- EmitOperand(dst, src);
-}
-
-void AssemblerX8632::psra(Type Ty, XmmRegister dst, const Immediate &imm) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- assert(imm.is_int8());
- EmitUint8(0x66);
- EmitUint8(0x0F);
- if (Ty == IceType_i16) {
- EmitUint8(0x71);
- } else {
- assert(Ty == IceType_i32);
- EmitUint8(0x72);
- }
- EmitRegisterOperand(4, dst);
- EmitUint8(imm.value() & 0xFF);
-}
-
-void AssemblerX8632::psrl(Type Ty, XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- if (Ty == IceType_i16) {
- EmitUint8(0xD1);
- } else if (Ty == IceType_f64) {
- EmitUint8(0xD3);
- } else {
- assert(Ty == IceType_i32 || Ty == IceType_f32 || Ty == IceType_v4f32);
- EmitUint8(0xD2);
- }
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::psrl(Type Ty, XmmRegister dst, const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- if (Ty == IceType_i16) {
- EmitUint8(0xD1);
- } else if (Ty == IceType_f64) {
- EmitUint8(0xD3);
- } else {
- assert(Ty == IceType_i32 || Ty == IceType_f32 || Ty == IceType_v4f32);
- EmitUint8(0xD2);
- }
- EmitOperand(dst, src);
-}
-
-void AssemblerX8632::psrl(Type Ty, XmmRegister dst, const Immediate &imm) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- assert(imm.is_int8());
- EmitUint8(0x66);
- EmitUint8(0x0F);
- if (Ty == IceType_i16) {
- EmitUint8(0x71);
- } else if (Ty == IceType_f64) {
- EmitUint8(0x73);
- } else {
- assert(Ty == IceType_i32 || Ty == IceType_f32 || Ty == IceType_v4f32);
- EmitUint8(0x72);
- }
- EmitRegisterOperand(2, dst);
- EmitUint8(imm.value() & 0xFF);
-}
-
-// {add,sub,mul,div}ps are given a Ty parameter for consistency with
-// {add,sub,mul,div}ss. In the future, when the PNaCl ABI allows
-// addpd, etc., we can use the Ty parameter to decide on adding
-// a 0x66 prefix.
-void AssemblerX8632::addps(Type /* Ty */, XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x0F);
- EmitUint8(0x58);
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::addps(Type /* Ty */, XmmRegister dst, const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x0F);
- EmitUint8(0x58);
- EmitOperand(dst, src);
-}
-
-void AssemblerX8632::subps(Type /* Ty */, XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x0F);
- EmitUint8(0x5C);
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::subps(Type /* Ty */, XmmRegister dst, const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x0F);
- EmitUint8(0x5C);
- EmitOperand(dst, src);
-}
-
-void AssemblerX8632::divps(Type /* Ty */, XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x0F);
- EmitUint8(0x5E);
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::divps(Type /* Ty */, XmmRegister dst, const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x0F);
- EmitUint8(0x5E);
- EmitOperand(dst, src);
-}
-
-void AssemblerX8632::mulps(Type /* Ty */, XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x0F);
- EmitUint8(0x59);
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::mulps(Type /* Ty */, XmmRegister dst, const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x0F);
- EmitUint8(0x59);
- EmitOperand(dst, src);
-}
-
-void AssemblerX8632::minps(XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x0F);
- EmitUint8(0x5D);
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::maxps(XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x0F);
- EmitUint8(0x5F);
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::andps(XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x0F);
- EmitUint8(0x54);
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::andps(XmmRegister dst, const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x0F);
- EmitUint8(0x54);
- EmitOperand(dst, src);
-}
-
-void AssemblerX8632::orps(XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x0F);
- EmitUint8(0x56);
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::blendvps(Type /* Ty */, XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0x38);
- EmitUint8(0x14);
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::blendvps(Type /* Ty */, XmmRegister dst,
- const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0x38);
- EmitUint8(0x14);
- EmitOperand(dst, src);
-}
-
-void AssemblerX8632::pblendvb(Type /* Ty */, XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0x38);
- EmitUint8(0x10);
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::pblendvb(Type /* Ty */, XmmRegister dst,
- const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0x38);
- EmitUint8(0x10);
- EmitOperand(dst, src);
-}
-
-void AssemblerX8632::cmpps(XmmRegister dst, XmmRegister src,
- CondX86::CmppsCond CmpCondition) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x0F);
- EmitUint8(0xC2);
- EmitXmmRegisterOperand(dst, src);
- EmitUint8(CmpCondition);
-}
-
-void AssemblerX8632::cmpps(XmmRegister dst, const Address &src,
- CondX86::CmppsCond CmpCondition) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x0F);
- EmitUint8(0xC2);
- EmitOperand(dst, src);
- EmitUint8(CmpCondition);
-}
-
-void AssemblerX8632::sqrtps(XmmRegister dst) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x0F);
- EmitUint8(0x51);
- EmitXmmRegisterOperand(dst, dst);
-}
-
-void AssemblerX8632::rsqrtps(XmmRegister dst) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x0F);
- EmitUint8(0x52);
- EmitXmmRegisterOperand(dst, dst);
-}
-
-void AssemblerX8632::reciprocalps(XmmRegister dst) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x0F);
- EmitUint8(0x53);
- EmitXmmRegisterOperand(dst, dst);
-}
-
-void AssemblerX8632::movhlps(XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x0F);
- EmitUint8(0x12);
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::movlhps(XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x0F);
- EmitUint8(0x16);
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::unpcklps(XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x0F);
- EmitUint8(0x14);
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::unpckhps(XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x0F);
- EmitUint8(0x15);
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::unpcklpd(XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0x14);
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::unpckhpd(XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0x15);
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::set1ps(XmmRegister dst, GPRRegister tmp1,
- const Immediate &imm) {
- // Load 32-bit immediate value into tmp1.
- mov(IceType_i32, tmp1, imm);
- // Move value from tmp1 into dst.
- movd(dst, tmp1);
- // Broadcast low lane into other three lanes.
- shufps(dst, dst, Immediate(0x0));
-}
-
-void AssemblerX8632::shufps(XmmRegister dst, XmmRegister src,
- const Immediate &imm) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x0F);
- EmitUint8(0xC6);
- EmitXmmRegisterOperand(dst, src);
- assert(imm.is_uint8());
- EmitUint8(imm.value());
-}
-
-void AssemblerX8632::pshufd(Type /* Ty */, XmmRegister dst, XmmRegister src,
- const Immediate &imm) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0x70);
- EmitXmmRegisterOperand(dst, src);
- assert(imm.is_uint8());
- EmitUint8(imm.value());
-}
-
-void AssemblerX8632::pshufd(Type /* Ty */, XmmRegister dst, const Address &src,
- const Immediate &imm) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0x70);
- EmitOperand(dst, src);
- assert(imm.is_uint8());
- EmitUint8(imm.value());
-}
-
-void AssemblerX8632::shufps(Type /* Ty */, XmmRegister dst, XmmRegister src,
- const Immediate &imm) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x0F);
- EmitUint8(0xC6);
- EmitXmmRegisterOperand(dst, src);
- assert(imm.is_uint8());
- EmitUint8(imm.value());
-}
-
-void AssemblerX8632::shufps(Type /* Ty */, XmmRegister dst, const Address &src,
- const Immediate &imm) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x0F);
- EmitUint8(0xC6);
- EmitOperand(dst, src);
- assert(imm.is_uint8());
- EmitUint8(imm.value());
-}
-
-void AssemblerX8632::minpd(XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0x5D);
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::maxpd(XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0x5F);
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::sqrtpd(XmmRegister dst) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0x51);
- EmitXmmRegisterOperand(dst, dst);
-}
-
-void AssemblerX8632::shufpd(XmmRegister dst, XmmRegister src,
- const Immediate &imm) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0xC6);
- EmitXmmRegisterOperand(dst, src);
- assert(imm.is_uint8());
- EmitUint8(imm.value());
-}
-
-void AssemblerX8632::cvtdq2ps(Type /* Ignore */, XmmRegister dst,
- XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x0F);
- EmitUint8(0x5B);
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::cvtdq2ps(Type /* Ignore */, XmmRegister dst,
- const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x0F);
- EmitUint8(0x5B);
- EmitOperand(dst, src);
-}
-
-void AssemblerX8632::cvttps2dq(Type /* Ignore */, XmmRegister dst,
- XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0xF3);
- EmitUint8(0x0F);
- EmitUint8(0x5B);
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::cvttps2dq(Type /* Ignore */, XmmRegister dst,
- const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0xF3);
- EmitUint8(0x0F);
- EmitUint8(0x5B);
- EmitOperand(dst, src);
-}
-
-void AssemblerX8632::cvtsi2ss(Type DestTy, XmmRegister dst, GPRRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(isFloat32Asserting32Or64(DestTy) ? 0xF3 : 0xF2);
- EmitUint8(0x0F);
- EmitUint8(0x2A);
- EmitRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::cvtsi2ss(Type DestTy, XmmRegister dst,
- const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(isFloat32Asserting32Or64(DestTy) ? 0xF3 : 0xF2);
- EmitUint8(0x0F);
- EmitUint8(0x2A);
- EmitOperand(dst, src);
-}
-
-void AssemblerX8632::cvtfloat2float(Type SrcTy, XmmRegister dst,
- XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- // ss2sd or sd2ss
- EmitUint8(isFloat32Asserting32Or64(SrcTy) ? 0xF3 : 0xF2);
- EmitUint8(0x0F);
- EmitUint8(0x5A);
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::cvtfloat2float(Type SrcTy, XmmRegister dst,
- const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(isFloat32Asserting32Or64(SrcTy) ? 0xF3 : 0xF2);
- EmitUint8(0x0F);
- EmitUint8(0x5A);
- EmitOperand(dst, src);
-}
-
-void AssemblerX8632::cvttss2si(Type SrcTy, GPRRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(isFloat32Asserting32Or64(SrcTy) ? 0xF3 : 0xF2);
- EmitUint8(0x0F);
- EmitUint8(0x2C);
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::cvttss2si(Type SrcTy, GPRRegister dst,
- const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(isFloat32Asserting32Or64(SrcTy) ? 0xF3 : 0xF2);
- EmitUint8(0x0F);
- EmitUint8(0x2C);
- EmitOperand(dst, src);
-}
-
-void AssemblerX8632::ucomiss(Type Ty, XmmRegister a, XmmRegister b) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (Ty == IceType_f64)
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0x2E);
- EmitXmmRegisterOperand(a, b);
-}
-
-void AssemblerX8632::ucomiss(Type Ty, XmmRegister a, const Address &b) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (Ty == IceType_f64)
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0x2E);
- EmitOperand(a, b);
-}
-
-void AssemblerX8632::movmskpd(GPRRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0x50);
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::movmskps(GPRRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x0F);
- EmitUint8(0x50);
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::sqrtss(Type Ty, XmmRegister dst, const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
- EmitUint8(0x0F);
- EmitUint8(0x51);
- EmitOperand(dst, src);
-}
-
-void AssemblerX8632::sqrtss(Type Ty, XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
- EmitUint8(0x0F);
- EmitUint8(0x51);
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::xorpd(XmmRegister dst, const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0x57);
- EmitOperand(dst, src);
-}
-
-void AssemblerX8632::xorpd(XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0x57);
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::orpd(XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0x56);
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::xorps(XmmRegister dst, const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x0F);
- EmitUint8(0x57);
- EmitOperand(dst, src);
-}
-
-void AssemblerX8632::xorps(XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x0F);
- EmitUint8(0x57);
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::andpd(XmmRegister dst, const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0x54);
- EmitOperand(dst, src);
-}
-
-void AssemblerX8632::andpd(XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0x54);
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::insertps(Type Ty, XmmRegister dst, XmmRegister src,
- const Immediate &imm) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- assert(imm.is_uint8());
- assert(isVectorFloatingType(Ty));
- (void)Ty;
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0x3A);
- EmitUint8(0x21);
- EmitXmmRegisterOperand(dst, src);
- EmitUint8(imm.value());
-}
-
-void AssemblerX8632::insertps(Type Ty, XmmRegister dst, const Address &src,
- const Immediate &imm) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- assert(imm.is_uint8());
- assert(isVectorFloatingType(Ty));
- (void)Ty;
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0x3A);
- EmitUint8(0x21);
- EmitOperand(dst, src);
- EmitUint8(imm.value());
-}
-
-void AssemblerX8632::pinsr(Type Ty, XmmRegister dst, GPRRegister src,
- const Immediate &imm) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- assert(imm.is_uint8());
- if (Ty == IceType_i16) {
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0xC4);
- EmitXmmRegisterOperand(dst, XmmRegister(src));
- EmitUint8(imm.value());
- } else {
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0x3A);
- EmitUint8(isByteSizedType(Ty) ? 0x20 : 0x22);
- EmitXmmRegisterOperand(dst, XmmRegister(src));
- EmitUint8(imm.value());
- }
-}
-
-void AssemblerX8632::pinsr(Type Ty, XmmRegister dst, const Address &src,
- const Immediate &imm) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- assert(imm.is_uint8());
- if (Ty == IceType_i16) {
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0xC4);
- EmitOperand(dst, src);
- EmitUint8(imm.value());
- } else {
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0x3A);
- EmitUint8(isByteSizedType(Ty) ? 0x20 : 0x22);
- EmitOperand(dst, src);
- EmitUint8(imm.value());
- }
-}
-
-void AssemblerX8632::pextr(Type Ty, GPRRegister dst, XmmRegister src,
- const Immediate &imm) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- assert(imm.is_uint8());
- if (Ty == IceType_i16) {
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0xC5);
- EmitXmmRegisterOperand(XmmRegister(dst), src);
- EmitUint8(imm.value());
- } else {
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0x3A);
- EmitUint8(isByteSizedType(Ty) ? 0x14 : 0x16);
- // SSE 4.1 versions are "MRI" because dst can be mem, while
- // pextrw (SSE2) is RMI because dst must be reg.
- EmitXmmRegisterOperand(src, XmmRegister(dst));
- EmitUint8(imm.value());
- }
-}
-
-void AssemblerX8632::pmovsxdq(XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0x38);
- EmitUint8(0x25);
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::pcmpeq(Type Ty, XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- if (isByteSizedArithType(Ty)) {
- EmitUint8(0x74);
- } else if (Ty == IceType_i16) {
- EmitUint8(0x75);
- } else {
- EmitUint8(0x76);
- }
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::pcmpeq(Type Ty, XmmRegister dst, const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- if (isByteSizedArithType(Ty)) {
- EmitUint8(0x74);
- } else if (Ty == IceType_i16) {
- EmitUint8(0x75);
- } else {
- EmitUint8(0x76);
- }
- EmitOperand(dst, src);
-}
-
-void AssemblerX8632::pcmpgt(Type Ty, XmmRegister dst, XmmRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- if (isByteSizedArithType(Ty)) {
- EmitUint8(0x64);
- } else if (Ty == IceType_i16) {
- EmitUint8(0x65);
- } else {
- EmitUint8(0x66);
- }
- EmitXmmRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::pcmpgt(Type Ty, XmmRegister dst, const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- if (isByteSizedArithType(Ty)) {
- EmitUint8(0x64);
- } else if (Ty == IceType_i16) {
- EmitUint8(0x65);
- } else {
- EmitUint8(0x66);
- }
- EmitOperand(dst, src);
-}
-
-void AssemblerX8632::roundsd(XmmRegister dst, XmmRegister src,
- RoundingMode mode) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0x3A);
- EmitUint8(0x0B);
- EmitXmmRegisterOperand(dst, src);
- // Mask precision exeption.
- EmitUint8(static_cast<uint8_t>(mode) | 0x8);
-}
-
-void AssemblerX8632::fnstcw(const Address &dst) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0xD9);
- EmitOperand(7, dst);
-}
-
-void AssemblerX8632::fldcw(const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0xD9);
- EmitOperand(5, src);
-}
-
-void AssemblerX8632::fistpl(const Address &dst) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0xDF);
- EmitOperand(7, dst);
-}
-
-void AssemblerX8632::fistps(const Address &dst) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0xDB);
- EmitOperand(3, dst);
-}
-
-void AssemblerX8632::fildl(const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0xDF);
- EmitOperand(5, src);
-}
-
-void AssemblerX8632::filds(const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0xDB);
- EmitOperand(0, src);
-}
-
-void AssemblerX8632::fincstp() {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0xD9);
- EmitUint8(0xF7);
-}
-
-void AssemblerX8632::cmp(Type Ty, GPRRegister reg, const Immediate &imm) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (isByteSizedType(Ty)) {
- EmitComplexI8(7, Operand(reg), imm);
- return;
- }
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- EmitComplex(Ty, 7, Operand(reg), imm);
-}
-
-void AssemblerX8632::cmp(Type Ty, GPRRegister reg0, GPRRegister reg1) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- if (isByteSizedType(Ty))
- EmitUint8(0x3A);
- else
- EmitUint8(0x3B);
- EmitRegisterOperand(reg0, reg1);
-}
-
-void AssemblerX8632::cmp(Type Ty, GPRRegister reg, const Address &address) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- if (isByteSizedType(Ty))
- EmitUint8(0x3A);
- else
- EmitUint8(0x3B);
- EmitOperand(reg, address);
-}
-
-void AssemblerX8632::cmp(Type Ty, const Address &address, GPRRegister reg) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- if (isByteSizedType(Ty))
- EmitUint8(0x38);
- else
- EmitUint8(0x39);
- EmitOperand(reg, address);
-}
-
-void AssemblerX8632::cmp(Type Ty, const Address &address,
- const Immediate &imm) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (isByteSizedType(Ty)) {
- EmitComplexI8(7, address, imm);
- return;
- }
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- EmitComplex(Ty, 7, address, imm);
-}
-
-void AssemblerX8632::test(Type Ty, GPRRegister reg1, GPRRegister reg2) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- if (isByteSizedType(Ty))
- EmitUint8(0x84);
- else
- EmitUint8(0x85);
- EmitRegisterOperand(reg1, reg2);
-}
-
-void AssemblerX8632::test(Type Ty, const Address &addr, GPRRegister reg) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- if (isByteSizedType(Ty))
- EmitUint8(0x84);
- else
- EmitUint8(0x85);
- EmitOperand(reg, addr);
-}
-
-void AssemblerX8632::test(Type Ty, GPRRegister reg,
- const Immediate &immediate) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- // For registers that have a byte variant (EAX, EBX, ECX, and EDX)
- // we only test the byte register to keep the encoding short.
- // This is legal even if the register had high bits set since
- // this only sets flags registers based on the "AND" of the two operands,
- // and the immediate had zeros at those high bits.
- if (immediate.is_uint8() && reg < 4) {
- // Use zero-extended 8-bit immediate.
- if (reg == RegX8632::Encoded_Reg_eax) {
- EmitUint8(0xA8);
- } else {
- EmitUint8(0xF6);
- EmitUint8(0xC0 + reg);
- }
- EmitUint8(immediate.value() & 0xFF);
- } else if (reg == RegX8632::Encoded_Reg_eax) {
- // Use short form if the destination is EAX.
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- EmitUint8(0xA9);
- EmitImmediate(Ty, immediate);
- } else {
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- EmitUint8(0xF7);
- EmitRegisterOperand(0, reg);
- EmitImmediate(Ty, immediate);
- }
-}
-
-void AssemblerX8632::test(Type Ty, const Address &addr,
- const Immediate &immediate) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- // If the immediate is short, we only test the byte addr to keep the
- // encoding short.
- if (immediate.is_uint8()) {
- // Use zero-extended 8-bit immediate.
- EmitUint8(0xF6);
- EmitOperand(0, addr);
- EmitUint8(immediate.value() & 0xFF);
- } else {
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- EmitUint8(0xF7);
- EmitOperand(0, addr);
- EmitImmediate(Ty, immediate);
- }
-}
-
-void AssemblerX8632::And(Type Ty, GPRRegister dst, GPRRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- if (isByteSizedType(Ty))
- EmitUint8(0x22);
- else
- EmitUint8(0x23);
- EmitRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::And(Type Ty, GPRRegister dst, const Address &address) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- if (isByteSizedType(Ty))
- EmitUint8(0x22);
- else
- EmitUint8(0x23);
- EmitOperand(dst, address);
-}
-
-void AssemblerX8632::And(Type Ty, GPRRegister dst, const Immediate &imm) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (isByteSizedType(Ty)) {
- EmitComplexI8(4, Operand(dst), imm);
- return;
- }
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- EmitComplex(Ty, 4, Operand(dst), imm);
-}
-
-void AssemblerX8632::Or(Type Ty, GPRRegister dst, GPRRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- if (isByteSizedType(Ty))
- EmitUint8(0x0A);
- else
- EmitUint8(0x0B);
- EmitRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::Or(Type Ty, GPRRegister dst, const Address &address) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- if (isByteSizedType(Ty))
- EmitUint8(0x0A);
- else
- EmitUint8(0x0B);
- EmitOperand(dst, address);
-}
-
-void AssemblerX8632::Or(Type Ty, GPRRegister dst, const Immediate &imm) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (isByteSizedType(Ty)) {
- EmitComplexI8(1, Operand(dst), imm);
- return;
- }
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- EmitComplex(Ty, 1, Operand(dst), imm);
-}
-
-void AssemblerX8632::Xor(Type Ty, GPRRegister dst, GPRRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- if (isByteSizedType(Ty))
- EmitUint8(0x32);
- else
- EmitUint8(0x33);
- EmitRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::Xor(Type Ty, GPRRegister dst, const Address &address) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- if (isByteSizedType(Ty))
- EmitUint8(0x32);
- else
- EmitUint8(0x33);
- EmitOperand(dst, address);
-}
-
-void AssemblerX8632::Xor(Type Ty, GPRRegister dst, const Immediate &imm) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (isByteSizedType(Ty)) {
- EmitComplexI8(6, Operand(dst), imm);
- return;
- }
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- EmitComplex(Ty, 6, Operand(dst), imm);
-}
-
-void AssemblerX8632::add(Type Ty, GPRRegister dst, GPRRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- if (isByteSizedArithType(Ty))
- EmitUint8(0x02);
- else
- EmitUint8(0x03);
- EmitRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::add(Type Ty, GPRRegister reg, const Address &address) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- if (isByteSizedArithType(Ty))
- EmitUint8(0x02);
- else
- EmitUint8(0x03);
- EmitOperand(reg, address);
-}
-
-void AssemblerX8632::add(Type Ty, GPRRegister reg, const Immediate &imm) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (isByteSizedArithType(Ty)) {
- EmitComplexI8(0, Operand(reg), imm);
- return;
- }
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- EmitComplex(Ty, 0, Operand(reg), imm);
-}
-
-void AssemblerX8632::adc(Type Ty, GPRRegister dst, GPRRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- if (isByteSizedArithType(Ty))
- EmitUint8(0x12);
- else
- EmitUint8(0x13);
- EmitRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::adc(Type Ty, GPRRegister dst, const Address &address) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- if (isByteSizedArithType(Ty))
- EmitUint8(0x12);
- else
- EmitUint8(0x13);
- EmitOperand(dst, address);
-}
-
-void AssemblerX8632::adc(Type Ty, GPRRegister reg, const Immediate &imm) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (isByteSizedArithType(Ty)) {
- EmitComplexI8(2, Operand(reg), imm);
- return;
- }
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- EmitComplex(Ty, 2, Operand(reg), imm);
-}
-
-void AssemblerX8632::sub(Type Ty, GPRRegister dst, GPRRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- if (isByteSizedArithType(Ty))
- EmitUint8(0x2A);
- else
- EmitUint8(0x2B);
- EmitRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::sub(Type Ty, GPRRegister reg, const Address &address) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- if (isByteSizedArithType(Ty))
- EmitUint8(0x2A);
- else
- EmitUint8(0x2B);
- EmitOperand(reg, address);
-}
-
-void AssemblerX8632::sub(Type Ty, GPRRegister reg, const Immediate &imm) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (isByteSizedArithType(Ty)) {
- EmitComplexI8(5, Operand(reg), imm);
- return;
- }
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- EmitComplex(Ty, 5, Operand(reg), imm);
-}
-
-void AssemblerX8632::sbb(Type Ty, GPRRegister dst, GPRRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- if (isByteSizedArithType(Ty))
- EmitUint8(0x1A);
- else
- EmitUint8(0x1B);
- EmitRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::sbb(Type Ty, GPRRegister dst, const Address &address) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- if (isByteSizedArithType(Ty))
- EmitUint8(0x1A);
- else
- EmitUint8(0x1B);
- EmitOperand(dst, address);
-}
-
-void AssemblerX8632::sbb(Type Ty, GPRRegister reg, const Immediate &imm) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (isByteSizedArithType(Ty)) {
- EmitComplexI8(3, Operand(reg), imm);
- return;
- }
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- EmitComplex(Ty, 3, Operand(reg), imm);
-}
-
-void AssemblerX8632::cbw() {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitOperandSizeOverride();
- EmitUint8(0x98);
-}
-
-void AssemblerX8632::cwd() {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitOperandSizeOverride();
- EmitUint8(0x99);
-}
-
-void AssemblerX8632::cdq() {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x99);
-}
-
-void AssemblerX8632::div(Type Ty, GPRRegister reg) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- if (isByteSizedArithType(Ty))
- EmitUint8(0xF6);
- else
- EmitUint8(0xF7);
- EmitRegisterOperand(6, reg);
-}
-
-void AssemblerX8632::div(Type Ty, const Address &addr) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- if (isByteSizedArithType(Ty))
- EmitUint8(0xF6);
- else
- EmitUint8(0xF7);
- EmitOperand(6, addr);
-}
-
-void AssemblerX8632::idiv(Type Ty, GPRRegister reg) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- if (isByteSizedArithType(Ty))
- EmitUint8(0xF6);
- else
- EmitUint8(0xF7);
- EmitRegisterOperand(7, reg);
-}
-
-void AssemblerX8632::idiv(Type Ty, const Address &addr) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- if (isByteSizedArithType(Ty))
- EmitUint8(0xF6);
- else
- EmitUint8(0xF7);
- EmitOperand(7, addr);
-}
-
-void AssemblerX8632::imul(Type Ty, GPRRegister dst, GPRRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- assert(Ty == IceType_i16 || Ty == IceType_i32);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- EmitUint8(0x0F);
- EmitUint8(0xAF);
- EmitRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::imul(Type Ty, GPRRegister reg, const Address &address) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- assert(Ty == IceType_i16 || Ty == IceType_i32);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- EmitUint8(0x0F);
- EmitUint8(0xAF);
- EmitOperand(reg, address);
-}
-
-void AssemblerX8632::imul(Type Ty, GPRRegister reg, const Immediate &imm) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- assert(Ty == IceType_i16 || Ty == IceType_i32);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- if (imm.is_int8()) {
- EmitUint8(0x6B);
- EmitRegisterOperand(reg, reg);
- EmitUint8(imm.value() & 0xFF);
- } else {
- EmitUint8(0x69);
- EmitRegisterOperand(reg, reg);
- EmitImmediate(Ty, imm);
- }
-}
-
-void AssemblerX8632::imul(Type Ty, GPRRegister reg) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- if (isByteSizedArithType(Ty))
- EmitUint8(0xF6);
- else
- EmitUint8(0xF7);
- EmitRegisterOperand(5, reg);
-}
-
-void AssemblerX8632::imul(Type Ty, const Address &address) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- if (isByteSizedArithType(Ty))
- EmitUint8(0xF6);
- else
- EmitUint8(0xF7);
- EmitOperand(5, address);
-}
-
-void AssemblerX8632::mul(Type Ty, GPRRegister reg) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- if (isByteSizedArithType(Ty))
- EmitUint8(0xF6);
- else
- EmitUint8(0xF7);
- EmitRegisterOperand(4, reg);
-}
-
-void AssemblerX8632::mul(Type Ty, const Address &address) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- if (isByteSizedArithType(Ty))
- EmitUint8(0xF6);
- else
- EmitUint8(0xF7);
- EmitOperand(4, address);
-}
-
-void AssemblerX8632::incl(GPRRegister reg) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x40 + reg);
-}
-
-void AssemblerX8632::incl(const Address &address) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0xFF);
- EmitOperand(0, address);
-}
-
-void AssemblerX8632::decl(GPRRegister reg) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x48 + reg);
-}
-
-void AssemblerX8632::decl(const Address &address) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0xFF);
- EmitOperand(1, address);
-}
-
-void AssemblerX8632::rol(Type Ty, GPRRegister reg, const Immediate &imm) {
- EmitGenericShift(0, Ty, reg, imm);
-}
-
-void AssemblerX8632::rol(Type Ty, GPRRegister operand, GPRRegister shifter) {
- EmitGenericShift(0, Ty, Operand(operand), shifter);
-}
-
-void AssemblerX8632::rol(Type Ty, const Address &operand, GPRRegister shifter) {
- EmitGenericShift(0, Ty, operand, shifter);
-}
-
-void AssemblerX8632::shl(Type Ty, GPRRegister reg, const Immediate &imm) {
- EmitGenericShift(4, Ty, reg, imm);
-}
-
-void AssemblerX8632::shl(Type Ty, GPRRegister operand, GPRRegister shifter) {
- EmitGenericShift(4, Ty, Operand(operand), shifter);
-}
-
-void AssemblerX8632::shl(Type Ty, const Address &operand, GPRRegister shifter) {
- EmitGenericShift(4, Ty, operand, shifter);
-}
-
-void AssemblerX8632::shr(Type Ty, GPRRegister reg, const Immediate &imm) {
- EmitGenericShift(5, Ty, reg, imm);
-}
-
-void AssemblerX8632::shr(Type Ty, GPRRegister operand, GPRRegister shifter) {
- EmitGenericShift(5, Ty, Operand(operand), shifter);
-}
-
-void AssemblerX8632::shr(Type Ty, const Address &operand, GPRRegister shifter) {
- EmitGenericShift(5, Ty, operand, shifter);
-}
-
-void AssemblerX8632::sar(Type Ty, GPRRegister reg, const Immediate &imm) {
- EmitGenericShift(7, Ty, reg, imm);
-}
-
-void AssemblerX8632::sar(Type Ty, GPRRegister operand, GPRRegister shifter) {
- EmitGenericShift(7, Ty, Operand(operand), shifter);
-}
-
-void AssemblerX8632::sar(Type Ty, const Address &address, GPRRegister shifter) {
- EmitGenericShift(7, Ty, address, shifter);
-}
-
-void AssemblerX8632::shld(Type Ty, GPRRegister dst, GPRRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- assert(Ty == IceType_i16 || Ty == IceType_i32);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- EmitUint8(0x0F);
- EmitUint8(0xA5);
- EmitRegisterOperand(src, dst);
-}
-
-void AssemblerX8632::shld(Type Ty, GPRRegister dst, GPRRegister src,
- const Immediate &imm) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- assert(Ty == IceType_i16 || Ty == IceType_i32);
- assert(imm.is_int8());
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- EmitUint8(0x0F);
- EmitUint8(0xA4);
- EmitRegisterOperand(src, dst);
- EmitUint8(imm.value() & 0xFF);
-}
-
-void AssemblerX8632::shld(Type Ty, const Address &operand, GPRRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- assert(Ty == IceType_i16 || Ty == IceType_i32);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- EmitUint8(0x0F);
- EmitUint8(0xA5);
- EmitOperand(src, operand);
-}
-
-void AssemblerX8632::shrd(Type Ty, GPRRegister dst, GPRRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- assert(Ty == IceType_i16 || Ty == IceType_i32);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- EmitUint8(0x0F);
- EmitUint8(0xAD);
- EmitRegisterOperand(src, dst);
-}
-
-void AssemblerX8632::shrd(Type Ty, GPRRegister dst, GPRRegister src,
- const Immediate &imm) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- assert(Ty == IceType_i16 || Ty == IceType_i32);
- assert(imm.is_int8());
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- EmitUint8(0x0F);
- EmitUint8(0xAC);
- EmitRegisterOperand(src, dst);
- EmitUint8(imm.value() & 0xFF);
-}
-
-void AssemblerX8632::shrd(Type Ty, const Address &dst, GPRRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- assert(Ty == IceType_i16 || Ty == IceType_i32);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- EmitUint8(0x0F);
- EmitUint8(0xAD);
- EmitOperand(src, dst);
-}
-
-void AssemblerX8632::neg(Type Ty, GPRRegister reg) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- if (isByteSizedArithType(Ty))
- EmitUint8(0xF6);
- else
- EmitUint8(0xF7);
- EmitRegisterOperand(3, reg);
-}
-
-void AssemblerX8632::neg(Type Ty, const Address &addr) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- if (isByteSizedArithType(Ty))
- EmitUint8(0xF6);
- else
- EmitUint8(0xF7);
- EmitOperand(3, addr);
-}
-
-void AssemblerX8632::notl(GPRRegister reg) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0xF7);
- EmitUint8(0xD0 | reg);
-}
-
-void AssemblerX8632::bswap(Type Ty, GPRRegister reg) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- assert(Ty == IceType_i32);
- (void)Ty;
- EmitUint8(0x0F);
- EmitUint8(0xC8 | reg);
-}
-
-void AssemblerX8632::bsf(Type Ty, GPRRegister dst, GPRRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- assert(Ty == IceType_i16 || Ty == IceType_i32);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- EmitUint8(0x0F);
- EmitUint8(0xBC);
- EmitRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::bsf(Type Ty, GPRRegister dst, const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- assert(Ty == IceType_i16 || Ty == IceType_i32);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- EmitUint8(0x0F);
- EmitUint8(0xBC);
- EmitOperand(dst, src);
-}
-
-void AssemblerX8632::bsr(Type Ty, GPRRegister dst, GPRRegister src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- assert(Ty == IceType_i16 || Ty == IceType_i32);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- EmitUint8(0x0F);
- EmitUint8(0xBD);
- EmitRegisterOperand(dst, src);
-}
-
-void AssemblerX8632::bsr(Type Ty, GPRRegister dst, const Address &src) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- assert(Ty == IceType_i16 || Ty == IceType_i32);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- EmitUint8(0x0F);
- EmitUint8(0xBD);
- EmitOperand(dst, src);
-}
-
-void AssemblerX8632::bt(GPRRegister base, GPRRegister offset) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x0F);
- EmitUint8(0xA3);
- EmitRegisterOperand(offset, base);
-}
-
-void AssemblerX8632::ret() {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0xC3);
-}
-
-void AssemblerX8632::ret(const Immediate &imm) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0xC2);
- assert(imm.is_uint16());
- EmitUint8(imm.value() & 0xFF);
- EmitUint8((imm.value() >> 8) & 0xFF);
-}
-
-void AssemblerX8632::nop(int size) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- // There are nops up to size 15, but for now just provide up to size 8.
- assert(0 < size && size <= MAX_NOP_SIZE);
- switch (size) {
- case 1:
- EmitUint8(0x90);
- break;
- case 2:
- EmitUint8(0x66);
- EmitUint8(0x90);
- break;
- case 3:
- EmitUint8(0x0F);
- EmitUint8(0x1F);
- EmitUint8(0x00);
- break;
- case 4:
- EmitUint8(0x0F);
- EmitUint8(0x1F);
- EmitUint8(0x40);
- EmitUint8(0x00);
- break;
- case 5:
- EmitUint8(0x0F);
- EmitUint8(0x1F);
- EmitUint8(0x44);
- EmitUint8(0x00);
- EmitUint8(0x00);
- break;
- case 6:
- EmitUint8(0x66);
- EmitUint8(0x0F);
- EmitUint8(0x1F);
- EmitUint8(0x44);
- EmitUint8(0x00);
- EmitUint8(0x00);
- break;
- case 7:
- EmitUint8(0x0F);
- EmitUint8(0x1F);
- EmitUint8(0x80);
- EmitUint8(0x00);
- EmitUint8(0x00);
- EmitUint8(0x00);
- EmitUint8(0x00);
- break;
- case 8:
- EmitUint8(0x0F);
- EmitUint8(0x1F);
- EmitUint8(0x84);
- EmitUint8(0x00);
- EmitUint8(0x00);
- EmitUint8(0x00);
- EmitUint8(0x00);
- EmitUint8(0x00);
- break;
- default:
- llvm_unreachable("Unimplemented");
- }
-}
-
-void AssemblerX8632::int3() {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0xCC);
-}
-
-void AssemblerX8632::hlt() {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0xF4);
-}
-
-void AssemblerX8632::ud2() {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x0F);
- EmitUint8(0x0B);
-}
-
-void AssemblerX8632::j(CondX86::BrCond condition, Label *label, bool near) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (label->IsBound()) {
- static const int kShortSize = 2;
- static const int kLongSize = 6;
- intptr_t offset = label->Position() - buffer_.Size();
- assert(offset <= 0);
- if (Utils::IsInt(8, offset - kShortSize)) {
- // TODO(stichnot): Here and in jmp(), we may need to be more
- // conservative about the backward branch distance if the branch
- // instruction is within a bundle_lock sequence, because the
- // distance may increase when padding is added. This isn't an
- // issue for branches outside a bundle_lock, because if padding
- // is added, the retry may change it to a long backward branch
- // without affecting any of the bookkeeping.
- EmitUint8(0x70 + condition);
- EmitUint8((offset - kShortSize) & 0xFF);
- } else {
- EmitUint8(0x0F);
- EmitUint8(0x80 + condition);
- EmitInt32(offset - kLongSize);
- }
- } else if (near) {
- EmitUint8(0x70 + condition);
- EmitNearLabelLink(label);
- } else {
- EmitUint8(0x0F);
- EmitUint8(0x80 + condition);
- EmitLabelLink(label);
- }
-}
-
-void AssemblerX8632::j(CondX86::BrCond condition,
- const ConstantRelocatable *label) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x0F);
- EmitUint8(0x80 + condition);
- EmitFixup(this->createFixup(llvm::ELF::R_386_PC32, label));
- EmitInt32(-4);
-}
-
-void AssemblerX8632::jmp(GPRRegister reg) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0xFF);
- EmitRegisterOperand(4, reg);
-}
-
-void AssemblerX8632::jmp(Label *label, bool near) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (label->IsBound()) {
- static const int kShortSize = 2;
- static const int kLongSize = 5;
- intptr_t offset = label->Position() - buffer_.Size();
- assert(offset <= 0);
- if (Utils::IsInt(8, offset - kShortSize)) {
- EmitUint8(0xEB);
- EmitUint8((offset - kShortSize) & 0xFF);
- } else {
- EmitUint8(0xE9);
- EmitInt32(offset - kLongSize);
- }
- } else if (near) {
- EmitUint8(0xEB);
- EmitNearLabelLink(label);
- } else {
- EmitUint8(0xE9);
- EmitLabelLink(label);
- }
-}
-
-void AssemblerX8632::jmp(const ConstantRelocatable *label) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0xE9);
- EmitFixup(this->createFixup(llvm::ELF::R_386_PC32, label));
- EmitInt32(-4);
-}
-
-void AssemblerX8632::mfence() {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0x0F);
- EmitUint8(0xAE);
- EmitUint8(0xF0);
-}
-
-void AssemblerX8632::lock() {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(0xF0);
-}
-
-void AssemblerX8632::cmpxchg(Type Ty, const Address &address, GPRRegister reg,
- bool Locked) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- if (Locked)
- EmitUint8(0xF0);
- EmitUint8(0x0F);
- if (isByteSizedArithType(Ty))
- EmitUint8(0xB0);
- else
- EmitUint8(0xB1);
- EmitOperand(reg, address);
-}
-
-void AssemblerX8632::cmpxchg8b(const Address &address, bool Locked) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (Locked)
- EmitUint8(0xF0);
- EmitUint8(0x0F);
- EmitUint8(0xC7);
- EmitOperand(1, address);
-}
-
-void AssemblerX8632::xadd(Type Ty, const Address &addr, GPRRegister reg,
- bool Locked) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- if (Locked)
- EmitUint8(0xF0);
- EmitUint8(0x0F);
- if (isByteSizedArithType(Ty))
- EmitUint8(0xC0);
- else
- EmitUint8(0xC1);
- EmitOperand(reg, addr);
-}
-
-void AssemblerX8632::xchg(Type Ty, const Address &addr, GPRRegister reg) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- if (isByteSizedArithType(Ty))
- EmitUint8(0x86);
- else
- EmitUint8(0x87);
- EmitOperand(reg, addr);
-}
-
-void AssemblerX8632::EmitSegmentOverride(uint8_t prefix) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- EmitUint8(prefix);
-}
-
-void AssemblerX8632::Align(intptr_t alignment, intptr_t offset) {
- assert(llvm::isPowerOf2_32(alignment));
- intptr_t pos = offset + buffer_.GetPosition();
- intptr_t mod = pos & (alignment - 1);
- if (mod == 0) {
- return;
- }
- intptr_t bytes_needed = alignment - mod;
- while (bytes_needed > MAX_NOP_SIZE) {
- nop(MAX_NOP_SIZE);
- bytes_needed -= MAX_NOP_SIZE;
- }
- if (bytes_needed) {
- nop(bytes_needed);
- }
- assert(((offset + buffer_.GetPosition()) & (alignment - 1)) == 0);
-}
-
-void AssemblerX8632::Bind(Label *label) {
- intptr_t bound = buffer_.Size();
- assert(!label->IsBound()); // Labels can only be bound once.
- while (label->IsLinked()) {
- intptr_t position = label->LinkPosition();
- intptr_t next = buffer_.Load<int32_t>(position);
- buffer_.Store<int32_t>(position, bound - (position + 4));
- label->position_ = next;
- }
- while (label->HasNear()) {
- intptr_t position = label->NearPosition();
- intptr_t offset = bound - (position + 1);
- assert(Utils::IsInt(8, offset));
- buffer_.Store<int8_t>(position, offset);
- }
- label->BindTo(bound);
-}
-
-void AssemblerX8632::EmitOperand(int rm, const Operand &operand) {
- assert(rm >= 0 && rm < 8);
- const intptr_t length = operand.length_;
- assert(length > 0);
- // Emit the ModRM byte updated with the given RM value.
- assert((operand.encoding_[0] & 0x38) == 0);
- EmitUint8(operand.encoding_[0] + (rm << 3));
- if (operand.fixup()) {
- EmitFixup(operand.fixup());
- }
- // Emit the rest of the encoded operand.
- for (intptr_t i = 1; i < length; i++) {
- EmitUint8(operand.encoding_[i]);
- }
-}
-
-void AssemblerX8632::EmitImmediate(Type Ty, const Immediate &imm) {
- if (Ty == IceType_i16) {
- assert(!imm.fixup());
- EmitInt16(imm.value());
- } else {
- if (imm.fixup()) {
- EmitFixup(imm.fixup());
- }
- EmitInt32(imm.value());
- }
-}
-
-void AssemblerX8632::EmitComplexI8(int rm, const Operand &operand,
- const Immediate &immediate) {
- assert(rm >= 0 && rm < 8);
- assert(immediate.is_int8());
- if (operand.IsRegister(RegX8632::Encoded_Reg_eax)) {
- // Use short form if the destination is al.
- EmitUint8(0x04 + (rm << 3));
- EmitUint8(immediate.value() & 0xFF);
- } else {
- // Use sign-extended 8-bit immediate.
- EmitUint8(0x80);
- EmitOperand(rm, operand);
- EmitUint8(immediate.value() & 0xFF);
- }
-}
-
-void AssemblerX8632::EmitComplex(Type Ty, int rm, const Operand &operand,
- const Immediate &immediate) {
- assert(rm >= 0 && rm < 8);
- if (immediate.is_int8()) {
- // Use sign-extended 8-bit immediate.
- EmitUint8(0x83);
- EmitOperand(rm, operand);
- EmitUint8(immediate.value() & 0xFF);
- } else if (operand.IsRegister(RegX8632::Encoded_Reg_eax)) {
- // Use short form if the destination is eax.
- EmitUint8(0x05 + (rm << 3));
- EmitImmediate(Ty, immediate);
- } else {
- EmitUint8(0x81);
- EmitOperand(rm, operand);
- EmitImmediate(Ty, immediate);
- }
-}
-
-void AssemblerX8632::EmitLabel(Label *label, intptr_t instruction_size) {
- if (label->IsBound()) {
- intptr_t offset = label->Position() - buffer_.Size();
- assert(offset <= 0);
- EmitInt32(offset - instruction_size);
- } else {
- EmitLabelLink(label);
- }
-}
-
-void AssemblerX8632::EmitLabelLink(Label *label) {
- assert(!label->IsBound());
- intptr_t position = buffer_.Size();
- EmitInt32(label->position_);
- if (!getPreliminary())
- label->LinkTo(position);
-}
-
-void AssemblerX8632::EmitNearLabelLink(Label *label) {
- assert(!label->IsBound());
- intptr_t position = buffer_.Size();
- EmitUint8(0);
- if (!getPreliminary())
- label->NearLinkTo(position);
-}
-
-void AssemblerX8632::EmitGenericShift(int rm, Type Ty, GPRRegister reg,
- const Immediate &imm) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- assert(imm.is_int8());
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- if (imm.value() == 1) {
- EmitUint8(isByteSizedArithType(Ty) ? 0xD0 : 0xD1);
- EmitOperand(rm, Operand(reg));
- } else {
- EmitUint8(isByteSizedArithType(Ty) ? 0xC0 : 0xC1);
- EmitOperand(rm, Operand(reg));
- EmitUint8(imm.value() & 0xFF);
- }
-}
-
-void AssemblerX8632::EmitGenericShift(int rm, Type Ty, const Operand &operand,
- GPRRegister shifter) {
- AssemblerBuffer::EnsureCapacity ensured(&buffer_);
- assert(shifter == RegX8632::Encoded_Reg_ecx);
- (void)shifter;
- if (Ty == IceType_i16)
- EmitOperandSizeOverride();
- EmitUint8(isByteSizedArithType(Ty) ? 0xD2 : 0xD3);
- EmitOperand(rm, operand);
-}
-
-} // end of namespace X8632
-} // end of namespace Ice