]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/common/cgen-utils.c
import gdb-1999-08-30 snapshot
[thirdparty/binutils-gdb.git] / sim / common / cgen-utils.c
CommitLineData
c906108c
SS
1/* Support code for various pieces of CGEN simulators.
2 Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
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
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
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
17You should have received a copy of the GNU General Public License along
18with this program; if not, write to the Free Software Foundation, Inc.,
1959 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20
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[] = {
35 "VM",
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
JM
323\f
324SI
325RORSI (val, shift)
326 SI val;
327 int shift;
328{
329 if (shift != 0)
330 {
331 int remain = 32 - shift;
332 int mask = (1 << shift) - 1;
333 SI result = (val & mask) << remain;
334 mask = (1 << remain) - 1;
335 result |= (val >> shift) & mask;
336 return result;
337 }
338 return val;
339}
340
341SI
342ROLSI (val, shift)
343 SI val;
344 int shift;
345{
346 if (shift != 0)
347 {
348 int remain = 32 - shift;
349 int mask = (1 << remain) - 1;
350 SI result = (val & mask) << shift;
351 mask = (1 << shift) - 1;
352 result |= (val >> remain) & mask;
353 return result;
354 }
355
356 return val;
357}