[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
This commit is contained in:
Richard Sandiford 2013-09-25 10:29:47 +00:00
parent 9f3f4bf377
commit e39a156b92
4 changed files with 70 additions and 41 deletions

View File

@ -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:

View File

@ -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;

View File

@ -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

View File

@ -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.