]> Git Repo - binutils.git/blob - sim/iq2000/iq2000.c
Automatic date update in version.in
[binutils.git] / sim / iq2000 / iq2000.c
1 /* IQ2000 simulator support code
2    Copyright (C) 2000-2022 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 "target-newlib-syscall.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_NEWLIB_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_NEWLIB_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_NEWLIB_SYS_exit:
99       sim_engine_halt (CPU_STATE (current_cpu), current_cpu,
100                        NULL, pc, sim_exited, PARM1);
101       break;
102
103     case TARGET_NEWLIB_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),
109                  (unsigned char *) buf, PARM3);
110       free (buf);
111       break;
112             
113     case TARGET_NEWLIB_SYS_open:
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));
118       free (buf);
119       break;
120
121     case TARGET_NEWLIB_SYS_close:
122       SET_H_GR (ret_reg,
123                 sim_io_close (CPU_STATE (current_cpu), PARM1));
124       break;
125
126     case TARGET_NEWLIB_SYS_time:
127       SET_H_GR (ret_reg, time (0));
128       break;
129
130     default:
131       SET_H_GR (ret_reg, -1);
132     }
133 }
134
135 void 
136 do_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
144 SEM_PC
145 sim_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
156 void
157 iq2000_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
170 void
171 iq2000bf_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
182 void
183 iq2000bf_model_insn_after(SIM_CPU *cpu, int last_p, int cycles)
184 {
185   /* Do nothing.  */
186 }
187
188
189 int
190 iq2000bf_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
196 PCADDR
197 get_h_pc (SIM_CPU *cpu)
198 {
199   return CPU_CGEN_HW(cpu)->h_pc;
200 }
201
202 void
203 set_h_pc (SIM_CPU *cpu, PCADDR addr)
204 {
205   CPU_CGEN_HW(cpu)->h_pc = addr | IQ2000_INSN_MASK;
206 }
207
208 int
209 iq2000bf_fetch_register (SIM_CPU *cpu, int nr, void *buf, int len)
210 {
211   if (nr >= GPR0_REGNUM
212       && nr < (GPR0_REGNUM + NR_GPR)
213       && len == 4)
214     {
215       *((uint32_t*)buf) =
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     {
222       *((uint32_t*)buf) = H2T_4 (get_h_pc (cpu));
223       return 4;
224     }
225   else
226     return 0;
227 }
228
229 int
230 iq2000bf_store_register (SIM_CPU *cpu, int nr, const void *buf, int len)
231 {
232   if (nr >= GPR0_REGNUM
233       && nr < (GPR0_REGNUM + NR_GPR)
234       && len == 4)
235     {
236       iq2000bf_h_gr_set (cpu, nr - GPR0_REGNUM, T2H_4 (*((uint32_t*)buf)));
237       return 4;
238     }
239   else if (nr == PC_REGNUM
240            && len == 4)
241     {
242       set_h_pc (cpu, T2H_4 (*((uint32_t*)buf)));
243       return 4;
244     }
245   else
246     return 0;
247 }
This page took 0.036557 seconds and 4 git commands to generate.