-def XSHWvec:
- RRForm_1<0b01101101010, (outs VECREG:$rDest), (ins VECREG:$rSrc),
- "xshw\t$rDest, $rSrc", IntegerOp,
- [(set (v4i32 VECREG:$rDest), (sext (v8i16 VECREG:$rSrc)))]>;
-
-def XSHWr32:
- RRForm_1<0b01101101010, (outs R32C:$rDst), (ins R32C:$rSrc),
- "xshw\t$rDst, $rSrc", IntegerOp,
- [(set R32C:$rDst, (sext_inreg R32C:$rSrc, i16))]>;
-
-def XSHWr16:
- RRForm_1<0b01101101010, (outs R32C:$rDst), (ins R16C:$rSrc),
- "xshw\t$rDst, $rSrc", IntegerOp,
- [(set R32C:$rDst, (sext R16C:$rSrc))]>;
-
-def XSWDvec:
- RRForm_1<0b01100101010, (outs VECREG:$rDst), (ins VECREG:$rSrc),
- "xswd\t$rDst, $rSrc", IntegerOp,
- [(set (v2i64 VECREG:$rDst), (sext (v4i32 VECREG:$rSrc)))]>;
-
-def XSWDr64:
- RRForm_1<0b01100101010, (outs R64C:$rDst), (ins R64C:$rSrc),
- "xswd\t$rDst, $rSrc", IntegerOp,
- [(set R64C:$rDst, (sext_inreg R64C:$rSrc, i32))]>;
-
-def XSWDr32:
- RRForm_1<0b01100101010, (outs R64C:$rDst), (ins R32C:$rSrc),
- "xswd\t$rDst, $rSrc", IntegerOp,
- [(set R64C:$rDst, (SPUsext32_to_64 R32C:$rSrc))]>;
-
-def : Pat<(sext R32C:$inp),
- (XSWDr32 R32C:$inp)>;
+
+class XSHWInst<dag OOL, dag IOL, list<dag> pattern>:
+ RRForm_1<0b01101101010, OOL, IOL, "xshw\t$rDest, $rSrc",
+ IntegerOp, pattern>;
+
+class XSHWVecInst<ValueType in_vectype, ValueType out_vectype>:
+ XSHWInst<(outs VECREG:$rDest), (ins VECREG:$rSrc),
+ [(set (out_vectype VECREG:$rDest),
+ (sext (in_vectype VECREG:$rSrc)))]>;
+
+class XSHWInRegInst<RegisterClass rclass, list<dag> pattern>:
+ XSHWInst<(outs rclass:$rDest), (ins rclass:$rSrc),
+ pattern>;
+
+class XSHWRegInst<RegisterClass rclass>:
+ XSHWInst<(outs rclass:$rDest), (ins R16C:$rSrc),
+ [(set rclass:$rDest, (sext R16C:$rSrc))]>;
+
+multiclass ExtendHalfwordWord {
+ def v4i32: XSHWVecInst<v4i32, v8i16>;
+
+ def r16: XSHWRegInst<R32C>;
+
+ def r32: XSHWInRegInst<R32C,
+ [(set R32C:$rDest, (sext_inreg R32C:$rSrc, i16))]>;
+ def r64: XSHWInRegInst<R64C, [/* no pattern */]>;
+}
+
+defm XSHW : ExtendHalfwordWord;
+
+// Sign-extend words to doublewords (32->64 bits)
+
+class XSWDInst<dag OOL, dag IOL, list<dag> pattern>:
+ RRForm_1<0b01100101010, OOL, IOL, "xswd\t$rDst, $rSrc",
+ IntegerOp, pattern>;
+
+class XSWDVecInst<ValueType in_vectype, ValueType out_vectype>:
+ XSWDInst<(outs VECREG:$rDst), (ins VECREG:$rSrc),
+ [(set (out_vectype VECREG:$rDst),
+ (sext (out_vectype VECREG:$rSrc)))]>;
+
+class XSWDRegInst<RegisterClass in_rclass, RegisterClass out_rclass>:
+ XSWDInst<(outs out_rclass:$rDst), (ins in_rclass:$rSrc),
+ [(set out_rclass:$rDst, (sext in_rclass:$rSrc))]>;
+
+multiclass ExtendWordToDoubleWord {
+ def v2i64: XSWDVecInst<v4i32, v2i64>;
+ def r64: XSWDRegInst<R32C, R64C>;
+
+ def r64_inreg: XSWDInst<(outs R64C:$rDst), (ins R64C:$rSrc),
+ [(set R64C:$rDst, (sext_inreg R64C:$rSrc, i32))]>;
+}
+
+defm XSWD : ExtendWordToDoubleWord;