none/tests/fdleak_cmsg_supp.supp: Add suppressions for older glibc
[valgrind.git] / none / tests / mips64 / change_fp_mode.c
blob4dca120afc78a7f653be3e8a50769b24e6f100b7
1 #if defined(__mips_hard_float)
3 #include <elf.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <sys/prctl.h>
7 #include "pub_core_basics.h"
9 #if !defined(PR_SET_FP_MODE)
10 # define PR_SET_FP_MODE 45
11 #endif
13 #if !defined(PR_GET_FP_MODE)
14 # define PR_GET_FP_MODE 46
15 #endif
17 #define TEST_LD(instruction, source) \
18 { \
19 unsigned int result1, result2; \
20 __asm__ volatile( \
21 ".set push\n\t" \
22 ".set noreorder\n\t" \
23 "li $t0, 0x5a5a\n\t" \
24 "mtc1 $t0, $f0\n\t" \
25 "mtc1 $t0, $f1\n\t" \
26 "move $t0, %2\n\t" \
27 instruction"\n\t" \
28 "swc1 $f0, %0\n\t" \
29 "swc1 $f1, %1\n\t" \
30 ".set pop\n\t" \
31 : "=m"(result1), "=m"(result2) \
32 : "r" (&source) \
33 : "t0", "$f0", "$f1"); \
34 printf(instruction" :: lo32(f1): %x, lo32(f0): %x\n", \
35 result2, result1); \
38 #define _TEST_ST(instruction) \
39 __asm__ volatile( \
40 ".set push\n\t" \
41 ".set noreorder\n\t" \
42 "li $t0, 0x5a5a\n\t" \
43 "dmtc1 $t0, $f1\n\t" \
44 "move $t0, %0\n\t" \
45 "ldc1 $f0, 0($t0)\n\t" \
46 "move $t0, %1\n\t" \
47 instruction"\n\t" \
48 ".set pop\n\t" \
49 : \
50 : "r" (&source64), "r" (&result) \
51 : "t0", "$f0", "$f1", "memory")
53 #define TEST_ST64(instruction) \
54 { \
55 RegWord result; \
56 _TEST_ST(instruction); \
57 printf(instruction" :: mem: %" FMT_REGWORD "x\n", result); \
60 #define TEST_ST32(instruction) \
61 { \
62 unsigned int result; \
63 _TEST_ST(instruction); \
64 printf(instruction" :: mem: %x\n", result); \
67 #define TEST_MT(instruction) \
68 { \
69 unsigned int result1, result2; \
70 __asm__ volatile( \
71 ".set push\n\t" \
72 ".set noreorder\n\t" \
73 "li $t0, 0x5a5a\n\t" \
74 "mtc1 $t0, $f0\n\t" \
75 "mtc1 $t0, $f1\n\t" \
76 "ld $t0, %2\n\t" \
77 instruction"\n\t" \
78 "swc1 $f0, %0\n\t" \
79 "swc1 $f1, %1\n\t" \
80 ".set pop\n\t" \
81 : "=m"(result1), "=m"(result2) \
82 : "m" (source64) \
83 : "t0", "$f0", "$f1"); \
84 printf(instruction" :: lo32(f1): %x, lo32(f0): %x\n", \
85 result2, result1); \
88 #define TEST_MF(instruction) \
89 { \
90 RegWord result; \
91 __asm__ volatile( \
92 ".set push\n\t" \
93 ".set noreorder\n\t" \
94 "li $t0, 0x5a5a\n\t" \
95 "dmtc1 $t0, $f1\n\t" \
96 "ldc1 $f0, %1\n\t" \
97 "move $t0, $0\n\t" \
98 instruction"\n\t" \
99 "sd $t0, %0\n\t" \
100 ".set pop\n\t" \
101 : "=m" (result) \
102 : "m" (source64) \
103 : "t0", "$f0", "$f1"); \
104 printf(instruction" :: t0: %" FMT_REGWORD "x\n", result); \
107 #define TEST_MOVE(instruction) \
109 unsigned int result1, result2; \
110 __asm__ volatile( \
111 ".set push\n\t" \
112 ".set noreorder\n\t" \
113 "li $t0, 0x5a5a\n\t" \
114 "mtc1 $t0, $f0\n\t" \
115 "li $t0, 0x6b6b\n\t" \
116 "mtc1 $t0, $f1\n\t" \
117 "li $t0, 0x7c7c\n\t" \
118 "dmtc1 $t0, $f2\n\t" \
119 "ldc1 $f2, %2\n\t" \
120 instruction"\n\t" \
121 "swc1 $f0, %0\n\t" \
122 "swc1 $f1, %1\n\t" \
123 ".set pop\n\t" \
124 : "=m"(result1), "=m"(result2) \
125 : "m" (source64) \
126 : "t0", "$f0", "$f1", "$f2"); \
127 printf(instruction" :: lo32(f1): %x, lo32(f0): %x\n", \
128 result2, result1); \
131 ULong source64 = 0x1234567890abcdefull;
132 unsigned int source32 = 0x12345678u;
134 /* Determine FP mode based on sdc1 behavior
135 returns 1 if FR = 1 mode is detected (assumes FRE = 0) */
136 static int get_fp_mode(void) {
137 unsigned long long result = 0;
138 __asm__ volatile(
139 ".set push\n\t"
140 ".set noreorder\n\t"
141 "lui $t0, 0x3ff0\n\t"
142 "ldc1 $f0, %0\n\t"
143 "mtc1 $t0, $f1\n\t"
144 "sdc1 $f0, %0\n\t"
145 ".set pop\n\t"
146 : "+m"(result)
148 : "t0", "$f0", "$f1", "memory");
150 return (result != 0x3ff0000000000000ull);
153 static void fatal_error(const char* msg) {
154 fprintf(stderr, "Error: %s\n", msg);
155 exit(1);
158 static void test(int* fr_prctl, int* fr_detected) {
159 #if (__mips_isa_rev<6)
160 *fr_prctl = prctl(PR_GET_FP_MODE);
161 *fr_detected = get_fp_mode();
163 if (*fr_prctl < 0) {
164 fatal_error("prctl(PR_GET_FP_MODE) fails.");
167 printf("fr_prctl: %d, fr_detected: %d\n", *fr_prctl, *fr_detected);
169 if (*fr_prctl != *fr_detected) {
170 fatal_error("fr_prctl != fr_detected");
173 TEST_LD("lwc1 $f0, 0($t0)", source32);
174 TEST_LD("lwc1 $f1, 0($t0)", source32);
176 TEST_LD("lwxc1 $f0, $0($t0)", source32);
177 TEST_LD("lwxc1 $f1, $0($t0)", source32);
179 TEST_LD("ldc1 $f0, 0($t0)", source64);
180 TEST_LD("ldc1 $f1, 0($t0)", source64);
182 TEST_LD("ldxc1 $f0, $0($t0)", source64);
183 TEST_LD("ldxc1 $f1, $0($t0)", source64);
185 TEST_ST32("swc1 $f0, 0($t0)");
186 TEST_ST32("swc1 $f1, 0($t0)");
188 TEST_ST32("swxc1 $f0, $0($t0)");
189 TEST_ST32("swxc1 $f1, $0($t0)");
191 TEST_ST64("sdc1 $f0, 0($t0)");
192 TEST_ST64("sdc1 $f1, 0($t0)");
194 TEST_ST64("sdxc1 $f0, $0($t0)");
195 TEST_ST64("sdxc1 $f1, $0($t0)");
197 TEST_MT("mtc1 $t0, $f0");
198 TEST_MT("mtc1 $t0, $f1");
200 TEST_MT("dmtc1 $t0, $f0");
201 TEST_MT("dmtc1 $t0, $f1");
203 TEST_MF("mfc1 $t0, $f0");
204 TEST_MF("mfc1 $t0, $f1");
206 TEST_MF("dmfc1 $t0, $f0");
207 TEST_MF("dmfc1 $t0, $f1");
209 TEST_MOVE("movn.s $f0, $f2, $t0");
210 TEST_MOVE("movn.s $f0, $f1, $t0");
211 TEST_MOVE("movn.s $f1, $f2, $t0");
212 TEST_MOVE("movn.s $f0, $f2, $0");
213 TEST_MOVE("movn.s $f0, $f1, $0");
214 TEST_MOVE("movn.s $f1, $f2, $0");
216 TEST_MOVE("movn.d $f0, $f2, $t0");
217 TEST_MOVE("movn.d $f0, $f1, $t0");
218 TEST_MOVE("movn.d $f1, $f2, $t0");
219 TEST_MOVE("movn.d $f0, $f2, $0");
220 TEST_MOVE("movn.d $f0, $f1, $0");
221 TEST_MOVE("movn.d $f1, $f2, $0");
223 TEST_MOVE("movz.s $f0, $f2, $t0");
224 TEST_MOVE("movz.s $f0, $f1, $t0");
225 TEST_MOVE("movz.s $f1, $f2, $t0");
226 TEST_MOVE("movz.s $f0, $f2, $0");
227 TEST_MOVE("movz.s $f0, $f1, $0");
228 TEST_MOVE("movz.s $f1, $f2, $0");
230 TEST_MOVE("movz.d $f0, $f2, $t0");
231 TEST_MOVE("movz.d $f0, $f1, $t0");
232 TEST_MOVE("movz.d $f1, $f2, $t0");
233 TEST_MOVE("movz.d $f0, $f2, $0");
234 TEST_MOVE("movz.d $f0, $f1, $0");
235 TEST_MOVE("movz.d $f1, $f2, $0");
236 #endif
239 int main() {
240 int fr_prctl, fr_detected;
242 test(&fr_prctl, &fr_detected);
244 /* FP64 */
245 if (fr_prctl == 1) {
247 /* Change mode to FP32 */
248 if (prctl(PR_SET_FP_MODE, 0) != 0) {
249 fatal_error("prctl(PR_SET_FP_MODE, 0) fails.");
252 test(&fr_prctl, &fr_detected);
254 /* Change back FP mode */
255 if (prctl(PR_SET_FP_MODE, 1) != 0) {
256 fatal_error("prctl(PR_SET_FP_MODE, 1) fails.");
259 test(&fr_prctl, &fr_detected);
262 return 0;
264 #else
265 int main() {
266 return 0;
268 #endif