15
15
*/
16
16
17
17
// ----------------------------------------------------------------------------
18
- // RCP masks
19
- #if !PICO_RP2040
18
+ // RCP instructions (this header is Arm-only)
19
+ #if HAS_REDUNDANCY_COPROCESSOR
20
+ #ifdef __riscv
21
+ #error "HAS_REDUNDANCY_COPROCESSOR should be false on RISC-V"
22
+ #endif
20
23
24
+ #define rcp_is_true (x ) ((x) == RCP_MASK_TRUE)
21
25
#define RCP_MASK_TRUE _u(0xa500a500)
22
26
#define RCP_MASK_FALSE _u(0x00c300c3)
23
27
#define RCP_MASK_INTXOR _u(0x96009600)
24
28
25
- // RCP instructions (these instructions are Arm-only)
26
- #if HAS_REDUNDANCY_COPROCESSOR
27
29
// ----------------------------------------------------------------------------
28
30
// Macros and inline functions for use in C files
29
31
#ifndef __ASSEMBLER__
@@ -86,6 +88,7 @@ static __rcpinline void rcp_salt_core1_nodelay(uint64_t salt) {
86
88
87
89
// Get a 32-bit canary value. `tag` must be a constant expression.
88
90
#define rcp_canary_get (tag ) ({ \
91
+ static_assert(!((tag) & ~0xffu), "Tag out of range"); \
89
92
uint32_t __canary_u32; \
90
93
rcp_asm ( \
91
94
"mrc p7, #0, %0, c%c1, c%c2, #1\n" \
@@ -96,6 +99,7 @@ static __rcpinline void rcp_salt_core1_nodelay(uint64_t salt) {
96
99
})
97
100
98
101
#define rcp_canary_get_nodelay (tag ) ({ \
102
+ static_assert(!((tag) & ~0xffu), "Tag out of range"); \
99
103
uint32_t __canary_u32; \
100
104
rcp_asm ( \
101
105
"mrc2 p7, #0, %0, c%c1, c%c2, #1\n" \
@@ -107,6 +111,7 @@ static __rcpinline void rcp_salt_core1_nodelay(uint64_t salt) {
107
111
108
112
// Assert that canary matches result of rcp_canary_get with the same tags:
109
113
#define rcp_canary_check (tag , canary ) ({ \
114
+ static_assert(!((tag) & ~0xffu), "Tag out of range"); \
110
115
rcp_asm ( \
111
116
"mcr p7, #0, %0, c%c1, c%c2, #1\n" \
112
117
: : "r" (canary), \
@@ -115,6 +120,7 @@ static __rcpinline void rcp_salt_core1_nodelay(uint64_t salt) {
115
120
})
116
121
117
122
#define rcp_canary_check_nodelay (tag , canary ) ({ \
123
+ static_assert(!((tag) & ~0xffu), "Tag out of range"); \
118
124
rcp_asm ( \
119
125
"mcr2 p7, #0, %0, c%c1, c%c2, #1\n" \
120
126
: : "r" (canary), \
@@ -141,6 +147,9 @@ static __rcpinline uint32_t rcp_canary_status_nodelay(void) {
141
147
// ----------------------------------------------------------------------------
142
148
// RCP Boolean instructions
143
149
150
+ // These instructions assert that all their arguments are valid booleans, in
151
+ // addition to any other logical conditions
152
+
144
153
// Assert b is a valid boolean (0xa500a500u or 0x00c300c3u)
145
154
static __rcpinline void rcp_bvalid (uint32_t b ) {
146
155
rcp_asm ("mcr p7, #1, %0, c0, c0, #0\n" : : "r" (b ));
@@ -308,106 +317,8 @@ static __rcpinline __attribute__((noreturn)) void rcp_panic(void) {
308
317
#else // __ASSEMBLER__
309
318
#ifndef __riscv
310
319
311
- // Assert b is a valid boolean (0xa500a500u or 0x00c300c3u)
312
- .macro rcp_bvalid r
313
- mcr p7 , #1 , \r , c0, c0, #0
314
- .endm
315
-
316
- .macro rcp_bvalid_nodelay r
317
- mcr2 p7 , #1 , \r , c0, c0, #0
318
- .endm
319
-
320
- // Assert b is true (0xa500a500u)
321
- .macro rcp_btrue r
322
- mcr p7 , #2 , \r , c0, c0, #0
323
- .endm
324
-
325
- .macro rcp_btrue_nodelay r
326
- mcr2 p7 , #2 , \r , c0, c0, #0
327
- .endm
328
-
329
- // Assert b is false (0x00c300c3u)
330
- .macro rcp_bfalse r
331
- mcr p7 , #3 , \r , c0, c0, #1
332
- .endm
333
-
334
- .macro rcp_bfalse_nodelay r
335
- mcr2 p7 , #3 , \r , c0, c0, #1
336
- .endm
337
-
338
- // Assert b0 and b1 are both valid booleans
339
- .macro rcp_b2valid b0 , b1
340
- mcrr p7 , #0 , \b0 , \b1 , c8
341
- .endm
342
-
343
- .macro rcp_b2valid_nodelay b0 , b1
344
- mcrr2 p7 , #0 , \b0 , \b1 , c8
345
- .endm
346
-
347
- // Assert b0 and b1 are both true
348
- .macro rcp_b2and b0 , b1
349
- mcrr p7 , #1 , \b0 , \b1 , c0
350
- .endm
351
-
352
- .macro rcp_b2and_nodelay b0 , b1
353
- mcrr2 p7 , #1 , \b0 , \b1 , c0
354
- .endm
355
-
356
- // Assert b0 and b1 are valid, and at least one is true
357
- .macro rcp_b2or b0 , b1
358
- mcrr p7 , #2 , \b0 , \b1 , c0
359
- .endm
360
-
361
- .macro rcp_b2or_nodelay b0 , b1
362
- mcrr2 p7 , #2 , \b0 , \b1 , c0
363
- .endm
364
-
365
- // Assert (b ^ mask) is a valid boolean
366
- .macro rcp_bxorvalid b , mask
367
- mcrr p7 , #3 , \b , \mask , c8
368
- .endm
369
-
370
- .macro rcp_bxorvalid_nodelay b , mask
371
- mcrr2 p7 , #3 , \b , \mask , c8
372
- .endm
373
-
374
- // Assert (b ^ mask) is true
375
- .macro rcp_bxortrue b , mask
376
- mcrr p7 , #4 , \b , \mask , c0
377
- .endm
378
-
379
- .macro rcp_bxortrue_nodelay b , mask
380
- mcrr2 p7 , #4 , \b , \mask , c0
381
- .endm
382
-
383
- // Assert (b ^ mask) is false
384
- .macro rcp_bxorfalse b , mask
385
- mcrr p7 , #5 , \b , \mask , c8
386
- .endm
387
-
388
- .macro rcp_bxorfalse_nodelay b , mask
389
- mcrr2 p7 , #5 , \b , \mask , c8
390
- .endm
391
-
392
- // Assert (x ^ parity) == 0x96009600u
393
- .macro rcp_ivalid x , parity
394
- mcrr p7 , #6 , \x , \parity , c8
395
- .endm
396
-
397
- .macro rcp_ivalid_nodelay x , parity
398
- mcrr2 p7 , #6 , \x , \parity , c8
399
- .endm
400
-
401
- // Assert x == y
402
- .macro rcp_iequal x , y
403
- mcrr p7 , #7 , \x , \y , c0
404
- .endm
405
-
406
- .macro rcp_iequal_nodelay x , y
407
- mcrr2 p7 , #7 , \x , \y , c0
408
- .endm
409
-
410
- // They call this "metaprogramming" I think
320
+ // Meta-macro for evaluating assembler constant expressions and encoding as
321
+ // coprocessor register pairs:
411
322
.macro rcp_switch_u8_to_ch_cl macro_name , x , args :vararg
412
323
.if (\x ) == 0
413
324
\macro_name c0 , c0 , \args
@@ -926,6 +837,114 @@ static __rcpinline __attribute__((noreturn)) void rcp_panic(void) {
926
837
.endif
927
838
.endm
928
839
840
+ // ----------------------------------------------------------------------------
841
+ // RCP Boolean instructions
842
+
843
+ // Assert b is a valid boolean (0xa500a500u or 0x00c300c3u)
844
+ .macro rcp_bvalid r
845
+ mcr p7 , #1 , \r , c0 , c0 , #0
846
+ .endm
847
+
848
+ .macro rcp_bvalid_nodelay r
849
+ mcr2 p7 , #1 , \r , c0 , c0 , #0
850
+ .endm
851
+
852
+ // Assert b is true (0xa500a500u)
853
+ .macro rcp_btrue r
854
+ mcr p7 , #2 , \r , c0 , c0 , #0
855
+ .endm
856
+
857
+ .macro rcp_btrue_nodelay r
858
+ mcr2 p7 , #2 , \r , c0 , c0 , #0
859
+ .endm
860
+
861
+ // Assert b is false (0x00c300c3u)
862
+ .macro rcp_bfalse r
863
+ mcr p7 , #3 , \r , c0 , c0 , #1
864
+ .endm
865
+
866
+ .macro rcp_bfalse_nodelay r
867
+ mcr2 p7 , #3 , \r , c0 , c0 , #1
868
+ .endm
869
+
870
+ // Assert b0 and b1 are both valid booleans
871
+ .macro rcp_b2valid b0 , b1
872
+ mcrr p7 , #0 , \b0 , \b1 , c8
873
+ .endm
874
+
875
+ .macro rcp_b2valid_nodelay b0 , b1
876
+ mcrr2 p7 , #0 , \b0 , \b1 , c8
877
+ .endm
878
+
879
+ // Assert b0 and b1 are both true
880
+ .macro rcp_b2and b0 , b1
881
+ mcrr p7 , #1 , \b0 , \b1 , c0
882
+ .endm
883
+
884
+ .macro rcp_b2and_nodelay b0 , b1
885
+ mcrr2 p7 , #1 , \b0 , \b1 , c0
886
+ .endm
887
+
888
+ // Assert b0 and b1 are valid, and at least one is true
889
+ .macro rcp_b2or b0 , b1
890
+ mcrr p7 , #2 , \b0 , \b1 , c0
891
+ .endm
892
+
893
+ .macro rcp_b2or_nodelay b0 , b1
894
+ mcrr2 p7 , #2 , \b0 , \b1 , c0
895
+ .endm
896
+
897
+ // Assert (b ^ mask) is a valid boolean
898
+ .macro rcp_bxorvalid b , mask
899
+ mcrr p7 , #3 , \b , \mask , c8
900
+ .endm
901
+
902
+ .macro rcp_bxorvalid_nodelay b , mask
903
+ mcrr2 p7 , #3 , \b , \mask , c8
904
+ .endm
905
+
906
+ // Assert (b ^ mask) is true
907
+ .macro rcp_bxortrue b , mask
908
+ mcrr p7 , #4 , \b , \mask , c0
909
+ .endm
910
+
911
+ .macro rcp_bxortrue_nodelay b , mask
912
+ mcrr2 p7 , #4 , \b , \mask , c0
913
+ .endm
914
+
915
+ // Assert (b ^ mask) is false
916
+ .macro rcp_bxorfalse b , mask
917
+ mcrr p7 , #5 , \b , \mask , c8
918
+ .endm
919
+
920
+ .macro rcp_bxorfalse_nodelay b , mask
921
+ mcrr2 p7 , #5 , \b , \mask , c8
922
+ .endm
923
+
924
+ // ----------------------------------------------------------------------------
925
+ // RCP Integer instructions
926
+
927
+ // Assert (x ^ parity) == 0x96009600u
928
+ .macro rcp_ivalid x , parity
929
+ mcrr p7 , #6 , \x , \parity , c8
930
+ .endm
931
+
932
+ .macro rcp_ivalid_nodelay x , parity
933
+ mcrr2 p7 , #6 , \x , \parity , c8
934
+ .endm
935
+
936
+ // Assert x == y
937
+ .macro rcp_iequal x , y
938
+ mcrr p7 , #7 , \x , \y , c0
939
+ .endm
940
+
941
+ .macro rcp_iequal_nodelay x , y
942
+ mcrr2 p7 , #7 , \x , \y , c0
943
+ .endm
944
+
945
+ // ----------------------------------------------------------------------------
946
+ // RCP Sequence count instructions
947
+
929
948
// Directly write 8-bit constant expression cnt to the sequence counter.
930
949
.macro rcp_count_set_impl h , l
931
950
mcr p7 , #4 , r0 , \h , \l , #0
@@ -957,20 +976,20 @@ rcp_switch_u8_to_ch_cl rcp_count_check_impl, \cnt
957
976
rcp_switch_u8_to_ch_cl rcp_count_check_nodelay_impl , \cnt
958
977
.endm
959
978
979
+ // ----------------------------------------------------------------------------
980
+ // RCP Canary instructions
981
+
960
982
// Get a 32-bit canary value. `tag` must be a constant expression.
961
983
.macro rcp_canary_get_impl h , l , x
962
984
mrc p7 , #0 , \x , \h , \l , #1
963
985
.endm
964
-
965
986
.macro rcp_canary_get x , tag
966
987
rcp_switch_u8_to_ch_cl rcp_canary_get_impl \tag , \x
967
988
.endm
968
989
969
- // Get a 32-bit canary value. `tag` must be a constant expression.
970
990
.macro rcp_canary_get_nodelay_impl h , l , x
971
991
mrc2 p7 , #0 , \x , \h , \l , #1
972
992
.endm
973
-
974
993
.macro rcp_canary_get_nodelay x , tag
975
994
rcp_switch_u8_to_ch_cl rcp_canary_get_nodelay_impl \tag , \x
976
995
.endm
@@ -979,15 +998,13 @@ rcp_switch_u8_to_ch_cl rcp_canary_get_nodelay_impl \tag, \x
979
998
.macro rcp_canary_check_impl h , l , x
980
999
mcr p7 , #0 , \x , \h , \l , #1
981
1000
.endm
982
-
983
1001
.macro rcp_canary_check x , tag
984
1002
rcp_switch_u8_to_ch_cl rcp_canary_check_impl \tag , \x
985
1003
.endm
986
1004
987
1005
.macro rcp_canary_check_nodelay_impl h , l , x
988
1006
mcr2 p7 , #0 , \x , \h , \l , #1
989
1007
.endm
990
-
991
1008
.macro rcp_canary_check_nodelay x , tag
992
1009
rcp_switch_u8_to_ch_cl rcp_canary_check_nodelay_impl \tag , \x
993
1010
.endm
@@ -996,13 +1013,14 @@ rcp_switch_u8_to_ch_cl rcp_canary_check_nodelay_impl \tag, \x
996
1013
cdp p7 , #0 , c0 , c0 , c0 , #1
997
1014
.endm
998
1015
999
- #endif // HAS_REDUNDANCY_COPROCESSOR
1000
- #endif // !PICO_RP2040
1016
+ #endif // !__riscv
1001
1017
#endif // __ASSEMBLER__
1002
1018
// ----------------------------------------------------------------------------
1003
1019
1004
1020
#ifdef __cplusplus
1005
1021
}
1006
1022
#endif
1023
+ #else
1024
+ #define rcp_is_true (x ) ((int32_t )(x ) < 0 )
1007
1025
#endif
1008
1026
#endif
0 commit comments