diff options
author | Hal Finkel <hfinkel@anl.gov> | 2014-05-11 19:29:11 +0000 |
---|---|---|
committer | Hal Finkel <hfinkel@anl.gov> | 2014-05-11 19:29:11 +0000 |
commit | 70a83b490ea9e2e9c5ae4991a8c71248467974c8 (patch) | |
tree | fd1b86d25cf4b3a6f29d80b7943f4048ae56b5c7 | |
parent | 24f554f05277413fd8ec77f80c3241d0298ab57f (diff) |
[PowerPC] Add global named register support
Support for the intrinsics that read from and write to global named registers
is added for r1, r2 and r13 (depending on the subtarget).
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@208509 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | docs/LangRef.rst | 2 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPCISelLowering.cpp | 25 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPCISelLowering.h | 2 | ||||
-rw-r--r-- | test/CodeGen/PowerPC/named-reg-alloc-r0.ll | 15 | ||||
-rw-r--r-- | test/CodeGen/PowerPC/named-reg-alloc-r1-64.ll | 18 | ||||
-rw-r--r-- | test/CodeGen/PowerPC/named-reg-alloc-r1.ll | 20 | ||||
-rw-r--r-- | test/CodeGen/PowerPC/named-reg-alloc-r13-64.ll | 18 | ||||
-rw-r--r-- | test/CodeGen/PowerPC/named-reg-alloc-r13.ll | 18 | ||||
-rw-r--r-- | test/CodeGen/PowerPC/named-reg-alloc-r2-64.ll | 17 | ||||
-rw-r--r-- | test/CodeGen/PowerPC/named-reg-alloc-r2.ll | 18 |
10 files changed, 152 insertions, 1 deletions
diff --git a/docs/LangRef.rst b/docs/LangRef.rst index 77433ab1422..54b606d037a 100644 --- a/docs/LangRef.rst +++ b/docs/LangRef.rst @@ -6848,7 +6848,7 @@ register in surrounding code, including inline assembly. Because of that, allocatable registers are not supported. Warning: So far it only works with the stack pointer on selected -architectures (ARM, ARM64, x86_64 and AArch64). Significant amount of +architectures (ARM, ARM64, AArch64, PowerPC and x86_64). Significant amount of work is needed to support other registers and even more so, allocatable registers. diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index e5fa0d6a24f..2fd5e1061a1 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -18,6 +18,7 @@ #include "PPCTargetMachine.h" #include "PPCTargetObjectFile.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringSwitch.h" #include "llvm/CodeGen/CallingConvLower.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" @@ -8757,6 +8758,30 @@ SDValue PPCTargetLowering::LowerFRAMEADDR(SDValue Op, return FrameAddr; } +// FIXME? Maybe this could be a TableGen attribute on some registers and +// this table could be generated automatically from RegInfo. +unsigned PPCTargetLowering::getRegisterByName(const char* RegName, + EVT VT) const { + bool isPPC64 = PPCSubTarget.isPPC64(); + bool isDarwinABI = PPCSubTarget.isDarwinABI(); + + if ((isPPC64 && VT != MVT::i64 && VT != MVT::i32) || + (!isPPC64 && VT != MVT::i32)) + report_fatal_error("Invalid register global variable type"); + + bool is64Bit = isPPC64 && VT == MVT::i64; + unsigned Reg = StringSwitch<unsigned>(RegName) + .Case("r1", is64Bit ? PPC::X1 : PPC::R1) + .Case("r2", isDarwinABI ? 0 : (is64Bit ? PPC::X2 : PPC::R2)) + .Case("r13", (!isPPC64 && isDarwinABI) ? 0 : + (is64Bit ? PPC::X13 : PPC::R13)) + .Default(0); + + if (Reg) + return Reg; + report_fatal_error("Invalid register name global variable"); +} + bool PPCTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const { // The PowerPC target isn't yet aware of offsets. diff --git a/lib/Target/PowerPC/PPCISelLowering.h b/lib/Target/PowerPC/PPCISelLowering.h index f05f5dd6a68..98bdf266438 100644 --- a/lib/Target/PowerPC/PPCISelLowering.h +++ b/lib/Target/PowerPC/PPCISelLowering.h @@ -398,6 +398,8 @@ namespace llvm { SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override; + unsigned getRegisterByName(const char* RegName, EVT VT) const override; + void computeMaskedBitsForTargetNode(const SDValue Op, APInt &KnownZero, APInt &KnownOne, diff --git a/test/CodeGen/PowerPC/named-reg-alloc-r0.ll b/test/CodeGen/PowerPC/named-reg-alloc-r0.ll new file mode 100644 index 00000000000..e683f99bd42 --- /dev/null +++ b/test/CodeGen/PowerPC/named-reg-alloc-r0.ll @@ -0,0 +1,15 @@ +; RUN: not llc < %s -mtriple=powerpc-apple-darwin 2>&1 | FileCheck %s +; RUN: not llc < %s -mtriple=powerpc-unknown-linux-gnu 2>&1 | FileCheck %s +; RUN: not llc < %s -mtriple=powerpc64-unknown-linux-gnu 2>&1 | FileCheck %s + +define i32 @get_reg() nounwind { +entry: +; FIXME: Include an allocatable-specific error message +; CHECK: Invalid register name global variable + %reg = call i32 @llvm.read_register.i32(metadata !0) + ret i32 %reg +} + +declare i32 @llvm.read_register.i32(metadata) nounwind + +!0 = metadata !{metadata !"r0\00"} diff --git a/test/CodeGen/PowerPC/named-reg-alloc-r1-64.ll b/test/CodeGen/PowerPC/named-reg-alloc-r1-64.ll new file mode 100644 index 00000000000..b047f9f9258 --- /dev/null +++ b/test/CodeGen/PowerPC/named-reg-alloc-r1-64.ll @@ -0,0 +1,18 @@ +; RUN: llc < %s -mtriple=powerpc64-apple-darwin 2>&1 | FileCheck %s --check-prefix=CHECK-DARWIN +; RUN: llc < %s -mtriple=powerpc64-unknown-linux-gnu 2>&1 | FileCheck %s + +define i64 @get_reg() nounwind { +entry: + %reg = call i64 @llvm.read_register.i64(metadata !0) + ret i64 %reg + +; CHECK-LABEL: @get_reg +; CHECK: mr 3, 1 + +; CHECK-DARWIN-LABEL: @get_reg +; CHECK-DARWIN: mr r3, r1 +} + +declare i64 @llvm.read_register.i64(metadata) nounwind + +!0 = metadata !{metadata !"r1\00"} diff --git a/test/CodeGen/PowerPC/named-reg-alloc-r1.ll b/test/CodeGen/PowerPC/named-reg-alloc-r1.ll new file mode 100644 index 00000000000..9d0eb34caa5 --- /dev/null +++ b/test/CodeGen/PowerPC/named-reg-alloc-r1.ll @@ -0,0 +1,20 @@ +; RUN: llc < %s -mtriple=powerpc-apple-darwin 2>&1 | FileCheck %s --check-prefix=CHECK-DARWIN +; RUN: llc < %s -mtriple=powerpc64-apple-darwin 2>&1 | FileCheck %s --check-prefix=CHECK-DARWIN +; RUN: llc < %s -mtriple=powerpc-unknown-linux-gnu 2>&1 | FileCheck %s +; RUN: llc < %s -mtriple=powerpc64-unknown-linux-gnu 2>&1 | FileCheck %s + +define i32 @get_reg() nounwind { +entry: + %reg = call i32 @llvm.read_register.i32(metadata !0) + ret i32 %reg + +; CHECK-LABEL: @get_reg +; CHECK: mr 3, 1 + +; CHECK-DARWIN-LABEL: @get_reg +; CHECK-DARWIN: mr r3, r1 +} + +declare i32 @llvm.read_register.i32(metadata) nounwind + +!0 = metadata !{metadata !"r1\00"} diff --git a/test/CodeGen/PowerPC/named-reg-alloc-r13-64.ll b/test/CodeGen/PowerPC/named-reg-alloc-r13-64.ll new file mode 100644 index 00000000000..df5085bbf7d --- /dev/null +++ b/test/CodeGen/PowerPC/named-reg-alloc-r13-64.ll @@ -0,0 +1,18 @@ +; RUN: llc < %s -mtriple=powerpc64-apple-darwin 2>&1 | FileCheck %s --check-prefix=CHECK-DARWIN +; RUN: llc < %s -mtriple=powerpc64-unknown-linux-gnu 2>&1 | FileCheck %s + +define i64 @get_reg() nounwind { +entry: + %reg = call i64 @llvm.read_register.i64(metadata !0) + ret i64 %reg + +; CHECK-LABEL: @get_reg +; CHECK: mr 3, 13 + +; CHECK-DARWIN-LABEL: @get_reg +; CHECK-DARWIN: mr r3, r13 +} + +declare i64 @llvm.read_register.i64(metadata) nounwind + +!0 = metadata !{metadata !"r13\00"} diff --git a/test/CodeGen/PowerPC/named-reg-alloc-r13.ll b/test/CodeGen/PowerPC/named-reg-alloc-r13.ll new file mode 100644 index 00000000000..900ebb2f485 --- /dev/null +++ b/test/CodeGen/PowerPC/named-reg-alloc-r13.ll @@ -0,0 +1,18 @@ +; RUN: not llc < %s -mtriple=powerpc-apple-darwin 2>&1 | FileCheck %s --check-prefix=CHECK-DARWIN +; RUN: llc < %s -mtriple=powerpc-unknown-linux-gnu 2>&1 | FileCheck %s +; RUN: llc < %s -mtriple=powerpc64-unknown-linux-gnu 2>&1 | FileCheck %s + +define i32 @get_reg() nounwind { +entry: +; FIXME: Include an allocatable-specific error message +; CHECK-DARWIN: Invalid register name global variable + %reg = call i32 @llvm.read_register.i32(metadata !0) + ret i32 %reg + +; CHECK-LABEL: @get_reg +; CHECK: mr 3, 13 +} + +declare i32 @llvm.read_register.i32(metadata) nounwind + +!0 = metadata !{metadata !"r13\00"} diff --git a/test/CodeGen/PowerPC/named-reg-alloc-r2-64.ll b/test/CodeGen/PowerPC/named-reg-alloc-r2-64.ll new file mode 100644 index 00000000000..0da33fa5f19 --- /dev/null +++ b/test/CodeGen/PowerPC/named-reg-alloc-r2-64.ll @@ -0,0 +1,17 @@ +; RUN: not llc < %s -mtriple=powerpc64-apple-darwin 2>&1 | FileCheck %s --check-prefix=CHECK-DARWIN +; RUN: llc < %s -mtriple=powerpc64-unknown-linux-gnu 2>&1 | FileCheck %s + +define i64 @get_reg() nounwind { +entry: +; FIXME: Include an allocatable-specific error message +; CHECK-DARWIN: Invalid register name global variable + %reg = call i64 @llvm.read_register.i64(metadata !0) + ret i64 %reg + +; CHECK-LABEL: @get_reg +; CHECK: mr 3, 2 +} + +declare i64 @llvm.read_register.i64(metadata) nounwind + +!0 = metadata !{metadata !"r2\00"} diff --git a/test/CodeGen/PowerPC/named-reg-alloc-r2.ll b/test/CodeGen/PowerPC/named-reg-alloc-r2.ll new file mode 100644 index 00000000000..51e7e3ee033 --- /dev/null +++ b/test/CodeGen/PowerPC/named-reg-alloc-r2.ll @@ -0,0 +1,18 @@ +; RUN: not llc < %s -mtriple=powerpc-apple-darwin 2>&1 | FileCheck %s --check-prefix=CHECK-DARWIN +; RUN: llc < %s -mtriple=powerpc-unknown-linux-gnu 2>&1 | FileCheck %s +; RUN: llc < %s -mtriple=powerpc64-unknown-linux-gnu 2>&1 | FileCheck %s + +define i32 @get_reg() nounwind { +entry: +; FIXME: Include an allocatable-specific error message +; CHECK-DARWIN: Invalid register name global variable + %reg = call i32 @llvm.read_register.i32(metadata !0) + ret i32 %reg + +; CHECK-LABEL: @get_reg +; CHECK: mr 3, 2 +} + +declare i32 @llvm.read_register.i32(metadata) nounwind + +!0 = metadata !{metadata !"r2\00"} |