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