]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/common/cgen-utils.c
sim: switch config.h usage to defs.h
[thirdparty/binutils-gdb.git] / sim / common / cgen-utils.c
1 /* Support code for various pieces of CGEN simulators.
2 Copyright (C) 1996-2021 Free Software Foundation, Inc.
3 Contributed by Cygnus Support.
4
5 This file is part of GDB, the GNU debugger.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20 /* This must come before any other includes. */
21 #include "defs.h"
22
23 #include "bfd.h"
24 #include "sim-main.h"
25 #include "dis-asm.h"
26
27 #define MEMOPS_DEFINE_INLINE
28 #include "cgen-mem.h"
29
30 #define SEMOPS_DEFINE_INLINE
31 #include "cgen-ops.h"
32
33 const char * const cgen_mode_names[] = {
34 "VOID",
35 "BI",
36 "QI",
37 "HI",
38 "SI",
39 "DI",
40 "UQI",
41 "UHI",
42 "USI",
43 "UDI",
44 "SF",
45 "DF",
46 "XF",
47 "TF",
48 0, /* MODE_TARGET_MAX */
49 "INT",
50 "UINT",
51 "PTR"
52 };
53
54 /* Opcode table for virtual insns used by the simulator. */
55
56 #define V CGEN_ATTR_MASK (CGEN_INSN_VIRTUAL)
57
58 static const CGEN_IBASE virtual_insn_entries[] =
59 {
60 {
61 VIRTUAL_INSN_X_INVALID, "--invalid--", NULL, 0, { V, {} }
62 },
63 {
64 VIRTUAL_INSN_X_BEFORE, "--before--", NULL, 0, { V, {} }
65 },
66 {
67 VIRTUAL_INSN_X_AFTER, "--after--", NULL, 0, { V, {} }
68 },
69 {
70 VIRTUAL_INSN_X_BEGIN, "--begin--", NULL, 0, { V, {} }
71 },
72 {
73 VIRTUAL_INSN_X_CHAIN, "--chain--", NULL, 0, { V, {} }
74 },
75 {
76 VIRTUAL_INSN_X_CTI_CHAIN, "--cti-chain--", NULL, 0, { V, {} }
77 }
78 };
79
80 #undef V
81
82 const CGEN_INSN cgen_virtual_insn_table[] =
83 {
84 { & virtual_insn_entries[0] },
85 { & virtual_insn_entries[1] },
86 { & virtual_insn_entries[2] },
87 { & virtual_insn_entries[3] },
88 { & virtual_insn_entries[4] },
89 { & virtual_insn_entries[5] }
90 };
91
92 /* Initialize cgen things.
93 This is called after sim_post_argv_init. */
94
95 void
96 cgen_init (SIM_DESC sd)
97 {
98 int i, c;
99
100 /* If no profiling or tracing has been enabled, run in fast mode. */
101 {
102 int run_fast_p = 1;
103
104 for (c = 0; c < MAX_NR_PROCESSORS; ++c)
105 {
106 SIM_CPU *cpu = STATE_CPU (sd, c);
107
108 for (i = 0; i < MAX_PROFILE_VALUES; ++i)
109 if (CPU_PROFILE_FLAGS (cpu) [i])
110 {
111 run_fast_p = 0;
112 break;
113 }
114 for (i = 0; i < MAX_TRACE_VALUES; ++i)
115 if (CPU_TRACE_FLAGS (cpu) [i])
116 {
117 run_fast_p = 0;
118 break;
119 }
120 if (! run_fast_p)
121 break;
122 }
123 STATE_RUN_FAST_P (sd) = run_fast_p;
124 }
125 }
126
127 /* Return the name of insn number I. */
128
129 const char *
130 cgen_insn_name (SIM_CPU *cpu, int i)
131 {
132 return CGEN_INSN_NAME ((* CPU_GET_IDATA (cpu)) ((cpu), (i)));
133 }
134
135 /* Return the maximum number of extra bytes required for a SIM_CPU struct. */
136
137 int
138 cgen_cpu_max_extra_bytes (void)
139 {
140 int i;
141 int extra = 0;
142
143 for (i = 0; sim_machs[i] != 0; ++i)
144 {
145 int size = IMP_PROPS_SIM_CPU_SIZE (MACH_IMP_PROPS (sim_machs[i]));
146 if (size > extra)
147 extra = size;
148 }
149 return extra;
150 }
151 \f
152 #ifdef DI_FN_SUPPORT
153
154 DI
155 make_struct_di (hi, lo)
156 SI hi, lo;
157 {
158 DI result;
159
160 result.hi = hi;
161 result.lo = lo;
162 return result;
163 }
164
165 DI
166 ANDDI (a, b)
167 DI a, b;
168 {
169 SI ahi = GETHIDI (a);
170 SI alo = GETLODI (a);
171 SI bhi = GETHIDI (b);
172 SI blo = GETLODI (b);
173 return MAKEDI (ahi & bhi, alo & blo);
174 }
175
176 DI
177 ORDI (a, b)
178 DI a, b;
179 {
180 SI ahi = GETHIDI (a);
181 SI alo = GETLODI (a);
182 SI bhi = GETHIDI (b);
183 SI blo = GETLODI (b);
184 return MAKEDI (ahi | bhi, alo | blo);
185 }
186
187 DI
188 ADDDI (a, b)
189 DI a, b;
190 {
191 USI ahi = GETHIDI (a);
192 USI alo = GETLODI (a);
193 USI bhi = GETHIDI (b);
194 USI blo = GETLODI (b);
195 USI x = alo + blo;
196 return MAKEDI (ahi + bhi + (x < alo), x);
197 }
198
199 DI
200 MULDI (a, b)
201 DI a, b;
202 {
203 USI ahi = GETHIDI (a);
204 USI alo = GETLODI (a);
205 USI bhi = GETHIDI (b);
206 USI blo = GETLODI (b);
207 USI rhi,rlo;
208 USI x0, x1, x2, x3;
209
210 x0 = alo * blo;
211 x1 = alo * bhi;
212 x2 = ahi * blo;
213 x3 = ahi * bhi;
214
215 #define SI_TYPE_SIZE 32
216 #define BITS4 (SI_TYPE_SIZE / 4)
217 #define ll_B (1L << (SI_TYPE_SIZE / 2))
218 #define ll_lowpart(t) ((USI) (t) % ll_B)
219 #define ll_highpart(t) ((USI) (t) / ll_B)
220 x1 += ll_highpart (x0); /* this can't give carry */
221 x1 += x2; /* but this indeed can */
222 if (x1 < x2) /* did we get it? */
223 x3 += ll_B; /* yes, add it in the proper pos. */
224
225 rhi = x3 + ll_highpart (x1);
226 rlo = ll_lowpart (x1) * ll_B + ll_lowpart (x0);
227 return MAKEDI (rhi + (alo * bhi) + (ahi * blo), rlo);
228 }
229
230 DI
231 SHLDI (val, shift)
232 DI val;
233 SI shift;
234 {
235 USI hi = GETHIDI (val);
236 USI lo = GETLODI (val);
237 /* FIXME: Need to worry about shift < 0 || shift >= 32. */
238 return MAKEDI ((hi << shift) | (lo >> (32 - shift)), lo << shift);
239 }
240
241 DI
242 SLADI (val, shift)
243 DI val;
244 SI shift;
245 {
246 SI hi = GETHIDI (val);
247 USI lo = GETLODI (val);
248 /* FIXME: Need to worry about shift < 0 || shift >= 32. */
249 return MAKEDI ((hi << shift) | (lo >> (32 - shift)), lo << shift);
250 }
251
252 DI
253 SRADI (val, shift)
254 DI val;
255 SI shift;
256 {
257 SI hi = GETHIDI (val);
258 USI lo = GETLODI (val);
259 /* We use SRASI because the result is implementation defined if hi < 0. */
260 /* FIXME: Need to worry about shift < 0 || shift >= 32. */
261 return MAKEDI (SRASI (hi, shift), (hi << (32 - shift)) | (lo >> shift));
262 }
263
264 int
265 GEDI (a, b)
266 DI a, b;
267 {
268 SI ahi = GETHIDI (a);
269 USI alo = GETLODI (a);
270 SI bhi = GETHIDI (b);
271 USI blo = GETLODI (b);
272 if (ahi > bhi)
273 return 1;
274 if (ahi == bhi)
275 return alo >= blo;
276 return 0;
277 }
278
279 int
280 LEDI (a, b)
281 DI a, b;
282 {
283 SI ahi = GETHIDI (a);
284 USI alo = GETLODI (a);
285 SI bhi = GETHIDI (b);
286 USI blo = GETLODI (b);
287 if (ahi < bhi)
288 return 1;
289 if (ahi == bhi)
290 return alo <= blo;
291 return 0;
292 }
293
294 DI
295 CONVHIDI (val)
296 HI val;
297 {
298 if (val < 0)
299 return MAKEDI (-1, val);
300 else
301 return MAKEDI (0, val);
302 }
303
304 DI
305 CONVSIDI (val)
306 SI val;
307 {
308 if (val < 0)
309 return MAKEDI (-1, val);
310 else
311 return MAKEDI (0, val);
312 }
313
314 SI
315 CONVDISI (val)
316 DI val;
317 {
318 return GETLODI (val);
319 }
320
321 #endif /* DI_FN_SUPPORT */
322 \f
323 QI
324 RORQI (QI val, int shift)
325 {
326 if (shift != 0)
327 {
328 int remain = 8 - shift;
329 int mask = (1 << shift) - 1;
330 QI result = (val & mask) << remain;
331 mask = (1 << remain) - 1;
332 result |= (val >> shift) & mask;
333 return result;
334 }
335 return val;
336 }
337
338 QI
339 ROLQI (QI val, int shift)
340 {
341 if (shift != 0)
342 {
343 int remain = 8 - shift;
344 int mask = (1 << remain) - 1;
345 QI result = (val & mask) << shift;
346 mask = (1 << shift) - 1;
347 result |= (val >> remain) & mask;
348 return result;
349 }
350 return val;
351 }
352
353 HI
354 RORHI (HI val, int shift)
355 {
356 if (shift != 0)
357 {
358 int remain = 16 - shift;
359 int mask = (1 << shift) - 1;
360 HI result = (val & mask) << remain;
361 mask = (1 << remain) - 1;
362 result |= (val >> shift) & mask;
363 return result;
364 }
365 return val;
366 }
367
368 HI
369 ROLHI (HI val, int shift)
370 {
371 if (shift != 0)
372 {
373 int remain = 16 - shift;
374 int mask = (1 << remain) - 1;
375 HI result = (val & mask) << shift;
376 mask = (1 << shift) - 1;
377 result |= (val >> remain) & mask;
378 return result;
379 }
380 return val;
381 }
382
383 SI
384 RORSI (SI val, int shift)
385 {
386 if (shift != 0)
387 {
388 int remain = 32 - shift;
389 int mask = (1 << shift) - 1;
390 SI result = (val & mask) << remain;
391 mask = (1 << remain) - 1;
392 result |= (val >> shift) & mask;
393 return result;
394 }
395 return val;
396 }
397
398 SI
399 ROLSI (SI val, int shift)
400 {
401 if (shift != 0)
402 {
403 int remain = 32 - shift;
404 int mask = (1 << remain) - 1;
405 SI result = (val & mask) << shift;
406 mask = (1 << shift) - 1;
407 result |= (val >> remain) & mask;
408 return result;
409 }
410
411 return val;
412 }
413
414 /* Emit an error message from CGEN RTL. */
415
416 void
417 cgen_rtx_error (SIM_CPU *cpu, const char * msg)
418 {
419 SIM_DESC sd = CPU_STATE (cpu);
420
421 sim_io_printf (sd, "%s", msg);
422 sim_io_printf (sd, "\n");
423
424 sim_engine_halt (sd, cpu, NULL, CPU_PC_GET (cpu), sim_stopped, SIM_SIGTRAP);
425 }