diff options
Diffstat (limited to 'deps/v8/src/ia32/assembler-ia32.h')
-rw-r--r-- | deps/v8/src/ia32/assembler-ia32.h | 153 |
1 files changed, 104 insertions, 49 deletions
diff --git a/deps/v8/src/ia32/assembler-ia32.h b/deps/v8/src/ia32/assembler-ia32.h index 69d243a749..b721542f13 100644 --- a/deps/v8/src/ia32/assembler-ia32.h +++ b/deps/v8/src/ia32/assembler-ia32.h @@ -140,7 +140,6 @@ typedef XMMRegister Simd128Register; constexpr DoubleRegister R = DoubleRegister::from_code<kDoubleCode_##R>(); DOUBLE_REGISTERS(DEFINE_REGISTER) #undef DEFINE_REGISTER -constexpr DoubleRegister no_double_reg = DoubleRegister::no_reg(); constexpr DoubleRegister no_dreg = DoubleRegister::no_reg(); // Note that the bit values must match those used in actual instruction encoding @@ -208,7 +207,7 @@ enum RoundingMode { // ----------------------------------------------------------------------------- // Machine instruction Immediates -class Immediate BASE_EMBEDDED { +class Immediate { public: // Calls where x is an Address (uintptr_t) resolve to this overload. inline explicit Immediate(int x, RelocInfo::Mode rmode = RelocInfo::NONE) { @@ -224,6 +223,7 @@ class Immediate BASE_EMBEDDED { static Immediate EmbeddedNumber(double number); // Smi or HeapNumber. static Immediate EmbeddedCode(CodeStub* code); + static Immediate EmbeddedStringConstant(const StringConstantBase* str); static Immediate CodeRelativeOffset(Label* label) { return Immediate(label); @@ -361,10 +361,17 @@ class V8_EXPORT_PRIVATE Operand { // register. Register reg() const; +#ifdef DEBUG + bool UsesEbx() const { return uses_ebx_; } +#endif // DEBUG + private: // Set the ModRM byte without an encoded 'reg' register. The // register is encoded later as part of the emit_operand operation. inline void set_modrm(int mod, Register rm) { +#ifdef DEBUG + AddUsedRegister(rm); +#endif DCHECK_EQ(mod & -4, 0); buf_[0] = mod << 6 | rm.code(); len_ = 1; @@ -391,12 +398,23 @@ class V8_EXPORT_PRIVATE Operand { // Only valid if len_ > 4. RelocInfo::Mode rmode_ = RelocInfo::NONE; +#ifdef DEBUG + // TODO(v8:6666): Remove once kRootRegister support is complete. + bool uses_ebx_ = false; + void AddUsedRegister(Register reg) { + if (reg == ebx) uses_ebx_ = true; + } +#endif // DEBUG + // TODO(clemensh): Get rid of this friendship, or make Operand immutable. friend class Assembler; }; ASSERT_TRIVIALLY_COPYABLE(Operand); +// TODO(v8:6666): Re-enable globally once kRootRegister support is complete. +#ifndef DEBUG static_assert(sizeof(Operand) <= 2 * kPointerSize, "Operand must be small enough to pass it by value"); +#endif // ----------------------------------------------------------------------------- // A Displacement describes the 32bit immediate field of an instruction which @@ -417,7 +435,7 @@ static_assert(sizeof(Operand) <= 2 * kPointerSize, // |31.....2|1......0| // [ next | type | -class Displacement BASE_EMBEDDED { +class Displacement { public: enum Type { UNCONDITIONAL_JUMP, CODE_RELATIVE, OTHER, CODE_ABSOLUTE }; @@ -667,7 +685,10 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { void and_(Operand dst, Register src); void and_(Operand dst, const Immediate& x); - void cmpb(Register reg, Immediate imm8) { cmpb(Operand(reg), imm8); } + void cmpb(Register reg, Immediate imm8) { + DCHECK(reg.is_byte_register()); + cmpb(Operand(reg), imm8); + } void cmpb(Operand op, Immediate imm8); void cmpb(Register reg, Operand op); void cmpb(Operand op, Register reg); @@ -983,7 +1004,7 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { void maxps(XMMRegister dst, Operand src); void maxps(XMMRegister dst, XMMRegister src) { maxps(dst, Operand(src)); } - void cmpps(XMMRegister dst, Operand src, int8_t cmp); + void cmpps(XMMRegister dst, Operand src, uint8_t cmp); #define SSE_CMP_P(instr, imm8) \ void instr##ps(XMMRegister dst, XMMRegister src) { \ cmpps(dst, Operand(src), imm8); \ @@ -1088,15 +1109,15 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { void movss(XMMRegister dst, XMMRegister src) { movss(dst, Operand(src)); } void extractps(Register dst, XMMRegister src, byte imm8); - void psllw(XMMRegister reg, int8_t shift); - void pslld(XMMRegister reg, int8_t shift); - void psrlw(XMMRegister reg, int8_t shift); - void psrld(XMMRegister reg, int8_t shift); - void psraw(XMMRegister reg, int8_t shift); - void psrad(XMMRegister reg, int8_t shift); - void psllq(XMMRegister reg, int8_t shift); + void psllw(XMMRegister reg, uint8_t shift); + void pslld(XMMRegister reg, uint8_t shift); + void psrlw(XMMRegister reg, uint8_t shift); + void psrld(XMMRegister reg, uint8_t shift); + void psraw(XMMRegister reg, uint8_t shift); + void psrad(XMMRegister reg, uint8_t shift); + void psllq(XMMRegister reg, uint8_t shift); void psllq(XMMRegister dst, XMMRegister src); - void psrlq(XMMRegister reg, int8_t shift); + void psrlq(XMMRegister reg, uint8_t shift); void psrlq(XMMRegister dst, XMMRegister src); void pshufhw(XMMRegister dst, XMMRegister src, uint8_t shuffle) { @@ -1122,36 +1143,36 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { } void palignr(XMMRegister dst, Operand src, uint8_t mask); - void pextrb(Register dst, XMMRegister src, int8_t offset) { + void pextrb(Register dst, XMMRegister src, uint8_t offset) { pextrb(Operand(dst), src, offset); } - void pextrb(Operand dst, XMMRegister src, int8_t offset); + void pextrb(Operand dst, XMMRegister src, uint8_t offset); // Use SSE4_1 encoding for pextrw reg, xmm, imm8 for consistency - void pextrw(Register dst, XMMRegister src, int8_t offset) { + void pextrw(Register dst, XMMRegister src, uint8_t offset) { pextrw(Operand(dst), src, offset); } - void pextrw(Operand dst, XMMRegister src, int8_t offset); - void pextrd(Register dst, XMMRegister src, int8_t offset) { + void pextrw(Operand dst, XMMRegister src, uint8_t offset); + void pextrd(Register dst, XMMRegister src, uint8_t offset) { pextrd(Operand(dst), src, offset); } - void pextrd(Operand dst, XMMRegister src, int8_t offset); + void pextrd(Operand dst, XMMRegister src, uint8_t offset); - void insertps(XMMRegister dst, XMMRegister src, int8_t offset) { + void insertps(XMMRegister dst, XMMRegister src, uint8_t offset) { insertps(dst, Operand(src), offset); } - void insertps(XMMRegister dst, Operand src, int8_t offset); - void pinsrb(XMMRegister dst, Register src, int8_t offset) { + void insertps(XMMRegister dst, Operand src, uint8_t offset); + void pinsrb(XMMRegister dst, Register src, uint8_t offset) { pinsrb(dst, Operand(src), offset); } - void pinsrb(XMMRegister dst, Operand src, int8_t offset); - void pinsrw(XMMRegister dst, Register src, int8_t offset) { + void pinsrb(XMMRegister dst, Operand src, uint8_t offset); + void pinsrw(XMMRegister dst, Register src, uint8_t offset) { pinsrw(dst, Operand(src), offset); } - void pinsrw(XMMRegister dst, Operand src, int8_t offset); - void pinsrd(XMMRegister dst, Register src, int8_t offset) { + void pinsrw(XMMRegister dst, Operand src, uint8_t offset); + void pinsrd(XMMRegister dst, Register src, uint8_t offset) { pinsrd(dst, Operand(src), offset); } - void pinsrd(XMMRegister dst, Operand src, int8_t offset); + void pinsrd(XMMRegister dst, Operand src, uint8_t offset); // AVX instructions void vfmadd132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { @@ -1414,12 +1435,12 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { } void vshufps(XMMRegister dst, XMMRegister src1, Operand src2, byte imm8); - void vpsllw(XMMRegister dst, XMMRegister src, int8_t imm8); - void vpslld(XMMRegister dst, XMMRegister src, int8_t imm8); - void vpsrlw(XMMRegister dst, XMMRegister src, int8_t imm8); - void vpsrld(XMMRegister dst, XMMRegister src, int8_t imm8); - void vpsraw(XMMRegister dst, XMMRegister src, int8_t imm8); - void vpsrad(XMMRegister dst, XMMRegister src, int8_t imm8); + void vpsllw(XMMRegister dst, XMMRegister src, uint8_t imm8); + void vpslld(XMMRegister dst, XMMRegister src, uint8_t imm8); + void vpsrlw(XMMRegister dst, XMMRegister src, uint8_t imm8); + void vpsrld(XMMRegister dst, XMMRegister src, uint8_t imm8); + void vpsraw(XMMRegister dst, XMMRegister src, uint8_t imm8); + void vpsrad(XMMRegister dst, XMMRegister src, uint8_t imm8); void vpshufhw(XMMRegister dst, XMMRegister src, uint8_t shuffle) { vpshufhw(dst, Operand(src), shuffle); @@ -1446,40 +1467,40 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { } void vpalignr(XMMRegister dst, XMMRegister src1, Operand src2, uint8_t mask); - void vpextrb(Register dst, XMMRegister src, int8_t offset) { + void vpextrb(Register dst, XMMRegister src, uint8_t offset) { vpextrb(Operand(dst), src, offset); } - void vpextrb(Operand dst, XMMRegister src, int8_t offset); - void vpextrw(Register dst, XMMRegister src, int8_t offset) { + void vpextrb(Operand dst, XMMRegister src, uint8_t offset); + void vpextrw(Register dst, XMMRegister src, uint8_t offset) { vpextrw(Operand(dst), src, offset); } - void vpextrw(Operand dst, XMMRegister src, int8_t offset); - void vpextrd(Register dst, XMMRegister src, int8_t offset) { + void vpextrw(Operand dst, XMMRegister src, uint8_t offset); + void vpextrd(Register dst, XMMRegister src, uint8_t offset) { vpextrd(Operand(dst), src, offset); } - void vpextrd(Operand dst, XMMRegister src, int8_t offset); + void vpextrd(Operand dst, XMMRegister src, uint8_t offset); void vinsertps(XMMRegister dst, XMMRegister src1, XMMRegister src2, - int8_t offset) { + uint8_t offset) { vinsertps(dst, src1, Operand(src2), offset); } void vinsertps(XMMRegister dst, XMMRegister src1, Operand src2, - int8_t offset); + uint8_t offset); void vpinsrb(XMMRegister dst, XMMRegister src1, Register src2, - int8_t offset) { + uint8_t offset) { vpinsrb(dst, src1, Operand(src2), offset); } - void vpinsrb(XMMRegister dst, XMMRegister src1, Operand src2, int8_t offset); + void vpinsrb(XMMRegister dst, XMMRegister src1, Operand src2, uint8_t offset); void vpinsrw(XMMRegister dst, XMMRegister src1, Register src2, - int8_t offset) { + uint8_t offset) { vpinsrw(dst, src1, Operand(src2), offset); } - void vpinsrw(XMMRegister dst, XMMRegister src1, Operand src2, int8_t offset); + void vpinsrw(XMMRegister dst, XMMRegister src1, Operand src2, uint8_t offset); void vpinsrd(XMMRegister dst, XMMRegister src1, Register src2, - int8_t offset) { + uint8_t offset) { vpinsrd(dst, src1, Operand(src2), offset); } - void vpinsrd(XMMRegister dst, XMMRegister src1, Operand src2, int8_t offset); + void vpinsrd(XMMRegister dst, XMMRegister src1, Operand src2, uint8_t offset); void vcvtdq2ps(XMMRegister dst, XMMRegister src) { vcvtdq2ps(dst, Operand(src)); @@ -1612,7 +1633,7 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { void vps(byte op, XMMRegister dst, XMMRegister src1, Operand src2); void vpd(byte op, XMMRegister dst, XMMRegister src1, Operand src2); - void vcmpps(XMMRegister dst, XMMRegister src1, Operand src2, int8_t cmp); + void vcmpps(XMMRegister dst, XMMRegister src1, Operand src2, uint8_t cmp); #define AVX_CMP_P(instr, imm8) \ void instr##ps(XMMRegister dst, XMMRegister src1, XMMRegister src2) { \ vcmpps(dst, src1, Operand(src2), imm8); \ @@ -1757,6 +1778,30 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { UNREACHABLE(); } + // Temporary helper data structures while adding kRootRegister support to ia32 + // builtins. The SupportsRootRegisterScope is intended to mark each builtin + // and helper that fully supports the root register, i.e. that does not + // clobber ebx. The AllowExplicitEbxAccessScope marks regions that are allowed + // to clobber ebx, e.g. when ebx is spilled and restored. + // TODO(v8:6666): Remove once kRootRegister is fully supported. + template <bool new_value> + class SetRootRegisterSupportScope final { + public: + explicit SetRootRegisterSupportScope(Assembler* assembler) + : assembler_(assembler), old_value_(assembler->is_ebx_addressable_) { + assembler_->is_ebx_addressable_ = new_value; + } + ~SetRootRegisterSupportScope() { + assembler_->is_ebx_addressable_ = old_value_; + } + + private: + Assembler* assembler_; + const bool old_value_; + }; + typedef SetRootRegisterSupportScope<false> SupportsRootRegisterScope; + typedef SetRootRegisterSupportScope<true> AllowExplicitEbxAccessScope; + protected: void emit_sse_operand(XMMRegister reg, Operand adr); void emit_sse_operand(XMMRegister dst, XMMRegister src); @@ -1765,6 +1810,16 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { byte* addr_at(int pos) { return buffer_ + pos; } +#ifdef DEBUG + // TODO(v8:6666): Remove once kRootRegister is fully supported. + void AssertIsAddressable(const Register& reg); + void AssertIsAddressable(const Operand& operand); +#else + // An empty inline definition to avoid slowing down release builds. + void AssertIsAddressable(const Register&) {} + void AssertIsAddressable(const Operand&) {} +#endif // DEBUG + bool is_ebx_addressable_ = true; private: uint32_t long_at(int pos) { @@ -1868,7 +1923,7 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { // instructions and relocation information. The constructor makes // sure that there is enough space and (in debug mode) the destructor // checks that we did not generate too much. -class EnsureSpace BASE_EMBEDDED { +class EnsureSpace { public: explicit EnsureSpace(Assembler* assembler) : assembler_(assembler) { if (assembler_->buffer_overflow()) assembler_->GrowBuffer(); |