riscv_math_memory.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  1. /******************************************************************************
  2. * @file riscv_math_memory.h
  3. * @brief Public header file for NMSIS DSP Library
  4. * @version V1.10.0
  5. * @date 08 July 2021
  6. * Target Processor: RISC-V Cores
  7. ******************************************************************************/
  8. /*
  9. * Copyright (c) 2010-2021 Arm Limited or its affiliates. All rights reserved.
  10. * Copyright (c) 2019 Nuclei Limited. All rights reserved.
  11. *
  12. * SPDX-License-Identifier: Apache-2.0
  13. *
  14. * Licensed under the Apache License, Version 2.0 (the License); you may
  15. * not use this file except in compliance with the License.
  16. * You may obtain a copy of the License at
  17. *
  18. * www.apache.org/licenses/LICENSE-2.0
  19. *
  20. * Unless required by applicable law or agreed to in writing, software
  21. * distributed under the License is distributed on an AS IS BASIS, WITHOUT
  22. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  23. * See the License for the specific language governing permissions and
  24. * limitations under the License.
  25. */
  26. #ifndef RISCV_MATH_MEMORY_H_
  27. #define RISCV_MATH_MEMORY_H_
  28. #include "riscv_math_types.h"
  29. #ifdef __cplusplus
  30. extern "C"
  31. {
  32. #endif
  33. /**
  34. @brief definition to read/write two 16 bit values.
  35. @deprecated
  36. */
  37. #if defined ( __GNUC__ )
  38. #define __SIMD32_TYPE int32_t
  39. #elif defined ( __TI_RISCV__ )
  40. #define __SIMD32_TYPE int32_t
  41. #elif defined ( __CSMC__ )
  42. #define __SIMD32_TYPE int32_t
  43. #elif defined ( __TASKING__ )
  44. #define __SIMD32_TYPE __un(aligned) int32_t
  45. #elif defined(_MSC_VER )
  46. #define __SIMD32_TYPE int32_t
  47. #elif defined(__ICCRISCV__ )
  48. #define __SIMD32_TYPE int32_t
  49. #else
  50. #error Unknown compiler
  51. #endif
  52. #define __SIMD32(addr) (*(__SIMD32_TYPE **) & (addr))
  53. #define __SIMD32_CONST(addr) ( (__SIMD32_TYPE * ) (addr))
  54. #define _SIMD32_OFFSET(addr) (*(__SIMD32_TYPE * ) (addr))
  55. #define __SIMD64(addr) (*( int64_t **) & (addr))
  56. /* SIMD replacement */
  57. /**
  58. @brief Read 2 Q31 from Q31 pointer.
  59. @param[in] pQ31 points to input value
  60. @return Q63 value
  61. */
  62. __STATIC_FORCEINLINE q63_t read_q31x2 (
  63. q31_t const * pQ31)
  64. {
  65. q63_t val;
  66. #ifndef __RISCV_FEATURE_UNALIGNED
  67. #if __RISCV_XLEN == 64
  68. val = __LD((q31_t *)pQ31);
  69. #else
  70. val = *((q63_t *)pQ31);
  71. #endif /* __RISCV_XLEN == 64 */
  72. #else
  73. memcpy((void *)(&val), (void *)(pQ31), 8);
  74. #endif
  75. return (val);
  76. }
  77. /**
  78. @brief Read 2 Q31 from Q31 pointer and increment pointer afterwards.
  79. @param[in] pQ31 points to input value
  80. @return Q63 value
  81. */
  82. __STATIC_FORCEINLINE q63_t read_q31x2_ia (
  83. q31_t ** pQ31)
  84. {
  85. q63_t val;
  86. val = read_q31x2(*pQ31);
  87. *pQ31 += 2;
  88. return (val);
  89. }
  90. /**
  91. @brief Read 2 Q31 from Q31 pointer and decrement pointer afterwards.
  92. @param[in] pQ31 points to input value
  93. @return Q63 value
  94. */
  95. __STATIC_FORCEINLINE q63_t read_q31x2_da (
  96. q31_t ** pQ31)
  97. {
  98. q63_t val;
  99. val = read_q31x2(*pQ31);
  100. *pQ31 -= 2;
  101. return (val);
  102. }
  103. /**
  104. @brief Write 2 Q31 to Q31 pointer.
  105. @param[in] pQ31 points to input value
  106. @param[in] value Q63 value
  107. */
  108. __STATIC_FORCEINLINE void write_q31x2 (
  109. q31_t * pQ31,
  110. q63_t value)
  111. {
  112. #ifndef __RISCV_FEATURE_UNALIGNED
  113. #if __RISCV_XLEN == 64
  114. __SD(pQ31, value);
  115. #else
  116. *((q63_t *)pQ31) = value;
  117. #endif /* __RISCV_XLEN == 64 */
  118. #else
  119. memcpy((void *)(pQ31), (void *)(&value), 8);
  120. #endif
  121. }
  122. /**
  123. @brief Write 2 Q31 to Q31 pointer and increment pointer afterwards.
  124. @param[in] pQ31 points to input value
  125. @param[in] value Q63 value
  126. */
  127. __STATIC_FORCEINLINE void write_q31x2_ia (
  128. q31_t ** pQ31,
  129. q63_t value)
  130. {
  131. write_q31x2(*pQ31, value);
  132. *pQ31 += 2;
  133. }
  134. /**
  135. @brief Read 2 Q15 from Q15 pointer.
  136. @param[in] pQ15 points to input value
  137. @return Q31 value
  138. */
  139. __STATIC_FORCEINLINE q31_t read_q15x2 (
  140. q15_t const * pQ15)
  141. {
  142. q31_t val;
  143. #ifdef __RISCV_FEATURE_UNALIGNED
  144. memcpy (&val, pQ15, 4);
  145. #else
  146. val = __LW((q15_t *)pQ15);
  147. #endif
  148. return (val);
  149. }
  150. /**
  151. @brief Read 2 Q15 from Q15 pointer and increment pointer afterwards.
  152. @param[in] pQ15 points to input value
  153. @return Q31 value
  154. */
  155. __STATIC_FORCEINLINE q31_t read_q15x2_ia (
  156. q15_t ** pQ15)
  157. {
  158. q31_t val;
  159. val = read_q15x2(*pQ15);
  160. *pQ15 += 2;
  161. return (val);
  162. }
  163. /**
  164. @brief Read 2 Q15 from Q15 pointer and decrement pointer afterwards.
  165. @param[in] pQ15 points to input value
  166. @return Q31 value
  167. */
  168. __STATIC_FORCEINLINE q31_t read_q15x2_da (
  169. q15_t ** pQ15)
  170. {
  171. q31_t val;
  172. val = read_q15x2(*pQ15);
  173. *pQ15 -= 2;
  174. return (val);
  175. }
  176. /**
  177. @brief Write 2 Q15 to Q15 pointer.
  178. @param[in] pQ15 points to input value
  179. @param[in] value Q31 value
  180. */
  181. __STATIC_FORCEINLINE void write_q15x2 (
  182. q15_t * pQ15,
  183. q31_t value)
  184. {
  185. #ifdef __RISCV_FEATURE_UNALIGNED
  186. memcpy (pQ15, &value, 4);
  187. #else
  188. __SW(pQ15, value);
  189. #endif
  190. }
  191. /**
  192. @brief Write 2 Q15 to Q15 pointer and increment pointer afterwards.
  193. @param[in] pQ15 points to input value
  194. @param[in] value Q31 value
  195. */
  196. __STATIC_FORCEINLINE void write_q15x2_ia (
  197. q15_t ** pQ15,
  198. q31_t value)
  199. {
  200. write_q15x2(*pQ15, value);
  201. *pQ15 += 2;
  202. }
  203. /**
  204. @brief Write 4 Q15 to Q15 pointer.
  205. @param[in] pQ15 points to input value
  206. @param[in] value Q31 value
  207. */
  208. __STATIC_FORCEINLINE void write_q15x4 (
  209. q15_t * pQ15,
  210. q63_t value)
  211. {
  212. #ifndef __RISCV_FEATURE_UNALIGNED
  213. #if __RISCV_XLEN == 64
  214. __SD(pQ15, value);
  215. #else
  216. *((q63_t *)pQ15) = value;
  217. #endif
  218. #else
  219. memcpy((void *)(pQ15), (void *)(&value), 8);
  220. #endif
  221. }
  222. /**
  223. @brief Write 4 Q15 to Q15 pointer and increment pointer afterwards.
  224. @param[in] pQ15 points to input value
  225. @param[in] value Q31 value
  226. */
  227. __STATIC_FORCEINLINE void write_q15x4_ia (
  228. q15_t ** pQ15,
  229. q63_t value)
  230. {
  231. write_q15x4(*pQ15, value);
  232. *pQ15 += 4;
  233. }
  234. /**
  235. @brief Write 4 Q15 to Q15 pointer and decrement pointer afterwards.
  236. @param[in] pQ15 points to input value
  237. @param[in] value Q31 value
  238. */
  239. __STATIC_FORCEINLINE void write_q15x4_da (
  240. q15_t ** pQ15,
  241. q63_t value)
  242. {
  243. write_q15x4(*pQ15, value);
  244. *pQ15 -= 4;
  245. }
  246. /**
  247. @brief Read 4 Q15 from Q15 pointer.
  248. @param[in] pQ15 points to input value
  249. @return Q63 value
  250. */
  251. __STATIC_FORCEINLINE q63_t read_q15x4 (
  252. q15_t const * pQ15)
  253. {
  254. q63_t val;
  255. #ifndef __RISCV_FEATURE_UNALIGNED
  256. #if __RISCV_XLEN == 64
  257. val = __LD((q15_t *)pQ15);
  258. #else
  259. val = *((q63_t *)pQ15);
  260. #endif /* __RISCV_XLEN == 64 */
  261. #else
  262. memcpy((void *)(&val), (void *)(pQ15), 8);
  263. #endif
  264. return (val);
  265. }
  266. /**
  267. @brief Read 4 Q15 from Q15 pointer and increment pointer afterwards.
  268. @param[in] pQ15 points to input value
  269. @return Q63 value
  270. */
  271. __STATIC_FORCEINLINE q63_t read_q15x4_ia (
  272. q15_t ** pQ15)
  273. {
  274. q63_t val;
  275. val = read_q15x4(*pQ15);
  276. *pQ15 += 4;
  277. return (val);
  278. }
  279. /**
  280. @brief Read 4 Q15 from Q15 pointer and decrement pointer afterwards.
  281. @param[in] pQ15 points to input value
  282. @return Q31 value
  283. */
  284. __STATIC_FORCEINLINE q63_t read_q15x4_da (
  285. q15_t ** pQ15)
  286. {
  287. q63_t val;
  288. val = read_q15x4(*pQ15);
  289. *pQ15 -= 4;
  290. return (val);
  291. }
  292. /**
  293. @brief Read 4 Q7 from Q7 pointer
  294. @param[in] pQ7 points to input value
  295. @return Q31 value
  296. */
  297. __STATIC_FORCEINLINE q31_t read_q7x4 (
  298. q7_t const * pQ7)
  299. {
  300. q31_t val;
  301. #ifdef __RISCV_FEATURE_UNALIGNED
  302. memcpy (&val, pQ7, 4);
  303. #else
  304. val = __LW((q7_t *)pQ7);
  305. #endif
  306. return (val);
  307. }
  308. /**
  309. @brief Read 4 Q7 from Q7 pointer and increment pointer afterwards.
  310. @param[in] pQ7 points to input value
  311. @return Q31 value
  312. */
  313. __STATIC_FORCEINLINE q31_t read_q7x4_ia (
  314. q7_t ** pQ7)
  315. {
  316. q31_t val;
  317. val = read_q7x4(*pQ7);
  318. *pQ7 += 4;
  319. return (val);
  320. }
  321. /**
  322. @brief Read 4 Q7 from Q7 pointer and decrement pointer afterwards.
  323. @param[in] pQ7 points to input value
  324. @return Q31 value
  325. */
  326. __STATIC_FORCEINLINE q31_t read_q7x4_da (
  327. q7_t ** pQ7)
  328. {
  329. q31_t val;
  330. val = read_q7x4(*pQ7);
  331. *pQ7 -= 4;
  332. return (val);
  333. }
  334. /**
  335. @brief Read 8 Q7 from Q7 pointer.
  336. @param[in] pQ7 points to input value
  337. @return Q63 value
  338. */
  339. __STATIC_FORCEINLINE q63_t read_q7x8 (
  340. q7_t const * pQ7)
  341. {
  342. q63_t val;
  343. #ifndef __RISCV_FEATURE_UNALIGNED
  344. #if __RISCV_XLEN == 64
  345. val = __LD((q7_t *)pQ7);
  346. #else
  347. val = *((q63_t *)pQ7);
  348. #endif
  349. #else
  350. memcpy((void *)(&val), (void *)pQ7, 8);
  351. #endif
  352. return val;
  353. }
  354. /**
  355. @brief Read 8 Q7 from Q7 pointer and increment pointer afterwards.
  356. @param[in] pQ7 points to input value
  357. @return Q63 value
  358. */
  359. __STATIC_FORCEINLINE q63_t read_q7x8_ia (
  360. q7_t ** pQ7)
  361. {
  362. q63_t val;
  363. val = read_q7x8(*pQ7);
  364. *pQ7 += 8;
  365. return val;
  366. }
  367. /**
  368. @brief Read 8 Q7 from Q7 pointer and decrement pointer afterwards.
  369. @param[in] pQ7 points to input value
  370. @return Q63 value
  371. */
  372. __STATIC_FORCEINLINE q63_t read_q7x8_da (
  373. q7_t ** pQ7)
  374. {
  375. q63_t val;
  376. val = read_q7x8(*pQ7);
  377. *pQ7 -= 8;
  378. return val;
  379. }
  380. /**
  381. @brief Write 4 Q7 to Q7 pointer.
  382. @param[in] pQ7 points to input value
  383. @param[in] value Q31 value
  384. */
  385. __STATIC_FORCEINLINE void write_q7x4 (
  386. q7_t * pQ7,
  387. q31_t value)
  388. {
  389. q31_t val = value;
  390. #ifdef __RISCV_FEATURE_UNALIGNED
  391. memcpy (pQ7, &val, 4);
  392. #else
  393. __SW(pQ7, val);
  394. #endif
  395. }
  396. /**
  397. @brief Write 4 Q7 to Q7 pointer and increment pointer afterwards.
  398. @param[in] pQ7 points to input value
  399. @param[in] value Q31 value
  400. */
  401. __STATIC_FORCEINLINE void write_q7x4_ia (
  402. q7_t ** pQ7,
  403. q31_t value)
  404. {
  405. write_q7x4(*pQ7, value);
  406. *pQ7 += 4;
  407. }
  408. /**
  409. @brief Write 8 Q7 to Q7 pointer and increment pointer afterwards.
  410. @param[in] pQ7 points to input value
  411. @param[in] value Q63 value
  412. */
  413. __STATIC_FORCEINLINE void write_q7x8_ia (
  414. q7_t ** pQ7,
  415. q63_t value)
  416. {
  417. #ifndef __RISCV_FEATURE_UNALIGNED
  418. #if __RISCV_XLEN == 64
  419. __SD(*pQ7,value);
  420. #else
  421. *((q63_t *)*pQ7) = value;
  422. #endif
  423. #else
  424. memcpy((void *)(*pQ7), (void *)(&value), 8);
  425. #endif
  426. *pQ7 += 8;
  427. }
  428. #ifdef __cplusplus
  429. }
  430. #endif
  431. #endif /*ifndef _RISCV_MATH_MEMORY_H_ */