int.zig (27737B) - Raw
1 //! Builtin functions that operate on integer types 2 3 const builtin = @import("builtin"); 4 const std = @import("std"); 5 const testing = std.testing; 6 const maxInt = std.math.maxInt; 7 const minInt = std.math.minInt; 8 const arch = builtin.cpu.arch; 9 const common = @import("common.zig"); 10 const udivmod = @import("udivmod.zig").udivmod; 11 const __divti3 = @import("divti3.zig").__divti3; 12 13 pub const panic = common.panic; 14 15 comptime { 16 @export(&__divmodti4, .{ .name = "__divmodti4", .linkage = common.linkage, .visibility = common.visibility }); 17 @export(&__udivmoddi4, .{ .name = "__udivmoddi4", .linkage = common.linkage, .visibility = common.visibility }); 18 @export(&__divmoddi4, .{ .name = "__divmoddi4", .linkage = common.linkage, .visibility = common.visibility }); 19 if (common.want_aeabi) { 20 @export(&__aeabi_idiv, .{ .name = "__aeabi_idiv", .linkage = common.linkage, .visibility = common.visibility }); 21 @export(&__aeabi_uidiv, .{ .name = "__aeabi_uidiv", .linkage = common.linkage, .visibility = common.visibility }); 22 } else { 23 @export(&__divsi3, .{ .name = "__divsi3", .linkage = common.linkage, .visibility = common.visibility }); 24 @export(&__udivsi3, .{ .name = "__udivsi3", .linkage = common.linkage, .visibility = common.visibility }); 25 } 26 @export(&__divdi3, .{ .name = "__divdi3", .linkage = common.linkage, .visibility = common.visibility }); 27 @export(&__udivdi3, .{ .name = "__udivdi3", .linkage = common.linkage, .visibility = common.visibility }); 28 @export(&__modsi3, .{ .name = "__modsi3", .linkage = common.linkage, .visibility = common.visibility }); 29 @export(&__moddi3, .{ .name = "__moddi3", .linkage = common.linkage, .visibility = common.visibility }); 30 @export(&__umodsi3, .{ .name = "__umodsi3", .linkage = common.linkage, .visibility = common.visibility }); 31 @export(&__umoddi3, .{ .name = "__umoddi3", .linkage = common.linkage, .visibility = common.visibility }); 32 @export(&__divmodsi4, .{ .name = "__divmodsi4", .linkage = common.linkage, .visibility = common.visibility }); 33 @export(&__udivmodsi4, .{ .name = "__udivmodsi4", .linkage = common.linkage, .visibility = common.visibility }); 34 } 35 36 pub fn __divmodti4(a: i128, b: i128, rem: *i128) callconv(.c) i128 { 37 const d = __divti3(a, b); 38 rem.* = a -% (d * b); 39 return d; 40 } 41 42 test "test_divmodti4" { 43 const cases = [_][4]i128{ 44 [_]i128{ 0, 1, 0, 0 }, 45 [_]i128{ 0, -1, 0, 0 }, 46 [_]i128{ 2, 1, 2, 0 }, 47 [_]i128{ 2, -1, -2, 0 }, 48 [_]i128{ -2, 1, -2, 0 }, 49 [_]i128{ -2, -1, 2, 0 }, 50 [_]i128{ 7, 5, 1, 2 }, 51 [_]i128{ -7, 5, -1, -2 }, 52 [_]i128{ 19, 5, 3, 4 }, 53 [_]i128{ 19, -5, -3, 4 }, 54 [_]i128{ @bitCast(@as(u128, 0x80000000000000000000000000000000)), 8, @bitCast(@as(u128, 0xf0000000000000000000000000000000)), 0 }, 55 [_]i128{ @bitCast(@as(u128, 0x80000000000000000000000000000007)), 8, @bitCast(@as(u128, 0xf0000000000000000000000000000001)), -1 }, 56 }; 57 58 for (cases) |case| { 59 try test_one_divmodti4(case[0], case[1], case[2], case[3]); 60 } 61 } 62 63 fn test_one_divmodti4(a: i128, b: i128, expected_q: i128, expected_r: i128) !void { 64 var r: i128 = undefined; 65 const q: i128 = __divmodti4(a, b, &r); 66 try testing.expect(q == expected_q and r == expected_r); 67 } 68 69 pub fn __divmoddi4(a: i64, b: i64, rem: *i64) callconv(.c) i64 { 70 const d = __divdi3(a, b); 71 rem.* = a -% (d * b); 72 return d; 73 } 74 75 fn test_one_divmoddi4(a: i64, b: i64, expected_q: i64, expected_r: i64) !void { 76 var r: i64 = undefined; 77 const q: i64 = __divmoddi4(a, b, &r); 78 try testing.expect(q == expected_q and r == expected_r); 79 } 80 81 const cases__divmoddi4 = 82 [_][4]i64{ 83 [_]i64{ 0, 1, 0, 0 }, 84 [_]i64{ 0, -1, 0, 0 }, 85 [_]i64{ 2, 1, 2, 0 }, 86 [_]i64{ 2, -1, -2, 0 }, 87 [_]i64{ -2, 1, -2, 0 }, 88 [_]i64{ -2, -1, 2, 0 }, 89 [_]i64{ 7, 5, 1, 2 }, 90 [_]i64{ -7, 5, -1, -2 }, 91 [_]i64{ 19, 5, 3, 4 }, 92 [_]i64{ 19, -5, -3, 4 }, 93 [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 8, @as(i64, @bitCast(@as(u64, 0xf000000000000000))), 0 }, 94 [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000007))), 8, @as(i64, @bitCast(@as(u64, 0xf000000000000001))), -1 }, 95 }; 96 97 test "test_divmoddi4" { 98 for (cases__divmoddi4) |case| { 99 try test_one_divmoddi4(case[0], case[1], case[2], case[3]); 100 } 101 } 102 103 pub fn __udivmoddi4(a: u64, b: u64, maybe_rem: ?*u64) callconv(.c) u64 { 104 return udivmod(u64, a, b, maybe_rem); 105 } 106 107 test "test_udivmoddi4" { 108 _ = @import("udivmoddi4_test.zig"); 109 } 110 111 pub fn __divdi3(a: i64, b: i64) callconv(.c) i64 { 112 // Set aside the sign of the quotient. 113 const sign: u64 = @bitCast((a ^ b) >> 63); 114 // Take absolute value of a and b via abs(x) = (x^(x >> 63)) - (x >> 63). 115 const abs_a = (a ^ (a >> 63)) -% (a >> 63); 116 const abs_b = (b ^ (b >> 63)) -% (b >> 63); 117 // Unsigned division 118 const res = __udivmoddi4(@bitCast(abs_a), @bitCast(abs_b), null); 119 // Apply sign of quotient to result and return. 120 return @bitCast((res ^ sign) -% sign); 121 } 122 123 test "test_divdi3" { 124 const cases = [_][3]i64{ 125 [_]i64{ 0, 1, 0 }, 126 [_]i64{ 0, -1, 0 }, 127 [_]i64{ 2, 1, 2 }, 128 [_]i64{ 2, -1, -2 }, 129 [_]i64{ -2, 1, -2 }, 130 [_]i64{ -2, -1, 2 }, 131 132 [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 1, @as(i64, @bitCast(@as(u64, 0x8000000000000000))) }, 133 [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), -1, @as(i64, @bitCast(@as(u64, 0x8000000000000000))) }, 134 [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), -2, 0x4000000000000000 }, 135 [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 2, @as(i64, @bitCast(@as(u64, 0xC000000000000000))) }, 136 }; 137 138 for (cases) |case| { 139 try test_one_divdi3(case[0], case[1], case[2]); 140 } 141 } 142 143 fn test_one_divdi3(a: i64, b: i64, expected_q: i64) !void { 144 const q: i64 = __divdi3(a, b); 145 try testing.expect(q == expected_q); 146 } 147 148 pub fn __moddi3(a: i64, b: i64) callconv(.c) i64 { 149 // Take absolute value of a and b via abs(x) = (x^(x >> 63)) - (x >> 63). 150 const abs_a = (a ^ (a >> 63)) -% (a >> 63); 151 const abs_b = (b ^ (b >> 63)) -% (b >> 63); 152 // Unsigned division 153 var r: u64 = undefined; 154 _ = __udivmoddi4(@bitCast(abs_a), @bitCast(abs_b), &r); 155 // Apply the sign of the dividend and return. 156 return (@as(i64, @bitCast(r)) ^ (a >> 63)) -% (a >> 63); 157 } 158 159 test "test_moddi3" { 160 const cases = [_][3]i64{ 161 [_]i64{ 0, 1, 0 }, 162 [_]i64{ 0, -1, 0 }, 163 [_]i64{ 5, 3, 2 }, 164 [_]i64{ 5, -3, 2 }, 165 [_]i64{ -5, 3, -2 }, 166 [_]i64{ -5, -3, -2 }, 167 168 [_]i64{ @bitCast(@as(u64, 0x8000000000000000)), 1, 0 }, 169 [_]i64{ @bitCast(@as(u64, 0x8000000000000000)), -1, 0 }, 170 [_]i64{ @bitCast(@as(u64, 0x8000000000000000)), 2, 0 }, 171 [_]i64{ @bitCast(@as(u64, 0x8000000000000000)), -2, 0 }, 172 [_]i64{ @bitCast(@as(u64, 0x8000000000000000)), 3, -2 }, 173 [_]i64{ @bitCast(@as(u64, 0x8000000000000000)), -3, -2 }, 174 }; 175 176 for (cases) |case| { 177 try test_one_moddi3(case[0], case[1], case[2]); 178 } 179 } 180 181 fn test_one_moddi3(a: i64, b: i64, expected_r: i64) !void { 182 const r: i64 = __moddi3(a, b); 183 try testing.expect(r == expected_r); 184 } 185 186 pub fn __udivdi3(a: u64, b: u64) callconv(.c) u64 { 187 return __udivmoddi4(a, b, null); 188 } 189 190 pub fn __umoddi3(a: u64, b: u64) callconv(.c) u64 { 191 var r: u64 = undefined; 192 _ = __udivmoddi4(a, b, &r); 193 return r; 194 } 195 196 test "test_umoddi3" { 197 try test_one_umoddi3(0, 1, 0); 198 try test_one_umoddi3(2, 1, 0); 199 try test_one_umoddi3(0x8000000000000000, 1, 0x0); 200 try test_one_umoddi3(0x8000000000000000, 2, 0x0); 201 try test_one_umoddi3(0xFFFFFFFFFFFFFFFF, 2, 0x1); 202 } 203 204 fn test_one_umoddi3(a: u64, b: u64, expected_r: u64) !void { 205 const r = __umoddi3(a, b); 206 try testing.expect(r == expected_r); 207 } 208 209 pub fn __divmodsi4(a: i32, b: i32, rem: *i32) callconv(.c) i32 { 210 const d = __divsi3(a, b); 211 rem.* = a -% (d * b); 212 return d; 213 } 214 215 const cases__divmodsi4 = 216 [_][4]i32{ 217 [_]i32{ 0, 1, 0, 0 }, 218 [_]i32{ 0, -1, 0, 0 }, 219 [_]i32{ 2, 1, 2, 0 }, 220 [_]i32{ 2, -1, -2, 0 }, 221 [_]i32{ -2, 1, -2, 0 }, 222 [_]i32{ -2, -1, 2, 0 }, 223 [_]i32{ 7, 5, 1, 2 }, 224 [_]i32{ -7, 5, -1, -2 }, 225 [_]i32{ 19, 5, 3, 4 }, 226 [_]i32{ 19, -5, -3, 4 }, 227 [_]i32{ @bitCast(@as(u32, 0x80000000)), 8, @bitCast(@as(u32, 0xf0000000)), 0 }, 228 [_]i32{ @bitCast(@as(u32, 0x80000007)), 8, @bitCast(@as(u32, 0xf0000001)), -1 }, 229 }; 230 231 fn test_one_divmodsi4(a: i32, b: i32, expected_q: i32, expected_r: i32) !void { 232 var r: i32 = undefined; 233 const q: i32 = __divmodsi4(a, b, &r); 234 try testing.expect(q == expected_q and r == expected_r); 235 } 236 237 test "test_divmodsi4" { 238 for (cases__divmodsi4) |case| { 239 try test_one_divmodsi4(case[0], case[1], case[2], case[3]); 240 } 241 } 242 243 pub fn __udivmodsi4(a: u32, b: u32, rem: *u32) callconv(.c) u32 { 244 const d = __udivsi3(a, b); 245 rem.* = @bitCast(@as(i32, @bitCast(a)) -% (@as(i32, @bitCast(d)) * @as(i32, @bitCast(b)))); 246 return d; 247 } 248 249 pub fn __divsi3(n: i32, d: i32) callconv(.c) i32 { 250 return div_i32(n, d); 251 } 252 253 fn __aeabi_idiv(n: i32, d: i32) callconv(.{ .arm_aapcs = .{} }) i32 { 254 return div_i32(n, d); 255 } 256 257 inline fn div_i32(n: i32, d: i32) i32 { 258 // Set aside the sign of the quotient. 259 const sign: u32 = @bitCast((n ^ d) >> 31); 260 // Take absolute value of a and b via abs(x) = (x^(x >> 31)) - (x >> 31). 261 const abs_n = (n ^ (n >> 31)) -% (n >> 31); 262 const abs_d = (d ^ (d >> 31)) -% (d >> 31); 263 // abs(a) / abs(b) 264 const res = @as(u32, @bitCast(abs_n)) / @as(u32, @bitCast(abs_d)); 265 // Apply sign of quotient to result and return. 266 return @bitCast((res ^ sign) -% sign); 267 } 268 269 test "test_divsi3" { 270 const cases = [_][3]i32{ 271 [_]i32{ 0, 1, 0 }, 272 [_]i32{ 0, -1, 0 }, 273 [_]i32{ 2, 1, 2 }, 274 [_]i32{ 2, -1, -2 }, 275 [_]i32{ -2, 1, -2 }, 276 [_]i32{ -2, -1, 2 }, 277 278 [_]i32{ @bitCast(@as(u32, 0x80000000)), 1, @bitCast(@as(u32, 0x80000000)) }, 279 [_]i32{ @bitCast(@as(u32, 0x80000000)), -1, @bitCast(@as(u32, 0x80000000)) }, 280 [_]i32{ @bitCast(@as(u32, 0x80000000)), -2, 0x40000000 }, 281 [_]i32{ @bitCast(@as(u32, 0x80000000)), 2, @bitCast(@as(u32, 0xC0000000)) }, 282 }; 283 284 for (cases) |case| { 285 try test_one_divsi3(case[0], case[1], case[2]); 286 } 287 } 288 289 fn test_one_divsi3(a: i32, b: i32, expected_q: i32) !void { 290 const q: i32 = __divsi3(a, b); 291 try testing.expect(q == expected_q); 292 } 293 294 pub fn __udivsi3(n: u32, d: u32) callconv(.c) u32 { 295 return div_u32(n, d); 296 } 297 298 fn __aeabi_uidiv(n: u32, d: u32) callconv(.{ .arm_aapcs = .{} }) u32 { 299 return div_u32(n, d); 300 } 301 302 inline fn div_u32(n: u32, d: u32) u32 { 303 const n_uword_bits: c_uint = 32; 304 // special cases 305 if (d == 0) return 0; // ?! 306 if (n == 0) return 0; 307 var sr = @as(c_uint, @bitCast(@as(c_int, @clz(d)) - @as(c_int, @clz(n)))); 308 // 0 <= sr <= n_uword_bits - 1 or sr large 309 if (sr > n_uword_bits - 1) { 310 // d > r 311 return 0; 312 } 313 if (sr == n_uword_bits - 1) { 314 // d == 1 315 return n; 316 } 317 sr += 1; 318 // 1 <= sr <= n_uword_bits - 1 319 // Not a special case 320 var q: u32 = n << @intCast(n_uword_bits - sr); 321 var r: u32 = n >> @intCast(sr); 322 var carry: u32 = 0; 323 while (sr > 0) : (sr -= 1) { 324 // r:q = ((r:q) << 1) | carry 325 r = (r << 1) | (q >> @intCast(n_uword_bits - 1)); 326 q = (q << 1) | carry; 327 // carry = 0; 328 // if (r.all >= d.all) 329 // { 330 // r.all -= d.all; 331 // carry = 1; 332 // } 333 const s = @as(i32, @bitCast(d -% r -% 1)) >> @intCast(n_uword_bits - 1); 334 carry = @intCast(s & 1); 335 r -= d & @as(u32, @bitCast(s)); 336 } 337 q = (q << 1) | carry; 338 return q; 339 } 340 341 test "test_udivsi3" { 342 const cases = [_][3]u32{ 343 [_]u32{ 0x00000000, 0x00000001, 0x00000000 }, 344 [_]u32{ 0x00000000, 0x00000002, 0x00000000 }, 345 [_]u32{ 0x00000000, 0x00000003, 0x00000000 }, 346 [_]u32{ 0x00000000, 0x00000010, 0x00000000 }, 347 [_]u32{ 0x00000000, 0x078644FA, 0x00000000 }, 348 [_]u32{ 0x00000000, 0x0747AE14, 0x00000000 }, 349 [_]u32{ 0x00000000, 0x7FFFFFFF, 0x00000000 }, 350 [_]u32{ 0x00000000, 0x80000000, 0x00000000 }, 351 [_]u32{ 0x00000000, 0xFFFFFFFD, 0x00000000 }, 352 [_]u32{ 0x00000000, 0xFFFFFFFE, 0x00000000 }, 353 [_]u32{ 0x00000000, 0xFFFFFFFF, 0x00000000 }, 354 [_]u32{ 0x00000001, 0x00000001, 0x00000001 }, 355 [_]u32{ 0x00000001, 0x00000002, 0x00000000 }, 356 [_]u32{ 0x00000001, 0x00000003, 0x00000000 }, 357 [_]u32{ 0x00000001, 0x00000010, 0x00000000 }, 358 [_]u32{ 0x00000001, 0x078644FA, 0x00000000 }, 359 [_]u32{ 0x00000001, 0x0747AE14, 0x00000000 }, 360 [_]u32{ 0x00000001, 0x7FFFFFFF, 0x00000000 }, 361 [_]u32{ 0x00000001, 0x80000000, 0x00000000 }, 362 [_]u32{ 0x00000001, 0xFFFFFFFD, 0x00000000 }, 363 [_]u32{ 0x00000001, 0xFFFFFFFE, 0x00000000 }, 364 [_]u32{ 0x00000001, 0xFFFFFFFF, 0x00000000 }, 365 [_]u32{ 0x00000002, 0x00000001, 0x00000002 }, 366 [_]u32{ 0x00000002, 0x00000002, 0x00000001 }, 367 [_]u32{ 0x00000002, 0x00000003, 0x00000000 }, 368 [_]u32{ 0x00000002, 0x00000010, 0x00000000 }, 369 [_]u32{ 0x00000002, 0x078644FA, 0x00000000 }, 370 [_]u32{ 0x00000002, 0x0747AE14, 0x00000000 }, 371 [_]u32{ 0x00000002, 0x7FFFFFFF, 0x00000000 }, 372 [_]u32{ 0x00000002, 0x80000000, 0x00000000 }, 373 [_]u32{ 0x00000002, 0xFFFFFFFD, 0x00000000 }, 374 [_]u32{ 0x00000002, 0xFFFFFFFE, 0x00000000 }, 375 [_]u32{ 0x00000002, 0xFFFFFFFF, 0x00000000 }, 376 [_]u32{ 0x00000003, 0x00000001, 0x00000003 }, 377 [_]u32{ 0x00000003, 0x00000002, 0x00000001 }, 378 [_]u32{ 0x00000003, 0x00000003, 0x00000001 }, 379 [_]u32{ 0x00000003, 0x00000010, 0x00000000 }, 380 [_]u32{ 0x00000003, 0x078644FA, 0x00000000 }, 381 [_]u32{ 0x00000003, 0x0747AE14, 0x00000000 }, 382 [_]u32{ 0x00000003, 0x7FFFFFFF, 0x00000000 }, 383 [_]u32{ 0x00000003, 0x80000000, 0x00000000 }, 384 [_]u32{ 0x00000003, 0xFFFFFFFD, 0x00000000 }, 385 [_]u32{ 0x00000003, 0xFFFFFFFE, 0x00000000 }, 386 [_]u32{ 0x00000003, 0xFFFFFFFF, 0x00000000 }, 387 [_]u32{ 0x00000010, 0x00000001, 0x00000010 }, 388 [_]u32{ 0x00000010, 0x00000002, 0x00000008 }, 389 [_]u32{ 0x00000010, 0x00000003, 0x00000005 }, 390 [_]u32{ 0x00000010, 0x00000010, 0x00000001 }, 391 [_]u32{ 0x00000010, 0x078644FA, 0x00000000 }, 392 [_]u32{ 0x00000010, 0x0747AE14, 0x00000000 }, 393 [_]u32{ 0x00000010, 0x7FFFFFFF, 0x00000000 }, 394 [_]u32{ 0x00000010, 0x80000000, 0x00000000 }, 395 [_]u32{ 0x00000010, 0xFFFFFFFD, 0x00000000 }, 396 [_]u32{ 0x00000010, 0xFFFFFFFE, 0x00000000 }, 397 [_]u32{ 0x00000010, 0xFFFFFFFF, 0x00000000 }, 398 [_]u32{ 0x078644FA, 0x00000001, 0x078644FA }, 399 [_]u32{ 0x078644FA, 0x00000002, 0x03C3227D }, 400 [_]u32{ 0x078644FA, 0x00000003, 0x028216FE }, 401 [_]u32{ 0x078644FA, 0x00000010, 0x0078644F }, 402 [_]u32{ 0x078644FA, 0x078644FA, 0x00000001 }, 403 [_]u32{ 0x078644FA, 0x0747AE14, 0x00000001 }, 404 [_]u32{ 0x078644FA, 0x7FFFFFFF, 0x00000000 }, 405 [_]u32{ 0x078644FA, 0x80000000, 0x00000000 }, 406 [_]u32{ 0x078644FA, 0xFFFFFFFD, 0x00000000 }, 407 [_]u32{ 0x078644FA, 0xFFFFFFFE, 0x00000000 }, 408 [_]u32{ 0x078644FA, 0xFFFFFFFF, 0x00000000 }, 409 [_]u32{ 0x0747AE14, 0x00000001, 0x0747AE14 }, 410 [_]u32{ 0x0747AE14, 0x00000002, 0x03A3D70A }, 411 [_]u32{ 0x0747AE14, 0x00000003, 0x026D3A06 }, 412 [_]u32{ 0x0747AE14, 0x00000010, 0x00747AE1 }, 413 [_]u32{ 0x0747AE14, 0x078644FA, 0x00000000 }, 414 [_]u32{ 0x0747AE14, 0x0747AE14, 0x00000001 }, 415 [_]u32{ 0x0747AE14, 0x7FFFFFFF, 0x00000000 }, 416 [_]u32{ 0x0747AE14, 0x80000000, 0x00000000 }, 417 [_]u32{ 0x0747AE14, 0xFFFFFFFD, 0x00000000 }, 418 [_]u32{ 0x0747AE14, 0xFFFFFFFE, 0x00000000 }, 419 [_]u32{ 0x0747AE14, 0xFFFFFFFF, 0x00000000 }, 420 [_]u32{ 0x7FFFFFFF, 0x00000001, 0x7FFFFFFF }, 421 [_]u32{ 0x7FFFFFFF, 0x00000002, 0x3FFFFFFF }, 422 [_]u32{ 0x7FFFFFFF, 0x00000003, 0x2AAAAAAA }, 423 [_]u32{ 0x7FFFFFFF, 0x00000010, 0x07FFFFFF }, 424 [_]u32{ 0x7FFFFFFF, 0x078644FA, 0x00000011 }, 425 [_]u32{ 0x7FFFFFFF, 0x0747AE14, 0x00000011 }, 426 [_]u32{ 0x7FFFFFFF, 0x7FFFFFFF, 0x00000001 }, 427 [_]u32{ 0x7FFFFFFF, 0x80000000, 0x00000000 }, 428 [_]u32{ 0x7FFFFFFF, 0xFFFFFFFD, 0x00000000 }, 429 [_]u32{ 0x7FFFFFFF, 0xFFFFFFFE, 0x00000000 }, 430 [_]u32{ 0x7FFFFFFF, 0xFFFFFFFF, 0x00000000 }, 431 [_]u32{ 0x80000000, 0x00000001, 0x80000000 }, 432 [_]u32{ 0x80000000, 0x00000002, 0x40000000 }, 433 [_]u32{ 0x80000000, 0x00000003, 0x2AAAAAAA }, 434 [_]u32{ 0x80000000, 0x00000010, 0x08000000 }, 435 [_]u32{ 0x80000000, 0x078644FA, 0x00000011 }, 436 [_]u32{ 0x80000000, 0x0747AE14, 0x00000011 }, 437 [_]u32{ 0x80000000, 0x7FFFFFFF, 0x00000001 }, 438 [_]u32{ 0x80000000, 0x80000000, 0x00000001 }, 439 [_]u32{ 0x80000000, 0xFFFFFFFD, 0x00000000 }, 440 [_]u32{ 0x80000000, 0xFFFFFFFE, 0x00000000 }, 441 [_]u32{ 0x80000000, 0xFFFFFFFF, 0x00000000 }, 442 [_]u32{ 0xFFFFFFFD, 0x00000001, 0xFFFFFFFD }, 443 [_]u32{ 0xFFFFFFFD, 0x00000002, 0x7FFFFFFE }, 444 [_]u32{ 0xFFFFFFFD, 0x00000003, 0x55555554 }, 445 [_]u32{ 0xFFFFFFFD, 0x00000010, 0x0FFFFFFF }, 446 [_]u32{ 0xFFFFFFFD, 0x078644FA, 0x00000022 }, 447 [_]u32{ 0xFFFFFFFD, 0x0747AE14, 0x00000023 }, 448 [_]u32{ 0xFFFFFFFD, 0x7FFFFFFF, 0x00000001 }, 449 [_]u32{ 0xFFFFFFFD, 0x80000000, 0x00000001 }, 450 [_]u32{ 0xFFFFFFFD, 0xFFFFFFFD, 0x00000001 }, 451 [_]u32{ 0xFFFFFFFD, 0xFFFFFFFE, 0x00000000 }, 452 [_]u32{ 0xFFFFFFFD, 0xFFFFFFFF, 0x00000000 }, 453 [_]u32{ 0xFFFFFFFE, 0x00000001, 0xFFFFFFFE }, 454 [_]u32{ 0xFFFFFFFE, 0x00000002, 0x7FFFFFFF }, 455 [_]u32{ 0xFFFFFFFE, 0x00000003, 0x55555554 }, 456 [_]u32{ 0xFFFFFFFE, 0x00000010, 0x0FFFFFFF }, 457 [_]u32{ 0xFFFFFFFE, 0x078644FA, 0x00000022 }, 458 [_]u32{ 0xFFFFFFFE, 0x0747AE14, 0x00000023 }, 459 [_]u32{ 0xFFFFFFFE, 0x7FFFFFFF, 0x00000002 }, 460 [_]u32{ 0xFFFFFFFE, 0x80000000, 0x00000001 }, 461 [_]u32{ 0xFFFFFFFE, 0xFFFFFFFD, 0x00000001 }, 462 [_]u32{ 0xFFFFFFFE, 0xFFFFFFFE, 0x00000001 }, 463 [_]u32{ 0xFFFFFFFE, 0xFFFFFFFF, 0x00000000 }, 464 [_]u32{ 0xFFFFFFFF, 0x00000001, 0xFFFFFFFF }, 465 [_]u32{ 0xFFFFFFFF, 0x00000002, 0x7FFFFFFF }, 466 [_]u32{ 0xFFFFFFFF, 0x00000003, 0x55555555 }, 467 [_]u32{ 0xFFFFFFFF, 0x00000010, 0x0FFFFFFF }, 468 [_]u32{ 0xFFFFFFFF, 0x078644FA, 0x00000022 }, 469 [_]u32{ 0xFFFFFFFF, 0x0747AE14, 0x00000023 }, 470 [_]u32{ 0xFFFFFFFF, 0x7FFFFFFF, 0x00000002 }, 471 [_]u32{ 0xFFFFFFFF, 0x80000000, 0x00000001 }, 472 [_]u32{ 0xFFFFFFFF, 0xFFFFFFFD, 0x00000001 }, 473 [_]u32{ 0xFFFFFFFF, 0xFFFFFFFE, 0x00000001 }, 474 [_]u32{ 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001 }, 475 }; 476 477 for (cases) |case| { 478 try test_one_udivsi3(case[0], case[1], case[2]); 479 } 480 } 481 482 fn test_one_udivsi3(a: u32, b: u32, expected_q: u32) !void { 483 const q: u32 = __udivsi3(a, b); 484 try testing.expect(q == expected_q); 485 } 486 487 pub fn __modsi3(n: i32, d: i32) callconv(.c) i32 { 488 return n -% __divsi3(n, d) * d; 489 } 490 491 test "test_modsi3" { 492 const cases = [_][3]i32{ 493 [_]i32{ 0, 1, 0 }, 494 [_]i32{ 0, -1, 0 }, 495 [_]i32{ 5, 3, 2 }, 496 [_]i32{ 5, -3, 2 }, 497 [_]i32{ -5, 3, -2 }, 498 [_]i32{ -5, -3, -2 }, 499 [_]i32{ @bitCast(@as(u32, @intCast(0x80000000))), 1, 0x0 }, 500 [_]i32{ @bitCast(@as(u32, @intCast(0x80000000))), 2, 0x0 }, 501 [_]i32{ @bitCast(@as(u32, @intCast(0x80000000))), -2, 0x0 }, 502 [_]i32{ @bitCast(@as(u32, @intCast(0x80000000))), 3, -2 }, 503 [_]i32{ @bitCast(@as(u32, @intCast(0x80000000))), -3, -2 }, 504 }; 505 506 for (cases) |case| { 507 try test_one_modsi3(case[0], case[1], case[2]); 508 } 509 } 510 511 fn test_one_modsi3(a: i32, b: i32, expected_r: i32) !void { 512 const r: i32 = __modsi3(a, b); 513 try testing.expect(r == expected_r); 514 } 515 516 pub fn __umodsi3(n: u32, d: u32) callconv(.c) u32 { 517 return n -% __udivsi3(n, d) * d; 518 } 519 520 test "test_umodsi3" { 521 const cases = [_][3]u32{ 522 [_]u32{ 0x00000000, 0x00000001, 0x00000000 }, 523 [_]u32{ 0x00000000, 0x00000002, 0x00000000 }, 524 [_]u32{ 0x00000000, 0x00000003, 0x00000000 }, 525 [_]u32{ 0x00000000, 0x00000010, 0x00000000 }, 526 [_]u32{ 0x00000000, 0x078644FA, 0x00000000 }, 527 [_]u32{ 0x00000000, 0x0747AE14, 0x00000000 }, 528 [_]u32{ 0x00000000, 0x7FFFFFFF, 0x00000000 }, 529 [_]u32{ 0x00000000, 0x80000000, 0x00000000 }, 530 [_]u32{ 0x00000000, 0xFFFFFFFD, 0x00000000 }, 531 [_]u32{ 0x00000000, 0xFFFFFFFE, 0x00000000 }, 532 [_]u32{ 0x00000000, 0xFFFFFFFF, 0x00000000 }, 533 [_]u32{ 0x00000001, 0x00000001, 0x00000000 }, 534 [_]u32{ 0x00000001, 0x00000002, 0x00000001 }, 535 [_]u32{ 0x00000001, 0x00000003, 0x00000001 }, 536 [_]u32{ 0x00000001, 0x00000010, 0x00000001 }, 537 [_]u32{ 0x00000001, 0x078644FA, 0x00000001 }, 538 [_]u32{ 0x00000001, 0x0747AE14, 0x00000001 }, 539 [_]u32{ 0x00000001, 0x7FFFFFFF, 0x00000001 }, 540 [_]u32{ 0x00000001, 0x80000000, 0x00000001 }, 541 [_]u32{ 0x00000001, 0xFFFFFFFD, 0x00000001 }, 542 [_]u32{ 0x00000001, 0xFFFFFFFE, 0x00000001 }, 543 [_]u32{ 0x00000001, 0xFFFFFFFF, 0x00000001 }, 544 [_]u32{ 0x00000002, 0x00000001, 0x00000000 }, 545 [_]u32{ 0x00000002, 0x00000002, 0x00000000 }, 546 [_]u32{ 0x00000002, 0x00000003, 0x00000002 }, 547 [_]u32{ 0x00000002, 0x00000010, 0x00000002 }, 548 [_]u32{ 0x00000002, 0x078644FA, 0x00000002 }, 549 [_]u32{ 0x00000002, 0x0747AE14, 0x00000002 }, 550 [_]u32{ 0x00000002, 0x7FFFFFFF, 0x00000002 }, 551 [_]u32{ 0x00000002, 0x80000000, 0x00000002 }, 552 [_]u32{ 0x00000002, 0xFFFFFFFD, 0x00000002 }, 553 [_]u32{ 0x00000002, 0xFFFFFFFE, 0x00000002 }, 554 [_]u32{ 0x00000002, 0xFFFFFFFF, 0x00000002 }, 555 [_]u32{ 0x00000003, 0x00000001, 0x00000000 }, 556 [_]u32{ 0x00000003, 0x00000002, 0x00000001 }, 557 [_]u32{ 0x00000003, 0x00000003, 0x00000000 }, 558 [_]u32{ 0x00000003, 0x00000010, 0x00000003 }, 559 [_]u32{ 0x00000003, 0x078644FA, 0x00000003 }, 560 [_]u32{ 0x00000003, 0x0747AE14, 0x00000003 }, 561 [_]u32{ 0x00000003, 0x7FFFFFFF, 0x00000003 }, 562 [_]u32{ 0x00000003, 0x80000000, 0x00000003 }, 563 [_]u32{ 0x00000003, 0xFFFFFFFD, 0x00000003 }, 564 [_]u32{ 0x00000003, 0xFFFFFFFE, 0x00000003 }, 565 [_]u32{ 0x00000003, 0xFFFFFFFF, 0x00000003 }, 566 [_]u32{ 0x00000010, 0x00000001, 0x00000000 }, 567 [_]u32{ 0x00000010, 0x00000002, 0x00000000 }, 568 [_]u32{ 0x00000010, 0x00000003, 0x00000001 }, 569 [_]u32{ 0x00000010, 0x00000010, 0x00000000 }, 570 [_]u32{ 0x00000010, 0x078644FA, 0x00000010 }, 571 [_]u32{ 0x00000010, 0x0747AE14, 0x00000010 }, 572 [_]u32{ 0x00000010, 0x7FFFFFFF, 0x00000010 }, 573 [_]u32{ 0x00000010, 0x80000000, 0x00000010 }, 574 [_]u32{ 0x00000010, 0xFFFFFFFD, 0x00000010 }, 575 [_]u32{ 0x00000010, 0xFFFFFFFE, 0x00000010 }, 576 [_]u32{ 0x00000010, 0xFFFFFFFF, 0x00000010 }, 577 [_]u32{ 0x078644FA, 0x00000001, 0x00000000 }, 578 [_]u32{ 0x078644FA, 0x00000002, 0x00000000 }, 579 [_]u32{ 0x078644FA, 0x00000003, 0x00000000 }, 580 [_]u32{ 0x078644FA, 0x00000010, 0x0000000A }, 581 [_]u32{ 0x078644FA, 0x078644FA, 0x00000000 }, 582 [_]u32{ 0x078644FA, 0x0747AE14, 0x003E96E6 }, 583 [_]u32{ 0x078644FA, 0x7FFFFFFF, 0x078644FA }, 584 [_]u32{ 0x078644FA, 0x80000000, 0x078644FA }, 585 [_]u32{ 0x078644FA, 0xFFFFFFFD, 0x078644FA }, 586 [_]u32{ 0x078644FA, 0xFFFFFFFE, 0x078644FA }, 587 [_]u32{ 0x078644FA, 0xFFFFFFFF, 0x078644FA }, 588 [_]u32{ 0x0747AE14, 0x00000001, 0x00000000 }, 589 [_]u32{ 0x0747AE14, 0x00000002, 0x00000000 }, 590 [_]u32{ 0x0747AE14, 0x00000003, 0x00000002 }, 591 [_]u32{ 0x0747AE14, 0x00000010, 0x00000004 }, 592 [_]u32{ 0x0747AE14, 0x078644FA, 0x0747AE14 }, 593 [_]u32{ 0x0747AE14, 0x0747AE14, 0x00000000 }, 594 [_]u32{ 0x0747AE14, 0x7FFFFFFF, 0x0747AE14 }, 595 [_]u32{ 0x0747AE14, 0x80000000, 0x0747AE14 }, 596 [_]u32{ 0x0747AE14, 0xFFFFFFFD, 0x0747AE14 }, 597 [_]u32{ 0x0747AE14, 0xFFFFFFFE, 0x0747AE14 }, 598 [_]u32{ 0x0747AE14, 0xFFFFFFFF, 0x0747AE14 }, 599 [_]u32{ 0x7FFFFFFF, 0x00000001, 0x00000000 }, 600 [_]u32{ 0x7FFFFFFF, 0x00000002, 0x00000001 }, 601 [_]u32{ 0x7FFFFFFF, 0x00000003, 0x00000001 }, 602 [_]u32{ 0x7FFFFFFF, 0x00000010, 0x0000000F }, 603 [_]u32{ 0x7FFFFFFF, 0x078644FA, 0x00156B65 }, 604 [_]u32{ 0x7FFFFFFF, 0x0747AE14, 0x043D70AB }, 605 [_]u32{ 0x7FFFFFFF, 0x7FFFFFFF, 0x00000000 }, 606 [_]u32{ 0x7FFFFFFF, 0x80000000, 0x7FFFFFFF }, 607 [_]u32{ 0x7FFFFFFF, 0xFFFFFFFD, 0x7FFFFFFF }, 608 [_]u32{ 0x7FFFFFFF, 0xFFFFFFFE, 0x7FFFFFFF }, 609 [_]u32{ 0x7FFFFFFF, 0xFFFFFFFF, 0x7FFFFFFF }, 610 [_]u32{ 0x80000000, 0x00000001, 0x00000000 }, 611 [_]u32{ 0x80000000, 0x00000002, 0x00000000 }, 612 [_]u32{ 0x80000000, 0x00000003, 0x00000002 }, 613 [_]u32{ 0x80000000, 0x00000010, 0x00000000 }, 614 [_]u32{ 0x80000000, 0x078644FA, 0x00156B66 }, 615 [_]u32{ 0x80000000, 0x0747AE14, 0x043D70AC }, 616 [_]u32{ 0x80000000, 0x7FFFFFFF, 0x00000001 }, 617 [_]u32{ 0x80000000, 0x80000000, 0x00000000 }, 618 [_]u32{ 0x80000000, 0xFFFFFFFD, 0x80000000 }, 619 [_]u32{ 0x80000000, 0xFFFFFFFE, 0x80000000 }, 620 [_]u32{ 0x80000000, 0xFFFFFFFF, 0x80000000 }, 621 [_]u32{ 0xFFFFFFFD, 0x00000001, 0x00000000 }, 622 [_]u32{ 0xFFFFFFFD, 0x00000002, 0x00000001 }, 623 [_]u32{ 0xFFFFFFFD, 0x00000003, 0x00000001 }, 624 [_]u32{ 0xFFFFFFFD, 0x00000010, 0x0000000D }, 625 [_]u32{ 0xFFFFFFFD, 0x078644FA, 0x002AD6C9 }, 626 [_]u32{ 0xFFFFFFFD, 0x0747AE14, 0x01333341 }, 627 [_]u32{ 0xFFFFFFFD, 0x7FFFFFFF, 0x7FFFFFFE }, 628 [_]u32{ 0xFFFFFFFD, 0x80000000, 0x7FFFFFFD }, 629 [_]u32{ 0xFFFFFFFD, 0xFFFFFFFD, 0x00000000 }, 630 [_]u32{ 0xFFFFFFFD, 0xFFFFFFFE, 0xFFFFFFFD }, 631 [_]u32{ 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFD }, 632 [_]u32{ 0xFFFFFFFE, 0x00000001, 0x00000000 }, 633 [_]u32{ 0xFFFFFFFE, 0x00000002, 0x00000000 }, 634 [_]u32{ 0xFFFFFFFE, 0x00000003, 0x00000002 }, 635 [_]u32{ 0xFFFFFFFE, 0x00000010, 0x0000000E }, 636 [_]u32{ 0xFFFFFFFE, 0x078644FA, 0x002AD6CA }, 637 [_]u32{ 0xFFFFFFFE, 0x0747AE14, 0x01333342 }, 638 [_]u32{ 0xFFFFFFFE, 0x7FFFFFFF, 0x00000000 }, 639 [_]u32{ 0xFFFFFFFE, 0x80000000, 0x7FFFFFFE }, 640 [_]u32{ 0xFFFFFFFE, 0xFFFFFFFD, 0x00000001 }, 641 [_]u32{ 0xFFFFFFFE, 0xFFFFFFFE, 0x00000000 }, 642 [_]u32{ 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFE }, 643 [_]u32{ 0xFFFFFFFF, 0x00000001, 0x00000000 }, 644 [_]u32{ 0xFFFFFFFF, 0x00000002, 0x00000001 }, 645 [_]u32{ 0xFFFFFFFF, 0x00000003, 0x00000000 }, 646 [_]u32{ 0xFFFFFFFF, 0x00000010, 0x0000000F }, 647 [_]u32{ 0xFFFFFFFF, 0x078644FA, 0x002AD6CB }, 648 [_]u32{ 0xFFFFFFFF, 0x0747AE14, 0x01333343 }, 649 [_]u32{ 0xFFFFFFFF, 0x7FFFFFFF, 0x00000001 }, 650 [_]u32{ 0xFFFFFFFF, 0x80000000, 0x7FFFFFFF }, 651 [_]u32{ 0xFFFFFFFF, 0xFFFFFFFD, 0x00000002 }, 652 [_]u32{ 0xFFFFFFFF, 0xFFFFFFFE, 0x00000001 }, 653 [_]u32{ 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000 }, 654 }; 655 656 for (cases) |case| { 657 try test_one_umodsi3(case[0], case[1], case[2]); 658 } 659 } 660 661 fn test_one_umodsi3(a: u32, b: u32, expected_r: u32) !void { 662 const r: u32 = __umodsi3(a, b); 663 try testing.expect(r == expected_r); 664 }