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 unsigned long ins_type_counters
[ (int)INS_MAX
];
19 static long hash
PARAMS ((long insn
, int format
));
20 static struct hash_entry
*lookup_hash
PARAMS ((uint32 ins
, int size
));
21 static void get_operands
PARAMS ((struct simops
*s
, uint32 ins
));
22 static void do_long
PARAMS ((uint32 ins
));
23 static void do_2_short
PARAMS ((uint16 ins1
, uint16 ins2
, enum _leftright leftright
));
24 static void do_parallel
PARAMS ((uint16 ins1
, uint16 ins2
));
25 static char *add_commas
PARAMS ((char *buf
, int sizeof_buf
, unsigned long value
));
26 extern void sim_size
PARAMS ((int power
));
27 static void init_system
PARAMS ((void));
28 extern int sim_write
PARAMS ((SIM_ADDR addr
, unsigned char *buffer
, int size
));
29 extern void sim_open
PARAMS ((char *args
));
30 extern void sim_close
PARAMS ((int quitting
));
31 extern void sim_set_profile
PARAMS ((int n
));
32 extern void sim_set_profile_size
PARAMS ((int n
));
33 extern void sim_resume
PARAMS ((int step
, int siggnal
));
34 extern void sim_info
PARAMS ((int verbose
));
35 extern void sim_create_inferior
PARAMS ((SIM_ADDR start_address
, char **argv
, char **env
));
36 extern void sim_kill
PARAMS ((void));
37 extern void sim_set_callbacks
PARAMS ((host_callback
*p
));
38 extern void sim_stop_reason
PARAMS ((enum sim_stop
*reason
, int *sigrc
));
39 extern void sim_fetch_register
PARAMS ((int rn
, unsigned char *memory
));
40 extern void sim_store_register
PARAMS ((int rn
, unsigned char *memory
));
41 extern int sim_read
PARAMS ((SIM_ADDR addr
, unsigned char *buffer
, int size
));
42 extern void sim_do_command
PARAMS ((char *cmd
));
45 #if defined(__GNUC__) && defined(__OPTIMIZE__)
46 #define INLINE __inline__
55 struct hash_entry
*next
;
61 struct hash_entry hash_table
[MAX_HASH
+1];
68 if (format
& LONG_OPCODE
)
69 return ((insn
& 0x3F000000) >> 24);
71 return((insn
& 0x7E00) >> 9);
74 INLINE
static struct hash_entry
*
75 lookup_hash (ins
, size
)
82 h
= &hash_table
[(ins
& 0x3F000000) >> 24];
84 h
= &hash_table
[(ins
& 0x7E00) >> 9];
86 while ((ins
& h
->mask
) != h
->opcode
)
90 (*d10v_callback
->printf_filtered
) (d10v_callback
, "ERROR looking up hash for %x at PC %x\n",ins
, PC
);
99 get_operands (struct simops
*s
, uint32 ins
)
101 int i
, shift
, bits
, flags
;
103 for (i
=0; i
< s
->numops
; i
++)
105 shift
= s
->operands
[3*i
];
106 bits
= s
->operands
[3*i
+1];
107 flags
= s
->operands
[3*i
+2];
108 mask
= 0x7FFFFFFF >> (31 - bits
);
109 OP
[i
] = (ins
>> shift
) & mask
;
117 struct hash_entry
*h
;
119 if ((d10v_debug
& DEBUG_INSTRUCTION
) != 0)
120 (*d10v_callback
->printf_filtered
) (d10v_callback
, "do_long 0x%x\n", ins
);
122 h
= lookup_hash (ins
, 1);
123 get_operands (h
->ops
, ins
);
124 State
.ins_type
= INS_LONG
;
125 ins_type_counters
[ (int)State
.ins_type
]++;
130 do_2_short (ins1
, ins2
, leftright
)
132 enum _leftright leftright
;
134 struct hash_entry
*h
;
138 if ((d10v_debug
& DEBUG_INSTRUCTION
) != 0)
139 (*d10v_callback
->printf_filtered
) (d10v_callback
, "do_2_short 0x%x (%s) -> 0x%x\n",
140 ins1
, (leftright
) ? "left" : "right", ins2
);
142 /* printf ("do_2_short %x -> %x\n",ins1,ins2); */
143 h
= lookup_hash (ins1
, 0);
144 get_operands (h
->ops
, ins1
);
145 State
.ins_type
= (leftright
== LEFT_FIRST
) ? INS_LEFT
: INS_RIGHT
;
146 ins_type_counters
[ (int)State
.ins_type
]++;
149 /* If the PC has changed (ie, a jump), don't do the second instruction */
150 if (orig_pc
== PC
&& !State
.exception
)
152 h
= lookup_hash (ins2
, 0);
153 get_operands (h
->ops
, ins2
);
154 State
.ins_type
= (leftright
== LEFT_FIRST
) ? INS_RIGHT
: INS_LEFT
;
155 ins_type_counters
[ (int)State
.ins_type
]++;
161 do_parallel (ins1
, ins2
)
164 struct hash_entry
*h1
, *h2
;
166 if ((d10v_debug
& DEBUG_INSTRUCTION
) != 0)
167 (*d10v_callback
->printf_filtered
) (d10v_callback
, "do_parallel 0x%x || 0x%x\n", ins1
, ins2
);
169 h1
= lookup_hash (ins1
, 0);
170 h2
= lookup_hash (ins2
, 0);
172 if (h1
->ops
->exec_type
== PARONLY
)
174 get_operands (h1
->ops
, ins1
);
175 State
.ins_type
= INS_LEFT_COND_TEST
;
176 ins_type_counters
[ (int)State
.ins_type
]++;
180 ins_type_counters
[ (int)INS_COND_TRUE
]++;
181 get_operands (h2
->ops
, ins2
);
182 State
.ins_type
= INS_RIGHT_COND_EXE
;
183 ins_type_counters
[ (int)State
.ins_type
]++;
187 ins_type_counters
[ (int)INS_COND_FALSE
]++;
189 else if (h2
->ops
->exec_type
== PARONLY
)
191 get_operands (h2
->ops
, ins2
);
192 State
.ins_type
= INS_RIGHT_COND_TEST
;
193 ins_type_counters
[ (int)State
.ins_type
]++;
197 ins_type_counters
[ (int)INS_COND_TRUE
]++;
198 get_operands (h1
->ops
, ins1
);
199 State
.ins_type
= INS_LEFT_COND_EXE
;
200 ins_type_counters
[ (int)State
.ins_type
]++;
204 ins_type_counters
[ (int)INS_COND_FALSE
]++;
208 get_operands (h1
->ops
, ins1
);
209 State
.ins_type
= INS_LEFT_PARALLEL
;
210 ins_type_counters
[ (int)State
.ins_type
]++;
212 if (!State
.exception
)
214 get_operands (h2
->ops
, ins2
);
215 State
.ins_type
= INS_RIGHT_PARALLEL
;
216 ins_type_counters
[ (int)State
.ins_type
]++;
223 add_commas(buf
, sizeof_buf
, value
)
229 char *endbuf
= buf
+ sizeof_buf
- 1;
239 *--endbuf
= (value
% 10) + '0';
240 } while ((value
/= 10) != 0);
256 State
.imem
= (uint8
*)calloc(1,1<<IMEM_SIZE
);
257 State
.dmem
= (uint8
*)calloc(1,1<<DMEM_SIZE
);
258 if (!State
.imem
|| !State
.dmem
)
260 (*d10v_callback
->printf_filtered
) (d10v_callback
, "Memory allocation failed.\n");
264 State
.mem_min
= 1<<IMEM_SIZE
;
268 if ((d10v_debug
& DEBUG_MEMSIZE
) != 0)
271 (*d10v_callback
->printf_filtered
) (d10v_callback
,
272 "Allocated %s bytes instruction memory and\n",
273 add_commas (buffer
, sizeof (buffer
), (1UL<<IMEM_SIZE
)));
275 (*d10v_callback
->printf_filtered
) (d10v_callback
, " %s bytes data memory.\n",
276 add_commas (buffer
, sizeof (buffer
), (1UL<<IMEM_SIZE
)));
289 sim_write (addr
, buffer
, size
)
291 unsigned char *buffer
;
297 if ((d10v_debug
& DEBUG_INSTRUCTION
) != 0)
298 (*d10v_callback
->printf_filtered
) (d10v_callback
, "sim_write %d bytes to 0x%x, min = 0x%x, max = 0x%x\n",
299 size
, addr
, State
.mem_min
, State
.mem_max
);
302 if (State
.mem_min
> addr
)
303 State
.mem_min
= addr
;
305 if (State
.mem_max
< addr
+size
-1)
306 State
.mem_max
= addr
+size
-1;
308 memcpy (State
.imem
+addr
, buffer
, size
);
317 struct hash_entry
*h
;
318 static int init_p
= 0;
323 if (strcmp (args
, "-t") == 0)
327 (*d10v_callback
->printf_filtered
) (d10v_callback
, "ERROR: unsupported option(s): %s\n",args
);
330 /* put all the opcodes in the hash table */
333 for (s
= Simops
; s
->func
; s
++)
335 h
= &hash_table
[hash(s
->opcode
,s
->format
)];
337 /* go to the last entry in the chain */
343 h
->next
= calloc(1,sizeof(struct hash_entry
));
348 h
->opcode
= s
->opcode
;
365 (*d10v_callback
->printf_filtered
) (d10v_callback
, "sim_set_profile %d\n",n
);
369 sim_set_profile_size (n
)
372 (*d10v_callback
->printf_filtered
) (d10v_callback
, "sim_set_profile_size %d\n",n
);
376 sim_resume (step
, siggnal
)
382 /* (*d10v_callback->printf_filtered) (d10v_callback, "sim_resume (%d,%d) PC=0x%x\n",step,siggnal,PC); */
387 uint32 byte_pc
= ((uint32
)PC
) << 2;
388 if ((byte_pc
< State
.mem_min
) || (byte_pc
> State
.mem_max
))
390 (*d10v_callback
->printf_filtered
) (d10v_callback
,
391 "PC (0x%lx) out of range, oldpc = 0x%lx, min = 0x%lx, max = 0x%lx\n",
392 (long)byte_pc
, (long)oldpc
, (long)State
.mem_min
, (long)State
.mem_max
);
393 State
.exception
= SIGILL
;
397 inst
= RLW (byte_pc
);
399 ins_type_counters
[ (int)INS_CYCLES
]++;
400 switch (inst
& 0xC0000000)
403 /* long instruction */
404 do_long (inst
& 0x3FFFFFFF);
408 do_2_short ( inst
& 0x7FFF, (inst
& 0x3FFF8000) >> 15, 0);
412 do_2_short ((inst
& 0x3FFF8000) >> 15, inst
& 0x7FFF, 1);
415 do_parallel ((inst
& 0x3FFF8000) >> 15, inst
& 0x7FFF);
419 if (State
.RP
&& PC
== RPT_E
)
433 while ( !State
.exception
&& !step
);
435 if (step
&& !State
.exception
)
436 State
.exception
= SIGTRAP
;
458 unsigned long left
= ins_type_counters
[ (int)INS_LEFT
] + ins_type_counters
[ (int)INS_LEFT_COND_EXE
];
459 unsigned long left_nops
= ins_type_counters
[ (int)INS_LEFT_NOPS
];
460 unsigned long left_parallel
= ins_type_counters
[ (int)INS_LEFT_PARALLEL
];
461 unsigned long left_cond
= ins_type_counters
[ (int)INS_LEFT_COND_TEST
];
462 unsigned long left_total
= left
+ left_parallel
+ left_cond
+ left_nops
;
464 unsigned long right
= ins_type_counters
[ (int)INS_RIGHT
] + ins_type_counters
[ (int)INS_RIGHT_COND_EXE
];
465 unsigned long right_nops
= ins_type_counters
[ (int)INS_RIGHT_NOPS
];
466 unsigned long right_parallel
= ins_type_counters
[ (int)INS_RIGHT_PARALLEL
];
467 unsigned long right_cond
= ins_type_counters
[ (int)INS_RIGHT_COND_TEST
];
468 unsigned long right_total
= right
+ right_parallel
+ right_cond
+ right_nops
;
470 unsigned long unknown
= ins_type_counters
[ (int)INS_UNKNOWN
];
471 unsigned long ins_long
= ins_type_counters
[ (int)INS_LONG
];
472 unsigned long cond_true
= ins_type_counters
[ (int)INS_COND_TRUE
];
473 unsigned long cond_false
= ins_type_counters
[ (int)INS_COND_FALSE
];
474 unsigned long cycles
= ins_type_counters
[ (int)INS_CYCLES
];
475 unsigned long total
= (unknown
+ left_total
+ right_total
+ ins_long
);
477 int size
= strlen (add_commas (buf1
, sizeof (buf1
), total
));
478 int parallel_size
= strlen (add_commas (buf1
, sizeof (buf1
),
479 (left_parallel
> right_parallel
) ? left_parallel
: right_parallel
));
480 int cond_size
= strlen (add_commas (buf1
, sizeof (buf1
), (left_cond
> right_cond
) ? left_cond
: right_cond
));
481 int nop_size
= strlen (add_commas (buf1
, sizeof (buf1
), (left_nops
> right_nops
) ? left_nops
: right_nops
));
482 int normal_size
= strlen (add_commas (buf1
, sizeof (buf1
), (left
> right
) ? left
: right
));
484 (*d10v_callback
->printf_filtered
) (d10v_callback
,
485 "executed %*s left instructions, %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
486 size
, add_commas (buf1
, sizeof (buf1
), left_total
),
487 normal_size
, add_commas (buf2
, sizeof (buf2
), left
),
488 parallel_size
, add_commas (buf3
, sizeof (buf3
), left_parallel
),
489 cond_size
, add_commas (buf4
, sizeof (buf4
), left_cond
),
490 nop_size
, add_commas (buf5
, sizeof (buf5
), left_nops
));
492 (*d10v_callback
->printf_filtered
) (d10v_callback
,
493 "executed %*s right instructions, %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
494 size
, add_commas (buf1
, sizeof (buf1
), right_total
),
495 normal_size
, add_commas (buf2
, sizeof (buf2
), right
),
496 parallel_size
, add_commas (buf3
, sizeof (buf3
), right_parallel
),
497 cond_size
, add_commas (buf4
, sizeof (buf4
), right_cond
),
498 nop_size
, add_commas (buf5
, sizeof (buf5
), right_nops
));
500 (*d10v_callback
->printf_filtered
) (d10v_callback
,
501 "executed %*s long instructions\n",
502 size
, add_commas (buf1
, sizeof (buf1
), ins_long
));
505 (*d10v_callback
->printf_filtered
) (d10v_callback
,
506 "executed %*s unknown instructions\n",
507 size
, add_commas (buf1
, sizeof (buf1
), unknown
));
509 (*d10v_callback
->printf_filtered
) (d10v_callback
,
510 "executed %*s instructions conditionally\n",
511 size
, add_commas (buf1
, sizeof (buf1
), cond_true
));
513 (*d10v_callback
->printf_filtered
) (d10v_callback
,
514 "skipped %*s instructions due to conditional failure\n",
515 size
, add_commas (buf1
, sizeof (buf1
), cond_false
));
517 (*d10v_callback
->printf_filtered
) (d10v_callback
,
518 "executed %*s cycles\n",
519 size
, add_commas (buf1
, sizeof (buf1
), cycles
));
521 (*d10v_callback
->printf_filtered
) (d10v_callback
,
522 "executed %*s total instructions\n",
523 size
, add_commas (buf1
, sizeof (buf1
), total
));
527 sim_create_inferior (start_address
, argv
, env
)
528 SIM_ADDR start_address
;
533 uint32 mem_min
, mem_max
;
536 (*d10v_callback
->printf_filtered
) (d10v_callback
, "sim_create_inferior: PC=0x%x\n", start_address
);
538 /* save memory pointers */
541 mem_min
= State
.mem_min
;
542 mem_max
= State
.mem_max
;
543 /* reset all state information */
544 memset (&State
, 0, sizeof(State
));
545 /* restore memory pointers */
548 State
.mem_min
= mem_min
;
549 State
.mem_max
= mem_max
;
551 PC
= start_address
>> 2;
565 /* printf ("sim_set_callbacks\n"); */
570 sim_stop_reason (reason
, sigrc
)
571 enum sim_stop
*reason
;
574 /* (*d10v_callback->printf_filtered) (d10v_callback, "sim_stop_reason: PC=0x%x\n",PC<<2); */
576 switch (State
.exception
)
578 case SIG_D10V_STOP
: /* stop instruction */
579 *reason
= sim_exited
;
583 case SIG_D10V_EXIT
: /* exit trap */
584 *reason
= sim_exited
;
585 *sigrc
= State
.regs
[2];
588 default: /* some signal */
589 *reason
= sim_stopped
;
590 *sigrc
= State
.exception
;
596 sim_fetch_register (rn
, memory
)
598 unsigned char *memory
;
602 WRITE_64 (memory
, State
.a
[rn
-32]);
603 /* (*d10v_callback->printf_filtered) (d10v_callback, "sim_fetch_register %d 0x%llx\n",rn,State.a[rn-32]); */
607 WRITE_16 (memory
, State
.regs
[rn
]);
608 /* (*d10v_callback->printf_filtered) (d10v_callback, "sim_fetch_register %d 0x%x\n",rn,State.regs[rn]); */
613 sim_store_register (rn
, memory
)
615 unsigned char *memory
;
619 State
.a
[rn
-32] = READ_64 (memory
) & MASK40
;
620 /* (*d10v_callback->printf_filtered) (d10v_callback, "store: a%d=0x%llx\n",rn-32,State.a[rn-32]); */
624 State
.regs
[rn
]= READ_16 (memory
);
625 /* (*d10v_callback->printf_filtered) (d10v_callback, "store: r%d=0x%x\n",rn,State.regs[rn]); */
630 sim_read (addr
, buffer
, size
)
632 unsigned char *buffer
;
636 for (i
= 0; i
< size
; i
++)
638 buffer
[i
] = State
.imem
[addr
+ i
];
647 (*d10v_callback
->printf_filtered
) (d10v_callback
, "sim_do_command: %s\n",cmd
);
651 sim_load (prog
, from_tty
)
655 /* Return nonzero so GDB will handle it. */
This page took 0.042322 seconds and 4 git commands to generate.