mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-28 19:31:58 +00:00
[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:
parent
9f3f4bf377
commit
e39a156b92
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user