[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
This commit is contained in:
Hal Finkel 2014-05-11 19:29:11 +00:00
parent 24f554f052
commit 70a83b490e
10 changed files with 152 additions and 1 deletions

View File

@ -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.

View File

@ -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.

View File

@ -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,

View File

@ -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"}

View File

@ -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"}

View File

@ -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"}

View File

@ -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"}

View File

@ -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"}

View File

@ -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"}

View File

@ -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"}