// Return the destination register of one instruction xed_reg_enum_t DestRegister(xed_decoded_inst_t &xedd) { const xed_inst_t* inst = xed_decoded_inst_inst(&xedd); unsigned int operandNum = xed_inst_noperands(inst); // get the number of the operands // if the instruction has no operands, return invalid if(operandNum == 0) return XED_REG_INVALID; const xed_operand_t* operand = xed_inst_operand(inst, 0); //the first operand is the destination. xed_operand_enum_t oper_type = xed_operand_name(operand); xed_uint_t mark = xed_operand_is_register(oper_type); // check whether the operand is a register operand if(mark == 1) { xed_reg_enum_t reg = xed_decoded_inst_get_reg(&xedd, oper_type); ASSERT(reg != XED_REG_INVALID); return reg; } return XED_REG_INVALID; }
static void add_write_operands(xed_dot_graph_supp_t* gg, xed_decoded_inst_t* xedd, xed_dot_node_t* n) { xed_uint_t i, noperands; xed_reg_enum_t r, r_enclosing; const xed_inst_t* xi = 0; xi = xed_decoded_inst_inst(xedd); noperands = xed_inst_noperands(xi); for( i=0; i < noperands ; i++) { const xed_operand_t* op = xed_inst_operand(xi,i); xed_operand_enum_t opname = xed_operand_name(op); if (xed_operand_is_register(opname) || xed_operand_is_memory_addressing_register(opname)) { if (xed_operand_written(op)) { /* set n as the source of the value. */ /* ignoring partial writes */ r = xed_decoded_inst_get_reg(xedd, opname); r_enclosing = xed_get_largest_enclosing_register(r); gg->xed_reg_to_node[r_enclosing] = n; } } } /* for */ }
static void add_read_operands(xed_dot_graph_supp_t* gg, xed_decoded_inst_t* xedd, xed_dot_node_t* n) { xed_uint_t i, noperands; xed_reg_enum_t r; const xed_inst_t* xi = 0; xed_bool_t found = 0; xi = xed_decoded_inst_inst(xedd); noperands = xed_inst_noperands(xi); for( i=0; i < noperands ; i++) { int memop = -1; const xed_operand_t* op = xed_inst_operand(xi,i); xed_operand_enum_t opname = xed_operand_name(op); if (xed_operand_is_register(opname) || xed_operand_is_memory_addressing_register(opname)) { if (xed_operand_read(op)) { /* add edge to n */ r = xed_decoded_inst_get_reg(xedd, opname); found |= add_edge(gg, n, r); } continue; } if (opname == XED_OPERAND_MEM0) memop = 0; else if (opname == XED_OPERAND_MEM1 ) memop = 1; if (memop != -1) { /* get reads of base/index regs, if any */ xed_reg_enum_t base, indx; base = xed_decoded_inst_get_base_reg(xedd,memop); indx = xed_decoded_inst_get_index_reg(xedd,memop); if (base != XED_REG_INVALID) found |= add_edge(gg, n, base); indx = xed_decoded_inst_get_index_reg(xedd,memop); if (indx != XED_REG_INVALID) found |= add_edge(gg, n, indx); } } /* for */ if (!found) { /* add an edge from start */ xed_dot_edge(gg->g, gg->start, n); } }
void print_operands(xed_decoded_inst_t* xedd) { unsigned int i = 0; xed_inst_t const* const xi = xed_decoded_inst_inst(xedd); const unsigned int noperands = xed_inst_noperands(xi); for( i=0; i < noperands ; i++) { xed_operand_t const* op = xed_inst_operand(xi,i); xed_operand_enum_t op_name = xed_operand_name(op); if (xed_operand_is_register(op_name)) { xed_reg_enum_t reg = xed_decoded_inst_get_reg(xedd,op_name); xed_operand_action_enum_t rw = xed_operand_rw(op); printf("%2d: %5s %5s\n", i, xed_reg_enum_t2str(reg), xed_operand_action_enum_t2str(rw)); } } }