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