| Index: src/arm/simulator-arm.cc
|
| ===================================================================
|
| --- src/arm/simulator-arm.cc (revision 3799)
|
| +++ src/arm/simulator-arm.cc (working copy)
|
| @@ -1741,7 +1741,7 @@
|
|
|
|
|
| void Simulator::DecodeType3(Instr* instr) {
|
| - ASSERT(instr->Bit(4) == 0);
|
| + ASSERT(instr->Bits(6, 4) == 0x5 || instr->Bit(4) == 0);
|
| int rd = instr->RdField();
|
| int rn = instr->RnField();
|
| int32_t rn_val = get_register(rn);
|
| @@ -1768,10 +1768,26 @@
|
| break;
|
| }
|
| case 3: {
|
| - // Format(instr, "'memop'cond'b 'rd, ['rn, +'shift_rm]'w");
|
| - addr = rn_val + shifter_operand;
|
| - if (instr->HasW()) {
|
| - set_register(rn, addr);
|
| + if (instr->HasW() && (instr->Bits(6, 4) == 0x5)) {
|
| + uint32_t widthminus1 = static_cast<uint32_t>(instr->Bits(20, 16));
|
| + uint32_t lsbit = static_cast<uint32_t>(instr->ShiftAmountField());
|
| + uint32_t msbit = widthminus1 + lsbit;
|
| + if (msbit <= 31) {
|
| + uint32_t rm_val =
|
| + static_cast<uint32_t>(get_register(instr->RmField()));
|
| + uint32_t extr_val = rm_val << (31 - msbit);
|
| + extr_val = extr_val >> (31 - widthminus1);
|
| + set_register(instr->RdField(), extr_val);
|
| + } else {
|
| + UNREACHABLE();
|
| + }
|
| + return;
|
| + } else {
|
| + // Format(instr, "'memop'cond'b 'rd, ['rn, +'shift_rm]'w");
|
| + addr = rn_val + shifter_operand;
|
| + if (instr->HasW()) {
|
| + set_register(rn, addr);
|
| + }
|
| }
|
| break;
|
| }
|
|
|