virtual bool fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, bool Resolved,
uint64_t Value,
const MCRelaxableFragment *DF,
- const MCAsmLayout &Layout) const;
+ const MCAsmLayout &Layout,
+ const bool WasForced) const;
/// Simple predicate for targets where !Resolved implies requiring relaxation
virtual bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
/// evaluates to.
/// \param Value [out] On return, the value of the fixup as currently laid
/// out.
+ /// \param WasForced [out] On return, the value in the fixup is set to the
+ /// correct value if WasForced is true, even if evaluateFixup returns false.
/// \return Whether the fixup value was fully resolved. This is true if the
/// \p Value result is fixed, otherwise the value may change due to
/// relocation.
bool evaluateFixup(const MCAsmLayout &Layout, const MCFixup &Fixup,
const MCFragment *DF, MCValue &Target,
- uint64_t &Value) const;
+ uint64_t &Value, bool &WasForced) const;
/// Check whether a fixup can be satisfied, or whether it needs to be relaxed
/// (increased in size, in order to hold its value correctly).
bool MCAsmBackend::fixupNeedsRelaxationAdvanced(
const MCFixup &Fixup, bool Resolved, uint64_t Value,
- const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const {
+ const MCRelaxableFragment *DF, const MCAsmLayout &Layout,
+ const bool WasForced) const {
if (!Resolved)
return true;
return fixupNeedsRelaxation(Fixup, Value, DF, Layout);
bool MCAsmBackend::relaxFragment(MCPaddingFragment *PF, MCAsmLayout &Layout) {
return CodePadder->relaxFragment(PF, Layout);
-}
\ No newline at end of file
+}
bool MCAssembler::evaluateFixup(const MCAsmLayout &Layout,
const MCFixup &Fixup, const MCFragment *DF,
- MCValue &Target, uint64_t &Value) const {
+ MCValue &Target, uint64_t &Value,
+ bool &WasForced) const {
++stats::evaluateFixup;
// FIXME: This code has some duplication with recordRelocation. We should
const MCExpr *Expr = Fixup.getValue();
MCContext &Ctx = getContext();
Value = 0;
+ WasForced = false;
if (!Expr->evaluateAsRelocatable(Target, &Layout, &Fixup)) {
Ctx.reportError(Fixup.getLoc(), "expected relocatable expression");
return true;
}
// Let the backend force a relocation if needed.
- if (IsResolved && getBackend().shouldForceRelocation(*this, Fixup, Target))
+ if (IsResolved && getBackend().shouldForceRelocation(*this, Fixup, Target)) {
IsResolved = false;
+ WasForced = true;
+ }
return IsResolved;
}
// Evaluate the fixup.
MCValue Target;
uint64_t FixedValue;
- bool IsResolved = evaluateFixup(Layout, Fixup, &F, Target, FixedValue);
+ bool WasForced;
+ bool IsResolved = evaluateFixup(Layout, Fixup, &F, Target, FixedValue,
+ WasForced);
if (!IsResolved) {
// The fixup was unresolved, we need a relocation. Inform the object
// writer of the relocation, and give it an opportunity to adjust the
assert(getBackendPtr() && "Expected assembler backend");
MCValue Target;
uint64_t Value;
- bool Resolved = evaluateFixup(Layout, Fixup, DF, Target, Value);
+ bool WasForced;
+ bool Resolved = evaluateFixup(Layout, Fixup, DF, Target, Value, WasForced);
if (Target.getSymA() &&
Target.getSymA()->getKind() == MCSymbolRefExpr::VK_X86_ABS8 &&
Fixup.getKind() == FK_Data_1)
return false;
return getBackend().fixupNeedsRelaxationAdvanced(Fixup, Resolved, Value, DF,
- Layout);
+ Layout, WasForced);
}
bool MCAssembler::fragmentNeedsRelaxation(const MCRelaxableFragment *F,
bool fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, bool Resolved,
uint64_t Value,
const MCRelaxableFragment *DF,
- const MCAsmLayout &Layout) const override {
+ const MCAsmLayout &Layout,
+ const bool WasForced) const override {
MCInst const &MCB = DF->getInst();
assert(HexagonMCInstrInfo::isBundle(MCB));
bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
const MCRelaxableFragment *DF,
- const MCAsmLayout &Layout) const override;
+ const MCAsmLayout &Layout) const override {
+ llvm_unreachable("Handled by fixupNeedsRelaxationAdvanced");
+ }
+
+ bool fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, bool Resolved,
+ uint64_t Value,
+ const MCRelaxableFragment *DF,
+ const MCAsmLayout &Layout,
+ const bool WasForced) const override;
unsigned getNumFixupKinds() const override {
return RISCV::NumTargetFixupKinds;
};
-bool RISCVAsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup,
- uint64_t Value,
- const MCRelaxableFragment *DF,
- const MCAsmLayout &Layout) const {
+bool RISCVAsmBackend::fixupNeedsRelaxationAdvanced(const MCFixup &Fixup,
+ bool Resolved,
+ uint64_t Value,
+ const MCRelaxableFragment *DF,
+ const MCAsmLayout &Layout,
+ const bool WasForced) const {
+ // Return true if the symbol is actually unresolved.
+ // Resolved could be always false when shouldForceRelocation return true.
+ // We use !WasForced to indicate that the symbol is unresolved and not forced
+ // by shouldForceRelocation.
+ if (!Resolved && !WasForced)
+ return true;
+
int64_t Offset = int64_t(Value);
switch ((unsigned)Fixup.getKind()) {
default:
# RUN: | FileCheck -check-prefix=INSTR -check-prefix=FIXUP %s
# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+c < %s \
# RUN: | llvm-readobj -r | FileCheck -check-prefix=RELOC %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+c,+relax < %s \
+# RUN: | llvm-readobj -r | FileCheck -check-prefix=RELOC %s
# Check prefixes:
# RELOC - Check the relocation in the object.
# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+c < %s \
# RUN: | llvm-objdump -d -riscv-no-aliases - | FileCheck -check-prefix=INSTR %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+c,+relax < %s \
+# RUN: | llvm-objdump -d -riscv-no-aliases - | FileCheck -check-prefix=RELAX-INSTR %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+c,+relax < %s \
+# RUN: | llvm-readobj -r | FileCheck -check-prefix=RELAX-RELOC %s
FAR_JUMP_NEGATIVE:
c.nop
start:
c.bnez a0, NEAR
#INSTR: c.bnez a0, 72
+#RELAX-INSTR: c.bnez a0, 0
+#RELAX-RELOC: R_RISCV_RVC_BRANCH
c.bnez a0, NEAR_NEGATIVE
#INSTR: c.bnez a0, -4
+#RELAX-INSTR: c.bnez a0, 0
+#RELAX-RELOC: R_RISCV_RVC_BRANCH
c.bnez a0, FAR_BRANCH
#INSTR-NEXT: bne a0, zero, 326
+#RELAX-INSTR-NEXT: bne a0, zero, 0
+#RELAX-RELOC: R_RISCV_BRANCH
c.bnez a0, FAR_BRANCH_NEGATIVE
#INSTR-NEXT: bne a0, zero, -268
+#RELAX-INSTR-NEXT: bne a0, zero, 0
+#RELAX-RELOC: R_RISCV_BRANCH
c.bnez a0, FAR_JUMP
#INSTR-NEXT: bne a0, zero, 2320
+#RELAX-INSTR-NEXT: bne a0, zero, 0
+#RELAX-RELOC: R_RISCV_BRANCH
c.bnez a0, FAR_JUMP_NEGATIVE
#INSTR-NEXT: bne a0, zero, -2278
+#RELAX-INSTR-NEXT: bne a0, zero, 0
+#RELAX-RELOC: R_RISCV_BRANCH
c.beqz a0, NEAR
#INSTR-NEXT: c.beqz a0, 52
+#RELAX-INSTR-NEXT: c.beqz a0, 0
+#RELAX-RELOC: R_RISCV_RVC_BRANCH
c.beqz a0, NEAR_NEGATIVE
#INSTR-NEXT: c.beqz a0, -24
+#RELAX-INSTR-NEXT: c.beqz a0, 0
+#RELAX-RELOC: R_RISCV_RVC_BRANCH
c.beqz a0, FAR_BRANCH
#INSTR-NEXT: beq a0, zero, 306
+#RELAX-INSTR-NEXT: beq a0, zero, 0
+#RELAX-RELOC: R_RISCV_BRANCH
c.beqz a0, FAR_BRANCH_NEGATIVE
#INSTR-NEXT: beq a0, zero, -288
+#RELAX-INSTR-NEXT: beq a0, zero, 0
+#RELAX-RELOC: R_RISCV_BRANCH
c.beqz a0, FAR_JUMP
#INSTR-NEXT: beq a0, zero, 2300
+#RELAX-INSTR-NEXT: beq a0, zero, 0
+#RELAX-RELOC: R_RISCV_BRANCH
c.beqz a0, FAR_JUMP_NEGATIVE
#INSTR-NEXT: beq a0, zero, -2298
+#RELAX-INSTR-NEXT: beq a0, zero, 0
+#RELAX-RELOC: R_RISCV_BRANCH
c.j NEAR
#INSTR-NEXT: c.j 32
+#RELAX-INSTR-NEXT: c.j 0
+#RELAX-RELOC: R_RISCV_RVC_JUMP
c.j NEAR_NEGATIVE
#INSTR-NEXT: c.j -44
+#RELAX-INSTR-NEXT: c.j 0
+#RELAX-RELOC: R_RISCV_RVC_JUMP
c.j FAR_BRANCH
#INSTR-NEXT: c.j 286
+#RELAX-INSTR-NEXT: c.j 0
+#RELAX-RELOC: R_RISCV_RVC_JUMP
c.j FAR_BRANCH_NEGATIVE
#INSTR-NEXT: c.j -306
+#RELAX-INSTR-NEXT: c.j 0
+#RELAX-RELOC: R_RISCV_RVC_JUMP
c.j FAR_JUMP
#INSTR-NEXT: jal zero, 2284
+#RELAX-INSTR-NEXT: jal zero, 0
+#RELAX-RELOC: R_RISCV_JAL
c.j FAR_JUMP_NEGATIVE
#INSTR-NEXT: jal zero, -2314
+#RELAX-INSTR-NEXT: jal zero, 0
+#RELAX-RELOC: R_RISCV_JAL
c.jal NEAR
#INSTR: c.jal 16
+#RELAX-INSTR: c.jal 0
+#RELAX-RELOC: R_RISCV_RVC_JUMP
c.jal NEAR_NEGATIVE
#INSTR: c.jal -60
+#RELAX-INSTR: c.jal 0
+#RELAX-RELOC: R_RISCV_RVC_JUMP
c.jal FAR_BRANCH
#INSTR-NEXT: c.jal 270
+#RELAX-INSTR-NEXT: c.jal 0
+#RELAX-RELOC: R_RISCV_RVC_JUMP
c.jal FAR_BRANCH_NEGATIVE
#INSTR-NEXT: c.jal -322
+#RELAX-INSTR-NEXT: c.jal 0
+#RELAX-RELOC: R_RISCV_RVC_JUMP
c.jal FAR_JUMP
#INSTR-NEXT: jal ra, 2268
+#RELAX-INSTR-NEXT: jal ra, 0
+#RELAX-RELOC: R_RISCV_JAL
c.jal FAR_JUMP_NEGATIVE
#INSTR-NEXT: jal ra, -2330
+#RELAX-INSTR-NEXT: jal ra, 0
+#RELAX-RELOC: R_RISCV_JAL
NEAR:
c.nop
# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+c < %s \
# RUN: | llvm-objdump -d -riscv-no-aliases - | FileCheck -check-prefix=INSTR %s
+# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+c,+relax < %s \
+# RUN: | llvm-objdump -d -riscv-no-aliases - | FileCheck -check-prefix=RELAX-INSTR %s
+# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+c,+relax < %s \
+# RUN: | llvm-readobj -r | FileCheck -check-prefix=RELAX-RELOC %s
FAR_JUMP_NEGATIVE:
c.nop
start:
c.bnez a0, NEAR
#INSTR: c.bnez a0, 56
+#RELAX-INSTR: c.bnez a0, 0
+#RELAX-RELOC: R_RISCV_RVC_BRANCH
c.bnez a0, NEAR_NEGATIVE
#INSTR: c.bnez a0, -4
+#RELAX-INSTR: c.bnez a0, 0
+#RELAX-RELOC: R_RISCV_RVC_BRANCH
c.bnez a0, FAR_BRANCH
#INSTR-NEXT: bne a0, zero, 310
+#RELAX-INSTR-NEXT: bne a0, zero, 0
+#RELAX-RELOC: R_RISCV_BRANCH
c.bnez a0, FAR_BRANCH_NEGATIVE
#INSTR-NEXT: bne a0, zero, -268
+#RELAX-INSTR-NEXT: bne a0, zero, 0
+#RELAX-RELOC: R_RISCV_BRANCH
c.bnez a0, FAR_JUMP
#INSTR-NEXT: bne a0, zero, 2304
+#RELAX-INSTR-NEXT: bne a0, zero, 0
+#RELAX-RELOC: R_RISCV_BRANCH
c.bnez a0, FAR_JUMP_NEGATIVE
#INSTR-NEXT: bne a0, zero, -2278
+#RELAX-INSTR-NEXT: bne a0, zero, 0
+#RELAX-RELOC: R_RISCV_BRANCH
c.beqz a0, NEAR
#INSTR-NEXT: c.beqz a0, 36
+#RELAX-INSTR-NEXT: c.beqz a0, 0
+#RELAX-RELOC: R_RISCV_RVC_BRANCH
c.beqz a0, NEAR_NEGATIVE
#INSTR-NEXT: c.beqz a0, -24
+#RELAX-INSTR-NEXT: c.beqz a0, 0
+#RELAX-RELOC: R_RISCV_RVC_BRANCH
c.beqz a0, FAR_BRANCH
#INSTR-NEXT: beq a0, zero, 290
+#RELAX-INSTR-NEXT: beq a0, zero, 0
+#RELAX-RELOC: R_RISCV_BRANCH
c.beqz a0, FAR_BRANCH_NEGATIVE
#INSTR-NEXT: beq a0, zero, -288
+#RELAX-INSTR-NEXT: beq a0, zero, 0
+#RELAX-RELOC: R_RISCV_BRANCH
c.beqz a0, FAR_JUMP
#INSTR-NEXT: beq a0, zero, 2284
+#RELAX-INSTR-NEXT: beq a0, zero, 0
+#RELAX-RELOC: R_RISCV_BRANCH
c.beqz a0, FAR_JUMP_NEGATIVE
#INSTR-NEXT: beq a0, zero, -2298
+#RELAX-INSTR-NEXT: beq a0, zero, 0
+#RELAX-RELOC: R_RISCV_BRANCH
c.j NEAR
#INSTR-NEXT: c.j 16
+#RELAX-INSTR-NEXT: c.j 0
+#RELAX-RELOC: R_RISCV_RVC_JUMP
c.j NEAR_NEGATIVE
#INSTR-NEXT: c.j -44
+#RELAX-INSTR-NEXT: c.j 0
+#RELAX-RELOC: R_RISCV_RVC_JUMP
c.j FAR_BRANCH
#INSTR-NEXT: c.j 270
+#RELAX-INSTR-NEXT: c.j 0
+#RELAX-RELOC: R_RISCV_RVC_JUMP
c.j FAR_BRANCH_NEGATIVE
#INSTR-NEXT: c.j -306
+#RELAX-INSTR-NEXT: c.j 0
+#RELAX-RELOC: R_RISCV_RVC_JUMP
c.j FAR_JUMP
#INSTR-NEXT: jal zero, 2268
+#RELAX-INSTR-NEXT: jal zero, 0
+#RELAX-RELOC: R_RISCV_JAL
c.j FAR_JUMP_NEGATIVE
#INSTR-NEXT: jal zero, -2314
+#RELAX-INSTR-NEXT: jal zero, 0
+#RELAX-RELOC: R_RISCV_JAL
NEAR:
c.nop