OSDN Git Service

AMDGPU/SI: Emit fixups for long branches
authorTom Stellard <thomas.stellard@amd.com>
Fri, 7 Oct 2016 16:01:18 +0000 (16:01 +0000)
committerTom Stellard <thomas.stellard@amd.com>
Fri, 7 Oct 2016 16:01:18 +0000 (16:01 +0000)
Reviewers: arsenm

Subscribers: kzhuravl, wdng, nhaehnle, yaxunl, llvm-commits, tony-tye

Differential Revision: https://reviews.llvm.org/D25366

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@283570 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/AMDGPU/MCTargetDesc/AMDGPUAsmBackend.cpp

index 5e69739..021f3fe 100644 (file)
@@ -107,6 +107,24 @@ void AMDGPUAsmBackend::processFixupValue(const MCAssembler &Asm,
                                          const MCFixup &Fixup, const MCFragment *DF,
                                          const MCValue &Target, uint64_t &Value,
                                          bool &IsResolved) {
+  MCValue Res;
+
+  // When we have complex expressions like: BB0_1 + (BB0_2 - 4), which are
+  // used for long branches, this function will be called with
+  // IsResolved = false and Value set to some pre-computed value.  In
+  // the example above, the value would be:
+  // (BB0_1 + (BB0_2 - 4)) - CurrentOffsetFromStartOfFunction.
+  // This is not what we want.  We just want the expression computation
+  // only.  The reason the MC layer subtracts the current offset from the
+  // expression is because the fixup is of kind FK_PCRel_4.
+  // For these scenarios, evaluateAsValue gives us the computation that we
+  // want.
+  if (!IsResolved && Fixup.getValue()->evaluateAsValue(Res, Layout) &&
+      Res.isAbsolute()) {
+    Value = Res.getConstant();
+    IsResolved = true;
+
+  }
   if (IsResolved)
     Value = adjustFixupValue(Fixup, Value, &Asm.getContext());
 }