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