1if (NOT TARGET pico_double)
2    # library to be depended on - we make this depend on particular implementations using per target generator expressions
3    pico_add_library(pico_double)
4
5    # no custom implementation; falls thru to compiler
6    pico_add_library(pico_double_compiler)
7
8    target_include_directories(pico_double_headers SYSTEM INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include)
9
10    # add alias "default" which is just pico.
11    add_library(pico_double_default INTERFACE)
12    if (PICO_RISCV)
13        target_link_libraries(pico_double_default INTERFACE pico_double_compiler)
14    else()
15        target_link_libraries(pico_double_default INTERFACE pico_double_pico)
16    endif()
17
18    if (NOT PICO_DEFAULT_DOUBLE_IMPL)
19        set(PICO_DEFAULT_DOUBLE_IMPL pico_double_default)
20    endif()
21
22    target_link_libraries(pico_double INTERFACE
23            $<IF:$<BOOL:$<TARGET_PROPERTY:PICO_TARGET_DOUBLE_IMPL>>,$<TARGET_PROPERTY:PICO_TARGET_DOUBLE_IMPL>,${PICO_DEFAULT_DOUBLE_IMPL}>)
24
25    # todo maybe this should be pico_double_dcp (note FreeRTOS has a dependency on the LIB_PICO_DOUBLE_FOO)
26    pico_add_library(pico_double_pico)
27    if (PICO_RP2040)
28        target_sources(pico_double_pico INTERFACE
29                ${CMAKE_CURRENT_LIST_DIR}/double_aeabi_rp2040.S
30                ${CMAKE_CURRENT_LIST_DIR}/double_init_rom_rp2040.c
31                ${CMAKE_CURRENT_LIST_DIR}/double_math.c
32                ${CMAKE_CURRENT_LIST_DIR}/double_v1_rom_shim_rp2040.S
33        )
34    elseif(NOT PICO_RISCV)
35        target_sources(pico_double_pico INTERFACE
36                ${CMAKE_CURRENT_LIST_DIR}/double_math.c
37                ${CMAKE_CURRENT_LIST_DIR}/double_aeabi_dcp.S
38                ${CMAKE_CURRENT_LIST_DIR}/double_fma_dcp.S
39                ${CMAKE_CURRENT_LIST_DIR}/double_sci_m33.S
40                ${CMAKE_CURRENT_LIST_DIR}/double_conv_m33.S
41                )
42    endif()
43
44    target_link_libraries(pico_double_pico INTERFACE pico_bootrom pico_double_headers hardware_divider)
45
46    pico_add_library(pico_double_none)
47    target_sources(pico_double_none INTERFACE
48            ${CMAKE_CURRENT_LIST_DIR}/double_none.S
49            )
50
51    target_link_libraries(pico_double_none INTERFACE pico_double_headers)
52
53    target_compile_definitions(pico_double_none_headers INTERFACE
54            PICO_PRINTF_SUPPORT_FLOAT=0 # printing floats/doubles won't work, so we can save space by removing it
55    )
56
57    function(wrap_double_functions TARGET)
58        pico_wrap_function(${TARGET} __aeabi_dadd)
59        pico_wrap_function(${TARGET} __aeabi_ddiv)
60        pico_wrap_function(${TARGET} __aeabi_dmul)
61        pico_wrap_function(${TARGET} __aeabi_drsub)
62        pico_wrap_function(${TARGET} __aeabi_dsub)
63        pico_wrap_function(${TARGET} __aeabi_cdcmpeq)
64        pico_wrap_function(${TARGET} __aeabi_cdrcmple)
65        pico_wrap_function(${TARGET} __aeabi_cdcmple)
66        pico_wrap_function(${TARGET} __aeabi_dcmpeq)
67        pico_wrap_function(${TARGET} __aeabi_dcmplt)
68        pico_wrap_function(${TARGET} __aeabi_dcmple)
69        pico_wrap_function(${TARGET} __aeabi_dcmpge)
70        pico_wrap_function(${TARGET} __aeabi_dcmpgt)
71        pico_wrap_function(${TARGET} __aeabi_dcmpun)
72        pico_wrap_function(${TARGET} __aeabi_i2d)
73        pico_wrap_function(${TARGET} __aeabi_l2d)
74        pico_wrap_function(${TARGET} __aeabi_ui2d)
75        pico_wrap_function(${TARGET} __aeabi_ul2d)
76        pico_wrap_function(${TARGET} __aeabi_d2iz)
77        pico_wrap_function(${TARGET} __aeabi_d2lz)
78        pico_wrap_function(${TARGET} __aeabi_d2uiz)
79        pico_wrap_function(${TARGET} __aeabi_d2ulz)
80        pico_wrap_function(${TARGET} __aeabi_d2f)
81        pico_wrap_function(${TARGET} sqrt)
82        pico_wrap_function(${TARGET} cos)
83        pico_wrap_function(${TARGET} sin)
84        pico_wrap_function(${TARGET} tan)
85        pico_wrap_function(${TARGET} atan2)
86        pico_wrap_function(${TARGET} exp)
87        pico_wrap_function(${TARGET} log)
88
89        pico_wrap_function(${TARGET} ldexp)
90        pico_wrap_function(${TARGET} copysign)
91        pico_wrap_function(${TARGET} trunc)
92        pico_wrap_function(${TARGET} floor)
93        pico_wrap_function(${TARGET} ceil)
94        pico_wrap_function(${TARGET} round)
95        pico_wrap_function(${TARGET} sincos) # gnu
96        pico_wrap_function(${TARGET} asin)
97        pico_wrap_function(${TARGET} acos)
98        pico_wrap_function(${TARGET} atan)
99        pico_wrap_function(${TARGET} sinh)
100        pico_wrap_function(${TARGET} cosh)
101        pico_wrap_function(${TARGET} tanh)
102        pico_wrap_function(${TARGET} asinh)
103        pico_wrap_function(${TARGET} acosh)
104        pico_wrap_function(${TARGET} atanh)
105        pico_wrap_function(${TARGET} exp2)
106        pico_wrap_function(${TARGET} log2)
107        pico_wrap_function(${TARGET} exp10)
108        pico_wrap_function(${TARGET} log10)
109        pico_wrap_function(${TARGET} pow)
110        pico_wrap_function(${TARGET} powint) #gnu
111        pico_wrap_function(${TARGET} hypot)
112        pico_wrap_function(${TARGET} cbrt)
113        pico_wrap_function(${TARGET} fmod)
114        pico_wrap_function(${TARGET} drem)
115        pico_wrap_function(${TARGET} remainder)
116        pico_wrap_function(${TARGET} remquo)
117        pico_wrap_function(${TARGET} expm1)
118        pico_wrap_function(${TARGET} log1p)
119        pico_wrap_function(${TARGET} fma)
120    endfunction()
121
122    wrap_double_functions(pico_double_pico)
123    wrap_double_functions(pico_double_none)
124
125    macro(pico_set_double_implementation TARGET IMPL)
126        get_target_property(target_type ${TARGET} TYPE)
127        if ("EXECUTABLE" STREQUAL "${target_type}")
128            set_target_properties(${TARGET} PROPERTIES PICO_TARGET_DOUBLE_IMPL "pico_double_${IMPL}")
129        else()
130            message(FATAL_ERROR "double implementation must be set on executable not library")
131        endif()
132    endmacro()
133endif()
134