diff options
Diffstat (limited to 'deps/v8/src/arm/assembler-arm.cc')
-rw-r--r-- | deps/v8/src/arm/assembler-arm.cc | 114 |
1 files changed, 71 insertions, 43 deletions
diff --git a/deps/v8/src/arm/assembler-arm.cc b/deps/v8/src/arm/assembler-arm.cc index 4cb421c577..ebbd9b1138 100644 --- a/deps/v8/src/arm/assembler-arm.cc +++ b/deps/v8/src/arm/assembler-arm.cc @@ -317,8 +317,7 @@ static const Instr kLdrStrOffsetMask = 0x00000fff; static const int kMinimalBufferSize = 4*KB; static byte* spare_buffer_ = NULL; -Assembler::Assembler(void* buffer, int buffer_size) - : positions_recorder_(this) { +Assembler::Assembler(void* buffer, int buffer_size) { if (buffer == NULL) { // Do our own buffer management. if (buffer_size <= kMinimalBufferSize) { @@ -355,6 +354,10 @@ Assembler::Assembler(void* buffer, int buffer_size) no_const_pool_before_ = 0; last_const_pool_end_ = 0; last_bound_pos_ = 0; + current_statement_position_ = RelocInfo::kNoPosition; + current_position_ = RelocInfo::kNoPosition; + written_statement_position_ = current_statement_position_; + written_position_ = current_position_; } @@ -749,15 +752,15 @@ static bool fits_shifter(uint32_t imm32, // if they can be encoded in the ARM's 12 bits of immediate-offset instruction // space. There is no guarantee that the relocated location can be similarly // encoded. -bool Operand::must_use_constant_pool() const { - if (rmode_ == RelocInfo::EXTERNAL_REFERENCE) { +static bool MustUseConstantPool(RelocInfo::Mode rmode) { + if (rmode == RelocInfo::EXTERNAL_REFERENCE) { #ifdef DEBUG if (!Serializer::enabled()) { Serializer::TooLateToEnableNow(); } #endif // def DEBUG return Serializer::enabled(); - } else if (rmode_ == RelocInfo::NONE) { + } else if (rmode == RelocInfo::NONE) { return false; } return true; @@ -766,7 +769,7 @@ bool Operand::must_use_constant_pool() const { bool Operand::is_single_instruction() const { if (rm_.is_valid()) return true; - if (must_use_constant_pool()) return false; + if (MustUseConstantPool(rmode_)) return false; uint32_t dummy1, dummy2; return fits_shifter(imm32_, &dummy1, &dummy2, NULL); } @@ -782,7 +785,7 @@ void Assembler::addrmod1(Instr instr, // Immediate. uint32_t rotate_imm; uint32_t immed_8; - if (x.must_use_constant_pool() || + if (MustUseConstantPool(x.rmode_) || !fits_shifter(x.imm32_, &rotate_imm, &immed_8, &instr)) { // The immediate operand cannot be encoded as a shifter operand, so load // it first to register ip and change the original instruction to use ip. @@ -791,7 +794,8 @@ void Assembler::addrmod1(Instr instr, CHECK(!rn.is(ip)); // rn should never be ip, or will be trashed Condition cond = static_cast<Condition>(instr & CondMask); if ((instr & ~CondMask) == 13*B21) { // mov, S not set - if (x.must_use_constant_pool() || !CpuFeatures::IsSupported(ARMv7)) { + if (MustUseConstantPool(x.rmode_) || + !CpuFeatures::IsSupported(ARMv7)) { RecordRelocInfo(x.rmode_, x.imm32_); ldr(rd, MemOperand(pc, 0), cond); } else { @@ -802,7 +806,7 @@ void Assembler::addrmod1(Instr instr, } else { // If this is not a mov or mvn instruction we may still be able to avoid // a constant pool entry by using mvn or movw. - if (!x.must_use_constant_pool() && + if (!MustUseConstantPool(x.rmode_) && (instr & kMovMvnMask) != kMovMvnPattern) { mov(ip, x, LeaveCC, cond); } else { @@ -995,7 +999,7 @@ void Assembler::bl(int branch_offset, Condition cond) { void Assembler::blx(int branch_offset) { // v5 and above - positions_recorder()->WriteRecordedPositions(); + WriteRecordedPositions(); ASSERT((branch_offset & 1) == 0); int h = ((branch_offset & 2) >> 1)*B24; int imm24 = branch_offset >> 2; @@ -1005,14 +1009,14 @@ void Assembler::blx(int branch_offset) { // v5 and above void Assembler::blx(Register target, Condition cond) { // v5 and above - positions_recorder()->WriteRecordedPositions(); + WriteRecordedPositions(); ASSERT(!target.is(pc)); emit(cond | B24 | B21 | 15*B16 | 15*B12 | 15*B8 | 3*B4 | target.code()); } void Assembler::bx(Register target, Condition cond) { // v5 and above, plus v4t - positions_recorder()->WriteRecordedPositions(); + WriteRecordedPositions(); ASSERT(!target.is(pc)); // use of pc is actually allowed, but discouraged emit(cond | B24 | B21 | 15*B16 | 15*B12 | 15*B8 | B4 | target.code()); } @@ -1110,7 +1114,7 @@ void Assembler::orr(Register dst, Register src1, const Operand& src2, void Assembler::mov(Register dst, const Operand& src, SBit s, Condition cond) { if (dst.is(pc)) { - positions_recorder()->WriteRecordedPositions(); + WriteRecordedPositions(); } // Don't allow nop instructions in the form mov rn, rn to be generated using // the mov instruction. They must be generated using nop(int) @@ -1335,7 +1339,7 @@ void Assembler::msr(SRegisterFieldMask fields, const Operand& src, // Immediate. uint32_t rotate_imm; uint32_t immed_8; - if (src.must_use_constant_pool() || + if (MustUseConstantPool(src.rmode_) || !fits_shifter(src.imm32_, &rotate_imm, &immed_8, NULL)) { // Immediate operand cannot be encoded, load it first to register ip. RecordRelocInfo(src.rmode_, src.imm32_); @@ -1355,7 +1359,7 @@ void Assembler::msr(SRegisterFieldMask fields, const Operand& src, // Load/Store instructions. void Assembler::ldr(Register dst, const MemOperand& src, Condition cond) { if (dst.is(pc)) { - positions_recorder()->WriteRecordedPositions(); + WriteRecordedPositions(); } addrmod2(cond | B26 | L, dst, src); @@ -2144,7 +2148,6 @@ static Instr EncodeVCVT(const VFPType dst_type, const int dst_code, const VFPType src_type, const int src_code, - Assembler::ConversionMode mode, const Condition cond) { ASSERT(src_type != dst_type); int D, Vd, M, Vm; @@ -2163,7 +2166,7 @@ static Instr EncodeVCVT(const VFPType dst_type, if (IsIntegerVFPType(dst_type)) { opc2 = IsSignedVFPType(dst_type) ? 0x5 : 0x4; sz = IsDoubleVFPType(src_type) ? 0x1 : 0x0; - op = mode; + op = 1; // round towards zero } else { ASSERT(IsIntegerVFPType(src_type)); opc2 = 0x0; @@ -2187,64 +2190,57 @@ static Instr EncodeVCVT(const VFPType dst_type, void Assembler::vcvt_f64_s32(const DwVfpRegister dst, const SwVfpRegister src, - ConversionMode mode, const Condition cond) { ASSERT(CpuFeatures::IsEnabled(VFP3)); - emit(EncodeVCVT(F64, dst.code(), S32, src.code(), mode, cond)); + emit(EncodeVCVT(F64, dst.code(), S32, src.code(), cond)); } void Assembler::vcvt_f32_s32(const SwVfpRegister dst, const SwVfpRegister src, - ConversionMode mode, const Condition cond) { ASSERT(CpuFeatures::IsEnabled(VFP3)); - emit(EncodeVCVT(F32, dst.code(), S32, src.code(), mode, cond)); + emit(EncodeVCVT(F32, dst.code(), S32, src.code(), cond)); } void Assembler::vcvt_f64_u32(const DwVfpRegister dst, const SwVfpRegister src, - ConversionMode mode, const Condition cond) { ASSERT(CpuFeatures::IsEnabled(VFP3)); - emit(EncodeVCVT(F64, dst.code(), U32, src.code(), mode, cond)); + emit(EncodeVCVT(F64, dst.code(), U32, src.code(), cond)); } void Assembler::vcvt_s32_f64(const SwVfpRegister dst, const DwVfpRegister src, - ConversionMode mode, const Condition cond) { ASSERT(CpuFeatures::IsEnabled(VFP3)); - emit(EncodeVCVT(S32, dst.code(), F64, src.code(), mode, cond)); + emit(EncodeVCVT(S32, dst.code(), F64, src.code(), cond)); } void Assembler::vcvt_u32_f64(const SwVfpRegister dst, const DwVfpRegister src, - ConversionMode mode, const Condition cond) { ASSERT(CpuFeatures::IsEnabled(VFP3)); - emit(EncodeVCVT(U32, dst.code(), F64, src.code(), mode, cond)); + emit(EncodeVCVT(U32, dst.code(), F64, src.code(), cond)); } void Assembler::vcvt_f64_f32(const DwVfpRegister dst, const SwVfpRegister src, - ConversionMode mode, const Condition cond) { ASSERT(CpuFeatures::IsEnabled(VFP3)); - emit(EncodeVCVT(F64, dst.code(), F32, src.code(), mode, cond)); + emit(EncodeVCVT(F64, dst.code(), F32, src.code(), cond)); } void Assembler::vcvt_f32_f64(const SwVfpRegister dst, const DwVfpRegister src, - ConversionMode mode, const Condition cond) { ASSERT(CpuFeatures::IsEnabled(VFP3)); - emit(EncodeVCVT(F32, dst.code(), F64, src.code(), mode, cond)); + emit(EncodeVCVT(F32, dst.code(), F64, src.code(), cond)); } @@ -2337,16 +2333,6 @@ void Assembler::vcmp(const DwVfpRegister src1, } -void Assembler::vmsr(Register dst, Condition cond) { - // Instruction details available in ARM DDI 0406A, A8-652. - // cond(31-28) | 1110 (27-24) | 1110(23-20)| 0001 (19-16) | - // Rt(15-12) | 1010 (11-8) | 0(7) | 00 (6-5) | 1(4) | 0000(3-0) - ASSERT(CpuFeatures::IsEnabled(VFP3)); - emit(cond | 0xE*B24 | 0xE*B20 | B16 | - dst.code()*B12 | 0xA*B8 | B4); -} - - void Assembler::vmrs(Register dst, Condition cond) { // Instruction details available in ARM DDI 0406A, A8-652. // cond(31-28) | 1110 (27-24) | 1111(23-20)| 0001 (19-16) | @@ -2357,6 +2343,7 @@ void Assembler::vmrs(Register dst, Condition cond) { } + void Assembler::vsqrt(const DwVfpRegister dst, const DwVfpRegister src, const Condition cond) { @@ -2390,14 +2377,14 @@ void Assembler::BlockConstPoolFor(int instructions) { // Debugging. void Assembler::RecordJSReturn() { - positions_recorder()->WriteRecordedPositions(); + WriteRecordedPositions(); CheckBuffer(); RecordRelocInfo(RelocInfo::JS_RETURN); } void Assembler::RecordDebugBreakSlot() { - positions_recorder()->WriteRecordedPositions(); + WriteRecordedPositions(); CheckBuffer(); RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT); } @@ -2411,6 +2398,47 @@ void Assembler::RecordComment(const char* msg) { } +void Assembler::RecordPosition(int pos) { + if (pos == RelocInfo::kNoPosition) return; + ASSERT(pos >= 0); + current_position_ = pos; +} + + +void Assembler::RecordStatementPosition(int pos) { + if (pos == RelocInfo::kNoPosition) return; + ASSERT(pos >= 0); + current_statement_position_ = pos; +} + + +bool Assembler::WriteRecordedPositions() { + bool written = false; + + // Write the statement position if it is different from what was written last + // time. + if (current_statement_position_ != written_statement_position_) { + CheckBuffer(); + RecordRelocInfo(RelocInfo::STATEMENT_POSITION, current_statement_position_); + written_statement_position_ = current_statement_position_; + written = true; + } + + // Write the position if it is different from what was written last time and + // also different from the written statement position. + if (current_position_ != written_position_ && + current_position_ != written_statement_position_) { + CheckBuffer(); + RecordRelocInfo(RelocInfo::POSITION, current_position_); + written_position_ = current_position_; + written = true; + } + + // Return whether something was written. + return written; +} + + void Assembler::GrowBuffer() { if (!own_buffer_) FATAL("external code buffer is too small"); |