Home | History | Annotate | Download | only in ppc32
      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