1load("//bazel:defs.bzl", "compatible_with_rp2", "incompatible_with_config")
2
3package(default_visibility = ["//visibility:public"])
4
5_WRAP_FLOAT_AEABI_FLAGS = [
6    "-Wl,--wrap=__aeabi_fadd",
7    "-Wl,--wrap=__aeabi_fdiv",
8    "-Wl,--wrap=__aeabi_fmul",
9    "-Wl,--wrap=__aeabi_frsub",
10    "-Wl,--wrap=__aeabi_fsub",
11    "-Wl,--wrap=__aeabi_cfcmpeq",
12    "-Wl,--wrap=__aeabi_cfrcmple",
13    "-Wl,--wrap=__aeabi_cfcmple",
14    "-Wl,--wrap=__aeabi_fcmpeq",
15    "-Wl,--wrap=__aeabi_fcmplt",
16    "-Wl,--wrap=__aeabi_fcmple",
17    "-Wl,--wrap=__aeabi_fcmpge",
18    "-Wl,--wrap=__aeabi_fcmpgt",
19    "-Wl,--wrap=__aeabi_fcmpun",
20    "-Wl,--wrap=__aeabi_i2f",
21    "-Wl,--wrap=__aeabi_l2f",
22    "-Wl,--wrap=__aeabi_ui2f",
23    "-Wl,--wrap=__aeabi_ul2f",
24    "-Wl,--wrap=__aeabi_f2iz",
25    "-Wl,--wrap=__aeabi_f2lz",
26    "-Wl,--wrap=__aeabi_f2uiz",
27    "-Wl,--wrap=__aeabi_f2ulz",
28    "-Wl,--wrap=__aeabi_f2d",
29    "-Wl,--wrap=sqrtf",
30]
31
32_WRAP_FLOAT_SCI_FLAGS = [
33    "-Wl,--wrap=cosf",
34    "-Wl,--wrap=sinf",
35    "-Wl,--wrap=tanf",
36    "-Wl,--wrap=atan2f",
37    "-Wl,--wrap=expf",
38    "-Wl,--wrap=logf",
39    "-Wl,--wrap=ldexpf",
40    "-Wl,--wrap=copysignf",
41    "-Wl,--wrap=truncf",
42    "-Wl,--wrap=floorf",
43    "-Wl,--wrap=ceilf",
44    "-Wl,--wrap=roundf",
45    "-Wl,--wrap=sincosf",  # gnu
46    "-Wl,--wrap=asinf",
47    "-Wl,--wrap=acosf",
48    "-Wl,--wrap=atanf",
49    "-Wl,--wrap=sinhf",
50    "-Wl,--wrap=coshf",
51    "-Wl,--wrap=tanhf",
52    "-Wl,--wrap=asinhf",
53    "-Wl,--wrap=acoshf",
54    "-Wl,--wrap=atanhf",
55    "-Wl,--wrap=exp2f",
56    "-Wl,--wrap=log2f",
57    "-Wl,--wrap=exp10f",
58    "-Wl,--wrap=log10f",
59    "-Wl,--wrap=powf",
60    "-Wl,--wrap=powintf",  # gnu
61    "-Wl,--wrap=hypotf",
62    "-Wl,--wrap=cbrtf",
63    "-Wl,--wrap=fmodf",
64    "-Wl,--wrap=dremf",
65    "-Wl,--wrap=remainderf",
66    "-Wl,--wrap=remquof",
67    "-Wl,--wrap=expm1f",
68    "-Wl,--wrap=log1pf",
69    "-Wl,--wrap=fmaf",
70]
71
72alias(
73    name = "pico_float",
74    actual = select({
75        "//bazel/constraint:pico_float_auto_enabled": ":pico_float_platform_default",
76        "//bazel/constraint:pico_float_compiler_enabled": ":pico_float_compiler",
77        "//bazel/constraint:pico_float_dcp_enabled": ":pico_float_dcp",
78        "//bazel/constraint:pico_float_rp2040_enabled": ":pico_float_pico",
79        "//bazel/constraint:pico_float_vfp_enabled": ":pico_float_vfp",
80        "//conditions:default": ":pico_float_none",
81    }),
82)
83
84alias(
85    name = "pico_float_platform_default",
86    actual = select({
87        "//bazel/constraint:rp2040": ":pico_float_pico",
88        "@platforms//cpu:armv8-m": ":pico_float_vfp",
89        "@platforms//cpu:riscv32": ":pico_float_single_hazard3",
90        "//conditions:default": ":pico_float_compiler",
91    }),
92    visibility = ["//visibility:private"],
93)
94
95# An empty stub that just lets the compiler use M33 FPU instructions.
96cc_library(
97    name = "pico_float_compiler",
98    hdrs = ["include/pico/float.h"],
99    includes = ["include"],
100    target_compatible_with = compatible_with_rp2(),
101)
102
103# This highlights the differences between the various float implementations.
104# Most of the cc_library attributes are shared, so this prevents significant
105# duplication.
106_PICO_FLOAT_IMPLS = [
107    {
108        "name": "pico",  # RP2040-specific float implementation.
109        "srcs": [
110            "float_aeabi_rp2040.S",
111            "float_init_rom_rp2040.c",
112            "float_math.c",
113            "float_v1_rom_shim_rp2040.S",
114        ],
115        "compatibility": incompatible_with_config("@platforms//cpu:riscv32") + ["//bazel/constraint:rp2040"],
116        "extra_deps": [],
117        "linkopts": _WRAP_FLOAT_AEABI_FLAGS + _WRAP_FLOAT_SCI_FLAGS,
118    },
119    {
120        "name": "dcp",
121        "srcs": [
122            "float_aeabi_dcp.S",
123            "float_conv_m33.S",
124            "float_math.c",
125            "float_sci_m33.S",
126        ],
127        "compatibility": compatible_with_rp2() + incompatible_with_config("@platforms//cpu:riscv32") + incompatible_with_config("//bazel/constraint:rp2040"),
128        "extra_deps": ["//src/rp2_common/hardware_dcp"],
129        "linkopts": _WRAP_FLOAT_SCI_FLAGS,
130    },
131    {
132        "name": "vfp",
133        "srcs": [
134            "float_sci_m33_vfp.S",
135            "float_conv_m33.S",
136            "float_math.c",
137        ],
138        "compatibility": compatible_with_rp2() + incompatible_with_config("@platforms//cpu:riscv32") + incompatible_with_config("//bazel/constraint:rp2040"),
139        "extra_deps": ["//src/rp2_common/hardware_dcp"],
140        "linkopts": _WRAP_FLOAT_SCI_FLAGS,
141    },
142    {
143        "name": "single_hazard3",
144        "srcs": [
145            "float_single_hazard3.S",
146        ],
147        "compatibility": compatible_with_rp2() + ["@platforms//cpu:riscv32"],
148        "extra_deps": ["//src/rp2_common/hardware_hazard3"],
149        "linkopts": _WRAP_FLOAT_SCI_FLAGS,
150    },
151]
152
153# Creates:
154#   * pico_float_pico
155#   * pico_float_dcp
156#   * pico_float_vfp
157#   * pico_float_single_hazard3
158[
159    cc_library(
160        name = "pico_float_{}".format(impl["name"]),
161        srcs = impl["srcs"],
162        hdrs = ["include/pico/float.h"],
163        defines = [
164            "LIB_PICO_FLOAT_PICO=1",
165            "LIB_PICO_FLOAT_PICO_{}=1".format(impl["name"].upper()),
166        ],
167        includes = ["include"],
168        linkopts = impl["linkopts"],
169        target_compatible_with = impl["compatibility"],
170        visibility = ["//visibility:private"],
171        deps = [
172            "//src/rp2_common:pico_platform",
173            "//src/rp2_common/hardware_divider",
174            "//src/rp2_common/pico_bootrom",
175        ] + impl["extra_deps"],
176        alwayslink = True,  # Ensures the wrapped symbols are linked in.
177    )
178    for impl in _PICO_FLOAT_IMPLS
179]
180
181cc_library(
182    name = "pico_float_none",
183    srcs = ["float_none.S"],
184    hdrs = ["include/pico/float.h"],
185    defines = ["LIB_PICO_FLOAT_PICO=0"],
186    includes = ["include"],
187    linkopts = _WRAP_FLOAT_AEABI_FLAGS + _WRAP_FLOAT_SCI_FLAGS,
188    target_compatible_with = compatible_with_rp2(),
189    visibility = ["//visibility:private"],
190    deps = [
191        "//src/rp2_common:pico_platform",
192        "//src/rp2_common/pico_bootrom",
193    ],
194    alwayslink = True,  # Ensures the wrapped symbols are linked in.
195)
196