Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

decode_test.gno

2.66 Kb · 61 lines
 1package riscv
 2
 3import (
 4	"testing"
 5
 6	"gno.land/p/nt/uassert/v0"
 7)
 8
 9// jal is only needed to exercise immJ, the one format no program in
10// riscv_test.gno reaches for.
11func jal(rd, imm uint32) uint32 { return jType(imm, rd, opJAL) }
12
13// The assembler in riscv_test.gno and the decoders here were written from the
14// spec independently, so encoding a known field and reading it back is a real
15// cross-check rather than a tautology: a field in the wrong place fails unless
16// both files put it in the same wrong place.
17func TestDecodeRoundTripsTheAssembler(t *testing.T) {
18	inst := add(5, 6, 7)
19	uassert.Equal(t, uint64(opReg), uint64(opcode(inst)))
20	uassert.Equal(t, uint64(5), uint64(rd(inst)))
21	uassert.Equal(t, uint64(6), uint64(rs1(inst)))
22	uassert.Equal(t, uint64(7), uint64(rs2(inst)))
23	uassert.Equal(t, uint64(0), uint64(funct3(inst)))
24	uassert.Equal(t, uint64(0), uint64(funct7(inst)))
25	uassert.Equal(t, uint64(0x20), uint64(funct7(sub(5, 6, 7))))
26	uassert.Equal(t, uint64(0x01), uint64(funct7(mul(5, 6, 7))))
27}
28
29// Every immediate in the base set is sign extended from its own top bit, and
30// the top bit is in a different place in each of the five formats. These are
31// the boundary values: the largest positive, the value one past it that must
32// come back negative, and all-ones for minus one.
33func TestImmediatesSignExtend(t *testing.T) {
34	// I-type, 12 bits.
35	uassert.Equal(t, uint64(0x7FF), uint64(immI(addi(1, 2, 0x7FF))))
36	uassert.Equal(t, uint64(0xFFFFF800), uint64(immI(addi(1, 2, 0x800))))
37	uassert.Equal(t, uint64(0xFFFFFFFF), uint64(immI(addi(1, 2, 0xFFF))))
38
39	// S-type, 12 bits split across two fields.
40	uassert.Equal(t, uint64(0x7FF), uint64(immS(sw(3, 4, 0x7FF))))
41	uassert.Equal(t, uint64(0xFFFFF800), uint64(immS(sw(3, 4, 0x800))))
42	uassert.Equal(t, uint64(0xFFFFFFFF), uint64(immS(sw(3, 4, 0xFFF))))
43
44	// B-type, 13 bits with bit 0 always zero. -12 is the encoding the
45	// benchmark's loop branch uses, and getting its width wrong is what makes
46	// a backward branch jump forward instead.
47	uassert.Equal(t, uint64(0x7FE), uint64(immB(bne(1, 2, 0x7FE))))
48	uassert.Equal(t, uint64(0xFFFFF000), uint64(immB(bne(1, 2, 0x1000))))
49	uassert.Equal(t, uint64(0xFFFFFFF4), uint64(immB(bne(1, 2, 0x1FF4))))
50
51	// U-type is the only one that is not sign extended, because it is already
52	// the top 20 bits.
53	uassert.Equal(t, uint64(0xDEADB000), uint64(immU(lui(1, 0xDEADB000))))
54
55	// J-type, 21 bits with bit 0 always zero.
56	uassert.Equal(t, uint64(0x7FE), uint64(immJ(jal(1, 0x7FE))))
57	uassert.Equal(t, uint64(0xFFF00000), uint64(immJ(jal(1, 0x100000))))
58	uassert.Equal(t, uint64(0xFFFFFFFE), uint64(immJ(jal(1, 0x1FFFFE))))
59}
60
61func jalr(rd, rs1, imm uint32) uint32 { return iType(imm, rs1, 0x0, rd, opJALR) }