[Hexagon] PC-relative offsets are relative to packet start rather than the offset...
authorColin LeMahieu <colinl@codeaurora.org>
Mon, 15 Jun 2015 21:52:13 +0000 (21:52 +0000)
committerColin LeMahieu <colinl@codeaurora.org>
Mon, 15 Jun 2015 21:52:13 +0000 (21:52 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@239769 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp
test/CodeGen/Hexagon/simple_addend.ll [new file with mode: 0644]

index 1eee852996fdb33dd7d0d156dfde36c8b5b2a3e7..9fc4e2aeaba6ab243496fafcdf7f2ab7ca12fcd5 100644 (file)
@@ -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);
diff --git a/test/CodeGen/Hexagon/simple_addend.ll b/test/CodeGen/Hexagon/simple_addend.ll
new file mode 100644 (file)
index 0000000..d8ea61a
--- /dev/null
@@ -0,0 +1,10 @@
+; RUN: llc -march=hexagon -filetype=obj -o - < %s | llvm-objdump -d -r - | FileCheck %s
+
+declare void @bar(i32);
+
+define void @foo(i32 %a) {
+  %b = mul i32 %a, 3
+  call void @bar(i32 %b)
+  ret void
+}
+; CHECK:     0x8 R_HEX_B22_PCREL - 0x4