mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 12:09:14 +00:00
8355699: RISC-V: support SUADD/SADD/SUSUB/SSUB
Reviewed-by: fyang, luhenry
This commit is contained in:
parent
da004cb657
commit
1a4bbb0027
@ -1904,8 +1904,14 @@ enum VectorMask {
|
||||
INSN(vand_vv, 0b1010111, 0b000, 0b001001);
|
||||
|
||||
// Vector Single-Width Integer Add and Subtract
|
||||
INSN(vsub_vv, 0b1010111, 0b000, 0b000010);
|
||||
INSN(vadd_vv, 0b1010111, 0b000, 0b000000);
|
||||
INSN(vsub_vv, 0b1010111, 0b000, 0b000010);
|
||||
|
||||
// Vector Saturating Integer Add and Subtract
|
||||
INSN(vsadd_vv, 0b1010111, 0b000, 0b100001);
|
||||
INSN(vsaddu_vv, 0b1010111, 0b000, 0b100000);
|
||||
INSN(vssub_vv, 0b1010111, 0b000, 0b100011);
|
||||
INSN(vssubu_vv, 0b1010111, 0b000, 0b100010);
|
||||
|
||||
// Vector Register Gather Instructions
|
||||
INSN(vrgather_vv, 0b1010111, 0b000, 0b001100);
|
||||
|
||||
@ -650,6 +650,144 @@ instruct vsubL_vx_masked(vReg dst_src, iRegL src2, vRegMask_V0 v0) %{
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
// -------- vector saturating integer operations
|
||||
|
||||
// vector saturating signed integer addition
|
||||
|
||||
instruct vsadd(vReg dst, vReg src1, vReg src2) %{
|
||||
predicate(n->is_SaturatingVector() && !n->as_SaturatingVector()->is_unsigned());
|
||||
match(Set dst (SaturatingAddV src1 src2));
|
||||
ins_cost(VEC_COST);
|
||||
format %{ "vsadd $dst, $src1, $src2" %}
|
||||
ins_encode %{
|
||||
BasicType bt = Matcher::vector_element_basic_type(this);
|
||||
assert(is_integral_type(bt), "unsupported type");
|
||||
__ vsetvli_helper(bt, Matcher::vector_length(this));
|
||||
__ vsadd_vv(as_VectorRegister($dst$$reg),
|
||||
as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
// vector saturating unsigned integer addition
|
||||
|
||||
instruct vsaddu(vReg dst, vReg src1, vReg src2) %{
|
||||
predicate(n->is_SaturatingVector() && n->as_SaturatingVector()->is_unsigned());
|
||||
match(Set dst (SaturatingAddV src1 src2));
|
||||
ins_cost(VEC_COST);
|
||||
format %{ "vsaddu $dst, $src1, $src2" %}
|
||||
ins_encode %{
|
||||
BasicType bt = Matcher::vector_element_basic_type(this);
|
||||
assert(is_integral_type(bt), "unsupported type");
|
||||
__ vsetvli_helper(bt, Matcher::vector_length(this));
|
||||
__ vsaddu_vv(as_VectorRegister($dst$$reg),
|
||||
as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
// vector saturating signed integer addition (predicated)
|
||||
|
||||
instruct vsadd_masked(vReg dst_src, vReg src1, vRegMask_V0 v0) %{
|
||||
predicate(n->is_SaturatingVector() && !n->as_SaturatingVector()->is_unsigned());
|
||||
match(Set dst_src (SaturatingAddV (Binary dst_src src1) v0));
|
||||
ins_cost(VEC_COST);
|
||||
format %{ "vsadd_masked $dst_src, $dst_src, $src1, $v0" %}
|
||||
ins_encode %{
|
||||
BasicType bt = Matcher::vector_element_basic_type(this);
|
||||
assert(is_integral_type(bt), "unsupported type");
|
||||
__ vsetvli_helper(bt, Matcher::vector_length(this));
|
||||
__ vsadd_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg),
|
||||
as_VectorRegister($src1$$reg), Assembler::v0_t);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
// vector saturating unsigned integer addition (predicated)
|
||||
|
||||
instruct vsaddu_masked(vReg dst_src, vReg src1, vRegMask_V0 v0) %{
|
||||
predicate(n->is_SaturatingVector() && n->as_SaturatingVector()->is_unsigned());
|
||||
match(Set dst_src (SaturatingAddV (Binary dst_src src1) v0));
|
||||
ins_cost(VEC_COST);
|
||||
format %{ "vsaddu_masked $dst_src, $dst_src, $src1, $v0" %}
|
||||
ins_encode %{
|
||||
BasicType bt = Matcher::vector_element_basic_type(this);
|
||||
assert(is_integral_type(bt), "unsupported type");
|
||||
__ vsetvli_helper(bt, Matcher::vector_length(this));
|
||||
__ vsaddu_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg),
|
||||
as_VectorRegister($src1$$reg), Assembler::v0_t);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
// vector saturating signed integer subtraction
|
||||
|
||||
instruct vssub(vReg dst, vReg src1, vReg src2) %{
|
||||
predicate(n->is_SaturatingVector() && !n->as_SaturatingVector()->is_unsigned());
|
||||
match(Set dst (SaturatingSubV src1 src2));
|
||||
ins_cost(VEC_COST);
|
||||
format %{ "vssub $dst, $src1, $src2" %}
|
||||
ins_encode %{
|
||||
BasicType bt = Matcher::vector_element_basic_type(this);
|
||||
assert(is_integral_type(bt), "unsupported type");
|
||||
__ vsetvli_helper(bt, Matcher::vector_length(this));
|
||||
__ vssub_vv(as_VectorRegister($dst$$reg),
|
||||
as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
// vector saturating unsigned integer subtraction
|
||||
|
||||
instruct vssubu(vReg dst, vReg src1, vReg src2) %{
|
||||
predicate(n->is_SaturatingVector() && n->as_SaturatingVector()->is_unsigned());
|
||||
match(Set dst (SaturatingSubV src1 src2));
|
||||
ins_cost(VEC_COST);
|
||||
format %{ "vssubu $dst, $src1, $src2" %}
|
||||
ins_encode %{
|
||||
BasicType bt = Matcher::vector_element_basic_type(this);
|
||||
assert(is_integral_type(bt), "unsupported type");
|
||||
__ vsetvli_helper(bt, Matcher::vector_length(this));
|
||||
__ vssubu_vv(as_VectorRegister($dst$$reg),
|
||||
as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
// vector saturating signed integer subtraction (predicated)
|
||||
|
||||
instruct vssub_masked(vReg dst_src, vReg src1, vRegMask_V0 v0) %{
|
||||
predicate(n->is_SaturatingVector() && !n->as_SaturatingVector()->is_unsigned());
|
||||
match(Set dst_src (SaturatingSubV (Binary dst_src src1) v0));
|
||||
ins_cost(VEC_COST);
|
||||
format %{ "vssub_masked $dst_src, $dst_src, $src1, $v0" %}
|
||||
ins_encode %{
|
||||
BasicType bt = Matcher::vector_element_basic_type(this);
|
||||
assert(is_integral_type(bt), "unsupported type");
|
||||
__ vsetvli_helper(bt, Matcher::vector_length(this));
|
||||
__ vssub_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg),
|
||||
as_VectorRegister($src1$$reg), Assembler::v0_t);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
// vector saturating unsigned integer subtraction (predicated)
|
||||
|
||||
instruct vssubu_masked(vReg dst_src, vReg src1, vRegMask_V0 v0) %{
|
||||
predicate(n->is_SaturatingVector() && n->as_SaturatingVector()->is_unsigned());
|
||||
match(Set dst_src (SaturatingSubV (Binary dst_src src1) v0));
|
||||
ins_cost(VEC_COST);
|
||||
format %{ "vssubu_masked $dst_src, $dst_src, $src1, $v0" %}
|
||||
ins_encode %{
|
||||
BasicType bt = Matcher::vector_element_basic_type(this);
|
||||
assert(is_integral_type(bt), "unsupported type");
|
||||
__ vsetvli_helper(bt, Matcher::vector_length(this));
|
||||
__ vssubu_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg),
|
||||
as_VectorRegister($src1$$reg), Assembler::v0_t);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
// vector and
|
||||
|
||||
instruct vand(vReg dst, vReg src1, vReg src2) %{
|
||||
|
||||
@ -147,7 +147,8 @@ public class VectorCommutativeOperSharingTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.SATURATING_ADD_VI, IRNode.VECTOR_SIZE_ANY, " 2 "}, applyIfCPUFeature = {"avx2", "true"})
|
||||
@IR(counts = {IRNode.SATURATING_ADD_VI, IRNode.VECTOR_SIZE_ANY, " 2 "},
|
||||
applyIfCPUFeatureOr = {"avx2", "true", "rvv", "true"})
|
||||
public void testVectorIRSharing3(int index) {
|
||||
IntVector vec1 = IntVector.fromArray(I_SPECIES, ia, index);
|
||||
IntVector vec2 = IntVector.fromArray(I_SPECIES, ib, index);
|
||||
|
||||
@ -166,7 +166,7 @@ public class VectorSaturatedOperationsTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.SATURATING_ADD_VB, " >0 "}, applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
|
||||
@IR(counts = {IRNode.SATURATING_ADD_VB, " >0 "}, applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"})
|
||||
@Warmup(value = 10000)
|
||||
public void sadd_byte() {
|
||||
for (int i = 0; i < COUNT; i += bspec.length()) {
|
||||
@ -189,7 +189,7 @@ public class VectorSaturatedOperationsTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.SATURATING_ADD_VS, " >0 "}, applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
|
||||
@IR(counts = {IRNode.SATURATING_ADD_VS, " >0 "}, applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"})
|
||||
@Warmup(value = 10000)
|
||||
public void sadd_short() {
|
||||
for (int i = 0; i < COUNT; i += sspec.length()) {
|
||||
@ -212,7 +212,7 @@ public class VectorSaturatedOperationsTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.SATURATING_ADD_VI, " >0 "}, applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
|
||||
@IR(counts = {IRNode.SATURATING_ADD_VI, " >0 "}, applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"})
|
||||
@Warmup(value = 10000)
|
||||
public void sadd_int() {
|
||||
for (int i = 0; i < COUNT; i += ispec.length()) {
|
||||
@ -235,7 +235,7 @@ public class VectorSaturatedOperationsTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.SATURATING_ADD_VL, " >0 "}, applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
|
||||
@IR(counts = {IRNode.SATURATING_ADD_VL, " >0 "}, applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"})
|
||||
@Warmup(value = 10000)
|
||||
public void sadd_long() {
|
||||
for (int i = 0; i < COUNT; i += lspec.length()) {
|
||||
@ -260,7 +260,7 @@ public class VectorSaturatedOperationsTest {
|
||||
@Test
|
||||
@IR(counts = {IRNode.SATURATING_ADD_VB, " >0 " , "unsigned_vector_node", " >0 "},
|
||||
phase = {CompilePhase.BEFORE_MATCHING},
|
||||
applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
|
||||
applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"})
|
||||
@Warmup(value = 10000)
|
||||
public void suadd_byte() {
|
||||
for (int i = 0; i < COUNT; i += bspec.length()) {
|
||||
@ -285,7 +285,7 @@ public class VectorSaturatedOperationsTest {
|
||||
@Test
|
||||
@IR(counts = {IRNode.SATURATING_ADD_VS, " >0 ", "unsigned_vector_node", " >0 "},
|
||||
phase = {CompilePhase.BEFORE_MATCHING},
|
||||
applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
|
||||
applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"})
|
||||
@Warmup(value = 10000)
|
||||
public void suadd_short() {
|
||||
for (int i = 0; i < COUNT; i += sspec.length()) {
|
||||
@ -310,7 +310,7 @@ public class VectorSaturatedOperationsTest {
|
||||
@Test
|
||||
@IR(counts = {IRNode.SATURATING_ADD_VI, " >0 ", "unsigned_vector_node", " >0 "},
|
||||
phase = {CompilePhase.BEFORE_MATCHING},
|
||||
applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
|
||||
applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"})
|
||||
@Warmup(value = 10000)
|
||||
public void suadd_int() {
|
||||
for (int i = 0; i < COUNT; i += ispec.length()) {
|
||||
@ -335,7 +335,7 @@ public class VectorSaturatedOperationsTest {
|
||||
@Test
|
||||
@IR(counts = {IRNode.SATURATING_ADD_VL, " >0 ", "unsigned_vector_node", " >0 "},
|
||||
phase = {CompilePhase.BEFORE_MATCHING},
|
||||
applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
|
||||
applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"})
|
||||
@Warmup(value = 10000)
|
||||
public void suadd_long() {
|
||||
for (int i = 0; i < COUNT; i += lspec.length()) {
|
||||
@ -358,7 +358,7 @@ public class VectorSaturatedOperationsTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.SATURATING_SUB_VB, " >0 "}, applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
|
||||
@IR(counts = {IRNode.SATURATING_SUB_VB, " >0 "}, applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"})
|
||||
@Warmup(value = 10000)
|
||||
public void ssub_byte() {
|
||||
for (int i = 0; i < COUNT; i += bspec.length()) {
|
||||
@ -381,7 +381,7 @@ public class VectorSaturatedOperationsTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.SATURATING_SUB_VS, " >0 "}, applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
|
||||
@IR(counts = {IRNode.SATURATING_SUB_VS, " >0 "}, applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"})
|
||||
@Warmup(value = 10000)
|
||||
public void ssub_short() {
|
||||
for (int i = 0; i < COUNT; i += sspec.length()) {
|
||||
@ -404,7 +404,7 @@ public class VectorSaturatedOperationsTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.SATURATING_SUB_VI, " >0 "}, applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
|
||||
@IR(counts = {IRNode.SATURATING_SUB_VI, " >0 "}, applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"})
|
||||
@Warmup(value = 10000)
|
||||
public void ssub_int() {
|
||||
for (int i = 0; i < COUNT; i += ispec.length()) {
|
||||
@ -427,7 +427,7 @@ public class VectorSaturatedOperationsTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.SATURATING_SUB_VL, " >0 "}, applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
|
||||
@IR(counts = {IRNode.SATURATING_SUB_VL, " >0 "}, applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"})
|
||||
@Warmup(value = 10000)
|
||||
public void ssub_long() {
|
||||
for (int i = 0; i < COUNT; i += lspec.length()) {
|
||||
@ -452,7 +452,7 @@ public class VectorSaturatedOperationsTest {
|
||||
@Test
|
||||
@IR(counts = {IRNode.SATURATING_SUB_VB, " >0 " , "unsigned_vector_node", " >0 "},
|
||||
phase = {CompilePhase.BEFORE_MATCHING},
|
||||
applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
|
||||
applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"})
|
||||
@Warmup(value = 10000)
|
||||
public void susub_byte() {
|
||||
for (int i = 0; i < COUNT; i += bspec.length()) {
|
||||
@ -477,7 +477,7 @@ public class VectorSaturatedOperationsTest {
|
||||
@Test
|
||||
@IR(counts = {IRNode.SATURATING_SUB_VS, " >0 ", "unsigned_vector_node", " >0 "},
|
||||
phase = {CompilePhase.BEFORE_MATCHING},
|
||||
applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
|
||||
applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"})
|
||||
@Warmup(value = 10000)
|
||||
public void susub_short() {
|
||||
for (int i = 0; i < COUNT; i += sspec.length()) {
|
||||
@ -502,7 +502,7 @@ public class VectorSaturatedOperationsTest {
|
||||
@Test
|
||||
@IR(counts = {IRNode.SATURATING_SUB_VI, " >0 ", "unsigned_vector_node", " >0 "},
|
||||
phase = {CompilePhase.BEFORE_MATCHING},
|
||||
applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
|
||||
applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"})
|
||||
@Warmup(value = 10000)
|
||||
public void susub_int() {
|
||||
for (int i = 0; i < COUNT; i += ispec.length()) {
|
||||
@ -527,7 +527,7 @@ public class VectorSaturatedOperationsTest {
|
||||
@Test
|
||||
@IR(counts = {IRNode.SATURATING_SUB_VL, " >0 ", "unsigned_vector_node", " >0 "},
|
||||
phase = {CompilePhase.BEFORE_MATCHING},
|
||||
applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
|
||||
applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"})
|
||||
@Warmup(value = 10000)
|
||||
public void susub_long() {
|
||||
for (int i = 0; i < COUNT; i += lspec.length()) {
|
||||
@ -550,7 +550,7 @@ public class VectorSaturatedOperationsTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.SATURATING_ADD_VB, " >0 "}, applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
|
||||
@IR(counts = {IRNode.SATURATING_ADD_VB, " >0 "}, applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"})
|
||||
@IR(counts = {IRNode.VECTOR_BLEND_B, " >0 "}, applyIfCPUFeatureAnd = {"asimd", "true", "sve2", "false"})
|
||||
@IR(failOn = IRNode.VECTOR_BLEND_B, applyIfCPUFeature = {"sve2", "true"})
|
||||
@Warmup(value = 10000)
|
||||
@ -576,7 +576,7 @@ public class VectorSaturatedOperationsTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.SATURATING_SUB_VS, " >0 "}, applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
|
||||
@IR(counts = {IRNode.SATURATING_SUB_VS, " >0 "}, applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"})
|
||||
@IR(counts = {IRNode.VECTOR_BLEND_S, " >0 "}, applyIfCPUFeatureAnd = {"asimd", "true", "sve2", "false"})
|
||||
@IR(failOn = IRNode.VECTOR_BLEND_S, applyIfCPUFeature = {"sve2", "true"})
|
||||
@Warmup(value = 10000)
|
||||
@ -604,7 +604,7 @@ public class VectorSaturatedOperationsTest {
|
||||
@Test
|
||||
@IR(counts = {IRNode.SATURATING_ADD_VI, " >0 ", "unsigned_vector_node", " >0 "},
|
||||
phase = {CompilePhase.BEFORE_MATCHING},
|
||||
applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
|
||||
applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"})
|
||||
@IR(counts = {IRNode.VECTOR_BLEND_I, " >0 "}, applyIfCPUFeatureAnd = {"asimd", "true", "sve2", "false"})
|
||||
@IR(failOn = IRNode.VECTOR_BLEND_I, applyIfCPUFeature = {"sve2", "true"})
|
||||
@Warmup(value = 10000)
|
||||
@ -632,7 +632,7 @@ public class VectorSaturatedOperationsTest {
|
||||
@Test
|
||||
@IR(counts = {IRNode.SATURATING_SUB_VL, " >0 ", "unsigned_vector_node", " >0 "},
|
||||
phase = {CompilePhase.BEFORE_MATCHING},
|
||||
applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"})
|
||||
applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true", "rvv", "true"})
|
||||
@IR(counts = {IRNode.VECTOR_BLEND_L, " >0 "}, applyIfCPUFeatureAnd = {"asimd", "true", "sve2", "false"})
|
||||
@IR(failOn = IRNode.VECTOR_BLEND_L, applyIfCPUFeature = {"sve2", "true"})
|
||||
@Warmup(value = 10000)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user