| ... | ... | @@ -42,46 +42,75 @@ pub fn __aeabi_unwind_cpp_pr2() callconv(.C) void { |
| 42 | 42 | unreachable; |
| 43 | 43 | } |
| 44 | 44 | |
| 45 | | pub fn __aeabi_uidivmod(n: u32, d: u32) callconv(.C) extern struct { |
| 46 | | q: u32, |
| 47 | | r: u32, |
| 48 | | } { |
| 49 | | @setRuntimeSafety(is_test); |
| 45 | // The following functions are wrapped in an asm block to ensure the required |
| 46 | // calling convention is always respected |
| 50 | 47 | |
| 51 | | var result: @TypeOf(__aeabi_uidivmod).ReturnType = undefined; |
| 52 | | result.q = __udivmodsi4(n, d, &result.r); |
| 53 | | return result; |
| 48 | pub fn __aeabi_uidivmod() callconv(.Naked) void { |
| 49 | // Divide r0 by r1; the quotient goes in r0, the remainder in r1 |
| 50 | asm volatile ( |
| 51 | \\ push {lr} |
| 52 | \\ sub sp, #4 |
| 53 | \\ mov r2, sp |
| 54 | \\ bl __udivmodsi4 |
| 55 | \\ ldr r1, [sp] |
| 56 | \\ add sp, #4 |
| 57 | \\ pop {pc} |
| 58 | : |
| 59 | : |
| 60 | : "memory" |
| 61 | ); |
| 62 | unreachable; |
| 54 | 63 | } |
| 55 | 64 | |
| 56 | | pub fn __aeabi_uldivmod(n: u64, d: u64) callconv(.C) extern struct { |
| 57 | | q: u64, |
| 58 | | r: u64, |
| 59 | | } { |
| 60 | | @setRuntimeSafety(is_test); |
| 61 | | |
| 62 | | var result: @TypeOf(__aeabi_uldivmod).ReturnType = undefined; |
| 63 | | result.q = __udivmoddi4(n, d, &result.r); |
| 64 | | return result; |
| 65 | pub fn __aeabi_uldivmod() callconv(.Naked) void { |
| 66 | // Divide r1:r0 by r3:r2; the quotient goes in r1:r0, the remainder in r3:r2 |
| 67 | asm volatile ( |
| 68 | \\ push {r4, lr} |
| 69 | \\ sub sp, #16 |
| 70 | \\ add r4, sp, #8 |
| 71 | \\ bl __udivmoddi4 |
| 72 | \\ ldr r3, [sp, #8] |
| 73 | \\ ldr r4, [sp, #12] |
| 74 | \\ add sp, #16 |
| 75 | \\ pop {r4, pc} |
| 76 | : |
| 77 | : |
| 78 | : "memory" |
| 79 | ); |
| 80 | unreachable; |
| 65 | 81 | } |
| 66 | 82 | |
| 67 | | pub fn __aeabi_idivmod(n: i32, d: i32) callconv(.C) extern struct { |
| 68 | | q: i32, |
| 69 | | r: i32, |
| 70 | | } { |
| 71 | | @setRuntimeSafety(is_test); |
| 72 | | |
| 73 | | var result: @TypeOf(__aeabi_idivmod).ReturnType = undefined; |
| 74 | | result.q = __divmodsi4(n, d, &result.r); |
| 75 | | return result; |
| 83 | pub fn __aeabi_idivmod() callconv(.Naked) void { |
| 84 | // Divide r0 by r1; the quotient goes in r0, the remainder in r1 |
| 85 | asm volatile ( |
| 86 | \\ push {lr} |
| 87 | \\ sub sp, #4 |
| 88 | \\ mov r2, sp |
| 89 | \\ bl __divmodsi4 |
| 90 | \\ ldr r1, [sp] |
| 91 | \\ add sp, #4 |
| 92 | \\ pop {pc} |
| 93 | : |
| 94 | : |
| 95 | : "memory" |
| 96 | ); |
| 97 | unreachable; |
| 76 | 98 | } |
| 77 | 99 | |
| 78 | | pub fn __aeabi_ldivmod(n: i64, d: i64) callconv(.C) extern struct { |
| 79 | | q: i64, |
| 80 | | r: i64, |
| 81 | | } { |
| 82 | | @setRuntimeSafety(is_test); |
| 83 | | |
| 84 | | var result: @TypeOf(__aeabi_ldivmod).ReturnType = undefined; |
| 85 | | result.q = __divmoddi4(n, d, &result.r); |
| 86 | | return result; |
| 100 | pub fn __aeabi_ldivmod() callconv(.Naked) void { |
| 101 | // Divide r1:r0 by r3:r2; the quotient goes in r1:r0, the remainder in r3:r2 |
| 102 | asm volatile ( |
| 103 | \\ push {r4, lr} |
| 104 | \\ sub sp, #16 |
| 105 | \\ add r4, sp, #8 |
| 106 | \\ bl __divmoddi4 |
| 107 | \\ ldr r3, [sp, #8] |
| 108 | \\ ldr r4, [sp, #12] |
| 109 | \\ add sp, #16 |
| 110 | \\ pop {r4, pc} |
| 111 | : |
| 112 | : |
| 113 | : "memory" |
| 114 | ); |
| 115 | unreachable; |
| 87 | 116 | } |