code wiki / (root) / _self_host_sat_trio_test.nx

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