_self_host_sat_trio_test.nx source
↩ module page · 62 lines · 2474 B
1// _self_host_sat_trio_test.nx -- exercise 3 new saturating ops
2// (vssub signed, vsaddu unsigned, vssubu unsigned) end-to-end.
3//
4// Returns 0 on full PASS, case-number on failure (1/2/3).
5
6import "nx_syscalls.nx"
7
8func main() -> i64 {
9 let a_raw: *u8 = sys_mmap(64)
10 let b_raw: *u8 = sys_mmap(64)
11 let o_raw: *u8 = sys_mmap(64)
12 let a: *i64 = a_raw as *i64
13 let b: *i64 = b_raw as *i64
14 let o: *i64 = o_raw as *i64
15
16 // Test 1: vssub signed sat. a = INT16_MIN at lane 0 = -32768
17 // b = 100; -32768 - 100 = -32868, clipped to INT16_MIN = -32768.
18 a[0] = 0x0001000200038000 // lane 0 = 0x8000 = -32768
19 a[1] = 0; a[2] = 0; a[3] = 0
20 b[0] = 0x0001000100010064 // lane 0 = 100
21 b[1] = 0; b[2] = 0; b[3] = 0
22 let dummy1: i64 = __simd_vssub_i16_x16(a as *i64, b as *i64, o as *i64)
23 // Min of output = -32768 (the sat clip), via vreduce_min.
24 let r1: i64 = __simd_vreduce_min_i16_x16(o as *i64)
25 if r1 != -32768 { return 1 }
26
27 // Test 2: vsaddu unsigned sat. a = 50000 + b = 20000 = 70000,
28 // clipped to UINT16_MAX = 65535.
29 // But vreduce_min/max return SIGNED i16. 65535 as i16 = -1.
30 // So vreduce_min(o) for all-65535 = -1.
31 a[0] = 0x0001000100013500 // lane 0 = 0x3500 wait no. Let me redo.
32 // Actually 50000 = 0xC350. 0xC350 doesn't fit in signed i16 (it's
33 // > 32767), so we treat as unsigned u16.
34 a[0] = 0xC350C350C350C350 // 4 lanes of 50000
35 a[1] = 0xC350C350C350C350
36 a[2] = 0xC350C350C350C350
37 a[3] = 0xC350C350C350C350
38 b[0] = 0x4E204E204E204E20 // 4 lanes of 20000 = 0x4E20
39 b[1] = 0x4E204E204E204E20
40 b[2] = 0x4E204E204E204E20
41 b[3] = 0x4E204E204E204E20
42 let dummy2: i64 = __simd_vsaddu_i16_x16(a as *i64, b as *i64, o as *i64)
43 // All output lanes = 65535 = 0xFFFF. Min as signed = -1.
44 let r2: i64 = __simd_vreduce_min_i16_x16(o as *i64)
45 if r2 != -1 { return 2 }
46
47 // Test 3: vssubu unsigned sat. a = 100, b = 1000. Underflow -> 0.
48 a[0] = 0x0064006400640064 // 4 lanes of 100
49 a[1] = 0x0064006400640064
50 a[2] = 0x0064006400640064
51 a[3] = 0x0064006400640064
52 b[0] = 0x03E803E803E803E8 // 4 lanes of 1000
53 b[1] = 0x03E803E803E803E8
54 b[2] = 0x03E803E803E803E8
55 b[3] = 0x03E803E803E803E8
56 let dummy3: i64 = __simd_vssubu_i16_x16(a as *i64, b as *i64, o as *i64)
57 // All lanes clipped to 0.
58 let r3: i64 = __simd_vreduce_max_i16_x16(o as *i64)
59 if r3 != 0 { return 3 }
60
61 return 0
62}