4 * The lxvx and stxvx instructions were extended mnemonics
5 * of the lxvd2x and stxvd2x instructions, which are Big-Endian
6 * by design in ISA 2.07 and earlier.
7 * Beginning with ISA 3.0 these are unique instructions and
9 * Tests of those instructions must be aware of which
10 * ISA level the code is being compiled to.
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License V2
16 * as published by the Free Software Foundation
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, see <http://www.gnu.org/licenses/>.
32 #include <ctype.h> // isspace
35 #include <unistd.h> // getopt
36 #include <altivec.h> // vector
37 #include <malloc.h> // memalign
39 #undef DEBUG_VECTOR_PERMUTE
40 static int verbose
= 0;
42 typedef uint64_t HWord_t
;
44 /* Define a small memory range used to test load-from and store-to vsx */
46 #define MAX_BUFFER_PATTERNS 6
47 unsigned long buffer
[BUFFER_SIZE
];
49 static void dump_small_buffer(void) {
54 for (x
= 0; x
< BUFFER_SIZE
; x
++)
55 printf("%016lx ", buffer
[x
] );
60 static void initialize_buffer(int t
)
64 for (x
= 0; x
< BUFFER_SIZE
; x
++)
65 /* Don't want each of the 32-bit chunks to be identical. Loads of a
66 * byte from the wrong 32-bit chuck are not detectable if the chunks
69 switch((t
+x
)%BUFFER_SIZE
) {
71 buffer
[x
] = 0xffffffffffffffff;
74 buffer
[x
] = 0x0001020304050607;
77 buffer
[x
] = 0x5555555555555555;
80 buffer
[x
] = 0x0000000000000000;
83 buffer
[x
] = 0x5a05a05a05a05a05;
86 buffer
[x
] = 0x0102030405060708;
89 buffer
[x
] = 0x1010101010101010;
94 #define ALLCR "cr0","cr1","cr2","cr3","cr4","cr5","cr6","cr7"
96 #define SET_CR(_arg) \
97 __asm__ __volatile__ ("mtcr %0" : : "b"(_arg) : ALLCR );
102 #define GET_CR(_lval) \
103 __asm__ __volatile__ ("mfcr %0" : "=b"(_lval) )
105 #define GET_XER(_lval) \
106 __asm__ __volatile__ ("mfxer %0" : "=b"(_lval) )
108 #define SET_CR_ZERO \
111 /* a table of exponent values for use in the float precision tests. */
112 unsigned long exponent_table
[] = {
113 #ifdef EXHAUSTIVE_TESTS
114 0x0000, /* +/-0 or +/-DENormalized, depending on associated mantissa. */
115 0x1a, /* within NORmalized for 16,32,64,128-bit. */
116 0x1f, /* +/-INF or +/-NaN for 16bit, NORmalized for 32,64,128 */
117 0xff, /* +/-INF or +/-NaN for 32bit, NORmalized for 64,128 */
118 0x7ff, /* +/-INF or +/-NaN for 32 and 64bit, NORmalized for 128 */
119 0x7fff, /* +/-INF or +/-NaN for 128bit. */
121 0x0000, /* +/-0 or +/-DENormalized, depending on associated mantissa. */
122 0xff, /* +/-INF or +/-NaN for 32bit, NORmalized for 64,128 */
123 0x7ff, /* +/-INF or +/-NaN for 32 and 64bit, NORmalized for 128 */
124 0x7fff, /* +/-INF or +/-NaN for 128bit. */
127 #define MAX_EXPONENTS (sizeof(exponent_table) / sizeof(unsigned long))
129 unsigned long nb_float_vsxargs
;
131 #define MAX_FLOAT_VSX_ARRAY_SIZE (((MAX_EXPONENTS * MAX_MANTISSAS) * 2 + 1) * 2)
133 static unsigned long * vsxargs
= NULL
;
134 unsigned long nb_vargs
;
136 #define MAX_VSX_ARRAY_SIZE 42
138 static void build_vsx_table (void)
141 // A VSX register is 128-bits wide.
142 // We build contents here using pairs of 64-bit longs.
143 // Permutes work against two (non-paired) VSX regs, so these are
144 // also grouped by twos.
145 vsxargs
= memalign(16, MAX_VSX_ARRAY_SIZE
* sizeof(unsigned long));
146 #ifdef EXHAUSTIVE_TESTS
147 vsxargs
[i
++] = 0x0000000000000000UL
; vsxargs
[i
++] = 0x0000000000000000UL
;
148 vsxargs
[i
++] = 0x0102030405060708UL
; vsxargs
[i
++] = 0x0102010201020102UL
;
150 vsxargs
[i
++] = 0xaaaaaaaaaaaaaaaaUL
; vsxargs
[i
++] = 0xaaaaaaaaaaaaaaaaUL
;
151 vsxargs
[i
++] = 0x5555555555555555UL
; vsxargs
[i
++] = 0x5555555555555555UL
;
153 vsxargs
[i
++] = 0x08090a0b0c0d0e0fUL
; vsxargs
[i
++] = 0x0102010201020102UL
;
154 vsxargs
[i
++] = 0xf0f1f2f3f4f5f6f7UL
; vsxargs
[i
++] = 0xf8f9fafbfcfdfeffUL
;
156 vsxargs
[i
++] = 0x7ea1a5a7abadb0baUL
; vsxargs
[i
++] = 0x070d111d1e555e70UL
;
157 vsxargs
[i
++] = 0xe5e7ecedeff0f1faUL
; vsxargs
[i
++] = 0xbeb1c0caced0dbdeUL
;
159 vsxargs
[i
++] = 0x00115e7eadbabec0UL
; vsxargs
[i
++] = 0xced0deede5ecef00UL
;
160 vsxargs
[i
++] = 0x00111e7ea5abadb1UL
; vsxargs
[i
++] = 0xbecad0deedeffe00UL
;
162 vsxargs
[i
++] = 0x0011223344556677UL
; vsxargs
[i
++] = 0x8899aabbccddeeffUL
;
163 vsxargs
[i
++] = 0xf0e0d0c0b0a09080UL
; vsxargs
[i
++] = 0x7060504030201000UL
;
165 vsxargs
[i
++] = 0x0000000000000000UL
; vsxargs
[i
++] = 0x0000000000000000UL
;
166 vsxargs
[i
++] = 0x0102030405060708UL
; vsxargs
[i
++] = 0x0102010201020102UL
;
168 vsxargs
[i
++] = 0x0011223344556677UL
; vsxargs
[i
++] = 0x8899aabbccddeeffUL
;
169 vsxargs
[i
++] = 0xf0e0d0c0b0a09080UL
; vsxargs
[i
++] = 0x7060504030201000UL
;
172 // these next three groups are specific for vector rotate tests.
173 // bits 11:15,19:23,27:31 of each 32-bit word contain mb,me,sh values.
174 vsxargs
[i
++] = 0x0000100000001002ULL
; vsxargs
[i
++] = 0x0000100800001010ULL
;
175 vsxargs
[i
++] = 0x0010100000101002ULL
; vsxargs
[i
++] = 0x0010100800101010ULL
;
177 // vector rotate special...
178 vsxargs
[i
++] = 0x00001c0000001c02ULL
; vsxargs
[i
++] = 0x00001c0800001c10ULL
;
179 vsxargs
[i
++] = 0x00101c0000101c02ULL
; vsxargs
[i
++] = 0x00101c0800101c10ULL
;
181 // vector rotate special...
182 vsxargs
[i
++] = 0x00001f0000001f02ULL
; vsxargs
[i
++] = 0x00001f0800001f10ULL
;
183 vsxargs
[i
++] = 0x00101f0000101f02ULL
; vsxargs
[i
++] = 0x00101f0800101f10ULL
;
188 #define VERBOSE_FUNCTION_CALLOUT \
190 printf("Test Harness Function: %s\n", __FUNCTION__);
192 /* XXXX these must all be callee-save regs! */
193 register HWord_t r14
__asm__ ("r14");
194 register HWord_t r15
__asm__ ("r15");
195 register HWord_t r16
__asm__ ("r16");
196 register HWord_t r17
__asm__ ("r17");
197 register double f14
__asm__ ("fr14");
198 register double f15
__asm__ ("fr15");
200 /* globals used for vector tests */
201 static vector
unsigned long vec_xt
;
203 /* globals for the condition register fields. These are used to
204 * capture the condition register values immediately after the
205 * instruction under test is tested.
206 * This is to help prevent other test overhead, switch statements,
207 * compares, what-not from interfering.
209 unsigned long local_cr
;
210 unsigned long local_fpscr
;
211 unsigned long local_xer
;
212 volatile unsigned int cr_value
;
214 /* global for holding the DFP values */
215 //dfp_val_t dfp_value;
217 /* individual instruction tests */
218 typedef void (*test_func_t
) (void);
223 typedef struct test_list_t test_list_t
;
225 /* vector splat value */
226 volatile int x_splat
;
227 //volatile int dfp_significance;
229 /* groups of instruction tests, calling individual tests */
230 typedef void (*test_group_t
) (const char *name
, test_func_t func
,
231 unsigned int test_flags
);
238 static void test_lxvx(void) {
239 __asm__
__volatile__ ("lxvx %x0, 14, 15" : "=wa" (vec_xt
));
243 static void test_stxvx(void) {
244 __asm__
__volatile__ ("stxvx %x0, 14, 15" :: "wa" (vec_xt
));
247 static test_list_t testgroup_vector_loadstore
[] = {
248 { &test_lxvx
, "lxvx" },
249 { &test_stxvx
, "stxvx" },
253 /* table containing all of the instruction groups */
254 struct test_group_table_t
{
260 typedef struct test_group_table_t test_group_table_t
;
262 static test_group_table_t all_tests
[] = {
264 testgroup_vector_loadstore
,
265 "ppc vector load/store",
268 { NULL
, NULL
, 0x00000000, },
271 static void testfunction_vector_loadstore (const char* instruction_name
,
272 test_func_t test_function
,
273 unsigned int ignore_flags
) {
274 /* exercises vector loads from memory, and vector stores from memory.
275 * <load or store instruction> XS, RA, RB
276 * For these tests, RA will be zero.
277 * EA is then, simply, RB. */
281 VERBOSE_FUNCTION_CALLOUT
283 for (i
= 0; i
< nb_vargs
; i
+= 2) {
285 vec_xt
= (vector
unsigned long){vsxargs
[i
], vsxargs
[i
+1]};
287 r15
= (unsigned long) & buffer
;
289 for (buffer_pattern
= 0; buffer_pattern
< MAX_BUFFER_PATTERNS
;
292 /* set patterns on both ends */
293 initialize_buffer(buffer_pattern
);
295 printf("%s ", instruction_name
);
296 printf("%016lx %016lx ", (unsigned long)vec_xt
[1],
297 (unsigned long)vec_xt
[0]);
303 printf("\t\t\t\t%016lx %016lx ", (unsigned long)vec_xt
[1],
304 (unsigned long)vec_xt
[0]);
311 typedef struct insn_sel_flags_t_struct
{
315 static void do_tests ( insn_sel_flags_t seln_flags
)
317 test_group_t group_function
;
324 printf("%s:\n", all_tests
[i
].name
);
325 group_function
= &testfunction_vector_loadstore
;
326 tests
= all_tests
[i
].tests
;
328 for (j
= 0; tests
[j
].name
!= NULL
; j
++) {
329 (*group_function
)(tests
[j
].name
, tests
[j
].func
, 0);
336 if (verbose
) printf("\n");
338 printf("All done. Tested %d different instructions\n", n
);
342 int main (int argc
, char **argv
)
345 insn_sel_flags_t flags
;
351 printf("HAS_ISA_2_07 not detected.\n");