]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/common/cgen-utils.c
sim: split sim-signal.h include out
[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 "sim-signal.h"
26 #include "dis-asm.h"
27
28 #define MEMOPS_DEFINE_INLINE
29 #include "cgen-mem.h"
30
31 #define SEMOPS_DEFINE_INLINE
32 #include "cgen-ops.h"
33
34 const char * const cgen_mode_names[] = {
35 "VOID",
36 "BI",
37 "QI",
38 "HI",
39 "SI",
40 "DI",
41 "UQI",
42 "UHI",
43 "USI",
44 "UDI",
45 "SF",
46 "DF",
47 "XF",
48 "TF",
49 0, /* MODE_TARGET_MAX */
50 "INT",
51 "UINT",
52 "PTR"
53 };
54
55 /* Opcode table for virtual insns used by the simulator. */
56
57 #define V CGEN_ATTR_MASK (CGEN_INSN_VIRTUAL)
58
59 static const CGEN_IBASE virtual_insn_entries[] =
60 {
61 {
62 VIRTUAL_INSN_X_INVALID, "--invalid--", NULL, 0, { V, {} }
63 },
64 {
65 VIRTUAL_INSN_X_BEFORE, "--before--", NULL, 0, { V, {} }
66 },
67 {
68 VIRTUAL_INSN_X_AFTER, "--after--", NULL, 0, { V, {} }
69 },
70 {
71 VIRTUAL_INSN_X_BEGIN, "--begin--", NULL, 0, { V, {} }
72 },
73 {
74 VIRTUAL_INSN_X_CHAIN, "--chain--", NULL, 0, { V, {} }
75 },
76 {
77 VIRTUAL_INSN_X_CTI_CHAIN, "--cti-chain--", NULL, 0, { V, {} }
78 }
79 };
80
81 #undef V
82
83 const CGEN_INSN cgen_virtual_insn_table[] =
84 {
85 { & virtual_insn_entries[0] },
86 { & virtual_insn_entries[1] },
87 { & virtual_insn_entries[2] },
88 { & virtual_insn_entries[3] },
89 { & virtual_insn_entries[4] },
90 { & virtual_insn_entries[5] }
91 };
92
93 /* Return the name of insn number I. */
94
95 const char *
96 cgen_insn_name (SIM_CPU *cpu, int i)
97 {
98 return CGEN_INSN_NAME ((* CPU_GET_IDATA (cpu)) ((cpu), (i)));
99 }
100
101 /* Return the maximum number of extra bytes required for a SIM_CPU struct. */
102
103 int
104 cgen_cpu_max_extra_bytes (void)
105 {
106 int i;
107 int extra = 0;
108
109 for (i = 0; sim_machs[i] != 0; ++i)
110 {
111 int size = IMP_PROPS_SIM_CPU_SIZE (MACH_IMP_PROPS (sim_machs[i]));
112 if (size > extra)
113 extra = size;
114 }
115 return extra;
116 }
117 \f
118 #ifdef DI_FN_SUPPORT
119
120 DI
121 make_struct_di (hi, lo)
122 SI hi, lo;
123 {
124 DI result;
125
126 result.hi = hi;
127 result.lo = lo;
128 return result;
129 }
130
131 DI
132 ANDDI (a, b)
133 DI a, b;
134 {
135 SI ahi = GETHIDI (a);
136 SI alo = GETLODI (a);
137 SI bhi = GETHIDI (b);
138 SI blo = GETLODI (b);
139 return MAKEDI (ahi & bhi, alo & blo);
140 }
141
142 DI
143 ORDI (a, b)
144 DI a, b;
145 {
146 SI ahi = GETHIDI (a);
147 SI alo = GETLODI (a);
148 SI bhi = GETHIDI (b);
149 SI blo = GETLODI (b);
150 return MAKEDI (ahi | bhi, alo | blo);
151 }
152
153 DI
154 ADDDI (a, b)
155 DI a, b;
156 {
157 USI ahi = GETHIDI (a);
158 USI alo = GETLODI (a);
159 USI bhi = GETHIDI (b);
160 USI blo = GETLODI (b);
161 USI x = alo + blo;
162 return MAKEDI (ahi + bhi + (x < alo), x);
163 }
164
165 DI
166 MULDI (a, b)
167 DI a, b;
168 {
169 USI ahi = GETHIDI (a);
170 USI alo = GETLODI (a);
171 USI bhi = GETHIDI (b);
172 USI blo = GETLODI (b);
173 USI rhi,rlo;
174 USI x0, x1, x2, x3;
175
176 x0 = alo * blo;
177 x1 = alo * bhi;
178 x2 = ahi * blo;
179 x3 = ahi * bhi;
180
181 #define SI_TYPE_SIZE 32
182 #define BITS4 (SI_TYPE_SIZE / 4)
183 #define ll_B (1L << (SI_TYPE_SIZE / 2))
184 #define ll_lowpart(t) ((USI) (t) % ll_B)
185 #define ll_highpart(t) ((USI) (t) / ll_B)
186 x1 += ll_highpart (x0); /* this can't give carry */
187 x1 += x2; /* but this indeed can */
188 if (x1 < x2) /* did we get it? */
189 x3 += ll_B; /* yes, add it in the proper pos. */
190
191 rhi = x3 + ll_highpart (x1);
192 rlo = ll_lowpart (x1) * ll_B + ll_lowpart (x0);
193 return MAKEDI (rhi + (alo * bhi) + (ahi * blo), rlo);
194 }
195
196 DI
197 SHLDI (val, shift)
198 DI val;
199 SI shift;
200 {
201 USI hi = GETHIDI (val);
202 USI lo = GETLODI (val);
203 /* FIXME: Need to worry about shift < 0 || shift >= 32. */
204 return MAKEDI ((hi << shift) | (lo >> (32 - shift)), lo << shift);
205 }
206
207 DI
208 SLADI (val, shift)
209 DI val;
210 SI shift;
211 {
212 SI hi = GETHIDI (val);
213 USI lo = GETLODI (val);
214 /* FIXME: Need to worry about shift < 0 || shift >= 32. */
215 return MAKEDI ((hi << shift) | (lo >> (32 - shift)), lo << shift);
216 }
217
218 DI
219 SRADI (val, shift)
220 DI val;
221 SI shift;
222 {
223 SI hi = GETHIDI (val);
224 USI lo = GETLODI (val);
225 /* We use SRASI because the result is implementation defined if hi < 0. */
226 /* FIXME: Need to worry about shift < 0 || shift >= 32. */
227 return MAKEDI (SRASI (hi, shift), (hi << (32 - shift)) | (lo >> shift));
228 }
229
230 int
231 GEDI (a, b)
232 DI a, b;
233 {
234 SI ahi = GETHIDI (a);
235 USI alo = GETLODI (a);
236 SI bhi = GETHIDI (b);
237 USI blo = GETLODI (b);
238 if (ahi > bhi)
239 return 1;
240 if (ahi == bhi)
241 return alo >= blo;
242 return 0;
243 }
244
245 int
246 LEDI (a, b)
247 DI a, b;
248 {
249 SI ahi = GETHIDI (a);
250 USI alo = GETLODI (a);
251 SI bhi = GETHIDI (b);
252 USI blo = GETLODI (b);
253 if (ahi < bhi)
254 return 1;
255 if (ahi == bhi)
256 return alo <= blo;
257 return 0;
258 }
259
260 DI
261 CONVHIDI (val)
262 HI val;
263 {
264 if (val < 0)
265 return MAKEDI (-1, val);
266 else
267 return MAKEDI (0, val);
268 }
269
270 DI
271 CONVSIDI (val)
272 SI val;
273 {
274 if (val < 0)
275 return MAKEDI (-1, val);
276 else
277 return MAKEDI (0, val);
278 }
279
280 SI
281 CONVDISI (val)
282 DI val;
283 {
284 return GETLODI (val);
285 }
286
287 #endif /* DI_FN_SUPPORT */
288 \f
289 QI
290 RORQI (QI val, int shift)
291 {
292 if (shift != 0)
293 {
294 int remain = 8 - shift;
295 int mask = (1 << shift) - 1;
296 QI result = (val & mask) << remain;
297 mask = (1 << remain) - 1;
298 result |= (val >> shift) & mask;
299 return result;
300 }
301 return val;
302 }
303
304 QI
305 ROLQI (QI val, int shift)
306 {
307 if (shift != 0)
308 {
309 int remain = 8 - shift;
310 int mask = (1 << remain) - 1;
311 QI result = (val & mask) << shift;
312 mask = (1 << shift) - 1;
313 result |= (val >> remain) & mask;
314 return result;
315 }
316 return val;
317 }
318
319 HI
320 RORHI (HI val, int shift)
321 {
322 if (shift != 0)
323 {
324 int remain = 16 - shift;
325 int mask = (1 << shift) - 1;
326 HI result = (val & mask) << remain;
327 mask = (1 << remain) - 1;
328 result |= (val >> shift) & mask;
329 return result;
330 }
331 return val;
332 }
333
334 HI
335 ROLHI (HI val, int shift)
336 {
337 if (shift != 0)
338 {
339 int remain = 16 - shift;
340 int mask = (1 << remain) - 1;
341 HI result = (val & mask) << shift;
342 mask = (1 << shift) - 1;
343 result |= (val >> remain) & mask;
344 return result;
345 }
346 return val;
347 }
348
349 SI
350 RORSI (SI val, int shift)
351 {
352 if (shift != 0)
353 {
354 int remain = 32 - shift;
355 int mask = (1 << shift) - 1;
356 SI result = (val & mask) << remain;
357 mask = (1 << remain) - 1;
358 result |= (val >> shift) & mask;
359 return result;
360 }
361 return val;
362 }
363
364 SI
365 ROLSI (SI val, int shift)
366 {
367 if (shift != 0)
368 {
369 int remain = 32 - shift;
370 int mask = (1 << remain) - 1;
371 SI result = (val & mask) << shift;
372 mask = (1 << shift) - 1;
373 result |= (val >> remain) & mask;
374 return result;
375 }
376
377 return val;
378 }
379
380 /* Emit an error message from CGEN RTL. */
381
382 void
383 cgen_rtx_error (SIM_CPU *cpu, const char * msg)
384 {
385 SIM_DESC sd = CPU_STATE (cpu);
386
387 sim_io_printf (sd, "%s", msg);
388 sim_io_printf (sd, "\n");
389
390 sim_engine_halt (sd, cpu, NULL, CPU_PC_GET (cpu), sim_stopped, SIM_SIGTRAP);
391 }