[llvm] ea60057 - MCFixup: Add PCRel to ctor parameter and set it in X86MCCodeEmitter
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 4 13:30:43 PDT 2025
Author: Fangrui Song
Date: 2025-07-04T13:30:38-07:00
New Revision: ea600576a6f94d6f28925c4b99962cc26b463c29
URL: https://github.com/llvm/llvm-project/commit/ea600576a6f94d6f28925c4b99962cc26b463c29
DIFF: https://github.com/llvm/llvm-project/commit/ea600576a6f94d6f28925c4b99962cc26b463c29.diff
LOG: MCFixup: Add PCRel to ctor parameter and set it in X86MCCodeEmitter
Added:
Modified:
llvm/include/llvm/MC/MCFixup.h
llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/MC/MCFixup.h b/llvm/include/llvm/MC/MCFixup.h
index ac8e0865e4af1..a8b6281f2fa4b 100644
--- a/llvm/include/llvm/MC/MCFixup.h
+++ b/llvm/include/llvm/MC/MCFixup.h
@@ -73,6 +73,10 @@ class MCFixup {
/// determine how the operand value should be encoded into the instruction.
uint16_t Kind = FK_NONE;
+ /// True if this is a PC-relative fixup. The relocatable expression is
+ /// typically resolved When SymB is nullptr and SymA is a local symbol defined
+ /// within the current section. While MCAssembler currently sets this based on
+ /// FKF_IsPCRel, targets should ideally set it at creation.
bool PCRel = false;
/// Used by RISC-V style linker relaxation. Whether the fixup is
@@ -82,11 +86,13 @@ class MCFixup {
/// Consider bit fields if we need more flags.
public:
- static MCFixup create(uint32_t Offset, const MCExpr *Value, uint16_t Kind) {
+ static MCFixup create(uint32_t Offset, const MCExpr *Value, uint16_t Kind,
+ bool PCRel = false) {
MCFixup FI;
FI.Value = Value;
FI.Offset = Offset;
FI.Kind = Kind;
+ FI.PCRel = PCRel;
return FI;
}
static MCFixup create(uint32_t Offset, const MCExpr *Value,
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
index fbffc93a6392f..1666518e3365c 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
@@ -359,7 +359,7 @@ class X86MCCodeEmitter : public MCCodeEmitter {
unsigned getX86RegEncoding(const MCInst &MI, unsigned OpNum) const;
void emitImmediate(const MCOperand &Disp, SMLoc Loc, unsigned ImmSize,
- MCFixupKind FixupKind, uint64_t StartByte,
+ unsigned FixupKind, uint64_t StartByte,
SmallVectorImpl<char> &CB,
SmallVectorImpl<MCFixup> &Fixups, int ImmOffset = 0) const;
@@ -528,7 +528,7 @@ unsigned X86MCCodeEmitter::getX86RegEncoding(const MCInst &MI,
}
void X86MCCodeEmitter::emitImmediate(const MCOperand &DispOp, SMLoc Loc,
- unsigned Size, MCFixupKind FixupKind,
+ unsigned Size, unsigned FixupKind,
uint64_t StartByte,
SmallVectorImpl<char> &CB,
SmallVectorImpl<MCFixup> &Fixups,
@@ -549,65 +549,71 @@ void X86MCCodeEmitter::emitImmediate(const MCOperand &DispOp, SMLoc Loc,
// If we have an immoffset, add it to the expression.
if ((FixupKind == FK_Data_4 || FixupKind == FK_Data_8 ||
- FixupKind == MCFixupKind(X86::reloc_signed_4byte))) {
+ FixupKind == X86::reloc_signed_4byte)) {
GlobalOffsetTableExprKind Kind = startsWithGlobalOffsetTable(Expr);
if (Kind != GOT_None) {
assert(ImmOffset == 0);
if (Size == 8) {
- FixupKind =
- MCFixupKind(FirstLiteralRelocationKind + ELF::R_X86_64_GOTPC64);
+ FixupKind = FirstLiteralRelocationKind + ELF::R_X86_64_GOTPC64;
} else {
assert(Size == 4);
- FixupKind = MCFixupKind(X86::reloc_global_offset_table);
+ FixupKind = X86::reloc_global_offset_table;
}
if (Kind == GOT_Normal)
ImmOffset = static_cast<int>(CB.size() - StartByte);
} else if (Expr->getKind() == MCExpr::SymbolRef) {
if (hasSecRelSymbolRef(Expr)) {
- FixupKind = MCFixupKind(FK_SecRel_4);
+ FixupKind = FK_SecRel_4;
}
} else if (Expr->getKind() == MCExpr::Binary) {
const MCBinaryExpr *Bin = static_cast<const MCBinaryExpr *>(Expr);
if (hasSecRelSymbolRef(Bin->getLHS()) ||
hasSecRelSymbolRef(Bin->getRHS())) {
- FixupKind = MCFixupKind(FK_SecRel_4);
+ FixupKind = FK_SecRel_4;
}
}
}
// If the fixup is pc-relative, we need to bias the value to be relative to
// the start of the field, not the end of the field.
- if (FixupKind == FK_PCRel_4 ||
- FixupKind == MCFixupKind(X86::reloc_riprel_4byte) ||
- FixupKind == MCFixupKind(X86::reloc_riprel_4byte_movq_load) ||
- FixupKind == MCFixupKind(X86::reloc_riprel_4byte_movq_load_rex2) ||
- FixupKind == MCFixupKind(X86::reloc_riprel_4byte_relax) ||
- FixupKind == MCFixupKind(X86::reloc_riprel_4byte_relax_rex) ||
- FixupKind == MCFixupKind(X86::reloc_riprel_4byte_relax_rex2) ||
- FixupKind == MCFixupKind(X86::reloc_branch_4byte_pcrel) ||
- FixupKind == MCFixupKind(X86::reloc_riprel_4byte_relax_evex)) {
+ bool PCRel = false;
+ switch (FixupKind) {
+ case FK_PCRel_1:
+ PCRel = true;
+ ImmOffset -= 1;
+ break;
+ case FK_PCRel_2:
+ PCRel = true;
+ ImmOffset -= 2;
+ break;
+ case FK_PCRel_4:
+ case X86::reloc_riprel_4byte:
+ case X86::reloc_riprel_4byte_movq_load:
+ case X86::reloc_riprel_4byte_movq_load_rex2:
+ case X86::reloc_riprel_4byte_relax:
+ case X86::reloc_riprel_4byte_relax_rex:
+ case X86::reloc_riprel_4byte_relax_rex2:
+ case X86::reloc_branch_4byte_pcrel:
+ case X86::reloc_riprel_4byte_relax_evex:
+ PCRel = true;
ImmOffset -= 4;
// If this is a pc-relative load off _GLOBAL_OFFSET_TABLE_:
// leaq _GLOBAL_OFFSET_TABLE_(%rip), %r15
// this needs to be a GOTPC32 relocation.
if (startsWithGlobalOffsetTable(Expr) != GOT_None)
- FixupKind = MCFixupKind(X86::reloc_global_offset_table);
+ FixupKind = X86::reloc_global_offset_table;
+ break;
}
- if (FixupKind == FK_PCRel_2)
- ImmOffset -= 2;
- if (FixupKind == FK_PCRel_1)
- ImmOffset -= 1;
-
if (ImmOffset)
Expr = MCBinaryExpr::createAdd(Expr, MCConstantExpr::create(ImmOffset, Ctx),
Ctx, Expr->getLoc());
// Emit a symbolic constant as a fixup and 4 zeros.
Fixups.push_back(MCFixup::create(static_cast<uint32_t>(CB.size() - StartByte),
- Expr, FixupKind));
+ Expr, FixupKind, PCRel));
emitConstant(0, Size, CB);
}
More information about the llvm-commits
mailing list