You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

169 lines
4.3KB

  1. /****************************************************************************
  2. * Assembly testing and benchmarking tool
  3. * Copyright (c) 2015 Martin Storsjo
  4. * Copyright (c) 2015 Janne Grunau
  5. *
  6. * This file is part of Libav.
  7. *
  8. * Libav is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * Libav is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
  21. *****************************************************************************/
  22. #include "libavutil/arm/asm.S"
  23. /* override fpu so that NEON instructions are rejected */
  24. #if HAVE_VFP
  25. FPU .fpu vfp
  26. ELF .eabi_attribute 10, 0 @ suppress Tag_FP_arch
  27. #endif
  28. const register_init, align=3
  29. .quad 0x21f86d66c8ca00ce
  30. .quad 0x75b6ba21077c48ad
  31. .quad 0xed56bb2dcb3c7736
  32. .quad 0x8bda43d3fd1a7e06
  33. .quad 0xb64a9c9e5d318408
  34. .quad 0xdf9a54b303f1d3a3
  35. .quad 0x4a75479abd64e097
  36. .quad 0x249214109d5d1c88
  37. endconst
  38. const error_message_fpscr
  39. .asciz "failed to preserve register FPSCR, changed bits: %x"
  40. error_message_gpr:
  41. .asciz "failed to preserve register r%d"
  42. error_message_vfp:
  43. .asciz "failed to preserve register d%d"
  44. endconst
  45. @ max number of args used by any asm function.
  46. #define MAX_ARGS 15
  47. #define ARG_STACK 4*(MAX_ARGS - 4)
  48. @ align the used stack space to 8 to preserve the stack alignment
  49. #define ARG_STACK_A (((ARG_STACK + pushed + 7) & ~7) - pushed)
  50. .macro clobbercheck variant
  51. .equ pushed, 4*9
  52. function checkasm_checked_call_\variant, export=1
  53. push {r4-r11, lr}
  54. .ifc \variant, vfp
  55. vpush {d8-d15}
  56. fmrx r4, FPSCR
  57. push {r4}
  58. .equ pushed, pushed + 16*4 + 4
  59. .endif
  60. movrel r12, register_init
  61. .ifc \variant, vfp
  62. vldm r12, {d8-d15}
  63. .endif
  64. ldm r12, {r4-r11}
  65. sub sp, sp, #ARG_STACK_A
  66. .equ pos, 0
  67. .rept MAX_ARGS-4
  68. ldr r12, [sp, #ARG_STACK_A + pushed + 8 + pos]
  69. str r12, [sp, #pos]
  70. .equ pos, pos + 4
  71. .endr
  72. mov r12, r0
  73. mov r0, r2
  74. mov r1, r3
  75. ldrd r2, r3, [sp, #ARG_STACK_A + pushed]
  76. blx r12
  77. add sp, sp, #ARG_STACK_A
  78. push {r0, r1}
  79. movrel r12, register_init
  80. .ifc \variant, vfp
  81. .macro check_reg_vfp, dreg, offset
  82. ldrd r2, r3, [r12, #8 * (\offset)]
  83. vmov r0, lr, \dreg
  84. eor r2, r2, r0
  85. eor r3, r3, lr
  86. orrs r2, r2, r3
  87. bne 4f
  88. .endm
  89. .irp n, 8, 9, 10, 11, 12, 13, 14, 15
  90. @ keep track of the checked double/SIMD register
  91. mov r1, #\n
  92. check_reg_vfp d\n, \n-8
  93. .endr
  94. .purgem check_reg_vfp
  95. fmrx r1, FPSCR
  96. ldr r3, [sp, #8]
  97. eor r1, r1, r3
  98. @ Ignore changes in bits 0-4 and 7
  99. bic r1, r1, #0x9f
  100. @ Ignore changes in the topmost 5 bits
  101. bics r1, r1, #0xf8000000
  102. bne 3f
  103. .endif
  104. @ keep track of the checked GPR
  105. mov r1, #4
  106. .macro check_reg reg1, reg2=
  107. ldrd r2, r3, [r12], #8
  108. eors r2, r2, \reg1
  109. bne 2f
  110. add r1, r1, #1
  111. .ifnb \reg2
  112. eors r3, r3, \reg2
  113. bne 2f
  114. .endif
  115. add r1, r1, #1
  116. .endm
  117. check_reg r4, r5
  118. check_reg r6, r7
  119. @ r9 is a volatile register in the ios ABI
  120. #ifdef __APPLE__
  121. check_reg r8
  122. #else
  123. check_reg r8, r9
  124. #endif
  125. check_reg r10, r11
  126. .purgem check_reg
  127. b 0f
  128. 4:
  129. movrel r0, error_message_vfp
  130. b 1f
  131. 3:
  132. movrel r0, error_message_fpscr
  133. b 1f
  134. 2:
  135. movrel r0, error_message_gpr
  136. 1:
  137. blx X(checkasm_fail_func)
  138. 0:
  139. pop {r0, r1}
  140. .ifc \variant, vfp
  141. pop {r2}
  142. fmxr FPSCR, r2
  143. vpop {d8-d15}
  144. .endif
  145. pop {r4-r11, pc}
  146. endfunc
  147. .endm
  148. #if HAVE_VFP || HAVE_NEON
  149. clobbercheck vfp
  150. #endif
  151. clobbercheck novfp