Update copyright year range in all GDB files.
[deliverable/binutils-gdb.git] / sim / common / cgen-utils.c
CommitLineData
c906108c 1/* Support code for various pieces of CGEN simulators.
b811d2c2 2 Copyright (C) 1996-2020 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
4c171e25 31const char * const 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 {
7a292a7a 59 VIRTUAL_INSN_X_INVALID, "--invalid--", NULL, 0, { V, { 0 } }
c906108c
SS
60 },
61 {
7a292a7a 62 VIRTUAL_INSN_X_BEFORE, "--before--", NULL, 0, { V, { 0 } }
c906108c
SS
63 },
64 {
7a292a7a 65 VIRTUAL_INSN_X_AFTER, "--after--", NULL, 0, { V, { 0 } }
c906108c
SS
66 },
67 {
7a292a7a 68 VIRTUAL_INSN_X_BEGIN, "--begin--", NULL, 0, { V, { 0 } }
c906108c
SS
69 },
70 {
7a292a7a 71 VIRTUAL_INSN_X_CHAIN, "--chain--", NULL, 0, { V, { 0 } }
c906108c
SS
72 },
73 {
7a292a7a 74 VIRTUAL_INSN_X_CTI_CHAIN, "--cti-chain--", NULL, 0, { V, { 0 } }
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
DB
321QI
322RORQI (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
338QI
339ROLQI (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
355HI
356RORHI (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
372HI
373ROLHI (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
adf40b2e
JM
389SI
390RORSI (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
406SI
407ROLSI (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}
a8d894af
BE
423
424/* Emit an error message from CGEN RTL. */
425
426void
427cgen_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
034685f9 434 sim_engine_halt (sd, cpu, NULL, CPU_PC_GET (cpu), sim_stopped, SIM_SIGTRAP);
a8d894af 435}
This page took 0.872108 seconds and 4 git commands to generate.