arm: Support pac_key_* register operand for MRS/MSR in Armv8.1-M Mainline
[binutils-gdb.git] / sim / iq2000 / iq2000.c
blobdf3d1a7c1cbf1e60eaad4275d2498f8ba002823b
1 /* IQ2000 simulator support code
2 Copyright (C) 2000-2024 Free Software Foundation, Inc.
3 Contributed by Cygnus Support.
5 This file is part of the GNU simulators.
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. */
21 #include "defs.h"
23 #define WANT_CPU
24 #define WANT_CPU_IQ2000BF
26 #include "sim-main.h"
27 #include "sim-signal.h"
28 #include "cgen-mem.h"
29 #include "cgen-ops.h"
30 #include "target-newlib-syscall.h"
31 #include <stdlib.h>
33 enum
35 GPR0_REGNUM = 0,
36 NR_GPR = 32,
37 PC_REGNUM = 32
40 /* Read a null terminated string from memory, return in a buffer */
41 static char *
42 fetch_str (SIM_CPU *current_cpu, PCADDR pc, DI addr)
44 char *buf;
45 int nr = 0;
46 while (sim_core_read_1 (current_cpu,
47 pc, read_map, CPU2DATA(addr + nr)) != 0)
48 nr++;
49 buf = NZALLOC (char, nr + 1);
50 sim_read (CPU_STATE (current_cpu), CPU2DATA(addr), buf, nr);
51 return buf;
54 void
55 do_syscall (SIM_CPU *current_cpu, PCADDR pc)
57 #if 0
58 int syscall = H2T_4 (iq2000bf_h_gr_get (current_cpu, 11));
59 #endif
60 int syscall_function = iq2000bf_h_gr_get (current_cpu, 4);
61 char *buf;
62 int PARM1 = iq2000bf_h_gr_get (current_cpu, 5);
63 int PARM2 = iq2000bf_h_gr_get (current_cpu, 6);
64 int PARM3 = iq2000bf_h_gr_get (current_cpu, 7);
65 const int ret_reg = 2;
67 switch (syscall_function)
69 case 0:
70 switch (H2T_4 (iq2000bf_h_gr_get (current_cpu, 11)))
72 case 0:
73 /* Pass. */
74 puts ("pass");
75 exit (0);
76 case 1:
77 /* Fail. */
78 puts ("fail");
79 exit (1);
80 default:
81 puts ("unknown exit");
82 exit (2);
85 case TARGET_NEWLIB_SYS_write:
86 buf = zalloc (PARM3);
87 sim_read (CPU_STATE (current_cpu), CPU2DATA(PARM2), buf, PARM3);
88 SET_H_GR (ret_reg,
89 sim_io_write (CPU_STATE (current_cpu),
90 PARM1, buf, PARM3));
91 free (buf);
92 break;
94 case TARGET_NEWLIB_SYS_lseek:
95 SET_H_GR (ret_reg,
96 sim_io_lseek (CPU_STATE (current_cpu),
97 PARM1, PARM2, PARM3));
98 break;
100 case TARGET_NEWLIB_SYS_exit:
101 sim_engine_halt (CPU_STATE (current_cpu), current_cpu,
102 NULL, pc, sim_exited, PARM1);
103 break;
105 case TARGET_NEWLIB_SYS_read:
106 buf = zalloc (PARM3);
107 SET_H_GR (ret_reg,
108 sim_io_read (CPU_STATE (current_cpu),
109 PARM1, buf, PARM3));
110 sim_write (CPU_STATE (current_cpu), CPU2DATA(PARM2),
111 (unsigned char *) buf, PARM3);
112 free (buf);
113 break;
115 case TARGET_NEWLIB_SYS_open:
116 buf = fetch_str (current_cpu, pc, PARM1);
117 SET_H_GR (ret_reg,
118 sim_io_open (CPU_STATE (current_cpu),
119 buf, PARM2));
120 free (buf);
121 break;
123 case TARGET_NEWLIB_SYS_close:
124 SET_H_GR (ret_reg,
125 sim_io_close (CPU_STATE (current_cpu), PARM1));
126 break;
128 case TARGET_NEWLIB_SYS_time:
129 SET_H_GR (ret_reg, time (0));
130 break;
132 default:
133 SET_H_GR (ret_reg, -1);
137 void
138 do_break (SIM_CPU *current_cpu, PCADDR pc)
140 SIM_DESC sd = CPU_STATE (current_cpu);
141 sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
144 /* The semantic code invokes this for invalid (unrecognized) instructions. */
146 SEM_PC
147 sim_engine_invalid_insn (SIM_CPU *current_cpu, IADDR cia, SEM_PC vpc)
149 SIM_DESC sd = CPU_STATE (current_cpu);
150 sim_engine_halt (sd, current_cpu, NULL, cia, sim_stopped, SIM_SIGILL);
152 return vpc;
156 /* Process an address exception. */
158 void
159 iq2000_core_signal (SIM_DESC sd, SIM_CPU *current_cpu, sim_cia cia,
160 unsigned int map, int nr_bytes, address_word addr,
161 transfer_type transfer, sim_core_signals sig)
163 sim_core_signal (sd, current_cpu, cia, map, nr_bytes, addr,
164 transfer, sig);
168 /* Initialize cycle counting for an insn.
169 FIRST_P is non-zero if this is the first insn in a set of parallel
170 insns. */
172 void
173 iq2000bf_model_insn_before (SIM_CPU *cpu, int first_p)
175 /* Do nothing. */
179 /* Record the cycles computed for an insn.
180 LAST_P is non-zero if this is the last insn in a set of parallel insns,
181 and we update the total cycle count.
182 CYCLES is the cycle count of the insn. */
184 void
185 iq2000bf_model_insn_after(SIM_CPU *cpu, int last_p, int cycles)
187 /* Do nothing. */
192 iq2000bf_model_iq2000_u_exec (SIM_CPU *cpu, const IDESC *idesc,
193 int unit_num, int referenced)
195 return idesc->timing->units[unit_num].done;
198 PCADDR
199 get_h_pc (SIM_CPU *cpu)
201 return CPU_CGEN_HW(cpu)->h_pc;
204 void
205 set_h_pc (SIM_CPU *cpu, PCADDR addr)
207 CPU_CGEN_HW(cpu)->h_pc = addr | IQ2000_INSN_MASK;
211 iq2000bf_fetch_register (SIM_CPU *cpu, int nr, void *buf, int len)
213 if (nr >= GPR0_REGNUM
214 && nr < (GPR0_REGNUM + NR_GPR)
215 && len == 4)
217 *((uint32_t*)buf) =
218 H2T_4 (iq2000bf_h_gr_get (cpu, nr - GPR0_REGNUM));
219 return 4;
221 else if (nr == PC_REGNUM
222 && len == 4)
224 *((uint32_t*)buf) = H2T_4 (get_h_pc (cpu));
225 return 4;
227 else
228 return 0;
232 iq2000bf_store_register (SIM_CPU *cpu, int nr, const void *buf, int len)
234 if (nr >= GPR0_REGNUM
235 && nr < (GPR0_REGNUM + NR_GPR)
236 && len == 4)
238 iq2000bf_h_gr_set (cpu, nr - GPR0_REGNUM, T2H_4 (*((uint32_t*)buf)));
239 return 4;
241 else if (nr == PC_REGNUM
242 && len == 4)
244 set_h_pc (cpu, T2H_4 (*((uint32_t*)buf)));
245 return 4;
247 else
248 return 0;