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