]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/iq2000/iq2000.c
sim: change to 64bit time keeping to avoid 32bit overflows
[thirdparty/binutils-gdb.git] / sim / iq2000 / iq2000.c
CommitLineData
edece237 1/* IQ2000 simulator support code
7b6bb8da 2 Copyright (C) 2000, 2004, 2007, 2008, 2009, 2010, 2011
dc3cf14f 3 Free Software Foundation, Inc.
edece237
CV
4 Contributed by Cygnus Support.
5
6 This file is part of the GNU simulators.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
4744ac1b
JB
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
edece237
CV
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
4744ac1b
JB
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
edece237
CV
20
21#define WANT_CPU
22#define WANT_CPU_IQ2000BF
23
24#include "sim-main.h"
25#include "cgen-mem.h"
26#include "cgen-ops.h"
27
28enum
29{
30 GPR0_REGNUM = 0,
31 NR_GPR = 32,
32 PC_REGNUM = 32
33};
34
35enum libgloss_syscall
36{
37 SYS_exit = 1,
38 SYS_open = 2,
39 SYS_close = 3,
40 SYS_read = 4,
41 SYS_write = 5,
42 SYS_lseek = 6,
43 SYS_unlink = 7,
44 SYS_getpid = 8,
45 SYS_kill = 9,
46 SYS_fstat = 10,
47 SYS_argvlen = 12,
48 SYS_argv = 13,
49 SYS_chdir = 14,
50 SYS_stat = 15,
51 SYS_chmod = 16,
52 SYS_utime = 17,
53 SYS_time = 18,
54 SYS_gettimeofday = 19,
55 SYS_times = 20
56};
57
58/* Read a null terminated string from memory, return in a buffer */
59static char *
60fetch_str (current_cpu, pc, addr)
61 SIM_CPU *current_cpu;
62 PCADDR pc;
63 DI addr;
64{
65 char *buf;
66 int nr = 0;
67 while (sim_core_read_1 (current_cpu,
68 pc, read_map, CPU2DATA(addr + nr)) != 0)
69 nr++;
70 buf = NZALLOC (char, nr + 1);
71 sim_read (CPU_STATE (current_cpu), CPU2DATA(addr), buf, nr);
72 return buf;
73}
74
75void
76do_syscall (SIM_CPU *current_cpu, PCADDR pc)
77{
78#if 0
79 int syscall = H2T_4 (iq2000bf_h_gr_get (current_cpu, 11));
80#endif
81 int syscall_function = iq2000bf_h_gr_get (current_cpu, 4);
82 int i;
83 char *buf;
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;
88
89 switch (syscall_function)
90 {
91 case 0:
92 switch (H2T_4 (iq2000bf_h_gr_get (current_cpu, 11)))
93 {
94 case 0:
95 /* Pass. */
96 puts ("pass");
97 exit (0);
98 case 1:
99 /* Fail. */
100 puts ("fail");
101 exit (1);
102 }
103
104 case SYS_write:
105 buf = zalloc (PARM3);
106 sim_read (CPU_STATE (current_cpu), CPU2DATA(PARM2), buf, PARM3);
107 SET_H_GR (ret_reg,
108 sim_io_write (CPU_STATE (current_cpu),
109 PARM1, buf, PARM3));
110 zfree (buf);
111 break;
112
113 case SYS_lseek:
114 SET_H_GR (ret_reg,
115 sim_io_lseek (CPU_STATE (current_cpu),
116 PARM1, PARM2, PARM3));
117 break;
118
119 case SYS_exit:
120 sim_engine_halt (CPU_STATE (current_cpu), current_cpu,
121 NULL, pc, sim_exited, PARM1);
122 break;
123
124 case SYS_read:
125 buf = zalloc (PARM3);
126 SET_H_GR (ret_reg,
127 sim_io_read (CPU_STATE (current_cpu),
128 PARM1, buf, PARM3));
129 sim_write (CPU_STATE (current_cpu), CPU2DATA(PARM2), buf, PARM3);
130 zfree (buf);
131 break;
132
133 case SYS_open:
134 buf = fetch_str (current_cpu, pc, PARM1);
135 SET_H_GR (ret_reg,
136 sim_io_open (CPU_STATE (current_cpu),
137 buf, PARM2));
138 zfree (buf);
139 break;
140
141 case SYS_close:
142 SET_H_GR (ret_reg,
143 sim_io_close (CPU_STATE (current_cpu), PARM1));
144 break;
145
146 case SYS_time:
147 SET_H_GR (ret_reg, time (0));
148 break;
149
150 default:
151 SET_H_GR (ret_reg, -1);
152 }
153}
154
155void
156do_break (SIM_CPU *current_cpu, PCADDR pc)
157{
158 SIM_DESC sd = CPU_STATE (current_cpu);
159 sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
160}
161
162/* The semantic code invokes this for invalid (unrecognized) instructions. */
163
164SEM_PC
165sim_engine_invalid_insn (SIM_CPU *current_cpu, IADDR cia, SEM_PC vpc)
166{
167 SIM_DESC sd = CPU_STATE (current_cpu);
168 sim_engine_halt (sd, current_cpu, NULL, cia, sim_stopped, SIM_SIGILL);
169
170 return vpc;
171}
172
173
174/* Process an address exception. */
175
176void
177iq2000_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)
180{
181 sim_core_signal (sd, current_cpu, cia, map, nr_bytes, addr,
182 transfer, sig);
183}
184
185
186/* Initialize cycle counting for an insn.
187 FIRST_P is non-zero if this is the first insn in a set of parallel
188 insns. */
189
190void
191iq2000bf_model_insn_before (SIM_CPU *cpu, int first_p)
192{
193 /* Do nothing. */
194}
195
196
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. */
201
202void
203iq2000bf_model_insn_after(SIM_CPU *cpu, int last_p, int cycles)
204{
205 /* Do nothing. */
206}
207
208
209int
210iq2000bf_model_iq2000_u_exec (SIM_CPU *cpu, const IDESC *idesc,
211 int unit_num, int referenced)
212{
213 return idesc->timing->units[unit_num].done;
214}
215
216PCADDR
217get_h_pc (SIM_CPU *cpu)
218{
219 return CPU_CGEN_HW(cpu)->h_pc;
220}
221
222void
223set_h_pc (SIM_CPU *cpu, PCADDR addr)
224{
225 CPU_CGEN_HW(cpu)->h_pc = addr | IQ2000_INSN_MASK;
226}
227
228int
229iq2000bf_fetch_register (SIM_CPU *cpu, int nr, unsigned char *buf, int len)
230{
231 if (nr >= GPR0_REGNUM
232 && nr < (GPR0_REGNUM + NR_GPR)
233 && len == 4)
234 {
235 *((unsigned32*)buf) =
236 H2T_4 (iq2000bf_h_gr_get (cpu, nr - GPR0_REGNUM));
237 return 4;
238 }
239 else if (nr == PC_REGNUM
240 && len == 4)
241 {
242 *((unsigned32*)buf) = H2T_4 (get_h_pc (cpu));
243 return 4;
244 }
245 else
246 return 0;
247}
248
249int
250iq2000bf_store_register (SIM_CPU *cpu, int nr, unsigned char *buf, int len)
251{
252 if (nr >= GPR0_REGNUM
253 && nr < (GPR0_REGNUM + NR_GPR)
254 && len == 4)
255 {
256 iq2000bf_h_gr_set (cpu, nr - GPR0_REGNUM, T2H_4 (*((unsigned32*)buf)));
257 return 4;
258 }
259 else if (nr == PC_REGNUM
260 && len == 4)
261 {
262 set_h_pc (cpu, T2H_4 (*((unsigned32*)buf)));
263 return 4;
264 }
265 else
266 return 0;
267}