/* STAT(type, name, explanation, variable, initial value, format string) */
/* STAT_OBSERVE(type, name, explanation, variable, initial value, format string) */
/* STAT_OBSERVE is used to register existing variables at statistics */
/* STAT_FORMULA(name, explanation, function, format string) */

/* register baseline stats */
STAT_OBSERVE(uquad, "sim_num_insn", "total number of instructions committed", q_tail, 0, NULL)
STAT(uquad, "sim_num_loads", "total number of loads committed", num_loads, 0, NULL)
STAT_FORMULA("sim_num_refs", "total number of loads and stores committed", "sim_num_loads + sim_num_stores", "%12.0f")
STAT(uquad, "sim_num_stores", "total number of stores committed", num_stores, 0, NULL)
STAT(uquad, "sim_num_control", "total number of control insts committed", num_control, 0, NULL)
STAT(uquad, "sim_num_cmov", "total number of cond. move insts committed", num_cmov, 0, NULL)
STAT(uquad, "sim_total_fetched", "total number of instructions fetched", num_fetched, 0, NULL)
STAT_OBSERVE(uquad, "sim_total_decoded", "total number of instructions decoded", sequence, 0, NULL)
STAT(uquad, "sim_total_insn", "total number of instructions executed", total_insts, 0, NULL)
STAT_FORMULA("sim_total_refs", "total number of loads and stores executed", "sim_total_stores + sim_total_loads", "%12.0f")
STAT(uquad, "sim_total_loads", "total number of loads executed", total_loads, 0, NULL)
STAT(uquad, "sim_total_stores", "total number of stores executed", total_stores, 0, NULL)
STAT(uquad, "sim_total_control", "total number of control insts executed", total_control, 0, NULL)

STAT_FORMULA("sim_inst_rate", "simulation speed (in insts/sec)", "sim_num_insn / elapsed_time", "%12.0f")

/* register performance stats */
STAT_FORMULA("sim_IPC", "instructions per cycle", "sim_num_insn / cycle", NULL)
STAT_FORMULA("sim_CPI", "cycles per instruction", "cycle / sim_num_insn", NULL)
STAT_FORMULA("sim_exec_BW", "total instructions (mis-spec + committed) per cycle", "sim_total_insn / cycle", NULL)
STAT_FORMULA("sim_IPB", "instruction per control transfer", "sim_num_insn / sim_num_control", NULL)
STAT_FORMULA("sim_mispredicts", "number of mispredictions", "sim_num_branch - sim_num_branch_hits + sim_num_indirect - sim_num_indirect_hits + sim_num_return - sim_num_return_hits", NULL)
STAT_FORMULA("sim_IPM", "instruction per misprediction", "sim_num_insn / sim_mispredicts", NULL)

/* register predictor stats */
STAT_OBSERVE(uquad, "sim_num_branch", "number of retired conditional branches", num_preds[PTYPE_COND], 0, NULL)
STAT_OBSERVE(uquad, "sim_num_branch_hits", "number of retired correctly predicted conditional branches", num_pred_hits[PTYPE_COND], 0, NULL)
STAT_FORMULA("sim_branch_accuracy", "percentage of correctly predicted conditional branches", "sim_num_branch_hits / sim_num_branch", NULL)

STAT_OBSERVE(uquad, "sim_num_indirect", "number of retired indirect branches", num_preds[PTYPE_INDIRECT], 0, NULL)
STAT_OBSERVE(uquad, "sim_num_indirect_hits", "number of retired correctly predicted indirect branches", num_pred_hits[PTYPE_INDIRECT], 0, NULL)
STAT_FORMULA("sim_indirect_accuracy", "percentage of correctly predicted indirect branches", "sim_num_indirect_hits / sim_num_indirect", NULL)

STAT_OBSERVE(uquad, "sim_num_return", "number of retired returns", num_preds[PTYPE_RAS], 0, NULL)
STAT_OBSERVE(uquad, "sim_num_return_hits", "number of retired correctly predicted returns", num_pred_hits[PTYPE_RAS], 0, NULL)
STAT_FORMULA("sim_return_accuracy", "percentage of correctly predicted returns", "sim_num_return_hits / sim_num_return", NULL)
STAT(uquad, "sim_zero_return_addr", "number of RAS returning addr 0", zero_return_address, 0, NULL)

/* register squash/exception stats */

STAT(uquad, "sim_bypasses", "number of loads satisfied by store queue", bypasses, 0, NULL)
STAT(uquad, "sim_early_stores", "number of stores scheduled before value", num_early_stores, 0, NULL)
STAT(uquad, "sim_early_store_bypasses", "number of loads waiting for early store resolution", num_early_store_bypasses, 0, NULL)

/* register squash/exception stats */

STAT(uquad, "sim_squashes", "total number of squashes", num_squashes, 0, NULL)
STAT(uquad, "sim_num_squashed", "total number of squashed decoded insts", num_squashed, 0, NULL)
STAT(uquad, "sim_fetch_squashes", "total number of spawn-related squashes", num_fetch_squashes, 0, NULL)
STAT(uquad, "sim_num_fetch_squashed", "total number of spawn-related squashed insts", num_fetch_squashed, 0, NULL)
STAT_OBSERVE(uquad, "unligned_replays", "number replays due to unaligned access", num_exceptions[UNALIGNED_ACCESS], 0, NULL)
STAT_OBSERVE(uquad, "sim_load_replays", "number replays due to load conflicts", num_exceptions[MEMORY_REPLAY_TRAP], 0, NULL)
STAT(uquad, "sim_num_restarts", "total number of consistency-related restarts", num_consist_restarts, 0, NULL)

/* occupancy stats */
STAT_DIST("sim_window_dist", "window occupancy distribution", window_dist, MAX_WINDOW + 2, 1)
STAT_DIST("sim_front_dist", "front-end occupancy distribution", front_dist, MAX_FRONT + 2, 1)
STAT_DIST("sim_execute_dist", "execution distribution", execute_dist, MAX_EXECUTE + 2, 1)
STAT_DIST("sim_retire_dist", "retirement distribution", retire_dist, MAX_WINDOW + 2, 1)
STAT(uquad, "sim_mshr_retire_stalls", "number of cycles instructions couldn't be retired due to a full mshr", num_mshr_retire_stalls, 0, NULL)
STAT(uquad, "sim_sync_retire_stalls", "number of cycles instructions couldn't be retired waiting for store buffer", num_sync_retire_stalls, 0, NULL)

/* cache stats */
STAT(uquad, "sim_icache_misses", "number fetches which miss in icache", num_icache_miss, 0, NULL)
STAT(uquad, "sim_load_misses", "number loads which miss in dcache", num_load_miss, 0, NULL)
STAT(uquad, "sim_store_misses", "number stores which miss in dcache", num_store_miss, 0, NULL)
