]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/common/cgen-utils.c
sim: arm/cr16/d10v/h8300/microblaze/sh: fill out sim-cpu pc fetch/store helpers
[thirdparty/binutils-gdb.git] / sim / common / cgen-utils.c
CommitLineData
c906108c 1/* Support code for various pieces of CGEN simulators.
32d0add0 2 Copyright (C) 1996-2015 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
31#undef min
32#define min(a,b) ((a) < (b) ? (a) : (b))
33
34const char *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 {
7a292a7a 62 VIRTUAL_INSN_X_INVALID, "--invalid--", NULL, 0, { V, { 0 } }
c906108c
SS
63 },
64 {
7a292a7a 65 VIRTUAL_INSN_X_BEFORE, "--before--", NULL, 0, { V, { 0 } }
c906108c
SS
66 },
67 {
7a292a7a 68 VIRTUAL_INSN_X_AFTER, "--after--", NULL, 0, { V, { 0 } }
c906108c
SS
69 },
70 {
7a292a7a 71 VIRTUAL_INSN_X_BEGIN, "--begin--", NULL, 0, { V, { 0 } }
c906108c
SS
72 },
73 {
7a292a7a 74 VIRTUAL_INSN_X_CHAIN, "--chain--", NULL, 0, { V, { 0 } }
c906108c
SS
75 },
76 {
7a292a7a 77 VIRTUAL_INSN_X_CTI_CHAIN, "--cti-chain--", NULL, 0, { V, { 0 } }
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
93/* Initialize cgen things.
94 This is called after sim_post_argv_init. */
95
96void
97cgen_init (SIM_DESC sd)
98{
99 int i, c;
100
101 /* If no profiling or tracing has been enabled, run in fast mode. */
102 {
103 int run_fast_p = 1;
104
105 for (c = 0; c < MAX_NR_PROCESSORS; ++c)
106 {
107 SIM_CPU *cpu = STATE_CPU (sd, c);
108
109 for (i = 0; i < MAX_PROFILE_VALUES; ++i)
110 if (CPU_PROFILE_FLAGS (cpu) [i])
111 {
112 run_fast_p = 0;
113 break;
114 }
115 for (i = 0; i < MAX_TRACE_VALUES; ++i)
116 if (CPU_TRACE_FLAGS (cpu) [i])
117 {
118 run_fast_p = 0;
119 break;
120 }
121 if (! run_fast_p)
122 break;
123 }
124 STATE_RUN_FAST_P (sd) = run_fast_p;
125 }
126}
127
128/* Return the name of insn number I. */
129
130const char *
131cgen_insn_name (SIM_CPU *cpu, int i)
132{
133 return CGEN_INSN_NAME ((* CPU_GET_IDATA (cpu)) ((cpu), (i)));
134}
135
136/* Return the maximum number of extra bytes required for a SIM_CPU struct. */
137
138int
139cgen_cpu_max_extra_bytes (void)
140{
141 int i;
142 int extra = 0;
143
144 for (i = 0; sim_machs[i] != 0; ++i)
145 {
146 int size = IMP_PROPS_SIM_CPU_SIZE (MACH_IMP_PROPS (sim_machs[i]));
147 if (size > extra)
148 extra = size;
149 }
150 return extra;
151}
152\f
153#ifdef DI_FN_SUPPORT
154
155DI
156make_struct_di (hi, lo)
157 SI hi, lo;
158{
159 DI result;
160
161 result.hi = hi;
162 result.lo = lo;
163 return result;
164}
165
166DI
167ANDDI (a, b)
168 DI a, b;
169{
170 SI ahi = GETHIDI (a);
171 SI alo = GETLODI (a);
172 SI bhi = GETHIDI (b);
173 SI blo = GETLODI (b);
174 return MAKEDI (ahi & bhi, alo & blo);
175}
176
177DI
178ORDI (a, b)
179 DI a, b;
180{
181 SI ahi = GETHIDI (a);
182 SI alo = GETLODI (a);
183 SI bhi = GETHIDI (b);
184 SI blo = GETLODI (b);
185 return MAKEDI (ahi | bhi, alo | blo);
186}
187
188DI
189ADDDI (a, b)
190 DI a, b;
191{
192 USI ahi = GETHIDI (a);
193 USI alo = GETLODI (a);
194 USI bhi = GETHIDI (b);
195 USI blo = GETLODI (b);
196 USI x = alo + blo;
197 return MAKEDI (ahi + bhi + (x < alo), x);
198}
199
200DI
201MULDI (a, b)
202 DI a, b;
203{
204 USI ahi = GETHIDI (a);
205 USI alo = GETLODI (a);
206 USI bhi = GETHIDI (b);
207 USI blo = GETLODI (b);
208 USI rhi,rlo;
209 USI x0, x1, x2, x3;
210
211 x0 = alo * blo;
212 x1 = alo * bhi;
213 x2 = ahi * blo;
214 x3 = ahi * bhi;
215
216#define SI_TYPE_SIZE 32
217#define BITS4 (SI_TYPE_SIZE / 4)
218#define ll_B (1L << (SI_TYPE_SIZE / 2))
219#define ll_lowpart(t) ((USI) (t) % ll_B)
220#define ll_highpart(t) ((USI) (t) / ll_B)
221 x1 += ll_highpart (x0); /* this can't give carry */
222 x1 += x2; /* but this indeed can */
223 if (x1 < x2) /* did we get it? */
224 x3 += ll_B; /* yes, add it in the proper pos. */
225
226 rhi = x3 + ll_highpart (x1);
227 rlo = ll_lowpart (x1) * ll_B + ll_lowpart (x0);
228 return MAKEDI (rhi + (alo * bhi) + (ahi * blo), rlo);
229}
230
231DI
232SHLDI (val, shift)
233 DI val;
234 SI shift;
235{
236 USI hi = GETHIDI (val);
237 USI lo = GETLODI (val);
238 /* FIXME: Need to worry about shift < 0 || shift >= 32. */
239 return MAKEDI ((hi << shift) | (lo >> (32 - shift)), lo << shift);
240}
241
242DI
243SLADI (val, shift)
244 DI val;
245 SI shift;
246{
247 SI hi = GETHIDI (val);
248 USI lo = GETLODI (val);
249 /* FIXME: Need to worry about shift < 0 || shift >= 32. */
250 return MAKEDI ((hi << shift) | (lo >> (32 - shift)), lo << shift);
251}
252
253DI
254SRADI (val, shift)
255 DI val;
256 SI shift;
257{
258 SI hi = GETHIDI (val);
259 USI lo = GETLODI (val);
260 /* We use SRASI because the result is implementation defined if hi < 0. */
261 /* FIXME: Need to worry about shift < 0 || shift >= 32. */
262 return MAKEDI (SRASI (hi, shift), (hi << (32 - shift)) | (lo >> shift));
263}
264
265int
266GEDI (a, b)
267 DI a, b;
268{
269 SI ahi = GETHIDI (a);
270 USI alo = GETLODI (a);
271 SI bhi = GETHIDI (b);
272 USI blo = GETLODI (b);
273 if (ahi > bhi)
274 return 1;
275 if (ahi == bhi)
276 return alo >= blo;
277 return 0;
278}
279
280int
281LEDI (a, b)
282 DI a, b;
283{
284 SI ahi = GETHIDI (a);
285 USI alo = GETLODI (a);
286 SI bhi = GETHIDI (b);
287 USI blo = GETLODI (b);
288 if (ahi < bhi)
289 return 1;
290 if (ahi == bhi)
291 return alo <= blo;
292 return 0;
293}
294
295DI
296CONVHIDI (val)
297 HI val;
298{
299 if (val < 0)
300 return MAKEDI (-1, val);
301 else
302 return MAKEDI (0, val);
303}
304
305DI
306CONVSIDI (val)
307 SI val;
308{
309 if (val < 0)
310 return MAKEDI (-1, val);
311 else
312 return MAKEDI (0, val);
313}
314
315SI
316CONVDISI (val)
317 DI val;
318{
319 return GETLODI (val);
320}
321
322#endif /* DI_FN_SUPPORT */
adf40b2e 323\f
6d4c43bf
DB
324QI
325RORQI (val, shift)
326 QI val;
327 int shift;
328{
329 if (shift != 0)
330 {
331 int remain = 8 - shift;
332 int mask = (1 << shift) - 1;
333 QI result = (val & mask) << remain;
334 mask = (1 << remain) - 1;
335 result |= (val >> shift) & mask;
336 return result;
337 }
338 return val;
339}
340
341QI
342ROLQI (val, shift)
343 QI val;
344 int shift;
345{
346 if (shift != 0)
347 {
348 int remain = 8 - shift;
349 int mask = (1 << remain) - 1;
350 QI result = (val & mask) << shift;
351 mask = (1 << shift) - 1;
352 result |= (val >> remain) & mask;
353 return result;
354 }
355 return val;
356}
357
358HI
359RORHI (val, shift)
360 HI val;
361 int shift;
362{
363 if (shift != 0)
364 {
365 int remain = 16 - shift;
366 int mask = (1 << shift) - 1;
367 HI result = (val & mask) << remain;
368 mask = (1 << remain) - 1;
369 result |= (val >> shift) & mask;
370 return result;
371 }
372 return val;
373}
374
375HI
376ROLHI (val, shift)
377 HI val;
378 int shift;
379{
380 if (shift != 0)
381 {
382 int remain = 16 - shift;
383 int mask = (1 << remain) - 1;
384 HI result = (val & mask) << shift;
385 mask = (1 << shift) - 1;
386 result |= (val >> remain) & mask;
387 return result;
388 }
389 return val;
390}
391
adf40b2e
JM
392SI
393RORSI (val, shift)
394 SI val;
395 int shift;
396{
397 if (shift != 0)
398 {
399 int remain = 32 - shift;
400 int mask = (1 << shift) - 1;
401 SI result = (val & mask) << remain;
402 mask = (1 << remain) - 1;
403 result |= (val >> shift) & mask;
404 return result;
405 }
406 return val;
407}
408
409SI
410ROLSI (val, shift)
411 SI val;
412 int shift;
413{
414 if (shift != 0)
415 {
416 int remain = 32 - shift;
417 int mask = (1 << remain) - 1;
418 SI result = (val & mask) << shift;
419 mask = (1 << shift) - 1;
420 result |= (val >> remain) & mask;
421 return result;
422 }
423
424 return val;
425}
a8d894af
BE
426
427/* Emit an error message from CGEN RTL. */
428
429void
430cgen_rtx_error (SIM_CPU *cpu, const char * msg)
431{
432 SIM_DESC sd = CPU_STATE (cpu);
433
434 sim_io_printf (sd, msg);
435 sim_io_printf (sd, "\n");
436
437 sim_engine_halt (sd, cpu, NULL, CIA_GET (cpu), sim_stopped, SIM_SIGTRAP);
438}