revert between 56095 -> 55830 in arch
[AROS.git] / arch / m68k-all / libgcc1 / _fixsfsi.s
blobd03a359ddd92b4f30e2b6b73f71a557072674111
1 | single float to long conversion routine
4 BIAS4 = 0x7F-1
6 .text
7 .even
8 .globl __fixsfsi
10 __fixsfsi:
11 lea %sp@(4),%a0 | pointer to parameters
12 moveml %d2/%d4/%d5,%sp@- | save registers
13 movel %a0@,%d4 | get the number
14 movew %a0@,%d0 | extract exp
15 movew %d0,%d2 | extract sign
16 lsrw #7,%d0
17 andw #0xff,%d0 | kill sign bit
19 andl #0x7fffff,%d4 | remove exponent from mantissa
20 orl #0x800000,%d4 | restore implied leading "1"
22 cmpw #BIAS4,%d0 | check exponent
23 blt zero | strictly factional, no integer part ?
24 cmpw #BIAS4+32,%d0 | is it too big to fit in a 32-bit integer ?
25 bgt toobig
27 subw #BIAS4+24,%d0 | adjust exponent
28 bgt L_2 | shift up
29 beq L_3 | no shift
31 cmpw #-8,%d0 | replace far shifts by swap
32 bgt L_1
33 movew %d4,%d5 | shift fast, 16 bits
34 swap %d5
35 clrw %d4
36 swap %d4
37 addw #16,%d0 | account for swap
38 bgt L_2
39 beq L_3
41 L_1: lsrl #1,%d4 | shift down to align radix point;
42 addw #1,%d0 | extra bits fall off the end (no rounding)
43 blt L_1 | shifted all the way down yet ?
44 bra L_3
46 L_2: addl %d5,%d5 | shift up to align radix point
47 addxl %d4,%d4
48 subw #1,%d0
49 bgt L_2
51 L_3: movel %d4,%d0 | put integer into result register
52 cmpl #0x80000000,%d0 | -2147483648 is a nasty evil special case
53 bne L_6
54 tstw %d2 | this had better be -2^31 and not 2^31
55 bpl toobig
56 bra L_8
57 L_6: tstl %d0 | sign bit set ? (i.e. too big)
58 bmi toobig
59 L_7:
60 tstw %d2 | is it negative ?
61 bpl L_8
62 negl %d0 | negate
63 L_8:
64 moveml %sp@+,%d2/%d4/%d5
65 rts
67 zero:
68 clrl %d0 | make the whole thing zero
69 bra L_7
71 toobig:
72 movel #0x7fffffff,%d0 | ugh. Should cause a trap here.
73 bra L_7