@@ -198,7 +198,7 @@ let DecoderNamespace = "XCValu" in {
198
198
199
199
} // DecoderNamespace = "XCValu"
200
200
201
- let Predicates = [HasVendorXCValu],
201
+ let Predicates = [HasVendorXCValu, IsRV32 ],
202
202
hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
203
203
// General ALU Operations
204
204
def CV_ABS : CVInstAluR<0b0101000, 0b011, "cv.abs">,
@@ -249,10 +249,10 @@ let Predicates = [HasVendorXCValu],
249
249
Sched<[]>;
250
250
def CV_SUBURN : CVInstAluRRI<0b11, 0b011, "cv.suburn">,
251
251
Sched<[]>;
252
- } // Predicates = [HasVendorXCValu],
252
+ } // Predicates = [HasVendorXCValu, IsRV32 ],
253
253
// hasSideEffects = 0, mayLoad = 0, mayStore = 0
254
254
255
- let Predicates = [HasVendorXCValu],
255
+ let Predicates = [HasVendorXCValu, IsRV32 ],
256
256
hasSideEffects = 0, mayLoad = 0, mayStore = 0,
257
257
Constraints = "$rd = $rd_wb" in {
258
258
def CV_ADDNR : CVInstAluRRNR<0b1000000, 0b011, "cv.addnr">,
@@ -272,7 +272,7 @@ let Predicates = [HasVendorXCValu],
272
272
def CV_SUBURNR : CVInstAluRRNR<0b1000111, 0b011, "cv.suburnr">,
273
273
Sched<[]>;
274
274
275
- } // Predicates = [HasVendorXCValu],
275
+ } // Predicates = [HasVendorXCValu, IsRV32 ],
276
276
// hasSideEffects = 0, mayLoad = 0, mayStore = 0,
277
277
// Constraints = "$rd = $rd_wb"
278
278
@@ -662,6 +662,8 @@ let Predicates = [HasVendorXCVelw, IsRV32], hasSideEffects = 0,
662
662
def cv_tuimm2 : TImmLeaf<XLenVT, [{return isUInt<2>(Imm);}]>;
663
663
def cv_tuimm5 : TImmLeaf<XLenVT, [{return isUInt<5>(Imm);}]>;
664
664
def cv_uimm10 : ImmLeaf<XLenVT, [{return isUInt<10>(Imm);}]>;
665
+ def cv_uimm_pow2: Operand<XLenVT>,
666
+ ImmLeaf<XLenVT, [{return isPowerOf2_32(Imm + 1);}]>;
665
667
666
668
def CV_LO5: SDNodeXForm<imm, [{
667
669
return CurDAG->getTargetConstant(N->getZExtValue() & 0x1f, SDLoc(N),
@@ -673,6 +675,49 @@ def CV_HI5: SDNodeXForm<imm, [{
673
675
N->getValueType(0));
674
676
}]>;
675
677
678
+ def between : PatFrags<(ops node:$lowerBound, node:$upperBound, node:$value),
679
+ [(smin (smax node:$value, node:$lowerBound), node:$upperBound),
680
+ (smax (smin node:$value, node:$upperBound), node:$lowerBound)]>;
681
+
682
+ def betweenu : PatFrags<(ops node:$upperBound, node:$value),
683
+ [(smin (smax node:$value, 0), node:$upperBound),
684
+ (smax (smin node:$value, node:$upperBound), 0)]>;
685
+ def powerOf2 : ImmLeaf<XLenVT, [{ return isPowerOf2_32(Imm); }]>;
686
+ def powerOf2Minus1 : ImmLeaf<XLenVT, [{ return isPowerOf2_32(Imm+1); }]>;
687
+ def negativePowerOf2 : ImmLeaf<XLenVT, [{ return isPowerOf2_32(-Imm); }]>;
688
+ def roundBit : PatFrag<(ops node:$shiftAmount),
689
+ (srl (shl 1, node:$shiftAmount), (XLenVT 1))>;
690
+ def trailing1sPlus1 : SDNodeXForm<imm, [{
691
+ return CurDAG->getTargetConstant(
692
+ llvm::countr_one(N->getZExtValue()) + 1,
693
+ SDLoc(N), N->getValueType(0));
694
+ }]>;
695
+
696
+ def shiftRound : PatFrag<(ops node:$value, node:$shiftAmount),
697
+ (sra (add node:$value, powerOf2), node:$shiftAmount), [{
698
+ if (auto powerOf2 = dyn_cast<ConstantSDNode>(N->getOperand(0)->getOperand(1)))
699
+ return (powerOf2->getZExtValue() << 1) == (1U << N->getConstantOperandVal(1));
700
+ return false;
701
+ }]>;
702
+
703
+ def ushiftRound : PatFrag<(ops node:$value, node:$shiftAmount),
704
+ (srl (add node:$value, powerOf2), node:$shiftAmount), [{
705
+ if (auto powerOf2 = dyn_cast<ConstantSDNode>(N->getOperand(0)->getOperand(1)))
706
+ return (powerOf2->getZExtValue() << 1) == (1U << N->getConstantOperandVal(1));
707
+ return false;
708
+ }]>;
709
+
710
+ def clip : PatFrag<(ops node:$upperBound, node:$value),
711
+ (between negativePowerOf2, node:$upperBound, node:$value), [{
712
+ // Checking lower & upper bound for the clip instruction
713
+ if (auto bound1 = dyn_cast<ConstantSDNode>(N->getOperand(0)->getOperand(1))) {
714
+ if (auto bound2 = dyn_cast<ConstantSDNode>(N->getOperand(1))) {
715
+ return (bound1->getSExtValue() == ~bound2->getSExtValue());
716
+ }
717
+ }
718
+ return false;
719
+ }]>;
720
+
676
721
multiclass PatCoreVBitManip<Intrinsic intr> {
677
722
def : PatGprGpr<intr, !cast<RVInst>("CV_" # NAME # "R")>;
678
723
def : Pat<(intr GPR:$rs1, cv_uimm10:$imm),
@@ -704,3 +749,109 @@ let Predicates = [HasVendorXCVbitmanip, IsRV32] in {
704
749
(CV_BITREV GPR:$rs1, cv_tuimm2:$radix, cv_tuimm5:$pts)>;
705
750
def : Pat<(bitreverse (XLenVT GPR:$rs)), (CV_BITREV GPR:$rs, 0, 0)>;
706
751
}
752
+
753
+ class PatCoreVAluGpr <string intr, string asm> :
754
+ PatGpr<!cast<Intrinsic>("int_riscv_cv_alu_" # intr),
755
+ !cast<RVInst>("CV_" # asm)>;
756
+ class PatCoreVAluGprGpr <string intr, string asm> :
757
+ PatGprGpr<!cast<Intrinsic>("int_riscv_cv_alu_" # intr),
758
+ !cast<RVInst>("CV_" # asm)>;
759
+
760
+ multiclass PatCoreVAluGprImm <Intrinsic intr> {
761
+ def : PatGprGpr<intr, !cast<RVInst>("CV_" # NAME # "R")>;
762
+ def : Pat<(intr (XLenVT GPR:$rs1), powerOf2Minus1:$upperBound),
763
+ (!cast<RVInst>("CV_" # NAME) GPR:$rs1,
764
+ (trailing1sPlus1 imm:$upperBound))>;
765
+ }
766
+
767
+ multiclass PatCoreVAluGprGprImm <Intrinsic intr> {
768
+ def : Pat<(intr GPR:$rs1, GPR:$rs2, GPR:$rs3),
769
+ (!cast<RVInst>("CV_" # NAME # "R") GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
770
+ def : Pat<(intr GPR:$rs1, GPR:$rs2, uimm5:$imm),
771
+ (!cast<RVInst>("CV_" # NAME) GPR:$rs1, GPR:$rs2, uimm5:$imm)>;
772
+ }
773
+
774
+ let Predicates = [HasVendorXCValu, IsRV32], AddedComplexity = 1 in {
775
+ def : PatGpr<abs, CV_ABS>;
776
+ def : PatGprGpr<setle, CV_SLET>;
777
+ def : PatGprGpr<setule, CV_SLETU>;
778
+ def : PatGprGpr<smin, CV_MIN>;
779
+ def : PatGprGpr<umin, CV_MINU>;
780
+ def : PatGprGpr<smax, CV_MAX>;
781
+ def : PatGprGpr<umax, CV_MAXU>;
782
+
783
+ def : Pat<(sext_inreg (XLenVT GPR:$rs1), i16), (CV_EXTHS GPR:$rs1)>;
784
+ def : Pat<(sext_inreg (XLenVT GPR:$rs1), i8), (CV_EXTBS GPR:$rs1)>;
785
+
786
+ def : Pat<(and (XLenVT GPR:$rs1), 0xffff), (CV_EXTHZ GPR:$rs1)>;
787
+ def : Pat<(and (XLenVT GPR:$rs1), 0xff), (CV_EXTBZ GPR:$rs1)>;
788
+
789
+ def : Pat<(clip powerOf2Minus1:$upperBound, (XLenVT GPR:$rs1)),
790
+ (CV_CLIP GPR:$rs1, (trailing1sPlus1 imm:$upperBound))>;
791
+ def : Pat<(between (not GPR:$rs2), GPR:$rs2, (XLenVT GPR:$rs1)),
792
+ (CV_CLIPR GPR:$rs1, GPR:$rs2)>;
793
+ def : Pat<(betweenu powerOf2Minus1:$upperBound, (XLenVT GPR:$rs1)),
794
+ (CV_CLIPU GPR:$rs1, (trailing1sPlus1 imm:$upperBound))>;
795
+ def : Pat<(betweenu GPR:$rs2, (XLenVT GPR:$rs1)),
796
+ (CV_CLIPUR GPR:$rs1, GPR:$rs2)>;
797
+
798
+ def : Pat<(sra (add (XLenVT GPR:$rs1), (XLenVT GPR:$rs2)), uimm5:$imm5),
799
+ (CV_ADDN GPR:$rs1, GPR:$rs2, uimm5:$imm5)>;
800
+ def : Pat<(srl (add (XLenVT GPR:$rs1), (XLenVT GPR:$rs2)), uimm5:$imm5),
801
+ (CV_ADDUN GPR:$rs1, GPR:$rs2, uimm5:$imm5)>;
802
+ def : Pat<(shiftRound (add (XLenVT GPR:$rs1), (XLenVT GPR:$rs2)),
803
+ uimm5:$imm5),
804
+ (CV_ADDRN GPR:$rs1, GPR:$rs2, uimm5:$imm5)>;
805
+ def : Pat<(ushiftRound (add (XLenVT GPR:$rs1), (XLenVT GPR:$rs2)),
806
+ uimm5:$imm5),
807
+ (CV_ADDURN GPR:$rs1, GPR:$rs2, uimm5:$imm5)>;
808
+
809
+ def : Pat<(sra (sub (XLenVT GPR:$rs1), (XLenVT GPR:$rs2)), uimm5:$imm5),
810
+ (CV_SUBN GPR:$rs1, GPR:$rs2, uimm5:$imm5)>;
811
+ def : Pat<(srl (sub (XLenVT GPR:$rs1), (XLenVT GPR:$rs2)), uimm5:$imm5),
812
+ (CV_SUBUN GPR:$rs1, GPR:$rs2, uimm5:$imm5)>;
813
+ def : Pat<(shiftRound (sub (XLenVT GPR:$rs1), (XLenVT GPR:$rs2)),
814
+ uimm5:$imm5),
815
+ (CV_SUBRN GPR:$rs1, GPR:$rs2, uimm5:$imm5)>;
816
+ def : Pat<(ushiftRound (sub (XLenVT GPR:$rs1), (XLenVT GPR:$rs2)),
817
+ uimm5:$imm5),
818
+ (CV_SUBURN GPR:$rs1, GPR:$rs2, uimm5:$imm5)>;
819
+
820
+ def : Pat<(sra (add (XLenVT GPR:$rd), (XLenVT GPR:$rs1)), (XLenVT GPR:$rs2)),
821
+ (CV_ADDNR GPR:$rd, GPR:$rs1, GPR:$rs2)>;
822
+ def : Pat<(srl (add (XLenVT GPR:$rd), (XLenVT GPR:$rs1)), (XLenVT GPR:$rs2)),
823
+ (CV_ADDUNR GPR:$rd, GPR:$rs1, GPR:$rs2)>;
824
+ def : Pat<(sra (add (add (XLenVT GPR:$rd), (XLenVT GPR:$rs1)),
825
+ (roundBit (XLenVT GPR:$rs2))), (XLenVT GPR:$rs2)),
826
+ (CV_ADDRNR GPR:$rd, GPR:$rs1, GPR:$rs2)>;
827
+ def : Pat<(srl (add (add (XLenVT GPR:$rd), (XLenVT GPR:$rs1)),
828
+ (roundBit (XLenVT GPR:$rs2))), (XLenVT GPR:$rs2)),
829
+ (CV_ADDURNR GPR:$rd, GPR:$rs1, GPR:$rs2)>;
830
+
831
+ def : Pat<(sra (sub (XLenVT GPR:$rd), (XLenVT GPR:$rs1)), (XLenVT GPR:$rs2)),
832
+ (CV_SUBNR GPR:$rd, GPR:$rs1, GPR:$rs2)>;
833
+ def : Pat<(srl (sub (XLenVT GPR:$rd), (XLenVT GPR:$rs1)), (XLenVT GPR:$rs2)),
834
+ (CV_SUBUNR GPR:$rd, GPR:$rs1, GPR:$rs2)>;
835
+ def : Pat<(sra (add (sub (XLenVT GPR:$rd), (XLenVT GPR:$rs1)),
836
+ (roundBit (XLenVT GPR:$rs2))), (XLenVT GPR:$rs2)),
837
+ (CV_SUBRNR GPR:$rd, GPR:$rs1, GPR:$rs2)>;
838
+ def : Pat<(srl (add (sub (XLenVT GPR:$rd), (XLenVT GPR:$rs1)),
839
+ (roundBit (XLenVT GPR:$rs2))), (XLenVT GPR:$rs2)),
840
+ (CV_SUBURNR GPR:$rd, GPR:$rs1, GPR:$rs2)>;
841
+
842
+ def : PatCoreVAluGpr<"exths", "EXTHS">;
843
+ def : PatCoreVAluGpr<"exthz", "EXTHZ">;
844
+ def : PatCoreVAluGpr<"extbs", "EXTBS">;
845
+ def : PatCoreVAluGpr<"extbz", "EXTBZ">;
846
+
847
+ defm CLIP : PatCoreVAluGprImm<int_riscv_cv_alu_clip>;
848
+ defm CLIPU : PatCoreVAluGprImm<int_riscv_cv_alu_clipu>;
849
+ defm ADDN : PatCoreVAluGprGprImm<int_riscv_cv_alu_addn>;
850
+ defm ADDUN : PatCoreVAluGprGprImm<int_riscv_cv_alu_addun>;
851
+ defm ADDRN : PatCoreVAluGprGprImm<int_riscv_cv_alu_addrn>;
852
+ defm ADDURN : PatCoreVAluGprGprImm<int_riscv_cv_alu_addurn>;
853
+ defm SUBN : PatCoreVAluGprGprImm<int_riscv_cv_alu_subn>;
854
+ defm SUBUN : PatCoreVAluGprGprImm<int_riscv_cv_alu_subun>;
855
+ defm SUBRN : PatCoreVAluGprGprImm<int_riscv_cv_alu_subrn>;
856
+ defm SUBURN : PatCoreVAluGprGprImm<int_riscv_cv_alu_suburn>;
857
+ } // Predicates = [HasVendorXCValu, IsRV32]
0 commit comments