Commit f18cd2238d39950f8a532cb2a2ee48a453d2e88f

Authored by aurel32
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
target-alpha/cpu.h
... ... @@ -277,8 +277,6 @@ struct CPUAlphaState {
277 277 */
278 278 target_ulong t0, t1;
279 279 #endif
280   - /* */
281   - double ft0, ft1, ft2;
282 280  
283 281 /* Those resources are used only in Qemu core */
284 282 CPU_COMMON
... ...
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:
... ...