[RISCV] Move pack instructions to Zbp extension only.

Zext.h will need to come back to Zbb, but that only uses specific
encodings of pack.

Reviewed By: asb, frasercrmck

Differential Revision: https://reviews.llvm.org/D94742
This commit is contained in:
Craig Topper 2021-01-22 11:47:36 -08:00
parent 5ae92f1e11
commit 83c92fdeda
11 changed files with 438 additions and 471 deletions

View File

@ -356,19 +356,17 @@ def BDECOMPRESS : ALU_rr<0b0100100, 0b110, "bdecompress">, Sched<[]>;
def BCOMPRESS : ALU_rr<0b0000100, 0b110, "bcompress">, Sched<[]>;
} // Predicates = [HasStdExtZbe]
let Predicates = [HasStdExtZbbOrZbp] in {
let Predicates = [HasStdExtZbp] in {
def PACK : ALU_rr<0b0000100, 0b100, "pack">, Sched<[]>;
def PACKU : ALU_rr<0b0100100, 0b100, "packu">, Sched<[]>;
} // Predicates = [HasStdExtZbbOrZbp]
def PACKH : ALU_rr<0b0000100, 0b111, "packh">, Sched<[]>;
} // Predicates = [HasStdExtZbp]
let Predicates = [HasStdExtZbm, IsRV64] in {
def BMATOR : ALU_rr<0b0000100, 0b011, "bmator">, Sched<[]>;
def BMATXOR : ALU_rr<0b0100100, 0b011, "bmatxor">, Sched<[]>;
} // Predicates = [HasStdExtZbm, IsRV64]
let Predicates = [HasStdExtZbbOrZbp] in
def PACKH : ALU_rr<0b0000100, 0b111, "packh">, Sched<[]>;
let Predicates = [HasStdExtZbf] in
def BFP : ALU_rr<0b0100100, 0b111, "bfp">, Sched<[]>;
@ -459,10 +457,10 @@ def BDECOMPRESSW : ALUW_rr<0b0100100, 0b110, "bdecompressw">, Sched<[]>;
def BCOMPRESSW : ALUW_rr<0b0000100, 0b110, "bcompressw">, Sched<[]>;
} // Predicates = [HasStdExtZbe, IsRV64]
let Predicates = [HasStdExtZbbOrZbp, IsRV64] in {
let Predicates = [HasStdExtZbp, IsRV64] in {
def PACKW : ALUW_rr<0b0000100, 0b100, "packw">, Sched<[]>;
def PACKUW : ALUW_rr<0b0100100, 0b100, "packuw">, Sched<[]>;
} // Predicates = [HasStdExtZbbOrZbp, IsRV64]
} // Predicates = [HasStdExtZbp, IsRV64]
let Predicates = [HasStdExtZbf, IsRV64] in
def BFPW : ALUW_rr<0b0100100, 0b111, "bfpw">, Sched<[]>;
@ -502,11 +500,11 @@ def C_ZEXTW : RVBInstC<0b10, "c.zext.w">, Sched<[]>;
// Pseudo Instructions
//===----------------------------------------------------------------------===//
let Predicates = [HasStdExtZbb, IsRV32] in {
let Predicates = [HasStdExtZbp, IsRV32] in {
def : InstAlias<"zext.h $rd, $rs", (PACK GPR:$rd, GPR:$rs, X0)>;
} // Predicates = [HasStdExtZbb, IsRV32]
let Predicates = [HasStdExtZbb, IsRV64] in {
let Predicates = [HasStdExtZbp, IsRV64] in {
def : InstAlias<"zext.h $rd, $rs", (PACKW GPR:$rd, GPR:$rs, X0)>;
} // Predicates = [HasStdExtZbb, IsRV64]
@ -790,26 +788,26 @@ def : Pat<(umin GPR:$rs1, GPR:$rs2), (MINU GPR:$rs1, GPR:$rs2)>;
def : Pat<(umax GPR:$rs1, GPR:$rs2), (MAXU GPR:$rs1, GPR:$rs2)>;
} // Predicates = [HasStdExtZbb]
let Predicates = [HasStdExtZbbOrZbp, IsRV32] in
let Predicates = [HasStdExtZbp, IsRV32] in
def : Pat<(or (and GPR:$rs1, 0x0000FFFF), (shl GPR:$rs2, (i32 16))),
(PACK GPR:$rs1, GPR:$rs2)>;
let Predicates = [HasStdExtZbbOrZbp, IsRV64] in
let Predicates = [HasStdExtZbp, IsRV64] in
def : Pat<(or (and GPR:$rs1, 0x00000000FFFFFFFF), (shl GPR:$rs2, (i64 32))),
(PACK GPR:$rs1, GPR:$rs2)>;
let Predicates = [HasStdExtZbbOrZbp, IsRV32] in
let Predicates = [HasStdExtZbp, IsRV32] in
def : Pat<(or (and GPR:$rs2, 0xFFFF0000), (srl GPR:$rs1, (i32 16))),
(PACKU GPR:$rs1, GPR:$rs2)>;
let Predicates = [HasStdExtZbbOrZbp, IsRV64] in
let Predicates = [HasStdExtZbp, IsRV64] in
def : Pat<(or (and GPR:$rs2, 0xFFFFFFFF00000000), (srl GPR:$rs1, (i64 32))),
(PACKU GPR:$rs1, GPR:$rs2)>;
let Predicates = [HasStdExtZbbOrZbp] in
let Predicates = [HasStdExtZbp] in
def : Pat<(or (and (shl GPR:$rs2, (XLenVT 8)), 0xFF00),
(and GPR:$rs1, 0x00FF)),
(PACKH GPR:$rs1, GPR:$rs2)>;
let Predicates = [HasStdExtZbbOrZbp, IsRV32] in
let Predicates = [HasStdExtZbp, IsRV32] in
def : Pat<(and GPR:$rs, 0x0000FFFF), (PACK GPR:$rs, X0)>;
let Predicates = [HasStdExtZbbOrZbp, IsRV64] in {
let Predicates = [HasStdExtZbp, IsRV64] in {
def : Pat<(and GPR:$rs, 0x000000000000FFFF), (PACKW GPR:$rs, X0)>;
}
@ -949,7 +947,7 @@ def : Pat<(cttz (or GPR:$rs1, (i64 0x100000000))),
def : Pat<(ctpop (and GPR:$rs1, (i64 0xFFFFFFFF))), (CPOPW GPR:$rs1)>;
} // Predicates = [HasStdExtZbb, IsRV64]
let Predicates = [HasStdExtZbbOrZbp, IsRV64] in {
let Predicates = [HasStdExtZbp, IsRV64] in {
def : Pat<(sext_inreg (or (shl GPR:$rs2, (i64 16)),
(and GPR:$rs1, 0x000000000000FFFF)),
i32),
@ -958,4 +956,4 @@ def : Pat<(or (and (assertsexti32 GPR:$rs2), 0xFFFFFFFFFFFF0000),
(srl (and GPR:$rs1, 0x00000000FFFF0000),
(i64 16))),
(PACKUW GPR:$rs1, GPR:$rs2)>;
} // Predicates = [HasStdExtZbbOrZbp, IsRV64]
} // Predicates = [HasStdExtZbp, IsRV64]

View File

@ -744,252 +744,3 @@ define i64 @rori_i64_fshr(i64 %a) nounwind {
%1 = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 63)
ret i64 %1
}
define i32 @pack_i32(i32 %a, i32 %b) nounwind {
; RV32I-LABEL: pack_i32:
; RV32I: # %bb.0:
; RV32I-NEXT: lui a2, 16
; RV32I-NEXT: addi a2, a2, -1
; RV32I-NEXT: and a0, a0, a2
; RV32I-NEXT: slli a1, a1, 16
; RV32I-NEXT: or a0, a1, a0
; RV32I-NEXT: ret
;
; RV32IB-LABEL: pack_i32:
; RV32IB: # %bb.0:
; RV32IB-NEXT: pack a0, a0, a1
; RV32IB-NEXT: ret
;
; RV32IBB-LABEL: pack_i32:
; RV32IBB: # %bb.0:
; RV32IBB-NEXT: pack a0, a0, a1
; RV32IBB-NEXT: ret
;
; RV32IBP-LABEL: pack_i32:
; RV32IBP: # %bb.0:
; RV32IBP-NEXT: pack a0, a0, a1
; RV32IBP-NEXT: ret
%shl = and i32 %a, 65535
%shl1 = shl i32 %b, 16
%or = or i32 %shl1, %shl
ret i32 %or
}
; As we are not matching directly i64 code patterns on RV32 some i64 patterns
; don't have yet any matching bit manipulation instructions on RV32.
; This test is presented here in case future expansions of the experimental-b
; extension introduce instructions suitable for this pattern.
define i64 @pack_i64(i64 %a, i64 %b) nounwind {
; RV32I-LABEL: pack_i64:
; RV32I: # %bb.0:
; RV32I-NEXT: mv a1, a2
; RV32I-NEXT: ret
;
; RV32IB-LABEL: pack_i64:
; RV32IB: # %bb.0:
; RV32IB-NEXT: mv a1, a2
; RV32IB-NEXT: ret
;
; RV32IBB-LABEL: pack_i64:
; RV32IBB: # %bb.0:
; RV32IBB-NEXT: mv a1, a2
; RV32IBB-NEXT: ret
;
; RV32IBP-LABEL: pack_i64:
; RV32IBP: # %bb.0:
; RV32IBP-NEXT: mv a1, a2
; RV32IBP-NEXT: ret
%shl = and i64 %a, 4294967295
%shl1 = shl i64 %b, 32
%or = or i64 %shl1, %shl
ret i64 %or
}
define i32 @packu_i32(i32 %a, i32 %b) nounwind {
; RV32I-LABEL: packu_i32:
; RV32I: # %bb.0:
; RV32I-NEXT: srli a0, a0, 16
; RV32I-NEXT: lui a2, 1048560
; RV32I-NEXT: and a1, a1, a2
; RV32I-NEXT: or a0, a1, a0
; RV32I-NEXT: ret
;
; RV32IB-LABEL: packu_i32:
; RV32IB: # %bb.0:
; RV32IB-NEXT: packu a0, a0, a1
; RV32IB-NEXT: ret
;
; RV32IBB-LABEL: packu_i32:
; RV32IBB: # %bb.0:
; RV32IBB-NEXT: packu a0, a0, a1
; RV32IBB-NEXT: ret
;
; RV32IBP-LABEL: packu_i32:
; RV32IBP: # %bb.0:
; RV32IBP-NEXT: packu a0, a0, a1
; RV32IBP-NEXT: ret
%shr = lshr i32 %a, 16
%shr1 = and i32 %b, -65536
%or = or i32 %shr1, %shr
ret i32 %or
}
; As we are not matching directly i64 code patterns on RV32 some i64 patterns
; don't have yet any matching bit manipulation instructions on RV32.
; This test is presented here in case future expansions of the experimental-b
; extension introduce instructions suitable for this pattern.
define i64 @packu_i64(i64 %a, i64 %b) nounwind {
; RV32I-LABEL: packu_i64:
; RV32I: # %bb.0:
; RV32I-NEXT: mv a0, a1
; RV32I-NEXT: mv a1, a3
; RV32I-NEXT: ret
;
; RV32IB-LABEL: packu_i64:
; RV32IB: # %bb.0:
; RV32IB-NEXT: mv a0, a1
; RV32IB-NEXT: mv a1, a3
; RV32IB-NEXT: ret
;
; RV32IBB-LABEL: packu_i64:
; RV32IBB: # %bb.0:
; RV32IBB-NEXT: mv a0, a1
; RV32IBB-NEXT: mv a1, a3
; RV32IBB-NEXT: ret
;
; RV32IBP-LABEL: packu_i64:
; RV32IBP: # %bb.0:
; RV32IBP-NEXT: mv a0, a1
; RV32IBP-NEXT: mv a1, a3
; RV32IBP-NEXT: ret
%shr = lshr i64 %a, 32
%shr1 = and i64 %b, -4294967296
%or = or i64 %shr1, %shr
ret i64 %or
}
define i32 @packh_i32(i32 %a, i32 %b) nounwind {
; RV32I-LABEL: packh_i32:
; RV32I: # %bb.0:
; RV32I-NEXT: andi a0, a0, 255
; RV32I-NEXT: slli a1, a1, 8
; RV32I-NEXT: lui a2, 16
; RV32I-NEXT: addi a2, a2, -256
; RV32I-NEXT: and a1, a1, a2
; RV32I-NEXT: or a0, a1, a0
; RV32I-NEXT: ret
;
; RV32IB-LABEL: packh_i32:
; RV32IB: # %bb.0:
; RV32IB-NEXT: packh a0, a0, a1
; RV32IB-NEXT: ret
;
; RV32IBB-LABEL: packh_i32:
; RV32IBB: # %bb.0:
; RV32IBB-NEXT: packh a0, a0, a1
; RV32IBB-NEXT: ret
;
; RV32IBP-LABEL: packh_i32:
; RV32IBP: # %bb.0:
; RV32IBP-NEXT: packh a0, a0, a1
; RV32IBP-NEXT: ret
%and = and i32 %a, 255
%and1 = shl i32 %b, 8
%shl = and i32 %and1, 65280
%or = or i32 %shl, %and
ret i32 %or
}
define i64 @packh_i64(i64 %a, i64 %b) nounwind {
; RV32I-LABEL: packh_i64:
; RV32I: # %bb.0:
; RV32I-NEXT: andi a0, a0, 255
; RV32I-NEXT: slli a1, a2, 8
; RV32I-NEXT: lui a2, 16
; RV32I-NEXT: addi a2, a2, -256
; RV32I-NEXT: and a1, a1, a2
; RV32I-NEXT: or a0, a1, a0
; RV32I-NEXT: mv a1, zero
; RV32I-NEXT: ret
;
; RV32IB-LABEL: packh_i64:
; RV32IB: # %bb.0:
; RV32IB-NEXT: packh a0, a0, a2
; RV32IB-NEXT: mv a1, zero
; RV32IB-NEXT: ret
;
; RV32IBB-LABEL: packh_i64:
; RV32IBB: # %bb.0:
; RV32IBB-NEXT: packh a0, a0, a2
; RV32IBB-NEXT: mv a1, zero
; RV32IBB-NEXT: ret
;
; RV32IBP-LABEL: packh_i64:
; RV32IBP: # %bb.0:
; RV32IBP-NEXT: packh a0, a0, a2
; RV32IBP-NEXT: mv a1, zero
; RV32IBP-NEXT: ret
%and = and i64 %a, 255
%and1 = shl i64 %b, 8
%shl = and i64 %and1, 65280
%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
}

View File

@ -3431,3 +3431,209 @@ define i64 @shfl8_i64(i64 %a, i64 %b) nounwind {
%or3 = or i64 %or, %and2
ret i64 %or3
}
define i32 @pack_i32(i32 %a, i32 %b) nounwind {
; RV32I-LABEL: pack_i32:
; RV32I: # %bb.0:
; RV32I-NEXT: lui a2, 16
; RV32I-NEXT: addi a2, a2, -1
; RV32I-NEXT: and a0, a0, a2
; RV32I-NEXT: slli a1, a1, 16
; RV32I-NEXT: or a0, a1, a0
; RV32I-NEXT: ret
;
; RV32IB-LABEL: pack_i32:
; RV32IB: # %bb.0:
; RV32IB-NEXT: pack a0, a0, a1
; RV32IB-NEXT: ret
;
; RV32IBP-LABEL: pack_i32:
; RV32IBP: # %bb.0:
; RV32IBP-NEXT: pack a0, a0, a1
; RV32IBP-NEXT: ret
%shl = and i32 %a, 65535
%shl1 = shl i32 %b, 16
%or = or i32 %shl1, %shl
ret i32 %or
}
; As we are not matching directly i64 code patterns on RV32 some i64 patterns
; don't have yet any matching bit manipulation instructions on RV32.
; This test is presented here in case future expansions of the experimental-b
; extension introduce instructions suitable for this pattern.
define i64 @pack_i64(i64 %a, i64 %b) nounwind {
; RV32I-LABEL: pack_i64:
; RV32I: # %bb.0:
; RV32I-NEXT: mv a1, a2
; RV32I-NEXT: ret
;
; RV32IB-LABEL: pack_i64:
; RV32IB: # %bb.0:
; RV32IB-NEXT: mv a1, a2
; RV32IB-NEXT: ret
;
; RV32IBP-LABEL: pack_i64:
; RV32IBP: # %bb.0:
; RV32IBP-NEXT: mv a1, a2
; RV32IBP-NEXT: ret
%shl = and i64 %a, 4294967295
%shl1 = shl i64 %b, 32
%or = or i64 %shl1, %shl
ret i64 %or
}
define i32 @packu_i32(i32 %a, i32 %b) nounwind {
; RV32I-LABEL: packu_i32:
; RV32I: # %bb.0:
; RV32I-NEXT: srli a0, a0, 16
; RV32I-NEXT: lui a2, 1048560
; RV32I-NEXT: and a1, a1, a2
; RV32I-NEXT: or a0, a1, a0
; RV32I-NEXT: ret
;
; RV32IB-LABEL: packu_i32:
; RV32IB: # %bb.0:
; RV32IB-NEXT: packu a0, a0, a1
; RV32IB-NEXT: ret
;
; RV32IBP-LABEL: packu_i32:
; RV32IBP: # %bb.0:
; RV32IBP-NEXT: packu a0, a0, a1
; RV32IBP-NEXT: ret
%shr = lshr i32 %a, 16
%shr1 = and i32 %b, -65536
%or = or i32 %shr1, %shr
ret i32 %or
}
; As we are not matching directly i64 code patterns on RV32 some i64 patterns
; don't have yet any matching bit manipulation instructions on RV32.
; This test is presented here in case future expansions of the experimental-b
; extension introduce instructions suitable for this pattern.
define i64 @packu_i64(i64 %a, i64 %b) nounwind {
; RV32I-LABEL: packu_i64:
; RV32I: # %bb.0:
; RV32I-NEXT: mv a0, a1
; RV32I-NEXT: mv a1, a3
; RV32I-NEXT: ret
;
; RV32IB-LABEL: packu_i64:
; RV32IB: # %bb.0:
; RV32IB-NEXT: mv a0, a1
; RV32IB-NEXT: mv a1, a3
; RV32IB-NEXT: ret
;
; RV32IBP-LABEL: packu_i64:
; RV32IBP: # %bb.0:
; RV32IBP-NEXT: mv a0, a1
; RV32IBP-NEXT: mv a1, a3
; RV32IBP-NEXT: ret
%shr = lshr i64 %a, 32
%shr1 = and i64 %b, -4294967296
%or = or i64 %shr1, %shr
ret i64 %or
}
define i32 @packh_i32(i32 %a, i32 %b) nounwind {
; RV32I-LABEL: packh_i32:
; RV32I: # %bb.0:
; RV32I-NEXT: andi a0, a0, 255
; RV32I-NEXT: slli a1, a1, 8
; RV32I-NEXT: lui a2, 16
; RV32I-NEXT: addi a2, a2, -256
; RV32I-NEXT: and a1, a1, a2
; RV32I-NEXT: or a0, a1, a0
; RV32I-NEXT: ret
;
; RV32IB-LABEL: packh_i32:
; RV32IB: # %bb.0:
; RV32IB-NEXT: packh a0, a0, a1
; RV32IB-NEXT: ret
;
; RV32IBP-LABEL: packh_i32:
; RV32IBP: # %bb.0:
; RV32IBP-NEXT: packh a0, a0, a1
; RV32IBP-NEXT: ret
%and = and i32 %a, 255
%and1 = shl i32 %b, 8
%shl = and i32 %and1, 65280
%or = or i32 %shl, %and
ret i32 %or
}
define i64 @packh_i64(i64 %a, i64 %b) nounwind {
; RV32I-LABEL: packh_i64:
; RV32I: # %bb.0:
; RV32I-NEXT: andi a0, a0, 255
; RV32I-NEXT: slli a1, a2, 8
; RV32I-NEXT: lui a2, 16
; RV32I-NEXT: addi a2, a2, -256
; RV32I-NEXT: and a1, a1, a2
; RV32I-NEXT: or a0, a1, a0
; RV32I-NEXT: mv a1, zero
; RV32I-NEXT: ret
;
; RV32IB-LABEL: packh_i64:
; RV32IB: # %bb.0:
; RV32IB-NEXT: packh a0, a0, a2
; RV32IB-NEXT: mv a1, zero
; RV32IB-NEXT: ret
;
; RV32IBP-LABEL: packh_i64:
; RV32IBP: # %bb.0:
; RV32IBP-NEXT: packh a0, a0, a2
; RV32IBP-NEXT: mv a1, zero
; RV32IBP-NEXT: ret
%and = and i64 %a, 255
%and1 = shl i64 %b, 8
%shl = and i64 %and1, 65280
%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
;
; RV32IBP-LABEL: zexth_i32:
; RV32IBP: # %bb.0:
; RV32IBP-NEXT: zext.h a0, a0
; 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
;
; RV32IBP-LABEL: zexth_i64:
; RV32IBP: # %bb.0:
; RV32IBP-NEXT: zext.h a0, a0
; RV32IBP-NEXT: mv a1, zero
; RV32IBP-NEXT: ret
%and = and i64 %a, 65535
ret i64 %and
}

View File

@ -609,186 +609,3 @@ define i64 @rori_i64_fshr(i64 %a) nounwind {
%1 = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 63)
ret i64 %1
}
define signext i32 @pack_i32(i32 signext %a, i32 signext %b) nounwind {
; RV64I-LABEL: pack_i32:
; RV64I: # %bb.0:
; RV64I-NEXT: lui a2, 16
; RV64I-NEXT: addiw a2, a2, -1
; RV64I-NEXT: and a0, a0, a2
; RV64I-NEXT: slli a1, a1, 16
; RV64I-NEXT: or a0, a1, a0
; RV64I-NEXT: sext.w a0, a0
; RV64I-NEXT: ret
;
; RV64IB-LABEL: pack_i32:
; RV64IB: # %bb.0:
; RV64IB-NEXT: packw a0, a0, a1
; RV64IB-NEXT: ret
;
; RV64IBB-LABEL: pack_i32:
; RV64IBB: # %bb.0:
; RV64IBB-NEXT: packw a0, a0, a1
; RV64IBB-NEXT: ret
;
; RV64IBP-LABEL: pack_i32:
; RV64IBP: # %bb.0:
; RV64IBP-NEXT: packw a0, a0, a1
; RV64IBP-NEXT: ret
%shl = and i32 %a, 65535
%shl1 = shl i32 %b, 16
%or = or i32 %shl1, %shl
ret i32 %or
}
define i64 @pack_i64(i64 %a, i64 %b) nounwind {
; RV64I-LABEL: pack_i64:
; RV64I: # %bb.0:
; RV64I-NEXT: slli a0, a0, 32
; RV64I-NEXT: srli a0, a0, 32
; RV64I-NEXT: slli a1, a1, 32
; RV64I-NEXT: or a0, a1, a0
; RV64I-NEXT: ret
;
; RV64IB-LABEL: pack_i64:
; RV64IB: # %bb.0:
; RV64IB-NEXT: pack a0, a0, a1
; RV64IB-NEXT: ret
;
; RV64IBB-LABEL: pack_i64:
; RV64IBB: # %bb.0:
; RV64IBB-NEXT: pack a0, a0, a1
; RV64IBB-NEXT: ret
;
; RV64IBP-LABEL: pack_i64:
; RV64IBP: # %bb.0:
; RV64IBP-NEXT: pack a0, a0, a1
; RV64IBP-NEXT: ret
%shl = and i64 %a, 4294967295
%shl1 = shl i64 %b, 32
%or = or i64 %shl1, %shl
ret i64 %or
}
define signext i32 @packu_i32(i32 signext %a, i32 signext %b) nounwind {
; RV64I-LABEL: packu_i32:
; RV64I: # %bb.0:
; RV64I-NEXT: srliw a0, a0, 16
; RV64I-NEXT: lui a2, 1048560
; RV64I-NEXT: and a1, a1, a2
; RV64I-NEXT: or a0, a1, a0
; RV64I-NEXT: ret
;
; RV64IB-LABEL: packu_i32:
; RV64IB: # %bb.0:
; RV64IB-NEXT: packuw a0, a0, a1
; RV64IB-NEXT: ret
;
; RV64IBB-LABEL: packu_i32:
; RV64IBB: # %bb.0:
; RV64IBB-NEXT: packuw a0, a0, a1
; RV64IBB-NEXT: ret
;
; RV64IBP-LABEL: packu_i32:
; RV64IBP: # %bb.0:
; RV64IBP-NEXT: packuw a0, a0, a1
; RV64IBP-NEXT: ret
%shr = lshr i32 %a, 16
%shr1 = and i32 %b, -65536
%or = or i32 %shr1, %shr
ret i32 %or
}
define i64 @packu_i64(i64 %a, i64 %b) nounwind {
; RV64I-LABEL: packu_i64:
; RV64I: # %bb.0:
; RV64I-NEXT: srli a0, a0, 32
; RV64I-NEXT: addi a2, zero, -1
; RV64I-NEXT: slli a2, a2, 32
; RV64I-NEXT: and a1, a1, a2
; RV64I-NEXT: or a0, a1, a0
; RV64I-NEXT: ret
;
; RV64IB-LABEL: packu_i64:
; RV64IB: # %bb.0:
; RV64IB-NEXT: packu a0, a0, a1
; RV64IB-NEXT: ret
;
; RV64IBB-LABEL: packu_i64:
; RV64IBB: # %bb.0:
; RV64IBB-NEXT: packu a0, a0, a1
; RV64IBB-NEXT: ret
;
; RV64IBP-LABEL: packu_i64:
; RV64IBP: # %bb.0:
; RV64IBP-NEXT: packu a0, a0, a1
; RV64IBP-NEXT: ret
%shr = lshr i64 %a, 32
%shr1 = and i64 %b, -4294967296
%or = or i64 %shr1, %shr
ret i64 %or
}
define signext i32 @packh_i32(i32 signext %a, i32 signext %b) nounwind {
; RV64I-LABEL: packh_i32:
; RV64I: # %bb.0:
; RV64I-NEXT: andi a0, a0, 255
; RV64I-NEXT: slli a1, a1, 8
; RV64I-NEXT: lui a2, 16
; RV64I-NEXT: addiw a2, a2, -256
; RV64I-NEXT: and a1, a1, a2
; RV64I-NEXT: or a0, a1, a0
; RV64I-NEXT: ret
;
; RV64IB-LABEL: packh_i32:
; RV64IB: # %bb.0:
; RV64IB-NEXT: packh a0, a0, a1
; RV64IB-NEXT: ret
;
; RV64IBB-LABEL: packh_i32:
; RV64IBB: # %bb.0:
; RV64IBB-NEXT: packh a0, a0, a1
; RV64IBB-NEXT: ret
;
; RV64IBP-LABEL: packh_i32:
; RV64IBP: # %bb.0:
; RV64IBP-NEXT: packh a0, a0, a1
; RV64IBP-NEXT: ret
%and = and i32 %a, 255
%and1 = shl i32 %b, 8
%shl = and i32 %and1, 65280
%or = or i32 %shl, %and
ret i32 %or
}
define i64 @packh_i64(i64 %a, i64 %b) nounwind {
; RV64I-LABEL: packh_i64:
; RV64I: # %bb.0:
; RV64I-NEXT: andi a0, a0, 255
; RV64I-NEXT: slli a1, a1, 8
; RV64I-NEXT: lui a2, 16
; RV64I-NEXT: addiw a2, a2, -256
; RV64I-NEXT: and a1, a1, a2
; RV64I-NEXT: or a0, a1, a0
; RV64I-NEXT: ret
;
; RV64IB-LABEL: packh_i64:
; RV64IB: # %bb.0:
; RV64IB-NEXT: packh a0, a0, a1
; RV64IB-NEXT: ret
;
; RV64IBB-LABEL: packh_i64:
; RV64IBB: # %bb.0:
; RV64IBB-NEXT: packh a0, a0, a1
; RV64IBB-NEXT: ret
;
; RV64IBP-LABEL: packh_i64:
; RV64IBP: # %bb.0:
; RV64IBP-NEXT: packh a0, a0, a1
; RV64IBP-NEXT: ret
%and = and i64 %a, 255
%and1 = shl i64 %b, 8
%shl = and i64 %and1, 65280
%or = or i64 %shl, %and
ret i64 %or
}

View File

@ -3921,3 +3921,198 @@ define i64 @shfl16(i64 %a, i64 %b) nounwind {
%or3 = or i64 %or, %and2
ret i64 %or3
}
define signext i32 @pack_i32(i32 signext %a, i32 signext %b) nounwind {
; RV64I-LABEL: pack_i32:
; RV64I: # %bb.0:
; RV64I-NEXT: lui a2, 16
; RV64I-NEXT: addiw a2, a2, -1
; RV64I-NEXT: and a0, a0, a2
; RV64I-NEXT: slli a1, a1, 16
; RV64I-NEXT: or a0, a1, a0
; RV64I-NEXT: sext.w a0, a0
; RV64I-NEXT: ret
;
; RV64IB-LABEL: pack_i32:
; RV64IB: # %bb.0:
; RV64IB-NEXT: packw a0, a0, a1
; RV64IB-NEXT: ret
;
; RV64IBP-LABEL: pack_i32:
; RV64IBP: # %bb.0:
; RV64IBP-NEXT: packw a0, a0, a1
; RV64IBP-NEXT: ret
%shl = and i32 %a, 65535
%shl1 = shl i32 %b, 16
%or = or i32 %shl1, %shl
ret i32 %or
}
define i64 @pack_i64(i64 %a, i64 %b) nounwind {
; RV64I-LABEL: pack_i64:
; RV64I: # %bb.0:
; RV64I-NEXT: slli a0, a0, 32
; RV64I-NEXT: srli a0, a0, 32
; RV64I-NEXT: slli a1, a1, 32
; RV64I-NEXT: or a0, a1, a0
; RV64I-NEXT: ret
;
; RV64IB-LABEL: pack_i64:
; RV64IB: # %bb.0:
; RV64IB-NEXT: pack a0, a0, a1
; RV64IB-NEXT: ret
;
; RV64IBP-LABEL: pack_i64:
; RV64IBP: # %bb.0:
; RV64IBP-NEXT: pack a0, a0, a1
; RV64IBP-NEXT: ret
%shl = and i64 %a, 4294967295
%shl1 = shl i64 %b, 32
%or = or i64 %shl1, %shl
ret i64 %or
}
define signext i32 @packu_i32(i32 signext %a, i32 signext %b) nounwind {
; RV64I-LABEL: packu_i32:
; RV64I: # %bb.0:
; RV64I-NEXT: srliw a0, a0, 16
; RV64I-NEXT: lui a2, 1048560
; RV64I-NEXT: and a1, a1, a2
; RV64I-NEXT: or a0, a1, a0
; RV64I-NEXT: ret
;
; RV64IB-LABEL: packu_i32:
; RV64IB: # %bb.0:
; RV64IB-NEXT: packuw a0, a0, a1
; RV64IB-NEXT: ret
;
; RV64IBP-LABEL: packu_i32:
; RV64IBP: # %bb.0:
; RV64IBP-NEXT: packuw a0, a0, a1
; RV64IBP-NEXT: ret
%shr = lshr i32 %a, 16
%shr1 = and i32 %b, -65536
%or = or i32 %shr1, %shr
ret i32 %or
}
define i64 @packu_i64(i64 %a, i64 %b) nounwind {
; RV64I-LABEL: packu_i64:
; RV64I: # %bb.0:
; RV64I-NEXT: srli a0, a0, 32
; RV64I-NEXT: addi a2, zero, -1
; RV64I-NEXT: slli a2, a2, 32
; RV64I-NEXT: and a1, a1, a2
; RV64I-NEXT: or a0, a1, a0
; RV64I-NEXT: ret
;
; RV64IB-LABEL: packu_i64:
; RV64IB: # %bb.0:
; RV64IB-NEXT: packu a0, a0, a1
; RV64IB-NEXT: ret
;
; RV64IBP-LABEL: packu_i64:
; RV64IBP: # %bb.0:
; RV64IBP-NEXT: packu a0, a0, a1
; RV64IBP-NEXT: ret
%shr = lshr i64 %a, 32
%shr1 = and i64 %b, -4294967296
%or = or i64 %shr1, %shr
ret i64 %or
}
define signext i32 @packh_i32(i32 signext %a, i32 signext %b) nounwind {
; RV64I-LABEL: packh_i32:
; RV64I: # %bb.0:
; RV64I-NEXT: andi a0, a0, 255
; RV64I-NEXT: slli a1, a1, 8
; RV64I-NEXT: lui a2, 16
; RV64I-NEXT: addiw a2, a2, -256
; RV64I-NEXT: and a1, a1, a2
; RV64I-NEXT: or a0, a1, a0
; RV64I-NEXT: ret
;
; RV64IB-LABEL: packh_i32:
; RV64IB: # %bb.0:
; RV64IB-NEXT: packh a0, a0, a1
; RV64IB-NEXT: ret
;
; RV64IBP-LABEL: packh_i32:
; RV64IBP: # %bb.0:
; RV64IBP-NEXT: packh a0, a0, a1
; RV64IBP-NEXT: ret
%and = and i32 %a, 255
%and1 = shl i32 %b, 8
%shl = and i32 %and1, 65280
%or = or i32 %shl, %and
ret i32 %or
}
define i64 @packh_i64(i64 %a, i64 %b) nounwind {
; RV64I-LABEL: packh_i64:
; RV64I: # %bb.0:
; RV64I-NEXT: andi a0, a0, 255
; RV64I-NEXT: slli a1, a1, 8
; RV64I-NEXT: lui a2, 16
; RV64I-NEXT: addiw a2, a2, -256
; RV64I-NEXT: and a1, a1, a2
; RV64I-NEXT: or a0, a1, a0
; RV64I-NEXT: ret
;
; RV64IB-LABEL: packh_i64:
; RV64IB: # %bb.0:
; RV64IB-NEXT: packh a0, a0, a1
; RV64IB-NEXT: ret
;
; RV64IBP-LABEL: packh_i64:
; RV64IBP: # %bb.0:
; RV64IBP-NEXT: packh a0, a0, a1
; RV64IBP-NEXT: ret
%and = and i64 %a, 255
%and1 = shl i64 %b, 8
%shl = and i64 %and1, 65280
%or = or i64 %shl, %and
ret i64 %or
}
define i32 @zexth_i32(i32 %a) nounwind {
; RV64I-LABEL: zexth_i32:
; RV64I: # %bb.0:
; RV64I-NEXT: lui a1, 16
; RV64I-NEXT: addiw a1, a1, -1
; RV64I-NEXT: and a0, a0, a1
; RV64I-NEXT: ret
;
; RV64IB-LABEL: zexth_i32:
; RV64IB: # %bb.0:
; RV64IB-NEXT: zext.h a0, a0
; RV64IB-NEXT: ret
;
; RV64IBP-LABEL: zexth_i32:
; RV64IBP: # %bb.0:
; RV64IBP-NEXT: zext.h a0, a0
; RV64IBP-NEXT: ret
%and = and i32 %a, 65535
ret i32 %and
}
define i64 @zexth_i64(i64 %a) nounwind {
; RV64I-LABEL: zexth_i64:
; RV64I: # %bb.0:
; RV64I-NEXT: lui a1, 16
; RV64I-NEXT: addiw a1, a1, -1
; RV64I-NEXT: and a0, a0, a1
; RV64I-NEXT: ret
;
; RV64IB-LABEL: zexth_i64:
; RV64IB: # %bb.0:
; RV64IB-NEXT: zext.h a0, a0
; RV64IB-NEXT: ret
;
; RV64IBP-LABEL: zexth_i64:
; RV64IBP: # %bb.0:
; RV64IBP-NEXT: zext.h a0, a0
; RV64IBP-NEXT: ret
%and = and i64 %a, 65535
ret i64 %and
}

View File

@ -15,9 +15,3 @@ rori t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
# Immediate operand out of range
rori t0, t1, 32 # CHECK: :[[@LINE]]:14: error: immediate must be an integer in the range [0, 31]
rori t0, t1, -1 # CHECK: :[[@LINE]]:14: error: immediate must be an integer in the range [0, 31]
# Too few operands
pack t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
# Too few operands
packu t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
# Too few operands
packh t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction

View File

@ -40,12 +40,3 @@ rori t0, t1, 31
# CHECK-ASM-AND-OBJ: rori t0, t1, 0
# CHECK-ASM: encoding: [0x93,0x52,0x03,0x60]
rori t0, t1, 0
# CHECK-ASM-AND-OBJ: pack t0, t1, t2
# CHECK-ASM: encoding: [0xb3,0x42,0x73,0x08]
pack t0, t1, t2
# CHECK-ASM-AND-OBJ: packu t0, t1, t2
# CHECK-ASM: encoding: [0xb3,0x42,0x73,0x48]
packu t0, t1, t2
# CHECK-ASM-AND-OBJ: packh t0, t1, t2
# CHECK-ASM: encoding: [0xb3,0x72,0x73,0x08]
packh t0, t1, t2

View File

@ -42,3 +42,9 @@ unshfli t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
# Immediate operand out of range
unshfli t0, t1, 16 # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 15]
unshfli t0, t1, -1 # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 15]
# Too few operands
pack t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
# Too few operands
packu t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
# Too few operands
packh t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction

View File

@ -48,3 +48,12 @@ shfli t0, t1, 0
# CHECK-ASM-AND-OBJ: unshfli t0, t1, 0
# CHECK-ASM: encoding: [0x93,0x52,0x03,0x08]
unshfli t0, t1, 0
# CHECK-ASM-AND-OBJ: pack t0, t1, t2
# CHECK-ASM: encoding: [0xb3,0x42,0x73,0x08]
pack t0, t1, t2
# CHECK-ASM-AND-OBJ: packu t0, t1, t2
# CHECK-ASM: encoding: [0xb3,0x42,0x73,0x48]
packu t0, t1, t2
# CHECK-ASM-AND-OBJ: packh t0, t1, t2
# CHECK-ASM: encoding: [0xb3,0x72,0x73,0x08]
packh t0, t1, t2

View File

@ -31,9 +31,3 @@ roriw t0, t1, 31
# CHECK-ASM-AND-OBJ: roriw t0, t1, 0
# CHECK-ASM: encoding: [0x9b,0x52,0x03,0x60]
roriw t0, t1, 0
# CHECK-ASM-AND-OBJ: packw t0, t1, t2
# CHECK-ASM: encoding: [0xbb,0x42,0x73,0x08]
packw t0, t1, t2
# CHECK-ASM-AND-OBJ: packuw t0, t1, t2
# CHECK-ASM: encoding: [0xbb,0x42,0x73,0x48]
packuw t0, t1, t2

View File

@ -42,3 +42,9 @@ shflw t0, t1, t2
# CHECK-ASM-AND-OBJ: unshflw t0, t1, t2
# CHECK-ASM: encoding: [0xbb,0x52,0x73,0x08]
unshflw t0, t1, t2
# CHECK-ASM-AND-OBJ: packw t0, t1, t2
# CHECK-ASM: encoding: [0xbb,0x42,0x73,0x08]
packw t0, t1, t2
# CHECK-ASM-AND-OBJ: packuw t0, t1, t2
# CHECK-ASM: encoding: [0xbb,0x42,0x73,0x48]
packuw t0, t1, t2