* terminal.h: Don't use #elif.
[deliverable/binutils-gdb.git] / sim / d10v / interp.c
CommitLineData
d70b4d42 1#include <signal.h>
2934d1c9
MH
2#include "sysdep.h"
3#include "bfd.h"
4#include "remote-sim.h"
2934d1c9
MH
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
87178dbd
MM
11enum _leftright { LEFT_FIRST, RIGHT_FIRST };
12
13host_callback *d10v_callback;
14
2934d1c9
MH
15uint16 OP[4];
16
17static struct hash_entry *lookup_hash PARAMS ((uint32 ins, int size));
18
19#define MAX_HASH 63
20struct hash_entry
21{
22 struct hash_entry *next;
23 long opcode;
24 long mask;
25 struct simops *ops;
26};
27
28struct hash_entry hash_table[MAX_HASH+1];
29
30static long
31hash(insn, format)
32 long insn;
33 int format;
34{
35 if (format & LONG_OPCODE)
36 return ((insn & 0x3F000000) >> 24);
37 else
38 return((insn & 0x7E00) >> 9);
39}
40
41static struct hash_entry *
42lookup_hash (ins, size)
43 uint32 ins;
44 int size;
45{
46 struct hash_entry *h;
47
48 if (size)
49 h = &hash_table[(ins & 0x3F000000) >> 24];
50 else
51 h = &hash_table[(ins & 0x7E00) >> 9];
52
53 while ( (ins & h->mask) != h->opcode)
54 {
55 if (h->next == NULL)
56 {
87178dbd 57 printf ("ERROR looking up hash for %x at PC %x\n",ins, PC);
2934d1c9
MH
58 exit(1);
59 }
60 h = h->next;
61 }
62 return (h);
63}
64
65uint32
d70b4d42
MH
66get_longword (x)
67 uint8 *x;
2934d1c9 68{
d70b4d42 69 uint8 *a = x;
2934d1c9
MH
70 return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + (a[3]);
71}
72
d70b4d42
MH
73int64
74get_longlong (x)
75 uint8 *x;
76{
77 uint8 *a = x;
78 return ((int64)a[0]<<56) + ((int64)a[1]<<48) + ((int64)a[2]<<40) + ((int64)a[3]<<32) +
79 ((int64)a[4]<< 24) + ((int64)a[5]<<16) + ((int64)a[6]<<8) + (int64)a[7];
80}
81
2934d1c9 82uint16
d70b4d42
MH
83get_word (x)
84 uint8 *x;
2934d1c9 85{
d70b4d42
MH
86 uint8 *a = x;
87 return ((uint16)a[0]<<8) + a[1];
2934d1c9
MH
88}
89
87178dbd 90
2934d1c9 91void
d70b4d42
MH
92write_word (addr, data)
93 uint8 *addr;
94 uint16 data;
2934d1c9 95{
d70b4d42 96 uint8 *a = addr;
2934d1c9
MH
97 a[0] = data >> 8;
98 a[1] = data & 0xff;
99}
100
87178dbd
MM
101void
102write_longword (addr, data)
103 uint8 *addr;
104 uint32 data;
105{
106 addr[0] = (data >> 24) & 0xff;
107 addr[1] = (data >> 16) & 0xff;
108 addr[2] = (data >> 8) & 0xff;
109 addr[3] = data & 0xff;
110}
111
d70b4d42
MH
112void
113write_longlong (addr, data)
114 uint8 *addr;
115 int64 data;
116{
117 uint8 *a = addr;
118 a[0] = data >> 56;
119 a[1] = (data >> 48) & 0xff;
120 a[2] = (data >> 40) & 0xff;
121 a[3] = (data >> 32) & 0xff;
122 a[4] = (data >> 24) & 0xff;
123 a[5] = (data >> 16) & 0xff;
124 a[6] = (data >> 8) & 0xff;
125 a[7] = data & 0xff;
126}
127
2934d1c9
MH
128static void
129get_operands (struct simops *s, uint32 ins)
130{
131 int i, shift, bits, flags;
132 uint32 mask;
133 for (i=0; i < s->numops; i++)
134 {
135 shift = s->operands[3*i];
136 bits = s->operands[3*i+1];
137 flags = s->operands[3*i+2];
138 mask = 0x7FFFFFFF >> (31 - bits);
139 OP[i] = (ins >> shift) & mask;
140 }
141}
142
143static void
144do_long (ins)
145 uint32 ins;
146{
147 struct hash_entry *h;
148 /* printf ("do_long %x\n",ins); */
149 h = lookup_hash (ins, 1);
150 get_operands (h->ops, ins);
87178dbd 151 State.ins_type = INS_LONG;
2934d1c9
MH
152 (h->ops->func)();
153}
154static void
87178dbd 155do_2_short (ins1, ins2, leftright)
2934d1c9 156 uint16 ins1, ins2;
87178dbd 157 enum _leftright leftright;
2934d1c9
MH
158{
159 struct hash_entry *h;
160 /* printf ("do_2_short %x -> %x\n",ins1,ins2); */
161 h = lookup_hash (ins1, 0);
162 get_operands (h->ops, ins1);
87178dbd 163 State.ins_type = (leftright == LEFT_FIRST) ? INS_LEFT : INS_RIGHT;
2934d1c9
MH
164 (h->ops->func)();
165 h = lookup_hash (ins2, 0);
166 get_operands (h->ops, ins2);
87178dbd 167 State.ins_type = (leftright == LEFT_FIRST) ? INS_RIGHT : INS_LEFT;
2934d1c9
MH
168 (h->ops->func)();
169}
170static void
171do_parallel (ins1, ins2)
172 uint16 ins1, ins2;
173{
174 struct hash_entry *h1, *h2;
d70b4d42 175 /* printf ("do_parallel %x || %x\n",ins1,ins2); */
2934d1c9 176 h1 = lookup_hash (ins1, 0);
2934d1c9 177 h2 = lookup_hash (ins2, 0);
d70b4d42 178
2934d1c9
MH
179 if (h1->ops->exec_type == PARONLY)
180 {
d70b4d42 181 get_operands (h1->ops, ins1);
87178dbd 182 State.ins_type = INS_LEFT;
2934d1c9
MH
183 (h1->ops->func)();
184 if (State.exe)
d70b4d42
MH
185 {
186 get_operands (h2->ops, ins2);
87178dbd 187 State.ins_type = INS_RIGHT;
d70b4d42
MH
188 (h2->ops->func)();
189 }
2934d1c9
MH
190 }
191 else if (h2->ops->exec_type == PARONLY)
192 {
d70b4d42 193 get_operands (h2->ops, ins2);
87178dbd 194 State.ins_type = INS_RIGHT;
2934d1c9
MH
195 (h2->ops->func)();
196 if (State.exe)
d70b4d42
MH
197 {
198 get_operands (h1->ops, ins1);
87178dbd 199 State.ins_type = INS_LEFT;
d70b4d42
MH
200 (h1->ops->func)();
201 }
2934d1c9
MH
202 }
203 else
204 {
d70b4d42 205 get_operands (h1->ops, ins1);
87178dbd 206 State.ins_type = INS_LEFT_PARALLEL;
2934d1c9 207 (h1->ops->func)();
d70b4d42 208 get_operands (h2->ops, ins2);
87178dbd 209 State.ins_type = INS_RIGHT_PARALLEL;
2934d1c9
MH
210 (h2->ops->func)();
211 }
212}
213
214
215void
216sim_size (power)
217 int power;
218
219{
220 if (State.imem)
221 {
222 free (State.imem);
223 free (State.dmem);
224 }
225
226 State.imem = (uint8 *)calloc(1,1<<IMEM_SIZE);
227 State.dmem = (uint8 *)calloc(1,1<<DMEM_SIZE);
228 if (!State.imem || !State.dmem )
229 {
230 fprintf (stderr,"Memory allocation failed.\n");
231 exit(1);
232 }
87178dbd 233#if (DEBUG & DEBUG_MEMSIZE) != 0
2934d1c9
MH
234 printf ("Allocated %d bytes instruction memory and\n",1<<IMEM_SIZE);
235 printf (" %d bytes data memory.\n",1<<DMEM_SIZE);
87178dbd 236#endif
2934d1c9
MH
237}
238
239static void
240init_system ()
241{
242 if (!State.imem)
243 sim_size(1);
244}
245
246int
247sim_write (addr, buffer, size)
248 SIM_ADDR addr;
249 unsigned char *buffer;
250 int size;
251{
252 int i;
253 init_system ();
254
d70b4d42 255 /* printf ("sim_write %d bytes to 0x%x\n",size,addr); */
2934d1c9
MH
256 for (i = 0; i < size; i++)
257 {
258 State.imem[i+addr] = buffer[i];
259 }
260 return size;
261}
262
263void
264sim_open (args)
265 char *args;
266{
267 struct simops *s;
268 struct hash_entry *h, *prev;
269 if (args != NULL)
270 printf ("sim_open %s\n",args);
271
272 /* put all the opcodes in the hash table */
273 for (s = Simops; s->func; s++)
274 {
275 h = &hash_table[hash(s->opcode,s->format)];
276
277 /* go to the last entry in the chain */
278 while (h->next)
279 h = h->next;
280
281 if (h->ops)
282 {
283 h->next = calloc(1,sizeof(struct hash_entry));
284 h = h->next;
285 }
286 h->ops = s;
287 h->mask = s->mask;
288 h->opcode = s->opcode;
289 }
290}
291
292
293void
294sim_close (quitting)
295 int quitting;
296{
297 /* nothing to do */
298}
299
300void
301sim_set_profile (n)
302 int n;
303{
304 printf ("sim_set_profile %d\n",n);
305}
306
307void
308sim_set_profile_size (n)
309 int n;
310{
311 printf ("sim_set_profile_size %d\n",n);
312}
313
314void
315sim_resume (step, siggnal)
316 int step, siggnal;
317{
318 uint32 inst;
319 int i;
320 reg_t oldpc;
321
d70b4d42 322/* printf ("sim_resume (%d,%d) PC=0x%x\n",step,siggnal,PC); */
2934d1c9 323
d70b4d42
MH
324 if (step)
325 State.exception = SIGTRAP;
326 else
327 State.exception = 0;
328
329 do
330 {
331 inst = RLW (PC << 2);
332 oldpc = PC;
333 switch (inst & 0xC0000000)
334 {
335 case 0xC0000000:
336 /* long instruction */
337 do_long (inst & 0x3FFFFFFF);
338 break;
339 case 0x80000000:
340 /* R -> L */
87178dbd 341 do_2_short ( inst & 0x7FFF, (inst & 0x3FFF8000) >> 15, 0);
d70b4d42
MH
342 break;
343 case 0x40000000:
344 /* L -> R */
87178dbd 345 do_2_short ((inst & 0x3FFF8000) >> 15, inst & 0x7FFF, 1);
d70b4d42
MH
346 break;
347 case 0:
348 do_parallel ((inst & 0x3FFF8000) >> 15, inst & 0x7FFF);
349 break;
350 }
351
352 if (State.RP && PC == RPT_E)
353 {
354 RPT_C -= 1;
355 if (RPT_C == 0)
356 State.RP = 0;
357 else
358 PC = RPT_S;
359 }
360
361 /* FIXME */
362 if (PC == oldpc)
363 PC++;
364 }
365 while (!State.exception);
2934d1c9
MH
366}
367
368int
369sim_trace ()
370{
371 printf ("sim_trace\n");
372 return 0;
373}
374
375void
376sim_info (verbose)
377 int verbose;
378{
d70b4d42 379 printf ("sim_info\n");
2934d1c9
MH
380}
381
382void
383sim_create_inferior (start_address, argv, env)
384 SIM_ADDR start_address;
385 char **argv;
386 char **env;
387{
388 printf ("sim_create_inferior: PC=0x%x\n",start_address);
389 PC = start_address >> 2;
390}
391
392
393void
394sim_kill ()
395{
396 /* nothing to do */
397}
398
399void
400sim_set_callbacks(p)
401 host_callback *p;
402{
87178dbd
MM
403/* printf ("sim_set_callbacks\n"); */
404 d10v_callback = p;
2934d1c9
MH
405}
406
407void
408sim_stop_reason (reason, sigrc)
409 enum sim_stop *reason;
410 int *sigrc;
411{
d70b4d42
MH
412/* printf ("sim_stop_reason: PC=0x%x\n",PC<<2); */
413
414 if (State.exception == SIGQUIT)
415 {
416 *reason = sim_exited;
417 *sigrc = State.exception;
418 }
419 else
420 {
421 *reason = sim_stopped;
422 *sigrc = State.exception;
423 }
424}
425
426void
427sim_fetch_register (rn, memory)
428 int rn;
429 unsigned char *memory;
430{
431 if (rn > 31)
432 {
433 WRITE_64 (memory, State.a[rn-32]);
434 /* printf ("sim_fetch_register %d 0x%llx\n",rn,State.a[rn-32]); */
435 }
436 else
437 {
438 WRITE_16 (memory, State.regs[rn]);
439 /* printf ("sim_fetch_register %d 0x%x\n",rn,State.regs[rn]); */
440 }
441}
442
443void
444sim_store_register (rn, memory)
445 int rn;
446 unsigned char *memory;
447{
448 if (rn > 31)
449 {
450 State.a[rn-32] = READ_64 (memory) & MASK40;
451 /* printf ("store: a%d=0x%llx\n",rn-32,State.a[rn-32]); */
452 }
453 else
454 {
455 State.regs[rn]= READ_16 (memory);
456 /* printf ("store: r%d=0x%x\n",rn,State.regs[rn]); */
457 }
2934d1c9 458}
d70b4d42
MH
459
460sim_read (addr, buffer, size)
461 SIM_ADDR addr;
462 unsigned char *buffer;
463 int size;
464{
465 int i;
466 for (i = 0; i < size; i++)
467 {
468 buffer[i] = State.imem[addr + i];
469 }
470 return size;
471}
472
473void
474sim_do_command (cmd)
475 char *cmd;
476{
477 printf("sim_do_command: %s\n",cmd);
478}
479
480int
481sim_load (prog, from_tty)
482 char *prog;
483 int from_tty;
484{
485 /* Return nonzero so GDB will handle it. */
486 return 1;
487}
This page took 0.04583 seconds and 4 git commands to generate.