summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp')
-rw-r--r--llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp121
1 files changed, 121 insertions, 0 deletions
diff --git a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp
index 698d50542fc..17b3a5507d7 100644
--- a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp
@@ -1971,3 +1971,124 @@ void HexagonDAGToDAGISel::SelectHvxRor(SDNode *N) {
HvxSelector(*this, *CurDAG).selectRor(N);
}
+void HexagonDAGToDAGISel::SelectV65GatherPred(SDNode *N) {
+ const SDLoc &dl(N);
+ SDValue Chain = N->getOperand(0);
+ SDValue Address = N->getOperand(2);
+ SDValue Predicate = N->getOperand(3);
+ SDValue Base = N->getOperand(4);
+ SDValue Modifier = N->getOperand(5);
+ SDValue Offset = N->getOperand(6);
+
+ unsigned Opcode;
+ unsigned IntNo = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue();
+ switch (IntNo) {
+ default:
+ llvm_unreachable("Unexpected HVX gather intrinsic.");
+ case Intrinsic::hexagon_V6_vgathermhq:
+ case Intrinsic::hexagon_V6_vgathermhq_128B:
+ Opcode = Hexagon::V6_vgathermhq_pseudo;
+ break;
+ case Intrinsic::hexagon_V6_vgathermwq:
+ case Intrinsic::hexagon_V6_vgathermwq_128B:
+ Opcode = Hexagon::V6_vgathermwq_pseudo;
+ break;
+ case Intrinsic::hexagon_V6_vgathermhwq:
+ case Intrinsic::hexagon_V6_vgathermhwq_128B:
+ Opcode = Hexagon::V6_vgathermhwq_pseudo;
+ break;
+ }
+
+ SDVTList VTs = CurDAG->getVTList(MVT::Other);
+ SDValue Ops[] = { Address, Predicate, Base, Modifier, Offset, Chain };
+ SDNode *Result = CurDAG->getMachineNode(Opcode, dl, VTs, Ops);
+
+ MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
+ MemOp[0] = cast<MemIntrinsicSDNode>(N)->getMemOperand();
+ cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
+
+ ReplaceUses(N, Result);
+ CurDAG->RemoveDeadNode(N);
+}
+
+void HexagonDAGToDAGISel::SelectV65Gather(SDNode *N) {
+ const SDLoc &dl(N);
+ SDValue Chain = N->getOperand(0);
+ SDValue Address = N->getOperand(2);
+ SDValue Base = N->getOperand(3);
+ SDValue Modifier = N->getOperand(4);
+ SDValue Offset = N->getOperand(5);
+
+ unsigned Opcode;
+ unsigned IntNo = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue();
+ switch (IntNo) {
+ default:
+ llvm_unreachable("Unexpected HVX gather intrinsic.");
+ case Intrinsic::hexagon_V6_vgathermh:
+ case Intrinsic::hexagon_V6_vgathermh_128B:
+ Opcode = Hexagon::V6_vgathermh_pseudo;
+ break;
+ case Intrinsic::hexagon_V6_vgathermw:
+ case Intrinsic::hexagon_V6_vgathermw_128B:
+ Opcode = Hexagon::V6_vgathermw_pseudo;
+ break;
+ case Intrinsic::hexagon_V6_vgathermhw:
+ case Intrinsic::hexagon_V6_vgathermhw_128B:
+ Opcode = Hexagon::V6_vgathermhw_pseudo;
+ break;
+ }
+
+ SDVTList VTs = CurDAG->getVTList(MVT::Other);
+ SDValue Ops[] = { Address, Base, Modifier, Offset, Chain };
+ SDNode *Result = CurDAG->getMachineNode(Opcode, dl, VTs, Ops);
+
+ MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
+ MemOp[0] = cast<MemIntrinsicSDNode>(N)->getMemOperand();
+ cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
+
+ ReplaceUses(N, Result);
+ CurDAG->RemoveDeadNode(N);
+}
+
+void HexagonDAGToDAGISel::SelectHVXDualOutput(SDNode *N) {
+ unsigned IID = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue();
+ SDNode *Result;
+ switch (IID) {
+ case Intrinsic::hexagon_V6_vaddcarry: {
+ SmallVector<SDValue, 3> Ops = { N->getOperand(1), N->getOperand(2),
+ N->getOperand(3) };
+ SDVTList VTs = CurDAG->getVTList(MVT::v16i32, MVT::v512i1);
+ Result = CurDAG->getMachineNode(Hexagon::V6_vaddcarry, SDLoc(N), VTs, Ops);
+ break;
+ }
+ case Intrinsic::hexagon_V6_vaddcarry_128B: {
+ SmallVector<SDValue, 3> Ops = { N->getOperand(1), N->getOperand(2),
+ N->getOperand(3) };
+ SDVTList VTs = CurDAG->getVTList(MVT::v32i32, MVT::v1024i1);
+ Result = CurDAG->getMachineNode(Hexagon::V6_vaddcarry, SDLoc(N), VTs, Ops);
+ break;
+ }
+ case Intrinsic::hexagon_V6_vsubcarry: {
+ SmallVector<SDValue, 3> Ops = { N->getOperand(1), N->getOperand(2),
+ N->getOperand(3) };
+ SDVTList VTs = CurDAG->getVTList(MVT::v16i32, MVT::v512i1);
+ Result = CurDAG->getMachineNode(Hexagon::V6_vsubcarry, SDLoc(N), VTs, Ops);
+ break;
+ }
+ case Intrinsic::hexagon_V6_vsubcarry_128B: {
+ SmallVector<SDValue, 3> Ops = { N->getOperand(1), N->getOperand(2),
+ N->getOperand(3) };
+ SDVTList VTs = CurDAG->getVTList(MVT::v32i32, MVT::v1024i1);
+ Result = CurDAG->getMachineNode(Hexagon::V6_vsubcarry, SDLoc(N), VTs, Ops);
+ break;
+ }
+ default:
+ llvm_unreachable("Unexpected HVX dual output intrinsic.");
+ }
+ ReplaceUses(N, Result);
+ ReplaceUses(SDValue(N, 0), SDValue(Result, 0));
+ ReplaceUses(SDValue(N, 1), SDValue(Result, 1));
+ CurDAG->RemoveDeadNode(N);
+}
+
+
OpenPOWER on IntegriCloud