summaryrefslogtreecommitdiff
path: root/deps/v8/src/ia32/assembler-ia32.h
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/ia32/assembler-ia32.h')
-rw-r--r--deps/v8/src/ia32/assembler-ia32.h150
1 files changed, 101 insertions, 49 deletions
diff --git a/deps/v8/src/ia32/assembler-ia32.h b/deps/v8/src/ia32/assembler-ia32.h
index b60157c752..6609b4fed9 100644
--- a/deps/v8/src/ia32/assembler-ia32.h
+++ b/deps/v8/src/ia32/assembler-ia32.h
@@ -37,6 +37,7 @@
#ifndef V8_IA32_ASSEMBLER_IA32_H_
#define V8_IA32_ASSEMBLER_IA32_H_
+#include "isolate.h"
#include "serialize.h"
namespace v8 {
@@ -248,23 +249,6 @@ inline Condition ReverseCondition(Condition cc) {
}
-enum Hint {
- no_hint = 0,
- not_taken = 0x2e,
- taken = 0x3e
-};
-
-
-// The result of negating a hint is as if the corresponding condition
-// were negated by NegateCondition. That is, no_hint is mapped to
-// itself and not_taken and taken are mapped to each other.
-inline Hint NegateHint(Hint hint) {
- return (hint == no_hint)
- ? no_hint
- : ((hint == not_taken) ? taken : not_taken);
-}
-
-
// -----------------------------------------------------------------------------
// Machine instruction Immediates
@@ -295,6 +279,7 @@ class Immediate BASE_EMBEDDED {
RelocInfo::Mode rmode_;
friend class Assembler;
+ friend class MacroAssembler;
};
@@ -447,14 +432,13 @@ class Displacement BASE_EMBEDDED {
// }
class CpuFeatures : public AllStatic {
public:
- // Detect features of the target CPU. If the portable flag is set,
- // the method sets safe defaults if the serializer is enabled
- // (snapshots must be portable).
- static void Probe(bool portable);
- static void Clear() { supported_ = 0; }
+ // Detect features of the target CPU. Set safe defaults if the serializer
+ // is enabled (snapshots must be portable).
+ static void Probe();
// Check whether a feature is supported by the target CPU.
static bool IsSupported(CpuFeature f) {
+ ASSERT(initialized_);
if (f == SSE2 && !FLAG_enable_sse2) return false;
if (f == SSE3 && !FLAG_enable_sse3) return false;
if (f == SSE4_1 && !FLAG_enable_sse4_1) return false;
@@ -462,10 +446,22 @@ class CpuFeatures : public AllStatic {
if (f == RDTSC && !FLAG_enable_rdtsc) return false;
return (supported_ & (static_cast<uint64_t>(1) << f)) != 0;
}
+
+#ifdef DEBUG
// Check whether a feature is currently enabled.
static bool IsEnabled(CpuFeature f) {
- return (enabled_ & (static_cast<uint64_t>(1) << f)) != 0;
+ ASSERT(initialized_);
+ Isolate* isolate = Isolate::UncheckedCurrent();
+ if (isolate == NULL) {
+ // When no isolate is available, work as if we're running in
+ // release mode.
+ return IsSupported(f);
+ }
+ uint64_t enabled = isolate->enabled_cpu_features();
+ return (enabled & (static_cast<uint64_t>(1) << f)) != 0;
}
+#endif
+
// Enable a specified feature within a scope.
class Scope BASE_EMBEDDED {
#ifdef DEBUG
@@ -473,26 +469,68 @@ class CpuFeatures : public AllStatic {
explicit Scope(CpuFeature f) {
uint64_t mask = static_cast<uint64_t>(1) << f;
ASSERT(CpuFeatures::IsSupported(f));
- ASSERT(!Serializer::enabled() || (found_by_runtime_probing_ & mask) == 0);
- old_enabled_ = CpuFeatures::enabled_;
- CpuFeatures::enabled_ |= mask;
+ ASSERT(!Serializer::enabled() ||
+ (CpuFeatures::found_by_runtime_probing_ & mask) == 0);
+ isolate_ = Isolate::UncheckedCurrent();
+ old_enabled_ = 0;
+ if (isolate_ != NULL) {
+ old_enabled_ = isolate_->enabled_cpu_features();
+ isolate_->set_enabled_cpu_features(old_enabled_ | mask);
+ }
+ }
+ ~Scope() {
+ ASSERT_EQ(Isolate::UncheckedCurrent(), isolate_);
+ if (isolate_ != NULL) {
+ isolate_->set_enabled_cpu_features(old_enabled_);
+ }
}
- ~Scope() { CpuFeatures::enabled_ = old_enabled_; }
private:
+ Isolate* isolate_;
uint64_t old_enabled_;
#else
public:
explicit Scope(CpuFeature f) {}
#endif
};
+
+ class TryForceFeatureScope BASE_EMBEDDED {
+ public:
+ explicit TryForceFeatureScope(CpuFeature f)
+ : old_supported_(CpuFeatures::supported_) {
+ if (CanForce()) {
+ CpuFeatures::supported_ |= (static_cast<uint64_t>(1) << f);
+ }
+ }
+
+ ~TryForceFeatureScope() {
+ if (CanForce()) {
+ CpuFeatures::supported_ = old_supported_;
+ }
+ }
+
+ private:
+ static bool CanForce() {
+ // It's only safe to temporarily force support of CPU features
+ // when there's only a single isolate, which is guaranteed when
+ // the serializer is enabled.
+ return Serializer::enabled();
+ }
+
+ const uint64_t old_supported_;
+ };
+
private:
+#ifdef DEBUG
+ static bool initialized_;
+#endif
static uint64_t supported_;
- static uint64_t enabled_;
static uint64_t found_by_runtime_probing_;
+
+ DISALLOW_COPY_AND_ASSIGN(CpuFeatures);
};
-class Assembler : public Malloced {
+class Assembler : public AssemblerBase {
private:
// We check before assembling an instruction that there is sufficient
// space to write an instruction and its relocation information.
@@ -519,9 +557,13 @@ class Assembler : public Malloced {
// for code generation and assumes its size to be buffer_size. If the buffer
// is too small, a fatal error occurs. No deallocation of the buffer is done
// upon destruction of the assembler.
- Assembler(void* buffer, int buffer_size);
+ // TODO(vitalyr): the assembler does not need an isolate.
+ Assembler(Isolate* isolate, void* buffer, int buffer_size);
~Assembler();
+ // Overrides the default provided by FLAG_debug_code.
+ void set_emit_debug_code(bool value) { emit_debug_code_ = value; }
+
// GetCode emits any pending (non-emitted) code and fills the descriptor
// desc. GetCode() is idempotent; it returns the same result if no other
// Assembler functions are invoked in between GetCode() calls.
@@ -617,6 +659,7 @@ class Assembler : public Malloced {
void push_imm32(int32_t imm32);
void push(Register src);
void push(const Operand& src);
+ void push(Handle<Object> handle);
void pop(Register dst);
void pop(const Operand& dst);
@@ -784,30 +827,30 @@ class Assembler : public Malloced {
// but it may be bound only once.
void bind(Label* L); // binds an unbound label L to the current code position
- void bind(NearLabel* L);
// Calls
void call(Label* L);
void call(byte* entry, RelocInfo::Mode rmode);
+ int CallSize(const Operand& adr);
void call(const Operand& adr);
- void call(Handle<Code> code, RelocInfo::Mode rmode);
+ int CallSize(Handle<Code> code, RelocInfo::Mode mode);
+ void call(Handle<Code> code,
+ RelocInfo::Mode rmode,
+ unsigned ast_id = kNoASTId);
// Jumps
- void jmp(Label* L); // unconditional jump to L
+ // unconditional jump to L
+ void jmp(Label* L, Label::Distance distance = Label::kFar);
void jmp(byte* entry, RelocInfo::Mode rmode);
void jmp(const Operand& adr);
void jmp(Handle<Code> code, RelocInfo::Mode rmode);
- // Short jump
- void jmp(NearLabel* L);
-
// Conditional jumps
- void j(Condition cc, Label* L, Hint hint = no_hint);
- void j(Condition cc, byte* entry, RelocInfo::Mode rmode, Hint hint = no_hint);
- void j(Condition cc, Handle<Code> code, Hint hint = no_hint);
-
- // Conditional short jump
- void j(Condition cc, NearLabel* L, Hint hint = no_hint);
+ void j(Condition cc,
+ Label* L,
+ Label::Distance distance = Label::kFar);
+ void j(Condition cc, byte* entry, RelocInfo::Mode rmode);
+ void j(Condition cc, Handle<Code> code);
// Floating-point operations
void fld(int i);
@@ -885,12 +928,14 @@ class Assembler : public Malloced {
void cvtsi2sd(XMMRegister dst, const Operand& src);
void cvtss2sd(XMMRegister dst, XMMRegister src);
+ void cvtsd2ss(XMMRegister dst, XMMRegister src);
void addsd(XMMRegister dst, XMMRegister src);
void subsd(XMMRegister dst, XMMRegister src);
void mulsd(XMMRegister dst, XMMRegister src);
void divsd(XMMRegister dst, XMMRegister src);
void xorpd(XMMRegister dst, XMMRegister src);
+ void xorps(XMMRegister dst, XMMRegister src);
void sqrtsd(XMMRegister dst, XMMRegister src);
void andpd(XMMRegister dst, XMMRegister src);
@@ -915,6 +960,10 @@ class Assembler : public Malloced {
void movd(const Operand& src, XMMRegister dst);
void movsd(XMMRegister dst, XMMRegister src);
+ void movss(XMMRegister dst, const Operand& src);
+ void movss(const Operand& src, XMMRegister dst);
+ void movss(XMMRegister dst, XMMRegister src);
+
void pand(XMMRegister dst, XMMRegister src);
void pxor(XMMRegister dst, XMMRegister src);
void por(XMMRegister dst, XMMRegister src);
@@ -982,6 +1031,8 @@ class Assembler : public Malloced {
static const int kMinimalBufferSize = 4*KB;
protected:
+ bool emit_debug_code() const { return emit_debug_code_; }
+
void movsd(XMMRegister dst, const Operand& src);
void movsd(const Operand& dst, XMMRegister src);
@@ -989,7 +1040,8 @@ class Assembler : public Malloced {
void emit_sse_operand(XMMRegister dst, XMMRegister src);
void emit_sse_operand(Register dst, XMMRegister src);
- byte* addr_at(int pos) { return buffer_ + pos; }
+ byte* addr_at(int pos) { return buffer_ + pos; }
+
private:
byte byte_at(int pos) { return buffer_[pos]; }
void set_byte_at(int pos, byte value) { buffer_[pos] = value; }
@@ -1004,7 +1056,9 @@ class Assembler : public Malloced {
void GrowBuffer();
inline void emit(uint32_t x);
inline void emit(Handle<Object> handle);
- inline void emit(uint32_t x, RelocInfo::Mode rmode);
+ inline void emit(uint32_t x,
+ RelocInfo::Mode rmode,
+ unsigned ast_id = kNoASTId);
inline void emit(const Immediate& x);
inline void emit_w(const Immediate& x);
@@ -1032,6 +1086,7 @@ class Assembler : public Malloced {
inline Displacement disp_at(Label* L);
inline void disp_at_put(Label* L, Displacement disp);
inline void emit_disp(Label* L, Displacement::Type type);
+ inline void emit_near_disp(Label* L);
// record reloc info for current pc_
void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
@@ -1045,18 +1100,15 @@ class Assembler : public Malloced {
int buffer_size_;
// True if the assembler owns the buffer, false if buffer is external.
bool own_buffer_;
- // A previously allocated buffer of kMinimalBufferSize bytes, or NULL.
- static byte* spare_buffer_;
// code generation
byte* pc_; // the program counter; moves forward
RelocInfoWriter reloc_info_writer;
- // push-pop elimination
- byte* last_pc_;
-
PositionsRecorder positions_recorder_;
+ bool emit_debug_code_;
+
friend class PositionsRecorder;
};