1 /* IQ2000 simulator support code
2 Copyright (C) 2000, 2004 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 2, or (at your option)
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 along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22 #define WANT_CPU_IQ2000BF
54 SYS_gettimeofday = 19,
58 /* Read a null terminated string from memory, return in a buffer */
60 fetch_str (current_cpu, pc, addr)
67 while (sim_core_read_1 (current_cpu,
68 pc, read_map, CPU2DATA(addr + nr)) != 0)
70 buf = NZALLOC (char, nr + 1);
71 sim_read (CPU_STATE (current_cpu), CPU2DATA(addr), buf, nr);
76 do_syscall (SIM_CPU *current_cpu, PCADDR pc)
79 int syscall = H2T_4 (iq2000bf_h_gr_get (current_cpu, 11));
81 int syscall_function = iq2000bf_h_gr_get (current_cpu, 4);
84 int PARM1 = iq2000bf_h_gr_get (current_cpu, 5);
85 int PARM2 = iq2000bf_h_gr_get (current_cpu, 6);
86 int PARM3 = iq2000bf_h_gr_get (current_cpu, 7);
87 const int ret_reg = 2;
89 switch (syscall_function)
92 switch (H2T_4 (iq2000bf_h_gr_get (current_cpu, 11)))
105 buf = zalloc (PARM3);
106 sim_read (CPU_STATE (current_cpu), CPU2DATA(PARM2), buf, PARM3);
108 sim_io_write (CPU_STATE (current_cpu),
115 sim_io_lseek (CPU_STATE (current_cpu),
116 PARM1, PARM2, PARM3));
120 sim_engine_halt (CPU_STATE (current_cpu), current_cpu,
121 NULL, pc, sim_exited, PARM1);
125 buf = zalloc (PARM3);
127 sim_io_read (CPU_STATE (current_cpu),
129 sim_write (CPU_STATE (current_cpu), CPU2DATA(PARM2), buf, PARM3);
134 buf = fetch_str (current_cpu, pc, PARM1);
136 sim_io_open (CPU_STATE (current_cpu),
143 sim_io_close (CPU_STATE (current_cpu), PARM1));
147 SET_H_GR (ret_reg, time (0));
151 SET_H_GR (ret_reg, -1);
156 do_break (SIM_CPU *current_cpu, PCADDR pc)
158 SIM_DESC sd = CPU_STATE (current_cpu);
159 sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
162 /* The semantic code invokes this for invalid (unrecognized) instructions. */
165 sim_engine_invalid_insn (SIM_CPU *current_cpu, IADDR cia, SEM_PC vpc)
167 SIM_DESC sd = CPU_STATE (current_cpu);
168 sim_engine_halt (sd, current_cpu, NULL, cia, sim_stopped, SIM_SIGILL);
174 /* Process an address exception. */
177 iq2000_core_signal (SIM_DESC sd, SIM_CPU *current_cpu, sim_cia cia,
178 unsigned int map, int nr_bytes, address_word addr,
179 transfer_type transfer, sim_core_signals sig)
181 sim_core_signal (sd, current_cpu, cia, map, nr_bytes, addr,
186 /* Initialize cycle counting for an insn.
187 FIRST_P is non-zero if this is the first insn in a set of parallel
191 iq2000bf_model_insn_before (SIM_CPU *cpu, int first_p)
197 /* Record the cycles computed for an insn.
198 LAST_P is non-zero if this is the last insn in a set of parallel insns,
199 and we update the total cycle count.
200 CYCLES is the cycle count of the insn. */
203 iq2000bf_model_insn_after(SIM_CPU *cpu, int last_p, int cycles)
210 iq2000bf_model_iq2000_u_exec (SIM_CPU *cpu, const IDESC *idesc,
211 int unit_num, int referenced)
213 return idesc->timing->units[unit_num].done;
217 get_h_pc (SIM_CPU *cpu)
219 return CPU_CGEN_HW(cpu)->h_pc;
223 set_h_pc (SIM_CPU *cpu, PCADDR addr)
225 CPU_CGEN_HW(cpu)->h_pc = addr | IQ2000_INSN_MASK;
229 iq2000bf_fetch_register (SIM_CPU *cpu, int nr, unsigned char *buf, int len)
231 if (nr >= GPR0_REGNUM
232 && nr < (GPR0_REGNUM + NR_GPR)
235 *((unsigned32*)buf) =
236 H2T_4 (iq2000bf_h_gr_get (cpu, nr - GPR0_REGNUM));
239 else if (nr == PC_REGNUM
242 *((unsigned32*)buf) = H2T_4 (get_h_pc (cpu));
250 iq2000bf_store_register (SIM_CPU *cpu, int nr, unsigned char *buf, int len)
252 if (nr >= GPR0_REGNUM
253 && nr < (GPR0_REGNUM + NR_GPR)
256 iq2000bf_h_gr_set (cpu, nr - GPR0_REGNUM, T2H_4 (*((unsigned32*)buf)));
259 else if (nr == PC_REGNUM
262 set_h_pc (cpu, T2H_4 (*((unsigned32*)buf)));