]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/common/cgen-utils.c
Automatic date update in version.in
[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
a6ff997c 20#include "config.h"
c906108c
SS
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
12279229 31const char * const cgen_mode_names[] = {
104c1213 32 "VOID",
c906108c
SS
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
56static const CGEN_IBASE virtual_insn_entries[] =
57{
58 {
aac7ce3c 59 VIRTUAL_INSN_X_INVALID, "--invalid--", NULL, 0, { V, {} }
c906108c
SS
60 },
61 {
aac7ce3c 62 VIRTUAL_INSN_X_BEFORE, "--before--", NULL, 0, { V, {} }
c906108c
SS
63 },
64 {
aac7ce3c 65 VIRTUAL_INSN_X_AFTER, "--after--", NULL, 0, { V, {} }
c906108c
SS
66 },
67 {
aac7ce3c 68 VIRTUAL_INSN_X_BEGIN, "--begin--", NULL, 0, { V, {} }
c906108c
SS
69 },
70 {
aac7ce3c 71 VIRTUAL_INSN_X_CHAIN, "--chain--", NULL, 0, { V, {} }
c906108c
SS
72 },
73 {
aac7ce3c 74 VIRTUAL_INSN_X_CTI_CHAIN, "--cti-chain--", NULL, 0, { V, {} }
c906108c
SS
75 }
76};
77
78#undef V
79
80const 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
93void
94cgen_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
127const char *
128cgen_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
135int
136cgen_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
152DI
153make_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
163DI
164ANDDI (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
174DI
175ORDI (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
185DI
186ADDDI (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
197DI
198MULDI (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
228DI
229SHLDI (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
239DI
240SLADI (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
250DI
251SRADI (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
262int
263GEDI (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
277int
278LEDI (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
292DI
293CONVHIDI (val)
294 HI val;
295{
296 if (val < 0)
297 return MAKEDI (-1, val);
298 else
299 return MAKEDI (0, val);
300}
301
302DI
303CONVSIDI (val)
304 SI val;
305{
306 if (val < 0)
307 return MAKEDI (-1, val);
308 else
309 return MAKEDI (0, val);
310}
311
312SI
313CONVDISI (val)
314 DI val;
315{
316 return GETLODI (val);
317}
318
319#endif /* DI_FN_SUPPORT */
adf40b2e 320\f
6d4c43bf 321QI
81e6e8ae 322RORQI (QI val, int shift)
6d4c43bf
DB
323{
324 if (shift != 0)
325 {
326 int remain = 8 - shift;
327 int mask = (1 << shift) - 1;
328 QI result = (val & mask) << remain;
329 mask = (1 << remain) - 1;
330 result |= (val >> shift) & mask;
331 return result;
332 }
333 return val;
334}
335
336QI
81e6e8ae 337ROLQI (QI val, int shift)
6d4c43bf
DB
338{
339 if (shift != 0)
340 {
341 int remain = 8 - shift;
342 int mask = (1 << remain) - 1;
343 QI result = (val & mask) << shift;
344 mask = (1 << shift) - 1;
345 result |= (val >> remain) & mask;
346 return result;
347 }
348 return val;
349}
350
351HI
81e6e8ae 352RORHI (HI val, int shift)
6d4c43bf
DB
353{
354 if (shift != 0)
355 {
356 int remain = 16 - shift;
357 int mask = (1 << shift) - 1;
358 HI result = (val & mask) << remain;
359 mask = (1 << remain) - 1;
360 result |= (val >> shift) & mask;
361 return result;
362 }
363 return val;
364}
365
366HI
81e6e8ae 367ROLHI (HI val, int shift)
6d4c43bf
DB
368{
369 if (shift != 0)
370 {
371 int remain = 16 - shift;
372 int mask = (1 << remain) - 1;
373 HI result = (val & mask) << shift;
374 mask = (1 << shift) - 1;
375 result |= (val >> remain) & mask;
376 return result;
377 }
378 return val;
379}
380
adf40b2e 381SI
81e6e8ae 382RORSI (SI val, int shift)
adf40b2e
JM
383{
384 if (shift != 0)
385 {
386 int remain = 32 - shift;
387 int mask = (1 << shift) - 1;
388 SI result = (val & mask) << remain;
389 mask = (1 << remain) - 1;
390 result |= (val >> shift) & mask;
391 return result;
392 }
393 return val;
394}
395
396SI
81e6e8ae 397ROLSI (SI val, int shift)
adf40b2e
JM
398{
399 if (shift != 0)
400 {
401 int remain = 32 - shift;
402 int mask = (1 << remain) - 1;
403 SI result = (val & mask) << shift;
404 mask = (1 << shift) - 1;
405 result |= (val >> remain) & mask;
406 return result;
407 }
408
409 return val;
410}
a8d894af
BE
411
412/* Emit an error message from CGEN RTL. */
413
414void
415cgen_rtx_error (SIM_CPU *cpu, const char * msg)
416{
417 SIM_DESC sd = CPU_STATE (cpu);
418
6ae9091a 419 sim_io_printf (sd, "%s", msg);
a8d894af
BE
420 sim_io_printf (sd, "\n");
421
034685f9 422 sim_engine_halt (sd, cpu, NULL, CPU_PC_GET (cpu), sim_stopped, SIM_SIGTRAP);
a8d894af 423}