Commit f18cd2238d39950f8a532cb2a2ee48a453d2e88f
1 parent
023d8ca2
target-alpha: convert FP ops to TCG
- Convert FP ops to TCG - Fix S format - Implement F and G formats (untested) - Fix MF_FPCR an MT_FPCR - Fix FTOIS, FTOIT, ITOFF, ITOFS, ITOFT - Fix CPYSN, CPYSE Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5354 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
11 changed files
with
786 additions
and
1482 deletions
target-alpha/cpu.h
target-alpha/exec.h
... | ... | @@ -44,9 +44,6 @@ register uint64_t T1 asm(AREG2); |
44 | 44 | |
45 | 45 | #define PARAM(n) ((uint64_t)PARAM##n) |
46 | 46 | #define SPARAM(n) ((int32_t)PARAM##n) |
47 | -#define FT0 (env->ft0) | |
48 | -#define FT1 (env->ft1) | |
49 | -#define FT2 (env->ft2) | |
50 | 47 | #define FP_STATUS (env->fp_status) |
51 | 48 | |
52 | 49 | #if defined (DEBUG_OP) | ... | ... |
target-alpha/helper.c
... | ... | @@ -434,12 +434,6 @@ void cpu_dump_state (CPUState *env, FILE *f, |
434 | 434 | if ((i % 3) == 2) |
435 | 435 | cpu_fprintf(f, "\n"); |
436 | 436 | } |
437 | - cpu_fprintf(f, "FT " TARGET_FMT_lx " " TARGET_FMT_lx " " TARGET_FMT_lx, | |
438 | - *((uint64_t *)(&env->ft0)), *((uint64_t *)(&env->ft1)), | |
439 | - *((uint64_t *)(&env->ft2))); | |
440 | - cpu_fprintf(f, "\nMEM " TARGET_FMT_lx " %d %d\n", | |
441 | - ldq_raw(0x000000004007df60ULL), | |
442 | - (uint8_t *)(&env->ft0), (uint8_t *)(&env->fir[0])); | |
443 | 437 | } |
444 | 438 | |
445 | 439 | void cpu_dump_EA (target_ulong EA) | ... | ... |
target-alpha/helper.h
... | ... | @@ -41,3 +41,70 @@ DEF_HELPER(uint64_t, helper_mskqh, (int64_t, uint64_t)) |
41 | 41 | DEF_HELPER(uint64_t, helper_insqh, (int64_t, uint64_t)) |
42 | 42 | |
43 | 43 | DEF_HELPER(uint64_t, helper_cmpbge, (uint64_t, uint64_t)) |
44 | + | |
45 | +DEF_HELPER(uint64_t, helper_load_fpcr, (void)) | |
46 | +DEF_HELPER(void, helper_store_fpcr, (uint64_t val)) | |
47 | + | |
48 | +DEF_HELPER(uint32_t, helper_f_to_memory, (uint64_t s)) | |
49 | +DEF_HELPER(uint64_t, helper_memory_to_f, (uint32_t s)) | |
50 | +DEF_HELPER(uint64_t, helper_addf, (uint64_t, uint64_t)) | |
51 | +DEF_HELPER(uint64_t, helper_subf, (uint64_t, uint64_t)) | |
52 | +DEF_HELPER(uint64_t, helper_mulf, (uint64_t, uint64_t)) | |
53 | +DEF_HELPER(uint64_t, helper_divf, (uint64_t, uint64_t)) | |
54 | +DEF_HELPER(uint64_t, helper_sqrtf, (uint64_t)) | |
55 | + | |
56 | +DEF_HELPER(uint64_t, helper_g_to_memory, (uint64_t s)) | |
57 | +DEF_HELPER(uint64_t, helper_memory_to_g, (uint64_t s)) | |
58 | +DEF_HELPER(uint64_t, helper_addg, (uint64_t, uint64_t)) | |
59 | +DEF_HELPER(uint64_t, helper_subg, (uint64_t, uint64_t)) | |
60 | +DEF_HELPER(uint64_t, helper_mulg, (uint64_t, uint64_t)) | |
61 | +DEF_HELPER(uint64_t, helper_divg, (uint64_t, uint64_t)) | |
62 | +DEF_HELPER(uint64_t, helper_sqrtg, (uint64_t)) | |
63 | + | |
64 | +DEF_HELPER(uint32_t, helper_s_to_memory, (uint64_t s)) | |
65 | +DEF_HELPER(uint64_t, helper_memory_to_s, (uint32_t s)) | |
66 | +DEF_HELPER(uint64_t, helper_adds, (uint64_t, uint64_t)) | |
67 | +DEF_HELPER(uint64_t, helper_subs, (uint64_t, uint64_t)) | |
68 | +DEF_HELPER(uint64_t, helper_muls, (uint64_t, uint64_t)) | |
69 | +DEF_HELPER(uint64_t, helper_divs, (uint64_t, uint64_t)) | |
70 | +DEF_HELPER(uint64_t, helper_sqrts, (uint64_t)) | |
71 | + | |
72 | +DEF_HELPER(uint64_t, helper_addt, (uint64_t, uint64_t)) | |
73 | +DEF_HELPER(uint64_t, helper_subt, (uint64_t, uint64_t)) | |
74 | +DEF_HELPER(uint64_t, helper_mult, (uint64_t, uint64_t)) | |
75 | +DEF_HELPER(uint64_t, helper_divt, (uint64_t, uint64_t)) | |
76 | +DEF_HELPER(uint64_t, helper_sqrtt, (uint64_t)) | |
77 | + | |
78 | +DEF_HELPER(uint64_t, helper_cmptun, (uint64_t, uint64_t)) | |
79 | +DEF_HELPER(uint64_t, helper_cmpteq, (uint64_t, uint64_t)) | |
80 | +DEF_HELPER(uint64_t, helper_cmptle, (uint64_t, uint64_t)) | |
81 | +DEF_HELPER(uint64_t, helper_cmptlt, (uint64_t, uint64_t)) | |
82 | +DEF_HELPER(uint64_t, helper_cmpgeq, (uint64_t, uint64_t)) | |
83 | +DEF_HELPER(uint64_t, helper_cmpgle, (uint64_t, uint64_t)) | |
84 | +DEF_HELPER(uint64_t, helper_cmpglt, (uint64_t, uint64_t)) | |
85 | + | |
86 | +DEF_HELPER(uint64_t, helper_cmpfeq, (uint64_t)) | |
87 | +DEF_HELPER(uint64_t, helper_cmpfne, (uint64_t)) | |
88 | +DEF_HELPER(uint64_t, helper_cmpflt, (uint64_t)) | |
89 | +DEF_HELPER(uint64_t, helper_cmpfle, (uint64_t)) | |
90 | +DEF_HELPER(uint64_t, helper_cmpfgt, (uint64_t)) | |
91 | +DEF_HELPER(uint64_t, helper_cmpfge, (uint64_t)) | |
92 | + | |
93 | +DEF_HELPER(uint64_t, helper_cpys, (uint64_t, uint64_t)) | |
94 | +DEF_HELPER(uint64_t, helper_cpysn, (uint64_t, uint64_t)) | |
95 | +DEF_HELPER(uint64_t, helper_cpyse, (uint64_t, uint64_t)) | |
96 | + | |
97 | +DEF_HELPER(uint64_t, helper_cvtts, (uint64_t)) | |
98 | +DEF_HELPER(uint64_t, helper_cvtst, (uint64_t)) | |
99 | +DEF_HELPER(uint64_t, helper_cvttq, (uint64_t)) | |
100 | +DEF_HELPER(uint32_t, helper_cvtqs, (uint64_t)) | |
101 | +DEF_HELPER(uint64_t, helper_cvtqt, (uint64_t)) | |
102 | +DEF_HELPER(uint64_t, helper_cvtqf, (uint64_t)) | |
103 | +DEF_HELPER(uint64_t, helper_cvtgf, (uint64_t)) | |
104 | +DEF_HELPER(uint64_t, helper_cvtgq, (uint64_t)) | |
105 | +DEF_HELPER(uint64_t, helper_cvtqg, (uint64_t)) | |
106 | +DEF_HELPER(uint64_t, helper_cvtlq, (uint64_t)) | |
107 | +DEF_HELPER(uint64_t, helper_cvtql, (uint64_t)) | |
108 | +DEF_HELPER(uint64_t, helper_cvtqlv, (uint64_t)) | |
109 | +DEF_HELPER(uint64_t, helper_cvtqlsv, (uint64_t)) | |
110 | + | ... | ... |
target-alpha/op.c
... | ... | @@ -23,105 +23,8 @@ |
23 | 23 | #include "config.h" |
24 | 24 | #include "exec.h" |
25 | 25 | #include "host-utils.h" |
26 | - | |
27 | 26 | #include "op_helper.h" |
28 | 27 | |
29 | -#define REG 0 | |
30 | -#include "op_template.h" | |
31 | - | |
32 | -#define REG 1 | |
33 | -#include "op_template.h" | |
34 | - | |
35 | -#define REG 2 | |
36 | -#include "op_template.h" | |
37 | - | |
38 | -#define REG 3 | |
39 | -#include "op_template.h" | |
40 | - | |
41 | -#define REG 4 | |
42 | -#include "op_template.h" | |
43 | - | |
44 | -#define REG 5 | |
45 | -#include "op_template.h" | |
46 | - | |
47 | -#define REG 6 | |
48 | -#include "op_template.h" | |
49 | - | |
50 | -#define REG 7 | |
51 | -#include "op_template.h" | |
52 | - | |
53 | -#define REG 8 | |
54 | -#include "op_template.h" | |
55 | - | |
56 | -#define REG 9 | |
57 | -#include "op_template.h" | |
58 | - | |
59 | -#define REG 10 | |
60 | -#include "op_template.h" | |
61 | - | |
62 | -#define REG 11 | |
63 | -#include "op_template.h" | |
64 | - | |
65 | -#define REG 12 | |
66 | -#include "op_template.h" | |
67 | - | |
68 | -#define REG 13 | |
69 | -#include "op_template.h" | |
70 | - | |
71 | -#define REG 14 | |
72 | -#include "op_template.h" | |
73 | - | |
74 | -#define REG 15 | |
75 | -#include "op_template.h" | |
76 | - | |
77 | -#define REG 16 | |
78 | -#include "op_template.h" | |
79 | - | |
80 | -#define REG 17 | |
81 | -#include "op_template.h" | |
82 | - | |
83 | -#define REG 18 | |
84 | -#include "op_template.h" | |
85 | - | |
86 | -#define REG 19 | |
87 | -#include "op_template.h" | |
88 | - | |
89 | -#define REG 20 | |
90 | -#include "op_template.h" | |
91 | - | |
92 | -#define REG 21 | |
93 | -#include "op_template.h" | |
94 | - | |
95 | -#define REG 22 | |
96 | -#include "op_template.h" | |
97 | - | |
98 | -#define REG 23 | |
99 | -#include "op_template.h" | |
100 | - | |
101 | -#define REG 24 | |
102 | -#include "op_template.h" | |
103 | - | |
104 | -#define REG 25 | |
105 | -#include "op_template.h" | |
106 | - | |
107 | -#define REG 26 | |
108 | -#include "op_template.h" | |
109 | - | |
110 | -#define REG 27 | |
111 | -#include "op_template.h" | |
112 | - | |
113 | -#define REG 28 | |
114 | -#include "op_template.h" | |
115 | - | |
116 | -#define REG 29 | |
117 | -#include "op_template.h" | |
118 | - | |
119 | -#define REG 30 | |
120 | -#include "op_template.h" | |
121 | - | |
122 | -#define REG 31 | |
123 | -#include "op_template.h" | |
124 | - | |
125 | 28 | /* Debug stuff */ |
126 | 29 | void OPPROTO op_no_op (void) |
127 | 30 | { |
... | ... | @@ -148,383 +51,6 @@ void OPPROTO op_no_op (void) |
148 | 51 | #include "op_mem.h" |
149 | 52 | #endif |
150 | 53 | |
151 | -/* Misc */ | |
152 | -void OPPROTO op_load_fpcr (void) | |
153 | -{ | |
154 | - helper_load_fpcr(); | |
155 | - RETURN(); | |
156 | -} | |
157 | - | |
158 | -void OPPROTO op_store_fpcr (void) | |
159 | -{ | |
160 | - helper_store_fpcr(); | |
161 | - RETURN(); | |
162 | -} | |
163 | - | |
164 | -/* Tests */ | |
165 | -#if 0 // Qemu does not know how to do this... | |
166 | -void OPPROTO op_bcond (void) | |
167 | -{ | |
168 | - if (T0) | |
169 | - env->pc = T1 & ~3; | |
170 | - else | |
171 | - env->pc = PARAM(1); | |
172 | - RETURN(); | |
173 | -} | |
174 | -#else | |
175 | -void OPPROTO op_bcond (void) | |
176 | -{ | |
177 | - if (T0) | |
178 | - env->pc = T1 & ~3; | |
179 | - else | |
180 | - env->pc = ((uint64_t)PARAM(1) << 32) | (uint64_t)PARAM(2); | |
181 | - RETURN(); | |
182 | -} | |
183 | -#endif | |
184 | - | |
185 | -/* IEEE floating point arithmetic */ | |
186 | -/* S floating (single) */ | |
187 | -void OPPROTO op_adds (void) | |
188 | -{ | |
189 | - FT0 = float32_add(FT0, FT1, &FP_STATUS); | |
190 | - RETURN(); | |
191 | -} | |
192 | - | |
193 | -void OPPROTO op_subs (void) | |
194 | -{ | |
195 | - FT0 = float32_sub(FT0, FT1, &FP_STATUS); | |
196 | - RETURN(); | |
197 | -} | |
198 | - | |
199 | -void OPPROTO op_muls (void) | |
200 | -{ | |
201 | - FT0 = float32_mul(FT0, FT1, &FP_STATUS); | |
202 | - RETURN(); | |
203 | -} | |
204 | - | |
205 | -void OPPROTO op_divs (void) | |
206 | -{ | |
207 | - FT0 = float32_div(FT0, FT1, &FP_STATUS); | |
208 | - RETURN(); | |
209 | -} | |
210 | - | |
211 | -void OPPROTO op_sqrts (void) | |
212 | -{ | |
213 | - helper_sqrts(); | |
214 | - RETURN(); | |
215 | -} | |
216 | - | |
217 | -void OPPROTO op_cpys (void) | |
218 | -{ | |
219 | - helper_cpys(); | |
220 | - RETURN(); | |
221 | -} | |
222 | - | |
223 | -void OPPROTO op_cpysn (void) | |
224 | -{ | |
225 | - helper_cpysn(); | |
226 | - RETURN(); | |
227 | -} | |
228 | - | |
229 | -void OPPROTO op_cpyse (void) | |
230 | -{ | |
231 | - helper_cpyse(); | |
232 | - RETURN(); | |
233 | -} | |
234 | - | |
235 | -void OPPROTO op_itofs (void) | |
236 | -{ | |
237 | - helper_itofs(); | |
238 | - RETURN(); | |
239 | -} | |
240 | - | |
241 | -void OPPROTO op_ftois (void) | |
242 | -{ | |
243 | - helper_ftois(); | |
244 | - RETURN(); | |
245 | -} | |
246 | - | |
247 | -/* T floating (double) */ | |
248 | -void OPPROTO op_addt (void) | |
249 | -{ | |
250 | - FT0 = float64_add(FT0, FT1, &FP_STATUS); | |
251 | - RETURN(); | |
252 | -} | |
253 | - | |
254 | -void OPPROTO op_subt (void) | |
255 | -{ | |
256 | - FT0 = float64_sub(FT0, FT1, &FP_STATUS); | |
257 | - RETURN(); | |
258 | -} | |
259 | - | |
260 | -void OPPROTO op_mult (void) | |
261 | -{ | |
262 | - FT0 = float64_mul(FT0, FT1, &FP_STATUS); | |
263 | - RETURN(); | |
264 | -} | |
265 | - | |
266 | -void OPPROTO op_divt (void) | |
267 | -{ | |
268 | - FT0 = float64_div(FT0, FT1, &FP_STATUS); | |
269 | - RETURN(); | |
270 | -} | |
271 | - | |
272 | -void OPPROTO op_sqrtt (void) | |
273 | -{ | |
274 | - helper_sqrtt(); | |
275 | - RETURN(); | |
276 | -} | |
277 | - | |
278 | -void OPPROTO op_cmptun (void) | |
279 | -{ | |
280 | - helper_cmptun(); | |
281 | - RETURN(); | |
282 | -} | |
283 | - | |
284 | -void OPPROTO op_cmpteq (void) | |
285 | -{ | |
286 | - helper_cmpteq(); | |
287 | - RETURN(); | |
288 | -} | |
289 | - | |
290 | -void OPPROTO op_cmptle (void) | |
291 | -{ | |
292 | - helper_cmptle(); | |
293 | - RETURN(); | |
294 | -} | |
295 | - | |
296 | -void OPPROTO op_cmptlt (void) | |
297 | -{ | |
298 | - helper_cmptlt(); | |
299 | - RETURN(); | |
300 | -} | |
301 | - | |
302 | -void OPPROTO op_itoft (void) | |
303 | -{ | |
304 | - helper_itoft(); | |
305 | - RETURN(); | |
306 | -} | |
307 | - | |
308 | -void OPPROTO op_ftoit (void) | |
309 | -{ | |
310 | - helper_ftoit(); | |
311 | - RETURN(); | |
312 | -} | |
313 | - | |
314 | -/* VAX floating point arithmetic */ | |
315 | -/* F floating */ | |
316 | -void OPPROTO op_addf (void) | |
317 | -{ | |
318 | - helper_addf(); | |
319 | - RETURN(); | |
320 | -} | |
321 | - | |
322 | -void OPPROTO op_subf (void) | |
323 | -{ | |
324 | - helper_subf(); | |
325 | - RETURN(); | |
326 | -} | |
327 | - | |
328 | -void OPPROTO op_mulf (void) | |
329 | -{ | |
330 | - helper_mulf(); | |
331 | - RETURN(); | |
332 | -} | |
333 | - | |
334 | -void OPPROTO op_divf (void) | |
335 | -{ | |
336 | - helper_divf(); | |
337 | - RETURN(); | |
338 | -} | |
339 | - | |
340 | -void OPPROTO op_sqrtf (void) | |
341 | -{ | |
342 | - helper_sqrtf(); | |
343 | - RETURN(); | |
344 | -} | |
345 | - | |
346 | -void OPPROTO op_cmpfeq (void) | |
347 | -{ | |
348 | - helper_cmpfeq(); | |
349 | - RETURN(); | |
350 | -} | |
351 | - | |
352 | -void OPPROTO op_cmpfne (void) | |
353 | -{ | |
354 | - helper_cmpfne(); | |
355 | - RETURN(); | |
356 | -} | |
357 | - | |
358 | -void OPPROTO op_cmpflt (void) | |
359 | -{ | |
360 | - helper_cmpflt(); | |
361 | - RETURN(); | |
362 | -} | |
363 | - | |
364 | -void OPPROTO op_cmpfle (void) | |
365 | -{ | |
366 | - helper_cmpfle(); | |
367 | - RETURN(); | |
368 | -} | |
369 | - | |
370 | -void OPPROTO op_cmpfgt (void) | |
371 | -{ | |
372 | - helper_cmpfgt(); | |
373 | - RETURN(); | |
374 | -} | |
375 | - | |
376 | -void OPPROTO op_cmpfge (void) | |
377 | -{ | |
378 | - helper_cmpfge(); | |
379 | - RETURN(); | |
380 | -} | |
381 | - | |
382 | -void OPPROTO op_itoff (void) | |
383 | -{ | |
384 | - helper_itoff(); | |
385 | - RETURN(); | |
386 | -} | |
387 | - | |
388 | -/* G floating */ | |
389 | -void OPPROTO op_addg (void) | |
390 | -{ | |
391 | - helper_addg(); | |
392 | - RETURN(); | |
393 | -} | |
394 | - | |
395 | -void OPPROTO op_subg (void) | |
396 | -{ | |
397 | - helper_subg(); | |
398 | - RETURN(); | |
399 | -} | |
400 | - | |
401 | -void OPPROTO op_mulg (void) | |
402 | -{ | |
403 | - helper_mulg(); | |
404 | - RETURN(); | |
405 | -} | |
406 | - | |
407 | -void OPPROTO op_divg (void) | |
408 | -{ | |
409 | - helper_divg(); | |
410 | - RETURN(); | |
411 | -} | |
412 | - | |
413 | -void OPPROTO op_sqrtg (void) | |
414 | -{ | |
415 | - helper_sqrtg(); | |
416 | - RETURN(); | |
417 | -} | |
418 | - | |
419 | -void OPPROTO op_cmpgeq (void) | |
420 | -{ | |
421 | - helper_cmpgeq(); | |
422 | - RETURN(); | |
423 | -} | |
424 | - | |
425 | -void OPPROTO op_cmpglt (void) | |
426 | -{ | |
427 | - helper_cmpglt(); | |
428 | - RETURN(); | |
429 | -} | |
430 | - | |
431 | -void OPPROTO op_cmpgle (void) | |
432 | -{ | |
433 | - helper_cmpgle(); | |
434 | - RETURN(); | |
435 | -} | |
436 | - | |
437 | -/* Floating point format conversion */ | |
438 | -void OPPROTO op_cvtst (void) | |
439 | -{ | |
440 | - FT0 = (float)FT0; | |
441 | - RETURN(); | |
442 | -} | |
443 | - | |
444 | -void OPPROTO op_cvtqs (void) | |
445 | -{ | |
446 | - helper_cvtqs(); | |
447 | - RETURN(); | |
448 | -} | |
449 | - | |
450 | -void OPPROTO op_cvtts (void) | |
451 | -{ | |
452 | - FT0 = (float)FT0; | |
453 | - RETURN(); | |
454 | -} | |
455 | - | |
456 | -void OPPROTO op_cvttq (void) | |
457 | -{ | |
458 | - helper_cvttq(); | |
459 | - RETURN(); | |
460 | -} | |
461 | - | |
462 | -void OPPROTO op_cvtqt (void) | |
463 | -{ | |
464 | - helper_cvtqt(); | |
465 | - RETURN(); | |
466 | -} | |
467 | - | |
468 | -void OPPROTO op_cvtqf (void) | |
469 | -{ | |
470 | - helper_cvtqf(); | |
471 | - RETURN(); | |
472 | -} | |
473 | - | |
474 | -void OPPROTO op_cvtgf (void) | |
475 | -{ | |
476 | - helper_cvtgf(); | |
477 | - RETURN(); | |
478 | -} | |
479 | - | |
480 | -void OPPROTO op_cvtgd (void) | |
481 | -{ | |
482 | - helper_cvtgd(); | |
483 | - RETURN(); | |
484 | -} | |
485 | - | |
486 | -void OPPROTO op_cvtgq (void) | |
487 | -{ | |
488 | - helper_cvtgq(); | |
489 | - RETURN(); | |
490 | -} | |
491 | - | |
492 | -void OPPROTO op_cvtqg (void) | |
493 | -{ | |
494 | - helper_cvtqg(); | |
495 | - RETURN(); | |
496 | -} | |
497 | - | |
498 | -void OPPROTO op_cvtdg (void) | |
499 | -{ | |
500 | - helper_cvtdg(); | |
501 | - RETURN(); | |
502 | -} | |
503 | - | |
504 | -void OPPROTO op_cvtlq (void) | |
505 | -{ | |
506 | - helper_cvtlq(); | |
507 | - RETURN(); | |
508 | -} | |
509 | - | |
510 | -void OPPROTO op_cvtql (void) | |
511 | -{ | |
512 | - helper_cvtql(); | |
513 | - RETURN(); | |
514 | -} | |
515 | - | |
516 | -void OPPROTO op_cvtqlv (void) | |
517 | -{ | |
518 | - helper_cvtqlv(); | |
519 | - RETURN(); | |
520 | -} | |
521 | - | |
522 | -void OPPROTO op_cvtqlsv (void) | |
523 | -{ | |
524 | - helper_cvtqlsv(); | |
525 | - RETURN(); | |
526 | -} | |
527 | - | |
528 | 54 | /* PALcode support special instructions */ |
529 | 55 | #if !defined (CONFIG_USER_ONLY) |
530 | 56 | void OPPROTO op_hw_rei (void) | ... | ... |
target-alpha/op_helper.c
... | ... | @@ -24,27 +24,6 @@ |
24 | 24 | |
25 | 25 | #include "op_helper.h" |
26 | 26 | |
27 | -#define MEMSUFFIX _raw | |
28 | -#include "op_helper_mem.h" | |
29 | - | |
30 | -#if !defined(CONFIG_USER_ONLY) | |
31 | -#define MEMSUFFIX _kernel | |
32 | -#include "op_helper_mem.h" | |
33 | - | |
34 | -#define MEMSUFFIX _executive | |
35 | -#include "op_helper_mem.h" | |
36 | - | |
37 | -#define MEMSUFFIX _supervisor | |
38 | -#include "op_helper_mem.h" | |
39 | - | |
40 | -#define MEMSUFFIX _user | |
41 | -#include "op_helper_mem.h" | |
42 | - | |
43 | -/* This is used for pal modes */ | |
44 | -#define MEMSUFFIX _data | |
45 | -#include "op_helper_mem.h" | |
46 | -#endif | |
47 | - | |
48 | 27 | void helper_tb_flush (void) |
49 | 28 | { |
50 | 29 | tlb_flush(env, 1); |
... | ... | @@ -91,37 +70,38 @@ uint64_t helper_load_implver (void) |
91 | 70 | return env->implver; |
92 | 71 | } |
93 | 72 | |
94 | -void helper_load_fpcr (void) | |
73 | +uint64_t helper_load_fpcr (void) | |
95 | 74 | { |
96 | - T0 = 0; | |
75 | + uint64_t ret = 0; | |
97 | 76 | #ifdef CONFIG_SOFTFLOAT |
98 | - T0 |= env->fp_status.float_exception_flags << 52; | |
77 | + ret |= env->fp_status.float_exception_flags << 52; | |
99 | 78 | if (env->fp_status.float_exception_flags) |
100 | - T0 |= 1ULL << 63; | |
79 | + ret |= 1ULL << 63; | |
101 | 80 | env->ipr[IPR_EXC_SUM] &= ~0x3E: |
102 | 81 | env->ipr[IPR_EXC_SUM] |= env->fp_status.float_exception_flags << 1; |
103 | 82 | #endif |
104 | 83 | switch (env->fp_status.float_rounding_mode) { |
105 | 84 | case float_round_nearest_even: |
106 | - T0 |= 2ULL << 58; | |
85 | + ret |= 2ULL << 58; | |
107 | 86 | break; |
108 | 87 | case float_round_down: |
109 | - T0 |= 1ULL << 58; | |
88 | + ret |= 1ULL << 58; | |
110 | 89 | break; |
111 | 90 | case float_round_up: |
112 | - T0 |= 3ULL << 58; | |
91 | + ret |= 3ULL << 58; | |
113 | 92 | break; |
114 | 93 | case float_round_to_zero: |
115 | 94 | break; |
116 | 95 | } |
96 | + return ret; | |
117 | 97 | } |
118 | 98 | |
119 | -void helper_store_fpcr (void) | |
99 | +void helper_store_fpcr (uint64_t val) | |
120 | 100 | { |
121 | 101 | #ifdef CONFIG_SOFTFLOAT |
122 | - set_float_exception_flags((T0 >> 52) & 0x3F, &FP_STATUS); | |
102 | + set_float_exception_flags((val >> 52) & 0x3F, &FP_STATUS); | |
123 | 103 | #endif |
124 | - switch ((T0 >> 58) & 3) { | |
104 | + switch ((val >> 58) & 3) { | |
125 | 105 | case 0: |
126 | 106 | set_float_rounding_mode(float_round_to_zero, &FP_STATUS); |
127 | 107 | break; |
... | ... | @@ -367,675 +347,647 @@ uint64_t helper_cmpbge (uint64_t op1, uint64_t op2) |
367 | 347 | return res; |
368 | 348 | } |
369 | 349 | |
370 | -void helper_cmov_fir (int freg) | |
350 | +/* Floating point helpers */ | |
351 | + | |
352 | +/* F floating (VAX) */ | |
353 | +static always_inline uint64_t float32_to_f (float32 fa) | |
371 | 354 | { |
372 | - if (FT0 != 0) | |
373 | - env->fir[freg] = FT1; | |
355 | + uint32_t a; | |
356 | + uint64_t r, exp, mant, sig; | |
357 | + | |
358 | + a = *(uint32_t*)(&fa); | |
359 | + sig = ((uint64_t)a & 0x80000000) << 32; | |
360 | + exp = (a >> 23) & 0xff; | |
361 | + mant = ((uint64_t)a & 0x007fffff) << 29; | |
362 | + | |
363 | + if (exp == 255) { | |
364 | + /* NaN or infinity */ | |
365 | + r = 1; /* VAX dirty zero */ | |
366 | + } else if (exp == 0) { | |
367 | + if (mant == 0) { | |
368 | + /* Zero */ | |
369 | + r = 0; | |
370 | + } else { | |
371 | + /* Denormalized */ | |
372 | + r = sig | ((exp + 1) << 52) | mant; | |
373 | + } | |
374 | + } else { | |
375 | + if (exp >= 253) { | |
376 | + /* Overflow */ | |
377 | + r = 1; /* VAX dirty zero */ | |
378 | + } else { | |
379 | + r = sig | ((exp + 2) << 52); | |
380 | + } | |
381 | + } | |
382 | + | |
383 | + return r; | |
374 | 384 | } |
375 | 385 | |
376 | -void helper_sqrts (void) | |
386 | +static always_inline float32 f_to_float32 (uint64_t a) | |
377 | 387 | { |
378 | - FT0 = float32_sqrt(FT0, &FP_STATUS); | |
388 | + uint32_t r, exp, mant_sig; | |
389 | + | |
390 | + exp = ((a >> 55) & 0x80) | ((a >> 52) & 0x7f); | |
391 | + mant_sig = ((a >> 32) & 0x80000000) | ((a >> 29) & 0x007fffff); | |
392 | + | |
393 | + if (unlikely(!exp && mant_sig)) { | |
394 | + /* Reserved operands / Dirty zero */ | |
395 | + helper_excp(EXCP_OPCDEC, 0); | |
396 | + } | |
397 | + | |
398 | + if (exp < 3) { | |
399 | + /* Underflow */ | |
400 | + r = 0; | |
401 | + } else { | |
402 | + r = ((exp - 2) << 23) | mant_sig; | |
403 | + } | |
404 | + | |
405 | + return *(float32*)(&a); | |
379 | 406 | } |
380 | 407 | |
381 | -void helper_cpys (void) | |
408 | +uint32_t helper_f_to_memory (uint64_t a) | |
382 | 409 | { |
383 | - union { | |
384 | - double d; | |
385 | - uint64_t i; | |
386 | - } p, q, r; | |
410 | + uint32_t r; | |
411 | + r = (a & 0x00001fffe0000000ull) >> 13; | |
412 | + r |= (a & 0x07ffe00000000000ull) >> 45; | |
413 | + r |= (a & 0xc000000000000000ull) >> 48; | |
414 | + return r; | |
415 | +} | |
387 | 416 | |
388 | - p.d = FT0; | |
389 | - q.d = FT1; | |
390 | - r.i = p.i & 0x8000000000000000ULL; | |
391 | - r.i |= q.i & ~0x8000000000000000ULL; | |
392 | - FT0 = r.d; | |
417 | +uint64_t helper_memory_to_f (uint32_t a) | |
418 | +{ | |
419 | + uint64_t r; | |
420 | + r = ((uint64_t)(a & 0x0000c000)) << 48; | |
421 | + r |= ((uint64_t)(a & 0x003fffff)) << 45; | |
422 | + r |= ((uint64_t)(a & 0xffff0000)) << 13; | |
423 | + if (!(a & 0x00004000)) | |
424 | + r |= 0x7ll << 59; | |
425 | + return r; | |
393 | 426 | } |
394 | 427 | |
395 | -void helper_cpysn (void) | |
428 | +uint64_t helper_addf (uint64_t a, uint64_t b) | |
396 | 429 | { |
397 | - union { | |
398 | - double d; | |
399 | - uint64_t i; | |
400 | - } p, q, r; | |
430 | + float32 fa, fb, fr; | |
401 | 431 | |
402 | - p.d = FT0; | |
403 | - q.d = FT1; | |
404 | - r.i = (~p.i) & 0x8000000000000000ULL; | |
405 | - r.i |= q.i & ~0x8000000000000000ULL; | |
406 | - FT0 = r.d; | |
432 | + fa = f_to_float32(a); | |
433 | + fb = f_to_float32(b); | |
434 | + fr = float32_add(fa, fb, &FP_STATUS); | |
435 | + return float32_to_f(fr); | |
407 | 436 | } |
408 | 437 | |
409 | -void helper_cpyse (void) | |
438 | +uint64_t helper_subf (uint64_t a, uint64_t b) | |
410 | 439 | { |
411 | - union { | |
412 | - double d; | |
413 | - uint64_t i; | |
414 | - } p, q, r; | |
440 | + float32 fa, fb, fr; | |
415 | 441 | |
416 | - p.d = FT0; | |
417 | - q.d = FT1; | |
418 | - r.i = p.i & 0xFFF0000000000000ULL; | |
419 | - r.i |= q.i & ~0xFFF0000000000000ULL; | |
420 | - FT0 = r.d; | |
442 | + fa = f_to_float32(a); | |
443 | + fb = f_to_float32(b); | |
444 | + fr = float32_sub(fa, fb, &FP_STATUS); | |
445 | + return float32_to_f(fr); | |
421 | 446 | } |
422 | 447 | |
423 | -void helper_itofs (void) | |
448 | +uint64_t helper_mulf (uint64_t a, uint64_t b) | |
424 | 449 | { |
425 | - union { | |
426 | - double d; | |
427 | - uint64_t i; | |
428 | - } p; | |
450 | + float32 fa, fb, fr; | |
429 | 451 | |
430 | - p.d = FT0; | |
431 | - FT0 = int64_to_float32(p.i, &FP_STATUS); | |
452 | + fa = f_to_float32(a); | |
453 | + fb = f_to_float32(b); | |
454 | + fr = float32_mul(fa, fb, &FP_STATUS); | |
455 | + return float32_to_f(fr); | |
432 | 456 | } |
433 | 457 | |
434 | -void helper_ftois (void) | |
458 | +uint64_t helper_divf (uint64_t a, uint64_t b) | |
435 | 459 | { |
436 | - union { | |
437 | - double d; | |
438 | - uint64_t i; | |
439 | - } p; | |
460 | + float32 fa, fb, fr; | |
440 | 461 | |
441 | - p.i = float32_to_int64(FT0, &FP_STATUS); | |
442 | - FT0 = p.d; | |
462 | + fa = f_to_float32(a); | |
463 | + fb = f_to_float32(b); | |
464 | + fr = float32_div(fa, fb, &FP_STATUS); | |
465 | + return float32_to_f(fr); | |
443 | 466 | } |
444 | 467 | |
445 | -void helper_sqrtt (void) | |
468 | +uint64_t helper_sqrtf (uint64_t t) | |
446 | 469 | { |
447 | - FT0 = float64_sqrt(FT0, &FP_STATUS); | |
470 | + float32 ft, fr; | |
471 | + | |
472 | + ft = f_to_float32(t); | |
473 | + fr = float32_sqrt(ft, &FP_STATUS); | |
474 | + return float32_to_f(fr); | |
448 | 475 | } |
449 | 476 | |
450 | -void helper_cmptun (void) | |
477 | + | |
478 | +/* G floating (VAX) */ | |
479 | +static always_inline uint64_t float64_to_g (float64 fa) | |
451 | 480 | { |
452 | - union { | |
453 | - double d; | |
454 | - uint64_t i; | |
455 | - } p; | |
481 | + uint64_t a, r, exp, mant, sig; | |
456 | 482 | |
457 | - p.i = 0; | |
458 | - if (float64_is_nan(FT0) || float64_is_nan(FT1)) | |
459 | - p.i = 0x4000000000000000ULL; | |
460 | - FT0 = p.d; | |
483 | + a = *(uint64_t*)(&fa); | |
484 | + sig = a & 0x8000000000000000ull; | |
485 | + exp = (a >> 52) & 0x7ff; | |
486 | + mant = a & 0x000fffffffffffffull; | |
487 | + | |
488 | + if (exp == 2047) { | |
489 | + /* NaN or infinity */ | |
490 | + r = 1; /* VAX dirty zero */ | |
491 | + } else if (exp == 0) { | |
492 | + if (mant == 0) { | |
493 | + /* Zero */ | |
494 | + r = 0; | |
495 | + } else { | |
496 | + /* Denormalized */ | |
497 | + r = sig | ((exp + 1) << 52) | mant; | |
498 | + } | |
499 | + } else { | |
500 | + if (exp >= 2045) { | |
501 | + /* Overflow */ | |
502 | + r = 1; /* VAX dirty zero */ | |
503 | + } else { | |
504 | + r = sig | ((exp + 2) << 52); | |
505 | + } | |
506 | + } | |
507 | + | |
508 | + return r; | |
461 | 509 | } |
462 | 510 | |
463 | -void helper_cmpteq (void) | |
511 | +static always_inline float64 g_to_float64 (uint64_t a) | |
464 | 512 | { |
465 | - union { | |
466 | - double d; | |
467 | - uint64_t i; | |
468 | - } p; | |
513 | + uint64_t r, exp, mant_sig; | |
514 | + | |
515 | + exp = (a >> 52) & 0x7ff; | |
516 | + mant_sig = a & 0x800fffffffffffffull; | |
517 | + | |
518 | + if (!exp && mant_sig) { | |
519 | + /* Reserved operands / Dirty zero */ | |
520 | + helper_excp(EXCP_OPCDEC, 0); | |
521 | + } | |
469 | 522 | |
470 | - p.i = 0; | |
471 | - if (float64_eq(FT0, FT1, &FP_STATUS)) | |
472 | - p.i = 0x4000000000000000ULL; | |
473 | - FT0 = p.d; | |
523 | + if (exp < 3) { | |
524 | + /* Underflow */ | |
525 | + r = 0; | |
526 | + } else { | |
527 | + r = ((exp - 2) << 52) | mant_sig; | |
528 | + } | |
529 | + | |
530 | + return *(float64*)(&a); | |
474 | 531 | } |
475 | 532 | |
476 | -void helper_cmptle (void) | |
533 | +uint64_t helper_g_to_memory (uint64_t a) | |
477 | 534 | { |
478 | - union { | |
479 | - double d; | |
480 | - uint64_t i; | |
481 | - } p; | |
535 | + uint64_t r; | |
536 | + r = (a & 0x000000000000ffffull) << 48; | |
537 | + r |= (a & 0x00000000ffff0000ull) << 16; | |
538 | + r |= (a & 0x0000ffff00000000ull) >> 16; | |
539 | + r |= (a & 0xffff000000000000ull) >> 48; | |
540 | + return r; | |
541 | +} | |
482 | 542 | |
483 | - p.i = 0; | |
484 | - if (float64_le(FT0, FT1, &FP_STATUS)) | |
485 | - p.i = 0x4000000000000000ULL; | |
486 | - FT0 = p.d; | |
543 | +uint64_t helper_memory_to_g (uint64_t a) | |
544 | +{ | |
545 | + uint64_t r; | |
546 | + r = (a & 0x000000000000ffffull) << 48; | |
547 | + r |= (a & 0x00000000ffff0000ull) << 16; | |
548 | + r |= (a & 0x0000ffff00000000ull) >> 16; | |
549 | + r |= (a & 0xffff000000000000ull) >> 48; | |
550 | + return r; | |
487 | 551 | } |
488 | 552 | |
489 | -void helper_cmptlt (void) | |
553 | +uint64_t helper_addg (uint64_t a, uint64_t b) | |
490 | 554 | { |
491 | - union { | |
492 | - double d; | |
493 | - uint64_t i; | |
494 | - } p; | |
555 | + float64 fa, fb, fr; | |
495 | 556 | |
496 | - p.i = 0; | |
497 | - if (float64_lt(FT0, FT1, &FP_STATUS)) | |
498 | - p.i = 0x4000000000000000ULL; | |
499 | - FT0 = p.d; | |
557 | + fa = g_to_float64(a); | |
558 | + fb = g_to_float64(b); | |
559 | + fr = float64_add(fa, fb, &FP_STATUS); | |
560 | + return float64_to_g(fr); | |
500 | 561 | } |
501 | 562 | |
502 | -void helper_itoft (void) | |
563 | +uint64_t helper_subg (uint64_t a, uint64_t b) | |
503 | 564 | { |
504 | - union { | |
505 | - double d; | |
506 | - uint64_t i; | |
507 | - } p; | |
565 | + float64 fa, fb, fr; | |
508 | 566 | |
509 | - p.d = FT0; | |
510 | - FT0 = int64_to_float64(p.i, &FP_STATUS); | |
567 | + fa = g_to_float64(a); | |
568 | + fb = g_to_float64(b); | |
569 | + fr = float64_sub(fa, fb, &FP_STATUS); | |
570 | + return float64_to_g(fr); | |
511 | 571 | } |
512 | 572 | |
513 | -void helper_ftoit (void) | |
573 | +uint64_t helper_mulg (uint64_t a, uint64_t b) | |
514 | 574 | { |
515 | - union { | |
516 | - double d; | |
517 | - uint64_t i; | |
518 | - } p; | |
575 | + float64 fa, fb, fr; | |
519 | 576 | |
520 | - p.i = float64_to_int64(FT0, &FP_STATUS); | |
521 | - FT0 = p.d; | |
577 | + fa = g_to_float64(a); | |
578 | + fb = g_to_float64(b); | |
579 | + fr = float64_mul(fa, fb, &FP_STATUS); | |
580 | + return float64_to_g(fr); | |
522 | 581 | } |
523 | 582 | |
524 | -static always_inline int vaxf_is_valid (float ff) | |
583 | +uint64_t helper_divg (uint64_t a, uint64_t b) | |
525 | 584 | { |
526 | - union { | |
527 | - float f; | |
528 | - uint32_t i; | |
529 | - } p; | |
530 | - uint32_t exp, mant; | |
585 | + float64 fa, fb, fr; | |
531 | 586 | |
532 | - p.f = ff; | |
533 | - exp = (p.i >> 23) & 0xFF; | |
534 | - mant = p.i & 0x007FFFFF; | |
535 | - if (exp == 0 && ((p.i & 0x80000000) || mant != 0)) { | |
536 | - /* Reserved operands / Dirty zero */ | |
537 | - return 0; | |
538 | - } | |
587 | + fa = g_to_float64(a); | |
588 | + fb = g_to_float64(b); | |
589 | + fr = float64_div(fa, fb, &FP_STATUS); | |
590 | + return float64_to_g(fr); | |
591 | +} | |
592 | + | |
593 | +uint64_t helper_sqrtg (uint64_t a) | |
594 | +{ | |
595 | + float64 fa, fr; | |
539 | 596 | |
540 | - return 1; | |
597 | + fa = g_to_float64(a); | |
598 | + fr = float64_sqrt(fa, &FP_STATUS); | |
599 | + return float64_to_g(fr); | |
541 | 600 | } |
542 | 601 | |
543 | -static always_inline float vaxf_to_ieee32 (float ff) | |
602 | + | |
603 | +/* S floating (single) */ | |
604 | +static always_inline uint64_t float32_to_s (float32 fa) | |
544 | 605 | { |
545 | - union { | |
546 | - float f; | |
547 | - uint32_t i; | |
548 | - } p; | |
549 | - uint32_t exp; | |
606 | + uint32_t a; | |
607 | + uint64_t r; | |
550 | 608 | |
551 | - p.f = ff; | |
552 | - exp = (p.i >> 23) & 0xFF; | |
553 | - if (exp < 3) { | |
554 | - /* Underflow */ | |
555 | - p.f = 0.0; | |
556 | - } else { | |
557 | - p.f *= 0.25; | |
558 | - } | |
609 | + a = *(uint32_t*)(&fa); | |
559 | 610 | |
560 | - return p.f; | |
611 | + r = (((uint64_t)(a & 0xc0000000)) << 32) | (((uint64_t)(a & 0x3fffffff)) << 29); | |
612 | + if (((a & 0x7f800000) != 0x7f800000) && (!(a & 0x40000000))) | |
613 | + r |= 0x7ll << 59; | |
614 | + return r; | |
561 | 615 | } |
562 | 616 | |
563 | -static always_inline float ieee32_to_vaxf (float fi) | |
617 | +static always_inline float32 s_to_float32 (uint64_t a) | |
564 | 618 | { |
565 | - union { | |
566 | - float f; | |
567 | - uint32_t i; | |
568 | - } p; | |
569 | - uint32_t exp, mant; | |
619 | + uint32_t r = ((a >> 32) & 0xc0000000) | ((a >> 29) & 0x3fffffff); | |
620 | + return *(float32*)(&r); | |
621 | +} | |
570 | 622 | |
571 | - p.f = fi; | |
572 | - exp = (p.i >> 23) & 0xFF; | |
573 | - mant = p.i & 0x007FFFFF; | |
574 | - if (exp == 255) { | |
575 | - /* NaN or infinity */ | |
576 | - p.i = 1; | |
577 | - } else if (exp == 0) { | |
578 | - if (mant == 0) { | |
579 | - /* Zero */ | |
580 | - p.i = 0; | |
581 | - } else { | |
582 | - /* Denormalized */ | |
583 | - p.f *= 2.0; | |
584 | - } | |
585 | - } else { | |
586 | - if (exp >= 253) { | |
587 | - /* Overflow */ | |
588 | - p.i = 1; | |
589 | - } else { | |
590 | - p.f *= 4.0; | |
591 | - } | |
592 | - } | |
623 | +uint32_t helper_s_to_memory (uint64_t a) | |
624 | +{ | |
625 | + /* Memory format is the same as float32 */ | |
626 | + float32 fa = s_to_float32(a); | |
627 | + return *(uint32_t*)(&fa); | |
628 | +} | |
593 | 629 | |
594 | - return p.f; | |
630 | +uint64_t helper_memory_to_s (uint32_t a) | |
631 | +{ | |
632 | + /* Memory format is the same as float32 */ | |
633 | + return float32_to_s(*(float32*)(&a)); | |
595 | 634 | } |
596 | 635 | |
597 | -void helper_addf (void) | |
636 | +uint64_t helper_adds (uint64_t a, uint64_t b) | |
598 | 637 | { |
599 | - float ft0, ft1, ft2; | |
638 | + float32 fa, fb, fr; | |
600 | 639 | |
601 | - if (!vaxf_is_valid(FT0) || !vaxf_is_valid(FT1)) { | |
602 | - /* XXX: TODO */ | |
603 | - } | |
604 | - ft0 = vaxf_to_ieee32(FT0); | |
605 | - ft1 = vaxf_to_ieee32(FT1); | |
606 | - ft2 = float32_add(ft0, ft1, &FP_STATUS); | |
607 | - FT0 = ieee32_to_vaxf(ft2); | |
640 | + fa = s_to_float32(a); | |
641 | + fb = s_to_float32(b); | |
642 | + fr = float32_add(fa, fb, &FP_STATUS); | |
643 | + return float32_to_s(fr); | |
608 | 644 | } |
609 | 645 | |
610 | -void helper_subf (void) | |
646 | +uint64_t helper_subs (uint64_t a, uint64_t b) | |
611 | 647 | { |
612 | - float ft0, ft1, ft2; | |
648 | + float32 fa, fb, fr; | |
613 | 649 | |
614 | - if (!vaxf_is_valid(FT0) || !vaxf_is_valid(FT1)) { | |
615 | - /* XXX: TODO */ | |
616 | - } | |
617 | - ft0 = vaxf_to_ieee32(FT0); | |
618 | - ft1 = vaxf_to_ieee32(FT1); | |
619 | - ft2 = float32_sub(ft0, ft1, &FP_STATUS); | |
620 | - FT0 = ieee32_to_vaxf(ft2); | |
650 | + fa = s_to_float32(a); | |
651 | + fb = s_to_float32(b); | |
652 | + fr = float32_sub(fa, fb, &FP_STATUS); | |
653 | + return float32_to_s(fr); | |
621 | 654 | } |
622 | 655 | |
623 | -void helper_mulf (void) | |
656 | +uint64_t helper_muls (uint64_t a, uint64_t b) | |
624 | 657 | { |
625 | - float ft0, ft1, ft2; | |
658 | + float32 fa, fb, fr; | |
626 | 659 | |
627 | - if (!vaxf_is_valid(FT0) || !vaxf_is_valid(FT1)) { | |
628 | - /* XXX: TODO */ | |
629 | - } | |
630 | - ft0 = vaxf_to_ieee32(FT0); | |
631 | - ft1 = vaxf_to_ieee32(FT1); | |
632 | - ft2 = float32_mul(ft0, ft1, &FP_STATUS); | |
633 | - FT0 = ieee32_to_vaxf(ft2); | |
660 | + fa = s_to_float32(a); | |
661 | + fb = s_to_float32(b); | |
662 | + fr = float32_mul(fa, fb, &FP_STATUS); | |
663 | + return float32_to_s(fr); | |
634 | 664 | } |
635 | 665 | |
636 | -void helper_divf (void) | |
666 | +uint64_t helper_divs (uint64_t a, uint64_t b) | |
637 | 667 | { |
638 | - float ft0, ft1, ft2; | |
668 | + float32 fa, fb, fr; | |
639 | 669 | |
640 | - if (!vaxf_is_valid(FT0) || !vaxf_is_valid(FT1)) { | |
641 | - /* XXX: TODO */ | |
642 | - } | |
643 | - ft0 = vaxf_to_ieee32(FT0); | |
644 | - ft1 = vaxf_to_ieee32(FT1); | |
645 | - ft2 = float32_div(ft0, ft1, &FP_STATUS); | |
646 | - FT0 = ieee32_to_vaxf(ft2); | |
670 | + fa = s_to_float32(a); | |
671 | + fb = s_to_float32(b); | |
672 | + fr = float32_div(fa, fb, &FP_STATUS); | |
673 | + return float32_to_s(fr); | |
647 | 674 | } |
648 | 675 | |
649 | -void helper_sqrtf (void) | |
676 | +uint64_t helper_sqrts (uint64_t a) | |
650 | 677 | { |
651 | - float ft0, ft1; | |
678 | + float32 fa, fr; | |
652 | 679 | |
653 | - if (!vaxf_is_valid(FT0) || !vaxf_is_valid(FT1)) { | |
654 | - /* XXX: TODO */ | |
655 | - } | |
656 | - ft0 = vaxf_to_ieee32(FT0); | |
657 | - ft1 = float32_sqrt(ft0, &FP_STATUS); | |
658 | - FT0 = ieee32_to_vaxf(ft1); | |
680 | + fa = s_to_float32(a); | |
681 | + fr = float32_sqrt(fa, &FP_STATUS); | |
682 | + return float32_to_s(fr); | |
659 | 683 | } |
660 | 684 | |
661 | -void helper_itoff (void) | |
685 | + | |
686 | +/* T floating (double) */ | |
687 | +static always_inline float64 t_to_float64 (uint64_t a) | |
662 | 688 | { |
663 | - /* XXX: TODO */ | |
689 | + /* Memory format is the same as float64 */ | |
690 | + return *(float64*)(&a); | |
664 | 691 | } |
665 | 692 | |
666 | -static always_inline int vaxg_is_valid (double ff) | |
693 | +static always_inline uint64_t float64_to_t (float64 fa) | |
667 | 694 | { |
668 | - union { | |
669 | - double f; | |
670 | - uint64_t i; | |
671 | - } p; | |
672 | - uint64_t exp, mant; | |
695 | + /* Memory format is the same as float64 */ | |
696 | + return *(uint64*)(&fa); | |
697 | +} | |
673 | 698 | |
674 | - p.f = ff; | |
675 | - exp = (p.i >> 52) & 0x7FF; | |
676 | - mant = p.i & 0x000FFFFFFFFFFFFFULL; | |
677 | - if (exp == 0 && ((p.i & 0x8000000000000000ULL) || mant != 0)) { | |
678 | - /* Reserved operands / Dirty zero */ | |
679 | - return 0; | |
680 | - } | |
699 | +uint64_t helper_addt (uint64_t a, uint64_t b) | |
700 | +{ | |
701 | + float64 fa, fb, fr; | |
681 | 702 | |
682 | - return 1; | |
703 | + fa = t_to_float64(a); | |
704 | + fb = t_to_float64(b); | |
705 | + fr = float64_add(fa, fb, &FP_STATUS); | |
706 | + return float64_to_t(fr); | |
683 | 707 | } |
684 | 708 | |
685 | -static always_inline double vaxg_to_ieee64 (double fg) | |
709 | +uint64_t helper_subt (uint64_t a, uint64_t b) | |
686 | 710 | { |
687 | - union { | |
688 | - double f; | |
689 | - uint64_t i; | |
690 | - } p; | |
691 | - uint32_t exp; | |
711 | + float64 fa, fb, fr; | |
692 | 712 | |
693 | - p.f = fg; | |
694 | - exp = (p.i >> 52) & 0x7FF; | |
695 | - if (exp < 3) { | |
696 | - /* Underflow */ | |
697 | - p.f = 0.0; | |
698 | - } else { | |
699 | - p.f *= 0.25; | |
700 | - } | |
701 | - | |
702 | - return p.f; | |
713 | + fa = t_to_float64(a); | |
714 | + fb = t_to_float64(b); | |
715 | + fr = float64_sub(fa, fb, &FP_STATUS); | |
716 | + return float64_to_t(fr); | |
703 | 717 | } |
704 | 718 | |
705 | -static always_inline double ieee64_to_vaxg (double fi) | |
719 | +uint64_t helper_mult (uint64_t a, uint64_t b) | |
706 | 720 | { |
707 | - union { | |
708 | - double f; | |
709 | - uint64_t i; | |
710 | - } p; | |
711 | - uint64_t mant; | |
712 | - uint32_t exp; | |
713 | - | |
714 | - p.f = fi; | |
715 | - exp = (p.i >> 52) & 0x7FF; | |
716 | - mant = p.i & 0x000FFFFFFFFFFFFFULL; | |
717 | - if (exp == 255) { | |
718 | - /* NaN or infinity */ | |
719 | - p.i = 1; /* VAX dirty zero */ | |
720 | - } else if (exp == 0) { | |
721 | - if (mant == 0) { | |
722 | - /* Zero */ | |
723 | - p.i = 0; | |
724 | - } else { | |
725 | - /* Denormalized */ | |
726 | - p.f *= 2.0; | |
727 | - } | |
728 | - } else { | |
729 | - if (exp >= 2045) { | |
730 | - /* Overflow */ | |
731 | - p.i = 1; /* VAX dirty zero */ | |
732 | - } else { | |
733 | - p.f *= 4.0; | |
734 | - } | |
735 | - } | |
721 | + float64 fa, fb, fr; | |
736 | 722 | |
737 | - return p.f; | |
723 | + fa = t_to_float64(a); | |
724 | + fb = t_to_float64(b); | |
725 | + fr = float64_mul(fa, fb, &FP_STATUS); | |
726 | + return float64_to_t(fr); | |
738 | 727 | } |
739 | 728 | |
740 | -void helper_addg (void) | |
729 | +uint64_t helper_divt (uint64_t a, uint64_t b) | |
741 | 730 | { |
742 | - double ft0, ft1, ft2; | |
731 | + float64 fa, fb, fr; | |
743 | 732 | |
744 | - if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) { | |
745 | - /* XXX: TODO */ | |
746 | - } | |
747 | - ft0 = vaxg_to_ieee64(FT0); | |
748 | - ft1 = vaxg_to_ieee64(FT1); | |
749 | - ft2 = float64_add(ft0, ft1, &FP_STATUS); | |
750 | - FT0 = ieee64_to_vaxg(ft2); | |
733 | + fa = t_to_float64(a); | |
734 | + fb = t_to_float64(b); | |
735 | + fr = float64_div(fa, fb, &FP_STATUS); | |
736 | + return float64_to_t(fr); | |
751 | 737 | } |
752 | 738 | |
753 | -void helper_subg (void) | |
739 | +uint64_t helper_sqrtt (uint64_t a) | |
754 | 740 | { |
755 | - double ft0, ft1, ft2; | |
741 | + float64 fa, fr; | |
756 | 742 | |
757 | - if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) { | |
758 | - /* XXX: TODO */ | |
759 | - } | |
760 | - ft0 = vaxg_to_ieee64(FT0); | |
761 | - ft1 = vaxg_to_ieee64(FT1); | |
762 | - ft2 = float64_sub(ft0, ft1, &FP_STATUS); | |
763 | - FT0 = ieee64_to_vaxg(ft2); | |
743 | + fa = t_to_float64(a); | |
744 | + fr = float64_sqrt(fa, &FP_STATUS); | |
745 | + return float64_to_t(fr); | |
764 | 746 | } |
765 | 747 | |
766 | -void helper_mulg (void) | |
767 | -{ | |
768 | - double ft0, ft1, ft2; | |
769 | 748 | |
770 | - if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) { | |
771 | - /* XXX: TODO */ | |
772 | - } | |
773 | - ft0 = vaxg_to_ieee64(FT0); | |
774 | - ft1 = vaxg_to_ieee64(FT1); | |
775 | - ft2 = float64_mul(ft0, ft1, &FP_STATUS); | |
776 | - FT0 = ieee64_to_vaxg(ft2); | |
749 | +/* Sign copy */ | |
750 | +uint64_t helper_cpys(uint64_t a, uint64_t b) | |
751 | +{ | |
752 | + return (a & 0x8000000000000000ULL) | (b & ~0x8000000000000000ULL); | |
777 | 753 | } |
778 | 754 | |
779 | -void helper_divg (void) | |
755 | +uint64_t helper_cpysn(uint64_t a, uint64_t b) | |
780 | 756 | { |
781 | - double ft0, ft1, ft2; | |
757 | + return ((~a) & 0x8000000000000000ULL) | (b & ~0x8000000000000000ULL); | |
758 | +} | |
782 | 759 | |
783 | - if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) { | |
784 | - /* XXX: TODO */ | |
785 | - } | |
786 | - ft0 = vaxg_to_ieee64(FT0); | |
787 | - ft1 = vaxg_to_ieee64(FT1); | |
788 | - ft2 = float64_div(ft0, ft1, &FP_STATUS); | |
789 | - FT0 = ieee64_to_vaxg(ft2); | |
760 | +uint64_t helper_cpyse(uint64_t a, uint64_t b) | |
761 | +{ | |
762 | + return (a & 0xFFF0000000000000ULL) | (b & ~0xFFF0000000000000ULL); | |
790 | 763 | } |
791 | 764 | |
792 | -void helper_sqrtg (void) | |
765 | + | |
766 | +/* Comparisons */ | |
767 | +uint64_t helper_cmptun (uint64_t a, uint64_t b) | |
793 | 768 | { |
794 | - double ft0, ft1; | |
769 | + float64 fa, fb; | |
795 | 770 | |
796 | - if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) { | |
797 | - /* XXX: TODO */ | |
798 | - } | |
799 | - ft0 = vaxg_to_ieee64(FT0); | |
800 | - ft1 = float64_sqrt(ft0, &FP_STATUS); | |
801 | - FT0 = ieee64_to_vaxg(ft1); | |
771 | + fa = t_to_float64(a); | |
772 | + fb = t_to_float64(b); | |
773 | + | |
774 | + if (float64_is_nan(fa) || float64_is_nan(fb)) | |
775 | + return 0x4000000000000000ULL; | |
776 | + else | |
777 | + return 0; | |
802 | 778 | } |
803 | 779 | |
804 | -void helper_cmpgeq (void) | |
780 | +uint64_t helper_cmpteq(uint64_t a, uint64_t b) | |
805 | 781 | { |
806 | - union { | |
807 | - double d; | |
808 | - uint64_t u; | |
809 | - } p; | |
810 | - double ft0, ft1; | |
782 | + float64 fa, fb; | |
811 | 783 | |
812 | - if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) { | |
813 | - /* XXX: TODO */ | |
814 | - } | |
815 | - ft0 = vaxg_to_ieee64(FT0); | |
816 | - ft1 = vaxg_to_ieee64(FT1); | |
817 | - p.u = 0; | |
818 | - if (float64_eq(ft0, ft1, &FP_STATUS)) | |
819 | - p.u = 0x4000000000000000ULL; | |
820 | - FT0 = p.d; | |
784 | + fa = t_to_float64(a); | |
785 | + fb = t_to_float64(b); | |
786 | + | |
787 | + if (float64_eq(fa, fb, &FP_STATUS)) | |
788 | + return 0x4000000000000000ULL; | |
789 | + else | |
790 | + return 0; | |
821 | 791 | } |
822 | 792 | |
823 | -void helper_cmpglt (void) | |
793 | +uint64_t helper_cmptle(uint64_t a, uint64_t b) | |
824 | 794 | { |
825 | - union { | |
826 | - double d; | |
827 | - uint64_t u; | |
828 | - } p; | |
829 | - double ft0, ft1; | |
795 | + float64 fa, fb; | |
830 | 796 | |
831 | - if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) { | |
832 | - /* XXX: TODO */ | |
833 | - } | |
834 | - ft0 = vaxg_to_ieee64(FT0); | |
835 | - ft1 = vaxg_to_ieee64(FT1); | |
836 | - p.u = 0; | |
837 | - if (float64_lt(ft0, ft1, &FP_STATUS)) | |
838 | - p.u = 0x4000000000000000ULL; | |
839 | - FT0 = p.d; | |
797 | + fa = t_to_float64(a); | |
798 | + fb = t_to_float64(b); | |
799 | + | |
800 | + if (float64_le(fa, fb, &FP_STATUS)) | |
801 | + return 0x4000000000000000ULL; | |
802 | + else | |
803 | + return 0; | |
840 | 804 | } |
841 | 805 | |
842 | -void helper_cmpgle (void) | |
806 | +uint64_t helper_cmptlt(uint64_t a, uint64_t b) | |
843 | 807 | { |
844 | - union { | |
845 | - double d; | |
846 | - uint64_t u; | |
847 | - } p; | |
848 | - double ft0, ft1; | |
808 | + float64 fa, fb; | |
849 | 809 | |
850 | - if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) { | |
851 | - /* XXX: TODO */ | |
852 | - } | |
853 | - ft0 = vaxg_to_ieee64(FT0); | |
854 | - ft1 = vaxg_to_ieee64(FT1); | |
855 | - p.u = 0; | |
856 | - if (float64_le(ft0, ft1, &FP_STATUS)) | |
857 | - p.u = 0x4000000000000000ULL; | |
858 | - FT0 = p.d; | |
810 | + fa = t_to_float64(a); | |
811 | + fb = t_to_float64(b); | |
812 | + | |
813 | + if (float64_lt(fa, fb, &FP_STATUS)) | |
814 | + return 0x4000000000000000ULL; | |
815 | + else | |
816 | + return 0; | |
859 | 817 | } |
860 | 818 | |
861 | -void helper_cvtqs (void) | |
819 | +uint64_t helper_cmpgeq(uint64_t a, uint64_t b) | |
862 | 820 | { |
863 | - union { | |
864 | - double d; | |
865 | - uint64_t u; | |
866 | - } p; | |
821 | + float64 fa, fb; | |
867 | 822 | |
868 | - p.d = FT0; | |
869 | - FT0 = (float)p.u; | |
823 | + fa = g_to_float64(a); | |
824 | + fb = g_to_float64(b); | |
825 | + | |
826 | + if (float64_eq(fa, fb, &FP_STATUS)) | |
827 | + return 0x4000000000000000ULL; | |
828 | + else | |
829 | + return 0; | |
870 | 830 | } |
871 | 831 | |
872 | -void helper_cvttq (void) | |
832 | +uint64_t helper_cmpgle(uint64_t a, uint64_t b) | |
873 | 833 | { |
874 | - union { | |
875 | - double d; | |
876 | - uint64_t u; | |
877 | - } p; | |
834 | + float64 fa, fb; | |
835 | + | |
836 | + fa = g_to_float64(a); | |
837 | + fb = g_to_float64(b); | |
878 | 838 | |
879 | - p.u = FT0; | |
880 | - FT0 = p.d; | |
839 | + if (float64_le(fa, fb, &FP_STATUS)) | |
840 | + return 0x4000000000000000ULL; | |
841 | + else | |
842 | + return 0; | |
881 | 843 | } |
882 | 844 | |
883 | -void helper_cvtqt (void) | |
845 | +uint64_t helper_cmpglt(uint64_t a, uint64_t b) | |
884 | 846 | { |
885 | - union { | |
886 | - double d; | |
887 | - uint64_t u; | |
888 | - } p; | |
847 | + float64 fa, fb; | |
848 | + | |
849 | + fa = g_to_float64(a); | |
850 | + fb = g_to_float64(b); | |
889 | 851 | |
890 | - p.d = FT0; | |
891 | - FT0 = p.u; | |
852 | + if (float64_lt(fa, fb, &FP_STATUS)) | |
853 | + return 0x4000000000000000ULL; | |
854 | + else | |
855 | + return 0; | |
892 | 856 | } |
893 | 857 | |
894 | -void helper_cvtqf (void) | |
858 | +uint64_t helper_cmpfeq (uint64_t a) | |
895 | 859 | { |
896 | - union { | |
897 | - double d; | |
898 | - uint64_t u; | |
899 | - } p; | |
900 | - | |
901 | - p.d = FT0; | |
902 | - FT0 = ieee32_to_vaxf(p.u); | |
860 | + return !(a & 0x7FFFFFFFFFFFFFFFULL); | |
903 | 861 | } |
904 | 862 | |
905 | -void helper_cvtgf (void) | |
863 | +uint64_t helper_cmpfne (uint64_t a) | |
906 | 864 | { |
907 | - double ft0; | |
865 | + return (a & 0x7FFFFFFFFFFFFFFFULL); | |
866 | +} | |
908 | 867 | |
909 | - ft0 = vaxg_to_ieee64(FT0); | |
910 | - FT0 = ieee32_to_vaxf(ft0); | |
868 | +uint64_t helper_cmpflt (uint64_t a) | |
869 | +{ | |
870 | + return (a & 0x8000000000000000ULL) && (a & 0x7FFFFFFFFFFFFFFFULL); | |
911 | 871 | } |
912 | 872 | |
913 | -void helper_cvtgd (void) | |
873 | +uint64_t helper_cmpfle (uint64_t a) | |
914 | 874 | { |
915 | - /* XXX: TODO */ | |
875 | + return (a & 0x8000000000000000ULL) || !(a & 0x7FFFFFFFFFFFFFFFULL); | |
916 | 876 | } |
917 | 877 | |
918 | -void helper_cvtgq (void) | |
878 | +uint64_t helper_cmpfgt (uint64_t a) | |
919 | 879 | { |
920 | - union { | |
921 | - double d; | |
922 | - uint64_t u; | |
923 | - } p; | |
880 | + return !(a & 0x8000000000000000ULL) && (a & 0x7FFFFFFFFFFFFFFFULL); | |
881 | +} | |
924 | 882 | |
925 | - p.u = vaxg_to_ieee64(FT0); | |
926 | - FT0 = p.d; | |
883 | +uint64_t helper_cmpfge (uint64_t a) | |
884 | +{ | |
885 | + return !(a & 0x8000000000000000ULL) || !(a & 0x7FFFFFFFFFFFFFFFULL); | |
927 | 886 | } |
928 | 887 | |
929 | -void helper_cvtqg (void) | |
888 | + | |
889 | +/* Floating point format conversion */ | |
890 | +uint64_t helper_cvtts (uint64_t a) | |
930 | 891 | { |
931 | - union { | |
932 | - double d; | |
933 | - uint64_t u; | |
934 | - } p; | |
892 | + float64 fa; | |
893 | + float32 fr; | |
935 | 894 | |
936 | - p.d = FT0; | |
937 | - FT0 = ieee64_to_vaxg(p.u); | |
895 | + fa = t_to_float64(a); | |
896 | + fr = float64_to_float32(fa, &FP_STATUS); | |
897 | + return float32_to_s(fr); | |
938 | 898 | } |
939 | 899 | |
940 | -void helper_cvtdg (void) | |
900 | +uint64_t helper_cvtst (uint64_t a) | |
941 | 901 | { |
942 | - /* XXX: TODO */ | |
902 | + float32 fa; | |
903 | + float64 fr; | |
904 | + | |
905 | + fa = s_to_float32(a); | |
906 | + fr = float32_to_float64(fa, &FP_STATUS); | |
907 | + return float64_to_t(fr); | |
943 | 908 | } |
944 | 909 | |
945 | -void helper_cvtlq (void) | |
910 | +uint64_t helper_cvtqs (uint64_t a) | |
946 | 911 | { |
947 | - union { | |
948 | - double d; | |
949 | - uint64_t u; | |
950 | - } p, q; | |
951 | - | |
952 | - p.d = FT0; | |
953 | - q.u = (p.u >> 29) & 0x3FFFFFFF; | |
954 | - q.u |= (p.u >> 32); | |
955 | - q.u = (int64_t)((int32_t)q.u); | |
956 | - FT0 = q.d; | |
912 | + float32 fr = int64_to_float32(a, &FP_STATUS); | |
913 | + return float32_to_s(fr); | |
957 | 914 | } |
958 | 915 | |
959 | -static always_inline void __helper_cvtql (int s, int v) | |
916 | +uint64_t helper_cvttq (uint64_t a) | |
960 | 917 | { |
961 | - union { | |
962 | - double d; | |
963 | - uint64_t u; | |
964 | - } p, q; | |
918 | + float64 fa = t_to_float64(a); | |
919 | + return float64_to_int64_round_to_zero(fa, &FP_STATUS); | |
920 | +} | |
965 | 921 | |
966 | - p.d = FT0; | |
967 | - q.u = ((uint64_t)(p.u & 0xC0000000)) << 32; | |
968 | - q.u |= ((uint64_t)(p.u & 0x7FFFFFFF)) << 29; | |
969 | - FT0 = q.d; | |
970 | - if (v && (int64_t)((int32_t)p.u) != (int64_t)p.u) { | |
971 | - helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW); | |
972 | - } | |
973 | - if (s) { | |
974 | - /* TODO */ | |
975 | - } | |
922 | +uint64_t helper_cvtqt (uint64_t a) | |
923 | +{ | |
924 | + float64 fr = int64_to_float64(a, &FP_STATUS); | |
925 | + return float64_to_t(fr); | |
976 | 926 | } |
977 | 927 | |
978 | -void helper_cvtql (void) | |
928 | +uint64_t helper_cvtqf (uint64_t a) | |
979 | 929 | { |
980 | - __helper_cvtql(0, 0); | |
930 | + float32 fr = int64_to_float32(a, &FP_STATUS); | |
931 | + return float32_to_f(fr); | |
981 | 932 | } |
982 | 933 | |
983 | -void helper_cvtqlv (void) | |
934 | +uint64_t helper_cvtgf (uint64_t a) | |
984 | 935 | { |
985 | - __helper_cvtql(0, 1); | |
936 | + float64 fa; | |
937 | + float32 fr; | |
938 | + | |
939 | + fa = g_to_float64(a); | |
940 | + fr = float64_to_float32(fa, &FP_STATUS); | |
941 | + return float32_to_f(fr); | |
986 | 942 | } |
987 | 943 | |
988 | -void helper_cvtqlsv (void) | |
944 | +uint64_t helper_cvtgq (uint64_t a) | |
989 | 945 | { |
990 | - __helper_cvtql(1, 1); | |
946 | + float64 fa = g_to_float64(a); | |
947 | + return float64_to_int64_round_to_zero(fa, &FP_STATUS); | |
991 | 948 | } |
992 | 949 | |
993 | -void helper_cmpfeq (void) | |
950 | +uint64_t helper_cvtqg (uint64_t a) | |
994 | 951 | { |
995 | - if (float64_eq(FT0, FT1, &FP_STATUS)) | |
996 | - T0 = 1; | |
997 | - else | |
998 | - T0 = 0; | |
952 | + float64 fr; | |
953 | + fr = int64_to_float64(a, &FP_STATUS); | |
954 | + return float64_to_g(fr); | |
999 | 955 | } |
1000 | 956 | |
1001 | -void helper_cmpfne (void) | |
957 | +uint64_t helper_cvtlq (uint64_t a) | |
1002 | 958 | { |
1003 | - if (float64_eq(FT0, FT1, &FP_STATUS)) | |
1004 | - T0 = 0; | |
1005 | - else | |
1006 | - T0 = 1; | |
959 | + return (int64_t)((int32_t)((a >> 32) | ((a >> 29) & 0x3FFFFFFF))); | |
1007 | 960 | } |
1008 | 961 | |
1009 | -void helper_cmpflt (void) | |
962 | +static always_inline uint64_t __helper_cvtql (uint64_t a, int s, int v) | |
1010 | 963 | { |
1011 | - if (float64_lt(FT0, FT1, &FP_STATUS)) | |
1012 | - T0 = 1; | |
1013 | - else | |
1014 | - T0 = 0; | |
964 | + uint64_t r; | |
965 | + | |
966 | + r = ((uint64_t)(a & 0xC0000000)) << 32; | |
967 | + r |= ((uint64_t)(a & 0x7FFFFFFF)) << 29; | |
968 | + | |
969 | + if (v && (int64_t)((int32_t)r) != (int64_t)r) { | |
970 | + helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW); | |
971 | + } | |
972 | + if (s) { | |
973 | + /* TODO */ | |
974 | + } | |
975 | + return r; | |
1015 | 976 | } |
1016 | 977 | |
1017 | -void helper_cmpfle (void) | |
978 | +uint64_t helper_cvtql (uint64_t a) | |
1018 | 979 | { |
1019 | - if (float64_lt(FT0, FT1, &FP_STATUS)) | |
1020 | - T0 = 1; | |
1021 | - else | |
1022 | - T0 = 0; | |
980 | + return __helper_cvtql(a, 0, 0); | |
1023 | 981 | } |
1024 | 982 | |
1025 | -void helper_cmpfgt (void) | |
983 | +uint64_t helper_cvtqlv (uint64_t a) | |
1026 | 984 | { |
1027 | - if (float64_le(FT0, FT1, &FP_STATUS)) | |
1028 | - T0 = 0; | |
1029 | - else | |
1030 | - T0 = 1; | |
985 | + return __helper_cvtql(a, 0, 1); | |
1031 | 986 | } |
1032 | 987 | |
1033 | -void helper_cmpfge (void) | |
988 | +uint64_t helper_cvtqlsv (uint64_t a) | |
1034 | 989 | { |
1035 | - if (float64_lt(FT0, FT1, &FP_STATUS)) | |
1036 | - T0 = 0; | |
1037 | - else | |
1038 | - T0 = 1; | |
990 | + return __helper_cvtql(a, 1, 1); | |
1039 | 991 | } |
1040 | 992 | |
1041 | 993 | #if !defined (CONFIG_USER_ONLY) |
... | ... | @@ -1053,23 +1005,6 @@ void helper_mtpr (int iprn) |
1053 | 1005 | } |
1054 | 1006 | #endif |
1055 | 1007 | |
1056 | -#if defined(HOST_SPARC) || defined(HOST_SPARC64) | |
1057 | -void helper_reset_FT0 (void) | |
1058 | -{ | |
1059 | - FT0 = 0; | |
1060 | -} | |
1061 | - | |
1062 | -void helper_reset_FT1 (void) | |
1063 | -{ | |
1064 | - FT1 = 0; | |
1065 | -} | |
1066 | - | |
1067 | -void helper_reset_FT2 (void) | |
1068 | -{ | |
1069 | - FT2 = 0; | |
1070 | -} | |
1071 | -#endif | |
1072 | - | |
1073 | 1008 | /*****************************************************************************/ |
1074 | 1009 | /* Softmmu support */ |
1075 | 1010 | #if !defined (CONFIG_USER_ONLY) | ... | ... |
target-alpha/op_helper.h
... | ... | @@ -19,9 +19,6 @@ |
19 | 19 | */ |
20 | 20 | |
21 | 21 | void helper_call_pal (uint32_t palcode); |
22 | -void helper_load_fpcr (void); | |
23 | -void helper_store_fpcr (void); | |
24 | -void helper_cmov_fir (int freg); | |
25 | 22 | |
26 | 23 | double helper_ldff_raw (target_ulong ea); |
27 | 24 | void helper_stff_raw (target_ulong ea, double op); |
... | ... | @@ -42,65 +39,9 @@ double helper_ldfg_data (target_ulong ea); |
42 | 39 | void helper_stfg_data (target_ulong ea, double op); |
43 | 40 | #endif |
44 | 41 | |
45 | -void helper_sqrts (void); | |
46 | -void helper_cpys (void); | |
47 | -void helper_cpysn (void); | |
48 | -void helper_cpyse (void); | |
49 | -void helper_itofs (void); | |
50 | -void helper_ftois (void); | |
51 | - | |
52 | -void helper_sqrtt (void); | |
53 | -void helper_cmptun (void); | |
54 | -void helper_cmpteq (void); | |
55 | -void helper_cmptle (void); | |
56 | -void helper_cmptlt (void); | |
57 | -void helper_itoft (void); | |
58 | -void helper_ftoit (void); | |
59 | - | |
60 | -void helper_addf (void); | |
61 | -void helper_subf (void); | |
62 | -void helper_mulf (void); | |
63 | -void helper_divf (void); | |
64 | -void helper_sqrtf (void); | |
65 | -void helper_cmpfeq (void); | |
66 | -void helper_cmpfne (void); | |
67 | -void helper_cmpflt (void); | |
68 | -void helper_cmpfle (void); | |
69 | -void helper_cmpfgt (void); | |
70 | -void helper_cmpfge (void); | |
71 | -void helper_itoff (void); | |
72 | - | |
73 | -void helper_addg (void); | |
74 | -void helper_subg (void); | |
75 | -void helper_mulg (void); | |
76 | -void helper_divg (void); | |
77 | -void helper_sqrtg (void); | |
78 | -void helper_cmpgeq (void); | |
79 | -void helper_cmpglt (void); | |
80 | -void helper_cmpgle (void); | |
81 | - | |
82 | -void helper_cvtqs (void); | |
83 | -void helper_cvttq (void); | |
84 | -void helper_cvtqt (void); | |
85 | -void helper_cvtqf (void); | |
86 | -void helper_cvtgf (void); | |
87 | -void helper_cvtgd (void); | |
88 | -void helper_cvtgq (void); | |
89 | -void helper_cvtqg (void); | |
90 | -void helper_cvtdg (void); | |
91 | -void helper_cvtlq (void); | |
92 | -void helper_cvtql (void); | |
93 | -void helper_cvtqlv (void); | |
94 | -void helper_cvtqlsv (void); | |
95 | - | |
96 | 42 | void helper_mfpr (int iprn); |
97 | 43 | void helper_mtpr (int iprn); |
98 | 44 | void helper_ld_phys_to_virt (void); |
99 | 45 | void helper_st_phys_to_virt (void); |
100 | 46 | void helper_tb_flush (void); |
101 | 47 | |
102 | -#if defined(HOST_SPARC) || defined(HOST_SPARC64) | |
103 | -void helper_reset_FT0 (void); | |
104 | -void helper_reset_FT1 (void); | |
105 | -void helper_reset_FT2 (void); | |
106 | -#endif | ... | ... |
target-alpha/op_helper_mem.h deleted
100644 โ 0
1 | -/* | |
2 | - * Alpha emulation cpu micro-operations helpers for memory accesses for qemu. | |
3 | - * | |
4 | - * Copyright (c) 2007 Jocelyn Mayer | |
5 | - * | |
6 | - * This library is free software; you can redistribute it and/or | |
7 | - * modify it under the terms of the GNU Lesser General Public | |
8 | - * License as published by the Free Software Foundation; either | |
9 | - * version 2 of the License, or (at your option) any later version. | |
10 | - * | |
11 | - * This library is distributed in the hope that it will be useful, | |
12 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | - * Lesser General Public License for more details. | |
15 | - * | |
16 | - * You should have received a copy of the GNU Lesser General Public | |
17 | - * License along with this library; if not, write to the Free Software | |
18 | - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
19 | - */ | |
20 | - | |
21 | -/* XXX: TODO */ | |
22 | -double glue(helper_ldff, MEMSUFFIX) (target_ulong ea) | |
23 | -{ | |
24 | - return 0; | |
25 | -} | |
26 | - | |
27 | -void glue(helper_stff, MEMSUFFIX) (target_ulong ea, double op) | |
28 | -{ | |
29 | -} | |
30 | - | |
31 | -double glue(helper_ldfg, MEMSUFFIX) (target_ulong ea) | |
32 | -{ | |
33 | - return 0; | |
34 | -} | |
35 | - | |
36 | -void glue(helper_stfg, MEMSUFFIX) (target_ulong ea, double op) | |
37 | -{ | |
38 | -} | |
39 | - | |
40 | -#undef MEMSUFFIX |
target-alpha/op_mem.h
... | ... | @@ -90,31 +90,4 @@ ALPHA_LD_OP(q_l, ldq_l); |
90 | 90 | ALPHA_ST_OP(l_c, stl_c); |
91 | 91 | ALPHA_ST_OP(q_c, stq_c); |
92 | 92 | |
93 | -#define ALPHA_LDF_OP(name, op) \ | |
94 | -void OPPROTO glue(glue(op_ld, name), MEMSUFFIX) (void) \ | |
95 | -{ \ | |
96 | - print_mem_EA(T0); \ | |
97 | - FT1 = glue(op, MEMSUFFIX)(T0); \ | |
98 | - RETURN(); \ | |
99 | -} | |
100 | - | |
101 | -#define ALPHA_STF_OP(name, op) \ | |
102 | -void OPPROTO glue(glue(op_st, name), MEMSUFFIX) (void) \ | |
103 | -{ \ | |
104 | - print_mem_EA(T0); \ | |
105 | - glue(op, MEMSUFFIX)(T0, FT1); \ | |
106 | - RETURN(); \ | |
107 | -} | |
108 | - | |
109 | -ALPHA_LDF_OP(t, ldfq); | |
110 | -ALPHA_STF_OP(t, stfq); | |
111 | -ALPHA_LDF_OP(s, ldfl); | |
112 | -ALPHA_STF_OP(s, stfl); | |
113 | - | |
114 | -/* VAX floating point */ | |
115 | -ALPHA_LDF_OP(f, helper_ldff); | |
116 | -ALPHA_STF_OP(f, helper_stff); | |
117 | -ALPHA_LDF_OP(g, helper_ldfg); | |
118 | -ALPHA_STF_OP(g, helper_stfg); | |
119 | - | |
120 | 93 | #undef MEMSUFFIX | ... | ... |
target-alpha/op_template.h deleted
100644 โ 0
1 | -/* | |
2 | - * Alpha emulation cpu micro-operations templates for qemu. | |
3 | - * | |
4 | - * Copyright (c) 2007 Jocelyn Mayer | |
5 | - * | |
6 | - * This library is free software; you can redistribute it and/or | |
7 | - * modify it under the terms of the GNU Lesser General Public | |
8 | - * License as published by the Free Software Foundation; either | |
9 | - * version 2 of the License, or (at your option) any later version. | |
10 | - * | |
11 | - * This library is distributed in the hope that it will be useful, | |
12 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | - * Lesser General Public License for more details. | |
15 | - * | |
16 | - * You should have received a copy of the GNU Lesser General Public | |
17 | - * License along with this library; if not, write to the Free Software | |
18 | - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
19 | - */ | |
20 | - | |
21 | -/* Optimized constant loads */ | |
22 | -#if REG < 3 | |
23 | - | |
24 | -#if !defined(HOST_SPARC) && !defined(HOST_SPARC64) | |
25 | -void OPPROTO glue(op_reset_FT, REG) (void) | |
26 | -{ | |
27 | - glue(FT, REG) = 0; | |
28 | - RETURN(); | |
29 | -} | |
30 | -#else | |
31 | -void OPPROTO glue(op_reset_FT, REG) (void) | |
32 | -{ | |
33 | - glue(helper_reset_FT, REG)(); | |
34 | - RETURN(); | |
35 | -} | |
36 | -#endif | |
37 | - | |
38 | -#endif /* REG < 3 */ | |
39 | - | |
40 | -#if REG < 31 | |
41 | -/* floating point registers moves */ | |
42 | -void OPPROTO glue(op_load_FT0_fir, REG) (void) | |
43 | -{ | |
44 | - FT0 = env->fir[REG]; | |
45 | - RETURN(); | |
46 | -} | |
47 | - | |
48 | -void OPPROTO glue(op_load_FT1_fir, REG) (void) | |
49 | -{ | |
50 | - FT1 = env->fir[REG]; | |
51 | - RETURN(); | |
52 | -} | |
53 | - | |
54 | -void OPPROTO glue(op_load_FT2_fir, REG) (void) | |
55 | -{ | |
56 | - FT2 = env->fir[REG]; | |
57 | - RETURN(); | |
58 | -} | |
59 | - | |
60 | -void OPPROTO glue(op_store_FT0_fir, REG) (void) | |
61 | -{ | |
62 | - env->fir[REG] = FT0; | |
63 | - RETURN(); | |
64 | -} | |
65 | - | |
66 | -void OPPROTO glue(op_store_FT1_fir, REG) (void) | |
67 | -{ | |
68 | - env->fir[REG] = FT1; | |
69 | - RETURN(); | |
70 | -} | |
71 | - | |
72 | -void OPPROTO glue(op_store_FT2_fir, REG) (void) | |
73 | -{ | |
74 | - env->fir[REG] = FT2; | |
75 | - RETURN(); | |
76 | -} | |
77 | - | |
78 | -void OPPROTO glue(op_cmov_fir, REG) (void) | |
79 | -{ | |
80 | - helper_cmov_fir(REG); | |
81 | - RETURN(); | |
82 | -} | |
83 | -#endif /* REG < 31 */ | |
84 | - | |
85 | -#undef REG |
target-alpha/translate.c
... | ... | @@ -48,13 +48,14 @@ struct DisasContext { |
48 | 48 | /* global register indexes */ |
49 | 49 | static TCGv cpu_env; |
50 | 50 | static TCGv cpu_ir[31]; |
51 | +static TCGv cpu_fir[31]; | |
51 | 52 | static TCGv cpu_pc; |
52 | 53 | |
53 | 54 | /* dyngen register indexes */ |
54 | 55 | static TCGv cpu_T[2]; |
55 | 56 | |
56 | 57 | /* register names */ |
57 | -static char cpu_reg_names[10*4+21*5]; | |
58 | +static char cpu_reg_names[10*4+21*5 + 10*5+21*6]; | |
58 | 59 | |
59 | 60 | #include "gen-icount.h" |
60 | 61 | |
... | ... | @@ -85,6 +86,11 @@ static void alpha_translate_init(void) |
85 | 86 | cpu_ir[i] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0, |
86 | 87 | offsetof(CPUState, ir[i]), p); |
87 | 88 | p += (i < 10) ? 4 : 5; |
89 | + | |
90 | + sprintf(p, "fir%d", i); | |
91 | + cpu_fir[i] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0, | |
92 | + offsetof(CPUState, fir[i]), p); | |
93 | + p += (i < 10) ? 5 : 6; | |
88 | 94 | } |
89 | 95 | |
90 | 96 | cpu_pc = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0, |
... | ... | @@ -105,69 +111,6 @@ static always_inline void gen_op_nop (void) |
105 | 111 | #endif |
106 | 112 | } |
107 | 113 | |
108 | -#define GEN32(func, NAME) \ | |
109 | -static GenOpFunc *NAME ## _table [32] = { \ | |
110 | -NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3, \ | |
111 | -NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7, \ | |
112 | -NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11, \ | |
113 | -NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15, \ | |
114 | -NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19, \ | |
115 | -NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23, \ | |
116 | -NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27, \ | |
117 | -NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31, \ | |
118 | -}; \ | |
119 | -static always_inline void func (int n) \ | |
120 | -{ \ | |
121 | - NAME ## _table[n](); \ | |
122 | -} | |
123 | - | |
124 | -/* FIR moves */ | |
125 | -/* Special hacks for fir31 */ | |
126 | -#define gen_op_load_FT0_fir31 gen_op_reset_FT0 | |
127 | -#define gen_op_load_FT1_fir31 gen_op_reset_FT1 | |
128 | -#define gen_op_load_FT2_fir31 gen_op_reset_FT2 | |
129 | -#define gen_op_store_FT0_fir31 gen_op_nop | |
130 | -#define gen_op_store_FT1_fir31 gen_op_nop | |
131 | -#define gen_op_store_FT2_fir31 gen_op_nop | |
132 | -#define gen_op_cmov_fir31 gen_op_nop | |
133 | -GEN32(gen_op_load_FT0_fir, gen_op_load_FT0_fir); | |
134 | -GEN32(gen_op_load_FT1_fir, gen_op_load_FT1_fir); | |
135 | -GEN32(gen_op_load_FT2_fir, gen_op_load_FT2_fir); | |
136 | -GEN32(gen_op_store_FT0_fir, gen_op_store_FT0_fir); | |
137 | -GEN32(gen_op_store_FT1_fir, gen_op_store_FT1_fir); | |
138 | -GEN32(gen_op_store_FT2_fir, gen_op_store_FT2_fir); | |
139 | -GEN32(gen_op_cmov_fir, gen_op_cmov_fir); | |
140 | - | |
141 | -static always_inline void gen_load_fir (DisasContext *ctx, int firn, int Tn) | |
142 | -{ | |
143 | - switch (Tn) { | |
144 | - case 0: | |
145 | - gen_op_load_FT0_fir(firn); | |
146 | - break; | |
147 | - case 1: | |
148 | - gen_op_load_FT1_fir(firn); | |
149 | - break; | |
150 | - case 2: | |
151 | - gen_op_load_FT2_fir(firn); | |
152 | - break; | |
153 | - } | |
154 | -} | |
155 | - | |
156 | -static always_inline void gen_store_fir (DisasContext *ctx, int firn, int Tn) | |
157 | -{ | |
158 | - switch (Tn) { | |
159 | - case 0: | |
160 | - gen_op_store_FT0_fir(firn); | |
161 | - break; | |
162 | - case 1: | |
163 | - gen_op_store_FT1_fir(firn); | |
164 | - break; | |
165 | - case 2: | |
166 | - gen_op_store_FT2_fir(firn); | |
167 | - break; | |
168 | - } | |
169 | -} | |
170 | - | |
171 | 114 | /* Memory moves */ |
172 | 115 | #if defined(CONFIG_USER_ONLY) |
173 | 116 | #define OP_LD_TABLE(width) \ |
... | ... | @@ -218,26 +161,6 @@ GEN_ST(l_c); |
218 | 161 | GEN_LD(q_l); |
219 | 162 | GEN_ST(q_c); |
220 | 163 | |
221 | -#if 0 /* currently unused */ | |
222 | -GEN_LD(f); | |
223 | -GEN_ST(f); | |
224 | -GEN_LD(g); | |
225 | -GEN_ST(g); | |
226 | -#endif /* 0 */ | |
227 | -GEN_LD(s); | |
228 | -GEN_ST(s); | |
229 | -GEN_LD(t); | |
230 | -GEN_ST(t); | |
231 | - | |
232 | -static always_inline void _gen_op_bcond (DisasContext *ctx) | |
233 | -{ | |
234 | -#if 0 // Qemu does not know how to do this... | |
235 | - gen_op_bcond(ctx->pc); | |
236 | -#else | |
237 | - gen_op_bcond(ctx->pc >> 32, ctx->pc); | |
238 | -#endif | |
239 | -} | |
240 | - | |
241 | 164 | static always_inline void gen_excp (DisasContext *ctx, |
242 | 165 | int exception, int error_code) |
243 | 166 | { |
... | ... | @@ -277,10 +200,34 @@ static always_inline void gen_load_mem_dyngen (DisasContext *ctx, |
277 | 200 | } |
278 | 201 | } |
279 | 202 | |
203 | +static always_inline void gen_qemu_ldf (TCGv t0, TCGv t1, int flags) | |
204 | +{ | |
205 | + TCGv tmp = tcg_temp_new(TCG_TYPE_I32); | |
206 | + tcg_gen_qemu_ld32u(tmp, t1, flags); | |
207 | + tcg_gen_helper_1_1(helper_memory_to_f, t0, tmp); | |
208 | + tcg_temp_free(tmp); | |
209 | +} | |
210 | + | |
211 | +static always_inline void gen_qemu_ldg (TCGv t0, TCGv t1, int flags) | |
212 | +{ | |
213 | + TCGv tmp = tcg_temp_new(TCG_TYPE_I64); | |
214 | + tcg_gen_qemu_ld64(tmp, t1, flags); | |
215 | + tcg_gen_helper_1_1(helper_memory_to_g, t0, tmp); | |
216 | + tcg_temp_free(tmp); | |
217 | +} | |
218 | + | |
219 | +static always_inline void gen_qemu_lds (TCGv t0, TCGv t1, int flags) | |
220 | +{ | |
221 | + TCGv tmp = tcg_temp_new(TCG_TYPE_I32); | |
222 | + tcg_gen_qemu_ld32u(tmp, t1, flags); | |
223 | + tcg_gen_helper_1_1(helper_memory_to_s, t0, tmp); | |
224 | + tcg_temp_free(tmp); | |
225 | +} | |
226 | + | |
280 | 227 | static always_inline void gen_load_mem (DisasContext *ctx, |
281 | 228 | void (*tcg_gen_qemu_load)(TCGv t0, TCGv t1, int flags), |
282 | 229 | int ra, int rb, int32_t disp16, |
283 | - int clear) | |
230 | + int fp, int clear) | |
284 | 231 | { |
285 | 232 | TCGv addr; |
286 | 233 | |
... | ... | @@ -297,7 +244,10 @@ static always_inline void gen_load_mem (DisasContext *ctx, |
297 | 244 | disp16 &= ~0x7; |
298 | 245 | tcg_gen_movi_i64(addr, disp16); |
299 | 246 | } |
300 | - tcg_gen_qemu_load(cpu_ir[ra], addr, ctx->mem_idx); | |
247 | + if (fp) | |
248 | + tcg_gen_qemu_load(cpu_fir[ra], addr, ctx->mem_idx); | |
249 | + else | |
250 | + tcg_gen_qemu_load(cpu_ir[ra], addr, ctx->mem_idx); | |
301 | 251 | tcg_temp_free(addr); |
302 | 252 | } |
303 | 253 | |
... | ... | @@ -319,10 +269,34 @@ static always_inline void gen_store_mem_dyngen (DisasContext *ctx, |
319 | 269 | (*gen_store_op)(ctx); |
320 | 270 | } |
321 | 271 | |
272 | +static always_inline void gen_qemu_stf (TCGv t0, TCGv t1, int flags) | |
273 | +{ | |
274 | + TCGv tmp = tcg_temp_new(TCG_TYPE_I32); | |
275 | + tcg_gen_helper_1_1(helper_f_to_memory, tmp, t0); | |
276 | + tcg_gen_qemu_st32(tmp, t1, flags); | |
277 | + tcg_temp_free(tmp); | |
278 | +} | |
279 | + | |
280 | +static always_inline void gen_qemu_stg (TCGv t0, TCGv t1, int flags) | |
281 | +{ | |
282 | + TCGv tmp = tcg_temp_new(TCG_TYPE_I64); | |
283 | + tcg_gen_helper_1_1(helper_g_to_memory, tmp, t0); | |
284 | + tcg_gen_qemu_st64(tmp, t1, flags); | |
285 | + tcg_temp_free(tmp); | |
286 | +} | |
287 | + | |
288 | +static always_inline void gen_qemu_sts (TCGv t0, TCGv t1, int flags) | |
289 | +{ | |
290 | + TCGv tmp = tcg_temp_new(TCG_TYPE_I32); | |
291 | + tcg_gen_helper_1_1(helper_s_to_memory, tmp, t0); | |
292 | + tcg_gen_qemu_st32(tmp, t1, flags); | |
293 | + tcg_temp_free(tmp); | |
294 | +} | |
295 | + | |
322 | 296 | static always_inline void gen_store_mem (DisasContext *ctx, |
323 | 297 | void (*tcg_gen_qemu_store)(TCGv t0, TCGv t1, int flags), |
324 | 298 | int ra, int rb, int32_t disp16, |
325 | - int clear) | |
299 | + int fp, int clear) | |
326 | 300 | { |
327 | 301 | TCGv addr = tcg_temp_new(TCG_TYPE_I64); |
328 | 302 | if (rb != 31) { |
... | ... | @@ -334,9 +308,12 @@ static always_inline void gen_store_mem (DisasContext *ctx, |
334 | 308 | disp16 &= ~0x7; |
335 | 309 | tcg_gen_movi_i64(addr, disp16); |
336 | 310 | } |
337 | - if (ra != 31) | |
338 | - tcg_gen_qemu_store(cpu_ir[ra], addr, ctx->mem_idx); | |
339 | - else { | |
311 | + if (ra != 31) { | |
312 | + if (fp) | |
313 | + tcg_gen_qemu_store(cpu_fir[ra], addr, ctx->mem_idx); | |
314 | + else | |
315 | + tcg_gen_qemu_store(cpu_ir[ra], addr, ctx->mem_idx); | |
316 | + } else { | |
340 | 317 | TCGv zero = tcg_const_i64(0); |
341 | 318 | tcg_gen_qemu_store(zero, addr, ctx->mem_idx); |
342 | 319 | tcg_temp_free(zero); |
... | ... | @@ -344,30 +321,6 @@ static always_inline void gen_store_mem (DisasContext *ctx, |
344 | 321 | tcg_temp_free(addr); |
345 | 322 | } |
346 | 323 | |
347 | -static always_inline void gen_load_fmem (DisasContext *ctx, | |
348 | - void (*gen_load_fop)(DisasContext *ctx), | |
349 | - int ra, int rb, int32_t disp16) | |
350 | -{ | |
351 | - if (rb != 31) | |
352 | - tcg_gen_addi_i64(cpu_T[0], cpu_ir[rb], disp16); | |
353 | - else | |
354 | - tcg_gen_movi_i64(cpu_T[0], disp16); | |
355 | - (*gen_load_fop)(ctx); | |
356 | - gen_store_fir(ctx, ra, 1); | |
357 | -} | |
358 | - | |
359 | -static always_inline void gen_store_fmem (DisasContext *ctx, | |
360 | - void (*gen_store_fop)(DisasContext *ctx), | |
361 | - int ra, int rb, int32_t disp16) | |
362 | -{ | |
363 | - if (rb != 31) | |
364 | - tcg_gen_addi_i64(cpu_T[0], cpu_ir[rb], disp16); | |
365 | - else | |
366 | - tcg_gen_movi_i64(cpu_T[0], disp16); | |
367 | - gen_load_fir(ctx, ra, 1); | |
368 | - (*gen_store_fop)(ctx); | |
369 | -} | |
370 | - | |
371 | 324 | static always_inline void gen_bcond (DisasContext *ctx, |
372 | 325 | TCGCond cond, |
373 | 326 | int ra, int32_t disp16, int mask) |
... | ... | @@ -398,13 +351,27 @@ static always_inline void gen_bcond (DisasContext *ctx, |
398 | 351 | } |
399 | 352 | |
400 | 353 | static always_inline void gen_fbcond (DisasContext *ctx, |
401 | - void (*gen_test_op)(void), | |
354 | + void* func, | |
402 | 355 | int ra, int32_t disp16) |
403 | 356 | { |
404 | - tcg_gen_movi_i64(cpu_T[1], ctx->pc + (int64_t)(disp16 << 2)); | |
405 | - gen_load_fir(ctx, ra, 0); | |
406 | - (*gen_test_op)(); | |
407 | - _gen_op_bcond(ctx); | |
357 | + int l1, l2; | |
358 | + TCGv tmp; | |
359 | + | |
360 | + l1 = gen_new_label(); | |
361 | + l2 = gen_new_label(); | |
362 | + if (ra != 31) { | |
363 | + tmp = tcg_temp_new(TCG_TYPE_I64); | |
364 | + tcg_gen_helper_1_1(func, tmp, cpu_fir[ra]); | |
365 | + } else { | |
366 | + tmp = tcg_const_i64(0); | |
367 | + tcg_gen_helper_1_1(func, tmp, tmp); | |
368 | + } | |
369 | + tcg_gen_brcondi_i64(TCG_COND_NE, tmp, 0, l1); | |
370 | + tcg_gen_movi_i64(cpu_pc, ctx->pc); | |
371 | + tcg_gen_br(l2); | |
372 | + gen_set_label(l1); | |
373 | + tcg_gen_movi_i64(cpu_pc, ctx->pc + (int64_t)(disp16 << 2)); | |
374 | + gen_set_label(l2); | |
408 | 375 | } |
409 | 376 | |
410 | 377 | static always_inline void gen_cmov (DisasContext *ctx, |
... | ... | @@ -441,55 +408,69 @@ static always_inline void gen_cmov (DisasContext *ctx, |
441 | 408 | gen_set_label(l1); |
442 | 409 | } |
443 | 410 | |
444 | -static always_inline void gen_farith2 (DisasContext *ctx, | |
445 | - void (*gen_arith_fop)(void), | |
411 | +static always_inline void gen_farith2 (void *helper, | |
446 | 412 | int rb, int rc) |
447 | 413 | { |
448 | - gen_load_fir(ctx, rb, 0); | |
449 | - (*gen_arith_fop)(); | |
450 | - gen_store_fir(ctx, rc, 0); | |
414 | + if (unlikely(rc == 31)) | |
415 | + return; | |
416 | + | |
417 | + if (rb != 31) | |
418 | + tcg_gen_helper_1_1(helper, cpu_fir[rc], cpu_fir[rb]); | |
419 | + else { | |
420 | + TCGv tmp = tcg_const_i64(0); | |
421 | + tcg_gen_helper_1_1(helper, cpu_fir[rc], tmp); | |
422 | + tcg_temp_free(tmp); | |
423 | + } | |
451 | 424 | } |
452 | 425 | |
453 | -static always_inline void gen_farith3 (DisasContext *ctx, | |
454 | - void (*gen_arith_fop)(void), | |
426 | +static always_inline void gen_farith3 (void *helper, | |
455 | 427 | int ra, int rb, int rc) |
456 | 428 | { |
457 | - gen_load_fir(ctx, ra, 0); | |
458 | - gen_load_fir(ctx, rb, 1); | |
459 | - (*gen_arith_fop)(); | |
460 | - gen_store_fir(ctx, rc, 0); | |
429 | + if (unlikely(rc == 31)) | |
430 | + return; | |
431 | + | |
432 | + if (ra != 31) { | |
433 | + if (rb != 31) | |
434 | + tcg_gen_helper_1_2(helper, cpu_fir[rc], cpu_fir[ra], cpu_fir[rb]); | |
435 | + else { | |
436 | + TCGv tmp = tcg_const_i64(0); | |
437 | + tcg_gen_helper_1_2(helper, cpu_fir[rc], cpu_fir[ra], tmp); | |
438 | + tcg_temp_free(tmp); | |
439 | + } | |
440 | + } else { | |
441 | + TCGv tmp = tcg_const_i64(0); | |
442 | + if (rb != 31) | |
443 | + tcg_gen_helper_1_2(helper, cpu_fir[rc], tmp, cpu_fir[rb]); | |
444 | + else | |
445 | + tcg_gen_helper_1_2(helper, cpu_fir[rc], tmp, tmp); | |
446 | + tcg_temp_free(tmp); | |
447 | + } | |
461 | 448 | } |
462 | 449 | |
463 | -static always_inline void gen_fcmov (DisasContext *ctx, | |
464 | - void (*gen_test_fop)(void), | |
450 | +static always_inline void gen_fcmov (void *func, | |
465 | 451 | int ra, int rb, int rc) |
466 | 452 | { |
467 | - gen_load_fir(ctx, ra, 0); | |
468 | - gen_load_fir(ctx, rb, 1); | |
469 | - (*gen_test_fop)(); | |
470 | - gen_op_cmov_fir(rc); | |
471 | -} | |
453 | + int l1; | |
454 | + TCGv tmp; | |
472 | 455 | |
473 | -static always_inline void gen_fti (DisasContext *ctx, | |
474 | - void (*gen_move_fop)(void), | |
475 | - int ra, int rc) | |
476 | -{ | |
477 | - gen_load_fir(ctx, rc, 0); | |
478 | - (*gen_move_fop)(); | |
479 | - if (ra != 31) | |
480 | - tcg_gen_mov_i64(cpu_ir[ra], cpu_T[0]); | |
481 | -} | |
456 | + if (unlikely(rc == 31)) | |
457 | + return; | |
482 | 458 | |
483 | -static always_inline void gen_itf (DisasContext *ctx, | |
484 | - void (*gen_move_fop)(void), | |
485 | - int ra, int rc) | |
486 | -{ | |
487 | - if (ra != 31) | |
488 | - tcg_gen_mov_i64(cpu_T[0], cpu_ir[ra]); | |
459 | + l1 = gen_new_label(); | |
460 | + tmp = tcg_temp_new(TCG_TYPE_I64); | |
461 | + if (ra != 31) { | |
462 | + tmp = tcg_temp_new(TCG_TYPE_I64); | |
463 | + tcg_gen_helper_1_1(func, tmp, cpu_fir[ra]); | |
464 | + } else { | |
465 | + tmp = tcg_const_i64(0); | |
466 | + tcg_gen_helper_1_1(func, tmp, tmp); | |
467 | + } | |
468 | + tcg_gen_brcondi_i64(TCG_COND_EQ, tmp, 0, l1); | |
469 | + if (rb != 31) | |
470 | + tcg_gen_mov_i64(cpu_fir[rc], cpu_fir[ra]); | |
489 | 471 | else |
490 | - tcg_gen_movi_i64(cpu_T[0], 0); | |
491 | - (*gen_move_fop)(); | |
492 | - gen_store_fir(ctx, rc, 0); | |
472 | + tcg_gen_movi_i64(cpu_fir[rc], 0); | |
473 | + gen_set_label(l1); | |
493 | 474 | } |
494 | 475 | |
495 | 476 | /* EXTWH, EXTWH, EXTLH, EXTQH */ |
... | ... | @@ -704,29 +685,29 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn) |
704 | 685 | /* LDBU */ |
705 | 686 | if (!(ctx->amask & AMASK_BWX)) |
706 | 687 | goto invalid_opc; |
707 | - gen_load_mem(ctx, &tcg_gen_qemu_ld8u, ra, rb, disp16, 0); | |
688 | + gen_load_mem(ctx, &tcg_gen_qemu_ld8u, ra, rb, disp16, 0, 0); | |
708 | 689 | break; |
709 | 690 | case 0x0B: |
710 | 691 | /* LDQ_U */ |
711 | - gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 1); | |
692 | + gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 0, 1); | |
712 | 693 | break; |
713 | 694 | case 0x0C: |
714 | 695 | /* LDWU */ |
715 | 696 | if (!(ctx->amask & AMASK_BWX)) |
716 | 697 | goto invalid_opc; |
717 | - gen_load_mem(ctx, &tcg_gen_qemu_ld16u, ra, rb, disp16, 1); | |
698 | + gen_load_mem(ctx, &tcg_gen_qemu_ld16u, ra, rb, disp16, 0, 1); | |
718 | 699 | break; |
719 | 700 | case 0x0D: |
720 | 701 | /* STW */ |
721 | - gen_store_mem(ctx, &tcg_gen_qemu_st16, ra, rb, disp16, 0); | |
702 | + gen_store_mem(ctx, &tcg_gen_qemu_st16, ra, rb, disp16, 0, 0); | |
722 | 703 | break; |
723 | 704 | case 0x0E: |
724 | 705 | /* STB */ |
725 | - gen_store_mem(ctx, &tcg_gen_qemu_st8, ra, rb, disp16, 0); | |
706 | + gen_store_mem(ctx, &tcg_gen_qemu_st8, ra, rb, disp16, 0, 0); | |
726 | 707 | break; |
727 | 708 | case 0x0F: |
728 | 709 | /* STQ_U */ |
729 | - gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 1); | |
710 | + gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 0, 1); | |
730 | 711 | break; |
731 | 712 | case 0x10: |
732 | 713 | switch (fn7) { |
... | ... | @@ -1349,47 +1330,64 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn) |
1349 | 1330 | /* ITOFS */ |
1350 | 1331 | if (!(ctx->amask & AMASK_FIX)) |
1351 | 1332 | goto invalid_opc; |
1352 | - gen_itf(ctx, &gen_op_itofs, ra, rc); | |
1333 | + if (likely(rc != 31)) { | |
1334 | + if (ra != 31) { | |
1335 | + TCGv tmp = tcg_temp_new(TCG_TYPE_I32); | |
1336 | + tcg_gen_trunc_i64_i32(tmp, cpu_ir[ra]); | |
1337 | + tcg_gen_helper_1_1(helper_memory_to_s, cpu_fir[rc], tmp); | |
1338 | + tcg_temp_free(tmp); | |
1339 | + } else | |
1340 | + tcg_gen_movi_i64(cpu_fir[rc], 0); | |
1341 | + } | |
1353 | 1342 | break; |
1354 | 1343 | case 0x0A: |
1355 | 1344 | /* SQRTF */ |
1356 | 1345 | if (!(ctx->amask & AMASK_FIX)) |
1357 | 1346 | goto invalid_opc; |
1358 | - gen_farith2(ctx, &gen_op_sqrtf, rb, rc); | |
1347 | + gen_farith2(&helper_sqrtf, rb, rc); | |
1359 | 1348 | break; |
1360 | 1349 | case 0x0B: |
1361 | 1350 | /* SQRTS */ |
1362 | 1351 | if (!(ctx->amask & AMASK_FIX)) |
1363 | 1352 | goto invalid_opc; |
1364 | - gen_farith2(ctx, &gen_op_sqrts, rb, rc); | |
1353 | + gen_farith2(&helper_sqrts, rb, rc); | |
1365 | 1354 | break; |
1366 | 1355 | case 0x14: |
1367 | 1356 | /* ITOFF */ |
1368 | 1357 | if (!(ctx->amask & AMASK_FIX)) |
1369 | 1358 | goto invalid_opc; |
1370 | -#if 0 // TODO | |
1371 | - gen_itf(ctx, &gen_op_itoff, ra, rc); | |
1372 | -#else | |
1373 | - goto invalid_opc; | |
1374 | -#endif | |
1359 | + if (likely(rc != 31)) { | |
1360 | + if (ra != 31) { | |
1361 | + TCGv tmp = tcg_temp_new(TCG_TYPE_I32); | |
1362 | + tcg_gen_trunc_i64_i32(tmp, cpu_ir[ra]); | |
1363 | + tcg_gen_helper_1_1(helper_memory_to_f, cpu_fir[rc], tmp); | |
1364 | + tcg_temp_free(tmp); | |
1365 | + } else | |
1366 | + tcg_gen_movi_i64(cpu_fir[rc], 0); | |
1367 | + } | |
1375 | 1368 | break; |
1376 | 1369 | case 0x24: |
1377 | 1370 | /* ITOFT */ |
1378 | 1371 | if (!(ctx->amask & AMASK_FIX)) |
1379 | 1372 | goto invalid_opc; |
1380 | - gen_itf(ctx, &gen_op_itoft, ra, rc); | |
1373 | + if (likely(rc != 31)) { | |
1374 | + if (ra != 31) | |
1375 | + tcg_gen_mov_i64(cpu_fir[rc], cpu_ir[ra]); | |
1376 | + else | |
1377 | + tcg_gen_movi_i64(cpu_fir[rc], 0); | |
1378 | + } | |
1381 | 1379 | break; |
1382 | 1380 | case 0x2A: |
1383 | 1381 | /* SQRTG */ |
1384 | 1382 | if (!(ctx->amask & AMASK_FIX)) |
1385 | 1383 | goto invalid_opc; |
1386 | - gen_farith2(ctx, &gen_op_sqrtg, rb, rc); | |
1384 | + gen_farith2(&helper_sqrtg, rb, rc); | |
1387 | 1385 | break; |
1388 | 1386 | case 0x02B: |
1389 | 1387 | /* SQRTT */ |
1390 | 1388 | if (!(ctx->amask & AMASK_FIX)) |
1391 | 1389 | goto invalid_opc; |
1392 | - gen_farith2(ctx, &gen_op_sqrtt, rb, rc); | |
1390 | + gen_farith2(&helper_sqrtt, rb, rc); | |
1393 | 1391 | break; |
1394 | 1392 | default: |
1395 | 1393 | goto invalid_opc; |
... | ... | @@ -1401,79 +1399,79 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn) |
1401 | 1399 | switch (fpfn) { /* f11 & 0x3F */ |
1402 | 1400 | case 0x00: |
1403 | 1401 | /* ADDF */ |
1404 | - gen_farith3(ctx, &gen_op_addf, ra, rb, rc); | |
1402 | + gen_farith3(&helper_addf, ra, rb, rc); | |
1405 | 1403 | break; |
1406 | 1404 | case 0x01: |
1407 | 1405 | /* SUBF */ |
1408 | - gen_farith3(ctx, &gen_op_subf, ra, rb, rc); | |
1406 | + gen_farith3(&helper_subf, ra, rb, rc); | |
1409 | 1407 | break; |
1410 | 1408 | case 0x02: |
1411 | 1409 | /* MULF */ |
1412 | - gen_farith3(ctx, &gen_op_mulf, ra, rb, rc); | |
1410 | + gen_farith3(&helper_mulf, ra, rb, rc); | |
1413 | 1411 | break; |
1414 | 1412 | case 0x03: |
1415 | 1413 | /* DIVF */ |
1416 | - gen_farith3(ctx, &gen_op_divf, ra, rb, rc); | |
1414 | + gen_farith3(&helper_divf, ra, rb, rc); | |
1417 | 1415 | break; |
1418 | 1416 | case 0x1E: |
1419 | 1417 | /* CVTDG */ |
1420 | 1418 | #if 0 // TODO |
1421 | - gen_farith2(ctx, &gen_op_cvtdg, rb, rc); | |
1419 | + gen_farith2(&helper_cvtdg, rb, rc); | |
1422 | 1420 | #else |
1423 | 1421 | goto invalid_opc; |
1424 | 1422 | #endif |
1425 | 1423 | break; |
1426 | 1424 | case 0x20: |
1427 | 1425 | /* ADDG */ |
1428 | - gen_farith3(ctx, &gen_op_addg, ra, rb, rc); | |
1426 | + gen_farith3(&helper_addg, ra, rb, rc); | |
1429 | 1427 | break; |
1430 | 1428 | case 0x21: |
1431 | 1429 | /* SUBG */ |
1432 | - gen_farith3(ctx, &gen_op_subg, ra, rb, rc); | |
1430 | + gen_farith3(&helper_subg, ra, rb, rc); | |
1433 | 1431 | break; |
1434 | 1432 | case 0x22: |
1435 | 1433 | /* MULG */ |
1436 | - gen_farith3(ctx, &gen_op_mulg, ra, rb, rc); | |
1434 | + gen_farith3(&helper_mulg, ra, rb, rc); | |
1437 | 1435 | break; |
1438 | 1436 | case 0x23: |
1439 | 1437 | /* DIVG */ |
1440 | - gen_farith3(ctx, &gen_op_divg, ra, rb, rc); | |
1438 | + gen_farith3(&helper_divg, ra, rb, rc); | |
1441 | 1439 | break; |
1442 | 1440 | case 0x25: |
1443 | 1441 | /* CMPGEQ */ |
1444 | - gen_farith3(ctx, &gen_op_cmpgeq, ra, rb, rc); | |
1442 | + gen_farith3(&helper_cmpgeq, ra, rb, rc); | |
1445 | 1443 | break; |
1446 | 1444 | case 0x26: |
1447 | 1445 | /* CMPGLT */ |
1448 | - gen_farith3(ctx, &gen_op_cmpglt, ra, rb, rc); | |
1446 | + gen_farith3(&helper_cmpglt, ra, rb, rc); | |
1449 | 1447 | break; |
1450 | 1448 | case 0x27: |
1451 | 1449 | /* CMPGLE */ |
1452 | - gen_farith3(ctx, &gen_op_cmpgle, ra, rb, rc); | |
1450 | + gen_farith3(&helper_cmpgle, ra, rb, rc); | |
1453 | 1451 | break; |
1454 | 1452 | case 0x2C: |
1455 | 1453 | /* CVTGF */ |
1456 | - gen_farith2(ctx, &gen_op_cvtgf, rb, rc); | |
1454 | + gen_farith2(&helper_cvtgf, rb, rc); | |
1457 | 1455 | break; |
1458 | 1456 | case 0x2D: |
1459 | 1457 | /* CVTGD */ |
1460 | 1458 | #if 0 // TODO |
1461 | - gen_farith2(ctx, &gen_op_cvtgd, rb, rc); | |
1459 | + gen_farith2(ctx, &helper_cvtgd, rb, rc); | |
1462 | 1460 | #else |
1463 | 1461 | goto invalid_opc; |
1464 | 1462 | #endif |
1465 | 1463 | break; |
1466 | 1464 | case 0x2F: |
1467 | 1465 | /* CVTGQ */ |
1468 | - gen_farith2(ctx, &gen_op_cvtgq, rb, rc); | |
1466 | + gen_farith2(&helper_cvtgq, rb, rc); | |
1469 | 1467 | break; |
1470 | 1468 | case 0x3C: |
1471 | 1469 | /* CVTQF */ |
1472 | - gen_farith2(ctx, &gen_op_cvtqf, rb, rc); | |
1470 | + gen_farith2(&helper_cvtqf, rb, rc); | |
1473 | 1471 | break; |
1474 | 1472 | case 0x3E: |
1475 | 1473 | /* CVTQG */ |
1476 | - gen_farith2(ctx, &gen_op_cvtqg, rb, rc); | |
1474 | + gen_farith2(&helper_cvtqg, rb, rc); | |
1477 | 1475 | break; |
1478 | 1476 | default: |
1479 | 1477 | goto invalid_opc; |
... | ... | @@ -1485,73 +1483,73 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn) |
1485 | 1483 | switch (fpfn) { /* f11 & 0x3F */ |
1486 | 1484 | case 0x00: |
1487 | 1485 | /* ADDS */ |
1488 | - gen_farith3(ctx, &gen_op_adds, ra, rb, rc); | |
1486 | + gen_farith3(&helper_adds, ra, rb, rc); | |
1489 | 1487 | break; |
1490 | 1488 | case 0x01: |
1491 | 1489 | /* SUBS */ |
1492 | - gen_farith3(ctx, &gen_op_subs, ra, rb, rc); | |
1490 | + gen_farith3(&helper_subs, ra, rb, rc); | |
1493 | 1491 | break; |
1494 | 1492 | case 0x02: |
1495 | 1493 | /* MULS */ |
1496 | - gen_farith3(ctx, &gen_op_muls, ra, rb, rc); | |
1494 | + gen_farith3(&helper_muls, ra, rb, rc); | |
1497 | 1495 | break; |
1498 | 1496 | case 0x03: |
1499 | 1497 | /* DIVS */ |
1500 | - gen_farith3(ctx, &gen_op_divs, ra, rb, rc); | |
1498 | + gen_farith3(&helper_divs, ra, rb, rc); | |
1501 | 1499 | break; |
1502 | 1500 | case 0x20: |
1503 | 1501 | /* ADDT */ |
1504 | - gen_farith3(ctx, &gen_op_addt, ra, rb, rc); | |
1502 | + gen_farith3(&helper_addt, ra, rb, rc); | |
1505 | 1503 | break; |
1506 | 1504 | case 0x21: |
1507 | 1505 | /* SUBT */ |
1508 | - gen_farith3(ctx, &gen_op_subt, ra, rb, rc); | |
1506 | + gen_farith3(&helper_subt, ra, rb, rc); | |
1509 | 1507 | break; |
1510 | 1508 | case 0x22: |
1511 | 1509 | /* MULT */ |
1512 | - gen_farith3(ctx, &gen_op_mult, ra, rb, rc); | |
1510 | + gen_farith3(&helper_mult, ra, rb, rc); | |
1513 | 1511 | break; |
1514 | 1512 | case 0x23: |
1515 | 1513 | /* DIVT */ |
1516 | - gen_farith3(ctx, &gen_op_divt, ra, rb, rc); | |
1514 | + gen_farith3(&helper_divt, ra, rb, rc); | |
1517 | 1515 | break; |
1518 | 1516 | case 0x24: |
1519 | 1517 | /* CMPTUN */ |
1520 | - gen_farith3(ctx, &gen_op_cmptun, ra, rb, rc); | |
1518 | + gen_farith3(&helper_cmptun, ra, rb, rc); | |
1521 | 1519 | break; |
1522 | 1520 | case 0x25: |
1523 | 1521 | /* CMPTEQ */ |
1524 | - gen_farith3(ctx, &gen_op_cmpteq, ra, rb, rc); | |
1522 | + gen_farith3(&helper_cmpteq, ra, rb, rc); | |
1525 | 1523 | break; |
1526 | 1524 | case 0x26: |
1527 | 1525 | /* CMPTLT */ |
1528 | - gen_farith3(ctx, &gen_op_cmptlt, ra, rb, rc); | |
1526 | + gen_farith3(&helper_cmptlt, ra, rb, rc); | |
1529 | 1527 | break; |
1530 | 1528 | case 0x27: |
1531 | 1529 | /* CMPTLE */ |
1532 | - gen_farith3(ctx, &gen_op_cmptle, ra, rb, rc); | |
1530 | + gen_farith3(&helper_cmptle, ra, rb, rc); | |
1533 | 1531 | break; |
1534 | 1532 | case 0x2C: |
1535 | 1533 | /* XXX: incorrect */ |
1536 | 1534 | if (fn11 == 0x2AC) { |
1537 | 1535 | /* CVTST */ |
1538 | - gen_farith2(ctx, &gen_op_cvtst, rb, rc); | |
1536 | + gen_farith2(&helper_cvtst, rb, rc); | |
1539 | 1537 | } else { |
1540 | 1538 | /* CVTTS */ |
1541 | - gen_farith2(ctx, &gen_op_cvtts, rb, rc); | |
1539 | + gen_farith2(&helper_cvtts, rb, rc); | |
1542 | 1540 | } |
1543 | 1541 | break; |
1544 | 1542 | case 0x2F: |
1545 | 1543 | /* CVTTQ */ |
1546 | - gen_farith2(ctx, &gen_op_cvttq, rb, rc); | |
1544 | + gen_farith2(&helper_cvttq, rb, rc); | |
1547 | 1545 | break; |
1548 | 1546 | case 0x3C: |
1549 | 1547 | /* CVTQS */ |
1550 | - gen_farith2(ctx, &gen_op_cvtqs, rb, rc); | |
1548 | + gen_farith2(&helper_cvtqs, rb, rc); | |
1551 | 1549 | break; |
1552 | 1550 | case 0x3E: |
1553 | 1551 | /* CVTQT */ |
1554 | - gen_farith2(ctx, &gen_op_cvtqt, rb, rc); | |
1552 | + gen_farith2(&helper_cvtqt, rb, rc); | |
1555 | 1553 | break; |
1556 | 1554 | default: |
1557 | 1555 | goto invalid_opc; |
... | ... | @@ -1561,76 +1559,76 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn) |
1561 | 1559 | switch (fn11) { |
1562 | 1560 | case 0x010: |
1563 | 1561 | /* CVTLQ */ |
1564 | - gen_farith2(ctx, &gen_op_cvtlq, rb, rc); | |
1562 | + gen_farith2(&helper_cvtlq, rb, rc); | |
1565 | 1563 | break; |
1566 | 1564 | case 0x020: |
1567 | - /* CPYS */ | |
1568 | - if (ra == rb) { | |
1569 | - if (ra == 31 && rc == 31) { | |
1570 | - /* FNOP */ | |
1571 | - gen_op_nop(); | |
1572 | - } else { | |
1565 | + if (likely(rc != 31)) { | |
1566 | + if (ra == rb) | |
1573 | 1567 | /* FMOV */ |
1574 | - gen_load_fir(ctx, rb, 0); | |
1575 | - gen_store_fir(ctx, rc, 0); | |
1576 | - } | |
1577 | - } else { | |
1578 | - gen_farith3(ctx, &gen_op_cpys, ra, rb, rc); | |
1568 | + tcg_gen_mov_i64(cpu_fir[rc], cpu_fir[ra]); | |
1569 | + else | |
1570 | + /* CPYS */ | |
1571 | + gen_farith3(&helper_cpys, ra, rb, rc); | |
1579 | 1572 | } |
1580 | 1573 | break; |
1581 | 1574 | case 0x021: |
1582 | 1575 | /* CPYSN */ |
1583 | - gen_farith2(ctx, &gen_op_cpysn, rb, rc); | |
1576 | + gen_farith3(&helper_cpysn, ra, rb, rc); | |
1584 | 1577 | break; |
1585 | 1578 | case 0x022: |
1586 | 1579 | /* CPYSE */ |
1587 | - gen_farith2(ctx, &gen_op_cpyse, rb, rc); | |
1580 | + gen_farith3(&helper_cpyse, ra, rb, rc); | |
1588 | 1581 | break; |
1589 | 1582 | case 0x024: |
1590 | 1583 | /* MT_FPCR */ |
1591 | - gen_load_fir(ctx, ra, 0); | |
1592 | - gen_op_store_fpcr(); | |
1584 | + if (likely(ra != 31)) | |
1585 | + tcg_gen_helper_0_1(helper_store_fpcr, cpu_fir[ra]); | |
1586 | + else { | |
1587 | + TCGv tmp = tcg_const_i64(0); | |
1588 | + tcg_gen_helper_0_1(helper_store_fpcr, tmp); | |
1589 | + tcg_temp_free(tmp); | |
1590 | + } | |
1593 | 1591 | break; |
1594 | 1592 | case 0x025: |
1595 | 1593 | /* MF_FPCR */ |
1596 | - gen_op_load_fpcr(); | |
1597 | - gen_store_fir(ctx, ra, 0); | |
1594 | + if (likely(ra != 31)) | |
1595 | + tcg_gen_helper_1_0(helper_load_fpcr, cpu_fir[ra]); | |
1598 | 1596 | break; |
1599 | 1597 | case 0x02A: |
1600 | 1598 | /* FCMOVEQ */ |
1601 | - gen_fcmov(ctx, &gen_op_cmpfeq, ra, rb, rc); | |
1599 | + gen_fcmov(&helper_cmpfeq, ra, rb, rc); | |
1602 | 1600 | break; |
1603 | 1601 | case 0x02B: |
1604 | 1602 | /* FCMOVNE */ |
1605 | - gen_fcmov(ctx, &gen_op_cmpfne, ra, rb, rc); | |
1603 | + gen_fcmov(&helper_cmpfne, ra, rb, rc); | |
1606 | 1604 | break; |
1607 | 1605 | case 0x02C: |
1608 | 1606 | /* FCMOVLT */ |
1609 | - gen_fcmov(ctx, &gen_op_cmpflt, ra, rb, rc); | |
1607 | + gen_fcmov(&helper_cmpflt, ra, rb, rc); | |
1610 | 1608 | break; |
1611 | 1609 | case 0x02D: |
1612 | 1610 | /* FCMOVGE */ |
1613 | - gen_fcmov(ctx, &gen_op_cmpfge, ra, rb, rc); | |
1611 | + gen_fcmov(&helper_cmpfge, ra, rb, rc); | |
1614 | 1612 | break; |
1615 | 1613 | case 0x02E: |
1616 | 1614 | /* FCMOVLE */ |
1617 | - gen_fcmov(ctx, &gen_op_cmpfle, ra, rb, rc); | |
1615 | + gen_fcmov(&helper_cmpfle, ra, rb, rc); | |
1618 | 1616 | break; |
1619 | 1617 | case 0x02F: |
1620 | 1618 | /* FCMOVGT */ |
1621 | - gen_fcmov(ctx, &gen_op_cmpfgt, ra, rb, rc); | |
1619 | + gen_fcmov(&helper_cmpfgt, ra, rb, rc); | |
1622 | 1620 | break; |
1623 | 1621 | case 0x030: |
1624 | 1622 | /* CVTQL */ |
1625 | - gen_farith2(ctx, &gen_op_cvtql, rb, rc); | |
1623 | + gen_farith2(&helper_cvtql, rb, rc); | |
1626 | 1624 | break; |
1627 | 1625 | case 0x130: |
1628 | 1626 | /* CVTQL/V */ |
1629 | - gen_farith2(ctx, &gen_op_cvtqlv, rb, rc); | |
1627 | + gen_farith2(&helper_cvtqlv, rb, rc); | |
1630 | 1628 | break; |
1631 | 1629 | case 0x530: |
1632 | 1630 | /* CVTQL/SV */ |
1633 | - gen_farith2(ctx, &gen_op_cvtqlsv, rb, rc); | |
1631 | + gen_farith2(&helper_cvtqlsv, rb, rc); | |
1634 | 1632 | break; |
1635 | 1633 | default: |
1636 | 1634 | goto invalid_opc; |
... | ... | @@ -1981,13 +1979,29 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn) |
1981 | 1979 | /* FTOIT */ |
1982 | 1980 | if (!(ctx->amask & AMASK_FIX)) |
1983 | 1981 | goto invalid_opc; |
1984 | - gen_fti(ctx, &gen_op_ftoit, ra, rb); | |
1982 | + if (likely(rc != 31)) { | |
1983 | + if (ra != 31) | |
1984 | + tcg_gen_mov_i64(cpu_ir[rc], cpu_fir[ra]); | |
1985 | + else | |
1986 | + tcg_gen_movi_i64(cpu_ir[rc], 0); | |
1987 | + } | |
1985 | 1988 | break; |
1986 | 1989 | case 0x78: |
1987 | 1990 | /* FTOIS */ |
1988 | 1991 | if (!(ctx->amask & AMASK_FIX)) |
1989 | 1992 | goto invalid_opc; |
1990 | - gen_fti(ctx, &gen_op_ftois, ra, rb); | |
1993 | + if (rc != 31) { | |
1994 | + TCGv tmp1 = tcg_temp_new(TCG_TYPE_I32); | |
1995 | + if (ra != 31) | |
1996 | + tcg_gen_helper_1_1(helper_s_to_memory, tmp1, cpu_fir[ra]); | |
1997 | + else { | |
1998 | + TCGv tmp2 = tcg_const_i64(0); | |
1999 | + tcg_gen_helper_1_1(helper_s_to_memory, tmp1, tmp2); | |
2000 | + tcg_temp_free(tmp2); | |
2001 | + } | |
2002 | + tcg_gen_ext_i32_i64(cpu_ir[rc], tmp1); | |
2003 | + tcg_temp_free(tmp1); | |
2004 | + } | |
1991 | 2005 | break; |
1992 | 2006 | default: |
1993 | 2007 | goto invalid_opc; |
... | ... | @@ -2116,59 +2130,43 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn) |
2116 | 2130 | #endif |
2117 | 2131 | case 0x20: |
2118 | 2132 | /* LDF */ |
2119 | -#if 0 // TODO | |
2120 | - gen_load_fmem(ctx, &gen_ldf, ra, rb, disp16); | |
2121 | -#else | |
2122 | - goto invalid_opc; | |
2123 | -#endif | |
2133 | + gen_load_mem(ctx, &gen_qemu_ldf, ra, rb, disp16, 1, 0); | |
2124 | 2134 | break; |
2125 | 2135 | case 0x21: |
2126 | 2136 | /* LDG */ |
2127 | -#if 0 // TODO | |
2128 | - gen_load_fmem(ctx, &gen_ldg, ra, rb, disp16); | |
2129 | -#else | |
2130 | - goto invalid_opc; | |
2131 | -#endif | |
2137 | + gen_load_mem(ctx, &gen_qemu_ldg, ra, rb, disp16, 1, 0); | |
2132 | 2138 | break; |
2133 | 2139 | case 0x22: |
2134 | 2140 | /* LDS */ |
2135 | - gen_load_fmem(ctx, &gen_lds, ra, rb, disp16); | |
2141 | + gen_load_mem(ctx, &gen_qemu_lds, ra, rb, disp16, 1, 0); | |
2136 | 2142 | break; |
2137 | 2143 | case 0x23: |
2138 | 2144 | /* LDT */ |
2139 | - gen_load_fmem(ctx, &gen_ldt, ra, rb, disp16); | |
2145 | + gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 1, 0); | |
2140 | 2146 | break; |
2141 | 2147 | case 0x24: |
2142 | 2148 | /* STF */ |
2143 | -#if 0 // TODO | |
2144 | - gen_store_fmem(ctx, &gen_stf, ra, rb, disp16); | |
2145 | -#else | |
2146 | - goto invalid_opc; | |
2147 | -#endif | |
2149 | + gen_store_mem(ctx, &gen_qemu_stf, ra, rb, disp16, 1, 0); | |
2148 | 2150 | break; |
2149 | 2151 | case 0x25: |
2150 | 2152 | /* STG */ |
2151 | -#if 0 // TODO | |
2152 | - gen_store_fmem(ctx, &gen_stg, ra, rb, disp16); | |
2153 | -#else | |
2154 | - goto invalid_opc; | |
2155 | -#endif | |
2153 | + gen_store_mem(ctx, &gen_qemu_stg, ra, rb, disp16, 1, 0); | |
2156 | 2154 | break; |
2157 | 2155 | case 0x26: |
2158 | 2156 | /* STS */ |
2159 | - gen_store_fmem(ctx, &gen_sts, ra, rb, disp16); | |
2157 | + gen_store_mem(ctx, &gen_qemu_sts, ra, rb, disp16, 1, 0); | |
2160 | 2158 | break; |
2161 | 2159 | case 0x27: |
2162 | 2160 | /* STT */ |
2163 | - gen_store_fmem(ctx, &gen_stt, ra, rb, disp16); | |
2161 | + gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 1, 0); | |
2164 | 2162 | break; |
2165 | 2163 | case 0x28: |
2166 | 2164 | /* LDL */ |
2167 | - gen_load_mem(ctx, &tcg_gen_qemu_ld32s, ra, rb, disp16, 0); | |
2165 | + gen_load_mem(ctx, &tcg_gen_qemu_ld32s, ra, rb, disp16, 0, 0); | |
2168 | 2166 | break; |
2169 | 2167 | case 0x29: |
2170 | 2168 | /* LDQ */ |
2171 | - gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 0); | |
2169 | + gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 0, 0); | |
2172 | 2170 | break; |
2173 | 2171 | case 0x2A: |
2174 | 2172 | /* LDL_L */ |
... | ... | @@ -2180,11 +2178,11 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn) |
2180 | 2178 | break; |
2181 | 2179 | case 0x2C: |
2182 | 2180 | /* STL */ |
2183 | - gen_store_mem(ctx, &tcg_gen_qemu_st32, ra, rb, disp16, 0); | |
2181 | + gen_store_mem(ctx, &tcg_gen_qemu_st32, ra, rb, disp16, 0, 0); | |
2184 | 2182 | break; |
2185 | 2183 | case 0x2D: |
2186 | 2184 | /* STQ */ |
2187 | - gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 0); | |
2185 | + gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 0, 0); | |
2188 | 2186 | break; |
2189 | 2187 | case 0x2E: |
2190 | 2188 | /* STL_C */ |
... | ... | @@ -2203,17 +2201,17 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn) |
2203 | 2201 | break; |
2204 | 2202 | case 0x31: |
2205 | 2203 | /* FBEQ */ |
2206 | - gen_fbcond(ctx, &gen_op_cmpfeq, ra, disp16); | |
2204 | + gen_fbcond(ctx, &helper_cmpfeq, ra, disp16); | |
2207 | 2205 | ret = 1; |
2208 | 2206 | break; |
2209 | 2207 | case 0x32: |
2210 | 2208 | /* FBLT */ |
2211 | - gen_fbcond(ctx, &gen_op_cmpflt, ra, disp16); | |
2209 | + gen_fbcond(ctx, &helper_cmpflt, ra, disp16); | |
2212 | 2210 | ret = 1; |
2213 | 2211 | break; |
2214 | 2212 | case 0x33: |
2215 | 2213 | /* FBLE */ |
2216 | - gen_fbcond(ctx, &gen_op_cmpfle, ra, disp16); | |
2214 | + gen_fbcond(ctx, &helper_cmpfle, ra, disp16); | |
2217 | 2215 | ret = 1; |
2218 | 2216 | break; |
2219 | 2217 | case 0x34: |
... | ... | @@ -2225,17 +2223,17 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn) |
2225 | 2223 | break; |
2226 | 2224 | case 0x35: |
2227 | 2225 | /* FBNE */ |
2228 | - gen_fbcond(ctx, &gen_op_cmpfne, ra, disp16); | |
2226 | + gen_fbcond(ctx, &helper_cmpfne, ra, disp16); | |
2229 | 2227 | ret = 1; |
2230 | 2228 | break; |
2231 | 2229 | case 0x36: |
2232 | 2230 | /* FBGE */ |
2233 | - gen_fbcond(ctx, &gen_op_cmpfge, ra, disp16); | |
2231 | + gen_fbcond(ctx, &helper_cmpfge, ra, disp16); | |
2234 | 2232 | ret = 1; |
2235 | 2233 | break; |
2236 | 2234 | case 0x37: |
2237 | 2235 | /* FBGT */ |
2238 | - gen_fbcond(ctx, &gen_op_cmpfgt, ra, disp16); | |
2236 | + gen_fbcond(ctx, &helper_cmpfgt, ra, disp16); | |
2239 | 2237 | ret = 1; |
2240 | 2238 | break; |
2241 | 2239 | case 0x38: | ... | ... |