]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/common/cgen-utils.c
sim: split sim-signal.h include out
[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"
1fef66b0 25#include "sim-signal.h"
c906108c
SS
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
12279229 34const char * const cgen_mode_names[] = {
104c1213 35 "VOID",
c906108c
SS
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
59static const CGEN_IBASE virtual_insn_entries[] =
60{
61 {
aac7ce3c 62 VIRTUAL_INSN_X_INVALID, "--invalid--", NULL, 0, { V, {} }
c906108c
SS
63 },
64 {
aac7ce3c 65 VIRTUAL_INSN_X_BEFORE, "--before--", NULL, 0, { V, {} }
c906108c
SS
66 },
67 {
aac7ce3c 68 VIRTUAL_INSN_X_AFTER, "--after--", NULL, 0, { V, {} }
c906108c
SS
69 },
70 {
aac7ce3c 71 VIRTUAL_INSN_X_BEGIN, "--begin--", NULL, 0, { V, {} }
c906108c
SS
72 },
73 {
aac7ce3c 74 VIRTUAL_INSN_X_CHAIN, "--chain--", NULL, 0, { V, {} }
c906108c
SS
75 },
76 {
aac7ce3c 77 VIRTUAL_INSN_X_CTI_CHAIN, "--cti-chain--", NULL, 0, { V, {} }
c906108c
SS
78 }
79};
80
81#undef V
82
83const 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
c906108c
SS
93/* Return the name of insn number I. */
94
95const char *
96cgen_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
103int
104cgen_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
120DI
121make_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
131DI
132ANDDI (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
142DI
143ORDI (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
153DI
154ADDDI (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
165DI
166MULDI (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
196DI
197SHLDI (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
207DI
208SLADI (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
218DI
219SRADI (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
230int
231GEDI (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
245int
246LEDI (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
260DI
261CONVHIDI (val)
262 HI val;
263{
264 if (val < 0)
265 return MAKEDI (-1, val);
266 else
267 return MAKEDI (0, val);
268}
269
270DI
271CONVSIDI (val)
272 SI val;
273{
274 if (val < 0)
275 return MAKEDI (-1, val);
276 else
277 return MAKEDI (0, val);
278}
279
280SI
281CONVDISI (val)
282 DI val;
283{
284 return GETLODI (val);
285}
286
287#endif /* DI_FN_SUPPORT */
adf40b2e 288\f
6d4c43bf 289QI
81e6e8ae 290RORQI (QI val, int shift)
6d4c43bf
DB
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
304QI
81e6e8ae 305ROLQI (QI val, int shift)
6d4c43bf
DB
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
319HI
81e6e8ae 320RORHI (HI val, int shift)
6d4c43bf
DB
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
334HI
81e6e8ae 335ROLHI (HI val, int shift)
6d4c43bf
DB
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
adf40b2e 349SI
81e6e8ae 350RORSI (SI val, int shift)
adf40b2e
JM
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
364SI
81e6e8ae 365ROLSI (SI val, int shift)
adf40b2e
JM
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}
a8d894af
BE
379
380/* Emit an error message from CGEN RTL. */
381
382void
383cgen_rtx_error (SIM_CPU *cpu, const char * msg)
384{
385 SIM_DESC sd = CPU_STATE (cpu);
386
6ae9091a 387 sim_io_printf (sd, "%s", msg);
a8d894af
BE
388 sim_io_printf (sd, "\n");
389
034685f9 390 sim_engine_halt (sd, cpu, NULL, CPU_PC_GET (cpu), sim_stopped, SIM_SIGTRAP);
a8d894af 391}