]> granicus.if.org Git - llvm/commitdiff
AArch64: implement copy for paired GPR registers.
authorTim Northover <tnorthover@apple.com>
Thu, 7 Feb 2019 10:35:34 +0000 (10:35 +0000)
committerTim Northover <tnorthover@apple.com>
Thu, 7 Feb 2019 10:35:34 +0000 (10:35 +0000)
When doing 128-bit atomics using CASP we might need to copy a GPRPair to a
different register, but that was unimplemented up to now.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@353383 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/AArch64/AArch64InstrInfo.cpp
lib/Target/AArch64/AArch64InstrInfo.h
test/CodeGen/AArch64/seqpaircopy.mir [new file with mode: 0644]

index e2018ab7578ef5b6824dca67cd7444bd5b9cdfc2..f5d86c2e54aefb9ac5b7c17b2793224b3f284177 100644 (file)
@@ -2291,6 +2291,31 @@ void AArch64InstrInfo::copyPhysRegTuple(MachineBasicBlock &MBB,
   }
 }
 
+void AArch64InstrInfo::copyGPRRegTuple(MachineBasicBlock &MBB,
+                                       MachineBasicBlock::iterator I,
+                                       DebugLoc DL, unsigned DestReg,
+                                       unsigned SrcReg, bool KillSrc,
+                                       unsigned Opcode, unsigned ZeroReg,
+                                       llvm::ArrayRef<unsigned> Indices) const {
+  const TargetRegisterInfo *TRI = &getRegisterInfo();
+  unsigned NumRegs = Indices.size();
+
+#ifndef NDEBUG
+  uint16_t DestEncoding = TRI->getEncodingValue(DestReg);
+  uint16_t SrcEncoding = TRI->getEncodingValue(SrcReg);
+  assert(DestEncoding % NumRegs == 0 && SrcEncoding % NumRegs == 0 &&
+         "GPR reg sequences should not be able to overlap");
+#endif
+
+  for (unsigned SubReg = 0; SubReg != NumRegs; ++SubReg) {
+    const MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(Opcode));
+    AddSubReg(MIB, DestReg, Indices[SubReg], RegState::Define, TRI);
+    MIB.addReg(ZeroReg);
+    AddSubReg(MIB, SrcReg, Indices[SubReg], getKillRegState(KillSrc), TRI);
+    MIB.addImm(0);
+  }
+}
+
 void AArch64InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
                                    MachineBasicBlock::iterator I,
                                    const DebugLoc &DL, unsigned DestReg,
@@ -2430,6 +2455,22 @@ void AArch64InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
     return;
   }
 
+  if (AArch64::XSeqPairsClassRegClass.contains(DestReg) &&
+      AArch64::XSeqPairsClassRegClass.contains(SrcReg)) {
+    static const unsigned Indices[] = {AArch64::sube64, AArch64::subo64};
+    copyGPRRegTuple(MBB, I, DL, DestReg, SrcReg, KillSrc, AArch64::ORRXrs,
+                    AArch64::XZR, Indices);
+    return;
+  }
+
+  if (AArch64::WSeqPairsClassRegClass.contains(DestReg) &&
+      AArch64::WSeqPairsClassRegClass.contains(SrcReg)) {
+    static const unsigned Indices[] = {AArch64::sube32, AArch64::subo32};
+    copyGPRRegTuple(MBB, I, DL, DestReg, SrcReg, KillSrc, AArch64::ORRWrs,
+                    AArch64::WZR, Indices);
+    return;
+  }
+
   if (AArch64::FPR128RegClass.contains(DestReg) &&
       AArch64::FPR128RegClass.contains(SrcReg)) {
     if (Subtarget.hasNEON()) {
index f9e37845a4561b3d96ba44da23b6030d8b71dc61..537a812264ac6a290024e6deb7e6f015b8903df7 100644 (file)
@@ -121,6 +121,10 @@ public:
                         const DebugLoc &DL, unsigned DestReg, unsigned SrcReg,
                         bool KillSrc, unsigned Opcode,
                         llvm::ArrayRef<unsigned> Indices) const;
+  void copyGPRRegTuple(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
+                       DebugLoc DL, unsigned DestReg, unsigned SrcReg,
+                       bool KillSrc, unsigned Opcode, unsigned ZeroReg,
+                       llvm::ArrayRef<unsigned> Indices) const;
   void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
                    const DebugLoc &DL, unsigned DestReg, unsigned SrcReg,
                    bool KillSrc) const override;
diff --git a/test/CodeGen/AArch64/seqpaircopy.mir b/test/CodeGen/AArch64/seqpaircopy.mir
new file mode 100644 (file)
index 0000000..89511cb
--- /dev/null
@@ -0,0 +1,23 @@
+# RUN: llc -o - %s -mtriple=aarch64-- -mattr=+v8.1a -run-pass=postrapseudos | FileCheck %s
+---
+# CHECK-LABEL: name: copy_xseqpairs
+name: copy_xseqpairs
+body: |
+  bb.0:
+    ; CHECK: $x4_x5 = CASPALX $x4_x5, $x2_x3, $x0
+    ; CHECK: $x0 = ORRXrs $xzr, $x4, 0
+    ; CHECK: $x1 = ORRXrs $xzr, $x5, 0
+    $x4_x5 = CASPALX $x4_x5, $x2_x3, $x0
+    $x0_x1 = COPY $x4_x5
+...
+---
+# CHECK-LABEL: name: copy_wseqpairs
+name: copy_wseqpairs
+body: |
+  bb.0:
+    ; CHECK: $w4_w5 = CASPALW $w4_w5, $w2_w3, $x0
+    ; CHECK: $w0 = ORRWrs $wzr, $w4, 0
+    ; CHECK: $w1 = ORRWrs $wzr, $w5, 0
+    $w4_w5 = CASPALW $w4_w5, $w2_w3, $x0
+    $w0_w1 = COPY $w4_w5
+...