aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r--llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp6
-rw-r--r--llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td17
-rw-r--r--llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.cpp93
-rw-r--r--llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.h6
4 files changed, 116 insertions, 6 deletions
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
index 5df70c4..4056724 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
@@ -1034,14 +1034,12 @@ MCELFStreamer &MipsTargetELFStreamer::getStreamer() {
void MipsTargetELFStreamer::emitGPRel32Value(const MCExpr *Value) {
auto &S = getStreamer();
- S.ensureHeadroom(4);
S.addFixup(Value, Mips::fixup_Mips_GPREL32);
S.appendContents(4, 0);
}
void MipsTargetELFStreamer::emitGPRel64Value(const MCExpr *Value) {
auto &S = getStreamer();
- S.ensureHeadroom(8);
// fixup_Mips_GPREL32 desginates R_MIPS_GPREL32+R_MIPS_64 on MIPS64.
S.addFixup(Value, Mips::fixup_Mips_GPREL32);
S.appendContents(8, 0);
@@ -1049,28 +1047,24 @@ void MipsTargetELFStreamer::emitGPRel64Value(const MCExpr *Value) {
void MipsTargetELFStreamer::emitDTPRel32Value(const MCExpr *Value) {
auto &S = getStreamer();
- S.ensureHeadroom(4);
S.addFixup(Value, Mips::fixup_Mips_DTPREL32);
S.appendContents(4, 0);
}
void MipsTargetELFStreamer::emitDTPRel64Value(const MCExpr *Value) {
auto &S = getStreamer();
- S.ensureHeadroom(8);
S.addFixup(Value, Mips::fixup_Mips_DTPREL64);
S.appendContents(8, 0);
}
void MipsTargetELFStreamer::emitTPRel32Value(const MCExpr *Value) {
auto &S = getStreamer();
- S.ensureHeadroom(4);
S.addFixup(Value, Mips::fixup_Mips_TPREL32);
S.appendContents(4, 0);
}
void MipsTargetELFStreamer::emitTPRel64Value(const MCExpr *Value) {
auto &S = getStreamer();
- S.ensureHeadroom(8);
S.addFixup(Value, Mips::fixup_Mips_TPREL64);
S.appendContents(8, 0);
}
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index 5265613..44a8245d 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -14,6 +14,14 @@
// Operand and SDNode transformation definitions.
//===----------------------------------------------------------------------===//
+def SDT_SetMultiple : SDTypeProfile<0, 4, [SDTCisSameAs<0, 1>,
+ SDTCisSameAs<1, 3>,
+ SDTCisPtrTy<2>,
+ SDTCisVT<3, XLenVT>]>;
+
+def qc_setwmi : RVSDNode<"QC_SETWMI", SDT_SetMultiple,
+ [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
+
def uimm5nonzero : RISCVOp<XLenVT>,
ImmLeaf<XLenVT, [{return (Imm != 0) && isUInt<5>(Imm);}]> {
let ParserMatchClass = UImmAsmOperand<5, "NonZero">;
@@ -27,6 +35,8 @@ def uimm5nonzero : RISCVOp<XLenVT>,
}];
}
+def tuimm5nonzero : TImmLeaf<XLenVT, [{return (Imm != 0) && isUInt<5>(Imm);}]>;
+
def uimm5gt3 : RISCVOp<XLenVT>, ImmLeaf<XLenVT,
[{return (Imm > 3) && isUInt<5>(Imm);}]> {
let ParserMatchClass = UImmAsmOperand<5, "GT3">;
@@ -92,6 +102,8 @@ def uimm5slist : RISCVOp<XLenVT>, ImmLeaf<XLenVT,
}];
}
+def tuimm7_lsb00 : TImmLeaf<XLenVT,[{return isShiftedUInt<5, 2>(Imm);}]>;
+
def uimm10 : RISCVUImmLeafOp<10>;
def uimm11 : RISCVUImmLeafOp<11>;
@@ -1566,6 +1578,11 @@ def : QCISELECTIICCPat <SETEQ, QC_SELECTIIEQ>;
def : QCISELECTIICCPat <SETNE, QC_SELECTIINE>;
} // Predicates = [HasVendorXqcics, IsRV32]
+let Predicates = [HasVendorXqcilsm, IsRV32] in {
+def : Pat<(qc_setwmi GPR:$rs3, GPR:$rs1, tuimm5nonzero:$uimm5, tuimm7_lsb00:$uimm7),
+ (QC_SETWMI GPR:$rs3, GPR:$rs1, tuimm5nonzero:$uimm5, tuimm7_lsb00:$uimm7)>;
+} // Predicates = [HasVendorXqcilsm, IsRV32]
+
//===----------------------------------------------------------------------===/i
// Compress Instruction tablegen backend.
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.cpp b/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.cpp
index 6ecddad..041dd07 100644
--- a/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.cpp
@@ -7,6 +7,8 @@
//===----------------------------------------------------------------------===//
#include "RISCVSelectionDAGInfo.h"
+#include "RISCVSubtarget.h"
+#include "llvm/CodeGen/SelectionDAG.h"
#define GET_SDNODE_DESC
#include "RISCVGenSDNodeInfo.inc"
@@ -62,3 +64,94 @@ void RISCVSelectionDAGInfo::verifyTargetNode(const SelectionDAG &DAG,
}
#endif
}
+
+SDValue RISCVSelectionDAGInfo::EmitTargetCodeForMemset(
+ SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src,
+ SDValue Size, Align Alignment, bool isVolatile, bool AlwaysInline,
+ MachinePointerInfo DstPtrInfo) const {
+ const auto &Subtarget = DAG.getSubtarget<RISCVSubtarget>();
+ // We currently do this only for Xqcilsm
+ if (!Subtarget.hasVendorXqcilsm())
+ return SDValue();
+
+ // Do this only if we know the size at compile time.
+ ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size);
+ if (!ConstantSize)
+ return SDValue();
+
+ uint64_t NumberOfBytesToWrite = ConstantSize->getZExtValue();
+
+ // Do this only if it is word aligned and we write a multiple of 4 bytes.
+ if (!(Alignment >= 4) || !((NumberOfBytesToWrite & 3) == 0))
+ return SDValue();
+
+ SmallVector<SDValue, 8> OutChains;
+ SDValue SrcValueReplicated = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i32, Src);
+ int NumberOfWords = NumberOfBytesToWrite / 4;
+ MachineFunction &MF = DAG.getMachineFunction();
+ auto Volatile =
+ isVolatile ? MachineMemOperand::MOVolatile : MachineMemOperand::MONone;
+
+ // Helper for constructing the QC_SETWMI instruction
+ auto getSetwmiNode = [&](uint8_t SizeWords, uint8_t OffsetSetwmi) -> SDValue {
+ SDValue Ops[] = {Chain, SrcValueReplicated, Dst,
+ DAG.getTargetConstant(SizeWords, dl, MVT::i32),
+ DAG.getTargetConstant(OffsetSetwmi, dl, MVT::i32)};
+ MachineMemOperand *BaseMemOperand = MF.getMachineMemOperand(
+ DstPtrInfo.getWithOffset(OffsetSetwmi),
+ MachineMemOperand::MOStore | Volatile, SizeWords * 4, Align(4));
+ return DAG.getMemIntrinsicNode(RISCVISD::QC_SETWMI, dl,
+ DAG.getVTList(MVT::Other), Ops, MVT::i32,
+ BaseMemOperand);
+ };
+
+ // If i8 type and constant non-zero value.
+ if ((Src.getValueType() == MVT::i8) && !isNullConstant(Src))
+ // Replicate byte to word by multiplication with 0x01010101.
+ SrcValueReplicated =
+ DAG.getNode(ISD::MUL, dl, MVT::i32, SrcValueReplicated,
+ DAG.getConstant(0x01010101ul, dl, MVT::i32));
+
+ // We limit a QC_SETWMI to 16 words or less to improve interruptibility.
+ // So for 1-16 words we use a single QC_SETWMI:
+ //
+ // QC_SETWMI reg1, N, 0(reg2)
+ //
+ // For 17-32 words we use two QC_SETWMI's with the first as 16 words and the
+ // second for the remainder:
+ //
+ // QC_SETWMI reg1, 16, 0(reg2)
+ // QC_SETWMI reg1, N, 64(reg2)
+ //
+ // For 33-48 words, we would like to use (16, 16, n), but that means the last
+ // QC_SETWMI needs an offset of 128 which the instruction doesn't support.
+ // So in this case we use a length of 15 for the second instruction and we do
+ // the rest with the third instruction.
+ // This means the maximum inlined number of words is 47 (for now):
+ //
+ // QC_SETWMI R2, R0, 16, 0
+ // QC_SETWMI R2, R0, 15, 64
+ // QC_SETWMI R2, R0, N, 124
+ //
+ // For 48 words or more, call the target independent memset
+ if (NumberOfWords >= 48)
+ return SDValue();
+
+ if (NumberOfWords <= 16) {
+ // 1 - 16 words
+ return getSetwmiNode(NumberOfWords, 0);
+ }
+
+ if (NumberOfWords <= 32) {
+ // 17 - 32 words
+ OutChains.push_back(getSetwmiNode(NumberOfWords - 16, 64));
+ OutChains.push_back(getSetwmiNode(16, 0));
+ } else {
+ // 33 - 47 words
+ OutChains.push_back(getSetwmiNode(NumberOfWords - 31, 124));
+ OutChains.push_back(getSetwmiNode(15, 64));
+ OutChains.push_back(getSetwmiNode(16, 0));
+ }
+
+ return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains);
+}
diff --git a/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.h b/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.h
index 641189f..08c8d11 100644
--- a/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.h
+++ b/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.h
@@ -34,6 +34,12 @@ public:
void verifyTargetNode(const SelectionDAG &DAG,
const SDNode *N) const override;
+ SDValue EmitTargetCodeForMemset(SelectionDAG &DAG, const SDLoc &dl,
+ SDValue Chain, SDValue Dst, SDValue Src,
+ SDValue Size, Align Alignment,
+ bool isVolatile, bool AlwaysInline,
+ MachinePointerInfo DstPtrInfo) const override;
+
bool hasPassthruOp(unsigned Opcode) const {
return GenNodeInfo.getDesc(Opcode).TSFlags & RISCVISD::HasPassthruOpMask;
}