NEORV32 Software Framework Documentation
The NEORV32 RISC-V Processor
Loading...
Searching...
No Matches
neorv32_intrinsics.h
Go to the documentation of this file.
1// ================================================================================ //
2// The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 //
3// Copyright (c) NEORV32 contributors. //
4// Copyright (c) 2020 - 2024 Stephan Nolting. All rights reserved. //
5// Licensed under the BSD-3-Clause license, see LICENSE for details. //
6// SPDX-License-Identifier: BSD-3-Clause //
7// ================================================================================ //
8
16#ifndef neorv32_intrinsics_h
17#define neorv32_intrinsics_h
18
19#include <stdint.h>
20
21
22// ****************************************************************************************************************************
23// Custom Instruction Intrinsics
24// Derived from https://github.com/google/CFU-Playground/blob/dfe5c2b75a4540dab62baef1b12fd03bfa78425e/third_party/SaxonSoc/riscv.h
25// Original license header:
26//
27// From https://github.com/SpinalHDL/SaxonSoc/blob/dev-0.1/software/standalone/driver/riscv.h
28//
29// Copyright (c) 2019 SaxonSoc contributors
30//
31// MIT License: https://github.com/SpinalHDL/SaxonSoc/blob/dev-0.1/LICENSE
32//
33// LICENSE:
34// MIT License
35//
36// Copyright (c) 2019 SaxonSoc contributors
37//
38// Permission is hereby granted, free of charge, to any person obtaining a copy
39// of this software and associated documentation files (the "Software"), to deal
40// in the Software without restriction, including without limitation the rights
41// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
42// copies of the Software, and to permit persons to whom the Software is
43// furnished to do so, subject to the following conditions:
44//
45// The above copyright notice and this permission notice shall be included in all
46// copies or substantial portions of the Software.
47//
48// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
49// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
50// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
51// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
52// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
53// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
54// SOFTWARE.
55// ****************************************************************************************************************************
56
57
58/**********************************************************************/
61asm (
62 ".set reg_x0, 0 \n"
63 ".set reg_x1, 1 \n"
64 ".set reg_x2, 2 \n"
65 ".set reg_x3, 3 \n"
66 ".set reg_x4, 4 \n"
67 ".set reg_x5, 5 \n"
68 ".set reg_x6, 6 \n"
69 ".set reg_x7, 7 \n"
70 ".set reg_x8, 8 \n"
71 ".set reg_x9, 9 \n"
72 ".set reg_x10, 10 \n"
73 ".set reg_x11, 11 \n"
74 ".set reg_x12, 12 \n"
75 ".set reg_x13, 13 \n"
76 ".set reg_x14, 14 \n"
77 ".set reg_x15, 15 \n"
78#ifndef __riscv_32e
79 ".set reg_x16, 16 \n"
80 ".set reg_x17, 17 \n"
81 ".set reg_x18, 18 \n"
82 ".set reg_x19, 19 \n"
83 ".set reg_x20, 20 \n"
84 ".set reg_x21, 21 \n"
85 ".set reg_x22, 22 \n"
86 ".set reg_x23, 23 \n"
87 ".set reg_x24, 24 \n"
88 ".set reg_x25, 25 \n"
89 ".set reg_x26, 26 \n"
90 ".set reg_x27, 27 \n"
91 ".set reg_x28, 28 \n"
92 ".set reg_x29, 29 \n"
93 ".set reg_x30, 30 \n"
94 ".set reg_x31, 31 \n"
95#endif
96 ".set reg_zero, 0 \n"
97 ".set reg_ra, 1 \n"
98 ".set reg_sp, 2 \n"
99 ".set reg_gp, 3 \n"
100 ".set reg_tp, 4 \n"
101 ".set reg_t0, 5 \n"
102 ".set reg_t1, 6 \n"
103 ".set reg_t2, 7 \n"
104 ".set reg_s0, 8 \n"
105 ".set reg_s1, 9 \n"
106 ".set reg_a0, 10 \n"
107 ".set reg_a1, 11 \n"
108 ".set reg_a2, 12 \n"
109 ".set reg_a3, 13 \n"
110 ".set reg_a4, 14 \n"
111 ".set reg_a5, 15 \n"
112#ifndef __riscv_32e
113 ".set reg_a6, 16 \n"
114 ".set reg_a7, 17 \n"
115 ".set reg_s2, 18 \n"
116 ".set reg_s3, 19 \n"
117 ".set reg_s4, 20 \n"
118 ".set reg_s5, 21 \n"
119 ".set reg_s6, 22 \n"
120 ".set reg_s7, 23 \n"
121 ".set reg_s8, 24 \n"
122 ".set reg_s9, 25 \n"
123 ".set reg_s10, 26 \n"
124 ".set reg_s11, 27 \n"
125 ".set reg_t3, 28 \n"
126 ".set reg_t4, 29 \n"
127 ".set reg_t5, 30 \n"
128 ".set reg_t6, 31 \n"
129#endif
130);
131
132
133/**********************************************************************/
136#define CUSTOM_INSTR_R2_TYPE(funct7, funct5, rs1, funct3, opcode) \
137({ \
138 uint32_t __return; \
139 asm volatile ( \
140 "" \
141 : [output] "=r" (__return) \
142 : [input_i] "r" (rs1) \
143 ); \
144 asm volatile( \
145 ".word ( \
146 (((" #funct7 ") & 0x7f) << 25) | \
147 (((" #funct5 ") & 0x1f) << 20) | \
148 ((( reg_%1 ) & 0x1f) << 15) | \
149 (((" #funct3 ") & 0x07) << 12) | \
150 ((( reg_%0 ) & 0x1f) << 7) | \
151 (((" #opcode ") & 0x7f) << 0) \
152 );" \
153 : [rd] "=r" (__return) \
154 : "r" (rs1) \
155 ); \
156 __return; \
157})
158
159
160/**********************************************************************/
163#define CUSTOM_INSTR_R3_TYPE(funct7, rs2, rs1, funct3, opcode) \
164({ \
165 uint32_t __return; \
166 asm volatile ( \
167 "" \
168 : [output] "=r" (__return) \
169 : [input_i] "r" (rs1), \
170 [input_j] "r" (rs2) \
171 ); \
172 asm volatile ( \
173 ".word ( \
174 (((" #funct7 ") & 0x7f) << 25) | \
175 ((( reg_%2 ) & 0x1f) << 20) | \
176 ((( reg_%1 ) & 0x1f) << 15) | \
177 (((" #funct3 ") & 0x07) << 12) | \
178 ((( reg_%0 ) & 0x1f) << 7) | \
179 (((" #opcode ") & 0x7f) << 0) \
180 );" \
181 : [rd] "=r" (__return) \
182 : "r" (rs1), \
183 "r" (rs2) \
184 ); \
185 __return; \
186})
187
188
189/**********************************************************************/
192#define CUSTOM_INSTR_R4_TYPE(rs3, rs2, rs1, funct3, opcode) \
193({ \
194 uint32_t __return; \
195 asm volatile ( \
196 "" \
197 : [output] "=r" (__return) \
198 : [input_i] "r" (rs1), \
199 [input_j] "r" (rs2), \
200 [input_k] "r" (rs3) \
201 ); \
202 asm volatile ( \
203 ".word ( \
204 ((( reg_%3 ) & 0x1f) << 27) | \
205 ((( reg_%2 ) & 0x1f) << 20) | \
206 ((( reg_%1 ) & 0x1f) << 15) | \
207 (((" #funct3 ") & 0x07) << 12) | \
208 ((( reg_%0 ) & 0x1f) << 7) | \
209 (((" #opcode ") & 0x7f) << 0) \
210 );" \
211 : [rd] "=r" (__return) \
212 : "r" (rs1), \
213 "r" (rs2), \
214 "r" (rs3) \
215 ); \
216 __return; \
217})
218
219
220/**********************************************************************/
224#define CUSTOM_INSTR_R5_TYPE(rs4, rs3, rs2, rs1, 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 [input_l] "r" (rs4) \
234 ); \
235 asm volatile ( \
236 ".word ( \
237 ((( reg_%3 ) & 0x1f) << 27) | \
238 (((( reg_%4 ) >> 3) & 0x03) << 25) | \
239 ((( reg_%2 ) & 0x1f) << 20) | \
240 ((( reg_%1 ) & 0x1f) << 15) | \
241 ((( reg_%4 ) & 0x07) << 12) | \
242 ((( reg_%0 ) & 0x1f) << 7) | \
243 (((" #opcode ") & 0x7f) << 0) \
244 );" \
245 : [rd] "=r" (__return) \
246 : "r" (rs1), \
247 "r" (rs2), \
248 "r" (rs3), \
249 "r" (rs4) \
250 ); \
251 __return; \
252})
253
254
255/**********************************************************************/
258#define CUSTOM_INSTR_I_TYPE(imm12, rs1, funct3, opcode) \
259({ \
260 uint32_t __return; \
261 asm volatile ( \
262 "" \
263 : [output] "=r" (__return) \
264 : [input_i] "r" (rs1) \
265 ); \
266 asm volatile ( \
267 ".word ( \
268 (((" #imm12 ") & 0xfff) << 20) | \
269 ((( reg_%1 ) & 0x1f) << 15) | \
270 (((" #funct3 ") & 0x07) << 12) | \
271 ((( reg_%0 ) & 0x1f) << 7) | \
272 (((" #opcode ") & 0x7f) << 0) \
273 );" \
274 : [rd] "=r" (__return) \
275 : "r" (rs1) \
276 ); \
277 __return; \
278})
279
280
281/**********************************************************************/
284#define CUSTOM_INSTR_S_TYPE(imm12, rs2, rs1, funct3, opcode) \
285({ \
286 asm volatile ( \
287 "" \
288 : \
289 : [input_i] "r" (rs1), \
290 [input_j] "r" (rs2) \
291 ); \
292 asm volatile ( \
293 ".word ( \
294 ((((" #imm12 ") >> 5) & 0x7f) << 25) | \
295 ((( reg_%1 ) & 0x1f) << 20) | \
296 ((( reg_%0 ) & 0x1f) << 15) | \
297 (((" #funct3 ") & 0x07) << 12) | \
298 (((" #imm12 ") & 0x1f) << 7) | \
299 (((" #opcode ") & 0x7f) << 0) \
300 );" \
301 : \
302 : "r" (rs1), \
303 "r" (rs2) \
304 ); \
305})
306
307
308#endif // neorv32_intrinsics_h