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) 2022, 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");
163/**********************************************************************/
166#define CUSTOM_INSTR_R1_TYPE(funct7, funct5, rs1, funct3, opcode) \
167({ \
168 uint32_t __return; \
169 asm volatile ( \
170 "" \
171 : [output] "=r" (__return) \
172 : [input_i] "r" (rs1) \
173 ); \
174 asm volatile( \
175 ".word ( \
176 (((" #funct7 ") & 0x7f) << 25) | \
177 (((" #funct5 ") & 0x1f) << 20) | \
178 ((( regnum_%1 ) & 0x1f) << 15) | \
179 (((" #funct3 ") & 0x07) << 12) | \
180 ((( regnum_%0 ) & 0x1f) << 7) | \
181 (((" #opcode ") & 0x7f) << 0) \
182 );" \
183 : [rd] "=r" (__return) \
184 : "r" (rs1) \
185 ); \
186 __return; \
187})
188
189
190/**********************************************************************/
193#define CUSTOM_INSTR_R2_TYPE(funct7, rs2, rs1, funct3, opcode) \
194({ \
195 uint32_t __return; \
196 asm volatile ( \
197 "" \
198 : [output] "=r" (__return) \
199 : [input_i] "r" (rs1), \
200 [input_j] "r" (rs2) \
201 ); \
202 asm volatile ( \
203 ".word ( \
204 (((" #funct7 ") & 0x7f) << 25) | \
205 ((( regnum_%2 ) & 0x1f) << 20) | \
206 ((( regnum_%1 ) & 0x1f) << 15) | \
207 (((" #funct3 ") & 0x07) << 12) | \
208 ((( regnum_%0 ) & 0x1f) << 7) | \
209 (((" #opcode ") & 0x7f) << 0) \
210 );" \
211 : [rd] "=r" (__return) \
212 : "r" (rs1), \
213 "r" (rs2) \
214 ); \
215 __return; \
216})
217
218
219/**********************************************************************/
222#define CUSTOM_INSTR_R3_TYPE(rs3, rs2, rs1, funct3, opcode) \
223({ \
224 uint32_t __return; \
225 asm volatile ( \
226 "" \
227 : [output] "=r" (__return) \
228 : [input_i] "r" (rs1), \
229 [input_j] "r" (rs2), \
230 [input_k] "r" (rs3) \
231 ); \
232 asm volatile ( \
233 ".word ( \
234 ((( regnum_%3 ) & 0x1f) << 25) | \
235 ((( regnum_%2 ) & 0x1f) << 20) | \
236 ((( regnum_%1 ) & 0x1f) << 15) | \
237 (((" #funct3 ") & 0x07) << 12) | \
238 ((( regnum_%0 ) & 0x1f) << 7) | \
239 (((" #opcode ") & 0x7f) << 0) \
240 );" \
241 : [rd] "=r" (__return) \
242 : "r" (rs1), \
243 "r" (rs2), \
244 "r" (rs3) \
245 ); \
246 __return; \
247})
248
249
250/**********************************************************************/
253#define CUSTOM_INSTR_I_TYPE(imm12, rs1, funct3, opcode) \
254({ \
255 uint32_t __return; \
256 asm volatile ( \
257 "" \
258 : [output] "=r" (__return) \
259 : [input_i] "r" (rs1) \
260 ); \
261 asm volatile ( \
262 ".word ( \
263 (((" #imm12 ") & 0xfff) << 20) | \
264 ((( regnum_%1 ) & 0x1f) << 15) | \
265 (((" #funct3 ") & 0x07) << 12) | \
266 ((( regnum_%0 ) & 0x1f) << 7) | \
267 (((" #opcode ") & 0x7f) << 0) \
268 );" \
269 : [rd] "=r" (__return) \
270 : "r" (rs1) \
271 ); \
272 __return; \
273})
274
275
276#endif // neorv32_intrinsics_h