예제 #1
0
DexOpcode select_move_opcode(const IRInstruction* insn) {
  auto move_tuple = move_opcode_tuple(insn->opcode());
  auto dest_width = required_bit_width(insn->dest());
  auto src_width = required_bit_width(insn->src(0));
  if (dest_width <= 4 && src_width <= 4) {
    return move_tuple.at(0);
  } else if (dest_width <= 8) {
    return move_tuple.at(1);
  } else {
    return move_tuple.at(2);
  }
}
예제 #2
0
DexOpcode select_const_opcode(const IRInstruction* insn) {
  auto op = insn->opcode();
  auto dest_width = required_bit_width(insn->dest());
  always_assert(dest_width <= 8);
  auto literal = insn->get_literal();
  switch (op) {
  case OPCODE_CONST:
    if (dest_width <= 4 && signed_int_fits<4>(literal)) {
      return DOPCODE_CONST_4;
    } else if (signed_int_fits<16>(literal)) {
      return DOPCODE_CONST_16;
    } else if (signed_int_fits_high16<32>(literal)) {
      return DOPCODE_CONST_HIGH16;
    } else {
      always_assert(signed_int_fits<32>(literal));
      return DOPCODE_CONST;
    }
  case OPCODE_CONST_WIDE:
    if (signed_int_fits<16>(literal)) {
      return DOPCODE_CONST_WIDE_16;
    } else if (signed_int_fits<32>(literal)) {
      return DOPCODE_CONST_WIDE_32;
    } else if (signed_int_fits_high16<64>(literal)) {
      return DOPCODE_CONST_WIDE_HIGH16;
    } else {
      return DOPCODE_CONST_WIDE;
    }
  default:
    not_reached();
  }
}
예제 #3
0
bool needs_range_conversion(const IRInstruction* insn) {
  auto op = insn->opcode();
  if (!opcode::has_range_form(op)) {
    return false;
  }
  if (insn->srcs_size() > dex_opcode::NON_RANGE_MAX) {
    return true;
  }
  always_assert(!opcode::is_internal(op));
  auto dex_op = opcode::to_dex_opcode(op);
  for (size_t i = 0; i < insn->srcs_size(); ++i) {
    if (required_bit_width(insn->src(i)) >
        dex_opcode::src_bit_width(dex_op, i)) {
      return true;
    }
  }
  return false;
}