cgen-utils.c revision 1.6.4.1 1 1.1 christos /* Support code for various pieces of CGEN simulators.
2 1.6.4.1 christos Copyright (C) 1996-2017 Free Software Foundation, Inc.
3 1.1 christos Contributed by Cygnus Support.
4 1.1 christos
5 1.1 christos This file is part of GDB, the GNU debugger.
6 1.1 christos
7 1.1 christos This program is free software; you can redistribute it and/or modify
8 1.1 christos it under the terms of the GNU General Public License as published by
9 1.1 christos the Free Software Foundation; either version 3 of the License, or
10 1.1 christos (at your option) any later version.
11 1.1 christos
12 1.1 christos This program is distributed in the hope that it will be useful,
13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 1.1 christos GNU General Public License for more details.
16 1.1 christos
17 1.1 christos You should have received a copy of the GNU General Public License
18 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 1.1 christos
20 1.1 christos #include "config.h"
21 1.1 christos #include "bfd.h"
22 1.1 christos #include "sim-main.h"
23 1.1 christos #include "dis-asm.h"
24 1.1 christos
25 1.1 christos #define MEMOPS_DEFINE_INLINE
26 1.1 christos #include "cgen-mem.h"
27 1.1 christos
28 1.1 christos #define SEMOPS_DEFINE_INLINE
29 1.1 christos #include "cgen-ops.h"
30 1.1 christos
31 1.6.4.1 christos const char * const mode_names[] = {
32 1.1 christos "VOID",
33 1.1 christos "BI",
34 1.1 christos "QI",
35 1.1 christos "HI",
36 1.1 christos "SI",
37 1.1 christos "DI",
38 1.1 christos "UQI",
39 1.1 christos "UHI",
40 1.1 christos "USI",
41 1.1 christos "UDI",
42 1.1 christos "SF",
43 1.1 christos "DF",
44 1.1 christos "XF",
45 1.1 christos "TF",
46 1.1 christos 0, /* MODE_TARGET_MAX */
47 1.1 christos "INT",
48 1.1 christos "UINT",
49 1.1 christos "PTR"
50 1.1 christos };
51 1.1 christos
52 1.1 christos /* Opcode table for virtual insns used by the simulator. */
53 1.1 christos
54 1.1 christos #define V CGEN_ATTR_MASK (CGEN_INSN_VIRTUAL)
55 1.1 christos
56 1.1 christos static const CGEN_IBASE virtual_insn_entries[] =
57 1.1 christos {
58 1.1 christos {
59 1.1 christos VIRTUAL_INSN_X_INVALID, "--invalid--", NULL, 0, { V, { 0 } }
60 1.1 christos },
61 1.1 christos {
62 1.1 christos VIRTUAL_INSN_X_BEFORE, "--before--", NULL, 0, { V, { 0 } }
63 1.1 christos },
64 1.1 christos {
65 1.1 christos VIRTUAL_INSN_X_AFTER, "--after--", NULL, 0, { V, { 0 } }
66 1.1 christos },
67 1.1 christos {
68 1.1 christos VIRTUAL_INSN_X_BEGIN, "--begin--", NULL, 0, { V, { 0 } }
69 1.1 christos },
70 1.1 christos {
71 1.1 christos VIRTUAL_INSN_X_CHAIN, "--chain--", NULL, 0, { V, { 0 } }
72 1.1 christos },
73 1.1 christos {
74 1.1 christos VIRTUAL_INSN_X_CTI_CHAIN, "--cti-chain--", NULL, 0, { V, { 0 } }
75 1.1 christos }
76 1.1 christos };
77 1.1 christos
78 1.1 christos #undef V
79 1.1 christos
80 1.1 christos const CGEN_INSN cgen_virtual_insn_table[] =
81 1.1 christos {
82 1.1 christos { & virtual_insn_entries[0] },
83 1.1 christos { & virtual_insn_entries[1] },
84 1.1 christos { & virtual_insn_entries[2] },
85 1.1 christos { & virtual_insn_entries[3] },
86 1.1 christos { & virtual_insn_entries[4] },
87 1.1 christos { & virtual_insn_entries[5] }
88 1.1 christos };
89 1.1 christos
90 1.1 christos /* Initialize cgen things.
91 1.1 christos This is called after sim_post_argv_init. */
92 1.1 christos
93 1.1 christos void
94 1.1 christos cgen_init (SIM_DESC sd)
95 1.1 christos {
96 1.1 christos int i, c;
97 1.1 christos
98 1.1 christos /* If no profiling or tracing has been enabled, run in fast mode. */
99 1.1 christos {
100 1.1 christos int run_fast_p = 1;
101 1.1 christos
102 1.1 christos for (c = 0; c < MAX_NR_PROCESSORS; ++c)
103 1.1 christos {
104 1.1 christos SIM_CPU *cpu = STATE_CPU (sd, c);
105 1.1 christos
106 1.1 christos for (i = 0; i < MAX_PROFILE_VALUES; ++i)
107 1.1 christos if (CPU_PROFILE_FLAGS (cpu) [i])
108 1.1 christos {
109 1.1 christos run_fast_p = 0;
110 1.1 christos break;
111 1.1 christos }
112 1.1 christos for (i = 0; i < MAX_TRACE_VALUES; ++i)
113 1.1 christos if (CPU_TRACE_FLAGS (cpu) [i])
114 1.1 christos {
115 1.1 christos run_fast_p = 0;
116 1.1 christos break;
117 1.1 christos }
118 1.1 christos if (! run_fast_p)
119 1.1 christos break;
120 1.1 christos }
121 1.1 christos STATE_RUN_FAST_P (sd) = run_fast_p;
122 1.1 christos }
123 1.1 christos }
124 1.1 christos
125 1.1 christos /* Return the name of insn number I. */
126 1.1 christos
127 1.1 christos const char *
128 1.1 christos cgen_insn_name (SIM_CPU *cpu, int i)
129 1.1 christos {
130 1.1 christos return CGEN_INSN_NAME ((* CPU_GET_IDATA (cpu)) ((cpu), (i)));
131 1.1 christos }
132 1.1 christos
133 1.1 christos /* Return the maximum number of extra bytes required for a SIM_CPU struct. */
134 1.1 christos
135 1.1 christos int
136 1.1 christos cgen_cpu_max_extra_bytes (void)
137 1.1 christos {
138 1.1 christos int i;
139 1.1 christos int extra = 0;
140 1.1 christos
141 1.1 christos for (i = 0; sim_machs[i] != 0; ++i)
142 1.1 christos {
143 1.1 christos int size = IMP_PROPS_SIM_CPU_SIZE (MACH_IMP_PROPS (sim_machs[i]));
144 1.1 christos if (size > extra)
145 1.1 christos extra = size;
146 1.1 christos }
147 1.1 christos return extra;
148 1.1 christos }
149 1.1 christos
150 1.1 christos #ifdef DI_FN_SUPPORT
152 1.1 christos
153 1.1 christos DI
154 1.1 christos make_struct_di (hi, lo)
155 1.1 christos SI hi, lo;
156 1.1 christos {
157 1.1 christos DI result;
158 1.1 christos
159 1.1 christos result.hi = hi;
160 1.1 christos result.lo = lo;
161 1.1 christos return result;
162 1.1 christos }
163 1.1 christos
164 1.1 christos DI
165 1.1 christos ANDDI (a, b)
166 1.1 christos DI a, b;
167 1.1 christos {
168 1.1 christos SI ahi = GETHIDI (a);
169 1.1 christos SI alo = GETLODI (a);
170 1.1 christos SI bhi = GETHIDI (b);
171 1.1 christos SI blo = GETLODI (b);
172 1.1 christos return MAKEDI (ahi & bhi, alo & blo);
173 1.1 christos }
174 1.1 christos
175 1.1 christos DI
176 1.1 christos ORDI (a, b)
177 1.1 christos DI a, b;
178 1.1 christos {
179 1.1 christos SI ahi = GETHIDI (a);
180 1.1 christos SI alo = GETLODI (a);
181 1.1 christos SI bhi = GETHIDI (b);
182 1.1 christos SI blo = GETLODI (b);
183 1.1 christos return MAKEDI (ahi | bhi, alo | blo);
184 1.1 christos }
185 1.1 christos
186 1.1 christos DI
187 1.1 christos ADDDI (a, b)
188 1.1 christos DI a, b;
189 1.1 christos {
190 1.1 christos USI ahi = GETHIDI (a);
191 1.1 christos USI alo = GETLODI (a);
192 1.1 christos USI bhi = GETHIDI (b);
193 1.1 christos USI blo = GETLODI (b);
194 1.1 christos USI x = alo + blo;
195 1.1 christos return MAKEDI (ahi + bhi + (x < alo), x);
196 1.1 christos }
197 1.1 christos
198 1.1 christos DI
199 1.1 christos MULDI (a, b)
200 1.1 christos DI a, b;
201 1.1 christos {
202 1.1 christos USI ahi = GETHIDI (a);
203 1.1 christos USI alo = GETLODI (a);
204 1.1 christos USI bhi = GETHIDI (b);
205 1.1 christos USI blo = GETLODI (b);
206 1.1 christos USI rhi,rlo;
207 1.1 christos USI x0, x1, x2, x3;
208 1.1 christos
209 1.1 christos x0 = alo * blo;
210 1.1 christos x1 = alo * bhi;
211 1.1 christos x2 = ahi * blo;
212 1.1 christos x3 = ahi * bhi;
213 1.1 christos
214 1.1 christos #define SI_TYPE_SIZE 32
215 1.1 christos #define BITS4 (SI_TYPE_SIZE / 4)
216 1.1 christos #define ll_B (1L << (SI_TYPE_SIZE / 2))
217 1.1 christos #define ll_lowpart(t) ((USI) (t) % ll_B)
218 1.1 christos #define ll_highpart(t) ((USI) (t) / ll_B)
219 1.1 christos x1 += ll_highpart (x0); /* this can't give carry */
220 1.1 christos x1 += x2; /* but this indeed can */
221 1.1 christos if (x1 < x2) /* did we get it? */
222 1.1 christos x3 += ll_B; /* yes, add it in the proper pos. */
223 1.1 christos
224 1.1 christos rhi = x3 + ll_highpart (x1);
225 1.1 christos rlo = ll_lowpart (x1) * ll_B + ll_lowpart (x0);
226 1.1 christos return MAKEDI (rhi + (alo * bhi) + (ahi * blo), rlo);
227 1.1 christos }
228 1.1 christos
229 1.1 christos DI
230 1.1 christos SHLDI (val, shift)
231 1.1 christos DI val;
232 1.1 christos SI shift;
233 1.1 christos {
234 1.1 christos USI hi = GETHIDI (val);
235 1.1 christos USI lo = GETLODI (val);
236 1.1 christos /* FIXME: Need to worry about shift < 0 || shift >= 32. */
237 1.1 christos return MAKEDI ((hi << shift) | (lo >> (32 - shift)), lo << shift);
238 1.1 christos }
239 1.1 christos
240 1.1 christos DI
241 1.1 christos SLADI (val, shift)
242 1.1 christos DI val;
243 1.1 christos SI shift;
244 1.1 christos {
245 1.1 christos SI hi = GETHIDI (val);
246 1.1 christos USI lo = GETLODI (val);
247 1.1 christos /* FIXME: Need to worry about shift < 0 || shift >= 32. */
248 1.1 christos return MAKEDI ((hi << shift) | (lo >> (32 - shift)), lo << shift);
249 1.1 christos }
250 1.1 christos
251 1.1 christos DI
252 1.1 christos SRADI (val, shift)
253 1.1 christos DI val;
254 1.1 christos SI shift;
255 1.1 christos {
256 1.1 christos SI hi = GETHIDI (val);
257 1.1 christos USI lo = GETLODI (val);
258 1.1 christos /* We use SRASI because the result is implementation defined if hi < 0. */
259 1.1 christos /* FIXME: Need to worry about shift < 0 || shift >= 32. */
260 1.1 christos return MAKEDI (SRASI (hi, shift), (hi << (32 - shift)) | (lo >> shift));
261 1.1 christos }
262 1.1 christos
263 1.1 christos int
264 1.1 christos GEDI (a, b)
265 1.1 christos DI a, b;
266 1.1 christos {
267 1.1 christos SI ahi = GETHIDI (a);
268 1.1 christos USI alo = GETLODI (a);
269 1.1 christos SI bhi = GETHIDI (b);
270 1.1 christos USI blo = GETLODI (b);
271 1.1 christos if (ahi > bhi)
272 1.1 christos return 1;
273 1.1 christos if (ahi == bhi)
274 1.1 christos return alo >= blo;
275 1.1 christos return 0;
276 1.1 christos }
277 1.1 christos
278 1.1 christos int
279 1.1 christos LEDI (a, b)
280 1.1 christos DI a, b;
281 1.1 christos {
282 1.1 christos SI ahi = GETHIDI (a);
283 1.1 christos USI alo = GETLODI (a);
284 1.1 christos SI bhi = GETHIDI (b);
285 1.1 christos USI blo = GETLODI (b);
286 1.1 christos if (ahi < bhi)
287 1.1 christos return 1;
288 1.1 christos if (ahi == bhi)
289 1.1 christos return alo <= blo;
290 1.1 christos return 0;
291 1.1 christos }
292 1.1 christos
293 1.1 christos DI
294 1.1 christos CONVHIDI (val)
295 1.1 christos HI val;
296 1.1 christos {
297 1.1 christos if (val < 0)
298 1.1 christos return MAKEDI (-1, val);
299 1.1 christos else
300 1.1 christos return MAKEDI (0, val);
301 1.1 christos }
302 1.1 christos
303 1.1 christos DI
304 1.1 christos CONVSIDI (val)
305 1.1 christos SI val;
306 1.1 christos {
307 1.1 christos if (val < 0)
308 1.1 christos return MAKEDI (-1, val);
309 1.1 christos else
310 1.1 christos return MAKEDI (0, val);
311 1.1 christos }
312 1.1 christos
313 1.1 christos SI
314 1.1 christos CONVDISI (val)
315 1.1 christos DI val;
316 1.1 christos {
317 1.1 christos return GETLODI (val);
318 1.1 christos }
319 1.1 christos
320 1.1 christos #endif /* DI_FN_SUPPORT */
321 1.1 christos
322 1.1 christos QI
324 1.1 christos RORQI (val, shift)
325 1.1 christos QI val;
326 1.1 christos int shift;
327 1.1 christos {
328 1.1 christos if (shift != 0)
329 1.1 christos {
330 1.1 christos int remain = 8 - shift;
331 1.1 christos int mask = (1 << shift) - 1;
332 1.1 christos QI result = (val & mask) << remain;
333 1.1 christos mask = (1 << remain) - 1;
334 1.1 christos result |= (val >> shift) & mask;
335 1.1 christos return result;
336 1.1 christos }
337 1.1 christos return val;
338 1.1 christos }
339 1.1 christos
340 1.1 christos QI
341 1.1 christos ROLQI (val, shift)
342 1.1 christos QI val;
343 1.1 christos int shift;
344 1.1 christos {
345 1.1 christos if (shift != 0)
346 1.1 christos {
347 1.1 christos int remain = 8 - shift;
348 1.1 christos int mask = (1 << remain) - 1;
349 1.1 christos QI result = (val & mask) << shift;
350 1.1 christos mask = (1 << shift) - 1;
351 1.1 christos result |= (val >> remain) & mask;
352 1.1 christos return result;
353 1.1 christos }
354 1.1 christos return val;
355 1.1 christos }
356 1.1 christos
357 1.1 christos HI
358 1.1 christos RORHI (val, shift)
359 1.1 christos HI val;
360 1.1 christos int shift;
361 1.1 christos {
362 1.1 christos if (shift != 0)
363 1.1 christos {
364 1.1 christos int remain = 16 - shift;
365 1.1 christos int mask = (1 << shift) - 1;
366 1.1 christos HI result = (val & mask) << remain;
367 1.1 christos mask = (1 << remain) - 1;
368 1.1 christos result |= (val >> shift) & mask;
369 1.1 christos return result;
370 1.1 christos }
371 1.1 christos return val;
372 1.1 christos }
373 1.1 christos
374 1.1 christos HI
375 1.1 christos ROLHI (val, shift)
376 1.1 christos HI val;
377 1.1 christos int shift;
378 1.1 christos {
379 1.1 christos if (shift != 0)
380 1.1 christos {
381 1.1 christos int remain = 16 - shift;
382 1.1 christos int mask = (1 << remain) - 1;
383 1.1 christos HI result = (val & mask) << shift;
384 1.1 christos mask = (1 << shift) - 1;
385 1.1 christos result |= (val >> remain) & mask;
386 1.1 christos return result;
387 1.1 christos }
388 1.1 christos return val;
389 1.1 christos }
390 1.1 christos
391 1.1 christos SI
392 1.1 christos RORSI (val, shift)
393 1.1 christos SI val;
394 1.1 christos int shift;
395 1.1 christos {
396 1.1 christos if (shift != 0)
397 1.1 christos {
398 1.1 christos int remain = 32 - shift;
399 1.1 christos int mask = (1 << shift) - 1;
400 1.1 christos SI result = (val & mask) << remain;
401 1.1 christos mask = (1 << remain) - 1;
402 1.1 christos result |= (val >> shift) & mask;
403 1.1 christos return result;
404 1.1 christos }
405 1.1 christos return val;
406 1.1 christos }
407 1.1 christos
408 1.1 christos SI
409 1.1 christos ROLSI (val, shift)
410 1.1 christos SI val;
411 1.1 christos int shift;
412 1.1 christos {
413 1.1 christos if (shift != 0)
414 1.1 christos {
415 1.1 christos int remain = 32 - shift;
416 1.1 christos int mask = (1 << remain) - 1;
417 1.1 christos SI result = (val & mask) << shift;
418 1.1 christos mask = (1 << shift) - 1;
419 1.1 christos result |= (val >> remain) & mask;
420 1.1 christos return result;
421 1.1 christos }
422 1.1 christos
423 1.1 christos return val;
424 1.1 christos }
425 1.1 christos
426 1.1 christos /* Emit an error message from CGEN RTL. */
427 1.1 christos
428 1.1 christos void
429 1.1 christos cgen_rtx_error (SIM_CPU *cpu, const char * msg)
430 1.1 christos {
431 1.1 christos SIM_DESC sd = CPU_STATE (cpu);
432 1.1 christos
433 1.1 christos sim_io_printf (sd, msg);
434 1.5 christos sim_io_printf (sd, "\n");
435 1.1 christos
436 sim_engine_halt (sd, cpu, NULL, CPU_PC_GET (cpu), sim_stopped, SIM_SIGTRAP);
437 }
438