include "XCoreInstrFormats.td"
-//===----------------------------------------------------------------------===//
-// Feature predicates.
-//===----------------------------------------------------------------------===//
-
-// HasXS1A - This predicate is true when the target processor supports XS1A
-// instructions.
-def HasXS1A : Predicate<"Subtarget.isXS1A()">;
-
-// HasXS1B - This predicate is true when the target processor supports XS1B
-// instructions.
-def HasXS1B : Predicate<"Subtarget.isXS1B()">;
-
//===----------------------------------------------------------------------===//
// XCore specific DAG Nodes.
//
[SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>;
def pcrelwrapper : SDNode<"XCoreISD::PCRelativeWrapper", SDT_XCoreAddress,
- []>;
+ []>;
def dprelwrapper : SDNode<"XCoreISD::DPRelativeWrapper", SDT_XCoreAddress,
- []>;
+ []>;
def cprelwrapper : SDNode<"XCoreISD::CPRelativeWrapper", SDT_XCoreAddress,
- []>;
+ []>;
def SDT_XCoreStwsp : SDTypeProfile<0, 2, [SDTCisInt<1>]>;
-def XCoreStwsp : SDNode<"XCoreISD::STWSP", SDT_XCoreStwsp,
- [SDNPHasChain]>;
+def XCoreStwsp : SDNode<"XCoreISD::STWSP", SDT_XCoreStwsp,
+ [SDNPHasChain]>;
// These are target-independent nodes, but have target-specific formats.
def SDT_XCoreCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>;
return getI32Imm(-value);
}]>;
+def bpwsub_xform : SDNodeXForm<imm, [{
+ // Transformation function: 32-imm
+ uint32_t value = N->getZExtValue();
+ return getI32Imm(32-value);
+}]>;
+
def div4neg_xform : SDNodeXForm<imm, [{
// Transformation function: -imm/4
uint32_t value = N->getZExtValue();
return (uint32_t)N->getZExtValue() < (1 << 20);
}]>;
-// FIXME check subtarget. Currently we check if the immediate
-// is in the common subset of legal immediate values for both
-// XS1A and XS1B.
def immMskBitp : PatLeaf<(imm), [{
uint32_t value = (uint32_t)N->getZExtValue();
if (!isMask_32(value)) {
|| msksize == 32;
}]>;
-// FIXME check subtarget. Currently we check if the immediate
-// is in the common subset of legal immediate values for both
-// XS1A and XS1B.
def immBitp : PatLeaf<(imm), [{
uint32_t value = (uint32_t)N->getZExtValue();
return (value >= 1 && value <= 8)
|| value == 32;
}]>;
+def immBpwSubBitp : PatLeaf<(imm), [{
+ uint32_t value = (uint32_t)N->getZExtValue();
+ return (value >= 24 && value <= 31)
+ || value == 16
+ || value == 8
+ || value == 0;
+}]>;
+
def lda16f : PatFrag<(ops node:$addr, node:$offset),
(add node:$addr, (shl node:$offset, 1))>;
def lda16b : PatFrag<(ops node:$addr, node:$offset),
[(callseq_end timm:$amt1, timm:$amt2)]>;
}
-// SELECT_CC_* - Used to implement the SELECT_CC DAG operation. Expanded by the
-// scheduler into a branch sequence.
-let usesCustomDAGSchedInserter = 1 in {
+def LDWFI : PseudoInstXCore<(outs GRRegs:$dst), (ins MEMii:$addr),
+ "${:comment} LDWFI $dst, $addr",
+ [(set GRRegs:$dst, (load ADDRspii:$addr))]>;
+
+def LDAWFI : PseudoInstXCore<(outs GRRegs:$dst), (ins MEMii:$addr),
+ "${:comment} LDAWFI $dst, $addr",
+ [(set GRRegs:$dst, ADDRspii:$addr)]>;
+
+def STWFI : PseudoInstXCore<(outs), (ins GRRegs:$src, MEMii:$addr),
+ "${:comment} STWFI $src, $addr",
+ [(store GRRegs:$src, ADDRspii:$addr)]>;
+
+// SELECT_CC_* - Used to implement the SELECT_CC DAG operation. Expanded after
+// instruction selection into a branch sequence.
+let usesCustomInserter = 1 in {
def SELECT_CC : PseudoInstXCore<(outs GRRegs:$dst),
(ins GRRegs:$cond, GRRegs:$T, GRRegs:$F),
"${:comment} SELECT_CC PSEUDO!",
}
// Four operand long
-let Predicates = [HasXS1B], Constraints = "$src1 = $dst1,$src2 = $dst2" in {
+let Constraints = "$src1 = $dst1,$src2 = $dst2" in {
def MACCU_l4r : _L4R<(outs GRRegs:$dst1, GRRegs:$dst2),
(ins GRRegs:$src1, GRRegs:$src2, GRRegs:$src3,
GRRegs:$src4),
// Five operand long
-let Predicates = [HasXS1B] in {
def LADD_l5r : _L5R<(outs GRRegs:$dst1, GRRegs:$dst2),
(ins GRRegs:$src1, GRRegs:$src2, GRRegs:$src3),
"ladd $dst1, $dst2, $src1, $src2, $src3",
(ins GRRegs:$src1, GRRegs:$src2, GRRegs:$src3),
"ldiv $dst1, $dst2, $src1, $src2, $src3",
[]>;
-}
// Six operand long
"lmul $dst1, $dst2, $src1, $src2, $src3, $src4",
[]>;
-let Predicates = [HasXS1A] in
-def MACC_l6r : _L6R<(outs GRRegs:$dst1, GRRegs:$dst2),
- (ins GRRegs:$src1, GRRegs:$src2, GRRegs:$src3,
- GRRegs:$src4),
- "macc $dst1, $dst2, $src1, $src2, $src3, $src4",
- []>;
-
// Register - U6
//let Uses = [DP] in ...
defm LDWCP : FRU6_LRU6_cp<"ldw">;
let Uses = [SP] in {
-let mayStore=1 in
+let mayStore=1 in {
def STWSP_ru6 : _FRU6<
- (outs), (ins GRRegs:$dst, MEMii:$b),
- "stw $dst, sp[$b]",
- []>;
+ (outs), (ins GRRegs:$val, i32imm:$index),
+ "stw $val, sp[$index]",
+ [(XCoreStwsp GRRegs:$val, immU6:$index)]>;
def STWSP_lru6 : _FLRU6<
- (outs), (ins GRRegs:$dst, MEMii:$b),
- "stw $dst, sp[$b]",
- [(store GRRegs:$dst, ADDRspii:$b)]>;
-
-let mayStore=1 in
-def STWSP_ru6_2 : _FRU6<
- (outs), (ins GRRegs:$dst, i32imm:$b),
- "stw $dst, sp[$b]",
- []>;
-
-def STWSP_lru6_2 : _FLRU6<
- (outs), (ins GRRegs:$dst, i32imm:$b),
- "stw $dst, sp[$b]",
- [(store GRRegs:$dst, ADDRspii:$b)]>;
+ (outs), (ins GRRegs:$val, i32imm:$index),
+ "stw $val, sp[$index]",
+ [(XCoreStwsp GRRegs:$val, immU16:$index)]>;
+}
-let mayLoad=1 in
+let mayLoad=1 in {
def LDWSP_ru6 : _FRU6<
- (outs GRRegs:$dst), (ins MEMii:$b),
+ (outs GRRegs:$dst), (ins i32imm:$b),
"ldw $dst, sp[$b]",
[]>;
def LDWSP_lru6 : _FLRU6<
- (outs GRRegs:$dst), (ins MEMii:$b),
+ (outs GRRegs:$dst), (ins i32imm:$b),
"ldw $dst, sp[$b]",
- [(set GRRegs:$dst, (load ADDRspii:$b))]>;
+ []>;
+}
-let neverHasSideEffects = 1 in
+let neverHasSideEffects = 1 in {
def LDAWSP_ru6 : _FRU6<
- (outs GRRegs:$dst), (ins MEMii:$b),
+ (outs GRRegs:$dst), (ins i32imm:$b),
"ldaw $dst, sp[$b]",
[]>;
def LDAWSP_lru6 : _FLRU6<
- (outs GRRegs:$dst), (ins MEMii:$b),
+ (outs GRRegs:$dst), (ins i32imm:$b),
"ldaw $dst, sp[$b]",
- [(set GRRegs: $dst, ADDRspii:$b)]>;
+ []>;
-let neverHasSideEffects = 1 in {
def LDAWSP_ru6_RRegs : _FRU6<
(outs RRegs:$dst), (ins i32imm:$b),
"ldaw $dst, sp[$b]",
let mayStore = 1 in
defm ENTSP : FU6_LU6_np<"entsp">;
-let isReturn = 1, isTerminator = 1, mayLoad = 1 in {
+let isReturn = 1, isTerminator = 1, mayLoad = 1, isBarrier = 1 in {
defm RETSP : FU6_LU6<"retsp", XCoreRetsp>;
}
}
}
//let Uses = [CP] in ...
-let Predicates = [HasXS1B], Defs = [R11], neverHasSideEffects = 1,
- isReMaterializable = 1 in
+let Defs = [R11], neverHasSideEffects = 1, isReMaterializable = 1 in
def LDAWCP_u6: _FRU6<(outs), (ins MEMii:$a),
"ldaw r11, cp[$a]",
[]>;
-let Predicates = [HasXS1B], Defs = [R11], isReMaterializable = 1 in
+let Defs = [R11], isReMaterializable = 1 in
def LDAWCP_lu6: _FLRU6<
(outs), (ins MEMii:$a),
"ldaw r11, cp[$a]",
"ldap r11, $addr",
[(set R11, (pcrelwrapper tglobaladdr:$addr))]>;
+let Defs = [R11], isReMaterializable = 1 in
+def LDAP_lu10_ba : _FLU10<(outs),
+ (ins i32imm:$addr),
+ "ldap r11, $addr",
+ [(set R11, (pcrelwrapper tblockaddress:$addr))]>;
+
let isCall=1,
-// All calls clobber the the link register and the non-callee-saved registers:
+// All calls clobber the link register and the non-callee-saved registers:
Defs = [R0, R1, R2, R3, R11, LR] in {
def BL_u10 : _FU10<
(outs),
// One operand short
// TODO edu, eeu, waitet, waitef, freer, tstart, msync, mjoin, syncr, clrtp
-// bru, setdp, setcp, setv, setev, kcall, ecallt, ecallf
+// bru, setdp, setcp, setv, setev, kcall
// dgetreg
let isBranch=1, isIndirectBranch=1, isTerminator=1 in
def BAU_1r : _F1R<(outs), (ins GRRegs:$addr),
"set sp, $src",
[]>;
+let isBarrier = 1, hasCtrlDep = 1 in
+def ECALLT_1r : _F1R<(outs), (ins GRRegs:$src),
+ "ecallt $src",
+ []>;
+
+let isBarrier = 1, hasCtrlDep = 1 in
+def ECALLF_1r : _F1R<(outs), (ins GRRegs:$src),
+ "ecallf $src",
+ []>;
+
let isCall=1,
-// All calls clobber the the link register and the non-callee-saved registers:
+// All calls clobber the link register and the non-callee-saved registers:
Defs = [R0, R1, R2, R3, R11, LR] in {
def BLA_1r : _F1R<(outs), (ins GRRegs:$addr, variable_ops),
"bla $addr",
def : Pat<(XCoreBranchLink tglobaladdr:$addr), (BL_lu10 tglobaladdr:$addr)>;
def : Pat<(XCoreBranchLink texternalsym:$addr), (BL_lu10 texternalsym:$addr)>;
-def : Pat<(XCoreStwsp GRRegs:$val, immU6:$index),
- (STWSP_ru6_2 GRRegs:$val, immU6:$index)>;
-def : Pat<(XCoreStwsp GRRegs:$val, immU16:$index),
- (STWSP_lru6_2 GRRegs:$val, immU16:$index)>;
/// sext_inreg
def : Pat<(sext_inreg GRRegs:$b, i1), (SEXT_rus GRRegs:$b, 1)>;
(LD8U_3r GRRegs:$addr, GRRegs:$offset)>;
def : Pat<(zextloadi8 GRRegs:$addr), (LD8U_3r GRRegs:$addr, (LDC_ru6 0))>;
-def : Pat<(zextloadi16 (lda16f GRRegs:$addr, GRRegs:$offset)),
+def : Pat<(sextloadi16 (lda16f GRRegs:$addr, GRRegs:$offset)),
(LD16S_3r GRRegs:$addr, GRRegs:$offset)>;
def : Pat<(sextloadi16 GRRegs:$addr), (LD16S_3r GRRegs:$addr, (LDC_ru6 0))>;
/// cttz
def : Pat<(cttz GRRegs:$src), (CLZ_l2r (BITREV_l2r GRRegs:$src))>;
+/// trap
+def : Pat<(trap), (ECALLF_1r (LDC_ru6 0))>;
+
///
/// branch patterns
///
def : Pat<(sra GRRegs:$src, 31),
(ASHR_l2rus GRRegs:$src, 32)>;
+def : Pat<(brcond (setlt GRRegs:$lhs, 0), bb:$dst),
+ (BRFT_lru6 (ASHR_l2rus GRRegs:$lhs, 32), bb:$dst)>;
+
+// setge X, 0 is canonicalized to setgt X, -1
+def : Pat<(brcond (setgt GRRegs:$lhs, -1), bb:$dst),
+ (BRFF_lru6 (ASHR_l2rus GRRegs:$lhs, 32), bb:$dst)>;
+
+def : Pat<(select (setlt GRRegs:$lhs, 0), GRRegs:$T, GRRegs:$F),
+ (SELECT_CC (ASHR_l2rus GRRegs:$lhs, 32), GRRegs:$T, GRRegs:$F)>;
+
+def : Pat<(select (setgt GRRegs:$lhs, -1), GRRegs:$T, GRRegs:$F),
+ (SELECT_CC (ASHR_l2rus GRRegs:$lhs, 32), GRRegs:$F, GRRegs:$T)>;
+
+def : Pat<(setgt GRRegs:$lhs, -1),
+ (EQ_2rus (ASHR_l2rus GRRegs:$lhs, 32), 0)>;
+
+def : Pat<(sra (shl GRRegs:$src, immBpwSubBitp:$imm), immBpwSubBitp:$imm),
+ (SEXT_rus GRRegs:$src, (bpwsub_xform immBpwSubBitp:$imm))>;