-
Notifications
You must be signed in to change notification settings - Fork 0
/
binutils_number_norma.i
90 lines (68 loc) · 1.68 KB
/
binutils_number_norma.i
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
; Copyright: Manfred Bergmann in 2018
; (re)normalize mantisse (subroutine)
;
; d0: input (float number)
; d1: size of int part
; d7: output
norm_mantisse
movem.l d0-d6,-(sp)
; the new '1' must be somewhere between the 2. and 32-9-d1 bit
; previous largest int part in d1
clr.l d3 ;used for shift counter
addi #31,d3
clr.l d6 ;left->right counter
move.l #$80000000,d4 ;mask
move.l d0,d5 ;safe
.loop_first_1
move.l d5,d0 ;copy back after each loop
cmpi.l #0,d3 ;shift counter off?
beq .loop_first_1_max_end
lsr.l #1,d4
subi #1,d3 ;decrement counter
addi #1,d6 ;increment counter
and.l d4,d0 ;is '1'?
cmpi.l #0,d0
beq .loop_first_1
; d6 contains count to first '1'
bra .loop_first_1_end
.loop_first_1_max_end
clr.l d6 ; clear d6 as the count is 0
.loop_first_1_end
; d6 now contains the shift count to the first '1'
; now calculate the number of bits to shift the mantisse to be within
; its 23 bit boundary
; if d6 = 0 there is nothing to shift and the int part is still 0
cmpi.l #0,d6
beq .build_new_exponent_end
move.l #32,d4
sub.l d6,d4
subi.l #23,d4
move.l d5,d0 ; restore original value
and.l #$80000000,d5 ; safe sign
move.l d4,d3 ; safe
.shift_mantisse
; check for shift left or right
cmpi.l #0,d4
beq .shift_end
blt .shift_left
.shift_right
lsr.l #1,d0
subi.l #1,d4
.shift_left
lsl.l #1,d0 ; shift mantisse
addi.l #1,d4
bra .shift_mantisse
.shift_end
or.l d5,d0 ; restore sign
.build_new_exponent
add.l d3,d1 ; new int part size
move.l #127,d2
add.l d1,d2
moveq #23,d6
lsl.l d6,d2 ; shift 15 bits to left
or.l d2,d0
.build_new_exponent_end
move.l d0,d7 ; copy result
movem.l (sp)+,d0-d6
.norm_mantisse_end
rts