rvv_regname_test.nx source
↩ module page · 107 lines · 3928 B
1// rvv_regname_test.nx -- reg_name + vbinop lowering dispatch.
2//
3// Exercises the RVV branch added to reg_name() AND the vadd.vv /
4// vfadd.vv emission from rv_emit_vbinop. Full vector codegen lands
5// when the IR + allocator are wired end-to-end; for now this
6// confirms the naming + mnemonic surface is correct.
7
8import "syscalls.nx"
9import "types.nx"
10import "ir.nx"
11import "outbuf.nx"
12import "regalloc.nx"
13import "riscv.nx"
14
15func buf_contains(buf: *u8, n: i64, needle: *u8) -> i64 {
16 var needle_len: i64 = 0
17 while needle[needle_len] != 0 { needle_len = needle_len + 1 }
18 if needle_len == 0 { return 1 }
19 var i: i64 = 0
20 while i + needle_len <= n {
21 var j: i64 = 0
22 var hit: i64 = 1
23 while j < needle_len {
24 if buf[i + j] != needle[j] { hit = 0; j = needle_len }
25 j = j + 1
26 }
27 if hit == 1 { return 1 }
28 i = i + 1
29 }
30 return 0
31}
32
33func main() -> i64 {
34 // v0 at index 300
35 let o0: *OutBuf = out_new(32)
36 reg_name(o0, 300)
37 if o0.pos != 2 { return __syscall(93, 10, 0, 0, 0, 0, 0) }
38 if o0.buf[0] != 0x76 { return __syscall(93, 11, 0, 0, 0, 0, 0) } // 'v'
39 if o0.buf[1] != 0x30 { return __syscall(93, 12, 0, 0, 0, 0, 0) } // '0'
40
41 // v7 at index 307
42 let o1: *OutBuf = out_new(32)
43 reg_name(o1, 307)
44 if o1.buf[0] != 0x76 { return __syscall(93, 20, 0, 0, 0, 0, 0) }
45 if o1.buf[1] != 0x37 { return __syscall(93, 21, 0, 0, 0, 0, 0) } // '7'
46
47 // v31 at index 331
48 let o2: *OutBuf = out_new(32)
49 reg_name(o2, 331)
50 if o2.buf[0] != 0x76 { return __syscall(93, 30, 0, 0, 0, 0, 0) }
51 if o2.buf[1] != 0x33 { return __syscall(93, 31, 0, 0, 0, 0, 0) } // '3'
52 if o2.buf[2] != 0x31 { return __syscall(93, 32, 0, 0, 0, 0, 0) } // '1'
53
54 // is_vec_reg discriminator
55 if is_vec_reg(299) != 0 { return __syscall(93, 40, 0, 0, 0, 0, 0) }
56 if is_vec_reg(300) != 1 { return __syscall(93, 41, 0, 0, 0, 0, 0) }
57 if is_vec_reg(331) != 1 { return __syscall(93, 42, 0, 0, 0, 0, 0) }
58 // fs-regs (200..211) must NOT register as vec.
59 if is_vec_reg(200) != 0 { return __syscall(93, 43, 0, 0, 0, 0, 0) }
60
61 // Mnemonic dispatch sanity.
62 let m1: *OutBuf = out_new(64)
63 emit_vbinop_mnem(m1, OP_VADD)
64 if buf_contains(m1.buf, m1.pos, "vadd.vv" as *u8) != 1 {
65 return __syscall(93, 50, 0, 0, 0, 0, 0)
66 }
67 let m2: *OutBuf = out_new(64)
68 emit_vbinop_mnem(m2, OP_VFMUL)
69 if buf_contains(m2.buf, m2.pos, "vfmul.vv" as *u8) != 1 {
70 return __syscall(93, 51, 0, 0, 0, 0, 0)
71 }
72
73 // Full vbinop lowering: build a 3-value FADD-style IR with
74 // v4/v5/v6 homing and check the asm output contains
75 // 'vadd.vv v6, v4, v5'.
76 let m_raw: *u8 = sys_mmap(256)
77 let mm: *Module = m_raw as *Module
78 mm.name = "vtest" as *u8
79 mm.functions = 0 as *Function
80 mm.n_functions = 0
81 let f: *Function = ir_function_new(mm, "vadd_demo" as *u8, 9, ir_type_i64())
82 let b: *BasicBlock = ir_block_new(f)
83 let v0: i64 = alloc_value(f, VK_PARAM, ir_type_i64())
84 let v1: i64 = alloc_value(f, VK_PARAM, ir_type_i64())
85 let rid: i64 = ir_emit_binop(b, OP_VADD, v0, v1, ir_type_i64())
86 let add: *Instr = b.tail
87
88 let locs_raw: *u8 = sys_mmap(256)
89 let locs: *ValueLoc = locs_raw as *ValueLoc
90 let l0: *ValueLoc = loc_at(locs, v0)
91 l0.kind = VL_REGISTER
92 l0.idx = 304 // v4
93 let l1: *ValueLoc = loc_at(locs, v1)
94 l1.kind = VL_REGISTER
95 l1.idx = 305 // v5
96 let lr: *ValueLoc = loc_at(locs, rid)
97 lr.kind = VL_REGISTER
98 lr.idx = 306 // v6
99
100 let o_em: *OutBuf = out_new(256)
101 rv_emit_vbinop(f, locs, o_em, add)
102 if buf_contains(o_em.buf, o_em.pos, "vadd.vv v6, v4, v5" as *u8) != 1 {
103 return __syscall(93, 60, 0, 0, 0, 0, 0)
104 }
105
106 return 0
107}