Skip to content

Commit d4c8d79

Browse files
charlie-rivospalmer-dabbelt
authored andcommitted
riscv: cpufeature: Extract common elements from extension checking
The __riscv_has_extension_likely() and __riscv_has_extension_unlikely() functions from the vendor_extensions.h can be used to simplify the standard extension checking code as well. Migrate those functions to cpufeature.h and reorganize the code in the file to use the functions. Signed-off-by: Charlie Jenkins <[email protected]> Reviewed-by: Conor Dooley <[email protected]> Reviewed-by: Andy Chiu <[email protected]> Link: https://lore.kernel.org/r/20240719-support_vendor_extensions-v3-4-0af7587bbec0@rivosinc.com Signed-off-by: Palmer Dabbelt <[email protected]>
1 parent 0f24254 commit d4c8d79

File tree

2 files changed

+44
-62
lines changed

2 files changed

+44
-62
lines changed

arch/riscv/include/asm/cpufeature.h

Lines changed: 44 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -104,67 +104,77 @@ extern bool riscv_isa_fallback;
104104

105105
unsigned long riscv_isa_extension_base(const unsigned long *isa_bitmap);
106106

107+
#define STANDARD_EXT 0
108+
107109
bool __riscv_isa_extension_available(const unsigned long *isa_bitmap, unsigned int bit);
108110
#define riscv_isa_extension_available(isa_bitmap, ext) \
109111
__riscv_isa_extension_available(isa_bitmap, RISCV_ISA_EXT_##ext)
110112

111-
static __always_inline bool
112-
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)
113115
{
114-
compiletime_assert(ext < RISCV_ISA_EXT_MAX,
115-
"ext must be < RISCV_ISA_EXT_MAX");
116-
117-
if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE)) {
118-
asm goto(
119-
ALTERNATIVE("j %l[l_no]", "nop", 0, %[ext], 1)
120-
:
121-
: [ext] "i" (ext)
122-
:
123-
: l_no);
124-
} else {
125-
if (!__riscv_isa_extension_available(NULL, ext))
126-
goto l_no;
127-
}
116+
asm goto(ALTERNATIVE("j %l[l_no]", "nop", %[vendor], %[ext], 1)
117+
:
118+
: [vendor] "i" (vendor), [ext] "i" (ext)
119+
:
120+
: l_no);
128121

129122
return true;
130123
l_no:
131124
return false;
132125
}
133126

134-
static __always_inline bool
135-
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)
136129
{
137-
compiletime_assert(ext < RISCV_ISA_EXT_MAX,
138-
"ext must be < RISCV_ISA_EXT_MAX");
139-
140-
if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE)) {
141-
asm goto(
142-
ALTERNATIVE("nop", "j %l[l_yes]", 0, %[ext], 1)
143-
:
144-
: [ext] "i" (ext)
145-
:
146-
: l_yes);
147-
} else {
148-
if (__riscv_isa_extension_available(NULL, ext))
149-
goto l_yes;
150-
}
130+
asm goto(ALTERNATIVE("nop", "j %l[l_yes]", %[vendor], %[ext], 1)
131+
:
132+
: [vendor] "i" (vendor), [ext] "i" (ext)
133+
:
134+
: l_yes);
151135

152136
return false;
153137
l_yes:
154138
return true;
155139
}
156140

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+
157161
static __always_inline bool riscv_cpu_has_extension_likely(int cpu, const unsigned long ext)
158162
{
159-
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))
160167
return true;
161168

162169
return __riscv_isa_extension_available(hart_isa[cpu].isa, ext);
163170
}
164171

165172
static __always_inline bool riscv_cpu_has_extension_unlikely(int cpu, const unsigned long ext)
166173
{
167-
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))
168178
return true;
169179

170180
return __riscv_isa_extension_available(hart_isa[cpu].isa, ext);

arch/riscv/include/asm/vendor_extensions.h

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -48,34 +48,6 @@ bool __riscv_isa_vendor_extension_available(int cpu, unsigned long vendor, unsig
4848
__riscv_isa_vendor_extension_available(VENDOR_EXT_ALL_CPUS, vendor, \
4949
RISCV_ISA_VENDOR_EXT_##ext)
5050

51-
static __always_inline bool __riscv_has_extension_likely(const unsigned long vendor,
52-
const unsigned long ext)
53-
{
54-
asm goto(ALTERNATIVE("j %l[l_no]", "nop", %[vendor], %[ext], 1)
55-
:
56-
: [vendor] "i" (vendor), [ext] "i" (ext)
57-
:
58-
: l_no);
59-
60-
return true;
61-
l_no:
62-
return false;
63-
}
64-
65-
static __always_inline bool __riscv_has_extension_unlikely(const unsigned long vendor,
66-
const unsigned long ext)
67-
{
68-
asm goto(ALTERNATIVE("nop", "j %l[l_yes]", %[vendor], %[ext], 1)
69-
:
70-
: [vendor] "i" (vendor), [ext] "i" (ext)
71-
:
72-
: l_yes);
73-
74-
return false;
75-
l_yes:
76-
return true;
77-
}
78-
7951
static __always_inline bool riscv_has_vendor_extension_likely(const unsigned long vendor,
8052
const unsigned long ext)
8153
{

0 commit comments

Comments
 (0)