summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHal Finkel <hfinkel@anl.gov>2015-01-16 04:40:58 +0000
committerHal Finkel <hfinkel@anl.gov>2015-01-16 04:40:58 +0000
commit92cd0ca3b223c3115ae3efc87ab0f9cfcaa64403 (patch)
tree525568a5788a134f46605fa97d22dc339099a99d
parent525f296ef1f3f9f0254dab3dc30aef1dce4a7796 (diff)
[PowerPC] Adjust PatchPoints for ppc64le
Bill Schmidt pointed out that some adjustments would be needed to properly support powerpc64le (using the ELF V2 ABI). For one thing, R11 is not available as a scratch register, so we need to use R12. R12 is also available under ELF V1, so to maintain consistency, I flipped the order to make R12 the first scratch register in the array under both ABIs. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@226247 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--docs/StackMaps.rst11
-rw-r--r--lib/Target/PowerPC/PPCISelLowering.cpp10
-rw-r--r--test/CodeGen/PowerPC/ppc64-patchpoint.ll34
3 files changed, 34 insertions, 21 deletions
diff --git a/docs/StackMaps.rst b/docs/StackMaps.rst
index 5bb05540dec..43c60c9e785 100644
--- a/docs/StackMaps.rst
+++ b/docs/StackMaps.rst
@@ -221,11 +221,12 @@ lowered according to the calling convention specified at the
intrinsic's callsite. Variants of the intrinsic with non-void return
type also return a value according to calling convention.
-On PowerPC, note that the ``<target>`` must be the actual intended target of
-the indirect call, not the function-descriptor address normally used as the
-C/C++ function-pointer representation. As a result, the call target must be
-local because no adjustment or restoration of the TOC pointer (in register r2)
-will be performed.
+On PowerPC, note that ``<target>`` must be the actual intended target of
+the indirect call. Specifically, even when compiling for the ELF V1 ABI,
+``<target>`` is not the function-descriptor address normally used as the C/C++
+function-pointer representation. As a result, the call target must be local
+because no adjustment or restoration of the TOC pointer (in register r2) will
+be performed.
Requesting zero patch point arguments is valid. In this case, all
variable operands are handled just like
diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp
index 1f525fe7f8b..e17c4e675c6 100644
--- a/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -9910,8 +9910,16 @@ PPCTargetLowering::getScratchRegisters(CallingConv::ID) const {
// site. Hence we include LR in the scratch registers, which are in turn added
// as implicit-defs for stackmaps and patchpoints. The same reasoning applies
// to CTR, which is used by any indirect call.
+ if (Subtarget.isELFv2ABI()) {
+ static const MCPhysReg ScratchRegs[] = {
+ PPC::X12, PPC::LR8, PPC::CTR8, 0
+ };
+
+ return ScratchRegs;
+ }
+
static const MCPhysReg ScratchRegs[] = {
- PPC::X11, PPC::X12, PPC::LR8, PPC::CTR8, 0
+ PPC::X12, PPC::X11, PPC::LR8, PPC::CTR8, 0
};
return ScratchRegs;
diff --git a/test/CodeGen/PowerPC/ppc64-patchpoint.ll b/test/CodeGen/PowerPC/ppc64-patchpoint.ll
index 5e58fdab216..6580effbba2 100644
--- a/test/CodeGen/PowerPC/ppc64-patchpoint.ll
+++ b/test/CodeGen/PowerPC/ppc64-patchpoint.ll
@@ -1,6 +1,8 @@
-; RUN: llc < %s | FileCheck %s
-; RUN: llc -fast-isel -fast-isel-abort < %s | FileCheck %s
-target datalayout = "E-m:e-i64:64-n32:64"
+; RUN: llc < %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-BE
+; RUN: llc -fast-isel -fast-isel-abort < %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-BE
+; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu < %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-LE
+; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu -fast-isel -fast-isel-abort < %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-LE
+
target triple = "powerpc64-unknown-linux-gnu"
; Trivial patchpoint codegen
@@ -9,18 +11,18 @@ define i64 @trivial_patchpoint_codegen(i64 %p1, i64 %p2, i64 %p3, i64 %p4) {
entry:
; CHECK-LABEL: trivial_patchpoint_codegen:
-; CHECK: li 11, -8531
-; CHECK-NEXT: rldic 11, 11, 32, 16
-; CHECK-NEXT: oris 11, 11, 48879
-; CHECK-NEXT: ori 11, 11, 51966
-; CHECK-NEXT: mtctr 11
+; CHECK: li 12, -8531
+; CHECK-NEXT: rldic 12, 12, 32, 16
+; CHECK-NEXT: oris 12, 12, 48879
+; CHECK-NEXT: ori 12, 12, 51966
+; CHECK-NEXT: mtctr 12
; CHECK-NEXT: bctrl
-; CHECK: li 11, -8531
-; CHECK-NEXT: rldic 11, 11, 32, 16
-; CHECK-NEXT: oris 11, 11, 48879
-; CHECK-NEXT: ori 11, 11, 51967
-; CHECK-NEXT: mtctr 11
+; CHECK: li 12, -8531
+; CHECK-NEXT: rldic 12, 12, 32, 16
+; CHECK-NEXT: oris 12, 12, 48879
+; CHECK-NEXT: ori 12, 12, 51967
+; CHECK-NEXT: mtctr 12
; CHECK-NEXT: bctrl
; CHECK: blr
@@ -36,9 +38,11 @@ entry:
; as a leaf function.
;
; CHECK-LABEL: caller_meta_leaf
-; CHECK: stdu 1, -80(1)
+; CHECK-BE: stdu 1, -80(1)
+; CHECK-LE: stdu 1, -64(1)
; CHECK: Ltmp
-; CHECK: addi 1, 1, 80
+; CHECK-BE: addi 1, 1, 80
+; CHECK-LE: addi 1, 1, 64
; CHECK: blr
define void @caller_meta_leaf() {