4 #include "remote-sim.h"
8 #define IMEM_SIZE 18 /* D10V instruction memory size is 18 bits */
9 #define DMEM_SIZE 16 /* Data memory */
11 enum _leftright { LEFT_FIRST, RIGHT_FIRST };
14 host_callback *d10v_callback;
15 long ins_type_counters[ (int)INS_MAX ];
16 long left_nops, right_nops;
20 static struct hash_entry *lookup_hash PARAMS ((uint32 ins, int size));
25 struct hash_entry *next;
31 struct hash_entry hash_table[MAX_HASH+1];
38 if (format & LONG_OPCODE)
39 return ((insn & 0x3F000000) >> 24);
41 return((insn & 0x7E00) >> 9);
44 static struct hash_entry *
45 lookup_hash (ins, size)
52 h = &hash_table[(ins & 0x3F000000) >> 24];
54 h = &hash_table[(ins & 0x7E00) >> 9];
56 while ( (ins & h->mask) != h->opcode)
60 (*d10v_callback->printf_filtered) (d10v_callback, "ERROR looking up hash for %x at PC %x\n",ins, PC);
73 return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + (a[3]);
81 return ((int64)a[0]<<56) + ((int64)a[1]<<48) + ((int64)a[2]<<40) + ((int64)a[3]<<32) +
82 ((int64)a[4]<< 24) + ((int64)a[5]<<16) + ((int64)a[6]<<8) + (int64)a[7];
90 return ((uint16)a[0]<<8) + a[1];
95 write_word (addr, data)
105 write_longword (addr, data)
109 addr[0] = (data >> 24) & 0xff;
110 addr[1] = (data >> 16) & 0xff;
111 addr[2] = (data >> 8) & 0xff;
112 addr[3] = data & 0xff;
116 write_longlong (addr, data)
122 a[1] = (data >> 48) & 0xff;
123 a[2] = (data >> 40) & 0xff;
124 a[3] = (data >> 32) & 0xff;
125 a[4] = (data >> 24) & 0xff;
126 a[5] = (data >> 16) & 0xff;
127 a[6] = (data >> 8) & 0xff;
132 get_operands (struct simops *s, uint32 ins)
134 int i, shift, bits, flags;
136 for (i=0; i < s->numops; i++)
138 shift = s->operands[3*i];
139 bits = s->operands[3*i+1];
140 flags = s->operands[3*i+2];
141 mask = 0x7FFFFFFF >> (31 - bits);
142 OP[i] = (ins >> shift) & mask;
150 struct hash_entry *h;
152 if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
153 (*d10v_callback->printf_filtered) (d10v_callback, "do_long 0x%x\n", ins);
155 h = lookup_hash (ins, 1);
156 get_operands (h->ops, ins);
157 State.ins_type = INS_LONG;
158 ins_type_counters[ (int)State.ins_type ]++;
163 do_2_short (ins1, ins2, leftright)
165 enum _leftright leftright;
167 struct hash_entry *h;
171 if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
172 (*d10v_callback->printf_filtered) (d10v_callback, "do_2_short 0x%x (%s) -> 0x%x\n",
173 ins1, (leftright) ? "left" : "right", ins2);
175 /* printf ("do_2_short %x -> %x\n",ins1,ins2); */
176 h = lookup_hash (ins1, 0);
177 get_operands (h->ops, ins1);
178 State.ins_type = (leftright == LEFT_FIRST) ? INS_LEFT : INS_RIGHT;
179 ins_type_counters[ (int)State.ins_type ]++;
182 /* If the PC has changed (ie, a jump), don't do the second instruction */
183 if (orig_pc == PC && !State.exception)
185 h = lookup_hash (ins2, 0);
186 get_operands (h->ops, ins2);
187 State.ins_type = (leftright == LEFT_FIRST) ? INS_RIGHT : INS_LEFT;
188 ins_type_counters[ (int)State.ins_type ]++;
194 do_parallel (ins1, ins2)
197 struct hash_entry *h1, *h2;
199 if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
200 (*d10v_callback->printf_filtered) (d10v_callback, "do_parallel 0x%x || 0x%x\n", ins1, ins2);
202 h1 = lookup_hash (ins1, 0);
203 h2 = lookup_hash (ins2, 0);
205 if (h1->ops->exec_type == PARONLY)
207 get_operands (h1->ops, ins1);
208 State.ins_type = INS_LEFT;
209 ins_type_counters[ (int)State.ins_type ]++;
213 get_operands (h2->ops, ins2);
214 State.ins_type = INS_RIGHT;
218 else if (h2->ops->exec_type == PARONLY)
220 get_operands (h2->ops, ins2);
221 State.ins_type = INS_RIGHT;
222 ins_type_counters[ (int)State.ins_type ]++;
226 get_operands (h1->ops, ins1);
227 State.ins_type = INS_LEFT;
233 get_operands (h1->ops, ins1);
234 State.ins_type = INS_LEFT_PARALLEL;
235 ins_type_counters[ (int)State.ins_type ]++;
237 if (!State.exception)
239 get_operands (h2->ops, ins2);
240 State.ins_type = INS_RIGHT_PARALLEL;
241 ins_type_counters[ (int)State.ins_type ]++;
259 State.imem = (uint8 *)calloc(1,1<<IMEM_SIZE);
260 State.dmem = (uint8 *)calloc(1,1<<DMEM_SIZE);
261 if (!State.imem || !State.dmem )
263 (*d10v_callback->printf_filtered) (d10v_callback, "Memory allocation failed.\n");
267 State.mem_min = 1<<IMEM_SIZE;
271 if ((d10v_debug & DEBUG_MEMSIZE) != 0)
273 (*d10v_callback->printf_filtered) (d10v_callback, "Allocated %d bytes instruction memory and\n",1<<IMEM_SIZE);
274 (*d10v_callback->printf_filtered) (d10v_callback, " %d bytes data memory.\n", 1<<DMEM_SIZE);
287 sim_write (addr, buffer, size)
289 unsigned char *buffer;
295 if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
296 (*d10v_callback->printf_filtered) (d10v_callback, "sim_write %d bytes to 0x%x, min = 0x%x, max = 0x%x\n",
297 size, addr, State.mem_min, State.mem_max);
300 if (State.mem_min > addr)
301 State.mem_min = addr;
303 if (State.mem_max < addr+size-1)
304 State.mem_max = addr+size-1;
306 memcpy (State.imem+addr, buffer, size);
315 struct hash_entry *h, *prev;
316 static int init_p = 0;
321 if (strcmp (args, "-t") == 0)
325 (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: unsupported option(s): %s\n",args);
328 /* put all the opcodes in the hash table */
331 for (s = Simops; s->func; s++)
333 h = &hash_table[hash(s->opcode,s->format)];
335 /* go to the last entry in the chain */
341 h->next = calloc(1,sizeof(struct hash_entry));
346 h->opcode = s->opcode;
363 (*d10v_callback->printf_filtered) (d10v_callback, "sim_set_profile %d\n",n);
367 sim_set_profile_size (n)
370 (*d10v_callback->printf_filtered) (d10v_callback, "sim_set_profile_size %d\n",n);
374 sim_resume (step, siggnal)
381 /* (*d10v_callback->printf_filtered) (d10v_callback, "sim_resume (%d,%d) PC=0x%x\n",step,siggnal,PC); */
384 State.exception = SIGTRAP;
390 uint32 byte_pc = ((uint32)PC) << 2;
391 if ((byte_pc < State.mem_min) || (byte_pc > State.mem_max))
393 (*d10v_callback->printf_filtered) (d10v_callback,
394 "PC (0x%lx) out of range, oldpc = 0x%lx, min = 0x%lx, max = 0x%lx\n",
395 (long)byte_pc, (long)oldpc, (long)State.mem_min, (long)State.mem_max);
396 State.exception = SIGILL;
400 inst = RLW (byte_pc);
402 switch (inst & 0xC0000000)
405 /* long instruction */
406 do_long (inst & 0x3FFFFFFF);
410 do_2_short ( inst & 0x7FFF, (inst & 0x3FFF8000) >> 15, 0);
414 do_2_short ((inst & 0x3FFF8000) >> 15, inst & 0x7FFF, 1);
417 do_parallel ((inst & 0x3FFF8000) >> 15, inst & 0x7FFF);
421 if (State.RP && PC == RPT_E)
435 while (!State.exception);
454 long total = (ins_type_counters[ (int)INS_LONG ]
455 + ins_type_counters[ (int)INS_LEFT ]
456 + ins_type_counters[ (int)INS_LEFT_PARALLEL ]
457 + ins_type_counters[ (int)INS_RIGHT ]
458 + ins_type_counters[ (int)INS_RIGHT_PARALLEL ]);
460 sprintf (buf, "%ld", total);
463 (*d10v_callback->printf_filtered) (d10v_callback,
464 "executed %*ld instructions in the left container, %*ld parallel, %*ld nops\n",
465 size, ins_type_counters[ (int)INS_LEFT ] + ins_type_counters[ (int)INS_LEFT_PARALLEL ],
466 size, ins_type_counters[ (int)INS_LEFT_PARALLEL ],
469 (*d10v_callback->printf_filtered) (d10v_callback,
470 "executed %*ld instructions in the right container, %*ld parallel, %*ld nops\n",
471 size, ins_type_counters[ (int)INS_RIGHT ] + ins_type_counters[ (int)INS_RIGHT_PARALLEL ],
472 size, ins_type_counters[ (int)INS_RIGHT_PARALLEL ],
475 (*d10v_callback->printf_filtered) (d10v_callback,
476 "executed %*ld long instructions\n",
477 size, ins_type_counters[ (int)INS_LONG ]);
479 (*d10v_callback->printf_filtered) (d10v_callback,
480 "executed %*ld total instructions\n",
485 sim_create_inferior (start_address, argv, env)
486 SIM_ADDR start_address;
491 uint32 mem_min, mem_max;
494 (*d10v_callback->printf_filtered) (d10v_callback, "sim_create_inferior: PC=0x%x\n", start_address);
496 /* save memory pointers */
499 mem_min = State.mem_min;
500 mem_max = State.mem_max;
501 /* reset all state information */
502 memset (&State, 0, sizeof(State));
503 /* restore memory pointers */
506 State.mem_min = mem_min;
507 State.mem_max = mem_max;
509 PC = start_address >> 2;
523 /* printf ("sim_set_callbacks\n"); */
528 sim_stop_reason (reason, sigrc)
529 enum sim_stop *reason;
532 /* (*d10v_callback->printf_filtered) (d10v_callback, "sim_stop_reason: PC=0x%x\n",PC<<2); */
534 switch (State.exception)
536 case SIG_D10V_STOP: /* stop instruction */
537 *reason = sim_exited;
541 case SIG_D10V_EXIT: /* exit trap */
542 *reason = sim_exited;
543 *sigrc = State.regs[2];
546 default: /* some signal */
547 *reason = sim_stopped;
548 *sigrc = State.exception;
554 sim_fetch_register (rn, memory)
556 unsigned char *memory;
560 WRITE_64 (memory, State.a[rn-32]);
561 /* (*d10v_callback->printf_filtered) (d10v_callback, "sim_fetch_register %d 0x%llx\n",rn,State.a[rn-32]); */
565 WRITE_16 (memory, State.regs[rn]);
566 /* (*d10v_callback->printf_filtered) (d10v_callback, "sim_fetch_register %d 0x%x\n",rn,State.regs[rn]); */
571 sim_store_register (rn, memory)
573 unsigned char *memory;
577 State.a[rn-32] = READ_64 (memory) & MASK40;
578 /* (*d10v_callback->printf_filtered) (d10v_callback, "store: a%d=0x%llx\n",rn-32,State.a[rn-32]); */
582 State.regs[rn]= READ_16 (memory);
583 /* (*d10v_callback->printf_filtered) (d10v_callback, "store: r%d=0x%x\n",rn,State.regs[rn]); */
587 sim_read (addr, buffer, size)
589 unsigned char *buffer;
593 for (i = 0; i < size; i++)
595 buffer[i] = State.imem[addr + i];
604 (*d10v_callback->printf_filtered) (d10v_callback, "sim_do_command: %s\n",cmd);
608 sim_load (prog, from_tty)
612 /* Return nonzero so GDB will handle it. */