diff options
39 files changed, 143 insertions, 0 deletions
diff --git a/lib/adddf3.c b/lib/adddf3.c index 5338a4b4f..16b394c2b 100644 --- a/lib/adddf3.c +++ b/lib/adddf3.c @@ -12,9 +12,13 @@ // //===----------------------------------------------------------------------===// +#include "int_lib.h" + #define DOUBLE_PRECISION #include "fp_lib.h" +ARM_EABI_FNALIAS(dadd, adddf3); + fp_t __adddf3(fp_t a, fp_t b) { rep_t aRep = toRep(a); diff --git a/lib/addsf3.c b/lib/addsf3.c index 061528b35..d4ee2c4c4 100644 --- a/lib/addsf3.c +++ b/lib/addsf3.c @@ -15,6 +15,10 @@ #define SINGLE_PRECISION #include "fp_lib.h" +#include "int_lib.h" + +ARM_EABI_FNALIAS(fadd, addsf3); + fp_t __addsf3(fp_t a, fp_t b) { rep_t aRep = toRep(a); diff --git a/lib/arm/divsi3.S b/lib/arm/divsi3.S index 045ae4fdb..00e61815a 100644 --- a/lib/arm/divsi3.S +++ b/lib/arm/divsi3.S @@ -22,6 +22,8 @@ .syntax unified .align 3 +// Ok, APCS and AAPCS agree on 32 bit args, so it's safe to use the same routine. +DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_idiv, __divsi3) DEFINE_COMPILERRT_FUNCTION(__divsi3) ESTABLISH_FRAME // Set aside the sign of the quotient. diff --git a/lib/arm/udivsi3.S b/lib/arm/udivsi3.S index 59a71b0b2..6d8966539 100644 --- a/lib/arm/udivsi3.S +++ b/lib/arm/udivsi3.S @@ -30,6 +30,8 @@ .syntax unified .align 3 +// Ok, APCS and AAPCS agree on 32 bit args, so it's safe to use the same routine. +DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_uidiv, __udivsi3) DEFINE_COMPILERRT_FUNCTION(__udivsi3) // We use a simple digit by digit algorithm; before we get into the actual // divide loop, we must calculate the left-shift amount necessary to align diff --git a/lib/ashldi3.c b/lib/ashldi3.c index 1067e6fc6..65bd7b202 100644 --- a/lib/ashldi3.c +++ b/lib/ashldi3.c @@ -18,6 +18,8 @@ /* Precondition: 0 <= b < bits_in_dword */ +ARM_EABI_FNALIAS(llsl, ashldi3); + di_int __ashldi3(di_int a, si_int b) { diff --git a/lib/ashrdi3.c b/lib/ashrdi3.c index 94d46f1b4..cd0855dd7 100644 --- a/lib/ashrdi3.c +++ b/lib/ashrdi3.c @@ -18,6 +18,8 @@ /* Precondition: 0 <= b < bits_in_dword */ +ARM_EABI_FNALIAS(lasr, ashrdi3); + di_int __ashrdi3(di_int a, si_int b) { diff --git a/lib/assembly.h b/lib/assembly.h index 928f5fd70..245f96d88 100644 --- a/lib/assembly.h +++ b/lib/assembly.h @@ -55,4 +55,15 @@ HIDDEN_DIRECTIVE name SEPARATOR \ name: +#define DEFINE_COMPILERRT_FUNCTION_ALIAS(name, target) \ + .globl SYMBOL_NAME(name) SEPARATOR \ + .set SYMBOL_NAME(name), SYMBOL_NAME(target) SEPARATOR + +#if defined (__ARM_EABI__) +# define DEFINE_AEABI_FUNCTION_ALIAS(aeabi_name, name) \ + DEFINE_COMPILERRT_FUNCTION_ALIAS(aeabi_name, name) +#else +# define DEFINE_AEABI_FUNCTION_ALIAS(aeabi_name, name) +#endif + #endif /* COMPILERRT_ASSEMBLY_H */ diff --git a/lib/divdf3.c b/lib/divdf3.c index 217d284bf..820b4c851 100644 --- a/lib/divdf3.c +++ b/lib/divdf3.c @@ -19,6 +19,10 @@ #define DOUBLE_PRECISION #include "fp_lib.h" +#include "int_lib.h" + +ARM_EABI_FNALIAS(ddiv, divdf3); + fp_t __divdf3(fp_t a, fp_t b) { const unsigned int aExponent = toRep(a) >> significandBits & maxExponent; diff --git a/lib/divsf3.c b/lib/divsf3.c index b798cfb03..84e9a37a0 100644 --- a/lib/divsf3.c +++ b/lib/divsf3.c @@ -19,6 +19,10 @@ #define SINGLE_PRECISION #include "fp_lib.h" +#include "int_lib.h" + +ARM_EABI_FNALIAS(fdiv, divsf3); + fp_t __divsf3(fp_t a, fp_t b) { const unsigned int aExponent = toRep(a) >> significandBits & maxExponent; diff --git a/lib/divsi3.c b/lib/divsi3.c index c48ecf45d..db2b6e80f 100644 --- a/lib/divsi3.c +++ b/lib/divsi3.c @@ -18,6 +18,8 @@ su_int __udivsi3(su_int n, su_int d); /* Returns: a / b */ +ARM_EABI_FNALIAS(idiv, divsi3); + si_int __divsi3(si_int a, si_int b) { diff --git a/lib/extendsfdf2.c b/lib/extendsfdf2.c index db65acf97..a63015430 100644 --- a/lib/extendsfdf2.c +++ b/lib/extendsfdf2.c @@ -41,6 +41,8 @@ #include <stdint.h> #include <limits.h> +#include "int_lib.h" + typedef float src_t; typedef uint32_t src_rep_t; #define SRC_REP_C UINT32_C @@ -67,6 +69,8 @@ static inline dst_t dstFromRep(dst_rep_t x) { // End helper routines. Conversion implementation follows. +ARM_EABI_FNALIAS(f2d, extendsfdf2); + dst_t __extendsfdf2(src_t a) { // Various constants whose values follow from the type parameters. diff --git a/lib/fixdfdi.c b/lib/fixdfdi.c index 3a760ff24..c6732dbbb 100644 --- a/lib/fixdfdi.c +++ b/lib/fixdfdi.c @@ -23,6 +23,8 @@ /* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */ +ARM_EABI_FNALIAS(d2lz, fixdfdi); + di_int __fixdfdi(double a) { diff --git a/lib/fixdfsi.c b/lib/fixdfsi.c index 98062abce..3d4379e8f 100644 --- a/lib/fixdfsi.c +++ b/lib/fixdfsi.c @@ -16,6 +16,10 @@ #define DOUBLE_PRECISION #include "fp_lib.h" +#include "int_lib.h" + +ARM_EABI_FNALIAS(d2iz, fixdfsi); + int __fixdfsi(fp_t a) { // Break a into sign, exponent, significand diff --git a/lib/fixsfdi.c b/lib/fixsfdi.c index 1a8530652..e32b85fd6 100644 --- a/lib/fixsfdi.c +++ b/lib/fixsfdi.c @@ -23,6 +23,8 @@ /* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */ +ARM_EABI_FNALIAS(d2lz, fixsfdi); + di_int __fixsfdi(float a) { diff --git a/lib/fixsfsi.c b/lib/fixsfsi.c index b68471d7c..4cdc47f7b 100644 --- a/lib/fixsfsi.c +++ b/lib/fixsfsi.c @@ -16,6 +16,10 @@ #define SINGLE_PRECISION #include "fp_lib.h" +#include "int_lib.h" + +ARM_EABI_FNALIAS(f2iz, fixsfsi); + int __fixsfsi(fp_t a) { // Break a into sign, exponent, significand diff --git a/lib/fixunsdfdi.c b/lib/fixunsdfdi.c index 1c78e2bb1..1721d3339 100644 --- a/lib/fixunsdfdi.c +++ b/lib/fixunsdfdi.c @@ -26,6 +26,8 @@ /* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */ +ARM_EABI_FNALIAS(d2ulz, fixunsdfdi); + du_int __fixunsdfdi(double a) { diff --git a/lib/fixunsdfsi.c b/lib/fixunsdfsi.c index e02989156..7a803f2d3 100644 --- a/lib/fixunsdfsi.c +++ b/lib/fixunsdfsi.c @@ -26,6 +26,8 @@ /* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */ +ARM_EABI_FNALIAS(d2uiz, fixunsdfsi); + su_int __fixunsdfsi(double a) { diff --git a/lib/fixunssfdi.c b/lib/fixunssfdi.c index 3b1bc4af9..3d7d95c86 100644 --- a/lib/fixunssfdi.c +++ b/lib/fixunssfdi.c @@ -26,6 +26,10 @@ /* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */ +#include "int_lib.h" + +ARM_EABI_FNALIAS(f2ulz, fixunssfdi); + du_int __fixunssfdi(float a) { diff --git a/lib/fixunssfsi.c b/lib/fixunssfsi.c index 023d7b244..b822ffe73 100644 --- a/lib/fixunssfsi.c +++ b/lib/fixunssfsi.c @@ -26,6 +26,8 @@ /* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */ +ARM_EABI_FNALIAS(f2uiz, fixunssfsi); + su_int __fixunssfsi(float a) { diff --git a/lib/floatdidf.c b/lib/floatdidf.c index cad354a57..1633f7384 100644 --- a/lib/floatdidf.c +++ b/lib/floatdidf.c @@ -23,6 +23,10 @@ /* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */ +#include "int_lib.h" + +ARM_EABI_FNALIAS(l2d, floatdidf); + #ifndef __SOFT_FP__ /* Support for systems that have hardware floating-point; we'll set the inexact flag * as a side-effect of this computation. diff --git a/lib/floatdisf.c b/lib/floatdisf.c index 71d603b56..cdede6c75 100644 --- a/lib/floatdisf.c +++ b/lib/floatdisf.c @@ -23,6 +23,10 @@ /* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */ +#include "int_lib.h" + +ARM_EABI_FNALIAS(l2f, floatdisf); + float __floatdisf(di_int a) { diff --git a/lib/floatsidf.c b/lib/floatsidf.c index 85facea16..74cb66b2a 100644 --- a/lib/floatsidf.c +++ b/lib/floatsidf.c @@ -16,6 +16,10 @@ #define DOUBLE_PRECISION #include "fp_lib.h" +#include "int_lib.h" + +ARM_EABI_FNALIAS(i2d, floatsidf); + fp_t __floatsidf(int a) { const int aWidth = sizeof a * CHAR_BIT; diff --git a/lib/floatsisf.c b/lib/floatsisf.c index d1bb46076..a981391b0 100644 --- a/lib/floatsisf.c +++ b/lib/floatsisf.c @@ -16,6 +16,10 @@ #define SINGLE_PRECISION #include "fp_lib.h" +#include "int_lib.h" + +ARM_EABI_FNALIAS(i2f, floatsisf); + fp_t __floatsisf(int a) { const int aWidth = sizeof a * CHAR_BIT; diff --git a/lib/floatundidf.c b/lib/floatundidf.c index 506fc3c4b..64bec04e5 100644 --- a/lib/floatundidf.c +++ b/lib/floatundidf.c @@ -23,6 +23,10 @@ /* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */ +#include "int_lib.h" + +ARM_EABI_FNALIAS(ul2d, floatundidf); + #ifndef __SOFT_FP__ /* Support for systems that have hardware floating-point; we'll set the inexact flag * as a side-effect of this computation. diff --git a/lib/floatundisf.c b/lib/floatundisf.c index 55e40230e..2d2a51458 100644 --- a/lib/floatundisf.c +++ b/lib/floatundisf.c @@ -23,6 +23,10 @@ /* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */ +#include "int_lib.h" + +ARM_EABI_FNALIAS(ul2f, floatundisf); + float __floatundisf(du_int a) { diff --git a/lib/floatunsidf.c b/lib/floatunsidf.c index 0f473aa1a..0722248dd 100644 --- a/lib/floatunsidf.c +++ b/lib/floatunsidf.c @@ -16,6 +16,10 @@ #define DOUBLE_PRECISION #include "fp_lib.h" +#include "int_lib.h" + +ARM_EABI_FNALIAS(ui2d, floatunsidf); + fp_t __floatunsidf(unsigned int a) { const int aWidth = sizeof a * CHAR_BIT; diff --git a/lib/floatunsisf.c b/lib/floatunsisf.c index 48eff93a2..3dc1cd442 100644 --- a/lib/floatunsisf.c +++ b/lib/floatunsisf.c @@ -16,6 +16,10 @@ #define SINGLE_PRECISION #include "fp_lib.h" +#include "int_lib.h" + +ARM_EABI_FNALIAS(ui2f, floatunsisf); + fp_t __floatunsisf(unsigned int a) { const int aWidth = sizeof a * CHAR_BIT; diff --git a/lib/int_lib.h b/lib/int_lib.h index e1fd6b73d..c0224ce74 100644 --- a/lib/int_lib.h +++ b/lib/int_lib.h @@ -37,6 +37,13 @@ extern void panic (const char *, ...); #define INFINITY HUGE_VAL #endif /* INFINITY */ +#if __ARM_EABI__ +# define ARM_EABI_FNALIAS(aeabi_name, name) \ + void __aeabi_##aeabi_name() __attribute__((alias("__" #name))); +#else +# define ARM_EABI_FNALIAS(aeabi_name, name) +#endif + typedef int si_int; typedef unsigned su_int; diff --git a/lib/lshrdi3.c b/lib/lshrdi3.c index 84525b78a..7468cb739 100644 --- a/lib/lshrdi3.c +++ b/lib/lshrdi3.c @@ -18,6 +18,8 @@ /* Precondition: 0 <= b < bits_in_dword */ +ARM_EABI_FNALIAS(llsr, lshrdi3); + di_int __lshrdi3(di_int a, si_int b) { diff --git a/lib/muldf3.c b/lib/muldf3.c index 85672e584..5cfe62bca 100644 --- a/lib/muldf3.c +++ b/lib/muldf3.c @@ -15,6 +15,10 @@ #define DOUBLE_PRECISION #include "fp_lib.h" +#include "int_lib.h" + +ARM_EABI_FNALIAS(dmul, muldf3); + fp_t __muldf3(fp_t a, fp_t b) { const unsigned int aExponent = toRep(a) >> significandBits & maxExponent; diff --git a/lib/muldi3.c b/lib/muldi3.c index 43637324b..537b7357f 100644 --- a/lib/muldi3.c +++ b/lib/muldi3.c @@ -40,6 +40,8 @@ __muldsi3(su_int a, su_int b) /* Returns: a * b */ +ARM_EABI_FNALIAS(lmul, muldi3); + di_int __muldi3(di_int a, di_int b) { diff --git a/lib/mulsf3.c b/lib/mulsf3.c index dd4ce11a0..96dcfd9e4 100644 --- a/lib/mulsf3.c +++ b/lib/mulsf3.c @@ -15,6 +15,10 @@ #define SINGLE_PRECISION #include "fp_lib.h" +#include "int_lib.h" + +ARM_EABI_FNALIAS(fmul, mulsf3); + fp_t __mulsf3(fp_t a, fp_t b) { const unsigned int aExponent = toRep(a) >> significandBits & maxExponent; diff --git a/lib/negdf2.c b/lib/negdf2.c index aeae2e8a3..9344ae105 100644 --- a/lib/negdf2.c +++ b/lib/negdf2.c @@ -14,6 +14,10 @@ #define DOUBLE_PRECISION #include "fp_lib.h" +#include "int_lib.h" + +ARM_EABI_FNALIAS(dneg, negdf2); + fp_t __negdf2(fp_t a) { return fromRep(toRep(a) ^ signBit); } diff --git a/lib/negsf2.c b/lib/negsf2.c index d211f7cc8..6b0e62c5b 100644 --- a/lib/negsf2.c +++ b/lib/negsf2.c @@ -14,6 +14,10 @@ #define SINGLE_PRECISION #include "fp_lib.h" +#include "int_lib.h" + +ARM_EABI_FNALIAS(fneg, negsf2); + fp_t __negsf2(fp_t a) { return fromRep(toRep(a) ^ signBit); } diff --git a/lib/subdf3.c b/lib/subdf3.c index 241bf1b12..d9ed494f4 100644 --- a/lib/subdf3.c +++ b/lib/subdf3.c @@ -15,9 +15,16 @@ #define DOUBLE_PRECISION #include "fp_lib.h" +#include "int_lib.h" + fp_t __adddf3(fp_t a, fp_t b); + +ARM_EABI_FNALIAS(dsub, subdf3); + // Subtraction; flip the sign bit of b and add. fp_t __subdf3(fp_t a, fp_t b) { return __adddf3(a, fromRep(toRep(b) ^ signBit)); } + +/* FIXME: rsub for ARM EABI */ diff --git a/lib/subsf3.c b/lib/subsf3.c index 9ce14d7ac..5345eb23a 100644 --- a/lib/subsf3.c +++ b/lib/subsf3.c @@ -15,9 +15,15 @@ #define SINGLE_PRECISION #include "fp_lib.h" +#include "int_lib.h" + fp_t __addsf3(fp_t a, fp_t b); +ARM_EABI_FNALIAS(fsub, subsf3); + // Subtraction; flip the sign bit of b and add. fp_t __subsf3(fp_t a, fp_t b) { return __addsf3(a, fromRep(toRep(b) ^ signBit)); } + +/* FIXME: rsub for ARM EABI */ diff --git a/lib/truncdfsf2.c b/lib/truncdfsf2.c index 92609fb78..f3de21959 100644 --- a/lib/truncdfsf2.c +++ b/lib/truncdfsf2.c @@ -41,6 +41,8 @@ #include <limits.h> #include <stdbool.h> +#include "int_lib.h" + typedef double src_t; typedef uint64_t src_rep_t; #define SRC_REP_C UINT64_C @@ -66,6 +68,8 @@ static inline dst_t dstFromRep(dst_rep_t x) { // End helper routines. Conversion implementation follows. +ARM_EABI_FNALIAS(d2f, truncdfsf2); + dst_t __truncdfsf2(src_t a) { // Various constants whose values follow from the type parameters. diff --git a/lib/udivmoddi4.c b/lib/udivmoddi4.c index 693736fb8..6b8c4e819 100644 --- a/lib/udivmoddi4.c +++ b/lib/udivmoddi4.c @@ -20,6 +20,8 @@ /* Translated from Figure 3-40 of The PowerPC Compiler Writer's Guide */ +ARM_EABI_FNALIAS(uldivmod, udivmoddi4); + du_int __udivmoddi4(du_int a, du_int b, du_int* rem) { diff --git a/lib/udivsi3.c b/lib/udivsi3.c index 476f2bc31..8a5695d20 100644 --- a/lib/udivsi3.c +++ b/lib/udivsi3.c @@ -18,6 +18,8 @@ /* Translated from Figure 3-40 of The PowerPC Compiler Writer's Guide */ +ARM_EABI_FNALIAS(uidiv, udivsi3); + su_int __udivsi3(su_int n, su_int d) { |