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