1 /* IQ2000 simulator support code
2 Copyright (C) 2000-2022 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. */
24 #define WANT_CPU_IQ2000BF
27 #include "sim-signal.h"
30 #include "target-newlib-syscall.h"
40 /* Read a null terminated string from memory, return in a buffer */
42 fetch_str (SIM_CPU *current_cpu, PCADDR pc, DI addr)
46 while (sim_core_read_1 (current_cpu,
47 pc, read_map, CPU2DATA(addr + nr)) != 0)
49 buf = NZALLOC (char, nr + 1);
50 sim_read (CPU_STATE (current_cpu), CPU2DATA(addr), buf, nr);
55 do_syscall (SIM_CPU *current_cpu, PCADDR pc)
58 int syscall = H2T_4 (iq2000bf_h_gr_get (current_cpu, 11));
60 int syscall_function = iq2000bf_h_gr_get (current_cpu, 4);
63 int PARM1 = iq2000bf_h_gr_get (current_cpu, 5);
64 int PARM2 = iq2000bf_h_gr_get (current_cpu, 6);
65 int PARM3 = iq2000bf_h_gr_get (current_cpu, 7);
66 const int ret_reg = 2;
68 switch (syscall_function)
71 switch (H2T_4 (iq2000bf_h_gr_get (current_cpu, 11)))
83 case TARGET_NEWLIB_SYS_write:
85 sim_read (CPU_STATE (current_cpu), CPU2DATA(PARM2), buf, PARM3);
87 sim_io_write (CPU_STATE (current_cpu),
92 case TARGET_NEWLIB_SYS_lseek:
94 sim_io_lseek (CPU_STATE (current_cpu),
95 PARM1, PARM2, PARM3));
98 case TARGET_NEWLIB_SYS_exit:
99 sim_engine_halt (CPU_STATE (current_cpu), current_cpu,
100 NULL, pc, sim_exited, PARM1);
103 case TARGET_NEWLIB_SYS_read:
104 buf = zalloc (PARM3);
106 sim_io_read (CPU_STATE (current_cpu),
108 sim_write (CPU_STATE (current_cpu), CPU2DATA(PARM2),
109 (unsigned char *) buf, PARM3);
113 case TARGET_NEWLIB_SYS_open:
114 buf = fetch_str (current_cpu, pc, PARM1);
116 sim_io_open (CPU_STATE (current_cpu),
121 case TARGET_NEWLIB_SYS_close:
123 sim_io_close (CPU_STATE (current_cpu), PARM1));
126 case TARGET_NEWLIB_SYS_time:
127 SET_H_GR (ret_reg, time (0));
131 SET_H_GR (ret_reg, -1);
136 do_break (SIM_CPU *current_cpu, PCADDR pc)
138 SIM_DESC sd = CPU_STATE (current_cpu);
139 sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
142 /* The semantic code invokes this for invalid (unrecognized) instructions. */
145 sim_engine_invalid_insn (SIM_CPU *current_cpu, IADDR cia, SEM_PC vpc)
147 SIM_DESC sd = CPU_STATE (current_cpu);
148 sim_engine_halt (sd, current_cpu, NULL, cia, sim_stopped, SIM_SIGILL);
154 /* Process an address exception. */
157 iq2000_core_signal (SIM_DESC sd, SIM_CPU *current_cpu, sim_cia cia,
158 unsigned int map, int nr_bytes, address_word addr,
159 transfer_type transfer, sim_core_signals sig)
161 sim_core_signal (sd, current_cpu, cia, map, nr_bytes, addr,
166 /* Initialize cycle counting for an insn.
167 FIRST_P is non-zero if this is the first insn in a set of parallel
171 iq2000bf_model_insn_before (SIM_CPU *cpu, int first_p)
177 /* Record the cycles computed for an insn.
178 LAST_P is non-zero if this is the last insn in a set of parallel insns,
179 and we update the total cycle count.
180 CYCLES is the cycle count of the insn. */
183 iq2000bf_model_insn_after(SIM_CPU *cpu, int last_p, int cycles)
190 iq2000bf_model_iq2000_u_exec (SIM_CPU *cpu, const IDESC *idesc,
191 int unit_num, int referenced)
193 return idesc->timing->units[unit_num].done;
197 get_h_pc (SIM_CPU *cpu)
199 return CPU_CGEN_HW(cpu)->h_pc;
203 set_h_pc (SIM_CPU *cpu, PCADDR addr)
205 CPU_CGEN_HW(cpu)->h_pc = addr | IQ2000_INSN_MASK;
209 iq2000bf_fetch_register (SIM_CPU *cpu, int nr, void *buf, int len)
211 if (nr >= GPR0_REGNUM
212 && nr < (GPR0_REGNUM + NR_GPR)
216 H2T_4 (iq2000bf_h_gr_get (cpu, nr - GPR0_REGNUM));
219 else if (nr == PC_REGNUM
222 *((uint32_t*)buf) = H2T_4 (get_h_pc (cpu));
230 iq2000bf_store_register (SIM_CPU *cpu, int nr, const void *buf, int len)
232 if (nr >= GPR0_REGNUM
233 && nr < (GPR0_REGNUM + NR_GPR)
236 iq2000bf_h_gr_set (cpu, nr - GPR0_REGNUM, T2H_4 (*((uint32_t*)buf)));
239 else if (nr == PC_REGNUM
242 set_h_pc (cpu, T2H_4 (*((uint32_t*)buf)));