interp.c revision 1.1.1.3
1/* Simulator for the moxie processor
2   Copyright (C) 2008-2014 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 "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
36typedef int word;
37typedef unsigned int uword;
38
39host_callback *       callback;
40
41FILE *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
53unsigned long
54moxie_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
77void
78moxie_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.  */
95static 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.  */
114struct 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
129union
130{
131  struct moxie_regset asregs;
132  word asints [1];		/* but accessed larger... */
133} cpu;
134
135static char *myname;
136static SIM_OPEN_KIND sim_kind;
137static int issue_messages = 0;
138
139void
140sim_size (int s)
141{
142}
143
144static void
145set_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
160static void
161interrupt ()
162{
163  cpu.asregs.exception = SIGINT;
164}
165
166/* Write a 1 byte value to memory.  */
167
168static void INLINE
169wbat (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
178static void INLINE
179wsat (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
188static void INLINE
189wlat (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
198static int INLINE
199rsat (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
208static int INLINE
209rbat (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
218static int INLINE
219rlat (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
228unsigned int
229convert_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
251static int tracing = 0;
252
253void
254sim_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
1029int
1030sim_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
1043int
1044sim_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
1058int
1059sim_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
1082int
1083sim_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
1106int
1107sim_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
1122void
1123sim_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
1141int
1142sim_stop (sd)
1143     SIM_DESC sd;
1144{
1145  cpu.asregs.exception = SIGINT;
1146  return 1;
1147}
1148
1149
1150void
1151sim_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
1160SIM_DESC
1161sim_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
1203void
1204sim_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
1214static void
1215load_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
1240SIM_RC
1241sim_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
1294SIM_RC
1295sim_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
1352void
1353sim_kill (sd)
1354     SIM_DESC sd;
1355{
1356  if (tracefile)
1357    fclose(tracefile);
1358}
1359
1360void
1361sim_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
1371void
1372sim_set_callbacks (ptr)
1373     host_callback * ptr;
1374{
1375  callback = ptr;
1376}
1377