bool SgAsmMipsInstruction::get_branch_target(rose_addr_t *target) { SgAsmExpressionPtrList &args = get_operandList()->get_operands(); switch (get_kind()) { case mips_j: case mips_jal: case mips_jalx: { // target address stored in first argument assert(args.size()>=1); if (target) { SgAsmIntegerValueExpression *ival = isSgAsmIntegerValueExpression(args[0]); assert(ival!=NULL); *target = ival->get_absolute_value(); } return true; } case mips_bgez: case mips_bgezal: case mips_bgezall: case mips_bgezl: case mips_bgtz: case mips_bgtzl: case mips_blez: case mips_blezl: case mips_bltz: case mips_bltzal: case mips_bltzall: case mips_bltzl: { // target address stored in the second argument assert(args.size()>=2); if (target) { SgAsmIntegerValueExpression *ival = isSgAsmIntegerValueExpression(args[1]); assert(ival!=NULL); *target = ival->get_absolute_value(); } return true; } case mips_beq: case mips_beql: case mips_bne: case mips_bnel: { // target address stored in the third argument assert(args.size()>=3); if (target) { SgAsmIntegerValueExpression *ival = isSgAsmIntegerValueExpression(args[2]); assert(ival!=NULL); *target = ival->get_absolute_value(); } return true; } default: // no known target; do not modify *target return false; } }
/* Helper for unparsePowerpcExpression(SgAsmExpression*) */ static std::string unparsePowerpcExpression(SgAsmExpression* expr, const AsmUnparser::LabelMap *labels, const RegisterDictionary *registers, bool useHex) { std::string result = ""; if (expr == NULL) return "BOGUS:NULL"; switch (expr->variantT()) { case V_SgAsmBinaryAdd: result = unparsePowerpcExpression(isSgAsmBinaryExpression(expr)->get_lhs(), labels, registers, false) + " + " + unparsePowerpcExpression(isSgAsmBinaryExpression(expr)->get_rhs(), labels, registers, false); break; case V_SgAsmMemoryReferenceExpression: { SgAsmMemoryReferenceExpression* mr = isSgAsmMemoryReferenceExpression(expr); SgAsmExpression* addr = mr->get_address(); switch (addr->variantT()) { case V_SgAsmBinaryAdd: { SgAsmBinaryAdd* a = isSgAsmBinaryAdd(addr); std::string lhs = unparsePowerpcExpression(a->get_lhs(), labels, registers, false); if (isSgAsmValueExpression(a->get_rhs())) { // Sign-extend from 16 bits SgAsmValueExpression *ve = isSgAsmValueExpression(a->get_rhs()); assert(ve!=NULL); result = boost::lexical_cast<std::string>( (int64_t)IntegerOps::signExtend<16, 64>(SageInterface::getAsmConstant(ve))); result += "(" + lhs + ")"; } else { result = lhs + ", " + unparsePowerpcExpression(a->get_rhs(), labels, registers, false); } break; } default: result = "(" + unparsePowerpcExpression(addr, labels, registers, false) + ")"; break; } break; } case V_SgAsmPowerpcRegisterReferenceExpression: { SgAsmPowerpcRegisterReferenceExpression* rr = isSgAsmPowerpcRegisterReferenceExpression(expr); result = unparsePowerpcRegister(rr->get_descriptor(), registers); break; } case V_SgAsmIntegerValueExpression: { uint64_t v = isSgAsmIntegerValueExpression(expr)->get_absolute_value(); if (useHex) { result = StringUtility::intToHex(v); } else { result = StringUtility::numberToString(v); } if (labels) { AsmUnparser::LabelMap::const_iterator li = labels->find(v); if (li!=labels->end()) result = StringUtility::appendAsmComment(result, li->second); } break; } default: { std::cerr << "Unhandled expression kind " << expr->class_name() << std::endl; ROSE_ASSERT (false); } } result = StringUtility::appendAsmComment(result, expr->get_replacement()); return result; }