asm.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  1. /* Copyright (C) 1997, 1998, 2002, 2003 Free Software Foundation, Inc.
  2. This file is part of the GNU C Library.
  3. Contributed by Ralf Baechle <ralf@gnu.org>.
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. The GNU C Library 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 GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with the GNU C Library; if not, write to the Free
  14. Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  15. 02111-1307 USA. */
  16. #ifndef _SYS_ASM_H
  17. #define _SYS_ASM_H
  18. #include <sgidefs.h>
  19. #ifndef CAT
  20. # ifdef __STDC__
  21. # define __CAT(str1,str2) str1##str2
  22. # else
  23. # define __CAT(str1,str2) str1/**/str2
  24. # endif
  25. # define CAT(str1,str2) __CAT(str1,str2)
  26. #endif
  27. /*
  28. * Macros to handle different pointer/register sizes for 32/64-bit code
  29. *
  30. * 64 bit address space isn't used yet, so we may use the R3000 32 bit
  31. * defines for now.
  32. */
  33. #if (_MIPS_SIM == _MIPS_SIM_ABI32) || (_MIPS_SIM == _MIPS_SIM_NABI32)
  34. # define PTR .word
  35. # define PTRSIZE 4
  36. # define PTRLOG 2
  37. #elif (_MIPS_SIM == _MIPS_SIM_ABI64)
  38. # define PTR .dword
  39. # define PTRSIZE 8
  40. # define PTRLOG 3
  41. #endif
  42. /*
  43. * PIC specific declarations
  44. */
  45. #if (_MIPS_SIM == _MIPS_SIM_ABI32)
  46. # ifdef __PIC__
  47. # define CPRESTORE(register) \
  48. .cprestore register
  49. # define CPLOAD(register) \
  50. .cpload register
  51. # else
  52. # define CPRESTORE(register)
  53. # define CPLOAD(register)
  54. # endif
  55. # define CPADD(register) \
  56. .cpadd register
  57. /*
  58. * Set gp when at 1st instruction
  59. */
  60. # define SETUP_GP \
  61. .set noreorder; \
  62. .cpload $25; \
  63. .set reorder
  64. /* Set gp when not at 1st instruction */
  65. # define SETUP_GPX(r) \
  66. .set noreorder; \
  67. move r, $31; /* Save old ra. */ \
  68. bal 10f; /* Find addr of cpload. */ \
  69. nop; \
  70. 10: \
  71. .cpload $31; \
  72. move $31, r; \
  73. .set reorder
  74. # define SETUP_GPX_L(r, l) \
  75. .set noreorder; \
  76. move r, $31; /* Save old ra. */ \
  77. bal l; /* Find addr of cpload. */ \
  78. nop; \
  79. l: \
  80. .cpload $31; \
  81. move $31, r; \
  82. .set reorder
  83. # define SAVE_GP(x) \
  84. .cprestore x /* Save gp trigger t9/jalr conversion. */
  85. # define SETUP_GP64(a, b)
  86. # define SETUP_GPX64(a, b)
  87. # define SETUP_GPX64_L(cp_reg, ra_save, l)
  88. # define RESTORE_GP64
  89. # define USE_ALT_CP(a)
  90. #else /* (_MIPS_SIM == _MIPS_SIM_ABI64) || (_MIPS_SIM == _MIPS_SIM_NABI32) */
  91. /*
  92. * For callee-saved gp calling convention:
  93. */
  94. # define SETUP_GP
  95. # define SETUP_GPX(r)
  96. # define SETUP_GPX_L(r, l)
  97. # define SAVE_GP(x)
  98. # define SETUP_GP64(gpoffset, proc) \
  99. .cpsetup $25, gpoffset, proc
  100. # define SETUP_GPX64(cp_reg, ra_save) \
  101. move ra_save, $31; /* Save old ra. */ \
  102. .set noreorder; \
  103. bal 10f; /* Find addr of .cpsetup. */ \
  104. nop; \
  105. 10: \
  106. .set reorder; \
  107. .cpsetup $31, cp_reg, 10b; \
  108. move $31, ra_save
  109. # define SETUP_GPX64_L(cp_reg, ra_save, l) \
  110. move ra_save, $31; /* Save old ra. */ \
  111. .set noreorder; \
  112. bal l; /* Find addr of .cpsetup. */ \
  113. nop; \
  114. l: \
  115. .set reorder; \
  116. .cpsetup $31, cp_reg, l; \
  117. move $31, ra_save
  118. # define RESTORE_GP64 \
  119. .cpreturn
  120. /* Use alternate register for context pointer. */
  121. # define USE_ALT_CP(reg) \
  122. .cplocal reg
  123. #endif /* _MIPS_SIM != _MIPS_SIM_ABI32 */
  124. /*
  125. * Stack Frame Definitions
  126. */
  127. #if (_MIPS_SIM == _MIPS_SIM_ABI32)
  128. # define NARGSAVE 4 /* Space for 4 argument registers must be allocated. */
  129. #endif
  130. #if (_MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32)
  131. # define NARGSAVE 0 /* No caller responsibilities. */
  132. #endif
  133. /*
  134. * LEAF - declare leaf routine
  135. */
  136. #define LEAF(symbol) \
  137. .globl symbol; \
  138. .align 2; \
  139. .type symbol,@function; \
  140. .ent symbol,0; \
  141. symbol: .frame sp,0,ra
  142. /*
  143. * NESTED - declare nested routine entry point
  144. */
  145. #define NESTED(symbol, framesize, rpc) \
  146. .globl symbol; \
  147. .align 2; \
  148. .type symbol,@function; \
  149. .ent symbol,0; \
  150. symbol: .frame sp, framesize, rpc
  151. /*
  152. * END - mark end of function
  153. */
  154. #ifndef END
  155. # define END(function) \
  156. .end function; \
  157. .size function,.-function
  158. #endif
  159. /*
  160. * EXPORT - export definition of symbol
  161. */
  162. #define EXPORT(symbol) \
  163. .globl symbol; \
  164. symbol:
  165. /*
  166. * ABS - export absolute symbol
  167. */
  168. #define ABS(symbol,value) \
  169. .globl symbol; \
  170. symbol = value
  171. #define PANIC(msg) \
  172. .set push; \
  173. .set reorder; \
  174. la a0,8f; \
  175. jal panic; \
  176. 9: b 9b; \
  177. .set pop; \
  178. TEXT(msg)
  179. /*
  180. * Print formated string
  181. */
  182. #define PRINT(string) \
  183. .set push; \
  184. .set reorder; \
  185. la a0,8f; \
  186. jal printk; \
  187. .set pop; \
  188. TEXT(string)
  189. #define TEXT(msg) \
  190. .data; \
  191. 8: .asciiz msg; \
  192. .previous;
  193. /*
  194. * Build text tables
  195. */
  196. #define TTABLE(string) \
  197. .text; \
  198. .word 1f; \
  199. .previous; \
  200. .data; \
  201. 1: .asciz string; \
  202. .previous
  203. /*
  204. * MIPS IV pref instruction.
  205. * Use with .set noreorder only!
  206. *
  207. * MIPS IV implementations are free to treat this as a nop. The R5000
  208. * is one of them. So we should have an option not to use this instruction.
  209. */
  210. #if (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \
  211. (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
  212. # define PREF(hint,addr) \
  213. pref hint,addr
  214. # define PREFX(hint,addr) \
  215. prefx hint,addr
  216. #else
  217. # define PREF
  218. # define PREFX
  219. #endif
  220. /*
  221. * MIPS ISA IV/V movn/movz instructions and equivalents for older CPUs.
  222. */
  223. #if _MIPS_ISA == _MIPS_ISA_MIPS1
  224. # define MOVN(rd,rs,rt) \
  225. .set push; \
  226. .set reorder; \
  227. beqz rt,9f; \
  228. move rd,rs; \
  229. .set pop; \
  230. 9:
  231. # define MOVZ(rd,rs,rt) \
  232. .set push; \
  233. .set reorder; \
  234. bnez rt,9f; \
  235. move rd,rt; \
  236. .set pop; \
  237. 9:
  238. #endif /* _MIPS_ISA == _MIPS_ISA_MIPS1 */
  239. #if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3)
  240. # define MOVN(rd,rs,rt) \
  241. .set push; \
  242. .set noreorder; \
  243. bnezl rt,9f; \
  244. move rd,rs; \
  245. .set pop; \
  246. 9:
  247. # define MOVZ(rd,rs,rt) \
  248. .set push; \
  249. .set noreorder; \
  250. beqzl rt,9f; \
  251. movz rd,rs; \
  252. .set pop; \
  253. 9:
  254. #endif /* (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) */
  255. #if (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \
  256. (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
  257. # define MOVN(rd,rs,rt) \
  258. movn rd,rs,rt
  259. # define MOVZ(rd,rs,rt) \
  260. movz rd,rs,rt
  261. #endif /* (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) */
  262. /*
  263. * Stack alignment
  264. */
  265. #if (_MIPS_SIM == _MIPS_SIM_ABI64) || (_MIPS_SIM == _MIPS_SIM_NABI32)
  266. # define ALSZ 15
  267. # define ALMASK ~15
  268. #else
  269. # define ALSZ 7
  270. # define ALMASK ~7
  271. #endif
  272. /*
  273. * Size of a register
  274. */
  275. #if (_MIPS_SIM == _MIPS_SIM_ABI64) || (_MIPS_SIM == _MIPS_SIM_NABI32)
  276. # define SZREG 8
  277. #else
  278. # define SZREG 4
  279. #endif
  280. /*
  281. * Use the following macros in assemblercode to load/store registers,
  282. * pointers etc.
  283. */
  284. #if (SZREG == 4)
  285. # define REG_S sw
  286. # define REG_L lw
  287. #else
  288. # define REG_S sd
  289. # define REG_L ld
  290. #endif
  291. /*
  292. * How to add/sub/load/store/shift C int variables.
  293. */
  294. #if (_MIPS_SZINT == 32)
  295. # define INT_ADD add
  296. # define INT_ADDI addi
  297. # define INT_ADDU addu
  298. # define INT_ADDIU addiu
  299. # define INT_SUB add
  300. # define INT_SUBI subi
  301. # define INT_SUBU subu
  302. # define INT_SUBIU subu
  303. # define INT_L lw
  304. # define INT_S sw
  305. #endif
  306. #if (_MIPS_SZINT == 64)
  307. # define INT_ADD dadd
  308. # define INT_ADDI daddi
  309. # define INT_ADDU daddu
  310. # define INT_ADDIU daddiu
  311. # define INT_SUB dadd
  312. # define INT_SUBI dsubi
  313. # define INT_SUBU dsubu
  314. # define INT_SUBIU dsubu
  315. # define INT_L ld
  316. # define INT_S sd
  317. #endif
  318. /*
  319. * How to add/sub/load/store/shift C long variables.
  320. */
  321. #if (_MIPS_SZLONG == 32)
  322. # define LONG_ADD add
  323. # define LONG_ADDI addi
  324. # define LONG_ADDU addu
  325. # define LONG_ADDIU addiu
  326. # define LONG_SUB add
  327. # define LONG_SUBI subi
  328. # define LONG_SUBU subu
  329. # define LONG_SUBIU subu
  330. # define LONG_L lw
  331. # define LONG_S sw
  332. # define LONG_SLL sll
  333. # define LONG_SLLV sllv
  334. # define LONG_SRL srl
  335. # define LONG_SRLV srlv
  336. # define LONG_SRA sra
  337. # define LONG_SRAV srav
  338. #endif
  339. #if (_MIPS_SZLONG == 64)
  340. # define LONG_ADD dadd
  341. # define LONG_ADDI daddi
  342. # define LONG_ADDU daddu
  343. # define LONG_ADDIU daddiu
  344. # define LONG_SUB dadd
  345. # define LONG_SUBI dsubi
  346. # define LONG_SUBU dsubu
  347. # define LONG_SUBIU dsubu
  348. # define LONG_L ld
  349. # define LONG_S sd
  350. # define LONG_SLL dsll
  351. # define LONG_SLLV dsllv
  352. # define LONG_SRL dsrl
  353. # define LONG_SRLV dsrlv
  354. # define LONG_SRA dsra
  355. # define LONG_SRAV dsrav
  356. #endif
  357. /*
  358. * How to add/sub/load/store/shift pointers.
  359. */
  360. #if (_MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32)
  361. # define PTR_ADD add
  362. # define PTR_ADDI addi
  363. # define PTR_ADDU addu
  364. # define PTR_ADDIU addiu
  365. # define PTR_SUB add
  366. # define PTR_SUBI subi
  367. # define PTR_SUBU subu
  368. # define PTR_SUBIU subu
  369. # define PTR_L lw
  370. # define PTR_LA la
  371. # define PTR_S sw
  372. # define PTR_SLL sll
  373. # define PTR_SLLV sllv
  374. # define PTR_SRL srl
  375. # define PTR_SRLV srlv
  376. # define PTR_SRA sra
  377. # define PTR_SRAV srav
  378. # define PTR_SCALESHIFT 2
  379. #endif
  380. #if _MIPS_SIM == _MIPS_SIM_NABI32
  381. # define PTR_ADD add
  382. # define PTR_ADDI addi
  383. # define PTR_ADDU add /* no u */
  384. # define PTR_ADDIU addi /* no u */
  385. # define PTR_SUB add
  386. # define PTR_SUBI subi
  387. # define PTR_SUBU sub /* no u */
  388. # define PTR_SUBIU sub /* no u */
  389. # define PTR_L lw
  390. # define PTR_LA la
  391. # define PTR_S sw
  392. # define PTR_SLL sll
  393. # define PTR_SLLV sllv
  394. # define PTR_SRL srl
  395. # define PTR_SRLV srlv
  396. # define PTR_SRA sra
  397. # define PTR_SRAV srav
  398. # define PTR_SCALESHIFT 2
  399. #endif
  400. #if (_MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 64 /* o64??? */) \
  401. || _MIPS_SIM == _MIPS_SIM_ABI64
  402. # define PTR_ADD dadd
  403. # define PTR_ADDI daddi
  404. # define PTR_ADDU daddu
  405. # define PTR_ADDIU daddiu
  406. # define PTR_SUB dadd
  407. # define PTR_SUBI dsubi
  408. # define PTR_SUBU dsubu
  409. # define PTR_SUBIU dsubu
  410. # define PTR_L ld
  411. # define PTR_LA dla
  412. # define PTR_S sd
  413. # define PTR_SLL dsll
  414. # define PTR_SLLV dsllv
  415. # define PTR_SRL dsrl
  416. # define PTR_SRLV dsrlv
  417. # define PTR_SRA dsra
  418. # define PTR_SRAV dsrav
  419. # define PTR_SCALESHIFT 3
  420. #endif
  421. /*
  422. * Some cp0 registers were extended to 64bit for MIPS III.
  423. */
  424. #if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) || \
  425. (_MIPS_ISA == _MIPS_ISA_MIPS32)
  426. # define MFC0 mfc0
  427. # define MTC0 mtc0
  428. #endif
  429. #if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \
  430. (_MIPS_ISA == _MIPS_ISA_MIPS5) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
  431. # define MFC0 dmfc0
  432. # define MTC0 dmtc0
  433. #endif
  434. #endif /* sys/asm.h */