diff --git a/arch/x86/core/Kconfig.ia32 b/arch/x86/core/Kconfig.ia32 index 593ba0da84a..864318a5f8f 100644 --- a/arch/x86/core/Kconfig.ia32 +++ b/arch/x86/core/Kconfig.ia32 @@ -86,7 +86,8 @@ config X86_PAE more memory for paging structures. menu "Architecture Floating Point Options" -depends on CPU_HAS_FPU + +if CPU_HAS_FPU config SSE bool "SSE registers" @@ -138,6 +139,15 @@ config LAZY_FPU_SHARING malware to read the contents of all floating point registers, see CVE-2018-3665. +endif # CPU_HAS_FPU + +config X86_FP_USE_SOFT_FLOAT + bool + prompt "Use Software Floating Point Operations" if !(NEWLIB_LIBC && !FPU) + default y if NEWLIB_LIBC && !FPU + help + Enable using software floating point operations. + endmenu config DCACHE_LINE_SIZE diff --git a/arch/x86/core/ia32.cmake b/arch/x86/core/ia32.cmake index f10276052fe..87964172e98 100644 --- a/arch/x86/core/ia32.cmake +++ b/arch/x86/core/ia32.cmake @@ -33,3 +33,8 @@ zephyr_library_sources_ifdef( # Last since we declare default exception handlers here zephyr_library_sources(ia32/fatal.c) + +zephyr_library_sources_ifdef( + CONFIG_X86_FP_USE_SOFT_FLOAT + ia32/soft_float_stubs.c +) diff --git a/arch/x86/core/ia32/soft_float_stubs.c b/arch/x86/core/ia32/soft_float_stubs.c new file mode 100644 index 00000000000..fe3e81a1b32 --- /dev/null +++ b/arch/x86/core/ia32/soft_float_stubs.c @@ -0,0 +1,280 @@ +/* + * Copyright (c) 2021 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/** + * @file + * @brief Provide soft float function stubs for long double operations. + * + * GCC soft float does not support long double so these need to be + * stubbed out. + * + * The function names come from the GCC public documentation. + */ + +extern void abort(void); + +__weak void __addtf3(long double a, long double b) +{ + k_oops(); +} + +__weak void __addxf3(long double a, long double b) +{ + k_oops(); +} + +__weak void __subtf3(long double a, long double b) +{ + k_oops(); +} + +__weak void __subxf3(long double a, long double b) +{ + k_oops(); +} + +__weak void __multf3(long double a, long double b) +{ + k_oops(); +} + +__weak void __mulxf3(long double a, long double b) +{ + k_oops(); +} + +__weak void __divtf3(long double a, long double b) +{ + k_oops(); +} + +__weak void __divxf3(long double a, long double b) +{ + k_oops(); +} + +__weak void __negtf2(long double a) +{ + k_oops(); +} + +__weak void __negxf2(long double a) +{ + k_oops(); +} + +__weak void __extendsftf2(float a) +{ + k_oops(); +} + +__weak void __extendsfxf2(float a) +{ + k_oops(); +} + +__weak void __extenddftf2(double a) +{ + k_oops(); +} + +__weak void __extenddfxf2(double a) +{ + k_oops(); +} + +__weak void __truncxfdf2(long double a) +{ + k_oops(); +} + +__weak void __trunctfdf2(long double a) +{ + k_oops(); +} + +__weak void __truncxfsf2(long double a) +{ + k_oops(); +} + +__weak void __trunctfsf2(long double a) +{ + k_oops(); +} + +__weak void __fixtfsi(long double a) +{ + k_oops(); +} + +__weak void __fixxfsi(long double a) +{ + k_oops(); +} + +__weak void __fixtfdi(long double a) +{ + k_oops(); +} + +__weak void __fixxfdi(long double a) +{ + k_oops(); +} + +__weak void __fixtfti(long double a) +{ + k_oops(); +} + +__weak void __fixxfti(long double a) +{ + k_oops(); +} + +__weak void __fixunstfsi(long double a) +{ + k_oops(); +} + +__weak void __fixunsxfsi(long double a) +{ + k_oops(); +} + +__weak void __fixunstfdi(long double a) +{ + k_oops(); +} + +__weak void __fixunsxfdi(long double a) +{ + k_oops(); +} + +__weak void __fixunstfti(long double a) +{ + k_oops(); +} + +__weak void __fixunsxfti(long double a) +{ + k_oops(); +} + +__weak void __floatsitf(int i) +{ + k_oops(); +} + +__weak void __floatsixf(int i) +{ + k_oops(); +} + +__weak void __floatditf(long i) +{ + k_oops(); +} + +__weak void __floatdixf(long i) +{ + k_oops(); +} + +__weak void __floattitf(long long i) +{ + k_oops(); +} + +__weak void __floattixf(long long i) +{ + k_oops(); +} + +__weak void __floatunsitf(unsigned int i) +{ + k_oops(); +} + +__weak void __floatunsixf(unsigned int i) +{ + k_oops(); +} + +__weak void __floatunditf(unsigned long i) +{ + k_oops(); +} + +__weak void __floatundixf(unsigned long i) +{ + k_oops(); +} + +__weak void __floatuntitf(unsigned long long i) +{ + k_oops(); +} + +__weak void __floatuntixf(unsigned long long i) +{ + k_oops(); +} + +__weak void __cmptf2(long double a, long double b) +{ + k_oops(); +} + +__weak void __unordtf2(long double a, long double b) +{ + k_oops(); +} + +__weak void __eqtf2(long double a, long double b) +{ + k_oops(); +} + +__weak void __netf2(long double a, long double b) +{ + k_oops(); +} + +__weak void __getf2(long double a, long double b) +{ + k_oops(); +} + +__weak void __lttf2(long double a, long double b) +{ + k_oops(); +} + +__weak void __letf2(long double a, long double b) +{ + k_oops(); +} + +__weak void __gttf2(long double a, long double b) +{ + k_oops(); +} + +__weak void __powitf2(long double a, int b) +{ + k_oops(); +} + +__weak void __powixf2(long double a, int b) +{ + k_oops(); +} diff --git a/cmake/compiler/gcc/target_x86.cmake b/cmake/compiler/gcc/target_x86.cmake index 4684945e751..8dac67a0068 100644 --- a/cmake/compiler/gcc/target_x86.cmake +++ b/cmake/compiler/gcc/target_x86.cmake @@ -8,6 +8,11 @@ else() string(PREPEND CMAKE_ASM_FLAGS "-m32 ") string(PREPEND CMAKE_C_FLAGS "-m32 ") string(PREPEND CMAKE_CXX_FLAGS "-m32 ") + + if(CONFIG_X86_FP_USE_SOFT_FLOAT) + list(APPEND TOOLCHAIN_C_FLAGS -msoft-float) + list(APPEND TOOLCHAIN_LD_FLAGS -msoft-float) + endif() endif() # GNU Assembler, by default on non-Linux targets, treats slashes as