invokeNative_thumb.s 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  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 argc
  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 = argc */
  35. cmp r5, #1 /* at least one argument required: exec_env */
  36. blt .Lreturn
  37. mov r6, #0 /* increased stack size */
  38. ldr r0, [r4] /* r0 = argv[0] = exec_env */
  39. add r4, r4, #4 /* r4 += 4 */
  40. cmp r5, #1
  41. beq .Lcall_func
  42. ldr r1, [r4] /* r1 = argv[1] */
  43. add r4, r4, #4
  44. cmp r5, #2
  45. beq .Lcall_func
  46. ldr r2, [r4] /* r2 = argv[2] */
  47. add r4, r4, #4
  48. cmp r5, #3
  49. beq .Lcall_func
  50. ldr r3, [r4] /* r3 = argv[3] */
  51. add r4, r4, #4
  52. cmp r5, #4
  53. beq .Lcall_func
  54. sub r5, r5, #4 /* argc -= 4, now we have r0 ~ r3 */
  55. /* Ensure address is 8 byte aligned */
  56. lsl r6, r5, #2 /* r6 = argc * 4 */
  57. mov r7, #7
  58. add r6, r6, r7 /* r6 = (r6 + 7) & ~7 */
  59. bic r6, r6, r7
  60. add r6, r6, #4 /* +4 because odd(5) registers are in stack */
  61. mov r7, sp
  62. sub r7, r7, r6 /* reserved stack space for left arguments */
  63. mov sp, r7
  64. mov lr, r2 /* save r2 */
  65. .Lloop_args: /* copy left arguments to stack */
  66. cmp r5, #0
  67. beq .Lcall_func1
  68. ldr r2, [r4]
  69. add r4, r4, #4
  70. str r2, [r7]
  71. add r7, r7, #4
  72. sub r5, r5, #1
  73. b .Lloop_args
  74. .Lcall_func1:
  75. mov r2, lr /* restore r2 */
  76. .Lcall_func:
  77. blx ip
  78. add sp, sp, r6 /* restore sp */
  79. .Lreturn:
  80. add sp, sp, #4 /* make sp 8 byte aligned */
  81. pop {r3}
  82. pop {r4, r5, r6, r7}
  83. mov lr, r3
  84. bx lr
  85. .cfi_endproc
  86. #if defined(__linux__) && defined(__ELF__)
  87. .section .note.GNU-stack,"",%progbits
  88. #endif