asm.h 12 KB

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