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