diff options
Diffstat (limited to 'deps/v8/src/x64/assembler-x64.h')
-rw-r--r-- | deps/v8/src/x64/assembler-x64.h | 112 |
1 files changed, 82 insertions, 30 deletions
diff --git a/deps/v8/src/x64/assembler-x64.h b/deps/v8/src/x64/assembler-x64.h index aeff5ee06d1..8823334a46f 100644 --- a/deps/v8/src/x64/assembler-x64.h +++ b/deps/v8/src/x64/assembler-x64.h @@ -220,6 +220,7 @@ typedef XMMRegister Simd128Register; DOUBLE_REGISTERS(DECLARE_REGISTER) #undef DECLARE_REGISTER constexpr DoubleRegister no_double_reg = DoubleRegister::no_reg(); +constexpr DoubleRegister no_dreg = DoubleRegister::no_reg(); enum Condition { // any value < 0 is considered no_condition @@ -266,31 +267,6 @@ inline Condition NegateCondition(Condition cc) { } -// Commute a condition such that {a cond b == b cond' a}. -inline Condition CommuteCondition(Condition cc) { - switch (cc) { - case below: - return above; - case above: - return below; - case above_equal: - return below_equal; - case below_equal: - return above_equal; - case less: - return greater; - case greater: - return less; - case greater_equal: - return less_equal; - case less_equal: - return greater_equal; - default: - return cc; - } -} - - enum RoundingMode { kRoundToNearest = 0x0, kRoundDown = 0x1, @@ -422,7 +398,68 @@ static_assert(sizeof(Operand) <= 2 * kPointerSize, V(shr, 0x5) \ V(sar, 0x7) -class Assembler : public AssemblerBase { +// Partial Constant Pool +// Different from complete constant pool (like arm does), partial constant pool +// only takes effects for shareable constants in order to reduce code size. +// Partial constant pool does not emit constant pool entries at the end of each +// code object. Instead, it keeps the first shareable constant inlined in the +// instructions and uses rip-relative memory loadings for the same constants in +// subsequent instructions. These rip-relative memory loadings will target at +// the position of the first inlined constant. For example: +// +// REX.W movq r10,0x7f9f75a32c20 ; 10 bytes +// … +// REX.W movq r10,0x7f9f75a32c20 ; 10 bytes +// … +// +// turns into +// +// REX.W movq r10,0x7f9f75a32c20 ; 10 bytes +// … +// REX.W movq r10,[rip+0xffffff96] ; 7 bytes +// … + +class ConstPool { + public: + explicit ConstPool(Assembler* assm) : assm_(assm) {} + // Returns true when partial constant pool is valid for this entry. + bool TryRecordEntry(intptr_t data, RelocInfo::Mode mode); + bool IsEmpty() const { return entries_.empty(); } + + void PatchEntries(); + // Discard any pending pool entries. + void Clear(); + + private: + // Adds a shared entry to entries_. Returns true if this is not the first time + // we add this entry, false otherwise. + bool AddSharedEntry(uint64_t data, int offset); + + // Check if the instruction is a rip-relative move. + bool IsMoveRipRelative(byte* instr); + + Assembler* assm_; + + // Values, pc offsets of entries. + typedef std::multimap<uint64_t, int> EntryMap; + EntryMap entries_; + + // Number of bytes taken up by the displacement of rip-relative addressing. + static constexpr int kRipRelativeDispSize = 4; // 32-bit displacement. + // Distance between the address of the displacement in the rip-relative move + // instruction and the head address of the instruction. + static constexpr int kMoveRipRelativeDispOffset = + 3; // REX Opcode ModRM Displacement + // Distance between the address of the imm64 in the 'movq reg, imm64' + // instruction and the head address of the instruction. + static constexpr int kMoveImm64Offset = 2; // REX Opcode imm64 + // A mask for rip-relative move instruction. + static constexpr uint32_t kMoveRipRelativeMask = 0x00C7FFFB; + // The bits for a rip-relative move instruction after mask. + static constexpr uint32_t kMoveRipRelativeInstr = 0x00058B48; +}; + +class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { private: // We check before assembling an instruction that there is sufficient // space to write an instruction and its relocation information. @@ -817,6 +854,8 @@ class Assembler : public AssemblerBase { void testw(Operand op, Register reg); // Bit operations. + void bswapl(Register dst); + void bswapq(Register dst); void bt(Operand dst, Register src); void bts(Operand dst, Register src); void bsrq(Register dst, Register src); @@ -841,6 +880,10 @@ class Assembler : public AssemblerBase { void pshufw(XMMRegister dst, XMMRegister src, uint8_t shuffle); void pshufw(XMMRegister dst, Operand src, uint8_t shuffle); + void pblendw(XMMRegister dst, Operand src, uint8_t mask); + void pblendw(XMMRegister dst, XMMRegister src, uint8_t mask); + void palignr(XMMRegister dst, Operand src, uint8_t mask); + void palignr(XMMRegister dst, XMMRegister src, uint8_t mask); // Label operations & relative jumps (PPUM Appendix D) // @@ -1146,6 +1189,8 @@ class Assembler : public AssemblerBase { void cvttss2siq(Register dst, Operand src); void cvttsd2siq(Register dst, XMMRegister src); void cvttsd2siq(Register dst, Operand src); + void cvttps2dq(XMMRegister dst, Operand src); + void cvttps2dq(XMMRegister dst, XMMRegister src); void cvtlsi2sd(XMMRegister dst, Operand src); void cvtlsi2sd(XMMRegister dst, Register src); @@ -1197,10 +1242,6 @@ class Assembler : public AssemblerBase { void movmskpd(Register dst, XMMRegister src); - void punpckldq(XMMRegister dst, XMMRegister src); - void punpckldq(XMMRegister dst, Operand src); - void punpckhdq(XMMRegister dst, XMMRegister src); - // SSE 4.1 instruction void insertps(XMMRegister dst, XMMRegister src, byte imm8); void extractps(Register dst, XMMRegister src, byte imm8); @@ -1894,6 +1935,12 @@ class Assembler : public AssemblerBase { void dp(uintptr_t data) { dq(data); } void dq(Label* label); + // Patch entries for partial constant pool. + void PatchConstPool(); + + // Check if use partial constant pool for this rmode. + static bool UseConstPoolFor(RelocInfo::Mode rmode); + // Check if there is less than kGap bytes available in the buffer. // If this is the case, we need to grow the buffer before emitting // an instruction or relocation information. @@ -1945,6 +1992,7 @@ class Assembler : public AssemblerBase { inline void emit_rex_64(XMMRegister reg, Register rm_reg); inline void emit_rex_64(Register reg, XMMRegister rm_reg); inline void emit_rex_64(Register reg, Register rm_reg); + inline void emit_rex_64(XMMRegister reg, XMMRegister rm_reg); // Emits a REX prefix that encodes a 64-bit operand size and // the top bit of the destination, index, and base register codes. @@ -2374,6 +2422,10 @@ class Assembler : public AssemblerBase { int farjmp_num_ = 0; std::deque<int> farjmp_positions_; std::map<Label*, std::vector<int>> label_farjmp_maps_; + + ConstPool constpool_; + + friend class ConstPool; }; |