summaryrefslogtreecommitdiff
path: root/deps/v8/src/arm/assembler-arm.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/arm/assembler-arm.cc')
-rw-r--r--deps/v8/src/arm/assembler-arm.cc114
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");