drd/tests/swapcontext: Improve the portability of this test further
[valgrind.git] / none / tests / ppc32 / ldst_multiple.c
blob90f4c57261e6e416319b7bf32da5913210ab3507
1 #include <stdio.h>
2 #include <stdint.h>
4 #ifndef __powerpc64__
5 typedef uint32_t HWord_t;
6 #else
7 typedef uint64_t HWord_t;
8 #endif
10 typedef void (*test_func_t)();
12 typedef struct test_table {
13 test_func_t func;
14 char *name;
15 } test_table_t;
17 static uint32_t values[] = {
18 0x6efbcfdf,
19 0xd16c2fd4,
20 0xf9dc1743,
21 0xa5aa0bd4,
22 0x6c8f0c14,
23 0x69a24188,
24 0x53b57f1b,
27 register HWord_t r27 asm("r27");
28 register HWord_t r28 asm("r28");
29 register HWord_t r29 asm("r29");
30 register HWord_t r30 asm("r30");
31 register HWord_t r31 asm("r31");
33 register HWord_t r14 asm("r14");
35 HWord_t temp[5];
37 #ifdef __powerpc64__
39 #define SAVE_REGS(addr) \
40 asm volatile( \
41 " std 27, 0(%0) \n" \
42 " std 28, 8(%0) \n" \
43 " std 29, 16(%0) \n" \
44 " std 30, 24(%0) \n" \
45 " std 31, 32(%0) \n" \
46 ::"b"(addr))
48 #define RESTORE_REGS(addr) \
49 asm volatile( \
50 " ld 27, 0(%0) \n" \
51 " ld 28, 8(%0) \n" \
52 " ld 29, 16(%0) \n" \
53 " ld 30, 24(%0) \n" \
54 " ld 31, 32(%0) \n" \
55 ::"b"(addr))
57 #else /* !__powerpc64__ */
59 #define SAVE_REGS(addr) \
60 asm volatile( \
61 " stw 27, 0(%0) \n" \
62 " stw 28, 4(%0) \n" \
63 " stw 29, 8(%0) \n" \
64 " stw 30, 12(%0) \n" \
65 " stw 31, 16(%0) \n" \
66 ::"b"(addr))
68 #define RESTORE_REGS(addr) \
69 asm volatile( \
70 " lwz 27, 0(%0) \n" \
71 " lwz 28, 4(%0) \n" \
72 " lwz 29, 8(%0) \n" \
73 " lwz 30, 12(%0) \n" \
74 " lwz 31, 16(%0) \n" \
75 ::"b"(addr))
77 #endif /* __powerpc64__ */
80 * gcc is not happy if we modify r31 (the frame pointer) behind its back
81 * so we omit it
83 static void __attribute__((optimize("-fomit-frame-pointer"))) test_lmw(void)
85 r14 = (HWord_t)values;
87 /* save r27 - r31 */
88 SAVE_REGS(temp);
90 /* load r27 - r31 */
91 asm volatile(
92 " lmw %r27, 0(%r14) \n");
94 #ifdef __powerpc64__
95 printf("lmw => %016lx %016lx %016lx %016lx %016lx\n",
96 #else
97 printf("lmw => %08x %08x %08x %08x %08x\n",
98 #endif
99 r27, r28, r29, r30, r31);
102 * test load multiple with nonzero immediate offset
103 * load the last two values into r30 - r31.
104 * r27 - r29 should remain the same
106 asm volatile(
107 " lmw %r30, 20(%r14) \n");
109 #ifdef __powerpc64__
110 printf("lmw => %016lx %016lx %016lx %016lx %016lx\n",
111 #else
112 printf("lmw => %08x %08x %08x %08x %08x\n",
113 #endif
114 r27, r28, r29, r30, r31);
116 /* restore r27 - r31 */
117 RESTORE_REGS(temp);
121 * gcc is not happy if we modify r31 (the frame pointer) behind its back
122 * so we omit it
124 static void __attribute__((optimize("-fomit-frame-pointer"))) test_stmw(void)
126 uint32_t result[7] = { 0 };
127 int i;
129 SAVE_REGS(temp);
131 #ifdef __powerpc64__
132 asm volatile(
133 " lwz 27, 0(%0) \n" \
134 " lwz 28, 4(%0) \n" \
135 " lwz 29, 8(%0) \n" \
136 " lwz 30, 12(%0) \n" \
137 " lwz 31, 16(%0) \n" \
138 ::"b"(values));
139 #else
140 RESTORE_REGS(values);
141 #endif
143 r14 = (HWord_t)&result;
145 /* store r27 - r31 */
146 asm volatile(
147 " stmw %r27, 0(%r14) \n");
149 printf("stmw => ");
150 for (i = 0; i < sizeof(result) / sizeof(result[0]); i++)
151 printf("%08x ", result[i]);
153 printf("\n");
156 * test store multiple with nonzero immediate offset
157 * store r30 - r31 into the last two places in the array
158 * the rest of the array should remain the same
160 asm volatile(
161 " stmw %r30, 20(%r14) \n");
163 printf("stmw => ");
164 for (i = 0; i < sizeof(result) / sizeof(result[0]); i++)
165 printf("%08x ", result[i]);
167 printf("\n");
169 RESTORE_REGS(temp);
172 static test_table_t all_tests[] = {
173 { &test_lmw,
174 "Test Load Multiple instruction" },
175 { &test_stmw,
176 "Test Store Multiple instruction" },
177 { NULL, NULL },
181 * gcc is not happy if we modify r31 (the frame pointer) behind its back
182 * so we omit it
184 int __attribute__((optimize("-fomit-frame-pointer"))) main(void)
186 test_func_t func;
187 int i = 0;
189 while ((func = all_tests[i].func)) {
190 (*func)();
191 i++;
194 return 0;