diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.h b/llvm/lib/Target/SystemZ/SystemZISelLowering.h --- a/llvm/lib/Target/SystemZ/SystemZISelLowering.h +++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.h @@ -473,6 +473,9 @@ return TargetLowering::getInlineAsmMemConstraint(ConstraintCode); } + Register getRegisterByName(const char *RegName, LLT VT, + const MachineFunction &MF) const override; + /// If a physical register, this returns the register that receives the /// exception address on entry to an EH pad. unsigned diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp --- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp +++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp @@ -1193,6 +1193,19 @@ return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT); } +// FIXME? Maybe this could be a TableGen attribute on some registers and +// this table could be generated automatically from RegInfo. +Register SystemZTargetLowering::getRegisterByName(const char *RegName, LLT VT, + const MachineFunction &MF) const { + + Register Reg = StringSwitch(RegName) + .Case("r15", SystemZ::R15D) + .Default(0); + if (Reg) + return Reg; + report_fatal_error("Invalid register name global variable"); +} + void SystemZTargetLowering:: LowerAsmOperandForConstraint(SDValue Op, std::string &Constraint, std::vector &Ops, diff --git a/llvm/test/CodeGen/SystemZ/stackpointer.ll b/llvm/test/CodeGen/SystemZ/stackpointer.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/SystemZ/stackpointer.ll @@ -0,0 +1,15 @@ +; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s + +define i8* @get_stack() nounwind { +entry: +; CHECK-LABEL: get_stack: +; CHECK: lgr %r2, %r15 +; CHECK-NEXT: br %r14 + %0 = call i64 @llvm.read_register.i64(metadata !0) + %1 = inttoptr i64 %0 to i8* + ret i8* %1 +} + +declare i64 @llvm.read_register.i64(metadata) nounwind + +!0 = !{!"r15"}