Merge tag 'qemu-macppc-20230206' of https://github.com/mcayland/qemu into staging
[qemu.git] / tests / tcg / s390x / branch-relative-long.c
blob8ce9f1c2e5921dd2f34dc5613d50f687a2fc8c2a
1 #include <stddef.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <sys/mman.h>
6 #define DEFINE_ASM(_name, _code) \
7 extern const char _name[]; \
8 extern const char _name ## _end[]; \
9 asm(" .globl " #_name "\n" \
10 #_name ":\n" \
11 " " _code "\n" \
12 " .globl " #_name "_end\n" \
13 #_name "_end:\n");
15 DEFINE_ASM(br_r14, "br %r14");
16 DEFINE_ASM(brasl_r0, "brasl %r0,-0x100000000");
17 DEFINE_ASM(brcl_0xf, "brcl 0xf,-0x100000000");
19 struct test {
20 const char *code;
21 const char *code_end;
24 static const struct test tests[] = {
26 .code = brasl_r0,
27 .code_end = brasl_r0_end,
30 .code = brcl_0xf,
31 .code_end = brcl_0xf_end,
35 int main(void)
37 unsigned char *buf;
38 size_t length = 0;
39 size_t i;
41 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) {
42 size_t test_length = 0x100000000 + (tests[i].code_end - tests[i].code);
44 if (test_length > length) {
45 length = test_length;
49 buf = mmap(NULL, length, PROT_READ | PROT_WRITE | PROT_EXEC,
50 MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0);
51 if (buf == MAP_FAILED) {
52 perror("SKIP: mmap() failed");
53 return 0;
56 memcpy(buf, br_r14, br_r14_end - br_r14);
57 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) {
58 void (*code)(void) = (void *)(buf + 0x100000000);
60 memcpy(code, tests[i].code, tests[i].code_end - tests[i].code);
61 code();
62 memset(code, 0, tests[i].code_end - tests[i].code);
65 munmap(buf, length);
67 return 0;