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