📄 inst.c
字号:
case Y_C_ULE_S_OP: { SET_COND(inst, COND_LT | COND_EQ | COND_UN); break; } case Y_C_UN_D_OP: case Y_C_UN_S_OP: { SET_COND(inst, COND_UN); break; } } store_instruction (inst);}/* Make and return a deep copy of INST. */instruction *copy_inst (instruction *inst){ instruction *new_inst = (instruction *) xmalloc (sizeof (instruction)); *new_inst = *inst; /*memcpy ((void*)new_inst, (void*)inst , sizeof (instruction));*/ SET_EXPR (new_inst, copy_imm_expr (EXPR (inst))); return (new_inst);}voidfree_inst (instruction *inst){ if (inst != break_inst) /* Don't free the breakpoint insructions since we only have one. */ { if (EXPR (inst)) free (EXPR (inst)); free (inst); }}/* Maintain a table mapping from opcode to instruction name and instruction type. Table must be sorted before first use since its entries are alphabetical on name, not ordered by opcode. *//* Sort all instruction table before first use. */voidinitialize_inst_tables (){ sort_name_table (); sort_i_opcode_table (); sort_a_opcode_table ();}/* Map from opcode -> name/type. */static name_val_val name_tbl [] = {#undef OP#define OP(NAME, OPCODE, TYPE, R_OPCODE) {NAME, OPCODE, TYPE},#include "op.h"};/* Sort the opcode table on their key (the opcode value). */static voidsort_name_table (){ qsort (name_tbl, sizeof (name_tbl) / sizeof (name_val_val), sizeof (name_val_val), (QSORT_FUNC) compare_pair_value);}/* Compare the VALUE1 field of two NAME_VAL_VAL entries in the format required by qsort. */static intcompare_pair_value (name_val_val *p1, name_val_val *p2){ if (p1->value1 < p2->value1) return (-1); else if (p1->value1 > p2->value1) return (1); else return (0);}/* Print the instruction stored at the memory ADDRESS. */voidprint_inst (mem_addr addr){ instruction *inst; static str_stream ss; exception_occurred = 0; inst = read_mem_inst (addr); if (exception_occurred) { error ("Can't print instruction not in text segment (0x%08x)\n", addr); return; } ss_clear (&ss); format_an_inst (&ss, inst, addr); write_output (message_out, ss_to_string (&ss));}voidformat_an_inst (str_stream *ss, instruction *inst, mem_addr addr){ name_val_val *entry; int line_start = ss_length (ss); if (inst_is_breakpoint (addr)) { delete_breakpoint (addr); ss_printf (ss, "*"); format_an_inst (ss, read_mem_inst (addr), addr); add_breakpoint (addr); return; } ss_printf (ss, "[0x%08x]\t", addr); if (inst == NULL) { ss_printf (ss, "<none>\n"); return; } entry = map_int_to_name_val_val (name_tbl, sizeof (name_tbl) / sizeof (name_val_val), OPCODE (inst)); if (entry == NULL) { ss_printf (ss, "<unknown instruction %d>\n", OPCODE (inst)); return; } ss_printf (ss, "0x%08x %s", (uint32)ENCODING (inst), entry->name); switch (entry->value2) { case BC_TYPE_INST: ss_printf (ss, "%d %d", CC (inst), IDISP (inst)); break; case B1_TYPE_INST: ss_printf (ss, " $%d %d", RS (inst), IDISP (inst)); break; case I1s_TYPE_INST: ss_printf (ss, " $%d, %d", RS (inst), IMM (inst)); break; case I1t_TYPE_INST: ss_printf (ss, " $%d, %d", RT (inst), IMM (inst)); break; case I2_TYPE_INST: ss_printf (ss, " $%d, $%d, %d", RT (inst), RS (inst), IMM (inst)); break; case B2_TYPE_INST: ss_printf (ss, " $%d, $%d, %d", RS (inst), RT (inst), IDISP (inst)); break; case I2a_TYPE_INST: ss_printf (ss, " $%d, %d($%d)", RT (inst), IMM (inst), BASE (inst)); break; case R1s_TYPE_INST: ss_printf (ss, " $%d", RS (inst)); break; case R1d_TYPE_INST: ss_printf (ss, " $%d", RD (inst)); break; case R2td_TYPE_INST: ss_printf (ss, " $%d, $%d", RT (inst), RD (inst)); break; case R2st_TYPE_INST: ss_printf (ss, " $%d, $%d", RS (inst), RT (inst)); break; case R2ds_TYPE_INST: ss_printf (ss, " $%d, $%d", RD (inst), RS (inst)); break; case R2sh_TYPE_INST: if (ENCODING (inst) == 0) { ss_erase (ss, 3); /* zap sll */ ss_printf (ss, "nop"); } else ss_printf (ss, " $%d, $%d, %d", RD (inst), RT (inst), SHAMT (inst)); break; case R3_TYPE_INST: ss_printf (ss, " $%d, $%d, $%d", RD (inst), RS (inst), RT (inst)); break; case R3sh_TYPE_INST: ss_printf (ss, " $%d, $%d, $%d", RD (inst), RT (inst), RS (inst)); break; case FP_I2a_TYPE_INST: ss_printf (ss, " $f%d, %d($%d)", FT (inst), IMM (inst), BASE (inst)); break; case FP_R2ds_TYPE_INST: ss_printf (ss, " $f%d, $f%d", FD (inst), FS (inst)); break; case FP_R2ts_TYPE_INST: ss_printf (ss, " $%d, $f%d", RT (inst), FS (inst)); break; case FP_CMP_TYPE_INST: ss_printf (ss, " $f%d, $f%d", FS (inst), FT (inst)); break; case FP_R3_TYPE_INST: ss_printf (ss, " $f%d, $f%d, $f%d", FD (inst), FS (inst), FT (inst)); break; case FP_MOVC_TYPE_INST: if (OPCODE (inst) == Y_MOVF_OP) ss_printf (ss, " $%d, $%d, %d", FD (inst), FS (inst), CC (inst)); else ss_printf (ss, " $f%d, $f%d, %d", FD (inst), FS (inst), CC (inst)); break; case J_TYPE_INST: ss_printf (ss, " 0x%08x", TARGET (inst) << 2); break; case NOARG_TYPE_INST: break; default: fatal_error ("Unknown instruction type in print_inst\n"); } if (EXPR (inst) != NULL && EXPR (inst)->symbol != NULL) { ss_printf (ss, " ["); if (opcode_is_load_store (OPCODE (inst))) format_imm_expr (ss, EXPR (inst), BASE (inst)); else format_imm_expr (ss, EXPR (inst), -1); ss_printf (ss, "]"); } if (SOURCE (inst) != NULL) { /* Comment is source line text of current line. */ int gap_length = 57 - (ss_length (ss) - line_start); for ( ; 0 < gap_length; gap_length -= 1) { ss_printf (ss, " "); } ss_printf (ss, "; "); ss_printf (ss, "%s", SOURCE (inst)); } ss_printf (ss, "\n");}/* Return non-zero if SPIM OPCODE (e.g. Y_...) represents a conditional branch. */intopcode_is_branch (int opcode){ switch (opcode) { case Y_BC1F_OP: case Y_BC1FL_OP: case Y_BC1T_OP: case Y_BC1TL_OP: case Y_BC2F_OP: case Y_BC2FL_OP: case Y_BC2T_OP: case Y_BC2TL_OP: case Y_BEQ_OP: case Y_BEQL_OP: case Y_BEQZ_POP: case Y_BGE_POP: case Y_BGEU_POP: case Y_BGEZ_OP: case Y_BGEZAL_OP: case Y_BGEZALL_OP: case Y_BGEZL_OP: case Y_BGT_POP: case Y_BGTU_POP: case Y_BGTZ_OP: case Y_BGTZL_OP: case Y_BLE_POP: case Y_BLEU_POP: case Y_BLEZ_OP: case Y_BLEZL_OP: case Y_BLT_POP: case Y_BLTU_POP: case Y_BLTZ_OP: case Y_BLTZAL_OP: case Y_BLTZALL_OP: case Y_BLTZL_OP: case Y_BNE_OP: case Y_BNEL_OP: case Y_BNEZ_POP: return (1); default: return (0); }}/* Return non-zero if SPIM OPCODE represents a nullified (e.g., Y_...L_OP) conditional branch. */intopcode_is_nullified_branch (int opcode){ switch (opcode) { case Y_BC1FL_OP: case Y_BC1TL_OP: case Y_BC2FL_OP: case Y_BC2TL_OP: case Y_BEQL_OP: case Y_BGEZALL_OP: case Y_BGEZL_OP: case Y_BGTZL_OP: case Y_BLEZL_OP: case Y_BLTZALL_OP: case Y_BLTZL_OP: case Y_BNEL_OP: return (1); default: return (0); }}/* Return non-zero if SPIM OPCODE (e.g. Y_...) represents a conditional branch on a true condition. */intopcode_is_true_branch (int opcode){ switch (opcode) { case Y_BC1T_OP: case Y_BC1TL_OP: case Y_BC2T_OP: case Y_BC2TL_OP: return (1); default: return (0); }}/* Return non-zero if SPIM OPCODE (e.g. Y_...) is a direct unconditional branch (jump). */intopcode_is_jump (int opcode){ switch (opcode) { case Y_J_OP: case Y_JAL_OP: return (1); default: return (0); }}/* Return non-zero if SPIM OPCODE (e.g. Y_...) is a load or store. */intopcode_is_load_store (int opcode){ switch (opcode) { case Y_LB_OP: case Y_LBU_OP: case Y_LH_OP: case Y_LHU_OP: case Y_LL_OP: case Y_LDC1_OP: case Y_LDC2_OP: case Y_LW_OP: case Y_LWC1_OP: case Y_LWC2_OP: case Y_LWL_OP: case Y_LWR_OP: case Y_SB_OP: case Y_SC_OP: case Y_SH_OP: case Y_SDC1_OP: case Y_SDC2_OP: case Y_SW_OP: case Y_SWC1_OP: case Y_SWC2_OP: case Y_SWL_OP: case Y_SWR_OP: return (1); default: return (0); }}/* Return non-zero if a breakpoint is set at ADDR. */intinst_is_breakpoint (mem_addr addr){ if (break_inst == NULL) break_inst = make_r_type_inst (Y_BREAK_OP, 1, 0, 0); return (read_mem_inst (addr) == break_inst);}/* Set a breakpoint at ADDR and return the old instruction. If the breakpoint cannot be set, return NULL. */instruction *set_breakpoint (mem_addr addr){ instruction *old_inst; if (break_inst == NULL) break_inst = make_r_type_inst (Y_BREAK_OP, 1, 0, 0); exception_occurred = 0; old_inst = read_mem_inst (addr); if (old_inst == break_inst) return (NULL); set_mem_inst (addr, break_inst); if (exception_occurred) return (NULL); else return (old_inst);}/* An immediate expression has the form: SYMBOL +/- IOFFSET, where either part may be omitted. *//* Make and return a new immediate expression */imm_expr *make_imm_expr (int offs, char *sym, int pc_rel){ imm_expr *expr = (imm_expr *) xmalloc (sizeof (imm_expr)); expr->offset = offs; expr->bits = 0; expr->pc_relative = (short)pc_rel; if (sym != NULL) expr->symbol = lookup_label (sym); else expr->symbol = NULL; return (expr);}/* Return a shallow copy of the EXPRESSION. */imm_expr *copy_imm_expr (imm_expr *old_expr){ imm_expr *expr = (imm_expr *) xmalloc (sizeof (imm_expr)); *expr = *old_expr; /*memcpy ((void*)expr, (void*)old_expr, sizeof (imm_expr));*/ return (expr);}/* Return a shallow copy of an EXPRESSION that only uses the upper sixteen bits of the expression's value. */imm_expr *upper_bits_of_expr (imm_expr *old_expr){ imm_expr *expr = copy_imm_expr (old_expr); expr->bits = 1; return (expr);}/* Return a shallow copy of the EXPRESSION that only uses the lower sixteen bits of the expression's value. */imm_expr *lower_bits_of_expr (imm_expr *old_expr){ imm_expr *expr = copy_imm_expr (old_expr);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -