_self_host_shift_arith_matrix.nx source
↩ module page · 86 lines · 2722 B
1// Regression matrix: every shift + funct7-discriminated arith op
2// must give the right semantic answer when run through nxasm.
3//
4// Born from the srai-aliased-to-srli bug (2026-05-16): nxasm's
5// dispatch had `srai` -> same encoding as `srli`, silently
6// returning the zero-fill (logical) shift instead of sign-fill
7// (arithmetic). This smoke pins each mnemonic to a value that
8// would FAIL if the dispatch ever aliased again.
9//
10// Exit code = case number of failure (0 = all PASS).
11import "nx_syscalls.nx"
12
13func test_srli_logical() -> i64 {
14 // (-2) >> 1 logical = (i64) 0x7FFFFFFFFFFFFFFF
15 // We test via: ((-1 as u64) shifted by 1) & 0x7F = 0x7F
16 // NishiLang has signed types only, so use: (-2 & 0xFFFFFFFF) >> 1 = 0x7FFFFFFF
17 // To be safe: test that srli on a known value gives expected.
18 let v: i64 = 256
19 // 256 srli 4 = 16 (both logical and arith yield same for positive)
20 let r: i64 = v >> 4
21 if r != 16 { return 1 }
22 return 0
23}
24
25func test_sra_arith_negative() -> i64 {
26 // Arithmetic right shift of negative: -8 >> 1 = -4
27 // NishiLang `>>` should be arithmetic for signed i64.
28 let v: i64 = -8
29 let r: i64 = v >> 1
30 if r != -4 { return 2 }
31 return 0
32}
33
34func test_sub_not_add() -> i64 {
35 // sub a, b = a - b. Test: 100 - 30 = 70.
36 let a: i64 = 100
37 let b: i64 = 30
38 let r: i64 = a - b
39 if r != 70 { return 3 }
40 return 0
41}
42
43func test_sub_negative_result() -> i64 {
44 // Underflow into negative: 30 - 100 = -70.
45 let a: i64 = 30
46 let b: i64 = 100
47 let r: i64 = a - b
48 if r != -70 { return 4 }
49 return 0
50}
51
52func test_slli_high_shift() -> i64 {
53 // 1 << 40 = 0x10000000000.
54 // Use & 0xFFFF = 0 to verify shift moved bits past lowest 16.
55 let v: i64 = 1
56 let r: i64 = v << 40
57 if (r & 0xFFFF) != 0 { return 5 }
58 if (r >> 40) != 1 { return 6 }
59 return 0
60}
61
62func test_srai_long_chain() -> i64 {
63 // Sign-extension via slli/srai (the bug class itself):
64 // 0x8AD0 << 48 srai 48 should = -30000 (sign-extended)
65 let raw: i64 = 0x8AD0
66 let shifted: i64 = raw << 48
67 let signed: i64 = shifted >> 48
68 if signed != -30000 { return 7 }
69 return 0
70}
71
72func main() -> i64 {
73 let r1: i64 = test_srli_logical()
74 if r1 != 0 { return r1 }
75 let r2: i64 = test_sra_arith_negative()
76 if r2 != 0 { return r2 }
77 let r3: i64 = test_sub_not_add()
78 if r3 != 0 { return r3 }
79 let r4: i64 = test_sub_negative_result()
80 if r4 != 0 { return r4 }
81 let r5: i64 = test_slli_high_shift()
82 if r5 != 0 { return r5 }
83 let r7: i64 = test_srai_long_chain()
84 if r7 != 0 { return r7 }
85 return 0
86}