mips_asm.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. /*
  2. * File : mips_asm.h
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2008 - 2012, RT-Thread Development Team
  5. *
  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 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along
  17. * with this program; if not, write to the Free Software Foundation, Inc.,
  18. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  19. *
  20. * Change Logs:
  21. * Date Author Notes
  22. * 2016Äê9ÔÂ7ÈÕ Urey the first version
  23. */
  24. #ifndef _MIPS_ASM_H_
  25. #define _MIPS_ASM_H_
  26. /* ********************************************************************* */
  27. /* Interface macro & data definition */
  28. #ifdef __ASSEMBLY__
  29. /******** ASSEMBLER SPECIFIC DEFINITIONS ********/
  30. #ifdef __ghs__
  31. #define ALIGN(x) .##align (1 << (x))
  32. #else
  33. #define ALIGN(x) .##align (x)
  34. #endif
  35. #ifdef __ghs__
  36. #define SET_MIPS3()
  37. #define SET_MIPS0()
  38. #define SET_PUSH()
  39. #define SET_POP()
  40. #else
  41. #define SET_MIPS3() .##set mips3
  42. #define SET_MIPS0() .##set mips0
  43. #define SET_PUSH() .##set push
  44. #define SET_POP() .##set pop
  45. #endif
  46. /* Different assemblers have different requirements for how to
  47. * indicate that the next section is bss :
  48. *
  49. * Some use : .bss
  50. * Others use : .section bss
  51. *
  52. * We select which to use based on _BSS_OLD_, which may be defined
  53. * in makefile.
  54. */
  55. #ifdef _BSS_OLD_
  56. #define BSS .##section bss
  57. #else
  58. #define BSS .##bss
  59. #endif
  60. #define LEAF(name)\
  61. .##text;\
  62. .##globl name;\
  63. .##ent name;\
  64. name:
  65. #define SLEAF(name)\
  66. .##text;\
  67. .##ent name;\
  68. name:
  69. #ifdef __ghs__
  70. #define END(name)\
  71. .##end name
  72. #else
  73. #define END(name)\
  74. .##size name,.-name;\
  75. .##end name
  76. #endif
  77. #define EXTERN(name)
  78. #else
  79. #define U64 unsigned long long
  80. #define U32 unsigned int
  81. #define U16 unsigned short
  82. #define U8 unsigned char
  83. #define S64 signed long long
  84. #define S32 int
  85. #define S16 short int
  86. #define S8 signed char
  87. //#define bool U8
  88. #ifndef _SIZE_T_
  89. #define _SIZE_T_
  90. #ifdef __ghs__
  91. typedef unsigned int size_t;
  92. #else
  93. typedef unsigned long size_t;
  94. #endif
  95. #endif
  96. /* Sets the result on bPort */
  97. #define BIT_SET(bPort,bBitMask) (bPort |= bBitMask)
  98. #define BIT_CLR(bPort,bBitMask) (bPort &= ~bBitMask)
  99. /* Returns the result */
  100. #define GET_BIT_SET(bPort,bBitMask) (bPort | bBitMask)
  101. #define GET_BIT_CLR(bPort,bBitMask) (bPort & ~bBitMask)
  102. /* Returns 0 if the condition is False & a non-zero value if it is True */
  103. #define TEST_BIT_SET(bPort,bBitMask) (bPort & bBitMask)
  104. #define TEST_BIT_CLR(bPort,bBitMask) ((~bPort) & bBitMask)
  105. /* Split union definitions */
  106. typedef union tunSU16
  107. {
  108. U16 hwHW;
  109. struct tst2U8
  110. {
  111. U8 bB0;
  112. U8 bB1;
  113. }st2U8;
  114. }tunSU16;
  115. typedef union tunSU32
  116. {
  117. U32 wW;
  118. struct tst2U16
  119. {
  120. U16 hwHW0;
  121. U16 hwHW1;
  122. }st2U16;
  123. struct tst4U8
  124. {
  125. U8 bB0;
  126. U8 bB1;
  127. U8 bB2;
  128. U8 bB3;
  129. }st4U8;
  130. }tunSU32;
  131. #endif /* #ifdef __ASSEMBLY__ */
  132. /******** DEFINITIONS FOR BOTH ASSEMBLER AND C ********/
  133. #define NO_ERR 0x00000000 /* operation completed successfully */
  134. #define ERR 0xffffffff /* operation completed not successfully */
  135. #define False 0
  136. #define True !False
  137. #ifndef NULL
  138. #define NULL ((void *)0)
  139. #endif//NULL
  140. #ifndef MIN
  141. #define MIN(x,y) ((x) < (y) ? (x) : (y))
  142. #endif//MIN
  143. #ifndef MAX
  144. #define MAX(x,y) ((x) > (y) ? (x) : (y))
  145. #endif//MAX
  146. #define MAXUINT(w) (\
  147. ((w) == sizeof(U8)) ? 0xFFU :\
  148. ((w) == sizeof(U16)) ? 0xFFFFU :\
  149. ((w) == sizeof(U32)) ? 0xFFFFFFFFU : 0\
  150. )
  151. #define MAXINT(w) (\
  152. ((w) == sizeof(S8)) ? 0x7F :\
  153. ((w) == sizeof(S16)) ? 0x7FFF :\
  154. ((w) == sizeof(S32)) ? 0x7FFFFFFF : 0\
  155. )
  156. #define MSK(n) ((1 << (n)) - 1)
  157. #define KUSEG_MSK 0x80000000
  158. #define KSEG_MSK 0xE0000000
  159. #define KUSEGBASE 0x00000000
  160. #define KSEG0BASE 0x80000000
  161. #define KSEG1BASE 0xA0000000
  162. #define KSSEGBASE 0xC0000000
  163. #define KSEG3BASE 0xE0000000
  164. /* Below macros perform the following functions :
  165. *
  166. * KSEG0 : Converts KSEG0/1 or physical addr (below 0.5GB) to KSEG0.
  167. * KSEG1 : Converts KSEG0/1 or physical addr (below 0.5GB) to KSEG1.
  168. * PHYS : Converts KSEG0/1 or physical addr (below 0.5GB) to physical address.
  169. * KSSEG : Not relevant for converting, but used for determining range.
  170. * KSEG3 : Not relevant for converting, but used for determining range.
  171. * KUSEG : Not relevant for converting, but used for determining range.
  172. * KSEG0A : Same as KSEG0 but operates on register rather than constant.
  173. * KSEG1A : Same as KSEG1 but operates on register rather than constant.
  174. * PHYSA : Same as PHYS but operates on register rather than constant.
  175. * CACHED : Alias for KSEG0 macro .
  176. * (Note that KSEG0 cache attribute is determined by K0
  177. * field of Config register, but this is typically cached).
  178. * UNCACHED : Alias for KSEG1 macro .
  179. */
  180. #ifdef __ASSEMBLY__
  181. #define KSEG0(addr) (((addr) & ~KSEG_MSK) | KSEG0BASE)
  182. #define KSEG1(addr) (((addr) & ~KSEG_MSK) | KSEG1BASE)
  183. #define KSSEG(addr) (((addr) & ~KSEG_MSK) | KSSEGBASE)
  184. #define KSEG3(addr) (((addr) & ~KSEG_MSK) | KSEG3BASE)
  185. #define KUSEG(addr) (((addr) & ~KUSEG_MSK) | KUSEGBASE)
  186. #define PHYS(addr) ( (addr) & ~KSEG_MSK)
  187. #define KSEG0A(reg) and reg, ~KSEG_MSK; or reg, KSEG0BASE
  188. #define KSEG1A(reg) and reg, ~KSEG_MSK; or reg, KSEG1BASE
  189. #define PHYSA(reg) and reg, ~KSEG_MSK
  190. #else
  191. #define KSEG0(addr) (((U32)(addr) & ~KSEG_MSK) | KSEG0BASE)
  192. #define KSEG1(addr) (((U32)(addr) & ~KSEG_MSK) | KSEG1BASE)
  193. #define KSSEG(addr) (((U32)(addr) & ~KSEG_MSK) | KSSEGBASE)
  194. #define KSEG3(addr) (((U32)(addr) & ~KSEG_MSK) | KSEG3BASE)
  195. #define KUSEG(addr) (((U32)(addr) & ~KUSEG_MSK) | KUSEGBASE)
  196. #define PHYS(addr) ((U32)(addr) & ~KSEG_MSK)
  197. #endif
  198. #define CACHED(addr) KSEG0(addr)
  199. #define UNCACHED(addr) KSEG1(addr)
  200. #ifdef __ASSEMBLY__
  201. /* Macroes to access variables at constant addresses
  202. * Compensates for signed 16 bit displacement
  203. * Typical use: li a0, HIKSEG1(ATLAS_ASCIIWORD)
  204. * sw v1, LO_OFFS(ATLAS_ASCIIWORD)(a0)
  205. */
  206. #define HIKSEG0(addr) ((KSEG0(addr) + 0x8000) & 0xffff0000)
  207. #define HIKSEG1(addr) ((KSEG1(addr) + 0x8000) & 0xffff0000)
  208. #define HI_PART(addr) (((addr) + 0x8000) & 0xffff0000)
  209. #define LO_OFFS(addr) ((addr) & 0xffff)
  210. #endif
  211. /* Most/Least significant 32 bit from 64 bit double word */
  212. #define HI32(data64) ((U32)(data64 >> 32))
  213. #define LO32(data64) ((U32)(data64 & 0xFFFFFFFF))
  214. #if ((!defined(__ASSEMBLY__)) && (!defined(__LANGUAGE_ASSEMBLY)))
  215. #define REG8( addr ) (*(volatile U8 *) (addr))
  216. #define REG16( addr ) (*(volatile U16 *)(addr))
  217. #define REG32( addr ) (*(volatile U32 *)(addr))
  218. #define REG64( addr ) (*(volatile U64 *)(addr))
  219. #endif
  220. /* Register field mapping */
  221. #define REGFIELD(reg, rfld) (((reg) & rfld##_MSK) >> rfld##_SHF)
  222. /* absolute register address, access */
  223. #define REGA(addr) REG32(addr)
  224. /* physical register address, access: base address + offsett */
  225. #define REGP(base,phys) REG32( (U32)(base) + (phys) )
  226. /* relative register address, access: base address + offsett */
  227. #define REG(base,offs) REG32( (U32)(base) + offs##_##OFS )
  228. /* relative register address, access: base address + offsett */
  229. #define REG_8(base,offs) REG8( (U32)(base) + offs##_##OFS )
  230. /* relative register address, access: base address + offsett */
  231. #define REG_16(base,offs) REG16( (U32)(base) + offs##_##OFS )
  232. /* relative register address, access: base address + offsett */
  233. #define REG_64(base,offs) REG64( (U32)(base) + offs##_##OFS )
  234. /**************************************
  235. * Macroes not used by YAMON any more
  236. * (kept for backwards compatibility)
  237. */
  238. /* register read field */
  239. #define REGARD(addr,fld) ((REGA(addr) & addr##_##fld##_##MSK) \
  240. >> addr##_##fld##_##SHF)
  241. /* register write numeric field value */
  242. #define REGAWRI(addr,fld,intval) ((REGA(addr) & ~(addr##_##fld##_##MSK))\
  243. | ((intval) << addr##_##fld##_##SHF))
  244. /* register write enumerated field value */
  245. #define REGAWRE(addr,fld,enumval) ((REGA(addr) & ~(addr##_##fld##_##MSK))\
  246. | ((addr##_##fld##_##enumval) << addr##_##fld##_##SHF))
  247. /* Examples:
  248. *
  249. * exccode = REGARD(CPU_CAUSE,EXC);
  250. *
  251. * REGA(SDR_CONTROL) = REGAWRI(OSG_CONTROL,TMO,17)
  252. * | REGAWRE(OSG_CONTROL,DTYPE,PC1);
  253. */
  254. /* register read field */
  255. #define REGRD(base,offs,fld) ((REG(base,offs) & offs##_##fld##_##MSK) \
  256. >> offs##_##fld##_##SHF)
  257. /* register write numeric field value */
  258. #define REGWRI(base,offs,fld,intval)((REG(base,offs)& ~(offs##_##fld##_##MSK))\
  259. | (((intval) << offs##_##fld##_##SHF) & offs##_##fld##_##MSK))
  260. /* register write enumerated field value */
  261. #define REGWRE(base,offs,fld,enumval)((REG(base,offs) & ~(offs##_##fld##_##MSK))\
  262. | ((offs##_##fld##_##enumval) << offs##_##fld##_##SHF))
  263. /* physical register read field */
  264. #define REGPRD(base,phys,fld) ((REGP(base,phys) & phys##_##fld##_##MSK) \
  265. >> phys##_##fld##_##SHF)
  266. /* physical register write numeric field value */
  267. #define REGPWRI(base,phys,fld,intval)((REGP(base,phys)& ~(phys##_##fld##_##MSK))\
  268. | ((intval) << phys##_##fld##_##SHF))
  269. /* physical register write enumerated field value */
  270. #define REGPWRE(base,phys,fld,enumval)((REGP(base,phys) & ~(phys##_##fld##_##MSK))\
  271. | ((phys##_##fld##_##enumval) << phys##_##fld##_##SHF))
  272. /*
  273. * End of macroes not used by YAMON any more
  274. *********************************************/
  275. /* Endian related macros */
  276. #define SWAP_BYTEADDR32( addr ) ( (addr) ^ 0x3 )
  277. #define SWAP_U16ADDR32( addr ) ( (addr) ^ 0x2 )
  278. /* Set byte address to little endian format */
  279. #ifdef EL
  280. #define SWAP_BYTEADDR_EL(addr) addr
  281. #else
  282. #define SWAP_BYTEADDR_EL(addr) SWAP_BYTEADDR32( addr )
  283. #endif
  284. /* Set byte address to big endian format */
  285. #ifdef EB
  286. #define SWAP_BYTEADDR_EB(addr) addr
  287. #else
  288. #define SWAP_BYTEADDR_EB(addr) SWAP_BYTEADDR32( addr )
  289. #endif
  290. /* Set U16 address to little endian format */
  291. #ifdef EL
  292. #define SWAP_U16ADDR_EL(addr) addr
  293. #else
  294. #define SWAP_U16ADDR_EL(addr) SWAP_U16ADDR32( addr )
  295. #endif
  296. /* Set U16 address to big endian format */
  297. #ifdef EB
  298. #define SWAP_U16ADDR_EB(addr) addr
  299. #else
  300. #define SWAP_U16ADDR_EB(addr) SWAP_U16ADDR32( addr )
  301. #endif
  302. #ifdef EL
  303. #define REGW32LE(addr, data) REG32(addr) = (data)
  304. #define REGR32LE(addr, data) (data) = REG32(addr)
  305. #else
  306. #define REGW32LE(addr, data) REG32(addr) = SWAPEND32(data)
  307. #define REGR32LE(addr, data) (data) = REG32(addr), (data) = SWAPEND32(data)
  308. #endif
  309. /* Set of 'LE'-macros, convert by BE: */
  310. #ifdef EL
  311. #define CPU_TO_LE32( value ) (value)
  312. #define LE32_TO_CPU( value ) (value)
  313. #define CPU_TO_LE16( value ) (value)
  314. #define LE16_TO_CPU( value ) (value)
  315. #else
  316. #define CPU_TO_LE32( value ) ( ( ((U32)value) << 24) | \
  317. ((0x0000FF00UL & ((U32)value)) << 8) | \
  318. ((0x00FF0000UL & ((U32)value)) >> 8) | \
  319. ( ((U32)value) >> 24) )
  320. #define LE32_TO_CPU( value ) CPU_TO_LE32( value )
  321. #define CPU_TO_LE16( value ) ( ((U16)(((U16)value) << 8)) | \
  322. ((U16)(((U16)value) >> 8)) )
  323. #define LE16_TO_CPU( value ) CPU_TO_LE16( value )
  324. #endif
  325. /* Set of 'BE'-macros, convert by LE: */
  326. #ifdef EB
  327. #define CPU_TO_BE32( value ) (value)
  328. #define BE32_TO_CPU( value ) (value)
  329. #define CPU_TO_BE16( value ) (value)
  330. #define BE16_TO_CPU( value ) (value)
  331. #else
  332. #define CPU_TO_BE32( value ) ( ( ((U32)value) << 24) | \
  333. ((0x0000FF00UL & ((U32)value)) << 8) | \
  334. ((0x00FF0000UL & ((U32)value)) >> 8) | \
  335. ( ((U32)value) >> 24) )
  336. #define BE32_TO_CPU( value ) CPU_TO_BE32( value )
  337. #define CPU_TO_BE16( value ) ( ((U16)(((U16)value) << 8)) | \
  338. ((U16)(((U16)value) >> 8)) )
  339. #define BE16_TO_CPU( value ) CPU_TO_BE16( value )
  340. #endif
  341. /* Control characters */
  342. #define CTRL_A ('A'-0x40)
  343. #define CTRL_B ('B'-0x40)
  344. #define CTRL_C ('C'-0x40)
  345. #define CTRL_D ('D'-0x40)
  346. #define CTRL_E ('E'-0x40)
  347. #define CTRL_F ('F'-0x40)
  348. #define CTRL_H ('H'-0x40)
  349. #define CTRL_K ('K'-0x40)
  350. #define CTRL_N ('N'-0x40)
  351. #define CTRL_P ('P'-0x40)
  352. #define CTRL_U ('U'-0x40)
  353. #define BACKSPACE 0x08
  354. #define DEL 0x7F
  355. #define TAB 0x09
  356. #define CR 0x0D /* Enter Key */
  357. #define LF 0x0A
  358. #define ESC 0x1B
  359. #define SP 0x20
  360. #define CSI 0x9B
  361. /* DEF2STR(x) converts #define symbol to string */
  362. #define DEF2STR1(x) #x
  363. #define DEF2STR(x) DEF2STR1(x)
  364. #endif /* _MIPS_ASM_H_ */