// significantly by Google Inc.
// Copyright 2012 the V8 project authors. All rights reserved.
-#include "v8.h"
+#include "src/v8.h"
#if V8_TARGET_ARCH_IA32
-#include "disassembler.h"
-#include "macro-assembler.h"
-#include "serialize.h"
+#include "src/base/bits.h"
+#include "src/base/cpu.h"
+#include "src/disassembler.h"
+#include "src/macro-assembler.h"
+#include "src/serialize.h"
namespace v8 {
namespace internal {
// -----------------------------------------------------------------------------
// Implementation of CpuFeatures
-#ifdef DEBUG
-bool CpuFeatures::initialized_ = false;
-#endif
-uint64_t CpuFeatures::supported_ = 0;
-uint64_t CpuFeatures::found_by_runtime_probing_only_ = 0;
-uint64_t CpuFeatures::cross_compile_ = 0;
-
-
-ExternalReference ExternalReference::cpu_features() {
- ASSERT(CpuFeatures::initialized_);
- return ExternalReference(&CpuFeatures::supported_);
-}
-
-
-int IntelDoubleRegister::NumAllocatableRegisters() {
- if (CpuFeatures::IsSupported(SSE2)) {
- return XMMRegister::kNumAllocatableRegisters;
- } else {
- return X87Register::kNumAllocatableRegisters;
- }
-}
+void CpuFeatures::ProbeImpl(bool cross_compile) {
+ base::CPU cpu;
+ CHECK(cpu.has_sse2()); // SSE2 support is mandatory.
+ CHECK(cpu.has_cmov()); // CMOV support is mandatory.
+ // Only use statically determined features for cross compile (snapshot).
+ if (cross_compile) return;
-int IntelDoubleRegister::NumRegisters() {
- if (CpuFeatures::IsSupported(SSE2)) {
- return XMMRegister::kNumRegisters;
- } else {
- return X87Register::kNumRegisters;
- }
+ if (cpu.has_sse41() && FLAG_enable_sse4_1) supported_ |= 1u << SSE4_1;
+ if (cpu.has_sse3() && FLAG_enable_sse3) supported_ |= 1u << SSE3;
}
-const char* IntelDoubleRegister::AllocationIndexToString(int index) {
- if (CpuFeatures::IsSupported(SSE2)) {
- return XMMRegister::AllocationIndexToString(index);
- } else {
- return X87Register::AllocationIndexToString(index);
- }
-}
-
-
-void CpuFeatures::Probe() {
- ASSERT(!initialized_);
- ASSERT(supported_ == 0);
-#ifdef DEBUG
- initialized_ = true;
-#endif
- if (Serializer::enabled()) {
- supported_ |= OS::CpuFeaturesImpliedByPlatform();
- return; // No features if we might serialize.
- }
-
- uint64_t probed_features = 0;
- CPU cpu;
- if (cpu.has_sse41()) {
- probed_features |= static_cast<uint64_t>(1) << SSE4_1;
- }
- if (cpu.has_sse3()) {
- probed_features |= static_cast<uint64_t>(1) << SSE3;
- }
- if (cpu.has_sse2()) {
- probed_features |= static_cast<uint64_t>(1) << SSE2;
- }
- if (cpu.has_cmov()) {
- probed_features |= static_cast<uint64_t>(1) << CMOV;
- }
-
- // SAHF must be available in compat/legacy mode.
- ASSERT(cpu.has_sahf());
- probed_features |= static_cast<uint64_t>(1) << SAHF;
-
- uint64_t platform_features = OS::CpuFeaturesImpliedByPlatform();
- supported_ = probed_features | platform_features;
- found_by_runtime_probing_only_ = probed_features & ~platform_features;
-}
+void CpuFeatures::PrintTarget() { }
+void CpuFeatures::PrintFeatures() { }
// -----------------------------------------------------------------------------
// Implementation of Displacement
void Displacement::init(Label* L, Type type) {
- ASSERT(!L->is_bound());
+ DCHECK(!L->is_bound());
int next = 0;
if (L->is_linked()) {
next = L->pos();
- ASSERT(next > 0); // Displacements must be at positions > 0
+ DCHECK(next > 0); // Displacements must be at positions > 0
}
// Ensure that we _never_ overflow the next field.
- ASSERT(NextField::is_valid(Assembler::kMaximalBufferSize));
+ DCHECK(NextField::is_valid(Assembler::kMaximalBufferSize));
data_ = NextField::encode(next) | TypeField::encode(type);
}
}
// Indicate that code has changed.
- CPU::FlushICache(pc_, instruction_count);
+ CpuFeatures::FlushICache(pc_, instruction_count);
}
patcher.masm()->call(target, RelocInfo::NONE32);
// Check that the size of the code generated is as expected.
- ASSERT_EQ(kCallCodeSize,
+ DCHECK_EQ(kCallCodeSize,
patcher.masm()->SizeOfCodeGeneratedSince(&check_codesize));
// Add the requested number of int3 instructions after the call.
- ASSERT_GE(guard_bytes, 0);
+ DCHECK_GE(guard_bytes, 0);
for (int i = 0; i < guard_bytes; i++) {
patcher.masm()->int3();
}
ScaleFactor scale,
int32_t disp,
RelocInfo::Mode rmode) {
- ASSERT(!index.is(esp)); // illegal addressing mode
+ DCHECK(!index.is(esp)); // illegal addressing mode
// [base + index*scale + disp/r]
if (disp == 0 && RelocInfo::IsNone(rmode) && !base.is(ebp)) {
// [base + index*scale]
ScaleFactor scale,
int32_t disp,
RelocInfo::Mode rmode) {
- ASSERT(!index.is(esp)); // illegal addressing mode
+ DCHECK(!index.is(esp)); // illegal addressing mode
// [index*scale + disp/r]
set_modrm(0, esp);
set_sib(scale, index, ebp);
}
-Operand::Operand(const Operand& operand, int32_t offset) {
- ASSERT(operand.len_ >= 1);
- // Operand encodes REX ModR/M [SIB] [Disp].
- byte modrm = operand.buf_[0];
- ASSERT(modrm < 0xC0); // Disallow mode 3 (register target).
- bool has_sib = ((modrm & 0x07) == 0x04);
- byte mode = modrm & 0xC0;
- int disp_offset = has_sib ? 2 : 1;
- int base_reg = (has_sib ? operand.buf_[1] : modrm) & 0x07;
- // Mode 0 with rbp/r13 as ModR/M or SIB base register always has a 32-bit
- // displacement.
- bool is_baseless = (mode == 0) && (base_reg == 0x05); // No base or RIP base.
- int32_t disp_value = 0;
- if (mode == 0x80 || is_baseless) {
- // Mode 2 or mode 0 with rbp/r13 as base: Word displacement.
- disp_value = *BitCast<const int32_t*>(&operand.buf_[disp_offset]);
- } else if (mode == 0x40) {
- // Mode 1: Byte displacement.
- disp_value = static_cast<signed char>(operand.buf_[disp_offset]);
- }
-
- // Write new operand with same registers, but with modified displacement.
- ASSERT(offset >= 0 ? disp_value + offset >= disp_value
- : disp_value + offset < disp_value); // No overflow.
- disp_value += offset;
- if (!is_int8(disp_value) || is_baseless) {
- // Need 32 bits of displacement, mode 2 or mode 1 with register rbp/r13.
- buf_[0] = (modrm & 0x3f) | (is_baseless ? 0x00 : 0x80);
- len_ = disp_offset + 4;
- Memory::int32_at(&buf_[disp_offset]) = disp_value;
- } else if (disp_value != 0 || (base_reg == 0x05)) {
- // Need 8 bits of displacement.
- buf_[0] = (modrm & 0x3f) | 0x40; // Mode 1.
- len_ = disp_offset + 1;
- buf_[disp_offset] = static_cast<byte>(disp_value);
- } else {
- // Need no displacement.
- buf_[0] = (modrm & 0x3f); // Mode 0.
- len_ = disp_offset;
- }
- if (has_sib) {
- buf_[1] = operand.buf_[1];
- }
-}
-
-
bool Operand::is_reg(Register reg) const {
return ((buf_[0] & 0xF8) == 0xC0) // addressing mode is register only.
&& ((buf_[0] & 0x07) == reg.code()); // register codes match.
Register Operand::reg() const {
- ASSERT(is_reg_only());
+ DCHECK(is_reg_only());
return Register::from_code(buf_[0] & 0x07);
}
void Assembler::GetCode(CodeDesc* desc) {
// Finalize code (at this point overflow() may be true, but the gap ensures
// that we are still not overlapping instructions and relocation info).
- ASSERT(pc_ <= reloc_info_writer.pos()); // No overlap.
+ DCHECK(pc_ <= reloc_info_writer.pos()); // No overlap.
// Set up code descriptor.
desc->buffer = buffer_;
desc->buffer_size = buffer_size_;
void Assembler::Align(int m) {
- ASSERT(IsPowerOf2(m));
+ DCHECK(base::bits::IsPowerOfTwo32(m));
int mask = m - 1;
int addr = pc_offset();
Nop((m - (addr & mask)) & mask);
void Assembler::Nop(int bytes) {
EnsureSpace ensure_space(this);
- if (!CpuFeatures::IsSupported(SSE2)) {
- // Older CPUs that do not support SSE2 may not support multibyte NOP
- // instructions.
- for (; bytes > 0; bytes--) {
- EMIT(0x90);
- }
- return;
- }
-
// Multi byte nops from http://support.amd.com/us/Processor_TechDocs/40546.pdf
while (bytes > 0) {
switch (bytes) {
void Assembler::pop(Register dst) {
- ASSERT(reloc_info_writer.last_pc() != NULL);
+ DCHECK(reloc_info_writer.last_pc() != NULL);
EnsureSpace ensure_space(this);
EMIT(0x58 | dst.code());
}
void Assembler::cmov(Condition cc, Register dst, const Operand& src) {
- ASSERT(IsEnabled(CMOV));
EnsureSpace ensure_space(this);
// Opcode: 0f 40 + cc /r.
EMIT(0x0F);
}
+void Assembler::xchg(Register dst, const Operand& src) {
+ EnsureSpace ensure_space(this);
+ EMIT(0x87);
+ emit_operand(dst, src);
+}
+
+
void Assembler::adc(Register dst, int32_t imm32) {
EnsureSpace ensure_space(this);
emit_arith(2, Operand(dst), Immediate(imm32));
void Assembler::add(const Operand& dst, const Immediate& x) {
- ASSERT(reloc_info_writer.last_pc() != NULL);
+ DCHECK(reloc_info_writer.last_pc() != NULL);
EnsureSpace ensure_space(this);
emit_arith(0, dst, x);
}
void Assembler::cmpw(const Operand& op, Immediate imm16) {
- ASSERT(imm16.is_int16());
+ DCHECK(imm16.is_int16());
EnsureSpace ensure_space(this);
EMIT(0x66);
EMIT(0x81);
}
-void Assembler::idiv(Register src) {
+void Assembler::idiv(const Operand& src) {
+ EnsureSpace ensure_space(this);
+ EMIT(0xF7);
+ emit_operand(edi, src);
+}
+
+
+void Assembler::div(const Operand& src) {
EnsureSpace ensure_space(this);
EMIT(0xF7);
- EMIT(0xF8 | src.code());
+ emit_operand(esi, src);
}
void Assembler::imul(Register dst, Register src, int32_t imm32) {
+ imul(dst, Operand(src), imm32);
+}
+
+
+void Assembler::imul(Register dst, const Operand& src, int32_t imm32) {
EnsureSpace ensure_space(this);
if (is_int8(imm32)) {
EMIT(0x6B);
- EMIT(0xC0 | dst.code() << 3 | src.code());
+ emit_operand(dst, src);
EMIT(imm32);
} else {
EMIT(0x69);
- EMIT(0xC0 | dst.code() << 3 | src.code());
+ emit_operand(dst, src);
emit(imm32);
}
}
}
+void Assembler::neg(const Operand& dst) {
+ EnsureSpace ensure_space(this);
+ EMIT(0xF7);
+ emit_operand(ebx, dst);
+}
+
+
void Assembler::not_(Register dst) {
EnsureSpace ensure_space(this);
EMIT(0xF7);
}
+void Assembler::not_(const Operand& dst) {
+ EnsureSpace ensure_space(this);
+ EMIT(0xF7);
+ emit_operand(edx, dst);
+}
+
+
void Assembler::or_(Register dst, int32_t imm32) {
EnsureSpace ensure_space(this);
emit_arith(1, Operand(dst), Immediate(imm32));
void Assembler::rcl(Register dst, uint8_t imm8) {
EnsureSpace ensure_space(this);
- ASSERT(is_uint5(imm8)); // illegal shift count
+ DCHECK(is_uint5(imm8)); // illegal shift count
if (imm8 == 1) {
EMIT(0xD1);
EMIT(0xD0 | dst.code());
void Assembler::rcr(Register dst, uint8_t imm8) {
EnsureSpace ensure_space(this);
- ASSERT(is_uint5(imm8)); // illegal shift count
+ DCHECK(is_uint5(imm8)); // illegal shift count
if (imm8 == 1) {
EMIT(0xD1);
EMIT(0xD8 | dst.code());
void Assembler::ror(Register dst, uint8_t imm8) {
EnsureSpace ensure_space(this);
- ASSERT(is_uint5(imm8)); // illegal shift count
+ DCHECK(is_uint5(imm8)); // illegal shift count
if (imm8 == 1) {
EMIT(0xD1);
EMIT(0xC8 | dst.code());
}
-void Assembler::sar(Register dst, uint8_t imm8) {
+void Assembler::sar(const Operand& dst, uint8_t imm8) {
EnsureSpace ensure_space(this);
- ASSERT(is_uint5(imm8)); // illegal shift count
+ DCHECK(is_uint5(imm8)); // illegal shift count
if (imm8 == 1) {
EMIT(0xD1);
- EMIT(0xF8 | dst.code());
+ emit_operand(edi, dst);
} else {
EMIT(0xC1);
- EMIT(0xF8 | dst.code());
+ emit_operand(edi, dst);
EMIT(imm8);
}
}
-void Assembler::sar_cl(Register dst) {
+void Assembler::sar_cl(const Operand& dst) {
EnsureSpace ensure_space(this);
EMIT(0xD3);
- EMIT(0xF8 | dst.code());
+ emit_operand(edi, dst);
}
}
-void Assembler::shl(Register dst, uint8_t imm8) {
+void Assembler::shl(const Operand& dst, uint8_t imm8) {
EnsureSpace ensure_space(this);
- ASSERT(is_uint5(imm8)); // illegal shift count
+ DCHECK(is_uint5(imm8)); // illegal shift count
if (imm8 == 1) {
EMIT(0xD1);
- EMIT(0xE0 | dst.code());
+ emit_operand(esp, dst);
} else {
EMIT(0xC1);
- EMIT(0xE0 | dst.code());
+ emit_operand(esp, dst);
EMIT(imm8);
}
}
-void Assembler::shl_cl(Register dst) {
+void Assembler::shl_cl(const Operand& dst) {
EnsureSpace ensure_space(this);
EMIT(0xD3);
- EMIT(0xE0 | dst.code());
+ emit_operand(esp, dst);
}
}
-void Assembler::shr(Register dst, uint8_t imm8) {
+void Assembler::shr(const Operand& dst, uint8_t imm8) {
EnsureSpace ensure_space(this);
- ASSERT(is_uint5(imm8)); // illegal shift count
+ DCHECK(is_uint5(imm8)); // illegal shift count
if (imm8 == 1) {
EMIT(0xD1);
- EMIT(0xE8 | dst.code());
+ emit_operand(ebp, dst);
} else {
EMIT(0xC1);
- EMIT(0xE8 | dst.code());
+ emit_operand(ebp, dst);
EMIT(imm8);
}
}
-void Assembler::shr_cl(Register dst) {
+void Assembler::shr_cl(const Operand& dst) {
EnsureSpace ensure_space(this);
EMIT(0xD3);
- EMIT(0xE8 | dst.code());
+ emit_operand(ebp, dst);
}
void Assembler::ret(int imm16) {
EnsureSpace ensure_space(this);
- ASSERT(is_uint16(imm16));
+ DCHECK(is_uint16(imm16));
if (imm16 == 0) {
EMIT(0xC3);
} else {
void Assembler::bind_to(Label* L, int pos) {
EnsureSpace ensure_space(this);
- ASSERT(0 <= pos && pos <= pc_offset()); // must have a valid binding position
+ DCHECK(0 <= pos && pos <= pc_offset()); // must have a valid binding position
while (L->is_linked()) {
Displacement disp = disp_at(L);
int fixup_pos = L->pos();
long_at_put(fixup_pos, pos + Code::kHeaderSize - kHeapObjectTag);
} else {
if (disp.type() == Displacement::UNCONDITIONAL_JUMP) {
- ASSERT(byte_at(fixup_pos - 1) == 0xE9); // jmp expected
+ DCHECK(byte_at(fixup_pos - 1) == 0xE9); // jmp expected
}
// Relative address, relative to point after address.
int imm32 = pos - (fixup_pos + sizeof(int32_t));
int fixup_pos = L->near_link_pos();
int offset_to_next =
static_cast<int>(*reinterpret_cast<int8_t*>(addr_at(fixup_pos)));
- ASSERT(offset_to_next <= 0);
+ DCHECK(offset_to_next <= 0);
// Relative address, relative to point after address.
int disp = pos - fixup_pos - sizeof(int8_t);
CHECK(0 <= disp && disp <= 127);
void Assembler::bind(Label* L) {
EnsureSpace ensure_space(this);
- ASSERT(!L->is_bound()); // label can only be bound once
+ DCHECK(!L->is_bound()); // label can only be bound once
bind_to(L, pc_offset());
}
if (L->is_bound()) {
const int long_size = 5;
int offs = L->pos() - pc_offset();
- ASSERT(offs <= 0);
+ DCHECK(offs <= 0);
// 1110 1000 #32-bit disp.
EMIT(0xE8);
emit(offs - long_size);
void Assembler::call(byte* entry, RelocInfo::Mode rmode) {
positions_recorder()->WriteRecordedPositions();
EnsureSpace ensure_space(this);
- ASSERT(!RelocInfo::IsCodeTarget(rmode));
+ DCHECK(!RelocInfo::IsCodeTarget(rmode));
EMIT(0xE8);
if (RelocInfo::IsRuntimeEntry(rmode)) {
emit(reinterpret_cast<uint32_t>(entry), rmode);
TypeFeedbackId ast_id) {
positions_recorder()->WriteRecordedPositions();
EnsureSpace ensure_space(this);
- ASSERT(RelocInfo::IsCodeTarget(rmode)
+ DCHECK(RelocInfo::IsCodeTarget(rmode)
|| rmode == RelocInfo::CODE_AGE_SEQUENCE);
EMIT(0xE8);
emit(code, rmode, ast_id);
const int short_size = 2;
const int long_size = 5;
int offs = L->pos() - pc_offset();
- ASSERT(offs <= 0);
+ DCHECK(offs <= 0);
if (is_int8(offs - short_size)) {
// 1110 1011 #8-bit disp.
EMIT(0xEB);
void Assembler::jmp(byte* entry, RelocInfo::Mode rmode) {
EnsureSpace ensure_space(this);
- ASSERT(!RelocInfo::IsCodeTarget(rmode));
+ DCHECK(!RelocInfo::IsCodeTarget(rmode));
EMIT(0xE9);
if (RelocInfo::IsRuntimeEntry(rmode)) {
emit(reinterpret_cast<uint32_t>(entry), rmode);
void Assembler::jmp(Handle<Code> code, RelocInfo::Mode rmode) {
EnsureSpace ensure_space(this);
- ASSERT(RelocInfo::IsCodeTarget(rmode));
+ DCHECK(RelocInfo::IsCodeTarget(rmode));
EMIT(0xE9);
emit(code, rmode);
}
void Assembler::j(Condition cc, Label* L, Label::Distance distance) {
EnsureSpace ensure_space(this);
- ASSERT(0 <= cc && static_cast<int>(cc) < 16);
+ DCHECK(0 <= cc && static_cast<int>(cc) < 16);
if (L->is_bound()) {
const int short_size = 2;
const int long_size = 6;
int offs = L->pos() - pc_offset();
- ASSERT(offs <= 0);
+ DCHECK(offs <= 0);
if (is_int8(offs - short_size)) {
// 0111 tttn #8-bit disp
EMIT(0x70 | cc);
void Assembler::j(Condition cc, byte* entry, RelocInfo::Mode rmode) {
EnsureSpace ensure_space(this);
- ASSERT((0 <= cc) && (static_cast<int>(cc) < 16));
+ DCHECK((0 <= cc) && (static_cast<int>(cc) < 16));
// 0000 1111 1000 tttn #32-bit disp.
EMIT(0x0F);
EMIT(0x80 | cc);
void Assembler::fisttp_s(const Operand& adr) {
- ASSERT(IsEnabled(SSE3));
+ DCHECK(IsEnabled(SSE3));
EnsureSpace ensure_space(this);
EMIT(0xDB);
emit_operand(ecx, adr);
void Assembler::fisttp_d(const Operand& adr) {
- ASSERT(IsEnabled(SSE3));
+ DCHECK(IsEnabled(SSE3));
EnsureSpace ensure_space(this);
EMIT(0xDD);
emit_operand(ecx, adr);
void Assembler::setcc(Condition cc, Register reg) {
- ASSERT(reg.is_byte_register());
+ DCHECK(reg.is_byte_register());
EnsureSpace ensure_space(this);
EMIT(0x0F);
EMIT(0x90 | cc);
void Assembler::cvttss2si(Register dst, const Operand& src) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0xF3);
EMIT(0x0F);
void Assembler::cvttsd2si(Register dst, const Operand& src) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0xF2);
EMIT(0x0F);
void Assembler::cvtsd2si(Register dst, XMMRegister src) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0xF2);
EMIT(0x0F);
void Assembler::cvtsi2sd(XMMRegister dst, const Operand& src) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0xF2);
EMIT(0x0F);
void Assembler::cvtss2sd(XMMRegister dst, XMMRegister src) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0xF3);
EMIT(0x0F);
void Assembler::cvtsd2ss(XMMRegister dst, XMMRegister src) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0xF2);
EMIT(0x0F);
void Assembler::addsd(XMMRegister dst, XMMRegister src) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0xF2);
EMIT(0x0F);
void Assembler::addsd(XMMRegister dst, const Operand& src) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0xF2);
EMIT(0x0F);
void Assembler::mulsd(XMMRegister dst, XMMRegister src) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0xF2);
EMIT(0x0F);
void Assembler::mulsd(XMMRegister dst, const Operand& src) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0xF2);
EMIT(0x0F);
void Assembler::subsd(XMMRegister dst, XMMRegister src) {
- ASSERT(IsEnabled(SSE2));
+ EnsureSpace ensure_space(this);
+ EMIT(0xF2);
+ EMIT(0x0F);
+ EMIT(0x5C);
+ emit_sse_operand(dst, src);
+}
+
+
+void Assembler::subsd(XMMRegister dst, const Operand& src) {
EnsureSpace ensure_space(this);
EMIT(0xF2);
EMIT(0x0F);
void Assembler::divsd(XMMRegister dst, XMMRegister src) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0xF2);
EMIT(0x0F);
void Assembler::xorpd(XMMRegister dst, XMMRegister src) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0x66);
EMIT(0x0F);
void Assembler::andps(XMMRegister dst, const Operand& src) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0x0F);
EMIT(0x54);
void Assembler::orps(XMMRegister dst, const Operand& src) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0x0F);
EMIT(0x56);
void Assembler::xorps(XMMRegister dst, const Operand& src) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0x0F);
EMIT(0x57);
void Assembler::addps(XMMRegister dst, const Operand& src) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0x0F);
EMIT(0x58);
void Assembler::subps(XMMRegister dst, const Operand& src) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0x0F);
EMIT(0x5C);
void Assembler::mulps(XMMRegister dst, const Operand& src) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0x0F);
EMIT(0x59);
void Assembler::divps(XMMRegister dst, const Operand& src) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0x0F);
EMIT(0x5E);
void Assembler::sqrtsd(XMMRegister dst, XMMRegister src) {
- ASSERT(IsEnabled(SSE2));
+ EnsureSpace ensure_space(this);
+ EMIT(0xF2);
+ EMIT(0x0F);
+ EMIT(0x51);
+ emit_sse_operand(dst, src);
+}
+
+
+void Assembler::sqrtsd(XMMRegister dst, const Operand& src) {
EnsureSpace ensure_space(this);
EMIT(0xF2);
EMIT(0x0F);
void Assembler::andpd(XMMRegister dst, XMMRegister src) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0x66);
EMIT(0x0F);
void Assembler::orpd(XMMRegister dst, XMMRegister src) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0x66);
EMIT(0x0F);
void Assembler::ucomisd(XMMRegister dst, const Operand& src) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0x66);
EMIT(0x0F);
void Assembler::roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode) {
- ASSERT(IsEnabled(SSE4_1));
+ DCHECK(IsEnabled(SSE4_1));
EnsureSpace ensure_space(this);
EMIT(0x66);
EMIT(0x0F);
void Assembler::movmskpd(Register dst, XMMRegister src) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0x66);
EMIT(0x0F);
void Assembler::movmskps(Register dst, XMMRegister src) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0x0F);
EMIT(0x50);
void Assembler::pcmpeqd(XMMRegister dst, XMMRegister src) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0x66);
EMIT(0x0F);
}
-void Assembler::pcmpgtd(XMMRegister dst, XMMRegister src) {
- ASSERT(IsEnabled(SSE2));
- EnsureSpace ensure_space(this);
- EMIT(0x66);
- EMIT(0x0F);
- EMIT(0x66);
- emit_sse_operand(dst, src);
-}
-
-
void Assembler::cmpltsd(XMMRegister dst, XMMRegister src) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0xF2);
EMIT(0x0F);
void Assembler::movaps(XMMRegister dst, XMMRegister src) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0x0F);
EMIT(0x28);
}
-void Assembler::movups(XMMRegister dst, const Operand& src) {
- ASSERT(IsEnabled(SSE2));
- EnsureSpace ensure_space(this);
- EMIT(0x0F);
- EMIT(0x10);
- emit_sse_operand(dst, src);
-}
-
-
-void Assembler::movups(const Operand& dst, XMMRegister src) {
- ASSERT(IsEnabled(SSE2));
- EnsureSpace ensure_space(this);
- EMIT(0x0F);
- EMIT(0x11);
- emit_sse_operand(src, dst);
-}
-
-
void Assembler::shufps(XMMRegister dst, XMMRegister src, byte imm8) {
- ASSERT(IsEnabled(SSE2));
- ASSERT(is_uint8(imm8));
+ DCHECK(is_uint8(imm8));
EnsureSpace ensure_space(this);
EMIT(0x0F);
EMIT(0xC6);
void Assembler::movdqa(const Operand& dst, XMMRegister src) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0x66);
EMIT(0x0F);
void Assembler::movdqa(XMMRegister dst, const Operand& src) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0x66);
EMIT(0x0F);
void Assembler::movdqu(const Operand& dst, XMMRegister src ) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0xF3);
EMIT(0x0F);
void Assembler::movdqu(XMMRegister dst, const Operand& src) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0xF3);
EMIT(0x0F);
void Assembler::movntdqa(XMMRegister dst, const Operand& src) {
- ASSERT(IsEnabled(SSE4_1));
+ DCHECK(IsEnabled(SSE4_1));
EnsureSpace ensure_space(this);
EMIT(0x66);
EMIT(0x0F);
void Assembler::movntdq(const Operand& dst, XMMRegister src) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0x66);
EMIT(0x0F);
void Assembler::prefetch(const Operand& src, int level) {
- ASSERT(is_uint2(level));
+ DCHECK(is_uint2(level));
EnsureSpace ensure_space(this);
EMIT(0x0F);
EMIT(0x18);
void Assembler::movsd(const Operand& dst, XMMRegister src ) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0xF2); // double
EMIT(0x0F);
void Assembler::movsd(XMMRegister dst, const Operand& src) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0xF2); // double
EMIT(0x0F);
void Assembler::movss(const Operand& dst, XMMRegister src ) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0xF3); // float
EMIT(0x0F);
void Assembler::movss(XMMRegister dst, const Operand& src) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0xF3); // float
EMIT(0x0F);
void Assembler::movd(XMMRegister dst, const Operand& src) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0x66);
EMIT(0x0F);
void Assembler::movd(const Operand& dst, XMMRegister src) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0x66);
EMIT(0x0F);
void Assembler::extractps(Register dst, XMMRegister src, byte imm8) {
- ASSERT(IsEnabled(SSE4_1));
- ASSERT(is_uint8(imm8));
+ DCHECK(IsEnabled(SSE4_1));
+ DCHECK(is_uint8(imm8));
EnsureSpace ensure_space(this);
EMIT(0x66);
EMIT(0x0F);
void Assembler::pand(XMMRegister dst, XMMRegister src) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0x66);
EMIT(0x0F);
void Assembler::pxor(XMMRegister dst, XMMRegister src) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0x66);
EMIT(0x0F);
void Assembler::por(XMMRegister dst, XMMRegister src) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0x66);
EMIT(0x0F);
void Assembler::ptest(XMMRegister dst, XMMRegister src) {
- ASSERT(IsEnabled(SSE4_1));
+ DCHECK(IsEnabled(SSE4_1));
EnsureSpace ensure_space(this);
EMIT(0x66);
EMIT(0x0F);
void Assembler::psllq(XMMRegister reg, int8_t shift) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0x66);
EMIT(0x0F);
void Assembler::psllq(XMMRegister dst, XMMRegister src) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0x66);
EMIT(0x0F);
}
-void Assembler::pslld(XMMRegister reg, int8_t shift) {
- ASSERT(IsEnabled(SSE2));
- EnsureSpace ensure_space(this);
- EMIT(0x66);
- EMIT(0x0F);
- EMIT(0x72);
- emit_sse_operand(esi, reg); // esi == 6
- EMIT(shift);
-}
-
-
-void Assembler::pslld(XMMRegister dst, XMMRegister src) {
- ASSERT(IsEnabled(SSE2));
- EnsureSpace ensure_space(this);
- EMIT(0x66);
- EMIT(0x0F);
- EMIT(0xF2);
- emit_sse_operand(dst, src);
-}
-
-
-void Assembler::psrld(XMMRegister reg, int8_t shift) {
- ASSERT(IsEnabled(SSE2));
- EnsureSpace ensure_space(this);
- EMIT(0x66);
- EMIT(0x0F);
- EMIT(0x72);
- emit_sse_operand(edx, reg); // edx == 2
- EMIT(shift);
-}
-
-
-void Assembler::psrld(XMMRegister dst, XMMRegister src) {
- ASSERT(IsEnabled(SSE2));
- EnsureSpace ensure_space(this);
- EMIT(0x66);
- EMIT(0x0F);
- EMIT(0xD2);
- emit_sse_operand(dst, src);
-}
-
-
-void Assembler::psrad(XMMRegister reg, int8_t shift) {
- ASSERT(IsEnabled(SSE2));
- EnsureSpace ensure_space(this);
- EMIT(0x66);
- EMIT(0x0F);
- EMIT(0x72);
- emit_sse_operand(esp, reg); // esp == 4
- EMIT(shift);
-}
-
-
-void Assembler::psrad(XMMRegister dst, XMMRegister src) {
- ASSERT(IsEnabled(SSE2));
- EnsureSpace ensure_space(this);
- EMIT(0x66);
- EMIT(0x0F);
- EMIT(0xE2);
- emit_sse_operand(dst, src);
-}
-
-
void Assembler::psrlq(XMMRegister reg, int8_t shift) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0x66);
EMIT(0x0F);
void Assembler::psrlq(XMMRegister dst, XMMRegister src) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0x66);
EMIT(0x0F);
void Assembler::pshufd(XMMRegister dst, XMMRegister src, uint8_t shuffle) {
- ASSERT(IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0x66);
EMIT(0x0F);
void Assembler::pextrd(const Operand& dst, XMMRegister src, int8_t offset) {
- ASSERT(IsEnabled(SSE4_1));
+ DCHECK(IsEnabled(SSE4_1));
EnsureSpace ensure_space(this);
EMIT(0x66);
EMIT(0x0F);
void Assembler::pinsrd(XMMRegister dst, const Operand& src, int8_t offset) {
- ASSERT(IsEnabled(SSE4_1));
+ DCHECK(IsEnabled(SSE4_1));
EnsureSpace ensure_space(this);
EMIT(0x66);
EMIT(0x0F);
}
-void Assembler::minps(XMMRegister dst, const Operand& src) {
- ASSERT(IsEnabled(SSE2));
- EnsureSpace ensure_space(this);
- EMIT(0x0F);
- EMIT(0x5D);
- emit_sse_operand(dst, src);
-}
-
-
-void Assembler::maxps(XMMRegister dst, const Operand& src) {
- ASSERT(IsEnabled(SSE2));
- EnsureSpace ensure_space(this);
- EMIT(0x0F);
- EMIT(0x5F);
- emit_sse_operand(dst, src);
-}
-
-
-void Assembler::rcpps(XMMRegister dst, const Operand& src) {
- ASSERT(IsEnabled(SSE2));
- EnsureSpace ensure_space(this);
- EMIT(0x0F);
- EMIT(0x53);
- emit_sse_operand(dst, src);
-}
-
-
-void Assembler::rsqrtps(XMMRegister dst, const Operand& src) {
- ASSERT(IsEnabled(SSE2));
- EnsureSpace ensure_space(this);
- EMIT(0x0F);
- EMIT(0x52);
- emit_sse_operand(dst, src);
-}
-
-
-void Assembler::sqrtps(XMMRegister dst, const Operand& src) {
- ASSERT(IsEnabled(SSE2));
- EnsureSpace ensure_space(this);
- EMIT(0x0F);
- EMIT(0x51);
- emit_sse_operand(dst, src);
-}
-
-
-void Assembler::cvtdq2ps(XMMRegister dst, const Operand& src) {
- ASSERT(IsEnabled(SSE2));
- EnsureSpace ensure_space(this);
- EMIT(0x0F);
- EMIT(0x5B);
- emit_sse_operand(dst, src);
-}
-
-
-void Assembler::paddd(XMMRegister dst, const Operand& src) {
- ASSERT(IsEnabled(SSE2));
- EnsureSpace ensure_space(this);
- EMIT(0x66);
- EMIT(0x0F);
- EMIT(0xFE);
- emit_sse_operand(dst, src);
-}
-
-
-void Assembler::psubd(XMMRegister dst, const Operand& src) {
- ASSERT(IsEnabled(SSE2));
- EnsureSpace ensure_space(this);
- EMIT(0x66);
- EMIT(0x0F);
- EMIT(0xFA);
- emit_sse_operand(dst, src);
-}
-
-
-void Assembler::pmulld(XMMRegister dst, const Operand& src) {
- ASSERT(IsEnabled(SSE4_1));
- EnsureSpace ensure_space(this);
- EMIT(0x66);
- EMIT(0x0F);
- EMIT(0x38);
- EMIT(0x40);
- emit_sse_operand(dst, src);
-}
-
-
-void Assembler::pmuludq(XMMRegister dst, const Operand& src) {
- ASSERT(IsEnabled(SSE2));
- EnsureSpace ensure_space(this);
- EMIT(0x66);
- EMIT(0x0F);
- EMIT(0xF4);
- emit_sse_operand(dst, src);
-}
-
-
-void Assembler::punpackldq(XMMRegister dst, const Operand& src) {
- ASSERT(IsEnabled(SSE2));
- EnsureSpace ensure_space(this);
- EMIT(0x66);
- EMIT(0x0F);
- EMIT(0x62);
- emit_sse_operand(dst, src);
-}
-
-
-void Assembler::cvtps2dq(XMMRegister dst, const Operand& src) {
- ASSERT(IsEnabled(SSE2));
- EnsureSpace ensure_space(this);
- EMIT(0x66);
- EMIT(0x0F);
- EMIT(0x5B);
- emit_sse_operand(dst, src);
-}
-
-
-void Assembler::cmpps(XMMRegister dst, XMMRegister src, int8_t cmp) {
- ASSERT(IsEnabled(SSE2));
- EnsureSpace ensure_space(this);
- EMIT(0x0F);
- EMIT(0xC2);
- emit_sse_operand(dst, src);
- EMIT(cmp);
-}
-
-
-void Assembler::cmpeqps(XMMRegister dst, XMMRegister src) {
- cmpps(dst, src, 0x0);
-}
-
-
-void Assembler::cmpltps(XMMRegister dst, XMMRegister src) {
- cmpps(dst, src, 0x1);
-}
-
-
-void Assembler::cmpleps(XMMRegister dst, XMMRegister src) {
- cmpps(dst, src, 0x2);
-}
-
-
-void Assembler::cmpneqps(XMMRegister dst, XMMRegister src) {
- cmpps(dst, src, 0x4);
-}
-
-
-void Assembler::cmpnltps(XMMRegister dst, XMMRegister src) {
- cmpps(dst, src, 0x5);
-}
-
-
-void Assembler::cmpnleps(XMMRegister dst, XMMRegister src) {
- cmpps(dst, src, 0x6);
-}
-
-
-void Assembler::insertps(XMMRegister dst, XMMRegister src, byte imm8) {
- ASSERT(CpuFeatures::IsSupported(SSE4_1));
- ASSERT(is_uint8(imm8));
- EnsureSpace ensure_space(this);
- EMIT(0x66);
- EMIT(0x0F);
- EMIT(0x3A);
- EMIT(0x21);
- emit_sse_operand(dst, src);
- EMIT(imm8);
-}
-
-
void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) {
Register ireg = { reg.code() };
emit_operand(ireg, adr);
void Assembler::GrowBuffer() {
- ASSERT(buffer_overflow());
+ DCHECK(buffer_overflow());
if (!own_buffer_) FATAL("external code buffer is too small");
// Compute new buffer size.
CodeDesc desc; // the new buffer
- if (buffer_size_ < 4*KB) {
- desc.buffer_size = 4*KB;
- } else {
- desc.buffer_size = 2*buffer_size_;
- }
+ desc.buffer_size = 2 * buffer_size_;
+
// Some internal data structures overflow for very large buffers,
// they must ensure that kMaximalBufferSize is not too large.
if ((desc.buffer_size > kMaximalBufferSize) ||
// Copy the data.
int pc_delta = desc.buffer - buffer_;
int rc_delta = (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_);
- OS::MemMove(desc.buffer, buffer_, desc.instr_size);
- OS::MemMove(rc_delta + reloc_info_writer.pos(),
- reloc_info_writer.pos(), desc.reloc_size);
+ MemMove(desc.buffer, buffer_, desc.instr_size);
+ MemMove(rc_delta + reloc_info_writer.pos(), reloc_info_writer.pos(),
+ desc.reloc_size);
// Switch buffers.
- if (isolate()->assembler_spare_buffer() == NULL &&
- buffer_size_ == kMinimalBufferSize) {
- isolate()->set_assembler_spare_buffer(buffer_);
- } else {
- DeleteArray(buffer_);
- }
+ DeleteArray(buffer_);
buffer_ = desc.buffer;
buffer_size_ = desc.buffer_size;
pc_ += pc_delta;
}
}
- ASSERT(!buffer_overflow());
+ DCHECK(!buffer_overflow());
}
void Assembler::emit_arith_b(int op1, int op2, Register dst, int imm8) {
- ASSERT(is_uint8(op1) && is_uint8(op2)); // wrong opcode
- ASSERT(is_uint8(imm8));
- ASSERT((op1 & 0x01) == 0); // should be 8bit operation
+ DCHECK(is_uint8(op1) && is_uint8(op2)); // wrong opcode
+ DCHECK(is_uint8(imm8));
+ DCHECK((op1 & 0x01) == 0); // should be 8bit operation
EMIT(op1);
EMIT(op2 | dst.code());
EMIT(imm8);
void Assembler::emit_arith(int sel, Operand dst, const Immediate& x) {
- ASSERT((0 <= sel) && (sel <= 7));
+ DCHECK((0 <= sel) && (sel <= 7));
Register ireg = { sel };
if (x.is_int8()) {
EMIT(0x83); // using a sign-extended 8-bit immediate.
void Assembler::emit_operand(Register reg, const Operand& adr) {
const unsigned length = adr.len_;
- ASSERT(length > 0);
+ DCHECK(length > 0);
// Emit updated ModRM byte containing the given register.
pc_[0] = (adr.buf_[0] & ~0x38) | (reg.code() << 3);
void Assembler::emit_farith(int b1, int b2, int i) {
- ASSERT(is_uint8(b1) && is_uint8(b2)); // wrong opcode
- ASSERT(0 <= i && i < 8); // illegal stack offset
+ DCHECK(is_uint8(b1) && is_uint8(b2)); // wrong opcode
+ DCHECK(0 <= i && i < 8); // illegal stack offset
EMIT(b1);
EMIT(b2 + i);
}
void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
- ASSERT(!RelocInfo::IsNone(rmode));
+ DCHECK(!RelocInfo::IsNone(rmode));
// Don't record external references unless the heap will be serialized.
- if (rmode == RelocInfo::EXTERNAL_REFERENCE) {
-#ifdef DEBUG
- if (!Serializer::enabled()) {
- Serializer::TooLateToEnableNow();
- }
-#endif
- if (!Serializer::enabled() && !emit_debug_code()) {
- return;
- }
+ if (rmode == RelocInfo::EXTERNAL_REFERENCE &&
+ !serializer_enabled() && !emit_debug_code()) {
+ return;
}
RelocInfo rinfo(pc_, rmode, data, NULL);
reloc_info_writer.Write(&rinfo);
}
-MaybeObject* Assembler::AllocateConstantPool(Heap* heap) {
+Handle<ConstantPoolArray> Assembler::NewConstantPool(Isolate* isolate) {
// No out-of-line constant pool support.
- UNREACHABLE();
- return NULL;
+ DCHECK(!FLAG_enable_ool_constant_pool);
+ return isolate->factory()->empty_constant_pool_array();
}
void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) {
// No out-of-line constant pool support.
- UNREACHABLE();
+ DCHECK(!FLAG_enable_ool_constant_pool);
+ return;
}