1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | #include "fpa11.h" |
22 | #include "fpu/softfloat.h" |
23 | #include "fpopcode.h" |
24 | |
25 | floatx80 floatx80_exp(floatx80 Fm); |
26 | floatx80 floatx80_ln(floatx80 Fm); |
27 | floatx80 floatx80_sin(floatx80 rFm); |
28 | floatx80 floatx80_cos(floatx80 rFm); |
29 | floatx80 floatx80_arcsin(floatx80 rFm); |
30 | floatx80 floatx80_arctan(floatx80 rFm); |
31 | floatx80 floatx80_log(floatx80 rFm); |
32 | floatx80 floatx80_tan(floatx80 rFm); |
33 | floatx80 floatx80_arccos(floatx80 rFm); |
34 | floatx80 floatx80_pow(floatx80 rFn,floatx80 rFm); |
35 | floatx80 floatx80_pol(floatx80 rFn,floatx80 rFm); |
36 | |
37 | unsigned int ExtendedCPDO(const unsigned int opcode) |
38 | { |
39 | FPA11 *fpa11 = GET_FPA11()(qemufpa); |
40 | floatx80 rFm, rFn; |
41 | unsigned int Fd, Fm, Fn, nRc = 1; |
42 | |
43 | |
44 | |
45 | Fm = getFm(opcode)(opcode & 0x00000007); |
46 | if (CONSTANT_FM(opcode)((opcode & 0x00000008) != 0)) |
| |
47 | { |
48 | rFm = getExtendedConstant(Fm); |
49 | } |
50 | else |
51 | { |
52 | switch (fpa11->fType[Fm]) |
| 2 | | Control jumps to 'case 3:' at line 62 | |
|
53 | { |
54 | case typeSingle0x01: |
55 | rFm = float32_to_floatx80(fpa11->fpreg[Fm].fSingle, &fpa11->fp_status); |
56 | break; |
57 | |
58 | case typeDouble0x02: |
59 | rFm = float64_to_floatx80(fpa11->fpreg[Fm].fDouble, &fpa11->fp_status); |
60 | break; |
61 | |
62 | case typeExtended0x03: |
63 | rFm = fpa11->fpreg[Fm].fExtended; |
64 | break; |
| 3 | | Execution continues on line 70 | |
|
65 | |
66 | default: return 0; |
67 | } |
68 | } |
69 | |
70 | if (!MONADIC_INSTRUCTION(opcode)((opcode & 0x00008000) != 0)) |
| |
71 | { |
72 | Fn = getFn(opcode)((opcode & 0x00070000) >> 16); |
73 | switch (fpa11->fType[Fn]) |
74 | { |
75 | case typeSingle0x01: |
76 | rFn = float32_to_floatx80(fpa11->fpreg[Fn].fSingle, &fpa11->fp_status); |
77 | break; |
78 | |
79 | case typeDouble0x02: |
80 | rFn = float64_to_floatx80(fpa11->fpreg[Fn].fDouble, &fpa11->fp_status); |
81 | break; |
82 | |
83 | case typeExtended0x03: |
84 | rFn = fpa11->fpreg[Fn].fExtended; |
85 | break; |
86 | |
87 | default: return 0; |
88 | } |
89 | } |
90 | |
91 | Fd = getFd(opcode)((opcode & 0x00007000) >> 12); |
92 | switch (opcode & MASK_ARITHMETIC_OPCODE0x00f08000) |
| 5 | | Control jumps to 'case 2097152:' at line 104 | |
|
93 | { |
94 | |
95 | case ADF_CODE0x00000000: |
96 | fpa11->fpreg[Fd].fExtended = floatx80_add(rFn,rFm, &fpa11->fp_status); |
97 | break; |
98 | |
99 | case MUF_CODE0x00100000: |
100 | case FML_CODE0x00900000: |
101 | fpa11->fpreg[Fd].fExtended = floatx80_mul(rFn,rFm, &fpa11->fp_status); |
102 | break; |
103 | |
104 | case SUF_CODE0x00200000: |
105 | fpa11->fpreg[Fd].fExtended = floatx80_sub(rFn,rFm, &fpa11->fp_status); |
| 6 | | Passed-by-value struct argument contains uninitialized data (e.g., field: 'low') |
|
106 | break; |
107 | |
108 | case RSF_CODE0x00300000: |
109 | fpa11->fpreg[Fd].fExtended = floatx80_sub(rFm,rFn, &fpa11->fp_status); |
110 | break; |
111 | |
112 | case DVF_CODE0x00400000: |
113 | case FDV_CODE0x00a00000: |
114 | fpa11->fpreg[Fd].fExtended = floatx80_div(rFn,rFm, &fpa11->fp_status); |
115 | break; |
116 | |
117 | case RDF_CODE0x00500000: |
118 | case FRD_CODE0x00b00000: |
119 | fpa11->fpreg[Fd].fExtended = floatx80_div(rFm,rFn, &fpa11->fp_status); |
120 | break; |
121 | |
122 | #if 0 |
123 | case POW_CODE0x00600000: |
124 | fpa11->fpreg[Fd].fExtended = floatx80_pow(rFn,rFm); |
125 | break; |
126 | |
127 | case RPW_CODE0x00700000: |
128 | fpa11->fpreg[Fd].fExtended = floatx80_pow(rFm,rFn); |
129 | break; |
130 | #endif |
131 | |
132 | case RMF_CODE0x00800000: |
133 | fpa11->fpreg[Fd].fExtended = floatx80_rem(rFn,rFm, &fpa11->fp_status); |
134 | break; |
135 | |
136 | #if 0 |
137 | case POL_CODE0x00c00000: |
138 | fpa11->fpreg[Fd].fExtended = floatx80_pol(rFn,rFm); |
139 | break; |
140 | #endif |
141 | |
142 | |
143 | case MVF_CODE0x00008000: |
144 | fpa11->fpreg[Fd].fExtended = rFm; |
145 | break; |
146 | |
147 | case MNF_CODE0x00108000: |
148 | rFm.high ^= 0x8000; |
149 | fpa11->fpreg[Fd].fExtended = rFm; |
150 | break; |
151 | |
152 | case ABS_CODE0x00208000: |
153 | rFm.high &= 0x7fff; |
154 | fpa11->fpreg[Fd].fExtended = rFm; |
155 | break; |
156 | |
157 | case RND_CODE0x00308000: |
158 | case URD_CODE0x00e08000: |
159 | fpa11->fpreg[Fd].fExtended = floatx80_round_to_int(rFm, &fpa11->fp_status); |
160 | break; |
161 | |
162 | case SQT_CODE0x00408000: |
163 | fpa11->fpreg[Fd].fExtended = floatx80_sqrt(rFm, &fpa11->fp_status); |
164 | break; |
165 | |
166 | #if 0 |
167 | case LOG_CODE0x00508000: |
168 | fpa11->fpreg[Fd].fExtended = floatx80_log(rFm); |
169 | break; |
170 | |
171 | case LGN_CODE0x00608000: |
172 | fpa11->fpreg[Fd].fExtended = floatx80_ln(rFm); |
173 | break; |
174 | |
175 | case EXP_CODE0x00708000: |
176 | fpa11->fpreg[Fd].fExtended = floatx80_exp(rFm); |
177 | break; |
178 | |
179 | case SIN_CODE0x00808000: |
180 | fpa11->fpreg[Fd].fExtended = floatx80_sin(rFm); |
181 | break; |
182 | |
183 | case COS_CODE0x00908000: |
184 | fpa11->fpreg[Fd].fExtended = floatx80_cos(rFm); |
185 | break; |
186 | |
187 | case TAN_CODE0x00a08000: |
188 | fpa11->fpreg[Fd].fExtended = floatx80_tan(rFm); |
189 | break; |
190 | |
191 | case ASN_CODE0x00b08000: |
192 | fpa11->fpreg[Fd].fExtended = floatx80_arcsin(rFm); |
193 | break; |
194 | |
195 | case ACS_CODE0x00c08000: |
196 | fpa11->fpreg[Fd].fExtended = floatx80_arccos(rFm); |
197 | break; |
198 | |
199 | case ATN_CODE0x00d08000: |
200 | fpa11->fpreg[Fd].fExtended = floatx80_arctan(rFm); |
201 | break; |
202 | #endif |
203 | |
204 | case NRM_CODE0x00f08000: |
205 | break; |
206 | |
207 | default: |
208 | { |
209 | nRc = 0; |
210 | } |
211 | } |
212 | |
213 | if (0 != nRc) fpa11->fType[Fd] = typeExtended0x03; |
214 | return nRc; |
215 | } |
216 | |
217 | #if 0 |
218 | floatx80 floatx80_exp(floatx80 Fm) |
219 | { |
220 | |
221 | } |
222 | |
223 | floatx80 floatx80_ln(floatx80 Fm) |
224 | { |
225 | |
226 | } |
227 | |
228 | floatx80 floatx80_sin(floatx80 rFm) |
229 | { |
230 | |
231 | } |
232 | |
233 | floatx80 floatx80_cos(floatx80 rFm) |
234 | { |
235 | |
236 | } |
237 | |
238 | floatx80 floatx80_arcsin(floatx80 rFm) |
239 | { |
240 | |
241 | } |
242 | |
243 | floatx80 floatx80_arctan(floatx80 rFm) |
244 | { |
245 | |
246 | } |
247 | |
248 | floatx80 floatx80_log(floatx80 rFm) |
249 | { |
250 | return floatx80_div(floatx80_ln(rFm),getExtendedConstant(7)); |
251 | } |
252 | |
253 | floatx80 floatx80_tan(floatx80 rFm) |
254 | { |
255 | return floatx80_div(floatx80_sin(rFm),floatx80_cos(rFm)); |
256 | } |
257 | |
258 | floatx80 floatx80_arccos(floatx80 rFm) |
259 | { |
260 | |
261 | } |
262 | |
263 | floatx80 floatx80_pow(floatx80 rFn,floatx80 rFm) |
264 | { |
265 | return floatx80_exp(floatx80_mul(rFm,floatx80_ln(rFn))); |
266 | } |
267 | |
268 | floatx80 floatx80_pol(floatx80 rFn,floatx80 rFm) |
269 | { |
270 | return floatx80_arctan(floatx80_div(rFn,rFm)); |
271 | } |
272 | #endif |