1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-21 20:12:56 +02:00

[Hexagon] Fixes/changes to instruction selection

- Add patterns for rr/abs addressing modes.
- Set addrMode to PostInc where necessary.
- Misc fixes.

llvm-svn: 275574
This commit is contained in:
Krzysztof Parzyszek 2016-07-15 16:29:02 +00:00
parent f9a637b0bf
commit af2caac28b
2 changed files with 72 additions and 27 deletions

View File

@ -2052,7 +2052,7 @@ let Defs = [R29, R30, R31], Uses = [R30], hasSideEffects = 0 in
}
// Load / Post increment circular addressing mode.
let Uses = [CS], hasSideEffects = 0 in
let Uses = [CS], hasSideEffects = 0, addrMode = PostInc in
class T_load_pcr<string mnemonic, RegisterClass RC, bits<4> MajOp>
: LDInst <(outs RC:$dst, IntRegs:$_dst_),
(ins IntRegs:$Rz, ModRegs:$Mu),
@ -2099,7 +2099,7 @@ let accessSize = DoubleWordAccess in
def L2_loadrd_pcr : T_load_pcr <"memd", DoubleRegs, 0b1110>;
// Load / Post increment circular addressing mode.
let Uses = [CS], hasSideEffects = 0 in
let Uses = [CS], hasSideEffects = 0, addrMode = PostInc in
class T_loadalign_pcr<string mnemonic, bits<4> MajOp, MemAccessSize AccessSz >
: LDInst <(outs DoubleRegs:$dst, IntRegs:$_dst_),
(ins DoubleRegs:$_src_, IntRegs:$Rz, ModRegs:$Mu),
@ -2128,7 +2128,7 @@ def L2_loadalignh_pcr : T_loadalign_pcr <"memh_fifo", 0b0010, HalfWordAccess>;
//===----------------------------------------------------------------------===//
// Circular loads with immediate offset.
//===----------------------------------------------------------------------===//
let Uses = [CS], mayLoad = 1, hasSideEffects = 0 in
let Uses = [CS], mayLoad = 1, hasSideEffects = 0, addrMode = PostInc in
class T_load_pci <string mnemonic, RegisterClass RC,
Operand ImmOp, bits<4> MajOp>
: LDInstPI<(outs RC:$dst, IntRegs:$_dst_),
@ -2240,7 +2240,7 @@ def S4_stored_locked : T_store_locked <"memd_locked", DoubleRegs>;
//===----------------------------------------------------------------------===//
// Bit-reversed loads with auto-increment register
//===----------------------------------------------------------------------===//
let hasSideEffects = 0 in
let hasSideEffects = 0, addrMode = PostInc in
class T_load_pbr<string mnemonic, RegisterClass RC,
MemAccessSize addrSize, bits<4> majOp>
: LDInst
@ -3609,7 +3609,8 @@ multiclass Storexm_pat<PatFrag Store, PatFrag Value, PatLeaf ImmPred,
// swapped. This relies on the knowledge that the F.Fragment uses names
// "ptr" and "val".
class SwapSt<PatFrag F>
: PatFrag<(ops node:$val, node:$ptr), F.Fragment>;
: PatFrag<(ops node:$val, node:$ptr), F.Fragment, F.PredicateCode,
F.OperandTransform>;
let AddedComplexity = 20 in {
defm: Storex_pat<truncstorei8, I32, s32_0ImmPred, S2_storerb_io>;
@ -3673,7 +3674,7 @@ def S2_allocframe: ST0Inst <
// S2_storer[bhwdf]_pci: Store byte/half/word/double.
// S2_storer[bhwdf]_pci -> S2_storerbnew_pci
let Uses = [CS] in
let Uses = [CS], addrMode = PostInc in
class T_store_pci <string mnemonic, RegisterClass RC,
Operand Imm, bits<4>MajOp,
MemAccessSize AlignSize, string RegSrc = "Rt">
@ -3716,7 +3717,8 @@ def S2_storeri_pci : T_store_pci<"memw", IntRegs, s4_2Imm, 0b1100,
def S2_storerd_pci : T_store_pci<"memd", DoubleRegs, s4_3Imm, 0b1110,
DoubleWordAccess>;
let Uses = [CS], isNewValue = 1, mayStore = 1, isNVStore = 1, opNewValue = 4 in
let Uses = [CS], isNewValue = 1, mayStore = 1, isNVStore = 1, opNewValue = 4,
addrMode = PostInc in
class T_storenew_pci <string mnemonic, Operand Imm,
bits<2>MajOp, MemAccessSize AlignSize>
: NVInst < (outs IntRegs:$_dst_),
@ -3752,7 +3754,7 @@ def S2_storerinew_pci : T_storenew_pci <"memw", s4_2Imm, 0b10, WordAccess>;
//===----------------------------------------------------------------------===//
// Circular stores with auto-increment register
//===----------------------------------------------------------------------===//
let Uses = [CS] in
let Uses = [CS], addrMode = PostInc in
class T_store_pcr <string mnemonic, RegisterClass RC, bits<4>MajOp,
MemAccessSize AlignSize, string RegSrc = "Rt">
: STInst <(outs IntRegs:$_dst_),
@ -3788,7 +3790,8 @@ def S2_storerf_pcr : T_store_pcr<"memh", IntRegs, 0b1011,
//===----------------------------------------------------------------------===//
// Circular .new stores with auto-increment register
//===----------------------------------------------------------------------===//
let Uses = [CS], isNewValue = 1, mayStore = 1, isNVStore = 1, opNewValue = 3 in
let Uses = [CS], isNewValue = 1, mayStore = 1, isNVStore = 1, opNewValue = 3,
addrMode = PostInc in
class T_storenew_pcr <string mnemonic, bits<2>MajOp,
MemAccessSize AlignSize>
: NVInst <(outs IntRegs:$_dst_),
@ -3819,7 +3822,7 @@ def S2_storerinew_pcr : T_storenew_pcr <"memw", 0b10, WordAccess>;
//===----------------------------------------------------------------------===//
// Bit-reversed stores with auto-increment register
//===----------------------------------------------------------------------===//
let hasSideEffects = 0 in
let hasSideEffects = 0, addrMode = PostInc in
class T_store_pbr<string mnemonic, RegisterClass RC,
MemAccessSize addrSize, bits<3> majOp,
bit isHalf = 0>
@ -3864,7 +3867,7 @@ def S2_storerd_pbr : T_store_pbr<"memd", DoubleRegs, DoubleWordAccess, 0b110>;
// Bit-reversed .new stores with auto-increment register
//===----------------------------------------------------------------------===//
let isNewValue = 1, mayStore = 1, isNVStore = 1, opNewValue = 3,
hasSideEffects = 0 in
hasSideEffects = 0, addrMode = PostInc in
class T_storenew_pbr<string mnemonic, MemAccessSize addrSize, bits<2> majOp>
: NVInst <(outs IntRegs:$_dst_),
(ins IntRegs:$Rz, ModRegs:$Mu, IntRegs:$Nt),
@ -4741,10 +4744,10 @@ def HexagonCONST32_GP : SDNode<"HexagonISD::CONST32_GP", SDTHexagonCONST32>;
// HI/LO Instructions
let isReMaterializable = 1, isMoveImm = 1, hasSideEffects = 0,
hasNewValue = 1, opNewValue = 0 in
class REG_IMMED<string RegHalf, string Op, bit Rs, bits<3> MajOp, bit MinOp>
class REG_IMMED<string RegHalf, bit Rs, bits<3> MajOp, bit MinOp>
: ALU32_ri<(outs IntRegs:$dst),
(ins i32imm:$imm_value),
"$dst"#RegHalf#" = #"#Op#"($imm_value)", []> {
(ins u16Imm:$imm_value),
"$dst"#RegHalf#" = $imm_value", []> {
bits<5> dst;
bits<32> imm_value;
let IClass = 0b0111;
@ -4753,15 +4756,13 @@ class REG_IMMED<string RegHalf, string Op, bit Rs, bits<3> MajOp, bit MinOp>
let Inst{26-24} = MajOp;
let Inst{21} = MinOp;
let Inst{20-16} = dst;
let Inst{23-22} = !if (!eq(Op, "LO"), imm_value{15-14}, imm_value{31-30});
let Inst{13-0} = !if (!eq(Op, "LO"), imm_value{13-0}, imm_value{29-16});
let Inst{23-22} = imm_value{15-14};
let Inst{13-0} = imm_value{13-0};
}
let isAsmParserOnly = 1 in {
def LO : REG_IMMED<".l", "LO", 0b0, 0b001, 0b1>;
def LO_H : REG_IMMED<".l", "HI", 0b0, 0b001, 0b1>;
def HI : REG_IMMED<".h", "HI", 0b0, 0b010, 0b1>;
def HI_L : REG_IMMED<".h", "LO", 0b0, 0b010, 0b1>;
def LO : REG_IMMED<".l", 0b0, 0b001, 0b1>;
def HI : REG_IMMED<".h", 0b0, 0b010, 0b1>;
}
let isMoveImm = 1, isCodeGenOnly = 1 in
@ -4828,7 +4829,7 @@ def TFR_PdTrue : SInst<(outs PredRegs:$dst), (ins), "",
let hasSideEffects = 0, isReMaterializable = 1, isPseudo = 1,
isCodeGenOnly = 1 in
def TFR_PdFalse : SInst<(outs PredRegs:$dst), (ins), "$dst = xor($dst, $dst)",
def TFR_PdFalse : SInst<(outs PredRegs:$dst), (ins), "",
[(set (i1 PredRegs:$dst), 0)]>;
// Pseudo instructions.

View File

@ -1047,6 +1047,18 @@ let AddedComplexity = 40 in {
def: Storexs_pat<store, I64, S4_storerd_rr>;
}
class Store_rr_pat<PatFrag Store, PatFrag Value, InstHexagon MI>
: Pat<(Store Value:$Ru, (add I32:$Rs, I32:$Rt)),
(MI IntRegs:$Rs, IntRegs:$Rt, 0, Value:$Ru)>;
let AddedComplexity = 20 in {
def: Store_rr_pat<truncstorei8, I32, S4_storerb_rr>;
def: Store_rr_pat<truncstorei16, I32, S4_storerh_rr>;
def: Store_rr_pat<store, I32, S4_storeri_rr>;
def: Store_rr_pat<store, I64, S4_storerd_rr>;
}
// memd(Rx++#s4:3)=Rtt
// memd(Rx++#s4:3:circ(Mu))=Rtt
// memd(Rx++I:circ(Mu))=Rtt
@ -1733,7 +1745,7 @@ class NVJ_ConstImm_template<string mnemonic, bits<3> majOp, string ImmVal,
: NVInst_V4<(outs),
(ins IntRegs:$src1, brtarget:$offset),
"if ("#!if(isNegCond, "!","")#mnemonic
#"($src1.new, #"#ImmVal#")) jump:"
#"($src1.new, #" # ImmVal # ")) jump:"
#!if(isTak, "t","nt")#" $offset", []> {
let isTaken = isTak;
@ -2822,13 +2834,13 @@ def S4_lsli: SInst <(outs IntRegs:$Rd), (ins s6Imm:$s6, IntRegs:$Rt),
//===----------------------------------------------------------------------===//
def m5Imm8Pred : PatLeaf<(i32 imm), [{
int32_t v = (int8_t)N->getSExtValue();
return v >= -32 && v <= -1;
int8_t v = (int8_t)N->getSExtValue();
return v > -32 && v <= -1;
}]>;
def m5Imm16Pred : PatLeaf<(i32 imm), [{
int32_t v = (int16_t)N->getSExtValue();
return v >= -32 && v <= -1;
int16_t v = (int16_t)N->getSExtValue();
return v > -32 && v <= -1;
}]>;
def Clr5Imm8Pred : PatLeaf<(i32 imm), [{
@ -3193,7 +3205,7 @@ let AddedComplexity = 200 in {
/*sext*/ Clr5Imm16, L4_iand_memoph_io>;
defm: Memopxi_pat<zextloadi16, truncstorei16, u6_1ImmPred, and, Clr5Imm16Pred,
/*zext*/ Clr5Imm16, L4_iand_memoph_io>;
defm: Memopxi_pat<load, store, u6_2ImmPred, and, Clr5ImmPred, Clr5Imm16,
defm: Memopxi_pat<load, store, u6_2ImmPred, and, Clr5ImmPred, Clr5Imm32,
L4_iand_memopw_io>;
// setbit imm
@ -3343,6 +3355,7 @@ defm L4_return: LD_MISC_L4_RETURN <"dealloc_return">, PredNewRel;
let isCall = 1, isBarrier = 1, isReturn = 1, isTerminator = 1,
Defs = [R29, R30, R31, PC], isPredicable = 0, isAsmParserOnly = 1 in {
def RESTORE_DEALLOC_RET_JMP_V4 : T_JMP<"">;
let isExtended = 1, opExtendable = 0 in
def RESTORE_DEALLOC_RET_JMP_V4_EXT : T_JMP<"">;
@ -3689,6 +3702,17 @@ class Stoream_pat<PatFrag Store, PatFrag Value, PatFrag Addr, PatFrag ValueMod,
: Pat<(Store Value:$val, Addr:$addr),
(MI Addr:$addr, (ValueMod Value:$val))>;
let AddedComplexity = 30 in {
def: Storea_pat<truncstorei8, I32, addrga, S2_storerbabs>;
def: Storea_pat<truncstorei16, I32, addrga, S2_storerhabs>;
def: Storea_pat<store, I32, addrga, S2_storeriabs>;
def: Storea_pat<store, I64, addrga, S2_storerdabs>;
def: Stoream_pat<truncstorei8, I64, addrga, LoReg, S2_storerbabs>;
def: Stoream_pat<truncstorei16, I64, addrga, LoReg, S2_storerhabs>;
def: Stoream_pat<truncstorei32, I64, addrga, LoReg, S2_storeriabs>;
}
def: Storea_pat<SwapSt<atomic_store_8>, I32, addrgp, S2_storerbgp>;
def: Storea_pat<SwapSt<atomic_store_16>, I32, addrgp, S2_storerhgp>;
def: Storea_pat<SwapSt<atomic_store_32>, I32, addrgp, S2_storerigp>;
@ -3826,6 +3850,26 @@ defm loadri : LD_Abs<"memw", "LDriw", IntRegs, u16_2Imm, 0b100>;
let accessSize = DoubleWordAccess in
defm loadrd : LD_Abs<"memd", "LDrid", DoubleRegs, u16_3Imm, 0b110>;
class LoadAbs_pats <PatFrag ldOp, InstHexagon MI, ValueType VT = i32>
: Pat <(VT (ldOp (HexagonCONST32 tglobaladdr:$absaddr))),
(VT (MI tglobaladdr:$absaddr))>;
let AddedComplexity = 30 in {
def: LoadAbs_pats <load, L4_loadri_abs>;
def: LoadAbs_pats <zextloadi1, L4_loadrub_abs>;
def: LoadAbs_pats <sextloadi8, L4_loadrb_abs>;
def: LoadAbs_pats <extloadi8, L4_loadrub_abs>;
def: LoadAbs_pats <zextloadi8, L4_loadrub_abs>;
def: LoadAbs_pats <sextloadi16, L4_loadrh_abs>;
def: LoadAbs_pats <extloadi16, L4_loadruh_abs>;
def: LoadAbs_pats <zextloadi16, L4_loadruh_abs>;
def: LoadAbs_pats <load, L4_loadrd_abs, i64>;
}
let AddedComplexity = 30 in
def: Pat<(i64 (zextloadi1 (HexagonCONST32 tglobaladdr:$absaddr))),
(Zext64 (L4_loadrub_abs tglobaladdr:$absaddr))>;
//===----------------------------------------------------------------------===//
// multiclass for load instructions with GP-relative addressing mode.
// Rx=mem[bhwd](##global)