Line data Source code
1 : // Copyright 2012 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #include "src/x64/assembler-x64.h"
6 :
7 : #include <cstring>
8 :
9 : #if V8_TARGET_ARCH_X64
10 :
11 : #if V8_LIBC_MSVCRT
12 : #include <intrin.h> // _xgetbv()
13 : #endif
14 : #if V8_OS_MACOSX
15 : #include <sys/sysctl.h>
16 : #endif
17 :
18 : #include "src/assembler-inl.h"
19 : #include "src/base/bits.h"
20 : #include "src/base/cpu.h"
21 : #include "src/deoptimizer.h"
22 : #include "src/macro-assembler.h"
23 : #include "src/string-constants.h"
24 : #include "src/v8.h"
25 :
26 : namespace v8 {
27 : namespace internal {
28 :
29 : // -----------------------------------------------------------------------------
30 : // Implementation of CpuFeatures
31 :
32 : namespace {
33 :
34 : V8_INLINE uint64_t xgetbv(unsigned int xcr) {
35 : #if V8_LIBC_MSVCRT
36 : return _xgetbv(xcr);
37 : #else
38 : unsigned eax, edx;
39 : // Check xgetbv; this uses a .byte sequence instead of the instruction
40 : // directly because older assemblers do not include support for xgetbv and
41 : // there is no easy way to conditionally compile based on the assembler
42 : // used.
43 60991 : __asm__ volatile(".byte 0x0F, 0x01, 0xD0" : "=a"(eax), "=d"(edx) : "c"(xcr));
44 60991 : return static_cast<uint64_t>(eax) | (static_cast<uint64_t>(edx) << 32);
45 : #endif
46 : }
47 :
48 : bool OSHasAVXSupport() {
49 : #if V8_OS_MACOSX
50 : // Mac OS X up to 10.9 has a bug where AVX transitions were indeed being
51 : // caused by ISRs, so we detect that here and disable AVX in that case.
52 : char buffer[128];
53 : size_t buffer_size = arraysize(buffer);
54 : int ctl_name[] = {CTL_KERN, KERN_OSRELEASE};
55 : if (sysctl(ctl_name, 2, buffer, &buffer_size, nullptr, 0) != 0) {
56 : FATAL("V8 failed to get kernel version");
57 : }
58 : // The buffer now contains a string of the form XX.YY.ZZ, where
59 : // XX is the major kernel version component.
60 : char* period_pos = strchr(buffer, '.');
61 : DCHECK_NOT_NULL(period_pos);
62 : *period_pos = '\0';
63 : long kernel_version_major = strtol(buffer, nullptr, 10); // NOLINT
64 : if (kernel_version_major <= 13) return false;
65 : #endif // V8_OS_MACOSX
66 : // Check whether OS claims to support AVX.
67 : uint64_t feature_mask = xgetbv(0); // XCR_XFEATURE_ENABLED_MASK
68 60991 : return (feature_mask & 0x6) == 0x6;
69 : }
70 :
71 : } // namespace
72 :
73 :
74 60992 : void CpuFeatures::ProbeImpl(bool cross_compile) {
75 60992 : base::CPU cpu;
76 60992 : CHECK(cpu.has_sse2()); // SSE2 support is mandatory.
77 60992 : CHECK(cpu.has_cmov()); // CMOV support is mandatory.
78 :
79 : // Only use statically determined features for cross compile (snapshot).
80 60993 : if (cross_compile) return;
81 :
82 60991 : if (cpu.has_sse41() && FLAG_enable_sse4_1) {
83 60981 : supported_ |= 1u << SSE4_1;
84 60981 : supported_ |= 1u << SSSE3;
85 : }
86 60991 : if (cpu.has_ssse3() && FLAG_enable_ssse3) supported_ |= 1u << SSSE3;
87 60991 : if (cpu.has_sse3() && FLAG_enable_sse3) supported_ |= 1u << SSE3;
88 : // SAHF is not generally available in long mode.
89 60991 : if (cpu.has_sahf() && FLAG_enable_sahf) supported_ |= 1u << SAHF;
90 121982 : if (cpu.has_avx() && FLAG_enable_avx && cpu.has_osxsave() &&
91 : OSHasAVXSupport()) {
92 60991 : supported_ |= 1u << AVX;
93 : }
94 60991 : if (cpu.has_fma3() && FLAG_enable_fma3 && cpu.has_osxsave() &&
95 : OSHasAVXSupport()) {
96 0 : supported_ |= 1u << FMA3;
97 : }
98 60991 : if (cpu.has_bmi1() && FLAG_enable_bmi1) supported_ |= 1u << BMI1;
99 60991 : if (cpu.has_bmi2() && FLAG_enable_bmi2) supported_ |= 1u << BMI2;
100 60991 : if (cpu.has_lzcnt() && FLAG_enable_lzcnt) supported_ |= 1u << LZCNT;
101 60991 : if (cpu.has_popcnt() && FLAG_enable_popcnt) supported_ |= 1u << POPCNT;
102 60991 : if (strcmp(FLAG_mcpu, "auto") == 0) {
103 60991 : if (cpu.is_atom()) supported_ |= 1u << ATOM;
104 0 : } else if (strcmp(FLAG_mcpu, "atom") == 0) {
105 0 : supported_ |= 1u << ATOM;
106 : }
107 : }
108 :
109 :
110 5 : void CpuFeatures::PrintTarget() { }
111 5 : void CpuFeatures::PrintFeatures() {
112 55 : printf(
113 : "SSE3=%d SSSE3=%d SSE4_1=%d SAHF=%d AVX=%d FMA3=%d BMI1=%d BMI2=%d "
114 : "LZCNT=%d "
115 : "POPCNT=%d ATOM=%d\n",
116 : CpuFeatures::IsSupported(SSE3), CpuFeatures::IsSupported(SSSE3),
117 : CpuFeatures::IsSupported(SSE4_1), CpuFeatures::IsSupported(SAHF),
118 : CpuFeatures::IsSupported(AVX), CpuFeatures::IsSupported(FMA3),
119 : CpuFeatures::IsSupported(BMI1), CpuFeatures::IsSupported(BMI2),
120 : CpuFeatures::IsSupported(LZCNT), CpuFeatures::IsSupported(POPCNT),
121 : CpuFeatures::IsSupported(ATOM));
122 5 : }
123 :
124 : // -----------------------------------------------------------------------------
125 : // Implementation of RelocInfo
126 :
127 557706 : uint32_t RelocInfo::wasm_call_tag() const {
128 : DCHECK(rmode_ == WASM_CALL || rmode_ == WASM_STUB_CALL);
129 1115412 : return ReadUnalignedValue<uint32_t>(pc_);
130 : }
131 :
132 : // -----------------------------------------------------------------------------
133 : // Implementation of Operand
134 :
135 : namespace {
136 : class OperandBuilder {
137 : public:
138 51972409 : OperandBuilder(Register base, int32_t disp) {
139 51972409 : if (base == rsp || base == r12) {
140 : // SIB byte is needed to encode (rsp + offset) or (r12 + offset).
141 : set_sib(times_1, rsp, base);
142 : }
143 :
144 51972409 : if (disp == 0 && base != rbp && base != r13) {
145 : set_modrm(0, base);
146 88635226 : } else if (is_int8(disp)) {
147 : set_modrm(1, base);
148 : set_disp8(disp);
149 : } else {
150 : set_modrm(2, base);
151 : set_disp32(disp);
152 : }
153 51972409 : }
154 :
155 2496740 : OperandBuilder(Register base, Register index, ScaleFactor scale,
156 : int32_t disp) {
157 : DCHECK(index != rsp);
158 : set_sib(scale, index, base);
159 2496740 : if (disp == 0 && base != rbp && base != r13) {
160 : // This call to set_modrm doesn't overwrite the REX.B (or REX.X) bits
161 : // possibly set by set_sib.
162 : set_modrm(0, rsp);
163 2490124 : } else if (is_int8(disp)) {
164 : set_modrm(1, rsp);
165 : set_disp8(disp);
166 : } else {
167 : set_modrm(2, rsp);
168 : set_disp32(disp);
169 : }
170 2496740 : }
171 :
172 152413 : OperandBuilder(Register index, ScaleFactor scale, int32_t disp) {
173 : DCHECK(index != rsp);
174 : set_modrm(0, rsp);
175 : set_sib(scale, index, rbp);
176 : set_disp32(disp);
177 152413 : }
178 :
179 : OperandBuilder(Label* label, int addend) {
180 365732 : data_.addend = addend;
181 : DCHECK_NOT_NULL(label);
182 : DCHECK(addend == 0 || (is_int8(addend) && label->is_bound()));
183 : set_modrm(0, rbp);
184 : set_disp64(reinterpret_cast<intptr_t>(label));
185 : }
186 :
187 2028 : OperandBuilder(Operand operand, int32_t offset) {
188 : DCHECK_GE(operand.data().len, 1);
189 : // Operand encodes REX ModR/M [SIB] [Disp].
190 2028 : byte modrm = operand.data().buf[0];
191 : DCHECK_LT(modrm, 0xC0); // Disallow mode 3 (register target).
192 : bool has_sib = ((modrm & 0x07) == 0x04);
193 2028 : byte mode = modrm & 0xC0;
194 2028 : int disp_offset = has_sib ? 2 : 1;
195 2028 : int base_reg = (has_sib ? operand.data().buf[1] : modrm) & 0x07;
196 : // Mode 0 with rbp/r13 as ModR/M or SIB base register always has a 32-bit
197 : // displacement.
198 : bool is_baseless =
199 2028 : (mode == 0) && (base_reg == 0x05); // No base or RIP base.
200 : int32_t disp_value = 0;
201 2028 : if (mode == 0x80 || is_baseless) {
202 : // Mode 2 or mode 0 with rbp/r13 as base: Word displacement.
203 : disp_value = ReadUnalignedValue<int32_t>(
204 : reinterpret_cast<Address>(&operand.data().buf[disp_offset]));
205 1998 : } else if (mode == 0x40) {
206 : // Mode 1: Byte displacement.
207 1933 : disp_value = static_cast<signed char>(operand.data().buf[disp_offset]);
208 : }
209 :
210 : // Write new operand with same registers, but with modified displacement.
211 : DCHECK(offset >= 0 ? disp_value + offset > disp_value
212 : : disp_value + offset < disp_value); // No overflow.
213 2028 : disp_value += offset;
214 2028 : data_.rex = operand.data().rex;
215 4056 : if (!is_int8(disp_value) || is_baseless) {
216 : // Need 32 bits of displacement, mode 2 or mode 1 with register rbp/r13.
217 50 : data_.buf[0] = (modrm & 0x3F) | (is_baseless ? 0x00 : 0x80);
218 50 : data_.len = disp_offset + 4;
219 : WriteUnalignedValue(reinterpret_cast<Address>(&data_.buf[disp_offset]),
220 : disp_value);
221 1978 : } else if (disp_value != 0 || (base_reg == 0x05)) {
222 : // Need 8 bits of displacement.
223 1948 : data_.buf[0] = (modrm & 0x3F) | 0x40; // Mode 1.
224 1948 : data_.len = disp_offset + 1;
225 1948 : data_.buf[disp_offset] = static_cast<byte>(disp_value);
226 : } else {
227 : // Need no displacement.
228 30 : data_.buf[0] = (modrm & 0x3F); // Mode 0.
229 30 : data_.len = disp_offset;
230 : }
231 2028 : if (has_sib) {
232 45 : data_.buf[1] = operand.data().buf[1];
233 : }
234 2028 : }
235 :
236 : void set_modrm(int mod, Register rm_reg) {
237 : DCHECK(is_uint2(mod));
238 54621562 : data_.buf[0] = mod << 6 | rm_reg.low_bits();
239 : // Set REX.B to the high bit of rm.code().
240 51972409 : data_.rex |= rm_reg.high_bit();
241 : }
242 :
243 : void set_sib(ScaleFactor scale, Register index, Register base) {
244 : DCHECK_EQ(data_.len, 1);
245 : DCHECK(is_uint2(scale));
246 : // Use SIB with no index register only for base rsp or r12. Otherwise we
247 : // would skip the SIB byte entirely.
248 : DCHECK(index != rsp || base == rsp || base == r12);
249 12777434 : data_.buf[1] = (scale << 6) | (index.low_bits() << 3) | base.low_bits();
250 10128281 : data_.rex |= index.high_bit() << 1 | base.high_bit();
251 7631541 : data_.len = 2;
252 : }
253 :
254 : void set_disp8(int disp) {
255 : DCHECK(is_int8(disp));
256 : DCHECK(data_.len == 1 || data_.len == 2);
257 33625046 : int8_t* p = reinterpret_cast<int8_t*>(&data_.buf[data_.len]);
258 33625046 : *p = disp;
259 33625046 : data_.len += sizeof(int8_t);
260 : }
261 :
262 : void set_disp32(int disp) {
263 : DCHECK(data_.len == 1 || data_.len == 2);
264 11708968 : Address p = reinterpret_cast<Address>(&data_.buf[data_.len]);
265 : WriteUnalignedValue(p, disp);
266 12090042 : data_.len += sizeof(int32_t);
267 : }
268 :
269 : void set_disp64(int64_t disp) {
270 : DCHECK_EQ(1, data_.len);
271 : Address p = reinterpret_cast<Address>(&data_.buf[data_.len]);
272 : WriteUnalignedValue(p, disp);
273 : data_.len += sizeof(disp);
274 : }
275 :
276 : const Operand::Data& data() const { return data_; }
277 :
278 : private:
279 : Operand::Data data_;
280 : };
281 : } // namespace
282 :
283 51969128 : Operand::Operand(Register base, int32_t disp)
284 51969128 : : data_(OperandBuilder(base, disp).data()) {}
285 :
286 2496707 : Operand::Operand(Register base, Register index, ScaleFactor scale, int32_t disp)
287 2496707 : : data_(OperandBuilder(base, index, scale, disp).data()) {}
288 :
289 152413 : Operand::Operand(Register index, ScaleFactor scale, int32_t disp)
290 152413 : : data_(OperandBuilder(index, scale, disp).data()) {}
291 :
292 365732 : Operand::Operand(Label* label, int addend)
293 5428449 : : data_(OperandBuilder(label, addend).data()) {}
294 :
295 2028 : Operand::Operand(Operand operand, int32_t offset)
296 2028 : : data_(OperandBuilder(operand, offset).data()) {}
297 :
298 464 : bool Operand::AddressUsesRegister(Register reg) const {
299 : int code = reg.code();
300 : DCHECK_NE(data_.buf[0] & 0xC0, 0xC0); // Always a memory operand.
301 : // Start with only low three bits of base register. Initial decoding
302 : // doesn't distinguish on the REX.B bit.
303 464 : int base_code = data_.buf[0] & 0x07;
304 464 : if (base_code == rsp.code()) {
305 : // SIB byte present in buf_[1].
306 : // Check the index register from the SIB byte + REX.X prefix.
307 368 : int index_code = ((data_.buf[1] >> 3) & 0x07) | ((data_.rex & 0x02) << 2);
308 : // Index code (including REX.X) of 0x04 (rsp) means no index register.
309 368 : if (index_code != rsp.code() && index_code == code) return true;
310 : // Add REX.B to get the full base register code.
311 304 : base_code = (data_.buf[1] & 0x07) | ((data_.rex & 0x01) << 3);
312 : // A base register of 0x05 (rbp) with mod = 0 means no base register.
313 304 : if (base_code == rbp.code() && ((data_.buf[0] & 0xC0) == 0)) return false;
314 304 : return code == base_code;
315 : } else {
316 : // A base register with low bits of 0x05 (rbp or r13) and mod = 0 means
317 : // no base register.
318 96 : if (base_code == rbp.code() && ((data_.buf[0] & 0xC0) == 0)) return false;
319 96 : base_code |= ((data_.rex & 0x01) << 3);
320 96 : return code == base_code;
321 : }
322 : }
323 :
324 3343372 : void Assembler::AllocateAndInstallRequestedHeapObjects(Isolate* isolate) {
325 : DCHECK_IMPLIES(isolate == nullptr, heap_object_requests_.empty());
326 3385234 : for (auto& request : heap_object_requests_) {
327 41862 : Address pc = reinterpret_cast<Address>(buffer_start_) + request.offset();
328 41862 : switch (request.kind()) {
329 : case HeapObjectRequest::kHeapNumber: {
330 : Handle<HeapNumber> object = isolate->factory()->NewHeapNumber(
331 39724 : request.heap_number(), AllocationType::kOld);
332 : WriteUnalignedValue(pc, object);
333 : break;
334 : }
335 : case HeapObjectRequest::kStringConstant: {
336 : const StringConstantBase* str = request.string();
337 2138 : CHECK_NOT_NULL(str);
338 2138 : Handle<String> allocated = str->AllocateStringConstant(isolate);
339 : WriteUnalignedValue(pc, allocated);
340 : break;
341 : }
342 : }
343 : }
344 3343372 : }
345 :
346 : // Partial Constant Pool.
347 48300871 : bool ConstPool::AddSharedEntry(uint64_t data, int offset) {
348 : auto existing = entries_.find(data);
349 48300871 : if (existing == entries_.end()) {
350 86476419 : entries_.insert(std::make_pair(data, offset + kMoveImm64Offset));
351 43238261 : return false;
352 : }
353 :
354 : // Make sure this is called with strictly ascending offsets.
355 : DCHECK_GT(offset + kMoveImm64Offset, existing->second);
356 :
357 10125430 : entries_.insert(std::make_pair(data, offset + kMoveRipRelativeDispOffset));
358 5062717 : return true;
359 : }
360 :
361 54551529 : bool ConstPool::TryRecordEntry(intptr_t data, RelocInfo::Mode mode) {
362 54551529 : if (!FLAG_partial_constant_pool) return false;
363 54551537 : if (!RelocInfo::IsShareableRelocMode(mode)) return false;
364 :
365 : // Currently, partial constant pool only handles the following kinds of
366 : // RelocInfo.
367 48300882 : if (mode != RelocInfo::NONE && mode != RelocInfo::EXTERNAL_REFERENCE &&
368 : mode != RelocInfo::OFF_HEAP_TARGET)
369 : return false;
370 :
371 48300881 : uint64_t raw_data = static_cast<uint64_t>(data);
372 48300881 : int offset = assm_->pc_offset();
373 48300881 : return AddSharedEntry(raw_data, offset);
374 : }
375 :
376 0 : bool ConstPool::IsMoveRipRelative(Address instr) {
377 0 : return (ReadUnalignedValue<uint32_t>(instr) & kMoveRipRelativeMask) ==
378 0 : kMoveRipRelativeInstr;
379 : }
380 :
381 0 : void ConstPool::Clear() { entries_.clear(); }
382 :
383 2213393 : void ConstPool::PatchEntries() {
384 9427424 : for (EntryMap::iterator iter = entries_.begin(); iter != entries_.end();
385 : iter = entries_.upper_bound(iter->first)) {
386 : std::pair<EntryMap::iterator, EntryMap::iterator> range =
387 7214020 : entries_.equal_range(iter->first);
388 : int constant_entry_offset = 0;
389 19490801 : for (EntryMap::iterator it = range.first; it != range.second; it++) {
390 12276770 : if (it == range.first) {
391 7214054 : constant_entry_offset = it->second;
392 7214054 : continue;
393 : }
394 :
395 : DCHECK_GT(constant_entry_offset, 0);
396 : DCHECK_LT(constant_entry_offset, it->second);
397 : int32_t disp32 =
398 5062716 : constant_entry_offset - (it->second + kRipRelativeDispSize);
399 5062716 : Address disp_addr = assm_->addr_at(it->second);
400 :
401 : // Check if the instruction is actually a rip-relative move.
402 : DCHECK(IsMoveRipRelative(disp_addr - kMoveRipRelativeDispOffset));
403 : // The displacement of the rip-relative move should be 0 before patching.
404 : DCHECK(ReadUnalignedValue<uint32_t>(disp_addr) == 0);
405 : WriteUnalignedValue(disp_addr, disp32);
406 : }
407 : }
408 : Clear();
409 2213441 : }
410 :
411 2655202 : void Assembler::PatchConstPool() {
412 : // There is nothing to do if there are no pending entries.
413 6000437 : if (constpool_.IsEmpty()) {
414 : return;
415 : }
416 2213383 : constpool_.PatchEntries();
417 : }
418 :
419 0 : bool Assembler::UseConstPoolFor(RelocInfo::Mode rmode) {
420 0 : if (!FLAG_partial_constant_pool) return false;
421 0 : return (rmode == RelocInfo::NONE || rmode == RelocInfo::EXTERNAL_REFERENCE ||
422 : rmode == RelocInfo::OFF_HEAP_TARGET);
423 : }
424 :
425 : // -----------------------------------------------------------------------------
426 : // Implementation of Assembler.
427 :
428 41344517 : Assembler::Assembler(const AssemblerOptions& options,
429 : std::unique_ptr<AssemblerBuffer> buffer)
430 124038552 : : AssemblerBase(options, std::move(buffer)), constpool_(this) {
431 82699502 : reloc_info_writer.Reposition(buffer_start_ + buffer_->size(), pc_);
432 41349540 : if (CpuFeatures::IsSupported(SSE4_1)) {
433 : EnableCpuFeature(SSSE3);
434 : }
435 :
436 : #if defined(V8_OS_WIN_X64)
437 : if (options.collect_win64_unwind_info) {
438 : xdata_encoder_ = std::make_unique<win64_unwindinfo::XdataEncoder>(*this);
439 : }
440 : #endif
441 41349540 : }
442 :
443 3345235 : void Assembler::GetCode(Isolate* isolate, CodeDesc* desc,
444 : SafepointTableBuilder* safepoint_table_builder,
445 : int handler_table_offset) {
446 : PatchConstPool();
447 : DCHECK(constpool_.IsEmpty());
448 :
449 3345239 : const int code_comments_size = WriteCodeComments();
450 :
451 : // At this point overflow() may be true, but the gap ensures
452 : // that we are still not overlapping instructions and relocation info.
453 : DCHECK(pc_ <= reloc_info_writer.pos()); // No overlap.
454 :
455 3343923 : AllocateAndInstallRequestedHeapObjects(isolate);
456 :
457 : // Set up code descriptor.
458 : // TODO(jgruber): Reconsider how these offsets and sizes are maintained up to
459 : // this point to make CodeDesc initialization less fiddly.
460 :
461 : static constexpr int kConstantPoolSize = 0;
462 : const int instruction_size = pc_offset();
463 3343591 : const int code_comments_offset = instruction_size - code_comments_size;
464 : const int constant_pool_offset = code_comments_offset - kConstantPoolSize;
465 : const int handler_table_offset2 = (handler_table_offset == kNoHandlerTable)
466 : ? constant_pool_offset
467 3343591 : : handler_table_offset;
468 : const int safepoint_table_offset =
469 : (safepoint_table_builder == kNoSafepointTable)
470 : ? handler_table_offset2
471 3343591 : : safepoint_table_builder->GetCodeOffset();
472 : const int reloc_info_offset =
473 6687062 : static_cast<int>(reloc_info_writer.pos() - buffer_->start());
474 : CodeDesc::Initialize(desc, this, safepoint_table_offset,
475 : handler_table_offset2, constant_pool_offset,
476 3344101 : code_comments_offset, reloc_info_offset);
477 3344734 : }
478 :
479 2639804 : void Assembler::FinalizeJumpOptimizationInfo() {
480 : // Collection stage
481 : auto jump_opt = jump_optimization_info();
482 2639804 : if (jump_opt && jump_opt->is_collecting()) {
483 : auto& bitmap = jump_opt->farjmp_bitmap();
484 65688 : int num = static_cast<int>(farjmp_positions_.size());
485 65688 : if (num && bitmap.empty()) {
486 : bool can_opt = false;
487 :
488 57456 : bitmap.resize((num + 31) / 32, 0);
489 3942790 : for (int i = 0; i < num; i++) {
490 1942667 : int disp_pos = farjmp_positions_[i];
491 1942667 : int disp = long_at(disp_pos);
492 3885334 : if (is_int8(disp)) {
493 2209192 : bitmap[i / 32] |= 1 << (i & 31);
494 : can_opt = true;
495 : }
496 : }
497 57456 : if (can_opt) {
498 : jump_opt->set_optimizable();
499 : }
500 : }
501 : }
502 2639804 : }
503 :
504 : #if defined(V8_OS_WIN_X64)
505 : win64_unwindinfo::BuiltinUnwindInfo Assembler::GetUnwindInfo() const {
506 : DCHECK(options().collect_win64_unwind_info);
507 : DCHECK_NOT_NULL(xdata_encoder_);
508 : return xdata_encoder_->unwinding_info();
509 : }
510 : #endif
511 :
512 3081592 : void Assembler::Align(int m) {
513 : DCHECK(base::bits::IsPowerOfTwo(m));
514 3138412 : int delta = (m - (pc_offset() & (m - 1))) & (m - 1);
515 3138412 : Nop(delta);
516 3081887 : }
517 :
518 :
519 56820 : void Assembler::CodeTargetAlign() {
520 : Align(16); // Preferred alignment of jump targets on x64.
521 56821 : }
522 :
523 :
524 0 : bool Assembler::IsNop(Address addr) {
525 0 : byte* a = reinterpret_cast<byte*>(addr);
526 0 : while (*a == 0x66) a++;
527 0 : if (*a == 0x90) return true;
528 0 : if (a[0] == 0xF && a[1] == 0x1F) return true;
529 0 : return false;
530 : }
531 :
532 :
533 38784349 : void Assembler::bind_to(Label* L, int pos) {
534 : DCHECK(!L->is_bound()); // Label may only be bound once.
535 : DCHECK(0 <= pos && pos <= pc_offset()); // Position must be valid.
536 38784349 : if (L->is_linked()) {
537 : int current = L->pos();
538 14224068 : int next = long_at(current);
539 20570424 : while (next != current) {
540 6346352 : if (current >= 4 && long_at(current - 4) == 0) {
541 : // Absolute address.
542 0 : intptr_t imm64 = reinterpret_cast<intptr_t>(buffer_start_ + pos);
543 0 : WriteUnalignedValue(addr_at(current - 4), imm64);
544 2 : internal_reference_positions_.push_back(current - 4);
545 : } else {
546 : // Relative address, relative to point after address.
547 3173176 : int imm32 = pos - (current + sizeof(int32_t));
548 : long_at_put(current, imm32);
549 : }
550 : current = next;
551 3173178 : next = long_at(next);
552 : }
553 : // Fix up last fixup on linked list.
554 28365032 : if (current >= 4 && long_at(current - 4) == 0) {
555 : // Absolute address.
556 2048 : intptr_t imm64 = reinterpret_cast<intptr_t>(buffer_start_ + pos);
557 2048 : WriteUnalignedValue(addr_at(current - 4), imm64);
558 4096 : internal_reference_positions_.push_back(current - 4);
559 : } else {
560 : // Relative address, relative to point after address.
561 14222022 : int imm32 = pos - (current + sizeof(int32_t));
562 : long_at_put(current, imm32);
563 : }
564 : }
565 39494960 : while (L->is_near_linked()) {
566 : int fixup_pos = L->near_link_pos();
567 : int offset_to_next =
568 710609 : static_cast<int>(*reinterpret_cast<int8_t*>(addr_at(fixup_pos)));
569 : DCHECK_LE(offset_to_next, 0);
570 710609 : int disp = pos - (fixup_pos + sizeof(int8_t));
571 1421218 : CHECK(is_int8(disp));
572 : set_byte_at(fixup_pos, disp);
573 710609 : if (offset_to_next < 0) {
574 2308 : L->link_to(fixup_pos + offset_to_next, Label::kNear);
575 : } else {
576 : L->UnuseNear();
577 : }
578 : }
579 :
580 : // Optimization stage
581 : auto jump_opt = jump_optimization_info();
582 38784351 : if (jump_opt && jump_opt->is_optimizing()) {
583 : auto it = label_farjmp_maps_.find(L);
584 4041453 : if (it != label_farjmp_maps_.end()) {
585 : auto& pos_vector = it->second;
586 2016279 : for (auto fixup_pos : pos_vector) {
587 1104596 : int disp = pos - (fixup_pos + sizeof(int8_t));
588 2209192 : CHECK(is_int8(disp));
589 : set_byte_at(fixup_pos, disp);
590 : }
591 : label_farjmp_maps_.erase(it);
592 : }
593 : }
594 : L->bind_to(pos);
595 38784351 : }
596 :
597 :
598 33722211 : void Assembler::bind(Label* L) {
599 38784929 : bind_to(L, pc_offset());
600 33722388 : }
601 :
602 0 : void Assembler::record_farjmp_position(Label* L, int pos) {
603 1104596 : auto& pos_vector = label_farjmp_maps_[L];
604 1104596 : pos_vector.push_back(pos);
605 0 : }
606 :
607 1942499 : bool Assembler::is_optimizable_farjmp(int idx) {
608 1942499 : if (predictable_code_size()) return false;
609 :
610 : auto jump_opt = jump_optimization_info();
611 1942499 : CHECK(jump_opt->is_optimizing());
612 :
613 : auto& bitmap = jump_opt->farjmp_bitmap();
614 1942499 : CHECK(idx < static_cast<int>(bitmap.size() * 32));
615 3884998 : return !!(bitmap[idx / 32] & (1 << (idx & 31)));
616 : }
617 :
618 44229 : void Assembler::GrowBuffer() {
619 : DCHECK(buffer_overflow());
620 :
621 : // Compute new buffer size.
622 : DCHECK_EQ(buffer_start_, buffer_->start());
623 44229 : int old_size = buffer_->size();
624 44229 : int new_size = 2 * old_size;
625 :
626 : // Some internal data structures overflow for very large buffers,
627 : // they must ensure that kMaximalBufferSize is not too large.
628 44229 : if (new_size > kMaximalBufferSize) {
629 0 : V8::FatalProcessOutOfMemory(nullptr, "Assembler::GrowBuffer");
630 : }
631 :
632 : // Set up new buffer.
633 44229 : std::unique_ptr<AssemblerBuffer> new_buffer = buffer_->Grow(new_size);
634 : DCHECK_EQ(new_size, new_buffer->size());
635 44229 : byte* new_start = new_buffer->start();
636 :
637 : // Copy the data.
638 44229 : intptr_t pc_delta = new_start - buffer_start_;
639 44229 : intptr_t rc_delta = (new_start + new_size) - (buffer_start_ + old_size);
640 44229 : size_t reloc_size = (buffer_start_ + old_size) - reloc_info_writer.pos();
641 44229 : MemMove(new_start, buffer_start_, pc_offset());
642 44229 : MemMove(rc_delta + reloc_info_writer.pos(), reloc_info_writer.pos(),
643 : reloc_size);
644 :
645 : // Switch buffers.
646 : buffer_ = std::move(new_buffer);
647 44229 : buffer_start_ = new_start;
648 44229 : pc_ += pc_delta;
649 44229 : reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
650 : reloc_info_writer.last_pc() + pc_delta);
651 :
652 : // Relocate internal references.
653 252628 : for (auto pos : internal_reference_positions_) {
654 208399 : Address p = reinterpret_cast<Address>(buffer_start_ + pos);
655 208399 : WriteUnalignedValue(p, ReadUnalignedValue<intptr_t>(p) + pc_delta);
656 : }
657 :
658 : DCHECK(!buffer_overflow());
659 44229 : }
660 :
661 60388800 : void Assembler::emit_operand(int code, Operand adr) {
662 : DCHECK(is_uint3(code));
663 60388800 : const unsigned length = adr.data().len;
664 : DCHECK_GT(length, 0);
665 :
666 : // Emit updated ModR/M byte containing the given register.
667 : DCHECK_EQ(adr.data().buf[0] & 0x38, 0);
668 60388800 : *pc_++ = adr.data().buf[0] | code << 3;
669 :
670 : // Recognize RIP relative addressing.
671 60388800 : if (adr.data().buf[0] == 5) {
672 : DCHECK_EQ(9u, length);
673 : Label* label = ReadUnalignedValue<Label*>(
674 : reinterpret_cast<Address>(&adr.data().buf[1]));
675 5428450 : if (label->is_bound()) {
676 : int offset =
677 113 : label->pos() - pc_offset() - sizeof(int32_t) + adr.data().addend;
678 : DCHECK_GE(0, offset);
679 : emitl(offset);
680 5428337 : } else if (label->is_linked()) {
681 0 : emitl(label->pos());
682 0 : label->link_to(pc_offset() - sizeof(int32_t));
683 : } else {
684 : DCHECK(label->is_unused());
685 : int32_t current = pc_offset();
686 5428337 : emitl(current);
687 : label->link_to(current);
688 : }
689 : } else {
690 : // Emit the rest of the encoded operand.
691 145201993 : for (unsigned i = 1; i < length; i++) *pc_++ = adr.data().buf[i];
692 : }
693 60388800 : }
694 :
695 :
696 : // Assembler Instruction implementations.
697 :
698 2897361 : void Assembler::arithmetic_op(byte opcode, Register reg, Operand op, int size) {
699 : EnsureSpace ensure_space(this);
700 : emit_rex(reg, op, size);
701 : emit(opcode);
702 : emit_operand(reg, op);
703 2897855 : }
704 :
705 :
706 6545458 : void Assembler::arithmetic_op(byte opcode,
707 : Register reg,
708 : Register rm_reg,
709 : int size) {
710 : EnsureSpace ensure_space(this);
711 : DCHECK_EQ(opcode & 0xC6, 2);
712 6545526 : if (rm_reg.low_bits() == 4) { // Forces SIB byte.
713 : // Swap reg and rm_reg and change opcode operand order.
714 272539 : emit_rex(rm_reg, reg, size);
715 272539 : emit(opcode ^ 0x02);
716 : emit_modrm(rm_reg, reg);
717 : } else {
718 6272987 : emit_rex(reg, rm_reg, size);
719 : emit(opcode);
720 : emit_modrm(reg, rm_reg);
721 : }
722 6545512 : }
723 :
724 :
725 448 : void Assembler::arithmetic_op_16(byte opcode, Register reg, Register rm_reg) {
726 : EnsureSpace ensure_space(this);
727 : DCHECK_EQ(opcode & 0xC6, 2);
728 448 : if (rm_reg.low_bits() == 4) { // Forces SIB byte.
729 : // Swap reg and rm_reg and change opcode operand order.
730 : emit(0x66);
731 : emit_optional_rex_32(rm_reg, reg);
732 0 : emit(opcode ^ 0x02);
733 : emit_modrm(rm_reg, reg);
734 : } else {
735 : emit(0x66);
736 : emit_optional_rex_32(reg, rm_reg);
737 : emit(opcode);
738 : emit_modrm(reg, rm_reg);
739 : }
740 448 : }
741 :
742 515 : void Assembler::arithmetic_op_16(byte opcode, Register reg, Operand rm_reg) {
743 : EnsureSpace ensure_space(this);
744 : emit(0x66);
745 : emit_optional_rex_32(reg, rm_reg);
746 : emit(opcode);
747 : emit_operand(reg, rm_reg);
748 515 : }
749 :
750 913 : void Assembler::arithmetic_op_8(byte opcode, Register reg, Operand op) {
751 : EnsureSpace ensure_space(this);
752 913 : if (!reg.is_byte_register()) {
753 : emit_rex_32(reg, op);
754 : } else {
755 : emit_optional_rex_32(reg, op);
756 : }
757 : emit(opcode);
758 : emit_operand(reg, op);
759 913 : }
760 :
761 :
762 3358 : void Assembler::arithmetic_op_8(byte opcode, Register reg, Register rm_reg) {
763 : EnsureSpace ensure_space(this);
764 : DCHECK_EQ(opcode & 0xC6, 2);
765 3358 : if (rm_reg.low_bits() == 4) { // Forces SIB byte.
766 : // Swap reg and rm_reg and change opcode operand order.
767 896 : if (!rm_reg.is_byte_register() || !reg.is_byte_register()) {
768 : // Register is not one of al, bl, cl, dl. Its encoding needs REX.
769 : emit_rex_32(rm_reg, reg);
770 : }
771 896 : emit(opcode ^ 0x02);
772 : emit_modrm(rm_reg, reg);
773 : } else {
774 2462 : if (!reg.is_byte_register() || !rm_reg.is_byte_register()) {
775 : // Register is not one of al, bl, cl, dl. Its encoding needs REX.
776 : emit_rex_32(reg, rm_reg);
777 : }
778 : emit(opcode);
779 : emit_modrm(reg, rm_reg);
780 : }
781 3358 : }
782 :
783 :
784 10637170 : void Assembler::immediate_arithmetic_op(byte subcode,
785 : Register dst,
786 : Immediate src,
787 : int size) {
788 : EnsureSpace ensure_space(this);
789 : emit_rex(dst, size);
790 21274646 : if (is_int8(src.value_) && RelocInfo::IsNone(src.rmode_)) {
791 : emit(0x83);
792 9644489 : emit_modrm(subcode, dst);
793 : emit(src.value_);
794 992834 : } else if (dst == rax) {
795 115907 : emit(0x05 | (subcode << 3));
796 115907 : emit(src);
797 : } else {
798 : emit(0x81);
799 876927 : emit_modrm(subcode, dst);
800 876927 : emit(src);
801 : }
802 10637323 : }
803 :
804 186208 : void Assembler::immediate_arithmetic_op(byte subcode, Operand dst,
805 : Immediate src, int size) {
806 : EnsureSpace ensure_space(this);
807 : emit_rex(dst, size);
808 372420 : if (is_int8(src.value_) && RelocInfo::IsNone(src.rmode_)) {
809 : emit(0x83);
810 176262 : emit_operand(subcode, dst);
811 : emit(src.value_);
812 : } else {
813 : emit(0x81);
814 9948 : emit_operand(subcode, dst);
815 9948 : emit(src);
816 : }
817 186217 : }
818 :
819 :
820 155163 : void Assembler::immediate_arithmetic_op_16(byte subcode,
821 : Register dst,
822 : Immediate src) {
823 : EnsureSpace ensure_space(this);
824 : emit(0x66); // Operand size override prefix.
825 : emit_optional_rex_32(dst);
826 310326 : if (is_int8(src.value_)) {
827 : emit(0x83);
828 8007 : emit_modrm(subcode, dst);
829 : emit(src.value_);
830 147156 : } else if (dst == rax) {
831 10910 : emit(0x05 | (subcode << 3));
832 : emitw(src.value_);
833 : } else {
834 : emit(0x81);
835 136246 : emit_modrm(subcode, dst);
836 : emitw(src.value_);
837 : }
838 155163 : }
839 :
840 224357 : void Assembler::immediate_arithmetic_op_16(byte subcode, Operand dst,
841 : Immediate src) {
842 : EnsureSpace ensure_space(this);
843 : emit(0x66); // Operand size override prefix.
844 : emit_optional_rex_32(dst);
845 448714 : if (is_int8(src.value_)) {
846 : emit(0x83);
847 112 : emit_operand(subcode, dst);
848 : emit(src.value_);
849 : } else {
850 : emit(0x81);
851 224245 : emit_operand(subcode, dst);
852 : emitw(src.value_);
853 : }
854 224357 : }
855 :
856 15210 : void Assembler::immediate_arithmetic_op_8(byte subcode, Operand dst,
857 : Immediate src) {
858 : EnsureSpace ensure_space(this);
859 : emit_optional_rex_32(dst);
860 : DCHECK(is_int8(src.value_) || is_uint8(src.value_));
861 : emit(0x80);
862 15210 : emit_operand(subcode, dst);
863 15210 : emit(src.value_);
864 15210 : }
865 :
866 :
867 9404 : void Assembler::immediate_arithmetic_op_8(byte subcode,
868 : Register dst,
869 : Immediate src) {
870 : EnsureSpace ensure_space(this);
871 9404 : if (!dst.is_byte_register()) {
872 : // Register is not one of al, bl, cl, dl. Its encoding needs REX.
873 : emit_rex_32(dst);
874 : }
875 : DCHECK(is_int8(src.value_) || is_uint8(src.value_));
876 : emit(0x80);
877 9404 : emit_modrm(subcode, dst);
878 9404 : emit(src.value_);
879 9404 : }
880 :
881 :
882 1246423 : void Assembler::shift(Register dst,
883 : Immediate shift_amount,
884 : int subcode,
885 : int size) {
886 : EnsureSpace ensure_space(this);
887 : DCHECK(size == kInt64Size ? is_uint6(shift_amount.value_)
888 : : is_uint5(shift_amount.value_));
889 1246507 : if (shift_amount.value_ == 1) {
890 : emit_rex(dst, size);
891 : emit(0xD1);
892 : emit_modrm(subcode, dst);
893 : } else {
894 : emit_rex(dst, size);
895 : emit(0xC1);
896 : emit_modrm(subcode, dst);
897 : emit(shift_amount.value_);
898 : }
899 1246507 : }
900 :
901 :
902 40 : void Assembler::shift(Operand dst, Immediate shift_amount, int subcode,
903 : int size) {
904 : EnsureSpace ensure_space(this);
905 : DCHECK(size == kInt64Size ? is_uint6(shift_amount.value_)
906 : : is_uint5(shift_amount.value_));
907 40 : if (shift_amount.value_ == 1) {
908 : emit_rex(dst, size);
909 : emit(0xD1);
910 20 : emit_operand(subcode, dst);
911 : } else {
912 : emit_rex(dst, size);
913 : emit(0xC1);
914 20 : emit_operand(subcode, dst);
915 : emit(shift_amount.value_);
916 : }
917 40 : }
918 :
919 :
920 62843 : void Assembler::shift(Register dst, int subcode, int size) {
921 : EnsureSpace ensure_space(this);
922 : emit_rex(dst, size);
923 : emit(0xD3);
924 : emit_modrm(subcode, dst);
925 62860 : }
926 :
927 :
928 40 : void Assembler::shift(Operand dst, int subcode, int size) {
929 : EnsureSpace ensure_space(this);
930 : emit_rex(dst, size);
931 : emit(0xD3);
932 40 : emit_operand(subcode, dst);
933 40 : }
934 :
935 49 : void Assembler::bswapl(Register dst) {
936 : EnsureSpace ensure_space(this);
937 : emit_rex_32(dst);
938 : emit(0x0F);
939 49 : emit(0xC8 + dst.low_bits());
940 49 : }
941 :
942 17 : void Assembler::bswapq(Register dst) {
943 : EnsureSpace ensure_space(this);
944 : emit_rex_64(dst);
945 : emit(0x0F);
946 17 : emit(0xC8 + dst.low_bits());
947 17 : }
948 :
949 5 : void Assembler::btq(Operand dst, Register src) {
950 : EnsureSpace ensure_space(this);
951 : emit_rex_64(src, dst);
952 : emit(0x0F);
953 : emit(0xA3);
954 : emit_operand(src, dst);
955 5 : }
956 :
957 10 : void Assembler::btsq(Operand dst, Register src) {
958 : EnsureSpace ensure_space(this);
959 : emit_rex_64(src, dst);
960 : emit(0x0F);
961 : emit(0xAB);
962 : emit_operand(src, dst);
963 10 : }
964 :
965 5 : void Assembler::btsq(Register dst, Immediate imm8) {
966 : EnsureSpace ensure_space(this);
967 : emit_rex_64(dst);
968 : emit(0x0F);
969 : emit(0xBA);
970 : emit_modrm(0x5, dst);
971 5 : emit(imm8.value_);
972 5 : }
973 :
974 18 : void Assembler::btrq(Register dst, Immediate imm8) {
975 : EnsureSpace ensure_space(this);
976 : emit_rex_64(dst);
977 : emit(0x0F);
978 : emit(0xBA);
979 : emit_modrm(0x6, dst);
980 18 : emit(imm8.value_);
981 18 : }
982 :
983 1223 : void Assembler::bsrl(Register dst, Register src) {
984 : EnsureSpace ensure_space(this);
985 : emit_optional_rex_32(dst, src);
986 : emit(0x0F);
987 : emit(0xBD);
988 : emit_modrm(dst, src);
989 1223 : }
990 :
991 45 : void Assembler::bsrl(Register dst, Operand src) {
992 : EnsureSpace ensure_space(this);
993 : emit_optional_rex_32(dst, src);
994 : emit(0x0F);
995 : emit(0xBD);
996 : emit_operand(dst, src);
997 45 : }
998 :
999 :
1000 34 : void Assembler::bsrq(Register dst, Register src) {
1001 : EnsureSpace ensure_space(this);
1002 : emit_rex_64(dst, src);
1003 : emit(0x0F);
1004 : emit(0xBD);
1005 : emit_modrm(dst, src);
1006 34 : }
1007 :
1008 0 : void Assembler::bsrq(Register dst, Operand src) {
1009 : EnsureSpace ensure_space(this);
1010 : emit_rex_64(dst, src);
1011 : emit(0x0F);
1012 : emit(0xBD);
1013 : emit_operand(dst, src);
1014 0 : }
1015 :
1016 :
1017 623 : void Assembler::bsfl(Register dst, Register src) {
1018 : EnsureSpace ensure_space(this);
1019 : emit_optional_rex_32(dst, src);
1020 : emit(0x0F);
1021 : emit(0xBC);
1022 : emit_modrm(dst, src);
1023 623 : }
1024 :
1025 0 : void Assembler::bsfl(Register dst, Operand src) {
1026 : EnsureSpace ensure_space(this);
1027 : emit_optional_rex_32(dst, src);
1028 : emit(0x0F);
1029 : emit(0xBC);
1030 : emit_operand(dst, src);
1031 0 : }
1032 :
1033 :
1034 34 : void Assembler::bsfq(Register dst, Register src) {
1035 : EnsureSpace ensure_space(this);
1036 : emit_rex_64(dst, src);
1037 : emit(0x0F);
1038 : emit(0xBC);
1039 : emit_modrm(dst, src);
1040 34 : }
1041 :
1042 0 : void Assembler::bsfq(Register dst, Operand src) {
1043 : EnsureSpace ensure_space(this);
1044 : emit_rex_64(dst, src);
1045 : emit(0x0F);
1046 : emit(0xBC);
1047 : emit_operand(dst, src);
1048 0 : }
1049 :
1050 5 : void Assembler::pshufw(XMMRegister dst, XMMRegister src, uint8_t shuffle) {
1051 : EnsureSpace ensure_space(this);
1052 : emit_optional_rex_32(dst, src);
1053 : emit(0x0F);
1054 : emit(0x70);
1055 : emit_sse_operand(dst, src);
1056 : emit(shuffle);
1057 5 : }
1058 :
1059 0 : void Assembler::pshufw(XMMRegister dst, Operand src, uint8_t shuffle) {
1060 : EnsureSpace ensure_space(this);
1061 : emit_optional_rex_32(dst, src);
1062 : emit(0x0F);
1063 : emit(0x70);
1064 0 : emit_operand(dst.code(), src);
1065 : emit(shuffle);
1066 0 : }
1067 :
1068 5 : void Assembler::pblendw(XMMRegister dst, Operand src, uint8_t mask) {
1069 5 : sse4_instr(dst, src, 0x66, 0x0F, 0x3A, 0x0E);
1070 : emit(mask);
1071 5 : }
1072 :
1073 873 : void Assembler::pblendw(XMMRegister dst, XMMRegister src, uint8_t mask) {
1074 873 : sse4_instr(dst, src, 0x66, 0x0F, 0x3A, 0x0E);
1075 : emit(mask);
1076 873 : }
1077 :
1078 5 : void Assembler::palignr(XMMRegister dst, Operand src, uint8_t mask) {
1079 5 : ssse3_instr(dst, src, 0x66, 0x0F, 0x3A, 0x0F);
1080 : emit(mask);
1081 5 : }
1082 :
1083 261 : void Assembler::palignr(XMMRegister dst, XMMRegister src, uint8_t mask) {
1084 261 : ssse3_instr(dst, src, 0x66, 0x0F, 0x3A, 0x0F);
1085 : emit(mask);
1086 261 : }
1087 :
1088 732726 : void Assembler::call(Label* L) {
1089 : EnsureSpace ensure_space(this);
1090 : // 1110 1000 #32-bit disp.
1091 : emit(0xE8);
1092 732726 : if (L->is_bound()) {
1093 5 : int offset = L->pos() - pc_offset() - sizeof(int32_t);
1094 : DCHECK_LE(offset, 0);
1095 : emitl(offset);
1096 732721 : } else if (L->is_linked()) {
1097 568430 : emitl(L->pos());
1098 568430 : L->link_to(pc_offset() - sizeof(int32_t));
1099 : } else {
1100 : DCHECK(L->is_unused());
1101 : int32_t current = pc_offset();
1102 164291 : emitl(current);
1103 : L->link_to(current);
1104 : }
1105 732726 : }
1106 :
1107 :
1108 3335849 : void Assembler::call(Address entry, RelocInfo::Mode rmode) {
1109 : DCHECK(RelocInfo::IsRuntimeEntry(rmode));
1110 : EnsureSpace ensure_space(this);
1111 : // 1110 1000 #32-bit disp.
1112 : emit(0xE8);
1113 3335849 : emit_runtime_entry(entry, rmode);
1114 3335854 : }
1115 :
1116 854976 : void Assembler::call(Handle<Code> target, RelocInfo::Mode rmode) {
1117 : DCHECK(RelocInfo::IsCodeTarget(rmode));
1118 : EnsureSpace ensure_space(this);
1119 : // 1110 1000 #32-bit disp.
1120 : emit(0xE8);
1121 854976 : RecordRelocInfo(rmode);
1122 854980 : int code_target_index = AddCodeTarget(target);
1123 854982 : emitl(code_target_index);
1124 854982 : }
1125 :
1126 562017 : void Assembler::near_call(intptr_t disp, RelocInfo::Mode rmode) {
1127 : EnsureSpace ensure_space(this);
1128 : emit(0xE8);
1129 : DCHECK(is_int32(disp));
1130 562017 : RecordRelocInfo(rmode);
1131 561878 : emitl(static_cast<int32_t>(disp));
1132 561878 : }
1133 :
1134 1445489 : void Assembler::near_jmp(intptr_t disp, RelocInfo::Mode rmode) {
1135 : EnsureSpace ensure_space(this);
1136 : emit(0xE9);
1137 : DCHECK(is_int32(disp));
1138 1445473 : if (!RelocInfo::IsNone(rmode)) RecordRelocInfo(rmode);
1139 1445473 : emitl(static_cast<int32_t>(disp));
1140 1445473 : }
1141 :
1142 6268676 : void Assembler::call(Register adr) {
1143 : EnsureSpace ensure_space(this);
1144 : // Opcode: FF /2 r64.
1145 : emit_optional_rex_32(adr);
1146 : emit(0xFF);
1147 : emit_modrm(0x2, adr);
1148 6268710 : }
1149 :
1150 3608 : void Assembler::call(Operand op) {
1151 : EnsureSpace ensure_space(this);
1152 : // Opcode: FF /2 m64.
1153 : emit_optional_rex_32(op);
1154 : emit(0xFF);
1155 3608 : emit_operand(0x2, op);
1156 3608 : }
1157 :
1158 :
1159 : // Calls directly to the given address using a relative offset.
1160 : // Should only ever be used in Code objects for calls within the
1161 : // same Code object. Should not be used when generating new code (use labels),
1162 : // but only when patching existing code.
1163 0 : void Assembler::call(Address target) {
1164 : EnsureSpace ensure_space(this);
1165 : // 1110 1000 #32-bit disp.
1166 : emit(0xE8);
1167 0 : Address source = reinterpret_cast<Address>(pc_) + 4;
1168 0 : intptr_t displacement = target - source;
1169 : DCHECK(is_int32(displacement));
1170 0 : emitl(static_cast<int32_t>(displacement));
1171 0 : }
1172 :
1173 :
1174 0 : void Assembler::clc() {
1175 : EnsureSpace ensure_space(this);
1176 : emit(0xF8);
1177 0 : }
1178 :
1179 :
1180 5 : void Assembler::cld() {
1181 : EnsureSpace ensure_space(this);
1182 : emit(0xFC);
1183 5 : }
1184 :
1185 60183 : void Assembler::cdq() {
1186 : EnsureSpace ensure_space(this);
1187 : emit(0x99);
1188 60183 : }
1189 :
1190 :
1191 120 : void Assembler::cmovq(Condition cc, Register dst, Register src) {
1192 120 : if (cc == always) {
1193 : movq(dst, src);
1194 120 : } else if (cc == never) {
1195 : return;
1196 : }
1197 : // No need to check CpuInfo for CMOV support, it's a required part of the
1198 : // 64-bit architecture.
1199 : DCHECK_GE(cc, 0); // Use mov for unconditional moves.
1200 : EnsureSpace ensure_space(this);
1201 : // Opcode: REX.W 0f 40 + cc /r.
1202 : emit_rex_64(dst, src);
1203 : emit(0x0F);
1204 120 : emit(0x40 + cc);
1205 : emit_modrm(dst, src);
1206 : }
1207 :
1208 80 : void Assembler::cmovq(Condition cc, Register dst, Operand src) {
1209 80 : if (cc == always) {
1210 : movq(dst, src);
1211 80 : } else if (cc == never) {
1212 : return;
1213 : }
1214 : DCHECK_GE(cc, 0);
1215 : EnsureSpace ensure_space(this);
1216 : // Opcode: REX.W 0f 40 + cc /r.
1217 : emit_rex_64(dst, src);
1218 : emit(0x0F);
1219 80 : emit(0x40 + cc);
1220 : emit_operand(dst, src);
1221 : }
1222 :
1223 :
1224 56 : void Assembler::cmovl(Condition cc, Register dst, Register src) {
1225 56 : if (cc == always) {
1226 : movl(dst, src);
1227 56 : } else if (cc == never) {
1228 : return;
1229 : }
1230 : DCHECK_GE(cc, 0);
1231 : EnsureSpace ensure_space(this);
1232 : // Opcode: 0f 40 + cc /r.
1233 : emit_optional_rex_32(dst, src);
1234 : emit(0x0F);
1235 56 : emit(0x40 + cc);
1236 : emit_modrm(dst, src);
1237 : }
1238 :
1239 0 : void Assembler::cmovl(Condition cc, Register dst, Operand src) {
1240 0 : if (cc == always) {
1241 : movl(dst, src);
1242 0 : } else if (cc == never) {
1243 : return;
1244 : }
1245 : DCHECK_GE(cc, 0);
1246 : EnsureSpace ensure_space(this);
1247 : // Opcode: 0f 40 + cc /r.
1248 : emit_optional_rex_32(dst, src);
1249 : emit(0x0F);
1250 0 : emit(0x40 + cc);
1251 : emit_operand(dst, src);
1252 : }
1253 :
1254 :
1255 0 : void Assembler::cmpb_al(Immediate imm8) {
1256 : DCHECK(is_int8(imm8.value_) || is_uint8(imm8.value_));
1257 : EnsureSpace ensure_space(this);
1258 : emit(0x3C);
1259 0 : emit(imm8.value_);
1260 0 : }
1261 :
1262 26037 : void Assembler::lock() {
1263 : EnsureSpace ensure_space(this);
1264 : emit(0xF0);
1265 26037 : }
1266 :
1267 9990 : void Assembler::cmpxchgb(Operand dst, Register src) {
1268 : EnsureSpace ensure_space(this);
1269 9991 : if (!src.is_byte_register()) {
1270 : // Register is not one of al, bl, cl, dl. Its encoding needs REX.
1271 : emit_rex_32(src, dst);
1272 : } else {
1273 : emit_optional_rex_32(src, dst);
1274 : }
1275 : emit(0x0F);
1276 : emit(0xB0);
1277 : emit_operand(src, dst);
1278 10002 : }
1279 :
1280 7503 : void Assembler::cmpxchgw(Operand dst, Register src) {
1281 : EnsureSpace ensure_space(this);
1282 : emit(0x66);
1283 : emit_optional_rex_32(src, dst);
1284 : emit(0x0F);
1285 : emit(0xB1);
1286 : emit_operand(src, dst);
1287 7506 : }
1288 :
1289 8583 : void Assembler::emit_cmpxchg(Operand dst, Register src, int size) {
1290 : EnsureSpace ensure_space(this);
1291 : emit_rex(src, dst, size);
1292 : emit(0x0F);
1293 : emit(0xB1);
1294 : emit_operand(src, dst);
1295 8584 : }
1296 :
1297 0 : void Assembler::lfence() {
1298 : EnsureSpace ensure_space(this);
1299 : emit(0x0F);
1300 : emit(0xAE);
1301 : emit(0xE8);
1302 0 : }
1303 :
1304 5 : void Assembler::cpuid() {
1305 : EnsureSpace ensure_space(this);
1306 : emit(0x0F);
1307 : emit(0xA2);
1308 5 : }
1309 :
1310 :
1311 3988 : void Assembler::cqo() {
1312 : EnsureSpace ensure_space(this);
1313 : emit_rex_64();
1314 : emit(0x99);
1315 3988 : }
1316 :
1317 :
1318 2421 : void Assembler::emit_dec(Register dst, int size) {
1319 : EnsureSpace ensure_space(this);
1320 : emit_rex(dst, size);
1321 : emit(0xFF);
1322 : emit_modrm(0x1, dst);
1323 2421 : }
1324 :
1325 0 : void Assembler::emit_dec(Operand dst, int size) {
1326 : EnsureSpace ensure_space(this);
1327 : emit_rex(dst, size);
1328 : emit(0xFF);
1329 0 : emit_operand(1, dst);
1330 0 : }
1331 :
1332 :
1333 5 : void Assembler::decb(Register dst) {
1334 : EnsureSpace ensure_space(this);
1335 5 : if (!dst.is_byte_register()) {
1336 : // Register is not one of al, bl, cl, dl. Its encoding needs REX.
1337 : emit_rex_32(dst);
1338 : }
1339 : emit(0xFE);
1340 : emit_modrm(0x1, dst);
1341 5 : }
1342 :
1343 10 : void Assembler::decb(Operand dst) {
1344 : EnsureSpace ensure_space(this);
1345 : emit_optional_rex_32(dst);
1346 : emit(0xFE);
1347 10 : emit_operand(1, dst);
1348 10 : }
1349 :
1350 :
1351 0 : void Assembler::enter(Immediate size) {
1352 : EnsureSpace ensure_space(this);
1353 : emit(0xC8);
1354 0 : emitw(size.value_); // 16 bit operand, always.
1355 : emit(0);
1356 0 : }
1357 :
1358 :
1359 5 : void Assembler::hlt() {
1360 : EnsureSpace ensure_space(this);
1361 : emit(0xF4);
1362 5 : }
1363 :
1364 :
1365 64169 : void Assembler::emit_idiv(Register src, int size) {
1366 : EnsureSpace ensure_space(this);
1367 : emit_rex(src, size);
1368 : emit(0xF7);
1369 : emit_modrm(0x7, src);
1370 64171 : }
1371 :
1372 :
1373 60242 : void Assembler::emit_div(Register src, int size) {
1374 : EnsureSpace ensure_space(this);
1375 : emit_rex(src, size);
1376 : emit(0xF7);
1377 : emit_modrm(0x6, src);
1378 60244 : }
1379 :
1380 :
1381 4199 : void Assembler::emit_imul(Register src, int size) {
1382 : EnsureSpace ensure_space(this);
1383 : emit_rex(src, size);
1384 : emit(0xF7);
1385 : emit_modrm(0x5, src);
1386 4199 : }
1387 :
1388 0 : void Assembler::emit_imul(Operand src, int size) {
1389 : EnsureSpace ensure_space(this);
1390 : emit_rex(src, size);
1391 : emit(0xF7);
1392 0 : emit_operand(0x5, src);
1393 0 : }
1394 :
1395 :
1396 22530 : void Assembler::emit_imul(Register dst, Register src, int size) {
1397 : EnsureSpace ensure_space(this);
1398 22530 : emit_rex(dst, src, size);
1399 : emit(0x0F);
1400 : emit(0xAF);
1401 : emit_modrm(dst, src);
1402 22532 : }
1403 :
1404 622 : void Assembler::emit_imul(Register dst, Operand src, int size) {
1405 : EnsureSpace ensure_space(this);
1406 : emit_rex(dst, src, size);
1407 : emit(0x0F);
1408 : emit(0xAF);
1409 : emit_operand(dst, src);
1410 622 : }
1411 :
1412 :
1413 64671 : void Assembler::emit_imul(Register dst, Register src, Immediate imm, int size) {
1414 : EnsureSpace ensure_space(this);
1415 64671 : emit_rex(dst, src, size);
1416 129342 : if (is_int8(imm.value_)) {
1417 : emit(0x6B);
1418 : emit_modrm(dst, src);
1419 : emit(imm.value_);
1420 : } else {
1421 : emit(0x69);
1422 : emit_modrm(dst, src);
1423 36210 : emitl(imm.value_);
1424 : }
1425 64671 : }
1426 :
1427 115 : void Assembler::emit_imul(Register dst, Operand src, Immediate imm, int size) {
1428 : EnsureSpace ensure_space(this);
1429 : emit_rex(dst, src, size);
1430 230 : if (is_int8(imm.value_)) {
1431 : emit(0x6B);
1432 : emit_operand(dst, src);
1433 : emit(imm.value_);
1434 : } else {
1435 : emit(0x69);
1436 : emit_operand(dst, src);
1437 11 : emitl(imm.value_);
1438 : }
1439 115 : }
1440 :
1441 :
1442 1862 : void Assembler::emit_inc(Register dst, int size) {
1443 : EnsureSpace ensure_space(this);
1444 : emit_rex(dst, size);
1445 : emit(0xFF);
1446 : emit_modrm(0x0, dst);
1447 1862 : }
1448 :
1449 3142 : void Assembler::emit_inc(Operand dst, int size) {
1450 : EnsureSpace ensure_space(this);
1451 : emit_rex(dst, size);
1452 : emit(0xFF);
1453 3142 : emit_operand(0, dst);
1454 3142 : }
1455 :
1456 :
1457 261890 : void Assembler::int3() {
1458 : EnsureSpace ensure_space(this);
1459 : emit(0xCC);
1460 261890 : }
1461 :
1462 :
1463 10757753 : void Assembler::j(Condition cc, Label* L, Label::Distance distance) {
1464 10757753 : if (cc == always) {
1465 392 : jmp(L);
1466 392 : return;
1467 10757361 : } else if (cc == never) {
1468 : return;
1469 : }
1470 : EnsureSpace ensure_space(this);
1471 : DCHECK(is_uint4(cc));
1472 10757447 : if (L->is_bound()) {
1473 : const int short_size = 2;
1474 : const int long_size = 6;
1475 1202680 : int offs = L->pos() - pc_offset();
1476 : DCHECK_LE(offs, 0);
1477 : // Determine whether we can use 1-byte offsets for backwards branches,
1478 : // which have a max range of 128 bytes.
1479 :
1480 : // We also need to check predictable_code_size() flag here, because on x64,
1481 : // when the full code generator recompiles code for debugging, some places
1482 : // need to be padded out to a certain size. The debugger is keeping track of
1483 : // how often it did this so that it can adjust return addresses on the
1484 : // stack, but if the size of jump instructions can also change, that's not
1485 : // enough and the calculated offsets would be incorrect.
1486 2405360 : if (is_int8(offs - short_size) && !predictable_code_size()) {
1487 : // 0111 tttn #8-bit disp.
1488 390211 : emit(0x70 | cc);
1489 390211 : emit((offs - short_size) & 0xFF);
1490 : } else {
1491 : // 0000 1111 1000 tttn #32-bit disp.
1492 : emit(0x0F);
1493 812469 : emit(0x80 | cc);
1494 812469 : emitl(offs - long_size);
1495 : }
1496 9554767 : } else if (distance == Label::kNear) {
1497 : // 0111 tttn #8-bit disp
1498 618618 : emit(0x70 | cc);
1499 : byte disp = 0x00;
1500 618618 : if (L->is_near_linked()) {
1501 1830 : int offset = L->near_link_pos() - pc_offset();
1502 : DCHECK(is_int8(offset));
1503 1830 : disp = static_cast<byte>(offset & 0xFF);
1504 : }
1505 : L->link_to(pc_offset(), Label::kNear);
1506 : emit(disp);
1507 : } else {
1508 : auto jump_opt = jump_optimization_info();
1509 8936149 : if (V8_UNLIKELY(jump_opt)) {
1510 2828198 : if (jump_opt->is_optimizing() && is_optimizable_farjmp(farjmp_num_++)) {
1511 : // 0111 tttn #8-bit disp
1512 765975 : emit(0x70 | cc);
1513 : record_farjmp_position(L, pc_offset());
1514 : emit(0);
1515 : return;
1516 : }
1517 2062223 : if (jump_opt->is_collecting()) {
1518 2828366 : farjmp_positions_.push_back(pc_offset() + 2);
1519 : }
1520 : }
1521 8170174 : if (L->is_linked()) {
1522 : // 0000 1111 1000 tttn #32-bit disp.
1523 : emit(0x0F);
1524 1673395 : emit(0x80 | cc);
1525 1673395 : emitl(L->pos());
1526 1673395 : L->link_to(pc_offset() - sizeof(int32_t));
1527 : } else {
1528 : DCHECK(L->is_unused());
1529 : emit(0x0F);
1530 6496779 : emit(0x80 | cc);
1531 : int32_t current = pc_offset();
1532 6496779 : emitl(current);
1533 : L->link_to(current);
1534 : }
1535 : }
1536 : }
1537 :
1538 :
1539 0 : void Assembler::j(Condition cc, Address entry, RelocInfo::Mode rmode) {
1540 : DCHECK(RelocInfo::IsRuntimeEntry(rmode));
1541 : EnsureSpace ensure_space(this);
1542 : DCHECK(is_uint4(cc));
1543 : emit(0x0F);
1544 0 : emit(0x80 | cc);
1545 0 : emit_runtime_entry(entry, rmode);
1546 0 : }
1547 :
1548 :
1549 50161 : void Assembler::j(Condition cc,
1550 : Handle<Code> target,
1551 : RelocInfo::Mode rmode) {
1552 50161 : if (cc == always) {
1553 49432 : jmp(target, rmode);
1554 49432 : return;
1555 729 : } else if (cc == never) {
1556 : return;
1557 : }
1558 : EnsureSpace ensure_space(this);
1559 : DCHECK(is_uint4(cc));
1560 : // 0000 1111 1000 tttn #32-bit disp.
1561 : emit(0x0F);
1562 729 : emit(0x80 | cc);
1563 : DCHECK(RelocInfo::IsCodeTarget(rmode));
1564 729 : RecordRelocInfo(rmode);
1565 729 : int code_target_index = AddCodeTarget(target);
1566 729 : emitl(code_target_index);
1567 : }
1568 :
1569 :
1570 6339334 : void Assembler::jmp(Label* L, Label::Distance distance) {
1571 : EnsureSpace ensure_space(this);
1572 : const int short_size = sizeof(int8_t);
1573 : const int long_size = sizeof(int32_t);
1574 6339241 : if (L->is_bound()) {
1575 3352867 : int offs = L->pos() - pc_offset() - 1;
1576 : DCHECK_LE(offs, 0);
1577 6705734 : if (is_int8(offs - short_size) && !predictable_code_size()) {
1578 : // 1110 1011 #8-bit disp.
1579 : emit(0xEB);
1580 903653 : emit((offs - short_size) & 0xFF);
1581 : } else {
1582 : // 1110 1001 #32-bit disp.
1583 : emit(0xE9);
1584 2449214 : emitl(offs - long_size);
1585 : }
1586 2986374 : } else if (distance == Label::kNear) {
1587 : emit(0xEB);
1588 : byte disp = 0x00;
1589 91990 : if (L->is_near_linked()) {
1590 478 : int offset = L->near_link_pos() - pc_offset();
1591 : DCHECK(is_int8(offset));
1592 478 : disp = static_cast<byte>(offset & 0xFF);
1593 : }
1594 : L->link_to(pc_offset(), Label::kNear);
1595 : emit(disp);
1596 : } else {
1597 : auto jump_opt = jump_optimization_info();
1598 2894384 : if (V8_UNLIKELY(jump_opt)) {
1599 1056968 : if (jump_opt->is_optimizing() && is_optimizable_farjmp(farjmp_num_++)) {
1600 : emit(0xEB);
1601 : record_farjmp_position(L, pc_offset());
1602 : emit(0);
1603 : return;
1604 : }
1605 718347 : if (jump_opt->is_collecting()) {
1606 1056968 : farjmp_positions_.push_back(pc_offset() + 1);
1607 : }
1608 : }
1609 2555763 : if (L->is_linked()) {
1610 : // 1110 1001 #32-bit disp.
1611 : emit(0xE9);
1612 931602 : emitl(L->pos());
1613 : L->link_to(pc_offset() - long_size);
1614 : } else {
1615 : // 1110 1001 #32-bit disp.
1616 : DCHECK(L->is_unused());
1617 : emit(0xE9);
1618 : int32_t current = pc_offset();
1619 1624161 : emitl(current);
1620 : L->link_to(current);
1621 : }
1622 : }
1623 : }
1624 :
1625 :
1626 49437 : void Assembler::jmp(Handle<Code> target, RelocInfo::Mode rmode) {
1627 : DCHECK(RelocInfo::IsCodeTarget(rmode));
1628 : EnsureSpace ensure_space(this);
1629 : // 1110 1001 #32-bit disp.
1630 : emit(0xE9);
1631 49437 : RecordRelocInfo(rmode);
1632 49437 : int code_target_index = AddCodeTarget(target);
1633 49437 : emitl(code_target_index);
1634 49437 : }
1635 :
1636 :
1637 36924548 : void Assembler::jmp(Register target) {
1638 : EnsureSpace ensure_space(this);
1639 : // Opcode FF/4 r64.
1640 : emit_optional_rex_32(target);
1641 : emit(0xFF);
1642 : emit_modrm(0x4, target);
1643 36924549 : }
1644 :
1645 348 : void Assembler::jmp(Operand src) {
1646 : EnsureSpace ensure_space(this);
1647 : // Opcode FF/4 m64.
1648 : emit_optional_rex_32(src);
1649 : emit(0xFF);
1650 348 : emit_operand(0x4, src);
1651 348 : }
1652 :
1653 3428349 : void Assembler::emit_lea(Register dst, Operand src, int size) {
1654 : EnsureSpace ensure_space(this);
1655 : emit_rex(dst, src, size);
1656 : emit(0x8D);
1657 : emit_operand(dst, src);
1658 3428456 : }
1659 :
1660 733004 : void Assembler::load_rax(Address value, RelocInfo::Mode mode) {
1661 : EnsureSpace ensure_space(this);
1662 : emit(0x48); // REX.W
1663 : emit(0xA1);
1664 733004 : emit(Immediate64(value, mode));
1665 733004 : }
1666 :
1667 733004 : void Assembler::load_rax(ExternalReference ref) {
1668 733004 : load_rax(ref.address(), RelocInfo::EXTERNAL_REFERENCE);
1669 733004 : }
1670 :
1671 280 : void Assembler::leave() {
1672 : EnsureSpace ensure_space(this);
1673 : emit(0xC9);
1674 280 : }
1675 :
1676 9725 : void Assembler::movb(Register dst, Operand src) {
1677 : EnsureSpace ensure_space(this);
1678 9726 : if (!dst.is_byte_register()) {
1679 : // Register is not one of al, bl, cl, dl. Its encoding needs REX.
1680 : emit_rex_32(dst, src);
1681 : } else {
1682 : emit_optional_rex_32(dst, src);
1683 : }
1684 : emit(0x8A);
1685 : emit_operand(dst, src);
1686 9739 : }
1687 :
1688 :
1689 5 : void Assembler::movb(Register dst, Immediate imm) {
1690 : EnsureSpace ensure_space(this);
1691 5 : if (!dst.is_byte_register()) {
1692 : // Register is not one of al, bl, cl, dl. Its encoding needs REX.
1693 : emit_rex_32(dst);
1694 : }
1695 5 : emit(0xB0 + dst.low_bits());
1696 5 : emit(imm.value_);
1697 5 : }
1698 :
1699 73687 : void Assembler::movb(Operand dst, Register src) {
1700 : EnsureSpace ensure_space(this);
1701 73689 : if (!src.is_byte_register()) {
1702 : // Register is not one of al, bl, cl, dl. Its encoding needs REX.
1703 : emit_rex_32(src, dst);
1704 : } else {
1705 : emit_optional_rex_32(src, dst);
1706 : }
1707 : emit(0x88);
1708 : emit_operand(src, dst);
1709 73687 : }
1710 :
1711 6738 : void Assembler::movb(Operand dst, Immediate imm) {
1712 : EnsureSpace ensure_space(this);
1713 : emit_optional_rex_32(dst);
1714 : emit(0xC6);
1715 6739 : emit_operand(0x0, dst);
1716 6738 : emit(static_cast<byte>(imm.value_));
1717 6738 : }
1718 :
1719 7224 : void Assembler::movw(Register dst, Operand src) {
1720 : EnsureSpace ensure_space(this);
1721 : emit(0x66);
1722 : emit_optional_rex_32(dst, src);
1723 : emit(0x8B);
1724 : emit_operand(dst, src);
1725 7227 : }
1726 :
1727 14618 : void Assembler::movw(Operand dst, Register src) {
1728 : EnsureSpace ensure_space(this);
1729 : emit(0x66);
1730 : emit_optional_rex_32(src, dst);
1731 : emit(0x89);
1732 : emit_operand(src, dst);
1733 14619 : }
1734 :
1735 971 : void Assembler::movw(Operand dst, Immediate imm) {
1736 : EnsureSpace ensure_space(this);
1737 : emit(0x66);
1738 : emit_optional_rex_32(dst);
1739 : emit(0xC7);
1740 971 : emit_operand(0x0, dst);
1741 : emit(static_cast<byte>(imm.value_ & 0xFF));
1742 971 : emit(static_cast<byte>(imm.value_ >> 8));
1743 971 : }
1744 :
1745 27770061 : void Assembler::emit_mov(Register dst, Operand src, int size) {
1746 : EnsureSpace ensure_space(this);
1747 : emit_rex(dst, src, size);
1748 : emit(0x8B);
1749 : emit_operand(dst, src);
1750 27772548 : }
1751 :
1752 :
1753 14232945 : void Assembler::emit_mov(Register dst, Register src, int size) {
1754 : EnsureSpace ensure_space(this);
1755 14234455 : if (src.low_bits() == 4) {
1756 4273729 : emit_rex(src, dst, size);
1757 : emit(0x89);
1758 : emit_modrm(src, dst);
1759 : } else {
1760 9960726 : emit_rex(dst, src, size);
1761 : emit(0x8B);
1762 : emit_modrm(dst, src);
1763 : }
1764 :
1765 : #if defined(V8_OS_WIN_X64)
1766 : if (xdata_encoder_ && dst == rbp && src == rsp) {
1767 : xdata_encoder_->onMovRbpRsp();
1768 : }
1769 : #endif
1770 14234259 : }
1771 :
1772 14019067 : void Assembler::emit_mov(Operand dst, Register src, int size) {
1773 : EnsureSpace ensure_space(this);
1774 : emit_rex(src, dst, size);
1775 : emit(0x89);
1776 : emit_operand(src, dst);
1777 14019113 : }
1778 :
1779 :
1780 8662926 : void Assembler::emit_mov(Register dst, Immediate value, int size) {
1781 : EnsureSpace ensure_space(this);
1782 : emit_rex(dst, size);
1783 8662943 : if (size == kInt64Size) {
1784 : emit(0xC7);
1785 : emit_modrm(0x0, dst);
1786 : } else {
1787 : DCHECK_EQ(size, kInt32Size);
1788 4382903 : emit(0xB8 + dst.low_bits());
1789 : }
1790 8662943 : emit(value);
1791 8662863 : }
1792 :
1793 907609 : void Assembler::emit_mov(Operand dst, Immediate value, int size) {
1794 : EnsureSpace ensure_space(this);
1795 : emit_rex(dst, size);
1796 : emit(0xC7);
1797 907609 : emit_operand(0x0, dst);
1798 907610 : emit(value);
1799 907611 : }
1800 :
1801 54551531 : void Assembler::emit_mov(Register dst, Immediate64 value, int size) {
1802 : DCHECK_EQ(size, kInt64Size);
1803 54551531 : if (constpool_.TryRecordEntry(value.value_, value.rmode_)) {
1804 : // Emit rip-relative move with offset = 0
1805 5062717 : Label label;
1806 5062717 : emit_mov(dst, Operand(&label, 0), size);
1807 : bind(&label);
1808 : } else {
1809 : EnsureSpace ensure_space(this);
1810 : emit_rex(dst, size);
1811 49488920 : emit(0xB8 | dst.low_bits());
1812 49488920 : emit(value);
1813 : }
1814 54551619 : }
1815 :
1816 39724 : void Assembler::movq_heap_number(Register dst, double value) {
1817 : EnsureSpace ensure_space(this);
1818 : emit_rex(dst, kInt64Size);
1819 39724 : emit(0xB8 | dst.low_bits());
1820 39724 : RequestHeapObject(HeapObjectRequest(value));
1821 39724 : emit(Immediate64(kNullAddress, RelocInfo::EMBEDDED_OBJECT));
1822 39724 : }
1823 :
1824 2139 : void Assembler::movq_string(Register dst, const StringConstantBase* str) {
1825 : EnsureSpace ensure_space(this);
1826 : emit_rex(dst, kInt64Size);
1827 2139 : emit(0xB8 | dst.low_bits());
1828 2139 : RequestHeapObject(HeapObjectRequest(str));
1829 2139 : emit(Immediate64(kNullAddress, RelocInfo::EMBEDDED_OBJECT));
1830 2139 : }
1831 :
1832 : // Loads the ip-relative location of the src label into the target location
1833 : // (as a 32-bit offset sign extended to 64-bit).
1834 525833 : void Assembler::movl(Operand dst, Label* src) {
1835 : EnsureSpace ensure_space(this);
1836 : emit_optional_rex_32(dst);
1837 : emit(0xC7);
1838 525833 : emit_operand(0, dst);
1839 525833 : if (src->is_bound()) {
1840 4 : int offset = src->pos() - pc_offset() - sizeof(int32_t);
1841 : DCHECK_LE(offset, 0);
1842 : emitl(offset);
1843 525829 : } else if (src->is_linked()) {
1844 0 : emitl(src->pos());
1845 0 : src->link_to(pc_offset() - sizeof(int32_t));
1846 : } else {
1847 : DCHECK(src->is_unused());
1848 : int32_t current = pc_offset();
1849 525829 : emitl(current);
1850 : src->link_to(current);
1851 : }
1852 525833 : }
1853 :
1854 :
1855 2408 : void Assembler::movsxbl(Register dst, Register src) {
1856 : EnsureSpace ensure_space(this);
1857 2408 : if (!src.is_byte_register()) {
1858 : // Register is not one of al, bl, cl, dl. Its encoding needs REX.
1859 : emit_rex_32(dst, src);
1860 : } else {
1861 : emit_optional_rex_32(dst, src);
1862 : }
1863 : emit(0x0F);
1864 : emit(0xBE);
1865 : emit_modrm(dst, src);
1866 2408 : }
1867 :
1868 47138 : void Assembler::movsxbl(Register dst, Operand src) {
1869 : EnsureSpace ensure_space(this);
1870 : emit_optional_rex_32(dst, src);
1871 : emit(0x0F);
1872 : emit(0xBE);
1873 : emit_operand(dst, src);
1874 47139 : }
1875 :
1876 13557 : void Assembler::movsxbq(Register dst, Operand src) {
1877 : EnsureSpace ensure_space(this);
1878 : emit_rex_64(dst, src);
1879 : emit(0x0F);
1880 : emit(0xBE);
1881 : emit_operand(dst, src);
1882 13557 : }
1883 :
1884 19 : void Assembler::movsxbq(Register dst, Register src) {
1885 : EnsureSpace ensure_space(this);
1886 : emit_rex_64(dst, src);
1887 : emit(0x0F);
1888 : emit(0xBE);
1889 : emit_modrm(dst, src);
1890 19 : }
1891 :
1892 2162 : void Assembler::movsxwl(Register dst, Register src) {
1893 : EnsureSpace ensure_space(this);
1894 : emit_optional_rex_32(dst, src);
1895 : emit(0x0F);
1896 : emit(0xBF);
1897 : emit_modrm(dst, src);
1898 2163 : }
1899 :
1900 10124 : void Assembler::movsxwl(Register dst, Operand src) {
1901 : EnsureSpace ensure_space(this);
1902 : emit_optional_rex_32(dst, src);
1903 : emit(0x0F);
1904 : emit(0xBF);
1905 : emit_operand(dst, src);
1906 10124 : }
1907 :
1908 9083 : void Assembler::movsxwq(Register dst, Operand src) {
1909 : EnsureSpace ensure_space(this);
1910 : emit_rex_64(dst, src);
1911 : emit(0x0F);
1912 : emit(0xBF);
1913 : emit_operand(dst, src);
1914 9083 : }
1915 :
1916 8 : void Assembler::movsxwq(Register dst, Register src) {
1917 : EnsureSpace ensure_space(this);
1918 : emit_rex_64(dst, src);
1919 : emit(0x0F);
1920 : emit(0xBF);
1921 : emit_modrm(dst, src);
1922 8 : }
1923 :
1924 86063 : void Assembler::movsxlq(Register dst, Register src) {
1925 : EnsureSpace ensure_space(this);
1926 : emit_rex_64(dst, src);
1927 : emit(0x63);
1928 : emit_modrm(dst, src);
1929 86063 : }
1930 :
1931 733633 : void Assembler::movsxlq(Register dst, Operand src) {
1932 : EnsureSpace ensure_space(this);
1933 : emit_rex_64(dst, src);
1934 : emit(0x63);
1935 : emit_operand(dst, src);
1936 733634 : }
1937 :
1938 634195 : void Assembler::emit_movzxb(Register dst, Operand src, int size) {
1939 : EnsureSpace ensure_space(this);
1940 : // 32 bit operations zero the top 32 bits of 64 bit registers. Therefore
1941 : // there is no need to make this a 64 bit operation.
1942 : emit_optional_rex_32(dst, src);
1943 : emit(0x0F);
1944 : emit(0xB6);
1945 : emit_operand(dst, src);
1946 634195 : }
1947 :
1948 :
1949 603322 : void Assembler::emit_movzxb(Register dst, Register src, int size) {
1950 : EnsureSpace ensure_space(this);
1951 : // 32 bit operations zero the top 32 bits of 64 bit registers. Therefore
1952 : // there is no need to make this a 64 bit operation.
1953 603327 : if (!src.is_byte_register()) {
1954 : // Register is not one of al, bl, cl, dl. Its encoding needs REX.
1955 : emit_rex_32(dst, src);
1956 : } else {
1957 : emit_optional_rex_32(dst, src);
1958 : }
1959 : emit(0x0F);
1960 : emit(0xB6);
1961 : emit_modrm(dst, src);
1962 603327 : }
1963 :
1964 527962 : void Assembler::emit_movzxw(Register dst, Operand src, int size) {
1965 : EnsureSpace ensure_space(this);
1966 : // 32 bit operations zero the top 32 bits of 64 bit registers. Therefore
1967 : // there is no need to make this a 64 bit operation.
1968 : emit_optional_rex_32(dst, src);
1969 : emit(0x0F);
1970 : emit(0xB7);
1971 : emit_operand(dst, src);
1972 527967 : }
1973 :
1974 :
1975 13666 : void Assembler::emit_movzxw(Register dst, Register src, int size) {
1976 : EnsureSpace ensure_space(this);
1977 : // 32 bit operations zero the top 32 bits of 64 bit registers. Therefore
1978 : // there is no need to make this a 64 bit operation.
1979 : emit_optional_rex_32(dst, src);
1980 : emit(0x0F);
1981 : emit(0xB7);
1982 : emit_modrm(dst, src);
1983 13667 : }
1984 :
1985 :
1986 0 : void Assembler::repmovsb() {
1987 : EnsureSpace ensure_space(this);
1988 : emit(0xF3);
1989 : emit(0xA4);
1990 0 : }
1991 :
1992 :
1993 0 : void Assembler::repmovsw() {
1994 : EnsureSpace ensure_space(this);
1995 : emit(0x66); // Operand size override.
1996 : emit(0xF3);
1997 : emit(0xA4);
1998 0 : }
1999 :
2000 :
2001 0 : void Assembler::emit_repmovs(int size) {
2002 : EnsureSpace ensure_space(this);
2003 : emit(0xF3);
2004 : emit_rex(size);
2005 : emit(0xA5);
2006 0 : }
2007 :
2008 :
2009 1673 : void Assembler::mull(Register src) {
2010 : EnsureSpace ensure_space(this);
2011 : emit_optional_rex_32(src);
2012 : emit(0xF7);
2013 : emit_modrm(0x4, src);
2014 1673 : }
2015 :
2016 0 : void Assembler::mull(Operand src) {
2017 : EnsureSpace ensure_space(this);
2018 : emit_optional_rex_32(src);
2019 : emit(0xF7);
2020 0 : emit_operand(0x4, src);
2021 0 : }
2022 :
2023 :
2024 5 : void Assembler::mulq(Register src) {
2025 : EnsureSpace ensure_space(this);
2026 : emit_rex_64(src);
2027 : emit(0xF7);
2028 : emit_modrm(0x4, src);
2029 5 : }
2030 :
2031 :
2032 146641 : void Assembler::emit_neg(Register dst, int size) {
2033 : EnsureSpace ensure_space(this);
2034 : emit_rex(dst, size);
2035 : emit(0xF7);
2036 : emit_modrm(0x3, dst);
2037 146642 : }
2038 :
2039 0 : void Assembler::emit_neg(Operand dst, int size) {
2040 : EnsureSpace ensure_space(this);
2041 : emit_rex_64(dst);
2042 : emit(0xF7);
2043 0 : emit_operand(3, dst);
2044 0 : }
2045 :
2046 :
2047 2657153 : void Assembler::nop() {
2048 : EnsureSpace ensure_space(this);
2049 : emit(0x90);
2050 2657153 : }
2051 :
2052 :
2053 2829 : void Assembler::emit_not(Register dst, int size) {
2054 : EnsureSpace ensure_space(this);
2055 : emit_rex(dst, size);
2056 : emit(0xF7);
2057 : emit_modrm(0x2, dst);
2058 2829 : }
2059 :
2060 0 : void Assembler::emit_not(Operand dst, int size) {
2061 : EnsureSpace ensure_space(this);
2062 : emit_rex(dst, size);
2063 : emit(0xF7);
2064 0 : emit_operand(2, dst);
2065 0 : }
2066 :
2067 :
2068 40622564 : void Assembler::Nop(int n) {
2069 : // The recommended muti-byte sequences of NOP instructions from the Intel 64
2070 : // and IA-32 Architectures Software Developer's Manual.
2071 : //
2072 : // Length Assembly Byte Sequence
2073 : // 2 bytes 66 NOP 66 90H
2074 : // 3 bytes NOP DWORD ptr [EAX] 0F 1F 00H
2075 : // 4 bytes NOP DWORD ptr [EAX + 00H] 0F 1F 40 00H
2076 : // 5 bytes NOP DWORD ptr [EAX + EAX*1 + 00H] 0F 1F 44 00 00H
2077 : // 6 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 00H] 66 0F 1F 44 00 00H
2078 : // 7 bytes NOP DWORD ptr [EAX + 00000000H] 0F 1F 80 00 00 00 00H
2079 : // 8 bytes NOP DWORD ptr [EAX + EAX*1 + 00000000H] 0F 1F 84 00 00 00 00 00H
2080 : // 9 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 66 0F 1F 84 00 00 00 00
2081 : // 00000000H] 00H
2082 :
2083 : EnsureSpace ensure_space(this);
2084 43569960 : while (n > 0) {
2085 41108303 : switch (n) {
2086 : case 2:
2087 : emit(0x66);
2088 : V8_FALLTHROUGH;
2089 : case 1:
2090 : emit(0x90);
2091 : return;
2092 : case 3:
2093 : emit(0x0F);
2094 : emit(0x1F);
2095 : emit(0x00);
2096 : return;
2097 : case 4:
2098 : emit(0x0F);
2099 : emit(0x1F);
2100 : emit(0x40);
2101 : emit(0x00);
2102 : return;
2103 : case 6:
2104 : emit(0x66);
2105 : V8_FALLTHROUGH;
2106 : case 5:
2107 : emit(0x0F);
2108 : emit(0x1F);
2109 : emit(0x44);
2110 : emit(0x00);
2111 : emit(0x00);
2112 : return;
2113 : case 7:
2114 : emit(0x0F);
2115 : emit(0x1F);
2116 : emit(0x80);
2117 : emit(0x00);
2118 : emit(0x00);
2119 : emit(0x00);
2120 : emit(0x00);
2121 : return;
2122 : default:
2123 : case 11:
2124 : emit(0x66);
2125 1461300 : n--;
2126 : V8_FALLTHROUGH;
2127 : case 10:
2128 : emit(0x66);
2129 1465477 : n--;
2130 : V8_FALLTHROUGH;
2131 : case 9:
2132 : emit(0x66);
2133 1470630 : n--;
2134 : V8_FALLTHROUGH;
2135 : case 8:
2136 : emit(0x0F);
2137 : emit(0x1F);
2138 : emit(0x84);
2139 : emit(0x00);
2140 : emit(0x00);
2141 : emit(0x00);
2142 : emit(0x00);
2143 : emit(0x00);
2144 1473265 : n -= 8;
2145 : }
2146 : }
2147 : }
2148 :
2149 :
2150 10892569 : void Assembler::popq(Register dst) {
2151 : EnsureSpace ensure_space(this);
2152 : emit_optional_rex_32(dst);
2153 10892825 : emit(0x58 | dst.low_bits());
2154 10892825 : }
2155 :
2156 1484250 : void Assembler::popq(Operand dst) {
2157 : EnsureSpace ensure_space(this);
2158 : emit_optional_rex_32(dst);
2159 : emit(0x8F);
2160 1484251 : emit_operand(0, dst);
2161 1484248 : }
2162 :
2163 :
2164 608 : void Assembler::popfq() {
2165 : EnsureSpace ensure_space(this);
2166 : emit(0x9D);
2167 608 : }
2168 :
2169 :
2170 15646931 : void Assembler::pushq(Register src) {
2171 : EnsureSpace ensure_space(this);
2172 : emit_optional_rex_32(src);
2173 15647283 : emit(0x50 | src.low_bits());
2174 :
2175 : #if defined(V8_OS_WIN_X64)
2176 : if (xdata_encoder_ && src == rbp) {
2177 : xdata_encoder_->onPushRbp();
2178 : }
2179 : #endif
2180 15647283 : }
2181 :
2182 1625343 : void Assembler::pushq(Operand src) {
2183 : EnsureSpace ensure_space(this);
2184 : emit_optional_rex_32(src);
2185 : emit(0xFF);
2186 1625343 : emit_operand(6, src);
2187 1625343 : }
2188 :
2189 :
2190 2278452 : void Assembler::pushq(Immediate value) {
2191 : EnsureSpace ensure_space(this);
2192 4557250 : if (is_int8(value.value_)) {
2193 : emit(0x6A);
2194 : emit(value.value_); // Emit low byte of value.
2195 : } else {
2196 : emit(0x68);
2197 94615 : emitl(value.value_);
2198 : }
2199 2278625 : }
2200 :
2201 :
2202 0 : void Assembler::pushq_imm32(int32_t imm32) {
2203 : EnsureSpace ensure_space(this);
2204 : emit(0x68);
2205 0 : emitl(imm32);
2206 0 : }
2207 :
2208 :
2209 288 : void Assembler::pushfq() {
2210 : EnsureSpace ensure_space(this);
2211 : emit(0x9C);
2212 288 : }
2213 :
2214 :
2215 3703802 : void Assembler::ret(int imm16) {
2216 : EnsureSpace ensure_space(this);
2217 : DCHECK(is_uint16(imm16));
2218 3704226 : if (imm16 == 0) {
2219 : emit(0xC3);
2220 : } else {
2221 : emit(0xC2);
2222 : emit(imm16 & 0xFF);
2223 638269 : emit((imm16 >> 8) & 0xFF);
2224 : }
2225 3704226 : }
2226 :
2227 :
2228 8 : void Assembler::ud2() {
2229 : EnsureSpace ensure_space(this);
2230 : emit(0x0F);
2231 : emit(0x0B);
2232 8 : }
2233 :
2234 :
2235 590990 : void Assembler::setcc(Condition cc, Register reg) {
2236 590990 : if (cc > last_condition) {
2237 0 : movb(reg, Immediate(cc == always ? 1 : 0));
2238 : return;
2239 : }
2240 : EnsureSpace ensure_space(this);
2241 : DCHECK(is_uint4(cc));
2242 590989 : if (!reg.is_byte_register()) {
2243 : // Register is not one of al, bl, cl, dl. Its encoding needs REX.
2244 : emit_rex_32(reg);
2245 : }
2246 : emit(0x0F);
2247 590989 : emit(0x90 | cc);
2248 : emit_modrm(0x0, reg);
2249 : }
2250 :
2251 :
2252 10 : void Assembler::shld(Register dst, Register src) {
2253 : EnsureSpace ensure_space(this);
2254 : emit_rex_64(src, dst);
2255 : emit(0x0F);
2256 : emit(0xA5);
2257 : emit_modrm(src, dst);
2258 10 : }
2259 :
2260 :
2261 10 : void Assembler::shrd(Register dst, Register src) {
2262 : EnsureSpace ensure_space(this);
2263 : emit_rex_64(src, dst);
2264 : emit(0x0F);
2265 : emit(0xAD);
2266 : emit_modrm(src, dst);
2267 10 : }
2268 :
2269 3209 : void Assembler::xchgb(Register reg, Operand op) {
2270 : EnsureSpace ensure_space(this);
2271 3209 : if (!reg.is_byte_register()) {
2272 : // Register is not one of al, bl, cl, dl. Its encoding needs REX.
2273 : emit_rex_32(reg, op);
2274 : } else {
2275 : emit_optional_rex_32(reg, op);
2276 : }
2277 : emit(0x86);
2278 : emit_operand(reg, op);
2279 3211 : }
2280 :
2281 2835 : void Assembler::xchgw(Register reg, Operand op) {
2282 : EnsureSpace ensure_space(this);
2283 : emit(0x66);
2284 : emit_optional_rex_32(reg, op);
2285 : emit(0x87);
2286 : emit_operand(reg, op);
2287 2838 : }
2288 :
2289 89 : void Assembler::emit_xchg(Register dst, Register src, int size) {
2290 : EnsureSpace ensure_space(this);
2291 173 : if (src == rax || dst == rax) { // Single-byte encoding
2292 70 : Register other = src == rax ? dst : src;
2293 : emit_rex(other, size);
2294 70 : emit(0x90 | other.low_bits());
2295 19 : } else if (dst.low_bits() == 4) {
2296 0 : emit_rex(dst, src, size);
2297 : emit(0x87);
2298 : emit_modrm(dst, src);
2299 : } else {
2300 19 : emit_rex(src, dst, size);
2301 : emit(0x87);
2302 : emit_modrm(src, dst);
2303 : }
2304 89 : }
2305 :
2306 2692 : void Assembler::emit_xchg(Register dst, Operand src, int size) {
2307 : EnsureSpace ensure_space(this);
2308 : emit_rex(dst, src, size);
2309 : emit(0x87);
2310 : emit_operand(dst, src);
2311 2692 : }
2312 :
2313 576 : void Assembler::store_rax(Address dst, RelocInfo::Mode mode) {
2314 : EnsureSpace ensure_space(this);
2315 : emit(0x48); // REX.W
2316 : emit(0xA3);
2317 576 : emit(Immediate64(dst, mode));
2318 576 : }
2319 :
2320 576 : void Assembler::store_rax(ExternalReference ref) {
2321 576 : store_rax(ref.address(), RelocInfo::EXTERNAL_REFERENCE);
2322 576 : }
2323 :
2324 901866 : void Assembler::sub_sp_32(uint32_t imm) {
2325 : emit_rex_64();
2326 : emit(0x81); // using a literal 32-bit immediate.
2327 : emit_modrm(0x5, rsp);
2328 : emitl(imm);
2329 901866 : }
2330 :
2331 412 : void Assembler::testb(Register dst, Register src) {
2332 : EnsureSpace ensure_space(this);
2333 412 : emit_test(dst, src, sizeof(int8_t));
2334 412 : }
2335 :
2336 301958 : void Assembler::testb(Register reg, Immediate mask) {
2337 : DCHECK(is_int8(mask.value_) || is_uint8(mask.value_));
2338 301958 : emit_test(reg, mask, sizeof(int8_t));
2339 301958 : }
2340 :
2341 746005 : void Assembler::testb(Operand op, Immediate mask) {
2342 : DCHECK(is_int8(mask.value_) || is_uint8(mask.value_));
2343 746005 : emit_test(op, mask, sizeof(int8_t));
2344 746004 : }
2345 :
2346 2429 : void Assembler::testb(Operand op, Register reg) {
2347 2429 : emit_test(op, reg, sizeof(int8_t));
2348 2429 : }
2349 :
2350 404 : void Assembler::testw(Register dst, Register src) {
2351 404 : emit_test(dst, src, sizeof(uint16_t));
2352 404 : }
2353 :
2354 20924 : void Assembler::testw(Register reg, Immediate mask) {
2355 20924 : emit_test(reg, mask, sizeof(int16_t));
2356 20924 : }
2357 :
2358 1156 : void Assembler::testw(Operand op, Immediate mask) {
2359 1156 : emit_test(op, mask, sizeof(int16_t));
2360 1156 : }
2361 :
2362 800 : void Assembler::testw(Operand op, Register reg) {
2363 800 : emit_test(op, reg, sizeof(int16_t));
2364 800 : }
2365 :
2366 449877 : void Assembler::emit_test(Register dst, Register src, int size) {
2367 : EnsureSpace ensure_space(this);
2368 449874 : if (src.low_bits() == 4) std::swap(dst, src);
2369 449874 : if (size == sizeof(int16_t)) {
2370 : emit(0x66);
2371 : size = sizeof(int32_t);
2372 : }
2373 : bool byte_operand = size == sizeof(int8_t);
2374 449874 : if (byte_operand) {
2375 : size = sizeof(int32_t);
2376 412 : if (!src.is_byte_register() || !dst.is_byte_register()) {
2377 : emit_rex_32(dst, src);
2378 : }
2379 : } else {
2380 449462 : emit_rex(dst, src, size);
2381 : }
2382 449878 : emit(byte_operand ? 0x84 : 0x85);
2383 : emit_modrm(dst, src);
2384 449878 : }
2385 :
2386 :
2387 985035 : void Assembler::emit_test(Register reg, Immediate mask, int size) {
2388 985035 : if (is_uint8(mask.value_)) {
2389 : size = sizeof(int8_t);
2390 18855 : } else if (is_uint16(mask.value_)) {
2391 : size = sizeof(int16_t);
2392 : }
2393 : EnsureSpace ensure_space(this);
2394 : bool half_word = size == sizeof(int16_t);
2395 985035 : if (half_word) {
2396 : emit(0x66);
2397 : size = sizeof(int32_t);
2398 : }
2399 : bool byte_operand = size == sizeof(int8_t);
2400 985035 : if (byte_operand) {
2401 : size = sizeof(int32_t);
2402 966180 : if (!reg.is_byte_register()) emit_rex_32(reg);
2403 : } else {
2404 : emit_rex(reg, size);
2405 : }
2406 985035 : if (reg == rax) {
2407 337273 : emit(byte_operand ? 0xA8 : 0xA9);
2408 : } else {
2409 647762 : emit(byte_operand ? 0xF6 : 0xF7);
2410 : emit_modrm(0x0, reg);
2411 : }
2412 985035 : if (byte_operand) {
2413 : emit(mask.value_);
2414 18855 : } else if (half_word) {
2415 : emitw(mask.value_);
2416 : } else {
2417 16131 : emit(mask);
2418 : }
2419 985035 : }
2420 :
2421 1366258 : void Assembler::emit_test(Operand op, Immediate mask, int size) {
2422 1366258 : if (is_uint8(mask.value_)) {
2423 : size = sizeof(int8_t);
2424 63512 : } else if (is_uint16(mask.value_)) {
2425 : size = sizeof(int16_t);
2426 : }
2427 : EnsureSpace ensure_space(this);
2428 : bool half_word = size == sizeof(int16_t);
2429 1366266 : if (half_word) {
2430 : emit(0x66);
2431 : size = sizeof(int32_t);
2432 : }
2433 : bool byte_operand = size == sizeof(int8_t);
2434 1366266 : if (byte_operand) {
2435 : size = sizeof(int32_t);
2436 : }
2437 : emit_rex(rax, op, size);
2438 1366266 : emit(byte_operand ? 0xF6 : 0xF7);
2439 : emit_operand(rax, op); // Operation code 0
2440 1366262 : if (byte_operand) {
2441 : emit(mask.value_);
2442 63512 : } else if (half_word) {
2443 : emitw(mask.value_);
2444 : } else {
2445 62772 : emit(mask);
2446 : }
2447 1366262 : }
2448 :
2449 3736 : void Assembler::emit_test(Operand op, Register reg, int size) {
2450 : EnsureSpace ensure_space(this);
2451 3736 : if (size == sizeof(int16_t)) {
2452 : emit(0x66);
2453 : size = sizeof(int32_t);
2454 : }
2455 : bool byte_operand = size == sizeof(int8_t);
2456 3736 : if (byte_operand) {
2457 : size = sizeof(int32_t);
2458 2429 : if (!reg.is_byte_register()) {
2459 : // Register is not one of al, bl, cl, dl. Its encoding needs REX.
2460 : emit_rex_32(reg, op);
2461 : } else {
2462 : emit_optional_rex_32(reg, op);
2463 : }
2464 : } else {
2465 : emit_rex(reg, op, size);
2466 : }
2467 3736 : emit(byte_operand ? 0x84 : 0x85);
2468 : emit_operand(reg, op);
2469 3736 : }
2470 :
2471 :
2472 : // FPU instructions.
2473 :
2474 :
2475 5 : void Assembler::fld(int i) {
2476 : EnsureSpace ensure_space(this);
2477 : emit_farith(0xD9, 0xC0, i);
2478 5 : }
2479 :
2480 :
2481 5 : void Assembler::fld1() {
2482 : EnsureSpace ensure_space(this);
2483 : emit(0xD9);
2484 : emit(0xE8);
2485 5 : }
2486 :
2487 :
2488 5 : void Assembler::fldz() {
2489 : EnsureSpace ensure_space(this);
2490 : emit(0xD9);
2491 : emit(0xEE);
2492 5 : }
2493 :
2494 :
2495 5 : void Assembler::fldpi() {
2496 : EnsureSpace ensure_space(this);
2497 : emit(0xD9);
2498 : emit(0xEB);
2499 5 : }
2500 :
2501 :
2502 0 : void Assembler::fldln2() {
2503 : EnsureSpace ensure_space(this);
2504 : emit(0xD9);
2505 : emit(0xED);
2506 0 : }
2507 :
2508 5 : void Assembler::fld_s(Operand adr) {
2509 : EnsureSpace ensure_space(this);
2510 : emit_optional_rex_32(adr);
2511 : emit(0xD9);
2512 5 : emit_operand(0, adr);
2513 5 : }
2514 :
2515 3163 : void Assembler::fld_d(Operand adr) {
2516 : EnsureSpace ensure_space(this);
2517 : emit_optional_rex_32(adr);
2518 : emit(0xDD);
2519 3163 : emit_operand(0, adr);
2520 3163 : }
2521 :
2522 5 : void Assembler::fstp_s(Operand adr) {
2523 : EnsureSpace ensure_space(this);
2524 : emit_optional_rex_32(adr);
2525 : emit(0xD9);
2526 5 : emit_operand(3, adr);
2527 5 : }
2528 :
2529 1584 : void Assembler::fstp_d(Operand adr) {
2530 : EnsureSpace ensure_space(this);
2531 : emit_optional_rex_32(adr);
2532 : emit(0xDD);
2533 1584 : emit_operand(3, adr);
2534 1584 : }
2535 :
2536 :
2537 1579 : void Assembler::fstp(int index) {
2538 : DCHECK(is_uint3(index));
2539 : EnsureSpace ensure_space(this);
2540 : emit_farith(0xDD, 0xD8, index);
2541 1579 : }
2542 :
2543 5 : void Assembler::fild_s(Operand adr) {
2544 : EnsureSpace ensure_space(this);
2545 : emit_optional_rex_32(adr);
2546 : emit(0xDB);
2547 5 : emit_operand(0, adr);
2548 5 : }
2549 :
2550 5 : void Assembler::fild_d(Operand adr) {
2551 : EnsureSpace ensure_space(this);
2552 : emit_optional_rex_32(adr);
2553 : emit(0xDF);
2554 5 : emit_operand(5, adr);
2555 5 : }
2556 :
2557 5 : void Assembler::fistp_s(Operand adr) {
2558 : EnsureSpace ensure_space(this);
2559 : emit_optional_rex_32(adr);
2560 : emit(0xDB);
2561 5 : emit_operand(3, adr);
2562 5 : }
2563 :
2564 0 : void Assembler::fisttp_s(Operand adr) {
2565 : DCHECK(IsEnabled(SSE3));
2566 : EnsureSpace ensure_space(this);
2567 : emit_optional_rex_32(adr);
2568 : emit(0xDB);
2569 0 : emit_operand(1, adr);
2570 0 : }
2571 :
2572 0 : void Assembler::fisttp_d(Operand adr) {
2573 : DCHECK(IsEnabled(SSE3));
2574 : EnsureSpace ensure_space(this);
2575 : emit_optional_rex_32(adr);
2576 : emit(0xDD);
2577 0 : emit_operand(1, adr);
2578 0 : }
2579 :
2580 0 : void Assembler::fist_s(Operand adr) {
2581 : EnsureSpace ensure_space(this);
2582 : emit_optional_rex_32(adr);
2583 : emit(0xDB);
2584 0 : emit_operand(2, adr);
2585 0 : }
2586 :
2587 5 : void Assembler::fistp_d(Operand adr) {
2588 : EnsureSpace ensure_space(this);
2589 : emit_optional_rex_32(adr);
2590 : emit(0xDF);
2591 5 : emit_operand(7, adr);
2592 5 : }
2593 :
2594 :
2595 5 : void Assembler::fabs() {
2596 : EnsureSpace ensure_space(this);
2597 : emit(0xD9);
2598 : emit(0xE1);
2599 5 : }
2600 :
2601 :
2602 5 : void Assembler::fchs() {
2603 : EnsureSpace ensure_space(this);
2604 : emit(0xD9);
2605 : emit(0xE0);
2606 5 : }
2607 :
2608 :
2609 0 : void Assembler::fcos() {
2610 : EnsureSpace ensure_space(this);
2611 : emit(0xD9);
2612 : emit(0xFF);
2613 0 : }
2614 :
2615 :
2616 0 : void Assembler::fsin() {
2617 : EnsureSpace ensure_space(this);
2618 : emit(0xD9);
2619 : emit(0xFE);
2620 0 : }
2621 :
2622 :
2623 0 : void Assembler::fptan() {
2624 : EnsureSpace ensure_space(this);
2625 : emit(0xD9);
2626 : emit(0xF2);
2627 0 : }
2628 :
2629 :
2630 0 : void Assembler::fyl2x() {
2631 : EnsureSpace ensure_space(this);
2632 : emit(0xD9);
2633 : emit(0xF1);
2634 0 : }
2635 :
2636 :
2637 0 : void Assembler::f2xm1() {
2638 : EnsureSpace ensure_space(this);
2639 : emit(0xD9);
2640 : emit(0xF0);
2641 0 : }
2642 :
2643 :
2644 0 : void Assembler::fscale() {
2645 : EnsureSpace ensure_space(this);
2646 : emit(0xD9);
2647 : emit(0xFD);
2648 0 : }
2649 :
2650 :
2651 5 : void Assembler::fninit() {
2652 : EnsureSpace ensure_space(this);
2653 : emit(0xDB);
2654 : emit(0xE3);
2655 5 : }
2656 :
2657 :
2658 5 : void Assembler::fadd(int i) {
2659 : EnsureSpace ensure_space(this);
2660 : emit_farith(0xDC, 0xC0, i);
2661 5 : }
2662 :
2663 :
2664 5 : void Assembler::fsub(int i) {
2665 : EnsureSpace ensure_space(this);
2666 : emit_farith(0xDC, 0xE8, i);
2667 5 : }
2668 :
2669 0 : void Assembler::fisub_s(Operand adr) {
2670 : EnsureSpace ensure_space(this);
2671 : emit_optional_rex_32(adr);
2672 : emit(0xDA);
2673 0 : emit_operand(4, adr);
2674 0 : }
2675 :
2676 :
2677 5 : void Assembler::fmul(int i) {
2678 : EnsureSpace ensure_space(this);
2679 : emit_farith(0xDC, 0xC8, i);
2680 5 : }
2681 :
2682 :
2683 5 : void Assembler::fdiv(int i) {
2684 : EnsureSpace ensure_space(this);
2685 : emit_farith(0xDC, 0xF8, i);
2686 5 : }
2687 :
2688 :
2689 5 : void Assembler::faddp(int i) {
2690 : EnsureSpace ensure_space(this);
2691 : emit_farith(0xDE, 0xC0, i);
2692 5 : }
2693 :
2694 :
2695 5 : void Assembler::fsubp(int i) {
2696 : EnsureSpace ensure_space(this);
2697 : emit_farith(0xDE, 0xE8, i);
2698 5 : }
2699 :
2700 :
2701 0 : void Assembler::fsubrp(int i) {
2702 : EnsureSpace ensure_space(this);
2703 : emit_farith(0xDE, 0xE0, i);
2704 0 : }
2705 :
2706 :
2707 5 : void Assembler::fmulp(int i) {
2708 : EnsureSpace ensure_space(this);
2709 : emit_farith(0xDE, 0xC8, i);
2710 5 : }
2711 :
2712 :
2713 5 : void Assembler::fdivp(int i) {
2714 : EnsureSpace ensure_space(this);
2715 : emit_farith(0xDE, 0xF8, i);
2716 5 : }
2717 :
2718 :
2719 1584 : void Assembler::fprem() {
2720 : EnsureSpace ensure_space(this);
2721 : emit(0xD9);
2722 : emit(0xF8);
2723 1584 : }
2724 :
2725 :
2726 5 : void Assembler::fprem1() {
2727 : EnsureSpace ensure_space(this);
2728 : emit(0xD9);
2729 : emit(0xF5);
2730 5 : }
2731 :
2732 :
2733 5 : void Assembler::fxch(int i) {
2734 : EnsureSpace ensure_space(this);
2735 : emit_farith(0xD9, 0xC8, i);
2736 5 : }
2737 :
2738 :
2739 5 : void Assembler::fincstp() {
2740 : EnsureSpace ensure_space(this);
2741 : emit(0xD9);
2742 : emit(0xF7);
2743 5 : }
2744 :
2745 :
2746 5 : void Assembler::ffree(int i) {
2747 : EnsureSpace ensure_space(this);
2748 : emit_farith(0xDD, 0xC0, i);
2749 5 : }
2750 :
2751 :
2752 5 : void Assembler::ftst() {
2753 : EnsureSpace ensure_space(this);
2754 : emit(0xD9);
2755 : emit(0xE4);
2756 5 : }
2757 :
2758 :
2759 0 : void Assembler::fucomp(int i) {
2760 : EnsureSpace ensure_space(this);
2761 : emit_farith(0xDD, 0xE8, i);
2762 0 : }
2763 :
2764 :
2765 0 : void Assembler::fucompp() {
2766 : EnsureSpace ensure_space(this);
2767 : emit(0xDA);
2768 : emit(0xE9);
2769 0 : }
2770 :
2771 :
2772 0 : void Assembler::fucomi(int i) {
2773 : EnsureSpace ensure_space(this);
2774 : emit(0xDB);
2775 0 : emit(0xE8 + i);
2776 0 : }
2777 :
2778 :
2779 0 : void Assembler::fucomip() {
2780 : EnsureSpace ensure_space(this);
2781 : emit(0xDF);
2782 : emit(0xE9);
2783 0 : }
2784 :
2785 :
2786 5 : void Assembler::fcompp() {
2787 : EnsureSpace ensure_space(this);
2788 : emit(0xDE);
2789 : emit(0xD9);
2790 5 : }
2791 :
2792 :
2793 1584 : void Assembler::fnstsw_ax() {
2794 : EnsureSpace ensure_space(this);
2795 : emit(0xDF);
2796 : emit(0xE0);
2797 1584 : }
2798 :
2799 :
2800 5 : void Assembler::fwait() {
2801 : EnsureSpace ensure_space(this);
2802 : emit(0x9B);
2803 5 : }
2804 :
2805 :
2806 5 : void Assembler::frndint() {
2807 : EnsureSpace ensure_space(this);
2808 : emit(0xD9);
2809 : emit(0xFC);
2810 5 : }
2811 :
2812 :
2813 0 : void Assembler::fnclex() {
2814 : EnsureSpace ensure_space(this);
2815 : emit(0xDB);
2816 : emit(0xE2);
2817 0 : }
2818 :
2819 :
2820 1547 : void Assembler::sahf() {
2821 : // TODO(X64): Test for presence. Not all 64-bit intel CPU's have sahf
2822 : // in 64-bit mode. Test CpuID.
2823 : DCHECK(IsEnabled(SAHF));
2824 : EnsureSpace ensure_space(this);
2825 : emit(0x9E);
2826 1547 : }
2827 :
2828 :
2829 0 : void Assembler::emit_farith(int b1, int b2, int i) {
2830 : DCHECK(is_uint8(b1) && is_uint8(b2)); // wrong opcode
2831 : DCHECK(is_uint3(i)); // illegal stack offset
2832 : emit(b1);
2833 1634 : emit(b2 + i);
2834 0 : }
2835 :
2836 :
2837 : // SSE operations.
2838 :
2839 37 : void Assembler::andps(XMMRegister dst, XMMRegister src) {
2840 : EnsureSpace ensure_space(this);
2841 : emit_optional_rex_32(dst, src);
2842 : emit(0x0F);
2843 : emit(0x54);
2844 : emit_sse_operand(dst, src);
2845 37 : }
2846 :
2847 5 : void Assembler::andps(XMMRegister dst, Operand src) {
2848 : EnsureSpace ensure_space(this);
2849 : emit_optional_rex_32(dst, src);
2850 : emit(0x0F);
2851 : emit(0x54);
2852 : emit_sse_operand(dst, src);
2853 5 : }
2854 :
2855 13 : void Assembler::andnps(XMMRegister dst, XMMRegister src) {
2856 : EnsureSpace ensure_space(this);
2857 : emit_optional_rex_32(dst, src);
2858 : emit(0x0F);
2859 : emit(0x55);
2860 : emit_sse_operand(dst, src);
2861 13 : }
2862 :
2863 5 : void Assembler::andnps(XMMRegister dst, Operand src) {
2864 : EnsureSpace ensure_space(this);
2865 : emit_optional_rex_32(dst, src);
2866 : emit(0x0F);
2867 : emit(0x55);
2868 : emit_sse_operand(dst, src);
2869 5 : }
2870 :
2871 17 : void Assembler::orps(XMMRegister dst, XMMRegister src) {
2872 : EnsureSpace ensure_space(this);
2873 : emit_optional_rex_32(dst, src);
2874 : emit(0x0F);
2875 : emit(0x56);
2876 : emit_sse_operand(dst, src);
2877 17 : }
2878 :
2879 5 : void Assembler::orps(XMMRegister dst, Operand src) {
2880 : EnsureSpace ensure_space(this);
2881 : emit_optional_rex_32(dst, src);
2882 : emit(0x0F);
2883 : emit(0x56);
2884 : emit_sse_operand(dst, src);
2885 5 : }
2886 :
2887 :
2888 429 : void Assembler::xorps(XMMRegister dst, XMMRegister src) {
2889 : DCHECK(!IsEnabled(AVX));
2890 : EnsureSpace ensure_space(this);
2891 : emit_optional_rex_32(dst, src);
2892 : emit(0x0F);
2893 : emit(0x57);
2894 : emit_sse_operand(dst, src);
2895 429 : }
2896 :
2897 5 : void Assembler::xorps(XMMRegister dst, Operand src) {
2898 : DCHECK(!IsEnabled(AVX));
2899 : EnsureSpace ensure_space(this);
2900 : emit_optional_rex_32(dst, src);
2901 : emit(0x0F);
2902 : emit(0x57);
2903 : emit_sse_operand(dst, src);
2904 5 : }
2905 :
2906 :
2907 29 : void Assembler::addps(XMMRegister dst, XMMRegister src) {
2908 : EnsureSpace ensure_space(this);
2909 : emit_optional_rex_32(dst, src);
2910 : emit(0x0F);
2911 : emit(0x58);
2912 : emit_sse_operand(dst, src);
2913 29 : }
2914 :
2915 5 : void Assembler::addps(XMMRegister dst, Operand src) {
2916 : EnsureSpace ensure_space(this);
2917 : emit_optional_rex_32(dst, src);
2918 : emit(0x0F);
2919 : emit(0x58);
2920 : emit_sse_operand(dst, src);
2921 5 : }
2922 :
2923 :
2924 21 : void Assembler::subps(XMMRegister dst, XMMRegister src) {
2925 : EnsureSpace ensure_space(this);
2926 : emit_optional_rex_32(dst, src);
2927 : emit(0x0F);
2928 : emit(0x5C);
2929 : emit_sse_operand(dst, src);
2930 21 : }
2931 :
2932 5 : void Assembler::subps(XMMRegister dst, Operand src) {
2933 : EnsureSpace ensure_space(this);
2934 : emit_optional_rex_32(dst, src);
2935 : emit(0x0F);
2936 : emit(0x5C);
2937 : emit_sse_operand(dst, src);
2938 5 : }
2939 :
2940 :
2941 13 : void Assembler::mulps(XMMRegister dst, XMMRegister src) {
2942 : EnsureSpace ensure_space(this);
2943 : emit_optional_rex_32(dst, src);
2944 : emit(0x0F);
2945 : emit(0x59);
2946 : emit_sse_operand(dst, src);
2947 13 : }
2948 :
2949 5 : void Assembler::mulps(XMMRegister dst, Operand src) {
2950 : EnsureSpace ensure_space(this);
2951 : emit_optional_rex_32(dst, src);
2952 : emit(0x0F);
2953 : emit(0x59);
2954 : emit_sse_operand(dst, src);
2955 5 : }
2956 :
2957 :
2958 9 : void Assembler::divps(XMMRegister dst, XMMRegister src) {
2959 : EnsureSpace ensure_space(this);
2960 : emit_optional_rex_32(dst, src);
2961 : emit(0x0F);
2962 : emit(0x5E);
2963 : emit_sse_operand(dst, src);
2964 9 : }
2965 :
2966 5 : void Assembler::divps(XMMRegister dst, Operand src) {
2967 : EnsureSpace ensure_space(this);
2968 : emit_optional_rex_32(dst, src);
2969 : emit(0x0F);
2970 : emit(0x5E);
2971 : emit_sse_operand(dst, src);
2972 5 : }
2973 :
2974 :
2975 : // SSE 2 operations.
2976 :
2977 1882 : void Assembler::movd(XMMRegister dst, Register src) {
2978 : DCHECK(!IsEnabled(AVX));
2979 : EnsureSpace ensure_space(this);
2980 : emit(0x66);
2981 : emit_optional_rex_32(dst, src);
2982 : emit(0x0F);
2983 : emit(0x6E);
2984 : emit_sse_operand(dst, src);
2985 1882 : }
2986 :
2987 0 : void Assembler::movd(XMMRegister dst, Operand src) {
2988 : DCHECK(!IsEnabled(AVX));
2989 : EnsureSpace ensure_space(this);
2990 : emit(0x66);
2991 : emit_optional_rex_32(dst, src);
2992 : emit(0x0F);
2993 : emit(0x6E);
2994 : emit_sse_operand(dst, src);
2995 0 : }
2996 :
2997 :
2998 4 : void Assembler::movd(Register dst, XMMRegister src) {
2999 : DCHECK(!IsEnabled(AVX));
3000 : EnsureSpace ensure_space(this);
3001 : emit(0x66);
3002 : emit_optional_rex_32(src, dst);
3003 : emit(0x0F);
3004 : emit(0x7E);
3005 : emit_sse_operand(src, dst);
3006 4 : }
3007 :
3008 :
3009 216 : void Assembler::movq(XMMRegister dst, Register src) {
3010 : DCHECK(!IsEnabled(AVX));
3011 : EnsureSpace ensure_space(this);
3012 : emit(0x66);
3013 : emit_rex_64(dst, src);
3014 : emit(0x0F);
3015 : emit(0x6E);
3016 : emit_sse_operand(dst, src);
3017 216 : }
3018 :
3019 :
3020 336 : void Assembler::movq(Register dst, XMMRegister src) {
3021 : DCHECK(!IsEnabled(AVX));
3022 : EnsureSpace ensure_space(this);
3023 : emit(0x66);
3024 : emit_rex_64(src, dst);
3025 : emit(0x0F);
3026 : emit(0x7E);
3027 : emit_sse_operand(src, dst);
3028 336 : }
3029 :
3030 :
3031 0 : void Assembler::movq(XMMRegister dst, XMMRegister src) {
3032 : DCHECK(!IsEnabled(AVX));
3033 : EnsureSpace ensure_space(this);
3034 0 : if (dst.low_bits() == 4) {
3035 : // Avoid unnecessary SIB byte.
3036 : emit(0xF3);
3037 : emit_optional_rex_32(dst, src);
3038 : emit(0x0F);
3039 : emit(0x7E);
3040 : emit_sse_operand(dst, src);
3041 : } else {
3042 : emit(0x66);
3043 : emit_optional_rex_32(src, dst);
3044 : emit(0x0F);
3045 : emit(0xD6);
3046 : emit_sse_operand(src, dst);
3047 : }
3048 0 : }
3049 :
3050 10 : void Assembler::movdqa(Operand dst, XMMRegister src) {
3051 : EnsureSpace ensure_space(this);
3052 : emit(0x66);
3053 : emit_rex_64(src, dst);
3054 : emit(0x0F);
3055 : emit(0x7F);
3056 : emit_sse_operand(src, dst);
3057 10 : }
3058 :
3059 14 : void Assembler::movdqa(XMMRegister dst, Operand src) {
3060 : EnsureSpace ensure_space(this);
3061 : emit(0x66);
3062 : emit_rex_64(dst, src);
3063 : emit(0x0F);
3064 : emit(0x6F);
3065 : emit_sse_operand(dst, src);
3066 14 : }
3067 :
3068 4421 : void Assembler::movdqu(Operand dst, XMMRegister src) {
3069 : EnsureSpace ensure_space(this);
3070 : emit(0xF3);
3071 : emit_rex_64(src, dst);
3072 : emit(0x0F);
3073 : emit(0x7F);
3074 : emit_sse_operand(src, dst);
3075 4421 : }
3076 :
3077 6269 : void Assembler::movdqu(XMMRegister dst, Operand src) {
3078 : EnsureSpace ensure_space(this);
3079 : emit(0xF3);
3080 : emit_rex_64(dst, src);
3081 : emit(0x0F);
3082 : emit(0x6F);
3083 : emit_sse_operand(dst, src);
3084 6269 : }
3085 :
3086 :
3087 41 : void Assembler::extractps(Register dst, XMMRegister src, byte imm8) {
3088 : DCHECK(IsEnabled(SSE4_1));
3089 : DCHECK(is_uint8(imm8));
3090 : EnsureSpace ensure_space(this);
3091 : emit(0x66);
3092 : emit_optional_rex_32(src, dst);
3093 : emit(0x0F);
3094 : emit(0x3A);
3095 : emit(0x17);
3096 : emit_sse_operand(src, dst);
3097 : emit(imm8);
3098 41 : }
3099 :
3100 48 : void Assembler::pextrb(Register dst, XMMRegister src, int8_t imm8) {
3101 : DCHECK(IsEnabled(SSE4_1));
3102 : DCHECK(is_uint8(imm8));
3103 : EnsureSpace ensure_space(this);
3104 : emit(0x66);
3105 : emit_optional_rex_32(src, dst);
3106 : emit(0x0F);
3107 : emit(0x3A);
3108 : emit(0x14);
3109 : emit_sse_operand(src, dst);
3110 48 : emit(imm8);
3111 48 : }
3112 :
3113 0 : void Assembler::pextrb(Operand dst, XMMRegister src, int8_t imm8) {
3114 : DCHECK(IsEnabled(SSE4_1));
3115 : DCHECK(is_uint8(imm8));
3116 : EnsureSpace ensure_space(this);
3117 : emit(0x66);
3118 : emit_optional_rex_32(src, dst);
3119 : emit(0x0F);
3120 : emit(0x3A);
3121 : emit(0x14);
3122 : emit_sse_operand(src, dst);
3123 0 : emit(imm8);
3124 0 : }
3125 :
3126 57 : void Assembler::pinsrw(XMMRegister dst, Register src, int8_t imm8) {
3127 : DCHECK(is_uint8(imm8));
3128 : EnsureSpace ensure_space(this);
3129 : emit(0x66);
3130 : emit_optional_rex_32(dst, src);
3131 : emit(0x0F);
3132 : emit(0xC4);
3133 : emit_sse_operand(dst, src);
3134 57 : emit(imm8);
3135 57 : }
3136 :
3137 0 : void Assembler::pinsrw(XMMRegister dst, Operand src, int8_t imm8) {
3138 : DCHECK(is_uint8(imm8));
3139 : EnsureSpace ensure_space(this);
3140 : emit(0x66);
3141 : emit_optional_rex_32(dst, src);
3142 : emit(0x0F);
3143 : emit(0xC4);
3144 : emit_sse_operand(dst, src);
3145 0 : emit(imm8);
3146 0 : }
3147 :
3148 53 : void Assembler::pextrw(Register dst, XMMRegister src, int8_t imm8) {
3149 : DCHECK(IsEnabled(SSE4_1));
3150 : DCHECK(is_uint8(imm8));
3151 : EnsureSpace ensure_space(this);
3152 : emit(0x66);
3153 : emit_optional_rex_32(src, dst);
3154 : emit(0x0F);
3155 : emit(0x3A);
3156 : emit(0x15);
3157 : emit_sse_operand(src, dst);
3158 53 : emit(imm8);
3159 53 : }
3160 :
3161 0 : void Assembler::pextrw(Operand dst, XMMRegister src, int8_t imm8) {
3162 : DCHECK(IsEnabled(SSE4_1));
3163 : DCHECK(is_uint8(imm8));
3164 : EnsureSpace ensure_space(this);
3165 : emit(0x66);
3166 : emit_optional_rex_32(src, dst);
3167 : emit(0x0F);
3168 : emit(0x3A);
3169 : emit(0x15);
3170 : emit_sse_operand(src, dst);
3171 0 : emit(imm8);
3172 0 : }
3173 :
3174 42361 : void Assembler::pextrd(Register dst, XMMRegister src, int8_t imm8) {
3175 : DCHECK(IsEnabled(SSE4_1));
3176 : EnsureSpace ensure_space(this);
3177 : emit(0x66);
3178 : emit_optional_rex_32(src, dst);
3179 : emit(0x0F);
3180 : emit(0x3A);
3181 : emit(0x16);
3182 : emit_sse_operand(src, dst);
3183 42361 : emit(imm8);
3184 42361 : }
3185 :
3186 0 : void Assembler::pextrd(Operand dst, XMMRegister src, int8_t imm8) {
3187 : DCHECK(IsEnabled(SSE4_1));
3188 : EnsureSpace ensure_space(this);
3189 : emit(0x66);
3190 : emit_optional_rex_32(src, dst);
3191 : emit(0x0F);
3192 : emit(0x3A);
3193 : emit(0x16);
3194 : emit_sse_operand(src, dst);
3195 0 : emit(imm8);
3196 0 : }
3197 :
3198 419 : void Assembler::pinsrd(XMMRegister dst, Register src, int8_t imm8) {
3199 : DCHECK(IsEnabled(SSE4_1));
3200 : EnsureSpace ensure_space(this);
3201 : emit(0x66);
3202 : emit_optional_rex_32(dst, src);
3203 : emit(0x0F);
3204 : emit(0x3A);
3205 : emit(0x22);
3206 : emit_sse_operand(dst, src);
3207 419 : emit(imm8);
3208 419 : }
3209 :
3210 1493 : void Assembler::pinsrd(XMMRegister dst, Operand src, int8_t imm8) {
3211 : DCHECK(IsEnabled(SSE4_1));
3212 : EnsureSpace ensure_space(this);
3213 : emit(0x66);
3214 : emit_optional_rex_32(dst, src);
3215 : emit(0x0F);
3216 : emit(0x3A);
3217 : emit(0x22);
3218 : emit_sse_operand(dst, src);
3219 1493 : emit(imm8);
3220 1493 : }
3221 :
3222 84 : void Assembler::pinsrb(XMMRegister dst, Register src, int8_t imm8) {
3223 : DCHECK(IsEnabled(SSE4_1));
3224 : EnsureSpace ensure_space(this);
3225 : emit(0x66);
3226 : emit_optional_rex_32(dst, src);
3227 : emit(0x0F);
3228 : emit(0x3A);
3229 : emit(0x20);
3230 : emit_sse_operand(dst, src);
3231 84 : emit(imm8);
3232 84 : }
3233 :
3234 0 : void Assembler::pinsrb(XMMRegister dst, Operand src, int8_t imm8) {
3235 : DCHECK(IsEnabled(SSE4_1));
3236 : EnsureSpace ensure_space(this);
3237 : emit(0x66);
3238 : emit_optional_rex_32(dst, src);
3239 : emit(0x0F);
3240 : emit(0x3A);
3241 : emit(0x20);
3242 : emit_sse_operand(dst, src);
3243 0 : emit(imm8);
3244 0 : }
3245 :
3246 37 : void Assembler::insertps(XMMRegister dst, XMMRegister src, byte imm8) {
3247 : DCHECK(CpuFeatures::IsSupported(SSE4_1));
3248 : DCHECK(is_uint8(imm8));
3249 : EnsureSpace ensure_space(this);
3250 : emit(0x66);
3251 : emit_optional_rex_32(dst, src);
3252 : emit(0x0F);
3253 : emit(0x3A);
3254 : emit(0x21);
3255 : emit_sse_operand(dst, src);
3256 : emit(imm8);
3257 37 : }
3258 :
3259 0 : void Assembler::insertps(XMMRegister dst, Operand src, byte imm8) {
3260 : DCHECK(CpuFeatures::IsSupported(SSE4_1));
3261 : DCHECK(is_uint8(imm8));
3262 : EnsureSpace ensure_space(this);
3263 : emit(0x66);
3264 : emit_optional_rex_32(dst, src);
3265 : emit(0x0F);
3266 : emit(0x3A);
3267 : emit(0x21);
3268 : emit_sse_operand(dst, src);
3269 : emit(imm8);
3270 0 : }
3271 :
3272 2502 : void Assembler::movsd(Operand dst, XMMRegister src) {
3273 : DCHECK(!IsEnabled(AVX));
3274 : EnsureSpace ensure_space(this);
3275 : emit(0xF2); // double
3276 : emit_optional_rex_32(src, dst);
3277 : emit(0x0F);
3278 : emit(0x11); // store
3279 : emit_sse_operand(src, dst);
3280 2502 : }
3281 :
3282 :
3283 4 : void Assembler::movsd(XMMRegister dst, XMMRegister src) {
3284 : DCHECK(!IsEnabled(AVX));
3285 : EnsureSpace ensure_space(this);
3286 : emit(0xF2); // double
3287 : emit_optional_rex_32(dst, src);
3288 : emit(0x0F);
3289 : emit(0x10); // load
3290 : emit_sse_operand(dst, src);
3291 4 : }
3292 :
3293 4572 : void Assembler::movsd(XMMRegister dst, Operand src) {
3294 : DCHECK(!IsEnabled(AVX));
3295 : EnsureSpace ensure_space(this);
3296 : emit(0xF2); // double
3297 : emit_optional_rex_32(dst, src);
3298 : emit(0x0F);
3299 : emit(0x10); // load
3300 : emit_sse_operand(dst, src);
3301 4572 : }
3302 :
3303 :
3304 381 : void Assembler::movaps(XMMRegister dst, XMMRegister src) {
3305 : DCHECK(!IsEnabled(AVX));
3306 : EnsureSpace ensure_space(this);
3307 381 : if (src.low_bits() == 4) {
3308 : // Try to avoid an unnecessary SIB byte.
3309 : emit_optional_rex_32(src, dst);
3310 : emit(0x0F);
3311 : emit(0x29);
3312 : emit_sse_operand(src, dst);
3313 : } else {
3314 : emit_optional_rex_32(dst, src);
3315 : emit(0x0F);
3316 : emit(0x28);
3317 : emit_sse_operand(dst, src);
3318 : }
3319 381 : }
3320 :
3321 :
3322 173 : void Assembler::shufps(XMMRegister dst, XMMRegister src, byte imm8) {
3323 : DCHECK(is_uint8(imm8));
3324 : EnsureSpace ensure_space(this);
3325 : emit_optional_rex_32(dst, src);
3326 : emit(0x0F);
3327 : emit(0xC6);
3328 : emit_sse_operand(dst, src);
3329 : emit(imm8);
3330 173 : }
3331 :
3332 :
3333 542 : void Assembler::movapd(XMMRegister dst, XMMRegister src) {
3334 : DCHECK(!IsEnabled(AVX));
3335 : EnsureSpace ensure_space(this);
3336 542 : if (src.low_bits() == 4) {
3337 : // Try to avoid an unnecessary SIB byte.
3338 : emit(0x66);
3339 : emit_optional_rex_32(src, dst);
3340 : emit(0x0F);
3341 : emit(0x29);
3342 : emit_sse_operand(src, dst);
3343 : } else {
3344 : emit(0x66);
3345 : emit_optional_rex_32(dst, src);
3346 : emit(0x0F);
3347 : emit(0x28);
3348 : emit_sse_operand(dst, src);
3349 : }
3350 542 : }
3351 :
3352 15 : void Assembler::movupd(XMMRegister dst, Operand src) {
3353 : EnsureSpace ensure_space(this);
3354 : emit(0x66);
3355 : emit_optional_rex_32(dst, src);
3356 : emit(0x0F);
3357 : emit(0x10);
3358 : emit_sse_operand(dst, src);
3359 15 : }
3360 :
3361 15 : void Assembler::movupd(Operand dst, XMMRegister src) {
3362 : EnsureSpace ensure_space(this);
3363 : emit(0x66);
3364 : emit_optional_rex_32(src, dst);
3365 : emit(0x0F);
3366 : emit(0x11);
3367 : emit_sse_operand(src, dst);
3368 15 : }
3369 :
3370 121 : void Assembler::addss(XMMRegister dst, XMMRegister src) {
3371 : EnsureSpace ensure_space(this);
3372 : emit(0xF3);
3373 : emit_optional_rex_32(dst, src);
3374 : emit(0x0F);
3375 : emit(0x58);
3376 : emit_sse_operand(dst, src);
3377 122 : }
3378 :
3379 5 : void Assembler::addss(XMMRegister dst, Operand src) {
3380 : EnsureSpace ensure_space(this);
3381 : emit(0xF3);
3382 : emit_optional_rex_32(dst, src);
3383 : emit(0x0F);
3384 : emit(0x58);
3385 : emit_sse_operand(dst, src);
3386 5 : }
3387 :
3388 :
3389 9 : void Assembler::subss(XMMRegister dst, XMMRegister src) {
3390 : EnsureSpace ensure_space(this);
3391 : emit(0xF3);
3392 : emit_optional_rex_32(dst, src);
3393 : emit(0x0F);
3394 : emit(0x5C);
3395 : emit_sse_operand(dst, src);
3396 9 : }
3397 :
3398 5 : void Assembler::subss(XMMRegister dst, Operand src) {
3399 : EnsureSpace ensure_space(this);
3400 : emit(0xF3);
3401 : emit_optional_rex_32(dst, src);
3402 : emit(0x0F);
3403 : emit(0x5C);
3404 : emit_sse_operand(dst, src);
3405 5 : }
3406 :
3407 :
3408 17 : void Assembler::mulss(XMMRegister dst, XMMRegister src) {
3409 : EnsureSpace ensure_space(this);
3410 : emit(0xF3);
3411 : emit_optional_rex_32(dst, src);
3412 : emit(0x0F);
3413 : emit(0x59);
3414 : emit_sse_operand(dst, src);
3415 17 : }
3416 :
3417 5 : void Assembler::mulss(XMMRegister dst, Operand src) {
3418 : EnsureSpace ensure_space(this);
3419 : emit(0xF3);
3420 : emit_optional_rex_32(dst, src);
3421 : emit(0x0F);
3422 : emit(0x59);
3423 : emit_sse_operand(dst, src);
3424 5 : }
3425 :
3426 :
3427 9 : void Assembler::divss(XMMRegister dst, XMMRegister src) {
3428 : EnsureSpace ensure_space(this);
3429 : emit(0xF3);
3430 : emit_optional_rex_32(dst, src);
3431 : emit(0x0F);
3432 : emit(0x5E);
3433 : emit_sse_operand(dst, src);
3434 9 : }
3435 :
3436 5 : void Assembler::divss(XMMRegister dst, Operand src) {
3437 : EnsureSpace ensure_space(this);
3438 : emit(0xF3);
3439 : emit_optional_rex_32(dst, src);
3440 : emit(0x0F);
3441 : emit(0x5E);
3442 : emit_sse_operand(dst, src);
3443 5 : }
3444 :
3445 :
3446 9 : void Assembler::maxss(XMMRegister dst, XMMRegister src) {
3447 : EnsureSpace ensure_space(this);
3448 : emit(0xF3);
3449 : emit_optional_rex_32(dst, src);
3450 : emit(0x0F);
3451 : emit(0x5F);
3452 : emit_sse_operand(dst, src);
3453 9 : }
3454 :
3455 5 : void Assembler::maxss(XMMRegister dst, Operand src) {
3456 : EnsureSpace ensure_space(this);
3457 : emit(0xF3);
3458 : emit_optional_rex_32(dst, src);
3459 : emit(0x0F);
3460 : emit(0x5F);
3461 : emit_sse_operand(dst, src);
3462 5 : }
3463 :
3464 :
3465 9 : void Assembler::minss(XMMRegister dst, XMMRegister src) {
3466 : EnsureSpace ensure_space(this);
3467 : emit(0xF3);
3468 : emit_optional_rex_32(dst, src);
3469 : emit(0x0F);
3470 : emit(0x5D);
3471 : emit_sse_operand(dst, src);
3472 9 : }
3473 :
3474 5 : void Assembler::minss(XMMRegister dst, Operand src) {
3475 : EnsureSpace ensure_space(this);
3476 : emit(0xF3);
3477 : emit_optional_rex_32(dst, src);
3478 : emit(0x0F);
3479 : emit(0x5D);
3480 : emit_sse_operand(dst, src);
3481 5 : }
3482 :
3483 :
3484 187 : void Assembler::sqrtss(XMMRegister dst, XMMRegister src) {
3485 : EnsureSpace ensure_space(this);
3486 : emit(0xF3);
3487 : emit_optional_rex_32(dst, src);
3488 : emit(0x0F);
3489 : emit(0x51);
3490 : emit_sse_operand(dst, src);
3491 187 : }
3492 :
3493 5 : void Assembler::sqrtss(XMMRegister dst, Operand src) {
3494 : EnsureSpace ensure_space(this);
3495 : emit(0xF3);
3496 : emit_optional_rex_32(dst, src);
3497 : emit(0x0F);
3498 : emit(0x51);
3499 : emit_sse_operand(dst, src);
3500 5 : }
3501 :
3502 :
3503 29 : void Assembler::ucomiss(XMMRegister dst, XMMRegister src) {
3504 : DCHECK(!IsEnabled(AVX));
3505 : EnsureSpace ensure_space(this);
3506 : emit_optional_rex_32(dst, src);
3507 : emit(0x0F);
3508 : emit(0x2E);
3509 : emit_sse_operand(dst, src);
3510 29 : }
3511 :
3512 5 : void Assembler::ucomiss(XMMRegister dst, Operand src) {
3513 : DCHECK(!IsEnabled(AVX));
3514 : EnsureSpace ensure_space(this);
3515 : emit_optional_rex_32(dst, src);
3516 : emit(0x0F);
3517 : emit(0x2E);
3518 : emit_sse_operand(dst, src);
3519 5 : }
3520 :
3521 :
3522 140 : void Assembler::movss(XMMRegister dst, XMMRegister src) {
3523 : DCHECK(!IsEnabled(AVX));
3524 : EnsureSpace ensure_space(this);
3525 : emit(0xF3); // single
3526 : emit_optional_rex_32(dst, src);
3527 : emit(0x0F);
3528 : emit(0x10); // load
3529 : emit_sse_operand(dst, src);
3530 140 : }
3531 :
3532 15710 : void Assembler::movss(XMMRegister dst, Operand src) {
3533 : DCHECK(!IsEnabled(AVX));
3534 : EnsureSpace ensure_space(this);
3535 : emit(0xF3); // single
3536 : emit_optional_rex_32(dst, src);
3537 : emit(0x0F);
3538 : emit(0x10); // load
3539 : emit_sse_operand(dst, src);
3540 15710 : }
3541 :
3542 13157 : void Assembler::movss(Operand src, XMMRegister dst) {
3543 : DCHECK(!IsEnabled(AVX));
3544 : EnsureSpace ensure_space(this);
3545 : emit(0xF3); // single
3546 : emit_optional_rex_32(dst, src);
3547 : emit(0x0F);
3548 : emit(0x11); // store
3549 : emit_sse_operand(dst, src);
3550 13157 : }
3551 :
3552 :
3553 371 : void Assembler::psllq(XMMRegister reg, byte imm8) {
3554 : DCHECK(!IsEnabled(AVX));
3555 : EnsureSpace ensure_space(this);
3556 : emit(0x66);
3557 : emit_optional_rex_32(reg);
3558 : emit(0x0F);
3559 : emit(0x73);
3560 : emit_sse_operand(rsi, reg); // rsi == 6
3561 : emit(imm8);
3562 371 : }
3563 :
3564 :
3565 293 : void Assembler::psrlq(XMMRegister reg, byte imm8) {
3566 : DCHECK(!IsEnabled(AVX));
3567 : EnsureSpace ensure_space(this);
3568 : emit(0x66);
3569 : emit_optional_rex_32(reg);
3570 : emit(0x0F);
3571 : emit(0x73);
3572 : emit_sse_operand(rdx, reg); // rdx == 2
3573 : emit(imm8);
3574 293 : }
3575 :
3576 1048 : void Assembler::psllw(XMMRegister reg, byte imm8) {
3577 : EnsureSpace ensure_space(this);
3578 : emit(0x66);
3579 : emit_optional_rex_32(reg);
3580 : emit(0x0F);
3581 : emit(0x71);
3582 : emit_sse_operand(rsi, reg); // rsi == 6
3583 : emit(imm8);
3584 1048 : }
3585 :
3586 137 : void Assembler::pslld(XMMRegister reg, byte imm8) {
3587 : EnsureSpace ensure_space(this);
3588 : emit(0x66);
3589 : emit_optional_rex_32(reg);
3590 : emit(0x0F);
3591 : emit(0x72);
3592 : emit_sse_operand(rsi, reg); // rsi == 6
3593 : emit(imm8);
3594 137 : }
3595 :
3596 1284 : void Assembler::psrlw(XMMRegister reg, byte imm8) {
3597 : EnsureSpace ensure_space(this);
3598 : emit(0x66);
3599 : emit_optional_rex_32(reg);
3600 : emit(0x0F);
3601 : emit(0x71);
3602 : emit_sse_operand(rdx, reg); // rdx == 2
3603 : emit(imm8);
3604 1284 : }
3605 :
3606 385 : void Assembler::psrld(XMMRegister reg, byte imm8) {
3607 : EnsureSpace ensure_space(this);
3608 : emit(0x66);
3609 : emit_optional_rex_32(reg);
3610 : emit(0x0F);
3611 : emit(0x72);
3612 : emit_sse_operand(rdx, reg); // rdx == 2
3613 : emit(imm8);
3614 385 : }
3615 :
3616 116 : void Assembler::psraw(XMMRegister reg, byte imm8) {
3617 : EnsureSpace ensure_space(this);
3618 : emit(0x66);
3619 : emit_optional_rex_32(reg);
3620 : emit(0x0F);
3621 : emit(0x71);
3622 : emit_sse_operand(rsp, reg); // rsp == 4
3623 : emit(imm8);
3624 116 : }
3625 :
3626 128 : void Assembler::psrad(XMMRegister reg, byte imm8) {
3627 : EnsureSpace ensure_space(this);
3628 : emit(0x66);
3629 : emit_optional_rex_32(reg);
3630 : emit(0x0F);
3631 : emit(0x72);
3632 : emit_sse_operand(rsp, reg); // rsp == 4
3633 : emit(imm8);
3634 128 : }
3635 :
3636 75 : void Assembler::cmpps(XMMRegister dst, XMMRegister src, int8_t cmp) {
3637 : EnsureSpace ensure_space(this);
3638 : emit_optional_rex_32(dst, src);
3639 : emit(0x0F);
3640 : emit(0xC2);
3641 : emit_sse_operand(dst, src);
3642 75 : emit(cmp);
3643 75 : }
3644 :
3645 35 : void Assembler::cmpps(XMMRegister dst, Operand src, int8_t cmp) {
3646 : EnsureSpace ensure_space(this);
3647 : emit_optional_rex_32(dst, src);
3648 : emit(0x0F);
3649 : emit(0xC2);
3650 : emit_sse_operand(dst, src);
3651 35 : emit(cmp);
3652 35 : }
3653 :
3654 35 : void Assembler::cmppd(XMMRegister dst, XMMRegister src, int8_t cmp) {
3655 : EnsureSpace ensure_space(this);
3656 : emit_optional_rex_32(dst, src);
3657 : emit(0x66);
3658 : emit(0x0F);
3659 : emit(0xC2);
3660 : emit_sse_operand(dst, src);
3661 35 : emit(cmp);
3662 35 : }
3663 :
3664 35 : void Assembler::cmppd(XMMRegister dst, Operand src, int8_t cmp) {
3665 : EnsureSpace ensure_space(this);
3666 : emit_optional_rex_32(dst, src);
3667 : emit(0x66);
3668 : emit(0x0F);
3669 : emit(0xC2);
3670 : emit_sse_operand(dst, src);
3671 35 : emit(cmp);
3672 35 : }
3673 :
3674 5 : void Assembler::cvttss2si(Register dst, Operand src) {
3675 : DCHECK(!IsEnabled(AVX));
3676 : EnsureSpace ensure_space(this);
3677 : emit(0xF3);
3678 : emit_optional_rex_32(dst, src);
3679 : emit(0x0F);
3680 : emit(0x2C);
3681 : emit_operand(dst, src);
3682 5 : }
3683 :
3684 :
3685 13 : void Assembler::cvttss2si(Register dst, XMMRegister src) {
3686 : DCHECK(!IsEnabled(AVX));
3687 : EnsureSpace ensure_space(this);
3688 : emit(0xF3);
3689 : emit_optional_rex_32(dst, src);
3690 : emit(0x0F);
3691 : emit(0x2C);
3692 : emit_sse_operand(dst, src);
3693 13 : }
3694 :
3695 5 : void Assembler::cvttsd2si(Register dst, Operand src) {
3696 : DCHECK(!IsEnabled(AVX));
3697 : EnsureSpace ensure_space(this);
3698 : emit(0xF2);
3699 : emit_optional_rex_32(dst, src);
3700 : emit(0x0F);
3701 : emit(0x2C);
3702 : emit_operand(dst, src);
3703 5 : }
3704 :
3705 :
3706 527 : void Assembler::cvttsd2si(Register dst, XMMRegister src) {
3707 : DCHECK(!IsEnabled(AVX));
3708 : EnsureSpace ensure_space(this);
3709 : emit(0xF2);
3710 : emit_optional_rex_32(dst, src);
3711 : emit(0x0F);
3712 : emit(0x2C);
3713 : emit_sse_operand(dst, src);
3714 527 : }
3715 :
3716 :
3717 0 : void Assembler::cvttss2siq(Register dst, XMMRegister src) {
3718 : DCHECK(!IsEnabled(AVX));
3719 : EnsureSpace ensure_space(this);
3720 : emit(0xF3);
3721 : emit_rex_64(dst, src);
3722 : emit(0x0F);
3723 : emit(0x2C);
3724 : emit_sse_operand(dst, src);
3725 0 : }
3726 :
3727 0 : void Assembler::cvttss2siq(Register dst, Operand src) {
3728 : DCHECK(!IsEnabled(AVX));
3729 : EnsureSpace ensure_space(this);
3730 : emit(0xF3);
3731 : emit_rex_64(dst, src);
3732 : emit(0x0F);
3733 : emit(0x2C);
3734 : emit_sse_operand(dst, src);
3735 0 : }
3736 :
3737 :
3738 416 : void Assembler::cvttsd2siq(Register dst, XMMRegister src) {
3739 : DCHECK(!IsEnabled(AVX));
3740 : EnsureSpace ensure_space(this);
3741 : emit(0xF2);
3742 : emit_rex_64(dst, src);
3743 : emit(0x0F);
3744 : emit(0x2C);
3745 : emit_sse_operand(dst, src);
3746 416 : }
3747 :
3748 5 : void Assembler::cvttsd2siq(Register dst, Operand src) {
3749 : DCHECK(!IsEnabled(AVX));
3750 : EnsureSpace ensure_space(this);
3751 : emit(0xF2);
3752 : emit_rex_64(dst, src);
3753 : emit(0x0F);
3754 : emit(0x2C);
3755 : emit_sse_operand(dst, src);
3756 5 : }
3757 :
3758 5 : void Assembler::cvttps2dq(XMMRegister dst, Operand src) {
3759 : EnsureSpace ensure_space(this);
3760 : emit(0xF3);
3761 : emit_rex_64(dst, src);
3762 : emit(0x0F);
3763 : emit(0x5B);
3764 : emit_sse_operand(dst, src);
3765 5 : }
3766 :
3767 17 : void Assembler::cvttps2dq(XMMRegister dst, XMMRegister src) {
3768 : EnsureSpace ensure_space(this);
3769 : emit(0xF3);
3770 : emit_rex_64(dst, src);
3771 : emit(0x0F);
3772 : emit(0x5B);
3773 : emit_sse_operand(dst, src);
3774 17 : }
3775 :
3776 2 : void Assembler::cvtlsi2sd(XMMRegister dst, Operand src) {
3777 : DCHECK(!IsEnabled(AVX));
3778 : EnsureSpace ensure_space(this);
3779 : emit(0xF2);
3780 : emit_optional_rex_32(dst, src);
3781 : emit(0x0F);
3782 : emit(0x2A);
3783 : emit_sse_operand(dst, src);
3784 2 : }
3785 :
3786 :
3787 2026 : void Assembler::cvtlsi2sd(XMMRegister dst, Register src) {
3788 : DCHECK(!IsEnabled(AVX));
3789 : EnsureSpace ensure_space(this);
3790 : emit(0xF2);
3791 : emit_optional_rex_32(dst, src);
3792 : emit(0x0F);
3793 : emit(0x2A);
3794 : emit_sse_operand(dst, src);
3795 2026 : }
3796 :
3797 0 : void Assembler::cvtlsi2ss(XMMRegister dst, Operand src) {
3798 : DCHECK(!IsEnabled(AVX));
3799 : EnsureSpace ensure_space(this);
3800 : emit(0xF3);
3801 : emit_optional_rex_32(dst, src);
3802 : emit(0x0F);
3803 : emit(0x2A);
3804 : emit_sse_operand(dst, src);
3805 0 : }
3806 :
3807 :
3808 14 : void Assembler::cvtlsi2ss(XMMRegister dst, Register src) {
3809 : EnsureSpace ensure_space(this);
3810 : emit(0xF3);
3811 : emit_optional_rex_32(dst, src);
3812 : emit(0x0F);
3813 : emit(0x2A);
3814 : emit_sse_operand(dst, src);
3815 14 : }
3816 :
3817 0 : void Assembler::cvtqsi2ss(XMMRegister dst, Operand src) {
3818 : DCHECK(!IsEnabled(AVX));
3819 : EnsureSpace ensure_space(this);
3820 : emit(0xF3);
3821 : emit_rex_64(dst, src);
3822 : emit(0x0F);
3823 : emit(0x2A);
3824 : emit_sse_operand(dst, src);
3825 0 : }
3826 :
3827 :
3828 0 : void Assembler::cvtqsi2ss(XMMRegister dst, Register src) {
3829 : DCHECK(!IsEnabled(AVX));
3830 : EnsureSpace ensure_space(this);
3831 : emit(0xF3);
3832 : emit_rex_64(dst, src);
3833 : emit(0x0F);
3834 : emit(0x2A);
3835 : emit_sse_operand(dst, src);
3836 0 : }
3837 :
3838 39 : void Assembler::cvtqsi2sd(XMMRegister dst, Operand src) {
3839 : DCHECK(!IsEnabled(AVX));
3840 : EnsureSpace ensure_space(this);
3841 : emit(0xF2);
3842 : emit_rex_64(dst, src);
3843 : emit(0x0F);
3844 : emit(0x2A);
3845 : emit_sse_operand(dst, src);
3846 39 : }
3847 :
3848 :
3849 321 : void Assembler::cvtqsi2sd(XMMRegister dst, Register src) {
3850 : DCHECK(!IsEnabled(AVX));
3851 : EnsureSpace ensure_space(this);
3852 : emit(0xF2);
3853 : emit_rex_64(dst, src);
3854 : emit(0x0F);
3855 : emit(0x2A);
3856 : emit_sse_operand(dst, src);
3857 321 : }
3858 :
3859 :
3860 16 : void Assembler::cvtss2sd(XMMRegister dst, XMMRegister src) {
3861 : DCHECK(!IsEnabled(AVX));
3862 : EnsureSpace ensure_space(this);
3863 : emit(0xF3);
3864 : emit_optional_rex_32(dst, src);
3865 : emit(0x0F);
3866 : emit(0x5A);
3867 : emit_sse_operand(dst, src);
3868 16 : }
3869 :
3870 0 : void Assembler::cvtss2sd(XMMRegister dst, Operand src) {
3871 : DCHECK(!IsEnabled(AVX));
3872 : EnsureSpace ensure_space(this);
3873 : emit(0xF3);
3874 : emit_optional_rex_32(dst, src);
3875 : emit(0x0F);
3876 : emit(0x5A);
3877 : emit_sse_operand(dst, src);
3878 0 : }
3879 :
3880 :
3881 24 : void Assembler::cvtsd2ss(XMMRegister dst, XMMRegister src) {
3882 : DCHECK(!IsEnabled(AVX));
3883 : EnsureSpace ensure_space(this);
3884 : emit(0xF2);
3885 : emit_optional_rex_32(dst, src);
3886 : emit(0x0F);
3887 : emit(0x5A);
3888 : emit_sse_operand(dst, src);
3889 24 : }
3890 :
3891 5 : void Assembler::cvtsd2ss(XMMRegister dst, Operand src) {
3892 : DCHECK(!IsEnabled(AVX));
3893 : EnsureSpace ensure_space(this);
3894 : emit(0xF2);
3895 : emit_optional_rex_32(dst, src);
3896 : emit(0x0F);
3897 : emit(0x5A);
3898 : emit_sse_operand(dst, src);
3899 5 : }
3900 :
3901 :
3902 0 : void Assembler::cvtsd2si(Register dst, XMMRegister src) {
3903 : DCHECK(!IsEnabled(AVX));
3904 : EnsureSpace ensure_space(this);
3905 : emit(0xF2);
3906 : emit_optional_rex_32(dst, src);
3907 : emit(0x0F);
3908 : emit(0x2D);
3909 : emit_sse_operand(dst, src);
3910 0 : }
3911 :
3912 :
3913 0 : void Assembler::cvtsd2siq(Register dst, XMMRegister src) {
3914 : DCHECK(!IsEnabled(AVX));
3915 : EnsureSpace ensure_space(this);
3916 : emit(0xF2);
3917 : emit_rex_64(dst, src);
3918 : emit(0x0F);
3919 : emit(0x2D);
3920 : emit_sse_operand(dst, src);
3921 0 : }
3922 :
3923 :
3924 6966 : void Assembler::addsd(XMMRegister dst, XMMRegister src) {
3925 : EnsureSpace ensure_space(this);
3926 : emit(0xF2);
3927 : emit_optional_rex_32(dst, src);
3928 : emit(0x0F);
3929 : emit(0x58);
3930 : emit_sse_operand(dst, src);
3931 6966 : }
3932 :
3933 11 : void Assembler::addsd(XMMRegister dst, Operand src) {
3934 : EnsureSpace ensure_space(this);
3935 : emit(0xF2);
3936 : emit_optional_rex_32(dst, src);
3937 : emit(0x0F);
3938 : emit(0x58);
3939 : emit_sse_operand(dst, src);
3940 11 : }
3941 :
3942 :
3943 33 : void Assembler::mulsd(XMMRegister dst, XMMRegister src) {
3944 : EnsureSpace ensure_space(this);
3945 : emit(0xF2);
3946 : emit_optional_rex_32(dst, src);
3947 : emit(0x0F);
3948 : emit(0x59);
3949 : emit_sse_operand(dst, src);
3950 33 : }
3951 :
3952 5 : void Assembler::mulsd(XMMRegister dst, Operand src) {
3953 : EnsureSpace ensure_space(this);
3954 : emit(0xF2);
3955 : emit_optional_rex_32(dst, src);
3956 : emit(0x0F);
3957 : emit(0x59);
3958 : emit_sse_operand(dst, src);
3959 5 : }
3960 :
3961 :
3962 343 : void Assembler::subsd(XMMRegister dst, XMMRegister src) {
3963 : EnsureSpace ensure_space(this);
3964 : emit(0xF2);
3965 : emit_optional_rex_32(dst, src);
3966 : emit(0x0F);
3967 : emit(0x5C);
3968 : emit_sse_operand(dst, src);
3969 343 : }
3970 :
3971 5 : void Assembler::subsd(XMMRegister dst, Operand src) {
3972 : EnsureSpace ensure_space(this);
3973 : emit(0xF2);
3974 : emit_optional_rex_32(dst, src);
3975 : emit(0x0F);
3976 : emit(0x5C);
3977 : emit_sse_operand(dst, src);
3978 5 : }
3979 :
3980 :
3981 35 : void Assembler::divsd(XMMRegister dst, XMMRegister src) {
3982 : EnsureSpace ensure_space(this);
3983 : emit(0xF2);
3984 : emit_optional_rex_32(dst, src);
3985 : emit(0x0F);
3986 : emit(0x5E);
3987 : emit_sse_operand(dst, src);
3988 35 : }
3989 :
3990 5 : void Assembler::divsd(XMMRegister dst, Operand src) {
3991 : EnsureSpace ensure_space(this);
3992 : emit(0xF2);
3993 : emit_optional_rex_32(dst, src);
3994 : emit(0x0F);
3995 : emit(0x5E);
3996 : emit_sse_operand(dst, src);
3997 5 : }
3998 :
3999 :
4000 5 : void Assembler::maxsd(XMMRegister dst, XMMRegister src) {
4001 : EnsureSpace ensure_space(this);
4002 : emit(0xF2);
4003 : emit_optional_rex_32(dst, src);
4004 : emit(0x0F);
4005 : emit(0x5F);
4006 : emit_sse_operand(dst, src);
4007 5 : }
4008 :
4009 5 : void Assembler::maxsd(XMMRegister dst, Operand src) {
4010 : EnsureSpace ensure_space(this);
4011 : emit(0xF2);
4012 : emit_optional_rex_32(dst, src);
4013 : emit(0x0F);
4014 : emit(0x5F);
4015 : emit_sse_operand(dst, src);
4016 5 : }
4017 :
4018 :
4019 5 : void Assembler::minsd(XMMRegister dst, XMMRegister src) {
4020 : EnsureSpace ensure_space(this);
4021 : emit(0xF2);
4022 : emit_optional_rex_32(dst, src);
4023 : emit(0x0F);
4024 : emit(0x5D);
4025 : emit_sse_operand(dst, src);
4026 5 : }
4027 :
4028 5 : void Assembler::minsd(XMMRegister dst, Operand src) {
4029 : EnsureSpace ensure_space(this);
4030 : emit(0xF2);
4031 : emit_optional_rex_32(dst, src);
4032 : emit(0x0F);
4033 : emit(0x5D);
4034 : emit_sse_operand(dst, src);
4035 5 : }
4036 :
4037 :
4038 11 : void Assembler::andpd(XMMRegister dst, XMMRegister src) {
4039 : EnsureSpace ensure_space(this);
4040 : emit(0x66);
4041 : emit_optional_rex_32(dst, src);
4042 : emit(0x0F);
4043 : emit(0x54);
4044 : emit_sse_operand(dst, src);
4045 11 : }
4046 :
4047 5 : void Assembler::andpd(XMMRegister dst, Operand src) {
4048 : EnsureSpace ensure_space(this);
4049 : emit(0x66);
4050 : emit_optional_rex_32(dst, src);
4051 : emit(0x0F);
4052 : emit(0x54);
4053 : emit_sse_operand(dst, src);
4054 5 : }
4055 :
4056 :
4057 5 : void Assembler::orpd(XMMRegister dst, XMMRegister src) {
4058 : EnsureSpace ensure_space(this);
4059 : emit(0x66);
4060 : emit_optional_rex_32(dst, src);
4061 : emit(0x0F);
4062 : emit(0x56);
4063 : emit_sse_operand(dst, src);
4064 5 : }
4065 :
4066 5 : void Assembler::orpd(XMMRegister dst, Operand src) {
4067 : EnsureSpace ensure_space(this);
4068 : emit(0x66);
4069 : emit_optional_rex_32(dst, src);
4070 : emit(0x0F);
4071 : emit(0x56);
4072 : emit_sse_operand(dst, src);
4073 5 : }
4074 :
4075 :
4076 3053 : void Assembler::xorpd(XMMRegister dst, XMMRegister src) {
4077 : DCHECK(!IsEnabled(AVX));
4078 : EnsureSpace ensure_space(this);
4079 : emit(0x66);
4080 : emit_optional_rex_32(dst, src);
4081 : emit(0x0F);
4082 : emit(0x57);
4083 : emit_sse_operand(dst, src);
4084 3053 : }
4085 :
4086 5 : void Assembler::xorpd(XMMRegister dst, Operand src) {
4087 : DCHECK(!IsEnabled(AVX));
4088 : EnsureSpace ensure_space(this);
4089 : emit(0x66);
4090 : emit_optional_rex_32(dst, src);
4091 : emit(0x0F);
4092 : emit(0x57);
4093 : emit_sse_operand(dst, src);
4094 5 : }
4095 :
4096 :
4097 7 : void Assembler::sqrtsd(XMMRegister dst, XMMRegister src) {
4098 : DCHECK(!IsEnabled(AVX));
4099 : EnsureSpace ensure_space(this);
4100 : emit(0xF2);
4101 : emit_optional_rex_32(dst, src);
4102 : emit(0x0F);
4103 : emit(0x51);
4104 : emit_sse_operand(dst, src);
4105 7 : }
4106 :
4107 5 : void Assembler::sqrtsd(XMMRegister dst, Operand src) {
4108 : DCHECK(!IsEnabled(AVX));
4109 : EnsureSpace ensure_space(this);
4110 : emit(0xF2);
4111 : emit_optional_rex_32(dst, src);
4112 : emit(0x0F);
4113 : emit(0x51);
4114 : emit_sse_operand(dst, src);
4115 5 : }
4116 :
4117 13 : void Assembler::haddps(XMMRegister dst, XMMRegister src) {
4118 : DCHECK(IsEnabled(SSE3));
4119 : EnsureSpace ensure_space(this);
4120 : emit(0xF2);
4121 : emit_optional_rex_32(dst, src);
4122 : emit(0x0F);
4123 : emit(0x7C);
4124 : emit_sse_operand(dst, src);
4125 13 : }
4126 :
4127 5 : void Assembler::haddps(XMMRegister dst, Operand src) {
4128 : DCHECK(IsEnabled(SSE3));
4129 : EnsureSpace ensure_space(this);
4130 : emit(0xF2);
4131 : emit_optional_rex_32(dst, src);
4132 : emit(0x0F);
4133 : emit(0x7C);
4134 : emit_sse_operand(dst, src);
4135 5 : }
4136 :
4137 1849 : void Assembler::ucomisd(XMMRegister dst, XMMRegister src) {
4138 : DCHECK(!IsEnabled(AVX));
4139 : EnsureSpace ensure_space(this);
4140 : emit(0x66);
4141 : emit_optional_rex_32(dst, src);
4142 : emit(0x0F);
4143 : emit(0x2E);
4144 : emit_sse_operand(dst, src);
4145 1849 : }
4146 :
4147 0 : void Assembler::ucomisd(XMMRegister dst, Operand src) {
4148 : DCHECK(!IsEnabled(AVX));
4149 : EnsureSpace ensure_space(this);
4150 : emit(0x66);
4151 : emit_optional_rex_32(dst, src);
4152 : emit(0x0F);
4153 : emit(0x2E);
4154 : emit_sse_operand(dst, src);
4155 0 : }
4156 :
4157 :
4158 0 : void Assembler::cmpltsd(XMMRegister dst, XMMRegister src) {
4159 : EnsureSpace ensure_space(this);
4160 : emit(0xF2);
4161 : emit_optional_rex_32(dst, src);
4162 : emit(0x0F);
4163 : emit(0xC2);
4164 : emit_sse_operand(dst, src);
4165 : emit(0x01); // LT == 1
4166 0 : }
4167 :
4168 :
4169 0 : void Assembler::roundss(XMMRegister dst, XMMRegister src, RoundingMode mode) {
4170 : DCHECK(!IsEnabled(AVX));
4171 : DCHECK(IsEnabled(SSE4_1));
4172 : EnsureSpace ensure_space(this);
4173 : emit(0x66);
4174 : emit_optional_rex_32(dst, src);
4175 : emit(0x0F);
4176 : emit(0x3A);
4177 : emit(0x0A);
4178 : emit_sse_operand(dst, src);
4179 : // Mask precision exception.
4180 0 : emit(static_cast<byte>(mode) | 0x8);
4181 0 : }
4182 :
4183 :
4184 0 : void Assembler::roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode) {
4185 : DCHECK(!IsEnabled(AVX));
4186 : DCHECK(IsEnabled(SSE4_1));
4187 : EnsureSpace ensure_space(this);
4188 : emit(0x66);
4189 : emit_optional_rex_32(dst, src);
4190 : emit(0x0F);
4191 : emit(0x3A);
4192 : emit(0x0B);
4193 : emit_sse_operand(dst, src);
4194 : // Mask precision exception.
4195 0 : emit(static_cast<byte>(mode) | 0x8);
4196 0 : }
4197 :
4198 :
4199 4 : void Assembler::movmskpd(Register dst, XMMRegister src) {
4200 : EnsureSpace ensure_space(this);
4201 : emit(0x66);
4202 : emit_optional_rex_32(dst, src);
4203 : emit(0x0F);
4204 : emit(0x50);
4205 : emit_sse_operand(dst, src);
4206 4 : }
4207 :
4208 :
4209 4 : void Assembler::movmskps(Register dst, XMMRegister src) {
4210 : EnsureSpace ensure_space(this);
4211 : emit_optional_rex_32(dst, src);
4212 : emit(0x0F);
4213 : emit(0x50);
4214 : emit_sse_operand(dst, src);
4215 4 : }
4216 :
4217 :
4218 : // AVX instructions
4219 0 : void Assembler::vfmasd(byte op, XMMRegister dst, XMMRegister src1,
4220 : XMMRegister src2) {
4221 : DCHECK(IsEnabled(FMA3));
4222 : EnsureSpace ensure_space(this);
4223 0 : emit_vex_prefix(dst, src1, src2, kLIG, k66, k0F38, kW1);
4224 : emit(op);
4225 : emit_sse_operand(dst, src2);
4226 0 : }
4227 :
4228 0 : void Assembler::vfmasd(byte op, XMMRegister dst, XMMRegister src1,
4229 : Operand src2) {
4230 : DCHECK(IsEnabled(FMA3));
4231 : EnsureSpace ensure_space(this);
4232 0 : emit_vex_prefix(dst, src1, src2, kLIG, k66, k0F38, kW1);
4233 : emit(op);
4234 : emit_sse_operand(dst, src2);
4235 0 : }
4236 :
4237 :
4238 0 : void Assembler::vfmass(byte op, XMMRegister dst, XMMRegister src1,
4239 : XMMRegister src2) {
4240 : DCHECK(IsEnabled(FMA3));
4241 : EnsureSpace ensure_space(this);
4242 0 : emit_vex_prefix(dst, src1, src2, kLIG, k66, k0F38, kW0);
4243 : emit(op);
4244 : emit_sse_operand(dst, src2);
4245 0 : }
4246 :
4247 0 : void Assembler::vfmass(byte op, XMMRegister dst, XMMRegister src1,
4248 : Operand src2) {
4249 : DCHECK(IsEnabled(FMA3));
4250 : EnsureSpace ensure_space(this);
4251 0 : emit_vex_prefix(dst, src1, src2, kLIG, k66, k0F38, kW0);
4252 : emit(op);
4253 : emit_sse_operand(dst, src2);
4254 0 : }
4255 :
4256 :
4257 88401 : void Assembler::vmovd(XMMRegister dst, Register src) {
4258 : DCHECK(IsEnabled(AVX));
4259 : EnsureSpace ensure_space(this);
4260 88401 : XMMRegister isrc = XMMRegister::from_code(src.code());
4261 88401 : emit_vex_prefix(dst, xmm0, isrc, kL128, k66, k0F, kW0);
4262 : emit(0x6E);
4263 : emit_sse_operand(dst, src);
4264 88412 : }
4265 :
4266 5 : void Assembler::vmovd(XMMRegister dst, Operand src) {
4267 : DCHECK(IsEnabled(AVX));
4268 : EnsureSpace ensure_space(this);
4269 5 : emit_vex_prefix(dst, xmm0, src, kL128, k66, k0F, kW0);
4270 : emit(0x6E);
4271 : emit_sse_operand(dst, src);
4272 5 : }
4273 :
4274 :
4275 70825 : void Assembler::vmovd(Register dst, XMMRegister src) {
4276 : DCHECK(IsEnabled(AVX));
4277 : EnsureSpace ensure_space(this);
4278 70825 : XMMRegister idst = XMMRegister::from_code(dst.code());
4279 70825 : emit_vex_prefix(src, xmm0, idst, kL128, k66, k0F, kW0);
4280 : emit(0x7E);
4281 : emit_sse_operand(src, dst);
4282 70833 : }
4283 :
4284 :
4285 128683 : void Assembler::vmovq(XMMRegister dst, Register src) {
4286 : DCHECK(IsEnabled(AVX));
4287 : EnsureSpace ensure_space(this);
4288 128683 : XMMRegister isrc = XMMRegister::from_code(src.code());
4289 128683 : emit_vex_prefix(dst, xmm0, isrc, kL128, k66, k0F, kW1);
4290 : emit(0x6E);
4291 : emit_sse_operand(dst, src);
4292 128688 : }
4293 :
4294 9 : void Assembler::vmovq(XMMRegister dst, Operand src) {
4295 : DCHECK(IsEnabled(AVX));
4296 : EnsureSpace ensure_space(this);
4297 9 : emit_vex_prefix(dst, xmm0, src, kL128, k66, k0F, kW1);
4298 : emit(0x6E);
4299 : emit_sse_operand(dst, src);
4300 9 : }
4301 :
4302 :
4303 69755 : void Assembler::vmovq(Register dst, XMMRegister src) {
4304 : DCHECK(IsEnabled(AVX));
4305 : EnsureSpace ensure_space(this);
4306 69755 : XMMRegister idst = XMMRegister::from_code(dst.code());
4307 69755 : emit_vex_prefix(src, xmm0, idst, kL128, k66, k0F, kW1);
4308 : emit(0x7E);
4309 : emit_sse_operand(src, dst);
4310 69760 : }
4311 :
4312 1461495 : void Assembler::vinstr(byte op, XMMRegister dst, XMMRegister src1,
4313 : XMMRegister src2, SIMDPrefix pp, LeadingOpcode m,
4314 : VexW w) {
4315 : DCHECK(IsEnabled(AVX));
4316 : EnsureSpace ensure_space(this);
4317 1461495 : emit_vex_prefix(dst, src1, src2, kLIG, pp, m, w);
4318 : emit(op);
4319 : emit_sse_operand(dst, src2);
4320 1461531 : }
4321 :
4322 3026960 : void Assembler::vinstr(byte op, XMMRegister dst, XMMRegister src1, Operand src2,
4323 : SIMDPrefix pp, LeadingOpcode m, VexW w) {
4324 : DCHECK(IsEnabled(AVX));
4325 : EnsureSpace ensure_space(this);
4326 3026960 : emit_vex_prefix(dst, src1, src2, kLIG, pp, m, w);
4327 : emit(op);
4328 : emit_sse_operand(dst, src2);
4329 3026971 : }
4330 :
4331 :
4332 15465 : void Assembler::vps(byte op, XMMRegister dst, XMMRegister src1,
4333 : XMMRegister src2) {
4334 : DCHECK(IsEnabled(AVX));
4335 : EnsureSpace ensure_space(this);
4336 15465 : emit_vex_prefix(dst, src1, src2, kL128, kNone, k0F, kWIG);
4337 : emit(op);
4338 : emit_sse_operand(dst, src2);
4339 15465 : }
4340 :
4341 15202 : void Assembler::vps(byte op, XMMRegister dst, XMMRegister src1, Operand src2) {
4342 : DCHECK(IsEnabled(AVX));
4343 : EnsureSpace ensure_space(this);
4344 15202 : emit_vex_prefix(dst, src1, src2, kL128, kNone, k0F, kWIG);
4345 : emit(op);
4346 : emit_sse_operand(dst, src2);
4347 15202 : }
4348 :
4349 :
4350 1117360 : void Assembler::vpd(byte op, XMMRegister dst, XMMRegister src1,
4351 : XMMRegister src2) {
4352 : DCHECK(IsEnabled(AVX));
4353 : EnsureSpace ensure_space(this);
4354 1117360 : emit_vex_prefix(dst, src1, src2, kL128, k66, k0F, kWIG);
4355 : emit(op);
4356 : emit_sse_operand(dst, src2);
4357 1117396 : }
4358 :
4359 142 : void Assembler::vpd(byte op, XMMRegister dst, XMMRegister src1, Operand src2) {
4360 : DCHECK(IsEnabled(AVX));
4361 : EnsureSpace ensure_space(this);
4362 142 : emit_vex_prefix(dst, src1, src2, kL128, k66, k0F, kWIG);
4363 : emit(op);
4364 : emit_sse_operand(dst, src2);
4365 142 : }
4366 :
4367 :
4368 2141 : void Assembler::vucomiss(XMMRegister dst, XMMRegister src) {
4369 : DCHECK(IsEnabled(AVX));
4370 : EnsureSpace ensure_space(this);
4371 2141 : emit_vex_prefix(dst, xmm0, src, kLIG, kNone, k0F, kWIG);
4372 : emit(0x2E);
4373 : emit_sse_operand(dst, src);
4374 2149 : }
4375 :
4376 68 : void Assembler::vucomiss(XMMRegister dst, Operand src) {
4377 : DCHECK(IsEnabled(AVX));
4378 : EnsureSpace ensure_space(this);
4379 68 : emit_vex_prefix(dst, xmm0, src, kLIG, kNone, k0F, kWIG);
4380 : emit(0x2E);
4381 : emit_sse_operand(dst, src);
4382 68 : }
4383 :
4384 :
4385 43149 : void Assembler::vss(byte op, XMMRegister dst, XMMRegister src1,
4386 : XMMRegister src2) {
4387 : DCHECK(IsEnabled(AVX));
4388 : EnsureSpace ensure_space(this);
4389 43149 : emit_vex_prefix(dst, src1, src2, kLIG, kF3, k0F, kWIG);
4390 : emit(op);
4391 : emit_sse_operand(dst, src2);
4392 43148 : }
4393 :
4394 699871 : void Assembler::vss(byte op, XMMRegister dst, XMMRegister src1, Operand src2) {
4395 : DCHECK(IsEnabled(AVX));
4396 : EnsureSpace ensure_space(this);
4397 699871 : emit_vex_prefix(dst, src1, src2, kLIG, kF3, k0F, kWIG);
4398 : emit(op);
4399 : emit_sse_operand(dst, src2);
4400 699874 : }
4401 :
4402 :
4403 0 : void Assembler::bmi1q(byte op, Register reg, Register vreg, Register rm) {
4404 : DCHECK(IsEnabled(BMI1));
4405 : EnsureSpace ensure_space(this);
4406 : emit_vex_prefix(reg, vreg, rm, kLZ, kNone, k0F38, kW1);
4407 : emit(op);
4408 : emit_modrm(reg, rm);
4409 0 : }
4410 :
4411 0 : void Assembler::bmi1q(byte op, Register reg, Register vreg, Operand rm) {
4412 : DCHECK(IsEnabled(BMI1));
4413 : EnsureSpace ensure_space(this);
4414 : emit_vex_prefix(reg, vreg, rm, kLZ, kNone, k0F38, kW1);
4415 : emit(op);
4416 : emit_operand(reg, rm);
4417 0 : }
4418 :
4419 :
4420 0 : void Assembler::bmi1l(byte op, Register reg, Register vreg, Register rm) {
4421 : DCHECK(IsEnabled(BMI1));
4422 : EnsureSpace ensure_space(this);
4423 : emit_vex_prefix(reg, vreg, rm, kLZ, kNone, k0F38, kW0);
4424 : emit(op);
4425 : emit_modrm(reg, rm);
4426 0 : }
4427 :
4428 0 : void Assembler::bmi1l(byte op, Register reg, Register vreg, Operand rm) {
4429 : DCHECK(IsEnabled(BMI1));
4430 : EnsureSpace ensure_space(this);
4431 : emit_vex_prefix(reg, vreg, rm, kLZ, kNone, k0F38, kW0);
4432 : emit(op);
4433 : emit_operand(reg, rm);
4434 0 : }
4435 :
4436 :
4437 0 : void Assembler::tzcntq(Register dst, Register src) {
4438 : DCHECK(IsEnabled(BMI1));
4439 : EnsureSpace ensure_space(this);
4440 : emit(0xF3);
4441 : emit_rex_64(dst, src);
4442 : emit(0x0F);
4443 : emit(0xBC);
4444 : emit_modrm(dst, src);
4445 0 : }
4446 :
4447 0 : void Assembler::tzcntq(Register dst, Operand src) {
4448 : DCHECK(IsEnabled(BMI1));
4449 : EnsureSpace ensure_space(this);
4450 : emit(0xF3);
4451 : emit_rex_64(dst, src);
4452 : emit(0x0F);
4453 : emit(0xBC);
4454 : emit_operand(dst, src);
4455 0 : }
4456 :
4457 :
4458 0 : void Assembler::tzcntl(Register dst, Register src) {
4459 : DCHECK(IsEnabled(BMI1));
4460 : EnsureSpace ensure_space(this);
4461 : emit(0xF3);
4462 : emit_optional_rex_32(dst, src);
4463 : emit(0x0F);
4464 : emit(0xBC);
4465 : emit_modrm(dst, src);
4466 0 : }
4467 :
4468 0 : void Assembler::tzcntl(Register dst, Operand src) {
4469 : DCHECK(IsEnabled(BMI1));
4470 : EnsureSpace ensure_space(this);
4471 : emit(0xF3);
4472 : emit_optional_rex_32(dst, src);
4473 : emit(0x0F);
4474 : emit(0xBC);
4475 : emit_operand(dst, src);
4476 0 : }
4477 :
4478 :
4479 0 : void Assembler::lzcntq(Register dst, Register src) {
4480 : DCHECK(IsEnabled(LZCNT));
4481 : EnsureSpace ensure_space(this);
4482 : emit(0xF3);
4483 : emit_rex_64(dst, src);
4484 : emit(0x0F);
4485 : emit(0xBD);
4486 : emit_modrm(dst, src);
4487 0 : }
4488 :
4489 0 : void Assembler::lzcntq(Register dst, Operand src) {
4490 : DCHECK(IsEnabled(LZCNT));
4491 : EnsureSpace ensure_space(this);
4492 : emit(0xF3);
4493 : emit_rex_64(dst, src);
4494 : emit(0x0F);
4495 : emit(0xBD);
4496 : emit_operand(dst, src);
4497 0 : }
4498 :
4499 :
4500 0 : void Assembler::lzcntl(Register dst, Register src) {
4501 : DCHECK(IsEnabled(LZCNT));
4502 : EnsureSpace ensure_space(this);
4503 : emit(0xF3);
4504 : emit_optional_rex_32(dst, src);
4505 : emit(0x0F);
4506 : emit(0xBD);
4507 : emit_modrm(dst, src);
4508 0 : }
4509 :
4510 0 : void Assembler::lzcntl(Register dst, Operand src) {
4511 : DCHECK(IsEnabled(LZCNT));
4512 : EnsureSpace ensure_space(this);
4513 : emit(0xF3);
4514 : emit_optional_rex_32(dst, src);
4515 : emit(0x0F);
4516 : emit(0xBD);
4517 : emit_operand(dst, src);
4518 0 : }
4519 :
4520 :
4521 50 : void Assembler::popcntq(Register dst, Register src) {
4522 : DCHECK(IsEnabled(POPCNT));
4523 : EnsureSpace ensure_space(this);
4524 : emit(0xF3);
4525 : emit_rex_64(dst, src);
4526 : emit(0x0F);
4527 : emit(0xB8);
4528 : emit_modrm(dst, src);
4529 50 : }
4530 :
4531 9 : void Assembler::popcntq(Register dst, Operand src) {
4532 : DCHECK(IsEnabled(POPCNT));
4533 : EnsureSpace ensure_space(this);
4534 : emit(0xF3);
4535 : emit_rex_64(dst, src);
4536 : emit(0x0F);
4537 : emit(0xB8);
4538 : emit_operand(dst, src);
4539 9 : }
4540 :
4541 :
4542 145 : void Assembler::popcntl(Register dst, Register src) {
4543 : DCHECK(IsEnabled(POPCNT));
4544 : EnsureSpace ensure_space(this);
4545 : emit(0xF3);
4546 : emit_optional_rex_32(dst, src);
4547 : emit(0x0F);
4548 : emit(0xB8);
4549 : emit_modrm(dst, src);
4550 145 : }
4551 :
4552 9 : void Assembler::popcntl(Register dst, Operand src) {
4553 : DCHECK(IsEnabled(POPCNT));
4554 : EnsureSpace ensure_space(this);
4555 : emit(0xF3);
4556 : emit_optional_rex_32(dst, src);
4557 : emit(0x0F);
4558 : emit(0xB8);
4559 : emit_operand(dst, src);
4560 9 : }
4561 :
4562 :
4563 0 : void Assembler::bmi2q(SIMDPrefix pp, byte op, Register reg, Register vreg,
4564 : Register rm) {
4565 : DCHECK(IsEnabled(BMI2));
4566 : EnsureSpace ensure_space(this);
4567 : emit_vex_prefix(reg, vreg, rm, kLZ, pp, k0F38, kW1);
4568 : emit(op);
4569 : emit_modrm(reg, rm);
4570 0 : }
4571 :
4572 0 : void Assembler::bmi2q(SIMDPrefix pp, byte op, Register reg, Register vreg,
4573 : Operand rm) {
4574 : DCHECK(IsEnabled(BMI2));
4575 : EnsureSpace ensure_space(this);
4576 : emit_vex_prefix(reg, vreg, rm, kLZ, pp, k0F38, kW1);
4577 : emit(op);
4578 : emit_operand(reg, rm);
4579 0 : }
4580 :
4581 :
4582 0 : void Assembler::bmi2l(SIMDPrefix pp, byte op, Register reg, Register vreg,
4583 : Register rm) {
4584 : DCHECK(IsEnabled(BMI2));
4585 : EnsureSpace ensure_space(this);
4586 : emit_vex_prefix(reg, vreg, rm, kLZ, pp, k0F38, kW0);
4587 : emit(op);
4588 : emit_modrm(reg, rm);
4589 0 : }
4590 :
4591 0 : void Assembler::bmi2l(SIMDPrefix pp, byte op, Register reg, Register vreg,
4592 : Operand rm) {
4593 : DCHECK(IsEnabled(BMI2));
4594 : EnsureSpace ensure_space(this);
4595 : emit_vex_prefix(reg, vreg, rm, kLZ, pp, k0F38, kW0);
4596 : emit(op);
4597 : emit_operand(reg, rm);
4598 0 : }
4599 :
4600 :
4601 0 : void Assembler::rorxq(Register dst, Register src, byte imm8) {
4602 : DCHECK(IsEnabled(BMI2));
4603 : DCHECK(is_uint8(imm8));
4604 : Register vreg = Register::from_code<0>(); // VEX.vvvv unused
4605 : EnsureSpace ensure_space(this);
4606 : emit_vex_prefix(dst, vreg, src, kLZ, kF2, k0F3A, kW1);
4607 : emit(0xF0);
4608 : emit_modrm(dst, src);
4609 : emit(imm8);
4610 0 : }
4611 :
4612 0 : void Assembler::rorxq(Register dst, Operand src, byte imm8) {
4613 : DCHECK(IsEnabled(BMI2));
4614 : DCHECK(is_uint8(imm8));
4615 : Register vreg = Register::from_code<0>(); // VEX.vvvv unused
4616 : EnsureSpace ensure_space(this);
4617 : emit_vex_prefix(dst, vreg, src, kLZ, kF2, k0F3A, kW1);
4618 : emit(0xF0);
4619 : emit_operand(dst, src);
4620 : emit(imm8);
4621 0 : }
4622 :
4623 :
4624 0 : void Assembler::rorxl(Register dst, Register src, byte imm8) {
4625 : DCHECK(IsEnabled(BMI2));
4626 : DCHECK(is_uint8(imm8));
4627 : Register vreg = Register::from_code<0>(); // VEX.vvvv unused
4628 : EnsureSpace ensure_space(this);
4629 : emit_vex_prefix(dst, vreg, src, kLZ, kF2, k0F3A, kW0);
4630 : emit(0xF0);
4631 : emit_modrm(dst, src);
4632 : emit(imm8);
4633 0 : }
4634 :
4635 0 : void Assembler::rorxl(Register dst, Operand src, byte imm8) {
4636 : DCHECK(IsEnabled(BMI2));
4637 : DCHECK(is_uint8(imm8));
4638 : Register vreg = Register::from_code<0>(); // VEX.vvvv unused
4639 : EnsureSpace ensure_space(this);
4640 : emit_vex_prefix(dst, vreg, src, kLZ, kF2, k0F3A, kW0);
4641 : emit(0xF0);
4642 : emit_operand(dst, src);
4643 : emit(imm8);
4644 0 : }
4645 :
4646 5 : void Assembler::pause() {
4647 : emit(0xF3);
4648 : emit(0x90);
4649 5 : }
4650 :
4651 13 : void Assembler::minps(XMMRegister dst, XMMRegister src) {
4652 : EnsureSpace ensure_space(this);
4653 : emit_optional_rex_32(dst, src);
4654 : emit(0x0F);
4655 : emit(0x5D);
4656 : emit_sse_operand(dst, src);
4657 13 : }
4658 :
4659 5 : void Assembler::minps(XMMRegister dst, Operand src) {
4660 : EnsureSpace ensure_space(this);
4661 : emit_optional_rex_32(dst, src);
4662 : emit(0x0F);
4663 : emit(0x5D);
4664 : emit_sse_operand(dst, src);
4665 5 : }
4666 :
4667 17 : void Assembler::maxps(XMMRegister dst, XMMRegister src) {
4668 : EnsureSpace ensure_space(this);
4669 : emit_optional_rex_32(dst, src);
4670 : emit(0x0F);
4671 : emit(0x5F);
4672 : emit_sse_operand(dst, src);
4673 17 : }
4674 :
4675 5 : void Assembler::maxps(XMMRegister dst, Operand src) {
4676 : EnsureSpace ensure_space(this);
4677 : emit_optional_rex_32(dst, src);
4678 : emit(0x0F);
4679 : emit(0x5F);
4680 : emit_sse_operand(dst, src);
4681 5 : }
4682 :
4683 9 : void Assembler::rcpps(XMMRegister dst, XMMRegister src) {
4684 : EnsureSpace ensure_space(this);
4685 : emit_optional_rex_32(dst, src);
4686 : emit(0x0F);
4687 : emit(0x53);
4688 : emit_sse_operand(dst, src);
4689 9 : }
4690 :
4691 5 : void Assembler::rcpps(XMMRegister dst, Operand src) {
4692 : EnsureSpace ensure_space(this);
4693 : emit_optional_rex_32(dst, src);
4694 : emit(0x0F);
4695 : emit(0x53);
4696 : emit_sse_operand(dst, src);
4697 5 : }
4698 :
4699 4 : void Assembler::rsqrtps(XMMRegister dst, XMMRegister src) {
4700 : EnsureSpace ensure_space(this);
4701 : emit_optional_rex_32(dst, src);
4702 : emit(0x0F);
4703 : emit(0x52);
4704 : emit_sse_operand(dst, src);
4705 4 : }
4706 :
4707 0 : void Assembler::rsqrtps(XMMRegister dst, Operand src) {
4708 : EnsureSpace ensure_space(this);
4709 : emit_optional_rex_32(dst, src);
4710 : emit(0x0F);
4711 : emit(0x52);
4712 : emit_sse_operand(dst, src);
4713 0 : }
4714 :
4715 5 : void Assembler::sqrtps(XMMRegister dst, XMMRegister src) {
4716 : EnsureSpace ensure_space(this);
4717 : emit_optional_rex_32(dst, src);
4718 : emit(0x0F);
4719 : emit(0x51);
4720 : emit_sse_operand(dst, src);
4721 5 : }
4722 :
4723 5 : void Assembler::sqrtps(XMMRegister dst, Operand src) {
4724 : EnsureSpace ensure_space(this);
4725 : emit_optional_rex_32(dst, src);
4726 : emit(0x0F);
4727 : emit(0x51);
4728 : emit_sse_operand(dst, src);
4729 5 : }
4730 :
4731 21 : void Assembler::cvtdq2ps(XMMRegister dst, XMMRegister src) {
4732 : EnsureSpace ensure_space(this);
4733 : emit_optional_rex_32(dst, src);
4734 : emit(0x0F);
4735 : emit(0x5B);
4736 : emit_sse_operand(dst, src);
4737 21 : }
4738 :
4739 5 : void Assembler::cvtdq2ps(XMMRegister dst, Operand src) {
4740 : EnsureSpace ensure_space(this);
4741 : emit_optional_rex_32(dst, src);
4742 : emit(0x0F);
4743 : emit(0x5B);
4744 : emit_sse_operand(dst, src);
4745 5 : }
4746 :
4747 1885 : void Assembler::movups(XMMRegister dst, XMMRegister src) {
4748 : EnsureSpace ensure_space(this);
4749 1885 : if (src.low_bits() == 4) {
4750 : // Try to avoid an unnecessary SIB byte.
4751 : emit_optional_rex_32(src, dst);
4752 : emit(0x0F);
4753 : emit(0x11);
4754 : emit_sse_operand(src, dst);
4755 : } else {
4756 : emit_optional_rex_32(dst, src);
4757 : emit(0x0F);
4758 : emit(0x10);
4759 : emit_sse_operand(dst, src);
4760 : }
4761 1885 : }
4762 :
4763 785 : void Assembler::movups(XMMRegister dst, Operand src) {
4764 : EnsureSpace ensure_space(this);
4765 : emit_optional_rex_32(dst, src);
4766 : emit(0x0F);
4767 : emit(0x10);
4768 : emit_sse_operand(dst, src);
4769 785 : }
4770 :
4771 769 : void Assembler::movups(Operand dst, XMMRegister src) {
4772 : EnsureSpace ensure_space(this);
4773 : emit_optional_rex_32(src, dst);
4774 : emit(0x0F);
4775 : emit(0x11);
4776 : emit_sse_operand(src, dst);
4777 769 : }
4778 :
4779 4139 : void Assembler::sse2_instr(XMMRegister dst, XMMRegister src, byte prefix,
4780 : byte escape, byte opcode) {
4781 : EnsureSpace ensure_space(this);
4782 : emit(prefix);
4783 : emit_optional_rex_32(dst, src);
4784 : emit(escape);
4785 : emit(opcode);
4786 : emit_sse_operand(dst, src);
4787 4139 : }
4788 :
4789 255 : void Assembler::sse2_instr(XMMRegister dst, Operand src, byte prefix,
4790 : byte escape, byte opcode) {
4791 : EnsureSpace ensure_space(this);
4792 : emit(prefix);
4793 : emit_optional_rex_32(dst, src);
4794 : emit(escape);
4795 : emit(opcode);
4796 : emit_sse_operand(dst, src);
4797 255 : }
4798 :
4799 646 : void Assembler::ssse3_instr(XMMRegister dst, XMMRegister src, byte prefix,
4800 : byte escape1, byte escape2, byte opcode) {
4801 : DCHECK(IsEnabled(SSSE3));
4802 : EnsureSpace ensure_space(this);
4803 : emit(prefix);
4804 : emit_optional_rex_32(dst, src);
4805 : emit(escape1);
4806 : emit(escape2);
4807 : emit(opcode);
4808 : emit_sse_operand(dst, src);
4809 646 : }
4810 :
4811 2442 : void Assembler::ssse3_instr(XMMRegister dst, Operand src, byte prefix,
4812 : byte escape1, byte escape2, byte opcode) {
4813 : DCHECK(IsEnabled(SSSE3));
4814 : EnsureSpace ensure_space(this);
4815 : emit(prefix);
4816 : emit_optional_rex_32(dst, src);
4817 : emit(escape1);
4818 : emit(escape2);
4819 : emit(opcode);
4820 : emit_sse_operand(dst, src);
4821 2442 : }
4822 :
4823 1449 : void Assembler::sse4_instr(XMMRegister dst, XMMRegister src, byte prefix,
4824 : byte escape1, byte escape2, byte opcode) {
4825 : DCHECK(IsEnabled(SSE4_1));
4826 : EnsureSpace ensure_space(this);
4827 : emit(prefix);
4828 : emit_optional_rex_32(dst, src);
4829 : emit(escape1);
4830 : emit(escape2);
4831 : emit(opcode);
4832 : emit_sse_operand(dst, src);
4833 1449 : }
4834 :
4835 85 : void Assembler::sse4_instr(XMMRegister dst, Operand src, byte prefix,
4836 : byte escape1, byte escape2, byte opcode) {
4837 : DCHECK(IsEnabled(SSE4_1));
4838 : EnsureSpace ensure_space(this);
4839 : emit(prefix);
4840 : emit_optional_rex_32(dst, src);
4841 : emit(escape1);
4842 : emit(escape2);
4843 : emit(opcode);
4844 : emit_sse_operand(dst, src);
4845 85 : }
4846 :
4847 5 : void Assembler::lddqu(XMMRegister dst, Operand src) {
4848 : DCHECK(IsEnabled(SSE3));
4849 : EnsureSpace ensure_space(this);
4850 : emit(0xF2);
4851 : emit_optional_rex_32(dst, src);
4852 : emit(0x0F);
4853 : emit(0xF0);
4854 : emit_sse_operand(dst, src);
4855 5 : }
4856 :
4857 5 : void Assembler::psrldq(XMMRegister dst, uint8_t shift) {
4858 : EnsureSpace ensure_space(this);
4859 : emit(0x66);
4860 : emit_optional_rex_32(dst);
4861 : emit(0x0F);
4862 : emit(0x73);
4863 : emit_sse_operand(dst);
4864 : emit(shift);
4865 5 : }
4866 :
4867 781 : void Assembler::pshufhw(XMMRegister dst, XMMRegister src, uint8_t shuffle) {
4868 : EnsureSpace ensure_space(this);
4869 : emit(0xF3);
4870 : emit_optional_rex_32(dst, src);
4871 : emit(0x0F);
4872 : emit(0x70);
4873 : emit_sse_operand(dst, src);
4874 : emit(shuffle);
4875 781 : }
4876 :
4877 0 : void Assembler::pshufhw(XMMRegister dst, Operand src, uint8_t shuffle) {
4878 : EnsureSpace ensure_space(this);
4879 : emit(0xF3);
4880 : emit_optional_rex_32(dst, src);
4881 : emit(0x0F);
4882 : emit(0x70);
4883 : emit_sse_operand(dst, src);
4884 : emit(shuffle);
4885 0 : }
4886 :
4887 1441 : void Assembler::pshuflw(XMMRegister dst, XMMRegister src, uint8_t shuffle) {
4888 : EnsureSpace ensure_space(this);
4889 : emit(0xF2);
4890 : emit_optional_rex_32(dst, src);
4891 : emit(0x0F);
4892 : emit(0x70);
4893 : emit_sse_operand(dst, src);
4894 : emit(shuffle);
4895 1441 : }
4896 :
4897 0 : void Assembler::pshuflw(XMMRegister dst, Operand src, uint8_t shuffle) {
4898 : EnsureSpace ensure_space(this);
4899 : emit(0xF2);
4900 : emit_optional_rex_32(dst, src);
4901 : emit(0x0F);
4902 : emit(0x70);
4903 : emit_sse_operand(dst, src);
4904 : emit(shuffle);
4905 0 : }
4906 :
4907 3001 : void Assembler::pshufd(XMMRegister dst, XMMRegister src, uint8_t shuffle) {
4908 : EnsureSpace ensure_space(this);
4909 : emit(0x66);
4910 : emit_optional_rex_32(dst, src);
4911 : emit(0x0F);
4912 : emit(0x70);
4913 : emit_sse_operand(dst, src);
4914 : emit(shuffle);
4915 3001 : }
4916 :
4917 0 : void Assembler::pshufd(XMMRegister dst, Operand src, uint8_t shuffle) {
4918 : EnsureSpace ensure_space(this);
4919 : emit(0x66);
4920 : emit_optional_rex_32(dst, src);
4921 : emit(0x0F);
4922 : emit(0x70);
4923 : emit_sse_operand(dst, src);
4924 : emit(shuffle);
4925 0 : }
4926 :
4927 0 : void Assembler::emit_sse_operand(XMMRegister reg, Operand adr) {
4928 : Register ireg = Register::from_code(reg.code());
4929 : emit_operand(ireg, adr);
4930 0 : }
4931 :
4932 0 : void Assembler::emit_sse_operand(Register reg, Operand adr) {
4933 : emit_operand(reg, adr);
4934 0 : }
4935 :
4936 :
4937 0 : void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) {
4938 5332954 : emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
4939 0 : }
4940 :
4941 :
4942 0 : void Assembler::emit_sse_operand(XMMRegister dst, Register src) {
4943 811110 : emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
4944 0 : }
4945 :
4946 :
4947 0 : void Assembler::emit_sse_operand(Register dst, XMMRegister src) {
4948 5690 : emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
4949 0 : }
4950 :
4951 0 : void Assembler::emit_sse_operand(XMMRegister dst) {
4952 5 : emit(0xD8 | dst.low_bits());
4953 0 : }
4954 :
4955 23048726 : void Assembler::db(uint8_t data) {
4956 : EnsureSpace ensure_space(this);
4957 : emit(data);
4958 23048726 : }
4959 :
4960 :
4961 24623060 : void Assembler::dd(uint32_t data) {
4962 : EnsureSpace ensure_space(this);
4963 : emitl(data);
4964 24623060 : }
4965 :
4966 :
4967 0 : void Assembler::dq(uint64_t data) {
4968 : EnsureSpace ensure_space(this);
4969 : emitq(data);
4970 0 : }
4971 :
4972 :
4973 204499 : void Assembler::dq(Label* label) {
4974 : EnsureSpace ensure_space(this);
4975 204499 : if (label->is_bound()) {
4976 404902 : internal_reference_positions_.push_back(pc_offset());
4977 404902 : emit(Immediate64(reinterpret_cast<Address>(buffer_start_) + label->pos(),
4978 202451 : RelocInfo::INTERNAL_REFERENCE));
4979 : } else {
4980 2048 : RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE);
4981 : emitl(0); // Zero for the first 32bit marks it as 64bit absolute address.
4982 2048 : if (label->is_linked()) {
4983 0 : emitl(label->pos());
4984 0 : label->link_to(pc_offset() - sizeof(int32_t));
4985 : } else {
4986 : DCHECK(label->is_unused());
4987 : int32_t current = pc_offset();
4988 2048 : emitl(current);
4989 : label->link_to(current);
4990 : }
4991 : }
4992 204499 : }
4993 :
4994 :
4995 : // Relocation information implementations.
4996 :
4997 53916797 : void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
4998 95924938 : if (!ShouldRecordRelocInfo(rmode)) return;
4999 11908656 : RelocInfo rinfo(reinterpret_cast<Address>(pc_), rmode, data, Code());
5000 11908656 : reloc_info_writer.Write(&rinfo);
5001 : }
5002 :
5003 : const int RelocInfo::kApplyMask =
5004 : RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
5005 : RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY) |
5006 : RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE) |
5007 : RelocInfo::ModeMask(RelocInfo::WASM_CALL);
5008 :
5009 399024 : bool RelocInfo::IsCodedSpecially() {
5010 : // The deserializer needs to know whether a pointer is specially coded. Being
5011 : // specially coded on x64 means that it is a relative 32 bit address, as used
5012 : // by branch instructions.
5013 399024 : return (1 << rmode_) & kApplyMask;
5014 : }
5015 :
5016 507605 : bool RelocInfo::IsInConstantPool() {
5017 507605 : return false;
5018 : }
5019 :
5020 : } // namespace internal
5021 122004 : } // namespace v8
5022 :
5023 : #endif // V8_TARGET_ARCH_X64
|