📄 inst.c
字号:
COND(inst) = COND_LT | COND_EQ | COND_UN; break; } case Y_C_UN_D_OP: case Y_C_UN_S_OP: { COND(inst) = COND_UN; break; } } store_instruction (inst);}/* Make and return a deep copy of INST. */#ifdef __STDC__instruction *copy_inst (instruction *inst)#elseinstruction *copy_inst (inst)instruction *inst;#endif{ 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);}#ifdef __STDC__voidfree_inst (instruction *inst)#elsevoidfree_inst (inst)instruction *inst;#endif{ 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. */static int sorted_name_table = 0; /* Non-zero => table sorted *//* Map from opcode -> name/type. */static inst_info name_tbl [] = {#undef OP#define OP(NAME, OPCODE, TYPE, R_OPCODE) {NAME, OPCODE, TYPE},#include "op.h"};/* Compare the VALUE1 field of two INST_INFO entries in the format required by qsort. */#ifdef __STDC__static intcompare_pair_value (inst_info *p1, inst_info *p2)#elsestatic intcompare_pair_value (p1, p2) inst_info *p1, *p2;#endif{ if (p1->value1 < p2->value1) return (-1); else if (p1->value1 > p2->value1) return (1); else return (0);}/* Sort the opcode table on their key (the opcode value). */#ifdef __STDC__static voidsort_name_table (void)#elsestatic voidsort_name_table ()#endif{ qsort (name_tbl, sizeof (name_tbl) / sizeof (inst_info), sizeof (inst_info), (QSORT_FUNC) compare_pair_value); sorted_name_table = 1;}/* Print the instruction stored at the memory ADDRESS. */#ifdef __STDC__voidprint_inst (mem_addr addr)#elsevoidprint_inst (addr) mem_addr addr;#endif{ instruction *inst; char buf [1024]; exception_occurred = 0; READ_MEM_INST (inst, addr); if (exception_occurred) { error ("Can't print instruction not in text segment (0x%08x)\n", addr); return; } print_inst_internal (buf, sizeof(buf), inst, addr); write_output (message_out, buf);}#ifdef __STDC__intprint_inst_internal (char *buf, int length, instruction *inst, mem_addr addr)#elseintprint_inst_internal (buf, length, inst, addr) char *buf; int length; instruction *inst; mem_addr addr;#endif{ char *bp = buf; inst_info *entry; if (!sorted_name_table) sort_name_table (); sprintf (buf, "[0x%08x]\t", addr); buf += strlen (buf); if (inst == NULL) { sprintf (buf, "<none>\n"); buf += strlen (buf); return (buf - bp); } entry = map_int_to_inst_info (name_tbl, sizeof (name_tbl) / sizeof (inst_info), OPCODE (inst)); if (entry == NULL) { sprintf (buf, "<unknown instruction %d>\n", OPCODE (inst)); buf += strlen (buf); return (buf - bp); } sprintf (buf, "0x%08x %s", ENCODING (inst), entry->name); buf += strlen (buf); switch (entry->value2) { case B0_TYPE_INST: sprintf (buf, " %d", IDISP (inst)); buf += strlen (buf); break; case B1_TYPE_INST: sprintf (buf, " $%d %d", RS (inst), IDISP (inst)); buf += strlen (buf); break; case I1t_TYPE_INST: sprintf (buf, " $%d, %d", RT (inst), IMM (inst)); buf += strlen (buf); break; case I2_TYPE_INST: sprintf (buf, " $%d, $%d, %d", RT (inst), RS (inst), IMM (inst)); buf += strlen (buf); break; case B2_TYPE_INST: sprintf (buf, " $%d, $%d, %d", RS (inst), RT (inst), IDISP (inst)); buf += strlen (buf); break; case I2a_TYPE_INST: sprintf (buf, " $%d, %d($%d)", RT (inst), IMM (inst), BASE (inst)); buf += strlen (buf); break; case R1s_TYPE_INST: sprintf (buf, " $%d", RS (inst)); buf += strlen (buf); break; case R1d_TYPE_INST: sprintf (buf, " $%d", RD (inst)); buf += strlen (buf); break; case R2td_TYPE_INST: sprintf (buf, " $%d, $%d", RT (inst), RD (inst)); buf += strlen (buf); break; case R2st_TYPE_INST: sprintf (buf, " $%d, $%d", RS (inst), RT (inst)); buf += strlen (buf); break; case R2ds_TYPE_INST: sprintf (buf, " $%d, $%d", RD (inst), RS (inst)); buf += strlen (buf); break; case R2sh_TYPE_INST: if (ENCODING (inst) == 0) { buf -= 3; /* zap sll */ sprintf (buf, "nop"); } else sprintf (buf, " $%d, $%d, %d", RD (inst), RT (inst), SHAMT (inst)); buf += strlen (buf); break; case R3_TYPE_INST: sprintf (buf, " $%d, $%d, $%d", RD (inst), RS (inst), RT (inst)); buf += strlen (buf); break; case R3sh_TYPE_INST: sprintf (buf, " $%d, $%d, $%d", RD (inst), RT (inst), RS (inst)); buf += strlen (buf); break; case FP_I2a_TYPE_INST: sprintf (buf, " $f%d, %d($%d)", FT (inst), IMM (inst), BASE (inst)); buf += strlen (buf); break; case FP_R2ds_TYPE_INST: sprintf (buf, " $f%d, $f%d", FD (inst), FS (inst)); buf += strlen (buf); break; case FP_CMP_TYPE_INST: sprintf (buf, " $f%d, $f%d", FS (inst), FT (inst)); buf += strlen (buf); break; case FP_R3_TYPE_INST: sprintf (buf, " $f%d, $f%d, $f%d", FD (inst), FS (inst), FT (inst)); buf += strlen (buf); break; case FP_MOV_TYPE_INST: sprintf (buf, " $f%d, $f%d", FD (inst), FS (inst)); buf += strlen (buf); break; case J_TYPE_INST: sprintf (buf, " 0x%08x", TARGET (inst) << 2); buf += strlen (buf); break; case CP_TYPE_INST: sprintf (buf, " $%d, $%d", RT (inst), RD (inst)); buf += strlen (buf); break; case NOARG_TYPE_INST: break; case ASM_DIR: case PSEUDO_OP: default: fatal_error ("Unknown instruction type in print_inst\n"); } if (EXPR (inst) != NULL && EXPR (inst)->symbol != NULL) { sprintf (buf, " ["); buf += strlen (buf); if (opcode_is_load_store (OPCODE (inst))) buf = print_imm_expr (buf, length - (buf - bp) - 2, EXPR (inst), BASE (inst)); else buf = print_imm_expr (buf, length - (buf - bp) - 2, EXPR (inst), -1); sprintf (buf, "]"); buf += strlen (buf); } if (SOURCE (inst) != NULL && 10 < length - (buf - bp)) { /* Comment is source line text of current line. */ int gap_length = 57 - (buf - bp); int n = strlen (SOURCE (inst)); int remaining; for ( ; 0 < gap_length; gap_length -= 1) { sprintf (buf, " "); buf += 1; } strcpy (buf, "; "); buf += strlen (buf); remaining = length - (buf - bp); if (n < remaining - 2) { strncpy (buf, SOURCE (inst), n + 1); buf += n; } else { strncpy (buf, SOURCE (inst), remaining - 3); strncpy (buf + remaining - 3, "...", 3); buf += remaining; } } sprintf (buf, "\n"); buf += strlen (buf); return (buf - bp);}/* Return non-zero if an INSTRUCTION is a conditional branch. */#ifdef __STDC__intopcode_is_branch (int opcode)#elseintopcode_is_branch (opcode) int opcode;#endif{ switch (opcode) { case Y_BEQ_OP: case Y_BEQZ_POP: case Y_BGE_POP: case Y_BGEU_POP: case Y_BGEZ_OP: case Y_BGEZAL_OP: case Y_BGT_POP: case Y_BGTU_POP: case Y_BGTZ_OP: case Y_BLE_POP: case Y_BLEU_POP: case Y_BLEZ_OP: case Y_BLT_POP: case Y_BLTU_POP: case Y_BLTZ_OP: case Y_BLTZAL_OP: case Y_BNE_OP: case Y_BNEZ_POP: case Y_BC1F_OP: case Y_BC1T_OP: return (1); default: return (0); }}/* Return non-zero if an INSTRUCTION is an conditional branch (jump). */#ifdef __STDC__intopcode_is_jump (int opcode)#elseintopcode_is_jump (opcode) int opcode;#endif{ switch (opcode) { case Y_J_OP: case Y_JAL_OP: return (1); default: return (0); }}/* Return non-zero if an INSTRUCTION is a load or store. */#ifdef __STDC__intopcode_is_load_store (int opcode)#elseintopcode_is_load_store (opcode) int opcode;#endif{ switch (opcode) { case Y_LB_OP: return (1); case Y_LBU_OP: return (1); case Y_LH_OP: return (1); case Y_LHU_OP: return (1); case Y_LW_OP: return (1); case Y_LWC0_OP: return (1); case Y_LWC1_OP: return (1); case Y_LWC2_OP: return (1); case Y_LWC3_OP: return (1); case Y_LWL_OP: return (1); case Y_LWR_OP: return (1); case Y_SB_OP: return (1); case Y_SH_OP: return (1); case Y_SW_OP: return (1); case Y_SWC0_OP: return (1); case Y_SWC1_OP: return (1); case Y_SWC2_OP: return (1); case Y_SWC3_OP: return (1); case Y_SWL_OP: return (1); case Y_SWR_OP: return (1); case Y_L_D_POP: return (1); case Y_L_S_POP: return (1); case Y_S_D_POP: return (1); case Y_S_S_POP: return (1); default: return (0); }}/* Return non-zero if a breakpoint is set at ADDR. */#ifdef __STDC__intinst_is_breakpoint (mem_addr addr)#elseintinst_is_breakpoint (addr) mem_addr addr;#endif{ instruction *old_inst; if (break_inst == NULL) break_inst = make_r_type_inst (Y_BREAK_OP, 1, 0, 0); READ_MEM_INST (old_inst, addr); return (old_inst == break_inst);}/* Set a breakpoint at ADDR and return the old instruction. If the breakpoint cannot be set, return NULL. */#ifdef __STDC__instruction *set_breakpoint (mem_addr addr)#elseinstruction *set_breakpoint (addr) mem_addr addr;#endif{ instruction *old_inst; if (break_inst == NULL) break_inst = make_r_type_inst (Y_BREAK_OP, 1, 0, 0); exception_occurred = 0; READ_MEM_INST (old_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 */#ifdef __STDC__imm_expr *make_imm_expr (int offs, char *sym, int pc_rel)#elseimm_expr *make_imm_expr (offs, sym, pc_rel) int offs; char *sym; int pc_rel;#endif{ 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. */#ifdef __STDC__imm_expr *copy_imm_expr (imm_expr *old_expr)#elseimm_expr *copy_imm_expr (old_expr) imm_expr *old_expr;#endif{ 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. */#ifdef __STDC__imm_expr *upper_bits_of_expr (imm_expr *old_expr)#elseimm_expr *upper_bits_of_expr (old_expr) imm_expr *old_expr;#endif{ 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. */#ifdef __STDC__imm_expr *lower_bits_of_expr (imm_expr *old_expr)#elseimm_expr *lower_bits_of_expr (old_expr) imm_expr *old_expr;#endif{ imm_expr *expr = copy_imm_expr (old_expr); expr->bits = -1; return (expr);}/* Return an instruction expression for a constant VALUE. */#ifdef __STDC__imm_expr *const_imm_expr (int32 value)#elseimm_expr *const_imm_expr (value) int32 value;#endif{ return (make_imm_expr (value, NULL, 0));}/* Return a shallow copy of the EXPRESSION with the offset field incremented by the given amount. */#ifdef __STDC__imm_expr *incr_expr_offset (imm_expr *expr, int32 value)#elseimm_expr *incr_expr_offset (expr, value) imm_expr *expr; int32 value;#endif{ imm_expr *new_expr = copy_imm_expr (expr); new_expr->offset += value; return (new_expr);}/* Return the value of the EXPRESSION. */#ifdef __STDC__int32eval_imm_expr (imm_expr *expr)#elseint32eval_imm_expr (expr) imm_expr *expr;#endif{ int32 value; if (expr->symbol == NULL) value = expr->offset;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -