1 /*******************************************************************************
2 * Derived from the test case for the "dcbzl" instruction support by
3 * Dave Goodell * <goodell@mcs.anl.gov>
4 * (see: Bug 135264 - dcbzl instruction missing)
5 * and: coregrind/m_machine.c/find_ppc_dcbz_sz()
6 ******************************************************************************/
8 /* ensure we have posix_memalign */
9 #define _POSIX_C_SOURCE 200112L
16 static int query_block_size(void)
18 #define MAX_DCBZL_SZB (128) /* largest known effect of dcbzl */
19 char *test_block
= NULL
;
20 register char *rb
asm ("r14");
21 int block_size
, test_block_size
= 4 * MAX_DCBZL_SZB
, err
;
24 err
= posix_memalign ((void **)&test_block
, MAX_DCBZL_SZB
, test_block_size
);
26 fprintf(stderr
, "posix_memalign() failed (err = %d [%s])\n", err
, strerror(err
));
32 memset(rb
, 0xff, test_block_size
);
33 asm volatile ("dcbzl 0, %[RB]" : : [RB
] "r" (rb
));
34 for (block_size
= 0, p
= rb
; (p
- rb
) < test_block_size
; p
++)
37 assert(block_size
== 16 || block_size
== 32 || block_size
== 64 || block_size
== 128);
43 /* Test dcbzl at addr in buffer given dcbzl_block_size */
44 static void test_dcbzl_at(char *addr
, char *buffer
, int block_size
)
48 /* Note: Assumption is that the length of buffer is three times the block_size. */
49 memset(buffer
, 0xff, 3 * block_size
);
50 asm volatile ("dcbzl %[RA], %[RB]" : : [RA
] "r" (0), [RB
] "r" (addr
));
51 for (i
= 0; i
< block_size
; i
++) {
52 assert(buffer
[i
] == 0xff);
53 assert(buffer
[block_size
+ i
] == 0x00);
54 assert(buffer
[2 * block_size
+ i
] == 0xff);
58 /* Test for insn: dcbzl */
59 static int test_dcbzl(void)
66 block_size
= query_block_size();
67 assert(block_size
== 16 || block_size
== 32 || block_size
== 64 || block_size
== 128);
68 buffer_size
= 3 * block_size
;
69 err
= posix_memalign((void **) &buffer
, block_size
, buffer_size
);
71 fprintf(stderr
, "posix_memalign() failed (err = %d [%s])\n", err
, strerror(err
));
75 /* check at aligned address within the test block */
76 test_dcbzl_at(&buffer
[block_size
], buffer
, block_size
);
77 fprintf(stdout
, "Passed dcbzl test at aligned address within the test block.\n");
79 /* check at un-aligned (1 modulo block_size) address within the test block */
80 test_dcbzl_at(&buffer
[block_size
+1], buffer
, block_size
);
81 fprintf(stdout
, "Passed dcbzl test at un-aligned (1 modulo block_size) address within the test block.\n");
83 /* check at un-aligned ((block_size - 1) modulo block_size) address within the test block */
84 test_dcbzl_at(&buffer
[2 * block_size
- 1], buffer
, block_size
);
85 fprintf(stdout
, "Passed dcbzl test at un-aligned ((block_size - 1) modulo block_size) address within the test block.\n");
91 int main(int argc
, char **argv
)
94 status
= test_dcbzl ();