1 /* Simulator for the moxie processor
2    Copyright (C) 2008, 2009, 2010, 2011 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 <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 
34 typedef int word;
35 typedef unsigned int uword;
36 
37 host_callback *       callback;
38 
39 FILE *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 
51 unsigned long
moxie_extract_unsigned_integer(addr,len)52 moxie_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 
75 void
moxie_store_unsigned_integer(addr,len,val)76 moxie_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.  */
93 static 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.  */
112 struct 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 
127 union
128 {
129   struct moxie_regset asregs;
130   word asints [1];		/* but accessed larger... */
131 } cpu;
132 
133 static char *myname;
134 static SIM_OPEN_KIND sim_kind;
135 static int issue_messages = 0;
136 
137 void
sim_size(int s)138 sim_size (int s)
139 {
140 }
141 
142 static void
set_initial_gprs()143 set_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 
158 static void
interrupt()159 interrupt ()
160 {
161   cpu.asregs.exception = SIGINT;
162 }
163 
164 /* Write a 1 byte value to memory.  */
165 
166 static void INLINE
wbat(sim_cpu * scpu,word pc,word x,word v)167 wbat (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 
176 static void INLINE
wsat(sim_cpu * scpu,word pc,word x,word v)177 wsat (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 
186 static void INLINE
wlat(sim_cpu * scpu,word pc,word x,word v)187 wlat (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 
196 static int INLINE
rsat(sim_cpu * scpu,word pc,word x)197 rsat (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 
206 static int INLINE
rbat(sim_cpu * scpu,word pc,word x)207 rbat (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 
216 static int INLINE
rlat(sim_cpu * scpu,word pc,word x)217 rlat (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 
226 unsigned int
convert_target_flags(unsigned int tflags)227 convert_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 
249 static int tracing = 0;
250 
251 void
sim_resume(sd,step,siggnal)252 sim_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 
1027 int
sim_write(sd,addr,buffer,size)1028 sim_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 
1041 int
sim_read(sd,addr,buffer,size)1042 sim_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 
1056 int
sim_store_register(sd,rn,memory,length)1057 sim_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 
1080 int
sim_fetch_register(sd,rn,memory,length)1081 sim_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 
1104 int
sim_trace(sd)1105 sim_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 
1120 void
sim_stop_reason(sd,reason,sigrc)1121 sim_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 
1139 int
sim_stop(sd)1140 sim_stop (sd)
1141      SIM_DESC sd;
1142 {
1143   cpu.asregs.exception = SIGINT;
1144   return 1;
1145 }
1146 
1147 
1148 void
sim_info(sd,verbose)1149 sim_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 
1158 SIM_DESC
sim_open(kind,cb,abfd,argv)1159 sim_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 
1202 void
sim_close(sd,quitting)1203 sim_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 
1213 static void
load_dtb(SIM_DESC sd,const char * filename)1214 load_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 
1239 SIM_RC
sim_load(sd,prog,abfd,from_tty)1240 sim_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 
1293 SIM_RC
sim_create_inferior(sd,prog_bfd,argv,env)1294 sim_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 
1351 void
sim_kill(sd)1352 sim_kill (sd)
1353      SIM_DESC sd;
1354 {
1355   if (tracefile)
1356     fclose(tracefile);
1357 }
1358 
1359 void
sim_do_command(sd,cmd)1360 sim_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 
1370 void
sim_set_callbacks(ptr)1371 sim_set_callbacks (ptr)
1372      host_callback * ptr;
1373 {
1374   callback = ptr;
1375 }
1376