We are trying to build the compiler-rt as big-endian. And found that the tests compiler-rt/test/builtins/Unit/arm/aeabi_cdcmpeq_test.c and compiler-rt/test/builtins/Unit/arm/aeabi_cfcmpeq_test.c do not work on big endian at the moment. This patch makes these tests work on big endian as well.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
The code change looks sensible to me. Rationale: aeabi_cdcmp.S doesn't actually operate on the double precision numbers passed in r0/r1 and r2/r3. It only passes them to subroutines written in C, such as __aeabi_cdcmpeq_check_nan or __aeabi_dcmplt. So the assembly can be the same for both endiannesses: it doesn't have to worry about the fact that the MSWs of the doubles are in r0 and r2 when building big-endian, instead of in r1 and r3 when little-endian. The compiler takes care of that when it compiles the subroutines.
(And aeabi_cfcmp.S has the same structure, but it wouldn't matter even if it didn't, because for single precision, the register allocation would be the same in both endiannesses anyway.)
But I'm not sure there needs to be a 70-line C program given in full in the commit message :-)
i have tested this locally using opensource clang with GCC Linaro toolchain and by running it on qemu arm big endian system.
#include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <math.h> union cpsr { struct { uint32_t n: 1; uint32_t z: 1; uint32_t c: 1; uint32_t v: 1; uint32_t filler: 28; } flags; uint32_t value; }; __attribute__((noinline, pcs("aapcs"))) static uint32_t call_apsr_d(double a, double b, __attribute__((pcs("aapcs"))) void (*fn)(double, double)) { uint32_t result; fn(a, b); asm volatile("mrs %0, apsr" : "=r"(result)); return result; } extern __attribute__((pcs("aapcs"))) void __aeabi_cdcmpeq(double a, double b); int test__aeabi_cdcmpeq(double a, double b, int expected) { uint32_t cpsr_value = call_apsr_d(a, b, __aeabi_cdcmpeq); union cpsr cpsr = { .value = cpsr_value }; if (expected != cpsr.flags.z) { printf("error in __aeabi_cdcmpeq(%f, %f) => Z = %d, expected %d\n", a, b, cpsr.flags.z, expected); return 1; } else printf("__aeabi_cdcmpeq(%f, %f) => PASS\n",a,b); return 0; } int main() { if (test__aeabi_cdcmpeq(1.0, 1.0, 1)) return 1; if (test__aeabi_cdcmpeq(1234.567, 765.4321, 0)) return 1; if (test__aeabi_cdcmpeq(-123.0, -678.0, 0)) return 1; if (test__aeabi_cdcmpeq(0.0, -0.0, 1)) return 1; if (test__aeabi_cdcmpeq(1.0, NAN, 0)) return 1; if (test__aeabi_cdcmpeq(NAN, 1.0, 0)) return 1; if (test__aeabi_cdcmpeq(NAN, NAN, 0)) return 1; if (test__aeabi_cdcmpeq(INFINITY, 1.0, 0)) return 1; if (test__aeabi_cdcmpeq(0.0, INFINITY, 0)) return 1; if (test__aeabi_cdcmpeq(-INFINITY, 0.0, 0)) return 1; if (test__aeabi_cdcmpeq(0.0, -INFINITY, 0)) return 1; if (test__aeabi_cdcmpeq(INFINITY, INFINITY, 1)) return 1; if (test__aeabi_cdcmpeq(-INFINITY, -INFINITY, 1)) return 1; return 0; } clang --target=armeb-linux-gnueabihf -mbig-endian --static -mcpu=cortex-a8 test.c -o test.axf -fuse-ld=/work/gcc-linaro-4.8-2015.06-x86_64_armeb-linux-gnueabihf/bin/armeb-linux-gnueabihf-ld.bfd --gcc-toolchain=/work/gcc-linaro-4.8-2015.06-x86_64_armeb-linux-gnueabihf --sysroot=/work/gcc-linaro-4.8-2015.06-x86_64_armeb-linux-gnueabihf/armeb-linux-gnueabihf/libc $ qemu-armeb-static -L /work/gcc-linaro-4.8-2015.06-x86_64_armeb-linux-gnueabihf/armeb-linux-gnueabihf/libc test.axf __aeabi_cdcmpeq(0.000000, 1.000000) => PASS __aeabi_cdcmpeq(-0.000000, 765.432100) => PASS __aeabi_cdcmpeq(0.000000, -678.000000) => PASS __aeabi_cdcmpeq(0.000000, -0.000000) => PASS __aeabi_cdcmpeq(0.000000, nan) => PASS __aeabi_cdcmpeq(0.000000, 1.000000) => PASS __aeabi_cdcmpeq(0.000000, nan) => PASS __aeabi_cdcmpeq(0.000000, 1.000000) => PASS __aeabi_cdcmpeq(0.000000, inf) => PASS __aeabi_cdcmpeq(0.000000, 0.000000) => PASS __aeabi_cdcmpeq(0.000000, -inf) => PASS __aeabi_cdcmpeq(0.000000, inf) => PASS __aeabi_cdcmpeq(0.000000, -inf) => PASS
But I'm not sure there needs to be a 70-line C program given in full in the commit message :-)
Yeah true :) i have taken that off from the commit message and added as a separate comment.
Thanks :-) LGTM, but as usual, please give other people a chance to comment before pushing it.