switch_arm32_gcc.h 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. /*
  2. * this is the internal transfer function.
  3. *
  4. * HISTORY
  5. * 14-Aug-06 File creation. Ported from Arm Thumb. Sylvain Baro
  6. * 3-Sep-06 Commented out saving of r1-r3 (r4 already commented out) as I
  7. * read that these do not need to be saved. Also added notes and
  8. * errors related to the frame pointer. Richard Tew.
  9. *
  10. * NOTES
  11. *
  12. * It is not possible to detect if fp is used or not, so the supplied
  13. * switch function needs to support it, so that you can remove it if
  14. * it does not apply to you.
  15. *
  16. * POSSIBLE ERRORS
  17. *
  18. * "fp cannot be used in asm here"
  19. *
  20. * - Try commenting out "fp" in REGS_TO_SAVE.
  21. *
  22. */
  23. #define STACK_REFPLUS 1
  24. #ifdef SLP_EVAL
  25. #define STACK_MAGIC 0
  26. #define REG_SP "sp"
  27. #define REG_SPSP "sp,sp"
  28. #ifdef __thumb__
  29. #define REG_FP "r7"
  30. #define REG_FPFP "r7,r7"
  31. #define REGS_TO_SAVE_GENERAL "r4", "r5", "r6", "r8", "r9", "r10", "r11", "lr"
  32. #else
  33. #define REG_FP "fp"
  34. #define REG_FPFP "fp,fp"
  35. #define REGS_TO_SAVE_GENERAL "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr"
  36. #endif
  37. #if defined(__SOFTFP__)
  38. #define REGS_TO_SAVE REGS_TO_SAVE_GENERAL
  39. #elif defined(__VFP_FP__)
  40. #define REGS_TO_SAVE REGS_TO_SAVE_GENERAL, "d8", "d9", "d10", "d11", \
  41. "d12", "d13", "d14", "d15"
  42. #elif defined(__MAVERICK__)
  43. #define REGS_TO_SAVE REGS_TO_SAVE_GENERAL, "mvf4", "mvf5", "mvf6", "mvf7", \
  44. "mvf8", "mvf9", "mvf10", "mvf11", \
  45. "mvf12", "mvf13", "mvf14", "mvf15"
  46. #else
  47. #define REGS_TO_SAVE REGS_TO_SAVE_GENERAL, "f4", "f5", "f6", "f7"
  48. #endif
  49. static int
  50. #ifdef __GNUC__
  51. __attribute__((optimize("no-omit-frame-pointer")))
  52. #endif
  53. slp_switch(void)
  54. {
  55. void *fp;
  56. register int *stackref, stsizediff;
  57. int result;
  58. __asm__ volatile ("" : : : REGS_TO_SAVE);
  59. __asm__ volatile ("mov r0," REG_FP "\n\tstr r0,%0" : "=m" (fp) : : "r0");
  60. __asm__ ("mov %0," REG_SP : "=r" (stackref));
  61. {
  62. SLP_SAVE_STATE(stackref, stsizediff);
  63. __asm__ volatile (
  64. "add " REG_SPSP ",%0\n"
  65. "add " REG_FPFP ",%0\n"
  66. :
  67. : "r" (stsizediff)
  68. );
  69. SLP_RESTORE_STATE();
  70. }
  71. __asm__ volatile ("ldr r0,%1\n\tmov " REG_FP ",r0\n\tmov %0, #0" : "=r" (result) : "m" (fp) : "r0");
  72. __asm__ volatile ("" : : : REGS_TO_SAVE);
  73. return result;
  74. }
  75. #endif