summaryrefslogtreecommitdiff
path: root/deps/v8/src/x64/assembler-x64.h
diff options
context:
space:
mode:
authorRyan <ry@tinyclouds.org>2009-06-29 10:55:05 +0200
committerRyan <ry@tinyclouds.org>2009-06-29 10:55:05 +0200
commite763efdadf4bbd9c0155a4c7f782d271a2fd5814 (patch)
tree094824e55548cdeb2ce9b796cbf29aaa591bb69f /deps/v8/src/x64/assembler-x64.h
parente876d6629e8682f5d818141bc0710f6d82311373 (diff)
downloadnode-new-e763efdadf4bbd9c0155a4c7f782d271a2fd5814.tar.gz
Upgrade v8 to 1.2.10 and libev to 3.6
Diffstat (limited to 'deps/v8/src/x64/assembler-x64.h')
-rw-r--r--deps/v8/src/x64/assembler-x64.h192
1 files changed, 155 insertions, 37 deletions
diff --git a/deps/v8/src/x64/assembler-x64.h b/deps/v8/src/x64/assembler-x64.h
index 650c218f11..0d98e5fe4a 100644
--- a/deps/v8/src/x64/assembler-x64.h
+++ b/deps/v8/src/x64/assembler-x64.h
@@ -45,7 +45,7 @@ namespace internal {
// Test whether a 64-bit value is in a specific range.
static inline bool is_uint32(int64_t x) {
const int64_t kUInt32Mask = V8_INT64_C(0xffffffff);
- return x == x & kUInt32Mask;
+ return x == (x & kUInt32Mask);
}
static inline bool is_int32(int64_t x) {
@@ -82,8 +82,6 @@ struct Register {
}
bool is_valid() const { return 0 <= code_ && code_ < 16; }
bool is(Register reg) const { return code_ == reg.code_; }
- // The byte-register distinction of ai32 has dissapeared.
- bool is_byte_register() const { return false; }
int code() const {
ASSERT(is_valid());
return code_;
@@ -92,6 +90,17 @@ struct Register {
return 1 << code_;
}
+ // Return the high bit of the register code as a 0 or 1. Used often
+ // when constructing the REX prefix byte.
+ int high_bit() const {
+ return code_ >> 3;
+ }
+ // Return the 3 low bits of the register code. Used when encoding registers
+ // in modR/M, SIB, and opcode bytes.
+ int low_bits() const {
+ return code_ & 0x7;
+ }
+
// (unfortunately we can't make this private in a struct when initializing
// by assignment.)
int code_;
@@ -115,7 +124,8 @@ extern Register r14;
extern Register r15;
extern Register no_reg;
-struct XMMRegister {
+
+struct MMXRegister {
bool is_valid() const { return 0 <= code_ && code_ < 2; }
int code() const {
ASSERT(is_valid());
@@ -125,6 +135,34 @@ struct XMMRegister {
int code_;
};
+extern MMXRegister mm0;
+extern MMXRegister mm1;
+extern MMXRegister mm2;
+extern MMXRegister mm3;
+extern MMXRegister mm4;
+extern MMXRegister mm5;
+extern MMXRegister mm6;
+extern MMXRegister mm7;
+extern MMXRegister mm8;
+extern MMXRegister mm9;
+extern MMXRegister mm10;
+extern MMXRegister mm11;
+extern MMXRegister mm12;
+extern MMXRegister mm13;
+extern MMXRegister mm14;
+extern MMXRegister mm15;
+
+
+struct XMMRegister {
+ bool is_valid() const { return 0 <= code_ && code_ < 16; }
+ int code() const {
+ ASSERT(is_valid());
+ return code_;
+ }
+
+ int code_;
+};
+
extern XMMRegister xmm0;
extern XMMRegister xmm1;
extern XMMRegister xmm2;
@@ -238,12 +276,12 @@ class Immediate BASE_EMBEDDED {
// Machine instruction Operands
enum ScaleFactor {
- kTimes1 = 0,
- kTimes2 = 1,
- kTimes4 = 2,
- kTimes8 = 3,
- kTimesIntSize = kTimes4,
- kTimesPointerSize = kTimes8
+ times_1 = 0,
+ times_2 = 1,
+ times_4 = 2,
+ times_8 = 3,
+ times_int_size = times_4,
+ times_pointer_size = times_8
};
@@ -290,11 +328,11 @@ class Operand BASE_EMBEDDED {
// CpuFeatures keeps track of which features are supported by the target CPU.
// Supported features must be enabled by a Scope before use.
// Example:
-// if (CpuFeatures::IsSupported(SSE2)) {
-// CpuFeatures::Scope fscope(SSE2);
-// // Generate SSE2 floating point code.
+// if (CpuFeatures::IsSupported(SSE3)) {
+// CpuFeatures::Scope fscope(SSE3);
+// // Generate SSE3 floating point code.
// } else {
-// // Generate standard x87 floating point code.
+// // Generate standard x87 or SSE2 floating point code.
// }
class CpuFeatures : public AllStatic {
public:
@@ -331,6 +369,10 @@ class CpuFeatures : public AllStatic {
#endif
};
private:
+ // Safe defaults include SSE2 and CMOV for X64. It is always available, if
+ // anyone checks, but they shouldn't need to check.
+ static const uint64_t kDefaultCpuFeatures =
+ (1 << CpuFeatures::SSE2 | 1 << CpuFeatures::CMOV);
static uint64_t supported_;
static uint64_t enabled_;
};
@@ -338,11 +380,15 @@ class CpuFeatures : public AllStatic {
class Assembler : public Malloced {
private:
- // The relocation writer's position is kGap bytes below the end of
+ // We check before assembling an instruction that there is sufficient
+ // space to write an instruction and its relocation information.
+ // The relocation writer's position must be kGap bytes above the end of
// the generated instructions. This leaves enough space for the
- // longest possible x64 instruction (There is a 15 byte limit on
- // instruction length, ruling out some otherwise valid instructions) and
- // allows for a single, fast space check per instruction.
+ // longest possible x64 instruction, 15 bytes, and the longest possible
+ // relocation information encoding, RelocInfoWriter::kMaxLength == 16.
+ // (There is a 15 byte limit on x64 instruction length that rules out some
+ // otherwise valid instructions.)
+ // This allows for a single, fast space check per instruction.
static const int kGap = 32;
public:
@@ -373,8 +419,8 @@ class Assembler : public Malloced {
static inline void set_target_address_at(Address pc, Address target);
// Distance between the address of the code target in the call instruction
- // and the return address
- static const int kTargetAddrToReturnAddrDist = kPointerSize;
+ // and the return address. Checked in the debug build.
+ static const int kTargetAddrToReturnAddrDist = 3 + kPointerSize;
// ---------------------------------------------------------------------------
@@ -446,12 +492,19 @@ class Assembler : public Malloced {
void movq(Register dst, ExternalReference ext);
void movq(Register dst, Handle<Object> handle, RelocInfo::Mode rmode);
+ void movsxlq(Register dst, Register src);
+ void movsxlq(Register dst, const Operand& src);
+ void movzxbq(Register dst, const Operand& src);
+
// New x64 instruction to load from an immediate 64-bit pointer into RAX.
void load_rax(void* ptr, RelocInfo::Mode rmode);
void load_rax(ExternalReference ext);
- // Conditional moves
- // Implement conditional moves here.
+ // Conditional moves.
+ void cmovq(Condition cc, Register dst, Register src);
+ void cmovq(Condition cc, Register dst, const Operand& src);
+ void cmovl(Condition cc, Register dst, Register src);
+ void cmovl(Condition cc, Register dst, const Operand& src);
// Exchange two registers
void xchg(Register dst, Register src);
@@ -461,6 +514,14 @@ class Assembler : public Malloced {
arithmetic_op(0x03, dst, src);
}
+ void addl(Register dst, Register src) {
+ arithmetic_op_32(0x03, dst, src);
+ }
+
+ void addl(Register dst, Immediate src) {
+ immediate_arithmetic_op_32(0x0, dst, src);
+ }
+
void addq(Register dst, const Operand& src) {
arithmetic_op(0x03, dst, src);
}
@@ -482,6 +543,10 @@ class Assembler : public Malloced {
immediate_arithmetic_op_32(0x0, dst, src);
}
+ void cmpb(Register dst, Immediate src) {
+ immediate_arithmetic_op_8(0x7, dst, src);
+ }
+
void cmpb(const Operand& dst, Immediate src) {
immediate_arithmetic_op_8(0x7, dst, src);
}
@@ -502,6 +567,10 @@ class Assembler : public Malloced {
immediate_arithmetic_op(0x7, dst, src);
}
+ void cmpl(Register dst, Immediate src) {
+ immediate_arithmetic_op_32(0x7, dst, src);
+ }
+
void cmpq(const Operand& dst, Immediate src) {
immediate_arithmetic_op(0x7, dst, src);
}
@@ -540,6 +609,8 @@ class Assembler : public Malloced {
void imul(Register dst, const Operand& src);
// Performs the operation dst = src * imm.
void imul(Register dst, Register src, Immediate imm);
+ // Multiply 32 bit registers
+ void imull(Register dst, Register src);
void incq(Register dst);
void incq(const Operand& dst);
@@ -604,6 +675,10 @@ class Assembler : public Malloced {
shift(dst, 0x4);
}
+ void shll(Register dst) {
+ shift_32(dst, 0x4);
+ }
+
void shr(Register dst, Immediate shift_amount) {
shift(dst, shift_amount, 0x5);
}
@@ -612,6 +687,10 @@ class Assembler : public Malloced {
shift(dst, 0x5);
}
+ void shrl(Register dst) {
+ shift_32(dst, 0x5);
+ }
+
void store_rax(void* dst, RelocInfo::Mode mode);
void store_rax(ExternalReference ref);
@@ -635,6 +714,10 @@ class Assembler : public Malloced {
immediate_arithmetic_op(0x5, dst, src);
}
+ void subl(Register dst, Register src) {
+ arithmetic_op_32(0x2B, dst, src);
+ }
+
void subl(const Operand& dst, Immediate src) {
immediate_arithmetic_op_32(0x5, dst, src);
}
@@ -770,19 +853,37 @@ class Assembler : public Malloced {
void fwait();
void fnclex();
+ void fsin();
+ void fcos();
+
void frndint();
+ void sahf();
+
// SSE2 instructions
+ void movsd(const Operand& dst, XMMRegister src);
+ void movsd(Register src, XMMRegister dst);
+ void movsd(XMMRegister dst, Register src);
+ void movsd(XMMRegister src, const Operand& dst);
+
void cvttss2si(Register dst, const Operand& src);
void cvttsd2si(Register dst, const Operand& src);
- void cvtsi2sd(XMMRegister dst, const Operand& src);
+ void cvtlsi2sd(XMMRegister dst, const Operand& src);
+ void cvtlsi2sd(XMMRegister dst, Register src);
+ void cvtqsi2sd(XMMRegister dst, const Operand& src);
+ void cvtqsi2sd(XMMRegister dst, Register 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 emit_sse_operand(XMMRegister dst, XMMRegister src);
+ void emit_sse_operand(XMMRegister reg, const Operand& adr);
+ void emit_sse_operand(XMMRegister dst, Register src);
+
// Use either movsd or movlpd.
// void movdbl(XMMRegister dst, const Operand& src);
// void movdbl(const Operand& dst, XMMRegister src);
@@ -812,11 +913,6 @@ class Assembler : public Malloced {
// Used for inline tables, e.g., jump-tables.
// void dd(uint64_t data, RelocInfo::Mode reloc_info);
- // Writes the absolute address of a bound label at the given position in
- // the generated code. That positions should have the relocation mode
- // internal_reference!
- void WriteInternalReference(int position, const Label& bound_label);
-
int pc_offset() const { return pc_ - buffer_; }
int current_statement_position() const { return current_statement_position_; }
int current_position() const { return current_position_; }
@@ -866,6 +962,7 @@ class Assembler : public Malloced {
// High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
// REX.W is set.
inline void emit_rex_64(Register reg, Register rm_reg);
+ inline void emit_rex_64(XMMRegister reg, Register 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.
@@ -873,6 +970,7 @@ class Assembler : public Malloced {
// register is used for REX.B, and the high bit of op's index register
// is used for REX.X. REX.W is set.
inline void emit_rex_64(Register reg, const Operand& op);
+ inline void emit_rex_64(XMMRegister reg, const Operand& op);
// Emits a REX prefix that encodes a 64-bit operand size and
// the top bit of the register code.
@@ -917,6 +1015,18 @@ class Assembler : public Malloced {
// is emitted.
inline void emit_optional_rex_32(Register reg, const Operand& op);
+ // As for emit_optional_rex_32(Register, Register), except that
+ // the registers are XMM registers.
+ inline void emit_optional_rex_32(XMMRegister reg, XMMRegister base);
+
+ // As for emit_optional_rex_32(Register, Register), except that
+ // the registers are XMM registers.
+ inline void emit_optional_rex_32(XMMRegister reg, Register base);
+
+ // As for emit_optional_rex_32(Register, const Operand&), except that
+ // the register is an XMM register.
+ inline void emit_optional_rex_32(XMMRegister reg, const Operand& op);
+
// Optionally do as emit_rex_32(Register) if the register number has
// the high bit set.
inline void emit_optional_rex_32(Register rm_reg);
@@ -931,7 +1041,7 @@ class Assembler : public Malloced {
// the second operand of the operation, a register or operation
// subcode, into the reg field of the ModR/M byte.
void emit_operand(Register reg, const Operand& adr) {
- emit_operand(reg.code() & 0x07, adr);
+ emit_operand(reg.low_bits(), adr);
}
// Emit the ModR/M byte, and optionally the SIB byte and
@@ -941,14 +1051,14 @@ class Assembler : public Malloced {
// Emit a ModR/M byte with registers coded in the reg and rm_reg fields.
void emit_modrm(Register reg, Register rm_reg) {
- emit(0xC0 | (reg.code() & 0x7) << 3 | (rm_reg.code() & 0x7));
+ emit(0xC0 | reg.low_bits() << 3 | rm_reg.low_bits());
}
// Emit a ModR/M byte with an operation subcode in the reg field and
// a register in the rm_reg field.
void emit_modrm(int code, Register rm_reg) {
- ASSERT((code & ~0x7) == 0);
- emit(0xC0 | (code & 0x7) << 3 | (rm_reg.code() & 0x7));
+ ASSERT(is_uint3(code));
+ emit(0xC0 | code << 3 | rm_reg.low_bits());
}
// Emit the code-object-relative offset of the label's position
@@ -959,23 +1069,31 @@ class Assembler : public Malloced {
// similar, differing just in the opcode or in the reg field of the
// ModR/M byte.
void arithmetic_op(byte opcode, Register dst, Register src);
+ void arithmetic_op_32(byte opcode, Register dst, Register src);
void arithmetic_op(byte opcode, Register reg, const Operand& op);
void immediate_arithmetic_op(byte subcode, Register dst, Immediate src);
void immediate_arithmetic_op(byte subcode, const Operand& dst, Immediate src);
- // Operate on a 32-bit word in memory.
+ // Operate on a 32-bit word in memory or register.
void immediate_arithmetic_op_32(byte subcode,
const Operand& dst,
Immediate src);
- // Operate on a byte in memory.
- void immediate_arithmetic_op_8(byte subcode,
- const Operand& dst,
+ void immediate_arithmetic_op_32(byte subcode,
+ Register dst,
Immediate src);
+ // Operate on a byte in memory or register.
+ void immediate_arithmetic_op_8(byte subcode,
+ const Operand& dst,
+ Immediate src);
+ void immediate_arithmetic_op_8(byte subcode,
+ Register dst,
+ Immediate src);
// Emit machine code for a shift operation.
void shift(Register dst, Immediate shift_amount, int subcode);
// Shift dst by cl % 64 bits.
void shift(Register dst, int subcode);
+ void shift_32(Register dst, int subcode);
- // void emit_farith(int b1, int b2, int i);
+ void emit_farith(int b1, int b2, int i);
// labels
// void print(Label* L);