The Zba address generation, Zbb unary bit operations, Zbc carry-less multiplication and Zbs single-bit families were names the table carried and the encoder refused: thirty spellings plus RORI and XNOR fell over. The register and immediate forms now encode as the toolchain does, the unary operations carry their fixed rs2 constant, RORI lowers to ROR's expansion (its reverse shift compressing like ROR's), XNOR XORs and inverts in place, and ROL/ROLW rotate left through the same temporary the toolchain uses, taking a register amount only as its own expansion requires. The toolchain's whole testdata block for these families is now a differential test: every word must agree byte for byte. Assisted-by: GLM 5.3 Flash
106 lines
2.2 KiB
Go
106 lines
2.2 KiB
Go
// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
package asm
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
)
|
|
|
|
// TestRISCVBitManipDifferential proves the Zba, Zbb, Zbc and Zbs families
|
|
// against the toolchain: the toolchain's own testdata spellings (every
|
|
// operand form each section carries) assembled by gasm and by go tool asm
|
|
// must agree byte for byte. The lines are the oracle's own, so a wrong
|
|
// funct6, a swapped operand pair or a missed two-operand collapse names
|
|
// itself through the first differing word.
|
|
func TestRISCVBitManipDifferential(t *testing.T) {
|
|
src := `#include "textflag.h"
|
|
|
|
TEXT ·bitmanip(SB), NOSPLIT, $0
|
|
ADDUW X10, X11, X12
|
|
ADDUW X10, X11
|
|
SH1ADD X11, X12, X13
|
|
SH1ADD X11, X12
|
|
SH1ADDUW X12, X13, X14
|
|
SH1ADDUW X12, X13
|
|
SH2ADD X13, X14, X15
|
|
SH2ADD X13, X14
|
|
SH2ADDUW X14, X15, X16
|
|
SH2ADDUW X14, X15
|
|
SH3ADD X15, X16, X17
|
|
SH3ADD X15, X16
|
|
SH3ADDUW X16, X17, X18
|
|
SH3ADDUW X16, X17
|
|
SLLIUW $31, X17, X18
|
|
SLLIUW $63, X17
|
|
SLLIUW $63, X17, X18
|
|
SLLIUW $1, X18, X19
|
|
ANDN X19, X20, X21
|
|
ANDN X19, X20
|
|
CLZ X20, X21
|
|
CLZW X21, X22
|
|
CPOP X22, X23
|
|
CPOPW X23, X24
|
|
CTZ X24, X25
|
|
CTZW X25, X26
|
|
MAX X26, X28, X29
|
|
MAX X26, X28
|
|
MAXU X28, X29, X30
|
|
MAXU X28, X29
|
|
MIN X29, X30, X5
|
|
MIN X29, X30
|
|
MINU X30, X5, X6
|
|
MINU X30, X5
|
|
ORN X6, X7, X8
|
|
ORN X6, X7
|
|
SEXTB X16, X17
|
|
SEXTH X17, X18
|
|
XNOR X18, X19, X20
|
|
XNOR X18, X19
|
|
ZEXTH X19, X20
|
|
ROL X8, X9, X10
|
|
ROL X8, X9
|
|
ROLW X9, X10, X11
|
|
ROLW X9, X10
|
|
ROR X10, X11, X12
|
|
ROR X10, X11
|
|
ROR $63, X11
|
|
RORI $63, X11, X12
|
|
RORI $1, X12, X13
|
|
RORIW $31, X13, X14
|
|
RORIW $1, X14, X15
|
|
RORW X15, X16, X17
|
|
RORW X15, X16
|
|
RORW $31, X13
|
|
ORCB X5, X6
|
|
REV8 X7, X8
|
|
CLMUL X5, X6, X7
|
|
CLMUL X5, X6
|
|
CLMULH X5, X6, X7
|
|
CLMULH X5, X6
|
|
CLMULR X5, X6, X7
|
|
CLMULR X5, X6
|
|
BCLR X23, X24, X25
|
|
BCLR $63, X24
|
|
BCLRI $1, X25, X26
|
|
BEXT X26, X28, X29
|
|
BEXT $63, X28
|
|
BEXTI $1, X29, X30
|
|
BINV X30, X5, X6
|
|
BINV $63, X6
|
|
BINVI $1, X7, X8
|
|
BSET X8, X9, X10
|
|
BSET $63, X9
|
|
BSETI $1, X10, X11
|
|
RET
|
|
`
|
|
dir := t.TempDir()
|
|
path := filepath.Join(dir, "bitmanip_riscv64.s")
|
|
if err := os.WriteFile(path, []byte(src), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
assertRISCVDifferential(t, path, src, "bitmanip")
|
|
}
|