]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/iq2000/iq2000.c
sim: common: change sim_{fetch,store}_register helpers to use void* buffers
[thirdparty/binutils-gdb.git] / sim / iq2000 / iq2000.c
CommitLineData
edece237 1/* IQ2000 simulator support code
4a94e368 2 Copyright (C) 2000-2022 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 19
6df01ab8
MF
20/* This must come before any other includes. */
21#include "defs.h"
22
edece237
CV
23#define WANT_CPU
24#define WANT_CPU_IQ2000BF
25
26#include "sim-main.h"
1fef66b0 27#include "sim-signal.h"
edece237
CV
28#include "cgen-mem.h"
29#include "cgen-ops.h"
e38330f8 30#include "target-newlib-syscall.h"
32a046ab 31#include <stdlib.h>
edece237
CV
32
33enum
34{
35 GPR0_REGNUM = 0,
36 NR_GPR = 32,
37 PC_REGNUM = 32
38};
39
edece237
CV
40/* Read a null terminated string from memory, return in a buffer */
41static char *
81e6e8ae 42fetch_str (SIM_CPU *current_cpu, PCADDR pc, DI addr)
edece237
CV
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);
5b94c380 50 sim_read (CPU_STATE (current_cpu), CPU2DATA(addr), buf, nr);
edece237
CV
51 return buf;
52}
53
54void
55do_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
e38330f8 83 case TARGET_NEWLIB_SYS_write:
edece237 84 buf = zalloc (PARM3);
5b94c380 85 sim_read (CPU_STATE (current_cpu), CPU2DATA(PARM2), buf, PARM3);
edece237
CV
86 SET_H_GR (ret_reg,
87 sim_io_write (CPU_STATE (current_cpu),
88 PARM1, buf, PARM3));
d79fe0d6 89 free (buf);
edece237
CV
90 break;
91
e38330f8 92 case TARGET_NEWLIB_SYS_lseek:
edece237
CV
93 SET_H_GR (ret_reg,
94 sim_io_lseek (CPU_STATE (current_cpu),
95 PARM1, PARM2, PARM3));
96 break;
97
e38330f8 98 case TARGET_NEWLIB_SYS_exit:
edece237
CV
99 sim_engine_halt (CPU_STATE (current_cpu), current_cpu,
100 NULL, pc, sim_exited, PARM1);
101 break;
102
e38330f8 103 case TARGET_NEWLIB_SYS_read:
edece237
CV
104 buf = zalloc (PARM3);
105 SET_H_GR (ret_reg,
106 sim_io_read (CPU_STATE (current_cpu),
107 PARM1, buf, PARM3));
feab6abf
AB
108 sim_write (CPU_STATE (current_cpu), CPU2DATA(PARM2),
109 (unsigned char *) buf, PARM3);
d79fe0d6 110 free (buf);
edece237
CV
111 break;
112
e38330f8 113 case TARGET_NEWLIB_SYS_open:
edece237
CV
114 buf = fetch_str (current_cpu, pc, PARM1);
115 SET_H_GR (ret_reg,
116 sim_io_open (CPU_STATE (current_cpu),
117 buf, PARM2));
d79fe0d6 118 free (buf);
edece237
CV
119 break;
120
e38330f8 121 case TARGET_NEWLIB_SYS_close:
edece237
CV
122 SET_H_GR (ret_reg,
123 sim_io_close (CPU_STATE (current_cpu), PARM1));
124 break;
125
e38330f8 126 case TARGET_NEWLIB_SYS_time:
edece237
CV
127 SET_H_GR (ret_reg, time (0));
128 break;
129
130 default:
131 SET_H_GR (ret_reg, -1);
132 }
133}
134
135void
136do_break (SIM_CPU *current_cpu, PCADDR pc)
137{
138 SIM_DESC sd = CPU_STATE (current_cpu);
139 sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
140}
141
142/* The semantic code invokes this for invalid (unrecognized) instructions. */
143
144SEM_PC
145sim_engine_invalid_insn (SIM_CPU *current_cpu, IADDR cia, SEM_PC vpc)
146{
147 SIM_DESC sd = CPU_STATE (current_cpu);
148 sim_engine_halt (sd, current_cpu, NULL, cia, sim_stopped, SIM_SIGILL);
149
150 return vpc;
151}
152
153
154/* Process an address exception. */
155
156void
157iq2000_core_signal (SIM_DESC sd, SIM_CPU *current_cpu, sim_cia cia,
158 unsigned int map, int nr_bytes, address_word addr,
159 transfer_type transfer, sim_core_signals sig)
160{
161 sim_core_signal (sd, current_cpu, cia, map, nr_bytes, addr,
162 transfer, sig);
163}
164
165
166/* Initialize cycle counting for an insn.
167 FIRST_P is non-zero if this is the first insn in a set of parallel
168 insns. */
169
170void
171iq2000bf_model_insn_before (SIM_CPU *cpu, int first_p)
172{
173 /* Do nothing. */
174}
175
176
177/* Record the cycles computed for an insn.
178 LAST_P is non-zero if this is the last insn in a set of parallel insns,
179 and we update the total cycle count.
180 CYCLES is the cycle count of the insn. */
181
182void
183iq2000bf_model_insn_after(SIM_CPU *cpu, int last_p, int cycles)
184{
185 /* Do nothing. */
186}
187
188
189int
190iq2000bf_model_iq2000_u_exec (SIM_CPU *cpu, const IDESC *idesc,
191 int unit_num, int referenced)
192{
193 return idesc->timing->units[unit_num].done;
194}
195
196PCADDR
197get_h_pc (SIM_CPU *cpu)
198{
199 return CPU_CGEN_HW(cpu)->h_pc;
200}
201
202void
203set_h_pc (SIM_CPU *cpu, PCADDR addr)
204{
205 CPU_CGEN_HW(cpu)->h_pc = addr | IQ2000_INSN_MASK;
206}
207
208int
ee1cffd3 209iq2000bf_fetch_register (SIM_CPU *cpu, int nr, void *buf, int len)
edece237
CV
210{
211 if (nr >= GPR0_REGNUM
212 && nr < (GPR0_REGNUM + NR_GPR)
213 && len == 4)
214 {
1e1e987a 215 *((uint32_t*)buf) =
edece237
CV
216 H2T_4 (iq2000bf_h_gr_get (cpu, nr - GPR0_REGNUM));
217 return 4;
218 }
219 else if (nr == PC_REGNUM
220 && len == 4)
221 {
1e1e987a 222 *((uint32_t*)buf) = H2T_4 (get_h_pc (cpu));
edece237
CV
223 return 4;
224 }
225 else
226 return 0;
227}
228
229int
ee1cffd3 230iq2000bf_store_register (SIM_CPU *cpu, int nr, const void *buf, int len)
edece237
CV
231{
232 if (nr >= GPR0_REGNUM
233 && nr < (GPR0_REGNUM + NR_GPR)
234 && len == 4)
235 {
1e1e987a 236 iq2000bf_h_gr_set (cpu, nr - GPR0_REGNUM, T2H_4 (*((uint32_t*)buf)));
edece237
CV
237 return 4;
238 }
239 else if (nr == PC_REGNUM
240 && len == 4)
241 {
1e1e987a 242 set_h_pc (cpu, T2H_4 (*((uint32_t*)buf)));
edece237
CV
243 return 4;
244 }
245 else
246 return 0;
247}