From e39a156b921f47a374f091b43205555ee90cd555 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Wed, 25 Sep 2013 10:29:47 +0000 Subject: [PATCH] [SystemZ] Use subregs for 64-bit truncating stores Another patch to reduce the duplication of encoding information. Rather than define separate patterns for truncating 64-bit stores, use the 32-bit stores with a subreg. No behavioral changed intended. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191365 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/SystemZ/SystemZISelLowering.cpp | 12 ----- lib/Target/SystemZ/SystemZInstrInfo.cpp | 2 +- lib/Target/SystemZ/SystemZInstrInfo.td | 51 ++++++++++------------ lib/Target/SystemZ/SystemZPatterns.td | 46 +++++++++++++++++++ 4 files changed, 70 insertions(+), 41 deletions(-) diff --git a/lib/Target/SystemZ/SystemZISelLowering.cpp b/lib/Target/SystemZ/SystemZISelLowering.cpp index 81d824c7ff5..eb3dc498746 100644 --- a/lib/Target/SystemZ/SystemZISelLowering.cpp +++ b/lib/Target/SystemZ/SystemZISelLowering.cpp @@ -2872,18 +2872,6 @@ EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB) const { case SystemZ::SelectF128: return emitSelect(MI, MBB); - case SystemZ::CondStore8_32: - return emitCondStore(MI, MBB, SystemZ::STC32, 0, false); - case SystemZ::CondStore8_32Inv: - return emitCondStore(MI, MBB, SystemZ::STC32, 0, true); - case SystemZ::CondStore16_32: - return emitCondStore(MI, MBB, SystemZ::STH32, 0, false); - case SystemZ::CondStore16_32Inv: - return emitCondStore(MI, MBB, SystemZ::STH32, 0, true); - case SystemZ::CondStore32_32: - return emitCondStore(MI, MBB, SystemZ::ST32, SystemZ::STOC32, false); - case SystemZ::CondStore32_32Inv: - return emitCondStore(MI, MBB, SystemZ::ST32, SystemZ::STOC32, true); case SystemZ::CondStore8: return emitCondStore(MI, MBB, SystemZ::STC, 0, false); case SystemZ::CondStore8Inv: diff --git a/lib/Target/SystemZ/SystemZInstrInfo.cpp b/lib/Target/SystemZ/SystemZInstrInfo.cpp index 6f6b2bffba5..d20487ad367 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.cpp +++ b/lib/Target/SystemZ/SystemZInstrInfo.cpp @@ -819,7 +819,7 @@ void SystemZInstrInfo::getLoadStoreOpcodes(const TargetRegisterClass *RC, unsigned &StoreOpcode) const { if (RC == &SystemZ::GR32BitRegClass || RC == &SystemZ::ADDR32BitRegClass) { LoadOpcode = SystemZ::L; - StoreOpcode = SystemZ::ST32; + StoreOpcode = SystemZ::ST; } else if (RC == &SystemZ::GR64BitRegClass || RC == &SystemZ::ADDR64BitRegClass) { LoadOpcode = SystemZ::LG; diff --git a/lib/Target/SystemZ/SystemZInstrInfo.td b/lib/Target/SystemZ/SystemZInstrInfo.td index 94701726d50..cb48ca9a474 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.td +++ b/lib/Target/SystemZ/SystemZInstrInfo.td @@ -201,19 +201,19 @@ let Defs = [CC] in { def Select32 : SelectWrapper; def Select64 : SelectWrapper; -defm CondStore8_32 : CondStores; -defm CondStore16_32 : CondStores; -defm CondStore32_32 : CondStores; - -defm CondStore8 : CondStores; -defm CondStore16 : CondStores; -defm CondStore32 : CondStores; +defm CondStore32 : CondStores; + +defm : CondStores64; +defm : CondStores64; +defm : CondStores64; defm CondStore64 : CondStores; @@ -329,8 +329,7 @@ let Uses = [CC] in { // Register stores. let SimpleBDXStore = 1 in { - let isCodeGenOnly = 1 in - defm ST32 : StoreRXPair<"st", 0x50, 0xE350, store, GR32, 4>; + defm ST : StoreRXPair<"st", 0x50, 0xE350, store, GR32, 4>; def STG : StoreRXY<"stg", 0xE324, store, GR64, 8>; // These instructions are split after register allocation, so we don't @@ -340,15 +339,13 @@ let SimpleBDXStore = 1 in { [(store GR128:$src, bdxaddr20only128:$dst)]>; } } -let isCodeGenOnly = 1 in - def STRL32 : StoreRILPC<"strl", 0xC4F, aligned_store, GR32>; +def STRL : StoreRILPC<"strl", 0xC4F, aligned_store, GR32>; def STGRL : StoreRILPC<"stgrl", 0xC4B, aligned_store, GR64>; // Store on condition. let isCodeGenOnly = 1, Uses = [CC] in { - def STOC32 : CondStoreRSY<"stoc", 0xEBF3, GR32, 4>; - def STOC : CondStoreRSY<"stoc", 0xEBF3, GR64, 4>; - def STOCG : CondStoreRSY<"stocg", 0xEBE3, GR64, 8>; + def STOC : CondStoreRSY<"stoc", 0xEBF3, GR32, 4>; + def STOCG : CondStoreRSY<"stocg", 0xEBE3, GR64, 8>; } let Uses = [CC] in { def AsmSTOC : AsmCondStoreRSY<"stoc", 0xEBF3, GR32, 4>; @@ -459,18 +456,16 @@ def : Pat<(i32 (trunc GR64:$src)), (EXTRACT_SUBREG GR64:$src, subreg_32bit)>; // Truncations of 32-bit registers to memory. -let isCodeGenOnly = 1 in { - defm STC32 : StoreRXPair<"stc", 0x42, 0xE372, truncstorei8, GR32, 1>; - defm STH32 : StoreRXPair<"sth", 0x40, 0xE370, truncstorei16, GR32, 2>; - def STHRL32 : StoreRILPC<"sthrl", 0xC47, aligned_truncstorei16, GR32>; -} +defm STC : StoreRXPair<"stc", 0x42, 0xE372, truncstorei8, GR32, 1>; +defm STH : StoreRXPair<"sth", 0x40, 0xE370, truncstorei16, GR32, 2>; +def STHRL : StoreRILPC<"sthrl", 0xC47, aligned_truncstorei16, GR32>; // Truncations of 64-bit registers to memory. -defm STC : StoreRXPair<"stc", 0x42, 0xE372, truncstorei8, GR64, 1>; -defm STH : StoreRXPair<"sth", 0x40, 0xE370, truncstorei16, GR64, 2>; -def STHRL : StoreRILPC<"sthrl", 0xC47, aligned_truncstorei16, GR64>; -defm ST : StoreRXPair<"st", 0x50, 0xE350, truncstorei32, GR64, 4>; -def STRL : StoreRILPC<"strl", 0xC4F, aligned_truncstorei32, GR64>; +defm : StoreGR64Pair; +defm : StoreGR64Pair; +def : StoreGR64PC; +defm : StoreGR64Pair; +def : StoreGR64PC; //===----------------------------------------------------------------------===// // Multi-register moves diff --git a/lib/Target/SystemZ/SystemZPatterns.td b/lib/Target/SystemZ/SystemZPatterns.td index 481534b26a9..a1344a3a8e9 100644 --- a/lib/Target/SystemZ/SystemZPatterns.td +++ b/lib/Target/SystemZ/SystemZPatterns.td @@ -66,6 +66,52 @@ multiclass InsertMem; } +// INSN stores the low 32 bits of a GPR to a memory with addressing mode MODE. +// Record that it is equivalent to using OPERATOR to store a GR64. +class StoreGR64 + : Pat<(operator GR64:$R1, mode:$XBD2), + (insn (EXTRACT_SUBREG GR64:$R1, subreg_32bit), mode:$XBD2)>; + +// INSN and INSNY are an RX/RXY pair of instructions that store the low +// 32 bits of a GPR to memory. Record that they are equivalent to using +// OPERATOR to store a GR64. +multiclass StoreGR64Pair { + def : StoreGR64; + def : StoreGR64; +} + +// INSN stores the low 32 bits of a GPR using PC-relative addressing. +// Record that it is equivalent to using OPERATOR to store a GR64. +class StoreGR64PC + : Pat<(operator GR64:$R1, pcrel32:$XBD2), + (insn (EXTRACT_SUBREG GR64:$R1, subreg_32bit), pcrel32:$XBD2)> { + // We want PC-relative addresses to be tried ahead of BD and BDX addresses. + // However, BDXs have two extra operands and are therefore 6 units more + // complex. + let AddedComplexity = 7; +} + +// INSN and INSNINV conditionally store the low 32 bits of a GPR to memory, +// with INSN storing when the condition is true and INSNINV storing when the +// condition is false. Record that they are equivalent to a LOAD/select/STORE +// sequence for GR64s. +multiclass CondStores64 { + def : Pat<(store (z_select_ccmask GR64:$new, (load mode:$addr), + uimm8zx4:$valid, uimm8zx4:$cc), + mode:$addr), + (insn (EXTRACT_SUBREG GR64:$new, subreg_32bit), mode:$addr, + uimm8zx4:$valid, uimm8zx4:$cc)>; + def : Pat<(store (z_select_ccmask (load mode:$addr), GR64:$new, + uimm8zx4:$valid, uimm8zx4:$cc), + mode:$addr), + (insninv (EXTRACT_SUBREG GR64:$new, subreg_32bit), mode:$addr, + uimm8zx4:$valid, uimm8zx4:$cc)>; +} + // Try to use MVC instruction INSN for a load of type LOAD followed by a store // of the same size. VT is the type of the intermediate (legalized) value and // LENGTH is the number of bytes loaded by LOAD. -- 2.34.1