RISC-V: Fallback for instructions longer than 64b
[binutils-gdb.git] / sim / lm32 / cpu.h
1 /* CPU family header for lm32bf.
2
3 THIS FILE IS MACHINE GENERATED WITH CGEN.
4
5 Copyright 1996-2022 Free Software Foundation, Inc.
6
7 This file is part of the GNU simulators.
8
9 This file is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3, or (at your option)
12 any later version.
13
14 It is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 License for more details.
18
19 You should have received a copy of the GNU General Public License along
20 with this program; if not, see <http://www.gnu.org/licenses/>.
21
22 */
23
24 #ifndef CPU_LM32BF_H
25 #define CPU_LM32BF_H
26
27 /* Maximum number of instructions that are fetched at a time.
28 This is for LIW type instructions sets (e.g. m32r). */
29 #define MAX_LIW_INSNS 1
30
31 /* Maximum number of instructions that can be executed in parallel. */
32 #define MAX_PARALLEL_INSNS 1
33
34 /* The size of an "int" needed to hold an instruction word.
35 This is usually 32 bits, but some architectures needs 64 bits. */
36 typedef CGEN_INSN_INT CGEN_INSN_WORD;
37
38 #include "cgen-engine.h"
39
40 /* CPU state information. */
41 typedef struct {
42 /* Hardware elements. */
43 struct {
44 /* Program counter */
45 USI h_pc;
46 #define GET_H_PC() CPU (h_pc)
47 #define SET_H_PC(x) (CPU (h_pc) = (x))
48 /* General purpose registers */
49 SI h_gr[32];
50 #define GET_H_GR(a1) CPU (h_gr)[a1]
51 #define SET_H_GR(a1, x) (CPU (h_gr)[a1] = (x))
52 /* Control and status registers */
53 SI h_csr[32];
54 #define GET_H_CSR(a1) CPU (h_csr)[a1]
55 #define SET_H_CSR(a1, x) (CPU (h_csr)[a1] = (x))
56 } hardware;
57 #define CPU_CGEN_HW(cpu) (& (cpu)->cpu_data.hardware)
58 } LM32BF_CPU_DATA;
59
60 /* Cover fns for register access. */
61 USI lm32bf_h_pc_get (SIM_CPU *);
62 void lm32bf_h_pc_set (SIM_CPU *, USI);
63 SI lm32bf_h_gr_get (SIM_CPU *, UINT);
64 void lm32bf_h_gr_set (SIM_CPU *, UINT, SI);
65 SI lm32bf_h_csr_get (SIM_CPU *, UINT);
66 void lm32bf_h_csr_set (SIM_CPU *, UINT, SI);
67
68 /* These must be hand-written. */
69 extern CPUREG_FETCH_FN lm32bf_fetch_register;
70 extern CPUREG_STORE_FN lm32bf_store_register;
71
72 typedef struct {
73 int empty;
74 } MODEL_LM32_DATA;
75
76 /* Instruction argument buffer. */
77
78 union sem_fields {
79 struct { /* no operands */
80 int empty;
81 } sfmt_empty;
82 struct { /* */
83 IADDR i_call;
84 } sfmt_bi;
85 struct { /* */
86 UINT f_csr;
87 UINT f_r1;
88 } sfmt_wcsr;
89 struct { /* */
90 UINT f_csr;
91 UINT f_r2;
92 } sfmt_rcsr;
93 struct { /* */
94 IADDR i_branch;
95 UINT f_r0;
96 UINT f_r1;
97 } sfmt_be;
98 struct { /* */
99 UINT f_r0;
100 UINT f_r1;
101 UINT f_uimm;
102 } sfmt_andi;
103 struct { /* */
104 INT f_imm;
105 UINT f_r0;
106 UINT f_r1;
107 } sfmt_addi;
108 struct { /* */
109 UINT f_r0;
110 UINT f_r1;
111 UINT f_r2;
112 UINT f_user;
113 } sfmt_user;
114 #if WITH_SCACHE_PBB
115 /* Writeback handler. */
116 struct {
117 /* Pointer to argbuf entry for insn whose results need writing back. */
118 const struct argbuf *abuf;
119 } write;
120 /* x-before handler */
121 struct {
122 /*const SCACHE *insns[MAX_PARALLEL_INSNS];*/
123 int first_p;
124 } before;
125 /* x-after handler */
126 struct {
127 int empty;
128 } after;
129 /* This entry is used to terminate each pbb. */
130 struct {
131 /* Number of insns in pbb. */
132 int insn_count;
133 /* Next pbb to execute. */
134 SCACHE *next;
135 SCACHE *branch_target;
136 } chain;
137 #endif
138 };
139
140 /* The ARGBUF struct. */
141 struct argbuf {
142 /* These are the baseclass definitions. */
143 IADDR addr;
144 const IDESC *idesc;
145 char trace_p;
146 char profile_p;
147 /* ??? Temporary hack for skip insns. */
148 char skip_count;
149 char unused;
150 /* cpu specific data follows */
151 union sem semantic;
152 int written;
153 union sem_fields fields;
154 };
155
156 /* A cached insn.
157
158 ??? SCACHE used to contain more than just argbuf. We could delete the
159 type entirely and always just use ARGBUF, but for future concerns and as
160 a level of abstraction it is left in. */
161
162 struct scache {
163 struct argbuf argbuf;
164 };
165
166 /* From traps.c. */
167 extern USI lm32bf_b_insn (SIM_CPU * current_cpu, USI r0, USI f_r0);
168 extern USI lm32bf_divu_insn (SIM_CPU * current_cpu, IADDR pc, USI r0, USI r1, USI r2);
169 extern USI lm32bf_modu_insn (SIM_CPU * current_cpu, IADDR pc, USI r0, USI r1, USI r2);
170 extern void lm32bf_wcsr_insn (SIM_CPU * current_cpu, USI f_csr, USI r1);
171 extern USI lm32bf_break_insn (SIM_CPU * current_cpu, IADDR pc);
172 extern USI lm32bf_scall_insn (SIM_CPU * current_cpu, IADDR pc);
173
174 /* From user.c. */
175 extern UINT lm32bf_user_insn (SIM_CPU * current_cpu, INT r0, INT r1, UINT imm);
176
177 /* Macros to simplify extraction, reading and semantic code.
178 These define and assign the local vars that contain the insn's fields. */
179
180 #define EXTRACT_IFMT_EMPTY_VARS \
181 unsigned int length;
182 #define EXTRACT_IFMT_EMPTY_CODE \
183 length = 0; \
184
185 #define EXTRACT_IFMT_ADD_VARS \
186 UINT f_opcode; \
187 UINT f_r0; \
188 UINT f_r1; \
189 UINT f_r2; \
190 UINT f_resv0; \
191 unsigned int length;
192 #define EXTRACT_IFMT_ADD_CODE \
193 length = 4; \
194 f_opcode = EXTRACT_LSB0_UINT (insn, 32, 31, 6); \
195 f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5); \
196 f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5); \
197 f_r2 = EXTRACT_LSB0_UINT (insn, 32, 15, 5); \
198 f_resv0 = EXTRACT_LSB0_UINT (insn, 32, 10, 11); \
199
200 #define EXTRACT_IFMT_ADDI_VARS \
201 UINT f_opcode; \
202 UINT f_r0; \
203 UINT f_r1; \
204 INT f_imm; \
205 unsigned int length;
206 #define EXTRACT_IFMT_ADDI_CODE \
207 length = 4; \
208 f_opcode = EXTRACT_LSB0_UINT (insn, 32, 31, 6); \
209 f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5); \
210 f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5); \
211 f_imm = EXTRACT_LSB0_SINT (insn, 32, 15, 16); \
212
213 #define EXTRACT_IFMT_ANDI_VARS \
214 UINT f_opcode; \
215 UINT f_r0; \
216 UINT f_r1; \
217 UINT f_uimm; \
218 unsigned int length;
219 #define EXTRACT_IFMT_ANDI_CODE \
220 length = 4; \
221 f_opcode = EXTRACT_LSB0_UINT (insn, 32, 31, 6); \
222 f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5); \
223 f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5); \
224 f_uimm = EXTRACT_LSB0_UINT (insn, 32, 15, 16); \
225
226 #define EXTRACT_IFMT_ANDHII_VARS \
227 UINT f_opcode; \
228 UINT f_r0; \
229 UINT f_r1; \
230 UINT f_uimm; \
231 unsigned int length;
232 #define EXTRACT_IFMT_ANDHII_CODE \
233 length = 4; \
234 f_opcode = EXTRACT_LSB0_UINT (insn, 32, 31, 6); \
235 f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5); \
236 f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5); \
237 f_uimm = EXTRACT_LSB0_UINT (insn, 32, 15, 16); \
238
239 #define EXTRACT_IFMT_B_VARS \
240 UINT f_opcode; \
241 UINT f_r0; \
242 UINT f_r1; \
243 UINT f_r2; \
244 UINT f_resv0; \
245 unsigned int length;
246 #define EXTRACT_IFMT_B_CODE \
247 length = 4; \
248 f_opcode = EXTRACT_LSB0_UINT (insn, 32, 31, 6); \
249 f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5); \
250 f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5); \
251 f_r2 = EXTRACT_LSB0_UINT (insn, 32, 15, 5); \
252 f_resv0 = EXTRACT_LSB0_UINT (insn, 32, 10, 11); \
253
254 #define EXTRACT_IFMT_BI_VARS \
255 UINT f_opcode; \
256 SI f_call; \
257 unsigned int length;
258 #define EXTRACT_IFMT_BI_CODE \
259 length = 4; \
260 f_opcode = EXTRACT_LSB0_UINT (insn, 32, 31, 6); \
261 f_call = ((pc) + (((SI) (((EXTRACT_LSB0_SINT (insn, 32, 25, 26)) << (6))) >> (4)))); \
262
263 #define EXTRACT_IFMT_BE_VARS \
264 UINT f_opcode; \
265 UINT f_r0; \
266 UINT f_r1; \
267 SI f_branch; \
268 unsigned int length;
269 #define EXTRACT_IFMT_BE_CODE \
270 length = 4; \
271 f_opcode = EXTRACT_LSB0_UINT (insn, 32, 31, 6); \
272 f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5); \
273 f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5); \
274 f_branch = ((pc) + (((SI) (((EXTRACT_LSB0_SINT (insn, 32, 15, 16)) << (16))) >> (14)))); \
275
276 #define EXTRACT_IFMT_ORI_VARS \
277 UINT f_opcode; \
278 UINT f_r0; \
279 UINT f_r1; \
280 UINT f_uimm; \
281 unsigned int length;
282 #define EXTRACT_IFMT_ORI_CODE \
283 length = 4; \
284 f_opcode = EXTRACT_LSB0_UINT (insn, 32, 31, 6); \
285 f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5); \
286 f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5); \
287 f_uimm = EXTRACT_LSB0_UINT (insn, 32, 15, 16); \
288
289 #define EXTRACT_IFMT_RCSR_VARS \
290 UINT f_opcode; \
291 UINT f_csr; \
292 UINT f_r1; \
293 UINT f_r2; \
294 UINT f_resv0; \
295 unsigned int length;
296 #define EXTRACT_IFMT_RCSR_CODE \
297 length = 4; \
298 f_opcode = EXTRACT_LSB0_UINT (insn, 32, 31, 6); \
299 f_csr = EXTRACT_LSB0_UINT (insn, 32, 25, 5); \
300 f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5); \
301 f_r2 = EXTRACT_LSB0_UINT (insn, 32, 15, 5); \
302 f_resv0 = EXTRACT_LSB0_UINT (insn, 32, 10, 11); \
303
304 #define EXTRACT_IFMT_SEXTB_VARS \
305 UINT f_opcode; \
306 UINT f_r0; \
307 UINT f_r1; \
308 UINT f_r2; \
309 UINT f_resv0; \
310 unsigned int length;
311 #define EXTRACT_IFMT_SEXTB_CODE \
312 length = 4; \
313 f_opcode = EXTRACT_LSB0_UINT (insn, 32, 31, 6); \
314 f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5); \
315 f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5); \
316 f_r2 = EXTRACT_LSB0_UINT (insn, 32, 15, 5); \
317 f_resv0 = EXTRACT_LSB0_UINT (insn, 32, 10, 11); \
318
319 #define EXTRACT_IFMT_USER_VARS \
320 UINT f_opcode; \
321 UINT f_r0; \
322 UINT f_r1; \
323 UINT f_r2; \
324 UINT f_user; \
325 unsigned int length;
326 #define EXTRACT_IFMT_USER_CODE \
327 length = 4; \
328 f_opcode = EXTRACT_LSB0_UINT (insn, 32, 31, 6); \
329 f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5); \
330 f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5); \
331 f_r2 = EXTRACT_LSB0_UINT (insn, 32, 15, 5); \
332 f_user = EXTRACT_LSB0_UINT (insn, 32, 10, 11); \
333
334 #define EXTRACT_IFMT_WCSR_VARS \
335 UINT f_opcode; \
336 UINT f_csr; \
337 UINT f_r1; \
338 UINT f_r2; \
339 UINT f_resv0; \
340 unsigned int length;
341 #define EXTRACT_IFMT_WCSR_CODE \
342 length = 4; \
343 f_opcode = EXTRACT_LSB0_UINT (insn, 32, 31, 6); \
344 f_csr = EXTRACT_LSB0_UINT (insn, 32, 25, 5); \
345 f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5); \
346 f_r2 = EXTRACT_LSB0_UINT (insn, 32, 15, 5); \
347 f_resv0 = EXTRACT_LSB0_UINT (insn, 32, 10, 11); \
348
349 #define EXTRACT_IFMT_BREAK_VARS \
350 UINT f_opcode; \
351 UINT f_exception; \
352 unsigned int length;
353 #define EXTRACT_IFMT_BREAK_CODE \
354 length = 4; \
355 f_opcode = EXTRACT_LSB0_UINT (insn, 32, 31, 6); \
356 f_exception = EXTRACT_LSB0_UINT (insn, 32, 25, 26); \
357
358 /* Collection of various things for the trace handler to use. */
359
360 typedef struct trace_record {
361 IADDR pc;
362 /* FIXME:wip */
363 } TRACE_RECORD;
364
365 #endif /* CPU_LM32BF_H */