e500_expression.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /* e500 expression macros, for PSIM, the PowerPC simulator.
  2. Copyright 2003-2022 Free Software Foundation, Inc.
  3. Contributed by Red Hat Inc; developed under contract from Motorola.
  4. Written by matthew green <mrg@redhat.com>.
  5. This file is part of GDB.
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 3 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  16. /* e500 register dance */
  17. #define EV_SET_REG4(sh, sl, h0, h1, h2, h3) do { \
  18. (sh) = (((h0) & 0xffff) << 16) | ((h1) & 0xffff); \
  19. (sl) = (((h2) & 0xffff) << 16) | ((h3) & 0xffff); \
  20. } while (0)
  21. #define EV_SET_REG4_ACC(sh, sl, h0, h1, h2, h3) do { \
  22. (sh) = (((h0) & 0xffff) << 16) | ((h1) & 0xffff); \
  23. (sl) = (((h2) & 0xffff) << 16) | ((h3) & 0xffff); \
  24. ACC = ((uint64_t)(sh) << 32) | (sl & 0xffffffff); \
  25. } while (0)
  26. #define EV_SET_REG2(sh, sl, dh, dl) do { \
  27. (sh) = (dh) & 0xffffffff; \
  28. (sl) = (dl) & 0xffffffff; \
  29. } while (0)
  30. #define EV_SET_REG2_ACC(sh, sl, dh, dl) do { \
  31. (sh) = (dh) & 0xffffffff; \
  32. (sl) = (dl) & 0xffffffff; \
  33. ACC = ((uint64_t)(sh) << 32) | ((sl) & 0xffffffff); \
  34. } while (0)
  35. #define EV_SET_REG1(sh, sl, d) do { \
  36. (sh) = ((uint64_t)(d) >> 32) & 0xffffffff; \
  37. (sl) = (d) & 0xffffffff; \
  38. } while (0)
  39. #define EV_SET_REG1_ACC(sh, sl, d) do { \
  40. (sh) = ((uint64_t)(d) >> 32) & 0xffffffff; \
  41. (sl) = (d) & 0xffffffff; \
  42. ACC = (d); \
  43. } while (0)
  44. #define EV_SET_REG(s, d) do { \
  45. (s) = (d) & 0xffffffff; \
  46. } while (0)
  47. /* get the low or high half word of a word */
  48. #define EV_LOHALF(x) ((uint32_t)(x) & 0xffff)
  49. #define EV_HIHALF(x) (((uint32_t)(x) >> 16) & 0xffff)
  50. /* partially visible accumulator accessors */
  51. #define EV_SET_ACC(rh, rl) \
  52. ACC = ((uint64_t)(rh) << 32) | ((rl) & 0xffffffff)
  53. #define EV_ACCLOW (ACC & 0xffffffff)
  54. #define EV_ACCHIGH ((ACC >> 32) & 0xffffffff)
  55. /* bit manipulation macros needed for e500 SPE */
  56. #define EV_BITREVERSE16(x) \
  57. (((x) & 0x0001) << 15) \
  58. | (((x) & 0x0002) << 13) \
  59. | (((x) & 0x0004) << 11) \
  60. | (((x) & 0x0008) << 9) \
  61. | (((x) & 0x0010) << 7) \
  62. | (((x) & 0x0020) << 5) \
  63. | (((x) & 0x0040) << 3) \
  64. | (((x) & 0x0080) << 1) \
  65. | (((x) & 0x0100) >> 1) \
  66. | (((x) & 0x0200) >> 3) \
  67. | (((x) & 0x0400) >> 5) \
  68. | (((x) & 0x0800) >> 7) \
  69. | (((x) & 0x1000) >> 9) \
  70. | (((x) & 0x2000) >> 11) \
  71. | (((x) & 0x4000) >> 13) \
  72. | (((x) & 0x8000) >> 15)
  73. /* saturation helpers */
  74. #define EV_MUL16_SSF(a,b) ((int64_t)((int32_t)(int16_t)(a) * (int32_t)(int16_t)(b)) << 1)
  75. /* this one loses the top sign bit; be careful */
  76. #define EV_MUL32_SSF(a,b) (((int64_t)(int32_t)(a) * (int64_t)(int32_t)(b)) << 1)
  77. #define EV_SAT_P_S32(x) ((((int64_t)(x)) < -0x80000000LL) || (((int64_t)(x)) > 0x7fffffffLL))
  78. #define EV_SAT_P_U32(x) ((((int64_t)(x)) < -0LL) || (((int64_t)(x)) > 0xffffffffLL))
  79. #define EV_SATURATE(flag, sat_val, val) \
  80. ((flag) ? (sat_val) : (val))
  81. #define EV_SATURATE_ACC(flag, sign, negative_sat_val, positive_sat_val, val) \
  82. ((flag) ? ((((sign) >> 63) & 1) ? (negative_sat_val) : (positive_sat_val)) : (val))
  83. /* SPEFSCR handling. */
  84. /* These bits must be clear. */
  85. #define EV_SPEFSCR_MASK (BIT(40) | BIT(41) | spefscr_mode | BIT(56))
  86. /* The Inexact and Divide by zero sticky bits are based on others. */
  87. #define EV_SET_SPEFSCR(bits) do { \
  88. int finxs = (bits) & (spefscr_fgh|spefscr_fxh|spefscr_fg|spefscr_fx); \
  89. int fdbzs = (bits) & (spefscr_fdbzh|spefscr_fdbz); \
  90. SPREG(spr_spefscr) = ((bits) & ~EV_SPEFSCR_MASK) | \
  91. (finxs ? spefscr_finxs : 0) | \
  92. (fdbzs ? spefscr_fdbzs : 0); \
  93. } while (0)
  94. #define EV_SET_SPEFSCR_BITS(s) \
  95. EV_SET_SPEFSCR(SPREG(spr_spefscr) | (s))
  96. #define EV_SET_SPEFSCR_OV(l,h) do { \
  97. uint32_t _sPefScR = SPREG(spr_spefscr); \
  98. if (l) \
  99. _sPefScR |= spefscr_ov | spefscr_sov; \
  100. else \
  101. _sPefScR &= ~spefscr_ov; \
  102. if (h) \
  103. _sPefScR |= spefscr_ovh | spefscr_sovh; \
  104. else \
  105. _sPefScR &= ~spefscr_ovh; \
  106. EV_SET_SPEFSCR(_sPefScR); \
  107. } while (0)
  108. /* SPE floating point helpers. */
  109. #define EV_PMAX 0x7f7fffff
  110. #define EV_NMAX 0xff7fffff
  111. #define EV_PMIN 0x00800001
  112. #define EV_NMIN 0x80800001
  113. #define EV_IS_INFDENORMNAN(x) \
  114. (sim_fpu_is_infinity(x) || sim_fpu_is_denorm(x) || sim_fpu_is_nan(x))
  115. /* These aren't used (yet?) For now, SPU is always enabled.
  116. Would be nice if they were generated by igen for e500. */
  117. #define SPU_BEGIN \
  118. { \
  119. if (MSR & msr_e500_spu_enable) { \
  120. #define SPU_END \
  121. } else { \
  122. /* FIXME: raise SPU unavailable. */ \
  123. } \
  124. }
  125. /* These are also not yet used. */
  126. #define SPU_FP_BEGIN \
  127. {
  128. #define SPU_FP_END \
  129. { \
  130. unsigned s = SPEFSCR; \
  131. /* Check SPEFSCR; raise exceptions if any required. */ \
  132. if (((spefscr_finxe || spefscr_finve) \
  133. && (s & (spefscr_finvh|spefscr_finv))) \
  134. || ((spefscr_finxe || spefscr_fdbze) \
  135. && (s & (spefscr_fdbzh|spefscr_fdbz))) \
  136. || ((spefscr_finxe || spefscr_funfe) \
  137. && (s & (spefscr_funfh|spefscr_funf))) \
  138. || ((spefscr_finxe || spefscr_fovfe) \
  139. && (s & (spefscr_fovfh|spefscr_fovf)))) \
  140. /* FIXME: raise exceptions. */; \
  141. } \
  142. }