Commit 2de98f8e authored by whesse@chromium.org's avatar whesse@chromium.org

Add statistics operations and long calls and jumps to x64 macro assembler.

Remove unimplemented instructions from x64 assembler.  Add operand-size
suffixes to add, sub, inc, dec, and cmp.
Review URL: http://codereview.chromium.org/118380

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2139 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 85720fc0
...@@ -451,6 +451,24 @@ void Assembler::immediate_arithmetic_op(byte subcode, ...@@ -451,6 +451,24 @@ void Assembler::immediate_arithmetic_op(byte subcode,
} }
void Assembler::immediate_arithmetic_op_32(byte subcode,
const Operand& dst,
Immediate src) {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
emit_optional_rex_32(dst);
if (is_int8(src.value_)) {
emit(0x83);
emit_operand(Register::toRegister(subcode), dst);
emit(src.value_);
} else {
emit(0x81);
emit_operand(Register::toRegister(subcode), dst);
emitl(src.value_);
}
}
void Assembler::shift(Register dst, Immediate shift_amount, int subcode) { void Assembler::shift(Register dst, Immediate shift_amount, int subcode) {
EnsureSpace ensure_space(this); EnsureSpace ensure_space(this);
last_pc_ = pc_; last_pc_ = pc_;
...@@ -530,15 +548,6 @@ void Assembler::call(Register adr) { ...@@ -530,15 +548,6 @@ void Assembler::call(Register adr) {
} }
void Assembler::cpuid() {
ASSERT(CpuFeatures::IsEnabled(CpuFeatures::CPUID));
EnsureSpace ensure_space(this);
last_pc_ = pc_;
emit(0x0F);
emit(0xA2);
}
void Assembler::call(const Operand& op) { void Assembler::call(const Operand& op) {
EnsureSpace ensure_space(this); EnsureSpace ensure_space(this);
last_pc_ = pc_; last_pc_ = pc_;
...@@ -549,6 +558,15 @@ void Assembler::call(const Operand& op) { ...@@ -549,6 +558,15 @@ void Assembler::call(const Operand& op) {
} }
void Assembler::cpuid() {
ASSERT(CpuFeatures::IsEnabled(CpuFeatures::CPUID));
EnsureSpace ensure_space(this);
last_pc_ = pc_;
emit(0x0F);
emit(0xA2);
}
void Assembler::cqo() { void Assembler::cqo() {
EnsureSpace ensure_space(this); EnsureSpace ensure_space(this);
last_pc_ = pc_; last_pc_ = pc_;
...@@ -557,7 +575,7 @@ void Assembler::cqo() { ...@@ -557,7 +575,7 @@ void Assembler::cqo() {
} }
void Assembler::dec(Register dst) { void Assembler::decq(Register dst) {
EnsureSpace ensure_space(this); EnsureSpace ensure_space(this);
last_pc_ = pc_; last_pc_ = pc_;
emit_rex_64(dst); emit_rex_64(dst);
...@@ -566,7 +584,7 @@ void Assembler::dec(Register dst) { ...@@ -566,7 +584,7 @@ void Assembler::dec(Register dst) {
} }
void Assembler::dec(const Operand& dst) { void Assembler::decq(const Operand& dst) {
EnsureSpace ensure_space(this); EnsureSpace ensure_space(this);
last_pc_ = pc_; last_pc_ = pc_;
emit_rex_64(dst); emit_rex_64(dst);
...@@ -575,6 +593,15 @@ void Assembler::dec(const Operand& dst) { ...@@ -575,6 +593,15 @@ void Assembler::dec(const Operand& dst) {
} }
void Assembler::decl(const Operand& dst) {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
emit_optional_rex_32(dst);
emit(0xFF);
emit_operand(1, dst);
}
void Assembler::enter(Immediate size) { void Assembler::enter(Immediate size) {
EnsureSpace ensure_space(this); EnsureSpace ensure_space(this);
last_pc_ = pc_; last_pc_ = pc_;
...@@ -626,7 +653,7 @@ void Assembler::imul(Register dst, Register src, Immediate imm) { ...@@ -626,7 +653,7 @@ void Assembler::imul(Register dst, Register src, Immediate imm) {
} }
void Assembler::inc(Register dst) { void Assembler::incq(Register dst) {
EnsureSpace ensure_space(this); EnsureSpace ensure_space(this);
last_pc_ = pc_; last_pc_ = pc_;
emit_rex_64(dst); emit_rex_64(dst);
...@@ -635,7 +662,7 @@ void Assembler::inc(Register dst) { ...@@ -635,7 +662,7 @@ void Assembler::inc(Register dst) {
} }
void Assembler::inc(const Operand& dst) { void Assembler::incq(const Operand& dst) {
EnsureSpace ensure_space(this); EnsureSpace ensure_space(this);
last_pc_ = pc_; last_pc_ = pc_;
emit_rex_64(dst); emit_rex_64(dst);
...@@ -644,6 +671,15 @@ void Assembler::inc(const Operand& dst) { ...@@ -644,6 +671,15 @@ void Assembler::inc(const Operand& dst) {
} }
void Assembler::incl(const Operand& dst) {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
emit_optional_rex_32(dst);
emit(0xFF);
emit_operand(0, dst);
}
void Assembler::int3() { void Assembler::int3() {
EnsureSpace ensure_space(this); EnsureSpace ensure_space(this);
last_pc_ = pc_; last_pc_ = pc_;
...@@ -812,6 +848,16 @@ void Assembler::movl(const Operand& dst, Register src) { ...@@ -812,6 +848,16 @@ void Assembler::movl(const Operand& dst, Register src) {
} }
void Assembler::movl(const Operand& dst, Immediate value) {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
emit_optional_rex_32(dst);
emit(0xC7);
emit_operand(0x0, dst);
emit(value); // Only 32-bit immediates are possible, not 8-bit immediates.
}
void Assembler::movl(Register dst, Immediate value) { void Assembler::movl(Register dst, Immediate value) {
EnsureSpace ensure_space(this); EnsureSpace ensure_space(this);
last_pc_ = pc_; last_pc_ = pc_;
...@@ -1132,6 +1178,13 @@ void Assembler::rcl(Register dst, uint8_t imm8) { ...@@ -1132,6 +1178,13 @@ void Assembler::rcl(Register dst, uint8_t imm8) {
} }
} }
void Assembler::rdtsc() {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
emit(0x0F);
emit(0x31);
}
void Assembler::ret(int imm16) { void Assembler::ret(int imm16) {
EnsureSpace ensure_space(this); EnsureSpace ensure_space(this);
...@@ -1147,6 +1200,19 @@ void Assembler::ret(int imm16) { ...@@ -1147,6 +1200,19 @@ void Assembler::ret(int imm16) {
} }
void Assembler::setcc(Condition cc, Register reg) {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
ASSERT(0 <= cc && cc < 16);
if (reg.code() > 3) { // Use x64 byte registers, where different.
emit_rex_32(reg);
}
emit(0x0F);
emit(0x90 | cc);
emit_modrm(0x0, reg);
}
void Assembler::shld(Register dst, Register src) { void Assembler::shld(Register dst, Register src) {
EnsureSpace ensure_space(this); EnsureSpace ensure_space(this);
last_pc_ = pc_; last_pc_ = pc_;
......
...@@ -385,7 +385,8 @@ class Assembler : public Malloced { ...@@ -385,7 +385,8 @@ class Assembler : public Malloced {
// //
// If we need versions of an assembly instruction that operate on different // If we need versions of an assembly instruction that operate on different
// width arguments, we add a single-letter suffix specifying the width. // width arguments, we add a single-letter suffix specifying the width.
// This is done for the following instructions: mov, cmp. // This is done for the following instructions: mov, cmp, inc, dec,
// add, sub, and test.
// There are no versions of these instructions without the suffix. // There are no versions of these instructions without the suffix.
// - Instructions on 8-bit (byte) operands/registers have a trailing 'b'. // - Instructions on 8-bit (byte) operands/registers have a trailing 'b'.
// - Instructions on 16-bit (word) operands/registers have a trailing 'w'. // - Instructions on 16-bit (word) operands/registers have a trailing 'w'.
...@@ -423,6 +424,7 @@ class Assembler : public Malloced { ...@@ -423,6 +424,7 @@ class Assembler : public Malloced {
void movl(Register dst, Register src); void movl(Register dst, Register src);
void movl(Register dst, const Operand& src); void movl(Register dst, const Operand& src);
void movl(const Operand& dst, Register src); void movl(const Operand& dst, Register src);
void movl(const Operand& dst, Immediate imm);
// Load a 32-bit immediate value, zero-extended to 64 bits. // Load a 32-bit immediate value, zero-extended to 64 bits.
void movl(Register dst, Immediate imm32); void movl(Register dst, Immediate imm32);
...@@ -449,61 +451,55 @@ class Assembler : public Malloced { ...@@ -449,61 +451,55 @@ class Assembler : public Malloced {
void load_rax(void* ptr, RelocInfo::Mode rmode); void load_rax(void* ptr, RelocInfo::Mode rmode);
void load_rax(ExternalReference ext); void load_rax(ExternalReference ext);
void movsx_b(Register dst, const Operand& src);
void movsx_w(Register dst, const Operand& src);
void movzx_b(Register dst, const Operand& src);
void movzx_w(Register dst, const Operand& src);
// Conditional moves // Conditional moves
void cmov(Condition cc, Register dst, int32_t imm32); // Implement conditional moves here.
void cmov(Condition cc, Register dst, Handle<Object> handle);
void cmov(Condition cc, Register dst, const Operand& src);
// Exchange two registers // Exchange two registers
void xchg(Register dst, Register src); void xchg(Register dst, Register src);
// Arithmetics // Arithmetics
void add(Register dst, Register src) { void addq(Register dst, Register src) {
arithmetic_op(0x03, dst, src); arithmetic_op(0x03, dst, src);
} }
void add(Register dst, const Operand& src) { void addq(Register dst, const Operand& src) {
arithmetic_op(0x03, dst, src); arithmetic_op(0x03, dst, src);
} }
void add(const Operand& dst, Register src) { void addq(const Operand& dst, Register src) {
arithmetic_op(0x01, src, dst); arithmetic_op(0x01, src, dst);
} }
void add(Register dst, Immediate src) { void addq(Register dst, Immediate src) {
immediate_arithmetic_op(0x0, dst, src); immediate_arithmetic_op(0x0, dst, src);
} }
void add(const Operand& dst, Immediate src) { void addq(const Operand& dst, Immediate src) {
immediate_arithmetic_op(0x0, dst, src); immediate_arithmetic_op(0x0, dst, src);
} }
void cmp(Register dst, Register src) { void addl(const Operand& dst, Immediate src) {
immediate_arithmetic_op_32(0x0, dst, src);
}
void cmpq(Register dst, Register src) {
arithmetic_op(0x3B, dst, src); arithmetic_op(0x3B, dst, src);
} }
void cmp(Register dst, const Operand& src) { void cmpq(Register dst, const Operand& src) {
arithmetic_op(0x3B, dst, src); arithmetic_op(0x3B, dst, src);
} }
void cmp(const Operand& dst, Register src) { void cmpq(const Operand& dst, Register src) {
arithmetic_op(0x39, src, dst); arithmetic_op(0x39, src, dst);
} }
void cmp(Register dst, Immediate src) { void cmpq(Register dst, Immediate src) {
immediate_arithmetic_op(0x7, dst, src); immediate_arithmetic_op(0x7, dst, src);
} }
void cmp(const Operand& dst, Immediate src) { void cmpq(const Operand& dst, Immediate src) {
immediate_arithmetic_op(0x7, dst, src); immediate_arithmetic_op(0x7, dst, src);
} }
...@@ -527,15 +523,9 @@ class Assembler : public Malloced { ...@@ -527,15 +523,9 @@ class Assembler : public Malloced {
immediate_arithmetic_op(0x4, dst, src); immediate_arithmetic_op(0x4, dst, src);
} }
void cmpb(const Operand& op, int8_t imm8); void decq(Register dst);
void cmpb_al(const Operand& op); void decq(const Operand& dst);
void cmpw_ax(const Operand& op); void decl(const Operand& dst);
void cmpw(const Operand& op, Immediate imm16);
void dec_b(Register dst);
void dec(Register dst);
void dec(const Operand& dst);
// Sign-extends rax into rdx:rax. // Sign-extends rax into rdx:rax.
void cqo(); void cqo();
...@@ -548,8 +538,9 @@ class Assembler : public Malloced { ...@@ -548,8 +538,9 @@ class Assembler : public Malloced {
// Performs the operation dst = src * imm. // Performs the operation dst = src * imm.
void imul(Register dst, Register src, Immediate imm); void imul(Register dst, Register src, Immediate imm);
void inc(Register dst); void incq(Register dst);
void inc(const Operand& dst); void incq(const Operand& dst);
void incl(const Operand& dst);
void lea(Register dst, const Operand& src); void lea(Register dst, const Operand& src);
...@@ -621,26 +612,30 @@ class Assembler : public Malloced { ...@@ -621,26 +612,30 @@ class Assembler : public Malloced {
void store_rax(void* dst, RelocInfo::Mode mode); void store_rax(void* dst, RelocInfo::Mode mode);
void store_rax(ExternalReference ref); void store_rax(ExternalReference ref);
void sub(Register dst, Register src) { void subq(Register dst, Register src) {
arithmetic_op(0x2B, dst, src); arithmetic_op(0x2B, dst, src);
} }
void sub(Register dst, const Operand& src) { void subq(Register dst, const Operand& src) {
arithmetic_op(0x2B, dst, src); arithmetic_op(0x2B, dst, src);
} }
void sub(const Operand& dst, Register src) { void subq(const Operand& dst, Register src) {
arithmetic_op(0x29, src, dst); arithmetic_op(0x29, src, dst);
} }
void sub(Register dst, Immediate src) { void subq(Register dst, Immediate src) {
immediate_arithmetic_op(0x5, dst, src); immediate_arithmetic_op(0x5, dst, src);
} }
void sub(const Operand& dst, Immediate src) { void subq(const Operand& dst, Immediate src) {
immediate_arithmetic_op(0x5, dst, src); immediate_arithmetic_op(0x5, dst, src);
} }
void subl(const Operand& dst, Immediate src) {
immediate_arithmetic_op_32(0x5, dst, src);
}
void testb(Register reg, Immediate mask); void testb(Register reg, Immediate mask);
void testb(const Operand& op, Immediate mask); void testb(const Operand& op, Immediate mask);
void testl(Register reg, Immediate mask); void testl(Register reg, Immediate mask);
...@@ -669,18 +664,19 @@ class Assembler : public Malloced { ...@@ -669,18 +664,19 @@ class Assembler : public Malloced {
immediate_arithmetic_op(0x6, dst, src); immediate_arithmetic_op(0x6, dst, src);
} }
// Bit operations. // Bit operations.
void bt(const Operand& dst, Register src); void bt(const Operand& dst, Register src);
void bts(const Operand& dst, Register src); void bts(const Operand& dst, Register src);
// Miscellaneous // Miscellaneous
void cpuid();
void hlt(); void hlt();
void int3(); void int3();
void nop(); void nop();
void nop(int n); void nop(int n);
void rdtsc(); void rdtsc();
void ret(int imm16); void ret(int imm16);
void setcc(Condition cc, Register reg);
// Label operations & relative jumps (PPUM Appendix D) // Label operations & relative jumps (PPUM Appendix D)
// //
...@@ -718,8 +714,6 @@ class Assembler : public Malloced { ...@@ -718,8 +714,6 @@ class Assembler : public Malloced {
// Conditional jumps // Conditional jumps
void j(Condition cc, Label* L); void j(Condition cc, Label* L);
void j(Condition cc, byte* entry, RelocInfo::Mode rmode);
void j(Condition cc, Handle<Code> code);
// Floating-point operations // Floating-point operations
void fld(int i); void fld(int i);
...@@ -775,11 +769,6 @@ class Assembler : public Malloced { ...@@ -775,11 +769,6 @@ class Assembler : public Malloced {
void frndint(); void frndint();
void sahf();
void setcc(Condition cc, Register reg);
void cpuid();
// SSE2 instructions // SSE2 instructions
void cvttss2si(Register dst, const Operand& src); void cvttss2si(Register dst, const Operand& src);
void cvttsd2si(Register dst, const Operand& src); void cvttsd2si(Register dst, const Operand& src);
...@@ -792,8 +781,8 @@ class Assembler : public Malloced { ...@@ -792,8 +781,8 @@ class Assembler : public Malloced {
void divsd(XMMRegister dst, XMMRegister src); void divsd(XMMRegister dst, XMMRegister src);
// Use either movsd or movlpd. // Use either movsd or movlpd.
void movdbl(XMMRegister dst, const Operand& src); // void movdbl(XMMRegister dst, const Operand& src);
void movdbl(const Operand& dst, XMMRegister src); // void movdbl(const Operand& dst, XMMRegister src);
// Debugging // Debugging
void Print(); void Print();
...@@ -814,11 +803,11 @@ class Assembler : public Malloced { ...@@ -814,11 +803,11 @@ class Assembler : public Malloced {
// Writes a doubleword of data in the code stream. // Writes a doubleword of data in the code stream.
// Used for inline tables, e.g., jump-tables. // Used for inline tables, e.g., jump-tables.
void dd(uint32_t data); // void dd(uint32_t data);
// Writes a quadword of data in the code stream. // Writes a quadword of data in the code stream.
// Used for inline tables, e.g., jump-tables. // Used for inline tables, e.g., jump-tables.
void dd(uint64_t data, RelocInfo::Mode reloc_info); // void dd(uint64_t data, RelocInfo::Mode reloc_info);
// Writes the absolute address of a bound label at the given position in // Writes the absolute address of a bound label at the given position in
// the generated code. That positions should have the relocation mode // the generated code. That positions should have the relocation mode
...@@ -842,11 +831,11 @@ class Assembler : public Malloced { ...@@ -842,11 +831,11 @@ class Assembler : public Malloced {
static const int kMinimalBufferSize = 4*KB; static const int kMinimalBufferSize = 4*KB;
protected: protected:
void movsd(XMMRegister dst, const Operand& src); // void movsd(XMMRegister dst, const Operand& src);
void movsd(const Operand& dst, XMMRegister src); // void movsd(const Operand& dst, XMMRegister src);
void emit_sse_operand(XMMRegister reg, const Operand& adr); // void emit_sse_operand(XMMRegister reg, const Operand& adr);
void emit_sse_operand(XMMRegister dst, XMMRegister src); // void emit_sse_operand(XMMRegister dst, XMMRegister src);
private: private:
...@@ -970,15 +959,18 @@ class Assembler : public Malloced { ...@@ -970,15 +959,18 @@ class Assembler : public Malloced {
void arithmetic_op(byte opcode, Register reg, const Operand& op); 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, Register dst, Immediate src);
void immediate_arithmetic_op(byte subcode, const Operand& dst, Immediate src); void immediate_arithmetic_op(byte subcode, const Operand& dst, Immediate src);
void immediate_arithmetic_op_32(byte subcode,
const Operand& dst,
Immediate src);
// Emit machine code for a shift operation. // Emit machine code for a shift operation.
void shift(Register dst, Immediate shift_amount, int subcode); void shift(Register dst, Immediate shift_amount, int subcode);
// Shift dst by cl % 64 bits. // Shift dst by cl % 64 bits.
void shift(Register dst, int subcode); void shift(Register dst, int subcode);
void emit_farith(int b1, int b2, int i); // void emit_farith(int b1, int b2, int i);
// labels // labels
void print(Label* L); // void print(Label* L);
void bind_to(Label* L, int pos); void bind_to(Label* L, int pos);
void link_to(Label* L, Label* appendix); void link_to(Label* L, Label* appendix);
......
...@@ -141,9 +141,9 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, ...@@ -141,9 +141,9 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
__ bind(&loop); __ bind(&loop);
__ movq(kScratchRegister, Operand(rbx, rcx, kTimesPointerSize, 0)); __ movq(kScratchRegister, Operand(rbx, rcx, kTimesPointerSize, 0));
__ push(Operand(kScratchRegister, 0)); // dereference handle __ push(Operand(kScratchRegister, 0)); // dereference handle
__ add(rcx, Immediate(1)); __ addq(rcx, Immediate(1));
__ bind(&entry); __ bind(&entry);
__ cmp(rcx, rax); __ cmpq(rcx, rax);
__ j(not_equal, &loop); __ j(not_equal, &loop);
// Invoke the code. // Invoke the code.
...@@ -177,5 +177,3 @@ void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) { ...@@ -177,5 +177,3 @@ void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) {
} }
} } // namespace v8::internal } } // namespace v8::internal
...@@ -259,7 +259,7 @@ void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) { ...@@ -259,7 +259,7 @@ void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
// The frame pointer is NULL in the exception handler of a JS entry frame. // The frame pointer is NULL in the exception handler of a JS entry frame.
__ xor_(rsi, rsi); // tentatively set context pointer to NULL __ xor_(rsi, rsi); // tentatively set context pointer to NULL
Label skip; Label skip;
__ cmp(rbp, Immediate(0)); __ cmpq(rbp, Immediate(0));
__ j(equal, &skip); __ j(equal, &skip);
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
__ bind(&skip); __ bind(&skip);
...@@ -294,7 +294,7 @@ void CEntryStub::GenerateCore(MacroAssembler* masm, ...@@ -294,7 +294,7 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
ExternalReference::heap_always_allocate_scope_depth(); ExternalReference::heap_always_allocate_scope_depth();
if (always_allocate_scope) { if (always_allocate_scope) {
__ movq(kScratchRegister, scope_depth); __ movq(kScratchRegister, scope_depth);
__ inc(Operand(kScratchRegister, 0)); __ incl(Operand(kScratchRegister, 0));
} }
// Call C function. // Call C function.
...@@ -311,7 +311,7 @@ void CEntryStub::GenerateCore(MacroAssembler* masm, ...@@ -311,7 +311,7 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
if (always_allocate_scope) { if (always_allocate_scope) {
__ movq(kScratchRegister, scope_depth); __ movq(kScratchRegister, scope_depth);
__ dec(Operand(kScratchRegister, 0)); __ decl(Operand(kScratchRegister, 0));
} }
// Check for failure result. // Check for failure result.
...@@ -338,7 +338,7 @@ void CEntryStub::GenerateCore(MacroAssembler* masm, ...@@ -338,7 +338,7 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
Label continue_exception; Label continue_exception;
// If the returned failure is EXCEPTION then promote Top::pending_exception(). // If the returned failure is EXCEPTION then promote Top::pending_exception().
__ movq(kScratchRegister, Failure::Exception(), RelocInfo::NONE); __ movq(kScratchRegister, Failure::Exception(), RelocInfo::NONE);
__ cmp(rax, kScratchRegister); __ cmpq(rax, kScratchRegister);
__ j(not_equal, &continue_exception); __ j(not_equal, &continue_exception);
// Retrieve the pending exception and clear the variable. // Retrieve the pending exception and clear the variable.
...@@ -352,7 +352,7 @@ void CEntryStub::GenerateCore(MacroAssembler* masm, ...@@ -352,7 +352,7 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
__ bind(&continue_exception); __ bind(&continue_exception);
// Special handling of out of memory exception. // Special handling of out of memory exception.
__ movq(kScratchRegister, Failure::OutOfMemoryException(), RelocInfo::NONE); __ movq(kScratchRegister, Failure::OutOfMemoryException(), RelocInfo::NONE);
__ cmp(rax, kScratchRegister); __ cmpq(rax, kScratchRegister);
__ j(equal, throw_out_of_memory_exception); __ j(equal, throw_out_of_memory_exception);
// Handle normal exception. // Handle normal exception.
...@@ -373,7 +373,7 @@ void CEntryStub::GenerateThrowOutOfMemory(MacroAssembler* masm) { ...@@ -373,7 +373,7 @@ void CEntryStub::GenerateThrowOutOfMemory(MacroAssembler* masm) {
Label loop, done; Label loop, done;
__ bind(&loop); __ bind(&loop);
// Load the type of the current stack handler. // Load the type of the current stack handler.
__ cmp(Operand(rdx, StackHandlerConstants::kStateOffset), __ cmpq(Operand(rdx, StackHandlerConstants::kStateOffset),
Immediate(StackHandler::ENTRY)); Immediate(StackHandler::ENTRY));
__ j(equal, &done); __ j(equal, &done);
// Fetch the next handler in the list. // Fetch the next handler in the list.
...@@ -549,7 +549,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { ...@@ -549,7 +549,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
__ movq(kScratchRegister, ExternalReference(Top::k_handler_address)); __ movq(kScratchRegister, ExternalReference(Top::k_handler_address));
__ pop(Operand(kScratchRegister, 0)); __ pop(Operand(kScratchRegister, 0));
// Pop next_sp. // Pop next_sp.
__ add(rsp, Immediate(StackHandlerConstants::kSize - kPointerSize)); __ addq(rsp, Immediate(StackHandlerConstants::kSize - kPointerSize));
// Restore the top frame descriptor from the stack. // Restore the top frame descriptor from the stack.
__ bind(&exit); __ bind(&exit);
...@@ -564,7 +564,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { ...@@ -564,7 +564,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
__ pop(r14); __ pop(r14);
__ pop(r13); __ pop(r13);
__ pop(r12); __ pop(r12);
__ add(rsp, Immediate(2 * kPointerSize)); // remove markers __ addq(rsp, Immediate(2 * kPointerSize)); // remove markers
// Restore frame pointer and return. // Restore frame pointer and return.
__ pop(rbp); __ pop(rbp);
......
...@@ -120,6 +120,30 @@ void MacroAssembler::Set(const Operand& dst, int64_t x) { ...@@ -120,6 +120,30 @@ void MacroAssembler::Set(const Operand& dst, int64_t x) {
} }
void MacroAssembler::Jump(ExternalReference ext) {
movq(kScratchRegister, ext);
jmp(kScratchRegister);
}
void MacroAssembler::Jump(Address destination, RelocInfo::Mode rmode) {
movq(kScratchRegister, destination, rmode);
jmp(kScratchRegister);
}
void MacroAssembler::Call(ExternalReference ext) {
movq(kScratchRegister, ext);
call(kScratchRegister);
}
void MacroAssembler::Call(Address destination, RelocInfo::Mode rmode) {
movq(kScratchRegister, destination, rmode);
call(kScratchRegister);
}
void MacroAssembler::PushTryHandler(CodeLocation try_location, void MacroAssembler::PushTryHandler(CodeLocation try_location,
HandlerType type) { HandlerType type) {
// Adjust this code if not the case. // Adjust this code if not the case.
...@@ -158,6 +182,47 @@ void MacroAssembler::PushTryHandler(CodeLocation try_location, ...@@ -158,6 +182,47 @@ void MacroAssembler::PushTryHandler(CodeLocation try_location,
} }
void MacroAssembler::Ret() {
ret(0);
}
void MacroAssembler::SetCounter(StatsCounter* counter, int value) {
if (FLAG_native_code_counters && counter->Enabled()) {
movq(kScratchRegister, ExternalReference(counter));
movl(Operand(kScratchRegister, 0), Immediate(value));
}
}
void MacroAssembler::IncrementCounter(StatsCounter* counter, int value) {
ASSERT(value > 0);
if (FLAG_native_code_counters && counter->Enabled()) {
movq(kScratchRegister, ExternalReference(counter));
Operand operand(kScratchRegister, 0);
if (value == 1) {
incl(operand);
} else {
addl(operand, Immediate(value));
}
}
}
void MacroAssembler::DecrementCounter(StatsCounter* counter, int value) {
ASSERT(value > 0);
if (FLAG_native_code_counters && counter->Enabled()) {
movq(kScratchRegister, ExternalReference(counter));
Operand operand(kScratchRegister, 0);
if (value == 1) {
decl(operand);
} else {
subl(operand, Immediate(value));
}
}
}
#ifdef ENABLE_DEBUGGER_SUPPORT #ifdef ENABLE_DEBUGGER_SUPPORT
void MacroAssembler::PushRegistersFromMemory(RegList regs) { void MacroAssembler::PushRegistersFromMemory(RegList regs) {
...@@ -265,7 +330,7 @@ void MacroAssembler::EnterFrame(StackFrame::Type type) { ...@@ -265,7 +330,7 @@ void MacroAssembler::EnterFrame(StackFrame::Type type) {
movq(kScratchRegister, movq(kScratchRegister,
Factory::undefined_value(), Factory::undefined_value(),
RelocInfo::EMBEDDED_OBJECT); RelocInfo::EMBEDDED_OBJECT);
cmp(Operand(rsp, 0), kScratchRegister); cmpq(Operand(rsp, 0), kScratchRegister);
Check(not_equal, "code object not properly patched"); Check(not_equal, "code object not properly patched");
} }
} }
...@@ -274,7 +339,7 @@ void MacroAssembler::EnterFrame(StackFrame::Type type) { ...@@ -274,7 +339,7 @@ void MacroAssembler::EnterFrame(StackFrame::Type type) {
void MacroAssembler::LeaveFrame(StackFrame::Type type) { void MacroAssembler::LeaveFrame(StackFrame::Type type) {
if (FLAG_debug_code) { if (FLAG_debug_code) {
movq(kScratchRegister, Immediate(Smi::FromInt(type))); movq(kScratchRegister, Immediate(Smi::FromInt(type)));
cmp(Operand(rbp, StandardFrameConstants::kMarkerOffset), kScratchRegister); cmpq(Operand(rbp, StandardFrameConstants::kMarkerOffset), kScratchRegister);
Check(equal, "stack frame types must match"); Check(equal, "stack frame types must match");
} }
movq(rsp, rbp); movq(rsp, rbp);
...@@ -328,7 +393,7 @@ void MacroAssembler::EnterExitFrame(StackFrame::Type type) { ...@@ -328,7 +393,7 @@ void MacroAssembler::EnterExitFrame(StackFrame::Type type) {
#endif #endif
// Reserve space for two arguments: argc and argv. // Reserve space for two arguments: argc and argv.
sub(rsp, Immediate(2 * kPointerSize)); subq(rsp, Immediate(2 * kPointerSize));
// Get the required frame alignment for the OS. // Get the required frame alignment for the OS.
static const int kFrameAlignment = OS::ActivationFrameAlignment(); static const int kFrameAlignment = OS::ActivationFrameAlignment();
......
...@@ -141,10 +141,19 @@ class MacroAssembler: public Assembler { ...@@ -141,10 +141,19 @@ class MacroAssembler: public Assembler {
// Store the code object for the given builtin in the target register. // Store the code object for the given builtin in the target register.
void GetBuiltinEntry(Register target, Builtins::JavaScript id); void GetBuiltinEntry(Register target, Builtins::JavaScript id);
// ---------------------------------------------------------------------------
// Macro instructions
// Expression support // Expression support
void Set(Register dst, int64_t x); void Set(Register dst, int64_t x);
void Set(const Operand& dst, int64_t x); void Set(const Operand& dst, int64_t x);
// Control Flow
void Jump(Address destination, RelocInfo::Mode rmode);
void Jump(ExternalReference ext);
void Call(Address destination, RelocInfo::Mode rmode);
void Call(ExternalReference ext);
// Compare object type for heap object. // Compare object type for heap object.
// Incoming register is heap_object and outgoing register is map. // Incoming register is heap_object and outgoing register is map.
void CmpObjectType(Register heap_object, InstanceType type, Register map); void CmpObjectType(Register heap_object, InstanceType type, Register map);
......
...@@ -132,7 +132,7 @@ TEST(AssemblerX64ArithmeticOperations) { ...@@ -132,7 +132,7 @@ TEST(AssemblerX64ArithmeticOperations) {
// Assemble a simple function that copies argument 2 and returns it. // Assemble a simple function that copies argument 2 and returns it.
__ movq(rax, rsi); __ movq(rax, rsi);
__ add(rax, rdi); __ addq(rax, rdi);
__ ret(0); __ ret(0);
CodeDesc desc; CodeDesc desc;
...@@ -215,12 +215,12 @@ TEST(AssemblerX64LoopImmediates) { ...@@ -215,12 +215,12 @@ TEST(AssemblerX64LoopImmediates) {
Label Loop1_body; Label Loop1_body;
__ jmp(&Loop1_test); __ jmp(&Loop1_test);
__ bind(&Loop1_body); __ bind(&Loop1_body);
__ add(rax, Immediate(7)); __ addq(rax, Immediate(7));
__ bind(&Loop1_test); __ bind(&Loop1_test);
__ cmp(rax, Immediate(20)); __ cmpq(rax, Immediate(20));
__ j(less_equal, &Loop1_body); __ j(less_equal, &Loop1_body);
// Did the loop terminate with the expected value? // Did the loop terminate with the expected value?
__ cmp(rax, Immediate(25)); __ cmpq(rax, Immediate(25));
__ j(not_equal, &Fail); __ j(not_equal, &Fail);
Label Loop2_test; Label Loop2_test;
...@@ -228,12 +228,12 @@ TEST(AssemblerX64LoopImmediates) { ...@@ -228,12 +228,12 @@ TEST(AssemblerX64LoopImmediates) {
__ movq(rax, Immediate(0x11FEED00)); __ movq(rax, Immediate(0x11FEED00));
__ jmp(&Loop2_test); __ jmp(&Loop2_test);
__ bind(&Loop2_body); __ bind(&Loop2_body);
__ add(rax, Immediate(-0x1100)); __ addq(rax, Immediate(-0x1100));
__ bind(&Loop2_test); __ bind(&Loop2_test);
__ cmp(rax, Immediate(0x11FE8000)); __ cmpq(rax, Immediate(0x11FE8000));
__ j(greater, &Loop2_body); __ j(greater, &Loop2_body);
// Did the loop terminate with the expected value? // Did the loop terminate with the expected value?
__ cmp(rax, Immediate(0x11FE7600)); __ cmpq(rax, Immediate(0x11FE7600));
__ j(not_equal, &Fail); __ j(not_equal, &Fail);
__ movq(rax, Immediate(1)); __ movq(rax, Immediate(1));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment