sim: split sim-signal.h include out
[deliverable/binutils-gdb.git] / sim / iq2000 / iq2000.c
CommitLineData
edece237 1/* IQ2000 simulator support code
3666a048 2 Copyright (C) 2000-2021 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"
2390d779 30#include "targ-vals.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);
50 sim_read (CPU_STATE (current_cpu), CPU2DATA(addr), buf, nr);
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
2390d779 83 case TARGET_SYS_write:
edece237
CV
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));
d79fe0d6 89 free (buf);
edece237
CV
90 break;
91
2390d779 92 case TARGET_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
2390d779 98 case TARGET_SYS_exit:
edece237
CV
99 sim_engine_halt (CPU_STATE (current_cpu), current_cpu,
100 NULL, pc, sim_exited, PARM1);
101 break;
102
2390d779 103 case TARGET_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));
108 sim_write (CPU_STATE (current_cpu), CPU2DATA(PARM2), buf, PARM3);
d79fe0d6 109 free (buf);
edece237
CV
110 break;
111
2390d779 112 case TARGET_SYS_open:
edece237
CV
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));
d79fe0d6 117 free (buf);
edece237
CV
118 break;
119
2390d779 120 case TARGET_SYS_close:
edece237
CV
121 SET_H_GR (ret_reg,
122 sim_io_close (CPU_STATE (current_cpu), PARM1));
123 break;
124
2390d779 125 case TARGET_SYS_time:
edece237
CV
126 SET_H_GR (ret_reg, time (0));
127 break;
128
129 default:
130 SET_H_GR (ret_reg, -1);
131 }
132}
133
134void
135do_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
143SEM_PC
144sim_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
155void
156iq2000_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
169void
170iq2000bf_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
181void
182iq2000bf_model_insn_after(SIM_CPU *cpu, int last_p, int cycles)
183{
184 /* Do nothing. */
185}
186
187
188int
189iq2000bf_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
195PCADDR
196get_h_pc (SIM_CPU *cpu)
197{
198 return CPU_CGEN_HW(cpu)->h_pc;
199}
200
201void
202set_h_pc (SIM_CPU *cpu, PCADDR addr)
203{
204 CPU_CGEN_HW(cpu)->h_pc = addr | IQ2000_INSN_MASK;
205}
206
207int
208iq2000bf_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
228int
229iq2000bf_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.737144 seconds and 4 git commands to generate.