|
|
1.1 root 1: .file "reg_div.S"
2: /*---------------------------------------------------------------------------+
3: | reg_div.S |
4: | |
5: | Divide one FPU_REG by another and put the result in a destination FPU_REG.|
6: | |
7: | Copyright (C) 1992 W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
8: | Australia. E-mail [email protected] |
9: | |
10: | Call from C as: |
11: | void reg_div(FPU_REG *a, FPU_REG *b, FPU_REG *dest) |
12: | |
13: +---------------------------------------------------------------------------*/
14:
15: #include "exception.h"
16: #include "fpu_asm.h"
17:
18: .text
19: .align 2
20:
21: .globl reg_div
22: reg_div:
23: pushl %ebp
24: movl %esp,%ebp
25:
26: pushl %esi
27: pushl %edi
28: pushl %ebx
29:
30: movl PARAM1,%esi
31: movl PARAM2,%ebx
32: movl PARAM3,%edi
33:
34: movb TAG(%esi),%al
35: orb TAG(%ebx),%al
36:
37: jne xL_div_special // Not (both numbers TW_Valid)
38:
39:
40: // Both arguments are TW_Valid
41: movl EXP(%esi),%edx
42: movl EXP(%ebx),%eax
43: subl %eax,%edx
44: addl EXP_BIAS,%edx
45: movl %edx,EXP(%edi)
46:
47: movb TW_Valid,TAG(%edi)
48:
49: movb SIGN(%esi),%cl
50: cmpb %cl,SIGN(%ebx)
51: / changed to get it through my assembler
52: / setneb (%edi) // Set the sign, requires neg=1, pos=0
53: setne (%edi)
54: add $SIGL_OFFSET,%ebx
55: add $SIGL_OFFSET,%esi
56:
57: jmp divide_kernel
58:
59:
60: /*-----------------------------------------------------------------------*/
61: xL_div_special:
62: cmpb TW_NaN,TAG(%esi) // A NaN with anything to give NaN
63: je xL_arg1_NaN
64:
65: cmpb TW_NaN,TAG(%ebx) // A NaN with anything to give NaN
66: jne xL_no_NaN_arg
67:
68: // Operations on NaNs
69: xL_arg1_NaN:
70: xL_arg2_NaN:
71: pushl %edi
72: pushl %ebx
73: pushl %esi
74: call real_2op_NaN
75: jmp xL78
76:
77: // Invalid operations
78: xL_zero_zero:
79: xL_inf_inf:
80: pushl %esi
81: call arith_invalid
82: jmp xL78
83:
84: xL_no_NaN_arg:
85: cmpb TW_Infinity,TAG(%esi)
86: jne xL_arg1_not_inf
87:
88: cmpb TW_Infinity,TAG(%ebx)
89: je xL_inf_inf // invalid operation
90:
91: // Note that p16-9 says that infinity/0 returns infinity
92: jmp xL_copy_arg1 // Answer is Inf
93:
94: xL_arg1_not_inf:
95: cmpb TW_Zero,TAG(%ebx) // Priority to div-by-zero error
96: jne xL_arg2_not_zero
97:
98: cmpb TW_Zero,TAG(%esi)
99: je xL_zero_zero // invalid operation
100:
101: // Division by zero error
102: pushl %esi
103: movb SIGN(%esi),%al
104: xorb SIGN(%ebx),%al
105: pushl %eax // lower 8 bits have the sign
106: call divide_by_zero
107: jmp xL78
108:
109: xL_arg2_not_zero:
110: cmpb TW_Infinity,TAG(%ebx)
111: jne xL_arg2_not_inf
112:
113: jmp xL_return_zero // Answer is zero
114:
115: xL_arg2_not_inf:
116: cmpb TW_Zero,TAG(%esi)
117: jne xL_unknown_tags
118:
119: xL_copy_arg1:
120: mov TAG(%esi),%ax
121: mov %ax,TAG(%edi)
122: movl EXP(%esi),%eax
123: movl %eax,EXP(%edi)
124: movl SIGL(%esi),%eax
125: movl %eax,SIGL(%edi)
126: movl SIGH(%esi),%eax
127: movl %eax,SIGH(%edi)
128:
129: movb SIGN(%esi),%cl
130: cmpb %cl,SIGN(%ebx)
131: jne xL76
132:
133: movb SIGN_POS,SIGN(%edi)
134: jmp xL78
135:
136: xL71:
137: movb SIGN(%esi),%cl
138: cmpb %cl,SIGN(%edi)
139: jne xL76
140:
141: movb SIGN_POS,SIGN(%ebx)
142: jmp xL78
143:
144: .align 2,0x90
145: xL76:
146: movb SIGN_NEG,SIGN(%edi)
147:
148: xL78:
149: leal -12(%ebp),%esp
150:
151: popl %ebx
152: popl %edi
153: popl %esi
154: leave
155: ret
156:
157:
158: xL_return_zero:
159: movb TW_Zero,TAG(%edi)
160: jmp xL71
161:
162: xL_unknown_tags:
163: push EX_INTERNAL | 0x208
164: call EXCEPTION
165:
166: // Generate a NaN for unknown tags
167: movl CONST_QNaN,%eax
168: movl %eax,(%edi)
169: movl CONST_QNaN+4,%eax
170: movl %eax,SIGL(%edi)
171: movl CONST_QNaN+8,%eax
172: movl %eax,SIGH(%edi)
173: jmp xL78
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.