sync-ops.h 3.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. //===-- sync-ops.h - --===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file implements outline macros for the __sync_fetch_and_*
  10. // operations. Different instantiations will generate appropriate assembly for
  11. // ARM and Thumb-2 versions of the functions.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #include "../assembly.h"
  15. #if __ARM_ARCH >= 7
  16. #define DMB dmb
  17. #elif __ARM_ARCH >= 6
  18. #define DMB mcr p15, #0, r0, c7, c10, #5
  19. #else
  20. #error DMB is only supported on ARMv6+
  21. #endif
  22. #define SYNC_OP_4(op) \
  23. .p2align 2; \
  24. .syntax unified; \
  25. DEFINE_COMPILERRT_FUNCTION(__sync_fetch_and_##op) \
  26. DMB; \
  27. mov r12, r0; \
  28. LOCAL_LABEL(tryatomic_##op) : ldrex r0, [r12]; \
  29. op(r2, r0, r1); \
  30. strex r3, r2, [r12]; \
  31. cmp r3, #0; \
  32. bne LOCAL_LABEL(tryatomic_##op); \
  33. DMB; \
  34. bx lr
  35. #define SYNC_OP_8(op) \
  36. .p2align 2; \
  37. .syntax unified; \
  38. DEFINE_COMPILERRT_FUNCTION(__sync_fetch_and_##op) \
  39. push {r4, r5, r6, lr}; \
  40. DMB; \
  41. mov r12, r0; \
  42. LOCAL_LABEL(tryatomic_##op) : ldrexd r0, r1, [r12]; \
  43. op(r4, r5, r0, r1, r2, r3); \
  44. strexd r6, r4, r5, [r12]; \
  45. cmp r6, #0; \
  46. bne LOCAL_LABEL(tryatomic_##op); \
  47. DMB; \
  48. pop { r4, r5, r6, pc }
  49. #define MINMAX_4(rD, rN, rM, cmp_kind) \
  50. cmp rN, rM; \
  51. mov rD, rM; \
  52. it cmp_kind; \
  53. mov##cmp_kind rD, rN
  54. #define MINMAX_8(rD_LO, rD_HI, rN_LO, rN_HI, rM_LO, rM_HI, cmp_kind) \
  55. cmp rN_LO, rM_LO; \
  56. sbcs rN_HI, rM_HI; \
  57. mov rD_LO, rM_LO; \
  58. mov rD_HI, rM_HI; \
  59. itt cmp_kind; \
  60. mov##cmp_kind rD_LO, rN_LO; \
  61. mov##cmp_kind rD_HI, rN_HI