Browse Source

supporting lib code added and README updated

master
mntmn 1 month ago
parent
commit
9370194ef2

+ 16
- 5
README.md View File

@@ -12,7 +12,7 @@ To build the example applications, you need a version of GCC called arm-none-eab

# Building

Every example application has a build.sh script that calls arm-none-eabi-gcc to build and statically link the application with a special linker file, link.ld. Every application is per default linked to run at address 0x03000000 and can access arbitrary memory. There is no memory protection or memory management, but you can use the included libmemory for malloc/free as demonstrated by the nanojpeg example.
Every example application has a `build-appname.sh` script that calls `arm-none-eabi-gcc` to build and statically link the application with a special linker file, `link.ld`. Every application is per default linked to run at address `0x03000000` and can access arbitrary memory. There is no memory protection or memory management, but you can link in the included `libmemory` for malloc/free as demonstrated by the nanojpeg example (you just give it a fixed memory block on startup).

ZZ9000OS offers much less infrastructure to applications than traditional operating systems. Currently, only the following functions and arguments are provided by a structure called ZZ9K_ENV passed to your entry function:

@@ -34,22 +34,33 @@ struct ZZ9K_ENV {

# Loading

In the "zz9k-loader" directory, you can find sources for the zz9k-loader that runs on AmigaOS (m68k). With zz9k-loader, you can load an ARM application into the DDR3 memory of ZZ9000 and run it. The loader supports setting up multiple user interface modalities as a convenience:
In the `zz9k-loader` directory, you can find sources for the zz9k-loader that runs on AmigaOS (m68k). With `zz9k-loader`, you can load an ARM application into the DDR3 memory of ZZ9000 and run it. The loader supports setting up multiple user interface modalities as a convenience:

- `run` just jumps to your code with no user interface.
- `screen` sets up a 640x480@32 Intuition screen. If you pass a `!screen` parameter to your application, it will be substituted for the screen's bitmap address for direct access. Pass `!width` as a parameter to get the screen's width in pixels.
- `screen-low` similar to screen, but with 320x240@32 resolution.
- `attach` attaches stdin and stdout of the Shell to your application.
- `audio` experimental mode that plays back an audio buffer your application creates until a mouse button is pressed.
- `attach` attaches stdin and stdout of the Shell to your application, demonstrated by the `shell` example.
- `audio` experimental mode that plays back an audio buffer your application creates until a mouse button is pressed, demonstrated by `minimp3`.

Example:

```
zz9k-loader load vector.bin
zz9k-loader load conway.bin
zz9k-loader screen-low !screen !width
```

# Third Party Code

The SDK contains a collection of third-party libraries/code for ARM bare metal applications:

- Runtime ABI for Cortex-M0 (lib/div), by Jörg Mische <bobbl@gmx.de>
- Tiny printf, sprintf, vsnprintf (lib/printf), by Marco Paland <info@paland.com>
- libmemory memory allocator (lib/memory/libmemory_freelist.a), by Embedded Artistry, sources at: https://github.com/embeddedartistry/libmemory
- memcpy, memset, memmove (lib/memory), Public Domain

Portions of example code is lifted from the following sources:

- "Conway's game of life", Rosetta Code, https://rosettacode.org/wiki/Conway%27s_Game_of_Life#C

# License / Copyright


+ 79
- 0
lib/div/crt.S View File

@@ -0,0 +1,79 @@
/* Runtime ABI for the ARM Cortex-M0
* crt.S: C runtime environment
*
* 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
.thumb
.cpu cortex-a9



@ _start
@
@ Program entry point: call main(), then exit()
@
.thumb_func
.global _start
_start:
bl main
@ fallthrough to exit()


@ void exit(int status)
@
@ Exit from program: breakpoint 0
@
.thumb_func
.global exit
exit:
bkpt #0



@ void abort(void)
@
@ Abnormal program termination: breakpoint 1
@
.thumb_func
.global abort
abort:
bkpt #1



@ int __aeabi_idiv0(int r)
@
@ Handler for 32 bit division by zero
@
.thumb_func
.global __aeabi_idiv0
__aeabi_idiv0:



@ long long __aeabi_ldiv0(long long r)
@
@ Handler for 64 bit division by zero
@
.thumb_func
.global __aeabi_ldiv0
__aeabi_ldiv0:
bx lr

+ 72
- 0
lib/div/divdi3.S View File

@@ -0,0 +1,72 @@
/* Runtime ABI for the ARM Cortex-M0
* ldivmod.S: signed 64 bit division (only quotient)
*
* 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
.thumb
.cpu cortex-m0



@ long long __divdi3(long long numerator, long long denominator)
@
@ Divide r1:r0 by r3:r2 and return the quotient in r1:r0.
@ Same as _aeabi_ldivmod(), but ignore remainder.
@
.thumb_func
.global __divdi3
__divdi3:

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_result
movs r4, #0 @ den = -den
rsbs r2, r2, #0
sbcs r4, r3
mov r3, r4
bl __aeabi_uldivmod
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

L_neg_result:
bl __aeabi_uldivmod
movs r4, #0 @ quot = -quot
rsbs r0, r0, #0
sbcs r4, r1
mov r1, r4
pop {r4, pc}

+ 66
- 0
lib/div/idiv.S View File

@@ -0,0 +1,66 @@
/* Runtime ABI for the ARM Cortex-M0
* idiv.S: signed 32 bit division (only quotient)
*
* Copyright (c) 2012-2017 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-a9



@ int __divsi3(int num, int denom)
@
@ libgcc wrapper: just an alias for __aeabi_idivmod(), the remainder is ignored
@
.thumb_func
.global __divsi3
__divsi3:



@ 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
.global __aeabi_idiv
__aeabi_idiv:

cmp r0, #0
bge .Lnumerator_pos
rsbs r0, r0, #0 @ num = -num
cmp r1, #0
bge .Lneg_result
rsbs r1, r1, #0 @ den = -den

.Luidivmod:
b __aeabi_uidivmod

.Lnumerator_pos:
cmp r1, #0
bge .Luidivmod
rsbs r1, r1, #0 @ den = -den

.Lneg_result:
push {lr}
bl __aeabi_uidivmod
rsbs r0, r0, #0 @ quot = -quot
pop {pc}

+ 136
- 0
lib/div/idivmod.S View File

@@ -0,0 +1,136 @@
/* Runtime ABI for the ARM Cortex-M0
* idivmod.S: signed 32 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
.thumb
.cpu cortex-a9



@ {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
.global __aeabi_idivmod
__aeabi_idivmod:

cmp r0, #0
bge .Lnumerator_pos
rsbs r0, r0, #0 @ num = -num
cmp r1, #0
bge .Lboth_neg

rsbs r1, r1, #0 @ den = -den
push {lr}
bl __aeabi_uidivmod
rsbs r1, r1, #0 @ rem = -rem
pop {pc}

.Lboth_neg:
push {lr}
bl __aeabi_uidivmod
rsbs r0, r0, #0 @ quot = -quot
rsbs r1, r1, #0 @ rem = -rem
pop {pc}

.Lnumerator_pos:
cmp r1, #0
bge .Luidivmod

rsbs r1, r1, #0 @ den = -den
push {lr}
bl __aeabi_uidivmod
rsbs r0, r0, #0 @ quot = -quot
pop {pc}





@ unsigned __udivsi3(unsigned num, unsigned denom)
@
@ libgcc wrapper: just an alias for __aeabi_uidivmod(), the remainder is ignored
@
.thumb_func
.global __udivsi3
__udivsi3:



@ unsigned __aeabi_uidiv(unsigned num, unsigned denom)
@
@ Just an alias for __aeabi_uidivmod(), the remainder is ignored
@
.thumb_func
.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:



.Luidivmod:
cmp r1, #0
bne 1f
b __aeabi_idiv0
1:

@ Shift left the denominator until it is greater than the numerator
movs r2, #1 @ counter
movs r3, #0 @ result
cmp r0, r1
bls .Lsub_loop
adds r1, #0 @ dont shift if denominator would overflow
bmi .Lsub_loop

.Ldenom_shift_loop:
lsls r2, #1
lsls r1, #1
bmi .Lsub_loop
cmp r0, r1
bhi .Ldenom_shift_loop

.Lsub_loop:
cmp r0, r1
bcc .Ldont_sub @ if (num>denom)

subs r0, r1 @ numerator -= denom
orrs r3, r2 @ result(r3) |= bitmask(r2)
.Ldont_sub:

lsrs r1, #1 @ denom(r1) >>= 1
lsrs r2, #1 @ bitmask(r2) >>= 1
bne .Lsub_loop

mov r1, r0 @ remainder(r1) = numerator(r0)
mov r0, r3 @ quotient(r0) = result(r3)
bx lr

+ 62
- 0
lib/div/lasr.S View File

@@ -0,0 +1,62 @@
/* Runtime ABI for the ARM Cortex-M0
* lasr.S: 64 bit arithmetic shift right
*
* 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
.thumb
.cpu cortex-m0



@ long long __ashrdi3(long long r1:r0, int r2)
@
@ libgcc wrapper: just an alias for __aeabi_lasr()
@
.thumb_func
.global __ashrdi3
__ashrdi3:



@ long long __aeabi_lasr(long long r1:r0, int r2)
@
@ Arithmetic shift r1:r0 right by r2 bits
@
.thumb_func
.global __aeabi_lasr
__aeabi_lasr:
cmp r2, #31
bhi 1f
movs r3, r1 @ n < 32:
lsrs r0, r2
asrs r1, r2 @ hi = hi >> n
rsbs r2, r2, #0
adds r2, #32
lsls r3, r2
orrs r0, r3 @ lo = lo >> n | hi << (32-n)
bx lr

1: subs r2, #32 @ n >= 32:
movs r0, r1
asrs r0, r2 @ lo = hi >> (n-32)
asrs r1, #31 @ hi = hi >> 31
bx lr

+ 47
- 0
lib/div/lcmp.S View File

@@ -0,0 +1,47 @@
/* Runtime ABI for the ARM Cortex-M0
* lcmp.S: signed 64 bit comparison
*
* Copyright (c) 2017 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



@ int __aeabi_lcmp(long long r1:r0, long long r3:r2)
@
@ Compare signed integers and return -1 if lower, 0 if equal or +1 if greater
@
.thumb_func
.global __aeabi_lcmp
__aeabi_lcmp:

cmp r1, r3
blt 1f
bgt 2f
cmp r0, r2
bhi 2f
sbcs r0, r0, r0 @ 0 if cs and -1 if cc
bx lr
1: movs r0, #1
rsbs r0, r0, #0
bx lr
2: movs r0, #1
bx lr

+ 252
- 0
lib/div/ldivmod.S View File

@@ -0,0 +1,252 @@
/* Runtime ABI for the ARM Cortex-M0
* ldivmod.S: 64 bit division (quotient and remainder)
*
* Copyright (c) 2012-2017 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-a9



@ {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
.global __aeabi_ldivmod
__aeabi_ldivmod:

cmp r1, #0
bge .Lnumerator_pos

push {r4, lr}
movs r4, #0 @ num = -num
rsbs r0, r0, #0
sbcs r4, r1
mov r1, r4

cmp r3, #0
bge .Lboth_neg

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}
.Lboth_neg:
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}

.Lnumerator_pos:
cmp r3, #0
bge .Luldivmod

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}




@ unsigned long long __udivdi3(unsigned long long num, unsigned long long denom)
@
@ libgcc wrapper: just an alias for __aeabi_uldivmod(), the remainder is ignored
@
.thumb_func
.global __udivdi3
__udivdi3:



@ {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
.global __aeabi_uldivmod
__aeabi_uldivmod:



.Luldivmod:
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
b .L_sub_entry1

.L_sub_loop1:
lsrs r7, #1 @ denom(r7:r6) >>= 1

.L_sub_entry1:
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 r5, #1 @ bitmask(r5) >>= 1
bne .L_sub_loop1

movs r5, #1
lsls r5, #31
lsls r6, r7, #31 @ denom(r7:r6) = (r7:0) >> 1
lsrs r7, #1 @ dont forget least significant bit!
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:
eors r0, r0

.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}

+ 62
- 0
lib/div/llsl.S View File

@@ -0,0 +1,62 @@
/* Runtime ABI for the ARM Cortex-M0
* llsl.S: 64 bit shift left
*
* 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
.thumb
.cpu cortex-m0



@ long long __ashldi3(long long r1:r0, int r2)
@
@ libgcc wrapper: just an alias for __aeabi_llsl()
@
.thumb_func
.global __ashldi3
__ashldi3:



@ long long __aeabi_llsl(long long r1:r0, int r2)
@
@ Sshift r1:r0 left by r2 bits
@
.thumb_func
.global __aeabi_llsl
__aeabi_llsl:
cmp r2, #31
bhi 1f
movs r3, r1 @ n < 32:
lsls r0, r2 @ lo = lo << n
lsls r1, r2
rsbs r2, r2, #0
adds r2, #32
lsrs r3, r2
orrs r1, r3 @ hi = hi << n | lo >> (32-n)
bx lr

1: subs r2, #32 @ n >= 32:
movs r1, r0
lsls r1, r2 @ hi = lo << (n-32)
movs r0, #0 @ lo = 0
bx lr

+ 62
- 0
lib/div/llsr.S View File

@@ -0,0 +1,62 @@
/* Runtime ABI for the ARM Cortex-M0
* llsr.S: 64 bit logical shift right
*
* 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
.thumb
.cpu cortex-m0



@ long long __lshrdi3(long long r1:r0, int r2)
@
@ libgcc wrapper: just an alias for __aeabi_llsr()
@
.thumb_func
.global __lshrdi3
__lshrdi3:



@ long long __aeabi_llsr(long long r1:r0, int r2)
@
@ Logical shift r1:r0 right by r2 bits
@
.thumb_func
.global __aeabi_llsr
__aeabi_llsr:
cmp r2, #31
bhi 1f
movs r3, r1 @ n < 32:
lsrs r0, r2
lsrs r1, r2 @ hi = hi >> n
rsbs r2, r2, #0
adds r2, #32
lsls r3, r2
orrs r0, r3 @ lo = lo >> n | hi << (32-n)
bx lr

1: subs r2, #32 @ n >= 32:
movs r0, r1
lsrs r0, r2 @ lo = hi >> (n-32)
movs r1, #0 @ hi = 0
bx lr

+ 74
- 0
lib/div/lmul.S View File

@@ -0,0 +1,74 @@
/* 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 __muldi3(long long, long long)
@
@ libgcc wrapper: just an alias for __aeabi_lmul()
@
.thumb_func
.global __muldi3
__muldi3:



@ 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
.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}

+ 183
- 0
lib/div/memmove.S View File

@@ -0,0 +1,183 @@
/* Runtime ABI for the ARM Cortex-M0
* memmove.S: move memory block
*
* Copyright (c) 2017 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



@ void __aeabi_memmove8(void *r0, const void *r1, size_t r2);
@
@ Move r2 bytes from r1 to r0 and check for overlap.
@ r1 and r0 must be aligned to 8 bytes.
@
.thumb_func
.global __aeabi_memmove8
__aeabi_memmove8:



@ void __aeabi_memmove4(void *r0, const void *r1, size_t r2);
@
@ Move r2 bytes from r1 to r0 and check for overlap.
@ r1 and r0 must be aligned to 4 bytes.
@
.thumb_func
.global __aeabi_memmove4
__aeabi_memmove4:



cmp r0, r1
bls __aeabi_memcpy4
adds r3, r1, r2
cmp r0, r3
bhs __aeabi_memcpy4

b .Lbackward_entry

.Lbackward_loop:
ldrb r3, [r1, r2]
strb r3, [r0, r2]

.Lbackward_entry:
subs r2, #1
bhs .Lbackward_loop

bx lr



@ void __aeabi_memmove(void *r0, const void *r1, size_t r2);
@
@ Move r2 bytes from r1 to r0 and check for overlap.
@ r0 and r1 need not be aligned.
@
.thumb_func
.global __aeabi_memmove
__aeabi_memmove:



cmp r0, r1
bls __aeabi_memcpy
adds r3, r1, r2
cmp r0, r3
blo .Lbackward_entry



@ void __aeabi_memcpy(void *r0, const void *r1, size_t r2);
@
@ Move r2 bytes from r1 to r0. No overlap allowed.
@ r0 and r1 need not be aligned.
@
.thumb_func
.global __aeabi_memcpy
__aeabi_memcpy:



cmp r2, #8
blo .Lforward1
mov r3, r0
eors r3, r1
lsls r3, r3, #30
bne .Lforward1

lsrs r3, r0, #1
bcc .Lalign2
ldrb r3, [r1]
strb r3, [r0]
adds r0, #1
adds r1, #1
subs r2, #1
.Lalign2:
lsrs r3, r0, #2
bcc .Lalign4
ldrh r3, [r1]
strh r3, [r0]
adds r0, #2
adds r1, #2
subs r2, #2
.Lalign4:



@ void __aeabi_memcpy8(void *r0, const void *r1, size_t r2);
@
@ Move r2 bytes from r1 to r0. No overlap allowed.
@ r0 and r1 must be aligned to 8 bytes.
@
.thumb_func
.global __aeabi_memcpy8
__aeabi_memcpy8:



@ void __aeabi_memcpy4(void *r0, const void *r1, size_t r2);
@
@ Move r2 bytes from r1 to r0. No overlap allowed.
@ r0 and r1 must be aligned to 4 bytes.
@
.thumb_func
.global __aeabi_memcpy4
__aeabi_memcpy4:



subs r2, #20
blo .Lforward4
push {r4, r5, r6, r7}
.Lforward20_loop:
ldm r1!, {r3, r4, r5, r6, r7}
stm r0!, {r3, r4, r5, r6, r7}
subs r2, #20
bhs .Lforward20_loop
pop {r4, r5, r6, r7}

.Lforward4:
adds r2, #16
blo .Lforward4_corr
.Lforward4_loop:
ldm r1!, {r3}
stm r0!, {r3}
subs r2, #4
bhs .Lforward4_loop

.Lforward4_corr:
adds r2, #4

.Lforward1:
orrs r2, r2
beq 9f
push {r4}
eors r4, r4

.Lforward1_loop:
ldrb r3, [r1, r4]
strb r3, [r0, r4]
adds r4, #1
cmp r4, r2
blo .Lforward1_loop
pop {r4}
9: bx lr

+ 152
- 0
lib/div/memset.S View File

@@ -0,0 +1,152 @@
/* Runtime ABI for the ARM Cortex-M0
* memset.S: set memory region
*
* 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



@ void __aeabi_memclr(void *r0, size_t r1)
@
@ Set the r1 bytes beginning with *r0 to 0.
@
.thumb_func
.global __aeabi_memclr
__aeabi_memclr:


eors r2, r2 @ fallthrough to memset


@ void __aeabi_memset(void *r0, size_t r1, int r2)
@
@ Set the r1 bytes beginning with *r0 to r2
@
.thumb_func
.global __aeabi_memset
__aeabi_memset:

@ check if length=0
cmp r1, #0
beq L_return1
movs r3, #1 @ set one byte if odd address
tst r0, r3
beq L_align2
strb r2, [r0]
adds r0, #1
subs r1, #1
beq L_return1
L_align2:
movs r3, #2 @ set one halfword if address is not 32 bit aligned
tst r0, r3
beq __aeabi_memset4
strb r2, [r0]
cmp r1, #1 @ if length is 1 copy only 1 byte
beq L_return1
strb r2, [r0, #1]
adds r0, #2
subs r1, #2
bne __aeabi_memset4

L_return1:
bx lr



@ void __aeabi_memclr4(void *r0, size_t r1)
@
@ Set the r1 bytes beginning with *r0 to 0.
@ r0 must be 4-byte-aligned
@
.thumb_func
.global __aeabi_memclr4
__aeabi_memclr4:


@ void __aeabi_memclr8(void *r0, size_t r1)
@
@ Set the r1 bytes beginning with *r0 to 0.
@ r0 must be 8-byte-aligned
@
.thumb_func
.global __aeabi_memclr8
__aeabi_memclr8:


eors r2, r2 @ fallthrough to memset4


@ void __aeabi_memset4(void *r0, size_t r1, int r2)
@
@ Set the r1 bytes beginning with *r0 to r2.
@ r0 must be 4-byte-aligned
@
.thumb_func
.global __aeabi_memset4
__aeabi_memset4:


@ void __aeabi_memset8(void *r0, size_t r1, int r2)
@
@ Set the r1 bytes beginning with *r0 to r2.
@ r0 must be 8-byte-aligned
@
.thumb_func
.global __aeabi_memset8
__aeabi_memset8:


subs r1, #4
blo L_last_3bytes
lsls r2, r2, #24 @ copy lowest byte of r2 to all other bytes in r2
lsrs r3, r2, #8
orrs r2, r3
lsrs r3, r2, #16
orrs r2, r3
L_loop:
str r2, [r0]
adds r0, #4
subs r1, #4
bhs L_loop
L_last_3bytes: @ r1 = remaining len - 4
adds r1, #2
blo L_one_left @ branch if r1 was -4 or -3
strh r2, [r0]
beq L_return2 @ finished if r1 was -2
strb r2, [r0, #2]

L_return2:
bx lr

L_one_left:
adds r1, #1
bne L_return3
strb r2, [r0]

L_return3:
bx lr

+ 67
- 0
lib/div/moddi3.S View File

@@ -0,0 +1,67 @@
/* Runtime ABI for the ARM Cortex-M0
* ldivmod.S: signed 64 bit division (only 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
.thumb
.cpu cortex-m0



@ long long __moddi3(long long numerator, long long denominator)
@
@ Divide r1:r0 by r3:r2 and return the remainder in r1:r0 (all signed)
@ Special case of __aeabi_ldivmod() that is a lot simpler and moves the
@ remainder to r1:r0.
@
.thumb_func
.global __moddi3
__moddi3:

push {r4, lr}
cmp r3, #0
bge L_dont_neg_den
movs r4, #0 @ den = -den
rsbs r2, r2, #0
sbcs r4, r3
mov r3, r4
L_dont_neg_den:

cmp r1, #0
bge L_pos_result
movs r4, #0 @ num = -num
rsbs r0, r0, #0
sbcs r4, r1
mov r1, r4

bl __aeabi_uldivmod
movs r0, #0 @ rem = -rem
movs r1, #0
subs r0, r2
sbcs r1, r3
pop {r4, pc}

L_pos_result:
bl __aeabi_uldivmod
mov r1, r3
mov r0, r2
pop {r4, pc}

+ 56
- 0
lib/div/modsi3.S View File

@@ -0,0 +1,56 @@
/* Runtime ABI for the ARM Cortex-M0
* idivmod.S: signed 32 bit division 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
.thumb
.cpu cortex-m0



@ int __modsi3(int numerator:r0, int denominator:r1)
@
@ Divide r0 by r1 and return the remainder in r0
@ Special case of __aeabi_idivmod() that is a lot simpler and moves the
@ remainder to r0.
@
.thumb_func
.global __modsi3
__modsi3:

cmp r1, #0
bge L_dont_neg_den
rsbs r1, r1, #0 @ den = -den
L_dont_neg_den:

cmp r0, #0
bge L_pos_result
rsbs r0, r0, #0 @ num = -num
push {lr}
bl __aeabi_uidivmod
rsbs r0, r1, #0 @ return -rem
pop {pc}
L_pos_result:
push {lr}
bl __aeabi_uidivmod
movs r0, r1 @ return rem
pop {pc}

+ 59
- 0
lib/div/ulcmp.S View File

@@ -0,0 +1,59 @@
/* Runtime ABI for the ARM Cortex-M0
* ulcmp.S: unsigned 64 bit comparison
*
* Copyright (c) 2017 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



@ int __aeabi_ulcmp(unsigned long long r1:r0, unsigned long long r3:r2)
@
@ Compare unsigned integers and return -1 if lower, 0 if equal or +1 if greater
@
.thumb_func
.global __aeabi_ulcmp
__aeabi_ulcmp:

cmp r1, r3
blo 1f @ cc
bhi 2f
cmp r0, r2
blo 1f
bhi 2f
eors r0, r0
bx lr
1: movs r0, #1
rsbs r0, r0, #0
bx lr
2: movs r0, #1
bx lr


cmp r1, r3
blo 1f
bhi 2f
cmp r0, r2
bhi 2f
1: sbcs r0, r0, r0 @ 0 if cs and -1 if cc
bx lr
2: movs r0, #1
bx lr

+ 28
- 0
lib/div/uldivmod.S View File

@@ -0,0 +1,28 @@
//===-- aeabi_uldivmod.S - EABI uldivmod implementation -------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//#include "../assembly.h"
// struct { uint64_t quot, uint64_t rem}
// __aeabi_uldivmod(uint64_t numerator, uint64_t denominator) {
// uint64_t rem, quot;
// quot = __udivmoddi4(numerator, denominator, &rem);
// return {quot, rem};
// }
.syntax unified
.align 2
DEFINE_COMPILERRT_FUNCTION(__aeabi_uldivmod)
push {r11, lr}
sub sp, sp, #16
add r12, sp, #8
str r12, [sp]
bl SYMBOL_NAME(__udivmoddi4)
ldr r2, [sp, #8]
ldr r3, [sp, #12]
add sp, sp, #16
pop {r11, pc}

+ 38
- 0
lib/div/umoddi3.S View File

@@ -0,0 +1,38 @@
/* Runtime ABI for the ARM Cortex-M0
* 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.
*/



.syntax unified
.text
.thumb
.cpu cortex-m0


@ unsigned long long __umoddi3(unsigned long long num, unsigned long long denom)
@
@ libgcc wrapper: use __aeabi_uldivmod() and return remainder
@
.thumb_func
.global __umoddi3
__umoddi3:
push {lr}
bl __aeabi_uldivmod
mov r0, r2
mov r1, r3
pop {pc}

+ 38
- 0
lib/div/umodsi3.S View File

@@ -0,0 +1,38 @@
/* Runtime ABI for the ARM Cortex-M0
* umodsi3.S: wrapper for unsigned 32 bit division 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
.thumb
.cpu cortex-m0



@ unsigned __umodsi3(unsigned num, unsigned denom)
@
@ libgcc wrapper: use __aeabi_uidivmod() and return remainder
@
.thumb_func
.global __umodsi3
__umodsi3:
push {lr}
bl __aeabi_uidivmod
mov r0, r1
pop {pc}

+ 47
- 0
lib/div/uread4.S View File

@@ -0,0 +1,47 @@
/* Runtime ABI for the ARM Cortex-M0
* uread4.S: unaligned memory read
*
* Copyright (c) 2017 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



@ int __aeabi_uread4(void *r0)
@
@ Read 4 little endian bytes from unaligned memory address
@
.thumb_func
.global __aeabi_uread4
__aeabi_uread4:


lsls r1, r0, #30
lsrs r1, r1, #27 @ r1 = bit offset relative to aligned address
lsrs r0, r0, #2
lsls r0, r0, #2 @ r0 = round down address
ldm r0, {r0,r2} @ r2:r0 = 8 bytes including the unaligned word
lsrs r0, r1
subs r1, #32
negs r1, r1
lsls r2, r1
orrs r0, r2 @ r0 = (r0>>r1) | (r2<<(32-r1))
bx lr

+ 53
- 0
lib/div/uread8.S View File

@@ -0,0 +1,53 @@
/* Runtime ABI for the ARM Cortex-M0
* uread8.S: unaligned memory read
*
* Copyright (c) 2017 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_uread8(void *r0)
@
@ Read 8 little endian bytes from unaligned memory address
@
.thumb_func
.global __aeabi_uread8
__aeabi_uread8:


push {r4}
lsrs r1, r0, #2
lsls r1, r1, #2
lsls r2, r0, #30
lsrs r2, r2, #27
ldm r1, {r0, r1, r3}
lsrs r0, r2
mov r4, r1
lsrs r1, r2
subs r2, #32
negs r2, r2
lsls r4, r2
lsls r3, r2
orrs r0, r4
orrs r1, r3
pop {r4}
bx lr

+ 51
- 0
lib/div/uwrite4.S View File

@@ -0,0 +1,51 @@
/* Runtime ABI for the ARM Cortex-M0
* uread4.S: unaligned memory read
*
* Copyright (c) 2017 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



@ int __aeabi_uwrite4(int r0, void *r1)
@
@ Write 4 little endian bytes to unaligned memory address
@
.thumb_func
.global __aeabi_uwrite4
__aeabi_uwrite4:

lsrs r2, r1, #1
bcc .Lhalfword_aligned

strb r0, [r1]
adds r1, r1, #1
lsrs r0, r0, #8
strh r0, [r1]
lsrs r0, r0, #16
strb r0, [r1, #2]
bx lr

.Lhalfword_aligned:
strh r0, [r1]
lsrs r0, r0, #16
strh r0, [r1, #2]
bx lr

+ 60
- 0
lib/div/uwrite8.S View File

@@ -0,0 +1,60 @@
/* Runtime ABI for the ARM Cortex-M0
* uread4.S: unaligned memory read
*
* Copyright (c) 2017 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



@ int __aeabi_uwrite8(long longt r1:r0, void *r2)
@
@ Write 8 little endian bytes to unaligned memory address
@
.thumb_func
.global __aeabi_uwrite8
__aeabi_uwrite8:

lsrs r3, r2, #1
bcc .Lhalfword_aligned

strb r0, [r2]
adds r2, #1
lsrs r0, r0, #8
strh r0, [r2]
lsrs r0, r0, #16
lsls r3, r1, #8
orrs r0, r3
strh r0, [r2, #2]
lsrs r1, r1, #8
strh r1, [r2, #4]
lsrs r1, r1, #16
strb r1, [r2, #6]
bx lr

.Lhalfword_aligned:
strh r0, [r2]
lsrs r0, r0, #16
strh r0, [r2, #2]
strh r1, [r2, #4]
lsrs r1, r1, #16
strh r1, [r2, #6]
bx lr

BIN
lib/memory/libmemory_freelist.a View File


+ 13
- 0
lib/memory/memcpy.c View File

@@ -0,0 +1,13 @@
/* Public domain. */
#include <stddef.h>

void *
memcpy (void *dest, const void *src, size_t len)
{
char *d = dest;
const char *s = src;
while (len--) {
*d++ = *s++;
}
return dest;
}

+ 18
- 0
lib/memory/memmove.c View File

@@ -0,0 +1,18 @@
#include <stddef.h>

void *memmove(void *dest, void const *src, size_t n)
{
char *dp = dest;
char const *sp = src;
if(dp < sp) {
while(n-- > 0)
*dp++ = *sp++;
} else {
dp += n;
sp += n;
while(n-- > 0)
*--dp = *--sp;
}

return dest;
}

+ 10
- 0
lib/memory/memset.c View File

@@ -0,0 +1,10 @@
#include <stddef.h>

void *
memset (void *dest, int val, size_t len)
{
unsigned char *ptr = dest;
while (len-- > 0)
*ptr++ = val;
return dest;
}

+ 914
- 0
lib/printf/printf.c View File

@@ -0,0 +1,914 @@
///////////////////////////////////////////////////////////////////////////////
// \author (c) Marco Paland (info@paland.com)
// 2014-2019, PALANDesign Hannover, Germany
//
// \license The MIT License (MIT)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// \brief Tiny printf, sprintf and (v)snprintf implementation, optimized for speed on
// embedded systems with a very limited resources. These routines are thread
// safe and reentrant!
// Use this instead of the bloated standard/newlib printf cause these use
// malloc for printf (and may not be thread safe).
//
///////////////////////////////////////////////////////////////////////////////
#include <stdbool.h>
#include <stdint.h>
#include "printf.h"
// define this globally (e.g. gcc -DPRINTF_INCLUDE_CONFIG_H ...) to include the
// printf_config.h header file
// default: undefined
#ifdef PRINTF_INCLUDE_CONFIG_H
#include "printf_config.h"
#endif
// 'ntoa' conversion buffer size, this must be big enough to hold one converted
// numeric number including padded zeros (dynamically created on stack)
// default: 32 byte
#ifndef PRINTF_NTOA_BUFFER_SIZE
#define PRINTF_NTOA_BUFFER_SIZE 32U
#endif
// 'ftoa' conversion buffer size, this must be big enough to hold one converted
// float number including padded zeros (dynamically created on stack)
// default: 32 byte
#ifndef PRINTF_FTOA_BUFFER_SIZE
#define PRINTF_FTOA_BUFFER_SIZE 32U
#endif
// support for the floating point type (%f)
// default: activated
#ifndef PRINTF_DISABLE_SUPPORT_FLOAT
#define PRINTF_SUPPORT_FLOAT
#endif
// support for exponential floating point notation (%e/%g)
// default: activated
#ifndef PRINTF_DISABLE_SUPPORT_EXPONENTIAL
#define PRINTF_SUPPORT_EXPONENTIAL
#endif
// define the default floating point precision
// default: 6 digits
#ifndef PRINTF_DEFAULT_FLOAT_PRECISION
#define PRINTF_DEFAULT_FLOAT_PRECISION 6U
#endif
// define the largest float suitable to print with %f
// default: 1e9
#ifndef PRINTF_MAX_FLOAT
#define PRINTF_MAX_FLOAT 1e9
#endif
// support for the long long types (%llu or %p)
// default: activated
#ifndef PRINTF_DISABLE_SUPPORT_LONG_LONG
#define PRINTF_SUPPORT_LONG_LONG
#endif
// support for the ptrdiff_t type (%t)
// ptrdiff_t is normally defined in <stddef.h> as long or long long type
// default: activated
#ifndef PRINTF_DISABLE_SUPPORT_PTRDIFF_T
#define PRINTF_SUPPORT_PTRDIFF_T
#endif
///////////////////////////////////////////////////////////////////////////////
// internal flag definitions
#define FLAGS_ZEROPAD (1U << 0U)
#define FLAGS_LEFT (1U << 1U)
#define FLAGS_PLUS (1U << 2U)
#define FLAGS_SPACE (1U << 3U)
#define FLAGS_HASH (1U << 4U)
#define FLAGS_UPPERCASE (1U << 5U)
#define FLAGS_CHAR (1U << 6U)
#define FLAGS_SHORT (1U << 7U)
#define FLAGS_LONG (1U << 8U)
#define FLAGS_LONG_LONG (1U << 9U)
#define FLAGS_PRECISION (1U << 10U)
#define FLAGS_ADAPT_EXP (1U << 11U)
// import float.h for DBL_MAX
#if defined(PRINTF_SUPPORT_FLOAT)
#include <float.h>
#endif
// output function type
typedef void (*out_fct_type)(char character, void* buffer, size_t idx, size_t maxlen);
// wrapper (used as buffer) for output function type
typedef struct {
void (*fct)(char character, void* arg);
void* arg;
} out_fct_wrap_type;
// internal buffer output
static inline void _out_buffer(char character, void* buffer, size_t idx, size_t maxlen)
{
if (idx < maxlen) {
((char*)buffer)[idx] = character;
}
}
// internal null output
static inline void _out_null(char character, void* buffer, size_t idx, size_t maxlen)
{
(void)character; (void)buffer; (void)idx; (void)maxlen;
}
// internal _putchar wrapper
static inline void _out_char(char character, void* buffer, size_t idx, size_t maxlen)
{
(void)buffer; (void)idx; (void)maxlen;
if (character) {
_putchar(character);
}
}
// internal output function wrapper
static inline void _out_fct(char character, void* buffer, size_t idx, size_t maxlen)
{
(void)idx; (void)maxlen;
if (character) {
// buffer is the output fct pointer
((out_fct_wrap_type*)buffer)->fct(character, ((out_fct_wrap_type*)buffer)->arg);
}
}
// internal secure strlen
// \return The length of the string (excluding the terminating 0) limited by 'maxsize'
static inline unsigned int _strnlen_s(const char* str, size_t maxsize)
{
const char* s;
for (s = str; *s && maxsize--; ++s);
return (unsigned int)(s - str);
}
// internal test if char is a digit (0-9)
// \return true if char is a digit
static inline bool _is_digit(char ch)
{
return (ch >= '0') && (ch <= '9');
}
// internal ASCII string to unsigned int conversion
static unsigned int _atoi(const char** str)
{
unsigned int i = 0U;
while (_is_digit(**str)) {
i = i * 10U + (unsigned int)(*((*str)++) - '0');
}
return i;
}
// output the specified string in reverse, taking care of any zero-padding
static size_t _out_rev(out_fct_type out, char* buffer, size_t idx, size_t maxlen, const char* buf, size_t len, unsigned int width, unsigned int flags)
{
const size_t start_idx = idx;
// pad spaces up to given width
if (!(flags & FLAGS_LEFT) && !(flags & FLAGS_ZEROPAD)) {
for (size_t i = len; i < width; i++) {
out(' ', buffer, idx++, maxlen);
}
}
// reverse string
while (len) {
out(buf[--len], buffer, idx++, maxlen);
}
// append pad spaces up to given width
if (flags & FLAGS_LEFT) {
while (idx - start_idx < width) {
out(' ', buffer, idx++, maxlen);
}
}
return idx;
}
// internal itoa format
static size_t _ntoa_format(out_fct_type out, char* buffer, size_t idx, size_t maxlen, char* buf, size_t len, bool negative, unsigned int base, unsigned int prec, unsigned int width, unsigned int flags)
{
// pad leading zeros
if (!(flags & FLAGS_LEFT)) {
if (width && (flags & FLAGS_ZEROPAD) && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) {
width--;
}
while ((len < prec) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
buf[len++] = '0';
}
while ((flags & FLAGS_ZEROPAD) && (len < width) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
buf[len++] = '0';
}
}
// handle hash
if (flags & FLAGS_HASH) {
if (!(flags & FLAGS_PRECISION) && len && ((len == prec) || (len == width))) {
len--;
if (len && (base == 16U)) {
len--;
}
}
if ((base == 16U) && !(flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
buf[len++] = 'x';
}
else if ((base == 16U) && (flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
buf[len++] = 'X';
}
else if ((base == 2U) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
buf[len++] = 'b';
}
if (len < PRINTF_NTOA_BUFFER_SIZE) {
buf[len++] = '0';
}
}
if (len < PRINTF_NTOA_BUFFER_SIZE) {
if (negative) {
buf[len++] = '-';
}
else if (flags & FLAGS_PLUS) {
buf[len++] = '+'; // ignore the space if the '+' exists
}
else if (flags & FLAGS_SPACE) {
buf[len++] = ' ';
}
}
return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags);
}
// internal itoa for 'long' type
static size_t _ntoa_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long value, bool negative, unsigned long base, unsigned int prec, unsigned int width, unsigned int flags)
{
char buf[PRINTF_NTOA_BUFFER_SIZE];
size_t len = 0U;
// no hash for 0 values
if (!value) {
flags &= ~FLAGS_HASH;
}
// write if precision != 0 and value is != 0
if (!(flags & FLAGS_PRECISION) || value) {
do {
const char digit = (char)(value % base);
buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10;
value /= base;
} while (value && (len < PRINTF_NTOA_BUFFER_SIZE));
}
return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags);
}
// internal itoa for 'long long' type
#if defined(PRINTF_SUPPORT_LONG_LONG)
static size_t _ntoa_long_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long long value, bool negative, unsigned long long base, unsigned int prec, unsigned int width, unsigned int flags)