local-soft-fp.h 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. #include <stdlib.h>
  2. #include <soft-fp.h>
  3. #include <quad.h>
  4. /* Helpers for the Ots functions which receive long double arguments
  5. in two integer registers, and return values in $16+$17. */
  6. #define AXP_UNPACK_RAW_Q(X, val) \
  7. do { \
  8. union _FP_UNION_Q _flo; \
  9. _flo.longs.a = val##l; \
  10. _flo.longs.b = val##h; \
  11. FP_UNPACK_RAW_QP(X, &_flo); \
  12. } while (0)
  13. #define AXP_UNPACK_SEMIRAW_Q(X, val) \
  14. do { \
  15. union _FP_UNION_Q _flo; \
  16. _flo.longs.a = val##l; \
  17. _flo.longs.b = val##h; \
  18. FP_UNPACK_SEMIRAW_QP(X, &_flo); \
  19. } while (0)
  20. #define AXP_UNPACK_Q(X, val) \
  21. do { \
  22. AXP_UNPACK_RAW_Q(X, val); \
  23. _FP_UNPACK_CANONICAL(Q, 2, X); \
  24. } while (0)
  25. #define AXP_PACK_RAW_Q(val, X) FP_PACK_RAW_QP(&val##_flo, X)
  26. #define AXP_PACK_SEMIRAW_Q(val, X) \
  27. do { \
  28. _FP_PACK_SEMIRAW(Q, 2, X); \
  29. AXP_PACK_RAW_Q(val, X); \
  30. } while (0)
  31. #define AXP_PACK_Q(val, X) \
  32. do { \
  33. _FP_PACK_CANONICAL(Q, 2, X); \
  34. AXP_PACK_RAW_Q(val, X); \
  35. } while (0)
  36. #define AXP_DECL_RETURN_Q(X) union _FP_UNION_Q X##_flo
  37. /* ??? We don't have a real way to tell the compiler that we're wanting
  38. to return values in $16+$17. Instead use a volatile asm to make sure
  39. that the values are live, and just hope that nothing kills the values
  40. in between here and the end of the function. */
  41. #define AXP_RETURN_Q(X) \
  42. do { \
  43. register long r16 __asm__("16") = X##_flo.longs.a; \
  44. register long r17 __asm__("17") = X##_flo.longs.b; \
  45. asm volatile ("" : : "r"(r16), "r"(r17)); \
  46. } while (0)