diff --git a/libcxxabi/test/vendor/ibm/vec_reg_restore.pass.cpp b/libcxxabi/test/vendor/ibm/vec_reg_restore.pass.cpp --- a/libcxxabi/test/vendor/ibm/vec_reg_restore.pass.cpp +++ b/libcxxabi/test/vendor/ibm/vec_reg_restore.pass.cpp @@ -23,8 +23,9 @@ // VRs which should be 16-byte aligned and restores them correctly based on // the number specified in the traceback table. To simplify, only the 2 high // numbered VRs are checked. Because PowerPC CPUs do not have instructions to -// assign a literal value to a VR directly until Power10, the value is -// assigned to a GR and then from the GR to a VR in the code. +// assign a literal value to a VR directly until Power10, and the instructions +// to assign to a VR from a GR and vice versa are not available until Power8, +// a memory location is used to load into or store from a VR. // #include @@ -41,59 +42,76 @@ int __attribute__((noinline)) test(int i) { // Clobber VR63 and VR62 in the function body. // Set VR63=100. + long long buff[2]; asm volatile("li 30, 100\n\t" - "mtvsrd 63, 30\n\t" - : + "std 30, 0(%[b])\n\t" + "li 30, 0\n\t" + "std 30, 8(%[b])\n\t" + "lxvd2x 63, %[b], 30" : + : [b] "r"(buff) : "v31", "r30"); // Set VR62=200. asm volatile("li 29, 200\n\t" - "mtvsrd 62, 29\n\t" - : + "std 29, 0(%[b])\n\t" + "li 29, 0\n\t" + "std 29, 8(%[b])\n\t" + "lxvd2x 62, %[b], 29" : + : [b] "r"(buff) : "v30", "r29"); return test2(i); } // Return the value of VR63 in 'output'. -#define getFirstValue(output) \ - asm volatile( "mfvsrd 4, 63\n\t" \ - "std 4, %[d]" \ - : [d] "=rm"(output) \ - : \ - : ) +#define getFirstValue(output, buff) \ + asm volatile("li 30, 0\n\t" \ + "stxvd2x 63, %[b], 30\n\t" \ + "ld 30, 0(%[b])\n\t" \ + "std 30, %[d]" \ + : [d] "=rm"(output) \ + : [b] "r"(buff) \ + : "r30" ) // Return the value of VR62 in 'output'. -#define getSecondValue(output) \ - asm volatile( "mfvsrd 4, 62\n\t" \ - "std 4, %[d]" \ - : [d] "=rm"(output) \ - : \ - : ) - +#define getSecondValue(output, buff) \ + asm volatile("li 29, 0\n\t" \ + "stxvd2x 62, %[b], 29\n\t" \ + "ld 29, 0(%[b])\n\t" \ + "std 29, %[d]" \ + : [d] "=rm"(output) \ + : [b] "r"(buff) \ + : "r29" ) int main(int, char**) { + long long buff[2]; // Set VR63=1. asm volatile("li 30, 1\n\t" - "mtvsrd 63, 30\n\t" - : + "std 30, 0(%[b])\n\t" + "li 30, 0\n\t" + "std 30, 8(%[b])\n\t" + "lxvd2x 63, %[b], 30" : + : [b] "r"(buff) : "v31", "r30"); - // Set VR62=1. + // Set VR62=2. asm volatile("li 29, 2\n\t" - "mtvsrd 62, 29\n\t" - : + "std 29, 0(%[b])\n\t" + "li 29, 0\n\t" + "std 29, 8(%[b])\n\t" + "lxvd2x 62, %[b], 29" : + : [b] "r"(buff) : "v30", "r29"); long long old; long long old2; - getFirstValue(old); - getSecondValue(old2); + getFirstValue(old, buff); + getSecondValue(old2, buff); try { test(4); } catch (int num) { long long new_value; long long new_value2; - getFirstValue(new_value); - getSecondValue(new_value2); + getFirstValue(new_value, buff); + getSecondValue(new_value2, buff); // If the unwinder restores VR63 and VR62 correctly, they should contain // 1 and 2 respectively instead of 100 and 200. assert(old == new_value && old2 == new_value2);