swapforth

Форк
0
/
float.s 
784 строки · 20.2 Кб
1
# See http://www.ens-lyon.fr/LIP/Pub/Rapports/PhD/PhD2006/PhD2006-02.pdf
2
# for implementation details of all except division which is detailed below
3
#
4

5
/* .global __cmpsf2_ */
6

7
nan:            .long 0x7FFFFFFF    # also abs mask
8
inf:            .long 0x7F800000
9
sign_mask:      .long 0x80000000
10
m_mask:         .long 0x007FFFFF
11
exp_bias:       .long 127
12
edge_case:      .long 0x00FFFFFF
13
smallest_norm:  .long 0x00800000    # implicit bit
14
high_FF:        .long 0xFF000000
15
high_uint:      .long 0xFFFFFFFF
16

17
# Supply a few 'missing' instructions
18

19
# not
20
.macro      not rd,r1
21
    xor     \rd,\r1,-1
22
.endm
23

24
# negate
25
.macro      neg x
26
    not     \x, \x
27
    add     \x, \x, 1
28
.endm
29

30
# set $cc from the result of "ashl reg,dist"
31
.macro  ashlcc reg,dist
32
    .long   0x5de04008 | (\reg << 15) | (\dist << 4)
33
.endm
34

35

36
# converts an unsigned number x to a signed rep based on the bits in sign
37
# sign should be 0x00000000 or 0xffffffff.
38
.macro      to_signed x, sign
39
    add     \x,\x,\sign    # conditionally decrement x
40
    xor     \x,\x,\sign    # conditionally complement x
41
.endm
42

43

44
.macro  ld32    r,v
45
    ldk     \r,(\v>>10)
46
    ldl     \r,\r,(\v & 1023)
47
.endm
48

49
# calculate trailing zero count in x, also uses scr.
50
# Using Seal's algorithm
51
.macro      ntz x, scr
52
    not     \scr, \x
53
    add     \scr, \scr, 1
54
    and     \x, \x, \scr
55
    ashl    \scr, \x, 4
56
    add     \x, \scr, \x
57
    ashl    \scr, \x, 6
58
    add     \x, \scr, \x
59
    ashl    \scr, \x, 16
60
    sub     \x, \scr, \x
61
    lshr    \x, \x, 26
62
    ldk     \scr, ntz_table
63
    add     \x, \x, \scr
64
    lpmi.b  \x, \x, 0
65
.endm
66

67
ntz_table:
68
    .byte   32,0,1,12,2,6,0,13,3,0,7,0,0,0,0,14
69
    .byte   10,4,0,0,8,0,0,25,0,0,0,0,0,21,27,15
70
    .byte   31,11,5,0,0,0,0,0,9,0,0,24,0,0,20,26
71
    .byte   30,0,0,0,0,23,0,19,29,0,22,18,28,17,16,0
72

73
# calculate leading zero count
74
.macro      nlz x, scr
75
    flip    \x, \x, 31
76
    ntz     \x, \scr
77
.endm
78

79

80
# Round 26 bit mantissa to nearest
81
# | 23 bits frac | G | R | S |
82
.macro      round m,  s1, s2
83
    ldk     \s1,0xc8
84
    and     \s2,\m,7
85
    lshr    \s1,\s1,\s2
86
    and     \s1,\s1,1
87
    lshr    \m,\m,2
88
    add     \m,\m,\s1
89
.endm
90

91
# If NZ, set the LSB of reg
92
.macro      sticky reg
93
    jmpc    z,1f
94
    or      \reg,\reg,1             # set the sticky bit to 1
95
1:
96
.endm
97

98
##########################################################################
99
##########################################################################
100
## addition & subtraction
101

102
#if defined(L_subsf3) || defined(L_addsub_sf)
103
.global __subsf3
104
__subsf3:
105
    # this is subtraction, so we just change the sign of r1
106
    lpm     $r2,sign_mask
107
    xor     $r1,$r1,$r2
108
    jmp     __addsf3
109
#endif
110

111
#if defined(L_addsf3) || defined(L_addsub_sf)
112
.global __addsf3
113
__addsf3:
114
    # x in $r0, y in $r1, result z in $r0       --||| 100 instructions +/- |||--
115
    # unpack e, calc d
116
    bextu   $r2,$r0,(8<<5)|23   # ex in r2
117
    bextu   $r3,$r1,(8<<5)|23   # ey in r3
118
    sub     $r5,$r2,$r3         # d = ex - ey
119

120
    # Special values are 0x00 and 0xff in ex and ey.
121
    # If (ex&ey) != 0 or (xy|ey)=255 then there may be
122
    # a special value.
123
    tst     $r2,$r3
124
    jmpc    nz,1f
125
    jmp     slow
126
1:  or      $r4,$r2,$r3
127
    cmp     $r4,255
128
    jmpc    nz,no_special_vals
129
slow:
130
    # Check for early exit
131
    cmp     $r2,0
132
    jmpc    z,test_if_not_255
133
    cmp     $r3,0
134
    jmpc    nz,no_early_exit
135
test_if_not_255:
136
    cmp     $r2,255
137
    jmpc    z,no_early_exit
138
    cmp     $r3,255
139
    jmpc    z,no_early_exit
140
    or      $r6,$r2,$r3
141
    cmp     $r6,0
142
    jmpc    nz,was_not_zero
143
    and     $r0,$r0,$r1
144
    lpm     $r1,sign_mask
145
    and     $r0,$r0,$r1
146
    return
147
was_not_zero:
148
    cmp     $r2,0
149
    jmpc    nz,ret_x
150
    move    $r0,$r1
151
    return
152
ret_x:
153
    return
154
no_early_exit:
155
    # setup to test for special values
156
    sub     $r6,$r2,1
157
    and     $r6,$r6,0xFE
158
    sub     $r7,$r3,1
159
    and     $r7,$r7,0xFE
160
    # test for special values
161
    cmp     $r6,$r7
162
    jmpc    gte,ex_spec_is_gte
163
    move    $r6,$r7
164
ex_spec_is_gte:
165
    cmp     $r6,0xFE
166
    jmpc    nz,no_special_vals
167
    cmp     $r5,0
168
    jmpc    ns,d_gte_0
169
    cmp     $r3,0xFF
170
    jmpc    z,ret_y
171
    cmp     $r2,0
172
    jmpc    z,ret_y
173
ret_y:
174
    move    $r0,$r1
175
    return
176
d_gte_0:
177
    cmp     $r5,0
178
    jmpc    z,d_is_0
179
    cmp     $r2,0xFF
180
    jmpc    z,ret_x
181
    cmp     $r3,0
182
    jmpc    z,ret_x
183
d_is_0:
184
    cmp     $r2,0xFF
185
    jmpc    nz,no_special_vals
186
    ashl    $r6,$r0,9           # clear all except x frac
187
    ashl    $r7,$r1,9           # clear all except y frac
188
    or      $r6,$r6,$r7
189
    cmp     $r6,0
190
    jmpc    nz,ret_nan
191
    lshr    $r4,$r0,31          # sx in r4
192
    lshr    $r5,$r1,31          # sy in r4
193
    cmp     $r4,$r5
194
    jmpc    nz,ret_nan
195
    return
196
ret_nan:
197
    lpm     $r0,nan
198
    return
199
no_special_vals:
200
    ldk     $r8,(1<<10)|(9<<5)|26   # setup implicit bit and mask for e
201
    #----------------------
202
    ashr    $r4,$r0,31              # sx in r4
203
    ashl    $r0,$r0,3               # shift mx 3 for GRS bits
204
    bins    $r0,$r0,$r8             # clear sx, ex and add implicit bit mx
205
    # change mx to signed mantissa
206
    to_signed $r0,$r4
207
    #----------------------
208
    ashr    $r4,$r1,31              # sy in r4
209
    ashl    $r1,$r1,3               # shift my 3 for GRS bits
210
    bins    $r1,$r1,$r8             # clear sy, ey and add implicit bit my
211
    # change my to signed mantissa
212
    to_signed $r1,$r4
213
    #----------------------
214
    # test if we swap ms based on d sign
215
    cmp     $r5,0
216
    jmpc    gte,noswap
217
    # swap mx & my
218
    xor     $r0,$r0,$r1
219
    xor     $r1,$r0,$r1
220
    xor     $r0,$r0,$r1
221
    # d positive means that ex>=ey, so ez = ex
222
    # d negative means that ey>ex, so ez = ey
223
    move    $r2,$r3
224
    # |d|
225
    neg     $r5
226
noswap:
227
                                    # now $r2 = ez = max(ex,ey)
228
    cmp     $r5,26                  # max necessary alignment shift is 26
229
    jmpc    lt,under_26
230
    ldk     $r5,26
231
under_26:
232
    ldk     $r7,-1
233
    ashl    $r7,$r7,$r5             # create inverse of mask for test of S bit value in discarded my
234
    not     $r7,$r7
235
    tst     $r1,$r7                 # determine value of sticky bit
236
    # shift my >> |d|
237
    ashr    $r1,$r1,$r5
238
    sticky  $r1
239

240
    # add ms
241
    add     $r0,$r0,$r1
242

243
    # $r4 = sign(mx), mx = |mx|
244
    ashr    $r4,$r0,31
245
    xor     $r0,$r0,$r4
246
    sub     $r0,$r0,$r4
247

248
    # realign mantissa using leading zero count
249
    flip    $r7,$r0,31
250
    ntz     $r7,$r8
251
    ashl    $r0,$r0,$r7
252
    btst    $r0,(6<<5)|0            # test low bits for sticky again
253
    lshr    $r0,$r0,6
254
    sticky  $r0
255

256
    # update exponent
257
    add     $r2,$r2,5
258
    sub     $r2,$r2,$r7
259

260
    # Round to nearest
261
    round   $r0,$r7,$r6
262

263
    # detect_exp_update
264
    lshr    $r6,$r0,24
265
    add     $r2,$r2,$r6
266

267
    # final tests
268
    # mz == 0? if so, we just bail with a +0
269
    cmp     $r0,0
270
    jmpc    nz,msum_not_zero
271
    ldk     $r0,0
272
    return
273
msum_not_zero:
274
    # Combined check that (1 <= ez <= 254)
275
    sub     $r3,$r2,1
276
    cmp     $r3,254
277
    jmpc    b,no_special_ret
278
    # underflow?
279
    cmp     $r2,0
280
    jmpc    gt,no_under
281
    ldk     $r0,0
282
    jmp     pack_sz
283
no_under:
284
    # overflow?
285
    cmp     $r2,255
286
    jmpc    lt,no_special_ret
287
    ldk     $r0,0x7F8
288
    ashl    $r0,$r0,20
289
    jmp     pack_sz
290
no_special_ret:
291
    # Pack ez
292
    ldl     $r2,$r2,(8<<5)|23
293
    bins    $r0,$r0,$r2             # width = 8, pos = 23 pack ez
294
    # Pack sz
295
pack_sz:
296
    ldl     $r4,$r4,(1<<5)|31
297
    bins    $r0,$r0,$r4             # width = 1, pos = 31 set sz to sy
298
    return
299
#endif
300

301
##########################################################################
302
##########################################################################
303
## multiplication
304

305
#ifdef  L_mulsf3
306
.global __mulsf3
307
__mulsf3:
308
    # x in $r0, y in $r1, result z in $r0       --||| 61 instructions +/- |||--
309

310
    # unpack e
311
    bextu   $r2,$r0,(8<<5)|23   # ex in r2
312
    bextu   $r3,$r1,(8<<5)|23   # ey in r3
313
    # calc result sign
314
    xor     $r4,$r0,$r1
315
    lpm     $r5,sign_mask
316
    and     $r4,$r4,$r5         # sz in r4
317

318
    # unpack m add implicit bit
319
    ldk     $r5,(1<<10)|(9<<5)|23   # setup implicit bit and mask for e
320
    #----------------------
321
    bins    $r0,$r0,$r5             # clear sx, ex and add implicit bit mx
322

323
    sub     $r6,$r2,1
324
    cmp     $r6,254
325
    jmpc    b,1f
326
    jmp     slow_mul
327
1:  sub     $r6,$r3,1
328
    cmp     $r6,254
329
    jmpc    b,no_special_vals_mul
330

331
slow_mul:
332
    # Check for early exit
333
    cmp     $r2,0
334
    jmpc    z,op_is_zero
335
    cmp     $r3,0
336
    jmpc    nz,no_early_exit_mul
337
op_is_zero:
338
    cmp     $r2,255
339
    jmpc    z,no_early_exit_mul
340
    cmp     $r3,255
341
    jmpc    z,no_early_exit_mul
342
    move    $r0,$r4
343
    return
344
no_early_exit_mul:
345
    # setup to test for special values
346
    sub     $r6,$r2,1
347
    and     $r6,$r6,0xFE
348
    sub     $r7,$r3,1
349
    and     $r7,$r7,0xFE
350
    # test for special values
351
    cmp     $r6,$r7
352
    jmpc    gte,ex_spec_is_gte_ey_mul
353
    move    $r6,$r7
354
ex_spec_is_gte_ey_mul:
355
    cmp     $r6,0xFE
356
    jmpc    nz,no_special_vals_mul
357
    cmp     $r2,0xFF
358
    jmpc    nz,ex_not_FF_mul
359
    ashl    $r6,$r0,9
360
    cmp     $r6,0
361
    jmpc    nz,ret_nan
362
    cmp     $r3,0
363
    jmpc    z,ret_nan
364
    ashl    $r6,$r1,1
365
    lpm     $r7,high_FF
366
    cmp     $r6,$r7
367
    jmpc    a,ret_nan
368
    cmp     $r6,0
369
    jmpc    z,ret_nan
370
    # infinity
371
    lpm     $r0,inf
372
    or      $r0,$r0,$r4
373
    return
374
ex_not_FF_mul:
375
    cmp     $r2,0
376
    jmpc    nz,no_nan_mul
377
    cmp     $r3,0xFF
378
    jmpc    nz,no_nan_mul
379
    jmp     ret_nan
380
no_nan_mul:
381
    lpm     $r0,nan
382
    and     $r0,$r0,$r1
383
    or      $r0,$r0,$r4
384
    return
385

386
no_special_vals_mul:
387
    bins    $r1,$r1,$r5         # clear sy, ey and add implicit bit my
388
    # calc ez
389
    add     $r3,$r2,$r3
390
    sub     $r3,$r3,127         # ez in r3
391

392
    # (r1,r2) = R0 * R1
393
    mul     $r2,$r0,$r1
394
    muluh   $r1,$r0,$r1
395

396
    btst    $r1,(1<<5)|15       # XXX use jmpx
397
    jmpc    z,mul_z0
398

399
    # mz is 1X.XX...X
400
    # 48-bit product is in (r1,r2). The low 22 bits of r2
401
    # are discarded.
402
    lshr    $r0,$r2,22
403
    ashl    $r1,$r1,10
404
    or      $r0,$r0,$r1         # r0 = (r1,r2) >> 22
405
    ashlcc  2,10
406
    sticky  $r0
407
    add     $r3,$r3,1           # bump exponent
408

409
    # Round to nearest
410
    round   $r0, $r1, $r2
411
    lshr    $r6,$r0,24
412
    add     $r3,$r3,$r6
413

414
    sub     $r6,$r3,1
415
    cmp     $r6,254
416
    jmpc    b,no_special_ret_mul
417

418
special_ret_mul:
419
    # When the final exponent <= 0, result is flushed to 0 except
420
    # for the border case 0x00FFFFFF which is promoted to next higher
421
    # FP no., that is, the smallest "normalized" number.
422
    cmp     $r3,0
423
    jmpc    gt,exp_normal
424
    # Pack ez
425
    ldl     $r3,$r3,(8<<5)|23
426
    bins    $r0,$r0,$r3 # width = 8, pos = 23 pack ez
427
    lpm     $r2,edge_case
428
    cmp     $r0,$r2
429
    jmpc    nz,no_edge_case
430
    lpm     $r0,smallest_norm
431
    jmp     pack_sz_mul
432
no_edge_case:
433
    ldk     $r0,0
434
    jmp     pack_sz_mul
435
exp_normal:
436
    # overflow?
437
    cmp     $r3,255
438
    jmpc    lt,no_special_ret_mul
439
    ldk     $r0,0x7F8
440
    ashl    $r0,$r0,20
441
    jmp     pack_sz_mul
442
no_special_ret_mul:
443
    # Pack ez
444
    ldl     $r3,$r3,(8<<5)|23
445
    bins    $r0,$r0,$r3 # width = 8, pos = 23 pack ez
446
    # Pack sz
447
pack_sz_mul:
448
    or    $r0,$r0,$r4
449
    return
450

451
mul_z0:
452
    # mz is 0X.XX...X
453
    # 48-bit product is in (r1,r2). The low 21 bits of r2
454
    # are discarded.
455
    lshr    $r0,$r2,21
456
    ashl    $r1,$r1,11
457
    or      $r0,$r0,$r1         # r0 = (r1,r2) >> 22
458
    ashlcc  2,11
459
    sticky  $r0
460
    # Round to nearest
461
    round   $r0, $r1, $r2
462
    lshr    $r6,$r0,24
463
    add     $r3,$r3,$r6
464

465
    sub     $r6,$r3,1
466
    cmp     $r6,254
467
    jmpc    b,no_special_ret_mul
468
    jmp     special_ret_mul
469
#endif
470

471
##########################################################################
472
##########################################################################
473
## division
474

475
## See http://perso.ens-lyon.fr/gilles.villard/BIBLIOGRAPHIE/PDF/arith19.pdf
476
## for implementation details
477

478

479
dc_1: .long             0xffffe7d7
480
dc_2: .long             0xffffffe8
481
dc_3: .long             0xffbad86f
482
dc_4: .long             0xfffbece7
483
dc_5: .long             0xf3672b51
484
dc_6: .long             0xfd9d3a3e
485
dc_7: .long             0x9a3c4390
486
dc_8: .long             0xd4d2ce9b
487
dc_9: .long             0x1bba92b3
488
dc_10: .long            0x525a1a8b
489
dc_11: .long            0x0452b1bf
490
dc_12: .long            0xFFFFFFC0
491
spec_val_test:  .long   0x7F7FFFFF
492

493

494

495
#ifdef  L_divsf3
496
.global __divsf3
497
__divsf3:
498
    push    $r13
499
    # x in $r0, y in $r1, result z in $r0       --||| 73 instructions +/- |||-
500
    bextu   $r10,$r0,(8<<5)|23   # ex in r2
501
    bextu   $r11,$r1,(8<<5)|23   # ey in r3
502
    lpm     $r6, m_mask
503
    and     $r2, $r0, $r6        # mx
504
    and     $r3, $r1, $r6        # my
505
    cmp     $r2,$r3
506
    bextu   $r2,$r30,(1<<5)|4   # c = Tx >= T;
507
    ashl    $r3,$r3,9           # T = X << 9;
508
    lpm     $r13, sign_mask
509
    ashl    $r4,$r0,8           # X8 = X << 8;
510
    or      $r4,$r4,$r13        # Mx = X8 | 0x80000000;
511
    lshr    $r5,$r4,$r2         # S = Mx >> c;
512
    # calc D
513
    sub     $r2, $r11, $r2
514
    add     $r12, $r10, 125
515
    sub     $r2, $r12, $r2      # int D = (Ex + 125) - (Ey - c);
516
    # calc result sign
517
    xor     $r12,$r0,$r1
518
    and     $r12,$r12,$r13      # Sr = ( X ˆ Y ) & 0x80000000;
519
    # check early exit
520
    cmp     $r10, 0
521
    jmpc    nz, no_early_ret_dev
522
    cmp     $r11, 0
523
    jmpc    z, no_early_ret_dev
524
    cmp     $r11, 255
525
    jmpc    z, no_early_ret_dev
526
    move    $r0, $r12
527
    pop     $r13
528
    return
529
no_early_ret_dev:
530
 # setup to test for special values
531
    sub     $r8,$r10,1
532
    and     $r8,$r8,0xFE
533
    sub     $r9,$r11,1
534
    and     $r9,$r9,0xFE
535
    # test for special values
536
    cmp     $r8, $r9
537
    jmpc    gte, absXm1_gte_absYm1
538
    move    $r8, $r9
539
absXm1_gte_absYm1:
540
    cmp     $r8, 0xFE
541
    jmpc    nz, no_spec_ret_div
542
    cmp     $r10, 0xFF
543
    jmpc    nz, ex_not_FF_div
544
    lpm     $r6, m_mask
545
    and     $r2, $r0, $r6        # mx
546
    cmp     $r2, 0
547
    jmpc    nz, ret_nan_div
548
    cmp     $r11, 0xFF
549
    jmpc    z, ret_nan_div
550
    jmp     ret_inf_div
551
ex_not_FF_div:
552
    cmp     $r11, 0xFF
553
    jmpc    nz, ey_not_FF_div
554
    ashl    $r13, $r1, 9
555
    cmp     $r13, 0
556
    jmpc    nz, ret_nan_div
557
    move    $r0, $r12
558
    pop     $r13
559
    return
560
ey_not_FF_div:
561
    or      $r10, $r10, $r11
562
    cmp     $r10, 0
563
    jmpc    z, ret_nan_div
564
ret_inf_div:
565
    lpm     $r6, inf
566
    move    $r0, $r6
567
    or      $r0, $r0, $r12
568
    pop     $r13
569
    return
570
ret_nan_div:
571
    lpm     $r0, nan
572
    pop     $r13
573
    return
574

575
no_spec_ret_div:
576
# check for overflow
577
    ldk     $r6, 0xFE
578
    cmp     $r2, $r6
579
    jmpc    lt, no_overflow_div
580
    lpm     $r6, inf
581
    or      $r0, $r12, $r6
582
    pop     $r13
583
    return
584
no_overflow_div:
585
# check for underflow
586
    cmp     $r2, 0
587
    jmpc    ns, no_underflow_div
588
    xnor    $r6, $r6, $r6       # -1
589
    cmp     $r2, $r6
590
    jmpc    nz, ret_sr_div
591
    ldk     $r7, 0xFF
592
    xor     $r6, $r6, $r7       # 0xFF ^ -1 = 0xFFFFFF00
593
    cmp     $r4, $r6
594
    jmpc    nz, ret_sr_div
595
    lpm     $r6, sign_mask
596
    cmp     $r4, $r6
597
    jmpc    nz, ret_sr_div
598
    lshr    $r0, $r6, 8
599
    or      $r0, $r0, $r12
600
    pop     $r13
601
    return
602
ret_sr_div:
603
    move    $r0, $r12
604
    pop     $r13
605
    return
606
no_underflow_div:
607
    lpm     $r6, dc_1
608
    muluh   $r7, $r3, $r6       # i0 = mul( T , 0xffffe7d7 );
609
    lpm     $r6, dc_2
610
    sub     $r7, $r6, $r7       # i1 = 0xffffffe8 - i0;
611
    muluh   $r7, $r5, $r7       # i2 = mul( S , i1 );
612
    add     $r7, $r7, 0x20      # i3 = 0x00000020 + i2;
613
    muluh   $r8, $r3, $r3       # i4 = mul( T , T );
614
    muluh   $r9, $r5, $r8       # i5 = mul( S , i4 );
615
    lpm     $r6, dc_3
616
    muluh   $r10, $r3, $r6      # i6 = mul( T , 0xffbad86f );
617
    lpm     $r6, dc_4
618
    sub     $r10, $r6, $r10     # i7 = 0xfffbece7 - i6;
619
    muluh   $r10, $r9, $r10     # i8 = mul( i5 , i7 );
620
    add     $r7, $r7, $r10      # i9 = i3 + i8;
621
    muluh   $r9, $r8, $r9       # i10 = mul( i4 , i5 );
622
    lpm     $r6, dc_5
623
    muluh   $r10, $r3, $r6      # i11 = mul( T , 0xf3672b51 );
624
    lpm     $r6, dc_6
625
    sub     $r10, $r6, $r10     # i12 = 0xfd9d3a3e - i11;
626
    lpm     $r6, dc_7
627
    muluh   $r11, $r3, $r6      # i13 = mul( T , 0x9a3c4390 );
628
    lpm     $r6, dc_8
629
    sub     $r11, $r6, $r11     # i14 = 0xd4d2ce9b - i13
630
    muluh   $r11, $r8, $r11     # i15 = mul( i4 , i14 );
631
    add     $r10, $r10, $r11    # i16 = i12 + i15;
632
    muluh   $r10, $r9, $r10     # i17 = mul( i10 , i16 )
633
    add     $r7, $r7, $r10      # i18 = i9 + i17;
634
    muluh   $r10, $r8, $r8      # i19 = mul( i4 , i4 );
635
    lpm     $r6, dc_9
636
    muluh   $r11, $r3, $r6      # i20 = mul( T , 0x1bba92b3 );
637
    lpm     $r6, dc_10
638
    sub     $r11, $r6, $r11     # i21 = 0x525a1a8b - i20;
639
    lpm     $r6, dc_11
640
    muluh   $r8, $r8, $r6       # i22 = mul( i4 , 0x0452b1bf );
641
    add     $r8, $r11, $r8      # i23 = i21 + i22;
642
    muluh   $r8, $r10, $r8      # i24 = mul( i19 , i23 );
643
    muluh   $r8, $r9, $r8       # i25 = mul( i10 , i24 );
644
    add     $r3, $r7, $r8       # V = i18 + i25;
645
# W = V & 0xFFFFFFC0;
646
    lpm     $r6, dc_12
647
    and     $r3, $r3, $r6   # W
648
# round and pack final values
649
    ashl    $r0, $r2, 23        # pack D
650
    or      $r0, $r0, $r12      # pack Sr
651
    ashl    $r12, $r1, 8
652
    or      $r12, $r12, $r13    # My
653
    muluh   $r10, $r3, $r12
654
    lshr    $r11, $r5, 1
655
    cmp     $r10, $r11
656
    jmpc    gte, div_ret_1
657
    add     $r3, $r3, 0x40
658
div_ret_1:
659
    lshr    $r3, $r3, 7
660
    add     $r0, $r0, $r3
661
    pop     $r13
662
    return
663
#endif
664

665
##########################################################################
666
##########################################################################
667
## Negate
668

669
##########################################################################
670
## int & unsigned int to float
671

672
.macro  i2f x, s1, s2, s3, lbl
673
    move    \s1, \x
674
    nlz     \s1, \s2
675
    cmp     \s1, 8
676
    jmpc    s, float_round\lbl
677
    sub     \s2, \s1, 8
678
    ashl    \x, \x, \s2
679
    jmp     float_no_round\lbl
680
float_round\lbl:
681
    cmp     \s1, 6
682
    jmpc    s, float_shift_right\lbl
683
    sub     \s2, \s1, 6
684
    ashl    \x, \x, \s2
685
    jmp     float_round_and_pack\lbl
686
float_shift_right\lbl:
687
    ldk     \s2, 6
688
    sub     \s2, \s2, \s1
689
    xnor    \s3, \s3 ,\s3           # 0xFFFFFFFF
690
    ashl    \s3, \s3 ,\s2           # create inverse of mask for test of S bit value in discarded my
691
    xnor    \s3, \s3 ,0             # NOT
692
    tst     \x, \s3                # determine value of sticky bit
693
    lshr    \x, \x, \s2
694
    jmpc    z,float_round_and_pack\lbl
695
    or      \x, \x, 1               # set the sticky bit to 1
696
float_round_and_pack\lbl:
697
    bextu   \s2, \x, (1<<5)|2      # extract low bit of m
698
    or      \x, \x, \s2           # or p into r
699
    add     \x, \x, 1
700
    lshr    \x, \x, 2
701
    btst    \x, (1<<5)|24          # test for carry from round
702
    jmpc    z, float_no_round\lbl
703
    sub     \s1, \s1, 1             # inc e for carry (actually dec nlz)
704
    lshr    \x, \x, 1
705
float_no_round\lbl:
706
    ldk     \s2, 158
707
    sub     \s1, \s2, \s1
708
    # Pack e
709
    ldl     \s1, \s1, (8<<5)|23
710
    bins    \x, \x, \s1
711
.endm
712

713

714
#ifdef L_floatsisf
715
.global __floatsisf
716
__floatsisf:                       # 32 instructions
717
    cmp     $r0, 0
718
    jmpc    nz, float_not_zero
719
    return
720
float_not_zero:
721
    ashr    $r1, $r0, 31            # s in r1
722
    xor     $r0, $r0, $r1           # cond neg
723
    sub     $r0, $r0, $r1
724
    i2f     $r0, $r2, $r3, $r4, 1
725
    ldl     $r1, $r1, (1<<5)|31
726
    bins    $r0, $r0, $r1
727
    return
728
#endif
729

730
#ifdef L_floatunsisf
731
.global __floatunsisf
732
__floatunsisf:                        # 26 instructions
733
    cmp     $r0, 0
734
    jmpc    nz, float_not_zero2
735
    return
736
float_not_zero2:
737
    i2f     $r0, $r1, $r2, $r3, 2
738
    return
739
#endif
740

741
##########################################################################
742
##########################################################################
743
## float compare
744

745

746
__cmpsf2_:
747
    # calc abs vals
748
    lpm     $r3, nan                # also abs mask
749
    and     $r2, $r0, $r3
750
    and     $r3, $r1, $r3
751
    # test if either abs is nan
752
    lpm     $r4, inf
753
    cmp     $r2, $r4
754
    jmpc    gt, cmp_is_gt
755
    cmp     $r3, $r4
756
    jmpc    gt, cmp_is_gt
757
    # test if both are 0
758
    or      $r2, $r2, $r3
759
    cmp     $r2, 0
760
    jmpc    z, cmp_is_eq
761
    # test if eq
762
    cmp     $r0, $r1
763
    jmpc    z, cmp_is_eq
764
    # -- if either is pos
765
    and     $r2, $r0, $r1
766
    cmp     $r2, 0
767
    jmpc    s, cmp_both_neg
768
    cmp     $r0, $r1
769
    jmpc    gt, cmp_is_gt
770
    # r0 < r1
771
    lpm     $r0, high_uint
772
    return
773
cmp_both_neg:
774
    cmp     $r0, $r1
775
    jmpc    lt, cmp_is_gt
776
    # r0 < r1
777
    lpm     $r0, high_uint
778
    return
779
cmp_is_gt:
780
    ldk     $r0, 1
781
    return
782
cmp_is_eq:
783
    ldk     $r0, 0
784
    return
785

786

787

788

789

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.