39 #if defined(V8_TARGET_ARCH_IA32)
52 bool CpuFeatures::initialized_ =
false;
54 uint64_t CpuFeatures::supported_ = 0;
55 uint64_t CpuFeatures::found_by_runtime_probing_ = 0;
71 const int kBufferSize = 4 *
KB;
72 VirtualMemory* memory =
new VirtualMemory(kBufferSize);
73 if (!memory->IsReserved()) {
77 ASSERT(memory->size() >=
static_cast<size_t>(kBufferSize));
78 if (!memory->Commit(memory->address(), kBufferSize,
true)) {
83 Assembler assm(
NULL, memory->
address(), kBufferSize);
97 __ xor_(
eax, 0x200000);
115 supported_ = (1 <<
CPUID);
116 { Scope fscope(
CPUID);
137 typedef uint64_t (*
F0)();
138 F0 probe = FUNCTION_CAST<F0>(
reinterpret_cast<Address>(memory->address()));
139 supported_ = probe();
140 found_by_runtime_probing_ = supported_;
142 supported_ |= os_guarantees;
143 found_by_runtime_probing_ &= ~os_guarantees;
152 void Displacement::init(Label*
L, Type
type) {
155 if (L->is_linked()) {
161 data_ = NextField::encode(next) | TypeField::encode(type);
169 const int RelocInfo::kApplyMask =
171 1 << RelocInfo::JS_RETURN | 1 << RelocInfo::INTERNAL_REFERENCE |
172 1 << RelocInfo::DEBUG_BREAK_SLOT;
175 bool RelocInfo::IsCodedSpecially() {
180 return (1 << rmode_) & kApplyMask;
186 for (
int i = 0; i < instruction_count; i++) {
187 *(pc_ + i) = *(instructions + i);
197 void RelocInfo::PatchCodeWithCall(
Address target,
int guard_bytes) {
199 static const int kCallCodeSize = 5;
200 int code_size = kCallCodeSize + guard_bytes;
203 CodePatcher patcher(pc_, code_size);
207 Label check_codesize;
208 patcher.masm()->bind(&check_codesize);
216 patcher.masm()->SizeOfCodeGeneratedSince(&check_codesize));
220 for (
int i = 0; i < guard_bytes; i++) {
221 patcher.masm()->int3();
229 Operand::Operand(Register base,
int32_t disp, RelocInfo::Mode rmode) {
244 set_dispr(disp, rmode);
249 Operand::Operand(Register base,
253 RelocInfo::Mode rmode) {
259 set_sib(scale, index, base);
263 set_sib(scale, index, base);
268 set_sib(scale, index, base);
269 set_dispr(disp, rmode);
274 Operand::Operand(Register index,
277 RelocInfo::Mode rmode) {
281 set_sib(scale, index,
ebp);
282 set_dispr(disp, rmode);
286 bool Operand::is_reg(Register reg)
const {
287 return ((buf_[0] & 0xF8) == 0xC0)
288 && ((buf_[0] & 0x07) == reg.code());
292 bool Operand::is_reg_only()
const {
293 return (buf_[0] & 0xF8) == 0xC0;
297 Register Operand::reg()
const {
311 #ifdef GENERATED_CODE_COVERAGE
312 static void InitCoverageLog();
316 : AssemblerBase(arg_isolate),
317 positions_recorder_(this),
318 emit_debug_code_(FLAG_debug_code) {
319 if (buffer ==
NULL) {
321 if (buffer_size <= kMinimalBufferSize) {
322 buffer_size = kMinimalBufferSize;
324 if (isolate()->assembler_spare_buffer() !=
NULL) {
325 buffer = isolate()->assembler_spare_buffer();
326 isolate()->set_assembler_spare_buffer(
NULL);
329 if (buffer ==
NULL) {
330 buffer_ = NewArray<byte>(buffer_size);
334 buffer_size_ = buffer_size;
340 buffer_size_ = buffer_size;
349 memset(
buffer_, 0xCC, buffer_size);
356 reloc_info_writer.Reposition(
buffer_ + buffer_size, pc_);
358 #ifdef GENERATED_CODE_COVERAGE
368 isolate()->set_assembler_spare_buffer(buffer_);
379 ASSERT(pc_ <= reloc_info_writer.pos());
381 desc->buffer = buffer_;
382 desc->buffer_size = buffer_size_;
384 desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
393 Nop((m - (addr & mask)) & mask);
399 while (*a == 0x66) a++;
400 if (*a == 0x90)
return true;
401 if (a[0] == 0xf && a[1] == 0x1f)
return true;
412 for (; bytes > 0; bytes--) {
538 EMIT(0x50 | src.code());
545 emit_operand(
esi, src);
552 EMIT(0x58 | dst.code());
559 emit_operand(
eax, dst);
578 CHECK(dst.is_byte_register());
581 emit_operand(dst, src);
588 emit_operand(
eax, dst);
594 CHECK(src.is_byte_register());
597 emit_operand(src, dst);
605 emit_operand(dst, src);
613 emit_operand(src, dst);
619 EMIT(0xB8 | dst.code());
626 EMIT(0xB8 | dst.code());
633 EMIT(0xB8 | dst.code());
641 emit_operand(dst, src);
648 EMIT(0xC0 | src.code() << 3 | dst.code());
655 emit_operand(
eax, dst);
663 emit_operand(
eax, dst);
671 emit_operand(src, dst);
679 emit_operand(dst, src);
687 emit_operand(dst, src);
695 emit_operand(dst, src);
703 emit_operand(dst, src);
713 emit_operand(dst, src);
745 if (src.is(
eax) || dst.is(
eax)) {
746 EMIT(0x90 | (src.is(
eax) ? dst.code() : src.code()));
749 EMIT(0xC0 | src.code() << 3 | dst.code());
756 emit_arith(2, Operand(dst), Immediate(imm32));
763 emit_operand(dst, src);
770 emit_operand(dst, src);
777 emit_operand(src, dst);
784 emit_arith(0, dst, x);
789 and_(dst, Immediate(imm32));
795 emit_arith(4, Operand(dst), x);
802 emit_operand(dst, src);
808 emit_arith(4, dst, x);
815 emit_operand(src, dst);
821 if (op.is_reg(
eax)) {
825 emit_operand(
edi, op);
832 CHECK(reg.is_byte_register());
835 emit_operand(reg, op);
840 CHECK(reg.is_byte_register());
843 emit_operand(reg, op);
852 emit_operand(
edi, op);
859 emit_arith(7, Operand(reg), Immediate(imm32));
865 emit_arith(7, Operand(reg), Immediate(handle));
872 emit_operand(reg, op);
878 emit_arith(7, op, imm);
884 emit_arith(7, op, Immediate(handle));
891 emit_operand(
eax, op);
899 emit_operand(
eax, op);
904 CHECK(dst.is_byte_register());
907 EMIT(0xC8 | dst.code());
914 emit_operand(
ecx, dst);
920 EMIT(0x48 | dst.code());
927 emit_operand(
ecx, dst);
940 EMIT(0xF8 | src.code());
947 EMIT(0xE8 | reg.code());
955 emit_operand(dst, src);
963 EMIT(0xC0 | dst.code() << 3 | src.code());
967 EMIT(0xC0 | dst.code() << 3 | src.code());
975 EMIT(0x40 | dst.code());
982 emit_operand(
eax, dst);
989 emit_operand(dst, src);
996 EMIT(0xE0 | src.code());
1003 EMIT(0xD8 | dst.code());
1010 EMIT(0xD0 | dst.code());
1016 emit_arith(1, Operand(dst), Immediate(imm32));
1023 emit_operand(dst, src);
1029 emit_arith(1, dst, x);
1036 emit_operand(src, dst);
1045 EMIT(0xD0 | dst.code());
1048 EMIT(0xD0 | dst.code());
1059 EMIT(0xD8 | dst.code());
1062 EMIT(0xD8 | dst.code());
1073 EMIT(0xF8 | dst.code());
1076 EMIT(0xF8 | dst.code());
1085 EMIT(0xF8 | dst.code());
1092 emit_operand(dst, src);
1100 emit_operand(dst, src);
1109 EMIT(0xE0 | dst.code());
1112 EMIT(0xE0 | dst.code());
1121 EMIT(0xE0 | dst.code());
1129 emit_operand(dst, src);
1138 EMIT(0xE8 | dst.code());
1141 EMIT(0xE8 | dst.code());
1150 EMIT(0xE8 | dst.code());
1156 emit_arith(5, dst, x);
1163 emit_operand(dst, src);
1170 emit_operand(src, dst);
1180 reg.is_byte_register()) {
1181 uint8_t imm8 = imm.x_;
1186 emit_arith_b(0xF6, 0xC0, reg, imm8);
1195 EMIT(0xC0 | reg.code());
1205 emit_operand(reg, op);
1210 CHECK(reg.is_byte_register());
1213 emit_operand(reg, op);
1220 emit_operand(
eax, op);
1226 if (op.is_reg_only() && !op.reg().is_byte_register()) {
1227 test(op, Immediate(imm8));
1232 emit_operand(
eax, op);
1239 emit_arith(6, Operand(dst), Immediate(imm32));
1246 emit_operand(dst, src);
1253 emit_operand(src, dst);
1259 emit_arith(6, dst, x);
1267 emit_operand(src, dst);
1275 emit_operand(src, dst);
1313 EMIT((imm16 >> 8) & 0xFF);
1329 void Assembler::print(Label* L) {
1330 if (L->is_unused()) {
1331 PrintF(
"unused label\n");
1332 }
else if (L->is_bound()) {
1333 PrintF(
"bound label to %d\n", L->pos());
1334 }
else if (L->is_linked()) {
1337 while (l.is_linked()) {
1338 Displacement disp = disp_at(&l);
1339 PrintF(
"@ %d ", l.pos());
1345 PrintF(
"label in inconsistent state (pos = %d)\n", L->pos_);
1350 void Assembler::bind_to(Label* L,
int pos) {
1353 while (L->is_linked()) {
1354 Displacement disp = disp_at(L);
1355 int fixup_pos = L->pos();
1356 if (disp.type() == Displacement::CODE_RELATIVE) {
1360 if (disp.type() == Displacement::UNCONDITIONAL_JUMP) {
1364 int imm32 = pos - (fixup_pos +
sizeof(
int32_t));
1365 long_at_put(fixup_pos, imm32);
1369 while (L->is_near_linked()) {
1370 int fixup_pos = L->near_link_pos();
1371 int offset_to_next =
1372 static_cast<int>(*
reinterpret_cast<int8_t*
>(
addr_at(fixup_pos)));
1373 ASSERT(offset_to_next <= 0);
1375 int disp = pos - fixup_pos -
sizeof(int8_t);
1376 ASSERT(0 <= disp && disp <= 127);
1378 if (offset_to_next < 0) {
1379 L->link_to(fixup_pos + offset_to_next, Label::kNear);
1398 if (L->is_bound()) {
1399 const int long_size = 5;
1404 emit(offs - long_size);
1408 emit_disp(L, Displacement::OTHER);
1416 ASSERT(!RelocInfo::IsCodeTarget(rmode));
1418 emit(entry - (pc_ +
sizeof(
int32_t)), rmode);
1424 return 1 + adr.len_;
1432 emit_operand(
edx, adr);
1437 return 1 +
sizeof(uint32_t) ;
1442 RelocInfo::Mode rmode,
1446 ASSERT(RelocInfo::IsCodeTarget(rmode));
1448 emit(reinterpret_cast<intptr_t>(code.location()), rmode, ast_id);
1454 if (L->is_bound()) {
1455 const int short_size = 2;
1456 const int long_size = 5;
1459 if (
is_int8(offs - short_size)) {
1462 EMIT((offs - short_size) & 0xFF);
1466 emit(offs - long_size);
1468 }
else if (distance == Label::kNear) {
1474 emit_disp(L, Displacement::UNCONDITIONAL_JUMP);
1481 ASSERT(!RelocInfo::IsCodeTarget(rmode));
1483 emit(entry - (pc_ +
sizeof(
int32_t)), rmode);
1490 emit_operand(
esp, adr);
1496 ASSERT(RelocInfo::IsCodeTarget(rmode));
1498 emit(reinterpret_cast<intptr_t>(code.location()), rmode);
1504 ASSERT(0 <= cc && cc < 16);
1505 if (L->is_bound()) {
1506 const int short_size = 2;
1507 const int long_size = 6;
1510 if (
is_int8(offs - short_size)) {
1513 EMIT((offs - short_size) & 0xFF);
1518 emit(offs - long_size);
1520 }
else if (distance == Label::kNear) {
1529 emit_disp(L, Displacement::OTHER);
1536 ASSERT((0 <= cc) && (cc < 16));
1540 emit(entry - (pc_ +
sizeof(
int32_t)), rmode);
1549 emit(reinterpret_cast<intptr_t>(code.location()), RelocInfo::CODE_TARGET);
1557 emit_farith(0xD9, 0xC0, i);
1563 emit_farith(0xDD, 0xD8, i);
1598 emit_operand(
eax, adr);
1605 emit_operand(
eax, adr);
1612 emit_operand(
ebx, adr);
1619 emit_operand(
ebx, adr);
1626 emit_operand(
edx, adr);
1633 emit_operand(
eax, adr);
1640 emit_operand(
ebp, adr);
1647 emit_operand(
ebx, adr);
1655 emit_operand(
ecx, adr);
1663 emit_operand(
ecx, adr);
1670 emit_operand(
edx, adr);
1677 emit_operand(
edi, adr);
1746 emit_farith(0xDC, 0xC0, i);
1752 emit_farith(0xDC, 0xE8, i);
1759 emit_operand(
esp, adr);
1765 emit_farith(0xDC, 0xC8, i);
1771 emit_farith(0xDC, 0xF8, i);
1777 emit_farith(0xDE, 0xC0, i);
1783 emit_farith(0xDE, 0xE8, i);
1789 emit_farith(0xDE, 0xE0, i);
1795 emit_farith(0xDE, 0xC8, i);
1801 emit_farith(0xDE, 0xF8, i);
1821 emit_farith(0xD9, 0xC8, i);
1834 emit_farith(0xDD, 0xC0, i);
1847 emit_farith(0xDD, 0xE8, i);
1913 ASSERT(reg.is_byte_register());
1917 EMIT(0xC0 | reg.code());
1927 emit_operand(dst, src);
1937 emit_operand(dst, src);
2076 EMIT(static_cast<byte>(mode) | 0x8);
2175 XMMRegister code = { level };
2404 Register ireg = { reg.code() };
2405 emit_operand(ireg, adr);
2410 EMIT(0xC0 | dst.code() << 3 | src.code());
2415 EMIT(0xC0 | dst.code() << 3 | src.code());
2427 RecordRelocInfo(RelocInfo::JS_RETURN);
2434 RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT);
2439 if (FLAG_code_comments || force) {
2441 RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg));
2446 void Assembler::GrowBuffer() {
2448 if (!own_buffer_)
FATAL(
"external code buffer is too small");
2452 if (buffer_size_ < 4*
KB) {
2453 desc.buffer_size = 4*
KB;
2455 desc.buffer_size = 2*buffer_size_;
2460 (desc.buffer_size >
isolate()->heap()->MaxOldGenerationSize())) {
2465 desc.buffer = NewArray<byte>(desc.buffer_size);
2467 desc.reloc_size = (buffer_ + buffer_size_) - (reloc_info_writer.pos());
2472 memset(desc.buffer, 0xCC, desc.buffer_size);
2476 int pc_delta = desc.buffer - buffer_;
2477 int rc_delta = (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_);
2478 memmove(desc.buffer, buffer_, desc.instr_size);
2479 memmove(rc_delta + reloc_info_writer.pos(),
2480 reloc_info_writer.pos(), desc.reloc_size);
2483 if (
isolate()->assembler_spare_buffer() ==
NULL &&
2485 isolate()->set_assembler_spare_buffer(buffer_);
2489 buffer_ = desc.buffer;
2490 buffer_size_ = desc.buffer_size;
2492 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
2493 reloc_info_writer.last_pc() + pc_delta);
2496 for (RelocIterator it(desc); !it.done(); it.next()) {
2497 RelocInfo::Mode rmode = it.rinfo()->rmode();
2501 }
else if (rmode == RelocInfo::INTERNAL_REFERENCE) {
2513 void Assembler::emit_arith_b(
int op1,
int op2, Register dst,
int imm8) {
2516 ASSERT((op1 & 0x01) == 0);
2518 EMIT(op2 | dst.code());
2523 void Assembler::emit_arith(
int sel, Operand dst,
const Immediate& x) {
2524 ASSERT((0 <= sel) && (sel <= 7));
2525 Register ireg = { sel };
2528 emit_operand(ireg, dst);
2530 }
else if (dst.is_reg(
eax)) {
2531 EMIT((sel << 3) | 0x05);
2535 emit_operand(ireg, dst);
2541 void Assembler::emit_operand(Register reg,
const Operand& adr) {
2542 const unsigned length = adr.len_;
2546 pc_[0] = (adr.buf_[0] & ~0x38) | (reg.code() << 3);
2549 for (
unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i];
2555 RecordRelocInfo(adr.rmode_);
2561 void Assembler::emit_farith(
int b1,
int b2,
int i) {
2581 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
2584 if (rmode == RelocInfo::EXTERNAL_REFERENCE) {
2595 reloc_info_writer.Write(&rinfo);
2599 #ifdef GENERATED_CODE_COVERAGE
2600 static FILE* coverage_log =
NULL;
2603 static void InitCoverageLog() {
2604 char* file_name = getenv(
"V8_GENERATED_CODE_COVERAGE_LOG");
2605 if (file_name !=
NULL) {
2606 coverage_log = fopen(file_name,
"aw+");
2611 void LogGeneratedCodeCoverage(
const char* file_line) {
2612 const char* return_address = (&file_line)[-1];
2613 char* push_insn =
const_cast<char*
>(return_address - 12);
2614 push_insn[0] = 0xeb;
2616 if (coverage_log !=
NULL) {
2617 fprintf(coverage_log,
"%s\n", file_line);
2618 fflush(coverage_log);
2626 #endif // V8_TARGET_ARCH_IA32
void cmp(Register src1, const Operand &src2, Condition cond=al)
void psllq(XMMRegister reg, int8_t shift)
static const int kMaximalBufferSize
Isolate * isolate() const
void fst_d(const Operand &adr)
void ucomisd(XMMRegister dst, XMMRegister src)
void cmpb(Register reg, int8_t imm8)
void cvttss2si(Register dst, const Operand &src)
void PrintF(const char *format,...)
void roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode)
void por(XMMRegister dst, XMMRegister src)
void mulsd(XMMRegister dst, XMMRegister src)
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 bool IsSupported(CpuFeature f)
void sbb(Register dst, const Operand &src)
void andpd(XMMRegister dst, XMMRegister src)
void j(Condition cc, Label *L, Label::Distance distance=Label::kFar)
static const int kMinimalBufferSize
#define ASSERT(condition)
void ptest(XMMRegister dst, XMMRegister src)
#define ASSERT_GE(v1, v2)
void xorpd(XMMRegister dst, XMMRegister src)
StringInputBuffer *const buffer_
void bt(const Operand &dst, Register src)
void sar(Register dst, uint8_t imm8)
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)
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 instructions(ARM only)") DEFINE_bool(enable_armv7
void cmpb_al(const Operand &op)
void xchg(Register dst, Register src)
void fild_s(const Operand &adr)
void movntdqa(XMMRegister dst, const Operand &src)
void rcl(Register dst, uint8_t imm8)
void enter(const Immediate &size)
void shld(Register dst, Register src)
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 movsd(XMMRegister dst, XMMRegister src)
void GetCode(CodeDesc *desc)
void movdqa(XMMRegister dst, const Operand &src)
void movdqu(XMMRegister dst, const Operand &src)
static void TooLateToEnableNow()
void movmskpd(Register dst, XMMRegister src)
void fisttp_s(const Operand &adr)
void shl(Register dst, uint8_t imm8)
void cmpw_ax(const Operand &op)
static Register from_code(int code)
void emit_sse_operand(XMMRegister reg, const Operand &adr)
void rcr(Register dst, uint8_t imm8)
void xorps(XMMRegister dst, XMMRegister src)
void add(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)
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)
void push_imm32(int32_t imm32)
void fistp_d(const Operand &adr)
void pextrd(Register dst, XMMRegister src, int8_t offset)
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 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)
void mov(Register dst, const Operand &src, SBit s=LeaveCC, Condition cond=al)
static const int kHeaderSize
Assembler(Isolate *isolate, void *buffer, int buffer_size)
void cmpltsd(XMMRegister dst, XMMRegister src)
#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)
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)
void fisub_s(const Operand &adr)
void extractps(Register dst, XMMRegister src, byte imm8)
static uint64_t CpuFeaturesImpliedByPlatform()
#define RUNTIME_ENTRY(name, nargs, ressize)
static int Decode(FILE *f, byte *begin, byte *end)
static void FlushICache(void *start, size_t size)
void and_(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)
void fist_s(const Operand &adr)
void DeleteArray(T *array)
void bts(Register dst, Register src)
void prefetch(const Operand &src, int level)
void movzx_w(Register dst, Register src)
static void FatalProcessOutOfMemory(const char *location, bool take_snapshot=false)
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)
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 shl_cl(Register dst)
void adc(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)