cmd/internal/obj/riscv: add assembly support of Zbc extension
The Zbc extension adds carry-less multiplication instructions for polynomial arithmetic over GF(2), which is used in cryptographic algorithms and error-correcting codes. The instructions included are: clmul, clmulh, and clmulr.
diff --git a/src/cmd/asm/internal/asm/testdata/riscv64.s b/src/cmd/asm/internal/asm/testdata/riscv64.s
index 4615119..4b49d84 100644
--- a/src/cmd/asm/internal/asm/testdata/riscv64.s
+++ b/src/cmd/asm/internal/asm/testdata/riscv64.s
@@ -509,6 +509,11 @@
ORCB X5, X6 // 13d37228
REV8 X7, X8 // 13d4836b
+ // 28.4.3: Carry-less multiplication (Zbc)
+ CLMUL X5, X6, X7 // b313530a
+ CLMULH X5, X6, X7 // b333530a
+ CLMULR X5, X6, X7 // b323530a
+
// 28.4.4: Single-bit Instructions (Zbs)
BCLR X23, X24, X25 // b31c7c49
BCLR $63, X24 // 131cfc4b
diff --git a/src/cmd/internal/obj/riscv/anames.go b/src/cmd/internal/obj/riscv/anames.go
index 6c48e2f..1f777dd 100644
--- a/src/cmd/internal/obj/riscv/anames.go
+++ b/src/cmd/internal/obj/riscv/anames.go
@@ -263,6 +263,9 @@
"RORW",
"ORCB",
"REV8",
+ "CLMUL",
+ "CLMULH",
+ "CLMULR",
"BCLR",
"BCLRI",
"BEXT",
diff --git a/src/cmd/internal/obj/riscv/cpu.go b/src/cmd/internal/obj/riscv/cpu.go
index 60174a0..a43bb82 100644
--- a/src/cmd/internal/obj/riscv/cpu.go
+++ b/src/cmd/internal/obj/riscv/cpu.go
@@ -669,7 +669,7 @@
ASEXTH
AZEXTH
- // 28.4.3: Bitwise Rotation (Zbb)
+ // 28.4.2: Bitwise Rotation (Zbb)
AROL
AROLW
AROR
@@ -679,6 +679,11 @@
AORCB
AREV8
+ // 28.4.3: Carry-less multiplication (Zbc)
+ ACLMUL
+ ACLMULH
+ ACLMULR
+
// 28.4.4: Single-bit Instructions (Zbs)
ABCLR
ABCLRI
diff --git a/src/cmd/internal/obj/riscv/inst.go b/src/cmd/internal/obj/riscv/inst.go
index a5b3acd..a41b35d 100644
--- a/src/cmd/internal/obj/riscv/inst.go
+++ b/src/cmd/internal/obj/riscv/inst.go
@@ -1,4 +1,4 @@
-// Code generated by ./parse.py -go rv64_a rv64_c rv64_d rv64_f rv64_i rv64_m rv64_q rv64_zba rv64_zbb rv64_zbs rv_a rv_c rv_c_d rv_d rv_f rv_i rv_m rv_q rv_s rv_system rv_v rv_zba rv_zbb rv_zbs rv_zicond rv_zicsr; DO NOT EDIT.
+// Code generated by ./parse.py -go rv64_a rv64_c rv64_d rv64_f rv64_i rv64_m rv64_q rv64_zba rv64_zbb rv64_zbs rv_a rv_c rv_c_d rv_d rv_f rv_i rv_m rv_q rv_s rv_system rv_v rv_zba rv_zbb rv_zbc rv_zbs rv_zicond rv_zicsr; DO NOT EDIT.
package riscv
import "cmd/internal/obj"
@@ -170,6 +170,12 @@
return &inst{0x2, 0x4, 0x1, 0x0, 0, 0x0}
case ACXOR:
return &inst{0x21, 0x0, 0x1, 0x0, 0, 0x0}
+ case ACLMUL:
+ return &inst{0x33, 0x1, 0x0, 0x0, 160, 0x5}
+ case ACLMULH:
+ return &inst{0x33, 0x3, 0x0, 0x0, 160, 0x5}
+ case ACLMULR:
+ return &inst{0x33, 0x2, 0x0, 0x0, 160, 0x5}
case ACLZ:
return &inst{0x13, 0x1, 0x0, 0x0, 1536, 0x30}
case ACLZW:
diff --git a/src/cmd/internal/obj/riscv/obj.go b/src/cmd/internal/obj/riscv/obj.go
index 3deab34..dd13bba 100644
--- a/src/cmd/internal/obj/riscv/obj.go
+++ b/src/cmd/internal/obj/riscv/obj.go
@@ -2621,7 +2621,7 @@
AXNOR & obj.AMask: {enc: rIIIEncoding, ternary: true},
AZEXTH & obj.AMask: {enc: rIIEncoding},
- // 28.4.3: Bitwise Rotation (Zbb)
+ // 28.4.2: Bitwise Rotation (Zbb)
AROL & obj.AMask: {enc: rIIIEncoding, ternary: true},
AROLW & obj.AMask: {enc: rIIIEncoding, ternary: true},
AROR & obj.AMask: {enc: rIIIEncoding, immForm: ARORI, ternary: true},
@@ -2631,6 +2631,11 @@
AORCB & obj.AMask: {enc: rIIEncoding},
AREV8 & obj.AMask: {enc: rIIEncoding},
+ // 28.4.3: Carry-less Multiplication (Zbc)
+ ACLMUL & obj.AMask: {enc: rIIIEncoding, ternary: true},
+ ACLMULH & obj.AMask: {enc: rIIIEncoding, ternary: true},
+ ACLMULR & obj.AMask: {enc: rIIIEncoding, ternary: true},
+
// 28.4.4: Single-bit Instructions (Zbs)
ABCLR & obj.AMask: {enc: rIIIEncoding, immForm: ABCLRI, ternary: true},
ABCLRI & obj.AMask: {enc: iIIEncoding, ternary: true},
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
I spotted some possible problems with your PR:
1. You have a long 227 character line in the commit message body. Please add line breaks to long lines that should be wrapped. Lines in the commit message body should be wrapped at ~76 characters unless needed for things like URLs or tables. (Note: GitHub might render long lines as soft-wrapped, so double-check in the Gerrit commit message shown above.)
2. You usually need to reference a bug number for all but trivial or cosmetic fixes. For this repo, the format is usually 'Fixes #12345' or 'Updates #12345' at the end of the commit message. Should you have a bug reference?
Please address any problems by updating the GitHub PR.
When complete, mark this comment as 'Done' and click the [blue 'Reply' button](https://go.dev/wiki/GerritBot#i-left-a-reply-to-a-comment-in-gerrit-but-no-one-but-me-can-see-it) above. These findings are based on heuristics; if a finding does not apply, briefly reply here saying so.
To update the commit title or commit message body shown here in Gerrit, you must edit the GitHub PR title and PR description (the first comment) in the GitHub web interface using the 'Edit' button or 'Edit' menu entry there. Note: pushing a new commit to the PR will not automatically update the commit message used by Gerrit.
For more details, see:
(In general for Gerrit code reviews, the change author is expected to [log in to Gerrit](https://go-review.googlesource.com/login/) with a Gmail or other Google account and then close out each piece of feedback by marking it as 'Done' if implemented as suggested or otherwise reply to each review comment. See the [Review](https://go.dev/doc/contribute#review) section of the Contributing Guide for details.)
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
The Zbc extension adds carry-less multiplication instructions for polynomial arithmetic over GF(2), which is used in cryptographic algorithms and error-correcting codes. The instructions included are: clmul, clmulh, and clmulr.Please wrap to ~80 characters.
CLMUL X5, X6, X7 // b313530aPlease add two register versions (see ROL as an example):
```
CLMUL X5, X6, X7
CLMUL X5, X6
CLMULH X5, X6, X7
CLMULH X5, X6
CLMULR X5, X6, X7
CLMULR X5, X6
```
(all two register forms should expand to `X5, X6, X6`)
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
The Zbc extension adds carry-less multiplication instructions for polynomial arithmetic over GF(2), which is used in cryptographic algorithms and error-correcting codes. The instructions included are: clmul, clmulh, and clmulr.Please wrap to ~80 characters.
Done
CLMUL X5, X6, X7 // b313530aPlease add two register versions (see ROL as an example):
```
CLMUL X5, X6, X7
CLMUL X5, X6
CLMULH X5, X6, X7
CLMULH X5, X6
CLMULR X5, X6, X7
CLMULR X5, X6
```(all two register forms should expand to `X5, X6, X6`)
Fixed, thank you.
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
Before reviewing this patch and its counterpart (https://go-review.googlesource.com/c/arch/+/735880) (thanks so much for submitting a corresponding objdump patch BTW) I guess we should discuss whether we want to add support for Zbc in golang.
Why might we not want to add support for Zbc?
Zbc is listed as an expansion option in the RVA profiles (https://github.com/riscv/riscv-profiles/blob/main/src/rva23-profile.adoc#rva23u64-optional-extensions) meaning that it will probably never become mandatory. The only way to safely use Zbc will be to first dynamically detect it at runtime, a check we'll never be able to avoid by setting GORISCV64. Zvbc (the vector version of Zbc) on the other hand is listed as a development option in the profiles and is expected to become mandatory in a future profile. It can be used instead of Zbc on devices that support it.
So I guess I'm wondering whether there are any devices that support Zbc but not Zvbc? If not, then I'm not sure we'd use Zbc internally in Go. If we don't end up using Zbc internally in Go then we'd just be adding Zbc assembler support for 3rd party users of Go, which is fine if we agree it's worth doing.
@18243...@qq.com are you aware of any RISC-V devices that support Zbc and not Zvbc?
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
Before reviewing this patch and its counterpart (https://go-review.googlesource.com/c/arch/+/735880) (thanks so much for submitting a corresponding objdump patch BTW) I guess we should discuss whether we want to add support for Zbc in golang.
Why might we not want to add support for Zbc?
Zbc is listed as an expansion option in the RVA profiles (https://github.com/riscv/riscv-profiles/blob/main/src/rva23-profile.adoc#rva23u64-optional-extensions) meaning that it will probably never become mandatory. The only way to safely use Zbc will be to first dynamically detect it at runtime, a check we'll never be able to avoid by setting GORISCV64. Zvbc (the vector version of Zbc) on the other hand is listed as a development option in the profiles and is expected to become mandatory in a future profile. It can be used instead of Zbc on devices that support it.
So I guess I'm wondering whether there are any devices that support Zbc but not Zvbc? If not, then I'm not sure we'd use Zbc internally in Go. If we don't end up using Zbc internally in Go then we'd just be adding Zbc assembler support for 3rd party users of Go, which is fine if we agree it's worth doing.
@18243...@qq.com are you aware of any RISC-V devices that support Zbc and not Zvbc?
Hi @mark...@meta.com
Thanks for the feedback. To clarify the necessity of Zbc support, I’ve verified the hardware capabilities on a SOPHON SG2044 (a 64-core RISC-V server).
While the SoC is high-performance and supports Vector (V), it implements the scalar Zbc extension but lacks Zvbc or other Vector Crypto extensions. The /proc/cpuinfo confirms this:
isa : rv64imafdcv_..._zba_zbb_zbc_zbs_zve32f_zve32x_zve64d_zve64f_zve64x_...
I also ran a Go feature detection tool, which confirms that cpu.RISCV64.HasZvbc is false on this production silicon.
Since Zbc is already present in real-world server hardware while Zvbc is absent, supporting Zbc in the Go assembler allows cryptography and checksum libraries to utilize existing hardware acceleration rather than falling back to slower software implementations.
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
Xueqi LuoBefore reviewing this patch and its counterpart (https://go-review.googlesource.com/c/arch/+/735880) (thanks so much for submitting a corresponding objdump patch BTW) I guess we should discuss whether we want to add support for Zbc in golang.
Why might we not want to add support for Zbc?
Zbc is listed as an expansion option in the RVA profiles (https://github.com/riscv/riscv-profiles/blob/main/src/rva23-profile.adoc#rva23u64-optional-extensions) meaning that it will probably never become mandatory. The only way to safely use Zbc will be to first dynamically detect it at runtime, a check we'll never be able to avoid by setting GORISCV64. Zvbc (the vector version of Zbc) on the other hand is listed as a development option in the profiles and is expected to become mandatory in a future profile. It can be used instead of Zbc on devices that support it.
So I guess I'm wondering whether there are any devices that support Zbc but not Zvbc? If not, then I'm not sure we'd use Zbc internally in Go. If we don't end up using Zbc internally in Go then we'd just be adding Zbc assembler support for 3rd party users of Go, which is fine if we agree it's worth doing.
@18243...@qq.com are you aware of any RISC-V devices that support Zbc and not Zvbc?
Hi @mark...@meta.com
Thanks for the feedback. To clarify the necessity of Zbc support, I’ve verified the hardware capabilities on a SOPHON SG2044 (a 64-core RISC-V server).
While the SoC is high-performance and supports Vector (V), it implements the scalar Zbc extension but lacks Zvbc or other Vector Crypto extensions. The /proc/cpuinfo confirms this:
isa : rv64imafdcv_..._zba_zbb_zbc_zbs_zve32f_zve32x_zve64d_zve64f_zve64x_...
I also ran a Go feature detection tool, which confirms that cpu.RISCV64.HasZvbc is false on this production silicon.
Since Zbc is already present in real-world server hardware while Zvbc is absent, supporting Zbc in the Go assembler allows cryptography and checksum libraries to utilize existing hardware acceleration rather than falling back to slower software implementations.
Thanks for checking this @18243...@qq.com. Looks like it might be worth implementing after all. Just one quick question. What kernel version were you running? I think you need 6.8 or newer to detect zvbc.
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
Xueqi LuoBefore reviewing this patch and its counterpart (https://go-review.googlesource.com/c/arch/+/735880) (thanks so much for submitting a corresponding objdump patch BTW) I guess we should discuss whether we want to add support for Zbc in golang.
Why might we not want to add support for Zbc?
Zbc is listed as an expansion option in the RVA profiles (https://github.com/riscv/riscv-profiles/blob/main/src/rva23-profile.adoc#rva23u64-optional-extensions) meaning that it will probably never become mandatory. The only way to safely use Zbc will be to first dynamically detect it at runtime, a check we'll never be able to avoid by setting GORISCV64. Zvbc (the vector version of Zbc) on the other hand is listed as a development option in the profiles and is expected to become mandatory in a future profile. It can be used instead of Zbc on devices that support it.
So I guess I'm wondering whether there are any devices that support Zbc but not Zvbc? If not, then I'm not sure we'd use Zbc internally in Go. If we don't end up using Zbc internally in Go then we'd just be adding Zbc assembler support for 3rd party users of Go, which is fine if we agree it's worth doing.
@18243...@qq.com are you aware of any RISC-V devices that support Zbc and not Zvbc?
Mark RyanHi @mark...@meta.com
Thanks for the feedback. To clarify the necessity of Zbc support, I’ve verified the hardware capabilities on a SOPHON SG2044 (a 64-core RISC-V server).
While the SoC is high-performance and supports Vector (V), it implements the scalar Zbc extension but lacks Zvbc or other Vector Crypto extensions. The /proc/cpuinfo confirms this:
isa : rv64imafdcv_..._zba_zbb_zbc_zbs_zve32f_zve32x_zve64d_zve64f_zve64x_...
I also ran a Go feature detection tool, which confirms that cpu.RISCV64.HasZvbc is false on this production silicon.
Since Zbc is already present in real-world server hardware while Zvbc is absent, supporting Zbc in the Go assembler allows cryptography and checksum libraries to utilize existing hardware acceleration rather than falling back to slower software implementations.
Thanks for checking this @18243...@qq.com. Looks like it might be worth implementing after all. Just one quick question. What kernel version were you running? I think you need 6.8 or newer to detect zvbc.
Hi, @mark...@meta.com I'm using kernel 6.12, which is well above 6.8, so the detection should be reliable.
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |