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