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