39 #if defined(V8_TARGET_ARCH_ARM)
48 bool CpuFeatures::initialized_ =
false;
50 unsigned CpuFeatures::supported_ = 0;
51 unsigned CpuFeatures::found_by_runtime_probing_ = 0;
58 static unsigned CpuFeaturesImpliedByCompiler() {
60 #ifdef CAN_USE_ARMV7_INSTRUCTIONS
61 answer |= 1u <<
ARMv7;
62 #endif // CAN_USE_ARMV7_INSTRUCTIONS
63 #ifdef CAN_USE_VFP3_INSTRUCTIONS
65 #endif // CAN_USE_VFP3_INSTRUCTIONS
66 #ifdef CAN_USE_VFP2_INSTRUCTIONS
68 #endif // CAN_USE_VFP2_INSTRUCTIONS
74 #if defined(CAN_USE_ARMV7_INSTRUCTIONS) && defined(__VFP_FP__) \
75 && !defined(__SOFTFP__)
76 answer |= 1u <<
VFP3 | 1u << ARMv7 | 1u <<
VFP2;
77 #endif // defined(CAN_USE_ARMV7_INSTRUCTIONS) && defined(__VFP_FP__)
80 if (answer & (1u << ARMv7)) {
89 unsigned standard_features =
static_cast<unsigned>(
91 ASSERT(supported_ == 0 || supported_ == standard_features);
99 supported_ |= standard_features;
109 if (FLAG_enable_vfp3) {
110 supported_ |= 1u <<
VFP3 | 1u << ARMv7 | 1u <<
VFP2;
113 if (FLAG_enable_armv7) {
114 supported_ |= 1u <<
ARMv7;
117 if (FLAG_enable_sudiv) {
118 supported_ |= 1u <<
SUDIV;
121 if (FLAG_enable_movw_movt) {
130 found_by_runtime_probing_ |= 1u <<
VFP3 | 1u << ARMv7 | 1u <<
VFP2;
132 found_by_runtime_probing_ |= 1u <<
VFP2;
136 found_by_runtime_probing_ |= 1u <<
ARMv7;
140 found_by_runtime_probing_ |= 1u <<
SUDIV;
152 supported_ |= found_by_runtime_probing_;
163 const int RelocInfo::kApplyMask = 0;
166 bool RelocInfo::IsCodedSpecially() {
178 for (
int i = 0; i < instruction_count; i++) {
179 *(pc + i) = *(instr + i);
189 void RelocInfo::PatchCodeWithCall(
Address target,
int guard_bytes) {
199 Operand::Operand(Handle<Object> handle) {
204 if (obj->IsHeapObject()) {
205 imm32_ =
reinterpret_cast<intptr_t
>(handle.location());
206 rmode_ = RelocInfo::EMBEDDED_OBJECT;
209 imm32_ =
reinterpret_cast<intptr_t
>(obj);
215 Operand::Operand(Register rm,
ShiftOp shift_op,
int shift_imm) {
217 ASSERT(shift_op !=
ROR || shift_imm != 0);
220 shift_op_ = shift_op;
221 shift_imm_ = shift_imm & 31;
222 if (shift_op ==
RRX) {
231 Operand::Operand(Register rm,
ShiftOp shift_op, Register rs) {
235 shift_op_ = shift_op;
261 shift_op_ = shift_op;
262 shift_imm_ = shift_imm & 31;
322 static const int kMinimalBufferSize = 4*
KB;
326 : AssemblerBase(arg_isolate),
327 recorded_ast_id_(TypeFeedbackId::
None()),
328 positions_recorder_(this),
329 emit_debug_code_(FLAG_debug_code),
330 predictable_code_size_(
false) {
331 if (buffer ==
NULL) {
337 buffer =
isolate()->assembler_spare_buffer();
341 if (buffer ==
NULL) {
342 buffer_ = NewArray<byte>(buffer_size);
344 buffer_ =
static_cast<byte*
>(buffer);
346 buffer_size_ = buffer_size;
352 buffer_ =
static_cast<byte*
>(buffer);
353 buffer_size_ = buffer_size;
360 reloc_info_writer.Reposition(buffer_ + buffer_size, pc_);
361 num_pending_reloc_info_ = 0;
362 next_buffer_check_ = 0;
363 const_pool_blocked_nesting_ = 0;
364 no_const_pool_before_ = 0;
365 first_const_pool_use_ = -1;
372 ASSERT(const_pool_blocked_nesting_ == 0);
376 isolate()->set_assembler_spare_buffer(buffer_);
387 ASSERT(num_pending_reloc_info_ == 0);
390 desc->buffer = buffer_;
391 desc->buffer_size = buffer_size_;
393 desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
438 return positive ? offset : -offset;
445 if (!positive) offset = -offset;
448 instr = (instr & ~
B23) | (positive ?
B23 : 0);
461 bool positive = offset >= 0;
462 if (!positive) offset = -offset;
465 instr = (instr & ~B23) | (positive ? B23 : 0);
584 const int kEndOfChain = -4;
596 ((instr &
B24) != 0)) {
607 ASSERT(target_pos == kEndOfChain || target_pos >= 0);
623 int imm24 = imm26 >> 2;
629 void Assembler::print(Label*
L) {
630 if (L->is_unused()) {
632 }
else if (L->is_bound()) {
633 PrintF(
"bound label to %d\n", L->pos());
634 }
else if (L->is_linked()) {
637 while (l.is_linked()) {
651 if ((instr &
B24) != 0)
657 case eq: c =
"eq";
break;
658 case ne: c =
"ne";
break;
659 case hs: c =
"hs";
break;
660 case lo: c =
"lo";
break;
661 case mi: c =
"mi";
break;
662 case pl: c =
"pl";
break;
663 case vs: c =
"vs";
break;
664 case vc: c =
"vc";
break;
665 case hi: c =
"hi";
break;
666 case ls: c =
"ls";
break;
667 case ge: c =
"ge";
break;
668 case lt: c =
"lt";
break;
669 case gt: c =
"gt";
break;
670 case le: c =
"le";
break;
671 case al: c =
"";
break;
682 PrintF(
"label in inconsistent state (pos = %d)\n", L->pos_);
687 void Assembler::bind_to(Label* L,
int pos) {
689 while (L->is_linked()) {
690 int fixup_pos = L->pos();
698 if (pos > last_bound_pos_)
699 last_bound_pos_ = pos;
703 void Assembler::link_to(Label* L, Label* appendix) {
704 if (appendix->is_linked()) {
705 if (L->is_linked()) {
713 ASSERT(link == kEndOfChain);
730 void Assembler::next(Label* L) {
733 if (link == kEndOfChain) {
746 static bool fits_shifter(uint32_t imm32,
747 uint32_t* rotate_imm,
751 for (
int rot = 0; rot < 16; rot++) {
752 uint32_t imm8 = (imm32 << 2*rot) | (imm32 >> (32 - 2*rot));
753 if ((imm8 <= 0xff)) {
763 if (fits_shifter(~imm32, rotate_imm, immed_8,
NULL)) {
768 if (imm32 < 0x10000) {
770 *instr |= EncodeMovwImmediate(imm32);
771 *rotate_imm = *immed_8 = 0;
777 if (fits_shifter(-static_cast<int>(imm32), rotate_imm, immed_8,
NULL)) {
783 if (alu_insn ==
ADD ||
785 if (fits_shifter(-static_cast<int>(imm32), rotate_imm, immed_8,
NULL)) {
789 }
else if (alu_insn ==
AND ||
791 if (fits_shifter(~imm32, rotate_imm, immed_8,
NULL)) {
806 bool Operand::must_output_reloc_info(
const Assembler* assembler)
const {
807 if (rmode_ == RelocInfo::EXTERNAL_REFERENCE) {
813 if (assembler !=
NULL && assembler->predictable_code_size())
return true;
822 static bool use_movw_movt(
const Operand& x,
const Assembler* assembler) {
826 if (x.must_output_reloc_info(assembler)) {
833 bool Operand::is_single_instruction(
const Assembler* assembler,
835 if (rm_.is_valid())
return true;
836 uint32_t dummy1, dummy2;
837 if (must_output_reloc_info(assembler) ||
838 !fits_shifter(imm32_, &dummy1, &dummy2, &instr)) {
843 return !use_movw_movt(*
this, assembler);
859 void Assembler::move_32_bit_immediate(
Condition cond,
863 if (rd.code() != pc.code() && s ==
LeaveCC) {
864 if (use_movw_movt(x,
this)) {
865 if (x.must_output_reloc_info(
this)) {
866 RecordRelocInfo(x.rmode_, x.imm32_, DONT_USE_CONSTANT_POOL);
870 emit(cond | 0x30*
B20 | rd.code()*
B12 |
871 EncodeMovwImmediate(x.imm32_ & 0xffff));
872 movt(rd, static_cast<uint32_t>(x.imm32_) >> 16, cond);
877 RecordRelocInfo(x.rmode_, x.imm32_, USE_CONSTANT_POOL);
882 void Assembler::addrmod1(
Instr instr,
888 if (!x.rm_.is_valid()) {
892 if (x.must_output_reloc_info(
this) ||
893 !fits_shifter(x.imm32_, &rotate_imm, &immed_8, &instr)) {
901 move_32_bit_immediate(cond, rd,
LeaveCC, x);
905 RecordRelocInfo(x.rmode_, x.imm32_, USE_CONSTANT_POOL);
907 }
else if (x.must_output_reloc_info(
this)) {
909 move_32_bit_immediate(cond,
ip,
LeaveCC, x);
915 addrmod1(instr, rn, rd, Operand(
ip));
919 instr |=
I | rotate_imm*
B8 | immed_8;
920 }
else if (!x.rs_.is_valid()) {
922 instr |= x.shift_imm_*
B7 | x.shift_op_ | x.rm_.code();
925 ASSERT(!rn.is(pc) && !rd.is(pc) && !x.rm_.is(pc) && !x.rs_.is(pc));
926 instr |= x.rs_.code()*
B8 | x.shift_op_ |
B4 | x.rm_.code();
928 emit(instr | rn.code()*
B16 | rd.code()*
B12);
929 if (rn.is(pc) || x.rm_.is(pc)) {
936 void Assembler::addrmod2(
Instr instr, Register rd,
const MemOperand& x) {
939 if (!x.rm_.is_valid()) {
941 int offset_12 = x.offset_;
943 offset_12 = -offset_12;
949 ASSERT(!x.rn_.is(
ip) && ((instr &
L) == L || !rd.is(
ip)));
961 instr |=
B25 | x.shift_imm_*
B7 | x.shift_op_ | x.rm_.code();
963 ASSERT((am & (
P|
W)) ==
P || !x.rn_.is(pc));
964 emit(instr | am | x.rn_.code()*
B16 | rd.code()*
B12);
968 void Assembler::addrmod3(
Instr instr, Register rd,
const MemOperand& x) {
972 if (!x.rm_.is_valid()) {
974 int offset_8 = x.offset_;
976 offset_8 = -offset_8;
982 ASSERT(!x.rn_.is(
ip) && ((instr &
L) == L || !rd.is(
ip)));
988 instr |=
B | (offset_8 >> 4)*
B8 | (offset_8 & 0xf);
989 }
else if (x.shift_imm_ != 0) {
992 ASSERT(!x.rn_.is(
ip) && ((instr &
L) == L || !rd.is(
ip)));
993 mov(
ip, Operand(x.rm_, x.shift_op_, x.shift_imm_),
LeaveCC,
999 ASSERT((am & (
P|
W)) ==
P || !x.rm_.is(pc));
1000 instr |= x.rm_.code();
1002 ASSERT((am & (
P|
W)) ==
P || !x.rn_.is(pc));
1003 emit(instr | am | x.rn_.code()*
B16 | rd.code()*
B12);
1007 void Assembler::addrmod4(
Instr instr, Register rn,
RegList rl) {
1011 emit(instr | rn.code()*
B16 | rl);
1015 void Assembler::addrmod5(
Instr instr, CRegister crd,
const MemOperand& x) {
1019 ASSERT(x.rn_.is_valid() && !x.rm_.is_valid());
1021 int offset_8 = x.offset_;
1022 ASSERT((offset_8 & 3) == 0);
1025 offset_8 = -offset_8;
1029 ASSERT((am & (
P|
W)) ==
P || !x.rn_.is(pc));
1036 emit(instr | am | x.rn_.code()*
B16 | crd.code()*
B12 | offset_8);
1042 if (L->is_bound()) {
1043 target_pos = L->pos();
1045 if (L->is_linked()) {
1046 target_pos = L->pos();
1048 target_pos = kEndOfChain;
1062 if (L->is_bound()) {
1063 target_pos = L->pos();
1065 if (L->is_linked()) {
1066 target_pos = L->pos();
1068 target_pos = kEndOfChain;
1070 L->link_to(at_offset);
1078 ASSERT((branch_offset & 3) == 0);
1079 int imm24 = branch_offset >> 2;
1092 ASSERT((branch_offset & 3) == 0);
1093 int imm24 = branch_offset >> 2;
1101 ASSERT((branch_offset & 1) == 0);
1102 int h = ((branch_offset & 2) >> 1)*
B24;
1103 int imm24 = branch_offset >> 2;
1125 void Assembler::and_(Register dst, Register src1,
const Operand& src2,
1127 addrmod1(cond |
AND | s, src1, dst, src2);
1131 void Assembler::eor(Register dst, Register src1,
const Operand& src2,
1133 addrmod1(cond |
EOR | s, src1, dst, src2);
1137 void Assembler::sub(Register dst, Register src1,
const Operand& src2,
1139 addrmod1(cond |
SUB | s, src1, dst, src2);
1143 void Assembler::rsb(Register dst, Register src1,
const Operand& src2,
1145 addrmod1(cond |
RSB | s, src1, dst, src2);
1149 void Assembler::add(Register dst, Register src1,
const Operand& src2,
1151 addrmod1(cond |
ADD | s, src1, dst, src2);
1155 void Assembler::adc(Register dst, Register src1,
const Operand& src2,
1157 addrmod1(cond |
ADC | s, src1, dst, src2);
1161 void Assembler::sbc(Register dst, Register src1,
const Operand& src2,
1163 addrmod1(cond |
SBC | s, src1, dst, src2);
1167 void Assembler::rsc(Register dst, Register src1,
const Operand& src2,
1169 addrmod1(cond |
RSC | s, src1, dst, src2);
1174 addrmod1(cond |
TST |
S, src1,
r0, src2);
1179 addrmod1(cond |
TEQ |
S, src1,
r0, src2);
1184 addrmod1(cond |
CMP |
S, src1,
r0, src2);
1189 Register src,
int raw_immediate,
Condition cond) {
1191 emit(cond |
I |
CMP |
S | src.code() << 16 | raw_immediate);
1196 addrmod1(cond |
CMN |
S, src1,
r0, src2);
1200 void Assembler::orr(Register dst, Register src1,
const Operand& src2,
1202 addrmod1(cond |
ORR | s, src1, dst, src2);
1213 ASSERT(!(src.is_reg() && src.rm().is(dst) && s ==
LeaveCC && cond ==
al));
1214 addrmod1(cond |
MOV | s,
r0, dst, src);
1219 ASSERT(immediate < 0x10000);
1228 emit(cond | 0x34*
B20 | reg.code()*
B12 | EncodeMovwImmediate(immediate));
1232 void Assembler::bic(Register dst, Register src1,
const Operand& src2,
1234 addrmod1(cond |
BIC | s, src1, dst, src2);
1239 addrmod1(cond |
MVN | s,
r0, dst, src);
1244 void Assembler::mla(Register dst, Register src1, Register src2, Register srcA,
1246 ASSERT(!dst.is(pc) && !src1.is(pc) && !src2.is(pc) && !srcA.is(pc));
1247 emit(cond |
A | s | dst.code()*
B16 | srcA.code()*
B12 |
1248 src2.code()*
B8 |
B7 |
B4 | src1.code());
1252 void Assembler::mls(Register dst, Register src1, Register src2, Register srcA,
1254 ASSERT(!dst.is(pc) && !src1.is(pc) && !src2.is(pc) && !srcA.is(pc));
1255 emit(cond |
B22 |
B21 | dst.code()*
B16 | srcA.code()*
B12 |
1256 src2.code()*
B8 |
B7 |
B4 | src1.code());
1262 ASSERT(!dst.is(pc) && !src1.is(pc) && !src2.is(pc));
1264 src2.code()*
B8 |
B4 | src1.code());
1270 ASSERT(!dst.is(pc) && !src1.is(pc) && !src2.is(pc));
1272 emit(cond | s | dst.code()*
B16 | src2.code()*
B8 |
B7 |
B4 | src1.code());
1282 ASSERT(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc));
1284 emit(cond | B23 |
B22 |
A | s | dstH.code()*
B16 | dstL.code()*
B12 |
1285 src2.code()*
B8 |
B7 |
B4 | src1.code());
1295 ASSERT(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc));
1297 emit(cond | B23 |
B22 | s | dstH.code()*
B16 | dstL.code()*
B12 |
1298 src2.code()*
B8 |
B7 |
B4 | src1.code());
1308 ASSERT(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc));
1310 emit(cond | B23 |
A | s | dstH.code()*
B16 | dstL.code()*
B12 |
1311 src2.code()*
B8 |
B7 |
B4 | src1.code());
1321 ASSERT(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc));
1323 emit(cond | B23 | s | dstH.code()*
B16 | dstL.code()*
B12 |
1324 src2.code()*
B8 |
B7 |
B4 | src1.code());
1331 ASSERT(!dst.is(pc) && !src.is(pc));
1333 15*
B8 |
CLZ | src.code());
1346 ASSERT(!dst.is(pc) && !src.rm_.is(pc));
1347 ASSERT((satpos >= 0) && (satpos <= 31));
1348 ASSERT((src.shift_op_ ==
ASR) || (src.shift_op_ ==
LSL));
1352 if (src.shift_op_ ==
ASR) {
1356 emit(cond | 0x6*
B24 | 0xe*
B20 | satpos*
B16 | dst.code()*
B12 |
1357 src.shift_imm_*
B7 | sh*
B6 | 0x1*
B4 | src.rm_.code());
1374 ASSERT(!dst.is(pc) && !src.is(pc));
1375 ASSERT((lsb >= 0) && (lsb <= 31));
1376 ASSERT((width >= 1) && (width <= (32 - lsb)));
1377 emit(cond | 0xf*B23 |
B22 |
B21 | (width - 1)*
B16 | dst.code()*
B12 |
1378 lsb*
B7 |
B6 |
B4 | src.code());
1394 ASSERT(!dst.is(pc) && !src.is(pc));
1395 ASSERT((lsb >= 0) && (lsb <= 31));
1396 ASSERT((width >= 1) && (width <= (32 - lsb)));
1397 emit(cond | 0xf*B23 |
B21 | (width - 1)*
B16 | dst.code()*
B12 |
1398 lsb*
B7 |
B6 |
B4 | src.code());
1410 ASSERT((lsb >= 0) && (lsb <= 31));
1411 ASSERT((width >= 1) && (width <= (32 - lsb)));
1412 int msb = lsb + width - 1;
1413 emit(cond | 0x1f*
B22 | msb*
B16 | dst.code()*
B12 | lsb*
B7 |
B4 | 0xf);
1428 ASSERT(!dst.is(pc) && !src.is(pc));
1429 ASSERT((lsb >= 0) && (lsb <= 31));
1430 ASSERT((width >= 1) && (width <= (32 - lsb)));
1431 int msb = lsb + width - 1;
1432 emit(cond | 0x1f*
B22 | msb*
B16 | dst.code()*
B12 | lsb*
B7 |
B4 |
1440 emit(cond |
B24 | s | 15*
B16 | dst.code()*
B12);
1448 if (!src.rm_.is_valid()) {
1450 uint32_t rotate_imm;
1452 if (src.must_output_reloc_info(
this) ||
1453 !fits_shifter(src.imm32_, &rotate_imm, &immed_8,
NULL)) {
1455 RecordRelocInfo(src.rmode_, src.imm32_);
1457 msr(fields, Operand(
ip), cond);
1460 instr =
I | rotate_imm*
B8 | immed_8;
1462 ASSERT(!src.rs_.is_valid() && src.shift_imm_ == 0);
1463 instr = src.rm_.code();
1465 emit(cond | instr |
B24 |
B21 | fields | 15*
B12);
1474 addrmod2(cond |
B26 | L, dst, src);
1479 addrmod2(cond |
B26, src, dst);
1484 addrmod2(cond |
B26 |
B | L, dst, src);
1489 addrmod2(cond |
B26 |
B, src, dst);
1494 addrmod3(cond | L |
B7 |
H |
B4, dst, src);
1499 addrmod3(cond |
B7 |
H |
B4, src, dst);
1504 addrmod3(cond | L |
B7 |
S6 |
B4, dst, src);
1509 addrmod3(cond | L |
B7 |
S6 |
H |
B4, dst, src);
1515 ASSERT(CpuFeatures::IsEnabled(ARMv7));
1519 ASSERT_EQ(dst1.code() + 1, dst2.code());
1520 addrmod3(cond |
B7 |
B6 |
B4, dst1, src);
1529 ASSERT_EQ(src1.code() + 1, src2.code());
1530 ASSERT(CpuFeatures::IsEnabled(ARMv7));
1531 addrmod3(cond |
B7 |
B6 |
B5 |
B4, src1, dst);
1542 addrmod4(cond |
B27 | am | L, base, dst);
1545 if (cond ==
al && (dst & pc.bit()) != 0) {
1560 addrmod4(cond |
B27 | am, base, src);
1579 emit(reinterpret_cast<Instr>(msg));
1581 #else // def __arm__
1582 #ifdef CAN_USE_ARMV5_INSTRUCTIONS
1591 #else // ndef CAN_USE_ARMV5_INSTRUCTIONS
1592 svc(0x9f0001, cond);
1593 #endif // ndef CAN_USE_ARMV5_INSTRUCTIONS
1594 #endif // def __arm__
1606 emit(cond | 15*
B24 | imm24);
1620 crd.code()*
B12 | coproc*
B8 | (opcode_2 & 7)*
B5 | crm.code());
1643 rd.code()*
B12 | coproc*
B8 | (opcode_2 & 7)*
B5 |
B4 | crm.code());
1665 emit(cond |
B27 |
B26 |
B25 | (opcode_1 & 7)*
B21 | L | crn.code()*
B16 |
1666 rd.code()*
B12 | coproc*
B8 | (opcode_2 & 7)*
B5 |
B4 | crm.code());
1685 addrmod5(cond |
B27 |
B26 | l | L | coproc*
B8, crd, src);
1697 emit(cond |
B27 |
B26 |
U | l | L | rn.code()*
B16 | crd.code()*
B12 |
1698 coproc*
B8 | (option & 255));
1722 const Register base,
1729 ASSERT(CpuFeatures::IsEnabled(VFP2));
1737 if ((offset % 4) == 0 && (offset / 4) < 256) {
1738 emit(cond | u*B23 | 0xD1*
B20 | base.code()*
B16 | dst.code()*
B12 |
1739 0xB*
B8 | ((offset / 4) & 255));
1745 add(
ip, base, Operand(offset));
1747 sub(
ip, base, Operand(offset));
1757 ASSERT(!operand.rm().is_valid());
1759 vldr(dst, operand.rn(), operand.offset(), cond);
1764 const Register base,
1771 ASSERT(CpuFeatures::IsEnabled(VFP2));
1778 dst.split_code(&sd, &d);
1781 if ((offset % 4) == 0 && (offset / 4) < 256) {
1782 emit(cond | u*B23 | d*
B22 | 0xD1*
B20 | base.code()*
B16 | sd*
B12 |
1783 0xA*
B8 | ((offset / 4) & 255));
1789 add(
ip, base, Operand(offset));
1791 sub(
ip, base, Operand(offset));
1801 ASSERT(!operand.rm().is_valid());
1803 vldr(dst, operand.rn(), operand.offset(), cond);
1808 const Register base,
1815 ASSERT(CpuFeatures::IsEnabled(VFP2));
1822 if ((offset % 4) == 0 && (offset / 4) < 256) {
1823 emit(cond | u*B23 | 0xD0*
B20 | base.code()*
B16 | src.code()*
B12 |
1824 0xB*
B8 | ((offset / 4) & 255));
1830 add(
ip, base, Operand(offset));
1832 sub(
ip, base, Operand(offset));
1842 ASSERT(!operand.rm().is_valid());
1844 vstr(src, operand.rn(), operand.offset(), cond);
1849 const Register base,
1856 ASSERT(CpuFeatures::IsEnabled(VFP2));
1863 src.split_code(&sd, &d);
1865 if ((offset % 4) == 0 && (offset / 4) < 256) {
1866 emit(cond | u*B23 | d*
B22 | 0xD0*
B20 | base.code()*
B16 | sd*
B12 |
1867 0xA*
B8 | ((offset / 4) & 255));
1873 add(
ip, base, Operand(offset));
1875 sub(
ip, base, Operand(offset));
1885 ASSERT(!operand.rm().is_valid());
1887 vstr(src, operand.rn(), operand.offset(), cond);
1893 DwVfpRegister first,
1899 ASSERT(CpuFeatures::IsEnabled(VFP2));
1905 first.split_code(&sd, &d);
1906 int count = last.code() - first.code() + 1;
1915 DwVfpRegister first,
1921 ASSERT(CpuFeatures::IsEnabled(VFP2));
1927 first.split_code(&sd, &d);
1928 int count = last.code() - first.code() + 1;
1936 SwVfpRegister first,
1942 ASSERT(CpuFeatures::IsEnabled(VFP2));
1948 first.split_code(&sd, &d);
1949 int count = last.code() - first.code() + 1;
1957 SwVfpRegister first,
1963 ASSERT(CpuFeatures::IsEnabled(VFP2));
1969 first.split_code(&sd, &d);
1970 int count = last.code() - first.code() + 1;
1975 static void DoubleAsTwoUInt32(
double d, uint32_t*
lo, uint32_t*
hi) {
1979 *lo = i & 0xffffffff;
1985 static bool FitsVMOVDoubleImmediate(
double d, uint32_t *encoding) {
2007 DoubleAsTwoUInt32(d, &lo, &hi);
2010 if ((lo != 0) || ((hi & 0xffff) != 0)) {
2015 if (((hi & 0x3fc00000) != 0) && ((hi & 0x3fc00000) != 0x3fc00000)) {
2020 if (((hi ^ (hi << 1)) & (0x40000000)) == 0) {
2026 *encoding = (hi >> 16) & 0xf;
2027 *encoding |= (hi >> 4) & 0x70000;
2028 *encoding |= (hi >> 12) & 0x80000;
2036 const Register scratch,
2040 ASSERT(CpuFeatures::IsEnabled(VFP2));
2045 emit(cond | 0xE*
B24 | 0xB*
B20 | dst.code()*
B12 | 0xB*
B8 | enc);
2051 mov(
ip, Operand(lo));
2053 if (scratch.is(
no_reg)) {
2056 vmov(dst.low(),
ip, cond);
2060 mov(
ip, Operand(hi));
2061 vmov(dst.high(),
ip, cond);
2065 mov(scratch, Operand(hi));
2066 vmov(dst,
ip, scratch, cond);
2073 const SwVfpRegister src,
2077 ASSERT(CpuFeatures::IsEnabled(VFP2));
2079 dst.split_code(&sd, &d);
2080 src.split_code(&sm, &m);
2086 const DwVfpRegister src,
2090 ASSERT(CpuFeatures::IsEnabled(VFP2));
2091 emit(cond | 0xE*
B24 | 0xB*
B20 |
2092 dst.code()*
B12 | 0x5*
B9 |
B8 |
B6 | src.code());
2097 const Register src1,
2098 const Register src2,
2104 ASSERT(CpuFeatures::IsEnabled(VFP2));
2105 ASSERT(!src1.is(pc) && !src2.is(pc));
2106 emit(cond | 0xC*
B24 |
B22 | src2.code()*
B16 |
2107 src1.code()*
B12 | 0xB*
B8 |
B4 | dst.code());
2112 const Register dst2,
2113 const DwVfpRegister src,
2119 ASSERT(CpuFeatures::IsEnabled(VFP2));
2120 ASSERT(!dst1.is(pc) && !dst2.is(pc));
2122 dst1.code()*
B12 | 0xB*
B8 |
B4 | src.code());
2133 ASSERT(CpuFeatures::IsEnabled(VFP2));
2136 dst.split_code(&sn, &n);
2142 const SwVfpRegister src,
2148 ASSERT(CpuFeatures::IsEnabled(VFP2));
2151 src.split_code(&sn, &n);
2158 enum VFPType { S32, U32, F32, F64 };
2161 static bool IsSignedVFPType(VFPType type) {
2174 static bool IsIntegerVFPType(VFPType type) {
2189 static bool IsDoubleVFPType(VFPType type) {
2206 static void SplitRegCode(VFPType reg_type,
2210 ASSERT((reg_code >= 0) && (reg_code <= 31));
2211 if (IsIntegerVFPType(reg_type) || !IsDoubleVFPType(reg_type)) {
2213 *m = reg_code & 0x1;
2214 *vm = reg_code >> 1;
2217 *m = (reg_code & 0x10) >> 4;
2218 *vm = reg_code & 0x0F;
2224 static Instr EncodeVCVT(
const VFPType dst_type,
2226 const VFPType src_type,
2230 ASSERT(src_type != dst_type);
2232 SplitRegCode(src_type, src_code, &Vm, &M);
2233 SplitRegCode(dst_type, dst_code, &Vd, &D);
2235 if (IsIntegerVFPType(dst_type) || IsIntegerVFPType(src_type)) {
2240 ASSERT(!IsIntegerVFPType(dst_type) || !IsIntegerVFPType(src_type));
2244 if (IsIntegerVFPType(dst_type)) {
2245 opc2 = IsSignedVFPType(dst_type) ? 0x5 : 0x4;
2246 sz = IsDoubleVFPType(src_type) ? 0x1 : 0x0;
2249 ASSERT(IsIntegerVFPType(src_type));
2251 sz = IsDoubleVFPType(dst_type) ? 0x1 : 0x0;
2252 op = IsSignedVFPType(src_type) ? 0x1 : 0x0;
2262 int sz = IsDoubleVFPType(src_type) ? 0x1 : 0x0;
2263 return (cond | 0xE*
B24 | B23 | D*
B22 | 0x3*
B20 | 0x7*
B16 |
2270 const SwVfpRegister src,
2273 ASSERT(CpuFeatures::IsEnabled(VFP2));
2274 emit(EncodeVCVT(F64, dst.code(), S32, src.code(), mode, cond));
2279 const SwVfpRegister src,
2282 ASSERT(CpuFeatures::IsEnabled(VFP2));
2283 emit(EncodeVCVT(F32, dst.code(), S32, src.code(), mode, cond));
2288 const SwVfpRegister src,
2291 ASSERT(CpuFeatures::IsEnabled(VFP2));
2292 emit(EncodeVCVT(F64, dst.code(), U32, src.code(), mode, cond));
2297 const DwVfpRegister src,
2300 ASSERT(CpuFeatures::IsEnabled(VFP2));
2301 emit(EncodeVCVT(S32, dst.code(), F64, src.code(), mode, cond));
2306 const DwVfpRegister src,
2309 ASSERT(CpuFeatures::IsEnabled(VFP2));
2310 emit(EncodeVCVT(U32, dst.code(), F64, src.code(), mode, cond));
2315 const SwVfpRegister src,
2318 ASSERT(CpuFeatures::IsEnabled(VFP2));
2319 emit(EncodeVCVT(F64, dst.code(), F32, src.code(), mode, cond));
2324 const DwVfpRegister src,
2327 ASSERT(CpuFeatures::IsEnabled(VFP2));
2328 emit(EncodeVCVT(F32, dst.code(), F64, src.code(), mode, cond));
2333 const DwVfpRegister src,
2335 ASSERT(CpuFeatures::IsEnabled(VFP2));
2337 0x5*
B9 |
B8 |
B6 | src.code());
2342 const DwVfpRegister src,
2344 ASSERT(CpuFeatures::IsEnabled(VFP2));
2345 emit(cond | 0xE*
B24 | 0xB*
B20 | dst.code()*
B12 |
2346 0x5*
B9 |
B8 | 0x3*
B6 | src.code());
2351 const DwVfpRegister src1,
2352 const DwVfpRegister src2,
2359 ASSERT(CpuFeatures::IsEnabled(VFP2));
2360 emit(cond | 0xE*
B24 | 0x3*
B20 | src1.code()*
B16 |
2361 dst.code()*
B12 | 0x5*
B9 |
B8 | src2.code());
2366 const DwVfpRegister src1,
2367 const DwVfpRegister src2,
2374 ASSERT(CpuFeatures::IsEnabled(VFP2));
2375 emit(cond | 0xE*
B24 | 0x3*
B20 | src1.code()*
B16 |
2376 dst.code()*
B12 | 0x5*
B9 |
B8 |
B6 | src2.code());
2381 const DwVfpRegister src1,
2382 const DwVfpRegister src2,
2389 ASSERT(CpuFeatures::IsEnabled(VFP2));
2390 emit(cond | 0xE*
B24 | 0x2*
B20 | src1.code()*
B16 |
2391 dst.code()*
B12 | 0x5*
B9 |
B8 | src2.code());
2396 const DwVfpRegister src1,
2397 const DwVfpRegister src2,
2404 ASSERT(CpuFeatures::IsEnabled(VFP2));
2405 emit(cond | 0xE*
B24 | B23 | src1.code()*
B16 |
2406 dst.code()*
B12 | 0x5*
B9 |
B8 | src2.code());
2411 const DwVfpRegister src2,
2417 ASSERT(CpuFeatures::IsEnabled(VFP2));
2418 emit(cond | 0xE*
B24 |B23 | 0x3*
B20 |
B18 |
2419 src1.code()*
B12 | 0x5*
B9 |
B8 |
B6 | src2.code());
2430 ASSERT(CpuFeatures::IsEnabled(VFP2));
2441 ASSERT(CpuFeatures::IsEnabled(VFP2));
2443 dst.code()*
B12 | 0xA*
B8 |
B4);
2451 ASSERT(CpuFeatures::IsEnabled(VFP2));
2453 dst.code()*
B12 | 0xA*
B8 |
B4);
2458 const DwVfpRegister src,
2462 ASSERT(CpuFeatures::IsEnabled(VFP2));
2463 emit(cond | 0xE*
B24 | B23 | 0x3*
B20 |
B16 |
2464 dst.code()*
B12 | 0x5*
B9 |
B8 | 3*
B6 | src.code());
2475 ASSERT(0 <= type && type <= 14);
2476 emit(
al | 13*
B21 | type*
B12 | type);
2483 EncodeMovwImmediate(0xFFFF));
2484 return instr == 0x34*
B20;
2491 EncodeMovwImmediate(0xFFFF));
2492 return instr == 0x30*
B20;
2497 ASSERT(0 <= type && type <= 14);
2499 return instr == (
al | 13*
B21 | type*
B12 | type);
2506 return fits_shifter(imm32, &dummy1, &dummy2,
NULL);
2514 RecordRelocInfo(RelocInfo::JS_RETURN);
2521 RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT);
2526 if (FLAG_code_comments) {
2528 RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg));
2536 #ifdef ENABLE_DEBUGGER_SUPPORT
2537 RecordRelocInfo(RelocInfo::CONST_POOL, static_cast<intptr_t>(size));
2541 void Assembler::GrowBuffer() {
2542 if (!own_buffer_)
FATAL(
"external code buffer is too small");
2546 if (buffer_size_ < 4*
KB) {
2547 desc.buffer_size = 4*
KB;
2548 }
else if (buffer_size_ < 1*
MB) {
2549 desc.buffer_size = 2*buffer_size_;
2551 desc.buffer_size = buffer_size_ + 1*
MB;
2556 desc.buffer = NewArray<byte>(desc.buffer_size);
2559 desc.reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
2562 int pc_delta = desc.buffer - buffer_;
2563 int rc_delta = (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_);
2564 memmove(desc.buffer, buffer_, desc.instr_size);
2565 memmove(reloc_info_writer.pos() + rc_delta,
2566 reloc_info_writer.pos(), desc.reloc_size);
2570 buffer_ = desc.buffer;
2571 buffer_size_ = desc.buffer_size;
2573 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
2574 reloc_info_writer.last_pc() + pc_delta);
2581 for (
int i = 0; i < num_pending_reloc_info_; i++) {
2582 RelocInfo& rinfo = pending_reloc_info_[i];
2583 ASSERT(rinfo.rmode() != RelocInfo::COMMENT &&
2584 rinfo.rmode() != RelocInfo::POSITION);
2585 if (rinfo.rmode() != RelocInfo::JS_RETURN) {
2586 rinfo.set_pc(rinfo.pc() + pc_delta);
2596 ASSERT(num_pending_reloc_info_ == 0);
2598 *
reinterpret_cast<uint8_t*
>(pc_) = data;
2599 pc_ +=
sizeof(uint8_t);
2607 ASSERT(num_pending_reloc_info_ == 0);
2609 *
reinterpret_cast<uint32_t*
>(pc_) = data;
2610 pc_ +=
sizeof(uint32_t);
2614 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data,
2615 UseConstantPoolMode mode) {
2618 if (((rmode >= RelocInfo::JS_RETURN) &&
2619 (rmode <= RelocInfo::DEBUG_BREAK_SLOT)) ||
2620 (rmode == RelocInfo::CONST_POOL) ||
2621 mode == DONT_USE_CONSTANT_POOL) {
2623 ASSERT(RelocInfo::IsDebugBreakSlot(rmode)
2624 || RelocInfo::IsJSReturn(rmode)
2625 || RelocInfo::IsComment(rmode)
2626 || RelocInfo::IsPosition(rmode)
2627 || RelocInfo::IsConstPool(rmode)
2628 || mode == DONT_USE_CONSTANT_POOL);
2632 if (num_pending_reloc_info_ == 0) {
2635 pending_reloc_info_[num_pending_reloc_info_++] = rinfo;
2642 if (rmode == RelocInfo::EXTERNAL_REFERENCE) {
2653 if (rmode == RelocInfo::CODE_TARGET_WITH_ID) {
2659 reloc_info_writer.Write(&reloc_info_with_ast_id);
2661 reloc_info_writer.Write(&rinfo);
2669 if (no_const_pool_before_ < pc_limit) {
2672 ASSERT((num_pending_reloc_info_ == 0) ||
2674 no_const_pool_before_ = pc_limit;
2677 if (next_buffer_check_ < no_const_pool_before_) {
2678 next_buffer_check_ = no_const_pool_before_;
2694 if (num_pending_reloc_info_ == 0) {
2696 next_buffer_check_ =
pc_offset() + kCheckPoolInterval;
2706 ASSERT(first_const_pool_use_ >= 0);
2707 int dist =
pc_offset() - first_const_pool_use_;
2708 if (!force_emit && dist < kAvgDistToPool &&
2716 int jump_instr = require_jump ? kInstrSize : 0;
2717 int size = jump_instr + kInstrSize + num_pending_reloc_info_ *
kPointerSize;
2718 int needed_space = size + kGap;
2738 for (
int i = 0; i < num_pending_reloc_info_; i++) {
2739 RelocInfo& rinfo = pending_reloc_info_[i];
2740 ASSERT(rinfo.rmode() != RelocInfo::COMMENT &&
2741 rinfo.rmode() != RelocInfo::POSITION &&
2742 rinfo.rmode() != RelocInfo::STATEMENT_POSITION &&
2743 rinfo.rmode() != RelocInfo::CONST_POOL);
2763 num_pending_reloc_info_ = 0;
2764 first_const_pool_use_ = -1;
2768 if (after_pool.is_linked()) {
2775 next_buffer_check_ =
pc_offset() + kCheckPoolInterval;
2781 #endif // V8_TARGET_ARCH_ARM
void cmp(Register src1, const Operand &src2, Condition cond=al)
static bool IsBranch(Instr instr)
void ldrsb(Register dst, const MemOperand &src, Condition cond=al)
bool ImmediateFitsAddrMode1Instruction(int32_t imm32)
void sdiv(Register dst, Register src1, Register src2, Condition cond=al)
Isolate * isolate() const
void vcvt_f64_u32(const DwVfpRegister dst, const SwVfpRegister src, VFPConversionMode mode=kDefaultRoundToZero, const Condition cond=al)
void mrc(Coprocessor coproc, int opcode_1, Register rd, CRegister crn, CRegister crm, int opcode_2=0, Condition cond=al)
static int GetBranchOffset(Instr instr)
void ClearRecordedAstId()
void vcvt_f32_f64(const SwVfpRegister dst, const DwVfpRegister src, VFPConversionMode mode=kDefaultRoundToZero, const Condition cond=al)
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 instructions(ARM only)") DEFINE_bool(enable_vfp2
const Instr kLdrRegFpOffsetPattern
static bool IsCmpRegister(Instr instr)
void PrintF(const char *format,...)
const Instr kMovwLeaveCCFlip
void strh(Register src, const MemOperand &dst, Condition cond=al)
void bic(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)
void mrs(Register dst, SRegister s, Condition cond=al)
const Instr kLdrPCPattern
const Instr kMovMvnPattern
static bool IsStrRegFpNegOffset(Instr instr)
void instr_at_put(int pos, Instr instr)
void vabs(const DwVfpRegister dst, const DwVfpRegister src, const Condition cond=al)
void sbc(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)
static bool IsStrRegisterImmediate(Instr instr)
void cmp_raw_immediate(Register src1, int raw_immediate, Condition cond=al)
void vmov(const DwVfpRegister dst, double imm, const Register scratch=no_reg, const Condition cond=al)
static bool IsMovW(Instr instr)
void mla(Register dst, Register src1, Register src2, Register srcA, SBit s=LeaveCC, Condition cond=al)
const int kRegister_pc_Code
void bfi(Register dst, Register src, int lsb, int width, Condition cond=al)
static int GetCmpImmediateRawImmediate(Instr instr)
void b(int branch_offset, Condition cond=al)
void cmn(Register src1, const Operand &src2, Condition cond=al)
void ldrb(Register dst, const MemOperand &src, Condition cond=al)
void smull(Register dstL, Register dstH, Register src1, Register src2, SBit s=LeaveCC, Condition cond=al)
static bool IsSupported(CpuFeature f)
const Instr kLdrStrOffsetMask
void clz(Register dst, Register src, Condition cond=al)
void vmul(const DwVfpRegister dst, const DwVfpRegister src1, const DwVfpRegister src2, const Condition cond=al)
static bool IsStrRegFpOffset(Instr instr)
void vsqrt(const DwVfpRegister dst, const DwVfpRegister src, const Condition cond=al)
void RecordConstPool(int size)
static Register GetRm(Instr instr)
const uint32_t kMaxStopCode
static const int kMinimalBufferSize
TypeFeedbackId RecordedAstId()
#define ASSERT(condition)
friend class BlockConstPoolScope
void svc(uint32_t imm24, Condition cond=al)
static bool IsCmpImmediate(Instr instr)
void stm(BlockAddrMode am, Register base, RegList src, Condition cond=al)
void DoubleAsTwoUInt32(double d, uint32_t *lo, uint32_t *hi)
void ldrd(Register dst1, Register dst2, const MemOperand &src, Condition cond=al)
void ldc2(Coprocessor coproc, CRegister crd, const MemOperand &src, LFlag l=Short)
const Instr kCmpCmnPattern
void blx(int branch_offset)
void target_at_put(int pos, int target_pos)
void vdiv(const DwVfpRegister dst, const DwVfpRegister src1, const DwVfpRegister src2, const Condition cond=al)
void vcvt_s32_f64(const SwVfpRegister dst, const DwVfpRegister src, VFPConversionMode mode=kDefaultRoundToZero, const Condition cond=al)
static Instr SetLdrRegisterImmediateOffset(Instr instr, int offset)
void strb(Register src, const MemOperand &dst, Condition cond=al)
const Instr kPopRegPattern
void ldrh(Register dst, const MemOperand &src, Condition cond=al)
void BlockConstPoolFor(int instructions)
void mvn(Register dst, const Operand &src, SBit s=LeaveCC, Condition cond=al)
static Condition GetCondition(Instr instr)
void vneg(const DwVfpRegister dst, const DwVfpRegister src, const Condition cond=al)
const Instr kPushRegPattern
void vcvt_f64_s32(const DwVfpRegister dst, const SwVfpRegister src, VFPConversionMode mode=kDefaultRoundToZero, const Condition cond=al)
static bool IsPush(Instr instr)
void vldm(BlockAddrMode am, Register base, DwVfpRegister first, DwVfpRegister last, Condition cond=al)
void sh(Register rd, const MemOperand &rs)
const Instr kLdrStrInstrArgumentMask
const int32_t kDefaultStopCode
void vsub(const DwVfpRegister dst, const DwVfpRegister src1, const DwVfpRegister src2, const Condition cond=al)
const Instr kLdrRegFpNegOffsetPattern
void GetCode(CodeDesc *desc)
void strd(Register src1, Register src2, const MemOperand &dst, Condition cond=al)
static const int kPcLoadDelta
void teq(Register src1, const Operand &src2, Condition cond=al)
int branch_offset(Label *L, bool jump_elimination_allowed)
static void TooLateToEnableNow()
static bool use_immediate_embedded_pointer_loads(const Assembler *assembler)
void umlal(Register dstL, Register dstH, Register src1, Register src2, SBit s=LeaveCC, Condition cond=al)
static bool IsPop(Instr instr)
const Instr kMovLeaveCCMask
void movt(Register reg, uint32_t immediate, Condition cond=al)
void cdp2(Coprocessor coproc, int opcode_1, CRegister crd, CRegister crn, CRegister crm, int opcode_2)
static bool IsMovT(Instr instr)
void vadd(const DwVfpRegister dst, const DwVfpRegister src1, const DwVfpRegister src2, const Condition cond=al)
const Instr kPopInstruction
const Instr kStrRegFpOffsetPattern
static bool ArmCpuHasFeature(CpuFeature feature)
#define ASSERT_LE(v1, v2)
void vmrs(const Register dst, const Condition cond=al)
void str(Register src, const MemOperand &dst, Condition cond=al)
void ldm(BlockAddrMode am, Register base, RegList dst, Condition cond=al)
const int kRegister_fp_Code
static CpuImplementer GetCpuImplementer()
void CheckConstPool(bool force_emit, bool require_jump)
void mrc2(Coprocessor coproc, int opcode_1, Register rd, CRegister crn, CRegister crm, int opcode_2=0)
const int kRegister_lr_Code
static Register GetRn(Instr instr)
void eor(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)
void add(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)
activate correct semantics for inheriting readonliness false
static Instr SetStrRegisterImmediateOffset(Instr instr, int offset)
static bool IsTstImmediate(Instr instr)
void vcvt_f64_f32(const DwVfpRegister dst, const SwVfpRegister src, VFPConversionMode mode=kDefaultRoundToZero, const Condition cond=al)
static Register GetRd(Instr instr)
static bool IsNop(Instr instr, int type=NON_MARKING_NOP)
static const int kMaxNumPendingRelocInfo
void RecordDebugBreakSlot()
void vcvt_u32_f64(const SwVfpRegister dst, const DwVfpRegister src, VFPConversionMode mode=kDefaultRoundToZero, const Condition cond=al)
void ldr(Register dst, const MemOperand &src, Condition cond=al)
void stop(const char *msg, Condition cond=al, int32_t code=kDefaultStopCode)
const int kConstantPoolMarker
void movw(Register reg, uint32_t immediate, Condition cond=al)
static Instr SetAddRegisterImmediateOffset(Instr instr, int offset)
const Instr kMovLeaveCCPattern
const Instr kLdrStrInstrTypeMask
void smlal(Register dstL, Register dstH, Register src1, Register src2, SBit s=LeaveCC, Condition cond=al)
void vldr(const DwVfpRegister dst, const Register base, int offset, const Condition cond=al)
void RecordComment(const char *msg)
void bl(int branch_offset, Condition cond=al)
void rsb(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)
void sbfx(Register dst, Register src, int lsb, int width, Condition cond=al)
static Register GetCmpImmediateRegister(Instr instr)
const Instr kBlxRegPattern
bool is_const_pool_blocked() const
static bool IsAddRegisterImmediate(Instr instr)
void vcmp(const DwVfpRegister src1, const DwVfpRegister src2, const Condition cond=al)
void mov(Register dst, const Operand &src, SBit s=LeaveCC, Condition cond=al)
static const int kHeaderSize
void vmsr(const Register dst, const Condition cond=al)
void vstr(const DwVfpRegister src, const Register base, int offset, const Condition cond=al)
Assembler(Isolate *isolate, void *buffer, int buffer_size)
void usat(Register dst, int satpos, const Operand &src, Condition cond=al)
void ubfx(Register dst, Register src, int lsb, int width, Condition cond=al)
Condition NegateCondition(Condition cond)
#define ASSERT_EQ(v1, v2)
void bx(Register target, Condition cond=al)
void ldrsh(Register dst, const MemOperand &src, Condition cond=al)
uint32_t SRegisterFieldMask
void orr(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)
PositionsRecorder * positions_recorder()
Condition ConditionField() const
static const int kInstrSize
void cdp(Coprocessor coproc, int opcode_1, CRegister crd, CRegister crn, CRegister crm, int opcode_2, Condition cond=al)
MemOperand(Register rn, int32_t offset=0)
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
static uint64_t CpuFeaturesImpliedByPlatform()
void bfc(Register dst, int lsb, int width, Condition cond=al)
void mls(Register dst, Register src1, Register src2, Register srcA, Condition cond=al)
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
static void FlushICache(void *start, size_t size)
void and_(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)
void label_at_put(Label *L, int at_offset)
const Instr kStrRegFpNegOffsetPattern
const int kRegister_sp_Code
void DeleteArray(T *array)
void umull(Register dstL, Register dstH, Register src1, Register src2, SBit s=LeaveCC, Condition cond=al)
static bool IsLdrRegisterImmediate(Instr instr)
void msr(SRegisterFieldMask fields, const Operand &src, Condition cond=al)
void ldc(Coprocessor coproc, CRegister crd, const MemOperand &src, LFlag l=Short, Condition cond=al)
static bool IsLdrRegFpNegOffset(Instr instr)
void bkpt(uint32_t imm16)
void vstm(BlockAddrMode am, Register base, DwVfpRegister first, DwVfpRegister last, Condition cond=al)
static int GetLdrRegisterImmediateOffset(Instr instr)
void sub(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)
bool emit_debug_code() const
void vcvt_f32_s32(const SwVfpRegister dst, const SwVfpRegister src, VFPConversionMode mode=kDefaultRoundToZero, const Condition cond=al)
void rsc(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)
void tst(Register src1, const Operand &src2, Condition cond=al)
static bool IsLdrRegFpOffset(Instr instr)
void mcr2(Coprocessor coproc, int opcode_1, Register rd, CRegister crn, CRegister crm, int opcode_2=0)
void mul(Register dst, Register src1, Register src2, SBit s=LeaveCC, Condition cond=al)
static bool IsLdrPcImmediateOffset(Instr instr)
void mcr(Coprocessor coproc, int opcode_1, Register rd, CRegister crn, CRegister crm, int opcode_2=0, Condition cond=al)
void c(FPUCondition cond, SecondaryField fmt, FPURegister ft, FPURegister fs, uint16_t cc=0)
static const int kMaxDistToPool
void adc(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)