return true;
}
-bool AArch64DAGToDAGISel::SelectSVEAddSubImm(SDValue N, MVT VT, SDValue &Imm, SDValue &Shift) {
- if (auto CNode = dyn_cast<ConstantSDNode>(N)) {
- const int64_t ImmVal = CNode->getSExtValue();
- SDLoc DL(N);
+bool AArch64DAGToDAGISel::SelectSVEAddSubImm(SDValue N, MVT VT, SDValue &Imm,
+ SDValue &Shift) {
+ if (!isa<ConstantSDNode>(N))
+ return false;
- switch (VT.SimpleTy) {
- case MVT::i8:
- // Can always select i8s, no shift, mask the immediate value to
- // deal with sign-extended value from lowering.
+ SDLoc DL(N);
+ uint64_t Val = cast<ConstantSDNode>(N)
+ ->getAPIntValue()
+ .truncOrSelf(VT.getFixedSizeInBits())
+ .getZExtValue();
+
+ switch (VT.SimpleTy) {
+ case MVT::i8:
+ // All immediates are supported.
+ Shift = CurDAG->getTargetConstant(0, DL, MVT::i32);
+ Imm = CurDAG->getTargetConstant(Val, DL, MVT::i32);
+ return true;
+ case MVT::i16:
+ case MVT::i32:
+ case MVT::i64:
+ // Support 8bit unsigned immediates.
+ if (Val <= 255) {
Shift = CurDAG->getTargetConstant(0, DL, MVT::i32);
- Imm = CurDAG->getTargetConstant(ImmVal & 0xFF, DL, MVT::i32);
+ Imm = CurDAG->getTargetConstant(Val, DL, MVT::i32);
return true;
- case MVT::i16:
- // i16 values get sign-extended to 32-bits during lowering.
- if ((ImmVal & 0xFF) == ImmVal) {
- Shift = CurDAG->getTargetConstant(0, DL, MVT::i32);
- Imm = CurDAG->getTargetConstant(ImmVal, DL, MVT::i32);
- return true;
- } else if ((ImmVal & 0xFF) == 0) {
- Shift = CurDAG->getTargetConstant(8, DL, MVT::i32);
- Imm = CurDAG->getTargetConstant((ImmVal >> 8) & 0xFF, DL, MVT::i32);
- return true;
- }
- break;
- case MVT::i32:
- case MVT::i64:
- // Range of immediate won't trigger signedness problems for 32/64b.
- if ((ImmVal & 0xFF) == ImmVal) {
- Shift = CurDAG->getTargetConstant(0, DL, MVT::i32);
- Imm = CurDAG->getTargetConstant(ImmVal, DL, MVT::i32);
- return true;
- } else if ((ImmVal & 0xFF00) == ImmVal) {
- Shift = CurDAG->getTargetConstant(8, DL, MVT::i32);
- Imm = CurDAG->getTargetConstant(ImmVal >> 8, DL, MVT::i32);
- return true;
- }
- break;
- default:
- break;
}
+ // Support 16bit unsigned immediates that are a multiple of 256.
+ if (Val <= 65280 && Val % 256 == 0) {
+ Shift = CurDAG->getTargetConstant(8, DL, MVT::i32);
+ Imm = CurDAG->getTargetConstant(Val >> 8, DL, MVT::i32);
+ return true;
+ }
+ break;
+ default:
+ break;
}
return false;