PageRenderTime 49ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/src/freebsd/sys/mips/include/asm.h

https://bitbucket.org/killerpenguinassassins/open_distrib_devel
C Header | 869 lines | 588 code | 82 blank | 199 comment | 30 complexity | 641f0532bf75800e74cec39703154b37 MD5 | raw file
Possible License(s): CC0-1.0, MIT, LGPL-2.0, LGPL-3.0, WTFPL, GPL-2.0, BSD-2-Clause, AGPL-3.0, CC-BY-SA-3.0, MPL-2.0, JSON, BSD-3-Clause-No-Nuclear-License-2014, LGPL-2.1, CPL-1.0, AGPL-1.0, 0BSD, ISC, Apache-2.0, GPL-3.0, IPL-1.0, MPL-2.0-no-copyleft-exception, BSD-3-Clause
  1. /* $NetBSD: asm.h,v 1.29 2000/12/14 21:29:51 jeffs Exp $ */
  2. /*
  3. * Copyright (c) 1992, 1993
  4. * The Regents of the University of California. All rights reserved.
  5. *
  6. * This code is derived from software contributed to Berkeley by
  7. * Ralph Campbell.
  8. *
  9. * Redistribution and use in source and binary forms, with or without
  10. * modification, are permitted provided that the following conditions
  11. * are met:
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. * 2. Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in the
  16. * documentation and/or other materials provided with the distribution.
  17. * 4. Neither the name of the University nor the names of its contributors
  18. * may be used to endorse or promote products derived from this software
  19. * without specific prior written permission.
  20. *
  21. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31. * SUCH DAMAGE.
  32. *
  33. * @(#)machAsmDefs.h 8.1 (Berkeley) 6/10/93
  34. * JNPR: asm.h,v 1.10 2007/08/09 11:23:32 katta
  35. * $FreeBSD$
  36. */
  37. /*
  38. * machAsmDefs.h --
  39. *
  40. * Macros used when writing assembler programs.
  41. *
  42. * Copyright (C) 1989 Digital Equipment Corporation.
  43. * Permission to use, copy, modify, and distribute this software and
  44. * its documentation for any purpose and without fee is hereby granted,
  45. * provided that the above copyright notice appears in all copies.
  46. * Digital Equipment Corporation makes no representations about the
  47. * suitability of this software for any purpose. It is provided "as is"
  48. * without express or implied warranty.
  49. *
  50. * from: Header: /sprite/src/kernel/mach/ds3100.md/RCS/machAsmDefs.h,
  51. * v 1.2 89/08/15 18:28:24 rab Exp SPRITE (DECWRL)
  52. */
  53. #ifndef _MACHINE_ASM_H_
  54. #define _MACHINE_ASM_H_
  55. #ifndef NO_REG_DEFS
  56. #include <machine/regdef.h>
  57. #endif
  58. #include <machine/endian.h>
  59. #include <machine/cdefs.h>
  60. #undef __FBSDID
  61. #if !defined(lint) && !defined(STRIP_FBSDID)
  62. #define __FBSDID(s) .ident s
  63. #else
  64. #define __FBSDID(s) /* nothing */
  65. #endif
  66. /*
  67. * Define -pg profile entry code.
  68. * Must always be noreorder, must never use a macro instruction
  69. * Final addiu to t9 must always equal the size of this _KERN_MCOUNT
  70. */
  71. #define _KERN_MCOUNT \
  72. .set push; \
  73. .set noreorder; \
  74. .set noat; \
  75. subu sp,sp,16; \
  76. sw t9,12(sp); \
  77. move AT,ra; \
  78. lui t9,%hi(_mcount); \
  79. addiu t9,t9,%lo(_mcount); \
  80. jalr t9; \
  81. nop; \
  82. lw t9,4(sp); \
  83. addiu sp,sp,8; \
  84. addiu t9,t9,40; \
  85. .set pop;
  86. #ifdef GPROF
  87. #define MCOUNT _KERN_MCOUNT
  88. #else
  89. #define MCOUNT
  90. #endif
  91. #define _C_LABEL(x) x
  92. #ifdef USE_AENT
  93. #define AENT(x) \
  94. .aent x, 0
  95. #else
  96. #define AENT(x)
  97. #endif
  98. /*
  99. * WARN_REFERENCES: create a warning if the specified symbol is referenced
  100. */
  101. #define WARN_REFERENCES(_sym,_msg) \
  102. .section .gnu.warning. ## _sym ; .ascii _msg ; .text
  103. /*
  104. * These are temp registers whose names can be used in either the old
  105. * or new ABI, although they map to different physical registers. In
  106. * the old ABI, they map to t4-t7, and in the new ABI, they map to a4-a7.
  107. *
  108. * Because they overlap with the last 4 arg regs in the new ABI, ta0-ta3
  109. * should be used only when we need more than t0-t3.
  110. */
  111. #if defined(__mips_n32) || defined(__mips_n64)
  112. #define ta0 $8
  113. #define ta1 $9
  114. #define ta2 $10
  115. #define ta3 $11
  116. #else
  117. #define ta0 $12
  118. #define ta1 $13
  119. #define ta2 $14
  120. #define ta3 $15
  121. #endif /* __mips_n32 || __mips_n64 */
  122. #ifdef __ELF__
  123. # define _C_LABEL(x) x
  124. #else
  125. # define _C_LABEL(x) _ ## x
  126. #endif
  127. /*
  128. * WEAK_ALIAS: create a weak alias.
  129. */
  130. #define WEAK_ALIAS(alias,sym) \
  131. .weak alias; \
  132. alias = sym
  133. /*
  134. * STRONG_ALIAS: create a strong alias.
  135. */
  136. #define STRONG_ALIAS(alias,sym) \
  137. .globl alias; \
  138. alias = sym
  139. #define GLOBAL(sym) \
  140. .globl sym; sym:
  141. #define ENTRY(sym) \
  142. .text; .globl sym; .ent sym; sym:
  143. #define ASM_ENTRY(sym) \
  144. .text; .globl sym; .type sym,@function; sym:
  145. /*
  146. * LEAF
  147. * A leaf routine does
  148. * - call no other function,
  149. * - never use any register that callee-saved (S0-S8), and
  150. * - not use any local stack storage.
  151. */
  152. #define LEAF(x) \
  153. .globl _C_LABEL(x); \
  154. .ent _C_LABEL(x), 0; \
  155. _C_LABEL(x): ; \
  156. .frame sp, 0, ra; \
  157. MCOUNT
  158. /*
  159. * LEAF_NOPROFILE
  160. * No profilable leaf routine.
  161. */
  162. #define LEAF_NOPROFILE(x) \
  163. .globl _C_LABEL(x); \
  164. .ent _C_LABEL(x), 0; \
  165. _C_LABEL(x): ; \
  166. .frame sp, 0, ra
  167. /*
  168. * XLEAF
  169. * declare alternate entry to leaf routine
  170. */
  171. #define XLEAF(x) \
  172. .globl _C_LABEL(x); \
  173. AENT (_C_LABEL(x)); \
  174. _C_LABEL(x):
  175. /*
  176. * NESTED
  177. * A function calls other functions and needs
  178. * therefore stack space to save/restore registers.
  179. */
  180. #define NESTED(x, fsize, retpc) \
  181. .globl _C_LABEL(x); \
  182. .ent _C_LABEL(x), 0; \
  183. _C_LABEL(x): ; \
  184. .frame sp, fsize, retpc; \
  185. MCOUNT
  186. /*
  187. * NESTED_NOPROFILE(x)
  188. * No profilable nested routine.
  189. */
  190. #define NESTED_NOPROFILE(x, fsize, retpc) \
  191. .globl _C_LABEL(x); \
  192. .ent _C_LABEL(x), 0; \
  193. _C_LABEL(x): ; \
  194. .frame sp, fsize, retpc
  195. /*
  196. * XNESTED
  197. * declare alternate entry point to nested routine.
  198. */
  199. #define XNESTED(x) \
  200. .globl _C_LABEL(x); \
  201. AENT (_C_LABEL(x)); \
  202. _C_LABEL(x):
  203. /*
  204. * END
  205. * Mark end of a procedure.
  206. */
  207. #define END(x) \
  208. .end _C_LABEL(x)
  209. /*
  210. * IMPORT -- import external symbol
  211. */
  212. #define IMPORT(sym, size) \
  213. .extern _C_LABEL(sym),size
  214. /*
  215. * EXPORT -- export definition of symbol
  216. */
  217. #define EXPORT(x) \
  218. .globl _C_LABEL(x); \
  219. _C_LABEL(x):
  220. /*
  221. * VECTOR
  222. * exception vector entrypoint
  223. * XXX: regmask should be used to generate .mask
  224. */
  225. #define VECTOR(x, regmask) \
  226. .ent _C_LABEL(x),0; \
  227. EXPORT(x); \
  228. #define VECTOR_END(x) \
  229. EXPORT(x ## End); \
  230. END(x)
  231. /*
  232. * Macros to panic and printf from assembly language.
  233. */
  234. #define PANIC(msg) \
  235. PTR_LA a0, 9f; \
  236. jal _C_LABEL(panic); \
  237. nop; \
  238. MSG(msg)
  239. #define PANIC_KSEG0(msg, reg) PANIC(msg)
  240. #define PRINTF(msg) \
  241. PTR_LA a0, 9f; \
  242. jal _C_LABEL(printf); \
  243. nop; \
  244. MSG(msg)
  245. #define MSG(msg) \
  246. .rdata; \
  247. 9: .asciiz msg; \
  248. .text
  249. #define ASMSTR(str) \
  250. .asciiz str; \
  251. .align 3
  252. /*
  253. * Call ast if required
  254. *
  255. * XXX Do we really need to disable interrupts?
  256. */
  257. #define DO_AST \
  258. 44: \
  259. mfc0 t0, MIPS_COP_0_STATUS ;\
  260. and a0, t0, MIPS_SR_INT_IE ;\
  261. xor t0, a0, t0 ;\
  262. mtc0 t0, MIPS_COP_0_STATUS ;\
  263. COP0_SYNC ;\
  264. GET_CPU_PCPU(s1) ;\
  265. PTR_L s3, PC_CURPCB(s1) ;\
  266. PTR_L s1, PC_CURTHREAD(s1) ;\
  267. lw s2, TD_FLAGS(s1) ;\
  268. li s0, TDF_ASTPENDING | TDF_NEEDRESCHED;\
  269. and s2, s0 ;\
  270. mfc0 t0, MIPS_COP_0_STATUS ;\
  271. or t0, a0, t0 ;\
  272. mtc0 t0, MIPS_COP_0_STATUS ;\
  273. COP0_SYNC ;\
  274. beq s2, zero, 4f ;\
  275. nop ;\
  276. PTR_LA s0, _C_LABEL(ast) ;\
  277. jalr s0 ;\
  278. PTR_ADDU a0, s3, U_PCB_REGS ;\
  279. j 44b ;\
  280. nop ;\
  281. 4:
  282. /*
  283. * XXX retain dialects XXX
  284. */
  285. #define ALEAF(x) XLEAF(x)
  286. #define NLEAF(x) LEAF_NOPROFILE(x)
  287. #define NON_LEAF(x, fsize, retpc) NESTED(x, fsize, retpc)
  288. #define NNON_LEAF(x, fsize, retpc) NESTED_NOPROFILE(x, fsize, retpc)
  289. #if defined(__mips_o32)
  290. #define SZREG 4
  291. #else
  292. #define SZREG 8
  293. #endif
  294. #if defined(__mips_o32) || defined(__mips_o64)
  295. #define ALSK 7 /* stack alignment */
  296. #define ALMASK -7 /* stack alignment */
  297. #define SZFPREG 4
  298. #define FP_L lwc1
  299. #define FP_S swc1
  300. #else
  301. #define ALSK 15 /* stack alignment */
  302. #define ALMASK -15 /* stack alignment */
  303. #define SZFPREG 8
  304. #define FP_L ldc1
  305. #define FP_S sdc1
  306. #endif
  307. /*
  308. * standard callframe {
  309. * register_t cf_pad[N]; o32/64 (N=0), n32 (N=1) n64 (N=1)
  310. * register_t cf_args[4]; arg0 - arg3 (only on o32 and o64)
  311. * register_t cf_gp; global pointer (only on n32 and n64)
  312. * register_t cf_sp; frame pointer
  313. * register_t cf_ra; return address
  314. * };
  315. */
  316. #if defined(__mips_o32) || defined(__mips_o64)
  317. #define CALLFRAME_SIZ (SZREG * (4 + 2))
  318. #define CALLFRAME_S0 0
  319. #elif defined(__mips_n32) || defined(__mips_n64)
  320. #define CALLFRAME_SIZ (SZREG * 4)
  321. #define CALLFRAME_S0 (CALLFRAME_SIZ - 4 * SZREG)
  322. #endif
  323. #ifndef _KERNEL
  324. #define CALLFRAME_GP (CALLFRAME_SIZ - 3 * SZREG)
  325. #endif
  326. #define CALLFRAME_SP (CALLFRAME_SIZ - 2 * SZREG)
  327. #define CALLFRAME_RA (CALLFRAME_SIZ - 1 * SZREG)
  328. /*
  329. * Endian-independent assembly-code aliases for unaligned memory accesses.
  330. */
  331. #if _BYTE_ORDER == _LITTLE_ENDIAN
  332. # define LWHI lwr
  333. # define LWLO lwl
  334. # define SWHI swr
  335. # define SWLO swl
  336. # if SZREG == 4
  337. # define REG_LHI lwr
  338. # define REG_LLO lwl
  339. # define REG_SHI swr
  340. # define REG_SLO swl
  341. # else
  342. # define REG_LHI ldr
  343. # define REG_LLO ldl
  344. # define REG_SHI sdr
  345. # define REG_SLO sdl
  346. # endif
  347. #endif
  348. #if _BYTE_ORDER == _BIG_ENDIAN
  349. # define LWHI lwl
  350. # define LWLO lwr
  351. # define SWHI swl
  352. # define SWLO swr
  353. # if SZREG == 4
  354. # define REG_LHI lwl
  355. # define REG_LLO lwr
  356. # define REG_SHI swl
  357. # define REG_SLO swr
  358. # else
  359. # define REG_LHI ldl
  360. # define REG_LLO ldr
  361. # define REG_SHI sdl
  362. # define REG_SLO sdr
  363. # endif
  364. #endif
  365. /*
  366. * While it would be nice to be compatible with the SGI
  367. * REG_L and REG_S macros, because they do not take parameters, it
  368. * is impossible to use them with the _MIPS_SIM_ABIX32 model.
  369. *
  370. * These macros hide the use of mips3 instructions from the
  371. * assembler to prevent the assembler from generating 64-bit style
  372. * ABI calls.
  373. */
  374. #if _MIPS_SZPTR == 32
  375. #define PTR_ADD add
  376. #define PTR_ADDI addi
  377. #define PTR_ADDU addu
  378. #define PTR_ADDIU addiu
  379. #define PTR_SUB add
  380. #define PTR_SUBI subi
  381. #define PTR_SUBU subu
  382. #define PTR_SUBIU subu
  383. #define PTR_L lw
  384. #define PTR_LA la
  385. #define PTR_LI li
  386. #define PTR_S sw
  387. #define PTR_SLL sll
  388. #define PTR_SLLV sllv
  389. #define PTR_SRL srl
  390. #define PTR_SRLV srlv
  391. #define PTR_SRA sra
  392. #define PTR_SRAV srav
  393. #define PTR_LL ll
  394. #define PTR_SC sc
  395. #define PTR_WORD .word
  396. #define PTR_SCALESHIFT 2
  397. #else /* _MIPS_SZPTR == 64 */
  398. #define PTR_ADD dadd
  399. #define PTR_ADDI daddi
  400. #define PTR_ADDU daddu
  401. #define PTR_ADDIU daddiu
  402. #define PTR_SUB dadd
  403. #define PTR_SUBI dsubi
  404. #define PTR_SUBU dsubu
  405. #define PTR_SUBIU dsubu
  406. #define PTR_L ld
  407. #define PTR_LA dla
  408. #define PTR_LI dli
  409. #define PTR_S sd
  410. #define PTR_SLL dsll
  411. #define PTR_SLLV dsllv
  412. #define PTR_SRL dsrl
  413. #define PTR_SRLV dsrlv
  414. #define PTR_SRA dsra
  415. #define PTR_SRAV dsrav
  416. #define PTR_LL lld
  417. #define PTR_SC scd
  418. #define PTR_WORD .dword
  419. #define PTR_SCALESHIFT 3
  420. #endif /* _MIPS_SZPTR == 64 */
  421. #if _MIPS_SZINT == 32
  422. #define INT_ADD add
  423. #define INT_ADDI addi
  424. #define INT_ADDU addu
  425. #define INT_ADDIU addiu
  426. #define INT_SUB add
  427. #define INT_SUBI subi
  428. #define INT_SUBU subu
  429. #define INT_SUBIU subu
  430. #define INT_L lw
  431. #define INT_LA la
  432. #define INT_S sw
  433. #define INT_SLL sll
  434. #define INT_SLLV sllv
  435. #define INT_SRL srl
  436. #define INT_SRLV srlv
  437. #define INT_SRA sra
  438. #define INT_SRAV srav
  439. #define INT_LL ll
  440. #define INT_SC sc
  441. #define INT_WORD .word
  442. #define INT_SCALESHIFT 2
  443. #else
  444. #define INT_ADD dadd
  445. #define INT_ADDI daddi
  446. #define INT_ADDU daddu
  447. #define INT_ADDIU daddiu
  448. #define INT_SUB dadd
  449. #define INT_SUBI dsubi
  450. #define INT_SUBU dsubu
  451. #define INT_SUBIU dsubu
  452. #define INT_L ld
  453. #define INT_LA dla
  454. #define INT_S sd
  455. #define INT_SLL dsll
  456. #define INT_SLLV dsllv
  457. #define INT_SRL dsrl
  458. #define INT_SRLV dsrlv
  459. #define INT_SRA dsra
  460. #define INT_SRAV dsrav
  461. #define INT_LL lld
  462. #define INT_SC scd
  463. #define INT_WORD .dword
  464. #define INT_SCALESHIFT 3
  465. #endif
  466. #if _MIPS_SZLONG == 32
  467. #define LONG_ADD add
  468. #define LONG_ADDI addi
  469. #define LONG_ADDU addu
  470. #define LONG_ADDIU addiu
  471. #define LONG_SUB add
  472. #define LONG_SUBI subi
  473. #define LONG_SUBU subu
  474. #define LONG_SUBIU subu
  475. #define LONG_L lw
  476. #define LONG_LA la
  477. #define LONG_S sw
  478. #define LONG_SLL sll
  479. #define LONG_SLLV sllv
  480. #define LONG_SRL srl
  481. #define LONG_SRLV srlv
  482. #define LONG_SRA sra
  483. #define LONG_SRAV srav
  484. #define LONG_LL ll
  485. #define LONG_SC sc
  486. #define LONG_WORD .word
  487. #define LONG_SCALESHIFT 2
  488. #else
  489. #define LONG_ADD dadd
  490. #define LONG_ADDI daddi
  491. #define LONG_ADDU daddu
  492. #define LONG_ADDIU daddiu
  493. #define LONG_SUB dadd
  494. #define LONG_SUBI dsubi
  495. #define LONG_SUBU dsubu
  496. #define LONG_SUBIU dsubu
  497. #define LONG_L ld
  498. #define LONG_LA dla
  499. #define LONG_S sd
  500. #define LONG_SLL dsll
  501. #define LONG_SLLV dsllv
  502. #define LONG_SRL dsrl
  503. #define LONG_SRLV dsrlv
  504. #define LONG_SRA dsra
  505. #define LONG_SRAV dsrav
  506. #define LONG_LL lld
  507. #define LONG_SC scd
  508. #define LONG_WORD .dword
  509. #define LONG_SCALESHIFT 3
  510. #endif
  511. #if SZREG == 4
  512. #define REG_L lw
  513. #define REG_S sw
  514. #define REG_LI li
  515. #define REG_ADDU addu
  516. #define REG_SLL sll
  517. #define REG_SLLV sllv
  518. #define REG_SRL srl
  519. #define REG_SRLV srlv
  520. #define REG_SRA sra
  521. #define REG_SRAV srav
  522. #define REG_LL ll
  523. #define REG_SC sc
  524. #define REG_SCALESHIFT 2
  525. #else
  526. #define REG_L ld
  527. #define REG_S sd
  528. #define REG_LI dli
  529. #define REG_ADDU daddu
  530. #define REG_SLL dsll
  531. #define REG_SLLV dsllv
  532. #define REG_SRL dsrl
  533. #define REG_SRLV dsrlv
  534. #define REG_SRA dsra
  535. #define REG_SRAV dsrav
  536. #define REG_LL lld
  537. #define REG_SC scd
  538. #define REG_SCALESHIFT 3
  539. #endif
  540. #if _MIPS_ISA == _MIPS_ISA_MIPS1 || _MIPS_ISA == _MIPS_ISA_MIPS2 || \
  541. _MIPS_ISA == _MIPS_ISA_MIPS32
  542. #define MFC0 mfc0
  543. #define MTC0 mtc0
  544. #endif
  545. #if _MIPS_ISA == _MIPS_ISA_MIPS3 || _MIPS_ISA == _MIPS_ISA_MIPS4 || \
  546. _MIPS_ISA == _MIPS_ISA_MIPS64
  547. #define MFC0 dmfc0
  548. #define MTC0 dmtc0
  549. #endif
  550. #if defined(__mips_o32) || defined(__mips_o64)
  551. #ifdef __ABICALLS__
  552. #define CPRESTORE(r) .cprestore r
  553. #define CPLOAD(r) .cpload r
  554. #else
  555. #define CPRESTORE(r) /* not needed */
  556. #define CPLOAD(r) /* not needed */
  557. #endif
  558. #define SETUP_GP \
  559. .set push; \
  560. .set noreorder; \
  561. .cpload t9; \
  562. .set pop
  563. #define SETUP_GPX(r) \
  564. .set push; \
  565. .set noreorder; \
  566. move r,ra; /* save old ra */ \
  567. bal 7f; \
  568. nop; \
  569. 7: .cpload ra; \
  570. move ra,r; \
  571. .set pop
  572. #define SETUP_GPX_L(r,lbl) \
  573. .set push; \
  574. .set noreorder; \
  575. move r,ra; /* save old ra */ \
  576. bal lbl; \
  577. nop; \
  578. lbl: .cpload ra; \
  579. move ra,r; \
  580. .set pop
  581. #define SAVE_GP(x) .cprestore x
  582. #define SETUP_GP64(a,b) /* n32/n64 specific */
  583. #define SETUP_GP64_R(a,b) /* n32/n64 specific */
  584. #define SETUP_GPX64(a,b) /* n32/n64 specific */
  585. #define SETUP_GPX64_L(a,b,c) /* n32/n64 specific */
  586. #define RESTORE_GP64 /* n32/n64 specific */
  587. #define USE_ALT_CP(a) /* n32/n64 specific */
  588. #endif /* __mips_o32 || __mips_o64 */
  589. #if defined(__mips_o32) || defined(__mips_o64)
  590. #define REG_PROLOGUE .set push
  591. #define REG_EPILOGUE .set pop
  592. #endif
  593. #if defined(__mips_n32) || defined(__mips_n64)
  594. #define REG_PROLOGUE .set push ; .set mips3
  595. #define REG_EPILOGUE .set pop
  596. #endif
  597. #if defined(__mips_n32) || defined(__mips_n64)
  598. #define SETUP_GP /* o32 specific */
  599. #define SETUP_GPX(r) /* o32 specific */
  600. #define SETUP_GPX_L(r,lbl) /* o32 specific */
  601. #define SAVE_GP(x) /* o32 specific */
  602. #define SETUP_GP64(a,b) .cpsetup $25, a, b
  603. #define SETUP_GPX64(a,b) \
  604. .set push; \
  605. move b,ra; \
  606. .set noreorder; \
  607. bal 7f; \
  608. nop; \
  609. 7: .set pop; \
  610. .cpsetup ra, a, 7b; \
  611. move ra,b
  612. #define SETUP_GPX64_L(a,b,c) \
  613. .set push; \
  614. move b,ra; \
  615. .set noreorder; \
  616. bal c; \
  617. nop; \
  618. c: .set pop; \
  619. .cpsetup ra, a, c; \
  620. move ra,b
  621. #define RESTORE_GP64 .cpreturn
  622. #define USE_ALT_CP(a) .cplocal a
  623. #endif /* __mips_n32 || __mips_n64 */
  624. #define mfc0_macro(data, spr) \
  625. __asm __volatile ("mfc0 %0, $%1" \
  626. : "=r" (data) /* outputs */ \
  627. : "i" (spr)); /* inputs */
  628. #define mtc0_macro(data, spr) \
  629. __asm __volatile ("mtc0 %0, $%1" \
  630. : /* outputs */ \
  631. : "r" (data), "i" (spr)); /* inputs */
  632. #define cfc0_macro(data, spr) \
  633. __asm __volatile ("cfc0 %0, $%1" \
  634. : "=r" (data) /* outputs */ \
  635. : "i" (spr)); /* inputs */
  636. #define ctc0_macro(data, spr) \
  637. __asm __volatile ("ctc0 %0, $%1" \
  638. : /* outputs */ \
  639. : "r" (data), "i" (spr)); /* inputs */
  640. #define lbu_macro(data, addr) \
  641. __asm __volatile ("lbu %0, 0x0(%1)" \
  642. : "=r" (data) /* outputs */ \
  643. : "r" (addr)); /* inputs */
  644. #define lb_macro(data, addr) \
  645. __asm __volatile ("lb %0, 0x0(%1)" \
  646. : "=r" (data) /* outputs */ \
  647. : "r" (addr)); /* inputs */
  648. #define lwl_macro(data, addr) \
  649. __asm __volatile ("lwl %0, 0x0(%1)" \
  650. : "=r" (data) /* outputs */ \
  651. : "r" (addr)); /* inputs */
  652. #define lwr_macro(data, addr) \
  653. __asm __volatile ("lwr %0, 0x0(%1)" \
  654. : "=r" (data) /* outputs */ \
  655. : "r" (addr)); /* inputs */
  656. #define ldl_macro(data, addr) \
  657. __asm __volatile ("ldl %0, 0x0(%1)" \
  658. : "=r" (data) /* outputs */ \
  659. : "r" (addr)); /* inputs */
  660. #define ldr_macro(data, addr) \
  661. __asm __volatile ("ldr %0, 0x0(%1)" \
  662. : "=r" (data) /* outputs */ \
  663. : "r" (addr)); /* inputs */
  664. #define sb_macro(data, addr) \
  665. __asm __volatile ("sb %0, 0x0(%1)" \
  666. : /* outputs */ \
  667. : "r" (data), "r" (addr)); /* inputs */
  668. #define swl_macro(data, addr) \
  669. __asm __volatile ("swl %0, 0x0(%1)" \
  670. : /* outputs */ \
  671. : "r" (data), "r" (addr)); /* inputs */
  672. #define swr_macro(data, addr) \
  673. __asm __volatile ("swr %0, 0x0(%1)" \
  674. : /* outputs */ \
  675. : "r" (data), "r" (addr)); /* inputs */
  676. #define sdl_macro(data, addr) \
  677. __asm __volatile ("sdl %0, 0x0(%1)" \
  678. : /* outputs */ \
  679. : "r" (data), "r" (addr)); /* inputs */
  680. #define sdr_macro(data, addr) \
  681. __asm __volatile ("sdr %0, 0x0(%1)" \
  682. : /* outputs */ \
  683. : "r" (data), "r" (addr)); /* inputs */
  684. #define mfgr_macro(data, gr) \
  685. __asm __volatile ("move %0, $%1" \
  686. : "=r" (data) /* outputs */ \
  687. : "i" (gr)); /* inputs */
  688. #define dmfc0_macro(data, spr) \
  689. __asm __volatile ("dmfc0 %0, $%1" \
  690. : "=r" (data) /* outputs */ \
  691. : "i" (spr)); /* inputs */
  692. #define dmtc0_macro(data, spr, sel) \
  693. __asm __volatile ("dmtc0 %0, $%1, %2" \
  694. : /* no outputs */ \
  695. : "r" (data), "i" (spr), "i" (sel)); /* inputs */
  696. /*
  697. * The DYNAMIC_STATUS_MASK option adds an additional masking operation
  698. * when updating the hardware interrupt mask in the status register.
  699. *
  700. * This is useful for platforms that need to at run-time mask
  701. * interrupts based on motherboard configuration or to handle
  702. * slowly clearing interrupts.
  703. *
  704. * XXX this is only currently implemented for mips3.
  705. */
  706. #ifdef MIPS_DYNAMIC_STATUS_MASK
  707. #define DYNAMIC_STATUS_MASK(sr,scratch) \
  708. lw scratch, mips_dynamic_status_mask; \
  709. and sr, sr, scratch
  710. #define DYNAMIC_STATUS_MASK_TOUSER(sr,scratch1) \
  711. ori sr, (MIPS_INT_MASK | MIPS_SR_INT_IE); \
  712. DYNAMIC_STATUS_MASK(sr,scratch1)
  713. #else
  714. #define DYNAMIC_STATUS_MASK(sr,scratch)
  715. #define DYNAMIC_STATUS_MASK_TOUSER(sr,scratch1)
  716. #endif
  717. #define GET_CPU_PCPU(reg) \
  718. PTR_L reg, _C_LABEL(pcpup);
  719. /*
  720. * Description of the setjmp buffer
  721. *
  722. * word 0 magic number (dependant on creator)
  723. * 1 RA
  724. * 2 S0
  725. * 3 S1
  726. * 4 S2
  727. * 5 S3
  728. * 6 S4
  729. * 7 S5
  730. * 8 S6
  731. * 9 S7
  732. * 10 SP
  733. * 11 S8
  734. * 12 GP (dependent on ABI)
  735. * 13 signal mask (dependant on magic)
  736. * 14 (con't)
  737. * 15 (con't)
  738. * 16 (con't)
  739. *
  740. * The magic number number identifies the jmp_buf and
  741. * how the buffer was created as well as providing
  742. * a sanity check
  743. *
  744. */
  745. #define _JB_MAGIC__SETJMP 0xBADFACED
  746. #define _JB_MAGIC_SETJMP 0xFACEDBAD
  747. /* Valid for all jmp_buf's */
  748. #define _JB_MAGIC 0
  749. #define _JB_REG_RA 1
  750. #define _JB_REG_S0 2
  751. #define _JB_REG_S1 3
  752. #define _JB_REG_S2 4
  753. #define _JB_REG_S3 5
  754. #define _JB_REG_S4 6
  755. #define _JB_REG_S5 7
  756. #define _JB_REG_S6 8
  757. #define _JB_REG_S7 9
  758. #define _JB_REG_SP 10
  759. #define _JB_REG_S8 11
  760. #if defined(__mips_n32) || defined(__mips_n64)
  761. #define _JB_REG_GP 12
  762. #endif
  763. /* Only valid with the _JB_MAGIC_SETJMP magic */
  764. #define _JB_SIGMASK 13
  765. /*
  766. * Various macros for dealing with TLB hazards
  767. * (a) why so many?
  768. * (b) when to use?
  769. * (c) why not used everywhere?
  770. */
  771. /*
  772. * Assume that w alaways need nops to escape CP0 hazard
  773. * TODO: Make hazard delays configurable. Stuck with 5 cycles on the moment
  774. * For more info on CP0 hazards see Chapter 7 (p.99) of "MIPS32 Architecture
  775. * For Programmers Volume III: The MIPS32 Privileged Resource Architecture"
  776. */
  777. #if defined(CPU_NLM)
  778. #define HAZARD_DELAY sll $0,3
  779. #define ITLBNOPFIX sll $0,3
  780. #elif defined(CPU_RMI)
  781. #define HAZARD_DELAY
  782. #define ITLBNOPFIX
  783. #else
  784. #define ITLBNOPFIX nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;
  785. #define HAZARD_DELAY nop;nop;nop;nop;nop;
  786. #endif
  787. #endif /* !_MACHINE_ASM_H_ */