Index: src/arm/simulator-arm.cc |
diff --git a/src/arm/simulator-arm.cc b/src/arm/simulator-arm.cc |
index ccf31953cc3a54b99550ab2577ee74c8f2d50b6f..6c22a0a86acdf51736324dae3e2f943b35e39d35 100644 |
--- a/src/arm/simulator-arm.cc |
+++ b/src/arm/simulator-arm.cc |
@@ -1333,11 +1333,12 @@ bool Simulator::CarryFrom(int32_t left, int32_t right, int32_t carry) { |
// Calculate C flag value for subtractions. |
-bool Simulator::BorrowFrom(int32_t left, int32_t right) { |
+bool Simulator::BorrowFrom(int32_t left, int32_t right, int32_t carry) { |
uint32_t uleft = static_cast<uint32_t>(left); |
uint32_t uright = static_cast<uint32_t>(right); |
- return (uright > uleft); |
+ return (uright > uleft) || |
+ (!carry && (((uright + 1) > uleft) || (uright > (uleft - 1)))); |
} |
@@ -2493,8 +2494,15 @@ void Simulator::DecodeType01(Instruction* instr) { |
} |
case SBC: { |
- Format(instr, "sbc'cond's 'rd, 'rn, 'shift_rm"); |
- Format(instr, "sbc'cond's 'rd, 'rn, 'imm"); |
+ // Format(instr, "sbc'cond's 'rd, 'rn, 'shift_rm"); |
+ // Format(instr, "sbc'cond's 'rd, 'rn, 'imm"); |
+ alu_out = (rn_val - shifter_operand) - (GetCarry() ? 0 : 1); |
+ set_register(rd, alu_out); |
+ if (instr->HasS()) { |
+ SetNZFlags(alu_out); |
+ SetCFlag(!BorrowFrom(rn_val, shifter_operand, GetCarry())); |
+ SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, false)); |
+ } |
break; |
} |