Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/x64/assembler-x64.h')
-rw-r--r--deps/v8/src/x64/assembler-x64.h112
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;
};