diff options
author | Richard Sandiford <rsandifo@linux.vnet.ibm.com> | 2013-09-25 10:29:47 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@linux.vnet.ibm.com> | 2013-09-25 10:29:47 +0000 |
commit | e39a156b921f47a374f091b43205555ee90cd555 (patch) | |
tree | 04f843d6ac1662be6c62231a57552cbc3d9a21ad /lib | |
parent | 9f3f4bf377ac93fd32c8b93ae23378a82ad0f353 (diff) | |
download | external_llvm-e39a156b921f47a374f091b43205555ee90cd555.tar.gz external_llvm-e39a156b921f47a374f091b43205555ee90cd555.tar.bz2 external_llvm-e39a156b921f47a374f091b43205555ee90cd555.zip |
[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
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/SystemZ/SystemZISelLowering.cpp | 12 | ||||
-rw-r--r-- | lib/Target/SystemZ/SystemZInstrInfo.cpp | 2 | ||||
-rw-r--r-- | lib/Target/SystemZ/SystemZInstrInfo.td | 51 | ||||
-rw-r--r-- | 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 81d824c7ff..eb3dc49874 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 6f6b2bffba..d20487ad36 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 94701726d5..cb48ca9a47 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.td +++ b/lib/Target/SystemZ/SystemZInstrInfo.td @@ -201,19 +201,19 @@ let Defs = [CC] in { def Select32 : SelectWrapper<GR32>; def Select64 : SelectWrapper<GR64>; -defm CondStore8_32 : CondStores<GR32, nonvolatile_truncstorei8, - nonvolatile_anyextloadi8, bdxaddr20only>; -defm CondStore16_32 : CondStores<GR32, nonvolatile_truncstorei16, - nonvolatile_anyextloadi16, bdxaddr20only>; -defm CondStore32_32 : CondStores<GR32, nonvolatile_store, - nonvolatile_load, bdxaddr20only>; - -defm CondStore8 : CondStores<GR64, nonvolatile_truncstorei8, +defm CondStore8 : CondStores<GR32, nonvolatile_truncstorei8, nonvolatile_anyextloadi8, bdxaddr20only>; -defm CondStore16 : CondStores<GR64, nonvolatile_truncstorei16, +defm CondStore16 : CondStores<GR32, nonvolatile_truncstorei16, nonvolatile_anyextloadi16, bdxaddr20only>; -defm CondStore32 : CondStores<GR64, nonvolatile_truncstorei32, - nonvolatile_anyextloadi32, bdxaddr20only>; +defm CondStore32 : CondStores<GR32, nonvolatile_store, + nonvolatile_load, bdxaddr20only>; + +defm : CondStores64<CondStore8, CondStore8Inv, nonvolatile_truncstorei8, + nonvolatile_anyextloadi8, bdxaddr20only>; +defm : CondStores64<CondStore16, CondStore16Inv, nonvolatile_truncstorei16, + nonvolatile_anyextloadi16, bdxaddr20only>; +defm : CondStores64<CondStore32, CondStore32Inv, nonvolatile_truncstorei32, + nonvolatile_anyextloadi32, bdxaddr20only>; defm CondStore64 : CondStores<GR64, nonvolatile_store, nonvolatile_load, bdxaddr20only>; @@ -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<STC, STCY, truncstorei8>; +defm : StoreGR64Pair<STH, STHY, truncstorei16>; +def : StoreGR64PC<STHRL, aligned_truncstorei16>; +defm : StoreGR64Pair<ST, STY, truncstorei32>; +def : StoreGR64PC<STRL, aligned_truncstorei32>; //===----------------------------------------------------------------------===// // Multi-register moves diff --git a/lib/Target/SystemZ/SystemZPatterns.td b/lib/Target/SystemZ/SystemZPatterns.td index 481534b26a..a1344a3a8e 100644 --- a/lib/Target/SystemZ/SystemZPatterns.td +++ b/lib/Target/SystemZ/SystemZPatterns.td @@ -66,6 +66,52 @@ multiclass InsertMem<string type, Instruction insn, RegisterOperand cls, (insn cls:$src1, mode:$src2)>; } +// 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<Instruction insn, SDPatternOperator operator, + AddressingMode mode> + : 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<Instruction insn, Instruction insny, + SDPatternOperator operator> { + def : StoreGR64<insn, operator, bdxaddr12pair>; + def : StoreGR64<insny, operator, bdxaddr20pair>; +} + +// 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<Instruction insn, SDPatternOperator operator> + : 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<Instruction insn, Instruction insninv, + SDPatternOperator store, SDPatternOperator load, + AddressingMode mode> { + 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. |