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. */
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);
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
)
70 switch (H2T_4 (iq2000bf_h_gr_get (current_cpu
, 11)))
81 puts ("unknown exit");
85 case TARGET_NEWLIB_SYS_write
:
87 sim_read (CPU_STATE (current_cpu
), CPU2DATA(PARM2
), buf
, PARM3
);
89 sim_io_write (CPU_STATE (current_cpu
),
94 case TARGET_NEWLIB_SYS_lseek
:
96 sim_io_lseek (CPU_STATE (current_cpu
),
97 PARM1
, PARM2
, PARM3
));
100 case TARGET_NEWLIB_SYS_exit
:
101 sim_engine_halt (CPU_STATE (current_cpu
), current_cpu
,
102 NULL
, pc
, sim_exited
, PARM1
);
105 case TARGET_NEWLIB_SYS_read
:
106 buf
= zalloc (PARM3
);
108 sim_io_read (CPU_STATE (current_cpu
),
110 sim_write (CPU_STATE (current_cpu
), CPU2DATA(PARM2
),
111 (unsigned char *) buf
, PARM3
);
115 case TARGET_NEWLIB_SYS_open
:
116 buf
= fetch_str (current_cpu
, pc
, PARM1
);
118 sim_io_open (CPU_STATE (current_cpu
),
123 case TARGET_NEWLIB_SYS_close
:
125 sim_io_close (CPU_STATE (current_cpu
), PARM1
));
128 case TARGET_NEWLIB_SYS_time
:
129 SET_H_GR (ret_reg
, time (0));
133 SET_H_GR (ret_reg
, -1);
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. */
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
);
156 /* Process an address exception. */
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
,
168 /* Initialize cycle counting for an insn.
169 FIRST_P is non-zero if this is the first insn in a set of parallel
173 iq2000bf_model_insn_before (SIM_CPU
*cpu
, int first_p
)
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. */
185 iq2000bf_model_insn_after(SIM_CPU
*cpu
, int last_p
, int cycles
)
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
;
199 get_h_pc (SIM_CPU
*cpu
)
201 return CPU_CGEN_HW(cpu
)->h_pc
;
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
)
218 H2T_4 (iq2000bf_h_gr_get (cpu
, nr
- GPR0_REGNUM
));
221 else if (nr
== PC_REGNUM
224 *((uint32_t*)buf
) = H2T_4 (get_h_pc (cpu
));
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
)
238 iq2000bf_h_gr_set (cpu
, nr
- GPR0_REGNUM
, T2H_4 (*((uint32_t*)buf
)));
241 else if (nr
== PC_REGNUM
244 set_h_pc (cpu
, T2H_4 (*((uint32_t*)buf
)));