From b97911c37b84b3591875de813941616c278c429b Mon Sep 17 00:00:00 2001 From: gonglingqin Date: Tue, 15 Nov 2022 16:09:26 +0800 Subject: [PATCH] [LoongArch] Implement the TargetLowering::getRegisterByName hook Only reserved registers can be read. Differential Revision: https://reviews.llvm.org/D137532 --- .../lib/Target/LoongArch/LoongArchISelLowering.cpp | 21 +++++++++++++++++ llvm/lib/Target/LoongArch/LoongArchISelLowering.h | 3 +++ llvm/test/CodeGen/LoongArch/get-reg.ll | 27 ++++++++++++++++++++++ 3 files changed, 51 insertions(+) create mode 100644 llvm/test/CodeGen/LoongArch/get-reg.ll diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp index 348f5cd..f038694 100644 --- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp +++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp @@ -2457,3 +2457,24 @@ void LoongArchTargetLowering::LowerAsmOperandForConstraint( } TargetLowering::LowerAsmOperandForConstraint(Op, Constraint, Ops, DAG); } + +#define GET_REGISTER_MATCHER +#include "LoongArchGenAsmMatcher.inc" + +Register +LoongArchTargetLowering::getRegisterByName(const char *RegName, LLT VT, + const MachineFunction &MF) const { + std::pair Name = StringRef(RegName).split('$'); + std::string NewRegName = Name.second.str(); + Register Reg = MatchRegisterAltName(NewRegName); + if (Reg == LoongArch::NoRegister) + Reg = MatchRegisterName(NewRegName); + if (Reg == LoongArch::NoRegister) + report_fatal_error( + Twine("Invalid register name \"" + StringRef(RegName) + "\".")); + BitVector ReservedRegs = Subtarget.getRegisterInfo()->getReservedRegs(MF); + if (!ReservedRegs.test(Reg)) + report_fatal_error(Twine("Trying to obtain non-reserved register \"" + + StringRef(RegName) + "\".")); + return Reg; +} diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.h b/llvm/lib/Target/LoongArch/LoongArchISelLowering.h index 3cb9999..4b7bf9d 100644 --- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.h +++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.h @@ -140,6 +140,9 @@ public: return ISD::SIGN_EXTEND; } + Register getRegisterByName(const char *RegName, LLT VT, + const MachineFunction &MF) const override; + private: /// Target-specific function used to lower LoongArch calling conventions. typedef bool LoongArchCCAssignFn(const DataLayout &DL, LoongArchABI::ABI ABI, diff --git a/llvm/test/CodeGen/LoongArch/get-reg.ll b/llvm/test/CodeGen/LoongArch/get-reg.ll new file mode 100644 index 0000000..323030d --- /dev/null +++ b/llvm/test/CodeGen/LoongArch/get-reg.ll @@ -0,0 +1,27 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s --mtriple=loongarch64 | FileCheck %s + +define i64 @get_stack() nounwind { +; CHECK-LABEL: get_stack: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: move $a0, $sp +; CHECK-NEXT: ret +entry: + %sp = call i64 @llvm.read_register.i64(metadata !0) + ret i64 %sp +} + +define void @set_stack(i64 %val) nounwind { +; CHECK-LABEL: set_stack: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: move $sp, $a0 +; CHECK-NEXT: ret +entry: + call void @llvm.write_register.i64(metadata !0, i64 %val) + ret void +} + +declare i64 @llvm.read_register.i64(metadata) nounwind +declare void @llvm.write_register.i64(metadata, i64) nounwind + +!0 = !{!"$sp\00"} -- 2.7.4