-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFFPDIV.asm
156 lines (144 loc) · 6.67 KB
/
FFPDIV.asm
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
*****************************************
* (C) COPYRIGHT 1980 BY MOTOROLA INC. *
*****************************************
********************************************
* FFPDIV SUBROUTINE *
* *
* INPUT: *
* D6 - FLOATING POINT DIVISOR *
* D7 - FLOATING POINT DIVIDEND *
* *
* OUTPUT: *
* D7 - FLOATING POINT QUOTIENT *
* *
* CONDITION CODES: *
* N - SET IF RESULT NEGATIVE *
* Z - SET IF RESULT ZERO *
* V - SET IF RESULT OVERFLOWED *
* C - UNDEFINED *
* X - UNDEFINED *
* *
* REGISTERS D3 THRU D5 VOLATILE *
* *
* CODE: 150 BYTES STACK WORK: 0 BYTES *
* *
* NOTES: *
* 1) DIVISOR IS UNALTERED (D6). *
* 2) UNDERFLOWS RETURN ZERO WITHOUT *
* ANY INDICATORS SET. *
* 3) OVERFLOWS RETURN THE HIGHEST VALUE *
* WITH THE PROPER SIGN AND THE 'V' *
* BIT SET IN THE CCR. *
* 4) IF A DIVIDE BY ZERO IS ATTEMPTED *
* THE DIVIDE BY ZERO EXCEPTION TRAP *
* IS FORCED BY THIS CODE WITH THE *
* ORIGINAL ARGUMENTS INTACT. IF THE *
* EXCEPTION RETURNS WITH THE DENOM- *
* INATOR ALTERED THE DIVIDE OPERATION *
* CONTINUES, OTHERWISE AN OVERFLOW *
* IS FORCED WITH THE PROPER SIGN. *
* THE FLOATING DIVIDE BY ZERO CAN BE *
* DISTINGUISHED FROM TRUE ZERO DIVIDE *
* BY THE FACT THAT IT IS AN IMMEDIATE *
* ZERO DIVIDING INTO REGISTER D7. *
* *
* TIME: (8 MHZ NO WAIT STATES ASSUMED) *
* DIVIDEND ZERO 5.250 MICROSECONDS *
* MINIMUM TIME OTHERS 72.750 MICROSECONDS *
* MAXIMUM TIME OTHERS 85.000 MICROSECONDS *
* AVERAGE OTHERS 76.687 MICROSECONDS *
* *
********************************************
XDEF FFPDIV ENTRY POINT
* DIVIDE BY ZERO EXIT
FPDDZR DIVU.W #0,D7 **FORCE DIVIDE BY ZERO **
* IF THE EXCEPTION RETURNS WITH ALTERED DENOMINATOR - CONTINUE DIVIDE
TST.L D6 ? EXCEPTION ALTER THE ZERO
BNE.S FFPDIV BRANCH IF SO TO CONTINUE
* SETUP MAXIMUM NUMBER FOR DIVIDE OVERFLOW
FPDOVF OR.L #$FFFFFF7F,D7 MAXIMIZE WITH PROPER SIGN
TST.B D7 SET CONDITION CODE FOR SIGN
OR.B #$02,CCR SET OVERFLOW BIT
FPDRTN RTS RETURN TO CALLER
* OVER OR UNDERFLOW DETECTED
FPDOV2 SWAP.W D6 RESTORE ARG1
SWAP.W D7 RESTORE ARG2 FOR SIGN
FPDOVFS EOR.B D6,D7 SETUP CORRECT SIGN
BRA.S FPDOVF AND ENTER OVERFLOW HANDLING
FPDOUF BMI.S FPDOVFS BRANCH IF OVERFLOW
FPDUND MOVEQ #0,D7 UNDERFLOW TO ZERO
RTS AND RETURN TO CALLER
***************
* ENTRY POINT *
***************
* FIRST SUBTRACT EXPONENTS
FFPDIV MOVE.B D6,D5 COPY ARG1 (DIVISOR)
BEQ.S FPDDZR BRANCH IF DIVIDE BY ZERO
MOVE.L D7,D4 COPY ARG2 (DIVIDEND)
BEQ.S FPDRTN RETURN ZERO IF DIVIDEND ZERO
MOVEQ #-128,D3 SETUP SIGN MASK
ADD.W D5,D5 ISOLATE ARG1 SIGN FROM EXPONENT
ADD.W D4,D4 ISOLATE ARG2 SIGN FROM EXPONENT
EOR.B D3,D5 ADJUST ARG1 EXPONENT TO BINARY
EOR.B D3,D4 ADJUST ARG2 EXPONENT TO BINARY
SUB.B D5,D4 SUBTRACT EXPONENTS
BVS.S FPDOUF BRANCH IF OVERFLOW/UNDERFLOW
CLR.B D7 CLEAR ARG2 S+EXP
SWAP.W D7 PREPARE HIGH 16 BIT COMPARE
SWAP.W D6 AGAINST ARG1 AND ARG2
CMP.W D6,D7 ? CHECK IF OVERFLOW WILL OCCUR
BMI.S FPDNOV BRANCH IF NOT
* ADJUST FOR FIXED POINT DIVIDE OVERFLOW
ADDQ.B #2,D4 ADJUST EXPONENT UP ONE
BVS.S FPDOV2 BRANCH OVERFLOW HERE
ROR.L #1,D7 SHIFT DOWN BY POWER OF TWO
FPDNOV SWAP.W D7 CORRECT ARG2
MOVE.B D3,D5 MOVE $80 INTO D5.B
EOR.W D5,D4 CREATE SIGN AND ABSOLUTIZE EXPONENT
LSR.W #1,D4 D4.B NOW HAS SIGN+EXPONENT OF RESULT
* NOW DIVIDE JUST USING 16 BITS INTO 24
MOVE.L D7,D3 COPY ARG1 FOR INITIAL DIVIDE
DIVU.W D6,D3 OBTAIN TEST QUOTIENT
MOVE.W D3,D5 SAVE TEST QUOTIENT
* NOW MULTIPLY 16-BIT DIVIDE RESULT TIMES FULL 24 BIT DIVISOR AND COMPARE
* WITH THE DIVIDEND. MULTIPLYING BACK OUT WITH THE FULL 24-BITS ALLOWS
* US TO SEE IF THE RESULT WAS TOO LARGE DUE TO THE 8 MISSING DIVISOR BITS
* USED IN THE HARDWARE DIVIDE. THE RESULT CAN ONLY BE TOO LARGE BY 1 UNIT.
MULU.W D6,D3 HIGH DIVISOR X QUOTIENT
SUB.L D3,D7 D7=PARTIAL SUBTRACTION
SWAP.W D7 TO LOW DIVISOR
SWAP.W D6 REBUILD ARG1 TO NORMAL
MOVE.W D6,D3 SETUP ARG1 FOR PRODUCT
CLR.B D3 ZERO LOW BYTE
MULU.W D5,D3 FIND REMAINING PRODUCT
SUB.L D3,D7 NOW HAVE FULL SUBTRACTION
BCC.S FPDQOK BRANCH FIRST 16 BITS CORRECT
* ESTIMATE TOO HIGH, DECREMENT QUOTIENT BY ONE
MOVE.L D6,D3 REBUILD DIVISOR
CLR.B D3 REVERSE HALVES
ADD.L D3,D7 ADD ANOTHER DIVISOR
SUBQ.W #1,D5 DECREMENT QUOTIENT
* COMPUTE LAST 8 BITS WITH ANOTHER DIVIDE. THE EXACT REMAINDER FROM THE
* MULTIPLY AND COMPARE ABOVE IS DIVIDED AGAIN BY A 16-BIT ONLY DIVISOR.
* HOWEVER, THIS TIME WE REQUIRE ONLY 9 BITS OF ACCURACY IN THE RESULT
* (8 TO MAKE 24 BITS TOTAL AND 1 EXTRA BIT FOR ROUNDING PURPOSES) AND THIS
* DIVIDE ALWAYS RETURNS A PRECISION OF AT LEAST 9 BITS.
FPDQOK MOVE.L D6,D3 COPY ARG1 AGAIN
SWAP.W D3 FIRST 16 BITS DIVISOR IN D3.W
CLR.W D7 INTO FIRST 16 BITS OF DIVIDEND
DIVU.W D3,D7 OBTAIN FINAL 16 BIT RESULT
SWAP.W D5 FIRST 16 QUOTIENT TO HIGH HALF
BMI.S FPDISN BRANCH IF NORMALIZED
* RARE OCCURRANCE - UNNORMALIZED
* HAPPENDS WHEN MANTISSA ARG1 < ARG2 AND THEY DIFFER ONLY IN LAST 8 BITS
MOVE.W D7,D5 INSERT LOW WORD OF QUOTIENT
ADD.L D5,D5 SHIFT MANTISSA LEFT ONE
SUBQ.B #1,D4 ADJUST EXPONENT DOWN (CANNOT ZERO)
MOVE.W D5,D7 CANCEL NEXT INSTRUCTION
* REBUILD OUR FINAL RESULT AND RETURN
FPDISN MOVE.W D7,D5 APPEND NEXT 16 BITS
ADD.L #$80,D5 ROUND TO 24 BITS (CANNOT OVERFLOW)
MOVE.L D5,D7 RETURN IN D7
MOVE.B D4,D7 FINISH RESULT WITH SIGN+EXPONENT
BEQ.S FPDUND UNDERFLOW IF ZERO EXPONENT
RTS RETURN RESULT TO CALLER