sim: overhaul alignment settings management
[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"
27#include "cgen-mem.h"
28#include "cgen-ops.h"
2390d779 29#include "targ-vals.h"
32a046ab 30#include <stdlib.h>
edece237
CV
31
32enum
33{
34 GPR0_REGNUM = 0,
35 NR_GPR = 32,
36 PC_REGNUM = 32
37};
38
edece237
CV
39/* Read a null terminated string from memory, return in a buffer */
40static char *
81e6e8ae 41fetch_str (SIM_CPU *current_cpu, PCADDR pc, DI addr)
edece237
CV
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
53void
54do_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
2390d779 82 case TARGET_SYS_write:
edece237
CV
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));
d79fe0d6 88 free (buf);
edece237
CV
89 break;
90
2390d779 91 case TARGET_SYS_lseek:
edece237
CV
92 SET_H_GR (ret_reg,
93 sim_io_lseek (CPU_STATE (current_cpu),
94 PARM1, PARM2, PARM3));
95 break;
96
2390d779 97 case TARGET_SYS_exit:
edece237
CV
98 sim_engine_halt (CPU_STATE (current_cpu), current_cpu,
99 NULL, pc, sim_exited, PARM1);
100 break;
101
2390d779 102 case TARGET_SYS_read:
edece237
CV
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);
d79fe0d6 108 free (buf);
edece237
CV
109 break;
110
2390d779 111 case TARGET_SYS_open:
edece237
CV
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));
d79fe0d6 116 free (buf);
edece237
CV
117 break;
118
2390d779 119 case TARGET_SYS_close:
edece237
CV
120 SET_H_GR (ret_reg,
121 sim_io_close (CPU_STATE (current_cpu), PARM1));
122 break;
123
2390d779 124 case TARGET_SYS_time:
edece237
CV
125 SET_H_GR (ret_reg, time (0));
126 break;
127
128 default:
129 SET_H_GR (ret_reg, -1);
130 }
131}
132
133void
134do_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
142SEM_PC
143sim_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
154void
155iq2000_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
168void
169iq2000bf_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
180void
181iq2000bf_model_insn_after(SIM_CPU *cpu, int last_p, int cycles)
182{
183 /* Do nothing. */
184}
185
186
187int
188iq2000bf_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
194PCADDR
195get_h_pc (SIM_CPU *cpu)
196{
197 return CPU_CGEN_HW(cpu)->h_pc;
198}
199
200void
201set_h_pc (SIM_CPU *cpu, PCADDR addr)
202{
203 CPU_CGEN_HW(cpu)->h_pc = addr | IQ2000_INSN_MASK;
204}
205
206int
207iq2000bf_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
227int
228iq2000bf_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}
This page took 1.079483 seconds and 4 git commands to generate.