tst-gnu2-tls2.h 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /* Test TLSDESC relocation. ARM version.
  2. Copyright (C) 2024-2026 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. The GNU C Library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with the GNU C Library; if not, see
  14. <https://www.gnu.org/licenses/>. */
  15. #include <config.h>
  16. #include <sys/auxv.h>
  17. #include <string.h>
  18. #include <stdlib.h>
  19. #include <endian.h>
  20. #ifndef __SOFTFP__
  21. # ifdef HAVE_ARM_PCS_VFP_D32
  22. # define SAVE_VFP_D32 \
  23. asm volatile ("vldr d16,=17" : : : "d16"); \
  24. asm volatile ("vldr d17,=18" : : : "d17"); \
  25. asm volatile ("vldr d18,=19" : : : "d18"); \
  26. asm volatile ("vldr d19,=20" : : : "d19"); \
  27. asm volatile ("vldr d20,=21" : : : "d20"); \
  28. asm volatile ("vldr d21,=22" : : : "d21"); \
  29. asm volatile ("vldr d22,=23" : : : "d22"); \
  30. asm volatile ("vldr d23,=24" : : : "d23"); \
  31. asm volatile ("vldr d24,=25" : : : "d24"); \
  32. asm volatile ("vldr d25,=26" : : : "d25"); \
  33. asm volatile ("vldr d26,=27" : : : "d26"); \
  34. asm volatile ("vldr d27,=28" : : : "d27"); \
  35. asm volatile ("vldr d28,=29" : : : "d28"); \
  36. asm volatile ("vldr d29,=30" : : : "d29"); \
  37. asm volatile ("vldr d30,=31" : : : "d30"); \
  38. asm volatile ("vldr d31,=32" : : : "d31");
  39. # else
  40. # define SAVE_VFP_D32
  41. # endif
  42. # define INIT_TLSDESC_CALL() \
  43. unsigned long hwcap = getauxval (AT_HWCAP)
  44. /* Set each vector register to a value from 1 to 32 before the TLS access,
  45. dump to memory after TLS access, and compare with the expected values. */
  46. # define BEFORE_TLSDESC_CALL() \
  47. if (hwcap & HWCAP_ARM_VFP) \
  48. { \
  49. asm volatile ("vldr d0,=1" : : : "d0"); \
  50. asm volatile ("vldr d1,=2" : : : "d1"); \
  51. asm volatile ("vldr d2,=3" : : : "d1"); \
  52. asm volatile ("vldr d3,=4" : : : "d3"); \
  53. asm volatile ("vldr d4,=5" : : : "d4"); \
  54. asm volatile ("vldr d5,=6" : : : "d5"); \
  55. asm volatile ("vldr d6,=7" : : : "d6"); \
  56. asm volatile ("vldr d7,=8" : : : "d7"); \
  57. asm volatile ("vldr d8,=9" : : : "d8"); \
  58. asm volatile ("vldr d9,=10" : : : "d9"); \
  59. asm volatile ("vldr d10,=11" : : : "d10"); \
  60. asm volatile ("vldr d11,=12" : : : "d11"); \
  61. asm volatile ("vldr d12,=13" : : : "d12"); \
  62. asm volatile ("vldr d13,=14" : : : "d13"); \
  63. asm volatile ("vldr d14,=15" : : : "d14"); \
  64. asm volatile ("vldr d15,=16" : : : "d15"); \
  65. } \
  66. if (hwcap & HWCAP_ARM_VFPD32) \
  67. { \
  68. SAVE_VFP_D32 \
  69. }
  70. # define VFP_STACK_REQ (16*8)
  71. # if __BYTE_ORDER == __BIG_ENDIAN
  72. # define DISP 7
  73. # else
  74. # define DISP 0
  75. # endif
  76. # ifdef HAVE_ARM_PCS_VFP_D32
  77. # define CHECK_VFP_D32 \
  78. char vfp[VFP_STACK_REQ]; \
  79. asm volatile ("vstmia %0, {d16-d31}\n" \
  80. : \
  81. : "r" (vfp) \
  82. : "memory"); \
  83. \
  84. char expected[VFP_STACK_REQ] = { 0 }; \
  85. for (int i = 0; i < 16; ++i) \
  86. expected[i * 8 + DISP] = i + 17; \
  87. \
  88. if (memcmp (vfp, expected, VFP_STACK_REQ) != 0) \
  89. abort ();
  90. # else
  91. # define CHECK_VFP_D32
  92. # endif
  93. # define AFTER_TLSDESC_CALL() \
  94. if (hwcap & HWCAP_ARM_VFP) \
  95. { \
  96. char vfp[VFP_STACK_REQ]; \
  97. asm volatile ("vstmia %0, {d0-d15}\n" \
  98. : \
  99. : "r" (vfp) \
  100. : "memory"); \
  101. \
  102. char expected[VFP_STACK_REQ] = { 0 }; \
  103. for (int i = 0; i < 16; ++i) \
  104. expected[i * 8 + DISP] = i + 1; \
  105. \
  106. if (memcmp (vfp, expected, VFP_STACK_REQ) != 0) \
  107. abort (); \
  108. } \
  109. if (hwcap & HWCAP_ARM_VFPD32) \
  110. { \
  111. CHECK_VFP_D32 \
  112. }
  113. #endif /* __SOFTFP__ */
  114. #include_next <tst-gnu2-tls2.h>