77#include "pico/asm_helper.S"
88
99#if !HAS_DOUBLE_COPROCESSOR
10- #error attempt to compile double_aeabi_rp2350 when there is no DCP
10+ #error attempt to compile double_aeabi_dcp when there is no DCP
1111#else
1212
1313#include "hardware/dcp_instr.inc.S"
@@ -29,7 +29,7 @@ double_section WRAPPER_FUNC_NAME(\func)
2929
3030// ============== STATE SAVE AND RESTORE ===============
3131
32- .macro saving_func type func
32+ .macro saving_func type func, opt_label1 = '- ', opt_label2 = '-'
3333 // Note we are usually 32-bit aligned already at this point, as most of the
3434 // function bodies contain exactly two 16-bit instructions: bmi and bx lr.
3535 // We want the PCMP word-aligned.
@@ -41,6 +41,12 @@ double_section WRAPPER_FUNC_NAME(\func)
4141 push {lr} // 16-bit instruction
4242 bl generic_save_state // 32-bit instruction
4343 b 1f // 16-bit instruction
44+ .ifnc \opt_label1,'-'
45+ regular_func \opt_label1
46+ .endif
47+ .ifnc \opt_label2,'-'
48+ regular_func \opt_label2
49+ .endif
4450 // This is the actual entry point:
4551\type\()_func \func
4652 PCMP apsr_nzcv
@@ -128,53 +134,124 @@ saving_func wrapper sqrt
128134 dcp_dsqrt_m r0,r1,r0,r1,r0,r1,r2,r3,r12
129135 saving_func_return
130136
131- // todo not a real thing
132- double_wrapper_section __aeabi_dclassify
133- saving_func wrapper __aeabi_dclassify
134- @ with correct rounding
137+ double_section dclassify
138+ saving_func regular dclassify
135139 dcp_dclassify_m apsr_nzcv,r0,r1
136140 saving_func_return
137141
138142// ============== CONVERSION FUNCTIONS ===============
139143
140144double_wrapper_section __aeabi_d2f
141- saving_func wrapper __aeabi_d2f
145+ saving_func wrapper __aeabi_d2f double2float
142146@ with rounding
143147 dcp_double2float_m r0,r0,r1
144148 saving_func_return
145149
146150double_wrapper_section __aeabi_i2d
147- saving_func wrapper __aeabi_i2d
151+ saving_func wrapper __aeabi_i2d int2double
148152 dcp_int2double_m r0,r1,r0
149153 saving_func_return
150154
151155double_wrapper_section __aeabi_ui2d
152- saving_func wrapper __aeabi_ui2d
156+ saving_func wrapper __aeabi_ui2d uint2double
153157 dcp_uint2double_m r0,r1,r0
154158 saving_func_return
155159
160+ double_section double2fix_z
161+ saving_func regular double2fix_z
162+ ubfx r3, r1, #20, #11
163+ adds r3, r2
164+ beq 1f // very small; we don't care that we might make a denormal
165+ asrs ip, r3, #11
166+ beq 1f
167+ ite pl
168+ movpl r3, #0x7ff
169+ movsmi r3, #0
170+ 1:
171+ bfi r1, r3, #20, #11
172+ b double2int_z_entry
173+
174+ double_section double2ufix
175+ saving_func regular double2ufix_z double2ufix
176+ double2ufix_z_entry:
177+ ubfx r3, r1, #20, #11
178+ adds r3, r2
179+ beq 1f // very small; we don't care that we might make a denormal
180+ asrs ip, r3, #11
181+ beq 1f
182+ ite pl
183+ lsrspl r3, r1, #20 // 0x7ff
184+ movsmi r3, #0
185+ 1:
186+ bfi r1, r3, #20, #11
187+ b double2uint_z_entry
188+
189+ double_section double2fix
190+ saving_func regular double2fix
191+ ubfx r3, r1, #20, #11
192+ cbz r3, 2f // 0 or denormal
193+ adds r3, r2
194+ beq 1f // very small; we don't care that we might make a denormal
195+ asrs ip, r3, #11
196+ beq 1f
197+ ite pl
198+ movpl r3, #0x7ff
199+ movsmi r3, #0
200+ 1:
201+ bfi r1, r3, #20, #11
202+ b double2int_entry
203+ 2:
204+ movs r0, #0
205+ saving_func_return
206+
207+
208+ double_section double2int
209+ saving_func regular double2int
210+ double2int_entry:
211+ lsls r2, r1, #1
212+ bcc double2int_z_entry // positive is ok for int64_z
213+ lsrs r3, r2, #21
214+ beq double2int_z_entry // 0 or -0 or denormal is ok for int_z
215+
216+ lsrs r2, #21
217+ adds r2, #1
218+ subs r2, r2, #0x400
219+ bcc 1f // <1 means subtract 1
220+ cmp r2, #31
221+ bge double2int_z_entry // must be an integer or maxed out
222+ lsls r3, r1, #12
223+ adds r3, r3, r0, lsr #20 // r3 now has highest 32 mantissa bits
224+ lsls r3, r2
225+ orrs r3, r3, r0, lsl #12 // these bits are all guaranteed to be in the fraction
226+ beq double2int_z_entry // integer
227+ 1:
228+ dcp_double2int_m r0,r0,r1
229+ subs r0, #1
230+ saving_func_return
231+
156232double_wrapper_section __aeabi_d2iz
157- saving_func wrapper __aeabi_d2iz
233+ saving_func wrapper __aeabi_d2iz double2int_z
234+ double2int_z_entry:
158235@ with truncation towards 0
159236 dcp_double2int_m r0,r0,r1
237+ // note: this works with either saved or not saved call as it is just a `bx lr`
160238 saving_func_return
161239
162240double_wrapper_section __aeabi_d2uiz
163- saving_func wrapper __aeabi_d2uiz
241+ saving_func wrapper __aeabi_d2uiz double2uint double2uint_z
242+ double2uint_z_entry:
164243@ with truncation towards 0
165244 dcp_double2uint_m r0,r0,r1
166245 saving_func_return
167246
168- // todo not a real thing
169- double_wrapper_section __aeabi_d2i_r
170- saving_func wrapper __aeabi_d2i_r
247+ double_section double2int_r
248+ saving_func regular double2int_r
171249@ with rounding
172250 dcp_double2int_r_m r0,r0,r1
173251 saving_func_return
174252
175- // todo not a real thing
176- double_wrapper_section __aeabi_d2ui_r
177- saving_func wrapper __aeabi_d2ui_r
253+ double_section double2uint_r
254+ saving_func regular double2uint_r
178255@ with rounding
179256 dcp_double2uint_r_m r0,r0,r1
180257 saving_func_return
@@ -189,7 +266,6 @@ saving_func wrapper __aeabi_dcmpun
189266 saving_func_return
190267
191268double_wrapper_section __aeabi_dcmp
192-
193269saving_func wrapper __aeabi_cdrcmple
194270 dcp_dcmp_m apsr_nzcv,r2,r3,r0,r1 // with arguments reversed
195271 bvs cmp_nan
0 commit comments