| 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);
|
|
|
| Comment("EnterOsrFrame");
|
| mov(IP, Operand(PC));
|
|
|