@@ -33,6 +33,31 @@ extern struct riscv_isainfo hart_isa[NR_CPUS];
3333
3434void riscv_user_isa_enable (void );
3535
36+ #define _RISCV_ISA_EXT_DATA (_name , _id , _subset_exts , _subset_exts_size , _validate ) { \
37+ .name = #_name, \
38+ .property = #_name, \
39+ .id = _id, \
40+ .subset_ext_ids = _subset_exts, \
41+ .subset_ext_size = _subset_exts_size, \
42+ .validate = _validate \
43+ }
44+
45+ #define __RISCV_ISA_EXT_DATA (_name , _id ) _RISCV_ISA_EXT_DATA(_name, _id, NULL, 0, NULL)
46+
47+ #define __RISCV_ISA_EXT_DATA_VALIDATE (_name , _id , _validate ) \
48+ _RISCV_ISA_EXT_DATA(_name, _id, NULL, 0, _validate)
49+
50+ /* Used to declare pure "lasso" extension (Zk for instance) */
51+ #define __RISCV_ISA_EXT_BUNDLE (_name , _bundled_exts ) \
52+ _RISCV_ISA_EXT_DATA(_name, RISCV_ISA_EXT_INVALID, _bundled_exts, \
53+ ARRAY_SIZE(_bundled_exts), NULL)
54+
55+ /* Used to declare extensions that are a superset of other extensions (Zvbb for instance) */
56+ #define __RISCV_ISA_EXT_SUPERSET (_name , _id , _sub_exts ) \
57+ _RISCV_ISA_EXT_DATA(_name, _id, _sub_exts, ARRAY_SIZE(_sub_exts), NULL)
58+ #define __RISCV_ISA_EXT_SUPERSET_VALIDATE (_name , _id , _sub_exts , _validate ) \
59+ _RISCV_ISA_EXT_DATA(_name, _id, _sub_exts, ARRAY_SIZE(_sub_exts), _validate)
60+
3661#if defined(CONFIG_RISCV_MISALIGNED )
3762bool check_unaligned_access_emulated_all_cpus (void );
3863void unaligned_emulation_finish (void );
@@ -79,67 +104,77 @@ extern bool riscv_isa_fallback;
79104
80105unsigned long riscv_isa_extension_base (const unsigned long * isa_bitmap );
81106
107+ #define STANDARD_EXT 0
108+
82109bool __riscv_isa_extension_available (const unsigned long * isa_bitmap , unsigned int bit );
83110#define riscv_isa_extension_available (isa_bitmap , ext ) \
84111 __riscv_isa_extension_available(isa_bitmap, RISCV_ISA_EXT_##ext)
85112
86- static __always_inline bool
87- riscv_has_extension_likely ( const unsigned long ext )
113+ static __always_inline bool __riscv_has_extension_likely ( const unsigned long vendor ,
114+ const unsigned long ext )
88115{
89- compiletime_assert (ext < RISCV_ISA_EXT_MAX ,
90- "ext must be < RISCV_ISA_EXT_MAX" );
91-
92- if (IS_ENABLED (CONFIG_RISCV_ALTERNATIVE )) {
93- asm goto(
94- ALTERNATIVE ("j %l[l_no]" , "nop" , 0 , %[ext ], 1 )
95- :
96- : [ext ] "i" (ext )
97- :
98- : l_no );
99- } else {
100- if (!__riscv_isa_extension_available (NULL , ext ))
101- goto l_no ;
102- }
116+ asm goto(ALTERNATIVE ("j %l[l_no]" , "nop" , %[vendor ], %[ext ], 1 )
117+ :
118+ : [vendor ] "i" (vendor ), [ext ] "i" (ext )
119+ :
120+ : l_no );
103121
104122 return true;
105123l_no :
106124 return false;
107125}
108126
109- static __always_inline bool
110- riscv_has_extension_unlikely ( const unsigned long ext )
127+ static __always_inline bool __riscv_has_extension_unlikely ( const unsigned long vendor ,
128+ const unsigned long ext )
111129{
112- compiletime_assert (ext < RISCV_ISA_EXT_MAX ,
113- "ext must be < RISCV_ISA_EXT_MAX" );
114-
115- if (IS_ENABLED (CONFIG_RISCV_ALTERNATIVE )) {
116- asm goto(
117- ALTERNATIVE ("nop" , "j %l[l_yes]" , 0 , %[ext ], 1 )
118- :
119- : [ext ] "i" (ext )
120- :
121- : l_yes );
122- } else {
123- if (__riscv_isa_extension_available (NULL , ext ))
124- goto l_yes ;
125- }
130+ asm goto(ALTERNATIVE ("nop" , "j %l[l_yes]" , %[vendor ], %[ext ], 1 )
131+ :
132+ : [vendor ] "i" (vendor ), [ext ] "i" (ext )
133+ :
134+ : l_yes );
126135
127136 return false;
128137l_yes :
129138 return true;
130139}
131140
141+ static __always_inline bool riscv_has_extension_unlikely (const unsigned long ext )
142+ {
143+ compiletime_assert (ext < RISCV_ISA_EXT_MAX , "ext must be < RISCV_ISA_EXT_MAX" );
144+
145+ if (IS_ENABLED (CONFIG_RISCV_ALTERNATIVE ))
146+ return __riscv_has_extension_unlikely (STANDARD_EXT , ext );
147+
148+ return __riscv_isa_extension_available (NULL , ext );
149+ }
150+
151+ static __always_inline bool riscv_has_extension_likely (const unsigned long ext )
152+ {
153+ compiletime_assert (ext < RISCV_ISA_EXT_MAX , "ext must be < RISCV_ISA_EXT_MAX" );
154+
155+ if (IS_ENABLED (CONFIG_RISCV_ALTERNATIVE ))
156+ return __riscv_has_extension_likely (STANDARD_EXT , ext );
157+
158+ return __riscv_isa_extension_available (NULL , ext );
159+ }
160+
132161static __always_inline bool riscv_cpu_has_extension_likely (int cpu , const unsigned long ext )
133162{
134- if (IS_ENABLED (CONFIG_RISCV_ALTERNATIVE ) && riscv_has_extension_likely (ext ))
163+ compiletime_assert (ext < RISCV_ISA_EXT_MAX , "ext must be < RISCV_ISA_EXT_MAX" );
164+
165+ if (IS_ENABLED (CONFIG_RISCV_ALTERNATIVE ) &&
166+ __riscv_has_extension_likely (STANDARD_EXT , ext ))
135167 return true;
136168
137169 return __riscv_isa_extension_available (hart_isa [cpu ].isa , ext );
138170}
139171
140172static __always_inline bool riscv_cpu_has_extension_unlikely (int cpu , const unsigned long ext )
141173{
142- if (IS_ENABLED (CONFIG_RISCV_ALTERNATIVE ) && riscv_has_extension_unlikely (ext ))
174+ compiletime_assert (ext < RISCV_ISA_EXT_MAX , "ext must be < RISCV_ISA_EXT_MAX" );
175+
176+ if (IS_ENABLED (CONFIG_RISCV_ALTERNATIVE ) &&
177+ __riscv_has_extension_unlikely (STANDARD_EXT , ext ))
143178 return true;
144179
145180 return __riscv_isa_extension_available (hart_isa [cpu ].isa , ext );
0 commit comments