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