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

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

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) }