Thu Aug 1 17:05:24 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
[platform/upstream/binutils.git] / sim / d10v / interp.c
1 #include "sysdep.h"
2 #include "bfd.h"
3 #include "remote-sim.h"
4 #include "callback.h"
5
6 #include "d10v_sim.h"
7
8 #define IMEM_SIZE 18    /* D10V instruction memory size is 18 bits */
9 #define DMEM_SIZE 16    /* Data memory */
10
11 uint16 OP[4];
12
13 static struct hash_entry *lookup_hash PARAMS ((uint32 ins, int size));
14
15 #define MAX_HASH  63
16 struct hash_entry
17 {
18   struct hash_entry *next;
19   long opcode;
20   long mask;
21   struct simops *ops;
22 };
23
24 struct hash_entry hash_table[MAX_HASH+1];
25
26 static long 
27 hash(insn, format)
28      long insn;
29      int format;
30 {
31   if (format & LONG_OPCODE)
32     return ((insn & 0x3F000000) >> 24);
33   else
34     return((insn & 0x7E00) >> 9);
35 }
36
37 static struct hash_entry *
38 lookup_hash (ins, size)
39      uint32 ins;
40      int size;
41 {
42   struct hash_entry *h;
43
44   if (size)
45     h = &hash_table[(ins & 0x3F000000) >> 24];
46   else
47     h = &hash_table[(ins & 0x7E00) >> 9];
48
49   while ( (ins & h->mask) != h->opcode)
50     {
51       if (h->next == NULL)
52         {
53           printf ("ERROR looking up hash for %x\n",ins);
54           exit(1);
55         }
56       h = h->next;
57     }
58   return (h);
59 }
60
61 uint32
62 get_longword_swap (x)
63       uint16 x;
64 {
65   uint8 *a = (uint8 *)(x + State.imem);
66   return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + (a[3]);
67 }
68
69 uint16
70 get_word_swap (x)
71       uint16 x;
72 {
73   uint8 *a = (uint8 *)(x + State.imem);
74   return (a[0]<<8) + a[1];
75 }
76
77 void
78 write_word_swap (addr, data)
79      uint16 addr, data;
80 {
81   uint8 *a = (uint8 *)(addr + State.imem);
82   a[0] = data >> 8;
83   a[1] = data & 0xff;
84 }
85
86
87 static void
88 get_operands (struct simops *s, uint32 ins)
89 {
90   int i, shift, bits, flags;
91   uint32 mask;
92   for (i=0; i < s->numops; i++)
93     {
94       shift = s->operands[3*i];
95       bits = s->operands[3*i+1];
96       flags = s->operands[3*i+2];
97       mask = 0x7FFFFFFF >> (31 - bits);
98       OP[i] = (ins >> shift) & mask;
99     }
100 }
101
102 static void
103 do_long (ins)
104      uint32 ins;
105 {
106   struct hash_entry *h;
107   /*  printf ("do_long %x\n",ins); */
108   h = lookup_hash (ins, 1);
109   get_operands (h->ops, ins);
110   (h->ops->func)();
111 }
112 static void
113 do_2_short (ins1, ins2)
114      uint16 ins1, ins2;
115 {
116   struct hash_entry *h;
117   /*  printf ("do_2_short %x -> %x\n",ins1,ins2); */
118   h = lookup_hash (ins1, 0);
119   get_operands (h->ops, ins1);
120   (h->ops->func)();
121   h = lookup_hash (ins2, 0);
122   get_operands (h->ops, ins2);
123   (h->ops->func)();
124 }
125 static void
126 do_parallel (ins1, ins2)
127      uint16 ins1, ins2;
128 {
129   struct hash_entry *h1, *h2;
130   /*  printf ("do_parallel %x || %x\n",ins1,ins2); */
131   h1 = lookup_hash (ins1, 0);
132   get_operands (h1->ops, ins1);
133   h2 = lookup_hash (ins2, 0);
134   get_operands (h2->ops, ins2);
135   if (h1->ops->exec_type == PARONLY)
136     {
137       (h1->ops->func)();
138       if (State.exe)
139         (h2->ops->func)();
140     }
141   else if (h2->ops->exec_type == PARONLY)
142     {
143       (h2->ops->func)();
144       if (State.exe)
145         (h1->ops->func)();
146     }
147   else
148     {
149       (h1->ops->func)();
150       (h2->ops->func)();
151     }
152 }
153  
154
155 void
156 sim_size (power)
157      int power;
158
159 {
160   if (State.imem)
161     {
162       free (State.imem);
163       free (State.dmem);
164     }
165
166   State.imem = (uint8 *)calloc(1,1<<IMEM_SIZE);
167   State.dmem = (uint8 *)calloc(1,1<<DMEM_SIZE);
168   if (!State.imem || !State.dmem )
169     {
170       fprintf (stderr,"Memory allocation failed.\n");
171       exit(1);
172     }
173   printf ("Allocated %d bytes instruction memory and\n",1<<IMEM_SIZE);
174   printf ("          %d bytes data memory.\n",1<<DMEM_SIZE);
175 }
176
177 static void
178 init_system ()
179 {
180   if (!State.imem)
181     sim_size(1);
182 }
183
184 int
185 sim_write (addr, buffer, size)
186      SIM_ADDR addr;
187      unsigned char *buffer;
188      int size;
189 {
190   int i;
191   init_system ();
192
193   printf ("sim_write %d bytes to 0x%x\n",size,addr);
194   for (i = 0; i < size; i++)
195     {
196       State.imem[i+addr] = buffer[i]; 
197     }
198   return size;
199 }
200
201 void
202 sim_open (args)
203      char *args;
204 {
205   struct simops *s;
206   struct hash_entry *h, *prev;
207   if (args != NULL)
208       printf ("sim_open %s\n",args);
209
210   /* put all the opcodes in the hash table */
211   for (s = Simops; s->func; s++)
212     {
213       h = &hash_table[hash(s->opcode,s->format)];
214       
215       /* go to the last entry in the chain */
216       while (h->next)
217           h = h->next;
218
219       if (h->ops)
220         {
221           h->next = calloc(1,sizeof(struct hash_entry));
222           h = h->next;
223         }
224       h->ops = s;
225       h->mask = s->mask;
226       h->opcode = s->opcode;
227     }
228 }
229
230
231 void
232 sim_close (quitting)
233      int quitting;
234 {
235   /* nothing to do */
236 }
237
238 void
239 sim_set_profile (n)
240      int n;
241 {
242   printf ("sim_set_profile %d\n",n);
243 }
244
245 void
246 sim_set_profile_size (n)
247      int n;
248 {
249   printf ("sim_set_profile_size %d\n",n);
250 }
251
252 void
253 sim_resume (step, siggnal)
254      int step, siggnal;
255 {
256   uint32 inst;
257   int i;
258   reg_t oldpc;
259
260   printf ("sim_resume %d %d\n",step,siggnal);
261
262   while (1)
263     {
264       inst = RLW (PC << 2);
265       oldpc = PC;
266       switch (inst & 0xC0000000)
267         {
268         case 0xC0000000:
269           /* long instruction */
270           do_long (inst & 0x3FFFFFFF);
271           break;
272         case 0x80000000:
273           /* R -> L */
274           do_2_short ( inst & 0x7FFF, (inst & 0x3FFF8000) >> 15);
275           break;
276         case 0x40000000:
277           /* L -> R */
278           do_2_short ((inst & 0x3FFF8000) >> 15, inst & 0x7FFF);
279           break;
280         case 0:
281           do_parallel ((inst & 0x3FFF8000) >> 15, inst & 0x7FFF);
282           break;
283         }
284
285       if (State.RP && PC == RPT_E)
286         {
287           RPT_C -= 1;
288           if (RPT_C == 0)
289             State.RP = 0;
290           else
291             PC = RPT_S;
292         }
293
294       /* FIXME */
295       if (PC == oldpc)
296         PC++;
297     }
298 }
299
300 int
301 sim_trace ()
302 {
303   printf ("sim_trace\n");
304   return 0;
305 }
306
307 void
308 sim_info (verbose)
309      int verbose;
310 {
311   printf ("sim_verbose\n");
312 }
313
314 void
315 sim_create_inferior (start_address, argv, env)
316      SIM_ADDR start_address;
317      char **argv;
318      char **env;
319 {
320   printf ("sim_create_inferior:  PC=0x%x\n",start_address);
321   PC = start_address >> 2;
322 }
323
324
325 void
326 sim_kill ()
327 {
328   /* nothing to do */
329 }
330
331 void
332 sim_set_callbacks(p)
333      host_callback *p;
334 {
335   printf ("sim_set_callbacks\n");
336   /* callback = p; */
337 }
338
339 void
340 sim_stop_reason (reason, sigrc)
341      enum sim_stop *reason;
342      int *sigrc;
343 {
344   printf ("sim_stop_reason\n");
345 }