6#if defined(TARGET_ARCH_IA32)
8#define SHOULD_NOT_INCLUDE_RUNTIME
21class DirectCallRelocation :
public AssemblerFixup {
23 void Process(
const MemoryRegion& region, intptr_t position) {
25 int32_t pointer =
region.Load<int32_t>(position);
26 int32_t
delta =
region.start() + position +
sizeof(int32_t);
30 virtual bool IsPointerOffset()
const {
return false; }
33int32_t Assembler::jit_cookie() {
34 if (jit_cookie_ == 0) {
41 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
43 EmitRegisterOperand(2, reg);
47 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
49 EmitOperand(2, address);
53 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
56 EmitLabel(label,
kSize);
60 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
63 EmitFixup(
new DirectCallRelocation());
64 EmitInt32(label->address());
69 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
70 EmitUint8(0x50 + reg);
74 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
76 EmitOperand(6, address);
80 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
83 EmitUint8(imm.value() & 0xFF);
91 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
92 EmitUint8(0x58 + reg);
96 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
98 EmitOperand(0, address);
102 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
107 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
112 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
114 EmitUint8(0x90 + condition);
115 EmitUint8(0xC0 + dst);
119 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
120 EmitUint8(0xB8 + dst);
125 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
127 EmitRegisterOperand(src, dst);
131 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
133 EmitOperand(dst, src);
137 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
139 EmitOperand(src, dst);
143 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
150 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
153 EmitRegisterOperand(dst, src);
157 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
160 EmitOperand(dst, src);
164 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
167 EmitRegisterOperand(dst, src);
171 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
174 EmitOperand(dst, src);
181 FATAL(
"Use movzxb or movsxb instead.");
185 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
187 EmitOperand(src, dst);
191 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
193 EmitOperand(src, dst);
197 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
199 EmitOperand(
EAX, dst);
201 EmitUint8(imm.value() & 0xFF);
205 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
208 EmitRegisterOperand(dst, src);
212 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
215 EmitOperand(dst, src);
219 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
222 EmitRegisterOperand(dst, src);
226 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
229 EmitOperand(dst, src);
232void Assembler::movw(
Register dst,
const Address& src) {
236 FATAL(
"Use movzxw or movsxw instead.");
239void Assembler::movw(
const Address& dst,
Register src) {
240 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
241 EmitOperandSizeOverride();
243 EmitOperand(src, dst);
246void Assembler::movw(
const Address& dst,
const Immediate& imm) {
247 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
248 EmitOperandSizeOverride();
251 EmitUint8(imm.value() & 0xFF);
252 EmitUint8((imm.value() >> 8) & 0xFF);
256 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
258 EmitOperand(dst, src);
263 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
266 EmitRegisterOperand(dst, src);
270 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
273 EmitRegisterOperand(dst, src);
277 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
280 EmitRegisterOperand(dst, src);
284 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
287 EmitRegisterOperand(dst, src);
291 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
294 EmitRegisterOperand(dst, src);
298 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
301 EmitRegisterOperand(dst, src);
305 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
308 EmitRegisterOperand(dst, src);
312 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
318 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
325 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
331 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
335 EmitOperand(dst, src);
339 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
343 EmitOperand(src, dst);
347 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
351 EmitXmmRegisterOperand(src, dst);
355 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
359 EmitOperand(dst, Operand(src));
363 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
367 EmitOperand(src, Operand(dst));
371 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
375 EmitOperand(src, Operand(dst));
379 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
383 EmitOperand(dst, Operand(src));
387 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
391 EmitXmmRegisterOperand(dst, src);
395 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
399 EmitOperand(dst, src);
403 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
407 EmitXmmRegisterOperand(dst, src);
411 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
415 EmitOperand(dst, src);
419 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
423 EmitXmmRegisterOperand(dst, src);
427 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
431 EmitOperand(dst, src);
435 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
439 EmitXmmRegisterOperand(dst, src);
443 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
447 EmitOperand(dst, src);
451 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
457 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
463 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
467 EmitOperand(dst, src);
471 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
475 EmitOperand(src, dst);
479 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
483 EmitXmmRegisterOperand(src, dst);
487 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
490 EmitXmmRegisterOperand(dst, src);
494 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
497 EmitOperand(dst, src);
501 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
504 EmitOperand(src, dst);
508 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
512 EmitXmmRegisterOperand(dst, src);
516 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
520 EmitOperand(dst, src);
524 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
528 EmitXmmRegisterOperand(dst, src);
532 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
536 EmitXmmRegisterOperand(dst, src);
540 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
543 EmitXmmRegisterOperand(dst, src);
547 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
550 EmitXmmRegisterOperand(dst, src);
554 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
557 EmitXmmRegisterOperand(dst, src);
561 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
564 EmitXmmRegisterOperand(dst, src);
568 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
571 EmitXmmRegisterOperand(dst, src);
575 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
578 EmitXmmRegisterOperand(dst, src);
582 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
585 EmitXmmRegisterOperand(dst, src);
589 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
592 EmitOperand(dst, src);
596 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
599 EmitXmmRegisterOperand(dst, src);
645 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
648 EmitXmmRegisterOperand(dst, src);
653 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
656 EmitXmmRegisterOperand(dst, src);
661 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
664 EmitXmmRegisterOperand(dst, src);
669 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
672 EmitXmmRegisterOperand(dst, src);
677 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
680 EmitXmmRegisterOperand(dst, src);
685 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
688 EmitXmmRegisterOperand(dst, src);
693 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
696 EmitXmmRegisterOperand(dst, dst);
700 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
703 EmitXmmRegisterOperand(dst, dst);
707 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
710 EmitXmmRegisterOperand(dst, dst);
714 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
717 EmitXmmRegisterOperand(dst, src);
721 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
724 EmitXmmRegisterOperand(dst, src);
728 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
731 EmitXmmRegisterOperand(dst, src);
735 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
738 EmitXmmRegisterOperand(dst, src);
742 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
746 EmitXmmRegisterOperand(dst, src);
750 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
754 EmitXmmRegisterOperand(dst, src);
763 shufps(dst, dst, Immediate(0x0));
767 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
770 EmitXmmRegisterOperand(dst, src);
772 EmitUint8(imm.value());
776 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
780 EmitXmmRegisterOperand(dst, src);
793 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
797 EmitXmmRegisterOperand(dst, src);
801 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
805 EmitXmmRegisterOperand(dst, src);
809 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
813 EmitXmmRegisterOperand(dst, src);
820 } double_absolute_constant = {0x7FFFFFFFFFFFFFFFLL, 0x7FFFFFFFFFFFFFFFLL};
826 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
830 EmitXmmRegisterOperand(dst, src);
834 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
838 EmitXmmRegisterOperand(dst, src);
842 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
846 EmitXmmRegisterOperand(dst, dst);
850 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
853 EmitXmmRegisterOperand(dst, src);
857 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
861 EmitXmmRegisterOperand(dst, src);
865 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
869 EmitXmmRegisterOperand(dst, src);
871 EmitUint8(imm.value());
875 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
879 EmitXmmRegisterOperand(dst, src);
883 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
887 EmitOperand(dst, src);
891 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
895 EmitXmmRegisterOperand(dst, src);
899 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
903 EmitOperand(dst, src);
907 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
911 EmitXmmRegisterOperand(dst, src);
915 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
919 EmitOperand(dst, src);
923 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
927 EmitOperand(dst, Operand(src));
931 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
935 EmitOperand(dst, Operand(src));
939 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
943 EmitXmmRegisterOperand(dst, src);
947 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
951 EmitXmmRegisterOperand(dst, src);
955 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
959 EmitXmmRegisterOperand(dst, src);
963 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
967 EmitXmmRegisterOperand(dst, src);
971 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
975 EmitXmmRegisterOperand(dst, src);
979 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
983 EmitXmmRegisterOperand(dst, src);
987 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
991 EmitXmmRegisterOperand(dst, src);
995 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
998 EmitXmmRegisterOperand(
a,
b);
1002 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1006 EmitXmmRegisterOperand(
a,
b);
1010 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1014 EmitXmmRegisterOperand(dst, src);
1018 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1021 EmitXmmRegisterOperand(dst, src);
1025 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1029 EmitXmmRegisterOperand(dst, src);
1033 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1037 EmitXmmRegisterOperand(dst, src);
1041 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1045 EmitXmmRegisterOperand(dst, src);
1049 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1053 EmitOperand(dst, src);
1057 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1061 EmitXmmRegisterOperand(dst, src);
1065 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1069 EmitXmmRegisterOperand(dst, src);
1073 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1076 EmitOperand(dst, src);
1080 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1083 EmitXmmRegisterOperand(dst, src);
1087 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1091 EmitOperand(dst, src);
1095 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1099 EmitXmmRegisterOperand(dst, src);
1104 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1109 EmitOperand(src, Operand(dst));
1111 EmitUint8(imm.value());
1116 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1121 EmitXmmRegisterOperand(dst, src);
1126 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1131 EmitXmmRegisterOperand(dst, src);
1135 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1139 EmitXmmRegisterOperand(dst, src);
1144 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1149 EmitXmmRegisterOperand(dst, src);
1151 EmitUint8(
static_cast<uint8_t
>(mode) | 0x8);
1155 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1157 EmitOperand(0, src);
1161 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1163 EmitOperand(3, dst);
1167 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1169 EmitOperand(7, dst);
1173 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1175 EmitOperand(5, src);
1179 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1181 EmitOperand(7, dst);
1185 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1187 EmitOperand(3, dst);
1191 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1193 EmitOperand(5, src);
1197 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1199 EmitOperand(0, src);
1203 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1210 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1212 EmitUint8(0xC0 + value);
1216 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1222 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1228 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1234 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1240 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1242 EmitRegisterOperand(dst, src);
1246 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1247 EmitOperandSizeOverride();
1249 EmitOperand(7, address);
1250 EmitUint8(imm.value() & 0xFF);
1251 EmitUint8((imm.value() >> 8) & 0xFF);
1256 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1258 EmitOperand(7, address);
1259 EmitUint8(imm.value() & 0xFF);
1263 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1265 EmitRegisterOperand(reg1, reg2);
1269 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1272 if (immediate.is_uint8() && reg < 4) {
1278 EmitUint8(0xC0 + reg);
1280 EmitUint8(immediate.value() & 0xFF);
1281 }
else if (reg ==
EAX) {
1284 EmitImmediate(immediate);
1287 EmitOperand(0, Operand(reg));
1288 EmitImmediate(immediate);
1293 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1295 EmitOperand(0, address);
1296 EmitImmediate(immediate);
1300 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1302 EmitOperand(reg, address);
1307 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1309 EmitOperand(0, address);
1310 EmitUint8(imm.value() & 0xFF);
1314 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1316 EmitOperand(reg, address);
1319void Assembler::Alu(
int bytes, uint8_t opcode,
Register dst,
Register src) {
1320 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1322 EmitOperandSizeOverride();
1324 ASSERT((opcode & 7) == 3);
1326 EmitOperand(dst, Operand(src));
1329void Assembler::Alu(uint8_t modrm_opcode,
Register dst,
const Immediate& imm) {
1330 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1331 EmitComplex(modrm_opcode, Operand(dst), imm);
1334void Assembler::Alu(
int bytes,
1337 const Address& src) {
1338 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1340 EmitOperandSizeOverride();
1342 ASSERT((opcode & 7) == 3);
1344 EmitOperand(dst, src);
1347void Assembler::Alu(
int bytes,
1351 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1353 EmitOperandSizeOverride();
1355 ASSERT((opcode & 7) == 1);
1357 EmitOperand(src, dst);
1360void Assembler::Alu(uint8_t modrm_opcode,
1362 const Immediate& imm) {
1363 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1364 EmitComplex(modrm_opcode, dst, imm);
1368 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1373 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1375 EmitOperand(7, Operand(reg));
1379 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1381 EmitOperand(6, Operand(reg));
1385 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1388 EmitOperand(dst, Operand(src));
1392 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1394 EmitOperand(reg, Operand(reg));
1399 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1402 EmitOperand(reg, address);
1406 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1408 EmitOperand(5, Operand(reg));
1412 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1414 EmitOperand(5, address);
1418 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1420 EmitOperand(4, Operand(reg));
1424 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1426 EmitOperand(4, address);
1430 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1431 EmitUint8(0x40 + reg);
1435 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1437 EmitOperand(0, address);
1441 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1442 EmitUint8(0x48 + reg);
1446 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1448 EmitOperand(1, address);
1452 EmitGenericShift(4, reg, imm);
1456 EmitGenericShift(4, Operand(operand), shifter);
1460 EmitGenericShift(4, Operand(operand), shifter);
1464 EmitGenericShift(5, reg, imm);
1468 EmitGenericShift(5, Operand(operand), shifter);
1472 EmitGenericShift(7, reg, imm);
1476 EmitGenericShift(7, Operand(operand), shifter);
1480 EmitGenericShift(7, Operand(address), shifter);
1484 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1488 EmitRegisterOperand(src, dst);
1492 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1496 EmitRegisterOperand(src, dst);
1497 EmitUint8(imm.value() & 0xFF);
1501 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1505 EmitOperand(src, Operand(operand));
1509 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1513 EmitRegisterOperand(src, dst);
1517 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1521 EmitRegisterOperand(src, dst);
1522 EmitUint8(imm.value() & 0xFF);
1526 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1530 EmitOperand(src, Operand(dst));
1534 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1536 EmitOperand(3, Operand(reg));
1540 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1542 EmitUint8(0xD0 | reg);
1546 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1549 EmitRegisterOperand(dst, src);
1553 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1556 EmitRegisterOperand(dst, src);
1561 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1565 EmitRegisterOperand(dst, src);
1570 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1574 EmitRegisterOperand(dst, src);
1578 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1585 ASSERT(bit >= 0 && bit < 32);
1586 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1589 EmitRegisterOperand(4,
base);
1594 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1597 EmitUint8(imm.value() & 0xFF);
1598 EmitUint8((imm.value() >> 8) & 0xFF);
1603 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1608 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1613 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1616 EmitUint8(imm.value() & 0xFF);
1617 EmitUint8((imm.value() >> 8) & 0xFF);
1621 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1683 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1688 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1693 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1694 if (label->IsBound()) {
1695 const int kShortSize = 2;
1696 const int kLongSize = 6;
1700 EmitUint8(0x70 + condition);
1701 EmitUint8((
offset - kShortSize) & 0xFF);
1704 EmitUint8(0x80 + condition);
1705 EmitInt32(
offset - kLongSize);
1708 EmitUint8(0x70 + condition);
1709 EmitNearLabelLink(label);
1712 EmitUint8(0x80 + condition);
1713 EmitLabelLink(label);
1718 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1720 EmitUint8(0x80 + condition);
1721 EmitFixup(
new DirectCallRelocation());
1722 EmitInt32(label->address());
1726 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1728 EmitRegisterOperand(4, reg);
1732 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1734 EmitOperand(4, address);
1738 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1739 if (label->IsBound()) {
1740 const int kShortSize = 2;
1741 const int kLongSize = 5;
1746 EmitUint8((
offset - kShortSize) & 0xFF);
1749 EmitInt32(
offset - kLongSize);
1753 EmitNearLabelLink(label);
1756 EmitLabelLink(label);
1761 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1763 EmitFixup(
new DirectCallRelocation());
1764 EmitInt32(label->address());
1768 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1773 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1776 EmitOperand(reg, address);
1780 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1785 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1790 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1802 return movsxb(reg, address);
1804 return movzxb(reg, address);
1806 return movsxw(reg, address);
1808 return movzxw(reg, address);
1811 return movl(reg, address);
1822 return movb(address, reg);
1825 return movw(address, reg);
1828 return movl(address, reg);
1836 if (target::CanEmbedAsRawPointerInGeneratedCode(
object)) {
1837 movl(dst, Immediate(target::ToRawPointer(
object)));
1841 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
1843 EmitOperand(0, dst);
1849 sarl(reg, Immediate(shift));
1870 movl(dst, Address(
ESP, depth * target::kWordSize));
1875 movl(Address(
ESP, depth * target::kWordSize), src);
1879 cmpl(src, Address(
ESP, depth * target::kWordSize));
1886 if (to == from)
return;
1887 return movl(to, from);
1904 return andl(to, Immediate(0xFF));
1918 shll(to, Immediate(24));
1919 return sarl(to, Immediate(24));
1942 const intptr_t
value = imm.value();
1946 if ((value > 0) || (value ==
kMinInt32)) {
1966 leal(dest, Address(src, value));
1970 const intptr_t
value = imm.value();
1974 if ((value > 0) || (value ==
kMinInt32)) {
1992 }
else if (dst == src1) {
2001 ASSERT(stack_elements >= 0);
2002 if (stack_elements > 0) {
2003 addl(
ESP, Immediate(stack_elements * target::kWordSize));
2008 movl(dst, Address(
THR, target::Thread::isolate_offset()));
2012 movl(dst, Address(
THR, target::Thread::isolate_group_offset()));
2016 const Object&
object,
2017 bool movable_referent) {
2024 if (target::CanEmbedAsRawPointerInGeneratedCode(
object) &&
2025 !movable_referent) {
2026 movl(dst, Immediate(target::ToRawPointer(
object)));
2030 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
2031 EmitUint8(0xB8 + dst);
2039 const int32_t cookie = jit_cookie();
2041 xorl(dst, Immediate(cookie));
2049 if (target::CanEmbedAsRawPointerInGeneratedCode(
object)) {
2050 pushl(Immediate(target::ToRawPointer(
object)));
2054 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
2062 if (target::CanEmbedAsRawPointerInGeneratedCode(
object)) {
2063 cmpl(reg, Immediate(target::ToRawPointer(
object)));
2067 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
2069 EmitUint8(0x05 + (7 << 3));
2073 EmitOperand(7, Operand(reg));
2081 CanBeSmi can_be_smi,
2086 bool spill_scratch =
false;
2088 spill_scratch =
true;
2089 if (
object !=
EAX && value !=
EAX) {
2091 }
else if (
object !=
EBX && value !=
EBX) {
2097 ASSERT(scratch !=
object);
2098 ASSERT(scratch != value);
2115 Bind(&passed_check);
2118 if (spill_scratch) {
2121 movl(scratch, FieldAddress(
object, target::Object::tags_offset()));
2122 shrl(scratch, Immediate(target::UntaggedObject::kBarrierOverlapShift));
2123 andl(scratch, Address(
THR, target::Thread::write_barrier_mask_offset()));
2124 testl(FieldAddress(value, target::Object::tags_offset()), scratch);
2125 if (spill_scratch) {
2139 pushl(object_for_call);
2140 movl(object_for_call,
object);
2144 call(Address(
THR, target::Thread::write_barrier_wrappers_thread_offset(
2148 popl(object_for_call);
2158 CanBeSmi can_be_smi,
2161 ASSERT(scratch !=
object);
2162 ASSERT(scratch != value);
2180 Bind(&passed_check);
2183 movl(scratch, FieldAddress(
object, target::Object::tags_offset()));
2184 shrl(scratch, Immediate(target::UntaggedObject::kBarrierOverlapShift));
2185 andl(scratch, Address(
THR, target::Thread::write_barrier_mask_offset()));
2186 testl(FieldAddress(value, target::Object::tags_offset()), scratch);
2196 call(Address(
THR, target::Thread::array_write_barrier_entry_point_offset()));
2209 testb(FieldAddress(value, target::Object::tags_offset()),
2210 Immediate(1 << target::UntaggedObject::kNewBit));
2212 testb(FieldAddress(
object, target::Object::tags_offset()),
2213 Immediate(1 << target::UntaggedObject::kOldAndNotRememberedBit));
2215 Stop(
"Write barrier is required");
2220 const Address& dest,
2221 const Object& value,
2222 MemoryOrder memory_order,
2232#if defined(TARGET_USES_THREAD_SANITIZER)
2237 if (target::CanEmbedAsRawPointerInGeneratedCode(value)) {
2238 Immediate imm_value(target::ToRawPointer(value));
2239 movl(dest, imm_value);
2241 AssemblerBuffer::EnsureCapacity ensured(&
buffer_);
2243 EmitOperand(0, dest);
2250 const Address& dest,
2260 Stop(
"New value must be Smi.");
2275 addl(dest, inc_imm);
2279 int32_t constant = bit_cast<int32_t, float>(value);
2280 pushl(Immediate(constant));
2282 addl(
ESP, Immediate(target::kWordSize));
2287 int64_t constant = bit_cast<int64_t, double>(value);
2291 addl(
ESP, Immediate(2 * target::kWordSize));
2301 addl(
ESP, Immediate(4 * target::kWordSize));
2336 intptr_t check_offset =
CodeSize();
2344 if (frame_size != 0) {
2345 Immediate frame_space(frame_size);
2346 subl(
ESP, frame_space);
2367 leal(
EAX, Address(
EBP, target::frame_layout.exit_link_slot_from_entry_fp *
2368 target::kWordSize));
2371 Stop(
"target::frame_layout.exit_link_slot_from_entry_fp mismatch");
2381 Label have_cid, miss;
2383 jmp(Address(
THR, target::Thread::switchable_call_miss_entry_offset()));
2385 Comment(
"MonomorphicCheckedEntry");
2387 target::Instructions::kMonomorphicEntryOffsetJIT);
2389 const intptr_t cid_offset = target::Array::element_offset(0);
2390 const intptr_t count_offset = target::Array::element_offset(1);
2392 movl(
EAX, Immediate(kSmiCid << 1));
2400 cmpl(
EAX, FieldAddress(
ECX, cid_offset));
2408 target::Instructions::kPolymorphicEntryOffsetJIT);
2419 while (
CodeSize() < target::Instructions::kMonomorphicEntryOffsetJIT) {
2423 while (
CodeSize() < target::Instructions::kPolymorphicEntryOffsetJIT) {
2433 shll(other, Immediate(10));
2437 shrl(other, Immediate(6));
2451 shll(scratch, Immediate(3));
2455 shrl(scratch, Immediate(11));
2459 shll(scratch, Immediate(15));
2478 Label
done, slow_path;
2479 if (FLAG_use_slow_path) {
2484 movl(
EAX, Immediate(target::Thread::full_safepoint_state_unacquired()));
2485 movl(scratch, Immediate(target::Thread::full_safepoint_state_acquired()));
2486 LockCmpxchgl(Address(
THR, target::Thread::safepoint_state_offset()), scratch);
2489 cmpl(scratch, Immediate(target::Thread::full_safepoint_state_unacquired()));
2491 if (!FLAG_use_slow_path) {
2496 movl(scratch, Address(
THR, target::Thread::enter_safepoint_stub_offset()));
2497 movl(scratch, FieldAddress(scratch, target::Code::entry_point_offset()));
2506 bool enter_safepoint) {
2508 movl(Address(
THR, target::Thread::top_exit_frame_info_offset()),
2512 compiler::target::Thread::exit_through_ffi_offset()),
2513 new_exit_through_ffi);
2514 Register scratch = new_exit_through_ffi;
2518 movl(Address(
THR, target::Thread::execution_state_offset()),
2519 Immediate(target::Thread::native_execution_state()));
2521 if (enter_safepoint) {
2527 bool ignore_unwind_in_progress) {
2534 Label
done, slow_path;
2535 if (FLAG_use_slow_path) {
2540 movl(
EAX, Immediate(target::Thread::full_safepoint_state_acquired()));
2541 movl(scratch, Immediate(target::Thread::full_safepoint_state_unacquired()));
2542 LockCmpxchgl(Address(
THR, target::Thread::safepoint_state_offset()), scratch);
2545 cmpl(scratch, Immediate(target::Thread::full_safepoint_state_acquired()));
2547 if (!FLAG_use_slow_path) {
2552 if (ignore_unwind_in_progress) {
2556 exit_safepoint_ignore_unwind_in_progress_stub_offset()));
2558 movl(scratch, Address(
THR, target::Thread::exit_safepoint_stub_offset()));
2560 movl(scratch, FieldAddress(scratch, target::Code::entry_point_offset()));
2567 bool exit_safepoint,
2568 bool ignore_unwind_in_progress) {
2569 if (exit_safepoint) {
2573 ASSERT(!ignore_unwind_in_progress);
2576 movl(scratch, Address(
THR, target::Thread::safepoint_state_offset()));
2577 andl(scratch, Immediate(target::Thread::full_safepoint_state_acquired()));
2587 movl(Address(
THR, target::Thread::execution_state_offset()),
2588 Immediate(target::Thread::generated_execution_state()));
2591 movl(Address(
THR, target::Thread::top_exit_frame_info_offset()),
2594 compiler::target::Thread::exit_through_ffi_offset()),
2595 compiler::Immediate(0));
2598static constexpr intptr_t kNumberOfVolatileCpuRegisters = 3;
2599static const Register volatile_cpu_registers[kNumberOfVolatileCpuRegisters] = {
2604 ASSERT(!entry.is_leaf());
2607 movl(
ECX, compiler::Address(
THR, entry.OffsetFromThread()));
2609 call(Address(
THR, target::Thread::call_to_runtime_entry_point_offset()));
2612#define __ assembler_->
2615 intptr_t frame_size,
2616 bool preserve_registers)
2617 : assembler_(assembler), preserve_registers_(preserve_registers) {
2618 __ Comment(
"EnterCallRuntimeFrame");
2621 if (preserve_registers_) {
2623 for (intptr_t i = 0; i < kNumberOfVolatileCpuRegisters; i++) {
2624 __ pushl(volatile_cpu_registers[i]);
2628 __ subl(ESP, Immediate(kNumberOfXmmRegisters * kFpuRegisterSize));
2634 __ movups(Address(ESP,
offset), xmm_reg);
2642 __ ReserveAlignedFrameSpace(frame_size);
2645void LeafRuntimeScope::Call(
const RuntimeEntry& entry,
2648 __ movl(EAX, compiler::Address(THR, entry.OffsetFromThread()));
2649 __ movl(compiler::Assembler::VMTagAddress(), EAX);
2651 __ movl(compiler::Assembler::VMTagAddress(),
2652 compiler::Immediate(VMTag::kDartTagId));
2655LeafRuntimeScope::~LeafRuntimeScope() {
2656 if (preserve_registers_) {
2660 const intptr_t kPushedRegistersSize =
2661 kNumberOfVolatileCpuRegisters * target::kWordSize +
2663 __ leal(ESP, Address(EBP, -kPushedRegistersSize));
2670 __ movups(xmm_reg, Address(ESP,
offset));
2676 for (intptr_t i = kNumberOfVolatileCpuRegisters - 1; i >= 0; i--) {
2677 __ popl(volatile_cpu_registers[i]);
2684void Assembler::Call(
const Code&
target,
2685 bool movable_target,
2686 CodeEntryKind entry_kind) {
2688 call(FieldAddress(CODE_REG, target::Code::entry_point_offset(entry_kind)));
2691void Assembler::CallVmStub(
const Code&
target) {
2692 const Object& target_as_object = CastHandle<Object, Code>(
target);
2693 ASSERT(target::CanEmbedAsRawPointerInGeneratedCode(target_as_object));
2694 call(Address::Absolute(
2695 target::ToRawPointer(target_as_object) +
2696 target::Code::entry_point_offset(CodeEntryKind::kNormal) -
2700void Assembler::Jmp(
const Code&
target) {
2701 const ExternalLabel label(target::Code::EntryPointOf(
target));
2705void Assembler::J(Condition condition,
const Code&
target) {
2706 const ExternalLabel label(target::Code::EntryPointOf(
target));
2707 j(condition, &label);
2710void Assembler::Align(intptr_t alignment, intptr_t
offset) {
2711 ASSERT(Utils::IsPowerOfTwo(alignment));
2712 intptr_t
pos =
offset + buffer_.GetPosition();
2713 intptr_t mod =
pos & (alignment - 1);
2717 intptr_t bytes_needed = alignment - mod;
2718 while (bytes_needed > MAX_NOP_SIZE) {
2722 if (bytes_needed != 0) {
2725 ASSERT(((
offset + buffer_.GetPosition()) & (alignment - 1)) == 0);
2728void Assembler::Bind(Label* label) {
2729 intptr_t bound = buffer_.Size();
2730 ASSERT(!label->IsBound());
2731 while (label->IsLinked()) {
2732 intptr_t position = label->LinkPosition();
2733 intptr_t
next = buffer_.Load<int32_t>(position);
2734 buffer_.Store<int32_t>(position, bound - (position + 4));
2735 label->position_ =
next;
2737 while (label->HasNear()) {
2738 intptr_t position = label->NearPosition();
2739 intptr_t
offset = bound - (position + 1);
2741 buffer_.Store<int8_t>(position,
offset);
2743 label->BindTo(bound);
2746void Assembler::MoveMemoryToMemory(Address dst, Address src, Register tmp) {
2752void Assembler::MaybeTraceAllocation(intptr_t cid,
2755 JumpDistance distance) {
2757 Address state_address(kNoRegister, 0);
2759 ASSERT(temp_reg != kNoRegister);
2760 LoadIsolateGroup(temp_reg);
2761 movl(temp_reg, Address(temp_reg, target::IsolateGroup::class_table_offset()));
2764 target::ClassTable::allocation_tracing_state_table_offset()));
2765 cmpb(Address(temp_reg,
2766 target::ClassTable::AllocationTracingStateSlotOffsetFor(cid)),
2770 j(NOT_ZERO, trace, distance);
2774void Assembler::TryAllocateObject(intptr_t cid,
2775 intptr_t instance_size,
2777 JumpDistance distance,
2778 Register instance_reg,
2779 Register temp_reg) {
2780 ASSERT(failure !=
nullptr);
2781 ASSERT(instance_size != 0);
2782 ASSERT(Utils::IsAligned(instance_size,
2783 target::ObjectAlignment::kObjectAlignment));
2784 if (FLAG_inline_alloc &&
2785 target::Heap::IsAllocatableInNewSpace(instance_size)) {
2789 NOT_IN_PRODUCT(MaybeTraceAllocation(cid, failure, temp_reg, distance));
2790 movl(instance_reg, Address(THR, target::Thread::top_offset()));
2791 addl(instance_reg, Immediate(instance_size));
2793 cmpl(instance_reg, Address(THR, target::Thread::end_offset()));
2794 j(ABOVE_EQUAL, failure, distance);
2795 CheckAllocationCanary(instance_reg);
2798 movl(Address(THR, target::Thread::top_offset()), instance_reg);
2799 ASSERT(instance_size >= kHeapObjectTag);
2800 subl(instance_reg, Immediate(instance_size - kHeapObjectTag));
2801 const uword tags = target::MakeTagWordForNewSpaceObject(cid, instance_size);
2802 movl(FieldAddress(instance_reg, target::Object::tags_offset()),
2809void Assembler::TryAllocateArray(intptr_t cid,
2810 intptr_t instance_size,
2812 JumpDistance distance,
2814 Register end_address,
2815 Register temp_reg) {
2816 ASSERT(failure !=
nullptr);
2817 ASSERT(temp_reg != kNoRegister);
2818 if (FLAG_inline_alloc &&
2819 target::Heap::IsAllocatableInNewSpace(instance_size)) {
2823 NOT_IN_PRODUCT(MaybeTraceAllocation(cid, failure, temp_reg, distance));
2824 movl(
instance, Address(THR, target::Thread::top_offset()));
2827 addl(end_address, Immediate(instance_size));
2833 cmpl(end_address, Address(THR, target::Thread::end_offset()));
2834 j(ABOVE_EQUAL, failure);
2839 movl(Address(THR, target::Thread::top_offset()), end_address);
2840 addl(
instance, Immediate(kHeapObjectTag));
2843 const uword tags = target::MakeTagWordForNewSpaceObject(cid, instance_size);
2844 movl(FieldAddress(
instance, target::Object::tags_offset()),
2851void Assembler::CopyMemoryWords(Register src,
2860 cmpl(size, Immediate(0));
2863 movl(temp, Address(src, 0));
2864 addl(src, Immediate(target::kWordSize));
2865 movl(Address(dst, 0), temp);
2866 addl(dst, Immediate(target::kWordSize));
2867 subl(size, Immediate(target::kWordSize));
2868 j(NOT_ZERO, &loop, kNearJump);
2872void Assembler::PushCodeObject() {
2874 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2876 buffer_.EmitObject(code_);
2879void Assembler::EnterDartFrame(intptr_t frame_size) {
2884 if (frame_size != 0) {
2885 subl(ESP, Immediate(frame_size));
2889void Assembler::LeaveDartFrame() {
2897void Assembler::EnterOsrFrame(intptr_t extra_size) {
2898 Comment(
"EnterOsrFrame");
2899 if (prologue_offset_ == -1) {
2900 Comment(
"PrologueOffset = %" Pd "", CodeSize());
2901 prologue_offset_ = CodeSize();
2904 if (extra_size != 0) {
2905 subl(ESP, Immediate(extra_size));
2909void Assembler::EnterStubFrame() {
2913void Assembler::LeaveStubFrame() {
2917void Assembler::EnterCFrame(intptr_t frame_space) {
2922 ReserveAlignedFrameSpace(frame_space);
2925void Assembler::LeaveCFrame() {
2929void Assembler::EmitOperand(
int rm,
const Operand& operand) {
2930 ASSERT(rm >= 0 && rm < 8);
2931 const intptr_t
length = operand.length_;
2934 ASSERT((operand.encoding_[0] & 0x38) == 0);
2935 EmitUint8(operand.encoding_[0] + (rm << 3));
2937 for (intptr_t i = 1; i <
length; i++) {
2938 EmitUint8(operand.encoding_[i]);
2942void Assembler::EmitImmediate(
const Immediate& imm) {
2943 EmitInt32(imm.value());
2946void Assembler::EmitComplex(
int rm,
2947 const Operand& operand,
2948 const Immediate& immediate) {
2949 ASSERT(rm >= 0 && rm < 8);
2950 if (immediate.is_int8()) {
2953 EmitOperand(rm, operand);
2954 EmitUint8(immediate.value() & 0xFF);
2955 }
else if (operand.IsRegister(EAX)) {
2957 EmitUint8(0x05 + (rm << 3));
2958 EmitImmediate(immediate);
2961 EmitOperand(rm, operand);
2962 EmitImmediate(immediate);
2966void Assembler::EmitLabel(Label* label, intptr_t instruction_size) {
2967 if (label->IsBound()) {
2968 intptr_t
offset = label->Position() - buffer_.Size();
2970 EmitInt32(
offset - instruction_size);
2972 EmitLabelLink(label);
2976void Assembler::EmitLabelLink(Label* label) {
2977 ASSERT(!label->IsBound());
2978 intptr_t position = buffer_.Size();
2979 EmitInt32(label->position_);
2980 label->LinkTo(position);
2983void Assembler::EmitNearLabelLink(Label* label) {
2984 ASSERT(!label->IsBound());
2985 intptr_t position = buffer_.Size();
2987 label->NearLinkTo(position);
2990void Assembler::EmitGenericShift(
int rm, Register reg,
const Immediate& imm) {
2991 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2993 if (imm.value() == 1) {
2995 EmitOperand(rm, Operand(reg));
2998 EmitOperand(rm, Operand(reg));
2999 EmitUint8(imm.value() & 0xFF);
3003void Assembler::EmitGenericShift(
int rm,
3004 const Operand& operand,
3006 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
3009 EmitOperand(rm, Operand(operand));
3012void Assembler::LoadClassId(Register
result, Register
object) {
3013 ASSERT(target::UntaggedObject::kClassIdTagPos == 12);
3014 ASSERT(target::UntaggedObject::kClassIdTagSize == 20);
3015 movl(
result, FieldAddress(
object, target::Object::tags_offset()));
3016 shrl(
result, Immediate(target::UntaggedObject::kClassIdTagPos));
3019void Assembler::LoadClassById(Register
result, Register class_id) {
3022 const intptr_t table_offset =
3023 target::IsolateGroup::cached_class_table_table_offset();
3024 LoadIsolateGroup(
result);
3029void Assembler::CompareClassId(Register
object,
3032 LoadClassId(scratch,
object);
3033 cmpl(scratch, Immediate(class_id));
3036void Assembler::SmiUntagOrCheckClass(Register
object,
3040 ASSERT(kSmiTagShift == 1);
3041 ASSERT(target::UntaggedObject::kClassIdTagPos == 12);
3042 ASSERT(target::UntaggedObject::kClassIdTagSize == 20);
3045 j(NOT_CARRY, is_smi, kNearJump);
3048 movl(scratch, Address(
object, TIMES_2,
3049 target::Object::tags_offset() + kHeapObjectTag));
3050 shrl(scratch, Immediate(target::UntaggedObject::kClassIdTagPos));
3051 cmpl(scratch, Immediate(class_id));
3054void Assembler::LoadClassIdMayBeSmi(Register
result, Register
object) {
3058 testl(
object, Immediate(kSmiTagMask));
3059 j(
EQUAL, &smi, Assembler::kNearJump);
3060 LoadClassId(
result,
object);
3061 jmp(&join, Assembler::kNearJump);
3064 movl(
result, Immediate(kSmiCid));
3069 static const intptr_t kSmiCidSource =
3070 kSmiCid << target::UntaggedObject::kClassIdTagPos;
3073 movl(
result, Immediate(
reinterpret_cast<int32_t
>(&kSmiCidSource) + 1));
3076 testl(
object, Immediate(kSmiTagMask));
3085void Assembler::LoadTaggedClassIdMayBeSmi(Register
result, Register
object) {
3089 testl(
object, Immediate(kSmiTagMask));
3090 j(
EQUAL, &smi, Assembler::kNearJump);
3091 LoadClassId(
result,
object);
3093 jmp(&join, Assembler::kNearJump);
3096 movl(
result, Immediate(target::ToRawSmi(kSmiCid)));
3100 LoadClassIdMayBeSmi(
result,
object);
3105void Assembler::EnsureHasClassIdInDEBUG(intptr_t cid,
3110 Comment(
"Check that object in register has cid %" Pd "", cid);
3112 LoadClassIdMayBeSmi(scratch, src);
3113 CompareImmediate(scratch, cid);
3114 BranchIf(
EQUAL, &matches, Assembler::kNearJump);
3116 CompareImmediate(scratch, kNullCid);
3117 BranchIf(
EQUAL, &matches, Assembler::kNearJump);
3124bool Assembler::AddressCanHoldConstantIndex(
const Object& constant,
3127 intptr_t index_scale) {
3128 if (!IsSafeSmi(constant))
return false;
3129 const int64_t index = target::SmiValue(constant);
3131 is_external ? 0 : (target::Instance::DataOffsetFor(cid) -
kHeapObjectTag);
3132 const int64_t disp = index * index_scale +
offset;
3133 return Utils::IsInt(32, disp);
3136Address Assembler::ElementAddressForIntIndex(
bool is_external,
3138 intptr_t index_scale,
3141 intptr_t extra_disp) {
3143 return Address(array, index * index_scale + extra_disp);
3145 const int64_t disp =
static_cast<int64_t
>(index) * index_scale +
3146 target::Instance::DataOffsetFor(cid) + extra_disp;
3147 ASSERT(Utils::IsInt(32, disp));
3148 return FieldAddress(array,
static_cast<int32_t
>(disp));
3152Address Assembler::ElementAddressForRegIndex(
bool is_external,
3154 intptr_t index_scale,
3158 intptr_t extra_disp) {
3160 return Address(array, index, ToScaleFactor(index_scale, index_unboxed),
3163 return FieldAddress(array, index, ToScaleFactor(index_scale, index_unboxed),
3164 target::Instance::DataOffsetFor(cid) + extra_disp);
3168void Assembler::RangeCheck(Register value,
3172 RangeCheckCondition condition,
3176 if (temp != kNoRegister) {
3180 subl(to_check, Immediate(low));
3181 cmpl(to_check, Immediate(high - low));
static void done(const char *config, const char *src, const char *srcOptions, const char *name)
static float next(float f)
static bool ok(int result)
static bool equals(T *a, T *b)
#define DEBUG_ASSERT(cond)
#define ASSERT_EQUAL(expected, actual)
#define COMPILE_ASSERT(expr)
static intptr_t ActivationFrameAlignment()
static bool sse4_1_supported()
static bool popcnt_supported()
static bool abm_supported()
static bool IsInt(intptr_t N, T value)
static int32_t Low32Bits(int64_t value)
static constexpr T NBitMask(size_t n)
static int32_t High32Bits(int64_t value)
static Address Absolute(const uword addr)
intptr_t CodeSize() const
void Stop(const char *message)
bool has_monomorphic_entry_
uword CodeAddress(intptr_t offset)
void Comment(const char *format,...) PRINTF_ATTRIBUTE(2
intptr_t GetPosition() const
void PushRegistersInOrder(std::initializer_list< Register > regs)
void maxps(XmmRegister dst, XmmRegister src)
void unpcklpd(XmmRegister dst, XmmRegister src)
void FloatNegate(XmmRegister f)
void cvtdq2pd(XmmRegister dst, XmmRegister src)
void minpd(XmmRegister dst, XmmRegister src)
void fildl(const Address &src)
void CombineHashes(Register dst, Register other) override
void cmovns(Register dst, Register src)
void MonomorphicCheckedEntryJIT()
void BranchIfSmi(Register reg, Label *label, JumpDistance distance=kFarJump) override
void movups(XmmRegister dst, const Address &src)
void Load(Register reg, const Address &address, OperandSize type, Condition cond)
void unpckhpd(XmmRegister dst, XmmRegister src)
void movq(const Address &dst, XmmRegister src)
void shldl(Register dst, Register src, Register shifter)
void LoadIsolate(Register rd)
void EmitEntryFrameVerification()
void mulss(XmmRegister dst, XmmRegister src)
void IncrementSmiField(const Address &dest, int32_t increment)
void pxor(XmmRegister dst, XmmRegister src)
void movlhps(XmmRegister dst, XmmRegister src)
void ZeroInitSmiField(const Address &dest)
void pcmpeqq(XmmRegister dst, XmmRegister src)
void lzcntl(Register dst, Register src)
void cvtss2si(Register dst, XmmRegister src)
void movd(XmmRegister dst, Register src)
void negateps(XmmRegister dst)
void movl(Register dst, const Immediate &src)
void cvtsi2ss(XmmRegister dst, Register src)
void filds(const Address &src)
void j(Condition condition, Label *label, JumpDistance distance=kFarJump)
void maxpd(XmmRegister dst, XmmRegister src)
void addpd(XmmRegister dst, XmmRegister src)
void LoadFromStack(Register dst, intptr_t depth)
void movmskpd(Register dst, XmmRegister src)
void leal(Register dst, const Address &src)
void shufps(XmmRegister dst, XmmRegister src, const Immediate &mask)
void zerowps(XmmRegister dst)
void shll(Register reg, const Immediate &imm)
void shufpd(XmmRegister dst, XmmRegister src, const Immediate &mask)
void PushRegister(Register r)
void cvtpd2ps(XmmRegister dst, XmmRegister src)
void set1ps(XmmRegister dst, Register tmp, const Immediate &imm)
void orps(XmmRegister dst, XmmRegister src)
void mulps(XmmRegister dst, XmmRegister src)
void divsd(XmmRegister dst, XmmRegister src)
void roundsd(XmmRegister dst, XmmRegister src, RoundingMode mode)
void cmove(Register dst, Register src)
void pextrd(Register dst, XmmRegister src, const Immediate &imm)
void cvtps2pd(XmmRegister dst, XmmRegister src)
void LoadDImmediate(DRegister dd, double value, Register scratch, Condition cond=AL)
void subpl(XmmRegister dst, XmmRegister src)
void cmppsneq(XmmRegister dst, XmmRegister src)
void mulsd(XmmRegister dst, XmmRegister src)
void divpd(XmmRegister dst, XmmRegister src)
void movmskps(Register dst, XmmRegister src)
void sqrtss(XmmRegister dst, XmmRegister src)
void rsqrtps(XmmRegister dst)
void cmppseq(XmmRegister dst, XmmRegister src)
void StoreObjectIntoObjectNoBarrier(Register object, const Address &dest, const Object &value, MemoryOrder memory_order=kRelaxedNonAtomic, OperandSize size=kWordBytes) override
void EnterFullSafepoint()
void cvtss2sd(XmmRegister dst, XmmRegister src)
void movzxw(Register dst, Register src)
void cmovs(Register dst, Register src)
void cmpw(Register rn, Operand o)
void xorpd(XmmRegister dst, const Address &src)
void movsd(XmmRegister dst, const Address &src)
void fistpl(const Address &dst)
void cmppsnle(XmmRegister dst, XmmRegister src)
void TransitionNativeToGenerated(Register scratch0, Register scratch1, bool exit_safepoint, bool ignore_unwind_in_progress=false)
void flds(const Address &src)
void BranchIf(Condition condition, Label *label, JumpDistance distance=kFarJump)
void CompareObject(Register rn, const Object &object)
void bt(Register base, Register offset)
void comisd(XmmRegister a, XmmRegister b)
void fstps(const Address &dst)
void PushObject(const Object &object)
void pmovsxdq(XmmRegister dst, XmmRegister src)
void AndRegisters(Register dst, Register src1, Register src2=kNoRegister) override
void sqrtpd(XmmRegister dst)
void testb(const Address &address, const Immediate &imm)
void sarl(Register reg, const Immediate &imm)
void LoadQImmediate(QRegister dd, simd128_value_t value)
void divss(XmmRegister dst, XmmRegister src)
void testl(Register reg1, Register reg2)
void cvttsd2si(Register dst, XmmRegister src)
void StoreToStack(Register src, intptr_t depth)
void subpd(XmmRegister dst, XmmRegister src)
void StoreInternalPointer(Register object, const Address &dest, Register value)
void cmppslt(XmmRegister dst, XmmRegister src)
void sqrtsd(XmmRegister dst, XmmRegister src)
void andps(XmmRegister dst, XmmRegister src)
void Bind(Label *label) override
void ReserveAlignedFrameSpace(intptr_t frame_space)
void cmppsle(XmmRegister dst, XmmRegister src)
void MonomorphicCheckedEntryAOT()
void cmovno(Register dst, Register src)
void andpd(XmmRegister dst, const Address &src)
void cmovne(Register dst, Register src)
void LoadClassId(Register result, Register object, Condition cond=AL)
void enter(const Immediate &imm)
void setcc(Condition condition, ByteRegister dst)
void cvtsi2sd(XmmRegister dst, Register src)
void PopRegister(Register r)
void ArrayStoreBarrier(Register object, Register slot, Register value, CanBeSmi can_be_smi, Register scratch) override
void xchgl(Register dst, Register src)
void subss(XmmRegister dst, XmmRegister src)
void xorps(XmmRegister dst, const Address &src)
void ExitFullSafepoint(Register scratch0, Register scratch1, bool ignore_unwind_in_progress)
void subps(XmmRegister dst, XmmRegister src)
void popcntl(Register dst, Register src)
void addpl(XmmRegister dst, XmmRegister src)
void CallRuntime(const RuntimeEntry &entry, intptr_t argument_count)
void LockCmpxchgl(const Address &address, Register reg)
void LoadObject(Register rd, const Object &object, Condition cond=AL)
void CompareRegisters(Register rn, Register rm)
void fnstcw(const Address &dst)
void negatepd(XmmRegister dst)
void CompareToStack(Register src, intptr_t depth)
void addsd(XmmRegister dst, XmmRegister src)
void fldcw(const Address &src)
static Address VMTagAddress()
void cvtsd2ss(XmmRegister dst, XmmRegister src)
void cvtsd2si(Register dst, XmmRegister src)
void bsfl(Register dst, Register src)
void notps(XmmRegister dst)
void absps(XmmRegister dst)
void subsd(XmmRegister dst, XmmRegister src)
static bool IsSafeSmi(const Object &object)
void movsxb(Register dst, ByteRegister src)
void TransitionGeneratedToNative(Register destination_address, Register exit_frame_fp, Register exit_through_ffi, Register scratch0, bool enter_safepoint)
void SubImmediate(Register rd, Register rn, int32_t value, Condition cond=AL)
void Drop(intptr_t stack_elements)
void imull(Register dst, Register src)
void DoubleAbs(XmmRegister reg)
void reciprocalps(XmmRegister dst)
void minps(XmmRegister dst, XmmRegister src)
void StoreBarrier(Register object, Register value, CanBeSmi can_be_smi, Register scratch) override
void SmiTag(Register reg, Condition cond)
void VerifyStoreNeedsNoWriteBarrier(Register object, Register value) override
void CompareWords(Register reg1, Register reg2, intptr_t offset, Register count, Register temp, Label *equals) override
void addss(XmmRegister dst, XmmRegister src)
void ExtendValue(Register rd, Register rm, OperandSize sz, Condition cond)
void mulpd(XmmRegister dst, XmmRegister src)
void pmovmskb(Register dst, XmmRegister src)
void movhlps(XmmRegister dst, XmmRegister src)
void movb(Register dst, const Address &src)
void BranchIfNotSmi(Register reg, Label *label, JumpDistance distance=kFarJump)
void divps(XmmRegister dst, XmmRegister src)
void abspd(XmmRegister dst)
void StoreIntoSmiField(const Address &dest, Register value)
void addps(XmmRegister dst, XmmRegister src)
void fistps(const Address &dst)
void LoadSImmediate(SRegister sd, float value, Condition cond=AL)
void DoubleNegate(XmmRegister d)
void shrl(Register reg, const Immediate &imm)
void cvttss2si(Register dst, XmmRegister src)
void LoadIsolateGroup(Register dst)
void cmovgel(Register dst, Register src)
void BranchOnMonomorphicCheckedEntryJIT(Label *label)
void Store(Register reg, const Address &address, OperandSize type, Condition cond)
void movzxb(Register dst, ByteRegister src)
void movss(XmmRegister dst, const Address &src)
void cmpxchgl(const Address &address, Register reg)
void MoveRegister(Register rd, Register rm, Condition cond)
void Breakpoint() override
static constexpr intptr_t kCallExternalLabelSize
void EnterFrame(RegList regs, intptr_t frame_space)
void sqrtps(XmmRegister dst)
void fldl(const Address &src)
void unpckhps(XmmRegister dst, XmmRegister src)
void cmovlessl(Register dst, Register src)
void FinalizeHashForSize(intptr_t bit_size, Register dst, Register scratch=TMP) override
void orpd(XmmRegister dst, XmmRegister src)
void cmpb(const Address &address, const Immediate &imm)
void LoadObjectSafely(Register dst, const Object &object)
void shrdl(Register dst, Register src, Register shifter)
void AddImmediate(Register rd, int32_t value, Condition cond=AL)
void cmppsnlt(XmmRegister dst, XmmRegister src)
void movsxw(Register dst, Register src)
void fstpl(const Address &dst)
void bsrl(Register dst, Register src)
void unpcklps(XmmRegister dst, XmmRegister src)
void comiss(XmmRegister a, XmmRegister b)
void ffree(intptr_t value)
void ArithmeticShiftRightImmediate(Register reg, intptr_t shift) override
void movaps(XmmRegister dst, XmmRegister src)
LeafRuntimeScope(Assembler *assembler, intptr_t frame_size, bool preserve_registers)
static constexpr int kSize
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
ClipOpAndAA opAA SkRegion region
word ToRawSmi(const dart::Object &a)
bool IsOriginalObject(const Object &object)
int32_t CreateJitCookie()
bool IsInOldSpace(const Object &obj)
const Object & ToObject(const Code &handle)
const Register kWriteBarrierSlotReg
static const struct dart::ALIGN16 float_negate_constant
static const struct dart::ALIGN16 float_not_constant
const Register kWriteBarrierObjectReg
constexpr int32_t kMinInt32
static const struct dart::ALIGN16 float_absolute_constant
const Register kWriteBarrierValueReg
static const struct dart::ALIGN16 double_negate_constant
static const struct dart::ALIGN16 float_zerow_constant
constexpr intptr_t kBitsPerInt32
static const struct dart::ALIGN16 double_abs_constant
const int kFpuRegisterSize
ByteRegister ByteRegisterOf(Register reg)
SINT Vec< 2 *N, T > join(const Vec< N, T > &lo, const Vec< N, T > &hi)
#define NOT_IN_PRODUCT(code)