core/cortex-m[0]: Move core functions assembly files to third_party

The code originally comes from libaeabi-cortexm0. It is unclear
which exact git commit the code comes from, but since we have used
it without issue for 5 years, it is reliable, and a refresh is
probably not required at this stage.

BRANCH=none
BUG=chromium:884905
TEST=make buildall -j, which also include basic tests.

Change-Id: I910c1c4e6a46b2f0fe8b7a429f1b6f0f50c2dc21
Signed-off-by: Nicolas Boichat <drinkcat@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1599762
Reviewed-by: Aseda Aboagye <aaboagye@chromium.org>
This commit is contained in:
Nicolas Boichat 2019-05-09 14:15:36 +09:00 committed by Commit Bot
parent c830ecc1f7
commit 509f29d6ce
14 changed files with 801 additions and 765 deletions

View File

@ -1,86 +0,0 @@
/* Runtime ABI for the ARM Cortex-M
* ldivmod.S: signed 64 bit division (quotient and remainder)
*
* Copyright (c) 2012 Jörg Mische <bobbl@gmx.de>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
.syntax unified
.text
.code 16
@ {long long quotient, long long remainder}
@ __aeabi_ldivmod(long long numerator, long long denominator)
@
@ Divide r1:r0 by r3:r2 and return the quotient in r1:r0 and the remainder in
@ r3:r2 (all signed)
@
.thumb_func
.section .text.__aeabi_ldivmod
.global __aeabi_ldivmod
__aeabi_ldivmod:
cmp r1, #0
bge L_num_pos
push {r4, lr}
movs r4, #0 @ num = -num
rsbs r0, r0, #0
sbcs r4, r1
mov r1, r4
cmp r3, #0
bge L_neg_both
movs r4, #0 @ den = -den
rsbs r2, r2, #0
sbcs r4, r3
mov r3, r4
bl __aeabi_uldivmod
movs r4, #0 @ rem = -rem
rsbs r2, r2, #0
sbcs r4, r3
mov r3, r4
pop {r4, pc}
L_neg_both:
bl __aeabi_uldivmod
movs r4, #0 @ quot = -quot
rsbs r0, r0, #0
sbcs r4, r1
mov r1, r4
movs r4, #0 @ rem = -rem
rsbs r2, r2, #0
sbcs r4, r3
mov r3, r4
pop {r4, pc}
L_num_pos:
cmp r3, #0
bge __aeabi_uldivmod
push {r4, lr}
movs r4, #0 @ den = -den
rsbs r2, r2, #0
sbcs r4, r3
mov r3, r4
bl __aeabi_uldivmod
movs r4, #0 @ quot = -quot
rsbs r0, r0, #0
sbcs r4, r1
mov r1, r4
pop {r4, pc}

1
core/cortex-m/ldivmod.S Symbolic link
View File

@ -0,0 +1 @@
../../third_party/libaeabi-cortexm0/core/cortex-m/ldivmod.S

View File

@ -1,179 +0,0 @@
/* Runtime ABI for the ARM Cortex-M
* uldivmod.S: unsigned 64 bit division
*
* Copyright (c) 2012 Jörg Mische <bobbl@gmx.de>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "software_panic.h"
.syntax unified
.text
.code 16
@ {unsigned long long quotient, unsigned long long remainder}
@ __aeabi_uldivmod(unsigned long long numerator, unsigned long long denominator)
@
@ Divide r1:r0 by r3:r2 and return the quotient in r1:r0 and the remainder
@ in r3:r2 (all unsigned)
@
.thumb_func
.section .text.__aeabi_uldivmod
.global __aeabi_uldivmod
__aeabi_uldivmod:
cmp r3, #0
bne L_large_denom
cmp r2, #0
beq L_divison_by_0
cmp r1, #0
beq L_fallback_32bits
@ case 1: num >= 2^32 and denom < 2^32
@ Result might be > 2^32, therefore we first calculate the upper 32
@ bits of the result. It is done similar to the calculation of the
@ lower 32 bits, but with a denominator that is shifted by 32.
@ Hence the lower 32 bits of the denominator are always 0 and the
@ costly 64 bit shift and sub operations can be replaced by cheap 32
@ bit operations.
push {r4, r5, r6, r7, lr}
@ shift left the denominator until it is greater than the numerator
@ denom(r7:r6) = r3:r2 << 32
@ TODO(crosbug.com/p/36128): Loops like this (which occur in several
@ places in this file) are inefficent in ARMv6-m.
movs r5, #1 @ bitmask
adds r7, r2, #0 @ dont shift if denominator would overflow
bmi L_upper_result
cmp r1, r7
blo L_upper_result
L_denom_shift_loop1:
lsl r5, #1
lsls r7, #1
bmi L_upper_result @ dont shift if overflow
cmp r1, r7
bhs L_denom_shift_loop1
L_upper_result:
mov r3, r1
mov r2, r0
mov r1, #0 @ upper result = 0
mov r6, #0
L_sub_loop1:
orr r1, r5 @ result(r7:r6) |= bitmask(r5)
subs r2, r6 @ num -= denom
sbcs r3, r7
bhs L_done_sub1
eor r1, r5 @ undo add mask
adds r2, r6 @ undo subtract
adc r3, r3, r7
L_done_sub1:
lsrs r7, #1 @ denom(r7:r6) >>= 1
rrx r6, r6
lsrs r5, #1 @ bitmask(r5) >>= 1
bne L_sub_loop1
rrx r5, r5
b L_lower_result
@ case 2: division by 0
@ call __aeabi_ldiv0
L_divison_by_0:
b __aeabi_ldiv0
@ case 3: num < 2^32 and denom < 2^32
@ fallback to 32 bit division
L_fallback_32bits:
mov r1, r0
udiv r0, r0, r2 @ r0 = quotient
mul r3, r0, r2 @ r3 = quotient * divisor
sub r2, r1, r3 @ r2 = remainder
mov r1, #0
mov r3, #0
bx lr
@ case 4: denom >= 2^32
@ result is smaller than 2^32
L_large_denom:
push {r4, r5, r6, r7, lr}
mov r7, r3
mov r6, r2
mov r3, r1
mov r2, r0
@ Shift left the denominator until it is greater than the numerator
mov r1, #0 @ high word of result is 0
mov r5, #1 @ bitmask
adds r7, #0 @ dont shift if denominator would overflow
bmi L_lower_result
cmp r3, r7
blo L_lower_result
L_denom_shift_loop4:
lsl r5, #1
lsls r6, #1 @ denom(r7:r6) <<= 1
adcs r7, r7
bmi L_lower_result @ dont shift if overflow
cmp r3, r7
bhs L_denom_shift_loop4
L_lower_result:
movs r0, #0
L_sub_loop4:
orr r0, r5 @ result(r1:r0) |= bitmask(r5)
subs r2, r6 @ numerator -= denom
sbcs r3, r7
bhs L_done_sub4
eor r0, r5 @ undo add mask
adds r2, r6 @ undo subtract
adc r3, r3, r7
L_done_sub4:
lsrs r7, #1 @ denom(r7:r6) >>= 1
rrx r6, r6
lsrs r5, #1 @ bitmask(r5) >>= 1
bne L_sub_loop4
pop {r4, r5, r6, r7, pc}
__aeabi_ldiv0:
ldr SOFTWARE_PANIC_REASON_REG, =PANIC_SW_DIV_ZERO
bl exception_panic

1
core/cortex-m/uldivmod.S Symbolic link
View File

@ -0,0 +1 @@
../../third_party/libaeabi-cortexm0/core/cortex-m/uldivmod.S

View File

@ -1,166 +0,0 @@
/* Runtime ABI for the ARM Cortex-M0
* idiv.S: signed 32 bit division (only quotient)
* idivmod.S: signed 32 bit division (quotient and remainder)
* uidivmod.S: unsigned 32 bit division
*
* Copyright (c) 2012 Jörg Mische <bobbl@gmx.de>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "software_panic.h"
.syntax unified
.text
.thumb
.cpu cortex-m0
@ int __aeabi_idiv(int num:r0, int denom:r1)
@
@ Divide r0 by r1 and return quotient in r0 (all signed).
@ Use __aeabi_uidivmod() but check signs before and change signs afterwards.
@
.thumb_func
.section .text.__aeabi_idiv
.global __aeabi_idiv
__aeabi_idiv:
cmp r0, #0
bge L_num_pos
rsbs r0, r0, #0 @ num = -num
cmp r1, #0
bge L_neg_result
rsbs r1, r1, #0 @ den = -den
b __aeabi_uidivmod
L_num_pos:
cmp r1, #0
bge __aeabi_uidivmod
rsbs r1, r1, #0 @ den = -den
L_neg_result:
push {lr}
bl __aeabi_uidivmod
rsbs r0, r0, #0 @ quot = -quot
pop {pc}
@ {int quotient:r0, int remainder:r1}
@ __aeabi_idivmod(int numerator:r0, int denominator:r1)
@
@ Divide r0 by r1 and return the quotient in r0 and the remainder in r1
@
.thumb_func
.section .text.__aeabi_idivmod
.global __aeabi_idivmod
__aeabi_idivmod:
cmp r0, #0
bge L_num_pos_bis
rsbs r0, r0, #0 @ num = -num
cmp r1, #0
bge L_neg_both
rsbs r1, r1, #0 @ den = -den
push {lr}
bl __aeabi_uidivmod
rsbs r1, r1, #0 @ rem = -rem
pop {pc}
L_neg_both:
push {lr}
bl __aeabi_uidivmod
rsbs r0, r0, #0 @ quot = -quot
rsbs r1, r1, #0 @ rem = -rem
pop {pc}
L_num_pos_bis:
cmp r1, #0
bge __aeabi_uidivmod
rsbs r1, r1, #0 @ den = -den
push {lr}
bl __aeabi_uidivmod
rsbs r0, r0, #0 @ quot = -quot
pop {pc}
@ unsigned __aeabi_uidiv(unsigned num, unsigned denom)
@
@ Just an alias for __aeabi_uidivmod(), the remainder is ignored
@
.thumb_func
.section .text.__aeabi_uidivmod
.global __aeabi_uidiv
__aeabi_uidiv:
@ {unsigned quotient:r0, unsigned remainder:r1}
@ __aeabi_uidivmod(unsigned numerator:r0, unsigned denominator:r1)
@
@ Divide r0 by r1 and return the quotient in r0 and the remainder in r1
@
.thumb_func
.global __aeabi_uidivmod
__aeabi_uidivmod:
cmp r1, #0
bne L_no_div0
b __aeabi_idiv0
L_no_div0:
@ Shift left the denominator until it is greater than the numerator
movs r2, #1 @ counter
movs r3, #0 @ result
cmp r0, r1
bls L_sub_loop0
adds r1, #0 @ dont shift if denominator would overflow
bmi L_sub_loop0
L_denom_shift_loop:
lsls r2, #1
lsls r1, #1
bmi L_sub_loop0
cmp r0, r1
bhi L_denom_shift_loop
L_sub_loop0:
cmp r0, r1
bcc L_dont_sub0 @ if (num>denom)
subs r0, r1 @ numerator -= denom
orrs r3, r2 @ result(r3) |= bitmask(r2)
L_dont_sub0:
lsrs r1, #1 @ denom(r1) >>= 1
lsrs r2, #1 @ bitmask(r2) >>= 1
bne L_sub_loop0
mov r1, r0 @ remainder(r1) = numerator(r0)
mov r0, r3 @ quotient(r0) = result(r3)
bx lr
__aeabi_idiv0:
ldr SOFTWARE_PANIC_REASON_REG, =PANIC_SW_DIV_ZERO
bl exception_panic

1
core/cortex-m0/div.S Symbolic link
View File

@ -0,0 +1 @@
../../third_party/libaeabi-cortexm0/core/cortex-m0/div.S

View File

@ -1,92 +0,0 @@
/* Runtime ABI for the ARM Cortex-M0
* ldivmod.S: signed 64 bit division (quotient and remainder)
*
* Copyright 2012 Jörg Mische <bobbl@gmx.de>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
.syntax unified
.text
.thumb
.cpu cortex-m0
@ {long long quotient, long long remainder}
@ __aeabi_ldivmod(long long numerator, long long denominator)
@
@ Divide r1:r0 by r3:r2 and return the quotient in r1:r0 and the remainder in
@ r3:r2 (all signed)
@
.thumb_func
.section .text.__aeabi_ldivmod
.global __aeabi_ldivmod
__aeabi_ldivmod:
cmp r1, #0
bge L_num_pos
push {r4, lr}
movs r4, #0 @ num = -num
rsbs r0, r0, #0
sbcs r4, r1
mov r1, r4
cmp r3, #0
bge L_neg_both
movs r4, #0 @ den = -den
rsbs r2, r2, #0
sbcs r4, r3
mov r3, r4
bl __aeabi_uldivmod
movs r4, #0 @ rem = -rem
rsbs r2, r2, #0
sbcs r4, r3
mov r3, r4
pop {r4, pc}
L_neg_both:
bl __aeabi_uldivmod
movs r4, #0 @ quot = -quot
rsbs r0, r0, #0
sbcs r4, r1
mov r1, r4
movs r4, #0 @ rem = -rem
rsbs r2, r2, #0
sbcs r4, r3
mov r3, r4
pop {r4, pc}
L_num_pos:
cmp r3, #0
blt L_den_neg
push {r4, lr}
bl __aeabi_uldivmod @ offset too big for b / bge
pop {r4, pc}
L_den_neg:
push {r4, lr}
movs r4, #0 @ den = -den
rsbs r2, r2, #0
sbcs r4, r3
mov r3, r4
bl __aeabi_uldivmod
movs r4, #0 @ quot = -quot
rsbs r0, r0, #0
sbcs r4, r1
mov r1, r4
pop {r4, pc}

1
core/cortex-m0/ldivmod.S Symbolic link
View File

@ -0,0 +1 @@
../../third_party/libaeabi-cortexm0/core/cortex-m0/ldivmod.S

View File

@ -1,65 +0,0 @@
/* Runtime ABI for the ARM Cortex-M0
* lmul.S: 64 bit multiplication
*
* Copyright (c) 2013 Jörg Mische <bobbl@gmx.de>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
.syntax unified
.text
.thumb
.cpu cortex-m0
@ long long __aeabi_lmul(long long r1:r0, long long r3:r2)
@
@ Multiply r1:r0 and r3:r2 and return the product in r1:r0
@ Can also be used for unsigned long product
@
.thumb_func
.section .text.__aeabi_lmul
.global __aeabi_lmul
__aeabi_lmul:
push {r4, lr}
muls r1, r2
muls r3, r0
adds r1, r3
lsrs r3, r0, #16
lsrs r4, r2, #16
muls r3, r4
adds r1, r3
lsrs r3, r0, #16
uxth r0, r0
uxth r2, r2
muls r3, r2
muls r4, r0
muls r0, r2
movs r2, #0
adds r3, r4
adcs r2, r2
lsls r2, #16
adds r1, r2
lsls r2, r3, #16
lsrs r3, #16
adds r0, r2
adcs r1, r3
pop {r4, pc}

1
core/cortex-m0/lmul.S Symbolic link
View File

@ -0,0 +1 @@
../../third_party/libaeabi-cortexm0/core/cortex-m0/lmul.S

View File

@ -1,177 +0,0 @@
/* Runtime ABI for the ARM Cortex-M0
* uldivmod.S: unsigned 64 bit division
*
* Copyright 2012 Jörg Mische <bobbl@gmx.de>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "software_panic.h"
.syntax unified
.text
.thumb
.cpu cortex-m0
@ {unsigned long long quotient, unsigned long long remainder}
@ __aeabi_uldivmod(unsigned long long numerator, unsigned long long denominator)
@
@ Divide r1:r0 by r3:r2 and return the quotient in r1:r0 and the remainder
@ in r3:r2 (all unsigned)
@
.thumb_func
.section .text.__aeabi_uldivmod
.global __aeabi_uldivmod
__aeabi_uldivmod:
cmp r3, #0
bne L_large_denom
cmp r2, #0
beq L_divison_by_0
cmp r1, #0
beq L_fallback_32bits
@ case 1: num >= 2^32 and denom < 2^32
@ Result might be > 2^32, therefore we first calculate the upper 32
@ bits of the result. It is done similar to the calculation of the
@ lower 32 bits, but with a denominator that is shifted by 32.
@ Hence the lower 32 bits of the denominator are always 0 and the
@ costly 64 bit shift and sub operations can be replaced by cheap 32
@ bit operations.
push {r4, r5, r6, r7, lr}
@ shift left the denominator until it is greater than the numerator
@ denom(r7:r6) = r3:r2 << 32
movs r5, #1 @ bitmask
adds r7, r2, #0 @ dont shift if denominator would overflow
bmi L_upper_result
cmp r1, r7
blo L_upper_result
L_denom_shift_loop1:
lsls r5, #1
lsls r7, #1
bmi L_upper_result @ dont shift if overflow
cmp r1, r7
bhs L_denom_shift_loop1
L_upper_result:
mov r3, r1
mov r2, r0
movs r1, #0 @ upper result = 0
L_sub_loop1:
cmp r3, r7
bcc L_dont_sub1 @ if (num>denom)
subs r3, r7 @ num -= denom
orrs r1, r5 @ result(r7:r6) |= bitmask(r5)
L_dont_sub1:
lsrs r7, #1 @ denom(r7:r6) >>= 1
lsrs r5, #1 @ bitmask(r5) >>= 1
bne L_sub_loop1
movs r5, #1
lsls r5, #31
movs r6, #0
b L_lower_result
@ case 2: division by 0
@ call __aeabi_ldiv0
L_divison_by_0:
b __aeabi_ldiv0
@ case 3: num < 2^32 and denom < 2^32
@ fallback to 32 bit division
L_fallback_32bits:
mov r1, r2
push {lr}
bl __aeabi_uidivmod
mov r2, r1
movs r1, #0
movs r3, #0
pop {pc}
@ case 4: denom >= 2^32
@ result is smaller than 2^32
L_large_denom:
push {r4, r5, r6, r7, lr}
mov r7, r3
mov r6, r2
mov r3, r1
mov r2, r0
@ Shift left the denominator until it is greater than the numerator
movs r1, #0 @ high word of result is 0
movs r5, #1 @ bitmask
adds r7, #0 @ dont shift if denominator would overflow
bmi L_lower_result
cmp r3, r7
blo L_lower_result
L_denom_shift_loop4:
lsls r5, #1
lsls r7, #1
lsls r6, #1
adcs r7, r1 @ r1=0
bmi L_lower_result @ dont shift if overflow
cmp r3, r7
bhs L_denom_shift_loop4
L_lower_result:
movs r0, #0
L_sub_loop4:
mov r4, r3
cmp r2, r6
sbcs r4, r7
bcc L_dont_sub4 @ if (num>denom)
subs r2, r6 @ numerator -= denom
sbcs r3, r7
orrs r0, r5 @ result(r1:r0) |= bitmask(r5)
L_dont_sub4:
lsls r4, r7, #31 @ denom(r7:r6) >>= 1
lsrs r6, #1
lsrs r7, #1
orrs r6, r4
lsrs r5, #1 @ bitmask(r5) >>= 1
bne L_sub_loop4
pop {r4, r5, r6, r7, pc}
__aeabi_ldiv0:
ldr SOFTWARE_PANIC_REASON_REG, =PANIC_SW_DIV_ZERO
bl exception_panic

1
core/cortex-m0/uldivmod.S Symbolic link
View File

@ -0,0 +1 @@
../../third_party/libaeabi-cortexm0/core/cortex-m0/uldivmod.S

13
third_party/libaeabi-cortexm0/LICENSE vendored Normal file
View File

@ -0,0 +1,13 @@
Licensed under the ISC licence (similar to the MIT/Expat license).
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

17
third_party/libaeabi-cortexm0/METADATA vendored Normal file
View File

@ -0,0 +1,17 @@
name: "libaeabi-cortexm0"
description:
"ARM Run-Time ABI for the Cortex-M0 processor"
third_party {
url {
type: GIT
value: "https://github.com/bobbl/libaeabi-cortexm0"
}
# TODO(crbug.com/884905): Refresh as needed from upstream
version: "<as of 2014>"
last_upgrade_date { year: 2014 month: 04 day: 01 }
license_type: NOTICE
local_modifications: "cortex-m0: See git log. "
"cortex-m: Adapted from cortex-m0 code. "
"Created LICENSE file."
}

View File

@ -0,0 +1,86 @@
/* Runtime ABI for the ARM Cortex-M
* ldivmod.S: signed 64 bit division (quotient and remainder)
*
* Copyright (c) 2012 Jörg Mische <bobbl@gmx.de>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
.syntax unified
.text
.code 16
@ {long long quotient, long long remainder}
@ __aeabi_ldivmod(long long numerator, long long denominator)
@
@ Divide r1:r0 by r3:r2 and return the quotient in r1:r0 and the remainder in
@ r3:r2 (all signed)
@
.thumb_func
.section .text.__aeabi_ldivmod
.global __aeabi_ldivmod
__aeabi_ldivmod:
cmp r1, #0
bge L_num_pos
push {r4, lr}
movs r4, #0 @ num = -num
rsbs r0, r0, #0
sbcs r4, r1
mov r1, r4
cmp r3, #0
bge L_neg_both
movs r4, #0 @ den = -den
rsbs r2, r2, #0
sbcs r4, r3
mov r3, r4
bl __aeabi_uldivmod
movs r4, #0 @ rem = -rem
rsbs r2, r2, #0
sbcs r4, r3
mov r3, r4
pop {r4, pc}
L_neg_both:
bl __aeabi_uldivmod
movs r4, #0 @ quot = -quot
rsbs r0, r0, #0
sbcs r4, r1
mov r1, r4
movs r4, #0 @ rem = -rem
rsbs r2, r2, #0
sbcs r4, r3
mov r3, r4
pop {r4, pc}
L_num_pos:
cmp r3, #0
bge __aeabi_uldivmod
push {r4, lr}
movs r4, #0 @ den = -den
rsbs r2, r2, #0
sbcs r4, r3
mov r3, r4
bl __aeabi_uldivmod
movs r4, #0 @ quot = -quot
rsbs r0, r0, #0
sbcs r4, r1
mov r1, r4
pop {r4, pc}

View File

@ -0,0 +1,179 @@
/* Runtime ABI for the ARM Cortex-M
* uldivmod.S: unsigned 64 bit division
*
* Copyright (c) 2012 Jörg Mische <bobbl@gmx.de>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "software_panic.h"
.syntax unified
.text
.code 16
@ {unsigned long long quotient, unsigned long long remainder}
@ __aeabi_uldivmod(unsigned long long numerator, unsigned long long denominator)
@
@ Divide r1:r0 by r3:r2 and return the quotient in r1:r0 and the remainder
@ in r3:r2 (all unsigned)
@
.thumb_func
.section .text.__aeabi_uldivmod
.global __aeabi_uldivmod
__aeabi_uldivmod:
cmp r3, #0
bne L_large_denom
cmp r2, #0
beq L_divison_by_0
cmp r1, #0
beq L_fallback_32bits
@ case 1: num >= 2^32 and denom < 2^32
@ Result might be > 2^32, therefore we first calculate the upper 32
@ bits of the result. It is done similar to the calculation of the
@ lower 32 bits, but with a denominator that is shifted by 32.
@ Hence the lower 32 bits of the denominator are always 0 and the
@ costly 64 bit shift and sub operations can be replaced by cheap 32
@ bit operations.
push {r4, r5, r6, r7, lr}
@ shift left the denominator until it is greater than the numerator
@ denom(r7:r6) = r3:r2 << 32
@ TODO(crosbug.com/p/36128): Loops like this (which occur in several
@ places in this file) are inefficent in ARMv6-m.
movs r5, #1 @ bitmask
adds r7, r2, #0 @ dont shift if denominator would overflow
bmi L_upper_result
cmp r1, r7
blo L_upper_result
L_denom_shift_loop1:
lsl r5, #1
lsls r7, #1
bmi L_upper_result @ dont shift if overflow
cmp r1, r7
bhs L_denom_shift_loop1
L_upper_result:
mov r3, r1
mov r2, r0
mov r1, #0 @ upper result = 0
mov r6, #0
L_sub_loop1:
orr r1, r5 @ result(r7:r6) |= bitmask(r5)
subs r2, r6 @ num -= denom
sbcs r3, r7
bhs L_done_sub1
eor r1, r5 @ undo add mask
adds r2, r6 @ undo subtract
adc r3, r3, r7
L_done_sub1:
lsrs r7, #1 @ denom(r7:r6) >>= 1
rrx r6, r6
lsrs r5, #1 @ bitmask(r5) >>= 1
bne L_sub_loop1
rrx r5, r5
b L_lower_result
@ case 2: division by 0
@ call __aeabi_ldiv0
L_divison_by_0:
b __aeabi_ldiv0
@ case 3: num < 2^32 and denom < 2^32
@ fallback to 32 bit division
L_fallback_32bits:
mov r1, r0
udiv r0, r0, r2 @ r0 = quotient
mul r3, r0, r2 @ r3 = quotient * divisor
sub r2, r1, r3 @ r2 = remainder
mov r1, #0
mov r3, #0
bx lr
@ case 4: denom >= 2^32
@ result is smaller than 2^32
L_large_denom:
push {r4, r5, r6, r7, lr}
mov r7, r3
mov r6, r2
mov r3, r1
mov r2, r0
@ Shift left the denominator until it is greater than the numerator
mov r1, #0 @ high word of result is 0
mov r5, #1 @ bitmask
adds r7, #0 @ dont shift if denominator would overflow
bmi L_lower_result
cmp r3, r7
blo L_lower_result
L_denom_shift_loop4:
lsl r5, #1
lsls r6, #1 @ denom(r7:r6) <<= 1
adcs r7, r7
bmi L_lower_result @ dont shift if overflow
cmp r3, r7
bhs L_denom_shift_loop4
L_lower_result:
movs r0, #0
L_sub_loop4:
orr r0, r5 @ result(r1:r0) |= bitmask(r5)
subs r2, r6 @ numerator -= denom
sbcs r3, r7
bhs L_done_sub4
eor r0, r5 @ undo add mask
adds r2, r6 @ undo subtract
adc r3, r3, r7
L_done_sub4:
lsrs r7, #1 @ denom(r7:r6) >>= 1
rrx r6, r6
lsrs r5, #1 @ bitmask(r5) >>= 1
bne L_sub_loop4
pop {r4, r5, r6, r7, pc}
__aeabi_ldiv0:
ldr SOFTWARE_PANIC_REASON_REG, =PANIC_SW_DIV_ZERO
bl exception_panic

View File

@ -0,0 +1,166 @@
/* Runtime ABI for the ARM Cortex-M0
* idiv.S: signed 32 bit division (only quotient)
* idivmod.S: signed 32 bit division (quotient and remainder)
* uidivmod.S: unsigned 32 bit division
*
* Copyright (c) 2012 Jörg Mische <bobbl@gmx.de>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "software_panic.h"
.syntax unified
.text
.thumb
.cpu cortex-m0
@ int __aeabi_idiv(int num:r0, int denom:r1)
@
@ Divide r0 by r1 and return quotient in r0 (all signed).
@ Use __aeabi_uidivmod() but check signs before and change signs afterwards.
@
.thumb_func
.section .text.__aeabi_idiv
.global __aeabi_idiv
__aeabi_idiv:
cmp r0, #0
bge L_num_pos
rsbs r0, r0, #0 @ num = -num
cmp r1, #0
bge L_neg_result
rsbs r1, r1, #0 @ den = -den
b __aeabi_uidivmod
L_num_pos:
cmp r1, #0
bge __aeabi_uidivmod
rsbs r1, r1, #0 @ den = -den
L_neg_result:
push {lr}
bl __aeabi_uidivmod
rsbs r0, r0, #0 @ quot = -quot
pop {pc}
@ {int quotient:r0, int remainder:r1}
@ __aeabi_idivmod(int numerator:r0, int denominator:r1)
@
@ Divide r0 by r1 and return the quotient in r0 and the remainder in r1
@
.thumb_func
.section .text.__aeabi_idivmod
.global __aeabi_idivmod
__aeabi_idivmod:
cmp r0, #0
bge L_num_pos_bis
rsbs r0, r0, #0 @ num = -num
cmp r1, #0
bge L_neg_both
rsbs r1, r1, #0 @ den = -den
push {lr}
bl __aeabi_uidivmod
rsbs r1, r1, #0 @ rem = -rem
pop {pc}
L_neg_both:
push {lr}
bl __aeabi_uidivmod
rsbs r0, r0, #0 @ quot = -quot
rsbs r1, r1, #0 @ rem = -rem
pop {pc}
L_num_pos_bis:
cmp r1, #0
bge __aeabi_uidivmod
rsbs r1, r1, #0 @ den = -den
push {lr}
bl __aeabi_uidivmod
rsbs r0, r0, #0 @ quot = -quot
pop {pc}
@ unsigned __aeabi_uidiv(unsigned num, unsigned denom)
@
@ Just an alias for __aeabi_uidivmod(), the remainder is ignored
@
.thumb_func
.section .text.__aeabi_uidivmod
.global __aeabi_uidiv
__aeabi_uidiv:
@ {unsigned quotient:r0, unsigned remainder:r1}
@ __aeabi_uidivmod(unsigned numerator:r0, unsigned denominator:r1)
@
@ Divide r0 by r1 and return the quotient in r0 and the remainder in r1
@
.thumb_func
.global __aeabi_uidivmod
__aeabi_uidivmod:
cmp r1, #0
bne L_no_div0
b __aeabi_idiv0
L_no_div0:
@ Shift left the denominator until it is greater than the numerator
movs r2, #1 @ counter
movs r3, #0 @ result
cmp r0, r1
bls L_sub_loop0
adds r1, #0 @ dont shift if denominator would overflow
bmi L_sub_loop0
L_denom_shift_loop:
lsls r2, #1
lsls r1, #1
bmi L_sub_loop0
cmp r0, r1
bhi L_denom_shift_loop
L_sub_loop0:
cmp r0, r1
bcc L_dont_sub0 @ if (num>denom)
subs r0, r1 @ numerator -= denom
orrs r3, r2 @ result(r3) |= bitmask(r2)
L_dont_sub0:
lsrs r1, #1 @ denom(r1) >>= 1
lsrs r2, #1 @ bitmask(r2) >>= 1
bne L_sub_loop0
mov r1, r0 @ remainder(r1) = numerator(r0)
mov r0, r3 @ quotient(r0) = result(r3)
bx lr
__aeabi_idiv0:
ldr SOFTWARE_PANIC_REASON_REG, =PANIC_SW_DIV_ZERO
bl exception_panic

View File

@ -0,0 +1,92 @@
/* Runtime ABI for the ARM Cortex-M0
* ldivmod.S: signed 64 bit division (quotient and remainder)
*
* Copyright 2012 Jörg Mische <bobbl@gmx.de>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
.syntax unified
.text
.thumb
.cpu cortex-m0
@ {long long quotient, long long remainder}
@ __aeabi_ldivmod(long long numerator, long long denominator)
@
@ Divide r1:r0 by r3:r2 and return the quotient in r1:r0 and the remainder in
@ r3:r2 (all signed)
@
.thumb_func
.section .text.__aeabi_ldivmod
.global __aeabi_ldivmod
__aeabi_ldivmod:
cmp r1, #0
bge L_num_pos
push {r4, lr}
movs r4, #0 @ num = -num
rsbs r0, r0, #0
sbcs r4, r1
mov r1, r4
cmp r3, #0
bge L_neg_both
movs r4, #0 @ den = -den
rsbs r2, r2, #0
sbcs r4, r3
mov r3, r4
bl __aeabi_uldivmod
movs r4, #0 @ rem = -rem
rsbs r2, r2, #0
sbcs r4, r3
mov r3, r4
pop {r4, pc}
L_neg_both:
bl __aeabi_uldivmod
movs r4, #0 @ quot = -quot
rsbs r0, r0, #0
sbcs r4, r1
mov r1, r4
movs r4, #0 @ rem = -rem
rsbs r2, r2, #0
sbcs r4, r3
mov r3, r4
pop {r4, pc}
L_num_pos:
cmp r3, #0
blt L_den_neg
push {r4, lr}
bl __aeabi_uldivmod @ offset too big for b / bge
pop {r4, pc}
L_den_neg:
push {r4, lr}
movs r4, #0 @ den = -den
rsbs r2, r2, #0
sbcs r4, r3
mov r3, r4
bl __aeabi_uldivmod
movs r4, #0 @ quot = -quot
rsbs r0, r0, #0
sbcs r4, r1
mov r1, r4
pop {r4, pc}

View File

@ -0,0 +1,65 @@
/* Runtime ABI for the ARM Cortex-M0
* lmul.S: 64 bit multiplication
*
* Copyright (c) 2013 Jörg Mische <bobbl@gmx.de>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
.syntax unified
.text
.thumb
.cpu cortex-m0
@ long long __aeabi_lmul(long long r1:r0, long long r3:r2)
@
@ Multiply r1:r0 and r3:r2 and return the product in r1:r0
@ Can also be used for unsigned long product
@
.thumb_func
.section .text.__aeabi_lmul
.global __aeabi_lmul
__aeabi_lmul:
push {r4, lr}
muls r1, r2
muls r3, r0
adds r1, r3
lsrs r3, r0, #16
lsrs r4, r2, #16
muls r3, r4
adds r1, r3
lsrs r3, r0, #16
uxth r0, r0
uxth r2, r2
muls r3, r2
muls r4, r0
muls r0, r2
movs r2, #0
adds r3, r4
adcs r2, r2
lsls r2, #16
adds r1, r2
lsls r2, r3, #16
lsrs r3, #16
adds r0, r2
adcs r1, r3
pop {r4, pc}

View File

@ -0,0 +1,177 @@
/* Runtime ABI for the ARM Cortex-M0
* uldivmod.S: unsigned 64 bit division
*
* Copyright 2012 Jörg Mische <bobbl@gmx.de>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "software_panic.h"
.syntax unified
.text
.thumb
.cpu cortex-m0
@ {unsigned long long quotient, unsigned long long remainder}
@ __aeabi_uldivmod(unsigned long long numerator, unsigned long long denominator)
@
@ Divide r1:r0 by r3:r2 and return the quotient in r1:r0 and the remainder
@ in r3:r2 (all unsigned)
@
.thumb_func
.section .text.__aeabi_uldivmod
.global __aeabi_uldivmod
__aeabi_uldivmod:
cmp r3, #0
bne L_large_denom
cmp r2, #0
beq L_divison_by_0
cmp r1, #0
beq L_fallback_32bits
@ case 1: num >= 2^32 and denom < 2^32
@ Result might be > 2^32, therefore we first calculate the upper 32
@ bits of the result. It is done similar to the calculation of the
@ lower 32 bits, but with a denominator that is shifted by 32.
@ Hence the lower 32 bits of the denominator are always 0 and the
@ costly 64 bit shift and sub operations can be replaced by cheap 32
@ bit operations.
push {r4, r5, r6, r7, lr}
@ shift left the denominator until it is greater than the numerator
@ denom(r7:r6) = r3:r2 << 32
movs r5, #1 @ bitmask
adds r7, r2, #0 @ dont shift if denominator would overflow
bmi L_upper_result
cmp r1, r7
blo L_upper_result
L_denom_shift_loop1:
lsls r5, #1
lsls r7, #1
bmi L_upper_result @ dont shift if overflow
cmp r1, r7
bhs L_denom_shift_loop1
L_upper_result:
mov r3, r1
mov r2, r0
movs r1, #0 @ upper result = 0
L_sub_loop1:
cmp r3, r7
bcc L_dont_sub1 @ if (num>denom)
subs r3, r7 @ num -= denom
orrs r1, r5 @ result(r7:r6) |= bitmask(r5)
L_dont_sub1:
lsrs r7, #1 @ denom(r7:r6) >>= 1
lsrs r5, #1 @ bitmask(r5) >>= 1
bne L_sub_loop1
movs r5, #1
lsls r5, #31
movs r6, #0
b L_lower_result
@ case 2: division by 0
@ call __aeabi_ldiv0
L_divison_by_0:
b __aeabi_ldiv0
@ case 3: num < 2^32 and denom < 2^32
@ fallback to 32 bit division
L_fallback_32bits:
mov r1, r2
push {lr}
bl __aeabi_uidivmod
mov r2, r1
movs r1, #0
movs r3, #0
pop {pc}
@ case 4: denom >= 2^32
@ result is smaller than 2^32
L_large_denom:
push {r4, r5, r6, r7, lr}
mov r7, r3
mov r6, r2
mov r3, r1
mov r2, r0
@ Shift left the denominator until it is greater than the numerator
movs r1, #0 @ high word of result is 0
movs r5, #1 @ bitmask
adds r7, #0 @ dont shift if denominator would overflow
bmi L_lower_result
cmp r3, r7
blo L_lower_result
L_denom_shift_loop4:
lsls r5, #1
lsls r7, #1
lsls r6, #1
adcs r7, r1 @ r1=0
bmi L_lower_result @ dont shift if overflow
cmp r3, r7
bhs L_denom_shift_loop4
L_lower_result:
movs r0, #0
L_sub_loop4:
mov r4, r3
cmp r2, r6
sbcs r4, r7
bcc L_dont_sub4 @ if (num>denom)
subs r2, r6 @ numerator -= denom
sbcs r3, r7
orrs r0, r5 @ result(r1:r0) |= bitmask(r5)
L_dont_sub4:
lsls r4, r7, #31 @ denom(r7:r6) >>= 1
lsrs r6, #1
lsrs r7, #1
orrs r6, r4
lsrs r5, #1 @ bitmask(r5) >>= 1
bne L_sub_loop4
pop {r4, r5, r6, r7, pc}
__aeabi_ldiv0:
ldr SOFTWARE_PANIC_REASON_REG, =PANIC_SW_DIV_ZERO
bl exception_panic