37 #ifndef V8_IA32_ASSEMBLER_IA32_H_
38 #define V8_IA32_ASSEMBLER_IA32_H_
124 const char*
const kNames[] = {
"eax",
"ecx",
"edx",
"ebx",
"esi",
"edi" };
125 return kNames[index];
131 return (reg.code() >= 6) ? reg.code() - 2 : reg.code();
147 return reg.
code() - 1;
157 const char*
const names[] = {
268 inline explicit Immediate(
int x);
269 inline explicit Immediate(
const ExternalReference& ext);
270 inline explicit Immediate(Handle<Object> handle);
271 inline explicit Immediate(Smi* value);
272 inline explicit Immediate(
Address addr);
275 return Immediate(label);
287 inline explicit Immediate(Label* value);
290 RelocInfo::Mode rmode_;
315 INLINE(
explicit Operand(XMMRegister xmm_reg));
318 INLINE(
explicit Operand(
int32_t disp, RelocInfo::Mode rmode));
322 explicit Operand(Register base,
int32_t disp,
326 explicit Operand(Register base,
333 explicit Operand(Register index,
339 return Operand(reinterpret_cast<int32_t>(ext.address()),
340 RelocInfo::EXTERNAL_REFERENCE);
345 const ExternalReference& arr) {
346 return Operand(index, scale, reinterpret_cast<int32_t>(arr.address()),
347 RelocInfo::EXTERNAL_REFERENCE);
351 return Operand(reinterpret_cast<int32_t>(cell.
location()),
352 RelocInfo::GLOBAL_PROPERTY_CELL);
359 bool is_reg_only()
const;
371 inline void set_modrm(
int mod,
Register rm);
374 inline void set_disp8(int8_t disp);
375 inline void set_dispr(
int32_t disp, RelocInfo::Mode rmode);
381 RelocInfo::Mode rmode_;
385 friend class LCodeGen;
416 int data()
const {
return data_; }
417 Type type()
const {
return TypeField::decode(data_); }
419 int n = NextField::decode(data_);
420 n > 0 ? L->link_to(n) : L->Unuse();
429 PrintF(
"%s (%x) ", (type() == UNCONDITIONAL_JUMP ?
"jmp" :
"[other]"),
430 NextField::decode(data_));
436 class TypeField:
public BitField<Type, 0, 2> {};
437 class NextField:
public BitField<int, 2, 32-2> {};
439 void init(Label*
L, Type type);
453 class CpuFeatures :
public AllStatic {
462 if (f ==
SSE2 && !FLAG_enable_sse2)
return false;
463 if (f ==
SSE3 && !FLAG_enable_sse3)
return false;
464 if (f ==
SSE4_1 && !FLAG_enable_sse4_1)
return false;
465 if (f ==
CMOV && !FLAG_enable_cmov)
return false;
466 if (f ==
RDTSC && !FLAG_enable_rdtsc)
return false;
467 return (supported_ & (static_cast<uint64_t>(1) << f)) != 0;
474 Isolate* isolate = Isolate::UncheckedCurrent();
475 if (isolate ==
NULL) {
480 uint64_t enabled = isolate->enabled_cpu_features();
481 return (enabled & (static_cast<uint64_t>(1) << f)) != 0;
491 uint64_t mask =
static_cast<uint64_t
>(1) << f;
494 (CpuFeatures::found_by_runtime_probing_ & mask) == 0);
495 isolate_ = Isolate::UncheckedCurrent();
497 if (isolate_ !=
NULL) {
498 old_enabled_ = isolate_->enabled_cpu_features();
499 isolate_->set_enabled_cpu_features(old_enabled_ | mask);
503 ASSERT_EQ(Isolate::UncheckedCurrent(), isolate_);
504 if (isolate_ !=
NULL) {
505 isolate_->set_enabled_cpu_features(old_enabled_);
511 uint64_t old_enabled_;
524 CpuFeatures::supported_ |= (
static_cast<uint64_t
>(1) << f);
530 CpuFeatures::supported_ = old_supported_;
535 static bool CanForce() {
542 const uint64_t old_supported_;
547 static bool initialized_;
549 static uint64_t supported_;
550 static uint64_t found_by_runtime_probing_;
552 DISALLOW_COPY_AND_ASSIGN(CpuFeatures);
556 class Assembler :
public AssemblerBase {
567 static const int kGap = 32;
584 Assembler(Isolate* isolate,
void* buffer,
int buffer_size);
681 void Nop(
int bytes = 1);
692 void push(
const Immediate& x);
695 void push(
const Operand& src);
698 void pop(
const Operand& dst);
700 void enter(
const Immediate& size);
707 void mov_b(
const Operand& dst, int8_t imm8);
718 void mov(
const Operand& dst,
const Immediate& x);
736 cmov(cc, dst, Operand(src));
759 void add(
const Operand& dst,
const Immediate& x);
766 void and_(
const Operand& dst,
const Immediate& x);
769 void cmpb(
const Operand& op, int8_t imm8);
772 void cmpb_al(
const Operand& op);
773 void cmpw_ax(
const Operand& op);
774 void cmpw(
const Operand& op, Immediate imm16);
780 void cmp(
const Operand& op,
const Immediate& imm);
784 void dec_b(
const Operand& dst);
787 void dec(
const Operand& dst);
800 void inc(
const Operand& dst);
816 void or_(
const Operand& dst,
const Immediate& x);
839 void sub(
const Operand& dst,
const Immediate& x);
848 void test(
const Operand& op,
const Immediate& imm);
850 void test_b(
const Operand& op, uint8_t imm8);
857 void xor_(
const Operand& dst,
const Immediate& x);
890 void call(
byte* entry, RelocInfo::Mode rmode);
893 void call(
const Operand& adr);
896 RelocInfo::Mode rmode,
901 void jmp(Label*
L, Label::Distance distance = Label::kFar);
902 void jmp(
byte* entry, RelocInfo::Mode rmode);
904 void jmp(
const Operand& adr);
910 Label::Distance distance = Label::kFar);
923 void fld_s(
const Operand& adr);
924 void fld_d(
const Operand& adr);
926 void fstp_s(
const Operand& adr);
927 void fstp_d(
const Operand& adr);
928 void fst_d(
const Operand& adr);
930 void fild_s(
const Operand& adr);
931 void fild_d(
const Operand& adr);
933 void fist_s(
const Operand& adr);
935 void fistp_s(
const Operand& adr);
936 void fistp_d(
const Operand& adr);
957 void fisub_s(
const Operand& adr);
959 void faddp(
int i = 1);
960 void fsubp(
int i = 1);
962 void fmulp(
int i = 1);
963 void fdivp(
int i = 1);
967 void fxch(
int i = 1);
969 void ffree(
int i = 0);
1059 pextrd(Operand(dst), src, offset);
1063 pinsrd(dst, Operand(src), offset);
1073 void prefetch(
const Operand& src,
int level);
1097 void db(uint8_t data);
1098 void dd(uint32_t data);
1105 inline bool overflow()
const {
return pc_ >= reloc_info_writer.pos() - kGap; }
1115 return (buffer_ + buffer_size_) - reloc_info_writer.pos();
1140 uint32_t long_at(
int pos) {
1141 return *
reinterpret_cast<uint32_t*
>(
addr_at(pos));
1143 void long_at_put(
int pos, uint32_t x) {
1144 *
reinterpret_cast<uint32_t*
>(
addr_at(pos)) = x;
1149 inline void emit(uint32_t x);
1150 inline void emit(Handle<Object> handle);
1151 inline void emit(uint32_t x,
1152 RelocInfo::Mode rmode,
1154 inline void emit(
const Immediate& x);
1155 inline void emit_w(
const Immediate& x);
1158 inline void emit_code_relative_offset(Label* label);
1161 void emit_arith_b(
int op1,
int op2, Register dst,
int imm8);
1167 void emit_arith(
int sel, Operand dst,
const Immediate& x);
1169 void emit_operand(Register reg,
const Operand& adr);
1171 void emit_farith(
int b1,
int b2,
int i);
1174 void print(Label*
L);
1175 void bind_to(Label*
L,
int pos);
1178 inline Displacement disp_at(Label*
L);
1179 inline void disp_at_put(Label*
L, Displacement disp);
1180 inline void emit_disp(Label*
L, Displacement::Type type);
1181 inline void emit_near_disp(Label*
L);
1184 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
1198 RelocInfoWriter reloc_info_writer;
1202 bool emit_debug_code_;
1203 bool predictable_code_size_;
1216 if (assembler_->overflow()) assembler_->GrowBuffer();
1218 space_before_ = assembler_->available_space();
1224 int bytes_generated = space_before_ - assembler_->available_space();
1225 ASSERT(bytes_generated < assembler_->kGap);
1230 Assembler* assembler_;
1238 #endif // V8_IA32_ASSEMBLER_IA32_H_
void cmp(Register src1, const Operand &src2, Condition cond=al)
void psllq(XMMRegister reg, int8_t shift)
static const int kMaximalBufferSize
const int kRegister_ebp_Code
void test(Register reg0, Register reg1)
static Operand Cell(Handle< JSGlobalPropertyCell > cell)
void fst_d(const Operand &adr)
static const byte kJccShortPrefix
void ucomisd(XMMRegister dst, XMMRegister src)
static Immediate CodeRelativeOffset(Label *label)
void pcmpeqd(XMMRegister dst, XMMRegister src)
void cmpb(Register reg, int8_t imm8)
void cvttss2si(Register dst, const Operand &src)
void PrintF(const char *format,...)
TryForceFeatureScope(CpuFeature f)
void or_(Register dst, Register src)
void roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode)
void por(XMMRegister dst, XMMRegister src)
void add(Register dst, const Immediate &imm)
void mulsd(XMMRegister dst, XMMRegister src)
bool is_byte_register() const
void cvtsd2si(Register dst, XMMRegister src)
static TypeFeedbackId None()
void or_(Register dst, const Immediate &imm)
void imul(Register dst, Register src)
void orpd(XMMRegister dst, XMMRegister src)
static const int kPatchDebugBreakSlotReturnOffset
static Operand StaticVariable(const ExternalReference &ext)
int SizeOfCodeGeneratedSince(Label *label)
void movdbl(XMMRegister dst, const Operand &src)
void or_(Register dst, int32_t imm32)
void push(Register src, Condition cond=al)
void movntdq(const Operand &dst, XMMRegister src)
void cvtsi2sd(XMMRegister dst, Register src)
void cvtss2sd(XMMRegister dst, XMMRegister src)
void sqrtsd(XMMRegister dst, XMMRegister src)
static XMMRegister FromAllocationIndex(int index)
static bool IsSupported(CpuFeature f)
const int kRegister_ebx_Code
static Operand StaticArray(Register index, ScaleFactor scale, const ExternalReference &arr)
void sbb(Register dst, const Operand &src)
void andpd(XMMRegister dst, XMMRegister src)
static const int kCallInstructionLength
bool predictable_code_size() const
void j(Condition cc, Label *L, Label::Distance distance=Label::kFar)
void sub(Register dst, Register src)
static const int kMinimalBufferSize
#define ASSERT(condition)
void ptest(XMMRegister dst, XMMRegister src)
static const int kPatchReturnSequenceAddressOffset
static const byte kJmpShortOpcode
void test_b(Register reg, uint8_t imm8)
void set_predictable_code_size(bool value)
static const char * AllocationIndexToString(int index)
void xorpd(XMMRegister dst, XMMRegister src)
StringInputBuffer *const buffer_
void bt(const Operand &dst, Register src)
void sar(Register dst, uint8_t imm8)
static const byte kTestAlByte
const int kRegister_esp_Code
void fistp_s(const Operand &adr)
void movsx_b(Register dst, Register src)
void pxor(XMMRegister dst, XMMRegister src)
void addsd(XMMRegister dst, XMMRegister src)
void movzx_b(Register dst, Register src)
void shr_cl(Register dst)
void fld_d(const Operand &adr)
static const int kNumRegisters
void cmpb_al(const Operand &op)
void xchg(Register dst, Register src)
void fild_s(const Operand &adr)
EnsureSpace(Assembler *assembler)
void movntdqa(XMMRegister dst, const Operand &src)
void rcl(Register dst, uint8_t imm8)
void enter(const Immediate &size)
Condition ReverseCondition(Condition cond)
static const byte kJcShortOpcode
void movd(Register dst, XMMRegister src)
void shld(Register dst, Register src)
DwVfpRegister DoubleRegister
void fisttp_d(const Operand &adr)
void movss(XMMRegister dst, const Operand &src)
void set_byte_at(int pos, byte value)
void cvtsd2ss(XMMRegister dst, XMMRegister src)
void pinsrd(XMMRegister dst, Register src, int8_t offset)
void mov_b(Register dst, int8_t imm8)
static const int kSpecialTargetSize
void movsd(XMMRegister dst, XMMRegister src)
void GetCode(CodeDesc *desc)
void movdqa(XMMRegister dst, const Operand &src)
static const int kJSReturnSequenceLength
void movdqu(XMMRegister dst, const Operand &src)
static const byte kNopByte
int available_space() const
static void set_target_address_at(Address pc, Address target)
static const byte kJzShortOpcode
void movmskpd(Register dst, XMMRegister src)
void fisttp_s(const Operand &adr)
static void set_external_target_at(Address instruction_payload, Address target)
const int kRegister_edx_Code
static Register FromAllocationIndex(int index)
void xor_(Register dst, const Immediate &imm)
int relocation_writer_size()
void shl(Register dst, uint8_t imm8)
void cmpw_ax(const Operand &op)
static Register from_code(int code)
void set_emit_debug_code(bool value)
static int ToAllocationIndex(Register reg)
void emit_sse_operand(XMMRegister reg, const Operand &adr)
void rcr(Register dst, uint8_t imm8)
void xorps(XMMRegister dst, XMMRegister src)
static const int kCallTargetAddressOffset
void add(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)
static const int kDebugBreakSlotLength
void setcc(Condition cc, Register reg)
void fld_s(const Operand &adr)
static bool IsNop(Instr instr, int type=NON_MARKING_NOP)
void RecordDebugBreakSlot()
void pand(XMMRegister dst, XMMRegister src)
void mov_w(Register dst, const Operand &src)
void fstp_d(const Operand &adr)
static const int kNumAllocatableRegisters
const int kRegister_eax_Code
static int ToAllocationIndex(XMMRegister reg)
void push_imm32(int32_t imm32)
void fistp_d(const Operand &adr)
bool is(Register reg) const
static Address target_address_at(Address pc)
void pextrd(Register dst, XMMRegister src, int8_t offset)
static const byte kJncShortOpcode
void shrd(Register dst, Register src)
void movaps(XMMRegister dst, XMMRegister src)
void psrlq(XMMRegister reg, int8_t shift)
void RecordComment(const char *msg)
int CallSize(const Operand &adr)
void sub(Register dst, const Immediate &imm)
static void deserialization_set_special_target_at(Address instruction_payload, Address target)
INLINE(static HeapObject *EnsureDoubleAligned(Heap *heap, HeapObject *object, int size))
void mov_b(Register dst, Register src)
void fstp_s(const Operand &adr)
void divsd(XMMRegister dst, XMMRegister src)
void lea(Register dst, const Operand &src)
static Address target_address_from_return_address(Address pc)
void fild_d(const Operand &adr)
void xor_(Register dst, int32_t imm32)
friend class PositionsRecorder
void mov(Register dst, const Operand &src, SBit s=LeaveCC, Condition cond=al)
static const int kNumAllocatableRegisters
Displacement(Label *L, Type type)
Assembler(Isolate *isolate, void *buffer, int buffer_size)
void cmpltsd(XMMRegister dst, XMMRegister src)
Condition NegateCondition(Condition cond)
#define ASSERT_EQ(v1, v2)
void test(Register reg, const Immediate &imm)
void shr(Register dst, uint8_t imm8)
const int kRegister_ecx_Code
static XMMRegister from_code(int code)
void add(Register dst, Register src)
void sar_cl(Register dst)
void pshufd(XMMRegister dst, XMMRegister src, int8_t shuffle)
void movd(XMMRegister dst, Register src)
void cmov(Condition cc, Register dst, Register src)
PositionsRecorder * positions_recorder()
void movsx_w(Register dst, Register src)
static const char * AllocationIndexToString(int index)
void cmp(Register reg, const Immediate &imm)
void fisub_s(const Operand &adr)
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if NULL
void cmp(Register reg0, Register reg1)
void extractps(Register dst, XMMRegister src, byte imm8)
static const byte kJnzShortOpcode
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra code(assertions) for debugging") DEFINE_bool(code_comments
void and_(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)
void fist_s(const Operand &adr)
bool is(XMMRegister reg) const
const int kRegister_esi_Code
static const int kNumRegisters
void bts(Register dst, Register src)
const int kRegister_edi_Code
void prefetch(const Operand &src, int level)
static const int kPatchDebugBreakSlotAddressOffset
void movzx_w(Register dst, Register src)
void sub(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)
bool emit_debug_code() const
void subsd(XMMRegister dst, XMMRegister src)
void cmpw(const Operand &op, Immediate imm16)
const int kRegister_no_reg_Code
void xor_(Register dst, Register src)
void next(Label *L) const
void test_b(Register reg, const Operand &op)
void mul(Register dst, Register src1, Register src2, SBit s=LeaveCC, Condition cond=al)
void cvttsd2si(Register dst, const Operand &src)
void and_(Register dst, Register src)
void shl_cl(Register dst)
void adc(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)