intrinsics.h 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. /* intrinsics.h -- C interface for TriCore special machine instructions.
  2. Copyright (C) 1999-2014 HighTec EDV-Systeme GmbH.
  3. This file is part of GCC.
  4. GCC is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 3, or (at your option)
  7. any later version.
  8. GCC is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. Under Section 7 of GPL version 3, you are granted additional
  13. permissions described in the GCC Runtime Library Exception, version
  14. 3.1, as published by the Free Software Foundation.
  15. You should have received a copy of the GNU General Public License and
  16. a copy of the GCC Runtime Library Exception along with this program;
  17. see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  18. <http://www.gnu.org/licenses/>. */
  19. #ifndef __INTRINSICS_H__
  20. #define __INTRINSICS_H__
  21. #undef __STRINGIFY
  22. #define __STRINGIFY(x) #x
  23. /* Some of the TriCore instructions require an immediate operand.
  24. If the compiler cannot prove that the respective operand is a compile
  25. time constant, we get diagnostics like
  26. warning: asm operand <n> probably doesn't match constraints
  27. error: impossible constraint in 'asm'
  28. Therefore, we supply these instructions in two flavors:
  29. __XXXX: This is a macro that puts together the assembler template:
  30. stringifying the macro argument and then gluing it together
  31. to get the static constant string as required by __asm__.
  32. Some of the __XXXX macros are also supplied for backward
  33. compatibility with 3.x legacy code.
  34. _xxxx: An inline function that allows to feed in 0L for example.
  35. In some cases and where the argument does not matter (or there
  36. is no argument at all) this might also be a macro. Again, this
  37. is for compatibility.
  38. Neither of the two forms cover all use cases so that we need both.
  39. The __tric_xxxx macros are only used internally for macro double-expansion.
  40. Examples:
  41. =========
  42. int x;
  43. x = _mfcr (0);
  44. x = _mfcr (1L);
  45. x = __MFCR (0);
  46. x = __MFCR ($ICR);
  47. #define ADDR 0x123
  48. x = _mfcr (ADDR);
  49. x = __MFCR (ADDR);
  50. #define ADDR1 ADDR + 1
  51. x = _mfcr (ADDR1);
  52. x = __MFCR (ADDR1);
  53. */
  54. /*********************************************************************
  55. * BISR
  56. **********************************************************************/
  57. #define __bisr(irq_level) __tric_bisr(irq_level)
  58. #define __BISR(irq_level) __tric_bisr(irq_level)
  59. #define __tric_bisr(irq_level) \
  60. __asm__ volatile ("bisr " __STRINGIFY (irq_level) ::: "memory")
  61. static __inline__ __attribute__((__always_inline__))
  62. void _bisr (const unsigned __irq_level)
  63. {
  64. __asm__ volatile ("bisr %0" :: "i" (__irq_level) : "memory");
  65. }
  66. /*********************************************************************
  67. * MFCR
  68. **********************************************************************/
  69. #define __MFCR(regaddr) __tric_mfcr (regaddr)
  70. #define __mfcr(regaddr) __tric_mfcr (regaddr)
  71. #define __tric_mfcr(regaddr) \
  72. (__extension__({ \
  73. unsigned __res; \
  74. __asm__ volatile ("mfcr %0, LO:" __STRINGIFY (regaddr) \
  75. : "=d" (__res) :: "memory"); \
  76. __res; \
  77. }))
  78. static __inline__ __attribute__((__always_inline__))
  79. unsigned _mfcr (const unsigned __regaddr)
  80. {
  81. unsigned __res;
  82. __asm__ volatile ("mfcr %0, LO:%1"
  83. : "=d" (__res) : "i" (__regaddr) : "memory");
  84. return __res;
  85. }
  86. /*********************************************************************
  87. * MTCR
  88. **********************************************************************/
  89. #define __MTCR(regaddr, val) __tric_mtcr (regaddr, val)
  90. #define __mtcr(regaddr, val) __tric_mtcr (regaddr, val)
  91. #define __tric_mtcr(regaddr, val) \
  92. do { \
  93. unsigned __newval = (unsigned) (val); \
  94. __asm__ volatile ("mtcr LO:" __STRINGIFY (regaddr) ", %0" \
  95. :: "d" (__newval) : "memory"); \
  96. } while (0)
  97. static __inline__ __attribute__((__always_inline__))
  98. void _mtcr (const unsigned __regaddr, const unsigned __val)
  99. {
  100. __asm__ volatile ("mtcr LO:%0, %1"
  101. :: "i" (__regaddr), "d" (__val) : "memory");
  102. }
  103. /*********************************************************************
  104. * SYSCALL
  105. **********************************************************************/
  106. #define __syscall(service) __tric_syscall (service)
  107. #define __SYSCALL(service) __tric_syscall (service)
  108. #define __tric_syscall(service) \
  109. __asm__ volatile ("syscall "__STRINGIFY (service) ::: "memory")
  110. static __inline__ __attribute__((__always_inline__))
  111. void _syscall (const unsigned __service)
  112. {
  113. __asm__ volatile ("syscall %0" :: "i" (__service) : "memory");
  114. }
  115. /*********************************************************************
  116. * Misc, without operands
  117. **********************************************************************/
  118. static __inline__ __attribute__((__always_inline__))
  119. void _disable (void)
  120. {
  121. __asm__ volatile ("disable" ::: "memory");
  122. }
  123. static __inline__ __attribute__((__always_inline__))
  124. void _enable (void)
  125. {
  126. __asm__ volatile ("enable" ::: "memory");
  127. }
  128. static __inline__ __attribute__((__always_inline__))
  129. void _debug (void)
  130. {
  131. __asm__ volatile ("debug" ::: "memory");
  132. }
  133. static __inline__ __attribute__((__always_inline__))
  134. void _isync (void)
  135. {
  136. __asm__ volatile ("isync" ::: "memory");
  137. }
  138. static __inline__ __attribute__((__always_inline__))
  139. void _dsync (void)
  140. {
  141. __asm__ volatile ("dsync" ::: "memory");
  142. }
  143. static __inline__ __attribute__((__always_inline__))
  144. void _rstv (void)
  145. {
  146. __asm__ volatile ("rstv" ::: "memory");
  147. }
  148. static __inline__ __attribute__((__always_inline__))
  149. void _rslcx (void)
  150. {
  151. __asm__ volatile ("rslcx" ::: "memory",
  152. "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
  153. "a2", "a3", "a4", "a5", "a6", "a7", "a11");
  154. }
  155. static __inline__ __attribute__((__always_inline__))
  156. void _svlcx (void)
  157. {
  158. __asm__ volatile ("svlcx" ::: "memory");
  159. }
  160. static __inline__ __attribute__((__always_inline__))
  161. void _nop (void)
  162. {
  163. __asm__ volatile ("nop" ::: "memory");
  164. }
  165. /*********************************************************************
  166. * More Fiddling with Interrupt Enable / Disable
  167. **********************************************************************/
  168. /* Restore interrupt state. Directly supported for TriCore 1.6.
  169. Emulated on TC1.3. */
  170. static __inline__ __attribute__((__always_inline__))
  171. void _restore (const int irqs_on)
  172. {
  173. #if defined(__TC16__) || defined(__TC161__)
  174. __asm__ volatile ("restore %0" :: "d" (irqs_on) : "memory");
  175. #else
  176. if (irqs_on)
  177. _enable();
  178. else
  179. _disable();
  180. #endif
  181. }
  182. /*********************************************************************
  183. * Some compatibility defines with name mess of 3.x.
  184. * In 3.x, these names served to indicate wether or not a specific
  185. * built-in is available, but users started to use the marker macros
  186. * as function calls...
  187. * FIXME: We should clean this up.
  188. **********************************************************************/
  189. #define __CLZ(val) __builtin_clz (val)
  190. #define __CTZ(val) __builtin_ctz (val)
  191. #define __ABS(val) __builtin_abs (val)
  192. #endif /* __INTRINSICS_H__ */