ResNode = SelectARMIndexedLoad(N);
if (ResNode)
return ResNode;
+
+ // VLDMQ must be custom-selected for "v2f64 load" to set the AM5Opc value.
+ if (Subtarget->hasVFP2() &&
+ N->getValueType(0).getSimpleVT().SimpleTy == MVT::v2f64) {
+ SDValue Chain = N->getOperand(0);
+ SDValue AM5Opc =
+ CurDAG->getTargetConstant(ARM_AM::getAM5Opc(ARM_AM::ia, 4), MVT::i32);
+ SDValue Pred = CurDAG->getTargetConstant(14, MVT::i32);
+ SDValue PredReg = CurDAG->getRegister(0, MVT::i32);
+ SDValue Ops[] = { N->getOperand(1), AM5Opc, Pred, PredReg, Chain };
+ return CurDAG->getMachineNode(ARM::VLDMQ, dl, MVT::v2f64, MVT::Other,
+ Ops, 5);
+ }
+ // Other cases are autogenerated.
+ break;
+ }
+ case ISD::STORE: {
+ // VSTMQ must be custom-selected for "v2f64 store" to set the AM5Opc value.
+ if (Subtarget->hasVFP2() &&
+ N->getOperand(1).getValueType().getSimpleVT().SimpleTy == MVT::v2f64) {
+ SDValue Chain = N->getOperand(0);
+ SDValue AM5Opc =
+ CurDAG->getTargetConstant(ARM_AM::getAM5Opc(ARM_AM::ia, 4), MVT::i32);
+ SDValue Pred = CurDAG->getTargetConstant(14, MVT::i32);
+ SDValue PredReg = CurDAG->getRegister(0, MVT::i32);
+ SDValue Ops[] = { N->getOperand(1), N->getOperand(2),
+ AM5Opc, Pred, PredReg, Chain };
+ return CurDAG->getMachineNode(ARM::VSTMQ, dl, MVT::Other, Ops, 6);
+ }
// Other cases are autogenerated.
break;
}
pattern> {
}
-class NI4<dag oops, dag iops, InstrItinClass itin, string opc,
- string asm, list<dag> pattern>
- : NeonXI<oops, iops, AddrMode4, IndexModeNone, itin, opc, asm, "",
- pattern> {
-}
-
class NLdSt<bit op23, bits<2> op21_20, bits<4> op11_8, bits<4> op7_4,
dag oops, dag iops, InstrItinClass itin,
string opc, string dt, string asm, string cstr, list<dag> pattern>
// NEON load / store instructions
//===----------------------------------------------------------------------===//
+let mayLoad = 1 in {
// Use vldmia to load a Q register as a D register pair.
-// This is equivalent to VLDMD except that it has a Q register operand.
-def VLDMQ : NI4<(outs QPR:$dst), (ins addrmode4:$addr), IIC_fpLoadm,
- "vldmia", "$addr, ${dst:dregpair}",
- [(set QPR:$dst, (v2f64 (load addrmode4:$addr)))]> {
- let Inst{27-25} = 0b110;
- let Inst{24} = 0; // P bit
- let Inst{23} = 1; // U bit
- let Inst{20} = 1;
- let Inst{11-8} = 0b1011;
-}
+// This is equivalent to VLDMD except that it has a Q register operand
+// instead of a pair of D registers.
+def VLDMQ
+ : AXDI5<(outs QPR:$dst), (ins addrmode5:$addr, pred:$p),
+ IndexModeNone, IIC_fpLoadm,
+ "vldm${addr:submode}${p}\t${addr:base}, ${dst:dregpair}", "", []>;
+def VLDMQ_UPD
+ : AXDI5<(outs QPR:$dst, GPR:$wb), (ins addrmode5:$addr, pred:$p),
+ IndexModeUpd, IIC_fpLoadm,
+ "vldm${addr:submode}${p}\t${addr:base}!, ${dst:dregpair}",
+ "$addr.base = $wb", []>;
-let mayLoad = 1 in {
// Use vld1 to load a Q register as a D register pair.
// This alternative to VLDMQ allows an alignment to be specified.
// This is equivalent to VLD1q64 except that it has a Q register operand.
"${dst:dregpair}, $addr$offset", "$addr.addr = $wb", []>;
} // mayLoad = 1
+let mayStore = 1 in {
// Use vstmia to store a Q register as a D register pair.
-// This is equivalent to VSTMD except that it has a Q register operand.
-def VSTMQ : NI4<(outs), (ins QPR:$src, addrmode4:$addr), IIC_fpStorem,
- "vstmia", "$addr, ${src:dregpair}",
- [(store (v2f64 QPR:$src), addrmode4:$addr)]> {
- let Inst{27-25} = 0b110;
- let Inst{24} = 0; // P bit
- let Inst{23} = 1; // U bit
- let Inst{20} = 0;
- let Inst{11-8} = 0b1011;
-}
+// This is equivalent to VSTMD except that it has a Q register operand
+// instead of a pair of D registers.
+def VSTMQ
+ : AXDI5<(outs), (ins QPR:$src, addrmode5:$addr, pred:$p),
+ IndexModeNone, IIC_fpStorem,
+ "vstm${addr:submode}${p}\t${addr:base}, ${src:dregpair}", "", []>;
+def VSTMQ_UPD
+ : AXDI5<(outs GPR:$wb), (ins QPR:$src, addrmode5:$addr, pred:$p),
+ IndexModeUpd, IIC_fpStorem,
+ "vstm${addr:submode}${p}\t${addr:base}!, ${src:dregpair}",
+ "$addr.base = $wb", []>;
-let mayStore = 1 in {
// Use vst1 to store a Q register as a D register pair.
// This alternative to VSTMQ allows an alignment to be specified.
// This is equivalent to VST1q64 except that it has a Q register operand.