diff options
Diffstat (limited to 'deps/v8/src/ia32/assembler-ia32.h')
-rw-r--r-- | deps/v8/src/ia32/assembler-ia32.h | 150 |
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; }; |