def HasStdExtZbbOrZbp
: Predicate<"Subtarget->hasStdExtZbb() || Subtarget->hasStdExtZbp()">,
AssemblerPredicate<(any_of FeatureExtZbb, FeatureExtZbp)>;
+def NotHasStdExtZbbOrZbp
+ : Predicate<"!(Subtarget->hasStdExtZbb() || Subtarget->hasStdExtZbp())">;
def FeatureExtZbproposedc
: SubtargetFeature<"experimental-zbproposedc", "HasStdExtZbproposedc", "true",
/// RV64 patterns
+let Predicates = [IsRV64, NotHasStdExtZbbOrZbp] in
+def : Pat<(and GPR:$rs1, 0xffffffff), (SRLI (SLLI GPR:$rs1, 32), 32)>;
+
let Predicates = [IsRV64] in {
/// sext and zext
def : Pat<(sext_inreg GPR:$rs1, i32), (ADDIW GPR:$rs1, 0)>;
-def : Pat<(and GPR:$rs1, 0xffffffff), (SRLI (SLLI GPR:$rs1, 32), 32)>;
/// ALU operations
(and GPR:$rs1, 0x00FF)),
(PACKH GPR:$rs1, GPR:$rs2)>;
+let Predicates = [HasStdExtZbbOrZbp, IsRV32] in
+def : Pat<(and GPR:$rs, 0x0000FFFF), (PACK GPR:$rs, X0)>;
+let Predicates = [HasStdExtZbbOrZbp, IsRV64] in {
+def : Pat<(and GPR:$rs, 0x000000000000FFFF), (PACKW GPR:$rs, X0)>;
+def : Pat<(and GPR:$rs, 0x00000000FFFFFFFF), (PACK GPR:$rs, X0)>;
+}
+
let Predicates = [HasStdExtZbp, IsRV32] in {
def : Pat<(or (or (and (shl GPR:$rs1, (i32 8)), (i32 0x00FF0000)),
(and GPR:$rs1, (i32 0xFF0000FF))),
%or = or i64 %shl, %and
ret i64 %or
}
+
+define i32 @zexth_i32(i32 %a) nounwind {
+; RV32I-LABEL: zexth_i32:
+; RV32I: # %bb.0:
+; RV32I-NEXT: lui a1, 16
+; RV32I-NEXT: addi a1, a1, -1
+; RV32I-NEXT: and a0, a0, a1
+; RV32I-NEXT: ret
+;
+; RV32IB-LABEL: zexth_i32:
+; RV32IB: # %bb.0:
+; RV32IB-NEXT: zext.h a0, a0
+; RV32IB-NEXT: ret
+;
+; RV32IBB-LABEL: zexth_i32:
+; RV32IBB: # %bb.0:
+; RV32IBB-NEXT: zext.h a0, a0
+; RV32IBB-NEXT: ret
+;
+; RV32IBP-LABEL: zexth_i32:
+; RV32IBP: # %bb.0:
+; RV32IBP-NEXT: pack a0, a0, zero
+; RV32IBP-NEXT: ret
+ %and = and i32 %a, 65535
+ ret i32 %and
+}
+
+define i64 @zexth_i64(i64 %a) nounwind {
+; RV32I-LABEL: zexth_i64:
+; RV32I: # %bb.0:
+; RV32I-NEXT: lui a1, 16
+; RV32I-NEXT: addi a1, a1, -1
+; RV32I-NEXT: and a0, a0, a1
+; RV32I-NEXT: mv a1, zero
+; RV32I-NEXT: ret
+;
+; RV32IB-LABEL: zexth_i64:
+; RV32IB: # %bb.0:
+; RV32IB-NEXT: zext.h a0, a0
+; RV32IB-NEXT: mv a1, zero
+; RV32IB-NEXT: ret
+;
+; RV32IBB-LABEL: zexth_i64:
+; RV32IBB: # %bb.0:
+; RV32IBB-NEXT: zext.h a0, a0
+; RV32IBB-NEXT: mv a1, zero
+; RV32IBB-NEXT: ret
+;
+; RV32IBP-LABEL: zexth_i64:
+; RV32IBP: # %bb.0:
+; RV32IBP-NEXT: pack a0, a0, zero
+; RV32IBP-NEXT: mv a1, zero
+; RV32IBP-NEXT: ret
+ %and = and i64 %a, 65535
+ ret i64 %and
+}
%or = or i64 %shl, %and
ret i64 %or
}
+
+define i64 @zextw_i64(i64 %a) nounwind {
+; RV64I-LABEL: zextw_i64:
+; RV64I: # %bb.0:
+; RV64I-NEXT: slli a0, a0, 32
+; RV64I-NEXT: srli a0, a0, 32
+; RV64I-NEXT: ret
+;
+; RV64IB-LABEL: zextw_i64:
+; RV64IB: # %bb.0:
+; RV64IB-NEXT: zext.w a0, a0
+; RV64IB-NEXT: ret
+;
+; RV64IBB-LABEL: zextw_i64:
+; RV64IBB: # %bb.0:
+; RV64IBB-NEXT: zext.w a0, a0
+; RV64IBB-NEXT: ret
+;
+; RV64IBP-LABEL: zextw_i64:
+; RV64IBP: # %bb.0:
+; RV64IBP-NEXT: pack a0, a0, zero
+; RV64IBP-NEXT: ret
+ %and = and i64 %a, 4294967295
+ ret i64 %and
+}