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