}
// 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),
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),
//===----------------------------------------------------------------------===//
// 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_),
//===----------------------------------------------------------------------===//
// 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
// 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>;
// 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">
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_),
//===----------------------------------------------------------------------===//
// 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_),
//===----------------------------------------------------------------------===//
// 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_),
//===----------------------------------------------------------------------===//
// 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>
// 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),
// 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;
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
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.
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
: 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;
//===----------------------------------------------------------------------===//
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), [{
/*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
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<"">;
: 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>;
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)