1fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll#include <stdio.h> 2fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll#include <stdint.h> 3fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll 4fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll#ifndef __powerpc64__ 5fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarlltypedef uint32_t HWord_t; 6fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll#else 7fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarlltypedef uint64_t HWord_t; 8fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll#endif 9fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll 10fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarlltypedef void (*test_func_t)(); 11fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll 12fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarlltypedef struct test_table { 13fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll test_func_t func; 14fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll char *name; 15fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll} test_table_t; 16fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll 17fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarllstatic uint32_t values[] = { 18fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll 0x6efbcfdf, 19fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll 0xd16c2fd4, 20fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll 0xf9dc1743, 21fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll 0xa5aa0bd4, 22fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll 0x6c8f0c14, 23fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll 0x69a24188, 24fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll 0x53b57f1b, 25fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll}; 26fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll 27fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarllregister HWord_t r27 asm("r27"); 28fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarllregister HWord_t r28 asm("r28"); 29fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarllregister HWord_t r29 asm("r29"); 30fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarllregister HWord_t r30 asm("r30"); 31fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarllregister HWord_t r31 asm("r31"); 32fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll 33fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarllregister HWord_t r14 asm("r14"); 34fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll 35fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarllHWord_t temp[5]; 36fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll 37fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll#ifdef __powerpc64__ 38fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll 39fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll#define SAVE_REGS(addr) \ 40fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll asm volatile( \ 41fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll " std 27, 0(%0) \n" \ 42fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll " std 28, 8(%0) \n" \ 43fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll " std 29, 16(%0) \n" \ 44fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll " std 30, 24(%0) \n" \ 45fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll " std 31, 32(%0) \n" \ 46fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll ::"b"(addr)) 47fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll 48fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll#define RESTORE_REGS(addr) \ 49fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll asm volatile( \ 50fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll " ld 27, 0(%0) \n" \ 51fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll " ld 28, 8(%0) \n" \ 52fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll " ld 29, 16(%0) \n" \ 53fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll " ld 30, 24(%0) \n" \ 54fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll " ld 31, 32(%0) \n" \ 55fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll ::"b"(addr)) 56fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll 57fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll#else /* !__powerpc64__ */ 58fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll 59fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll#define SAVE_REGS(addr) \ 60fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll asm volatile( \ 61fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll " stw 27, 0(%0) \n" \ 62fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll " stw 28, 4(%0) \n" \ 63fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll " stw 29, 8(%0) \n" \ 64fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll " stw 30, 12(%0) \n" \ 65fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll " stw 31, 16(%0) \n" \ 66fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll ::"b"(addr)) 67fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll 68fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll#define RESTORE_REGS(addr) \ 69fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll asm volatile( \ 70fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll " lwz 27, 0(%0) \n" \ 71fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll " lwz 28, 4(%0) \n" \ 72fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll " lwz 29, 8(%0) \n" \ 73fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll " lwz 30, 12(%0) \n" \ 74fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll " lwz 31, 16(%0) \n" \ 75fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll ::"b"(addr)) 76fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll 77fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll#endif /* __powerpc64__ */ 78fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll 79fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll/* 80fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll * gcc is not happy if we modify r31 (the frame pointer) behind its back 81fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll * so we omit it 82fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll */ 83fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarllstatic void __attribute__((optimize("-fomit-frame-pointer"))) test_lmw(void) 84fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll{ 85fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll r14 = (HWord_t)values; 86fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll 87fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll /* save r27 - r31 */ 88fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll SAVE_REGS(temp); 89fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll 90fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll /* load r27 - r31 */ 91fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll asm volatile( 92fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll " lmw %r27, 0(%r14) \n"); 93fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll 94fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll#ifdef __powerpc64__ 95fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll printf("lmw => %016lx %016lx %016lx %016lx %016lx\n", 96fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll#else 97fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll printf("lmw => %08x %08x %08x %08x %08x\n", 98fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll#endif 99fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll r27, r28, r29, r30, r31); 100fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll 101fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll /* 102fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll * test load multiple with nonzero immediate offset 103fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll * load the last two values into r30 - r31. 104fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll * r27 - r29 should remain the same 105fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll */ 106fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll asm volatile( 107fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll " lmw %r30, 20(%r14) \n"); 108fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll 109fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll#ifdef __powerpc64__ 110fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll printf("lmw => %016lx %016lx %016lx %016lx %016lx\n", 111fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll#else 112fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll printf("lmw => %08x %08x %08x %08x %08x\n", 113fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll#endif 114fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll r27, r28, r29, r30, r31); 115fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll 116fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll /* restore r27 - r31 */ 117fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll RESTORE_REGS(temp); 118fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll} 119fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll 120fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll/* 121fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll * gcc is not happy if we modify r31 (the frame pointer) behind its back 122fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll * so we omit it 123fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll */ 124fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarllstatic void __attribute__((optimize("-fomit-frame-pointer"))) test_stmw(void) 125fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll{ 126fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll uint32_t result[7] = { 0 }; 127fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll int i; 128fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll 129fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll SAVE_REGS(temp); 130fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll 131fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll#ifdef __powerpc64__ 132fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll asm volatile( 133fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll " lwz 27, 0(%0) \n" \ 134fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll " lwz 28, 4(%0) \n" \ 135fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll " lwz 29, 8(%0) \n" \ 136fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll " lwz 30, 12(%0) \n" \ 137fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll " lwz 31, 16(%0) \n" \ 138fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll ::"b"(values)); 139fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll#else 140fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll RESTORE_REGS(values); 141fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll#endif 142fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll 143fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll r14 = (HWord_t)&result; 144fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll 145fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll /* store r27 - r31 */ 146fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll asm volatile( 147fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll " stmw %r27, 0(%r14) \n"); 148fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll 149fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll printf("stmw => "); 150fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll for (i = 0; i < sizeof(result) / sizeof(result[0]); i++) 151fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll printf("%08x ", result[i]); 152fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll 153fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll printf("\n"); 154fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll 155fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll /* 156fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll * test store multiple with nonzero immediate offset 157fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll * store r30 - r31 into the last two places in the array 158fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll * the rest of the array should remain the same 159fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll */ 160fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll asm volatile( 161fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll " stmw %r30, 20(%r14) \n"); 162fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll 163fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll printf("stmw => "); 164fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll for (i = 0; i < sizeof(result) / sizeof(result[0]); i++) 165fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll printf("%08x ", result[i]); 166fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll 167fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll printf("\n"); 168fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll 169fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll RESTORE_REGS(temp); 170fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll} 171fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll 172fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarllstatic test_table_t all_tests[] = { 173fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll { &test_lmw, 174fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll "Test Load Multiple instruction" }, 175fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll { &test_stmw, 176fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll "Test Store Multiple instruction" }, 177fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll { NULL, NULL }, 178fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll}; 179fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll 1801d19897b534ce0b1c762cdea2c9d06b8035a24edmjw/* 1811d19897b534ce0b1c762cdea2c9d06b8035a24edmjw * gcc is not happy if we modify r31 (the frame pointer) behind its back 1821d19897b534ce0b1c762cdea2c9d06b8035a24edmjw * so we omit it 1831d19897b534ce0b1c762cdea2c9d06b8035a24edmjw */ 1841d19897b534ce0b1c762cdea2c9d06b8035a24edmjwint __attribute__((optimize("-fomit-frame-pointer"))) main(void) 185fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll{ 186fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll test_func_t func; 187fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll int i = 0; 188fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll 189fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll while ((func = all_tests[i].func)) { 190fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll (*func)(); 191fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll i++; 192fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll } 193fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll 194fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll return 0; 195fec95c8f1c079b1525e5a22b0cf51bcd1a00366dcarll} 196