1 /* Support code for various pieces of CGEN simulators.
2 Copyright (C) 1996-2024 Free Software Foundation, Inc.
3 Contributed by Cygnus Support.
5 This file is part of GDB, the GNU debugger.
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.
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.
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/>. */
20 /* This must come before any other includes. */
27 #include "sim-signal.h"
29 #define MEMOPS_DEFINE_INLINE
32 #define SEMOPS_DEFINE_INLINE
35 const char * const cgen_mode_names
[] = {
50 0, /* MODE_TARGET_MAX */
56 /* Opcode table for virtual insns used by the simulator. */
58 #define V CGEN_ATTR_MASK (CGEN_INSN_VIRTUAL)
60 static const CGEN_IBASE virtual_insn_entries
[] =
63 VIRTUAL_INSN_X_INVALID
, "--invalid--", NULL
, 0, { V
, {} }
66 VIRTUAL_INSN_X_BEFORE
, "--before--", NULL
, 0, { V
, {} }
69 VIRTUAL_INSN_X_AFTER
, "--after--", NULL
, 0, { V
, {} }
72 VIRTUAL_INSN_X_BEGIN
, "--begin--", NULL
, 0, { V
, {} }
75 VIRTUAL_INSN_X_CHAIN
, "--chain--", NULL
, 0, { V
, {} }
78 VIRTUAL_INSN_X_CTI_CHAIN
, "--cti-chain--", NULL
, 0, { V
, {} }
84 const CGEN_INSN cgen_virtual_insn_table
[] =
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] }
94 /* Return the name of insn number I. */
97 cgen_insn_name (SIM_CPU
*cpu
, int i
)
99 return CGEN_INSN_NAME ((* CPU_GET_IDATA (cpu
)) ((cpu
), (i
)));
102 /* Return the maximum number of extra bytes required for a SIM_CPU struct. */
105 cgen_cpu_max_extra_bytes (SIM_DESC sd
)
107 const SIM_MACH
* const *machp
;
110 SIM_ASSERT (STATE_MACHS (sd
) != NULL
);
112 for (machp
= STATE_MACHS (sd
); *machp
!= NULL
; ++machp
)
114 int size
= IMP_PROPS_SIM_CPU_SIZE (MACH_IMP_PROPS (*machp
));
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
);
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
);
149 USI ahi
= GETHIDI (a
);
150 USI alo
= GETLODI (a
);
151 USI bhi
= GETHIDI (b
);
152 USI blo
= GETLODI (b
);
154 return MAKEDI (ahi
+ bhi
+ (x
< alo
), x
);
161 USI ahi
= GETHIDI (a
);
162 USI alo
= GETLODI (a
);
163 USI bhi
= GETHIDI (b
);
164 USI blo
= GETLODI (b
);
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. */
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
);
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
);
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
);
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
));
226 SI ahi
= GETHIDI (a
);
227 USI alo
= GETLODI (a
);
228 SI bhi
= GETHIDI (b
);
229 USI blo
= GETLODI (b
);
241 SI ahi
= GETHIDI (a
);
242 USI alo
= GETLODI (a
);
243 SI bhi
= GETHIDI (b
);
244 USI blo
= GETLODI (b
);
257 return MAKEDI (-1, val
);
259 return MAKEDI (0, val
);
267 return MAKEDI (-1, val
);
269 return MAKEDI (0, val
);
276 return GETLODI (val
);
279 #endif /* DI_FN_SUPPORT */
282 RORQI (QI val
, int shift
)
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
;
297 ROLQI (QI val
, int shift
)
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
;
312 RORHI (HI val
, int shift
)
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
;
327 ROLHI (HI val
, int shift
)
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
;
342 RORSI (SI val
, int shift
)
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
;
357 ROLSI (SI val
, int shift
)
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
;
372 /* Emit an error message from CGEN RTL. */
375 cgen_rtx_error (SIM_CPU
*cpu
, const char * msg
)
377 SIM_DESC sd
= CPU_STATE (cpu
);
379 sim_io_printf (sd
, "%s", msg
);
380 sim_io_printf (sd
, "\n");
382 sim_engine_halt (sd
, cpu
, NULL
, CPU_PC_GET (cpu
), sim_stopped
, SIM_SIGTRAP
);