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