summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Hexagon/MCTargetDesc
diff options
context:
space:
mode:
authorColin LeMahieu <colinl@codeaurora.org>2015-06-15 21:52:13 +0000
committerColin LeMahieu <colinl@codeaurora.org>2015-06-15 21:52:13 +0000
commita071a8e5b6b3624c669b7e005349d70f8f2112c0 (patch)
tree672650f6abb080eb9e4f49b67cdc1043e765c041 /llvm/lib/Target/Hexagon/MCTargetDesc
parent9d8663f8d0d4f45088540851565d3d249687f209 (diff)
downloadbcm5719-llvm-a071a8e5b6b3624c669b7e005349d70f8f2112c0.tar.gz
bcm5719-llvm-a071a8e5b6b3624c669b7e005349d70f8f2112c0.zip
[Hexagon] PC-relative offsets are relative to packet start rather than the offset of the relocation. Set relocation addend and check it's correct in the ELF.
llvm-svn: 239769
Diffstat (limited to 'llvm/lib/Target/Hexagon/MCTargetDesc')
-rw-r--r--llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp41
1 files changed, 38 insertions, 3 deletions
diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp
index 1eee852996f..9fc4e2aeaba 100644
--- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp
+++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp
@@ -342,6 +342,36 @@ static Hexagon::Fixups getFixupNoBits(MCInstrInfo const &MCII, const MCInst &MI,
return LastTargetFixupKind;
}
+namespace llvm {
+extern const MCInstrDesc HexagonInsts[];
+}
+
+namespace {
+ bool isPCRel (unsigned Kind) {
+ switch(Kind){
+ case fixup_Hexagon_B22_PCREL:
+ case fixup_Hexagon_B15_PCREL:
+ case fixup_Hexagon_B7_PCREL:
+ case fixup_Hexagon_B13_PCREL:
+ case fixup_Hexagon_B9_PCREL:
+ case fixup_Hexagon_B32_PCREL_X:
+ case fixup_Hexagon_B22_PCREL_X:
+ case fixup_Hexagon_B15_PCREL_X:
+ case fixup_Hexagon_B13_PCREL_X:
+ case fixup_Hexagon_B9_PCREL_X:
+ case fixup_Hexagon_B7_PCREL_X:
+ case fixup_Hexagon_32_PCREL:
+ case fixup_Hexagon_PLT_B22_PCREL:
+ case fixup_Hexagon_GD_PLT_B22_PCREL:
+ case fixup_Hexagon_LD_PLT_B22_PCREL:
+ case fixup_Hexagon_6_PCREL_X:
+ return true;
+ default:
+ return false;
+ }
+ }
+}
+
unsigned HexagonMCCodeEmitter::getExprOpValue(const MCInst &MI,
const MCOperand &MO,
const MCExpr *ME,
@@ -363,7 +393,7 @@ unsigned HexagonMCCodeEmitter::getExprOpValue(const MCInst &MI,
Res = getExprOpValue(MI, MO, cast<MCBinaryExpr>(ME)->getLHS(), Fixups, STI);
Res +=
getExprOpValue(MI, MO, cast<MCBinaryExpr>(ME)->getRHS(), Fixups, STI);
- return Res;
+ return 0;
}
assert(MK == MCExpr::SymbolRef);
@@ -662,8 +692,13 @@ unsigned HexagonMCCodeEmitter::getExprOpValue(const MCInst &MI,
break;
}
- MCFixup fixup =
- MCFixup::create(*Addend, MO.getExpr(), MCFixupKind(FixupKind));
+ MCExpr const *FixupExpression = (*Addend > 0 && isPCRel(FixupKind)) ?
+ MCBinaryExpr::createAdd(MO.getExpr(),
+ MCConstantExpr::create(*Addend, MCT), MCT) :
+ MO.getExpr();
+
+ MCFixup fixup = MCFixup::create(*Addend, FixupExpression,
+ MCFixupKind(FixupKind), MI.getLoc());
Fixups.push_back(fixup);
// All of the information is in the fixup.
return (0);
OpenPOWER on IntegriCloud