1 #include <stdio.h> 2 #include <stdint.h> 3 4 #ifndef __powerpc64__ 5 typedef uint32_t HWord_t; 6 #else 7 typedef uint64_t HWord_t; 8 #endif 9 10 typedef void (*test_func_t)(); 11 12 typedef struct test_table { 13 test_func_t func; 14 char *name; 15 } test_table_t; 16 17 static uint32_t values[] = { 18 0x6efbcfdf, 19 0xd16c2fd4, 20 0xf9dc1743, 21 0xa5aa0bd4, 22 0x6c8f0c14, 23 0x69a24188, 24 0x53b57f1b, 25 }; 26 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"); 32 33 register HWord_t r14 asm("r14"); 34 35 HWord_t temp[5]; 36 37 #ifdef __powerpc64__ 38 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)) 47 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)) 56 57 #else /* !__powerpc64__ */ 58 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)) 67 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)) 76 77 #endif /* __powerpc64__ */ 78 79 /* 80 * gcc is not happy if we modify r31 (the frame pointer) behind its back 81 * so we omit it 82 */ 83 static void __attribute__((optimize("-fomit-frame-pointer"))) test_lmw(void) 84 { 85 r14 = (HWord_t)values; 86 87 /* save r27 - r31 */ 88 SAVE_REGS(temp); 89 90 /* load r27 - r31 */ 91 asm volatile( 92 " lmw %r27, 0(%r14) \n"); 93 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); 100 101 /* 102 * test load multiple with nonzero immediate offset 103 * load the last two values into r30 - r31. 104 * r27 - r29 should remain the same 105 */ 106 asm volatile( 107 " lmw %r30, 20(%r14) \n"); 108 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); 115 116 /* restore r27 - r31 */ 117 RESTORE_REGS(temp); 118 } 119 120 /* 121 * gcc is not happy if we modify r31 (the frame pointer) behind its back 122 * so we omit it 123 */ 124 static void __attribute__((optimize("-fomit-frame-pointer"))) test_stmw(void) 125 { 126 uint32_t result[7] = { 0 }; 127 int i; 128 129 SAVE_REGS(temp); 130 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 142 143 r14 = (HWord_t)&result; 144 145 /* store r27 - r31 */ 146 asm volatile( 147 " stmw %r27, 0(%r14) \n"); 148 149 printf("stmw => "); 150 for (i = 0; i < sizeof(result) / sizeof(result[0]); i++) 151 printf("%08x ", result[i]); 152 153 printf("\n"); 154 155 /* 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 159 */ 160 asm volatile( 161 " stmw %r30, 20(%r14) \n"); 162 163 printf("stmw => "); 164 for (i = 0; i < sizeof(result) / sizeof(result[0]); i++) 165 printf("%08x ", result[i]); 166 167 printf("\n"); 168 169 RESTORE_REGS(temp); 170 } 171 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 }, 178 }; 179 180 /* 181 * gcc is not happy if we modify r31 (the frame pointer) behind its back 182 * so we omit it 183 */ 184 int __attribute__((optimize("-fomit-frame-pointer"))) main(void) 185 { 186 test_func_t func; 187 int i = 0; 188 189 while ((func = all_tests[i].func)) { 190 (*func)(); 191 i++; 192 } 193 194 return 0; 195 } 196