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