Chromium Code Reviews| Index: runtime/vm/assembler_arm.cc |
| =================================================================== |
| --- runtime/vm/assembler_arm.cc (revision 44777) |
| +++ runtime/vm/assembler_arm.cc (working copy) |
| @@ -435,7 +435,6 @@ |
| void Assembler::smull(Register rd_lo, Register rd_hi, |
| Register rn, Register rm, Condition cond) { |
| - ASSERT(TargetCPUFeatures::arm_version() == ARMv7); |
| // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. |
| EmitMulOp(cond, B23 | B22, rd_lo, rd_hi, rn, rm); |
| } |
| @@ -540,15 +539,27 @@ |
| } |
| -void Assembler::ldrd(Register rd, Address ad, Condition cond) { |
| +void Assembler::ldrd(Register rd, Register rn, int32_t offset, Condition cond) { |
| ASSERT((rd % 2) == 0); |
| - EmitMemOpAddressMode3(cond, B7 | B6 | B4, rd, ad); |
| + if (TargetCPUFeatures::arm_version() == ARMv5TE) { |
| + const Register rd2 = static_cast<Register>(static_cast<int32_t>(rd) + 1); |
| + ldr(rd, Address(rn, offset), cond); |
| + ldr(rd2, Address(rn, offset + kWordSize), cond); |
| + } else { |
| + EmitMemOpAddressMode3(cond, B7 | B6 | B4, rd, Address(rn, offset)); |
| + } |
| } |
| -void Assembler::strd(Register rd, Address ad, Condition cond) { |
| +void Assembler::strd(Register rd, Register rn, int32_t offset, Condition cond) { |
| ASSERT((rd % 2) == 0); |
| - EmitMemOpAddressMode3(cond, B7 | B6 | B5 | B4, rd, ad); |
| + if (TargetCPUFeatures::arm_version() == ARMv5TE) { |
| + const Register rd2 = static_cast<Register>(static_cast<int32_t>(rd) + 1); |
| + str(rd, Address(rn, offset), cond); |
| + str(rd2, Address(rn, offset + kWordSize), cond); |
| + } else { |
| + EmitMemOpAddressMode3(cond, B7 | B6 | B5 | B4, rd, Address(rn, offset)); |
| + } |
| } |
| @@ -556,11 +567,6 @@ |
| Condition cond) { |
| ASSERT(regs != 0); |
| EmitMultiMemOp(cond, am, true, base, regs); |
| - if (TargetCPUFeatures::arm_version() == ARMv5TE) { |
| - // On ARMv5, touching a "banked" register after an ldm gives undefined |
| - // behavior, so we just add a nop here to make that case easy to avoid. |
| - nop(); |
| - } |
| } |
| @@ -568,11 +574,6 @@ |
| Condition cond) { |
| ASSERT(regs != 0); |
| EmitMultiMemOp(cond, am, false, base, regs); |
| - if (TargetCPUFeatures::arm_version() == ARMv5TE) { |
| - // On ARMv5, touching a "banked" register after an stm gives undefined |
| - // behavior, so we just add a nop here to make that case easy to avoid. |
| - nop(); |
| - } |
| } |
| @@ -1676,10 +1677,10 @@ |
| ASSERT(base != value_odd); |
| Operand shadow(GetVerifiedMemoryShadow()); |
| add(base, base, shadow, cond); |
| - strd(value_even, Address(base, offset), cond); |
| + strd(value_even, base, offset, cond); |
| sub(base, base, shadow, cond); |
| } |
| - strd(value_even, Address(base, offset), cond); |
| + strd(value_even, base, offset, cond); |
| } |
| @@ -2794,7 +2795,7 @@ |
| ldr(reg, Address(base, offset), cond); |
| break; |
| case kWordPair: |
| - ldrd(reg, Address(base, offset), cond); |
| + ldrd(reg, base, offset, cond); |
| break; |
| default: |
| UNREACHABLE(); |
| @@ -2826,7 +2827,7 @@ |
| str(reg, Address(base, offset), cond); |
| break; |
| case kWordPair: |
| - strd(reg, Address(base, offset), cond); |
| + strd(reg, base, offset, cond); |
| break; |
| default: |
| UNREACHABLE(); |
| @@ -3132,60 +3133,6 @@ |
| } |
| -// If we aren't on ARMv7, there is no smull, and we have to check for overflow |
| -// manually. |
| -void Assembler::CheckMultSignedOverflow(Register left, |
| - Register right, |
| - Register tmp, |
| - DRegister dtmp0, DRegister dtmp1, |
| - Label* overflow) { |
| - Label done, left_neg, left_pos_right_neg, left_neg_right_pos; |
| - |
| - CompareImmediate(left, 0); |
| - b(&left_neg, LT); |
| - b(&done, EQ); |
| - CompareImmediate(right, 0); |
| - b(&left_pos_right_neg, LT); |
| - b(&done, EQ); |
| - |
| - // Both positive. |
| - LoadImmediate(tmp, INT_MAX); |
| - IntegerDivide(tmp, tmp, left, dtmp0, dtmp1); |
| - cmp(tmp, Operand(right)); |
| - b(overflow, LT); |
| - b(&done); |
| - |
| - // left positive, right non-positive. |
| - Bind(&left_pos_right_neg); |
| - LoadImmediate(tmp, INT_MIN); |
| - IntegerDivide(tmp, tmp, left, dtmp0, dtmp1); |
| - cmp(tmp, Operand(right)); |
| - b(overflow, GT); |
| - b(&done); |
| - |
| - Bind(&left_neg); |
| - CompareImmediate(right, 0); |
| - b(&left_neg_right_pos, GT); |
| - b(&done, EQ); |
| - |
| - // both negative. |
| - LoadImmediate(tmp, INT_MAX); |
| - IntegerDivide(tmp, tmp, left, dtmp0, dtmp1); |
| - cmp(tmp, Operand(right)); |
| - b(overflow, GT); |
| - b(&done); |
| - |
| - // left non-positive, right positive. |
| - Bind(&left_neg_right_pos); |
| - LoadImmediate(tmp, INT_MIN); |
| - IntegerDivide(tmp, tmp, right, dtmp0, dtmp1); |
| - cmp(tmp, Operand(left)); |
| - b(overflow, GT); |
| - |
| - Bind(&done); |
| -} |
| - |
| - |
| static int NumRegsBelowFP(RegList regs) { |
| int count = 0; |
| for (int i = 0; i < FP; i++) { |
| @@ -3323,7 +3270,11 @@ |
| // optimized function and there may be extra space for spill slots to |
| // allocate. We must also set up the pool pointer for the function. |
| void Assembler::EnterOsrFrame(intptr_t extra_size) { |
| - const intptr_t offset = CodeSize(); |
| + // The offset for the PC marker is adjusted by the difference in PC offset |
| + // between stores and other instructions. In particular, on some ARMv5's the |
| + // PC offset for stores is 12 and the offset in other instructions is 8. |
| + const intptr_t offset = CodeSize() - |
| + (TargetCPUFeatures::store_pc_read_offset() - Instr::kPCReadOffset); |
|
Vyacheslav Egorov (Google)
2015/03/31 08:05:30
I find this comment and expression really confusin
|
| Comment("EnterOsrFrame"); |
| mov(IP, Operand(PC)); |