void DisassemblerContext::print_instruction_term(const ValuePtr<Instruction>& term) { *m_output << term->operation_name(); class MyVisitor : public InstructionVisitor { DisassemblerContext *m_self; public: MyVisitor(DisassemblerContext *self) : m_self(self) {} virtual void next(ValuePtr<>& ptr) { *m_self->m_output << ' '; m_self->print_term(ptr, true); } }; MyVisitor my_visitor(this); term->instruction_visit(my_visitor); *m_output << ";\n"; }
void DisassemblerContext::print_functional_term(const ValuePtr<FunctionalValue>& term, bool bracket) { if (ValuePtr<BooleanValue> bool_value = dyn_cast<BooleanValue>(term)) { *m_output << (bool_value->value() ? "true" : "false"); } else if (ValuePtr<IntegerType> int_type = dyn_cast<IntegerType>(term)) { if (!int_type->is_signed()) *m_output << 'u'; *m_output << 'i'; const char *width; switch (int_type->width()) { case IntegerType::i8: width = "8"; break; case IntegerType::i16: width = "16"; break; case IntegerType::i32: width = "32"; break; case IntegerType::i64: width = "64"; break; case IntegerType::i128: width = "128"; break; case IntegerType::iptr: width = "ptr"; break; default: PSI_FAIL("unknown integer width"); } *m_output << width; } else if (ValuePtr<IntegerValue> int_value = dyn_cast<IntegerValue>(term)) { ValuePtr<IntegerType> type = int_value->type(); *m_output << '#'; if (!type->is_signed()) *m_output << 'u'; char width; switch (type->width()) { case IntegerType::i8: width = 'b'; break; case IntegerType::i16: width = 's'; break; case IntegerType::i32: width = 'i'; break; case IntegerType::i64: width = 'l'; break; case IntegerType::i128: width = 'q'; break; case IntegerType::iptr: width = 'p'; break; default: PSI_FAIL("unknown integer width"); } *m_output << width; int_value->value().print(error_context().bind(term->location()), *m_output, type->is_signed()); } else if (ValuePtr<FloatType> float_type = dyn_cast<FloatType>(term)) { const char *width; switch (float_type->width()) { case FloatType::fp32: width = "fp32"; break; case FloatType::fp64: width = "fp64"; break; case FloatType::fp128: width = "fp128"; break; case FloatType::fp_x86_80: width = "fp-x86-80"; break; case FloatType::fp_ppc_128: width = "fp-ppc-128"; break; default: PSI_FAIL("unknown integer width"); } *m_output << width; } else if (ValuePtr<ResolvedParameter> resolved_param = dyn_cast<ResolvedParameter>(term)) { ParameterNameList::reverse_iterator it = m_parameter_names.rbegin(); if (resolved_param->depth() < m_parameter_names.size()) { std::advance(it, resolved_param->depth()); PSI_ASSERT(resolved_param->index() < it->size()); *m_output << (*it)[resolved_param->index()]; } else { *m_output << "[unknown parameter : "; print_term(resolved_param->type(), false); *m_output << "]"; } } else if (ValuePtr<UnwrapParameter> unwrap_param = dyn_cast<UnwrapParameter>(term)) { *m_output << "unwrap_param "; print_term(unwrap_param->value(), true); *m_output << " " << unwrap_param->index(); } else { class MyVisitor : public FunctionalValueVisitor { DisassemblerContext *m_self; const char *m_operation; bool m_bracket; bool m_first; public: MyVisitor(DisassemblerContext *self, const char *operation, bool bracket) : m_self(self), m_operation(operation), m_bracket(bracket), m_first(true) {} virtual void next(const ValuePtr<>& ptr) { if (m_first) { if (m_bracket) *m_self->m_output << '('; *m_self->m_output << m_operation; m_first = false; } *m_self->m_output << ' '; m_self->print_term(ptr, true); } bool empty() const {return m_first;} }; MyVisitor my_visitor(this, term->operation_name(), bracket); term->functional_visit(my_visitor); if (my_visitor.empty()) { *m_output << term->operation_name(); } else if (bracket) { *m_output << ')'; } } }