forked from OSchip/llvm-project
[RISCV] Implement the TargetLowering::getRegisterByName hook
Summary: The hook should work for any RISC-V register. Non-allocatable registers do not need to be reserved, for the remaining the hook will only succeed if you pass clang the -ffixed-xX flag. This builds upon D67185, which currently only allows reserving GPRs. Reviewers: asb, lenary Reviewed By: lenary Tags: #llvm Differential Revision: https://reviews.llvm.org/D69130
This commit is contained in:
parent
91167e22ec
commit
51b4b17eb7
|
@ -2894,3 +2894,22 @@ bool RISCVTargetLowering::shouldExtendTypeInLibCall(EVT Type) const {
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
#define GET_REGISTER_MATCHER
|
||||
#include "RISCVGenAsmMatcher.inc"
|
||||
|
||||
Register
|
||||
RISCVTargetLowering::getRegisterByName(const char *RegName, EVT VT,
|
||||
const MachineFunction &MF) const {
|
||||
Register Reg = MatchRegisterAltName(RegName);
|
||||
if (Reg == RISCV::NoRegister)
|
||||
Reg = MatchRegisterName(RegName);
|
||||
if (Reg == RISCV::NoRegister)
|
||||
report_fatal_error(
|
||||
Twine("Invalid register name \"" + StringRef(RegName) + "\"."));
|
||||
BitVector ReservedRegs = Subtarget.getRegisterInfo()->getReservedRegs(MF);
|
||||
if (!ReservedRegs.test(Reg) && !Subtarget.isRegisterReservedByUser(Reg))
|
||||
report_fatal_error(Twine("Trying to obtain non-reserved register \"" +
|
||||
StringRef(RegName) + "\"."));
|
||||
return Reg;
|
||||
}
|
||||
|
|
|
@ -147,6 +147,13 @@ public:
|
|||
|
||||
bool shouldExtendTypeInLibCall(EVT Type) const override;
|
||||
|
||||
/// Returns the register with the specified architectural or ABI name. This
|
||||
/// method is necessary to lower the llvm.read_register.* and
|
||||
/// llvm.write_register.* intrinsics. Allocatable registers must be reserved
|
||||
/// with the clang -ffixed-xX flag for access to be allowed.
|
||||
Register getRegisterByName(const char *RegName, EVT VT,
|
||||
const MachineFunction &MF) const override;
|
||||
|
||||
private:
|
||||
void analyzeInputArgs(MachineFunction &MF, CCState &CCInfo,
|
||||
const SmallVectorImpl<ISD::InputArg> &Ins,
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
; RUN: not llc < %s -mtriple=riscv32 2>&1 | FileCheck %s
|
||||
|
||||
define i32 @get_invalid_reg() nounwind {
|
||||
entry:
|
||||
; CHECK: Invalid register name "notareg".
|
||||
%reg = call i32 @llvm.read_register.i32(metadata !0)
|
||||
ret i32 %reg
|
||||
}
|
||||
|
||||
declare i32 @llvm.read_register.i32(metadata) nounwind
|
||||
|
||||
!0 = !{!"notareg\00"}
|
|
@ -0,0 +1,38 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc < %s -mtriple=riscv32 | FileCheck %s
|
||||
|
||||
define i32 @get_stack() nounwind {
|
||||
; CHECK-LABEL: get_stack:
|
||||
; CHECK: # %bb.0: # %entry
|
||||
; CHECK-NEXT: mv a0, sp
|
||||
; CHECK-NEXT: ret
|
||||
entry:
|
||||
%sp = call i32 @llvm.read_register.i32(metadata !0)
|
||||
ret i32 %sp
|
||||
}
|
||||
|
||||
define void @set_stack(i32 %val) nounwind {
|
||||
; CHECK-LABEL: set_stack:
|
||||
; CHECK: # %bb.0: # %entry
|
||||
; CHECK-NEXT: mv sp, a0
|
||||
; CHECK-NEXT: ret
|
||||
entry:
|
||||
call void @llvm.write_register.i32(metadata !0, i32 %val)
|
||||
ret void
|
||||
}
|
||||
|
||||
define i32 @get_tp_arch_name() nounwind {
|
||||
; CHECK-LABEL: get_tp_arch_name:
|
||||
; CHECK: # %bb.0: # %entry
|
||||
; CHECK-NEXT: mv a0, tp
|
||||
; CHECK-NEXT: ret
|
||||
entry:
|
||||
%sp = call i32 @llvm.read_register.i32(metadata !1)
|
||||
ret i32 %sp
|
||||
}
|
||||
|
||||
declare i32 @llvm.read_register.i32(metadata) nounwind
|
||||
declare void @llvm.write_register.i32(metadata, i32) nounwind
|
||||
|
||||
!0 = !{!"sp\00"}
|
||||
!1 = !{!"x4\00"}
|
|
@ -0,0 +1,34 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: not llc < %s -mtriple=riscv32 -mattr +reserve-x8 2>&1 \
|
||||
; RUN: | FileCheck -check-prefix=NO-RESERVE-A1 %s
|
||||
; RUN: not llc < %s -mtriple=riscv32 -mattr +reserve-x11 2>&1 \
|
||||
; RUN: | FileCheck -check-prefix=NO-RESERVE-FP %s
|
||||
; RUN: llc < %s -mtriple=riscv32 -mattr +reserve-x8 -mattr +reserve-x11 \
|
||||
; RUN: | FileCheck -check-prefix=RESERVE %s
|
||||
|
||||
define i32 @get_reg_a1() nounwind {
|
||||
; NO-RESERVE-A1: Trying to obtain non-reserved register "a1".
|
||||
; RESERVE-LABEL: get_reg_a1:
|
||||
; RESERVE: # %bb.0: # %entry
|
||||
; RESERVE-NEXT: mv a0, a1
|
||||
; RESERVE-NEXT: ret
|
||||
entry:
|
||||
%a1 = call i32 @llvm.read_register.i32(metadata !0)
|
||||
ret i32 %a1
|
||||
}
|
||||
|
||||
define i32 @get_reg_fp() nounwind {
|
||||
; NO-RESERVE-FP: Trying to obtain non-reserved register "fp".
|
||||
; RESERVE-LABEL: get_reg_fp:
|
||||
; RESERVE: # %bb.0: # %entry
|
||||
; RESERVE-NEXT: mv a0, s0
|
||||
; RESERVE-NEXT: ret
|
||||
entry:
|
||||
%fp = call i32 @llvm.read_register.i32(metadata !1)
|
||||
ret i32 %fp
|
||||
}
|
||||
|
||||
declare i32 @llvm.read_register.i32(metadata) nounwind
|
||||
|
||||
!0 = !{!"a1\00"}
|
||||
!1 = !{!"fp\00"}
|
Loading…
Reference in New Issue