19#if HAS_REDUNDANCY_COPROCESSOR
21#error "HAS_REDUNDANCY_COPROCESSOR should be false on RISC-V"
24#define rcp_is_true(x) ((x) == RCP_MASK_TRUE)
25#define RCP_MASK_TRUE _u(0xa500a500)
26#define RCP_MASK_FALSE _u(0x00c300c3)
27#define RCP_MASK_INTXOR _u(0x96009600)
33#define __rcpinline __force_inline
40#if __ARM_ARCH_8M_MAIN__
41#define rcp_asm pico_default_asm_volatile
42#elif __ARM_ARCH_8M_BASE__
43#define rcp_asm(...) ({pico_default_asm_volatile(".cpu cortex-m33\n" __VA_ARGS__); pico_default_asm_volatile(".cpu cortex-m23"); })
45#define rcp_asm(...) ({pico_default_asm_volatile(".cpu cortex-m33\n" __VA_ARGS__); pico_default_asm_volatile(".cpu cortex-m0plus"); })
47#error unknown ARM architecture
60static __rcpinline
void rcp_salt_core0(uint64_t salt) {
62 "mcrr p7, #8, %0, %1, c0\n"
63 : :
"r" (salt & 0xffffffffu),
"r" (salt >> 32)
67static __rcpinline
void rcp_salt_core0_nodelay(uint64_t salt) {
69 "mcrr2 p7, #8, %0, %1, c0\n"
70 : :
"r" (salt & 0xffffffffu),
"r" (salt >> 32)
75static __rcpinline
void rcp_salt_core1(uint64_t salt) {
77 "mcrr p7, #8, %0, %1, c1\n"
78 : :
"r" (salt & 0xffffffffu),
"r" (salt >> 32)
82static __rcpinline
void rcp_salt_core1_nodelay(uint64_t salt) {
84 "mcrr2 p7, #8, %0, %1, c1\n"
85 : :
"r" (salt & 0xffffffffu),
"r" (salt >> 32)
90#define rcp_canary_get(tag) ({ \
91 static_assert(!((tag) & ~0xffu), "Tag out of range"); \
92 uint32_t __canary_u32; \
94 "mrc p7, #0, %0, c%c1, c%c2, #1\n" \
95 : "=r" (__canary_u32) \
96 : "i" ((tag >> 4) & 0xf), "i" (tag & 0xf) \
101#define rcp_canary_get_nodelay(tag) ({ \
102 static_assert(!((tag) & ~0xffu), "Tag out of range"); \
103 uint32_t __canary_u32; \
105 "mrc2 p7, #0, %0, c%c1, c%c2, #1\n" \
106 : "=r" (__canary_u32) \
107 : "i" (((tag) >> 4) & 0xf), "i" ((tag) & 0xf) \
113#define rcp_canary_check(tag, canary) ({ \
114 static_assert(!((tag) & ~0xffu), "Tag out of range"); \
116 "mcr p7, #0, %0, c%c1, c%c2, #1\n" \
118 "i" (((tag) >> 4) & 0xf), "i" ((tag) & 0xf) \
122#define rcp_canary_check_nodelay(tag, canary) ({ \
123 static_assert(!((tag) & ~0xffu), "Tag out of range"); \
125 "mcr2 p7, #0, %0, c%c1, c%c2, #1\n" \
127 "i" (((tag) >> 4) & 0xf), "i" ((tag) & 0xf) \
135static __rcpinline uint32_t rcp_canary_status(
void) {
137 rcp_asm (
"mrc p7, #1, %0, c0, c0, #0\n" :
"=r" (ret));
141static __rcpinline uint32_t rcp_canary_status_nodelay(
void) {
143 rcp_asm (
"mrc2 p7, #1, %0, c0, c0, #0\n" :
"=r" (ret));
154static __rcpinline
void rcp_bvalid(uint32_t b) {
155 rcp_asm (
"mcr p7, #1, %0, c0, c0, #0\n" : :
"r" (b));
158static __rcpinline
void rcp_bvalid_nodelay(uint32_t b) {
159 rcp_asm (
"mcr2 p7, #1, %0, c0, c0, #0\n" : :
"r" (b));
163static __rcpinline
void rcp_btrue(uint32_t b) {
164 rcp_asm (
"mcr p7, #2, %0, c0, c0, #0\n" : :
"r" (b));
167static __rcpinline
void rcp_btrue_nodelay(uint32_t b) {
168 rcp_asm (
"mcr2 p7, #2, %0, c0, c0, #0\n" : :
"r" (b));
172static __rcpinline
void rcp_bfalse(uint32_t b) {
173 rcp_asm (
"mcr p7, #3, %0, c0, c0, #1\n" : :
"r" (b));
176static __rcpinline
void rcp_bfalse_nodelay(uint32_t b) {
177 rcp_asm (
"mcr2 p7, #3, %0, c0, c0, #1\n" : :
"r" (b));
181static __rcpinline
void rcp_b2valid(uint32_t b0, uint32_t b1) {
182 rcp_asm (
"mcrr p7, #0, %0, %1, c8\n" : :
"r" (b0),
"r" (b1));
185static __rcpinline
void rcp_b2valid_nodelay(uint32_t b0, uint32_t b1) {
186 rcp_asm (
"mcrr2 p7, #0, %0, %1, c8\n" : :
"r" (b0),
"r" (b1));
190static __rcpinline
void rcp_b2and(uint32_t b0, uint32_t b1) {
191 rcp_asm (
"mcrr p7, #1, %0, %1, c0\n" : :
"r" (b0),
"r" (b1));
194static __rcpinline
void rcp_b2and_nodelay(uint32_t b0, uint32_t b1) {
195 rcp_asm (
"mcrr2 p7, #1, %0, %1, c0\n" : :
"r" (b0),
"r" (b1));
199static __rcpinline
void rcp_b2or(uint32_t b0, uint32_t b1) {
200 rcp_asm (
"mcrr p7, #2, %0, %1, c0\n" : :
"r" (b0),
"r" (b1));
203static __rcpinline
void rcp_b2or_nodelay(uint32_t b0, uint32_t b1) {
204 rcp_asm (
"mcrr2 p7, #2, %0, %1, c0\n" : :
"r" (b0),
"r" (b1));
208static __rcpinline
void rcp_bxorvalid(uint32_t b, uint32_t mask) {
209 rcp_asm (
"mcrr p7, #3, %0, %1, c8\n" : :
"r" (b),
"r" (mask));
212static __rcpinline
void rcp_bxorvalid_nodelay(uint32_t b, uint32_t mask) {
213 rcp_asm (
"mcrr2 p7, #3, %0, %1, c8\n" : :
"r" (b),
"r" (mask));
217static __rcpinline
void rcp_bxortrue(uint32_t b, uint32_t mask) {
218 rcp_asm (
"mcrr p7, #4, %0, %1, c0\n" : :
"r" (b),
"r" (mask));
221static __rcpinline
void rcp_bxortrue_nodelay(uint32_t b, uint32_t mask) {
222 rcp_asm (
"mcrr2 p7, #4, %0, %1, c0\n" : :
"r" (b),
"r" (mask));
226static __rcpinline
void rcp_bxorfalse(uint32_t b, uint32_t mask) {
227 rcp_asm (
"mcrr p7, #5, %0, %1, c8\n" : :
"r" (b),
"r" (mask));
230static __rcpinline
void rcp_bxorfalse_nodelay(uint32_t b, uint32_t mask) {
231 rcp_asm (
"mcrr2 p7, #5, %0, %1, c8\n" : :
"r" (b),
"r" (mask));
238static __rcpinline
void rcp_ivalid(uint32_t x, uint32_t parity) {
239 rcp_asm (
"mcrr p7, #6, %0, %1, c8\n" : :
"r" (x),
"r" (parity));
242static __rcpinline
void rcp_ivalid_nodelay(uint32_t x, uint32_t parity) {
243 rcp_asm (
"mcrr2 p7, #6, %0, %1, c8\n" : :
"r" (x),
"r" (parity));
247static __rcpinline
void rcp_iequal(uint32_t x, uint32_t y) {
248 rcp_asm (
"mcrr p7, #7, %0, %1, c0\n" : :
"r" (x),
"r" (y));
251static __rcpinline
void rcp_iequal_nodelay(uint32_t x, uint32_t y) {
252 rcp_asm (
"mcrr2 p7, #7, %0, %1, c0\n" : :
"r" (x),
"r" (y));
260static __rcpinline uint8_t rcp_random_byte(
void) {
262 rcp_asm (
"mrc2 p7, #2, %0, c0, c0, #0\n" :
"=r" (ret));
269static __rcpinline uint8_t rcp_random_byte_nodelay(
void) {
271 rcp_asm (
"mrc2 p7, #2, %0, c0, c0, #0\n" :
"=r" (ret));
280#define rcp_count_set(cnt) rcp_asm ( \
281 "mcr p7, #4, r0, c%c0, c%c1, #0\n" \
282 : : "i"(((cnt) >> 4) & 0xf), "i"((cnt) & 0xf) \
285#define rcp_count_set_nodelay(cnt) rcp_asm ( \
286 "mcr2 p7, #4, r0, c%c0, c%c1, #0\n" \
287 : : "i"(((cnt) >> 4) & 0xf), "i"((cnt) & 0xf) \
292#define rcp_count_check(cnt) rcp_asm ( \
293 "mcr p7, #5, r0, c%c0, c%c1, #1\n" \
294 : : "i"(((cnt) >> 4) & 0xf), "i"((cnt) & 0xf) \
297#define rcp_count_check_nodelay(cnt) rcp_asm ( \
298 "mcr2 p7, #5, r0, c%c0, c%c1, #1\n" \
299 : : "i"(((cnt) >> 4) & 0xf), "i"((cnt) & 0xf) \
307static __rcpinline __attribute__((noreturn))
void rcp_panic(
void) {
308 rcp_asm(
"cdp p7, #0, c0, c0, c0, #1");
309 __builtin_unreachable();
322.macro rcp_switch_u8_to_ch_cl macro_name, x, args:vararg
324\macro_name c0, c0, \args
326\macro_name c0, c1, \args
328\macro_name c0, c2, \args
330\macro_name c0, c3, \args
332\macro_name c0, c4, \args
334\macro_name c0, c5, \args
336\macro_name c0, c6, \args
338\macro_name c0, c7, \args
340\macro_name c0, c8, \args
342\macro_name c0, c9, \args
344\macro_name c0, c10, \args
346\macro_name c0, c11, \args
348\macro_name c0, c12, \args
350\macro_name c0, c13, \args
352\macro_name c0, c14, \args
354\macro_name c0, c15, \args
356\macro_name c1, c0, \args
358\macro_name c1, c1, \args
360\macro_name c1, c2, \args
362\macro_name c1, c3, \args
364\macro_name c1, c4, \args
366\macro_name c1, c5, \args
368\macro_name c1, c6, \args
370\macro_name c1, c7, \args
372\macro_name c1, c8, \args
374\macro_name c1, c9, \args
376\macro_name c1, c10, \args
378\macro_name c1, c11, \args
380\macro_name c1, c12, \args
382\macro_name c1, c13, \args
384\macro_name c1, c14, \args
386\macro_name c1, c15, \args
388\macro_name c2, c0, \args
390\macro_name c2, c1, \args
392\macro_name c2, c2, \args
394\macro_name c2, c3, \args
396\macro_name c2, c4, \args
398\macro_name c2, c5, \args
400\macro_name c2, c6, \args
402\macro_name c2, c7, \args
404\macro_name c2, c8, \args
406\macro_name c2, c9, \args
408\macro_name c2, c10, \args
410\macro_name c2, c11, \args
412\macro_name c2, c12, \args
414\macro_name c2, c13, \args
416\macro_name c2, c14, \args
418\macro_name c2, c15, \args
420\macro_name c3, c0, \args
422\macro_name c3, c1, \args
424\macro_name c3, c2, \args
426\macro_name c3, c3, \args
428\macro_name c3, c4, \args
430\macro_name c3, c5, \args
432\macro_name c3, c6, \args
434\macro_name c3, c7, \args
436\macro_name c3, c8, \args
438\macro_name c3, c9, \args
440\macro_name c3, c10, \args
442\macro_name c3, c11, \args
444\macro_name c3, c12, \args
446\macro_name c3, c13, \args
448\macro_name c3, c14, \args
450\macro_name c3, c15, \args
452\macro_name c4, c0, \args
454\macro_name c4, c1, \args
456\macro_name c4, c2, \args
458\macro_name c4, c3, \args
460\macro_name c4, c4, \args
462\macro_name c4, c5, \args
464\macro_name c4, c6, \args
466\macro_name c4, c7, \args
468\macro_name c4, c8, \args
470\macro_name c4, c9, \args
472\macro_name c4, c10, \args
474\macro_name c4, c11, \args
476\macro_name c4, c12, \args
478\macro_name c4, c13, \args
480\macro_name c4, c14, \args
482\macro_name c4, c15, \args
484\macro_name c5, c0, \args
486\macro_name c5, c1, \args
488\macro_name c5, c2, \args
490\macro_name c5, c3, \args
492\macro_name c5, c4, \args
494\macro_name c5, c5, \args
496\macro_name c5, c6, \args
498\macro_name c5, c7, \args
500\macro_name c5, c8, \args
502\macro_name c5, c9, \args
504\macro_name c5, c10, \args
506\macro_name c5, c11, \args
508\macro_name c5, c12, \args
510\macro_name c5, c13, \args
512\macro_name c5, c14, \args
514\macro_name c5, c15, \args
516\macro_name c6, c0, \args
518\macro_name c6, c1, \args
520\macro_name c6, c2, \args
522\macro_name c6, c3, \args
524\macro_name c6, c4, \args
526\macro_name c6, c5, \args
528\macro_name c6, c6, \args
530\macro_name c6, c7, \args
532\macro_name c6, c8, \args
534\macro_name c6, c9, \args
536\macro_name c6, c10, \args
538\macro_name c6, c11, \args
540\macro_name c6, c12, \args
542\macro_name c6, c13, \args
544\macro_name c6, c14, \args
546\macro_name c6, c15, \args
548\macro_name c7, c0, \args
550\macro_name c7, c1, \args
552\macro_name c7, c2, \args
554\macro_name c7, c3, \args
556\macro_name c7, c4, \args
558\macro_name c7, c5, \args
560\macro_name c7, c6, \args
562\macro_name c7, c7, \args
564\macro_name c7, c8, \args
566\macro_name c7, c9, \args
568\macro_name c7, c10, \args
570\macro_name c7, c11, \args
572\macro_name c7, c12, \args
574\macro_name c7, c13, \args
576\macro_name c7, c14, \args
578\macro_name c7, c15, \args
580\macro_name c8, c0, \args
582\macro_name c8, c1, \args
584\macro_name c8, c2, \args
586\macro_name c8, c3, \args
588\macro_name c8, c4, \args
590\macro_name c8, c5, \args
592\macro_name c8, c6, \args
594\macro_name c8, c7, \args
596\macro_name c8, c8, \args
598\macro_name c8, c9, \args
600\macro_name c8, c10, \args
602\macro_name c8, c11, \args
604\macro_name c8, c12, \args
606\macro_name c8, c13, \args
608\macro_name c8, c14, \args
610\macro_name c8, c15, \args
612\macro_name c9, c0, \args
614\macro_name c9, c1, \args
616\macro_name c9, c2, \args
618\macro_name c9, c3, \args
620\macro_name c9, c4, \args
622\macro_name c9, c5, \args
624\macro_name c9, c6, \args
626\macro_name c9, c7, \args
628\macro_name c9, c8, \args
630\macro_name c9, c9, \args
632\macro_name c9, c10, \args
634\macro_name c9, c11, \args
636\macro_name c9, c12, \args
638\macro_name c9, c13, \args
640\macro_name c9, c14, \args
642\macro_name c9, c15, \args
644\macro_name c10, c0, \args
646\macro_name c10, c1, \args
648\macro_name c10, c2, \args
650\macro_name c10, c3, \args
652\macro_name c10, c4, \args
654\macro_name c10, c5, \args
656\macro_name c10, c6, \args
658\macro_name c10, c7, \args
660\macro_name c10, c8, \args
662\macro_name c10, c9, \args
664\macro_name c10, c10, \args
666\macro_name c10, c11, \args
668\macro_name c10, c12, \args
670\macro_name c10, c13, \args
672\macro_name c10, c14, \args
674\macro_name c10, c15, \args
676\macro_name c11, c0, \args
678\macro_name c11, c1, \args
680\macro_name c11, c2, \args
682\macro_name c11, c3, \args
684\macro_name c11, c4, \args
686\macro_name c11, c5, \args
688\macro_name c11, c6, \args
690\macro_name c11, c7, \args
692\macro_name c11, c8, \args
694\macro_name c11, c9, \args
696\macro_name c11, c10, \args
698\macro_name c11, c11, \args
700\macro_name c11, c12, \args
702\macro_name c11, c13, \args
704\macro_name c11, c14, \args
706\macro_name c11, c15, \args
708\macro_name c12, c0, \args
710\macro_name c12, c1, \args
712\macro_name c12, c2, \args
714\macro_name c12, c3, \args
716\macro_name c12, c4, \args
718\macro_name c12, c5, \args
720\macro_name c12, c6, \args
722\macro_name c12, c7, \args
724\macro_name c12, c8, \args
726\macro_name c12, c9, \args
728\macro_name c12, c10, \args
730\macro_name c12, c11, \args
732\macro_name c12, c12, \args
734\macro_name c12, c13, \args
736\macro_name c12, c14, \args
738\macro_name c12, c15, \args
740\macro_name c13, c0, \args
742\macro_name c13, c1, \args
744\macro_name c13, c2, \args
746\macro_name c13, c3, \args
748\macro_name c13, c4, \args
750\macro_name c13, c5, \args
752\macro_name c13, c6, \args
754\macro_name c13, c7, \args
756\macro_name c13, c8, \args
758\macro_name c13, c9, \args
760\macro_name c13, c10, \args
762\macro_name c13, c11, \args
764\macro_name c13, c12, \args
766\macro_name c13, c13, \args
768\macro_name c13, c14, \args
770\macro_name c13, c15, \args
772\macro_name c14, c0, \args
774\macro_name c14, c1, \args
776\macro_name c14, c2, \args
778\macro_name c14, c3, \args
780\macro_name c14, c4, \args
782\macro_name c14, c5, \args
784\macro_name c14, c6, \args
786\macro_name c14, c7, \args
788\macro_name c14, c8, \args
790\macro_name c14, c9, \args
792\macro_name c14, c10, \args
794\macro_name c14, c11, \args
796\macro_name c14, c12, \args
798\macro_name c14, c13, \args
800\macro_name c14, c14, \args
802\macro_name c14, c15, \args
804\macro_name c15, c0, \args
806\macro_name c15, c1, \args
808\macro_name c15, c2, \args
810\macro_name c15, c3, \args
812\macro_name c15, c4, \args
814\macro_name c15, c5, \args
816\macro_name c15, c6, \args
818\macro_name c15, c7, \args
820\macro_name c15, c8, \args
822\macro_name c15, c9, \args
824\macro_name c15, c10, \args
826\macro_name c15, c11, \args
828\macro_name c15, c12, \args
830\macro_name c15, c13, \args
832\macro_name c15, c14, \args
834\macro_name c15, c15, \args
836.error
"Value outside of range 0-255"
845 mcr p7, #1, \r , c0, c0, #0
848.macro rcp_bvalid_nodelay r
849 mcr2 p7, #1, \r , c0, c0, #0
854 mcr p7, #2, \r , c0, c0, #0
857.macro rcp_btrue_nodelay r
858 mcr2 p7, #2, \r , c0, c0, #0
863 mcr p7, #3, \r , c0, c0, #1
866.macro rcp_bfalse_nodelay r
867 mcr2 p7, #3, \r , c0, c0, #1
871.macro rcp_b2valid b0, b1
872 mcrr p7, #0, \b0 , \b1 , c8
875.macro rcp_b2valid_nodelay b0, b1
876 mcrr2 p7, #0, \b0 , \b1 , c8
880.macro rcp_b2and b0, b1
881 mcrr p7, #1, \b0 , \b1 , c0
884.macro rcp_b2and_nodelay b0, b1
885 mcrr2 p7, #1, \b0 , \b1 , c0
889.macro rcp_b2or b0, b1
890 mcrr p7, #2, \b0 , \b1 , c0
893.macro rcp_b2or_nodelay b0, b1
894 mcrr2 p7, #2, \b0 , \b1 , c0
898.macro rcp_bxorvalid b, mask
899 mcrr p7, #3, \b , \mask , c8
902.macro rcp_bxorvalid_nodelay b, mask
903 mcrr2 p7, #3, \b , \mask , c8
907.macro rcp_bxortrue b, mask
908 mcrr p7, #4, \b , \mask , c0
911.macro rcp_bxortrue_nodelay b, mask
912 mcrr2 p7, #4, \b , \mask , c0
916.macro rcp_bxorfalse b, mask
917 mcrr p7, #5, \b , \mask , c8
920.macro rcp_bxorfalse_nodelay b, mask
921 mcrr2 p7, #5, \b , \mask , c8
928.macro rcp_ivalid x, parity
929 mcrr p7, #6, \x , \parity , c8
932.macro rcp_ivalid_nodelay x, parity
933 mcrr2 p7, #6, \x , \parity , c8
937.macro rcp_iequal x, y
938 mcrr p7, #7, \x , \y , c0
941.macro rcp_iequal_nodelay x, y
942 mcrr2 p7, #7, \x , \y , c0
949.macro rcp_count_set_impl h, l
950mcr p7, #4, r0, \h , \l , #0
952.macro rcp_count_set cnt
953rcp_switch_u8_to_ch_cl rcp_count_set_impl, \cnt
956.macro rcp_count_set_nodelay_impl h, l
957mcr2 p7, #4, r0, \h , \l , #0
959.macro rcp_count_set_nodelay cnt
960rcp_switch_u8_to_ch_cl rcp_count_set_nodelay_impl, \cnt
965.macro rcp_count_check_impl h, l
966 mcr p7, #5, r0, \h, \l, #1
968.macro rcp_count_check cnt
969rcp_switch_u8_to_ch_cl rcp_count_check_impl, \cnt
972.macro rcp_count_check_nodelay_impl h, l
973 mcr2 p7, #5, r0, \h, \l, #1
975.macro rcp_count_check_nodelay cnt
976rcp_switch_u8_to_ch_cl rcp_count_check_nodelay_impl, \cnt
983.macro rcp_canary_get_impl h, l, x
984 mrc p7, #0, \x, \h, \l, #1
986.macro rcp_canary_get x, tag
987rcp_switch_u8_to_ch_cl rcp_canary_get_impl \tag, \x
990.macro rcp_canary_get_nodelay_impl h, l, x
991 mrc2 p7, #0, \x, \h, \l, #1
993.macro rcp_canary_get_nodelay x, tag
994rcp_switch_u8_to_ch_cl rcp_canary_get_nodelay_impl \tag, \x
998.macro rcp_canary_check_impl h, l, x
999 mcr p7, #0, \x, \h, \l, #1
1001.macro rcp_canary_check x, tag
1002rcp_switch_u8_to_ch_cl rcp_canary_check_impl \tag, \x
1005.macro rcp_canary_check_nodelay_impl h, l, x
1006 mcr2 p7, #0, \x, \h, \l, #1
1008.macro rcp_canary_check_nodelay x, tag
1009rcp_switch_u8_to_ch_cl rcp_canary_check_nodelay_impl \tag, \x
1013 cdp p7, #0, c0, c0, c0, #1
1024#define rcp_is_true(x) ((int32_t)(x) < 0)