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