FreeBSD: add file descriptor tracking for _umtx_op
[valgrind.git] / none / tests / s390x / rounding-3.c
blobbd53db686c3350a176f0b018e0915cce89af233e
1 #include <assert.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <stdint.h>
5 #include <inttypes.h>
6 #include "opcodes.h"
8 /* Test "convert to fixed" with "per fpc" rounding.
9 Covers all generally available rounding modes.
12 void
13 set_rounding_mode(unsigned mode)
15 register unsigned r asm("1") = mode;
16 __asm__ volatile ( SFPC(1) : : "d"(r) );
19 unsigned
20 get_rounding_mode(void)
22 unsigned fpc;
24 __asm__ volatile ("stfpc %0" : "=Q"(fpc));
26 return fpc & 0x7;
30 const char *
31 rtext(unsigned fpc_round)
33 switch (fpc_round) {
34 case 0: return "[-> near]";
35 case 1: return "[-> zero]";
36 case 2: return "[-> +inf]";
37 case 3: return "[-> -inf]";
39 assert(0);
42 #define convert_to_int(opcode,src_type,dst_type,dst_fmt,round,value) \
43 do { \
44 src_type src = value; \
45 dst_type dst; \
46 unsigned cc; \
48 __asm__ volatile (opcode " %[dst]," #round ",%[src]\n\t" \
49 "ipm %[cc]\n\t" \
50 "srl %[cc],28\n\t" \
51 : [dst] "=d"(dst), [cc] "=d"(cc) \
52 : [src] "f"(src) \
53 : "cc"); \
55 printf("%s %f\t-> %"dst_fmt"\tcc = %u\n", \
56 opcode, src, dst, cc); \
57 } while (0)
60 #define cfebr(value) \
61 convert_to_int("cfebr",float,int32_t,PRId32,0,value)
62 #define cfdbr(value) \
63 convert_to_int("cfdbr",double,int32_t,PRId32,0,value)
64 #define cgebr(value) \
65 convert_to_int("cgebr",float,int64_t,PRId64,0,value)
66 #define cgdbr(value) \
67 convert_to_int("cgdbr",double,int64_t,PRId64,0,value)
69 int main(void)
71 int i, j;
72 static const unsigned rmodes[] = { 0, 1, 2, 3 };
73 static const float fval[] = {
74 1.25f, 1.5f, 2.5f, 1.75f, -1.25f, -1.5f, -2.5f, -1.75f, 0.0f,
76 static const double dval[] = {
77 1.25, 1.5, 2.5, 1.75, -1.25, -1.5, -2.5, -1.75, 0.0,
81 for (i = 0; i < sizeof rmodes / sizeof rmodes[0]; ++i) {
82 printf("setting rounding mode to %s\n", rtext(rmodes[i]));
83 set_rounding_mode(rmodes[i]);
84 assert(get_rounding_mode() == rmodes[i]);
86 /* f32 -> i32 */
87 for (j = 0; j < sizeof fval / sizeof fval[0]; ++j) {
88 cfebr(fval[j]);
89 assert(get_rounding_mode() == rmodes[i]);
92 /* f32 -> i64 */
93 for (j = 0; j < sizeof fval / sizeof fval[0]; ++j) {
94 cgebr(fval[j]);
95 assert(get_rounding_mode() == rmodes[i]);
98 /* f64 -> i32 */
99 for (j = 0; j < sizeof dval / sizeof dval[0]; ++j) {
100 cfdbr(dval[j]);
101 assert(get_rounding_mode() == rmodes[i]);
104 /* f64 -> i64 */
105 for (j = 0; j < sizeof dval / sizeof dval[0]; ++j) {
106 cgdbr(dval[j]);
107 assert(get_rounding_mode() == rmodes[i]);
112 return 0;