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);
671 void Nop(
int bytes = 1);
682 void push(
const Immediate& x);
685 void push(
const Operand& src);
688 void pop(
const Operand& dst);
690 void enter(
const Immediate& size);
697 void mov_b(
const Operand& dst, int8_t imm8);
708 void mov(
const Operand& dst,
const Immediate& x);
726 cmov(cc, dst, Operand(src));
749 void add(
const Operand& dst,
const Immediate& x);
756 void and_(
const Operand& dst,
const Immediate& x);
759 void cmpb(
const Operand& op, int8_t imm8);
762 void cmpb_al(
const Operand& op);
763 void cmpw_ax(
const Operand& op);
764 void cmpw(
const Operand& op, Immediate imm16);
770 void cmp(
const Operand& op,
const Immediate& imm);
774 void dec_b(
const Operand& dst);
777 void dec(
const Operand& dst);
790 void inc(
const Operand& dst);
806 void or_(
const Operand& dst,
const Immediate& x);
829 void sub(
const Operand& dst,
const Immediate& x);
838 void test(
const Operand& op,
const Immediate& imm);
840 void test_b(
const Operand& op, uint8_t imm8);
847 void xor_(
const Operand& dst,
const Immediate& x);
880 void call(
byte* entry, RelocInfo::Mode rmode);
883 void call(
const Operand& adr);
886 RelocInfo::Mode rmode = RelocInfo::CODE_TARGET,
891 void jmp(Label*
L, Label::Distance distance = Label::kFar);
892 void jmp(
byte* entry, RelocInfo::Mode rmode);
894 void jmp(
const Operand& adr);
900 Label::Distance distance = Label::kFar);
913 void fld_s(
const Operand& adr);
914 void fld_d(
const Operand& adr);
916 void fstp_s(
const Operand& adr);
917 void fstp_d(
const Operand& adr);
918 void fst_d(
const Operand& adr);
920 void fild_s(
const Operand& adr);
921 void fild_d(
const Operand& adr);
923 void fist_s(
const Operand& adr);
925 void fistp_s(
const Operand& adr);
926 void fistp_d(
const Operand& adr);
947 void fisub_s(
const Operand& adr);
949 void faddp(
int i = 1);
950 void fsubp(
int i = 1);
952 void fmulp(
int i = 1);
953 void fdivp(
int i = 1);
957 void fxch(
int i = 1);
959 void ffree(
int i = 0);
1046 pextrd(Operand(dst), src, offset);
1050 pinsrd(dst, Operand(src), offset);
1060 void prefetch(
const Operand& src,
int level);
1084 void db(uint8_t data);
1085 void dd(uint32_t data);
1092 inline bool overflow()
const {
return pc_ >= reloc_info_writer.pos() - kGap; }
1102 return (buffer_ + buffer_size_) - reloc_info_writer.pos();
1126 uint32_t long_at(
int pos) {
1127 return *
reinterpret_cast<uint32_t*
>(
addr_at(pos));
1129 void long_at_put(
int pos, uint32_t x) {
1130 *
reinterpret_cast<uint32_t*
>(
addr_at(pos)) = x;
1135 inline void emit(uint32_t x);
1136 inline void emit(Handle<Object> handle);
1137 inline void emit(uint32_t x,
1138 RelocInfo::Mode rmode,
1140 inline void emit(
const Immediate& x);
1141 inline void emit_w(
const Immediate& x);
1144 inline void emit_code_relative_offset(Label* label);
1147 void emit_arith_b(
int op1,
int op2, Register dst,
int imm8);
1153 void emit_arith(
int sel, Operand dst,
const Immediate& x);
1155 void emit_operand(Register reg,
const Operand& adr);
1157 void emit_farith(
int b1,
int b2,
int i);
1160 void print(Label*
L);
1161 void bind_to(Label*
L,
int pos);
1164 inline Displacement disp_at(Label*
L);
1165 inline void disp_at_put(Label*
L, Displacement disp);
1166 inline void emit_disp(Label*
L, Displacement::Type
type);
1167 inline void emit_near_disp(Label*
L);
1170 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
1184 RelocInfoWriter reloc_info_writer;
1188 bool emit_debug_code_;
1201 if (assembler_->overflow()) assembler_->GrowBuffer();
1203 space_before_ = assembler_->available_space();
1209 int bytes_generated = space_before_ - assembler_->available_space();
1210 ASSERT(bytes_generated < assembler_->kGap);
1215 Assembler* assembler_;
1223 #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 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 or_(Register dst, const Immediate &imm)
void imul(Register dst, Register src)
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
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)
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)
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)
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 trace on stack replacement optimize closures functions with arguments object optimize functions containing for in loops profiler considers IC stability primitive functions trigger their own optimization re try self optimization if it failed insert an interrupt check at function exit execution budget before interrupt is triggered call count before self optimization self_optimization count_based_interrupts weighted_back_edges trace_opt 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 enable use of ARMv7 instructions if enable use of MIPS FPU instructions if NULL
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)
void cmp(Register reg0, Register reg1)
void extractps(Register dst, XMMRegister src, byte imm8)
static const byte kJnzShortOpcode
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)