1 #include <float.h>
2 #include <stdio.h>
3 #include <assert.h>
4 #include "opcodes.h"
5
6
7 #define L2F(insn, initial, target,round) \
8 ({ \
9 register unsigned long source asm("2") = initial; \
10 register typeof(target) _t asm("f0"); \
11 asm volatile(insn(round,0,0,2) :"=f" (_t):"d"(source)); \
12 _t; \
13 })
14
15 #define F2L(insn, initial, type, round, cc) \
16 ({ \
17 register type source asm("f0") = initial; \
18 register unsigned long target asm ("2") = 0; \
19 asm volatile(insn(round,0,2,0) \
20 "ipm %1\n\t" \
21 "srl %1,28\n\t" \
22 :"=d" (target), "=d" (cc) :"f"(source):"cc"); \
23 target; \
24 })
25
26
27 #define DO_INSN_L2F32(insn, round) \
28 ({ \
29 float f32; \
30 printf(#insn " %f\n", L2F(insn, 0, f32, round)); \
31 printf(#insn " %f\n", L2F(insn, 1, f32, round)); \
32 printf(#insn " %f\n", L2F(insn, 0xffffffffUL, f32, round)); \
33 printf(#insn " %f\n", L2F(insn, 0x80000000UL, f32, round)); \
34 printf(#insn " %f\n", L2F(insn, 0x7fffffffUL, f32, round)); \
35 printf(#insn " %f\n", L2F(insn, 0x100000000UL, f32, round)); \
36 printf(#insn " %f\n", L2F(insn, 0xffffffffffffffffUL, f32, round)); \
37 printf(#insn " %f\n", L2F(insn, 0x8000000000000000UL, f32, round)); \
38 printf(#insn " %f\n", L2F(insn, 0x7fffffffffffffffUL, f32, round)); \
39 })
40
41 #define DO_INSN_L2F64(insn, round) \
42 ({ \
43 double f64; \
44 printf(#insn " %f\n", L2F(insn, 0, f64, round)); \
45 printf(#insn " %f\n", L2F(insn, 1, f64, round)); \
46 printf(#insn " %f\n", L2F(insn, 0xffffffffUL, f64, round)); \
47 printf(#insn " %f\n", L2F(insn, 0x80000000UL, f64, round)); \
48 printf(#insn " %f\n", L2F(insn, 0x7fffffffUL, f64, round)); \
49 printf(#insn " %f\n", L2F(insn, 0x100000000UL, f64, round)); \
50 printf(#insn " %f\n", L2F(insn, 0xffffffffffffffffUL, f64, round)); \
51 printf(#insn " %f\n", L2F(insn, 0x8000000000000000UL, f64, round)); \
52 printf(#insn " %f\n", L2F(insn, 0x7fffffffffffffffUL, f64, round)); \
53 })
54
55 #define DO_INSN_L2F128(insn, round) \
56 ({ \
57 long double f128; \
58 printf(#insn " %Lf\n", L2F(insn, 0, f128, round)); \
59 printf(#insn " %Lf\n", L2F(insn, 1, f128, round)); \
60 printf(#insn " %Lf\n", L2F(insn, 0xffffffffUL, f128, round)); \
61 printf(#insn " %Lf\n", L2F(insn, 0x80000000UL, f128, round)); \
62 printf(#insn " %Lf\n", L2F(insn, 0x7fffffffUL, f128, round)); \
63 printf(#insn " %Lf\n", L2F(insn, 0x100000000UL, f128, round)); \
64 printf(#insn " %Lf\n", L2F(insn, 0xffffffffffffffffUL, f128, round)); \
65 printf(#insn " %Lf\n", L2F(insn, 0x8000000000000000UL, f128, round)); \
66 printf(#insn " %Lf\n", L2F(insn, 0x7fffffffffffffffUL, f128, round)); \
67 })
68
69 #define DO_INSN_F2L(insn, round, type) \
70 ({ \
71 int cc; \
72 printf(#insn " %lu ", F2L(insn, -1.1, type, round, cc)); \
73 printf("cc=%d\n", cc); \
74 printf(#insn " %lu ", F2L(insn, 0, type, round, cc)); \
75 printf("cc=%d\n", cc); \
76 printf(#insn " %lu ", F2L(insn, 1, type, round, cc)); \
77 printf("cc=%d\n", cc); \
78 printf(#insn " %lu ", F2L(insn, 1.4, type, round, cc)); \
79 printf("cc=%d\n", cc); \
80 printf(#insn " %lu ", F2L(insn, 1.5, type, round, cc)); \
81 printf("cc=%d\n", cc); \
82 printf(#insn " %lu ", F2L(insn, 1.6, type, round, cc)); \
83 printf("cc=%d\n", cc); \
84 printf(#insn " %lu ", F2L(insn, 1.6E+4, type, round, cc)); \
85 printf("cc=%d\n", cc); \
86 printf(#insn " %lu ", F2L(insn, 1.6E+8, type, round, cc)); \
87 printf("cc=%d\n", cc); \
88 printf(#insn " %lu ", F2L(insn, 1.6E+12, type, round, cc)); \
89 printf("cc=%d\n", cc); \
90 printf(#insn " %lu ", F2L(insn, 1.6E+20, type, round, cc)); \
91 printf("cc=%d\n", cc); \
92 printf(#insn " %lu ", F2L(insn, 1.6E+200, type, round, cc)); \
93 printf("cc=%d\n", cc); \
94 printf(#insn " %lu ", F2L(insn, 1.6E+2000L, type, round, cc)); \
95 printf("cc=%d\n", cc); \
96 printf(#insn " %lu ", F2L(insn, 1.6E-4, type, round, cc)); \
97 printf("cc=%d\n", cc); \
98 printf(#insn " %lu ", F2L(insn, FLT_MIN, type, round, cc)); \
99 printf("cc=%d\n", cc); \
100 printf(#insn " %lu ", F2L(insn, FLT_MAX, type, round, cc)); \
101 printf("cc=%d\n", cc); \
102 printf(#insn " %lu ", F2L(insn, DBL_MIN, type, round, cc)); \
103 printf("cc=%d\n", cc); \
104 printf(#insn " %lu ", F2L(insn, DBL_MAX, type, round, cc)); \
105 printf("cc=%d\n", cc); \
106 printf(#insn " %lu ", F2L(insn, LDBL_MIN, type, round, cc)); \
107 printf("cc=%d\n", cc); \
108 printf(#insn " %lu ", F2L(insn, LDBL_MAX, type, round, cc)); \
109 printf("cc=%d\n", cc); \
110 })
111
112 #define DO_L2F(round) \
113 ({ \
114 DO_INSN_L2F32(CELFBR, round); \
115 DO_INSN_L2F32(CELGBR, round); \
116 DO_INSN_L2F64(CDLFBR, round); \
117 DO_INSN_L2F64(CDLGBR, round); \
118 DO_INSN_L2F128(CXLFBR, round); \
119 DO_INSN_L2F128(CXLGBR, round); \
120 })
121
122 #define DO_F2L(round) \
123 ({ \
124 DO_INSN_F2L(CLFEBR, round, float); \
125 DO_INSN_F2L(CLGEBR, round, float); \
126 DO_INSN_F2L(CLFDBR, round, double); \
127 DO_INSN_F2L(CLGDBR, round, double); \
128 DO_INSN_F2L(CLFXBR, round, long double); \
129 DO_INSN_F2L(CLGXBR, round, long double); \
130 })
131
132
main()133 int main()
134 {
135 assert(sizeof(long double) == 16);
136 DO_L2F(4);
137 DO_F2L(4);
138
139 DO_L2F(5);
140 DO_F2L(5);
141
142 DO_L2F(6);
143 DO_F2L(6);
144
145 DO_L2F(7);
146 DO_F2L(7);
147
148 return 0;
149 }
150