r4k_fpu.S 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. /*
  2. * This file is subject to the terms and conditions of the GNU General Public
  3. * License. See the file "COPYING" in the main directory of this archive
  4. * for more details.
  5. *
  6. * Copyright (C) 1996, 98, 99, 2000, 01 Ralf Baechle
  7. *
  8. * Multi-arch abstraction and asm macros for easier reading:
  9. * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
  10. *
  11. * Carsten Langgaard, carstenl@mips.com
  12. * Copyright (C) 2000 MIPS Technologies, Inc.
  13. * Copyright (C) 1999, 2001 Silicon Graphics, Inc.
  14. */
  15. #include <asm/asm.h>
  16. #include <asm/asmmacro.h>
  17. #include <asm/errno.h>
  18. #include <asm/fpregdef.h>
  19. #include <asm/mipsregs.h>
  20. #include <asm/asm-offsets.h>
  21. #include <asm/regdef.h>
  22. /* preprocessor replaces the fp in ".set fp=64" with $30 otherwise */
  23. #undef fp
  24. .macro EX insn, reg, src
  25. .set push
  26. SET_HARDFLOAT
  27. .set nomacro
  28. .ex\@: \insn \reg, \src
  29. .set pop
  30. .section __ex_table,"a"
  31. PTR .ex\@, fault
  32. .previous
  33. .endm
  34. .set noreorder
  35. /**
  36. * _save_fp_context() - save FP context from the FPU
  37. * @a0 - pointer to fpregs field of sigcontext
  38. * @a1 - pointer to fpc_csr field of sigcontext
  39. *
  40. * Save FP context, including the 32 FP data registers and the FP
  41. * control & status register, from the FPU to signal context.
  42. */
  43. LEAF(_save_fp_context)
  44. .set push
  45. SET_HARDFLOAT
  46. cfc1 t1, fcr31
  47. .set pop
  48. #if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2) || \
  49. defined(CONFIG_CPU_MIPS32_R6)
  50. .set push
  51. SET_HARDFLOAT
  52. #ifdef CONFIG_CPU_MIPS32_R2
  53. .set mips32r2
  54. .set fp=64
  55. mfc0 t0, CP0_STATUS
  56. sll t0, t0, 5
  57. bgez t0, 1f # skip storing odd if FR=0
  58. nop
  59. #endif
  60. /* Store the 16 odd double precision registers */
  61. EX sdc1 $f1, 8(a0)
  62. EX sdc1 $f3, 24(a0)
  63. EX sdc1 $f5, 40(a0)
  64. EX sdc1 $f7, 56(a0)
  65. EX sdc1 $f9, 72(a0)
  66. EX sdc1 $f11, 88(a0)
  67. EX sdc1 $f13, 104(a0)
  68. EX sdc1 $f15, 120(a0)
  69. EX sdc1 $f17, 136(a0)
  70. EX sdc1 $f19, 152(a0)
  71. EX sdc1 $f21, 168(a0)
  72. EX sdc1 $f23, 184(a0)
  73. EX sdc1 $f25, 200(a0)
  74. EX sdc1 $f27, 216(a0)
  75. EX sdc1 $f29, 232(a0)
  76. EX sdc1 $f31, 248(a0)
  77. 1: .set pop
  78. #endif
  79. .set push
  80. SET_HARDFLOAT
  81. /* Store the 16 even double precision registers */
  82. EX sdc1 $f0, 0(a0)
  83. EX sdc1 $f2, 16(a0)
  84. EX sdc1 $f4, 32(a0)
  85. EX sdc1 $f6, 48(a0)
  86. EX sdc1 $f8, 64(a0)
  87. EX sdc1 $f10, 80(a0)
  88. EX sdc1 $f12, 96(a0)
  89. EX sdc1 $f14, 112(a0)
  90. EX sdc1 $f16, 128(a0)
  91. EX sdc1 $f18, 144(a0)
  92. EX sdc1 $f20, 160(a0)
  93. EX sdc1 $f22, 176(a0)
  94. EX sdc1 $f24, 192(a0)
  95. EX sdc1 $f26, 208(a0)
  96. EX sdc1 $f28, 224(a0)
  97. EX sdc1 $f30, 240(a0)
  98. EX sw t1, 0(a1)
  99. jr ra
  100. li v0, 0 # success
  101. .set pop
  102. END(_save_fp_context)
  103. /**
  104. * _restore_fp_context() - restore FP context to the FPU
  105. * @a0 - pointer to fpregs field of sigcontext
  106. * @a1 - pointer to fpc_csr field of sigcontext
  107. *
  108. * Restore FP context, including the 32 FP data registers and the FP
  109. * control & status register, from signal context to the FPU.
  110. */
  111. LEAF(_restore_fp_context)
  112. EX lw t1, 0(a1)
  113. #if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2) || \
  114. defined(CONFIG_CPU_MIPS32_R6)
  115. .set push
  116. SET_HARDFLOAT
  117. #ifdef CONFIG_CPU_MIPS32_R2
  118. .set mips32r2
  119. .set fp=64
  120. mfc0 t0, CP0_STATUS
  121. sll t0, t0, 5
  122. bgez t0, 1f # skip loading odd if FR=0
  123. nop
  124. #endif
  125. EX ldc1 $f1, 8(a0)
  126. EX ldc1 $f3, 24(a0)
  127. EX ldc1 $f5, 40(a0)
  128. EX ldc1 $f7, 56(a0)
  129. EX ldc1 $f9, 72(a0)
  130. EX ldc1 $f11, 88(a0)
  131. EX ldc1 $f13, 104(a0)
  132. EX ldc1 $f15, 120(a0)
  133. EX ldc1 $f17, 136(a0)
  134. EX ldc1 $f19, 152(a0)
  135. EX ldc1 $f21, 168(a0)
  136. EX ldc1 $f23, 184(a0)
  137. EX ldc1 $f25, 200(a0)
  138. EX ldc1 $f27, 216(a0)
  139. EX ldc1 $f29, 232(a0)
  140. EX ldc1 $f31, 248(a0)
  141. 1: .set pop
  142. #endif
  143. .set push
  144. SET_HARDFLOAT
  145. EX ldc1 $f0, 0(a0)
  146. EX ldc1 $f2, 16(a0)
  147. EX ldc1 $f4, 32(a0)
  148. EX ldc1 $f6, 48(a0)
  149. EX ldc1 $f8, 64(a0)
  150. EX ldc1 $f10, 80(a0)
  151. EX ldc1 $f12, 96(a0)
  152. EX ldc1 $f14, 112(a0)
  153. EX ldc1 $f16, 128(a0)
  154. EX ldc1 $f18, 144(a0)
  155. EX ldc1 $f20, 160(a0)
  156. EX ldc1 $f22, 176(a0)
  157. EX ldc1 $f24, 192(a0)
  158. EX ldc1 $f26, 208(a0)
  159. EX ldc1 $f28, 224(a0)
  160. EX ldc1 $f30, 240(a0)
  161. ctc1 t1, fcr31
  162. .set pop
  163. jr ra
  164. li v0, 0 # success
  165. END(_restore_fp_context)
  166. #ifdef CONFIG_CPU_HAS_MSA
  167. .macro op_one_wr op, idx, base
  168. .align 4
  169. \idx: \op \idx, 0, \base
  170. jr ra
  171. nop
  172. .endm
  173. .macro op_msa_wr name, op
  174. LEAF(\name)
  175. .set push
  176. .set noreorder
  177. sll t0, a0, 4
  178. PTR_LA t1, 0f
  179. PTR_ADDU t0, t0, t1
  180. jr t0
  181. nop
  182. op_one_wr \op, 0, a1
  183. op_one_wr \op, 1, a1
  184. op_one_wr \op, 2, a1
  185. op_one_wr \op, 3, a1
  186. op_one_wr \op, 4, a1
  187. op_one_wr \op, 5, a1
  188. op_one_wr \op, 6, a1
  189. op_one_wr \op, 7, a1
  190. op_one_wr \op, 8, a1
  191. op_one_wr \op, 9, a1
  192. op_one_wr \op, 10, a1
  193. op_one_wr \op, 11, a1
  194. op_one_wr \op, 12, a1
  195. op_one_wr \op, 13, a1
  196. op_one_wr \op, 14, a1
  197. op_one_wr \op, 15, a1
  198. op_one_wr \op, 16, a1
  199. op_one_wr \op, 17, a1
  200. op_one_wr \op, 18, a1
  201. op_one_wr \op, 19, a1
  202. op_one_wr \op, 20, a1
  203. op_one_wr \op, 21, a1
  204. op_one_wr \op, 22, a1
  205. op_one_wr \op, 23, a1
  206. op_one_wr \op, 24, a1
  207. op_one_wr \op, 25, a1
  208. op_one_wr \op, 26, a1
  209. op_one_wr \op, 27, a1
  210. op_one_wr \op, 28, a1
  211. op_one_wr \op, 29, a1
  212. op_one_wr \op, 30, a1
  213. op_one_wr \op, 31, a1
  214. .set pop
  215. END(\name)
  216. .endm
  217. op_msa_wr read_msa_wr_b, st_b
  218. op_msa_wr read_msa_wr_h, st_h
  219. op_msa_wr read_msa_wr_w, st_w
  220. op_msa_wr read_msa_wr_d, st_d
  221. op_msa_wr write_msa_wr_b, ld_b
  222. op_msa_wr write_msa_wr_h, ld_h
  223. op_msa_wr write_msa_wr_w, ld_w
  224. op_msa_wr write_msa_wr_d, ld_d
  225. #endif /* CONFIG_CPU_HAS_MSA */
  226. #ifdef CONFIG_CPU_HAS_MSA
  227. .macro save_msa_upper wr, off, base
  228. .set push
  229. .set noat
  230. #ifdef CONFIG_64BIT
  231. copy_s_d \wr, 1
  232. EX sd $1, \off(\base)
  233. #elif defined(CONFIG_CPU_LITTLE_ENDIAN)
  234. copy_s_w \wr, 2
  235. EX sw $1, \off(\base)
  236. copy_s_w \wr, 3
  237. EX sw $1, (\off+4)(\base)
  238. #else /* CONFIG_CPU_BIG_ENDIAN */
  239. copy_s_w \wr, 2
  240. EX sw $1, (\off+4)(\base)
  241. copy_s_w \wr, 3
  242. EX sw $1, \off(\base)
  243. #endif
  244. .set pop
  245. .endm
  246. LEAF(_save_msa_all_upper)
  247. save_msa_upper 0, 0x00, a0
  248. save_msa_upper 1, 0x08, a0
  249. save_msa_upper 2, 0x10, a0
  250. save_msa_upper 3, 0x18, a0
  251. save_msa_upper 4, 0x20, a0
  252. save_msa_upper 5, 0x28, a0
  253. save_msa_upper 6, 0x30, a0
  254. save_msa_upper 7, 0x38, a0
  255. save_msa_upper 8, 0x40, a0
  256. save_msa_upper 9, 0x48, a0
  257. save_msa_upper 10, 0x50, a0
  258. save_msa_upper 11, 0x58, a0
  259. save_msa_upper 12, 0x60, a0
  260. save_msa_upper 13, 0x68, a0
  261. save_msa_upper 14, 0x70, a0
  262. save_msa_upper 15, 0x78, a0
  263. save_msa_upper 16, 0x80, a0
  264. save_msa_upper 17, 0x88, a0
  265. save_msa_upper 18, 0x90, a0
  266. save_msa_upper 19, 0x98, a0
  267. save_msa_upper 20, 0xa0, a0
  268. save_msa_upper 21, 0xa8, a0
  269. save_msa_upper 22, 0xb0, a0
  270. save_msa_upper 23, 0xb8, a0
  271. save_msa_upper 24, 0xc0, a0
  272. save_msa_upper 25, 0xc8, a0
  273. save_msa_upper 26, 0xd0, a0
  274. save_msa_upper 27, 0xd8, a0
  275. save_msa_upper 28, 0xe0, a0
  276. save_msa_upper 29, 0xe8, a0
  277. save_msa_upper 30, 0xf0, a0
  278. save_msa_upper 31, 0xf8, a0
  279. jr ra
  280. li v0, 0
  281. END(_save_msa_all_upper)
  282. .macro restore_msa_upper wr, off, base
  283. .set push
  284. .set noat
  285. #ifdef CONFIG_64BIT
  286. EX ld $1, \off(\base)
  287. insert_d \wr, 1
  288. #elif defined(CONFIG_CPU_LITTLE_ENDIAN)
  289. EX lw $1, \off(\base)
  290. insert_w \wr, 2
  291. EX lw $1, (\off+4)(\base)
  292. insert_w \wr, 3
  293. #else /* CONFIG_CPU_BIG_ENDIAN */
  294. EX lw $1, (\off+4)(\base)
  295. insert_w \wr, 2
  296. EX lw $1, \off(\base)
  297. insert_w \wr, 3
  298. #endif
  299. .set pop
  300. .endm
  301. LEAF(_restore_msa_all_upper)
  302. restore_msa_upper 0, 0x00, a0
  303. restore_msa_upper 1, 0x08, a0
  304. restore_msa_upper 2, 0x10, a0
  305. restore_msa_upper 3, 0x18, a0
  306. restore_msa_upper 4, 0x20, a0
  307. restore_msa_upper 5, 0x28, a0
  308. restore_msa_upper 6, 0x30, a0
  309. restore_msa_upper 7, 0x38, a0
  310. restore_msa_upper 8, 0x40, a0
  311. restore_msa_upper 9, 0x48, a0
  312. restore_msa_upper 10, 0x50, a0
  313. restore_msa_upper 11, 0x58, a0
  314. restore_msa_upper 12, 0x60, a0
  315. restore_msa_upper 13, 0x68, a0
  316. restore_msa_upper 14, 0x70, a0
  317. restore_msa_upper 15, 0x78, a0
  318. restore_msa_upper 16, 0x80, a0
  319. restore_msa_upper 17, 0x88, a0
  320. restore_msa_upper 18, 0x90, a0
  321. restore_msa_upper 19, 0x98, a0
  322. restore_msa_upper 20, 0xa0, a0
  323. restore_msa_upper 21, 0xa8, a0
  324. restore_msa_upper 22, 0xb0, a0
  325. restore_msa_upper 23, 0xb8, a0
  326. restore_msa_upper 24, 0xc0, a0
  327. restore_msa_upper 25, 0xc8, a0
  328. restore_msa_upper 26, 0xd0, a0
  329. restore_msa_upper 27, 0xd8, a0
  330. restore_msa_upper 28, 0xe0, a0
  331. restore_msa_upper 29, 0xe8, a0
  332. restore_msa_upper 30, 0xf0, a0
  333. restore_msa_upper 31, 0xf8, a0
  334. jr ra
  335. li v0, 0
  336. END(_restore_msa_all_upper)
  337. #endif /* CONFIG_CPU_HAS_MSA */
  338. .set reorder
  339. .type fault@function
  340. .ent fault
  341. fault: li v0, -EFAULT # failure
  342. jr ra
  343. .end fault