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