Commit 27fddcc3 by John Porto

Subzero. Enables moar complex relocation offsets.

This CL allows ConstantRelocatables in to Subzero have symbolic constants. A symbolic constant is an assembly label whose value is not known during lowering, but it is well defined during code emission. For example, the following code is now possible in Subzero: foo: push $foo.bar jmp target nop nop foo.bar: ... BUG= R=stichnot@chromium.org Review URL: https://codereview.chromium.org/1651163002 .
parent 9aef39af
...@@ -142,8 +142,8 @@ ifdef FORCEASM ...@@ -142,8 +142,8 @@ ifdef FORCEASM
# resulting nexe. So we just disable those tests for now. # resulting nexe. So we just disable those tests for now.
FORCEASM_XTEST_EXCLUDES = -e x8632,sandbox,test_sync_atomic FORCEASM_XTEST_EXCLUDES = -e x8632,sandbox,test_sync_atomic
FORCEASM_LIT_PARAM = --param=FORCEASM FORCEASM_LIT_PARAM = --param=FORCEASM
# x86 sandboxing lit tests are disabled because llvm-mc uses different # x86 sandboxing lit tests are disabled because filetype=asm does not
# relocations for pushing return addresses onto the stack. # handle bundle_lock pad-to-end correctly.
# TODO(jpp): fix this. # TODO(jpp): fix this.
FORCEASM_LIT_TEST_EXCLUDES = --filter='^(?!.*/x86/sandboxing.ll).*' FORCEASM_LIT_TEST_EXCLUDES = --filter='^(?!.*/x86/sandboxing.ll).*'
else else
......
...@@ -238,9 +238,6 @@ class Assembler { ...@@ -238,9 +238,6 @@ class Assembler {
Assembler &operator=(const Assembler &) = delete; Assembler &operator=(const Assembler &) = delete;
public: public:
using InternalRelocationList =
std::vector<std::pair<const IceString, const SizeT>>;
enum AssemblerKind { enum AssemblerKind {
Asm_ARM32, Asm_ARM32,
Asm_MIPS32, Asm_MIPS32,
...@@ -328,23 +325,12 @@ public: ...@@ -328,23 +325,12 @@ public:
AssemblerKind getKind() const { return Kind; } AssemblerKind getKind() const { return Kind; }
void addRelocationAtCurrentPosition(const IceString &RelocName) {
if (!getPreliminary()) {
InternalRelocs.emplace_back(RelocName, getBufferSize());
}
}
const InternalRelocationList &getInternalRelocations() const {
return InternalRelocs;
}
protected: protected:
explicit Assembler(AssemblerKind Kind) explicit Assembler(AssemblerKind Kind)
: Kind(Kind), Allocator(), Buffer(*this) {} : Kind(Kind), Allocator(), Buffer(*this) {}
private: private:
const AssemblerKind Kind; const AssemblerKind Kind;
InternalRelocationList InternalRelocs;
ArenaAllocator<32 * 1024> Allocator; ArenaAllocator<32 * 1024> Allocator;
/// FunctionName and IsInternal are transferred from the original Cfg object, /// FunctionName and IsInternal are transferred from the original Cfg object,
......
...@@ -171,6 +171,7 @@ public: ...@@ -171,6 +171,7 @@ public:
Label *getOrCreateCfgNodeLabel(SizeT Number); Label *getOrCreateCfgNodeLabel(SizeT Number);
Label *getOrCreateLocalLabel(SizeT Number); Label *getOrCreateLocalLabel(SizeT Number);
void bindLocalLabel(SizeT Number); void bindLocalLabel(SizeT Number);
void bindRelocOffset(RelocOffset *Offset);
bool fixupIsPCRel(FixupKind Kind) const override { bool fixupIsPCRel(FixupKind Kind) const override {
// Currently assuming this is the only PC-rel relocation type used. // Currently assuming this is the only PC-rel relocation type used.
......
...@@ -106,6 +106,13 @@ void AssemblerX86Base<TraitsType>::bindLocalLabel(SizeT Number) { ...@@ -106,6 +106,13 @@ void AssemblerX86Base<TraitsType>::bindLocalLabel(SizeT Number) {
} }
template <typename TraitsType> template <typename TraitsType>
void AssemblerX86Base<TraitsType>::bindRelocOffset(RelocOffset *Offset) {
if (!getPreliminary()) {
Offset->setOffset(Buffer.getPosition());
}
}
template <typename TraitsType>
void AssemblerX86Base<TraitsType>::call(GPRRegister reg) { void AssemblerX86Base<TraitsType>::call(GPRRegister reg) {
AssemblerBuffer::EnsureCapacity ensured(&Buffer); AssemblerBuffer::EnsureCapacity ensured(&Buffer);
emitRexB(RexTypeIrrelevant, reg); emitRexB(RexTypeIrrelevant, reg);
......
...@@ -309,6 +309,8 @@ enum RandomizationPassesEnum { ...@@ -309,6 +309,8 @@ enum RandomizationPassesEnum {
RPE_num RPE_num
}; };
using RelocOffsetArray = llvm::SmallVector<class RelocOffset *, 4>;
} // end of namespace Ice } // end of namespace Ice
#endif // SUBZERO_SRC_ICEDEFS_H #endif // SUBZERO_SRC_ICEDEFS_H
...@@ -256,15 +256,6 @@ void ELFObjectWriter::writeFunctionCode(const IceString &FuncName, ...@@ -256,15 +256,6 @@ void ELFObjectWriter::writeFunctionCode(const IceString &FuncName,
SymTab->createDefinedSym(FuncName, SymbolType, SymbolBinding, Section, SymTab->createDefinedSym(FuncName, SymbolType, SymbolBinding, Section,
OffsetInSection, SymbolSize); OffsetInSection, SymbolSize);
StrTab->add(FuncName); StrTab->add(FuncName);
for (const auto &InternalReloc : Asm->getInternalRelocations()) {
const IceString &RelocName = InternalReloc.first;
constexpr uint8_t RelocSymbolType = STT_NOTYPE;
constexpr uint8_t RelocSymbolBinding = STB_LOCAL;
const SizeT RelocOffsetInSection = OffsetInSection + InternalReloc.second;
SymTab->createDefinedSym(RelocName, RelocSymbolType, RelocSymbolBinding,
Section, RelocOffsetInSection, SymbolSize);
StrTab->add(RelocName);
}
// Copy the fixup information from per-function Assembler memory to the // Copy the fixup information from per-function Assembler memory to the
// object writer's memory, for writing later. // object writer's memory, for writing later.
......
...@@ -44,8 +44,18 @@ ...@@ -44,8 +44,18 @@
namespace std { namespace std {
template <> struct hash<Ice::RelocatableTuple> { template <> struct hash<Ice::RelocatableTuple> {
size_t operator()(const Ice::RelocatableTuple &Key) const { size_t operator()(const Ice::RelocatableTuple &Key) const {
if (!Key.EmitString.empty()) {
return hash<Ice::IceString>()(Key.EmitString);
}
assert(!Key.OffsetExpr.empty());
if (Key.OffsetExpr[0]->hasOffset()) {
return hash<Ice::IceString>()(Key.Name) +
hash<Ice::RelocOffsetT>()(Key.OffsetExpr[0]->getOffset());
}
return hash<Ice::IceString>()(Key.Name) + return hash<Ice::IceString>()(Key.Name) +
hash<Ice::RelocOffsetT>()(Key.Offset); hash<std::size_t>()(Key.OffsetExpr.size());
} }
}; };
} // end of namespace std } // end of namespace std
...@@ -785,18 +795,28 @@ Constant *GlobalContext::getConstantDouble(double ConstantDouble) { ...@@ -785,18 +795,28 @@ Constant *GlobalContext::getConstantDouble(double ConstantDouble) {
return getConstPool()->Doubles.getOrAdd(this, ConstantDouble); return getConstPool()->Doubles.getOrAdd(this, ConstantDouble);
} }
Constant *GlobalContext::getConstantSym(RelocOffsetT Offset, Constant *GlobalContext::getConstantSym(const RelocOffsetArray &Offset,
const IceString &Name, const IceString &Name,
const IceString &EmitString,
bool SuppressMangling) { bool SuppressMangling) {
return getConstPool()->Relocatables.getOrAdd( return getConstPool()->Relocatables.getOrAdd(
this, RelocatableTuple(Offset, Name, SuppressMangling)); this, RelocatableTuple(Offset, Name, EmitString, SuppressMangling));
}
Constant *GlobalContext::getConstantSym(RelocOffsetT Offset,
const IceString &Name,
bool SuppressMangling) {
constexpr char EmptyEmitString[] = "";
return getConstantSym({RelocOffset::create(this, Offset)}, Name,
EmptyEmitString, SuppressMangling);
} }
Constant *GlobalContext::getConstantExternSym(const IceString &Name) { Constant *GlobalContext::getConstantExternSym(const IceString &Name) {
constexpr RelocOffsetT Offset = 0; constexpr RelocOffsetT Offset = 0;
constexpr bool SuppressMangling = true; constexpr bool SuppressMangling = true;
return getConstPool()->ExternRelocatables.getOrAdd( return getConstPool()->ExternRelocatables.getOrAdd(
this, RelocatableTuple(Offset, Name, SuppressMangling)); this, RelocatableTuple({RelocOffset::create(this, Offset)}, Name,
SuppressMangling));
} }
Constant *GlobalContext::getConstantUndef(Type Ty) { Constant *GlobalContext::getConstantUndef(Type Ty) {
......
...@@ -200,6 +200,9 @@ public: ...@@ -200,6 +200,9 @@ public:
Constant *getConstantFloat(float Value); Constant *getConstantFloat(float Value);
Constant *getConstantDouble(double Value); Constant *getConstantDouble(double Value);
/// Returns a symbolic constant. /// Returns a symbolic constant.
Constant *getConstantSym(const RelocOffsetArray &Offset,
const IceString &Name, const IceString &EmitString,
bool SuppressMangling);
Constant *getConstantSym(RelocOffsetT Offset, const IceString &Name, Constant *getConstantSym(RelocOffsetT Offset, const IceString &Name,
bool SuppressMangling); bool SuppressMangling);
Constant *getConstantExternSym(const IceString &Name); Constant *getConstantExternSym(const IceString &Name);
......
...@@ -337,13 +337,13 @@ template <typename TraitsType> struct InstImpl { ...@@ -337,13 +337,13 @@ template <typename TraitsType> struct InstImpl {
void emit(const Cfg *Func) const override; void emit(const Cfg *Func) const override;
void emitIAS(const Cfg *Func) const override; void emitIAS(const Cfg *Func) const override;
void dump(const Cfg *Func) const override; void dump(const Cfg *Func) const override;
void setIsReturnLocation(bool Value) { IsReturnLocation = Value; } void setRelocOffset(RelocOffset *Value) { OffsetReloc = Value; }
private: private:
InstX86Label(Cfg *Func, TargetLowering *Target); InstX86Label(Cfg *Func, TargetLowering *Target);
SizeT Number; // used for unique label generation. SizeT Number; // used for unique label generation.
bool IsReturnLocation = false; RelocOffset *OffsetReloc = nullptr;
}; };
/// Conditional and unconditional branch instruction. /// Conditional and unconditional branch instruction.
......
...@@ -459,10 +459,10 @@ void InstImpl<TraitsType>::InstX86Label::emit(const Cfg *Func) const { ...@@ -459,10 +459,10 @@ void InstImpl<TraitsType>::InstX86Label::emit(const Cfg *Func) const {
template <typename TraitsType> template <typename TraitsType>
void InstImpl<TraitsType>::InstX86Label::emitIAS(const Cfg *Func) const { void InstImpl<TraitsType>::InstX86Label::emitIAS(const Cfg *Func) const {
Assembler *Asm = Func->getAssembler<Assembler>(); Assembler *Asm = Func->getAssembler<Assembler>();
if (IsReturnLocation) {
Asm->addRelocationAtCurrentPosition(getName(Func));
}
Asm->bindLocalLabel(Number); Asm->bindLocalLabel(Number);
if (OffsetReloc != nullptr) {
Asm->bindRelocOffset(OffsetReloc);
}
} }
template <typename TraitsType> template <typename TraitsType>
......
...@@ -24,7 +24,66 @@ ...@@ -24,7 +24,66 @@
namespace Ice { namespace Ice {
bool operator==(const RelocatableTuple &A, const RelocatableTuple &B) { bool operator==(const RelocatableTuple &A, const RelocatableTuple &B) {
return A.Offset == B.Offset && A.Name == B.Name; // A and B are the same if:
// (1) they have the same name; and
// (2) they have the same offset.
//
// (1) is trivial to check, but (2) requires some care.
//
// For (2):
// if A and B have known offsets (i.e., no symbolic references), then
// A == B -> A.Offset == B.Offset.
// else each element i in A.OffsetExpr[i] must be the same (or have the same
// value) as B.OffsetExpr[i].
if (A.Name != B.Name) {
return false;
}
bool BothHaveKnownOffsets = true;
RelocOffsetT OffsetA = 0;
RelocOffsetT OffsetB = 0;
for (SizeT i = 0; i < A.OffsetExpr.size() && BothHaveKnownOffsets; ++i) {
BothHaveKnownOffsets = A.OffsetExpr[i]->hasOffset();
if (BothHaveKnownOffsets) {
OffsetA += A.OffsetExpr[i]->getOffset();
}
}
for (SizeT i = 0; i < B.OffsetExpr.size() && BothHaveKnownOffsets; ++i) {
BothHaveKnownOffsets = B.OffsetExpr[i]->hasOffset();
if (BothHaveKnownOffsets) {
OffsetB += B.OffsetExpr[i]->getOffset();
}
}
if (BothHaveKnownOffsets) {
// Both have known offsets (i.e., no unresolved symbolic references), so
// A == B -> A.Offset == B.Offset.
return OffsetA == OffsetB;
}
// Otherwise, A and B are not the same if their OffsetExpr's have different
// sizes.
if (A.OffsetExpr.size() != B.OffsetExpr.size()) {
return false;
}
// If the OffsetExprs' sizes are the same, then
// for each i in OffsetExprSize:
for (SizeT i = 0; i < A.OffsetExpr.size(); ++i) {
const auto *const RelocOffsetA = A.OffsetExpr[i];
const auto *const RelocOffsetB = B.OffsetExpr[i];
if (RelocOffsetA->hasOffset() && RelocOffsetB->hasOffset()) {
// A.OffsetExpr[i].Offset == B.OffsetExpr[i].Offset iff they are both
// defined;
if (RelocOffsetA->getOffset() != RelocOffsetB->getOffset()) {
return false;
}
} else if (RelocOffsetA != RelocOffsetB) {
// or, if they are undefined, then the RelocOffsets must be the same.
return false;
}
}
return true;
} }
bool operator<(const RegWeight &A, const RegWeight &B) { bool operator<(const RegWeight &A, const RegWeight &B) {
...@@ -501,8 +560,13 @@ void ConstantRelocatable::dump(const Cfg *Func, Ostream &Str) const { ...@@ -501,8 +560,13 @@ void ConstantRelocatable::dump(const Cfg *Func, Ostream &Str) const {
} else { } else {
Str << Name; Str << Name;
} }
if (Offset) const RelocOffsetT Offset = getOffset();
Str << "+" << Offset; if (Offset) {
if (Offset >= 0) {
Str << "+";
}
Str << Offset;
}
} }
void ConstantUndef::emit(TargetLowering *Target) const { Target->emit(this); } void ConstantUndef::emit(TargetLowering *Target) const { Target->emit(this); }
......
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
#include "llvm/Support/Format.h" #include "llvm/Support/Format.h"
#include <limits>
namespace Ice { namespace Ice {
class Operand { class Operand {
...@@ -247,6 +249,43 @@ inline void ConstantInteger64::dump(const Cfg *, Ostream &Str) const { ...@@ -247,6 +249,43 @@ inline void ConstantInteger64::dump(const Cfg *, Ostream &Str) const {
Str << static_cast<int64_t>(getValue()); Str << static_cast<int64_t>(getValue());
} }
/// RelocOffset allows symbolic references in ConstantRelocatables' offsets,
/// e.g., 8 + LabelOffset, where label offset is the location (code or data)
/// of a Label that is only determinable during ELF emission.
class RelocOffset final {
RelocOffset(const RelocOffset &) = delete;
RelocOffset &operator=(const RelocOffset &) = delete;
public:
static RelocOffset *create(GlobalContext *Ctx) {
return new (Ctx->allocate<RelocOffset>()) RelocOffset();
}
static RelocOffset *create(GlobalContext *Ctx, RelocOffsetT Value) {
return new (Ctx->allocate<RelocOffset>()) RelocOffset(Value);
}
bool hasOffset() const { return HasOffset; }
RelocOffsetT getOffset() const {
assert(HasOffset);
return Offset;
}
void setOffset(const RelocOffsetT Value) {
assert(!HasOffset);
Offset = Value;
HasOffset = true;
}
private:
RelocOffset() = default;
explicit RelocOffset(RelocOffsetT Offset) { setOffset(Offset); }
bool HasOffset = false;
RelocOffsetT Offset;
};
/// RelocatableTuple bundles the parameters that are used to construct an /// RelocatableTuple bundles the parameters that are used to construct an
/// ConstantRelocatable. It is done this way so that ConstantRelocatable can fit /// ConstantRelocatable. It is done this way so that ConstantRelocatable can fit
/// into the global constant pool template mechanism. /// into the global constant pool template mechanism.
...@@ -255,14 +294,22 @@ class RelocatableTuple { ...@@ -255,14 +294,22 @@ class RelocatableTuple {
RelocatableTuple &operator=(const RelocatableTuple &) = delete; RelocatableTuple &operator=(const RelocatableTuple &) = delete;
public: public:
RelocatableTuple(const RelocOffsetT Offset, const IceString &Name, RelocatableTuple(const RelocOffsetArray &OffsetExpr, const IceString &Name,
bool SuppressMangling) bool SuppressMangling)
: Offset(Offset), Name(Name), SuppressMangling(SuppressMangling) {} : OffsetExpr(OffsetExpr), Name(Name), SuppressMangling(SuppressMangling) {
}
RelocatableTuple(const RelocOffsetArray &OffsetExpr, const IceString &Name,
const IceString &EmitString, bool SuppressMangling)
: OffsetExpr(OffsetExpr), Name(Name), EmitString(EmitString),
SuppressMangling(SuppressMangling) {}
RelocatableTuple(const RelocatableTuple &) = default; RelocatableTuple(const RelocatableTuple &) = default;
const RelocOffsetT Offset; const RelocOffsetArray OffsetExpr;
const IceString Name; const IceString Name;
bool SuppressMangling; const IceString EmitString;
const bool SuppressMangling;
}; };
bool operator==(const RelocatableTuple &A, const RelocatableTuple &B); bool operator==(const RelocatableTuple &A, const RelocatableTuple &B);
...@@ -277,13 +324,22 @@ class ConstantRelocatable : public Constant { ...@@ -277,13 +324,22 @@ class ConstantRelocatable : public Constant {
public: public:
static ConstantRelocatable *create(GlobalContext *Ctx, Type Ty, static ConstantRelocatable *create(GlobalContext *Ctx, Type Ty,
const RelocatableTuple &Tuple) { const RelocatableTuple &Tuple) {
return new (Ctx->allocate<ConstantRelocatable>()) ConstantRelocatable( return new (Ctx->allocate<ConstantRelocatable>())
Ty, Tuple.Offset, Tuple.Name, Tuple.SuppressMangling); ConstantRelocatable(Ty, Tuple.OffsetExpr, Tuple.Name, Tuple.EmitString,
Tuple.SuppressMangling);
} }
RelocOffsetT getOffset() const { return Offset; } RelocOffsetT getOffset() const {
RelocOffsetT Offset = 0;
for (const auto *const OffsetReloc : OffsetExpr) {
Offset += OffsetReloc->getOffset();
}
return Offset;
}
const IceString &getEmitString() const { return EmitString; }
const IceString &getName() const { return Name; } const IceString &getName() const { return Name; }
void setSuppressMangling(bool Value) { SuppressMangling = Value; }
bool getSuppressMangling() const { return SuppressMangling; } bool getSuppressMangling() const { return SuppressMangling; }
using Constant::emit; using Constant::emit;
void emit(TargetLowering *Target) const final; void emit(TargetLowering *Target) const final;
...@@ -298,13 +354,16 @@ public: ...@@ -298,13 +354,16 @@ public:
} }
private: private:
ConstantRelocatable(Type Ty, RelocOffsetT Offset, const IceString &Name, ConstantRelocatable(Type Ty, const RelocOffsetArray &OffsetExpr,
const IceString &Name, const IceString &EmitString,
bool SuppressMangling) bool SuppressMangling)
: Constant(kConstRelocatable, Ty), Offset(Offset), Name(Name), : Constant(kConstRelocatable, Ty), OffsetExpr(OffsetExpr), Name(Name),
SuppressMangling(SuppressMangling) {} EmitString(EmitString), SuppressMangling(SuppressMangling) {}
const RelocOffsetT Offset; /// fixed offset to add
const IceString Name; /// optional for debug/dump const RelocOffsetArray OffsetExpr; /// fixed offset to add
bool SuppressMangling; const IceString Name; /// optional for debug/dump
const IceString EmitString; /// optional for textual emission
const bool SuppressMangling;
}; };
/// ConstantUndef represents an unspecified bit pattern. Although it is legal to /// ConstantUndef represents an unspecified bit pattern. Although it is legal to
......
...@@ -704,6 +704,13 @@ void TargetLowering::emitWithoutPrefix(const ConstantRelocatable *C, ...@@ -704,6 +704,13 @@ void TargetLowering::emitWithoutPrefix(const ConstantRelocatable *C,
if (!BuildDefs::dump()) if (!BuildDefs::dump())
return; return;
Ostream &Str = Ctx->getStrEmit(); Ostream &Str = Ctx->getStrEmit();
const IceString &EmitStr = C->getEmitString();
if (!EmitStr.empty()) {
// C has a custom emit string, so we use it instead of the canonical
// Name + Offset form.
Str << EmitStr;
return;
}
if (C->getSuppressMangling()) if (C->getSuppressMangling())
Str << C->getName(); Str << C->getName();
else else
......
...@@ -598,15 +598,44 @@ Inst *TargetX8664::emitCallToTarget(Operand *CallTarget, Variable *ReturnReg) { ...@@ -598,15 +598,44 @@ Inst *TargetX8664::emitCallToTarget(Operand *CallTarget, Variable *ReturnReg) {
Inst *NewCall = nullptr; Inst *NewCall = nullptr;
auto *CallTargetR = llvm::dyn_cast<Variable>(CallTarget); auto *CallTargetR = llvm::dyn_cast<Variable>(CallTarget);
if (NeedSandboxing) { if (NeedSandboxing) {
// In NaCl sandbox, calls are replaced by a push/jmp pair:
//
// push .after_call
// jmp CallTarget
// .align bundle_size
// after_call:
//
// In order to emit this sequence, we need a temporary label ("after_call",
// in this example.)
//
// The operand to push is a ConstantRelocatable. The easy way to implement
// this sequence is to create a ConstantRelocatable(0, "after_call"), but
// this ends up creating more relocations for the linker to resolve.
// Therefore, we create a ConstantRelocatable from the name of the function
// being compiled (i.e., ConstantRelocatable(after_call - Func, Func).
//
// By default, ConstantRelocatables are emitted (in textual output) as
//
// ConstantName + Offset
//
// ReturnReloc has an offset that is only known during binary emission.
// Therefore, we set a custom emit string for ReturnReloc that will be
// used instead. In this particular case, the code will be emitted as
//
// push .after_call
InstX86Label *ReturnAddress = InstX86Label::create(Func, this); InstX86Label *ReturnAddress = InstX86Label::create(Func, this);
ReturnAddress->setIsReturnLocation(true); auto *ReturnRelocOffset = RelocOffset::create(Ctx);
ReturnAddress->setRelocOffset(ReturnRelocOffset);
constexpr bool SuppressMangling = true; constexpr bool SuppressMangling = true;
const IceString EmitString = ReturnAddress->getName(Func);
auto *ReturnReloc = llvm::cast<ConstantRelocatable>(Ctx->getConstantSym(
{ReturnRelocOffset}, Ctx->mangleName(Func->getFunctionName()),
EmitString, SuppressMangling));
/* AutoBundle scoping */ { /* AutoBundle scoping */ {
std::unique_ptr<AutoBundle> Bundler; std::unique_ptr<AutoBundle> Bundler;
if (CallTargetR == nullptr) { if (CallTargetR == nullptr) {
Bundler = makeUnique<AutoBundle>(this, InstBundleLock::Opt_PadToEnd); Bundler = makeUnique<AutoBundle>(this, InstBundleLock::Opt_PadToEnd);
_push(Ctx->getConstantSym(0, ReturnAddress->getName(Func), _push(ReturnReloc);
SuppressMangling));
} else { } else {
Variable *T = makeReg(IceType_i32); Variable *T = makeReg(IceType_i32);
Variable *T64 = makeReg(IceType_i64); Variable *T64 = makeReg(IceType_i64);
...@@ -615,8 +644,7 @@ Inst *TargetX8664::emitCallToTarget(Operand *CallTarget, Variable *ReturnReg) { ...@@ -615,8 +644,7 @@ Inst *TargetX8664::emitCallToTarget(Operand *CallTarget, Variable *ReturnReg) {
_mov(T, CallTargetR); _mov(T, CallTargetR);
Bundler = makeUnique<AutoBundle>(this, InstBundleLock::Opt_PadToEnd); Bundler = makeUnique<AutoBundle>(this, InstBundleLock::Opt_PadToEnd);
_push(Ctx->getConstantSym(0, ReturnAddress->getName(Func), _push(ReturnReloc);
SuppressMangling));
const SizeT BundleSize = const SizeT BundleSize =
1 << Func->getAssembler<>()->getBundleAlignLog2Bytes(); 1 << Func->getAssembler<>()->getBundleAlignLog2Bytes();
_and(T, Ctx->getConstantInt32(~(BundleSize - 1))); _and(T, Ctx->getConstantInt32(~(BundleSize - 1)));
......
...@@ -74,7 +74,7 @@ struct TargetX8664Traits { ...@@ -74,7 +74,7 @@ struct TargetX8664Traits {
RegX8664::Encoded_Reg_eax; RegX8664::Encoded_Reg_eax;
static constexpr GPRRegister Encoded_Reg_Counter = RegX8664::Encoded_Reg_ecx; 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_PcRel = llvm::ELF::R_X86_64_PC32;
static constexpr FixupKind FK_Abs = llvm::ELF::R_X86_64_32; 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_Gotoff = llvm::ELF::R_X86_64_GOTOFF64;
static constexpr FixupKind FK_GotPC = llvm::ELF::R_X86_64_GOTPC32; static constexpr FixupKind FK_GotPC = llvm::ELF::R_X86_64_GOTPC32;
......
...@@ -28,9 +28,8 @@ entry: ...@@ -28,9 +28,8 @@ entry:
; CHECK: 1b: {{.*}} call 1c ; CHECK: 1b: {{.*}} call 1c
; CHECK-NEXT: 20: ; CHECK-NEXT: 20:
; X8664-LABEL: test_direct_call ; X8664-LABEL: test_direct_call
; X8664: push {{.*}}$local$__0 ; X8664: push {{.*}} R_X86_64_32S test_direct_call+{{.*}}20
; X8664: jmp {{.*}} call_target ; X8664: jmp {{.*}} call_target
; X8664: {{0+}}20 <{{.*}}$local$__0>:
; An indirect call sequence uses the right mask and register-call sequence. ; An indirect call sequence uses the right mask and register-call sequence.
define internal void @test_indirect_call(i32 %target) { define internal void @test_indirect_call(i32 %target) {
...@@ -46,11 +45,10 @@ entry: ...@@ -46,11 +45,10 @@ entry:
; CHECK-NEXT: call [[REG]] ; CHECK-NEXT: call [[REG]]
; CHECk-NEXT: 20: ; CHECk-NEXT: 20:
; X8664-LABEL: test_indirect_call ; X8664-LABEL: test_indirect_call
; X8664: push {{.*}}$local$__0 ; X8664: push {{.*}} R_X86_64_32S test_indirect_call+{{.*}}20
; X8664: {{.*}} and e[[REG:..]],0xffffffe0 ; X8664: {{.*}} and e[[REG:..]],0xffffffe0
; X8664: add r[[REG]],r15 ; X8664: add r[[REG]],r15
; X8664: jmp r[[REG]] ; X8664: jmp r[[REG]]
; X8664: {{0+}}20 <{{.*}}$local$__0>:
; A return sequence uses the right pop / mask / jmp sequence. ; A return sequence uses the right pop / mask / jmp sequence.
define internal void @test_ret() { define internal void @test_ret() {
...@@ -271,8 +269,7 @@ define internal void @bundle_lock_pad_to_end_padding_0(i32 %arg0, i32 %arg1, ...@@ -271,8 +269,7 @@ define internal void @bundle_lock_pad_to_end_padding_0(i32 %arg0, i32 %arg1,
; bundle boundary ; bundle boundary
ret void ret void
} }
; X8664-LABEL: bundle_lock_pad_to_end_padding_0$local$__0 ; X8664: 56: {{.*}} push {{.*}} R_X86_64_32S bundle_lock_pad_to_end_padding_0+{{.*}}60
; X8664: 56: {{.*}} push {{.*}}$local$__1
; X8664: 5b: {{.*}} jmp {{.*}} call_target ; X8664: 5b: {{.*}} jmp {{.*}} call_target
; X8664: 60: {{.*}} add ; X8664: 60: {{.*}} add
...@@ -289,8 +286,7 @@ define internal void @bundle_lock_pad_to_end_padding_11(i32 %arg0, i32 %arg1, ...@@ -289,8 +286,7 @@ define internal void @bundle_lock_pad_to_end_padding_11(i32 %arg0, i32 %arg1,
; bundle boundary ; bundle boundary
ret void ret void
} }
; X8664-LABEL: bundle_lock_pad_to_end_padding_11$local$__0 ; X8664: 4b: {{.*}} push {{.*}} R_X86_64_32S bundle_lock_pad_to_end_padding_11+{{.*}}60
; X8664: 4b: {{.*}} push {{.*}}$local$__1
; X8664: 50: {{.*}} jmp {{.*}} call_target ; X8664: 50: {{.*}} jmp {{.*}} call_target
; X8664: 55: {{.*}} nop ; X8664: 55: {{.*}} nop
; X8664: 5d: {{.*}} nop ; X8664: 5d: {{.*}} nop
...@@ -308,8 +304,7 @@ define internal void @bundle_lock_pad_to_end_padding_22(i32 %arg0, i32 %arg1, ...@@ -308,8 +304,7 @@ define internal void @bundle_lock_pad_to_end_padding_22(i32 %arg0, i32 %arg1,
; bundle boundary ; bundle boundary
ret void ret void
} }
; X8664-LABEL: bundle_lock_pad_to_end_padding_22$local$__0 ; X8664: 40: {{.*}} push {{.*}} R_X86_64_32S bundle_lock_pad_to_end_padding_22+{{.*}}60
; X8664: 40: {{.*}} push {{.*}}$local$__1
; X8664: 45: {{.*}} jmp {{.*}} call_target ; X8664: 45: {{.*}} jmp {{.*}} call_target
; X8664: 4a: {{.*}} nop ; X8664: 4a: {{.*}} nop
; X8664: 52: {{.*}} nop ; X8664: 52: {{.*}} nop
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment