// Return the bit position we will set [0-31].
// As an SDNode.
int32_t imm = N->getSExtValue();
- return XformMskToBitPosU5Imm(imm);
+ return XformMskToBitPosU5Imm(imm, SDLoc(N));
}]>;
+
// Hexagon V4 Architecture spec defines 8 instruction classes:
// LD ST ALU32 XTYPE J JR MEMOP NV CR SYSTEM(system is not implemented in the
// compiler)
def : Pat <(VT (ldOp (add (shl IntRegs:$src1, u2ImmPred:$src2),
(HexagonCONST32 tglobaladdr:$src3)))),
(MI IntRegs:$src1, u2ImmPred:$src2, tglobaladdr:$src3)>;
-
def : Pat <(VT (ldOp (add IntRegs:$src1,
(HexagonCONST32 tglobaladdr:$src2)))),
(MI IntRegs:$src1, 0, tglobaladdr:$src2)>;
+
+ def : Pat <(VT (ldOp (add (shl IntRegs:$src1, u2ImmPred:$src2),
+ (HexagonCONST32 tconstpool:$src3)))),
+ (MI IntRegs:$src1, u2ImmPred:$src2, tconstpool:$src3)>;
+ def : Pat <(VT (ldOp (add IntRegs:$src1,
+ (HexagonCONST32 tconstpool:$src2)))),
+ (MI IntRegs:$src1, 0, tconstpool:$src2)>;
+
+ def : Pat <(VT (ldOp (add (shl IntRegs:$src1, u2ImmPred:$src2),
+ (HexagonCONST32 tjumptable:$src3)))),
+ (MI IntRegs:$src1, u2ImmPred:$src2, tjumptable:$src3)>;
+ def : Pat <(VT (ldOp (add IntRegs:$src1,
+ (HexagonCONST32 tjumptable:$src2)))),
+ (MI IntRegs:$src1, 0, tjumptable:$src2)>;
}
let AddedComplexity = 60 in {
def: Pat<(i64 (zext (i32 IntRegs:$src1))),
(Zext64 IntRegs:$src1)>;
-// zext i32->i64
-def: Pat <(i64 (zextloadi32 ADDRriS11_2:$src1)),
- (i64 (A4_combineir 0, (L2_loadri_io AddrFI:$src1, 0)))>;
-
-let AddedComplexity = 100 in
-def: Pat <(i64 (zextloadi32 (i32 (add IntRegs:$src1, s30_2ImmPred:$offset)))),
- (i64 (A4_combineir 0, (L2_loadri_io IntRegs:$src1,
- s30_2ImmPred:$offset)))>;
-
-// anyext i32->i64
-def: Pat <(i64 (extloadi32 ADDRriS11_2:$src1)),
- (i64 (A4_combineir 0, (L2_loadri_io AddrFI:$src1, 0)))>;
-
//===----------------------------------------------------------------------===//
// LD -
//===----------------------------------------------------------------------===//
// Template class for store instructions with Absolute set addressing mode.
//===----------------------------------------------------------------------===//
let isExtended = 1, opExtendable = 1, opExtentBits = 6,
- addrMode = AbsoluteSet, isNVStorable = 1 in
+ addrMode = AbsoluteSet in
class T_ST_absset <string mnemonic, string BaseOp, RegisterClass RC,
bits<3> MajOp, MemAccessSize AccessSz, bit isHalf = 0>
: STInst<(outs IntRegs:$dst),
let accessSize = AccessSz;
let BaseOpcode = BaseOp#"_AbsSet";
+ // Store upper-half and store doubleword cannot be NV.
+ let isNVStorable = !if (!eq(mnemonic, "memd"), 0, !if(isHalf,0,1));
+
let IClass = 0b1010;
let Inst{27-24} = 0b1011;
}
let isExtended = 1, opExtendable = 2, opExtentBits = 6, InputType = "imm",
-addrMode = BaseLongOffset, AddedComplexity = 40 in
+ addrMode = BaseLongOffset, AddedComplexity = 40 in
class T_StoreAbsReg <string mnemonic, string CextOp, RegisterClass RC,
bits<3> MajOp, MemAccessSize AccessSz, bit isHalf = 0>
: STInst<(outs),
let accessSize = AccessSz;
let CextOpcode = CextOp;
let BaseOpcode = CextOp#"_shl";
+
+ // Store upper-half and store doubleword cannot be NV.
+ let isNVStorable = !if (!eq(mnemonic, "memd"), 0, !if(isHalf,0,1));
+
let IClass = 0b1010;
let Inst{27-24} =0b1101;
bits<2> u2;
bits<5> Rt;
+ // Store upper-half and store doubleword cannot be NV.
+ let isNVStorable = !if (!eq(mnemonic, "memd"), 0, !if(isH,0,1));
+
let IClass = 0b0011;
let Inst{27-24} = 0b1011;
let isPredicatedFalse = isNot;
let isPredicatedNew = isPredNew;
+ // Store upper-half and store doubleword cannot be NV.
+ let isNVStorable = !if (!eq(mnemonic, "memd"), 0, !if(isH,0,1));
let IClass = 0b0011;
// -1 etc is represented as 255 etc
// assigning to a byte restores our desired signed value.
int8_t imm = N->getSExtValue();
- return CurDAG->getTargetConstant(imm, MVT::i32);
+ return CurDAG->getTargetConstant(imm, SDLoc(N), MVT::i32);
}]>;
def IMM_HALF : SDNodeXForm<imm, [{
// -1 etc is represented as 65535 etc
// assigning to a short restores our desired signed value.
int16_t imm = N->getSExtValue();
- return CurDAG->getTargetConstant(imm, MVT::i32);
+ return CurDAG->getTargetConstant(imm, SDLoc(N), MVT::i32);
}]>;
def IMM_WORD : SDNodeXForm<imm, [{
// might convert -1 to a large +ve number.
// assigning to a word restores our desired signed value.
int32_t imm = N->getSExtValue();
- return CurDAG->getTargetConstant(imm, MVT::i32);
+ return CurDAG->getTargetConstant(imm, SDLoc(N), MVT::i32);
}]>;
def ToImmByte : OutPatFrag<(ops node:$R), (IMM_BYTE $R)>;
(ins IntRegs:$Rs, IntRegs:$Ru, s6Ext:$s6),
"$Rd = add($Rs, add($Ru, #$s6))" ,
[(set (i32 IntRegs:$Rd), (add (i32 IntRegs:$Rs),
- (add (i32 IntRegs:$Ru), s16_16ImmPred:$s6)))],
+ (add (i32 IntRegs:$Ru), s32ImmPred:$s6)))],
"", ALU64_tc_2_SLOT23> {
bits<5> Rd;
bits<5> Rs;
def S2_ct1p : T_COUNT_LEADING_64<"ct1", 0b111, 0b100>;
def S4_clbpnorm : T_COUNT_LEADING_64<"normamt", 0b011, 0b000>;
-def: Pat<(i32 (trunc (cttz (i64 DoubleRegs:$Rss)))),
- (S2_ct0p (i64 DoubleRegs:$Rss))>;
-def: Pat<(i32 (trunc (cttz (not (i64 DoubleRegs:$Rss))))),
- (S2_ct1p (i64 DoubleRegs:$Rss))>;
+// Count trailing zeros: 64-bit.
+def: Pat<(i32 (trunc (cttz I64:$Rss))), (S2_ct0p I64:$Rss)>;
+def: Pat<(i32 (trunc (cttz_zero_undef I64:$Rss))), (S2_ct0p I64:$Rss)>;
+
+// Count trailing ones: 64-bit.
+def: Pat<(i32 (trunc (cttz (not I64:$Rss)))), (S2_ct1p I64:$Rss)>;
+def: Pat<(i32 (trunc (cttz_zero_undef (not I64:$Rss)))), (S2_ct1p I64:$Rss)>;
+
+// Define leading/trailing patterns that require zero-extensions to 64 bits.
+def: Pat<(i64 (ctlz I64:$Rss)), (Zext64 (S2_cl0p I64:$Rss))>;
+def: Pat<(i64 (ctlz_zero_undef I64:$Rss)), (Zext64 (S2_cl0p I64:$Rss))>;
+def: Pat<(i64 (cttz I64:$Rss)), (Zext64 (S2_ct0p I64:$Rss))>;
+def: Pat<(i64 (cttz_zero_undef I64:$Rss)), (Zext64 (S2_ct0p I64:$Rss))>;
+def: Pat<(i64 (ctlz (not I64:$Rss))), (Zext64 (S2_cl1p I64:$Rss))>;
+def: Pat<(i64 (ctlz_zero_undef (not I64:$Rss))), (Zext64 (S2_cl1p I64:$Rss))>;
+def: Pat<(i64 (cttz (not I64:$Rss))), (Zext64 (S2_ct1p I64:$Rss))>;
+def: Pat<(i64 (cttz_zero_undef (not I64:$Rss))), (Zext64 (S2_ct1p I64:$Rss))>;
+
let hasSideEffects = 0, hasNewValue = 1 in
def S4_clbaddi : SInst<(outs IntRegs:$Rd), (ins IntRegs:$Rs, s6Imm:$s6),
// Call the transformation function XformM5ToU5Imm to get the negative
// immediate's positive counterpart.
int32_t imm = N->getSExtValue();
- return XformM5ToU5Imm(imm);
+ return XformM5ToU5Imm(imm, SDLoc(N));
}]>;
def MEMOPIMM_HALF : SDNodeXForm<imm, [{
// Call the transformation function XformM5ToU5Imm to get the negative
// immediate's positive counterpart.
int16_t imm = N->getSExtValue();
- return XformM5ToU5Imm(imm);
+ return XformM5ToU5Imm(imm, SDLoc(N));
}]>;
def MEMOPIMM_BYTE : SDNodeXForm<imm, [{
// Call the transformation function XformM5ToU5Imm to get the negative
// immediate's positive counterpart.
int8_t imm = N->getSExtValue();
- return XformM5ToU5Imm(imm);
+ return XformM5ToU5Imm(imm, SDLoc(N));
}]>;
def SETMEMIMM : SDNodeXForm<imm, [{
// Return the bit position we will set [0-31].
// As an SDNode.
int32_t imm = N->getSExtValue();
- return XformMskToBitPosU5Imm(imm);
+ return XformMskToBitPosU5Imm(imm, SDLoc(N));
}]>;
def CLRMEMIMM : SDNodeXForm<imm, [{
// As an SDNode.
// we bit negate the value first
int32_t imm = ~(N->getSExtValue());
- return XformMskToBitPosU5Imm(imm);
+ return XformMskToBitPosU5Imm(imm, SDLoc(N));
}]>;
def SETMEMIMM_SHORT : SDNodeXForm<imm, [{
// Return the bit position we will set [0-15].
// As an SDNode.
int16_t imm = N->getSExtValue();
- return XformMskToBitPosU4Imm(imm);
+ return XformMskToBitPosU4Imm(imm, SDLoc(N));
}]>;
def CLRMEMIMM_SHORT : SDNodeXForm<imm, [{
// As an SDNode.
// we bit negate the value first
int16_t imm = ~(N->getSExtValue());
- return XformMskToBitPosU4Imm(imm);
+ return XformMskToBitPosU4Imm(imm, SDLoc(N));
}]>;
def SETMEMIMM_BYTE : SDNodeXForm<imm, [{
// Return the bit position we will set [0-7].
// As an SDNode.
int8_t imm = N->getSExtValue();
- return XformMskToBitPosU3Imm(imm);
+ return XformMskToBitPosU3Imm(imm, SDLoc(N));
}]>;
def CLRMEMIMM_BYTE : SDNodeXForm<imm, [{
// As an SDNode.
// we bit negate the value first
int8_t imm = ~(N->getSExtValue());
- return XformMskToBitPosU3Imm(imm);
+ return XformMskToBitPosU3Imm(imm, SDLoc(N));
}]>;
//===----------------------------------------------------------------------===//
def DEC_CONST_BYTE : SDNodeXForm<imm, [{
// Return the byte immediate const-1 as an SDNode.
int32_t imm = N->getSExtValue();
- return XformU7ToU7M1Imm(imm);
+ return XformU7ToU7M1Imm(imm, SDLoc(N));
}]>;
// For the sequence
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<"">;
}
// Restore registers and dealloc frame before a tail call.
let isCall = 1, Defs = [R29, R30, R31, PC], isAsmParserOnly = 1 in {
def RESTORE_DEALLOC_BEFORE_TAILCALL_V4 : T_Call<"">, PredRel;
+ let isExtended = 1, opExtendable = 0 in
+ def RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT : T_Call<"">, PredRel;
}
// Save registers function call.
let isCall = 1, Uses = [R29, R31], isAsmParserOnly = 1 in {
def SAVE_REGISTERS_CALL_V4 : T_Call<"">, PredRel;
+ let isExtended = 1, opExtendable = 0 in
+ def SAVE_REGISTERS_CALL_V4_EXT : T_Call<"">, PredRel;
}
//===----------------------------------------------------------------------===//
// Template class for non predicated store instructions with
// GP-Relative or absolute addressing.
//===----------------------------------------------------------------------===//
-let hasSideEffects = 0, isPredicable = 1, isNVStorable = 1 in
+let hasSideEffects = 0, isPredicable = 1 in
class T_StoreAbsGP <string mnemonic, RegisterClass RC, Operand ImmOp,
- bits<2>MajOp, Operand AddrOp, bit isAbs, bit isHalf>
- : STInst<(outs), (ins AddrOp:$addr, RC:$src),
- mnemonic # !if(isAbs, "(##", "(#")#"$addr) = $src"#!if(isHalf, ".h",""),
+ bits<2>MajOp, bit isAbs, bit isHalf>
+ : STInst<(outs), (ins ImmOp:$addr, RC:$src),
+ mnemonic # "(#$addr) = $src"#!if(isHalf, ".h",""),
[], "", V2LDST_tc_st_SLOT01> {
bits<19> addr;
bits<5> src;
!if (!eq(ImmOpStr, "u16_2Imm"), addr{17-2},
!if (!eq(ImmOpStr, "u16_1Imm"), addr{16-1},
/* u16_0Imm */ addr{15-0})));
+ // Store upper-half and store doubleword cannot be NV.
+ let isNVStorable = !if (!eq(mnemonic, "memd"), 0, !if(isHalf,0,1));
+
let IClass = 0b0100;
let Inst{27} = 1;
let Inst{26-25} = offsetBits{15-14};
// Template class for predicated store instructions with
// GP-Relative or absolute addressing.
//===----------------------------------------------------------------------===//
-let hasSideEffects = 0, isPredicated = 1, isNVStorable = 1, opExtentBits = 6,
- opExtendable = 1 in
+let hasSideEffects = 0, isPredicated = 1, opExtentBits = 6, opExtendable = 1 in
class T_StoreAbs_Pred <string mnemonic, RegisterClass RC, bits<2> MajOp,
bit isHalf, bit isNot, bit isNew>
- : STInst<(outs), (ins PredRegs:$src1, u6Ext:$absaddr, RC: $src2),
+ : STInst<(outs), (ins PredRegs:$src1, u32MustExt:$absaddr, RC: $src2),
!if(isNot, "if (!$src1", "if ($src1")#!if(isNew, ".new) ",
") ")#mnemonic#"(#$absaddr) = $src2"#!if(isHalf, ".h",""),
[], "", ST_tc_st_SLOT01>, AddrModeRel {
let isPredicatedNew = isNew;
let isPredicatedFalse = isNot;
+ // Store upper-half and store doubleword cannot be NV.
+ let isNVStorable = !if (!eq(mnemonic, "memd"), 0, !if(isHalf,0,1));
let IClass = 0b1010;
//===----------------------------------------------------------------------===//
class T_StoreAbs <string mnemonic, RegisterClass RC, Operand ImmOp,
bits<2> MajOp, bit isHalf>
- : T_StoreAbsGP <mnemonic, RC, ImmOp, MajOp, u32Imm, 1, isHalf>,
+ : T_StoreAbsGP <mnemonic, RC, u32MustExt, MajOp, 1, isHalf>,
AddrModeRel {
string ImmOpStr = !cast<string>(ImmOp);
let opExtentBits = !if (!eq(ImmOpStr, "u16_3Imm"), 19,
let isAsmParserOnly = 1 in
class T_StoreGP <string mnemonic, string BaseOp, RegisterClass RC,
Operand ImmOp, bits<2> MajOp, bit isHalf = 0>
- : T_StoreAbsGP <mnemonic, RC, ImmOp, MajOp, globaladdress, 0, isHalf> {
+ : T_StoreAbsGP <mnemonic, RC, ImmOp, MajOp, 0, isHalf> {
// Set BaseOpcode same as absolute addressing instructions so that
// non-predicated GP-Rel instructions can have relate with predicated
// Absolute instruction.
// Absolute instruction.
let BaseOpcode = BaseOp#_abs in {
def NAME#gp : T_StoreAbsGP <mnemonic, IntRegs, ImmOp, MajOp,
- globaladdress, 0, isHalf>;
+ 0, isHalf>;
// New-value store
def NAME#newgp : T_StoreAbsGP_NV <mnemonic, ImmOp, MajOp, 0> ;
}
//===----------------------------------------------------------------------===//
let isPredicable = 1, hasSideEffects = 0 in
class T_LoadAbsGP <string mnemonic, RegisterClass RC, Operand ImmOp,
- bits<3> MajOp, Operand AddrOp, bit isAbs>
- : LDInst <(outs RC:$dst), (ins AddrOp:$addr),
- "$dst = "#mnemonic# !if(isAbs, "(##", "(#")#"$addr)",
+ bits<3> MajOp>
+ : LDInst <(outs RC:$dst), (ins ImmOp:$addr),
+ "$dst = "#mnemonic# "(#$addr)",
[], "", V2LDST_tc_ld_SLOT01> {
bits<5> dst;
bits<19> addr;
class T_LoadAbs <string mnemonic, RegisterClass RC, Operand ImmOp,
bits<3> MajOp>
- : T_LoadAbsGP <mnemonic, RC, ImmOp, MajOp, u32Imm, 1>, AddrModeRel {
+ : T_LoadAbsGP <mnemonic, RC, u32MustExt, MajOp>, AddrModeRel {
string ImmOpStr = !cast<string>(ImmOp);
let opExtentBits = !if (!eq(ImmOpStr, "u16_3Imm"), 19,
// Template class for predicated load instructions with
// absolute addressing mode.
//===----------------------------------------------------------------------===//
-let isPredicated = 1, opExtentBits = 6, opExtendable = 2 in
+let isPredicated = 1, hasSideEffects = 0, hasNewValue = 1, opExtentBits = 6,
+ opExtendable = 2 in
class T_LoadAbs_Pred <string mnemonic, RegisterClass RC, bits<3> MajOp,
bit isPredNot, bit isPredNew>
- : LDInst <(outs RC:$dst), (ins PredRegs:$src1, u6Ext:$absaddr),
+ : LDInst <(outs RC:$dst), (ins PredRegs:$src1, u32MustExt:$absaddr),
!if(isPredNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
") ")#"$dst = "#mnemonic#"(#$absaddr)">, AddrModeRel {
bits<5> dst;
let isAsmParserOnly = 1 in
class T_LoadGP <string mnemonic, string BaseOp, RegisterClass RC, Operand ImmOp,
bits<3> MajOp>
- : T_LoadAbsGP <mnemonic, RC, ImmOp, MajOp, globaladdress, 0>, PredNewRel {
+ : T_LoadAbsGP <mnemonic, RC, ImmOp, MajOp>, PredNewRel {
let BaseOpcode = BaseOp#_abs;
}
def: Pat<(HexagonCONST32_GP tblockaddress:$Rs), (A2_tfrsi s16Ext:$Rs)>;
def: Pat<(HexagonCONST32_GP tglobaladdr:$Rs), (A2_tfrsi s16Ext:$Rs)>;
-def: Pat<(i64 (ctlz I64:$src1)), (Zext64 (S2_cl0p I64:$src1))>;
-def: Pat<(i64 (cttz I64:$src1)), (Zext64 (S2_ct0p I64:$src1))>;
-
let AddedComplexity = 30 in {
def: Storea_pat<truncstorei8, I32, u32ImmPred, S2_storerbabs>;
def: Storea_pat<truncstorei16, I32, u32ImmPred, S2_storerhabs>;
let Inst{19-16} = Rs;
let Inst{7-1} = r9_2{8-2};
}
+
+// Duplex instructions
+//===----------------------------------------------------------------------===//
+include "HexagonIsetDx.td"