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; //---------------------------------------------------------------------------- // __ ______ __ __ ______ ______ __ __ __ ______