OSDN Git Service

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