7
7
#include "pico/asm_helper.S"
8
8
9
9
#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
11
11
#else
12
12
13
13
#include "hardware/dcp_instr.inc.S"
@@ -29,7 +29,7 @@ double_section WRAPPER_FUNC_NAME(\func)
29
29
30
30
// ============== STATE SAVE AND RESTORE ===============
31
31
32
- .macro saving_func type func
32
+ .macro saving_func type func, opt_label1 = '- ', opt_label2 = '-'
33
33
// Note we are usually 32-bit aligned already at this point, as most of the
34
34
// function bodies contain exactly two 16-bit instructions: bmi and bx lr.
35
35
// We want the PCMP word-aligned.
@@ -41,6 +41,12 @@ double_section WRAPPER_FUNC_NAME(\func)
41
41
push {lr} // 16-bit instruction
42
42
bl generic_save_state // 32-bit instruction
43
43
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
44
50
// This is the actual entry point:
45
51
\type\()_func \func
46
52
PCMP apsr_nzcv
@@ -128,53 +134,124 @@ saving_func wrapper sqrt
128
134
dcp_dsqrt_m r0,r1,r0,r1,r0,r1,r2,r3,r12
129
135
saving_func_return
130
136
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
135
139
dcp_dclassify_m apsr_nzcv,r0,r1
136
140
saving_func_return
137
141
138
142
// ============== CONVERSION FUNCTIONS ===============
139
143
140
144
double_wrapper_section __aeabi_d2f
141
- saving_func wrapper __aeabi_d2f
145
+ saving_func wrapper __aeabi_d2f double2float
142
146
@ with rounding
143
147
dcp_double2float_m r0,r0,r1
144
148
saving_func_return
145
149
146
150
double_wrapper_section __aeabi_i2d
147
- saving_func wrapper __aeabi_i2d
151
+ saving_func wrapper __aeabi_i2d int2double
148
152
dcp_int2double_m r0,r1,r0
149
153
saving_func_return
150
154
151
155
double_wrapper_section __aeabi_ui2d
152
- saving_func wrapper __aeabi_ui2d
156
+ saving_func wrapper __aeabi_ui2d uint2double
153
157
dcp_uint2double_m r0,r1,r0
154
158
saving_func_return
155
159
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
+
156
232
double_wrapper_section __aeabi_d2iz
157
- saving_func wrapper __aeabi_d2iz
233
+ saving_func wrapper __aeabi_d2iz double2int_z
234
+ double2int_z_entry:
158
235
@ with truncation towards 0
159
236
dcp_double2int_m r0,r0,r1
237
+ // note: this works with either saved or not saved call as it is just a `bx lr`
160
238
saving_func_return
161
239
162
240
double_wrapper_section __aeabi_d2uiz
163
- saving_func wrapper __aeabi_d2uiz
241
+ saving_func wrapper __aeabi_d2uiz double2uint double2uint_z
242
+ double2uint_z_entry:
164
243
@ with truncation towards 0
165
244
dcp_double2uint_m r0,r0,r1
166
245
saving_func_return
167
246
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
171
249
@ with rounding
172
250
dcp_double2int_r_m r0,r0,r1
173
251
saving_func_return
174
252
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
178
255
@ with rounding
179
256
dcp_double2uint_r_m r0,r0,r1
180
257
saving_func_return
@@ -189,7 +266,6 @@ saving_func wrapper __aeabi_dcmpun
189
266
saving_func_return
190
267
191
268
double_wrapper_section __aeabi_dcmp
192
-
193
269
saving_func wrapper __aeabi_cdrcmple
194
270
dcp_dcmp_m apsr_nzcv,r2,r3,r0,r1 // with arguments reversed
195
271
bvs cmp_nan
0 commit comments