aboutsummaryrefslogtreecommitdiff
path: root/none/tests/s390x/fpext.c
blob: 62b6bb7f246adfe60593d2a9edadc6f4ef406e61 (plain)
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;
}