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