| ... | @@ -154,6 +154,109 @@ test "saturating subtraction 128bit" { | ... | @@ -154,6 +154,109 @@ test "saturating subtraction 128bit" { |
| 154 | try comptime S.doTheTest(); | 154 | try comptime S.doTheTest(); |
| 155 | } | 155 | } |
| 156 | | 156 | |
| | 157 | fn testSatMul(comptime T: type, a: T, b: T, expected: T) !void { |
| | 158 | const res: T = a *| b; |
| | 159 | try expect(res == expected); |
| | 160 | } |
| | 161 | |
| | 162 | test "saturating multiplication <= 32 bits" { |
| | 163 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| | 164 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| | 165 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| | 166 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| | 167 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; |
| | 168 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| | 169 | |
| | 170 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .wasm32) { |
| | 171 | // https://github.com/ziglang/zig/issues/9660 |
| | 172 | return error.SkipZigTest; |
| | 173 | } |
| | 174 | |
| | 175 | try testSatMul(u8, 0, maxInt(u8), 0); |
| | 176 | try testSatMul(u8, 1 << 7, 1 << 7, maxInt(u8)); |
| | 177 | try testSatMul(u8, maxInt(u8) - 1, 2, maxInt(u8)); |
| | 178 | try testSatMul(u8, 1 << 4, 1 << 4, maxInt(u8)); |
| | 179 | try testSatMul(u8, 1 << 4, 1 << 3, 1 << 7); |
| | 180 | try testSatMul(u8, 1 << 5, 1 << 3, maxInt(u8)); |
| | 181 | try testSatMul(u8, 10, 20, 200); |
| | 182 | |
| | 183 | try testSatMul(u16, 0, maxInt(u16), 0); |
| | 184 | try testSatMul(u16, 1 << 15, 1 << 15, maxInt(u16)); |
| | 185 | try testSatMul(u16, maxInt(u16) - 1, 2, maxInt(u16)); |
| | 186 | try testSatMul(u16, 1 << 8, 1 << 8, maxInt(u16)); |
| | 187 | try testSatMul(u16, 1 << 12, 1 << 3, 1 << 15); |
| | 188 | try testSatMul(u16, 1 << 13, 1 << 3, maxInt(u16)); |
| | 189 | try testSatMul(u16, 10, 20, 200); |
| | 190 | |
| | 191 | try testSatMul(u32, 0, maxInt(u32), 0); |
| | 192 | try testSatMul(u32, 1 << 31, 1 << 31, maxInt(u32)); |
| | 193 | try testSatMul(u32, maxInt(u32) - 1, 2, maxInt(u32)); |
| | 194 | try testSatMul(u32, 1 << 16, 1 << 16, maxInt(u32)); |
| | 195 | try testSatMul(u32, 1 << 28, 1 << 3, 1 << 31); |
| | 196 | try testSatMul(u32, 1 << 29, 1 << 3, maxInt(u32)); |
| | 197 | try testSatMul(u32, 10, 20, 200); |
| | 198 | |
| | 199 | try testSatMul(i8, 0, maxInt(i8), 0); |
| | 200 | try testSatMul(i8, 0, minInt(i8), 0); |
| | 201 | try testSatMul(i8, 1 << 6, 1 << 6, maxInt(i8)); |
| | 202 | try testSatMul(i8, minInt(i8), minInt(i8), maxInt(i8)); |
| | 203 | try testSatMul(i8, maxInt(i8) - 1, 2, maxInt(i8)); |
| | 204 | try testSatMul(i8, minInt(i8) + 1, 2, minInt(i8)); |
| | 205 | try testSatMul(i8, 1 << 4, 1 << 4, maxInt(i8)); |
| | 206 | try testSatMul(i8, minInt(i4), 1 << 4, minInt(i8)); |
| | 207 | try testSatMul(i8, 10, 12, 120); |
| | 208 | try testSatMul(i8, 10, -12, -120); |
| | 209 | |
| | 210 | try testSatMul(i16, 0, maxInt(i16), 0); |
| | 211 | try testSatMul(i16, 0, minInt(i16), 0); |
| | 212 | try testSatMul(i16, 1 << 14, 1 << 14, maxInt(i16)); |
| | 213 | try testSatMul(i16, minInt(i16), minInt(i16), maxInt(i16)); |
| | 214 | try testSatMul(i16, maxInt(i16) - 1, 2, maxInt(i16)); |
| | 215 | try testSatMul(i16, minInt(i16) + 1, 2, minInt(i16)); |
| | 216 | try testSatMul(i16, 1 << 8, 1 << 8, maxInt(i16)); |
| | 217 | try testSatMul(i16, minInt(i8), 1 << 8, minInt(i16)); |
| | 218 | try testSatMul(i16, 10, 12, 120); |
| | 219 | try testSatMul(i16, 10, -12, -120); |
| | 220 | |
| | 221 | try testSatMul(i32, 0, maxInt(i32), 0); |
| | 222 | try testSatMul(i32, 0, minInt(i32), 0); |
| | 223 | try testSatMul(i32, 1 << 30, 1 << 30, maxInt(i32)); |
| | 224 | try testSatMul(i32, minInt(i32), minInt(i32), maxInt(i32)); |
| | 225 | try testSatMul(i32, maxInt(i32) - 1, 2, maxInt(i32)); |
| | 226 | try testSatMul(i32, minInt(i32) + 1, 2, minInt(i32)); |
| | 227 | try testSatMul(i32, 1 << 16, 1 << 16, maxInt(i32)); |
| | 228 | try testSatMul(i32, minInt(i16), 1 << 16, minInt(i32)); |
| | 229 | try testSatMul(i32, 10, 12, 120); |
| | 230 | try testSatMul(i32, 10, -12, -120); |
| | 231 | } |
| | 232 | |
| | 233 | // TODO: remove this test, integrate into general test |
| | 234 | test "saturating mul i64, i128, wasm only" { |
| | 235 | if (builtin.zig_backend != .stage2_wasm) return error.SkipZigTest; |
| | 236 | |
| | 237 | try testSatMul(i64, 0, maxInt(i64), 0); |
| | 238 | try testSatMul(i64, 0, minInt(i64), 0); |
| | 239 | try testSatMul(i64, 1 << 62, 1 << 62, maxInt(i64)); |
| | 240 | try testSatMul(i64, minInt(i64), minInt(i64), maxInt(i64)); |
| | 241 | try testSatMul(i64, maxInt(i64) - 1, 2, maxInt(i64)); |
| | 242 | try testSatMul(i64, minInt(i64) + 1, 2, minInt(i64)); |
| | 243 | try testSatMul(i64, 1 << 32, 1 << 32, maxInt(i64)); |
| | 244 | try testSatMul(i64, minInt(i32), 1 << 32, minInt(i64)); |
| | 245 | try testSatMul(i64, 10, 12, 120); |
| | 246 | try testSatMul(i64, 10, -12, -120); |
| | 247 | |
| | 248 | try testSatMul(i128, 0, maxInt(i128), 0); |
| | 249 | try testSatMul(i128, 0, minInt(i128), 0); |
| | 250 | try testSatMul(i128, 1 << 126, 1 << 126, maxInt(i128)); |
| | 251 | try testSatMul(i128, minInt(i128), minInt(i128), maxInt(i128)); |
| | 252 | try testSatMul(i128, maxInt(i128) - 1, 2, maxInt(i128)); |
| | 253 | try testSatMul(i128, minInt(i128) + 1, 2, minInt(i128)); |
| | 254 | try testSatMul(i128, 1 << 64, 1 << 64, maxInt(i128)); |
| | 255 | try testSatMul(i128, minInt(i64), 1 << 64, minInt(i128)); |
| | 256 | try testSatMul(i128, 10, 12, 120); |
| | 257 | try testSatMul(i128, 10, -12, -120); |
| | 258 | } |
| | 259 | |
| 157 | test "saturating multiplication" { | 260 | test "saturating multiplication" { |
| 158 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 261 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 159 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 262 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| ... | @@ -183,23 +286,15 @@ test "saturating multiplication" { | ... | @@ -183,23 +286,15 @@ test "saturating multiplication" { |
| 183 | try testSatMul(u8, 2, 255, 255); | 286 | try testSatMul(u8, 2, 255, 255); |
| 184 | try testSatMul(u128, maxInt(u128), maxInt(u128), maxInt(u128)); | 287 | try testSatMul(u128, maxInt(u128), maxInt(u128), maxInt(u128)); |
| 185 | } | 288 | } |
| 186 | | | |
| 187 | fn testSatMul(comptime T: type, lhs: T, rhs: T, expected: T) !void { | | |
| 188 | try expect((lhs *| rhs) == expected); | | |
| 189 | | | |
| 190 | var x = lhs; | | |
| 191 | x *|= rhs; | | |
| 192 | try expect(x == expected); | | |
| 193 | } | | |
| 194 | }; | 289 | }; |
| 195 | | 290 | |
| 196 | try S.doTheTest(); | 291 | try S.doTheTest(); |
| 197 | try comptime S.doTheTest(); | 292 | try comptime S.doTheTest(); |
| 198 | | 293 | |
| 199 | try comptime S.testSatMul(comptime_int, 0, 0, 0); | 294 | try comptime testSatMul(comptime_int, 0, 0, 0); |
| 200 | try comptime S.testSatMul(comptime_int, 3, 2, 6); | 295 | try comptime testSatMul(comptime_int, 3, 2, 6); |
| 201 | try comptime S.testSatMul(comptime_int, 651075816498665588400716961808225370057, 468229432685078038144554201546849378455, 304852860194144160265083087140337419215516305999637969803722975979232817921935); | 296 | try comptime testSatMul(comptime_int, 651075816498665588400716961808225370057, 468229432685078038144554201546849378455, 304852860194144160265083087140337419215516305999637969803722975979232817921935); |
| 202 | try comptime S.testSatMul(comptime_int, 7, -593423721213448152027139550640105366508, -4153966048494137064189976854480737565556); | 297 | try comptime testSatMul(comptime_int, 7, -593423721213448152027139550640105366508, -4153966048494137064189976854480737565556); |
| 203 | } | 298 | } |
| 204 | | 299 | |
| 205 | test "saturating shift-left" { | 300 | test "saturating shift-left" { |