NEORV32 - Software Framework Documentation
Loading...
Searching...
No Matches
neorv32_intrinsics.h
Go to the documentation of this file.
1// #################################################################################################
2// # << NEORV32: neorv32_intrinsics.h - Helper functions/macros for (custom) "intrinsics" >> #
3// # ********************************************************************************************* #
4// # BSD 3-Clause License #
5// # #
6// # Copyright (c) 2023, Stephan Nolting. All rights reserved. #
7// # #
8// # Redistribution and use in source and binary forms, with or without modification, are #
9// # permitted provided that the following conditions are met: #
10// # #
11// # 1. Redistributions of source code must retain the above copyright notice, this list of #
12// # conditions and the following disclaimer. #
13// # #
14// # 2. Redistributions in binary form must reproduce the above copyright notice, this list of #
15// # conditions and the following disclaimer in the documentation and/or other materials #
16// # provided with the distribution. #
17// # #
18// # 3. Neither the name of the copyright holder nor the names of its contributors may be used to #
19// # endorse or promote products derived from this software without specific prior written #
20// # permission. #
21// # #
22// # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS #
23// # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF #
24// # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE #
25// # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, #
26// # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE #
27// # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED #
28// # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING #
29// # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED #
30// # OF THE POSSIBILITY OF SUCH DAMAGE. #
31// # ********************************************************************************************* #
32// # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
33// #################################################################################################
34
35
36/**********************************************************************/
41#ifndef neorv32_intrinsics_h
42#define neorv32_intrinsics_h
43
44
45// ****************************************************************************************************************************
46// Custom Instruction Intrinsics
47// Derived from https://github.com/google/CFU-Playground/blob/dfe5c2b75a4540dab62baef1b12fd03bfa78425e/third_party/SaxonSoc/riscv.h
48// Original license header:
49//
50// From https://github.com/SpinalHDL/SaxonSoc/blob/dev-0.1/software/standalone/driver/riscv.h
51//
52// Copyright (c) 2019 SaxonSoc contributors
53//
54// MIT License: https://github.com/SpinalHDL/SaxonSoc/blob/dev-0.1/LICENSE
55//
56// LICENSE:
57// MIT License
58//
59// Copyright (c) 2019 SaxonSoc contributors
60//
61// Permission is hereby granted, free of charge, to any person obtaining a copy
62// of this software and associated documentation files (the "Software"), to deal
63// in the Software without restriction, including without limitation the rights
64// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
65// copies of the Software, and to permit persons to whom the Software is
66// furnished to do so, subject to the following conditions:
67//
68// The above copyright notice and this permission notice shall be included in all
69// copies or substantial portions of the Software.
70//
71// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
72// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
73// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
74// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
75// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
76// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
77// SOFTWARE.
78// ****************************************************************************************************************************
79
80/**********************************************************************/
91asm(".set regnum_x0 , 0");
92asm(".set regnum_x1 , 1");
93asm(".set regnum_x2 , 2");
94asm(".set regnum_x3 , 3");
95asm(".set regnum_x4 , 4");
96asm(".set regnum_x5 , 5");
97asm(".set regnum_x6 , 6");
98asm(".set regnum_x7 , 7");
99asm(".set regnum_x8 , 8");
100asm(".set regnum_x9 , 9");
101asm(".set regnum_x10 , 10");
102asm(".set regnum_x11 , 11");
103asm(".set regnum_x12 , 12");
104asm(".set regnum_x13 , 13");
105asm(".set regnum_x14 , 14");
106asm(".set regnum_x15 , 15");
107asm(".set regnum_x16 , 16");
108asm(".set regnum_x17 , 17");
109asm(".set regnum_x18 , 18");
110asm(".set regnum_x19 , 19");
111asm(".set regnum_x20 , 20");
112asm(".set regnum_x21 , 21");
113asm(".set regnum_x22 , 22");
114asm(".set regnum_x23 , 23");
115asm(".set regnum_x24 , 24");
116asm(".set regnum_x25 , 25");
117asm(".set regnum_x26 , 26");
118asm(".set regnum_x27 , 27");
119asm(".set regnum_x28 , 28");
120asm(".set regnum_x29 , 29");
121asm(".set regnum_x30 , 30");
122asm(".set regnum_x31 , 31");
123
124asm(".set regnum_zero, 0");
125asm(".set regnum_ra , 1");
126asm(".set regnum_sp , 2");
127asm(".set regnum_gp , 3");
128asm(".set regnum_tp , 4");
129asm(".set regnum_t0 , 5");
130asm(".set regnum_t1 , 6");
131asm(".set regnum_t2 , 7");
132asm(".set regnum_s0 , 8");
133asm(".set regnum_s1 , 9");
134asm(".set regnum_a0 , 10");
135asm(".set regnum_a1 , 11");
136asm(".set regnum_a2 , 12");
137asm(".set regnum_a3 , 13");
138asm(".set regnum_a4 , 14");
139asm(".set regnum_a5 , 15");
140asm(".set regnum_a6 , 16");
141asm(".set regnum_a7 , 17");
142asm(".set regnum_s2 , 18");
143asm(".set regnum_s3 , 19");
144asm(".set regnum_s4 , 20");
145asm(".set regnum_s5 , 21");
146asm(".set regnum_s6 , 22");
147asm(".set regnum_s7 , 23");
148asm(".set regnum_s8 , 24");
149asm(".set regnum_s9 , 25");
150asm(".set regnum_s10 , 26");
151asm(".set regnum_s11 , 27");
152asm(".set regnum_t3 , 28");
153asm(".set regnum_t4 , 29");
154asm(".set regnum_t5 , 30");
155asm(".set regnum_t6 , 31");
156
158asm(".set RISCV_OPCODE_CUSTOM0 , 0b0001011");
159asm(".set RISCV_OPCODE_CUSTOM1 , 0b0101011");
160asm(".set RISCV_OPCODE_CUSTOM2 , 0b1011011");
161asm(".set RISCV_OPCODE_CUSTOM3 , 0b1111011");
165/**********************************************************************/
168#define CUSTOM_INSTR_R2_TYPE(funct7, funct5, rs1, funct3, opcode) \
169({ \
170 uint32_t __return; \
171 asm volatile ( \
172 "" \
173 : [output] "=r" (__return) \
174 : [input_i] "r" (rs1) \
175 ); \
176 asm volatile( \
177 ".word ( \
178 (((" #funct7 ") & 0x7f) << 25) | \
179 (((" #funct5 ") & 0x1f) << 20) | \
180 ((( regnum_%1 ) & 0x1f) << 15) | \
181 (((" #funct3 ") & 0x07) << 12) | \
182 ((( regnum_%0 ) & 0x1f) << 7) | \
183 (((" #opcode ") & 0x7f) << 0) \
184 );" \
185 : [rd] "=r" (__return) \
186 : "r" (rs1) \
187 ); \
188 __return; \
189})
190
191
192/**********************************************************************/
195#define CUSTOM_INSTR_R3_TYPE(funct7, rs2, rs1, funct3, opcode) \
196({ \
197 uint32_t __return; \
198 asm volatile ( \
199 "" \
200 : [output] "=r" (__return) \
201 : [input_i] "r" (rs1), \
202 [input_j] "r" (rs2) \
203 ); \
204 asm volatile ( \
205 ".word ( \
206 (((" #funct7 ") & 0x7f) << 25) | \
207 ((( regnum_%2 ) & 0x1f) << 20) | \
208 ((( regnum_%1 ) & 0x1f) << 15) | \
209 (((" #funct3 ") & 0x07) << 12) | \
210 ((( regnum_%0 ) & 0x1f) << 7) | \
211 (((" #opcode ") & 0x7f) << 0) \
212 );" \
213 : [rd] "=r" (__return) \
214 : "r" (rs1), \
215 "r" (rs2) \
216 ); \
217 __return; \
218})
219
220
221/**********************************************************************/
224#define CUSTOM_INSTR_R4_TYPE(rs3, rs2, rs1, funct3, opcode) \
225({ \
226 uint32_t __return; \
227 asm volatile ( \
228 "" \
229 : [output] "=r" (__return) \
230 : [input_i] "r" (rs1), \
231 [input_j] "r" (rs2), \
232 [input_k] "r" (rs3) \
233 ); \
234 asm volatile ( \
235 ".word ( \
236 ((( regnum_%3 ) & 0x1f) << 27) | \
237 ((( regnum_%2 ) & 0x1f) << 20) | \
238 ((( regnum_%1 ) & 0x1f) << 15) | \
239 (((" #funct3 ") & 0x07) << 12) | \
240 ((( regnum_%0 ) & 0x1f) << 7) | \
241 (((" #opcode ") & 0x7f) << 0) \
242 );" \
243 : [rd] "=r" (__return) \
244 : "r" (rs1), \
245 "r" (rs2), \
246 "r" (rs3) \
247 ); \
248 __return; \
249})
250
251
252/**********************************************************************/
256#define CUSTOM_INSTR_R5_TYPE(rs4, rs3, rs2, rs1, opcode) \
257({ \
258 uint32_t __return; \
259 asm volatile ( \
260 "" \
261 : [output] "=r" (__return) \
262 : [input_i] "r" (rs1), \
263 [input_j] "r" (rs2), \
264 [input_k] "r" (rs3), \
265 [input_l] "r" (rs4) \
266 ); \
267 asm volatile ( \
268 ".word ( \
269 ((( regnum_%3 ) & 0x1f) << 27) | \
270 (((( regnum_%4 ) >> 3) & 0x03) << 25) | \
271 ((( regnum_%2 ) & 0x1f) << 20) | \
272 ((( regnum_%1 ) & 0x1f) << 15) | \
273 ((( regnum_%4 ) & 0x07) << 12) | \
274 ((( regnum_%0 ) & 0x1f) << 7) | \
275 (((" #opcode ") & 0x7f) << 0) \
276 );" \
277 : [rd] "=r" (__return) \
278 : "r" (rs1), \
279 "r" (rs2), \
280 "r" (rs3), \
281 "r" (rs4) \
282 ); \
283 __return; \
284})
285
286
287/**********************************************************************/
290#define CUSTOM_INSTR_I_TYPE(imm12, rs1, funct3, opcode) \
291({ \
292 uint32_t __return; \
293 asm volatile ( \
294 "" \
295 : [output] "=r" (__return) \
296 : [input_i] "r" (rs1) \
297 ); \
298 asm volatile ( \
299 ".word ( \
300 (((" #imm12 ") & 0xfff) << 20) | \
301 ((( regnum_%1 ) & 0x1f) << 15) | \
302 (((" #funct3 ") & 0x07) << 12) | \
303 ((( regnum_%0 ) & 0x1f) << 7) | \
304 (((" #opcode ") & 0x7f) << 0) \
305 );" \
306 : [rd] "=r" (__return) \
307 : "r" (rs1) \
308 ); \
309 __return; \
310})
311
312
313/**********************************************************************/
316#define CUSTOM_INSTR_S_TYPE(imm12, rs2, rs1, funct3, opcode) \
317({ \
318 asm volatile ( \
319 "" \
320 : \
321 : [input_i] "r" (rs1), \
322 [input_j] "r" (rs2) \
323 ); \
324 asm volatile ( \
325 ".word ( \
326 ((((" #imm12 ") >> 5) & 0x7f) << 25) | \
327 ((( regnum_%1 ) & 0x1f) << 20) | \
328 ((( regnum_%0 ) & 0x1f) << 15) | \
329 (((" #funct3 ") & 0x07) << 12) | \
330 (((" #imm12 ") & 0x1f) << 7) | \
331 (((" #opcode ") & 0x7f) << 0) \
332 );" \
333 : \
334 : "r" (rs1), \
335 "r" (rs2) \
336 ); \
337})
338
339
340#endif // neorv32_intrinsics_h