mirror of
https://github.com/ioacademy-jikim/debugging
synced 2025-06-15 03:46:28 +00:00
196 lines
4.6 KiB
C
196 lines
4.6 KiB
C
#include <stdio.h>
|
|
#include <stdint.h>
|
|
|
|
#ifndef __powerpc64__
|
|
typedef uint32_t HWord_t;
|
|
#else
|
|
typedef uint64_t HWord_t;
|
|
#endif
|
|
|
|
typedef void (*test_func_t)();
|
|
|
|
typedef struct test_table {
|
|
test_func_t func;
|
|
char *name;
|
|
} test_table_t;
|
|
|
|
static uint32_t values[] = {
|
|
0x6efbcfdf,
|
|
0xd16c2fd4,
|
|
0xf9dc1743,
|
|
0xa5aa0bd4,
|
|
0x6c8f0c14,
|
|
0x69a24188,
|
|
0x53b57f1b,
|
|
};
|
|
|
|
register HWord_t r27 asm("r27");
|
|
register HWord_t r28 asm("r28");
|
|
register HWord_t r29 asm("r29");
|
|
register HWord_t r30 asm("r30");
|
|
register HWord_t r31 asm("r31");
|
|
|
|
register HWord_t r14 asm("r14");
|
|
|
|
HWord_t temp[5];
|
|
|
|
#ifdef __powerpc64__
|
|
|
|
#define SAVE_REGS(addr) \
|
|
asm volatile( \
|
|
" std 27, 0(%0) \n" \
|
|
" std 28, 8(%0) \n" \
|
|
" std 29, 16(%0) \n" \
|
|
" std 30, 24(%0) \n" \
|
|
" std 31, 32(%0) \n" \
|
|
::"b"(addr))
|
|
|
|
#define RESTORE_REGS(addr) \
|
|
asm volatile( \
|
|
" ld 27, 0(%0) \n" \
|
|
" ld 28, 8(%0) \n" \
|
|
" ld 29, 16(%0) \n" \
|
|
" ld 30, 24(%0) \n" \
|
|
" ld 31, 32(%0) \n" \
|
|
::"b"(addr))
|
|
|
|
#else /* !__powerpc64__ */
|
|
|
|
#define SAVE_REGS(addr) \
|
|
asm volatile( \
|
|
" stw 27, 0(%0) \n" \
|
|
" stw 28, 4(%0) \n" \
|
|
" stw 29, 8(%0) \n" \
|
|
" stw 30, 12(%0) \n" \
|
|
" stw 31, 16(%0) \n" \
|
|
::"b"(addr))
|
|
|
|
#define RESTORE_REGS(addr) \
|
|
asm volatile( \
|
|
" lwz 27, 0(%0) \n" \
|
|
" lwz 28, 4(%0) \n" \
|
|
" lwz 29, 8(%0) \n" \
|
|
" lwz 30, 12(%0) \n" \
|
|
" lwz 31, 16(%0) \n" \
|
|
::"b"(addr))
|
|
|
|
#endif /* __powerpc64__ */
|
|
|
|
/*
|
|
* gcc is not happy if we modify r31 (the frame pointer) behind its back
|
|
* so we omit it
|
|
*/
|
|
static void __attribute__((optimize("-fomit-frame-pointer"))) test_lmw(void)
|
|
{
|
|
r14 = (HWord_t)values;
|
|
|
|
/* save r27 - r31 */
|
|
SAVE_REGS(temp);
|
|
|
|
/* load r27 - r31 */
|
|
asm volatile(
|
|
" lmw %r27, 0(%r14) \n");
|
|
|
|
#ifdef __powerpc64__
|
|
printf("lmw => %016lx %016lx %016lx %016lx %016lx\n",
|
|
#else
|
|
printf("lmw => %08x %08x %08x %08x %08x\n",
|
|
#endif
|
|
r27, r28, r29, r30, r31);
|
|
|
|
/*
|
|
* test load multiple with nonzero immediate offset
|
|
* load the last two values into r30 - r31.
|
|
* r27 - r29 should remain the same
|
|
*/
|
|
asm volatile(
|
|
" lmw %r30, 20(%r14) \n");
|
|
|
|
#ifdef __powerpc64__
|
|
printf("lmw => %016lx %016lx %016lx %016lx %016lx\n",
|
|
#else
|
|
printf("lmw => %08x %08x %08x %08x %08x\n",
|
|
#endif
|
|
r27, r28, r29, r30, r31);
|
|
|
|
/* restore r27 - r31 */
|
|
RESTORE_REGS(temp);
|
|
}
|
|
|
|
/*
|
|
* gcc is not happy if we modify r31 (the frame pointer) behind its back
|
|
* so we omit it
|
|
*/
|
|
static void __attribute__((optimize("-fomit-frame-pointer"))) test_stmw(void)
|
|
{
|
|
uint32_t result[7] = { 0 };
|
|
int i;
|
|
|
|
SAVE_REGS(temp);
|
|
|
|
#ifdef __powerpc64__
|
|
asm volatile(
|
|
" lwz 27, 0(%0) \n" \
|
|
" lwz 28, 4(%0) \n" \
|
|
" lwz 29, 8(%0) \n" \
|
|
" lwz 30, 12(%0) \n" \
|
|
" lwz 31, 16(%0) \n" \
|
|
::"b"(values));
|
|
#else
|
|
RESTORE_REGS(values);
|
|
#endif
|
|
|
|
r14 = (HWord_t)&result;
|
|
|
|
/* store r27 - r31 */
|
|
asm volatile(
|
|
" stmw %r27, 0(%r14) \n");
|
|
|
|
printf("stmw => ");
|
|
for (i = 0; i < sizeof(result) / sizeof(result[0]); i++)
|
|
printf("%08x ", result[i]);
|
|
|
|
printf("\n");
|
|
|
|
/*
|
|
* test store multiple with nonzero immediate offset
|
|
* store r30 - r31 into the last two places in the array
|
|
* the rest of the array should remain the same
|
|
*/
|
|
asm volatile(
|
|
" stmw %r30, 20(%r14) \n");
|
|
|
|
printf("stmw => ");
|
|
for (i = 0; i < sizeof(result) / sizeof(result[0]); i++)
|
|
printf("%08x ", result[i]);
|
|
|
|
printf("\n");
|
|
|
|
RESTORE_REGS(temp);
|
|
}
|
|
|
|
static test_table_t all_tests[] = {
|
|
{ &test_lmw,
|
|
"Test Load Multiple instruction" },
|
|
{ &test_stmw,
|
|
"Test Store Multiple instruction" },
|
|
{ NULL, NULL },
|
|
};
|
|
|
|
/*
|
|
* gcc is not happy if we modify r31 (the frame pointer) behind its back
|
|
* so we omit it
|
|
*/
|
|
int __attribute__((optimize("-fomit-frame-pointer"))) main(void)
|
|
{
|
|
test_func_t func;
|
|
int i = 0;
|
|
|
|
while ((func = all_tests[i].func)) {
|
|
(*func)();
|
|
i++;
|
|
}
|
|
|
|
return 0;
|
|
}
|