]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/common/cgen-utils.c
Automatic Copyright Year update after running gdb/copyright.py
[thirdparty/binutils-gdb.git] / sim / common / cgen-utils.c
CommitLineData
c906108c 1/* Support code for various pieces of CGEN simulators.
4a94e368 2 Copyright (C) 1996-2022 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 23#include "bfd.h"
20a8e078
MF
24#include "dis-asm.h"
25
c906108c 26#include "sim-main.h"
1fef66b0 27#include "sim-signal.h"
c906108c
SS
28
29#define MEMOPS_DEFINE_INLINE
30#include "cgen-mem.h"
31
32#define SEMOPS_DEFINE_INLINE
33#include "cgen-ops.h"
34
12279229 35const char * const cgen_mode_names[] = {
104c1213 36 "VOID",
c906108c
SS
37 "BI",
38 "QI",
39 "HI",
40 "SI",
41 "DI",
42 "UQI",
43 "UHI",
44 "USI",
45 "UDI",
46 "SF",
47 "DF",
48 "XF",
49 "TF",
50 0, /* MODE_TARGET_MAX */
51 "INT",
52 "UINT",
53 "PTR"
54};
55
56/* Opcode table for virtual insns used by the simulator. */
57
58#define V CGEN_ATTR_MASK (CGEN_INSN_VIRTUAL)
59
60static const CGEN_IBASE virtual_insn_entries[] =
61{
62 {
aac7ce3c 63 VIRTUAL_INSN_X_INVALID, "--invalid--", NULL, 0, { V, {} }
c906108c
SS
64 },
65 {
aac7ce3c 66 VIRTUAL_INSN_X_BEFORE, "--before--", NULL, 0, { V, {} }
c906108c
SS
67 },
68 {
aac7ce3c 69 VIRTUAL_INSN_X_AFTER, "--after--", NULL, 0, { V, {} }
c906108c
SS
70 },
71 {
aac7ce3c 72 VIRTUAL_INSN_X_BEGIN, "--begin--", NULL, 0, { V, {} }
c906108c
SS
73 },
74 {
aac7ce3c 75 VIRTUAL_INSN_X_CHAIN, "--chain--", NULL, 0, { V, {} }
c906108c
SS
76 },
77 {
aac7ce3c 78 VIRTUAL_INSN_X_CTI_CHAIN, "--cti-chain--", NULL, 0, { V, {} }
c906108c
SS
79 }
80};
81
82#undef V
83
84const CGEN_INSN cgen_virtual_insn_table[] =
85{
86 { & virtual_insn_entries[0] },
87 { & virtual_insn_entries[1] },
88 { & virtual_insn_entries[2] },
89 { & virtual_insn_entries[3] },
90 { & virtual_insn_entries[4] },
91 { & virtual_insn_entries[5] }
92};
93
c906108c
SS
94/* Return the name of insn number I. */
95
96const char *
97cgen_insn_name (SIM_CPU *cpu, int i)
98{
99 return CGEN_INSN_NAME ((* CPU_GET_IDATA (cpu)) ((cpu), (i)));
100}
101
102/* Return the maximum number of extra bytes required for a SIM_CPU struct. */
103
104int
1c636da0 105cgen_cpu_max_extra_bytes (SIM_DESC sd)
c906108c 106{
1c636da0 107 const SIM_MACH * const *machp;
c906108c
SS
108 int extra = 0;
109
1c636da0
MF
110 SIM_ASSERT (STATE_MACHS (sd) != NULL);
111
112 for (machp = STATE_MACHS (sd); *machp != NULL; ++machp)
c906108c 113 {
1c636da0 114 int size = IMP_PROPS_SIM_CPU_SIZE (MACH_IMP_PROPS (*machp));
c906108c
SS
115 if (size > extra)
116 extra = size;
117 }
118 return extra;
119}
120\f
121#ifdef DI_FN_SUPPORT
122
c906108c
SS
123DI
124ANDDI (a, b)
125 DI a, b;
126{
127 SI ahi = GETHIDI (a);
128 SI alo = GETLODI (a);
129 SI bhi = GETHIDI (b);
130 SI blo = GETLODI (b);
131 return MAKEDI (ahi & bhi, alo & blo);
132}
133
134DI
135ORDI (a, b)
136 DI a, b;
137{
138 SI ahi = GETHIDI (a);
139 SI alo = GETLODI (a);
140 SI bhi = GETHIDI (b);
141 SI blo = GETLODI (b);
142 return MAKEDI (ahi | bhi, alo | blo);
143}
144
145DI
146ADDDI (a, b)
147 DI a, b;
148{
149 USI ahi = GETHIDI (a);
150 USI alo = GETLODI (a);
151 USI bhi = GETHIDI (b);
152 USI blo = GETLODI (b);
153 USI x = alo + blo;
154 return MAKEDI (ahi + bhi + (x < alo), x);
155}
156
157DI
158MULDI (a, b)
159 DI a, b;
160{
161 USI ahi = GETHIDI (a);
162 USI alo = GETLODI (a);
163 USI bhi = GETHIDI (b);
164 USI blo = GETLODI (b);
165 USI rhi,rlo;
166 USI x0, x1, x2, x3;
167
168 x0 = alo * blo;
169 x1 = alo * bhi;
170 x2 = ahi * blo;
171 x3 = ahi * bhi;
172
173#define SI_TYPE_SIZE 32
174#define BITS4 (SI_TYPE_SIZE / 4)
175#define ll_B (1L << (SI_TYPE_SIZE / 2))
176#define ll_lowpart(t) ((USI) (t) % ll_B)
177#define ll_highpart(t) ((USI) (t) / ll_B)
178 x1 += ll_highpart (x0); /* this can't give carry */
179 x1 += x2; /* but this indeed can */
180 if (x1 < x2) /* did we get it? */
181 x3 += ll_B; /* yes, add it in the proper pos. */
182
183 rhi = x3 + ll_highpart (x1);
184 rlo = ll_lowpart (x1) * ll_B + ll_lowpart (x0);
185 return MAKEDI (rhi + (alo * bhi) + (ahi * blo), rlo);
186}
187
188DI
189SHLDI (val, shift)
190 DI val;
191 SI shift;
192{
193 USI hi = GETHIDI (val);
194 USI lo = GETLODI (val);
195 /* FIXME: Need to worry about shift < 0 || shift >= 32. */
196 return MAKEDI ((hi << shift) | (lo >> (32 - shift)), lo << shift);
197}
198
199DI
200SLADI (val, shift)
201 DI val;
202 SI shift;
203{
204 SI hi = GETHIDI (val);
205 USI lo = GETLODI (val);
206 /* FIXME: Need to worry about shift < 0 || shift >= 32. */
207 return MAKEDI ((hi << shift) | (lo >> (32 - shift)), lo << shift);
208}
209
210DI
211SRADI (val, shift)
212 DI val;
213 SI shift;
214{
215 SI hi = GETHIDI (val);
216 USI lo = GETLODI (val);
217 /* We use SRASI because the result is implementation defined if hi < 0. */
218 /* FIXME: Need to worry about shift < 0 || shift >= 32. */
219 return MAKEDI (SRASI (hi, shift), (hi << (32 - shift)) | (lo >> shift));
220}
221
222int
223GEDI (a, b)
224 DI a, b;
225{
226 SI ahi = GETHIDI (a);
227 USI alo = GETLODI (a);
228 SI bhi = GETHIDI (b);
229 USI blo = GETLODI (b);
230 if (ahi > bhi)
231 return 1;
232 if (ahi == bhi)
233 return alo >= blo;
234 return 0;
235}
236
237int
238LEDI (a, b)
239 DI a, b;
240{
241 SI ahi = GETHIDI (a);
242 USI alo = GETLODI (a);
243 SI bhi = GETHIDI (b);
244 USI blo = GETLODI (b);
245 if (ahi < bhi)
246 return 1;
247 if (ahi == bhi)
248 return alo <= blo;
249 return 0;
250}
251
252DI
253CONVHIDI (val)
254 HI val;
255{
256 if (val < 0)
257 return MAKEDI (-1, val);
258 else
259 return MAKEDI (0, val);
260}
261
262DI
263CONVSIDI (val)
264 SI val;
265{
266 if (val < 0)
267 return MAKEDI (-1, val);
268 else
269 return MAKEDI (0, val);
270}
271
272SI
273CONVDISI (val)
274 DI val;
275{
276 return GETLODI (val);
277}
278
279#endif /* DI_FN_SUPPORT */
adf40b2e 280\f
6d4c43bf 281QI
81e6e8ae 282RORQI (QI val, int shift)
6d4c43bf
DB
283{
284 if (shift != 0)
285 {
286 int remain = 8 - shift;
287 int mask = (1 << shift) - 1;
288 QI result = (val & mask) << remain;
289 mask = (1 << remain) - 1;
290 result |= (val >> shift) & mask;
291 return result;
292 }
293 return val;
294}
295
296QI
81e6e8ae 297ROLQI (QI val, int shift)
6d4c43bf
DB
298{
299 if (shift != 0)
300 {
301 int remain = 8 - shift;
302 int mask = (1 << remain) - 1;
303 QI result = (val & mask) << shift;
304 mask = (1 << shift) - 1;
305 result |= (val >> remain) & mask;
306 return result;
307 }
308 return val;
309}
310
311HI
81e6e8ae 312RORHI (HI val, int shift)
6d4c43bf
DB
313{
314 if (shift != 0)
315 {
316 int remain = 16 - shift;
317 int mask = (1 << shift) - 1;
318 HI result = (val & mask) << remain;
319 mask = (1 << remain) - 1;
320 result |= (val >> shift) & mask;
321 return result;
322 }
323 return val;
324}
325
326HI
81e6e8ae 327ROLHI (HI val, int shift)
6d4c43bf
DB
328{
329 if (shift != 0)
330 {
331 int remain = 16 - shift;
332 int mask = (1 << remain) - 1;
333 HI result = (val & mask) << shift;
334 mask = (1 << shift) - 1;
335 result |= (val >> remain) & mask;
336 return result;
337 }
338 return val;
339}
340
adf40b2e 341SI
81e6e8ae 342RORSI (SI val, int shift)
adf40b2e
JM
343{
344 if (shift != 0)
345 {
346 int remain = 32 - shift;
347 int mask = (1 << shift) - 1;
348 SI result = (val & mask) << remain;
349 mask = (1 << remain) - 1;
350 result |= (val >> shift) & mask;
351 return result;
352 }
353 return val;
354}
355
356SI
81e6e8ae 357ROLSI (SI val, int shift)
adf40b2e
JM
358{
359 if (shift != 0)
360 {
361 int remain = 32 - shift;
362 int mask = (1 << remain) - 1;
363 SI result = (val & mask) << shift;
364 mask = (1 << shift) - 1;
365 result |= (val >> remain) & mask;
366 return result;
367 }
368
369 return val;
370}
a8d894af
BE
371
372/* Emit an error message from CGEN RTL. */
373
374void
375cgen_rtx_error (SIM_CPU *cpu, const char * msg)
376{
377 SIM_DESC sd = CPU_STATE (cpu);
378
6ae9091a 379 sim_io_printf (sd, "%s", msg);
a8d894af
BE
380 sim_io_printf (sd, "\n");
381
034685f9 382 sim_engine_halt (sd, cpu, NULL, CPU_PC_GET (cpu), sim_stopped, SIM_SIGTRAP);
a8d894af 383}