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