]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/common/cgen-utils.c
sim: cgen: require long long support
[thirdparty/binutils-gdb.git] / sim / common / cgen-utils.c
1 /* Support code for various pieces of CGEN simulators.
2 Copyright (C) 1996-2021 Free Software Foundation, Inc.
3 Contributed by Cygnus Support.
4
5 This file is part of GDB, the GNU debugger.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20 /* This must come before any other includes. */
21 #include "defs.h"
22
23 #include "bfd.h"
24 #include "sim-main.h"
25 #include "sim-signal.h"
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
34 const char * const cgen_mode_names[] = {
35 "VOID",
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
59 static const CGEN_IBASE virtual_insn_entries[] =
60 {
61 {
62 VIRTUAL_INSN_X_INVALID, "--invalid--", NULL, 0, { V, {} }
63 },
64 {
65 VIRTUAL_INSN_X_BEFORE, "--before--", NULL, 0, { V, {} }
66 },
67 {
68 VIRTUAL_INSN_X_AFTER, "--after--", NULL, 0, { V, {} }
69 },
70 {
71 VIRTUAL_INSN_X_BEGIN, "--begin--", NULL, 0, { V, {} }
72 },
73 {
74 VIRTUAL_INSN_X_CHAIN, "--chain--", NULL, 0, { V, {} }
75 },
76 {
77 VIRTUAL_INSN_X_CTI_CHAIN, "--cti-chain--", NULL, 0, { V, {} }
78 }
79 };
80
81 #undef V
82
83 const 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
93 /* Return the name of insn number I. */
94
95 const char *
96 cgen_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
103 int
104 cgen_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
120 DI
121 ANDDI (a, b)
122 DI a, b;
123 {
124 SI ahi = GETHIDI (a);
125 SI alo = GETLODI (a);
126 SI bhi = GETHIDI (b);
127 SI blo = GETLODI (b);
128 return MAKEDI (ahi & bhi, alo & blo);
129 }
130
131 DI
132 ORDI (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
142 DI
143 ADDDI (a, b)
144 DI a, b;
145 {
146 USI ahi = GETHIDI (a);
147 USI alo = GETLODI (a);
148 USI bhi = GETHIDI (b);
149 USI blo = GETLODI (b);
150 USI x = alo + blo;
151 return MAKEDI (ahi + bhi + (x < alo), x);
152 }
153
154 DI
155 MULDI (a, b)
156 DI a, b;
157 {
158 USI ahi = GETHIDI (a);
159 USI alo = GETLODI (a);
160 USI bhi = GETHIDI (b);
161 USI blo = GETLODI (b);
162 USI rhi,rlo;
163 USI x0, x1, x2, x3;
164
165 x0 = alo * blo;
166 x1 = alo * bhi;
167 x2 = ahi * blo;
168 x3 = ahi * bhi;
169
170 #define SI_TYPE_SIZE 32
171 #define BITS4 (SI_TYPE_SIZE / 4)
172 #define ll_B (1L << (SI_TYPE_SIZE / 2))
173 #define ll_lowpart(t) ((USI) (t) % ll_B)
174 #define ll_highpart(t) ((USI) (t) / ll_B)
175 x1 += ll_highpart (x0); /* this can't give carry */
176 x1 += x2; /* but this indeed can */
177 if (x1 < x2) /* did we get it? */
178 x3 += ll_B; /* yes, add it in the proper pos. */
179
180 rhi = x3 + ll_highpart (x1);
181 rlo = ll_lowpart (x1) * ll_B + ll_lowpart (x0);
182 return MAKEDI (rhi + (alo * bhi) + (ahi * blo), rlo);
183 }
184
185 DI
186 SHLDI (val, shift)
187 DI val;
188 SI shift;
189 {
190 USI hi = GETHIDI (val);
191 USI lo = GETLODI (val);
192 /* FIXME: Need to worry about shift < 0 || shift >= 32. */
193 return MAKEDI ((hi << shift) | (lo >> (32 - shift)), lo << shift);
194 }
195
196 DI
197 SLADI (val, shift)
198 DI val;
199 SI shift;
200 {
201 SI 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
207 DI
208 SRADI (val, shift)
209 DI val;
210 SI shift;
211 {
212 SI hi = GETHIDI (val);
213 USI lo = GETLODI (val);
214 /* We use SRASI because the result is implementation defined if hi < 0. */
215 /* FIXME: Need to worry about shift < 0 || shift >= 32. */
216 return MAKEDI (SRASI (hi, shift), (hi << (32 - shift)) | (lo >> shift));
217 }
218
219 int
220 GEDI (a, b)
221 DI a, b;
222 {
223 SI ahi = GETHIDI (a);
224 USI alo = GETLODI (a);
225 SI bhi = GETHIDI (b);
226 USI blo = GETLODI (b);
227 if (ahi > bhi)
228 return 1;
229 if (ahi == bhi)
230 return alo >= blo;
231 return 0;
232 }
233
234 int
235 LEDI (a, b)
236 DI a, b;
237 {
238 SI ahi = GETHIDI (a);
239 USI alo = GETLODI (a);
240 SI bhi = GETHIDI (b);
241 USI blo = GETLODI (b);
242 if (ahi < bhi)
243 return 1;
244 if (ahi == bhi)
245 return alo <= blo;
246 return 0;
247 }
248
249 DI
250 CONVHIDI (val)
251 HI val;
252 {
253 if (val < 0)
254 return MAKEDI (-1, val);
255 else
256 return MAKEDI (0, val);
257 }
258
259 DI
260 CONVSIDI (val)
261 SI val;
262 {
263 if (val < 0)
264 return MAKEDI (-1, val);
265 else
266 return MAKEDI (0, val);
267 }
268
269 SI
270 CONVDISI (val)
271 DI val;
272 {
273 return GETLODI (val);
274 }
275
276 #endif /* DI_FN_SUPPORT */
277 \f
278 QI
279 RORQI (QI val, int shift)
280 {
281 if (shift != 0)
282 {
283 int remain = 8 - shift;
284 int mask = (1 << shift) - 1;
285 QI result = (val & mask) << remain;
286 mask = (1 << remain) - 1;
287 result |= (val >> shift) & mask;
288 return result;
289 }
290 return val;
291 }
292
293 QI
294 ROLQI (QI val, int shift)
295 {
296 if (shift != 0)
297 {
298 int remain = 8 - shift;
299 int mask = (1 << remain) - 1;
300 QI result = (val & mask) << shift;
301 mask = (1 << shift) - 1;
302 result |= (val >> remain) & mask;
303 return result;
304 }
305 return val;
306 }
307
308 HI
309 RORHI (HI val, int shift)
310 {
311 if (shift != 0)
312 {
313 int remain = 16 - shift;
314 int mask = (1 << shift) - 1;
315 HI result = (val & mask) << remain;
316 mask = (1 << remain) - 1;
317 result |= (val >> shift) & mask;
318 return result;
319 }
320 return val;
321 }
322
323 HI
324 ROLHI (HI val, int shift)
325 {
326 if (shift != 0)
327 {
328 int remain = 16 - shift;
329 int mask = (1 << remain) - 1;
330 HI result = (val & mask) << shift;
331 mask = (1 << shift) - 1;
332 result |= (val >> remain) & mask;
333 return result;
334 }
335 return val;
336 }
337
338 SI
339 RORSI (SI val, int shift)
340 {
341 if (shift != 0)
342 {
343 int remain = 32 - shift;
344 int mask = (1 << shift) - 1;
345 SI result = (val & mask) << remain;
346 mask = (1 << remain) - 1;
347 result |= (val >> shift) & mask;
348 return result;
349 }
350 return val;
351 }
352
353 SI
354 ROLSI (SI val, int shift)
355 {
356 if (shift != 0)
357 {
358 int remain = 32 - shift;
359 int mask = (1 << remain) - 1;
360 SI result = (val & mask) << shift;
361 mask = (1 << shift) - 1;
362 result |= (val >> remain) & mask;
363 return result;
364 }
365
366 return val;
367 }
368
369 /* Emit an error message from CGEN RTL. */
370
371 void
372 cgen_rtx_error (SIM_CPU *cpu, const char * msg)
373 {
374 SIM_DESC sd = CPU_STATE (cpu);
375
376 sim_io_printf (sd, "%s", msg);
377 sim_io_printf (sd, "\n");
378
379 sim_engine_halt (sd, cpu, NULL, CPU_PC_GET (cpu), sim_stopped, SIM_SIGTRAP);
380 }