Whitespace cleanup
[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
370                     TRACE("inc");
371                     cpu.asregs.regs[a] = av + v;
372                   }
373                   break;
374                 case 0x01: /* dec */
375                   {
376                     int a = (inst >> 8) & 0xf;
377                     unsigned av = cpu.asregs.regs[a];
378                     unsigned v = (inst & 0xff);
379
380                     TRACE("dec");
381                     cpu.asregs.regs[a] = av - v;
382                   }
383                   break;
384                 case 0x02: /* gsr */
385                   {
386                     int a = (inst >> 8) & 0xf;
387                     unsigned v = (inst & 0xff);
388
389                     TRACE("gsr");
390                     cpu.asregs.regs[a] = cpu.asregs.sregs[v];
391                   }
392                   break;
393                 case 0x03: /* ssr */
394                   {
395                     int a = (inst >> 8) & 0xf;
396                     unsigned v = (inst & 0xff);
397
398                     TRACE("ssr");
399                     cpu.asregs.sregs[v] = cpu.asregs.regs[a];
400                   }
401                   break;
402                 default:
403                   TRACE("SIGILL2");
404                   cpu.asregs.exception = SIGILL;
405                   break;
406                 }
407             }
408         }
409       else
410         {
411           /* This is a Form 1 instruction.  */
412           int opcode = inst >> 8;
413           switch (opcode)
414             {
415             case 0x00: /* bad */
416               opc = opcode;
417               TRACE("SIGILL0");
418               cpu.asregs.exception = SIGILL;
419               break;
420             case 0x01: /* ldi.l (immediate) */
421               {
422                 int reg = (inst >> 4) & 0xf;
423
424                 TRACE("ldi.l");
425                 unsigned int val = EXTRACT_WORD(pc+2);
426                 cpu.asregs.regs[reg] = val;
427                 pc += 4;
428               }
429               break;
430             case 0x02: /* mov (register-to-register) */
431               {
432                 int dest  = (inst >> 4) & 0xf;
433                 int src = (inst ) & 0xf;
434
435                 TRACE("mov");
436                 cpu.asregs.regs[dest] = cpu.asregs.regs[src];
437               }
438               break;
439             case 0x03: /* jsra */
440               {
441                 unsigned int fn = EXTRACT_WORD(pc+2);
442                 unsigned int sp = cpu.asregs.regs[1];
443
444                 TRACE("jsra");
445                 /* Save a slot for the static chain.  */
446                 sp -= 4;
447
448                 /* Push the return address.  */
449                 sp -= 4;
450                 wlat (scpu, opc, sp, pc + 6);
451                 
452                 /* Push the current frame pointer.  */
453                 sp -= 4;
454                 wlat (scpu, opc, sp, cpu.asregs.regs[0]);
455  
456                 /* Uncache the stack pointer and set the pc and $fp.  */
457                 cpu.asregs.regs[1] = sp;
458                 cpu.asregs.regs[0] = sp;
459                 pc = fn - 2;
460               }
461               break;
462             case 0x04: /* ret */
463               {
464                 unsigned int sp = cpu.asregs.regs[0];
465
466                 TRACE("ret");
467  
468                 /* Pop the frame pointer.  */
469                 cpu.asregs.regs[0] = rlat (scpu, opc, sp);
470                 sp += 4;
471                 
472                 /* Pop the return address.  */
473                 pc = rlat (scpu, opc, sp) - 2;
474                 sp += 4;
475
476                 /* Skip over the static chain slot.  */
477                 sp += 4;
478  
479                 /* Uncache the stack pointer.  */
480                 cpu.asregs.regs[1] = sp;
481               }
482               break;
483             case 0x05: /* add.l */
484               {
485                 int a = (inst >> 4) & 0xf;
486                 int b = inst & 0xf;
487                 unsigned av = cpu.asregs.regs[a];
488                 unsigned bv = cpu.asregs.regs[b];
489
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
500                 TRACE("push");
501                 wlat (scpu, opc, sp, cpu.asregs.regs[b]);
502                 cpu.asregs.regs[a] = sp;
503               }
504               break;
505             case 0x07: /* pop */
506               {
507                 int a = (inst >> 4) & 0xf;
508                 int b = inst & 0xf;
509                 int sp = cpu.asregs.regs[a];
510
511                 TRACE("pop");
512                 cpu.asregs.regs[b] = rlat (scpu, opc, sp);
513                 cpu.asregs.regs[a] = sp + 4;
514               }
515               break;
516             case 0x08: /* lda.l */
517               {
518                 int reg = (inst >> 4) & 0xf;
519                 unsigned int addr = EXTRACT_WORD(pc+2);
520
521                 TRACE("lda.l");
522                 cpu.asregs.regs[reg] = rlat (scpu, opc, addr);
523                 pc += 4;
524               }
525               break;
526             case 0x09: /* sta.l */
527               {
528                 int reg = (inst >> 4) & 0xf;
529                 unsigned int addr = EXTRACT_WORD(pc+2);
530
531                 TRACE("sta.l");
532                 wlat (scpu, opc, addr, cpu.asregs.regs[reg]);
533                 pc += 4;
534               }
535               break;
536             case 0x0a: /* ld.l (register indirect) */
537               {
538                 int src  = inst & 0xf;
539                 int dest = (inst >> 4) & 0xf;
540                 int xv;
541
542                 TRACE("ld.l");
543                 xv = cpu.asregs.regs[src];
544                 cpu.asregs.regs[dest] = rlat (scpu, opc, xv);
545               }
546               break;
547             case 0x0b: /* st.l */
548               {
549                 int dest = (inst >> 4) & 0xf;
550                 int val  = inst & 0xf;
551
552                 TRACE("st.l");
553                 wlat (scpu, opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
554               }
555               break;
556             case 0x0c: /* ldo.l */
557               {
558                 unsigned int addr = EXTRACT_WORD(pc+2);
559                 int a = (inst >> 4) & 0xf;
560                 int b = inst & 0xf;
561
562                 TRACE("ldo.l");
563                 addr += cpu.asregs.regs[b];
564                 cpu.asregs.regs[a] = rlat (scpu, opc, addr);
565                 pc += 4;
566               }
567               break;
568             case 0x0d: /* sto.l */
569               {
570                 unsigned int addr = EXTRACT_WORD(pc+2);
571                 int a = (inst >> 4) & 0xf;
572                 int b = inst & 0xf;
573
574                 TRACE("sto.l");
575                 addr += cpu.asregs.regs[a];
576                 wlat (scpu, opc, addr, cpu.asregs.regs[b]);
577                 pc += 4;
578               }
579               break;
580             case 0x0e: /* cmp */
581               {
582                 int a  = (inst >> 4) & 0xf;
583                 int b  = inst & 0xf;
584                 int cc = 0;
585                 int va = cpu.asregs.regs[a];
586                 int vb = cpu.asregs.regs[b]; 
587
588                 TRACE("cmp");
589                 if (va == vb)
590                   cc = CC_EQ;
591                 else
592                   {
593                     cc |= (va < vb ? CC_LT : 0);
594                     cc |= (va > vb ? CC_GT : 0);
595                     cc |= ((unsigned int) va < (unsigned int) vb ? CC_LTU : 0);
596                     cc |= ((unsigned int) va > (unsigned int) vb ? CC_GTU : 0);
597                   }
598
599                 cpu.asregs.cc = cc;
600               }
601               break;
602             case 0x0f: /* nop */
603               break;
604             case 0x10: /* sex.b */
605               {
606                 int a = (inst >> 4) & 0xf;
607                 int b = inst & 0xf;
608                 signed char bv = cpu.asregs.regs[b];
609
610                 TRACE("sex.b");
611                 cpu.asregs.regs[a] = (int) bv;
612               }
613               break;
614             case 0x11: /* sex.s */
615               {
616                 int a = (inst >> 4) & 0xf;
617                 int b = inst & 0xf;
618                 signed short bv = cpu.asregs.regs[b];
619
620                 TRACE("sex.s");
621                 cpu.asregs.regs[a] = (int) bv;
622               }
623               break;
624             case 0x12: /* zex.b */
625               {
626                 int a = (inst >> 4) & 0xf;
627                 int b = inst & 0xf;
628                 signed char bv = cpu.asregs.regs[b];
629
630                 TRACE("zex.b");
631                 cpu.asregs.regs[a] = (int) bv & 0xff;
632               }
633               break;
634             case 0x13: /* zex.s */
635               {
636                 int a = (inst >> 4) & 0xf;
637                 int b = inst & 0xf;
638                 signed short bv = cpu.asregs.regs[b];
639
640                 TRACE("zex.s");
641                 cpu.asregs.regs[a] = (int) bv & 0xffff;
642               }
643               break;
644             case 0x14: /* mul.x */
645               {
646                 int a = (inst >> 4) & 0xf;
647                 int b = inst & 0xf;
648                 unsigned av = cpu.asregs.regs[a];
649                 unsigned bv = cpu.asregs.regs[b];
650                 signed long long r = 
651                   (signed long long) av * (signed long long) bv;
652
653                 TRACE("mul.x");
654                 cpu.asregs.regs[a] = r >> 32;
655               }
656               break;
657             case 0x15: /* umul.x */
658               {
659                 int a = (inst >> 4) & 0xf;
660                 int b = inst & 0xf;
661                 unsigned av = cpu.asregs.regs[a];
662                 unsigned bv = cpu.asregs.regs[b];
663                 unsigned long long r = 
664                   (unsigned long long) av * (unsigned long long) bv;
665
666                 TRACE("umul.x");
667                 cpu.asregs.regs[a] = r >> 32;
668               }
669               break;
670             case 0x16: /* bad */
671             case 0x17: /* bad */
672             case 0x18: /* bad */
673               {
674                 opc = opcode;
675                 TRACE("SIGILL0");
676                 cpu.asregs.exception = SIGILL;
677                 break;
678               }
679             case 0x19: /* jsr */
680               {
681                 unsigned int fn = cpu.asregs.regs[(inst >> 4) & 0xf];
682                 unsigned int sp = cpu.asregs.regs[1];
683
684                 TRACE("jsr");
685
686                 /* Save a slot for the static chain.  */
687                 sp -= 4;
688
689                 /* Push the return address.  */
690                 sp -= 4;
691                 wlat (scpu, opc, sp, pc + 2);
692                 
693                 /* Push the current frame pointer.  */
694                 sp -= 4;
695                 wlat (scpu, opc, sp, cpu.asregs.regs[0]);
696
697                 /* Uncache the stack pointer and set the fp & pc.  */
698                 cpu.asregs.regs[1] = sp;
699                 cpu.asregs.regs[0] = sp;
700                 pc = fn - 2;
701               }
702               break;
703             case 0x1a: /* jmpa */
704               {
705                 unsigned int tgt = EXTRACT_WORD(pc+2);
706
707                 TRACE("jmpa");
708                 pc = tgt - 2;
709               }
710               break;
711             case 0x1b: /* ldi.b (immediate) */
712               {
713                 int reg = (inst >> 4) & 0xf;
714                 unsigned int val = EXTRACT_WORD(pc+2);
715
716                 TRACE("ldi.b");
717                 cpu.asregs.regs[reg] = val;
718                 pc += 4;
719               }
720               break;
721             case 0x1c: /* ld.b (register indirect) */
722               {
723                 int src  = inst & 0xf;
724                 int dest = (inst >> 4) & 0xf;
725                 int xv;
726
727                 TRACE("ld.b");
728                 xv = cpu.asregs.regs[src];
729                 cpu.asregs.regs[dest] = rbat (scpu, opc, xv);
730               }
731               break;
732             case 0x1d: /* lda.b */
733               {
734                 int reg = (inst >> 4) & 0xf;
735                 unsigned int addr = EXTRACT_WORD(pc+2);
736
737                 TRACE("lda.b");
738                 cpu.asregs.regs[reg] = rbat (scpu, opc, addr);
739                 pc += 4;
740               }
741               break;
742             case 0x1e: /* st.b */
743               {
744                 int dest = (inst >> 4) & 0xf;
745                 int val  = inst & 0xf;
746
747                 TRACE("st.b");
748                 wbat (scpu, opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
749               }
750               break;
751             case 0x1f: /* sta.b */
752               {
753                 int reg = (inst >> 4) & 0xf;
754                 unsigned int addr = EXTRACT_WORD(pc+2);
755
756                 TRACE("sta.b");
757                 wbat (scpu, opc, addr, cpu.asregs.regs[reg]);
758                 pc += 4;
759               }
760               break;
761             case 0x20: /* ldi.s (immediate) */
762               {
763                 int reg = (inst >> 4) & 0xf;
764
765                 unsigned int val = EXTRACT_WORD(pc+2);
766
767                 TRACE("ldi.s");
768                 cpu.asregs.regs[reg] = val;
769                 pc += 4;
770               }
771               break;
772             case 0x21: /* ld.s (register indirect) */
773               {
774                 int src  = inst & 0xf;
775                 int dest = (inst >> 4) & 0xf;
776                 int xv;
777
778                 TRACE("ld.s");
779                 xv = cpu.asregs.regs[src];
780                 cpu.asregs.regs[dest] = rsat (scpu, opc, xv);
781               }
782               break;
783             case 0x22: /* lda.s */
784               {
785                 int reg = (inst >> 4) & 0xf;
786                 unsigned int addr = EXTRACT_WORD(pc+2);
787
788                 TRACE("lda.s");
789                 cpu.asregs.regs[reg] = rsat (scpu, opc, addr);
790                 pc += 4;
791               }
792               break;
793             case 0x23: /* st.s */
794               {
795                 int dest = (inst >> 4) & 0xf;
796                 int val  = inst & 0xf;
797
798                 TRACE("st.s");
799                 wsat (scpu, opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
800               }
801               break;
802             case 0x24: /* sta.s */
803               {
804                 int reg = (inst >> 4) & 0xf;
805                 unsigned int addr = EXTRACT_WORD(pc+2);
806
807                 TRACE("sta.s");
808                 wsat (scpu, opc, addr, cpu.asregs.regs[reg]);
809                 pc += 4;
810               }
811               break;
812             case 0x25: /* jmp */
813               {
814                 int reg = (inst >> 4) & 0xf;
815
816                 TRACE("jmp");
817                 pc = cpu.asregs.regs[reg] - 2;
818               }
819               break;
820             case 0x26: /* and */
821               {
822                 int a = (inst >> 4) & 0xf;
823                 int b = inst & 0xf;
824                 int av, bv;
825
826                 TRACE("and");
827                 av = cpu.asregs.regs[a];
828                 bv = cpu.asregs.regs[b];
829                 cpu.asregs.regs[a] = av & bv;
830               }
831               break;
832             case 0x27: /* lshr */
833               {
834                 int a = (inst >> 4) & 0xf;
835                 int b = inst & 0xf;
836                 int av = cpu.asregs.regs[a];
837                 int bv = cpu.asregs.regs[b];
838
839                 TRACE("lshr");
840                 cpu.asregs.regs[a] = (unsigned) ((unsigned) av >> bv);
841               }
842               break;
843             case 0x28: /* ashl */
844               {
845                 int a = (inst >> 4) & 0xf;
846                 int b = inst & 0xf;
847                 int av = cpu.asregs.regs[a];
848                 int bv = cpu.asregs.regs[b];
849
850                 TRACE("ashl");
851                 cpu.asregs.regs[a] = av << bv;
852               }
853               break;
854             case 0x29: /* sub.l */
855               {
856                 int a = (inst >> 4) & 0xf;
857                 int b = inst & 0xf;
858                 unsigned av = cpu.asregs.regs[a];
859                 unsigned bv = cpu.asregs.regs[b];
860
861                 TRACE("sub.l");
862                 cpu.asregs.regs[a] = av - bv;
863               }
864               break;
865             case 0x2a: /* neg */
866               {
867                 int a  = (inst >> 4) & 0xf;
868                 int b  = inst & 0xf;
869                 int bv = cpu.asregs.regs[b];
870
871                 TRACE("neg");
872                 cpu.asregs.regs[a] = - bv;
873               }
874               break;
875             case 0x2b: /* or */
876               {
877                 int a = (inst >> 4) & 0xf;
878                 int b = inst & 0xf;
879                 int av, bv;
880
881                 TRACE("or");
882                 av = cpu.asregs.regs[a];
883                 bv = cpu.asregs.regs[b];
884                 cpu.asregs.regs[a] = av | bv;
885               }
886               break;
887             case 0x2c: /* not */
888               {
889                 int a = (inst >> 4) & 0xf;
890                 int b = inst & 0xf;
891                 int bv = cpu.asregs.regs[b];
892
893                 TRACE("not");
894                 cpu.asregs.regs[a] = 0xffffffff ^ bv;
895               }
896               break;
897             case 0x2d: /* ashr */
898               {
899                 int a  = (inst >> 4) & 0xf;
900                 int b  = inst & 0xf;
901                 int av = cpu.asregs.regs[a];
902                 int bv = cpu.asregs.regs[b];
903
904                 TRACE("ashr");
905                 cpu.asregs.regs[a] = av >> bv;
906               }
907               break;
908             case 0x2e: /* xor */
909               {
910                 int a = (inst >> 4) & 0xf;
911                 int b = inst & 0xf;
912                 int av, bv;
913
914                 TRACE("xor");
915                 av = cpu.asregs.regs[a];
916                 bv = cpu.asregs.regs[b];
917                 cpu.asregs.regs[a] = av ^ bv;
918               }
919               break;
920             case 0x2f: /* mul.l */
921               {
922                 int a = (inst >> 4) & 0xf;
923                 int b = inst & 0xf;
924                 unsigned av = cpu.asregs.regs[a];
925                 unsigned bv = cpu.asregs.regs[b];
926
927                 TRACE("mul.l");
928                 cpu.asregs.regs[a] = av * bv;
929               }
930               break;
931             case 0x30: /* swi */
932               {
933                 unsigned int inum = EXTRACT_WORD(pc+2);
934
935                 TRACE("swi");
936                 /* Set the special registers appropriately.  */
937                 cpu.asregs.sregs[2] = 3; /* MOXIE_EX_SWI */
938                 cpu.asregs.sregs[3] = inum;
939                 switch (inum)
940                   {
941                   case 0x1: /* SYS_exit */
942                     {
943                       cpu.asregs.exception = SIGQUIT;
944                       break;
945                     }
946                   case 0x2: /* SYS_open */
947                     {
948                       char fname[1024];
949                       int mode = (int) convert_target_flags ((unsigned) cpu.asregs.regs[3]);
950                       int perm = (int) cpu.asregs.regs[4];
951                       int fd = open (fname, mode, perm);
952                       sim_core_read_buffer (sd, scpu, read_map, fname,
953                                             cpu.asregs.regs[2], 1024);
954                       /* FIXME - set errno */
955                       cpu.asregs.regs[2] = fd;
956                       break;
957                     }
958                   case 0x4: /* SYS_read */
959                     {
960                       int fd = cpu.asregs.regs[2];
961                       unsigned len = (unsigned) cpu.asregs.regs[4];
962                       char *buf = malloc (len);
963                       cpu.asregs.regs[2] = read (fd, buf, len);
964                       sim_core_write_buffer (sd, scpu, write_map, buf,
965                                              cpu.asregs.regs[3], len);
966                       free (buf);
967                       break;
968                     }
969                   case 0x5: /* SYS_write */
970                     {
971                       char *str;
972                       /* String length is at 0x12($fp) */
973                       unsigned count, len = (unsigned) cpu.asregs.regs[4];
974                       str = malloc (len);
975                       sim_core_read_buffer (sd, scpu, read_map, str,
976                                             cpu.asregs.regs[3], len);
977                       count = write (cpu.asregs.regs[2], str, len);
978                       free (str);
979                       cpu.asregs.regs[2] = count;
980                       break;
981                     }
982                   case 0xffffffff: /* Linux System Call */
983                     {
984                       unsigned int handler = cpu.asregs.sregs[1];
985                       unsigned int sp = cpu.asregs.regs[1];
986
987                       /* Save a slot for the static chain.  */
988                       sp -= 4;
989
990                       /* Push the return address.  */
991                       sp -= 4;
992                       wlat (scpu, opc, sp, pc + 6);
993                 
994                       /* Push the current frame pointer.  */
995                       sp -= 4;
996                       wlat (scpu, opc, sp, cpu.asregs.regs[0]);
997
998                       /* Uncache the stack pointer and set the fp & pc.  */
999                       cpu.asregs.regs[1] = sp;
1000                       cpu.asregs.regs[0] = sp;
1001                       pc = handler - 6;
1002                     }
1003                   default:
1004                     break;
1005                   }
1006                 pc += 4;
1007               }
1008               break;
1009             case 0x31: /* div.l */
1010               {
1011                 int a = (inst >> 4) & 0xf;
1012                 int b = inst & 0xf;
1013                 int av = cpu.asregs.regs[a];
1014                 int bv = cpu.asregs.regs[b];
1015
1016                 TRACE("div.l");
1017                 cpu.asregs.regs[a] = av / bv;
1018               }
1019               break;
1020             case 0x32: /* udiv.l */
1021               {
1022                 int a = (inst >> 4) & 0xf;
1023                 int b = inst & 0xf;
1024                 unsigned int av = cpu.asregs.regs[a];
1025                 unsigned int bv = cpu.asregs.regs[b];
1026
1027                 TRACE("udiv.l");
1028                 cpu.asregs.regs[a] = (av / bv);
1029               }
1030               break;
1031             case 0x33: /* mod.l */
1032               {
1033                 int a = (inst >> 4) & 0xf;
1034                 int b = inst & 0xf;
1035                 int av = cpu.asregs.regs[a];
1036                 int bv = cpu.asregs.regs[b];
1037
1038                 TRACE("mod.l");
1039                 cpu.asregs.regs[a] = av % bv;
1040               }
1041               break;
1042             case 0x34: /* umod.l */
1043               {
1044                 int a = (inst >> 4) & 0xf;
1045                 int b = inst & 0xf;
1046                 unsigned int av = cpu.asregs.regs[a];
1047                 unsigned int bv = cpu.asregs.regs[b];
1048
1049                 TRACE("umod.l");
1050                 cpu.asregs.regs[a] = (av % bv);
1051               }
1052               break;
1053             case 0x35: /* brk */
1054               TRACE("brk");
1055               cpu.asregs.exception = SIGTRAP;
1056               pc -= 2; /* Adjust pc */
1057               break;
1058             case 0x36: /* ldo.b */
1059               {
1060                 unsigned int addr = EXTRACT_WORD(pc+2);
1061                 int a = (inst >> 4) & 0xf;
1062                 int b = inst & 0xf;
1063
1064                 TRACE("ldo.b");
1065                 addr += cpu.asregs.regs[b];
1066                 cpu.asregs.regs[a] = rbat (scpu, opc, addr);
1067                 pc += 4;
1068               }
1069               break;
1070             case 0x37: /* sto.b */
1071               {
1072                 unsigned int addr = EXTRACT_WORD(pc+2);
1073                 int a = (inst >> 4) & 0xf;
1074                 int b = inst & 0xf;
1075
1076                 TRACE("sto.b");
1077                 addr += cpu.asregs.regs[a];
1078                 wbat (scpu, opc, addr, cpu.asregs.regs[b]);
1079                 pc += 4;
1080               }
1081               break;
1082             case 0x38: /* ldo.s */
1083               {
1084                 unsigned int addr = EXTRACT_WORD(pc+2);
1085                 int a = (inst >> 4) & 0xf;
1086                 int b = inst & 0xf;
1087
1088                 TRACE("ldo.s");
1089                 addr += cpu.asregs.regs[b];
1090                 cpu.asregs.regs[a] = rsat (scpu, opc, addr);
1091                 pc += 4;
1092               }
1093               break;
1094             case 0x39: /* sto.s */
1095               {
1096                 unsigned int addr = EXTRACT_WORD(pc+2);
1097                 int a = (inst >> 4) & 0xf;
1098                 int b = inst & 0xf;
1099
1100                 TRACE("sto.s");
1101                 addr += cpu.asregs.regs[a];
1102                 wsat (scpu, opc, addr, cpu.asregs.regs[b]);
1103                 pc += 4;
1104               }
1105               break;
1106             default:
1107               opc = opcode;
1108               TRACE("SIGILL1");
1109               cpu.asregs.exception = SIGILL;
1110               break;
1111             }
1112         }
1113
1114       insts++;
1115       pc += 2;
1116
1117     } while (!cpu.asregs.exception);
1118
1119   /* Hide away the things we've cached while executing.  */
1120   cpu.asregs.regs[PC_REGNO] = pc;
1121   cpu.asregs.insts += insts;            /* instructions done ... */
1122 }
1123
1124 int
1125 sim_write (sd, addr, buffer, size)
1126      SIM_DESC sd;
1127      SIM_ADDR addr;
1128      const unsigned char * buffer;
1129      int size;
1130 {
1131   sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
1132
1133   sim_core_write_buffer (sd, scpu, write_map, buffer, addr, size);
1134
1135   return size;
1136 }
1137
1138 int
1139 sim_read (sd, addr, buffer, size)
1140      SIM_DESC sd;
1141      SIM_ADDR addr;
1142      unsigned char * buffer;
1143      int size;
1144 {
1145   sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
1146
1147   sim_core_read_buffer (sd, scpu, read_map, buffer, addr, size);
1148   
1149   return size;
1150 }
1151
1152
1153 int
1154 sim_store_register (sd, rn, memory, length)
1155      SIM_DESC sd;
1156      int rn;
1157      unsigned char * memory;
1158      int length;
1159 {
1160   if (rn < NUM_MOXIE_REGS && rn >= 0)
1161     {
1162       if (length == 4)
1163         {
1164           long ival;
1165           
1166           /* misalignment safe */
1167           ival = moxie_extract_unsigned_integer (memory, 4);
1168           cpu.asints[rn] = ival;
1169         }
1170
1171       return 4;
1172     }
1173   else
1174     return 0;
1175 }
1176
1177 int
1178 sim_fetch_register (sd, rn, memory, length)
1179      SIM_DESC sd;
1180      int rn;
1181      unsigned char * memory;
1182      int length;
1183 {
1184   if (rn < NUM_MOXIE_REGS && rn >= 0)
1185     {
1186       if (length == 4)
1187         {
1188           long ival = cpu.asints[rn];
1189
1190           /* misalignment-safe */
1191           moxie_store_unsigned_integer (memory, 4, ival);
1192         }
1193       
1194       return 4;
1195     }
1196   else
1197     return 0;
1198 }
1199
1200
1201 int
1202 sim_trace (sd)
1203      SIM_DESC sd;
1204 {
1205   if (tracefile == 0)
1206     tracefile = fopen("trace.csv", "wb");
1207
1208   tracing = 1;
1209   
1210   sim_resume (sd, 0, 0);
1211
1212   tracing = 0;
1213   
1214   return 1;
1215 }
1216
1217 void
1218 sim_stop_reason (sd, reason, sigrc)
1219      SIM_DESC sd;
1220      enum sim_stop * reason;
1221      int * sigrc;
1222 {
1223   if (cpu.asregs.exception == SIGQUIT)
1224     {
1225       * reason = sim_exited;
1226       * sigrc = cpu.asregs.regs[2];
1227     }
1228   else
1229     {
1230       * reason = sim_stopped;
1231       * sigrc = cpu.asregs.exception;
1232     }
1233 }
1234
1235
1236 int
1237 sim_stop (sd)
1238      SIM_DESC sd;
1239 {
1240   cpu.asregs.exception = SIGINT;
1241   return 1;
1242 }
1243
1244
1245 void
1246 sim_info (sd, verbose)
1247      SIM_DESC sd;
1248      int verbose;
1249 {
1250   callback->printf_filtered (callback, "\n\n# instructions executed  %llu\n",
1251                              cpu.asregs.insts);
1252 }
1253
1254
1255 SIM_DESC
1256 sim_open (kind, cb, abfd, argv)
1257      SIM_OPEN_KIND kind;
1258      host_callback * cb;
1259      struct bfd * abfd;
1260      char ** argv;
1261 {
1262   SIM_DESC sd = sim_state_alloc (kind, cb);
1263   SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
1264
1265   if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
1266     return 0;
1267
1268   sim_do_command(sd," memory region 0x00000000,0x4000000") ; 
1269   sim_do_command(sd," memory region 0xE0000000,0x10000") ; 
1270
1271   myname = argv[0];
1272   callback = cb;
1273   
1274   if (kind == SIM_OPEN_STANDALONE)
1275     issue_messages = 1;
1276   
1277   set_initial_gprs ();  /* Reset the GPR registers.  */
1278   
1279   /* Configure/verify the target byte order and other runtime
1280      configuration options.  */
1281   if (sim_config (sd) != SIM_RC_OK)
1282     {
1283       sim_module_uninstall (sd);
1284       return 0;
1285     }
1286
1287   if (sim_post_argv_init (sd) != SIM_RC_OK)
1288     {
1289       /* Uninstall the modules to avoid memory leaks,
1290          file descriptor leaks, etc.  */
1291       sim_module_uninstall (sd);
1292       return 0;
1293     }
1294
1295   return sd;
1296 }
1297
1298 void
1299 sim_close (sd, quitting)
1300      SIM_DESC sd;
1301      int quitting;
1302 {
1303   /* nothing to do */
1304 }
1305
1306
1307 /* Load the device tree blob.  */
1308
1309 static void
1310 load_dtb (SIM_DESC sd, const char *filename)
1311 {
1312   int size = 0;
1313   FILE *f = fopen (filename, "rb");
1314   char *buf;
1315   sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */ 
1316  if (f == NULL)
1317     {
1318       printf ("WARNING: ``%s'' could not be opened.\n", filename);
1319       return;
1320     }
1321   fseek (f, 0, SEEK_END);
1322   size = ftell(f);
1323   fseek (f, 0, SEEK_SET);
1324   buf = alloca (size);
1325   if (size != fread (buf, 1, size, f))
1326     {
1327       printf ("ERROR: error reading ``%s''.\n", filename);
1328       return;
1329     }
1330   sim_core_write_buffer (sd, scpu, write_map, buf, 0xE0000000, size);
1331   cpu.asregs.sregs[9] = 0xE0000000;
1332   fclose (f);
1333 }
1334
1335 SIM_RC
1336 sim_load (sd, prog, abfd, from_tty)
1337      SIM_DESC sd;
1338      const char * prog;
1339      bfd * abfd;
1340      int from_tty;
1341 {
1342
1343   /* Do the right thing for ELF executables; this turns out to be
1344      just about the right thing for any object format that:
1345        - we crack using BFD routines
1346        - follows the traditional UNIX text/data/bss layout
1347        - calls the bss section ".bss".   */
1348
1349   extern bfd * sim_load_file (); /* ??? Don't know where this should live.  */
1350   bfd * prog_bfd;
1351
1352   {
1353     bfd * handle;
1354     handle = bfd_openr (prog, 0);       /* could be "moxie" */
1355     
1356     if (!handle)
1357       {
1358         printf("``%s'' could not be opened.\n", prog);
1359         return SIM_RC_FAIL;
1360       }
1361     
1362     /* Makes sure that we have an object file, also cleans gets the 
1363        section headers in place.  */
1364     if (!bfd_check_format (handle, bfd_object))
1365       {
1366         /* wasn't an object file */
1367         bfd_close (handle);
1368         printf ("``%s'' is not appropriate object file.\n", prog);
1369         return SIM_RC_FAIL;
1370       }
1371
1372     /* Clean up after ourselves.  */
1373     bfd_close (handle);
1374   }
1375
1376   /* from sh -- dac */
1377   prog_bfd = sim_load_file (sd, myname, callback, prog, abfd,
1378                             sim_kind == SIM_OPEN_DEBUG,
1379                             0, sim_write);
1380   if (prog_bfd == NULL)
1381     return SIM_RC_FAIL;
1382   
1383   if (abfd == NULL)
1384     bfd_close (prog_bfd);
1385
1386   return SIM_RC_OK;
1387 }
1388
1389 SIM_RC
1390 sim_create_inferior (sd, prog_bfd, argv, env)
1391      SIM_DESC sd;
1392      struct bfd * prog_bfd;
1393      char ** argv;
1394      char ** env;
1395 {
1396   char ** avp;
1397   int l, argc, i, tp;
1398   sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
1399
1400   /* Set the initial register set.  */
1401   l = issue_messages;
1402   issue_messages = 0;
1403   set_initial_gprs ();
1404   issue_messages = l;
1405   
1406   if (prog_bfd != NULL)
1407     cpu.asregs.regs[PC_REGNO] = bfd_get_start_address (prog_bfd);
1408
1409   /* Copy args into target memory.  */
1410   avp = argv;
1411   for (argc = 0; avp && *avp; avp++)
1412     argc++;
1413
1414   /* Target memory looks like this:
1415      0x00000000 zero word
1416      0x00000004 argc word
1417      0x00000008 start of argv
1418      .
1419      0x0000???? end of argv
1420      0x0000???? zero word 
1421      0x0000???? start of data pointed to by argv  */
1422
1423   wlat (scpu, 0, 0, 0);
1424   wlat (scpu, 0, 4, argc);
1425
1426   /* tp is the offset of our first argv data.  */
1427   tp = 4 + 4 + argc * 4 + 4;
1428
1429   for (i = 0; i < argc; i++)
1430     {
1431       /* Set the argv value.  */
1432       wlat (scpu, 0, 4 + 4 + i * 4, tp);
1433
1434       /* Store the string.  */
1435       sim_core_write_buffer (sd, scpu, write_map, argv[i],
1436                              tp, strlen(argv[i])+1);
1437       tp += strlen (argv[i]) + 1;
1438     }
1439
1440   wlat (scpu, 0, 4 + 4 + i * 4, 0);
1441
1442   load_dtb (sd, DTB);
1443
1444   return SIM_RC_OK;
1445 }
1446
1447 void
1448 sim_kill (sd)
1449      SIM_DESC sd;
1450 {
1451   if (tracefile)
1452     fclose(tracefile);
1453 }
1454
1455 void
1456 sim_do_command (sd, cmd)
1457      SIM_DESC sd;
1458      const char *cmd;
1459 {
1460   if (sim_args_command (sd, cmd) != SIM_RC_OK)
1461     sim_io_printf (sd, 
1462                    "Error: \"%s\" is not a valid moxie simulator command.\n",
1463                    cmd);
1464 }
1465
1466 void
1467 sim_set_callbacks (ptr)
1468      host_callback * ptr;
1469 {
1470   callback = ptr; 
1471 }