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