| 1 | const std = @import("std"); |
| 2 | const builtin = @import("builtin"); |
| 3 | const arch = builtin.cpu.arch; |
| 4 | const os = builtin.os.tag; |
| 5 | const abi = builtin.abi; |
| 6 | const compiler_rt = @import("../compiler_rt.zig"); |
| 7 | const symbol = compiler_rt.symbol; |
| 8 | |
| 9 | comptime { |
| 10 | if (compiler_rt.want_windows_x86_msvc_abi) { |
| 11 | // Don't let LLVM apply the stdcall name mangling on those MSVC builtins |
| 12 | symbol(&_allrem, "\x01__allrem"); |
| 13 | symbol(&_aullrem, "\x01__aullrem"); |
| 14 | } |
| 15 | } |
| 16 | |
| 17 | pub fn _allrem(a: i64, b: i64) callconv(.{ .x86_stdcall = .{} }) i64 { |
| 18 | const s_a = a >> (64 - 1); |
| 19 | const s_b = b >> (64 - 1); |
| 20 | |
| 21 | const an = (a ^ s_a) -% s_a; |
| 22 | const bn = (b ^ s_b) -% s_b; |
| 23 | |
| 24 | const r = @as(u64, @bitCast(an)) % @as(u64, @bitCast(bn)); |
| 25 | const s = s_a ^ s_b; |
| 26 | return (@as(i64, @bitCast(r)) ^ s) -% s; |
| 27 | } |
| 28 | |
| 29 | pub fn _aullrem() callconv(.naked) void { |
| 30 | @setRuntimeSafety(false); |
| 31 | |
| 32 | // The stack layout is: |
| 33 | // ESP+16 divisor (hi) |
| 34 | // ESP+12 divisor (low) |
| 35 | // ESP+8 dividend (hi) |
| 36 | // ESP+4 dividend (low) |
| 37 | // ESP return address |
| 38 | |
| 39 | asm volatile ( |
| 40 | \\ push %%ebx |
| 41 | \\ mov 0x14(%%esp),%%eax |
| 42 | \\ or %%eax,%%eax |
| 43 | \\ jne 1f |
| 44 | \\ mov 0x10(%%esp),%%ecx |
| 45 | \\ mov 0xc(%%esp),%%eax |
| 46 | \\ xor %%edx,%%edx |
| 47 | \\ div %%ecx |
| 48 | \\ mov 0x8(%%esp),%%eax |
| 49 | \\ div %%ecx |
| 50 | \\ mov %%edx,%%eax |
| 51 | \\ xor %%edx,%%edx |
| 52 | \\ jmp 6f |
| 53 | \\ 1: |
| 54 | \\ mov %%eax,%%ecx |
| 55 | \\ mov 0x10(%%esp),%%ebx |
| 56 | \\ mov 0xc(%%esp),%%edx |
| 57 | \\ mov 0x8(%%esp),%%eax |
| 58 | \\ 2: |
| 59 | \\ shr %%ecx |
| 60 | \\ rcr %%ebx |
| 61 | \\ shr %%edx |
| 62 | \\ rcr %%eax |
| 63 | \\ or %%ecx,%%ecx |
| 64 | \\ jne 2b |
| 65 | \\ div %%ebx |
| 66 | \\ mov %%eax,%%ecx |
| 67 | \\ mull 0x14(%%esp) |
| 68 | \\ xchg %%eax,%%ecx |
| 69 | \\ mull 0x10(%%esp) |
| 70 | \\ add %%ecx,%%edx |
| 71 | \\ jb 3f |
| 72 | \\ cmp 0xc(%%esp),%%edx |
| 73 | \\ ja 3f |
| 74 | \\ jb 4f |
| 75 | \\ cmp 0x8(%%esp),%%eax |
| 76 | \\ jbe 4f |
| 77 | \\ 3: |
| 78 | \\ sub 0x10(%%esp),%%eax |
| 79 | \\ sbb 0x14(%%esp),%%edx |
| 80 | \\ 4: |
| 81 | \\ sub 0x8(%%esp),%%eax |
| 82 | \\ sbb 0xc(%%esp),%%edx |
| 83 | \\ neg %%edx |
| 84 | \\ neg %%eax |
| 85 | \\ sbb $0x0,%%edx |
| 86 | \\ 6: |
| 87 | \\ pop %%ebx |
| 88 | \\ ret $0x10 |
| 89 | ); |
| 90 | } |