OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stdarg.h> | 5 #include <stdarg.h> |
6 #include <stdlib.h> | 6 #include <stdlib.h> |
7 #include <cmath> | 7 #include <cmath> |
8 | 8 |
9 #if V8_TARGET_ARCH_ARM | 9 #if V8_TARGET_ARCH_ARM |
10 | 10 |
(...skipping 1315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1326 uint32_t uleft = static_cast<uint32_t>(left); | 1326 uint32_t uleft = static_cast<uint32_t>(left); |
1327 uint32_t uright = static_cast<uint32_t>(right); | 1327 uint32_t uright = static_cast<uint32_t>(right); |
1328 uint32_t urest = 0xffffffffU - uleft; | 1328 uint32_t urest = 0xffffffffU - uleft; |
1329 | 1329 |
1330 return (uright > urest) || | 1330 return (uright > urest) || |
1331 (carry && (((uright + 1) > urest) || (uright > (urest - 1)))); | 1331 (carry && (((uright + 1) > urest) || (uright > (urest - 1)))); |
1332 } | 1332 } |
1333 | 1333 |
1334 | 1334 |
1335 // Calculate C flag value for subtractions. | 1335 // Calculate C flag value for subtractions. |
1336 bool Simulator::BorrowFrom(int32_t left, int32_t right) { | 1336 bool Simulator::BorrowFrom(int32_t left, int32_t right, int32_t carry) { |
1337 uint32_t uleft = static_cast<uint32_t>(left); | 1337 uint32_t uleft = static_cast<uint32_t>(left); |
1338 uint32_t uright = static_cast<uint32_t>(right); | 1338 uint32_t uright = static_cast<uint32_t>(right); |
1339 | 1339 |
1340 return (uright > uleft); | 1340 return (uright > uleft) || |
1341 (carry && (((uright + 1) > uleft) || (uright > (uleft - 1)))); | |
1341 } | 1342 } |
1342 | 1343 |
1343 | 1344 |
1344 // Calculate V flag value for additions and subtractions. | 1345 // Calculate V flag value for additions and subtractions. |
1345 bool Simulator::OverflowFrom(int32_t alu_out, | 1346 bool Simulator::OverflowFrom(int32_t alu_out, |
1346 int32_t left, int32_t right, bool addition) { | 1347 int32_t left, int32_t right, bool addition) { |
1347 bool overflow; | 1348 bool overflow; |
1348 if (addition) { | 1349 if (addition) { |
1349 // operands have the same sign | 1350 // operands have the same sign |
1350 overflow = ((left >= 0 && right >= 0) || (left < 0 && right < 0)) | 1351 overflow = ((left >= 0 && right >= 0) || (left < 0 && right < 0)) |
(...skipping 1135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2486 set_register(rd, alu_out); | 2487 set_register(rd, alu_out); |
2487 if (instr->HasS()) { | 2488 if (instr->HasS()) { |
2488 SetNZFlags(alu_out); | 2489 SetNZFlags(alu_out); |
2489 SetCFlag(CarryFrom(rn_val, shifter_operand, GetCarry())); | 2490 SetCFlag(CarryFrom(rn_val, shifter_operand, GetCarry())); |
2490 SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, true)); | 2491 SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, true)); |
2491 } | 2492 } |
2492 break; | 2493 break; |
2493 } | 2494 } |
2494 | 2495 |
2495 case SBC: { | 2496 case SBC: { |
2496 Format(instr, "sbc'cond's 'rd, 'rn, 'shift_rm"); | 2497 // Format(instr, "sbc'cond's 'rd, 'rn, 'shift_rm"); |
2497 Format(instr, "sbc'cond's 'rd, 'rn, 'imm"); | 2498 // Format(instr, "sbc'cond's 'rd, 'rn, 'imm"); |
2499 alu_out = (rn_val - shifter_operand) - (GetCarry() ? 0 : 1); | |
titzer
2016/03/14 09:36:06
Why is carry inverted here?
ahaas
2016/03/15 11:01:43
Because the arm instruction manual says so.
| |
2500 set_register(rd, alu_out); | |
2501 if (instr->HasS()) { | |
2502 SetNZFlags(alu_out); | |
2503 SetCFlag(!BorrowFrom(rn_val, shifter_operand, GetCarry())); | |
2504 SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, false)); | |
2505 } | |
2498 break; | 2506 break; |
2499 } | 2507 } |
2500 | 2508 |
2501 case RSC: { | 2509 case RSC: { |
2502 Format(instr, "rsc'cond's 'rd, 'rn, 'shift_rm"); | 2510 Format(instr, "rsc'cond's 'rd, 'rn, 'shift_rm"); |
2503 Format(instr, "rsc'cond's 'rd, 'rn, 'imm"); | 2511 Format(instr, "rsc'cond's 'rd, 'rn, 'imm"); |
2504 break; | 2512 break; |
2505 } | 2513 } |
2506 | 2514 |
2507 case TST: { | 2515 case TST: { |
(...skipping 1759 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4267 set_register(sp, current_sp + sizeof(uintptr_t)); | 4275 set_register(sp, current_sp + sizeof(uintptr_t)); |
4268 return address; | 4276 return address; |
4269 } | 4277 } |
4270 | 4278 |
4271 } // namespace internal | 4279 } // namespace internal |
4272 } // namespace v8 | 4280 } // namespace v8 |
4273 | 4281 |
4274 #endif // USE_SIMULATOR | 4282 #endif // USE_SIMULATOR |
4275 | 4283 |
4276 #endif // V8_TARGET_ARCH_ARM | 4284 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |