Skip to content

Commit c315da5

Browse files
ARM: Don't generate memory instructions with writeback where the data and address registers are the same.
BUG=http://dartbug.com/24855 [email protected] Review URL: https://codereview.chromium.org/1434323003 .
1 parent 974b461 commit c315da5

File tree

4 files changed

+17
-1
lines changed

4 files changed

+17
-1
lines changed

runtime/vm/assembler_arm.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ void Assembler::EmitMemOp(Condition cond,
105105
Address ad) {
106106
ASSERT(rd != kNoRegister);
107107
ASSERT(cond != kNoCondition);
108+
ASSERT(!ad.has_writeback() || (ad.rn() != rd)); // Unpredictable.
109+
108110
int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
109111
B26 | (ad.kind() == Address::Immediate ? 0 : B25) |
110112
(load ? L : 0) |

runtime/vm/assembler_arm.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,11 @@ class Address : public ValueObject {
321321

322322
Mode mode() const { return static_cast<Mode>(encoding() & kModeMask); }
323323

324+
bool has_writeback() const {
325+
return (mode() == PreIndex) || (mode() == PostIndex) ||
326+
(mode() == NegPreIndex) || (mode() == NegPostIndex);
327+
}
328+
324329
uint32_t encoding() const { return encoding_; }
325330

326331
// Encoding for addressing mode 3.

runtime/vm/simulator_arm.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1996,6 +1996,7 @@ void Simulator::DecodeType01(Instr* instr) {
19961996
HandleIllegalAccess(addr, instr);
19971997
} else {
19981998
if (write_back) {
1999+
ASSERT(rd != rn); // Unpredictable.
19992000
set_register(rn, rn_val);
20002001
}
20012002
if (!instr->HasSign()) {
@@ -2312,6 +2313,7 @@ void Simulator::DecodeType2(Instr* instr) {
23122313
HandleIllegalAccess(addr, instr);
23132314
} else {
23142315
if (write_back) {
2316+
ASSERT(rd != rn); // Unpredictable.
23152317
set_register(rn, rn_val);
23162318
}
23172319
if (instr->HasB()) {
@@ -2424,6 +2426,7 @@ void Simulator::DecodeType3(Instr* instr) {
24242426
HandleIllegalAccess(addr, instr);
24252427
} else {
24262428
if (write_back) {
2429+
ASSERT(rd != rn); // Unpredictable.
24272430
set_register(rn, rn_val);
24282431
}
24292432
if (instr->HasB()) {

runtime/vm/stub_code_arm.cc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,9 @@ static void GenerateDeoptimizationSequence(Assembler* assembler,
419419
__ eor(IP, IP, Operand(LR));
420420

421421
// Set up the frame manually with return address now stored in IP.
422+
COMPILE_ASSERT(PP < CODE_REG);
423+
COMPILE_ASSERT(CODE_REG < FP);
424+
COMPILE_ASSERT(FP < IP);
422425
__ EnterFrame((1 << PP) | (1 << CODE_REG) | (1 << FP) | (1 << IP), 0);
423426
__ LoadPoolPointer();
424427

@@ -434,9 +437,12 @@ static void GenerateDeoptimizationSequence(Assembler* assembler,
434437
if (i == CODE_REG) {
435438
// Save the original value of CODE_REG pushed before invoking this stub
436439
// instead of the value used to call this stub.
437-
COMPILE_ASSERT(IP > CODE_REG); // Assert IP is pushed first.
438440
__ ldr(IP, Address(FP, kCallerSpSlotFromFp * kWordSize));
439441
__ Push(IP);
442+
} else if (i == SP) {
443+
// Push(SP) has unpredictable behavior.
444+
__ mov(IP, Operand(SP));
445+
__ Push(IP);
440446
} else {
441447
__ Push(static_cast<Register>(i));
442448
}

0 commit comments

Comments
 (0)