code wiki / (root) / _self_host_shift_arith_matrix.nx

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