--- /dev/null
+#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 },
+};
+
+int main(void)
+{
+ test_func_t func;
+ int i = 0;
+
+ while ((func = all_tests[i].func)) {
+ (*func)();
+ i++;
+ }
+
+ return 0;
+}
jm_int_isa_2_07.stderr.exp jm_int_isa_2_07.stdout.exp jm_int_isa_2_07.vgtest \
test_isa_2_07_part2.stderr.exp test_isa_2_07_part2.stdout.exp test_isa_2_07_part2.vgtest \
test_tm.stderr.exp test_tm.stdout.exp test_tm.vgtest \
- test_touch_tm.stderr.exp test_touch_tm.stdout.exp test_touch_tm.vgtest
+ test_touch_tm.stderr.exp test_touch_tm.stdout.exp test_touch_tm.vgtest \
+ ldst_multiple.stderr.exp ldst_multiple.stdout.exp ldst_multiple.vgtest
check_PROGRAMS = \
allexec \
power6_mf_gpr test_isa_2_06_part1 test_isa_2_06_part2 \
test_isa_2_06_part3 test_dfp1 test_dfp2 test_dfp3 test_dfp4 \
test_dfp5 test_isa_2_07_part1 test_isa_2_07_part2 \
- test_tm test_touch_tm
+ test_tm test_touch_tm ldst_multiple
AM_CFLAGS += @FLAG_M64@
AM_CXXFLAGS += @FLAG_M64@