NEORV32 - Software Framework Documentation
Loading...
Searching...
No Matches
sw
lib
include
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
/**********************************************************************/
91
asm
(
".set regnum_x0 , 0"
);
92
asm
(
".set regnum_x1 , 1"
);
93
asm
(
".set regnum_x2 , 2"
);
94
asm
(
".set regnum_x3 , 3"
);
95
asm
(
".set regnum_x4 , 4"
);
96
asm
(
".set regnum_x5 , 5"
);
97
asm
(
".set regnum_x6 , 6"
);
98
asm
(
".set regnum_x7 , 7"
);
99
asm
(
".set regnum_x8 , 8"
);
100
asm
(
".set regnum_x9 , 9"
);
101
asm
(
".set regnum_x10 , 10"
);
102
asm
(
".set regnum_x11 , 11"
);
103
asm
(
".set regnum_x12 , 12"
);
104
asm
(
".set regnum_x13 , 13"
);
105
asm
(
".set regnum_x14 , 14"
);
106
asm
(
".set regnum_x15 , 15"
);
107
asm
(
".set regnum_x16 , 16"
);
108
asm
(
".set regnum_x17 , 17"
);
109
asm
(
".set regnum_x18 , 18"
);
110
asm
(
".set regnum_x19 , 19"
);
111
asm
(
".set regnum_x20 , 20"
);
112
asm
(
".set regnum_x21 , 21"
);
113
asm
(
".set regnum_x22 , 22"
);
114
asm
(
".set regnum_x23 , 23"
);
115
asm
(
".set regnum_x24 , 24"
);
116
asm
(
".set regnum_x25 , 25"
);
117
asm
(
".set regnum_x26 , 26"
);
118
asm
(
".set regnum_x27 , 27"
);
119
asm
(
".set regnum_x28 , 28"
);
120
asm
(
".set regnum_x29 , 29"
);
121
asm
(
".set regnum_x30 , 30"
);
122
asm
(
".set regnum_x31 , 31"
);
123
124
asm
(
".set regnum_zero, 0"
);
125
asm
(
".set regnum_ra , 1"
);
126
asm
(
".set regnum_sp , 2"
);
127
asm
(
".set regnum_gp , 3"
);
128
asm
(
".set regnum_tp , 4"
);
129
asm
(
".set regnum_t0 , 5"
);
130
asm
(
".set regnum_t1 , 6"
);
131
asm
(
".set regnum_t2 , 7"
);
132
asm
(
".set regnum_s0 , 8"
);
133
asm
(
".set regnum_s1 , 9"
);
134
asm
(
".set regnum_a0 , 10"
);
135
asm
(
".set regnum_a1 , 11"
);
136
asm
(
".set regnum_a2 , 12"
);
137
asm
(
".set regnum_a3 , 13"
);
138
asm
(
".set regnum_a4 , 14"
);
139
asm
(
".set regnum_a5 , 15"
);
140
asm
(
".set regnum_a6 , 16"
);
141
asm
(
".set regnum_a7 , 17"
);
142
asm
(
".set regnum_s2 , 18"
);
143
asm
(
".set regnum_s3 , 19"
);
144
asm
(
".set regnum_s4 , 20"
);
145
asm
(
".set regnum_s5 , 21"
);
146
asm
(
".set regnum_s6 , 22"
);
147
asm
(
".set regnum_s7 , 23"
);
148
asm
(
".set regnum_s8 , 24"
);
149
asm
(
".set regnum_s9 , 25"
);
150
asm
(
".set regnum_s10 , 26"
);
151
asm
(
".set regnum_s11 , 27"
);
152
asm
(
".set regnum_t3 , 28"
);
153
asm
(
".set regnum_t4 , 29"
);
154
asm
(
".set regnum_t5 , 30"
);
155
asm
(
".set regnum_t6 , 31"
);
156
158
asm
(
".set RISCV_OPCODE_CUSTOM0 , 0b0001011"
);
159
asm
(
".set RISCV_OPCODE_CUSTOM1 , 0b0101011"
);
160
asm
(
".set RISCV_OPCODE_CUSTOM2 , 0b1011011"
);
161
asm
(
".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
Generated by
1.10.0