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