From b6ecc5f2f1c6aa350b2fdb4d73b6bd410bdab951 Mon Sep 17 00:00:00 2001 From: cheapie Date: Sat, 7 Nov 2026 05:45:09 -0600 Subject: Add Zbc (and by extension, Zbkc) --- assembly/clmultest/Makefile | 24 +++++++++++++++++ assembly/clmultest/clmultest.S | 14 ++++++++++ assembly/clmultest/rvcontroller.ld | 1 + doc/_start_here.txt | 7 +++-- doc/instructions.txt | 8 ++++++ rvcontroller.lua | 55 ++++++++++++++++++++++++++++++++++++-- 6 files changed, 105 insertions(+), 4 deletions(-) create mode 100644 assembly/clmultest/Makefile create mode 100644 assembly/clmultest/clmultest.S create mode 120000 assembly/clmultest/rvcontroller.ld diff --git a/assembly/clmultest/Makefile b/assembly/clmultest/Makefile new file mode 100644 index 0000000..c4e7727 --- /dev/null +++ b/assembly/clmultest/Makefile @@ -0,0 +1,24 @@ +MARCH ?= rv32imacbzicntr_zicond_zicsr_zifencei_zihintpause_zilsd_zclsd_zabha_zacas_zbkb_zbkx_zcb_zcmp_zcmt_zicboz_zbc + +.PHONY: all dump load clean + +all: clmultest.hex + +clmultest.o: clmultest.S + riscv32-none-elf-as -I../rvcontroller-libraries -march=${MARCH} -o clmultest.o clmultest.S + +clmultest.elf: clmultest.o + riscv32-none-elf-ld -T rvcontroller.ld --no-warn-rwx-segments -o clmultest.elf clmultest.o + +dump: clmultest.elf + riscv32-none-elf-objdump -d clmultest.elf + +clmultest.hex: clmultest.elf + riscv32-none-elf-objcopy -O ihex clmultest.elf clmultest.hex + +load: clmultest.hex + bash -c "wl-copy < clmultest.hex" + +clean: + rm -f clmultest.hex clmultest.elf clmultest.o + diff --git a/assembly/clmultest/clmultest.S b/assembly/clmultest/clmultest.S new file mode 100644 index 0000000..397603f --- /dev/null +++ b/assembly/clmultest/clmultest.S @@ -0,0 +1,14 @@ +li t0,0xaaaaaaab +li t1,0x0002fe7d +clmul s0,t0,t1 +clmulh s1,t0,t1 +clmulr s2,t0,t1 + +li t0,0x7e00 +li t1,0xb6db6db7 +clmul s3,t0,t1 +clmulh s4,t0,t1 +clmulr s5,t0,t1 + +li a7,10 +ecall diff --git a/assembly/clmultest/rvcontroller.ld b/assembly/clmultest/rvcontroller.ld new file mode 120000 index 0000000..bc01402 --- /dev/null +++ b/assembly/clmultest/rvcontroller.ld @@ -0,0 +1 @@ +../../rvcontroller.ld \ No newline at end of file diff --git a/doc/_start_here.txt b/doc/_start_here.txt index 125de5f..745f83a 100644 --- a/doc/_start_here.txt +++ b/doc/_start_here.txt @@ -5,12 +5,12 @@ RVController is a program for use in Luacontrollers (from the mesecons mod) in L It emulates a single RISC-V hart and a configurable amount (64KiB default) of RAM. Features: -* RV32IMACBZicboz_Zicfilp_Zicntr_Zicond_Zicsr_Zifencei_Zihintpause_Zihpm_Zilsd_Zimop_Zabha_Zacas_Zalasr_Zawrs_Zcb_Zclsd_Zcmop_Zcmp_Zcmt_Zbkb_Zbkx_Xh3bextm_Xh3misa instruction set provides: +* RV32IMACBZicboz_Zicfilp_Zicntr_Zicond_Zicsr_Zifencei_Zihintpause_Zihpm_Zilsd_Zimop_Zabha_Zacas_Zalasr_Zawrs_Zcb_Zclsd_Zcmop_Zcmp_Zcmt_Zbc_Zbkb_Zbkc_Zbkx_Xh3bextm_Xh3misa instruction set provides: - 32-bit address space - 32 32-bit registers (31 general-purpose + 1 zero register) - Selectable endianness - Multiply/divide instructions - - Bit manipulation including crossbar permutation and multiple-bit extraction + - Bit manipulation including crossbar permutation, multiple-bit extraction, and carry-less multiplication - Atomic memory operations via load-reserved/store-conditional, compare-and-swap, or math/bitwise operations directly on memory - Byte/halfword/word atomic memory operation sizes - Conditional zero instructions @@ -66,6 +66,9 @@ RVController is intended to be compliant with the following specifications: - * Zba: Extension for Address generation, Version 1.0.0 - * Zbb: Extension for Basic bit-manipulation, Version 1.0.0 - * Zbs: Extension for Single-bit instructions, Version 1.0.0 +* Zbc: Extension for Carry-less multiplication, Version 1.0.0 + - Note: This implies the following: + - * Zbkc: Extension for Carry-less multiplication for Cryptography, Version 1.0.0 * "Zihintpause" Extension for Pause Hint, Version 2.0 * Zilsd, Zclsd: Extensions for Load/Store pair for RV32, Version 1.0 * "Zabha" Extension for Byte and Halfword Atomic Memory Operations, Version 1.0 diff --git a/doc/instructions.txt b/doc/instructions.txt index 149d3c5..524a2b8 100644 --- a/doc/instructions.txt +++ b/doc/instructions.txt @@ -70,6 +70,9 @@ RV32I Base Integer Instruction Set, Version 2.1: * amomin.w rd,rs1,rs2 | Atomic integer minimum(memory,register), word size * amominu.w rd,rs1,rs2 | Atomic integer minimum(memory,register) (unsigned), word size +"CMO" Extensions for Base Cache Management Operation ISA, Version 1.0.0 +* cbo.zero 0(rs1) | Cache block zero + "C" Extension for Compressed Instructions, Version 2.0 * c.lwsp rd,imm | Compressed load word, stack pointer relative * c.swsp rs2,imm | Compressed store word, stack pointer relative @@ -129,6 +132,11 @@ RV32I Base Integer Instruction Set, Version 2.1: * bset rd,rs1,rs2 | Single-bit set (by register) * bseti rd,rs1,rs2 | Single-bit set (by immediate) +Zbc: Extension for Carry-less multiplication, Version 1.0.0 +* clmul rd,rs1,rs2 | Carry-less multiply (low part) +* clmulh rd,rs1,rs2 | Carry-less multiply (high part) +* clmulr rd,rs1,rs2 | Carry-less multiply (reversed) + Zicfilp: Control Flow Integrity - Landing Pad: * lpad imm | Landing pad diff --git a/rvcontroller.lua b/rvcontroller.lua index 7d6a211..d7a93c6 100644 --- a/rvcontroller.lua +++ b/rvcontroller.lua @@ -459,9 +459,9 @@ local function readcsr(address) mem.isa.a, --Zacas mem.isa.b, --Zba mem.isa.b, --Zbb - false, --Zbc + mem.isa.b, --Zbc mem.isa.b, --Zbkb - false, --Zbkc + mem.isa.b, --Zbkc } return implodebits(bits,32) elseif page == 1 then @@ -1998,6 +1998,51 @@ local operations = { local segment = address/0x100 mem.ram[segment] = string.rep(string.char(0),256) end, + clmul = function(rd,rs1,rs2) + local outputbits = {} + local rs1bits = explodebits(getreg(rs1),32) + local rs2bits = explodebits(getreg(rs2),32) + for i=0,31 do + if rs2bits[i] then + for j=0,31 do + if rs1bits[j] then + outputbits[i+j] = not outputbits[i+j] + end + end + end + end + setreg(rd,implodebits(outputbits,32)) + end, + clmulh = function(rd,rs1,rs2) + local outputbits = {} + local rs1bits = explodebits(getreg(rs1),32) + local rs2bits = explodebits(getreg(rs2),32) + for i=0,31 do + if rs2bits[i] then + for j=0,31 do + if rs1bits[j] then + outputbits[i+j-32] = not outputbits[i+j-32] + end + end + end + end + setreg(rd,implodebits(outputbits,32)) + end, + clmulr = function(rd,rs1,rs2) + local outputbits = {} + local rs1bits = explodebits(getreg(rs1),32) + local rs2bits = explodebits(getreg(rs2),32) + for i=0,31 do + if rs2bits[31-i] then + for j=0,31 do + if rs1bits[j] then + outputbits[0-i+j] = not outputbits[0-i+j] + end + end + end + end + setreg(rd,implodebits(outputbits,32)) + end, } local function runinst(instruction) @@ -2066,6 +2111,12 @@ local function runinst(instruction) operations.orn(rd,rs1,rs2) elseif f3 == 0x4 and f7 == 0x20 and mem.isa.b then operations.xnor(rd,rs1,rs2) + elseif f3 == 0x1 and f7 == 0x5 and mem.isa.b then + operations.clmul(rd,rs1,rs2) + elseif f3 == 0x2 and f7 == 0x5 and mem.isa.b then + operations.clmulr(rd,rs1,rs2) + elseif f3 == 0x3 and f7 == 0x5 and mem.isa.b then + operations.clmulh(rd,rs1,rs2) elseif f3 == 0x6 and f7 == 0x5 then operations.max(rd,rs1,rs2) elseif f3 == 0x7 and f7 == 0x5 then -- cgit v1.2.3