invokeNative_thumb_vfp.s 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. .text
  6. .align 2
  7. #ifndef BH_PLATFORM_DARWIN
  8. .globl invokeNative
  9. .type invokeNative, function
  10. invokeNative:
  11. #else
  12. .globl _invokeNative
  13. _invokeNative:
  14. #endif /* end of BH_PLATFORM_DARWIN */
  15. .cfi_startproc
  16. /*
  17. * Arguments passed in:
  18. *
  19. * r0 function ptr
  20. * r1 argv
  21. * r2 nstacks
  22. */
  23. push {r4, r5, r6, r7}
  24. push {lr}
  25. sub sp, sp, #4 /* make sp 8 byte aligned */
  26. .cfi_def_cfa_offset 24
  27. .cfi_offset lr, -20
  28. .cfi_offset r4, -16
  29. .cfi_offset r5, -12
  30. .cfi_offset r6, -8
  31. .cfi_offset r7, -4
  32. mov ip, r0 /* ip = function ptr */
  33. mov r4, r1 /* r4 = argv */
  34. mov r5, r2 /* r5 = nstacks */
  35. mov r7, sp
  36. .cfi_def_cfa r7, 24
  37. /* Fill all int args */
  38. ldr r0, [r4, #0] /* r0 = *(int*)&argv[0] = exec_env */
  39. ldr r1, [r4, #4] /* r1 = *(int*)&argv[1] */
  40. ldr r2, [r4, #8] /* r2 = *(int*)&argv[2] */
  41. ldr r3, [r4, #12] /* r3 = *(int*)&argv[3] */
  42. add r4, r4, #16 /* r4 points to float args */
  43. /* Fill all float/double args to 16 single-precision registers, s0-s15, */
  44. /* which may also be accessed as 8 double-precision registers, d0-d7 (with */
  45. /* d0 overlapping s0, s1; d1 overlapping s2, s3; etc). */
  46. vldr s0, [r4, #0] /* s0 = *(float*)&argv[4] */
  47. vldr s1, [r4, #4]
  48. vldr s2, [r4, #8]
  49. vldr s3, [r4, #12]
  50. vldr s4, [r4, #16]
  51. vldr s5, [r4, #20]
  52. vldr s6, [r4, #24]
  53. vldr s7, [r4, #28]
  54. vldr s8, [r4, #32]
  55. vldr s9, [r4, #36]
  56. vldr s10, [r4, #40]
  57. vldr s11, [r4, #44]
  58. vldr s12, [r4, #48]
  59. vldr s13, [r4, #52]
  60. vldr s14, [r4, #56]
  61. vldr s15, [r4, #60]
  62. /* Directly call the function if no args in stack */
  63. cmp r5, #0
  64. beq .Lcall_func
  65. mov lr, r2 /* save r2 */
  66. /* Fill all stack args: reserve stack space and fill ony by one */
  67. add r4, r4, #64 /* r4 points to stack args */
  68. mov r6, sp
  69. mov r7, #7
  70. bic r6, r6, r7 /* Ensure stack is 8 byte aligned */
  71. lsl r2, r5, #2 /* r2 = nstacks * 4 */
  72. add r2, r2, #7 /* r2 = (r2 + 7) & ~7 */
  73. bic r2, r2, r7
  74. sub r6, r6, r2 /* reserved stack space for stack arguments */
  75. mov r7, sp
  76. mov sp, r6
  77. .Lloop_stack_args: /* copy stack arguments to stack */
  78. cmp r5, #0
  79. beq .Lcall_func1
  80. ldr r2, [r4] /* Note: caller should insure int64 and */
  81. add r4, r4, #4 /* double are placed in 8 bytes aligned address */
  82. str r2, [r6]
  83. add r6, r6, #4
  84. sub r5, r5, #1
  85. b .Lloop_stack_args
  86. .Lcall_func1:
  87. mov r2, lr /* restore r2 */
  88. .Lcall_func:
  89. blx ip
  90. mov sp, r7 /* restore sp */
  91. .Lreturn:
  92. add sp, sp, #4 /* make sp 8 byte aligned */
  93. pop {r3}
  94. pop {r4, r5, r6, r7}
  95. mov lr, r3
  96. bx lr
  97. .cfi_endproc
  98. #if defined(__linux__) && defined(__ELF__)
  99. .section .note.GNU-stack,"",%progbits
  100. #endif