Skip to content

Commit 712a70c

Browse files
author
Hamlin Li
committed
8318220: RISC-V: C2 ReverseI
8318221: RISC-V: C2 ReverseL Reviewed-by: fyang, luhenry
1 parent 985ca12 commit 712a70c

File tree

9 files changed

+323
-0
lines changed

9 files changed

+323
-0
lines changed

src/hotspot/cpu/riscv/assembler_riscv.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2384,6 +2384,7 @@ enum Nf {
23842384
emit(insn); \
23852385
}
23862386

2387+
INSN(brev8, 0b0010011, 0b101, 0b011010000111);
23872388
INSN(rev8, 0b0010011, 0b101, 0b011010111000);
23882389
INSN(_sext_b, 0b0010011, 0b001, 0b011000000100);
23892390
INSN(_sext_h, 0b0010011, 0b001, 0b011000000101);

src/hotspot/cpu/riscv/globals_riscv.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ define_pd_global(intx, InlineSmallCode, 1000);
102102
product(bool, UseRVV, false, DIAGNOSTIC, "Use RVV instructions") \
103103
product(bool, UseZba, false, DIAGNOSTIC, "Use Zba instructions") \
104104
product(bool, UseZbb, false, DIAGNOSTIC, "Use Zbb instructions") \
105+
product(bool, UseZbkb, false, EXPERIMENTAL, "Use Zbkb instructions") \
105106
product(bool, UseZbs, false, DIAGNOSTIC, "Use Zbs instructions") \
106107
product(bool, UseZfa, false, EXPERIMENTAL, "Use Zfa instructions") \
107108
product(bool, UseZfh, false, DIAGNOSTIC, "Use Zfh instructions") \

src/hotspot/cpu/riscv/riscv.ad

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1896,6 +1896,10 @@ bool Matcher::match_rule_supported(int opcode) {
18961896
case Op_PopCountL:
18971897
return UsePopCountInstruction;
18981898

1899+
case Op_ReverseI:
1900+
case Op_ReverseL:
1901+
return UseZbkb;
1902+
18991903
case Op_ReverseBytesI:
19001904
case Op_ReverseBytesL:
19011905
case Op_ReverseBytesS:

src/hotspot/cpu/riscv/riscv_b.ad

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,33 @@ instruct bytes_reverse_short_b(iRegINoSp dst, iRegIorL2I src) %{
245245
ins_pipe(ialu_reg);
246246
%}
247247

248+
// Reverse bits instruction
249+
instruct bits_reverse_I(iRegINoSp dst, iRegIorL2I src)
250+
%{
251+
match(Set dst (ReverseI src));
252+
ins_cost(ALU_COST * 3);
253+
format %{ "bits_reverse_I $dst, $src" %}
254+
ins_encode %{
255+
__ rev8($dst$$Register, $src$$Register);
256+
__ brev8($dst$$Register, $dst$$Register);
257+
__ srai($dst$$Register, $dst$$Register, 32);
258+
%}
259+
ins_pipe(ialu_reg);
260+
%}
261+
262+
instruct bits_reverse_L(iRegLNoSp dst, iRegL src)
263+
%{
264+
match(Set dst (ReverseL src));
265+
ins_cost(ALU_COST * 2);
266+
format %{ "bits_reverse_L $dst, $src" %}
267+
ins_encode %{
268+
__ rev8($dst$$Register, $src$$Register);
269+
__ brev8($dst$$Register, $dst$$Register);
270+
%}
271+
ins_pipe(ialu_reg);
272+
%}
273+
274+
248275
// Shift Add Pointer
249276
instruct shaddP_reg_reg_b(iRegPNoSp dst, iRegP src1, iRegL src2, immIScale imm) %{
250277
predicate(UseZba);

src/hotspot/cpu/riscv/vm_version_riscv.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ class VM_Version : public Abstract_VM_Version {
156156
decl(ext_Zbb , "Zbb" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZbb)) \
157157
decl(ext_Zbc , "Zbc" , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \
158158
decl(ext_Zbs , "Zbs" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZbs)) \
159+
decl(ext_Zbkb , "Zbkb" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZbkb)) \
159160
decl(ext_Zcb , "Zcb" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZcb)) \
160161
decl(ext_Zfa , "Zfa" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZfa)) \
161162
decl(ext_Zfh , "Zfh" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZfh)) \
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
/*
2+
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
3+
* Copyright (c) 2025, Rivos Inc. All rights reserved.
4+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5+
*
6+
* This code is free software; you can redistribute it and/or modify it
7+
* under the terms of the GNU General Public License version 2 only, as
8+
* published by the Free Software Foundation.
9+
*
10+
* This code is distributed in the hope that it will be useful, but WITHOUT
11+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13+
* version 2 for more details (a copy is included in the LICENSE file that
14+
* accompanied this code).
15+
*
16+
* You should have received a copy of the GNU General Public License version
17+
* 2 along with this work; if not, write to the Free Software Foundation,
18+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19+
*
20+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21+
* or visit www.oracle.com if you need additional information or have any
22+
* questions.
23+
*/
24+
25+
/**
26+
* @test
27+
* @key randomness
28+
* @bug 8318220
29+
* @summary Test ReverseI intrinsic
30+
*
31+
* @library /test/lib /
32+
* @requires os.arch == "riscv64" & vm.cpu.features ~= ".*zbkb.*"
33+
* @run main/othervm compiler.c2.riscv64.TestIntegerReverse
34+
*/
35+
36+
package compiler.c2.riscv64;
37+
38+
import compiler.lib.ir_framework.*;
39+
import java.util.Random;
40+
import jdk.test.lib.Asserts;
41+
import jdk.test.lib.Utils;
42+
43+
import static compiler.lib.golden.GoldenReverse.golden_reverse_integer;
44+
45+
public class TestIntegerReverse {
46+
47+
static Random r = Utils.getRandomInstance();
48+
static final int ITERS = 11000;
49+
static final int ARRLEN = 997;
50+
static int input[] = new int[ARRLEN];
51+
static int outputI[] = new int[ARRLEN];
52+
static long outputL[] = new long[ARRLEN];
53+
static int err;
54+
55+
public static void main(String args[]) {
56+
TestFramework.runWithFlags("-XX:-TieredCompilation", "-XX:CompileThresholdScaling=0.3",
57+
"-XX:+UnlockDiagnosticVMOptions", "-XX:-UseRVV"); // Only test scalar version
58+
}
59+
60+
@Test
61+
@IR(counts = {IRNode.REVERSE_I, "> 0"})
62+
static void test_reverse_ia(int[] input, int[] outputI) {
63+
for (int i = 0; i < input.length; i+=1) {
64+
outputI[i] = Integer.reverse(input[i]);
65+
}
66+
}
67+
68+
@Test
69+
@IR(counts = {IRNode.REVERSE_I, "> 0"})
70+
static void test_reverse_la(int[] input, long[] outputL) {
71+
for (int i = 0; i < input.length; i+=1) {
72+
outputL[i] = Integer.reverse(input[i]);
73+
}
74+
}
75+
76+
@Test
77+
@IR(counts = {IRNode.REVERSE_I, "> 0"})
78+
static void test_reverse_l(int input, long expected) {
79+
if (Integer.reverse(input) != expected) {
80+
err++;
81+
System.out.println("Test failure, input: " + input +
82+
", actual: " + Integer.reverse(input) +
83+
", expected: " + expected);
84+
}
85+
}
86+
87+
@Run(test = {"test_reverse_ia", "test_reverse_la", "test_reverse_l"})
88+
@Warmup(ITERS)
89+
static void test(RunInfo runInfo) {
90+
// Initialize
91+
for (int i = 0; i < ARRLEN; i++) {
92+
input[i] = r.nextInt();
93+
}
94+
input[0] = 0;
95+
input[1] = 1;
96+
input[2] = -1;
97+
input[3] = Integer.MIN_VALUE;
98+
input[4] = Integer.MAX_VALUE;
99+
100+
test_reverse_ia(input, outputI);
101+
test_reverse_la(input, outputL);
102+
for (int i = 0; i < ARRLEN; i++) {
103+
test_reverse_l(input[i], golden_reverse_integer(input[i]));
104+
}
105+
// skip test/verify when warming up
106+
if (runInfo.isWarmUp()) {
107+
return;
108+
}
109+
110+
test_reverse_ia(input, outputI);
111+
test_reverse_la(input, outputL);
112+
113+
for (int i = 0; i < ARRLEN; i++) {
114+
int golden_val = golden_reverse_integer(input[i]);
115+
Asserts.assertEquals(outputI[i], golden_val,
116+
"Test failure (integer array), input: " + input[i] +
117+
", actual: " + outputI[i] +
118+
", expected: " + golden_val);
119+
Asserts.assertEquals(outputL[i], (long)golden_val,
120+
"Test failure (long array), input: " + input[i] +
121+
", actual: " + outputL[i] +
122+
", expected: " + (long)golden_val);
123+
}
124+
125+
err = 0;
126+
for (int i = 0; i < ARRLEN; i++) {
127+
test_reverse_l(input[i], golden_reverse_integer(input[i]));
128+
}
129+
Asserts.assertTrue(err == 0, "Some tests(" + err + ") failed, check previous log for details");
130+
}
131+
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/*
2+
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
3+
* Copyright (c) 2025, Rivos Inc. All rights reserved.
4+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5+
*
6+
* This code is free software; you can redistribute it and/or modify it
7+
* under the terms of the GNU General Public License version 2 only, as
8+
* published by the Free Software Foundation.
9+
*
10+
* This code is distributed in the hope that it will be useful, but WITHOUT
11+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13+
* version 2 for more details (a copy is included in the LICENSE file that
14+
* accompanied this code).
15+
*
16+
* You should have received a copy of the GNU General Public License version
17+
* 2 along with this work; if not, write to the Free Software Foundation,
18+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19+
*
20+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21+
* or visit www.oracle.com if you need additional information or have any
22+
* questions.
23+
*/
24+
25+
/**
26+
* @test
27+
* @key randomness
28+
* @bug 8318221
29+
* @summary Test ReverseL intrinsic
30+
*
31+
* @library /test/lib /
32+
* @requires os.arch == "riscv64" & vm.cpu.features ~= ".*zbkb.*"
33+
* @run main/othervm compiler.c2.riscv64.TestLongReverse
34+
*/
35+
36+
package compiler.c2.riscv64;
37+
38+
import compiler.lib.ir_framework.*;
39+
import java.util.Random;
40+
import jdk.test.lib.Asserts;
41+
import jdk.test.lib.Utils;
42+
43+
import static compiler.lib.golden.GoldenReverse.golden_reverse_long;
44+
45+
public class TestLongReverse {
46+
47+
static Random r = Utils.getRandomInstance();
48+
static final int ITERS = 11000;
49+
static final int ARRLEN = 997;
50+
static long input[] = new long[ARRLEN];
51+
static long output[] = new long[ARRLEN];
52+
53+
public static void main(String args[]) {
54+
TestFramework.runWithFlags("-XX:-TieredCompilation", "-XX:CompileThresholdScaling=0.3",
55+
"-XX:+UnlockDiagnosticVMOptions", "-XX:-UseRVV"); // Only test scalar version
56+
}
57+
58+
@Test
59+
@IR(counts = {IRNode.REVERSE_L, "> 0"})
60+
static void test_reverse(long[] input, long[] output) {
61+
for (int i = 0; i < input.length; i+=1) {
62+
output[i] = Long.reverse(input[i]);
63+
}
64+
}
65+
66+
@Run(test = "test_reverse")
67+
@Warmup(ITERS)
68+
static void test(RunInfo runInfo) {
69+
// Initialize
70+
for (int i = 0; i < ARRLEN; i++) {
71+
input[i] = r.nextLong();
72+
}
73+
input[0] = 0L;
74+
input[1] = 1L;
75+
input[2] = -1L;
76+
input[3] = Long.MIN_VALUE;
77+
input[4] = Long.MAX_VALUE;
78+
79+
test_reverse(input, output);
80+
// skip test/verify when warming up
81+
if (runInfo.isWarmUp()) {
82+
return;
83+
}
84+
85+
test_reverse(input, output);
86+
87+
for (int i = 0; i < ARRLEN; i++) {
88+
long golden_val = golden_reverse_long(input[i]);
89+
Asserts.assertEquals(output[i], golden_val,
90+
"Test failure, input: " + input[i] +
91+
", actual: " + output[i] +
92+
", expected: " + golden_val);
93+
}
94+
}
95+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
3+
* Copyright (c) 2025, Rivos Inc. All rights reserved.
4+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5+
*
6+
* This code is free software; you can redistribute it and/or modify it
7+
* under the terms of the GNU General Public License version 2 only, as
8+
* published by the Free Software Foundation.
9+
*
10+
* This code is distributed in the hope that it will be useful, but WITHOUT
11+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13+
* version 2 for more details (a copy is included in the LICENSE file that
14+
* accompanied this code).
15+
*
16+
* You should have received a copy of the GNU General Public License version
17+
* 2 along with this work; if not, write to the Free Software Foundation,
18+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19+
*
20+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21+
* or visit www.oracle.com if you need additional information or have any
22+
* questions.
23+
*/
24+
25+
package compiler.lib.golden;
26+
27+
public class GoldenReverse {
28+
// The code is copied from java.lang.Integer.reverse(int i)
29+
public static int golden_reverse_integer(int i) {
30+
// HD, Figure 7-1
31+
i = (i & 0x55555555) << 1 | (i >>> 1) & 0x55555555;
32+
i = (i & 0x33333333) << 2 | (i >>> 2) & 0x33333333;
33+
i = (i & 0x0f0f0f0f) << 4 | (i >>> 4) & 0x0f0f0f0f;
34+
35+
return golden_reverseBytes_integer(i);
36+
}
37+
38+
// The code is copied from java.lang.Integer.reverseBytes(int i)
39+
static int golden_reverseBytes_integer(int i) {
40+
return (i << 24) |
41+
((i & 0xff00) << 8) |
42+
((i >>> 8) & 0xff00) |
43+
(i >>> 24);
44+
}
45+
46+
// The code is copied from java.lang.Long.reverse(long i)
47+
public static long golden_reverse_long(long i) {
48+
// HD, Figure 7-1
49+
i = (i & 0x5555555555555555L) << 1 | (i >>> 1) & 0x5555555555555555L;
50+
i = (i & 0x3333333333333333L) << 2 | (i >>> 2) & 0x3333333333333333L;
51+
i = (i & 0x0f0f0f0f0f0f0f0fL) << 4 | (i >>> 4) & 0x0f0f0f0f0f0f0f0fL;
52+
53+
return golden_reverseBytes_long(i);
54+
}
55+
56+
// The code is copied from java.lang.Long.reverseBytes(long i)
57+
static long golden_reverseBytes_long(long i) {
58+
i = (i & 0x00ff00ff00ff00ffL) << 8 | (i >>> 8) & 0x00ff00ff00ff00ffL;
59+
return (i << 48) | ((i & 0xffff0000L) << 16) |
60+
((i >>> 16) & 0xffff0000L) | (i >>> 48);
61+
}
62+
}

test/hotspot/jtreg/compiler/lib/ir_framework/test/IREncodingPrinter.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ public class IREncodingPrinter {
110110
"sve",
111111
// Riscv64
112112
"rvv",
113+
"zbkb",
113114
"zfh",
114115
"zvbb",
115116
"zvfh"

0 commit comments

Comments
 (0)