]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/common/cgen-utils.c
sim: switch config.h usage to defs.h
[thirdparty/binutils-gdb.git] / sim / common / cgen-utils.c
CommitLineData
c906108c 1/* Support code for various pieces of CGEN simulators.
3666a048 2 Copyright (C) 1996-2021 Free Software Foundation, Inc.
c906108c
SS
3 Contributed by Cygnus Support.
4
5This file is part of GDB, the GNU debugger.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
4744ac1b
JB
9the Free Software Foundation; either version 3 of the License, or
10(at your option) any later version.
c906108c
SS
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
4744ac1b
JB
17You should have received a copy of the GNU General Public License
18along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c 19
6df01ab8
MF
20/* This must come before any other includes. */
21#include "defs.h"
22
c906108c
SS
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
12279229 33const char * const cgen_mode_names[] = {
104c1213 34 "VOID",
c906108c
SS
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
58static const CGEN_IBASE virtual_insn_entries[] =
59{
60 {
aac7ce3c 61 VIRTUAL_INSN_X_INVALID, "--invalid--", NULL, 0, { V, {} }
c906108c
SS
62 },
63 {
aac7ce3c 64 VIRTUAL_INSN_X_BEFORE, "--before--", NULL, 0, { V, {} }
c906108c
SS
65 },
66 {
aac7ce3c 67 VIRTUAL_INSN_X_AFTER, "--after--", NULL, 0, { V, {} }
c906108c
SS
68 },
69 {
aac7ce3c 70 VIRTUAL_INSN_X_BEGIN, "--begin--", NULL, 0, { V, {} }
c906108c
SS
71 },
72 {
aac7ce3c 73 VIRTUAL_INSN_X_CHAIN, "--chain--", NULL, 0, { V, {} }
c906108c
SS
74 },
75 {
aac7ce3c 76 VIRTUAL_INSN_X_CTI_CHAIN, "--cti-chain--", NULL, 0, { V, {} }
c906108c
SS
77 }
78};
79
80#undef V
81
82const 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
95void
96cgen_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
129const char *
130cgen_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
137int
138cgen_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
154DI
155make_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
165DI
166ANDDI (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
176DI
177ORDI (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
187DI
188ADDDI (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
199DI
200MULDI (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
230DI
231SHLDI (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
241DI
242SLADI (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
252DI
253SRADI (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
264int
265GEDI (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
279int
280LEDI (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
294DI
295CONVHIDI (val)
296 HI val;
297{
298 if (val < 0)
299 return MAKEDI (-1, val);
300 else
301 return MAKEDI (0, val);
302}
303
304DI
305CONVSIDI (val)
306 SI val;
307{
308 if (val < 0)
309 return MAKEDI (-1, val);
310 else
311 return MAKEDI (0, val);
312}
313
314SI
315CONVDISI (val)
316 DI val;
317{
318 return GETLODI (val);
319}
320
321#endif /* DI_FN_SUPPORT */
adf40b2e 322\f
6d4c43bf 323QI
81e6e8ae 324RORQI (QI val, int shift)
6d4c43bf
DB
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
338QI
81e6e8ae 339ROLQI (QI val, int shift)
6d4c43bf
DB
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
353HI
81e6e8ae 354RORHI (HI val, int shift)
6d4c43bf
DB
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
368HI
81e6e8ae 369ROLHI (HI val, int shift)
6d4c43bf
DB
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
adf40b2e 383SI
81e6e8ae 384RORSI (SI val, int shift)
adf40b2e
JM
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
398SI
81e6e8ae 399ROLSI (SI val, int shift)
adf40b2e
JM
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}
a8d894af
BE
413
414/* Emit an error message from CGEN RTL. */
415
416void
417cgen_rtx_error (SIM_CPU *cpu, const char * msg)
418{
419 SIM_DESC sd = CPU_STATE (cpu);
420
6ae9091a 421 sim_io_printf (sd, "%s", msg);
a8d894af
BE
422 sim_io_printf (sd, "\n");
423
034685f9 424 sim_engine_halt (sd, cpu, NULL, CPU_PC_GET (cpu), sim_stopped, SIM_SIGTRAP);
a8d894af 425}