interp.c revision 1.1.1.7 1 1.1 christos /* Simulator for the moxie processor
2 1.1.1.7 christos Copyright (C) 2008-2020 Free Software Foundation, Inc.
3 1.1 christos Contributed by Anthony Green
4 1.1 christos
5 1.1 christos This file is part of GDB, the GNU debugger.
6 1.1 christos
7 1.1 christos This program is free software; you can redistribute it and/or modify
8 1.1 christos it under the terms of the GNU General Public License as published by
9 1.1 christos the Free Software Foundation; either version 3 of the License, or
10 1.1 christos (at your option) any later version.
11 1.1 christos
12 1.1 christos This program is distributed in the hope that it will be useful,
13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 1.1 christos GNU General Public License for more details.
16 1.1 christos
17 1.1 christos You should have received a copy of the GNU General Public License
18 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 1.1 christos
20 1.1 christos #include "config.h"
21 1.1 christos #include <fcntl.h>
22 1.1 christos #include <signal.h>
23 1.1 christos #include <stdlib.h>
24 1.1.1.3 christos #include <string.h>
25 1.1 christos #include <sys/times.h>
26 1.1 christos #include <sys/param.h>
27 1.1.1.3 christos #include <unistd.h>
28 1.1 christos #include "bfd.h"
29 1.1 christos #include "libiberty.h"
30 1.1 christos #include "gdb/remote-sim.h"
31 1.1 christos
32 1.1 christos #include "sim-main.h"
33 1.1 christos #include "sim-base.h"
34 1.1.1.3 christos #include "sim-options.h"
35 1.1.1.7 christos #include "sim-io.h"
36 1.1 christos
37 1.1 christos typedef int word;
38 1.1 christos typedef unsigned int uword;
39 1.1 christos
40 1.1 christos /* Extract the signed 10-bit offset from a 16-bit branch
41 1.1 christos instruction. */
42 1.1 christos #define INST2OFFSET(o) ((((signed short)((o & ((1<<10)-1))<<6))>>6)<<1)
43 1.1 christos
44 1.1 christos #define EXTRACT_WORD(addr) \
45 1.1 christos ((sim_core_read_aligned_1 (scpu, cia, read_map, addr) << 24) \
46 1.1 christos + (sim_core_read_aligned_1 (scpu, cia, read_map, addr+1) << 16) \
47 1.1 christos + (sim_core_read_aligned_1 (scpu, cia, read_map, addr+2) << 8) \
48 1.1 christos + (sim_core_read_aligned_1 (scpu, cia, read_map, addr+3)))
49 1.1 christos
50 1.1.1.2 christos #define EXTRACT_OFFSET(addr) \
51 1.1.1.2 christos (unsigned int) \
52 1.1.1.2 christos (((signed short) \
53 1.1.1.2 christos ((sim_core_read_aligned_1 (scpu, cia, read_map, addr) << 8) \
54 1.1.1.2 christos + (sim_core_read_aligned_1 (scpu, cia, read_map, addr+1))) << 16) >> 16)
55 1.1.1.2 christos
56 1.1.1.3 christos static unsigned long
57 1.1.1.3 christos moxie_extract_unsigned_integer (unsigned char *addr, int len)
58 1.1 christos {
59 1.1 christos unsigned long retval;
60 1.1 christos unsigned char * p;
61 1.1 christos unsigned char * startaddr = (unsigned char *)addr;
62 1.1 christos unsigned char * endaddr = startaddr + len;
63 1.1 christos
64 1.1 christos if (len > (int) sizeof (unsigned long))
65 1.1.1.3 christos printf ("That operation is not available on integers of more than %zu bytes.",
66 1.1 christos sizeof (unsigned long));
67 1.1 christos
68 1.1 christos /* Start at the most significant end of the integer, and work towards
69 1.1 christos the least significant. */
70 1.1 christos retval = 0;
71 1.1 christos
72 1.1 christos for (p = endaddr; p > startaddr;)
73 1.1 christos retval = (retval << 8) | * -- p;
74 1.1 christos
75 1.1 christos return retval;
76 1.1 christos }
77 1.1 christos
78 1.1.1.3 christos static void
79 1.1.1.3 christos moxie_store_unsigned_integer (unsigned char *addr, int len, unsigned long val)
80 1.1 christos {
81 1.1 christos unsigned char * p;
82 1.1 christos unsigned char * startaddr = (unsigned char *)addr;
83 1.1 christos unsigned char * endaddr = startaddr + len;
84 1.1 christos
85 1.1 christos for (p = endaddr; p > startaddr;)
86 1.1 christos {
87 1.1 christos * -- p = val & 0xff;
88 1.1 christos val >>= 8;
89 1.1 christos }
90 1.1 christos }
91 1.1 christos
92 1.1 christos /* moxie register names. */
93 1.1 christos static const char *reg_names[16] =
94 1.1 christos { "$fp", "$sp", "$r0", "$r1", "$r2", "$r3", "$r4", "$r5",
95 1.1 christos "$r6", "$r7", "$r8", "$r9", "$r10", "$r11", "$r12", "$r13" };
96 1.1 christos
97 1.1 christos /* The machine state.
98 1.1 christos
99 1.1 christos This state is maintained in host byte order. The fetch/store
100 1.1 christos register functions must translate between host byte order and the
101 1.1 christos target processor byte order. Keeping this data in target byte
102 1.1 christos order simplifies the register read/write functions. Keeping this
103 1.1 christos data in native order improves the performance of the simulator.
104 1.1 christos Simulation speed is deemed more important. */
105 1.1 christos
106 1.1 christos #define NUM_MOXIE_REGS 17 /* Including PC */
107 1.1 christos #define NUM_MOXIE_SREGS 256 /* The special registers */
108 1.1 christos #define PC_REGNO 16
109 1.1 christos
110 1.1 christos /* The ordering of the moxie_regset structure is matched in the
111 1.1 christos gdb/config/moxie/tm-moxie.h file in the REGISTER_NAMES macro. */
112 1.1.1.3 christos /* TODO: This should be moved to sim-main.h:_sim_cpu. */
113 1.1 christos struct moxie_regset
114 1.1 christos {
115 1.1 christos word regs[NUM_MOXIE_REGS + 1]; /* primary registers */
116 1.1 christos word sregs[256]; /* special registers */
117 1.1 christos word cc; /* the condition code reg */
118 1.1 christos unsigned long long insts; /* instruction counter */
119 1.1 christos };
120 1.1 christos
121 1.1 christos #define CC_GT 1<<0
122 1.1 christos #define CC_LT 1<<1
123 1.1 christos #define CC_EQ 1<<2
124 1.1 christos #define CC_GTU 1<<3
125 1.1 christos #define CC_LTU 1<<4
126 1.1 christos
127 1.1.1.3 christos /* TODO: This should be moved to sim-main.h:_sim_cpu. */
128 1.1 christos union
129 1.1 christos {
130 1.1 christos struct moxie_regset asregs;
131 1.1 christos word asints [1]; /* but accessed larger... */
132 1.1 christos } cpu;
133 1.1 christos
134 1.1 christos static void
135 1.1.1.3 christos set_initial_gprs (void)
136 1.1 christos {
137 1.1 christos int i;
138 1.1 christos long space;
139 1.1 christos
140 1.1 christos /* Set up machine just out of reset. */
141 1.1 christos cpu.asregs.regs[PC_REGNO] = 0;
142 1.1 christos
143 1.1 christos /* Clean out the register contents. */
144 1.1 christos for (i = 0; i < NUM_MOXIE_REGS; i++)
145 1.1 christos cpu.asregs.regs[i] = 0;
146 1.1 christos for (i = 0; i < NUM_MOXIE_SREGS; i++)
147 1.1 christos cpu.asregs.sregs[i] = 0;
148 1.1 christos }
149 1.1 christos
150 1.1 christos /* Write a 1 byte value to memory. */
151 1.1 christos
152 1.1.1.3 christos static INLINE void
153 1.1 christos wbat (sim_cpu *scpu, word pc, word x, word v)
154 1.1 christos {
155 1.1.1.3 christos address_word cia = CPU_PC_GET (scpu);
156 1.1 christos
157 1.1 christos sim_core_write_aligned_1 (scpu, cia, write_map, x, v);
158 1.1 christos }
159 1.1 christos
160 1.1 christos /* Write a 2 byte value to memory. */
161 1.1 christos
162 1.1.1.3 christos static INLINE void
163 1.1 christos wsat (sim_cpu *scpu, word pc, word x, word v)
164 1.1 christos {
165 1.1.1.3 christos address_word cia = CPU_PC_GET (scpu);
166 1.1 christos
167 1.1 christos sim_core_write_aligned_2 (scpu, cia, write_map, x, v);
168 1.1 christos }
169 1.1 christos
170 1.1 christos /* Write a 4 byte value to memory. */
171 1.1 christos
172 1.1.1.3 christos static INLINE void
173 1.1 christos wlat (sim_cpu *scpu, word pc, word x, word v)
174 1.1 christos {
175 1.1.1.3 christos address_word cia = CPU_PC_GET (scpu);
176 1.1 christos
177 1.1 christos sim_core_write_aligned_4 (scpu, cia, write_map, x, v);
178 1.1 christos }
179 1.1 christos
180 1.1 christos /* Read 2 bytes from memory. */
181 1.1 christos
182 1.1.1.3 christos static INLINE int
183 1.1 christos rsat (sim_cpu *scpu, word pc, word x)
184 1.1 christos {
185 1.1.1.3 christos address_word cia = CPU_PC_GET (scpu);
186 1.1 christos
187 1.1 christos return (sim_core_read_aligned_2 (scpu, cia, read_map, x));
188 1.1 christos }
189 1.1 christos
190 1.1 christos /* Read 1 byte from memory. */
191 1.1 christos
192 1.1.1.3 christos static INLINE int
193 1.1 christos rbat (sim_cpu *scpu, word pc, word x)
194 1.1 christos {
195 1.1.1.3 christos address_word cia = CPU_PC_GET (scpu);
196 1.1 christos
197 1.1 christos return (sim_core_read_aligned_1 (scpu, cia, read_map, x));
198 1.1 christos }
199 1.1 christos
200 1.1 christos /* Read 4 bytes from memory. */
201 1.1 christos
202 1.1.1.3 christos static INLINE int
203 1.1 christos rlat (sim_cpu *scpu, word pc, word x)
204 1.1 christos {
205 1.1.1.3 christos address_word cia = CPU_PC_GET (scpu);
206 1.1 christos
207 1.1 christos return (sim_core_read_aligned_4 (scpu, cia, read_map, x));
208 1.1 christos }
209 1.1 christos
210 1.1 christos #define CHECK_FLAG(T,H) if (tflags & T) { hflags |= H; tflags ^= T; }
211 1.1 christos
212 1.1.1.3 christos static unsigned int
213 1.1 christos convert_target_flags (unsigned int tflags)
214 1.1 christos {
215 1.1 christos unsigned int hflags = 0x0;
216 1.1 christos
217 1.1 christos CHECK_FLAG(0x0001, O_WRONLY);
218 1.1 christos CHECK_FLAG(0x0002, O_RDWR);
219 1.1 christos CHECK_FLAG(0x0008, O_APPEND);
220 1.1 christos CHECK_FLAG(0x0200, O_CREAT);
221 1.1 christos CHECK_FLAG(0x0400, O_TRUNC);
222 1.1 christos CHECK_FLAG(0x0800, O_EXCL);
223 1.1 christos CHECK_FLAG(0x2000, O_SYNC);
224 1.1 christos
225 1.1 christos if (tflags != 0x0)
226 1.1 christos fprintf (stderr,
227 1.1 christos "Simulator Error: problem converting target open flags for host. 0x%x\n",
228 1.1 christos tflags);
229 1.1 christos
230 1.1 christos return hflags;
231 1.1 christos }
232 1.1 christos
233 1.1.1.3 christos /* TODO: Split this up into finger trace levels than just insn. */
234 1.1.1.3 christos #define MOXIE_TRACE_INSN(str) \
235 1.1.1.3 christos TRACE_INSN (scpu, "0x%08x, %s, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x", \
236 1.1.1.3 christos opc, str, cpu.asregs.regs[0], cpu.asregs.regs[1], \
237 1.1.1.3 christos cpu.asregs.regs[2], cpu.asregs.regs[3], cpu.asregs.regs[4], \
238 1.1.1.3 christos cpu.asregs.regs[5], cpu.asregs.regs[6], cpu.asregs.regs[7], \
239 1.1.1.3 christos cpu.asregs.regs[8], cpu.asregs.regs[9], cpu.asregs.regs[10], \
240 1.1.1.3 christos cpu.asregs.regs[11], cpu.asregs.regs[12], cpu.asregs.regs[13], \
241 1.1.1.3 christos cpu.asregs.regs[14], cpu.asregs.regs[15])
242 1.1 christos
243 1.1 christos void
244 1.1.1.3 christos sim_engine_run (SIM_DESC sd,
245 1.1.1.3 christos int next_cpu_nr, /* ignore */
246 1.1.1.3 christos int nr_cpus, /* ignore */
247 1.1.1.3 christos int siggnal) /* ignore */
248 1.1 christos {
249 1.1 christos word pc, opc;
250 1.1 christos unsigned short inst;
251 1.1 christos sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
252 1.1.1.3 christos address_word cia = CPU_PC_GET (scpu);
253 1.1 christos
254 1.1 christos pc = cpu.asregs.regs[PC_REGNO];
255 1.1 christos
256 1.1 christos /* Run instructions here. */
257 1.1 christos do
258 1.1 christos {
259 1.1 christos opc = pc;
260 1.1 christos
261 1.1 christos /* Fetch the instruction at pc. */
262 1.1 christos inst = (sim_core_read_aligned_1 (scpu, cia, read_map, pc) << 8)
263 1.1 christos + sim_core_read_aligned_1 (scpu, cia, read_map, pc+1);
264 1.1 christos
265 1.1 christos /* Decode instruction. */
266 1.1 christos if (inst & (1 << 15))
267 1.1 christos {
268 1.1 christos if (inst & (1 << 14))
269 1.1 christos {
270 1.1 christos /* This is a Form 3 instruction. */
271 1.1 christos int opcode = (inst >> 10 & 0xf);
272 1.1 christos
273 1.1 christos switch (opcode)
274 1.1 christos {
275 1.1 christos case 0x00: /* beq */
276 1.1 christos {
277 1.1.1.3 christos MOXIE_TRACE_INSN ("beq");
278 1.1 christos if (cpu.asregs.cc & CC_EQ)
279 1.1 christos pc += INST2OFFSET(inst);
280 1.1 christos }
281 1.1 christos break;
282 1.1 christos case 0x01: /* bne */
283 1.1 christos {
284 1.1.1.3 christos MOXIE_TRACE_INSN ("bne");
285 1.1 christos if (! (cpu.asregs.cc & CC_EQ))
286 1.1 christos pc += INST2OFFSET(inst);
287 1.1 christos }
288 1.1 christos break;
289 1.1 christos case 0x02: /* blt */
290 1.1 christos {
291 1.1.1.3 christos MOXIE_TRACE_INSN ("blt");
292 1.1 christos if (cpu.asregs.cc & CC_LT)
293 1.1 christos pc += INST2OFFSET(inst);
294 1.1 christos } break;
295 1.1 christos case 0x03: /* bgt */
296 1.1 christos {
297 1.1.1.3 christos MOXIE_TRACE_INSN ("bgt");
298 1.1 christos if (cpu.asregs.cc & CC_GT)
299 1.1 christos pc += INST2OFFSET(inst);
300 1.1 christos }
301 1.1 christos break;
302 1.1 christos case 0x04: /* bltu */
303 1.1 christos {
304 1.1.1.3 christos MOXIE_TRACE_INSN ("bltu");
305 1.1 christos if (cpu.asregs.cc & CC_LTU)
306 1.1 christos pc += INST2OFFSET(inst);
307 1.1 christos }
308 1.1 christos break;
309 1.1 christos case 0x05: /* bgtu */
310 1.1 christos {
311 1.1.1.3 christos MOXIE_TRACE_INSN ("bgtu");
312 1.1 christos if (cpu.asregs.cc & CC_GTU)
313 1.1 christos pc += INST2OFFSET(inst);
314 1.1 christos }
315 1.1 christos break;
316 1.1 christos case 0x06: /* bge */
317 1.1 christos {
318 1.1.1.3 christos MOXIE_TRACE_INSN ("bge");
319 1.1 christos if (cpu.asregs.cc & (CC_GT | CC_EQ))
320 1.1 christos pc += INST2OFFSET(inst);
321 1.1 christos }
322 1.1 christos break;
323 1.1 christos case 0x07: /* ble */
324 1.1 christos {
325 1.1.1.3 christos MOXIE_TRACE_INSN ("ble");
326 1.1 christos if (cpu.asregs.cc & (CC_LT | CC_EQ))
327 1.1 christos pc += INST2OFFSET(inst);
328 1.1 christos }
329 1.1 christos break;
330 1.1 christos case 0x08: /* bgeu */
331 1.1 christos {
332 1.1.1.3 christos MOXIE_TRACE_INSN ("bgeu");
333 1.1 christos if (cpu.asregs.cc & (CC_GTU | CC_EQ))
334 1.1 christos pc += INST2OFFSET(inst);
335 1.1 christos }
336 1.1 christos break;
337 1.1 christos case 0x09: /* bleu */
338 1.1 christos {
339 1.1.1.3 christos MOXIE_TRACE_INSN ("bleu");
340 1.1 christos if (cpu.asregs.cc & (CC_LTU | CC_EQ))
341 1.1 christos pc += INST2OFFSET(inst);
342 1.1 christos }
343 1.1 christos break;
344 1.1 christos default:
345 1.1 christos {
346 1.1.1.3 christos MOXIE_TRACE_INSN ("SIGILL3");
347 1.1.1.6 christos sim_engine_halt (sd, scpu, NULL, pc, sim_stopped, SIM_SIGILL);
348 1.1 christos break;
349 1.1 christos }
350 1.1 christos }
351 1.1 christos }
352 1.1 christos else
353 1.1 christos {
354 1.1 christos /* This is a Form 2 instruction. */
355 1.1 christos int opcode = (inst >> 12 & 0x3);
356 1.1 christos switch (opcode)
357 1.1 christos {
358 1.1 christos case 0x00: /* inc */
359 1.1 christos {
360 1.1 christos int a = (inst >> 8) & 0xf;
361 1.1 christos unsigned av = cpu.asregs.regs[a];
362 1.1 christos unsigned v = (inst & 0xff);
363 1.1.1.2 christos
364 1.1.1.3 christos MOXIE_TRACE_INSN ("inc");
365 1.1 christos cpu.asregs.regs[a] = av + v;
366 1.1 christos }
367 1.1 christos break;
368 1.1 christos case 0x01: /* dec */
369 1.1 christos {
370 1.1 christos int a = (inst >> 8) & 0xf;
371 1.1 christos unsigned av = cpu.asregs.regs[a];
372 1.1 christos unsigned v = (inst & 0xff);
373 1.1.1.2 christos
374 1.1.1.3 christos MOXIE_TRACE_INSN ("dec");
375 1.1 christos cpu.asregs.regs[a] = av - v;
376 1.1 christos }
377 1.1 christos break;
378 1.1 christos case 0x02: /* gsr */
379 1.1 christos {
380 1.1 christos int a = (inst >> 8) & 0xf;
381 1.1 christos unsigned v = (inst & 0xff);
382 1.1.1.2 christos
383 1.1.1.3 christos MOXIE_TRACE_INSN ("gsr");
384 1.1 christos cpu.asregs.regs[a] = cpu.asregs.sregs[v];
385 1.1 christos }
386 1.1 christos break;
387 1.1 christos case 0x03: /* ssr */
388 1.1 christos {
389 1.1 christos int a = (inst >> 8) & 0xf;
390 1.1 christos unsigned v = (inst & 0xff);
391 1.1.1.2 christos
392 1.1.1.3 christos MOXIE_TRACE_INSN ("ssr");
393 1.1 christos cpu.asregs.sregs[v] = cpu.asregs.regs[a];
394 1.1 christos }
395 1.1 christos break;
396 1.1 christos default:
397 1.1.1.3 christos MOXIE_TRACE_INSN ("SIGILL2");
398 1.1.1.6 christos sim_engine_halt (sd, scpu, NULL, pc, sim_stopped, SIM_SIGILL);
399 1.1 christos break;
400 1.1 christos }
401 1.1 christos }
402 1.1 christos }
403 1.1 christos else
404 1.1 christos {
405 1.1 christos /* This is a Form 1 instruction. */
406 1.1 christos int opcode = inst >> 8;
407 1.1 christos switch (opcode)
408 1.1 christos {
409 1.1 christos case 0x00: /* bad */
410 1.1 christos opc = opcode;
411 1.1.1.3 christos MOXIE_TRACE_INSN ("SIGILL0");
412 1.1.1.6 christos sim_engine_halt (sd, scpu, NULL, pc, sim_stopped, SIM_SIGILL);
413 1.1 christos break;
414 1.1 christos case 0x01: /* ldi.l (immediate) */
415 1.1 christos {
416 1.1 christos int reg = (inst >> 4) & 0xf;
417 1.1 christos unsigned int val = EXTRACT_WORD(pc+2);
418 1.1.1.3 christos
419 1.1.1.3 christos MOXIE_TRACE_INSN ("ldi.l");
420 1.1 christos cpu.asregs.regs[reg] = val;
421 1.1 christos pc += 4;
422 1.1 christos }
423 1.1 christos break;
424 1.1 christos case 0x02: /* mov (register-to-register) */
425 1.1 christos {
426 1.1 christos int dest = (inst >> 4) & 0xf;
427 1.1 christos int src = (inst ) & 0xf;
428 1.1.1.2 christos
429 1.1.1.3 christos MOXIE_TRACE_INSN ("mov");
430 1.1 christos cpu.asregs.regs[dest] = cpu.asregs.regs[src];
431 1.1 christos }
432 1.1 christos break;
433 1.1 christos case 0x03: /* jsra */
434 1.1 christos {
435 1.1 christos unsigned int fn = EXTRACT_WORD(pc+2);
436 1.1 christos unsigned int sp = cpu.asregs.regs[1];
437 1.1.1.2 christos
438 1.1.1.3 christos MOXIE_TRACE_INSN ("jsra");
439 1.1 christos /* Save a slot for the static chain. */
440 1.1 christos sp -= 4;
441 1.1 christos
442 1.1 christos /* Push the return address. */
443 1.1 christos sp -= 4;
444 1.1 christos wlat (scpu, opc, sp, pc + 6);
445 1.1 christos
446 1.1 christos /* Push the current frame pointer. */
447 1.1 christos sp -= 4;
448 1.1 christos wlat (scpu, opc, sp, cpu.asregs.regs[0]);
449 1.1 christos
450 1.1 christos /* Uncache the stack pointer and set the pc and $fp. */
451 1.1 christos cpu.asregs.regs[1] = sp;
452 1.1 christos cpu.asregs.regs[0] = sp;
453 1.1 christos pc = fn - 2;
454 1.1 christos }
455 1.1 christos break;
456 1.1 christos case 0x04: /* ret */
457 1.1 christos {
458 1.1 christos unsigned int sp = cpu.asregs.regs[0];
459 1.1 christos
460 1.1.1.3 christos MOXIE_TRACE_INSN ("ret");
461 1.1 christos
462 1.1 christos /* Pop the frame pointer. */
463 1.1 christos cpu.asregs.regs[0] = rlat (scpu, opc, sp);
464 1.1 christos sp += 4;
465 1.1 christos
466 1.1 christos /* Pop the return address. */
467 1.1 christos pc = rlat (scpu, opc, sp) - 2;
468 1.1 christos sp += 4;
469 1.1 christos
470 1.1 christos /* Skip over the static chain slot. */
471 1.1 christos sp += 4;
472 1.1 christos
473 1.1 christos /* Uncache the stack pointer. */
474 1.1 christos cpu.asregs.regs[1] = sp;
475 1.1 christos }
476 1.1 christos break;
477 1.1 christos case 0x05: /* add.l */
478 1.1 christos {
479 1.1 christos int a = (inst >> 4) & 0xf;
480 1.1 christos int b = inst & 0xf;
481 1.1 christos unsigned av = cpu.asregs.regs[a];
482 1.1 christos unsigned bv = cpu.asregs.regs[b];
483 1.1.1.2 christos
484 1.1.1.3 christos MOXIE_TRACE_INSN ("add.l");
485 1.1 christos cpu.asregs.regs[a] = av + bv;
486 1.1 christos }
487 1.1 christos break;
488 1.1 christos case 0x06: /* push */
489 1.1 christos {
490 1.1 christos int a = (inst >> 4) & 0xf;
491 1.1 christos int b = inst & 0xf;
492 1.1 christos int sp = cpu.asregs.regs[a] - 4;
493 1.1.1.2 christos
494 1.1.1.3 christos MOXIE_TRACE_INSN ("push");
495 1.1 christos wlat (scpu, opc, sp, cpu.asregs.regs[b]);
496 1.1 christos cpu.asregs.regs[a] = sp;
497 1.1 christos }
498 1.1 christos break;
499 1.1 christos case 0x07: /* pop */
500 1.1 christos {
501 1.1 christos int a = (inst >> 4) & 0xf;
502 1.1 christos int b = inst & 0xf;
503 1.1 christos int sp = cpu.asregs.regs[a];
504 1.1.1.2 christos
505 1.1.1.3 christos MOXIE_TRACE_INSN ("pop");
506 1.1 christos cpu.asregs.regs[b] = rlat (scpu, opc, sp);
507 1.1 christos cpu.asregs.regs[a] = sp + 4;
508 1.1 christos }
509 1.1 christos break;
510 1.1 christos case 0x08: /* lda.l */
511 1.1 christos {
512 1.1 christos int reg = (inst >> 4) & 0xf;
513 1.1 christos unsigned int addr = EXTRACT_WORD(pc+2);
514 1.1.1.2 christos
515 1.1.1.3 christos MOXIE_TRACE_INSN ("lda.l");
516 1.1 christos cpu.asregs.regs[reg] = rlat (scpu, opc, addr);
517 1.1 christos pc += 4;
518 1.1 christos }
519 1.1 christos break;
520 1.1 christos case 0x09: /* sta.l */
521 1.1 christos {
522 1.1 christos int reg = (inst >> 4) & 0xf;
523 1.1 christos unsigned int addr = EXTRACT_WORD(pc+2);
524 1.1.1.2 christos
525 1.1.1.3 christos MOXIE_TRACE_INSN ("sta.l");
526 1.1 christos wlat (scpu, opc, addr, cpu.asregs.regs[reg]);
527 1.1 christos pc += 4;
528 1.1 christos }
529 1.1 christos break;
530 1.1 christos case 0x0a: /* ld.l (register indirect) */
531 1.1 christos {
532 1.1 christos int src = inst & 0xf;
533 1.1 christos int dest = (inst >> 4) & 0xf;
534 1.1 christos int xv;
535 1.1.1.2 christos
536 1.1.1.3 christos MOXIE_TRACE_INSN ("ld.l");
537 1.1 christos xv = cpu.asregs.regs[src];
538 1.1 christos cpu.asregs.regs[dest] = rlat (scpu, opc, xv);
539 1.1 christos }
540 1.1 christos break;
541 1.1 christos case 0x0b: /* st.l */
542 1.1 christos {
543 1.1 christos int dest = (inst >> 4) & 0xf;
544 1.1 christos int val = inst & 0xf;
545 1.1.1.2 christos
546 1.1.1.3 christos MOXIE_TRACE_INSN ("st.l");
547 1.1 christos wlat (scpu, opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
548 1.1 christos }
549 1.1 christos break;
550 1.1 christos case 0x0c: /* ldo.l */
551 1.1 christos {
552 1.1.1.2 christos unsigned int addr = EXTRACT_OFFSET(pc+2);
553 1.1 christos int a = (inst >> 4) & 0xf;
554 1.1 christos int b = inst & 0xf;
555 1.1.1.2 christos
556 1.1.1.3 christos MOXIE_TRACE_INSN ("ldo.l");
557 1.1 christos addr += cpu.asregs.regs[b];
558 1.1 christos cpu.asregs.regs[a] = rlat (scpu, opc, addr);
559 1.1.1.2 christos pc += 2;
560 1.1 christos }
561 1.1 christos break;
562 1.1 christos case 0x0d: /* sto.l */
563 1.1 christos {
564 1.1.1.2 christos unsigned int addr = EXTRACT_OFFSET(pc+2);
565 1.1 christos int a = (inst >> 4) & 0xf;
566 1.1 christos int b = inst & 0xf;
567 1.1.1.2 christos
568 1.1.1.3 christos MOXIE_TRACE_INSN ("sto.l");
569 1.1 christos addr += cpu.asregs.regs[a];
570 1.1 christos wlat (scpu, opc, addr, cpu.asregs.regs[b]);
571 1.1.1.2 christos pc += 2;
572 1.1 christos }
573 1.1 christos break;
574 1.1 christos case 0x0e: /* cmp */
575 1.1 christos {
576 1.1 christos int a = (inst >> 4) & 0xf;
577 1.1 christos int b = inst & 0xf;
578 1.1 christos int cc = 0;
579 1.1 christos int va = cpu.asregs.regs[a];
580 1.1 christos int vb = cpu.asregs.regs[b];
581 1.1 christos
582 1.1.1.3 christos MOXIE_TRACE_INSN ("cmp");
583 1.1 christos if (va == vb)
584 1.1 christos cc = CC_EQ;
585 1.1 christos else
586 1.1 christos {
587 1.1 christos cc |= (va < vb ? CC_LT : 0);
588 1.1 christos cc |= (va > vb ? CC_GT : 0);
589 1.1 christos cc |= ((unsigned int) va < (unsigned int) vb ? CC_LTU : 0);
590 1.1 christos cc |= ((unsigned int) va > (unsigned int) vb ? CC_GTU : 0);
591 1.1 christos }
592 1.1 christos
593 1.1 christos cpu.asregs.cc = cc;
594 1.1 christos }
595 1.1 christos break;
596 1.1 christos case 0x0f: /* nop */
597 1.1 christos break;
598 1.1.1.2 christos case 0x10: /* sex.b */
599 1.1.1.2 christos {
600 1.1.1.2 christos int a = (inst >> 4) & 0xf;
601 1.1.1.2 christos int b = inst & 0xf;
602 1.1.1.2 christos signed char bv = cpu.asregs.regs[b];
603 1.1.1.2 christos
604 1.1.1.3 christos MOXIE_TRACE_INSN ("sex.b");
605 1.1.1.2 christos cpu.asregs.regs[a] = (int) bv;
606 1.1.1.2 christos }
607 1.1.1.2 christos break;
608 1.1.1.2 christos case 0x11: /* sex.s */
609 1.1.1.2 christos {
610 1.1.1.2 christos int a = (inst >> 4) & 0xf;
611 1.1.1.2 christos int b = inst & 0xf;
612 1.1.1.2 christos signed short bv = cpu.asregs.regs[b];
613 1.1.1.2 christos
614 1.1.1.3 christos MOXIE_TRACE_INSN ("sex.s");
615 1.1.1.2 christos cpu.asregs.regs[a] = (int) bv;
616 1.1.1.2 christos }
617 1.1.1.2 christos break;
618 1.1.1.2 christos case 0x12: /* zex.b */
619 1.1.1.2 christos {
620 1.1.1.2 christos int a = (inst >> 4) & 0xf;
621 1.1.1.2 christos int b = inst & 0xf;
622 1.1.1.2 christos signed char bv = cpu.asregs.regs[b];
623 1.1.1.2 christos
624 1.1.1.3 christos MOXIE_TRACE_INSN ("zex.b");
625 1.1.1.2 christos cpu.asregs.regs[a] = (int) bv & 0xff;
626 1.1.1.2 christos }
627 1.1.1.2 christos break;
628 1.1.1.2 christos case 0x13: /* zex.s */
629 1.1.1.2 christos {
630 1.1.1.2 christos int a = (inst >> 4) & 0xf;
631 1.1.1.2 christos int b = inst & 0xf;
632 1.1.1.2 christos signed short bv = cpu.asregs.regs[b];
633 1.1.1.2 christos
634 1.1.1.3 christos MOXIE_TRACE_INSN ("zex.s");
635 1.1.1.2 christos cpu.asregs.regs[a] = (int) bv & 0xffff;
636 1.1.1.2 christos }
637 1.1.1.2 christos break;
638 1.1.1.2 christos case 0x14: /* umul.x */
639 1.1.1.2 christos {
640 1.1.1.2 christos int a = (inst >> 4) & 0xf;
641 1.1.1.2 christos int b = inst & 0xf;
642 1.1.1.2 christos unsigned av = cpu.asregs.regs[a];
643 1.1.1.2 christos unsigned bv = cpu.asregs.regs[b];
644 1.1.1.2 christos unsigned long long r =
645 1.1.1.2 christos (unsigned long long) av * (unsigned long long) bv;
646 1.1.1.2 christos
647 1.1.1.3 christos MOXIE_TRACE_INSN ("umul.x");
648 1.1.1.2 christos cpu.asregs.regs[a] = r >> 32;
649 1.1.1.2 christos }
650 1.1.1.2 christos break;
651 1.1.1.2 christos case 0x15: /* mul.x */
652 1.1.1.2 christos {
653 1.1.1.2 christos int a = (inst >> 4) & 0xf;
654 1.1.1.2 christos int b = inst & 0xf;
655 1.1.1.2 christos unsigned av = cpu.asregs.regs[a];
656 1.1.1.2 christos unsigned bv = cpu.asregs.regs[b];
657 1.1.1.2 christos signed long long r =
658 1.1.1.2 christos (signed long long) av * (signed long long) bv;
659 1.1.1.2 christos
660 1.1.1.3 christos MOXIE_TRACE_INSN ("mul.x");
661 1.1.1.2 christos cpu.asregs.regs[a] = r >> 32;
662 1.1.1.2 christos }
663 1.1.1.2 christos break;
664 1.1 christos case 0x16: /* bad */
665 1.1 christos case 0x17: /* bad */
666 1.1 christos case 0x18: /* bad */
667 1.1 christos {
668 1.1 christos opc = opcode;
669 1.1.1.3 christos MOXIE_TRACE_INSN ("SIGILL0");
670 1.1.1.6 christos sim_engine_halt (sd, scpu, NULL, pc, sim_stopped, SIM_SIGILL);
671 1.1 christos break;
672 1.1 christos }
673 1.1 christos case 0x19: /* jsr */
674 1.1 christos {
675 1.1 christos unsigned int fn = cpu.asregs.regs[(inst >> 4) & 0xf];
676 1.1 christos unsigned int sp = cpu.asregs.regs[1];
677 1.1 christos
678 1.1.1.3 christos MOXIE_TRACE_INSN ("jsr");
679 1.1 christos
680 1.1 christos /* Save a slot for the static chain. */
681 1.1 christos sp -= 4;
682 1.1 christos
683 1.1 christos /* Push the return address. */
684 1.1 christos sp -= 4;
685 1.1 christos wlat (scpu, opc, sp, pc + 2);
686 1.1 christos
687 1.1 christos /* Push the current frame pointer. */
688 1.1 christos sp -= 4;
689 1.1 christos wlat (scpu, opc, sp, cpu.asregs.regs[0]);
690 1.1 christos
691 1.1 christos /* Uncache the stack pointer and set the fp & pc. */
692 1.1 christos cpu.asregs.regs[1] = sp;
693 1.1 christos cpu.asregs.regs[0] = sp;
694 1.1 christos pc = fn - 2;
695 1.1 christos }
696 1.1 christos break;
697 1.1 christos case 0x1a: /* jmpa */
698 1.1 christos {
699 1.1 christos unsigned int tgt = EXTRACT_WORD(pc+2);
700 1.1.1.2 christos
701 1.1.1.3 christos MOXIE_TRACE_INSN ("jmpa");
702 1.1 christos pc = tgt - 2;
703 1.1 christos }
704 1.1 christos break;
705 1.1 christos case 0x1b: /* ldi.b (immediate) */
706 1.1 christos {
707 1.1 christos int reg = (inst >> 4) & 0xf;
708 1.1 christos unsigned int val = EXTRACT_WORD(pc+2);
709 1.1.1.2 christos
710 1.1.1.3 christos MOXIE_TRACE_INSN ("ldi.b");
711 1.1 christos cpu.asregs.regs[reg] = val;
712 1.1 christos pc += 4;
713 1.1 christos }
714 1.1 christos break;
715 1.1 christos case 0x1c: /* ld.b (register indirect) */
716 1.1 christos {
717 1.1 christos int src = inst & 0xf;
718 1.1 christos int dest = (inst >> 4) & 0xf;
719 1.1 christos int xv;
720 1.1.1.2 christos
721 1.1.1.3 christos MOXIE_TRACE_INSN ("ld.b");
722 1.1 christos xv = cpu.asregs.regs[src];
723 1.1 christos cpu.asregs.regs[dest] = rbat (scpu, opc, xv);
724 1.1 christos }
725 1.1 christos break;
726 1.1 christos case 0x1d: /* lda.b */
727 1.1 christos {
728 1.1 christos int reg = (inst >> 4) & 0xf;
729 1.1 christos unsigned int addr = EXTRACT_WORD(pc+2);
730 1.1.1.2 christos
731 1.1.1.3 christos MOXIE_TRACE_INSN ("lda.b");
732 1.1 christos cpu.asregs.regs[reg] = rbat (scpu, opc, addr);
733 1.1 christos pc += 4;
734 1.1 christos }
735 1.1 christos break;
736 1.1 christos case 0x1e: /* st.b */
737 1.1 christos {
738 1.1 christos int dest = (inst >> 4) & 0xf;
739 1.1 christos int val = inst & 0xf;
740 1.1.1.2 christos
741 1.1.1.3 christos MOXIE_TRACE_INSN ("st.b");
742 1.1 christos wbat (scpu, opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
743 1.1 christos }
744 1.1 christos break;
745 1.1 christos case 0x1f: /* sta.b */
746 1.1 christos {
747 1.1 christos int reg = (inst >> 4) & 0xf;
748 1.1 christos unsigned int addr = EXTRACT_WORD(pc+2);
749 1.1.1.2 christos
750 1.1.1.3 christos MOXIE_TRACE_INSN ("sta.b");
751 1.1 christos wbat (scpu, opc, addr, cpu.asregs.regs[reg]);
752 1.1 christos pc += 4;
753 1.1 christos }
754 1.1 christos break;
755 1.1 christos case 0x20: /* ldi.s (immediate) */
756 1.1 christos {
757 1.1 christos int reg = (inst >> 4) & 0xf;
758 1.1 christos
759 1.1 christos unsigned int val = EXTRACT_WORD(pc+2);
760 1.1.1.2 christos
761 1.1.1.3 christos MOXIE_TRACE_INSN ("ldi.s");
762 1.1 christos cpu.asregs.regs[reg] = val;
763 1.1 christos pc += 4;
764 1.1 christos }
765 1.1 christos break;
766 1.1 christos case 0x21: /* ld.s (register indirect) */
767 1.1 christos {
768 1.1 christos int src = inst & 0xf;
769 1.1 christos int dest = (inst >> 4) & 0xf;
770 1.1 christos int xv;
771 1.1.1.2 christos
772 1.1.1.3 christos MOXIE_TRACE_INSN ("ld.s");
773 1.1 christos xv = cpu.asregs.regs[src];
774 1.1 christos cpu.asregs.regs[dest] = rsat (scpu, opc, xv);
775 1.1 christos }
776 1.1 christos break;
777 1.1 christos case 0x22: /* lda.s */
778 1.1 christos {
779 1.1 christos int reg = (inst >> 4) & 0xf;
780 1.1 christos unsigned int addr = EXTRACT_WORD(pc+2);
781 1.1.1.2 christos
782 1.1.1.3 christos MOXIE_TRACE_INSN ("lda.s");
783 1.1 christos cpu.asregs.regs[reg] = rsat (scpu, opc, addr);
784 1.1 christos pc += 4;
785 1.1 christos }
786 1.1 christos break;
787 1.1 christos case 0x23: /* st.s */
788 1.1 christos {
789 1.1 christos int dest = (inst >> 4) & 0xf;
790 1.1 christos int val = inst & 0xf;
791 1.1.1.2 christos
792 1.1.1.3 christos MOXIE_TRACE_INSN ("st.s");
793 1.1 christos wsat (scpu, opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
794 1.1 christos }
795 1.1 christos break;
796 1.1 christos case 0x24: /* sta.s */
797 1.1 christos {
798 1.1 christos int reg = (inst >> 4) & 0xf;
799 1.1 christos unsigned int addr = EXTRACT_WORD(pc+2);
800 1.1.1.2 christos
801 1.1.1.3 christos MOXIE_TRACE_INSN ("sta.s");
802 1.1 christos wsat (scpu, opc, addr, cpu.asregs.regs[reg]);
803 1.1 christos pc += 4;
804 1.1 christos }
805 1.1 christos break;
806 1.1 christos case 0x25: /* jmp */
807 1.1 christos {
808 1.1 christos int reg = (inst >> 4) & 0xf;
809 1.1.1.2 christos
810 1.1.1.3 christos MOXIE_TRACE_INSN ("jmp");
811 1.1 christos pc = cpu.asregs.regs[reg] - 2;
812 1.1 christos }
813 1.1 christos break;
814 1.1 christos case 0x26: /* and */
815 1.1 christos {
816 1.1 christos int a = (inst >> 4) & 0xf;
817 1.1 christos int b = inst & 0xf;
818 1.1 christos int av, bv;
819 1.1.1.2 christos
820 1.1.1.3 christos MOXIE_TRACE_INSN ("and");
821 1.1 christos av = cpu.asregs.regs[a];
822 1.1 christos bv = cpu.asregs.regs[b];
823 1.1 christos cpu.asregs.regs[a] = av & bv;
824 1.1 christos }
825 1.1 christos break;
826 1.1 christos case 0x27: /* lshr */
827 1.1 christos {
828 1.1 christos int a = (inst >> 4) & 0xf;
829 1.1 christos int b = inst & 0xf;
830 1.1 christos int av = cpu.asregs.regs[a];
831 1.1 christos int bv = cpu.asregs.regs[b];
832 1.1.1.2 christos
833 1.1.1.3 christos MOXIE_TRACE_INSN ("lshr");
834 1.1 christos cpu.asregs.regs[a] = (unsigned) ((unsigned) av >> bv);
835 1.1 christos }
836 1.1 christos break;
837 1.1 christos case 0x28: /* ashl */
838 1.1 christos {
839 1.1 christos int a = (inst >> 4) & 0xf;
840 1.1 christos int b = inst & 0xf;
841 1.1 christos int av = cpu.asregs.regs[a];
842 1.1 christos int bv = cpu.asregs.regs[b];
843 1.1.1.2 christos
844 1.1.1.3 christos MOXIE_TRACE_INSN ("ashl");
845 1.1 christos cpu.asregs.regs[a] = av << bv;
846 1.1 christos }
847 1.1 christos break;
848 1.1 christos case 0x29: /* sub.l */
849 1.1 christos {
850 1.1 christos int a = (inst >> 4) & 0xf;
851 1.1 christos int b = inst & 0xf;
852 1.1 christos unsigned av = cpu.asregs.regs[a];
853 1.1 christos unsigned bv = cpu.asregs.regs[b];
854 1.1.1.2 christos
855 1.1.1.3 christos MOXIE_TRACE_INSN ("sub.l");
856 1.1 christos cpu.asregs.regs[a] = av - bv;
857 1.1 christos }
858 1.1 christos break;
859 1.1 christos case 0x2a: /* neg */
860 1.1 christos {
861 1.1 christos int a = (inst >> 4) & 0xf;
862 1.1 christos int b = inst & 0xf;
863 1.1 christos int bv = cpu.asregs.regs[b];
864 1.1.1.2 christos
865 1.1.1.3 christos MOXIE_TRACE_INSN ("neg");
866 1.1 christos cpu.asregs.regs[a] = - bv;
867 1.1 christos }
868 1.1 christos break;
869 1.1 christos case 0x2b: /* or */
870 1.1 christos {
871 1.1 christos int a = (inst >> 4) & 0xf;
872 1.1 christos int b = inst & 0xf;
873 1.1 christos int av, bv;
874 1.1.1.2 christos
875 1.1.1.3 christos MOXIE_TRACE_INSN ("or");
876 1.1 christos av = cpu.asregs.regs[a];
877 1.1 christos bv = cpu.asregs.regs[b];
878 1.1 christos cpu.asregs.regs[a] = av | bv;
879 1.1 christos }
880 1.1 christos break;
881 1.1 christos case 0x2c: /* not */
882 1.1 christos {
883 1.1 christos int a = (inst >> 4) & 0xf;
884 1.1 christos int b = inst & 0xf;
885 1.1 christos int bv = cpu.asregs.regs[b];
886 1.1.1.2 christos
887 1.1.1.3 christos MOXIE_TRACE_INSN ("not");
888 1.1 christos cpu.asregs.regs[a] = 0xffffffff ^ bv;
889 1.1 christos }
890 1.1 christos break;
891 1.1 christos case 0x2d: /* ashr */
892 1.1 christos {
893 1.1 christos int a = (inst >> 4) & 0xf;
894 1.1 christos int b = inst & 0xf;
895 1.1 christos int av = cpu.asregs.regs[a];
896 1.1 christos int bv = cpu.asregs.regs[b];
897 1.1.1.2 christos
898 1.1.1.3 christos MOXIE_TRACE_INSN ("ashr");
899 1.1 christos cpu.asregs.regs[a] = av >> bv;
900 1.1 christos }
901 1.1 christos break;
902 1.1 christos case 0x2e: /* xor */
903 1.1 christos {
904 1.1 christos int a = (inst >> 4) & 0xf;
905 1.1 christos int b = inst & 0xf;
906 1.1 christos int av, bv;
907 1.1.1.2 christos
908 1.1.1.3 christos MOXIE_TRACE_INSN ("xor");
909 1.1 christos av = cpu.asregs.regs[a];
910 1.1 christos bv = cpu.asregs.regs[b];
911 1.1 christos cpu.asregs.regs[a] = av ^ bv;
912 1.1 christos }
913 1.1 christos break;
914 1.1 christos case 0x2f: /* mul.l */
915 1.1 christos {
916 1.1 christos int a = (inst >> 4) & 0xf;
917 1.1 christos int b = inst & 0xf;
918 1.1 christos unsigned av = cpu.asregs.regs[a];
919 1.1 christos unsigned bv = cpu.asregs.regs[b];
920 1.1.1.2 christos
921 1.1.1.3 christos MOXIE_TRACE_INSN ("mul.l");
922 1.1 christos cpu.asregs.regs[a] = av * bv;
923 1.1 christos }
924 1.1 christos break;
925 1.1 christos case 0x30: /* swi */
926 1.1 christos {
927 1.1 christos unsigned int inum = EXTRACT_WORD(pc+2);
928 1.1.1.2 christos
929 1.1.1.3 christos MOXIE_TRACE_INSN ("swi");
930 1.1 christos /* Set the special registers appropriately. */
931 1.1 christos cpu.asregs.sregs[2] = 3; /* MOXIE_EX_SWI */
932 1.1 christos cpu.asregs.sregs[3] = inum;
933 1.1 christos switch (inum)
934 1.1 christos {
935 1.1 christos case 0x1: /* SYS_exit */
936 1.1 christos {
937 1.1.1.6 christos sim_engine_halt (sd, scpu, NULL, pc, sim_exited,
938 1.1.1.3 christos cpu.asregs.regs[2]);
939 1.1 christos break;
940 1.1 christos }
941 1.1 christos case 0x2: /* SYS_open */
942 1.1 christos {
943 1.1 christos char fname[1024];
944 1.1 christos int mode = (int) convert_target_flags ((unsigned) cpu.asregs.regs[3]);
945 1.1 christos int perm = (int) cpu.asregs.regs[4];
946 1.1.1.7 christos int fd;
947 1.1 christos sim_core_read_buffer (sd, scpu, read_map, fname,
948 1.1 christos cpu.asregs.regs[2], 1024);
949 1.1.1.7 christos fd = sim_io_open (sd, fname, mode);
950 1.1 christos /* FIXME - set errno */
951 1.1 christos cpu.asregs.regs[2] = fd;
952 1.1 christos break;
953 1.1 christos }
954 1.1 christos case 0x4: /* SYS_read */
955 1.1 christos {
956 1.1 christos int fd = cpu.asregs.regs[2];
957 1.1 christos unsigned len = (unsigned) cpu.asregs.regs[4];
958 1.1 christos char *buf = malloc (len);
959 1.1.1.7 christos cpu.asregs.regs[2] = sim_io_read (sd, fd, buf, len);
960 1.1 christos sim_core_write_buffer (sd, scpu, write_map, buf,
961 1.1 christos cpu.asregs.regs[3], len);
962 1.1 christos free (buf);
963 1.1 christos break;
964 1.1 christos }
965 1.1 christos case 0x5: /* SYS_write */
966 1.1 christos {
967 1.1 christos char *str;
968 1.1 christos /* String length is at 0x12($fp) */
969 1.1 christos unsigned count, len = (unsigned) cpu.asregs.regs[4];
970 1.1 christos str = malloc (len);
971 1.1 christos sim_core_read_buffer (sd, scpu, read_map, str,
972 1.1 christos cpu.asregs.regs[3], len);
973 1.1.1.7 christos count = sim_io_write (sd, cpu.asregs.regs[2], str, len);
974 1.1 christos free (str);
975 1.1 christos cpu.asregs.regs[2] = count;
976 1.1 christos break;
977 1.1 christos }
978 1.1.1.7 christos case 0x7: /* SYS_unlink */
979 1.1.1.7 christos {
980 1.1.1.7 christos char fname[1024];
981 1.1.1.7 christos int fd;
982 1.1.1.7 christos sim_core_read_buffer (sd, scpu, read_map, fname,
983 1.1.1.7 christos cpu.asregs.regs[2], 1024);
984 1.1.1.7 christos fd = sim_io_unlink (sd, fname);
985 1.1.1.7 christos /* FIXME - set errno */
986 1.1.1.7 christos cpu.asregs.regs[2] = fd;
987 1.1.1.7 christos break;
988 1.1.1.7 christos }
989 1.1 christos case 0xffffffff: /* Linux System Call */
990 1.1 christos {
991 1.1 christos unsigned int handler = cpu.asregs.sregs[1];
992 1.1 christos unsigned int sp = cpu.asregs.regs[1];
993 1.1 christos
994 1.1 christos /* Save a slot for the static chain. */
995 1.1 christos sp -= 4;
996 1.1 christos
997 1.1 christos /* Push the return address. */
998 1.1 christos sp -= 4;
999 1.1 christos wlat (scpu, opc, sp, pc + 6);
1000 1.1 christos
1001 1.1 christos /* Push the current frame pointer. */
1002 1.1 christos sp -= 4;
1003 1.1 christos wlat (scpu, opc, sp, cpu.asregs.regs[0]);
1004 1.1 christos
1005 1.1 christos /* Uncache the stack pointer and set the fp & pc. */
1006 1.1 christos cpu.asregs.regs[1] = sp;
1007 1.1 christos cpu.asregs.regs[0] = sp;
1008 1.1 christos pc = handler - 6;
1009 1.1 christos }
1010 1.1 christos default:
1011 1.1 christos break;
1012 1.1 christos }
1013 1.1 christos pc += 4;
1014 1.1 christos }
1015 1.1 christos break;
1016 1.1 christos case 0x31: /* div.l */
1017 1.1 christos {
1018 1.1 christos int a = (inst >> 4) & 0xf;
1019 1.1 christos int b = inst & 0xf;
1020 1.1 christos int av = cpu.asregs.regs[a];
1021 1.1 christos int bv = cpu.asregs.regs[b];
1022 1.1.1.2 christos
1023 1.1.1.3 christos MOXIE_TRACE_INSN ("div.l");
1024 1.1 christos cpu.asregs.regs[a] = av / bv;
1025 1.1 christos }
1026 1.1 christos break;
1027 1.1 christos case 0x32: /* udiv.l */
1028 1.1 christos {
1029 1.1 christos int a = (inst >> 4) & 0xf;
1030 1.1 christos int b = inst & 0xf;
1031 1.1 christos unsigned int av = cpu.asregs.regs[a];
1032 1.1 christos unsigned int bv = cpu.asregs.regs[b];
1033 1.1.1.2 christos
1034 1.1.1.3 christos MOXIE_TRACE_INSN ("udiv.l");
1035 1.1 christos cpu.asregs.regs[a] = (av / bv);
1036 1.1 christos }
1037 1.1 christos break;
1038 1.1 christos case 0x33: /* mod.l */
1039 1.1 christos {
1040 1.1 christos int a = (inst >> 4) & 0xf;
1041 1.1 christos int b = inst & 0xf;
1042 1.1 christos int av = cpu.asregs.regs[a];
1043 1.1 christos int bv = cpu.asregs.regs[b];
1044 1.1.1.2 christos
1045 1.1.1.3 christos MOXIE_TRACE_INSN ("mod.l");
1046 1.1 christos cpu.asregs.regs[a] = av % bv;
1047 1.1 christos }
1048 1.1 christos break;
1049 1.1 christos case 0x34: /* umod.l */
1050 1.1 christos {
1051 1.1 christos int a = (inst >> 4) & 0xf;
1052 1.1 christos int b = inst & 0xf;
1053 1.1 christos unsigned int av = cpu.asregs.regs[a];
1054 1.1 christos unsigned int bv = cpu.asregs.regs[b];
1055 1.1.1.2 christos
1056 1.1.1.3 christos MOXIE_TRACE_INSN ("umod.l");
1057 1.1 christos cpu.asregs.regs[a] = (av % bv);
1058 1.1 christos }
1059 1.1 christos break;
1060 1.1 christos case 0x35: /* brk */
1061 1.1.1.3 christos MOXIE_TRACE_INSN ("brk");
1062 1.1.1.6 christos sim_engine_halt (sd, scpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
1063 1.1 christos pc -= 2; /* Adjust pc */
1064 1.1 christos break;
1065 1.1 christos case 0x36: /* ldo.b */
1066 1.1 christos {
1067 1.1.1.2 christos unsigned int addr = EXTRACT_OFFSET(pc+2);
1068 1.1 christos int a = (inst >> 4) & 0xf;
1069 1.1 christos int b = inst & 0xf;
1070 1.1.1.2 christos
1071 1.1.1.3 christos MOXIE_TRACE_INSN ("ldo.b");
1072 1.1 christos addr += cpu.asregs.regs[b];
1073 1.1 christos cpu.asregs.regs[a] = rbat (scpu, opc, addr);
1074 1.1.1.2 christos pc += 2;
1075 1.1 christos }
1076 1.1 christos break;
1077 1.1 christos case 0x37: /* sto.b */
1078 1.1 christos {
1079 1.1.1.2 christos unsigned int addr = EXTRACT_OFFSET(pc+2);
1080 1.1 christos int a = (inst >> 4) & 0xf;
1081 1.1 christos int b = inst & 0xf;
1082 1.1.1.2 christos
1083 1.1.1.3 christos MOXIE_TRACE_INSN ("sto.b");
1084 1.1 christos addr += cpu.asregs.regs[a];
1085 1.1 christos wbat (scpu, opc, addr, cpu.asregs.regs[b]);
1086 1.1.1.2 christos pc += 2;
1087 1.1 christos }
1088 1.1 christos break;
1089 1.1 christos case 0x38: /* ldo.s */
1090 1.1 christos {
1091 1.1.1.2 christos unsigned int addr = EXTRACT_OFFSET(pc+2);
1092 1.1 christos int a = (inst >> 4) & 0xf;
1093 1.1 christos int b = inst & 0xf;
1094 1.1.1.2 christos
1095 1.1.1.3 christos MOXIE_TRACE_INSN ("ldo.s");
1096 1.1 christos addr += cpu.asregs.regs[b];
1097 1.1 christos cpu.asregs.regs[a] = rsat (scpu, opc, addr);
1098 1.1.1.2 christos pc += 2;
1099 1.1 christos }
1100 1.1 christos break;
1101 1.1 christos case 0x39: /* sto.s */
1102 1.1 christos {
1103 1.1.1.2 christos unsigned int addr = EXTRACT_OFFSET(pc+2);
1104 1.1 christos int a = (inst >> 4) & 0xf;
1105 1.1 christos int b = inst & 0xf;
1106 1.1.1.2 christos
1107 1.1.1.3 christos MOXIE_TRACE_INSN ("sto.s");
1108 1.1 christos addr += cpu.asregs.regs[a];
1109 1.1 christos wsat (scpu, opc, addr, cpu.asregs.regs[b]);
1110 1.1.1.2 christos pc += 2;
1111 1.1 christos }
1112 1.1 christos break;
1113 1.1 christos default:
1114 1.1 christos opc = opcode;
1115 1.1.1.3 christos MOXIE_TRACE_INSN ("SIGILL1");
1116 1.1.1.6 christos sim_engine_halt (sd, scpu, NULL, pc, sim_stopped, SIM_SIGILL);
1117 1.1 christos break;
1118 1.1 christos }
1119 1.1 christos }
1120 1.1 christos
1121 1.1.1.3 christos cpu.asregs.insts++;
1122 1.1 christos pc += 2;
1123 1.1.1.3 christos cpu.asregs.regs[PC_REGNO] = pc;
1124 1.1.1.6 christos
1125 1.1.1.6 christos if (sim_events_tick (sd))
1126 1.1.1.6 christos sim_events_process (sd);
1127 1.1.1.6 christos
1128 1.1.1.3 christos } while (1);
1129 1.1 christos }
1130 1.1 christos
1131 1.1.1.4 christos static int
1132 1.1.1.4 christos moxie_reg_store (SIM_CPU *scpu, int rn, unsigned char *memory, int length)
1133 1.1 christos {
1134 1.1 christos if (rn < NUM_MOXIE_REGS && rn >= 0)
1135 1.1 christos {
1136 1.1 christos if (length == 4)
1137 1.1 christos {
1138 1.1 christos long ival;
1139 1.1 christos
1140 1.1 christos /* misalignment safe */
1141 1.1 christos ival = moxie_extract_unsigned_integer (memory, 4);
1142 1.1 christos cpu.asints[rn] = ival;
1143 1.1 christos }
1144 1.1 christos
1145 1.1 christos return 4;
1146 1.1 christos }
1147 1.1 christos else
1148 1.1 christos return 0;
1149 1.1 christos }
1150 1.1 christos
1151 1.1.1.4 christos static int
1152 1.1.1.4 christos moxie_reg_fetch (SIM_CPU *scpu, int rn, unsigned char *memory, int length)
1153 1.1 christos {
1154 1.1 christos if (rn < NUM_MOXIE_REGS && rn >= 0)
1155 1.1 christos {
1156 1.1 christos if (length == 4)
1157 1.1 christos {
1158 1.1 christos long ival = cpu.asints[rn];
1159 1.1 christos
1160 1.1 christos /* misalignment-safe */
1161 1.1 christos moxie_store_unsigned_integer (memory, 4, ival);
1162 1.1 christos }
1163 1.1 christos
1164 1.1 christos return 4;
1165 1.1 christos }
1166 1.1 christos else
1167 1.1 christos return 0;
1168 1.1 christos }
1169 1.1 christos
1170 1.1.1.3 christos static sim_cia
1171 1.1.1.3 christos moxie_pc_get (sim_cpu *cpu)
1172 1.1 christos {
1173 1.1.1.3 christos return cpu->registers[PCIDX];
1174 1.1 christos }
1175 1.1 christos
1176 1.1.1.3 christos static void
1177 1.1.1.3 christos moxie_pc_set (sim_cpu *cpu, sim_cia pc)
1178 1.1 christos {
1179 1.1.1.3 christos cpu->registers[PCIDX] = pc;
1180 1.1 christos }
1181 1.1 christos
1182 1.1.1.3 christos static void
1183 1.1.1.3 christos free_state (SIM_DESC sd)
1184 1.1 christos {
1185 1.1.1.3 christos if (STATE_MODULES (sd) != NULL)
1186 1.1.1.3 christos sim_module_uninstall (sd);
1187 1.1.1.3 christos sim_cpu_free_all (sd);
1188 1.1.1.3 christos sim_state_free (sd);
1189 1.1 christos }
1190 1.1 christos
1191 1.1 christos SIM_DESC
1192 1.1.1.4 christos sim_open (SIM_OPEN_KIND kind, host_callback *cb,
1193 1.1.1.4 christos struct bfd *abfd, char * const *argv)
1194 1.1 christos {
1195 1.1.1.3 christos int i;
1196 1.1 christos SIM_DESC sd = sim_state_alloc (kind, cb);
1197 1.1 christos SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
1198 1.1 christos
1199 1.1.1.3 christos /* The cpu data is kept in a separately allocated chunk of memory. */
1200 1.1.1.3 christos if (sim_cpu_alloc_all (sd, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK)
1201 1.1.1.3 christos {
1202 1.1.1.3 christos free_state (sd);
1203 1.1.1.3 christos return 0;
1204 1.1.1.3 christos }
1205 1.1.1.3 christos
1206 1.1.1.3 christos STATE_WATCHPOINTS (sd)->pc = &cpu.asregs.regs[PC_REGNO];
1207 1.1.1.3 christos STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (word);
1208 1.1.1.3 christos
1209 1.1 christos if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
1210 1.1.1.3 christos {
1211 1.1.1.3 christos free_state (sd);
1212 1.1.1.3 christos return 0;
1213 1.1.1.3 christos }
1214 1.1.1.3 christos
1215 1.1.1.4 christos /* The parser will print an error message for us, so we silently return. */
1216 1.1.1.3 christos if (sim_parse_args (sd, argv) != SIM_RC_OK)
1217 1.1.1.3 christos {
1218 1.1.1.3 christos free_state (sd);
1219 1.1.1.3 christos return 0;
1220 1.1.1.3 christos }
1221 1.1 christos
1222 1.1 christos sim_do_command(sd," memory region 0x00000000,0x4000000") ;
1223 1.1 christos sim_do_command(sd," memory region 0xE0000000,0x10000") ;
1224 1.1 christos
1225 1.1.1.3 christos /* Check for/establish the a reference program image. */
1226 1.1.1.3 christos if (sim_analyze_program (sd,
1227 1.1.1.3 christos (STATE_PROG_ARGV (sd) != NULL
1228 1.1.1.3 christos ? *STATE_PROG_ARGV (sd)
1229 1.1.1.3 christos : NULL), abfd) != SIM_RC_OK)
1230 1.1.1.3 christos {
1231 1.1.1.3 christos free_state (sd);
1232 1.1.1.3 christos return 0;
1233 1.1.1.3 christos }
1234 1.1.1.3 christos
1235 1.1 christos /* Configure/verify the target byte order and other runtime
1236 1.1 christos configuration options. */
1237 1.1 christos if (sim_config (sd) != SIM_RC_OK)
1238 1.1 christos {
1239 1.1 christos sim_module_uninstall (sd);
1240 1.1 christos return 0;
1241 1.1 christos }
1242 1.1 christos
1243 1.1 christos if (sim_post_argv_init (sd) != SIM_RC_OK)
1244 1.1 christos {
1245 1.1 christos /* Uninstall the modules to avoid memory leaks,
1246 1.1 christos file descriptor leaks, etc. */
1247 1.1 christos sim_module_uninstall (sd);
1248 1.1 christos return 0;
1249 1.1 christos }
1250 1.1 christos
1251 1.1.1.3 christos /* CPU specific initialization. */
1252 1.1.1.3 christos for (i = 0; i < MAX_NR_PROCESSORS; ++i)
1253 1.1.1.3 christos {
1254 1.1.1.3 christos SIM_CPU *cpu = STATE_CPU (sd, i);
1255 1.1.1.3 christos
1256 1.1.1.4 christos CPU_REG_FETCH (cpu) = moxie_reg_fetch;
1257 1.1.1.4 christos CPU_REG_STORE (cpu) = moxie_reg_store;
1258 1.1.1.3 christos CPU_PC_FETCH (cpu) = moxie_pc_get;
1259 1.1.1.3 christos CPU_PC_STORE (cpu) = moxie_pc_set;
1260 1.1.1.3 christos
1261 1.1.1.3 christos set_initial_gprs (); /* Reset the GPR registers. */
1262 1.1.1.3 christos }
1263 1.1.1.3 christos
1264 1.1 christos return sd;
1265 1.1 christos }
1266 1.1 christos
1267 1.1 christos /* Load the device tree blob. */
1268 1.1 christos
1269 1.1 christos static void
1270 1.1 christos load_dtb (SIM_DESC sd, const char *filename)
1271 1.1 christos {
1272 1.1 christos int size = 0;
1273 1.1 christos FILE *f = fopen (filename, "rb");
1274 1.1 christos char *buf;
1275 1.1 christos sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
1276 1.1.1.3 christos
1277 1.1.1.3 christos /* Don't warn as the sim works fine w/out a device tree. */
1278 1.1.1.3 christos if (f == NULL)
1279 1.1.1.3 christos return;
1280 1.1 christos fseek (f, 0, SEEK_END);
1281 1.1 christos size = ftell(f);
1282 1.1 christos fseek (f, 0, SEEK_SET);
1283 1.1 christos buf = alloca (size);
1284 1.1 christos if (size != fread (buf, 1, size, f))
1285 1.1 christos {
1286 1.1.1.3 christos sim_io_eprintf (sd, "ERROR: error reading ``%s''.\n", filename);
1287 1.1.1.4 christos fclose (f);
1288 1.1 christos return;
1289 1.1 christos }
1290 1.1 christos sim_core_write_buffer (sd, scpu, write_map, buf, 0xE0000000, size);
1291 1.1 christos cpu.asregs.sregs[9] = 0xE0000000;
1292 1.1 christos fclose (f);
1293 1.1 christos }
1294 1.1 christos
1295 1.1 christos SIM_RC
1296 1.1.1.4 christos sim_create_inferior (SIM_DESC sd, struct bfd *prog_bfd,
1297 1.1.1.4 christos char * const *argv, char * const *env)
1298 1.1 christos {
1299 1.1 christos char ** avp;
1300 1.1 christos int l, argc, i, tp;
1301 1.1 christos sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
1302 1.1 christos
1303 1.1 christos if (prog_bfd != NULL)
1304 1.1 christos cpu.asregs.regs[PC_REGNO] = bfd_get_start_address (prog_bfd);
1305 1.1 christos
1306 1.1 christos /* Copy args into target memory. */
1307 1.1 christos avp = argv;
1308 1.1 christos for (argc = 0; avp && *avp; avp++)
1309 1.1 christos argc++;
1310 1.1 christos
1311 1.1 christos /* Target memory looks like this:
1312 1.1 christos 0x00000000 zero word
1313 1.1 christos 0x00000004 argc word
1314 1.1 christos 0x00000008 start of argv
1315 1.1 christos .
1316 1.1 christos 0x0000???? end of argv
1317 1.1 christos 0x0000???? zero word
1318 1.1 christos 0x0000???? start of data pointed to by argv */
1319 1.1 christos
1320 1.1 christos wlat (scpu, 0, 0, 0);
1321 1.1 christos wlat (scpu, 0, 4, argc);
1322 1.1 christos
1323 1.1 christos /* tp is the offset of our first argv data. */
1324 1.1 christos tp = 4 + 4 + argc * 4 + 4;
1325 1.1 christos
1326 1.1 christos for (i = 0; i < argc; i++)
1327 1.1 christos {
1328 1.1 christos /* Set the argv value. */
1329 1.1 christos wlat (scpu, 0, 4 + 4 + i * 4, tp);
1330 1.1 christos
1331 1.1 christos /* Store the string. */
1332 1.1 christos sim_core_write_buffer (sd, scpu, write_map, argv[i],
1333 1.1 christos tp, strlen(argv[i])+1);
1334 1.1 christos tp += strlen (argv[i]) + 1;
1335 1.1 christos }
1336 1.1 christos
1337 1.1 christos wlat (scpu, 0, 4 + 4 + i * 4, 0);
1338 1.1 christos
1339 1.1 christos load_dtb (sd, DTB);
1340 1.1 christos
1341 1.1 christos return SIM_RC_OK;
1342 1.1 christos }
1343