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