Commit 34946dfd authored by Kai Nacke's avatar Kai Nacke
Browse files

[SystemZ] Add implementation for the intrinsic llvm.read_register

This change implements the llvm intrinsic llvm.read_register for
the SystemZ platform which returns the value of the specified
register
(http://llvm.org/docs/LangRef.html#llvm-read-register-and-llvm-write-register-intrinsics).
This implementation returns the value of the stack register, and
can be extended to return the value of other registers. The
implementation for this intrinsic exists on various other platforms
including Power, x86, ARM, etc. but missing on SystemZ.

Reviewers: uweigand

Differential Revision: https://reviews.llvm.org/D73378
parent ea9850b6
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -1193,6 +1193,19 @@ SystemZTargetLowering::getRegForInlineAsmConstraint(
  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<Register>(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<SDValue> &Ops,
+3 −0
Original line number Diff line number Diff line
@@ -473,6 +473,9 @@ public:
    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
+15 −0
Original line number Diff line number Diff line
; 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"}