/* Create instruction from input parametres */ TList_item *create_ins(const int ins_type, TVariable *addr1, TVariable *addr2, TVariable *addr3) { TList_item *ins; if (ins_type == INS_ASSIGN) { if (operation_table[addr1->var_type][addr2->var_type] == ER) { my_exit_error(E_SEMANTIC_TYPES, 11); } if (addr1->var_type == TYPE_AUTO) { addr1->var_type = addr2->var_type; } } ins = malloc(sizeof(TList_item)); if (ins == NULL) { my_exit_error(E_ALLOC, 9); } ins->ins_type = ins_type; ins->addr1 = addr1; ins->addr2 = addr2; ins->addr3 = addr3; #ifdef DEBUG_MODE print_ins(&ins_type, addr1, addr2, addr3); #endif return ins; }
size_t asm_prescan_ins(struct assembler *asmer, struct asm_ins *ins, char *buf) { print_ins(ins); ins_writer writer = WRITERS[ins->name]; return writer(asmer, ins, buf); }
static void dfs_permu(int dep, int n) { int i; int tmp; struct ins tmp_ins; if (dep >= n) { tmp = eval_resched_buf(); if (tmp < best_hazards) { printf("original:\n"); for (i = 0; i < n; i++) { print_ins(&resched_buf_best[i]); printf("\n"); } printf("resched:\n"); for (i = 0; i < n; i++) { print_ins(&cpu.resched_buf[i]); printf("\n"); } best_hazards = tmp; memcpy(resched_buf_best, cpu.resched_buf, n * sizeof(struct ins)); } return; } dfs_permu(dep+1, n); for (i = dep; i < n-1 && !has_dep(&cpu.resched_buf[i], &cpu.resched_buf[i+1]); i++) { // swap tmp_ins = cpu.resched_buf[i+1]; cpu.resched_buf[i+1] = cpu.resched_buf[i]; cpu.resched_buf[i] = tmp_ins; dfs_permu(dep+1, n); } // swap back tmp_ins = cpu.resched_buf[dep]; cpu.resched_buf[dep] = cpu.resched_buf[i]; cpu.resched_buf[i] = tmp_ins; }
static void run() { int n_data_hazards = 0; int n_cycles = 0; char *mem; int rs, rt, rd, imm; int i, j = 0, k; init_cpu(); while (cpu.pc_mem < ins_buf + n_ins) { if (need_resched()) resched(); if (debug) { printf("%d: ", cpu.pc_mem - ins_buf); print_ins(cpu.pc_rb); } history_buf[j] = *cpu.pc_rb; exec_ins(); if (debug) { for (i = 0; i < 4; i++) printf("%ss%d=%d", i==0?"\t# ":", ", i, cpu.reg_value[REG_S0 + i]); for (i = 0; i < 2; i++) printf(", t%d=%d", i, cpu.reg_value[REG_T0 + i]); printf("\n"); } cpu.pc_mem++; if (cpu.pc_rb != NULL) cpu.pc_rb++; n_cycles++; // count hazard for (k = 1; k < stall_range && k < n_cycles; k++) if (has_dep(&history_buf[(j - k + HISTORY_BUF_LEN) % HISTORY_BUF_LEN], &history_buf[j])) { n_data_hazards++; break; } j = (j + 1) % HISTORY_BUF_LEN; } if (profile) printf("Cycles: %d, data hazards: %d\n", n_cycles, n_data_hazards); }
int main(int argc, char **argv) { int opt; int i; // yydebug = 1; while ((opt = getopt(argc, argv, "dO:phs:")) >= 0) { switch (opt) { case 'd': debug = 1; break; case 'O': optimized = 1; resched_buf_len = atoi(optarg); break; case 'p': profile = 1; break; case 'h': help(); return 0; case 's': stall_range = atoi(optarg); break; default: help(); return 1; } } if (optind < argc) { debug_msg("Read from %s.\n", argv[optind]); yyin = fopen(argv[optind], "r"); if (!yyin) die(); } else yyin = stdin; debug_msg("Parse assembly code.\n"); if (yyparse() > 0) { printf("Syntax error\n"); exit(1); } debug_msg("%d instruction(s) has been loaded.\n", n_ins); if (debug) { for (i = 0; i < n_ins; i++) { print_ins(&ins_buf[i]); printf("\n"); } } debug_msg("Start exectuion. Reschedule-buffer: %d.\n", resched_buf_len); run(); return 0; }