summaryrefslogtreecommitdiffstats
path: root/src/arch/arm32/libgcc
diff options
context:
space:
mode:
authorMichael Brown2016-05-08 01:18:35 +0200
committerMichael Brown2016-05-08 01:18:35 +0200
commitedea3a434ccae8dc980c715949287c9ba63babf5 (patch)
treed821d987dcf1ac0bc4f22e1363fa32c95f6bd0b2 /src/arch/arm32/libgcc
parent[arm] Avoid instruction references to symbols defined via ".equ" (diff)
downloadipxe-edea3a434ccae8dc980c715949287c9ba63babf5.tar.gz
ipxe-edea3a434ccae8dc980c715949287c9ba63babf5.tar.xz
ipxe-edea3a434ccae8dc980c715949287c9ba63babf5.zip
[arm] Split out 32-bit-specific code to arch/arm32
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/arch/arm32/libgcc')
-rw-r--r--src/arch/arm32/libgcc/lldivmod.S50
-rw-r--r--src/arch/arm32/libgcc/llshift.S88
2 files changed, 138 insertions, 0 deletions
diff --git a/src/arch/arm32/libgcc/lldivmod.S b/src/arch/arm32/libgcc/lldivmod.S
new file mode 100644
index 00000000..910be4b7
--- /dev/null
+++ b/src/arch/arm32/libgcc/lldivmod.S
@@ -0,0 +1,50 @@
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
+
+ .text
+ .thumb
+
+/**
+ * Unsigned long long division
+ *
+ * @v r1:r0 Dividend
+ * @v r3:r2 Divisor
+ * @ret r1:r0 Quotient
+ * @ret r3:r2 Remainder
+ */
+ .section ".text.__aeabi_uldivmod", "ax", %progbits
+ .globl __aeabi_uldivmod
+ .type __aeabi_uldivmod, %function
+__aeabi_uldivmod:
+ /* Allocate stack space for remainder and pointer to remainder */
+ push {r0, r1, r2, r3, r4, lr}
+ /* Call __udivmoddi4() */
+ add r4, sp, #8
+ str r4, [sp]
+ bl __udivmoddi4
+ /* Retrieve remainder and return */
+ add sp, sp, #8
+ pop {r2, r3, r4, pc}
+ .size __aeabi_uldivmod, . - __aeabi_uldivmod
+
+/**
+ * Signed long long division
+ *
+ * @v r1:r0 Dividend
+ * @v r3:r2 Divisor
+ * @ret r1:r0 Quotient
+ * @ret r3:r2 Remainder
+ */
+ .section ".text.__aeabi_ldivmod", "ax", %progbits
+ .globl __aeabi_ldivmod
+ .type __aeabi_ldivmod, %function
+__aeabi_ldivmod:
+ /* Allocate stack space for remainder and pointer to remainder */
+ push {r0, r1, r2, r3, r4, lr}
+ /* Call __divmoddi4() */
+ add r4, sp, #8
+ str r4, [sp]
+ bl __divmoddi4
+ /* Retrieve remainder and return */
+ add sp, sp, #8
+ pop {r2, r3, r4, pc}
+ .size __aeabi_ldivmod, . - __aeabi_ldivmod
diff --git a/src/arch/arm32/libgcc/llshift.S b/src/arch/arm32/libgcc/llshift.S
new file mode 100644
index 00000000..cc16e261
--- /dev/null
+++ b/src/arch/arm32/libgcc/llshift.S
@@ -0,0 +1,88 @@
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
+
+ .text
+ .arm
+
+/**
+ * Logical shift left
+ *
+ * @v r1:r0 Value to shift
+ * @v r2 Shift amount
+ * @ret r1:r0 Shifted value
+ */
+ .section ".text.__aeabi_llsl", "ax", %progbits
+ .globl __aeabi_llsl
+ .type __aeabi_llsl, %function
+__aeabi_llsl:
+ /* r3 = ( shift - 32 ) */
+ subs r3, r2, #32
+ /* If shift >= 32, then
+ * high = ( low << ( shift - 32 ) )
+ */
+ movpl r1, r0, lsl r3
+ /* If shift < 32, then
+ * high = ( ( high << shift ) | ( low >> ( 32 - shift ) ) )
+ */
+ movmi r1, r1, lsl r2
+ rsbmi r3, r2, #32
+ orrmi r1, r1, r0, lsr r3
+ /* low = ( low << shift ) */
+ mov r0, r0, lsl r2
+ bx lr
+ .size __aeabi_llsl, . - __aeabi_llsl
+
+/**
+ * Logical shift right
+ *
+ * @v r1:r0 Value to shift
+ * @v r2 Shift amount
+ * @ret r1:r0 Shifted value
+ */
+ .section ".text.__aeabi_llsr", "ax", %progbits
+ .globl __aeabi_llsr
+ .type __aeabi_llsr, %function
+__aeabi_llsr:
+ /* r3 = ( shift - 32 ) */
+ subs r3, r2, #32
+ /* If shift >= 32, then
+ * low = ( high >> ( shift - 32 ) )
+ */
+ movpl r0, r1, lsr r3
+ /* If shift < 32, then
+ * low = ( ( low >> shift ) | ( high << ( 32 - shift ) ) )
+ */
+ movmi r0, r0, lsr r2
+ rsbmi r3, r2, #32
+ orrmi r0, r0, r1, lsl r3
+ /* high = ( high >> shift ) */
+ mov r1, r1, lsr r2
+ bx lr
+ .size __aeabi_llsr, . - __aeabi_llsr
+
+/**
+ * Arithmetic shift right
+ *
+ * @v r1:r0 Value to shift
+ * @v r2 Shift amount
+ * @ret r1:r0 Shifted value
+ */
+ .section ".text.__aeabi_lasr", "ax", %progbits
+ .globl __aeabi_lasr
+ .type __aeabi_lasr, %function
+__aeabi_lasr:
+ /* r3 = ( shift - 32 ) */
+ subs r3, r2, #32
+ /* If shift >= 32, then
+ * low = ( high >> ( shift - 32 ) )
+ */
+ movpl r0, r1, asr r3
+ /* If shift < 32, then
+ * low = ( ( low >> shift ) | ( high << ( 32 - shift ) ) )
+ */
+ movmi r0, r0, lsr r2
+ rsbmi r3, r2, #32
+ orrmi r0, r0, r1, lsl r3
+ /* high = ( high >> shift ) */
+ mov r1, r1, asr r2
+ bx lr
+ .size __aeabi_lasr, . - __aeabi_lasr