Move Subzero Assembler traits to the Assembler header/source
Bug: b/192890685
Change-Id: Id4314d3d5494c7cc10df004d8511ac04d4f525ec
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/55848
Presubmit-Ready: Nicolas Capens <nicolascapens@google.com>
Kokoro-Result: kokoro <noreply+kokoro@google.com>
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Sean Risser <srisser@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/third_party/subzero/src/IceAssemblerX8632.cpp b/third_party/subzero/src/IceAssemblerX8632.cpp
index dbe6da2..83479cd 100644
--- a/third_party/subzero/src/IceAssemblerX8632.cpp
+++ b/third_party/subzero/src/IceAssemblerX8632.cpp
@@ -51,7 +51,7 @@
}
}
- GPRRegister Base = Traits::getEncodedGPR(BaseRegNum);
+ GPRRegister Base = Traits::Traits::getEncodedGPR(BaseRegNum);
if (Utils::IsInt(8, Offset)) {
SetModRM(1, Base);
@@ -86,7 +86,7 @@
} else if (const auto CR =
llvm::dyn_cast<ConstantRelocatable>(Mem->getOffset())) {
Disp += CR->getOffset();
- Fixup = Asm->createFixup(Traits::FK_Abs, CR);
+ Fixup = Asm->createFixup(FK_Abs, CR);
} else {
llvm_unreachable("Unexpected offset type");
}
@@ -94,14 +94,14 @@
// Now convert to the various possible forms.
if (Mem->getBase() && Mem->getIndex()) {
- SetBaseIndex(getEncodedGPR(Mem->getBase()->getRegNum()),
- getEncodedGPR(Mem->getIndex()->getRegNum()),
- X8632::Traits::ScaleFactor(Mem->getShift()), Disp, Fixup);
+ SetBaseIndex(Traits::getEncodedGPR(Mem->getBase()->getRegNum()),
+ Traits::getEncodedGPR(Mem->getIndex()->getRegNum()),
+ ScaleFactor(Mem->getShift()), Disp, Fixup);
} else if (Mem->getBase()) {
- SetBase(getEncodedGPR(Mem->getBase()->getRegNum()), Disp, Fixup);
+ SetBase(Traits::getEncodedGPR(Mem->getBase()->getRegNum()), Disp, Fixup);
} else if (Mem->getIndex()) {
- SetIndex(getEncodedGPR(Mem->getIndex()->getRegNum()),
- X8632::Traits::ScaleFactor(Mem->getShift()), Disp, Fixup);
+ SetIndex(Traits::getEncodedGPR(Mem->getIndex()->getRegNum()),
+ ScaleFactor(Mem->getShift()), Disp, Fixup);
} else {
SetAbsolute(Disp, Fixup);
}
@@ -111,7 +111,7 @@
assert(!Split->getVar()->hasReg());
const ::Ice::TargetLowering *Target = Func->getTarget();
int32_t Offset = Split->getVar()->getStackOffset() + Split->getOffset();
- SetBase(getEncodedGPR(Target->getFrameOrStackReg()), Offset,
+ SetBase(Traits::getEncodedGPR(Target->getFrameOrStackReg()), Offset,
AssemblerFixup::NoFixup);
}
@@ -198,7 +198,7 @@
AssemblerBuffer::EnsureCapacity ensured(&Buffer);
intptr_t call_start = Buffer.getPosition();
emitUint8(0xE8);
- auto *Fixup = this->createFixup(Traits::FK_PcRel, label);
+ auto *Fixup = this->createFixup(FK_PcRel, label);
Fixup->set_addend(-4);
emitFixup(Fixup);
emitInt32(0);
@@ -210,7 +210,7 @@
AssemblerBuffer::EnsureCapacity ensured(&Buffer);
intptr_t call_start = Buffer.getPosition();
emitUint8(0xE8);
- auto *Fixup = this->createFixup(Traits::FK_PcRel, AssemblerFixup::NullSymbol);
+ auto *Fixup = this->createFixup(FK_PcRel, AssemblerFixup::NullSymbol);
Fixup->set_addend(abs_address.value() - 4);
emitFixup(Fixup);
emitInt32(0);
@@ -232,7 +232,7 @@
void AssemblerX8632::pushl(const ConstantRelocatable *Label) {
AssemblerBuffer::EnsureCapacity ensured(&Buffer);
emitUint8(0x68);
- emitFixup(this->createFixup(Traits::FK_Abs, Label));
+ emitFixup(this->createFixup(FK_Abs, Label));
// In x86-32, the emitted value is an addend to the relocation. Therefore, we
// must emit a 0 (because we're pushing an absolute relocation.)
// In x86-64, the emitted value does not matter (the addend lives in the
@@ -2153,16 +2153,17 @@
// 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 <= Traits::Last8BitGPR) {
+ constexpr GPRRegister Last8BitGPR = GPRRegister::Encoded_Reg_ebx;
+ if (immediate.is_uint8() && reg <= Last8BitGPR) {
// Use zero-extended 8-bit immediate.
- if (reg == Traits::Encoded_Reg_Accumulator) {
+ if (reg == RegX8632::Encoded_Reg_eax) {
emitUint8(0xA8);
} else {
emitUint8(0xF6);
emitUint8(0xC0 + gprEncoding(reg));
}
emitUint8(immediate.value() & 0xFF);
- } else if (reg == Traits::Encoded_Reg_Accumulator) {
+ } else if (reg == RegX8632::Encoded_Reg_eax) {
// Use short form if the destination is EAX.
if (Ty == IceType_i16)
emitOperandSizeOverride();
@@ -2865,7 +2866,7 @@
AssemblerBuffer::EnsureCapacity ensured(&Buffer);
emitUint8(0x0F);
emitUint8(0x80 + condition);
- auto *Fixup = this->createFixup(Traits::FK_PcRel, label);
+ auto *Fixup = this->createFixup(FK_PcRel, label);
Fixup->set_addend(-4);
emitFixup(Fixup);
emitInt32(0);
@@ -2903,7 +2904,7 @@
void AssemblerX8632::jmp(const ConstantRelocatable *label) {
AssemblerBuffer::EnsureCapacity ensured(&Buffer);
emitUint8(0xE9);
- auto *Fixup = this->createFixup(Traits::FK_PcRel, label);
+ auto *Fixup = this->createFixup(FK_PcRel, label);
Fixup->set_addend(-4);
emitFixup(Fixup);
emitInt32(0);
@@ -2913,7 +2914,7 @@
AssemblerBuffer::EnsureCapacity ensured(&Buffer);
emitUint8(0xE9);
AssemblerFixup *Fixup =
- createFixup(Traits::FK_PcRel, AssemblerFixup::NullSymbol);
+ createFixup(FK_PcRel, AssemblerFixup::NullSymbol);
Fixup->set_addend(abs_address.value() - 4);
emitFixup(Fixup);
emitInt32(0);
@@ -2975,9 +2976,9 @@
if (Ty == IceType_i16)
emitOperandSizeOverride();
// Use short form if either register is EAX.
- if (reg0 == Traits::Encoded_Reg_Accumulator) {
+ if (reg0 == RegX8632::Encoded_Reg_eax) {
emitUint8(0x90 + gprEncoding(reg1));
- } else if (reg1 == Traits::Encoded_Reg_Accumulator) {
+ } else if (reg1 == RegX8632::Encoded_Reg_eax) {
emitUint8(0x90 + gprEncoding(reg0));
} else {
if (isByteSizedArithType(Ty))
@@ -3134,7 +3135,7 @@
const Immediate &immediate) {
assert(rm >= 0 && rm < 8);
assert(immediate.is_int8());
- if (operand.IsRegister(Traits::Encoded_Reg_Accumulator)) {
+ if (operand.IsRegister(RegX8632::Encoded_Reg_eax)) {
// Use short form if the destination is al.
emitUint8(0x04 + (rm << 3));
emitUint8(immediate.value() & 0xFF);
@@ -3156,7 +3157,7 @@
static constexpr RelocOffsetT OffsetFromNextInstruction = 1;
emitOperand(rm, operand, OffsetFromNextInstruction);
emitUint8(immediate.value() & 0xFF);
- } else if (operand.IsRegister(Traits::Encoded_Reg_Accumulator)) {
+ } else if (operand.IsRegister(RegX8632::Encoded_Reg_eax)) {
// Use short form if the destination is eax.
emitUint8(0x05 + (rm << 3));
emitImmediate(Ty, immediate);
@@ -3216,7 +3217,7 @@
const AsmOperand &operand,
GPRRegister shifter) {
AssemblerBuffer::EnsureCapacity ensured(&Buffer);
- assert(shifter == Traits::Encoded_Reg_Counter);
+ assert(shifter == RegX8632::Encoded_Reg_ecx);
(void)shifter;
if (Ty == IceType_i16)
emitOperandSizeOverride();
diff --git a/third_party/subzero/src/IceAssemblerX8632.h b/third_party/subzero/src/IceAssemblerX8632.h
index d4c1716..b845b0b 100644
--- a/third_party/subzero/src/IceAssemblerX8632.h
+++ b/third_party/subzero/src/IceAssemblerX8632.h
@@ -35,13 +35,200 @@
namespace X8632 {
using Traits = TargetX8632Traits;
-using AsmAddress = typename Traits::AsmAddress;
using ByteRegister = typename Traits::ByteRegister;
using BrCond = CondX86::BrCond;
using CmppsCond = CondX86::CmppsCond;
using GPRRegister = typename Traits::GPRRegister;
-using AsmOperand = typename Traits::AsmOperand;
using XmmRegister = typename Traits::XmmRegister;
+using X86OperandMem = typename Traits::X86OperandMem;
+using VariableSplit = typename Traits::VariableSplit;
+
+constexpr FixupKind FK_PcRel = llvm::ELF::R_386_PC32;
+constexpr FixupKind FK_Abs = llvm::ELF::R_386_32;
+constexpr FixupKind FK_Gotoff = llvm::ELF::R_386_GOTOFF;
+constexpr FixupKind FK_GotPC = llvm::ELF::R_386_GOTPC;
+
+enum ScaleFactor { TIMES_1 = 0, TIMES_2 = 1, TIMES_4 = 2, TIMES_8 = 3 };
+
+class AsmOperand {
+public:
+ AsmOperand(const AsmOperand &other)
+ : fixup_(other.fixup_), length_(other.length_) {
+ memmove(&encoding_[0], &other.encoding_[0], other.length_);
+ }
+
+ AsmOperand &operator=(const AsmOperand &other) {
+ length_ = other.length_;
+ fixup_ = other.fixup_;
+ memmove(&encoding_[0], &other.encoding_[0], other.length_);
+ return *this;
+ }
+
+ uint8_t mod() const { return (encoding_at(0) >> 6) & 3; }
+
+ GPRRegister rm() const {
+ return static_cast<GPRRegister>(encoding_at(0) & 7);
+ }
+
+ ScaleFactor scale() const {
+ return static_cast<ScaleFactor>((encoding_at(1) >> 6) & 3);
+ }
+
+ GPRRegister index() const {
+ return static_cast<GPRRegister>((encoding_at(1) >> 3) & 7);
+ }
+
+ GPRRegister base() const {
+ return static_cast<GPRRegister>(encoding_at(1) & 7);
+ }
+
+ int8_t disp8() const {
+ assert(length_ >= 2);
+ return static_cast<int8_t>(encoding_[length_ - 1]);
+ }
+
+ AssemblerFixup *fixup() const { return fixup_; }
+
+protected:
+ AsmOperand()
+ : fixup_(nullptr), length_(0) {} // Needed by subclass AsmAddress.
+
+ void SetModRM(int mod, GPRRegister rm) {
+ assert((mod & ~3) == 0);
+ encoding_[0] = (mod << 6) | rm;
+ length_ = 1;
+ }
+
+ void SetSIB(ScaleFactor scale, GPRRegister index, GPRRegister base) {
+ assert(length_ == 1);
+ assert((scale & ~3) == 0);
+ encoding_[1] = (scale << 6) | (index << 3) | base;
+ length_ = 2;
+ }
+
+ void SetDisp8(int8_t disp) {
+ assert(length_ == 1 || length_ == 2);
+ encoding_[length_++] = static_cast<uint8_t>(disp);
+ }
+
+ void SetDisp32(int32_t disp) {
+ assert(length_ == 1 || length_ == 2);
+ intptr_t disp_size = sizeof(disp);
+ memmove(&encoding_[length_], &disp, disp_size);
+ length_ += disp_size;
+ }
+
+ void SetFixup(AssemblerFixup *fixup) { fixup_ = fixup; }
+
+private:
+ AssemblerFixup *fixup_;
+ uint8_t encoding_[6];
+ uint8_t length_;
+
+ explicit AsmOperand(GPRRegister reg) : fixup_(nullptr) { SetModRM(3, reg); }
+
+ /// Get the operand encoding byte at the given index.
+ uint8_t encoding_at(intptr_t index) const {
+ assert(index >= 0 && index < length_);
+ return encoding_[index];
+ }
+
+ /// Returns whether or not this operand is really the given register in
+ /// disguise. Used from the assembler to generate better encodings.
+ bool IsRegister(GPRRegister reg) const {
+ return ((encoding_[0] & 0xF8) == 0xC0) // Addressing mode is register only.
+ && ((encoding_[0] & 0x07) == reg); // Register codes match.
+ }
+
+ friend class AssemblerX8632;
+};
+
+class AsmAddress : public AsmOperand {
+ AsmAddress() = delete;
+
+public:
+ AsmAddress(GPRRegister Base, int32_t Disp, AssemblerFixup *Fixup = nullptr) {
+ SetBase(Base, Disp, Fixup);
+ }
+ AsmAddress(const Variable *Var, const TargetX8632 *Target);
+ AsmAddress(const X86OperandMem *Mem, Ice::Assembler *Asm,
+ const Ice::TargetLowering *Target);
+ AsmAddress(const VariableSplit *Split, const Cfg *Func);
+
+ // Address into the constant pool.
+ AsmAddress(const Constant *Imm, Ice::Assembler *Asm) {
+ AssemblerFixup *Fixup = Asm->createFixup(llvm::ELF::R_386_32, Imm);
+ const RelocOffsetT Offset = 0;
+ SetAbsolute(Offset, Fixup);
+ }
+
+private:
+ AsmAddress(const AsmAddress &other) : AsmOperand(other) {}
+
+ AsmAddress &operator=(const AsmAddress &other) {
+ AsmOperand::operator=(other);
+ return *this;
+ }
+
+ void SetBase(GPRRegister Base, int32_t Disp, AssemblerFixup *Fixup) {
+ if (Fixup == nullptr && Disp == 0 && Base != RegX8632::Encoded_Reg_ebp) {
+ SetModRM(0, Base);
+ if (Base == RegX8632::Encoded_Reg_esp)
+ SetSIB(TIMES_1, RegX8632::Encoded_Reg_esp, Base);
+ } else if (Fixup == nullptr && Utils::IsInt(8, Disp)) {
+ SetModRM(1, Base);
+ if (Base == RegX8632::Encoded_Reg_esp)
+ SetSIB(TIMES_1, RegX8632::Encoded_Reg_esp, Base);
+ SetDisp8(Disp);
+ } else {
+ SetModRM(2, Base);
+ if (Base == RegX8632::Encoded_Reg_esp)
+ SetSIB(TIMES_1, RegX8632::Encoded_Reg_esp, Base);
+ SetDisp32(Disp);
+ if (Fixup)
+ SetFixup(Fixup);
+ }
+ }
+
+ void SetIndex(GPRRegister Index, ScaleFactor Scale, int32_t Disp,
+ AssemblerFixup *Fixup) {
+ assert(Index != RegX8632::Encoded_Reg_esp); // Illegal addressing mode.
+ SetModRM(0, RegX8632::Encoded_Reg_esp);
+ SetSIB(Scale, Index, RegX8632::Encoded_Reg_ebp);
+ SetDisp32(Disp);
+ if (Fixup)
+ SetFixup(Fixup);
+ }
+
+ void SetBaseIndex(GPRRegister Base, GPRRegister Index, ScaleFactor Scale,
+ int32_t Disp, AssemblerFixup *Fixup) {
+ assert(Index != RegX8632::Encoded_Reg_esp); // Illegal addressing mode.
+ if (Fixup == nullptr && Disp == 0 && Base != RegX8632::Encoded_Reg_ebp) {
+ SetModRM(0, RegX8632::Encoded_Reg_esp);
+ SetSIB(Scale, Index, Base);
+ } else if (Fixup == nullptr && Utils::IsInt(8, Disp)) {
+ SetModRM(1, RegX8632::Encoded_Reg_esp);
+ SetSIB(Scale, Index, Base);
+ SetDisp8(Disp);
+ } else {
+ SetModRM(2, RegX8632::Encoded_Reg_esp);
+ SetSIB(Scale, Index, Base);
+ SetDisp32(Disp);
+ if (Fixup)
+ SetFixup(Fixup);
+ }
+ }
+
+ /// Generate an absolute address expression on x86-32.
+ void SetAbsolute(RelocOffsetT Offset, AssemblerFixup *Fixup) {
+ SetModRM(0, RegX8632::Encoded_Reg_ebp);
+ // Use the Offset in the displacement for now. If we decide to process
+ // fixups later, we'll need to patch up the emitted displacement.
+ SetDisp32(Offset);
+ if (Fixup)
+ SetFixup(Fixup);
+ }
+};
class AssemblerX8632 : public ::Ice::Assembler {
AssemblerX8632(const AssemblerX8632 &) = delete;
@@ -162,7 +349,7 @@
bool fixupIsPCRel(FixupKind Kind) const override {
// Currently assuming this is the only PC-rel relocation type used.
// TODO(jpp): Traits.PcRelTypes.count(Kind) != 0
- return Kind == Traits::FK_PcRel;
+ return Kind == FK_PcRel;
}
// Operations to emit GPR instructions (and dispatch on operand type).
diff --git a/third_party/subzero/src/IceAssemblerX8664.cpp b/third_party/subzero/src/IceAssemblerX8664.cpp
index 24c4c10..6994a36 100644
--- a/third_party/subzero/src/IceAssemblerX8664.cpp
+++ b/third_party/subzero/src/IceAssemblerX8664.cpp
@@ -50,7 +50,8 @@
BaseRegNum = Target->getFrameOrStackReg();
}
}
- SetBase(Traits::getEncodedGPR(BaseRegNum), Offset, AssemblerFixup::NoFixup);
+ SetBase(Traits::Traits::getEncodedGPR(BaseRegNum), Offset,
+ AssemblerFixup::NoFixup);
}
AsmAddress::AsmAddress(const X86OperandMem *Mem, Ice::Assembler *Asm,
@@ -85,14 +86,14 @@
// Now convert to the various possible forms.
if (Mem->getBase() && Mem->getIndex()) {
- SetBaseIndex(getEncodedGPR(Mem->getBase()->getRegNum()),
- getEncodedGPR(Mem->getIndex()->getRegNum()),
- X8664::Traits::ScaleFactor(Mem->getShift()), Disp, Fixup);
+ SetBaseIndex(Traits::getEncodedGPR(Mem->getBase()->getRegNum()),
+ Traits::getEncodedGPR(Mem->getIndex()->getRegNum()),
+ ScaleFactor(Mem->getShift()), Disp, Fixup);
} else if (Mem->getBase()) {
- SetBase(getEncodedGPR(Mem->getBase()->getRegNum()), Disp, Fixup);
+ SetBase(Traits::getEncodedGPR(Mem->getBase()->getRegNum()), Disp, Fixup);
} else if (Mem->getIndex()) {
- SetIndex(getEncodedGPR(Mem->getIndex()->getRegNum()),
- X8664::Traits::ScaleFactor(Mem->getShift()), Disp, Fixup);
+ SetIndex(Traits::getEncodedGPR(Mem->getIndex()->getRegNum()),
+ ScaleFactor(Mem->getShift()), Disp, Fixup);
} else if (Fixup == nullptr) {
SetAbsolute(Disp);
} else {
@@ -185,7 +186,7 @@
AssemblerBuffer::EnsureCapacity ensured(&Buffer);
intptr_t call_start = Buffer.getPosition();
emitUint8(0xE8);
- auto *Fixup = this->createFixup(Traits::FK_PcRel, label);
+ auto *Fixup = this->createFixup(FK_PcRel, label);
Fixup->set_addend(-4);
emitFixup(Fixup);
emitInt32(0);
@@ -197,7 +198,7 @@
AssemblerBuffer::EnsureCapacity ensured(&Buffer);
intptr_t call_start = Buffer.getPosition();
emitUint8(0xE8);
- auto *Fixup = this->createFixup(Traits::FK_PcRel, AssemblerFixup::NullSymbol);
+ auto *Fixup = this->createFixup(FK_PcRel, AssemblerFixup::NullSymbol);
Fixup->set_addend(abs_address.value() - 4);
emitFixup(Fixup);
emitInt32(0);
@@ -220,7 +221,7 @@
void AssemblerX8664::pushl(const ConstantRelocatable *Label) {
AssemblerBuffer::EnsureCapacity ensured(&Buffer);
emitUint8(0x68);
- emitFixup(this->createFixup(Traits::FK_Abs, Label));
+ emitFixup(this->createFixup(FK_Abs, Label));
// In x86-32, the emitted value is an addend to the relocation. Therefore, we
// must emit a 0 (because we're pushing an absolute relocation.)
// In x86-64, the emitted value does not matter (the addend lives in the
@@ -2277,17 +2278,18 @@
// 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 <= Traits::Last8BitGPR) {
+ constexpr GPRRegister Last8BitGPR = GPRRegister::Encoded_Reg_r15d;
+ if (immediate.is_uint8() && reg <= Last8BitGPR) {
// Use zero-extended 8-bit immediate.
emitRexB(Ty, reg);
- if (reg == Traits::Encoded_Reg_Accumulator) {
+ if (reg == RegX8664::Encoded_Reg_rax) {
emitUint8(0xA8);
} else {
emitUint8(0xF6);
emitUint8(0xC0 + gprEncoding(reg));
}
emitUint8(immediate.value() & 0xFF);
- } else if (reg == Traits::Encoded_Reg_Accumulator) {
+ } else if (reg == RegX8664::Encoded_Reg_rax) {
// Use short form if the destination is EAX.
if (Ty == IceType_i16)
emitOperandSizeOverride();
@@ -3019,7 +3021,7 @@
AssemblerBuffer::EnsureCapacity ensured(&Buffer);
emitUint8(0x0F);
emitUint8(0x80 + condition);
- auto *Fixup = this->createFixup(Traits::FK_PcRel, label);
+ auto *Fixup = this->createFixup(FK_PcRel, label);
Fixup->set_addend(-4);
emitFixup(Fixup);
emitInt32(0);
@@ -3058,7 +3060,7 @@
void AssemblerX8664::jmp(const ConstantRelocatable *label) {
AssemblerBuffer::EnsureCapacity ensured(&Buffer);
emitUint8(0xE9);
- auto *Fixup = this->createFixup(Traits::FK_PcRel, label);
+ auto *Fixup = this->createFixup(FK_PcRel, label);
Fixup->set_addend(-4);
emitFixup(Fixup);
emitInt32(0);
@@ -3067,8 +3069,7 @@
void AssemblerX8664::jmp(const Immediate &abs_address) {
AssemblerBuffer::EnsureCapacity ensured(&Buffer);
emitUint8(0xE9);
- AssemblerFixup *Fixup =
- createFixup(Traits::FK_PcRel, AssemblerFixup::NullSymbol);
+ AssemblerFixup *Fixup = createFixup(FK_PcRel, AssemblerFixup::NullSymbol);
Fixup->set_addend(abs_address.value() - 4);
emitFixup(Fixup);
emitInt32(0);
@@ -3132,11 +3133,11 @@
AssemblerBuffer::EnsureCapacity ensured(&Buffer);
if (Ty == IceType_i16)
emitOperandSizeOverride();
- // Use short form if either register is EAX.
- if (reg0 == Traits::Encoded_Reg_Accumulator) {
+ // Use short form if either register is RAX.
+ if (reg0 == RegX8664::Encoded_Reg_rax) {
emitRexB(Ty, reg1);
emitUint8(0x90 + gprEncoding(reg1));
- } else if (reg1 == Traits::Encoded_Reg_Accumulator) {
+ } else if (reg1 == RegX8664::Encoded_Reg_rax) {
emitRexB(Ty, reg0);
emitUint8(0x90 + gprEncoding(reg0));
} else {
@@ -3298,7 +3299,7 @@
const Immediate &immediate) {
assert(rm >= 0 && rm < 8);
assert(immediate.is_int8());
- if (operand.IsRegister(Traits::Encoded_Reg_Accumulator)) {
+ if (operand.IsRegister(RegX8664::Encoded_Reg_rax)) {
// Use short form if the destination is al.
emitUint8(0x04 + (rm << 3));
emitUint8(immediate.value() & 0xFF);
@@ -3320,7 +3321,7 @@
static constexpr RelocOffsetT OffsetFromNextInstruction = 1;
emitOperand(rm, operand, OffsetFromNextInstruction);
emitUint8(immediate.value() & 0xFF);
- } else if (operand.IsRegister(Traits::Encoded_Reg_Accumulator)) {
+ } else if (operand.IsRegister(RegX8664::Encoded_Reg_rax)) {
// Use short form if the destination is eax.
emitUint8(0x05 + (rm << 3));
emitImmediate(Ty, immediate);
@@ -3381,7 +3382,7 @@
const AsmOperand &operand,
GPRRegister shifter) {
AssemblerBuffer::EnsureCapacity ensured(&Buffer);
- assert(shifter == Traits::Encoded_Reg_Counter);
+ assert(shifter == RegX8664::Encoded_Reg_rcx);
(void)shifter;
if (Ty == IceType_i16)
emitOperandSizeOverride();
diff --git a/third_party/subzero/src/IceAssemblerX8664.h b/third_party/subzero/src/IceAssemblerX8664.h
index 457a572..dbab294 100644
--- a/third_party/subzero/src/IceAssemblerX8664.h
+++ b/third_party/subzero/src/IceAssemblerX8664.h
@@ -35,13 +35,221 @@
namespace X8664 {
using Traits = TargetX8664Traits;
-using AsmAddress = typename Traits::AsmAddress;
using ByteRegister = typename Traits::ByteRegister;
using BrCond = CondX86::BrCond;
using CmppsCond = CondX86::CmppsCond;
using GPRRegister = typename Traits::GPRRegister;
-using AsmOperand = typename Traits::AsmOperand;
using XmmRegister = typename Traits::XmmRegister;
+using X86OperandMem = typename Traits::X86OperandMem;
+
+constexpr FixupKind FK_PcRel = llvm::ELF::R_X86_64_PC32;
+constexpr FixupKind FK_Abs = llvm::ELF::R_X86_64_32S;
+constexpr FixupKind FK_Gotoff = llvm::ELF::R_X86_64_GOTOFF64;
+constexpr FixupKind FK_GotPC = llvm::ELF::R_X86_64_GOTPC32;
+
+enum ScaleFactor { TIMES_1 = 0, TIMES_2 = 1, TIMES_4 = 2, TIMES_8 = 3 };
+
+class AsmOperand {
+public:
+ enum RexBits {
+ RexNone = 0x00,
+ RexBase = 0x40,
+ RexW = RexBase | (1 << 3),
+ RexR = RexBase | (1 << 2),
+ RexX = RexBase | (1 << 1),
+ RexB = RexBase | (1 << 0),
+ };
+
+protected:
+ // Needed by subclass AsmAddress.
+ AsmOperand() = default;
+
+public:
+ AsmOperand(const AsmOperand &) = default;
+ AsmOperand(AsmOperand &&) = default;
+ AsmOperand &operator=(const AsmOperand &) = default;
+ AsmOperand &operator=(AsmOperand &&) = default;
+
+ uint8_t mod() const { return (encoding_at(0) >> 6) & 3; }
+
+ uint8_t rexX() const { return (rex_ & RexX) != RexX ? RexNone : RexX; }
+ uint8_t rexB() const { return (rex_ & RexB) != RexB ? RexNone : RexB; }
+
+ GPRRegister rm() const {
+ return static_cast<GPRRegister>((rexB() != 0 ? 0x08 : 0) |
+ (encoding_at(0) & 7));
+ }
+
+ ScaleFactor scale() const {
+ return static_cast<ScaleFactor>((encoding_at(1) >> 6) & 3);
+ }
+
+ GPRRegister index() const {
+ return static_cast<GPRRegister>((rexX() != 0 ? 0x08 : 0) |
+ ((encoding_at(1) >> 3) & 7));
+ }
+
+ GPRRegister base() const {
+ return static_cast<GPRRegister>((rexB() != 0 ? 0x08 : 0) |
+ (encoding_at(1) & 7));
+ }
+
+ int8_t disp8() const {
+ assert(length_ >= 2);
+ return static_cast<int8_t>(encoding_[length_ - 1]);
+ }
+
+ AssemblerFixup *fixup() const { return fixup_; }
+
+protected:
+ void SetModRM(int mod, GPRRegister rm) {
+ assert((mod & ~3) == 0);
+ encoding_[0] = (mod << 6) | (rm & 0x07);
+ rex_ = (rm & 0x08) ? RexB : RexNone;
+ length_ = 1;
+ }
+
+ void SetSIB(ScaleFactor scale, GPRRegister index, GPRRegister base) {
+ assert(length_ == 1);
+ assert((scale & ~3) == 0);
+ encoding_[1] = (scale << 6) | ((index & 0x07) << 3) | (base & 0x07);
+ rex_ = ((base & 0x08) ? RexB : RexNone) | ((index & 0x08) ? RexX : RexNone);
+ length_ = 2;
+ }
+
+ void SetDisp8(int8_t disp) {
+ assert(length_ == 1 || length_ == 2);
+ encoding_[length_++] = static_cast<uint8_t>(disp);
+ }
+
+ void SetDisp32(int32_t disp) {
+ assert(length_ == 1 || length_ == 2);
+ intptr_t disp_size = sizeof(disp);
+ memmove(&encoding_[length_], &disp, disp_size);
+ length_ += disp_size;
+ }
+
+ void SetFixup(AssemblerFixup *fixup) { fixup_ = fixup; }
+
+private:
+ AssemblerFixup *fixup_ = nullptr;
+ uint8_t rex_ = 0;
+ uint8_t encoding_[6];
+ uint8_t length_ = 0;
+
+ explicit AsmOperand(GPRRegister reg) : fixup_(nullptr) { SetModRM(3, reg); }
+
+ /// Get the operand encoding byte at the given index.
+ uint8_t encoding_at(intptr_t index) const {
+ assert(index >= 0 && index < length_);
+ return encoding_[index];
+ }
+
+ /// Returns whether or not this operand is really the given register in
+ /// disguise. Used from the assembler to generate better encodings.
+ bool IsRegister(GPRRegister reg) const {
+ return ((encoding_[0] & 0xF8) == 0xC0) // Addressing mode is register only.
+ && (rm() == reg); // Register codes match.
+ }
+
+ friend class AssemblerX8664;
+};
+
+class AsmAddress : public AsmOperand {
+ AsmAddress() = default;
+
+public:
+ AsmAddress(const Variable *Var, const TargetX8664 *Target);
+ AsmAddress(const X86OperandMem *Mem, Ice::Assembler *Asm,
+ const Ice::TargetLowering *Target);
+
+ // Address into the constant pool.
+ AsmAddress(const Constant *Imm, Ice::Assembler *Asm) {
+ // TODO(jpp): ???
+ AssemblerFixup *Fixup = Asm->createFixup(FK_Abs, Imm);
+ const RelocOffsetT Offset = 4;
+ SetRipRelative(Offset, Fixup);
+ }
+
+private:
+ AsmAddress(const AsmAddress &) = default;
+ AsmAddress(AsmAddress &&) = default;
+ AsmAddress &operator=(const AsmAddress &) = default;
+ AsmAddress &operator=(AsmAddress &&) = default;
+
+ void SetBase(GPRRegister Base, int32_t Disp, AssemblerFixup *Fixup) {
+ if (Fixup == nullptr && Disp == 0 &&
+ (Base & 7) != RegX8664::Encoded_Reg_rbp) {
+ SetModRM(0, Base);
+ if ((Base & 7) == RegX8664::Encoded_Reg_rsp)
+ SetSIB(TIMES_1, RegX8664::Encoded_Reg_rsp, Base);
+ } else if (Fixup == nullptr && Utils::IsInt(8, Disp)) {
+ SetModRM(1, Base);
+ if ((Base & 7) == RegX8664::Encoded_Reg_rsp)
+ SetSIB(TIMES_1, RegX8664::Encoded_Reg_rsp, Base);
+ SetDisp8(Disp);
+ } else {
+ SetModRM(2, Base);
+ if ((Base & 7) == RegX8664::Encoded_Reg_rsp)
+ SetSIB(TIMES_1, RegX8664::Encoded_Reg_rsp, Base);
+ SetDisp32(Disp);
+ if (Fixup)
+ SetFixup(Fixup);
+ }
+ }
+
+ void SetIndex(GPRRegister Index, ScaleFactor Scale, int32_t Disp,
+ AssemblerFixup *Fixup) {
+ assert(Index != RegX8664::Encoded_Reg_rsp); // Illegal addressing mode.
+ SetModRM(0, RegX8664::Encoded_Reg_rsp);
+ SetSIB(Scale, Index, RegX8664::Encoded_Reg_rbp);
+ SetDisp32(Disp);
+ if (Fixup)
+ SetFixup(Fixup);
+ }
+
+ void SetBaseIndex(GPRRegister Base, GPRRegister Index, ScaleFactor Scale,
+ int32_t Disp, AssemblerFixup *Fixup) {
+ assert(Index != RegX8664::Encoded_Reg_rsp); // Illegal addressing mode.
+ if (Fixup == nullptr && Disp == 0 &&
+ (Base & 7) != RegX8664::Encoded_Reg_rbp) {
+ SetModRM(0, RegX8664::Encoded_Reg_rsp);
+ SetSIB(Scale, Index, Base);
+ } else if (Fixup == nullptr && Utils::IsInt(8, Disp)) {
+ SetModRM(1, RegX8664::Encoded_Reg_rsp);
+ SetSIB(Scale, Index, Base);
+ SetDisp8(Disp);
+ } else {
+ SetModRM(2, RegX8664::Encoded_Reg_rsp);
+ SetSIB(Scale, Index, Base);
+ SetDisp32(Disp);
+ if (Fixup)
+ SetFixup(Fixup);
+ }
+ }
+
+ /// Generate a RIP-relative address expression on x86-64.
+ void SetRipRelative(RelocOffsetT Offset, AssemblerFixup *Fixup) {
+ assert(Fixup != nullptr);
+ assert(Fixup->kind() == FK_PcRel);
+
+ SetModRM(0x0, RegX8664::Encoded_Reg_rbp);
+
+ // Use the Offset in the displacement for now. If we decide to process
+ // fixups later, we'll need to patch up the emitted displacement.
+ SetDisp32(Offset);
+ if (Fixup)
+ SetFixup(Fixup);
+ }
+
+ /// Generate an absolute address.
+ void SetAbsolute(RelocOffsetT Addr) {
+ SetModRM(0x0, RegX8664::Encoded_Reg_rsp);
+ static constexpr ScaleFactor NoScale = TIMES_1;
+ SetSIB(NoScale, RegX8664::Encoded_Reg_rsp, RegX8664::Encoded_Reg_rbp);
+ SetDisp32(Addr);
+ }
+};
class AssemblerX8664 : public ::Ice::Assembler {
AssemblerX8664(const AssemblerX8664 &) = delete;
@@ -162,7 +370,7 @@
bool fixupIsPCRel(FixupKind Kind) const override {
// Currently assuming this is the only PC-rel relocation type used.
// TODO(jpp): Traits.PcRelTypes.count(Kind) != 0
- return Kind == Traits::FK_PcRel;
+ return Kind == FK_PcRel;
}
// Operations to emit GPR instructions (and dispatch on operand type).
diff --git a/third_party/subzero/src/IceInstX8632.cpp b/third_party/subzero/src/IceInstX8632.cpp
index f82679c..51ff578 100644
--- a/third_party/subzero/src/IceInstX8632.cpp
+++ b/third_party/subzero/src/IceInstX8632.cpp
@@ -622,8 +622,8 @@
} else if (const auto *Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) {
const auto FixupKind = (Reloc->getName().hasStdString() &&
Reloc->getName().toString() == GlobalOffsetTable)
- ? Traits::FK_GotPC
- : Traits::FK_Abs;
+ ? FK_GotPC
+ : FK_Abs;
AssemblerFixup *Fixup = Asm->createFixup(FixupKind, Reloc);
(Asm->*(Emitter.GPRImm))(Ty, VarReg, AssemblerImmediate(Fixup));
} else if (const auto *Split = llvm::dyn_cast<VariableSplit>(Src)) {
@@ -646,8 +646,8 @@
} else if (const auto *Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) {
const auto FixupKind = (Reloc->getName().hasStdString() &&
Reloc->getName().toString() == GlobalOffsetTable)
- ? Traits::FK_GotPC
- : Traits::FK_Abs;
+ ? FK_GotPC
+ : FK_Abs;
AssemblerFixup *Fixup = Asm->createFixup(FixupKind, Reloc);
(Asm->*(Emitter.AddrImm))(Ty, Addr, AssemblerImmediate(Fixup));
} else {
diff --git a/third_party/subzero/src/IceInstX8632.h b/third_party/subzero/src/IceInstX8632.h
index e38d627..782df58 100644
--- a/third_party/subzero/src/IceInstX8632.h
+++ b/third_party/subzero/src/IceInstX8632.h
@@ -34,7 +34,6 @@
using Assembler = typename Traits::Assembler;
using AssemblerImmediate = typename Assembler::Immediate;
using TargetLowering = typename Traits::TargetLowering;
-using AsmAddress = typename Traits::AsmAddress;
using X86Operand = typename Traits::X86Operand;
using X86OperandMem = typename Traits::X86OperandMem;
using VariableSplit = typename Traits::VariableSplit;
diff --git a/third_party/subzero/src/IceInstX8664.cpp b/third_party/subzero/src/IceInstX8664.cpp
index 39f5212..71e7773 100644
--- a/third_party/subzero/src/IceInstX8664.cpp
+++ b/third_party/subzero/src/IceInstX8664.cpp
@@ -625,8 +625,8 @@
} else if (const auto *Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) {
const auto FixupKind = (Reloc->getName().hasStdString() &&
Reloc->getName().toString() == GlobalOffsetTable)
- ? Traits::FK_GotPC
- : Traits::FK_Abs;
+ ? FK_GotPC
+ : FK_Abs;
AssemblerFixup *Fixup = Asm->createFixup(FixupKind, Reloc);
(Asm->*(Emitter.GPRImm))(Ty, VarReg, AssemblerImmediate(Fixup));
} else {
@@ -650,8 +650,8 @@
} else if (const auto *Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) {
const auto FixupKind = (Reloc->getName().hasStdString() &&
Reloc->getName().toString() == GlobalOffsetTable)
- ? Traits::FK_GotPC
- : Traits::FK_Abs;
+ ? FK_GotPC
+ : FK_Abs;
AssemblerFixup *Fixup = Asm->createFixup(FixupKind, Reloc);
(Asm->*(Emitter.AddrImm))(Ty, Addr, AssemblerImmediate(Fixup));
} else {
diff --git a/third_party/subzero/src/IceInstX8664.h b/third_party/subzero/src/IceInstX8664.h
index f0aa3fa..02582c8 100644
--- a/third_party/subzero/src/IceInstX8664.h
+++ b/third_party/subzero/src/IceInstX8664.h
@@ -34,7 +34,6 @@
using Assembler = typename Traits::Assembler;
using AssemblerImmediate = typename Assembler::Immediate;
using TargetLowering = typename Traits::TargetLowering;
-using AsmAddress = typename Traits::AsmAddress;
using X86Operand = typename Traits::X86Operand;
using X86OperandMem = typename Traits::X86OperandMem;
diff --git a/third_party/subzero/src/IceTargetLoweringX8632.cpp b/third_party/subzero/src/IceTargetLoweringX8632.cpp
index 3489fec..0381a53 100644
--- a/third_party/subzero/src/IceTargetLoweringX8632.cpp
+++ b/third_party/subzero/src/IceTargetLoweringX8632.cpp
@@ -7822,7 +7822,7 @@
switch (getFlags().getOutFileType()) {
case FT_Elf: {
ELFObjectWriter *Writer = Ctx->getObjectWriter();
- const FixupKind RelocationKind = Traits::FK_Abs;
+ const FixupKind RelocationKind = FK_Abs;
for (const JumpTableData &JT : Ctx->getJumpTables())
Writer->writeJumpTable(JT, RelocationKind, IsPIC);
} break;
@@ -7856,7 +7856,7 @@
switch (getFlags().getOutFileType()) {
case FT_Elf: {
ELFObjectWriter *Writer = Ctx->getObjectWriter();
- Writer->writeDataSection(Vars, Traits::FK_Abs, SectionSuffix, IsPIC);
+ Writer->writeDataSection(Vars, FK_Abs, SectionSuffix, IsPIC);
} break;
case FT_Asm:
case FT_Iasm: {
diff --git a/third_party/subzero/src/IceTargetLoweringX8632.h b/third_party/subzero/src/IceTargetLoweringX8632.h
index 463ae2e..52e28b3 100644
--- a/third_party/subzero/src/IceTargetLoweringX8632.h
+++ b/third_party/subzero/src/IceTargetLoweringX8632.h
@@ -126,7 +126,6 @@
using BrCond = CondX86::BrCond;
using CmppsCond = CondX86::CmppsCond;
- using AsmAddress = typename Traits::AsmAddress;
using X86Operand = typename Traits::X86Operand;
using X86OperandMem = typename Traits::X86OperandMem;
using SegmentRegisters = typename Traits::X86OperandMem::SegmentRegisters;
@@ -205,8 +204,8 @@
bool hasFramePointer() const override { return IsEbpBasedFrame; }
void setHasFramePointer() override { IsEbpBasedFrame = true; }
- RegNumT getStackReg() const override { return Traits::StackPtr; }
- RegNumT getFrameReg() const override { return Traits::FramePtr; }
+ RegNumT getStackReg() const override { return RegX8632::Reg_esp; }
+ RegNumT getFrameReg() const override { return RegX8632::Reg_ebp; }
RegNumT getFrameOrStackReg() const override {
// If the stack pointer needs to be aligned, then the frame pointer is
// unaligned, so always use the stack pointer.
@@ -957,9 +956,6 @@
int8_t Idx14, int8_t Idx15);
/// @}
- static constexpr FixupKind PcRelFixup = Traits::FK_PcRel;
- static constexpr FixupKind AbsFixup = Traits::FK_Abs;
-
public:
static std::unique_ptr<::Ice::TargetLowering> create(Cfg *Func) {
return makeUnique<TargetX8632>(Func);
diff --git a/third_party/subzero/src/IceTargetLoweringX8632Traits.h b/third_party/subzero/src/IceTargetLoweringX8632Traits.h
index 4fa67b2..ac5fa32 100644
--- a/third_party/subzero/src/IceTargetLoweringX8632Traits.h
+++ b/third_party/subzero/src/IceTargetLoweringX8632Traits.h
@@ -38,219 +38,11 @@
class TargetX8632;
struct TargetX8632Traits {
- //----------------------------------------------------------------------------
- // ______ ______ __ __
- // /\ __ \/\ ___\/\ "-./ \
- // \ \ __ \ \___ \ \ \-./\ \
- // \ \_\ \_\/\_____\ \_\ \ \_\
- // \/_/\/_/\/_____/\/_/ \/_/
- //
- //----------------------------------------------------------------------------
- static constexpr ::Ice::RegX8632::GPRRegister Last8BitGPR =
- ::Ice::RegX8632::GPRRegister::Encoded_Reg_ebx;
-
- enum ScaleFactor { TIMES_1 = 0, TIMES_2 = 1, TIMES_4 = 2, TIMES_8 = 3 };
-
- using GPRRegister = ::Ice::RegX8632::GPRRegister;
- using ByteRegister = ::Ice::RegX8632::ByteRegister;
- using XmmRegister = ::Ice::RegX8632::XmmRegister;
- using X87STRegister = ::Ice::RegX8632::X87STRegister;
-
using RegisterSet = ::Ice::RegX8632;
- static constexpr RegisterSet::AllRegisters StackPtr = RegX8632::Reg_esp;
- static constexpr RegisterSet::AllRegisters FramePtr = RegX8632::Reg_ebp;
- static constexpr GPRRegister Encoded_Reg_Accumulator =
- RegX8632::Encoded_Reg_eax;
- static constexpr GPRRegister Encoded_Reg_Counter = RegX8632::Encoded_Reg_ecx;
- static constexpr FixupKind FK_PcRel = llvm::ELF::R_386_PC32;
- static constexpr FixupKind FK_Abs = llvm::ELF::R_386_32;
- static constexpr FixupKind FK_Gotoff = llvm::ELF::R_386_GOTOFF;
- static constexpr FixupKind FK_GotPC = llvm::ELF::R_386_GOTPC;
-
- class X86OperandMem;
- class VariableSplit;
-
- class AsmOperand {
- public:
- AsmOperand(const AsmOperand &other)
- : fixup_(other.fixup_), length_(other.length_) {
- memmove(&encoding_[0], &other.encoding_[0], other.length_);
- }
-
- AsmOperand &operator=(const AsmOperand &other) {
- length_ = other.length_;
- fixup_ = other.fixup_;
- memmove(&encoding_[0], &other.encoding_[0], other.length_);
- return *this;
- }
-
- uint8_t mod() const { return (encoding_at(0) >> 6) & 3; }
-
- GPRRegister rm() const {
- return static_cast<GPRRegister>(encoding_at(0) & 7);
- }
-
- ScaleFactor scale() const {
- return static_cast<ScaleFactor>((encoding_at(1) >> 6) & 3);
- }
-
- GPRRegister index() const {
- return static_cast<GPRRegister>((encoding_at(1) >> 3) & 7);
- }
-
- GPRRegister base() const {
- return static_cast<GPRRegister>(encoding_at(1) & 7);
- }
-
- int8_t disp8() const {
- assert(length_ >= 2);
- return static_cast<int8_t>(encoding_[length_ - 1]);
- }
-
- AssemblerFixup *fixup() const { return fixup_; }
-
- protected:
- AsmOperand()
- : fixup_(nullptr), length_(0) {} // Needed by subclass AsmAddress.
-
- void SetModRM(int mod, GPRRegister rm) {
- assert((mod & ~3) == 0);
- encoding_[0] = (mod << 6) | rm;
- length_ = 1;
- }
-
- void SetSIB(ScaleFactor scale, GPRRegister index, GPRRegister base) {
- assert(length_ == 1);
- assert((scale & ~3) == 0);
- encoding_[1] = (scale << 6) | (index << 3) | base;
- length_ = 2;
- }
-
- void SetDisp8(int8_t disp) {
- assert(length_ == 1 || length_ == 2);
- encoding_[length_++] = static_cast<uint8_t>(disp);
- }
-
- void SetDisp32(int32_t disp) {
- assert(length_ == 1 || length_ == 2);
- intptr_t disp_size = sizeof(disp);
- memmove(&encoding_[length_], &disp, disp_size);
- length_ += disp_size;
- }
-
- void SetFixup(AssemblerFixup *fixup) { fixup_ = fixup; }
-
- private:
- AssemblerFixup *fixup_;
- uint8_t encoding_[6];
- uint8_t length_;
-
- explicit AsmOperand(GPRRegister reg) : fixup_(nullptr) { SetModRM(3, reg); }
-
- /// Get the operand encoding byte at the given index.
- uint8_t encoding_at(intptr_t index) const {
- assert(index >= 0 && index < length_);
- return encoding_[index];
- }
-
- /// Returns whether or not this operand is really the given register in
- /// disguise. Used from the assembler to generate better encodings.
- bool IsRegister(GPRRegister reg) const {
- return ((encoding_[0] & 0xF8) ==
- 0xC0) // Addressing mode is register only.
- && ((encoding_[0] & 0x07) == reg); // Register codes match.
- }
-
- friend class AssemblerX8632;
- };
-
- class AsmAddress : public AsmOperand {
- AsmAddress() = delete;
-
- public:
- AsmAddress(GPRRegister Base, int32_t Disp,
- AssemblerFixup *Fixup = nullptr) {
- SetBase(Base, Disp, Fixup);
- }
- AsmAddress(const Variable *Var, const TargetX8632 *Target);
- AsmAddress(const X86OperandMem *Mem, Ice::Assembler *Asm,
- const Ice::TargetLowering *Target);
- AsmAddress(const VariableSplit *Split, const Cfg *Func);
-
- // Address into the constant pool.
- AsmAddress(const Constant *Imm, Ice::Assembler *Asm) {
- AssemblerFixup *Fixup = Asm->createFixup(llvm::ELF::R_386_32, Imm);
- const RelocOffsetT Offset = 0;
- SetAbsolute(Offset, Fixup);
- }
-
- private:
- AsmAddress(const AsmAddress &other) : AsmOperand(other) {}
-
- AsmAddress &operator=(const AsmAddress &other) {
- AsmOperand::operator=(other);
- return *this;
- }
-
- void SetBase(GPRRegister Base, int32_t Disp, AssemblerFixup *Fixup) {
- if (Fixup == nullptr && Disp == 0 && Base != RegX8632::Encoded_Reg_ebp) {
- SetModRM(0, Base);
- if (Base == RegX8632::Encoded_Reg_esp)
- SetSIB(TIMES_1, RegX8632::Encoded_Reg_esp, Base);
- } else if (Fixup == nullptr && Utils::IsInt(8, Disp)) {
- SetModRM(1, Base);
- if (Base == RegX8632::Encoded_Reg_esp)
- SetSIB(TIMES_1, RegX8632::Encoded_Reg_esp, Base);
- SetDisp8(Disp);
- } else {
- SetModRM(2, Base);
- if (Base == RegX8632::Encoded_Reg_esp)
- SetSIB(TIMES_1, RegX8632::Encoded_Reg_esp, Base);
- SetDisp32(Disp);
- if (Fixup)
- SetFixup(Fixup);
- }
- }
-
- void SetIndex(GPRRegister Index, ScaleFactor Scale, int32_t Disp,
- AssemblerFixup *Fixup) {
- assert(Index != RegX8632::Encoded_Reg_esp); // Illegal addressing mode.
- SetModRM(0, RegX8632::Encoded_Reg_esp);
- SetSIB(Scale, Index, RegX8632::Encoded_Reg_ebp);
- SetDisp32(Disp);
- if (Fixup)
- SetFixup(Fixup);
- }
-
- void SetBaseIndex(GPRRegister Base, GPRRegister Index, ScaleFactor Scale,
- int32_t Disp, AssemblerFixup *Fixup) {
- assert(Index != RegX8632::Encoded_Reg_esp); // Illegal addressing mode.
- if (Fixup == nullptr && Disp == 0 && Base != RegX8632::Encoded_Reg_ebp) {
- SetModRM(0, RegX8632::Encoded_Reg_esp);
- SetSIB(Scale, Index, Base);
- } else if (Fixup == nullptr && Utils::IsInt(8, Disp)) {
- SetModRM(1, RegX8632::Encoded_Reg_esp);
- SetSIB(Scale, Index, Base);
- SetDisp8(Disp);
- } else {
- SetModRM(2, RegX8632::Encoded_Reg_esp);
- SetSIB(Scale, Index, Base);
- SetDisp32(Disp);
- if (Fixup)
- SetFixup(Fixup);
- }
- }
-
- /// Generate an absolute address expression on x86-32.
- void SetAbsolute(RelocOffsetT Offset, AssemblerFixup *Fixup) {
- SetModRM(0, RegX8632::Encoded_Reg_ebp);
- // Use the Offset in the displacement for now. If we decide to process
- // fixups later, we'll need to patch up the emitted displacement.
- SetDisp32(Offset);
- if (Fixup)
- SetFixup(Fixup);
- }
- };
+ using GPRRegister = RegisterSet::GPRRegister;
+ using ByteRegister = RegisterSet::ByteRegister;
+ using XmmRegister = RegisterSet::XmmRegister;
+ using X87STRegister = RegisterSet::X87STRegister;
//----------------------------------------------------------------------------
// __ ______ __ __ ______ ______ __ __ __ ______
diff --git a/third_party/subzero/src/IceTargetLoweringX8664.cpp b/third_party/subzero/src/IceTargetLoweringX8664.cpp
index c411d12..a782914 100644
--- a/third_party/subzero/src/IceTargetLoweringX8664.cpp
+++ b/third_party/subzero/src/IceTargetLoweringX8664.cpp
@@ -7067,7 +7067,7 @@
ELFObjectWriter *Writer = Ctx->getObjectWriter();
constexpr FixupKind FK_Abs64 = llvm::ELF::R_X86_64_64;
const FixupKind RelocationKind =
- (getPointerType() == IceType_i32) ? Traits::FK_Abs : FK_Abs64;
+ (getPointerType() == IceType_i32) ? FK_Abs : FK_Abs64;
for (const JumpTableData &JT : Ctx->getJumpTables())
Writer->writeJumpTable(JT, RelocationKind, IsPIC);
} break;
@@ -7101,7 +7101,7 @@
switch (getFlags().getOutFileType()) {
case FT_Elf: {
ELFObjectWriter *Writer = Ctx->getObjectWriter();
- Writer->writeDataSection(Vars, Traits::FK_Abs, SectionSuffix, IsPIC);
+ Writer->writeDataSection(Vars, FK_Abs, SectionSuffix, IsPIC);
} break;
case FT_Asm:
case FT_Iasm: {
diff --git a/third_party/subzero/src/IceTargetLoweringX8664.h b/third_party/subzero/src/IceTargetLoweringX8664.h
index e84d29d..b31134a 100644
--- a/third_party/subzero/src/IceTargetLoweringX8664.h
+++ b/third_party/subzero/src/IceTargetLoweringX8664.h
@@ -127,7 +127,6 @@
using BrCond = CondX86::BrCond;
using CmppsCond = CondX86::CmppsCond;
- using AsmAddress = typename Traits::AsmAddress;
using X86Operand = typename Traits::X86Operand;
using X86OperandMem = typename Traits::X86OperandMem;
using SegmentRegisters = typename Traits::X86OperandMem::SegmentRegisters;
@@ -206,8 +205,8 @@
bool hasFramePointer() const override { return IsEbpBasedFrame; }
void setHasFramePointer() override { IsEbpBasedFrame = true; }
- RegNumT getStackReg() const override { return Traits::StackPtr; }
- RegNumT getFrameReg() const override { return Traits::FramePtr; }
+ RegNumT getStackReg() const override { return RegX8664::Reg_rsp; }
+ RegNumT getFrameReg() const override { return RegX8664::Reg_rbp; }
RegNumT getFrameOrStackReg() const override {
// If the stack pointer needs to be aligned, then the frame pointer is
// unaligned, so always use the stack pointer.
@@ -945,9 +944,6 @@
int8_t Idx14, int8_t Idx15);
/// @}
- static constexpr FixupKind PcRelFixup = Traits::FK_PcRel;
- static constexpr FixupKind AbsFixup = Traits::FK_Abs;
-
public:
static std::unique_ptr<::Ice::TargetLowering> create(Cfg *Func) {
return makeUnique<TargetX8664>(Func);
diff --git a/third_party/subzero/src/IceTargetLoweringX8664Traits.h b/third_party/subzero/src/IceTargetLoweringX8664Traits.h
index bba2281..5c8734a 100644
--- a/third_party/subzero/src/IceTargetLoweringX8664Traits.h
+++ b/third_party/subzero/src/IceTargetLoweringX8664Traits.h
@@ -39,239 +39,10 @@
class TargetX8664;
struct TargetX8664Traits {
- //----------------------------------------------------------------------------
- // ______ ______ __ __
- // /\ __ \/\ ___\/\ "-./ \
- // \ \ __ \ \___ \ \ \-./\ \
- // \ \_\ \_\/\_____\ \_\ \ \_\
- // \/_/\/_/\/_____/\/_/ \/_/
- //
- //----------------------------------------------------------------------------
- static constexpr ::Ice::RegX8664::GPRRegister Last8BitGPR =
- ::Ice::RegX8664::GPRRegister::Encoded_Reg_r15d;
-
- enum ScaleFactor { TIMES_1 = 0, TIMES_2 = 1, TIMES_4 = 2, TIMES_8 = 3 };
-
- using GPRRegister = ::Ice::RegX8664::GPRRegister;
- using ByteRegister = ::Ice::RegX8664::ByteRegister;
- using XmmRegister = ::Ice::RegX8664::XmmRegister;
-
using RegisterSet = ::Ice::RegX8664;
- static constexpr RegisterSet::AllRegisters StackPtr = RegX8664::Reg_rsp;
- static constexpr RegisterSet::AllRegisters FramePtr = RegX8664::Reg_rbp;
- static constexpr GPRRegister Encoded_Reg_Accumulator =
- RegX8664::Encoded_Reg_eax;
- static constexpr GPRRegister Encoded_Reg_Counter = RegX8664::Encoded_Reg_ecx;
- static constexpr FixupKind FK_PcRel = llvm::ELF::R_X86_64_PC32;
- static constexpr FixupKind FK_Abs = llvm::ELF::R_X86_64_32S;
- static constexpr FixupKind FK_Gotoff = llvm::ELF::R_X86_64_GOTOFF64;
- static constexpr FixupKind FK_GotPC = llvm::ELF::R_X86_64_GOTPC32;
-
- class X86OperandMem;
-
- class AsmOperand {
- public:
- enum RexBits {
- RexNone = 0x00,
- RexBase = 0x40,
- RexW = RexBase | (1 << 3),
- RexR = RexBase | (1 << 2),
- RexX = RexBase | (1 << 1),
- RexB = RexBase | (1 << 0),
- };
-
- protected:
- // Needed by subclass AsmAddress.
- AsmOperand() = default;
-
- public:
- AsmOperand(const AsmOperand &) = default;
- AsmOperand(AsmOperand &&) = default;
- AsmOperand &operator=(const AsmOperand &) = default;
- AsmOperand &operator=(AsmOperand &&) = default;
-
- uint8_t mod() const { return (encoding_at(0) >> 6) & 3; }
-
- uint8_t rexX() const { return (rex_ & RexX) != RexX ? RexNone : RexX; }
- uint8_t rexB() const { return (rex_ & RexB) != RexB ? RexNone : RexB; }
-
- GPRRegister rm() const {
- return static_cast<GPRRegister>((rexB() != 0 ? 0x08 : 0) |
- (encoding_at(0) & 7));
- }
-
- ScaleFactor scale() const {
- return static_cast<ScaleFactor>((encoding_at(1) >> 6) & 3);
- }
-
- GPRRegister index() const {
- return static_cast<GPRRegister>((rexX() != 0 ? 0x08 : 0) |
- ((encoding_at(1) >> 3) & 7));
- }
-
- GPRRegister base() const {
- return static_cast<GPRRegister>((rexB() != 0 ? 0x08 : 0) |
- (encoding_at(1) & 7));
- }
-
- int8_t disp8() const {
- assert(length_ >= 2);
- return static_cast<int8_t>(encoding_[length_ - 1]);
- }
-
- AssemblerFixup *fixup() const { return fixup_; }
-
- protected:
- void SetModRM(int mod, GPRRegister rm) {
- assert((mod & ~3) == 0);
- encoding_[0] = (mod << 6) | (rm & 0x07);
- rex_ = (rm & 0x08) ? RexB : RexNone;
- length_ = 1;
- }
-
- void SetSIB(ScaleFactor scale, GPRRegister index, GPRRegister base) {
- assert(length_ == 1);
- assert((scale & ~3) == 0);
- encoding_[1] = (scale << 6) | ((index & 0x07) << 3) | (base & 0x07);
- rex_ =
- ((base & 0x08) ? RexB : RexNone) | ((index & 0x08) ? RexX : RexNone);
- length_ = 2;
- }
-
- void SetDisp8(int8_t disp) {
- assert(length_ == 1 || length_ == 2);
- encoding_[length_++] = static_cast<uint8_t>(disp);
- }
-
- void SetDisp32(int32_t disp) {
- assert(length_ == 1 || length_ == 2);
- intptr_t disp_size = sizeof(disp);
- memmove(&encoding_[length_], &disp, disp_size);
- length_ += disp_size;
- }
-
- void SetFixup(AssemblerFixup *fixup) { fixup_ = fixup; }
-
- private:
- AssemblerFixup *fixup_ = nullptr;
- uint8_t rex_ = 0;
- uint8_t encoding_[6];
- uint8_t length_ = 0;
-
- explicit AsmOperand(GPRRegister reg) : fixup_(nullptr) { SetModRM(3, reg); }
-
- /// Get the operand encoding byte at the given index.
- uint8_t encoding_at(intptr_t index) const {
- assert(index >= 0 && index < length_);
- return encoding_[index];
- }
-
- /// Returns whether or not this operand is really the given register in
- /// disguise. Used from the assembler to generate better encodings.
- bool IsRegister(GPRRegister reg) const {
- return ((encoding_[0] & 0xF8) ==
- 0xC0) // Addressing mode is register only.
- && (rm() == reg); // Register codes match.
- }
-
- friend class AssemblerX8664;
- };
-
- class AsmAddress : public AsmOperand {
- AsmAddress() = default;
-
- public:
- AsmAddress(const Variable *Var, const TargetX8664 *Target);
- AsmAddress(const X86OperandMem *Mem, Ice::Assembler *Asm,
- const Ice::TargetLowering *Target);
-
- // Address into the constant pool.
- AsmAddress(const Constant *Imm, Ice::Assembler *Asm) {
- // TODO(jpp): ???
- AssemblerFixup *Fixup = Asm->createFixup(FK_Abs, Imm);
- const RelocOffsetT Offset = 4;
- SetRipRelative(Offset, Fixup);
- }
-
- private:
- AsmAddress(const AsmAddress &) = default;
- AsmAddress(AsmAddress &&) = default;
- AsmAddress &operator=(const AsmAddress &) = default;
- AsmAddress &operator=(AsmAddress &&) = default;
-
- void SetBase(GPRRegister Base, int32_t Disp, AssemblerFixup *Fixup) {
- if (Fixup == nullptr && Disp == 0 &&
- (Base & 7) != RegX8664::Encoded_Reg_rbp) {
- SetModRM(0, Base);
- if ((Base & 7) == RegX8664::Encoded_Reg_rsp)
- SetSIB(TIMES_1, RegX8664::Encoded_Reg_rsp, Base);
- } else if (Fixup == nullptr && Utils::IsInt(8, Disp)) {
- SetModRM(1, Base);
- if ((Base & 7) == RegX8664::Encoded_Reg_rsp)
- SetSIB(TIMES_1, RegX8664::Encoded_Reg_rsp, Base);
- SetDisp8(Disp);
- } else {
- SetModRM(2, Base);
- if ((Base & 7) == RegX8664::Encoded_Reg_rsp)
- SetSIB(TIMES_1, RegX8664::Encoded_Reg_rsp, Base);
- SetDisp32(Disp);
- if (Fixup)
- SetFixup(Fixup);
- }
- }
-
- void SetIndex(GPRRegister Index, ScaleFactor Scale, int32_t Disp,
- AssemblerFixup *Fixup) {
- assert(Index != RegX8664::Encoded_Reg_rsp); // Illegal addressing mode.
- SetModRM(0, RegX8664::Encoded_Reg_rsp);
- SetSIB(Scale, Index, RegX8664::Encoded_Reg_rbp);
- SetDisp32(Disp);
- if (Fixup)
- SetFixup(Fixup);
- }
-
- void SetBaseIndex(GPRRegister Base, GPRRegister Index, ScaleFactor Scale,
- int32_t Disp, AssemblerFixup *Fixup) {
- assert(Index != RegX8664::Encoded_Reg_rsp); // Illegal addressing mode.
- if (Fixup == nullptr && Disp == 0 &&
- (Base & 7) != RegX8664::Encoded_Reg_rbp) {
- SetModRM(0, RegX8664::Encoded_Reg_rsp);
- SetSIB(Scale, Index, Base);
- } else if (Fixup == nullptr && Utils::IsInt(8, Disp)) {
- SetModRM(1, RegX8664::Encoded_Reg_rsp);
- SetSIB(Scale, Index, Base);
- SetDisp8(Disp);
- } else {
- SetModRM(2, RegX8664::Encoded_Reg_rsp);
- SetSIB(Scale, Index, Base);
- SetDisp32(Disp);
- if (Fixup)
- SetFixup(Fixup);
- }
- }
-
- /// Generate a RIP-relative address expression on x86-64.
- void SetRipRelative(RelocOffsetT Offset, AssemblerFixup *Fixup) {
- assert(Fixup != nullptr);
- assert(Fixup->kind() == FK_PcRel);
-
- SetModRM(0x0, RegX8664::Encoded_Reg_rbp);
-
- // Use the Offset in the displacement for now. If we decide to process
- // fixups later, we'll need to patch up the emitted displacement.
- SetDisp32(Offset);
- if (Fixup)
- SetFixup(Fixup);
- }
-
- /// Generate an absolute address.
- void SetAbsolute(RelocOffsetT Addr) {
- SetModRM(0x0, RegX8664::Encoded_Reg_rsp);
- static constexpr ScaleFactor NoScale = TIMES_1;
- SetSIB(NoScale, RegX8664::Encoded_Reg_rsp, RegX8664::Encoded_Reg_rbp);
- SetDisp32(Addr);
- }
- };
+ using GPRRegister = RegisterSet::GPRRegister;
+ using ByteRegister = RegisterSet::ByteRegister;
+ using XmmRegister = RegisterSet::XmmRegister;
//----------------------------------------------------------------------------
// __ ______ __ __ ______ ______ __ __ __ ______