diff options
author | Michael Meissner <gnu@the-meissners.org> | 1996-10-22 19:49:37 +0000 |
---|---|---|
committer | Michael Meissner <gnu@the-meissners.org> | 1996-10-22 19:49:37 +0000 |
commit | aeb1f26ba82ba8624f71a4e43b9f28cd739e6f36 (patch) | |
tree | a1951abd8353ea7dc4e947261dd9ccdfc1f8b46f /sim/d10v/interp.c | |
parent | a3fac17e0b4288f6abc8957dc8028a9448159afb (diff) | |
download | gdb-aeb1f26ba82ba8624f71a4e43b9f28cd739e6f36.zip gdb-aeb1f26ba82ba8624f71a4e43b9f28cd739e6f36.tar.gz gdb-aeb1f26ba82ba8624f71a4e43b9f28cd739e6f36.tar.bz2 |
Provide better statistics, particularly for doing VLIW work; Fix ldb to correctly sign extend
Diffstat (limited to 'sim/d10v/interp.c')
-rw-r--r-- | sim/d10v/interp.c | 281 |
1 files changed, 194 insertions, 87 deletions
diff --git a/sim/d10v/interp.c b/sim/d10v/interp.c index 21d4811..a6c7b2e 100644 --- a/sim/d10v/interp.c +++ b/sim/d10v/interp.c @@ -12,12 +12,42 @@ enum _leftright { LEFT_FIRST, RIGHT_FIRST }; int d10v_debug; host_callback *d10v_callback; -long ins_type_counters[ (int)INS_MAX ]; -long left_nops, right_nops; +unsigned long ins_type_counters[ (int)INS_MAX ]; uint16 OP[4]; +static long hash PARAMS ((long insn, int format)); static struct hash_entry *lookup_hash PARAMS ((uint32 ins, int size)); +static void get_operands PARAMS ((struct simops *s, uint32 ins)); +static void do_long PARAMS ((uint32 ins)); +static void do_2_short PARAMS ((uint16 ins1, uint16 ins2, enum _leftright leftright)); +static void do_parallel PARAMS ((uint16 ins1, uint16 ins2)); +static char *add_commas PARAMS ((char *buf, int sizeof_buf, unsigned long value)); +extern void sim_size PARAMS ((int power)); +static void init_system PARAMS ((void)); +extern int sim_write PARAMS ((SIM_ADDR addr, unsigned char *buffer, int size)); +extern void sim_open PARAMS ((char *args)); +extern void sim_close PARAMS ((int quitting)); +extern void sim_set_profile PARAMS ((int n)); +extern void sim_set_profile_size PARAMS ((int n)); +extern void sim_resume PARAMS ((int step, int siggnal)); +extern void sim_info PARAMS ((int verbose)); +extern void sim_create_inferior PARAMS ((SIM_ADDR start_address, char **argv, char **env)); +extern void sim_kill PARAMS ((void)); +extern void sim_set_callbacks PARAMS ((host_callback *p)); +extern void sim_stop_reason PARAMS ((enum sim_stop *reason, int *sigrc)); +extern void sim_fetch_register PARAMS ((int rn, unsigned char *memory)); +extern void sim_store_register PARAMS ((int rn, unsigned char *memory)); +extern int sim_read PARAMS ((SIM_ADDR addr, unsigned char *buffer, int size)); +extern void sim_do_command PARAMS ((char *cmd)); + +#ifndef INLINE +#if defined(__GNUC__) && defined(__OPTIMIZE__) +#define INLINE __inline__ +#else +#define INLINE +#endif +#endif #define MAX_HASH 63 struct hash_entry @@ -30,7 +60,7 @@ struct hash_entry struct hash_entry hash_table[MAX_HASH+1]; -static long +INLINE static long hash(insn, format) long insn; int format; @@ -41,7 +71,7 @@ hash(insn, format) return((insn & 0x7E00) >> 9); } -static struct hash_entry * +INLINE static struct hash_entry * lookup_hash (ins, size) uint32 ins; int size; @@ -53,19 +83,19 @@ lookup_hash (ins, size) else h = &hash_table[(ins & 0x7E00) >> 9]; - while ( (ins & h->mask) != h->opcode) + while ((ins & h->mask) != h->opcode) { if (h->next == NULL) { (*d10v_callback->printf_filtered) (d10v_callback, "ERROR looking up hash for %x at PC %x\n",ins, PC); - exit(1); + exit (1); } h = h->next; } return (h); } -static void +INLINE static void get_operands (struct simops *s, uint32 ins) { int i, shift, bits, flags; @@ -142,28 +172,36 @@ do_parallel (ins1, ins2) if (h1->ops->exec_type == PARONLY) { get_operands (h1->ops, ins1); - State.ins_type = INS_LEFT; + State.ins_type = INS_LEFT_COND_TEST; ins_type_counters[ (int)State.ins_type ]++; (h1->ops->func)(); if (State.exe) { + ins_type_counters[ (int)INS_COND_TRUE ]++; get_operands (h2->ops, ins2); - State.ins_type = INS_RIGHT; + State.ins_type = INS_RIGHT_COND_EXE; + ins_type_counters[ (int)State.ins_type ]++; (h2->ops->func)(); } + else + ins_type_counters[ (int)INS_COND_FALSE ]++; } else if (h2->ops->exec_type == PARONLY) { get_operands (h2->ops, ins2); - State.ins_type = INS_RIGHT; + State.ins_type = INS_RIGHT_COND_TEST; ins_type_counters[ (int)State.ins_type ]++; (h2->ops->func)(); if (State.exe) { + ins_type_counters[ (int)INS_COND_TRUE ]++; get_operands (h1->ops, ins1); - State.ins_type = INS_LEFT; + State.ins_type = INS_LEFT_COND_EXE; + ins_type_counters[ (int)State.ins_type ]++; (h1->ops->func)(); } + else + ins_type_counters[ (int)INS_COND_FALSE ]++; } else { @@ -181,6 +219,28 @@ do_parallel (ins1, ins2) } } +static char * +add_commas(buf, sizeof_buf, value) + char *buf; + int sizeof_buf; + unsigned long value; +{ + int comma = 3; + char *endbuf = buf + sizeof_buf - 1; + + *--endbuf = '\0'; + do { + if (comma-- == 0) + { + *--endbuf = ','; + comma = 2; + } + + *--endbuf = (value % 10) + '0'; + } while ((value /= 10) != 0); + + return endbuf; +} void sim_size (power) @@ -207,8 +267,13 @@ sim_size (power) #ifdef DEBUG if ((d10v_debug & DEBUG_MEMSIZE) != 0) { - (*d10v_callback->printf_filtered) (d10v_callback, "Allocated %d bytes instruction memory and\n",1<<IMEM_SIZE); - (*d10v_callback->printf_filtered) (d10v_callback, " %d bytes data memory.\n", 1<<DMEM_SIZE); + char buffer[20]; + (*d10v_callback->printf_filtered) (d10v_callback, + "Allocated %s bytes instruction memory and\n", + add_commas (buffer, sizeof (buffer), (1UL<<IMEM_SIZE))); + + (*d10v_callback->printf_filtered) (d10v_callback, " %s bytes data memory.\n", + add_commas (buffer, sizeof (buffer), (1UL<<IMEM_SIZE))); } #endif } @@ -249,7 +314,7 @@ sim_open (args) char *args; { struct simops *s; - struct hash_entry *h, *prev; + struct hash_entry *h; static int init_p = 0; if (args != NULL) @@ -312,63 +377,63 @@ sim_resume (step, siggnal) int step, siggnal; { uint32 inst; - int i; - reg_t oldpc; + reg_t oldpc = 0; /* (*d10v_callback->printf_filtered) (d10v_callback, "sim_resume (%d,%d) PC=0x%x\n",step,siggnal,PC); */ State.exception = 0; - do - { - uint32 byte_pc = ((uint32)PC) << 2; - if ((byte_pc < State.mem_min) || (byte_pc > State.mem_max)) - { - (*d10v_callback->printf_filtered) (d10v_callback, - "PC (0x%lx) out of range, oldpc = 0x%lx, min = 0x%lx, max = 0x%lx\n", - (long)byte_pc, (long)oldpc, (long)State.mem_min, (long)State.mem_max); - State.exception = SIGILL; - } - else - { - inst = RLW (byte_pc); - oldpc = PC; - switch (inst & 0xC0000000) - { - case 0xC0000000: - /* long instruction */ - do_long (inst & 0x3FFFFFFF); - break; - case 0x80000000: - /* R -> L */ - do_2_short ( inst & 0x7FFF, (inst & 0x3FFF8000) >> 15, 0); - break; - case 0x40000000: - /* L -> R */ - do_2_short ((inst & 0x3FFF8000) >> 15, inst & 0x7FFF, 1); - break; - case 0: - do_parallel ((inst & 0x3FFF8000) >> 15, inst & 0x7FFF); - break; - } + do + { + uint32 byte_pc = ((uint32)PC) << 2; + if ((byte_pc < State.mem_min) || (byte_pc > State.mem_max)) + { + (*d10v_callback->printf_filtered) (d10v_callback, + "PC (0x%lx) out of range, oldpc = 0x%lx, min = 0x%lx, max = 0x%lx\n", + (long)byte_pc, (long)oldpc, (long)State.mem_min, (long)State.mem_max); + State.exception = SIGILL; + } + else + { + inst = RLW (byte_pc); + oldpc = PC; + ins_type_counters[ (int)INS_CYCLES ]++; + switch (inst & 0xC0000000) + { + case 0xC0000000: + /* long instruction */ + do_long (inst & 0x3FFFFFFF); + break; + case 0x80000000: + /* R -> L */ + do_2_short ( inst & 0x7FFF, (inst & 0x3FFF8000) >> 15, 0); + break; + case 0x40000000: + /* L -> R */ + do_2_short ((inst & 0x3FFF8000) >> 15, inst & 0x7FFF, 1); + break; + case 0: + do_parallel ((inst & 0x3FFF8000) >> 15, inst & 0x7FFF); + break; + } - if (State.RP && PC == RPT_E) - { - RPT_C -= 1; - if (RPT_C == 0) - State.RP = 0; - else - PC = RPT_S; - } - - /* FIXME */ - if (PC == oldpc) - PC++; - } - } - while ( !State.exception && !step); - - if (step && !State.exception) - State.exception = SIGTRAP; + if (State.RP && PC == RPT_E) + { + RPT_C -= 1; + if (RPT_C == 0) + State.RP = 0; + else + PC = RPT_S; + } + + /* FIXME */ + if (PC == oldpc) + PC++; + } + } + while ( !State.exception && !step); + + if (step && !State.exception) + State.exception = SIGTRAP; } int @@ -385,36 +450,77 @@ void sim_info (verbose) int verbose; { - char buf[40]; - int size; - long total = (ins_type_counters[ (int)INS_LONG ] - + ins_type_counters[ (int)INS_LEFT ] - + ins_type_counters[ (int)INS_LEFT_PARALLEL ] - + ins_type_counters[ (int)INS_RIGHT ] - + ins_type_counters[ (int)INS_RIGHT_PARALLEL ]); + char buf1[40]; + char buf2[40]; + char buf3[40]; + char buf4[40]; + char buf5[40]; + unsigned long left = ins_type_counters[ (int)INS_LEFT ] + ins_type_counters[ (int)INS_LEFT_COND_EXE ]; + unsigned long left_nops = ins_type_counters[ (int)INS_LEFT_NOPS ]; + unsigned long left_parallel = ins_type_counters[ (int)INS_LEFT_PARALLEL ]; + unsigned long left_cond = ins_type_counters[ (int)INS_LEFT_COND_TEST ]; + unsigned long left_total = left + left_parallel + left_cond + left_nops; + + unsigned long right = ins_type_counters[ (int)INS_RIGHT ] + ins_type_counters[ (int)INS_RIGHT_COND_EXE ]; + unsigned long right_nops = ins_type_counters[ (int)INS_RIGHT_NOPS ]; + unsigned long right_parallel = ins_type_counters[ (int)INS_RIGHT_PARALLEL ]; + unsigned long right_cond = ins_type_counters[ (int)INS_RIGHT_COND_TEST ]; + unsigned long right_total = right + right_parallel + right_cond + right_nops; + + unsigned long unknown = ins_type_counters[ (int)INS_UNKNOWN ]; + unsigned long ins_long = ins_type_counters[ (int)INS_LONG ]; + unsigned long cond_true = ins_type_counters[ (int)INS_COND_TRUE ]; + unsigned long cond_false = ins_type_counters[ (int)INS_COND_FALSE ]; + unsigned long cycles = ins_type_counters[ (int)INS_CYCLES ]; + unsigned long total = (unknown + left_total + right_total + ins_long); + + int size = strlen (add_commas (buf1, sizeof (buf1), total)); + int parallel_size = strlen (add_commas (buf1, sizeof (buf1), + (left_parallel > right_parallel) ? left_parallel : right_parallel)); + int cond_size = strlen (add_commas (buf1, sizeof (buf1), (left_cond > right_cond) ? left_cond : right_cond)); + int nop_size = strlen (add_commas (buf1, sizeof (buf1), (left_nops > right_nops) ? left_nops : right_nops)); + int normal_size = strlen (add_commas (buf1, sizeof (buf1), (left > right) ? left : right)); + + (*d10v_callback->printf_filtered) (d10v_callback, + "executed %*s left instructions, %*s normal, %*s parallel, %*s EXExxx, %*s nops\n", + size, add_commas (buf1, sizeof (buf1), left_total), + normal_size, add_commas (buf2, sizeof (buf2), left), + parallel_size, add_commas (buf3, sizeof (buf3), left_parallel), + cond_size, add_commas (buf4, sizeof (buf4), left_cond), + nop_size, add_commas (buf5, sizeof (buf5), left_nops)); + + (*d10v_callback->printf_filtered) (d10v_callback, + "executed %*s right instructions, %*s normal, %*s parallel, %*s EXExxx, %*s nops\n", + size, add_commas (buf1, sizeof (buf1), right_total), + normal_size, add_commas (buf2, sizeof (buf2), right), + parallel_size, add_commas (buf3, sizeof (buf3), right_parallel), + cond_size, add_commas (buf4, sizeof (buf4), right_cond), + nop_size, add_commas (buf5, sizeof (buf5), right_nops)); + + (*d10v_callback->printf_filtered) (d10v_callback, + "executed %*s long instructions\n", + size, add_commas (buf1, sizeof (buf1), ins_long)); - sprintf (buf, "%ld", total); - size = strlen (buf); + if (unknown) + (*d10v_callback->printf_filtered) (d10v_callback, + "executed %*s unknown instructions\n", + size, add_commas (buf1, sizeof (buf1), unknown)); (*d10v_callback->printf_filtered) (d10v_callback, - "executed %*ld instructions in the left container, %*ld parallel, %*ld nops\n", - size, ins_type_counters[ (int)INS_LEFT ] + ins_type_counters[ (int)INS_LEFT_PARALLEL ], - size, ins_type_counters[ (int)INS_LEFT_PARALLEL ], - size, left_nops); + "executed %*s instructions conditionally\n", + size, add_commas (buf1, sizeof (buf1), cond_true)); (*d10v_callback->printf_filtered) (d10v_callback, - "executed %*ld instructions in the right container, %*ld parallel, %*ld nops\n", - size, ins_type_counters[ (int)INS_RIGHT ] + ins_type_counters[ (int)INS_RIGHT_PARALLEL ], - size, ins_type_counters[ (int)INS_RIGHT_PARALLEL ], - size, right_nops); + "skipped %*s instructions due to conditional failure\n", + size, add_commas (buf1, sizeof (buf1), cond_false)); (*d10v_callback->printf_filtered) (d10v_callback, - "executed %*ld long instructions\n", - size, ins_type_counters[ (int)INS_LONG ]); + "executed %*s cycles\n", + size, add_commas (buf1, sizeof (buf1), cycles)); (*d10v_callback->printf_filtered) (d10v_callback, - "executed %*ld total instructions\n", - size, total); + "executed %*s total instructions\n", + size, add_commas (buf1, sizeof (buf1), total)); } void @@ -520,6 +626,7 @@ sim_store_register (rn, memory) } } +int sim_read (addr, buffer, size) SIM_ADDR addr; unsigned char *buffer; |