1 // Copyright (c) 1994-2006 Sun Microsystems Inc.
2 // All Rights Reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions
6 // are met:
7 //
8 // - Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer.
10 //
11 // - Redistribution in binary form must reproduce the above copyright
12 // notice, this list of conditions and the following disclaimer in the
13 // documentation and/or other materials provided with the
14 // distribution.
15 //
16 // - Neither the name of Sun Microsystems or the names of contributors may
17 // be used to endorse or promote products derived from this software without
18 // specific prior written permission.
19 //
20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
31 // OF THE POSSIBILITY OF SUCH DAMAGE.
32
33 // The original source code covered by the above license above has been modified
34 // significantly by Google Inc.
35 // Copyright 2012 the V8 project authors. All rights reserved.
36
37 #include "src/ia32/assembler-ia32.h"
38
39 #include <cstring>
40
41 #if V8_TARGET_ARCH_IA32
42
43 #if V8_LIBC_MSVCRT
44 #include <intrin.h> // _xgetbv()
45 #endif
46 #if V8_OS_MACOSX
47 #include <sys/sysctl.h>
48 #endif
49
50 #include "src/assembler-inl.h"
51 #include "src/base/bits.h"
52 #include "src/base/cpu.h"
53 #include "src/code-stubs.h"
54 #include "src/conversions-inl.h"
55 #include "src/deoptimizer.h"
56 #include "src/disassembler.h"
57 #include "src/macro-assembler.h"
58 #include "src/v8.h"
59
60 namespace v8 {
61 namespace internal {
62
EmbeddedNumber(double value)63 Immediate Immediate::EmbeddedNumber(double value) {
64 int32_t smi;
65 if (DoubleToSmiInteger(value, &smi)) return Immediate(Smi::FromInt(smi));
66 Immediate result(0, RelocInfo::EMBEDDED_OBJECT);
67 result.is_heap_object_request_ = true;
68 result.value_.heap_object_request = HeapObjectRequest(value);
69 return result;
70 }
71
EmbeddedCode(CodeStub * stub)72 Immediate Immediate::EmbeddedCode(CodeStub* stub) {
73 Immediate result(0, RelocInfo::CODE_TARGET);
74 result.is_heap_object_request_ = true;
75 result.value_.heap_object_request = HeapObjectRequest(stub);
76 return result;
77 }
78
79 // -----------------------------------------------------------------------------
80 // Implementation of CpuFeatures
81
82 namespace {
83
84 #if !V8_LIBC_MSVCRT
85
_xgetbv(unsigned int xcr)86 V8_INLINE uint64_t _xgetbv(unsigned int xcr) {
87 unsigned eax, edx;
88 // Check xgetbv; this uses a .byte sequence instead of the instruction
89 // directly because older assemblers do not include support for xgetbv and
90 // there is no easy way to conditionally compile based on the assembler
91 // used.
92 __asm__ volatile(".byte 0x0F, 0x01, 0xD0" : "=a"(eax), "=d"(edx) : "c"(xcr));
93 return static_cast<uint64_t>(eax) | (static_cast<uint64_t>(edx) << 32);
94 }
95
96 #define _XCR_XFEATURE_ENABLED_MASK 0
97
98 #endif // !V8_LIBC_MSVCRT
99
100
OSHasAVXSupport()101 bool OSHasAVXSupport() {
102 #if V8_OS_MACOSX
103 // Mac OS X up to 10.9 has a bug where AVX transitions were indeed being
104 // caused by ISRs, so we detect that here and disable AVX in that case.
105 char buffer[128];
106 size_t buffer_size = arraysize(buffer);
107 int ctl_name[] = {CTL_KERN, KERN_OSRELEASE};
108 if (sysctl(ctl_name, 2, buffer, &buffer_size, nullptr, 0) != 0) {
109 FATAL("V8 failed to get kernel version");
110 }
111 // The buffer now contains a string of the form XX.YY.ZZ, where
112 // XX is the major kernel version component.
113 char* period_pos = strchr(buffer, '.');
114 DCHECK_NOT_NULL(period_pos);
115 *period_pos = '\0';
116 long kernel_version_major = strtol(buffer, nullptr, 10); // NOLINT
117 if (kernel_version_major <= 13) return false;
118 #endif // V8_OS_MACOSX
119 // Check whether OS claims to support AVX.
120 uint64_t feature_mask = _xgetbv(_XCR_XFEATURE_ENABLED_MASK);
121 return (feature_mask & 0x6) == 0x6;
122 }
123
124 } // namespace
125
126
ProbeImpl(bool cross_compile)127 void CpuFeatures::ProbeImpl(bool cross_compile) {
128 base::CPU cpu;
129 CHECK(cpu.has_sse2()); // SSE2 support is mandatory.
130 CHECK(cpu.has_cmov()); // CMOV support is mandatory.
131
132 // Only use statically determined features for cross compile (snapshot).
133 if (cross_compile) return;
134
135 if (cpu.has_sse41() && FLAG_enable_sse4_1) supported_ |= 1u << SSE4_1;
136 if (cpu.has_ssse3() && FLAG_enable_ssse3) supported_ |= 1u << SSSE3;
137 if (cpu.has_sse3() && FLAG_enable_sse3) supported_ |= 1u << SSE3;
138 if (cpu.has_avx() && FLAG_enable_avx && cpu.has_osxsave() &&
139 OSHasAVXSupport()) {
140 supported_ |= 1u << AVX;
141 }
142 if (cpu.has_fma3() && FLAG_enable_fma3 && cpu.has_osxsave() &&
143 OSHasAVXSupport()) {
144 supported_ |= 1u << FMA3;
145 }
146 if (cpu.has_bmi1() && FLAG_enable_bmi1) supported_ |= 1u << BMI1;
147 if (cpu.has_bmi2() && FLAG_enable_bmi2) supported_ |= 1u << BMI2;
148 if (cpu.has_lzcnt() && FLAG_enable_lzcnt) supported_ |= 1u << LZCNT;
149 if (cpu.has_popcnt() && FLAG_enable_popcnt) supported_ |= 1u << POPCNT;
150 if (strcmp(FLAG_mcpu, "auto") == 0) {
151 if (cpu.is_atom()) supported_ |= 1u << ATOM;
152 } else if (strcmp(FLAG_mcpu, "atom") == 0) {
153 supported_ |= 1u << ATOM;
154 }
155 }
156
157
PrintTarget()158 void CpuFeatures::PrintTarget() { }
PrintFeatures()159 void CpuFeatures::PrintFeatures() {
160 printf(
161 "SSE3=%d SSSE3=%d SSE4_1=%d AVX=%d FMA3=%d BMI1=%d BMI2=%d LZCNT=%d "
162 "POPCNT=%d ATOM=%d\n",
163 CpuFeatures::IsSupported(SSE3), CpuFeatures::IsSupported(SSSE3),
164 CpuFeatures::IsSupported(SSE4_1), CpuFeatures::IsSupported(AVX),
165 CpuFeatures::IsSupported(FMA3), CpuFeatures::IsSupported(BMI1),
166 CpuFeatures::IsSupported(BMI2), CpuFeatures::IsSupported(LZCNT),
167 CpuFeatures::IsSupported(POPCNT), CpuFeatures::IsSupported(ATOM));
168 }
169
170
171 // -----------------------------------------------------------------------------
172 // Implementation of Displacement
173
init(Label * L,Type type)174 void Displacement::init(Label* L, Type type) {
175 DCHECK(!L->is_bound());
176 int next = 0;
177 if (L->is_linked()) {
178 next = L->pos();
179 DCHECK_GT(next, 0); // Displacements must be at positions > 0
180 }
181 // Ensure that we _never_ overflow the next field.
182 DCHECK(NextField::is_valid(Assembler::kMaximalBufferSize));
183 data_ = NextField::encode(next) | TypeField::encode(type);
184 }
185
186
187 // -----------------------------------------------------------------------------
188 // Implementation of RelocInfo
189
190 const int RelocInfo::kApplyMask =
191 RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
192 RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE) |
193 RelocInfo::ModeMask(RelocInfo::JS_TO_WASM_CALL) |
194 RelocInfo::ModeMask(RelocInfo::OFF_HEAP_TARGET) |
195 RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY);
196
IsCodedSpecially()197 bool RelocInfo::IsCodedSpecially() {
198 // The deserializer needs to know whether a pointer is specially coded. Being
199 // specially coded on IA32 means that it is a relative address, as used by
200 // branch instructions. These are also the ones that need changing when a
201 // code object moves.
202 return RelocInfo::ModeMask(rmode_) & kApplyMask;
203 }
204
205
IsInConstantPool()206 bool RelocInfo::IsInConstantPool() {
207 return false;
208 }
209
GetDeoptimizationId(Isolate * isolate,DeoptimizeKind kind)210 int RelocInfo::GetDeoptimizationId(Isolate* isolate, DeoptimizeKind kind) {
211 DCHECK(IsRuntimeEntry(rmode_));
212 return Deoptimizer::GetDeoptimizationId(isolate, target_address(), kind);
213 }
214
set_js_to_wasm_address(Address address,ICacheFlushMode icache_flush_mode)215 void RelocInfo::set_js_to_wasm_address(Address address,
216 ICacheFlushMode icache_flush_mode) {
217 DCHECK_EQ(rmode_, JS_TO_WASM_CALL);
218 Assembler::set_target_address_at(pc_, constant_pool_, address,
219 icache_flush_mode);
220 }
221
js_to_wasm_address() const222 Address RelocInfo::js_to_wasm_address() const {
223 DCHECK_EQ(rmode_, JS_TO_WASM_CALL);
224 return Assembler::target_address_at(pc_, constant_pool_);
225 }
226
wasm_call_tag() const227 uint32_t RelocInfo::wasm_call_tag() const {
228 DCHECK(rmode_ == WASM_CALL || rmode_ == WASM_STUB_CALL);
229 return Memory<uint32_t>(pc_);
230 }
231
232 // -----------------------------------------------------------------------------
233 // Implementation of Operand
234
Operand(Register base,int32_t disp,RelocInfo::Mode rmode)235 Operand::Operand(Register base, int32_t disp, RelocInfo::Mode rmode) {
236 // [base + disp/r]
237 if (disp == 0 && RelocInfo::IsNone(rmode) && base != ebp) {
238 // [base]
239 set_modrm(0, base);
240 if (base == esp) set_sib(times_1, esp, base);
241 } else if (is_int8(disp) && RelocInfo::IsNone(rmode)) {
242 // [base + disp8]
243 set_modrm(1, base);
244 if (base == esp) set_sib(times_1, esp, base);
245 set_disp8(disp);
246 } else {
247 // [base + disp/r]
248 set_modrm(2, base);
249 if (base == esp) set_sib(times_1, esp, base);
250 set_dispr(disp, rmode);
251 }
252 }
253
254
Operand(Register base,Register index,ScaleFactor scale,int32_t disp,RelocInfo::Mode rmode)255 Operand::Operand(Register base,
256 Register index,
257 ScaleFactor scale,
258 int32_t disp,
259 RelocInfo::Mode rmode) {
260 DCHECK(index != esp); // illegal addressing mode
261 // [base + index*scale + disp/r]
262 if (disp == 0 && RelocInfo::IsNone(rmode) && base != ebp) {
263 // [base + index*scale]
264 set_modrm(0, esp);
265 set_sib(scale, index, base);
266 } else if (is_int8(disp) && RelocInfo::IsNone(rmode)) {
267 // [base + index*scale + disp8]
268 set_modrm(1, esp);
269 set_sib(scale, index, base);
270 set_disp8(disp);
271 } else {
272 // [base + index*scale + disp/r]
273 set_modrm(2, esp);
274 set_sib(scale, index, base);
275 set_dispr(disp, rmode);
276 }
277 }
278
279
Operand(Register index,ScaleFactor scale,int32_t disp,RelocInfo::Mode rmode)280 Operand::Operand(Register index,
281 ScaleFactor scale,
282 int32_t disp,
283 RelocInfo::Mode rmode) {
284 DCHECK(index != esp); // illegal addressing mode
285 // [index*scale + disp/r]
286 set_modrm(0, esp);
287 set_sib(scale, index, ebp);
288 set_dispr(disp, rmode);
289 }
290
291
is_reg_only() const292 bool Operand::is_reg_only() const {
293 return (buf_[0] & 0xF8) == 0xC0; // Addressing mode is register only.
294 }
295
296
reg() const297 Register Operand::reg() const {
298 DCHECK(is_reg_only());
299 return Register::from_code(buf_[0] & 0x07);
300 }
301
AllocateAndInstallRequestedHeapObjects(Isolate * isolate)302 void Assembler::AllocateAndInstallRequestedHeapObjects(Isolate* isolate) {
303 for (auto& request : heap_object_requests_) {
304 Handle<HeapObject> object;
305 switch (request.kind()) {
306 case HeapObjectRequest::kHeapNumber:
307 object =
308 isolate->factory()->NewHeapNumber(request.heap_number(), TENURED);
309 break;
310 case HeapObjectRequest::kCodeStub:
311 request.code_stub()->set_isolate(isolate);
312 object = request.code_stub()->GetCode();
313 break;
314 }
315 Address pc = reinterpret_cast<Address>(buffer_) + request.offset();
316 Memory<Handle<Object>>(pc) = object;
317 }
318 }
319
320 // -----------------------------------------------------------------------------
321 // Implementation of Assembler.
322
323 // Emit a single byte. Must always be inlined.
324 #define EMIT(x) \
325 *pc_++ = (x)
326
Assembler(const AssemblerOptions & options,void * buffer,int buffer_size)327 Assembler::Assembler(const AssemblerOptions& options, void* buffer,
328 int buffer_size)
329 : AssemblerBase(options, buffer, buffer_size) {
330 // Clear the buffer in debug mode unless it was provided by the
331 // caller in which case we can't be sure it's okay to overwrite
332 // existing code in it.
333 #ifdef DEBUG
334 if (own_buffer_) ZapCode(reinterpret_cast<Address>(buffer_), buffer_size_);
335 #endif
336
337 reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_);
338 }
339
GetCode(Isolate * isolate,CodeDesc * desc)340 void Assembler::GetCode(Isolate* isolate, CodeDesc* desc) {
341 // Finalize code (at this point overflow() may be true, but the gap ensures
342 // that we are still not overlapping instructions and relocation info).
343 DCHECK(pc_ <= reloc_info_writer.pos()); // No overlap.
344
345 AllocateAndInstallRequestedHeapObjects(isolate);
346
347 // Set up code descriptor.
348 desc->buffer = buffer_;
349 desc->buffer_size = buffer_size_;
350 desc->instr_size = pc_offset();
351 desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
352 desc->origin = this;
353 desc->constant_pool_size = 0;
354 desc->unwinding_info_size = 0;
355 desc->unwinding_info = nullptr;
356
357 // Collection stage
358 auto jump_opt = jump_optimization_info();
359 if (jump_opt && jump_opt->is_collecting()) {
360 auto& bitmap = jump_opt->farjmp_bitmap();
361 int num = static_cast<int>(farjmp_positions_.size());
362 if (num && bitmap.empty()) {
363 bool can_opt = false;
364
365 bitmap.resize((num + 31) / 32, 0);
366 for (int i = 0; i < num; i++) {
367 int disp_pos = farjmp_positions_[i];
368 int disp = long_at(disp_pos);
369 if (is_int8(disp)) {
370 bitmap[i / 32] |= 1 << (i & 31);
371 can_opt = true;
372 }
373 }
374 if (can_opt) {
375 jump_opt->set_optimizable();
376 }
377 }
378 }
379 }
380
381
Align(int m)382 void Assembler::Align(int m) {
383 DCHECK(base::bits::IsPowerOfTwo(m));
384 int mask = m - 1;
385 int addr = pc_offset();
386 Nop((m - (addr & mask)) & mask);
387 }
388
389
IsNop(Address addr)390 bool Assembler::IsNop(Address addr) {
391 byte* a = reinterpret_cast<byte*>(addr);
392 while (*a == 0x66) a++;
393 if (*a == 0x90) return true;
394 if (a[0] == 0xF && a[1] == 0x1F) return true;
395 return false;
396 }
397
398
Nop(int bytes)399 void Assembler::Nop(int bytes) {
400 EnsureSpace ensure_space(this);
401
402 // Multi byte nops from http://support.amd.com/us/Processor_TechDocs/40546.pdf
403 while (bytes > 0) {
404 switch (bytes) {
405 case 2:
406 EMIT(0x66);
407 V8_FALLTHROUGH;
408 case 1:
409 EMIT(0x90);
410 return;
411 case 3:
412 EMIT(0xF);
413 EMIT(0x1F);
414 EMIT(0);
415 return;
416 case 4:
417 EMIT(0xF);
418 EMIT(0x1F);
419 EMIT(0x40);
420 EMIT(0);
421 return;
422 case 6:
423 EMIT(0x66);
424 V8_FALLTHROUGH;
425 case 5:
426 EMIT(0xF);
427 EMIT(0x1F);
428 EMIT(0x44);
429 EMIT(0);
430 EMIT(0);
431 return;
432 case 7:
433 EMIT(0xF);
434 EMIT(0x1F);
435 EMIT(0x80);
436 EMIT(0);
437 EMIT(0);
438 EMIT(0);
439 EMIT(0);
440 return;
441 default:
442 case 11:
443 EMIT(0x66);
444 bytes--;
445 V8_FALLTHROUGH;
446 case 10:
447 EMIT(0x66);
448 bytes--;
449 V8_FALLTHROUGH;
450 case 9:
451 EMIT(0x66);
452 bytes--;
453 V8_FALLTHROUGH;
454 case 8:
455 EMIT(0xF);
456 EMIT(0x1F);
457 EMIT(0x84);
458 EMIT(0);
459 EMIT(0);
460 EMIT(0);
461 EMIT(0);
462 EMIT(0);
463 bytes -= 8;
464 }
465 }
466 }
467
468
CodeTargetAlign()469 void Assembler::CodeTargetAlign() {
470 Align(16); // Preferred alignment of jump targets on ia32.
471 }
472
473
cpuid()474 void Assembler::cpuid() {
475 EnsureSpace ensure_space(this);
476 EMIT(0x0F);
477 EMIT(0xA2);
478 }
479
480
pushad()481 void Assembler::pushad() {
482 EnsureSpace ensure_space(this);
483 EMIT(0x60);
484 }
485
486
popad()487 void Assembler::popad() {
488 EnsureSpace ensure_space(this);
489 EMIT(0x61);
490 }
491
492
pushfd()493 void Assembler::pushfd() {
494 EnsureSpace ensure_space(this);
495 EMIT(0x9C);
496 }
497
498
popfd()499 void Assembler::popfd() {
500 EnsureSpace ensure_space(this);
501 EMIT(0x9D);
502 }
503
504
push(const Immediate & x)505 void Assembler::push(const Immediate& x) {
506 EnsureSpace ensure_space(this);
507 if (x.is_int8()) {
508 EMIT(0x6A);
509 EMIT(x.immediate());
510 } else {
511 EMIT(0x68);
512 emit(x);
513 }
514 }
515
516
push_imm32(int32_t imm32)517 void Assembler::push_imm32(int32_t imm32) {
518 EnsureSpace ensure_space(this);
519 EMIT(0x68);
520 emit(imm32);
521 }
522
523
push(Register src)524 void Assembler::push(Register src) {
525 EnsureSpace ensure_space(this);
526 EMIT(0x50 | src.code());
527 }
528
push(Operand src)529 void Assembler::push(Operand src) {
530 EnsureSpace ensure_space(this);
531 EMIT(0xFF);
532 emit_operand(esi, src);
533 }
534
535
pop(Register dst)536 void Assembler::pop(Register dst) {
537 DCHECK_NOT_NULL(reloc_info_writer.last_pc());
538 EnsureSpace ensure_space(this);
539 EMIT(0x58 | dst.code());
540 }
541
pop(Operand dst)542 void Assembler::pop(Operand dst) {
543 EnsureSpace ensure_space(this);
544 EMIT(0x8F);
545 emit_operand(eax, dst);
546 }
547
548
enter(const Immediate & size)549 void Assembler::enter(const Immediate& size) {
550 EnsureSpace ensure_space(this);
551 EMIT(0xC8);
552 emit_w(size);
553 EMIT(0);
554 }
555
556
leave()557 void Assembler::leave() {
558 EnsureSpace ensure_space(this);
559 EMIT(0xC9);
560 }
561
mov_b(Register dst,Operand src)562 void Assembler::mov_b(Register dst, Operand src) {
563 CHECK(dst.is_byte_register());
564 EnsureSpace ensure_space(this);
565 EMIT(0x8A);
566 emit_operand(dst, src);
567 }
568
mov_b(Operand dst,const Immediate & src)569 void Assembler::mov_b(Operand dst, const Immediate& src) {
570 EnsureSpace ensure_space(this);
571 EMIT(0xC6);
572 emit_operand(eax, dst);
573 EMIT(static_cast<int8_t>(src.immediate()));
574 }
575
mov_b(Operand dst,Register src)576 void Assembler::mov_b(Operand dst, Register src) {
577 CHECK(src.is_byte_register());
578 EnsureSpace ensure_space(this);
579 EMIT(0x88);
580 emit_operand(src, dst);
581 }
582
mov_w(Register dst,Operand src)583 void Assembler::mov_w(Register dst, Operand src) {
584 EnsureSpace ensure_space(this);
585 EMIT(0x66);
586 EMIT(0x8B);
587 emit_operand(dst, src);
588 }
589
mov_w(Operand dst,Register src)590 void Assembler::mov_w(Operand dst, Register src) {
591 EnsureSpace ensure_space(this);
592 EMIT(0x66);
593 EMIT(0x89);
594 emit_operand(src, dst);
595 }
596
mov_w(Operand dst,const Immediate & src)597 void Assembler::mov_w(Operand dst, const Immediate& src) {
598 EnsureSpace ensure_space(this);
599 EMIT(0x66);
600 EMIT(0xC7);
601 emit_operand(eax, dst);
602 EMIT(static_cast<int8_t>(src.immediate() & 0xFF));
603 EMIT(static_cast<int8_t>(src.immediate() >> 8));
604 }
605
606
mov(Register dst,int32_t imm32)607 void Assembler::mov(Register dst, int32_t imm32) {
608 EnsureSpace ensure_space(this);
609 EMIT(0xB8 | dst.code());
610 emit(imm32);
611 }
612
613
mov(Register dst,const Immediate & x)614 void Assembler::mov(Register dst, const Immediate& x) {
615 EnsureSpace ensure_space(this);
616 EMIT(0xB8 | dst.code());
617 emit(x);
618 }
619
mov(Register dst,Handle<HeapObject> handle)620 void Assembler::mov(Register dst, Handle<HeapObject> handle) {
621 EnsureSpace ensure_space(this);
622 EMIT(0xB8 | dst.code());
623 emit(handle);
624 }
625
mov(Register dst,Operand src)626 void Assembler::mov(Register dst, Operand src) {
627 EnsureSpace ensure_space(this);
628 EMIT(0x8B);
629 emit_operand(dst, src);
630 }
631
632
mov(Register dst,Register src)633 void Assembler::mov(Register dst, Register src) {
634 EnsureSpace ensure_space(this);
635 EMIT(0x89);
636 EMIT(0xC0 | src.code() << 3 | dst.code());
637 }
638
mov(Operand dst,const Immediate & x)639 void Assembler::mov(Operand dst, const Immediate& x) {
640 EnsureSpace ensure_space(this);
641 EMIT(0xC7);
642 emit_operand(eax, dst);
643 emit(x);
644 }
645
mov(Operand dst,Address src,RelocInfo::Mode rmode)646 void Assembler::mov(Operand dst, Address src, RelocInfo::Mode rmode) {
647 EnsureSpace ensure_space(this);
648 EMIT(0xC7);
649 emit_operand(eax, dst);
650 emit(src, rmode);
651 }
652
mov(Operand dst,Handle<HeapObject> handle)653 void Assembler::mov(Operand dst, Handle<HeapObject> handle) {
654 EnsureSpace ensure_space(this);
655 EMIT(0xC7);
656 emit_operand(eax, dst);
657 emit(handle);
658 }
659
mov(Operand dst,Register src)660 void Assembler::mov(Operand dst, Register src) {
661 EnsureSpace ensure_space(this);
662 EMIT(0x89);
663 emit_operand(src, dst);
664 }
665
movsx_b(Register dst,Operand src)666 void Assembler::movsx_b(Register dst, Operand src) {
667 EnsureSpace ensure_space(this);
668 EMIT(0x0F);
669 EMIT(0xBE);
670 emit_operand(dst, src);
671 }
672
movsx_w(Register dst,Operand src)673 void Assembler::movsx_w(Register dst, Operand src) {
674 EnsureSpace ensure_space(this);
675 EMIT(0x0F);
676 EMIT(0xBF);
677 emit_operand(dst, src);
678 }
679
movzx_b(Register dst,Operand src)680 void Assembler::movzx_b(Register dst, Operand src) {
681 EnsureSpace ensure_space(this);
682 EMIT(0x0F);
683 EMIT(0xB6);
684 emit_operand(dst, src);
685 }
686
movzx_w(Register dst,Operand src)687 void Assembler::movzx_w(Register dst, Operand src) {
688 EnsureSpace ensure_space(this);
689 EMIT(0x0F);
690 EMIT(0xB7);
691 emit_operand(dst, src);
692 }
693
movq(XMMRegister dst,Operand src)694 void Assembler::movq(XMMRegister dst, Operand src) {
695 EnsureSpace ensure_space(this);
696 EMIT(0xF3);
697 EMIT(0x0F);
698 EMIT(0x7E);
699 emit_operand(dst, src);
700 }
701
cmov(Condition cc,Register dst,Operand src)702 void Assembler::cmov(Condition cc, Register dst, Operand src) {
703 EnsureSpace ensure_space(this);
704 // Opcode: 0f 40 + cc /r.
705 EMIT(0x0F);
706 EMIT(0x40 + cc);
707 emit_operand(dst, src);
708 }
709
710
cld()711 void Assembler::cld() {
712 EnsureSpace ensure_space(this);
713 EMIT(0xFC);
714 }
715
716
rep_movs()717 void Assembler::rep_movs() {
718 EnsureSpace ensure_space(this);
719 EMIT(0xF3);
720 EMIT(0xA5);
721 }
722
723
rep_stos()724 void Assembler::rep_stos() {
725 EnsureSpace ensure_space(this);
726 EMIT(0xF3);
727 EMIT(0xAB);
728 }
729
730
stos()731 void Assembler::stos() {
732 EnsureSpace ensure_space(this);
733 EMIT(0xAB);
734 }
735
736
xchg(Register dst,Register src)737 void Assembler::xchg(Register dst, Register src) {
738 EnsureSpace ensure_space(this);
739 if (src == eax || dst == eax) { // Single-byte encoding.
740 EMIT(0x90 | (src == eax ? dst.code() : src.code()));
741 } else {
742 EMIT(0x87);
743 EMIT(0xC0 | src.code() << 3 | dst.code());
744 }
745 }
746
xchg(Register dst,Operand src)747 void Assembler::xchg(Register dst, Operand src) {
748 EnsureSpace ensure_space(this);
749 EMIT(0x87);
750 emit_operand(dst, src);
751 }
752
xchg_b(Register reg,Operand op)753 void Assembler::xchg_b(Register reg, Operand op) {
754 DCHECK(reg.is_byte_register());
755 EnsureSpace ensure_space(this);
756 EMIT(0x86);
757 emit_operand(reg, op);
758 }
759
xchg_w(Register reg,Operand op)760 void Assembler::xchg_w(Register reg, Operand op) {
761 EnsureSpace ensure_space(this);
762 EMIT(0x66);
763 EMIT(0x87);
764 emit_operand(reg, op);
765 }
766
lock()767 void Assembler::lock() {
768 EnsureSpace ensure_space(this);
769 EMIT(0xF0);
770 }
771
cmpxchg(Operand dst,Register src)772 void Assembler::cmpxchg(Operand dst, Register src) {
773 EnsureSpace ensure_space(this);
774 EMIT(0x0F);
775 EMIT(0xB1);
776 emit_operand(src, dst);
777 }
778
cmpxchg_b(Operand dst,Register src)779 void Assembler::cmpxchg_b(Operand dst, Register src) {
780 DCHECK(src.is_byte_register());
781 EnsureSpace ensure_space(this);
782 EMIT(0x0F);
783 EMIT(0xB0);
784 emit_operand(src, dst);
785 }
786
cmpxchg_w(Operand dst,Register src)787 void Assembler::cmpxchg_w(Operand dst, Register src) {
788 EnsureSpace ensure_space(this);
789 EMIT(0x66);
790 EMIT(0x0F);
791 EMIT(0xB1);
792 emit_operand(src, dst);
793 }
794
cmpxchg8b(Operand dst)795 void Assembler::cmpxchg8b(Operand dst) {
796 EnsureSpace enure_space(this);
797 EMIT(0x0F);
798 EMIT(0xC7);
799 emit_operand(ecx, dst);
800 }
801
lfence()802 void Assembler::lfence() {
803 EnsureSpace ensure_space(this);
804 EMIT(0x0F);
805 EMIT(0xAE);
806 EMIT(0xE8);
807 }
808
pause()809 void Assembler::pause() {
810 EnsureSpace ensure_space(this);
811 EMIT(0xF3);
812 EMIT(0x90);
813 }
814
adc(Register dst,int32_t imm32)815 void Assembler::adc(Register dst, int32_t imm32) {
816 EnsureSpace ensure_space(this);
817 emit_arith(2, Operand(dst), Immediate(imm32));
818 }
819
adc(Register dst,Operand src)820 void Assembler::adc(Register dst, Operand src) {
821 EnsureSpace ensure_space(this);
822 EMIT(0x13);
823 emit_operand(dst, src);
824 }
825
add(Register dst,Operand src)826 void Assembler::add(Register dst, Operand src) {
827 EnsureSpace ensure_space(this);
828 EMIT(0x03);
829 emit_operand(dst, src);
830 }
831
add(Operand dst,Register src)832 void Assembler::add(Operand dst, Register src) {
833 EnsureSpace ensure_space(this);
834 EMIT(0x01);
835 emit_operand(src, dst);
836 }
837
add(Operand dst,const Immediate & x)838 void Assembler::add(Operand dst, const Immediate& x) {
839 DCHECK_NOT_NULL(reloc_info_writer.last_pc());
840 EnsureSpace ensure_space(this);
841 emit_arith(0, dst, x);
842 }
843
844
and_(Register dst,int32_t imm32)845 void Assembler::and_(Register dst, int32_t imm32) {
846 and_(dst, Immediate(imm32));
847 }
848
849
and_(Register dst,const Immediate & x)850 void Assembler::and_(Register dst, const Immediate& x) {
851 EnsureSpace ensure_space(this);
852 emit_arith(4, Operand(dst), x);
853 }
854
and_(Register dst,Operand src)855 void Assembler::and_(Register dst, Operand src) {
856 EnsureSpace ensure_space(this);
857 EMIT(0x23);
858 emit_operand(dst, src);
859 }
860
and_(Operand dst,const Immediate & x)861 void Assembler::and_(Operand dst, const Immediate& x) {
862 EnsureSpace ensure_space(this);
863 emit_arith(4, dst, x);
864 }
865
and_(Operand dst,Register src)866 void Assembler::and_(Operand dst, Register src) {
867 EnsureSpace ensure_space(this);
868 EMIT(0x21);
869 emit_operand(src, dst);
870 }
871
cmpb(Operand op,Immediate imm8)872 void Assembler::cmpb(Operand op, Immediate imm8) {
873 DCHECK(imm8.is_int8() || imm8.is_uint8());
874 EnsureSpace ensure_space(this);
875 if (op.is_reg(eax)) {
876 EMIT(0x3C);
877 } else {
878 EMIT(0x80);
879 emit_operand(edi, op); // edi == 7
880 }
881 emit_b(imm8);
882 }
883
cmpb(Operand op,Register reg)884 void Assembler::cmpb(Operand op, Register reg) {
885 CHECK(reg.is_byte_register());
886 EnsureSpace ensure_space(this);
887 EMIT(0x38);
888 emit_operand(reg, op);
889 }
890
cmpb(Register reg,Operand op)891 void Assembler::cmpb(Register reg, Operand op) {
892 CHECK(reg.is_byte_register());
893 EnsureSpace ensure_space(this);
894 EMIT(0x3A);
895 emit_operand(reg, op);
896 }
897
cmpw(Operand op,Immediate imm16)898 void Assembler::cmpw(Operand op, Immediate imm16) {
899 DCHECK(imm16.is_int16() || imm16.is_uint16());
900 EnsureSpace ensure_space(this);
901 EMIT(0x66);
902 EMIT(0x81);
903 emit_operand(edi, op);
904 emit_w(imm16);
905 }
906
cmpw(Register reg,Operand op)907 void Assembler::cmpw(Register reg, Operand op) {
908 EnsureSpace ensure_space(this);
909 EMIT(0x66);
910 EMIT(0x3B);
911 emit_operand(reg, op);
912 }
913
cmpw(Operand op,Register reg)914 void Assembler::cmpw(Operand op, Register reg) {
915 EnsureSpace ensure_space(this);
916 EMIT(0x66);
917 EMIT(0x39);
918 emit_operand(reg, op);
919 }
920
cmp(Register reg,int32_t imm32)921 void Assembler::cmp(Register reg, int32_t imm32) {
922 EnsureSpace ensure_space(this);
923 emit_arith(7, Operand(reg), Immediate(imm32));
924 }
925
cmp(Register reg,Handle<HeapObject> handle)926 void Assembler::cmp(Register reg, Handle<HeapObject> handle) {
927 EnsureSpace ensure_space(this);
928 emit_arith(7, Operand(reg), Immediate(handle));
929 }
930
cmp(Register reg,Operand op)931 void Assembler::cmp(Register reg, Operand op) {
932 EnsureSpace ensure_space(this);
933 EMIT(0x3B);
934 emit_operand(reg, op);
935 }
936
cmp(Operand op,Register reg)937 void Assembler::cmp(Operand op, Register reg) {
938 EnsureSpace ensure_space(this);
939 EMIT(0x39);
940 emit_operand(reg, op);
941 }
942
cmp(Operand op,const Immediate & imm)943 void Assembler::cmp(Operand op, const Immediate& imm) {
944 EnsureSpace ensure_space(this);
945 emit_arith(7, op, imm);
946 }
947
cmp(Operand op,Handle<HeapObject> handle)948 void Assembler::cmp(Operand op, Handle<HeapObject> handle) {
949 EnsureSpace ensure_space(this);
950 emit_arith(7, op, Immediate(handle));
951 }
952
cmpb_al(Operand op)953 void Assembler::cmpb_al(Operand op) {
954 EnsureSpace ensure_space(this);
955 EMIT(0x38); // CMP r/m8, r8
956 emit_operand(eax, op); // eax has same code as register al.
957 }
958
cmpw_ax(Operand op)959 void Assembler::cmpw_ax(Operand op) {
960 EnsureSpace ensure_space(this);
961 EMIT(0x66);
962 EMIT(0x39); // CMP r/m16, r16
963 emit_operand(eax, op); // eax has same code as register ax.
964 }
965
966
dec_b(Register dst)967 void Assembler::dec_b(Register dst) {
968 CHECK(dst.is_byte_register());
969 EnsureSpace ensure_space(this);
970 EMIT(0xFE);
971 EMIT(0xC8 | dst.code());
972 }
973
dec_b(Operand dst)974 void Assembler::dec_b(Operand dst) {
975 EnsureSpace ensure_space(this);
976 EMIT(0xFE);
977 emit_operand(ecx, dst);
978 }
979
980
dec(Register dst)981 void Assembler::dec(Register dst) {
982 EnsureSpace ensure_space(this);
983 EMIT(0x48 | dst.code());
984 }
985
dec(Operand dst)986 void Assembler::dec(Operand dst) {
987 EnsureSpace ensure_space(this);
988 EMIT(0xFF);
989 emit_operand(ecx, dst);
990 }
991
992
cdq()993 void Assembler::cdq() {
994 EnsureSpace ensure_space(this);
995 EMIT(0x99);
996 }
997
idiv(Operand src)998 void Assembler::idiv(Operand src) {
999 EnsureSpace ensure_space(this);
1000 EMIT(0xF7);
1001 emit_operand(edi, src);
1002 }
1003
div(Operand src)1004 void Assembler::div(Operand src) {
1005 EnsureSpace ensure_space(this);
1006 EMIT(0xF7);
1007 emit_operand(esi, src);
1008 }
1009
1010
imul(Register reg)1011 void Assembler::imul(Register reg) {
1012 EnsureSpace ensure_space(this);
1013 EMIT(0xF7);
1014 EMIT(0xE8 | reg.code());
1015 }
1016
imul(Register dst,Operand src)1017 void Assembler::imul(Register dst, Operand src) {
1018 EnsureSpace ensure_space(this);
1019 EMIT(0x0F);
1020 EMIT(0xAF);
1021 emit_operand(dst, src);
1022 }
1023
1024
imul(Register dst,Register src,int32_t imm32)1025 void Assembler::imul(Register dst, Register src, int32_t imm32) {
1026 imul(dst, Operand(src), imm32);
1027 }
1028
imul(Register dst,Operand src,int32_t imm32)1029 void Assembler::imul(Register dst, Operand src, int32_t imm32) {
1030 EnsureSpace ensure_space(this);
1031 if (is_int8(imm32)) {
1032 EMIT(0x6B);
1033 emit_operand(dst, src);
1034 EMIT(imm32);
1035 } else {
1036 EMIT(0x69);
1037 emit_operand(dst, src);
1038 emit(imm32);
1039 }
1040 }
1041
1042
inc(Register dst)1043 void Assembler::inc(Register dst) {
1044 EnsureSpace ensure_space(this);
1045 EMIT(0x40 | dst.code());
1046 }
1047
inc(Operand dst)1048 void Assembler::inc(Operand dst) {
1049 EnsureSpace ensure_space(this);
1050 EMIT(0xFF);
1051 emit_operand(eax, dst);
1052 }
1053
lea(Register dst,Operand src)1054 void Assembler::lea(Register dst, Operand src) {
1055 EnsureSpace ensure_space(this);
1056 EMIT(0x8D);
1057 emit_operand(dst, src);
1058 }
1059
1060
mul(Register src)1061 void Assembler::mul(Register src) {
1062 EnsureSpace ensure_space(this);
1063 EMIT(0xF7);
1064 EMIT(0xE0 | src.code());
1065 }
1066
1067
neg(Register dst)1068 void Assembler::neg(Register dst) {
1069 EnsureSpace ensure_space(this);
1070 EMIT(0xF7);
1071 EMIT(0xD8 | dst.code());
1072 }
1073
neg(Operand dst)1074 void Assembler::neg(Operand dst) {
1075 EnsureSpace ensure_space(this);
1076 EMIT(0xF7);
1077 emit_operand(ebx, dst);
1078 }
1079
1080
not_(Register dst)1081 void Assembler::not_(Register dst) {
1082 EnsureSpace ensure_space(this);
1083 EMIT(0xF7);
1084 EMIT(0xD0 | dst.code());
1085 }
1086
not_(Operand dst)1087 void Assembler::not_(Operand dst) {
1088 EnsureSpace ensure_space(this);
1089 EMIT(0xF7);
1090 emit_operand(edx, dst);
1091 }
1092
1093
or_(Register dst,int32_t imm32)1094 void Assembler::or_(Register dst, int32_t imm32) {
1095 EnsureSpace ensure_space(this);
1096 emit_arith(1, Operand(dst), Immediate(imm32));
1097 }
1098
or_(Register dst,Operand src)1099 void Assembler::or_(Register dst, Operand src) {
1100 EnsureSpace ensure_space(this);
1101 EMIT(0x0B);
1102 emit_operand(dst, src);
1103 }
1104
or_(Operand dst,const Immediate & x)1105 void Assembler::or_(Operand dst, const Immediate& x) {
1106 EnsureSpace ensure_space(this);
1107 emit_arith(1, dst, x);
1108 }
1109
or_(Operand dst,Register src)1110 void Assembler::or_(Operand dst, Register src) {
1111 EnsureSpace ensure_space(this);
1112 EMIT(0x09);
1113 emit_operand(src, dst);
1114 }
1115
1116
rcl(Register dst,uint8_t imm8)1117 void Assembler::rcl(Register dst, uint8_t imm8) {
1118 EnsureSpace ensure_space(this);
1119 DCHECK(is_uint5(imm8)); // illegal shift count
1120 if (imm8 == 1) {
1121 EMIT(0xD1);
1122 EMIT(0xD0 | dst.code());
1123 } else {
1124 EMIT(0xC1);
1125 EMIT(0xD0 | dst.code());
1126 EMIT(imm8);
1127 }
1128 }
1129
1130
rcr(Register dst,uint8_t imm8)1131 void Assembler::rcr(Register dst, uint8_t imm8) {
1132 EnsureSpace ensure_space(this);
1133 DCHECK(is_uint5(imm8)); // illegal shift count
1134 if (imm8 == 1) {
1135 EMIT(0xD1);
1136 EMIT(0xD8 | dst.code());
1137 } else {
1138 EMIT(0xC1);
1139 EMIT(0xD8 | dst.code());
1140 EMIT(imm8);
1141 }
1142 }
1143
ror(Operand dst,uint8_t imm8)1144 void Assembler::ror(Operand dst, uint8_t imm8) {
1145 EnsureSpace ensure_space(this);
1146 DCHECK(is_uint5(imm8)); // illegal shift count
1147 if (imm8 == 1) {
1148 EMIT(0xD1);
1149 emit_operand(ecx, dst);
1150 } else {
1151 EMIT(0xC1);
1152 emit_operand(ecx, dst);
1153 EMIT(imm8);
1154 }
1155 }
1156
ror_cl(Operand dst)1157 void Assembler::ror_cl(Operand dst) {
1158 EnsureSpace ensure_space(this);
1159 EMIT(0xD3);
1160 emit_operand(ecx, dst);
1161 }
1162
sar(Operand dst,uint8_t imm8)1163 void Assembler::sar(Operand dst, uint8_t imm8) {
1164 EnsureSpace ensure_space(this);
1165 DCHECK(is_uint5(imm8)); // illegal shift count
1166 if (imm8 == 1) {
1167 EMIT(0xD1);
1168 emit_operand(edi, dst);
1169 } else {
1170 EMIT(0xC1);
1171 emit_operand(edi, dst);
1172 EMIT(imm8);
1173 }
1174 }
1175
sar_cl(Operand dst)1176 void Assembler::sar_cl(Operand dst) {
1177 EnsureSpace ensure_space(this);
1178 EMIT(0xD3);
1179 emit_operand(edi, dst);
1180 }
1181
sbb(Register dst,Operand src)1182 void Assembler::sbb(Register dst, Operand src) {
1183 EnsureSpace ensure_space(this);
1184 EMIT(0x1B);
1185 emit_operand(dst, src);
1186 }
1187
shld(Register dst,Register src,uint8_t shift)1188 void Assembler::shld(Register dst, Register src, uint8_t shift) {
1189 DCHECK(is_uint5(shift));
1190 EnsureSpace ensure_space(this);
1191 EMIT(0x0F);
1192 EMIT(0xA4);
1193 emit_operand(src, Operand(dst));
1194 EMIT(shift);
1195 }
1196
shld_cl(Register dst,Register src)1197 void Assembler::shld_cl(Register dst, Register src) {
1198 EnsureSpace ensure_space(this);
1199 EMIT(0x0F);
1200 EMIT(0xA5);
1201 emit_operand(src, Operand(dst));
1202 }
1203
shl(Operand dst,uint8_t imm8)1204 void Assembler::shl(Operand dst, uint8_t imm8) {
1205 EnsureSpace ensure_space(this);
1206 DCHECK(is_uint5(imm8)); // illegal shift count
1207 if (imm8 == 1) {
1208 EMIT(0xD1);
1209 emit_operand(esp, dst);
1210 } else {
1211 EMIT(0xC1);
1212 emit_operand(esp, dst);
1213 EMIT(imm8);
1214 }
1215 }
1216
shl_cl(Operand dst)1217 void Assembler::shl_cl(Operand dst) {
1218 EnsureSpace ensure_space(this);
1219 EMIT(0xD3);
1220 emit_operand(esp, dst);
1221 }
1222
shr(Operand dst,uint8_t imm8)1223 void Assembler::shr(Operand dst, uint8_t imm8) {
1224 EnsureSpace ensure_space(this);
1225 DCHECK(is_uint5(imm8)); // illegal shift count
1226 if (imm8 == 1) {
1227 EMIT(0xD1);
1228 emit_operand(ebp, dst);
1229 } else {
1230 EMIT(0xC1);
1231 emit_operand(ebp, dst);
1232 EMIT(imm8);
1233 }
1234 }
1235
shr_cl(Operand dst)1236 void Assembler::shr_cl(Operand dst) {
1237 EnsureSpace ensure_space(this);
1238 EMIT(0xD3);
1239 emit_operand(ebp, dst);
1240 }
1241
shrd(Register dst,Register src,uint8_t shift)1242 void Assembler::shrd(Register dst, Register src, uint8_t shift) {
1243 DCHECK(is_uint5(shift));
1244 EnsureSpace ensure_space(this);
1245 EMIT(0x0F);
1246 EMIT(0xAC);
1247 emit_operand(dst, Operand(src));
1248 EMIT(shift);
1249 }
1250
shrd_cl(Operand dst,Register src)1251 void Assembler::shrd_cl(Operand dst, Register src) {
1252 EnsureSpace ensure_space(this);
1253 EMIT(0x0F);
1254 EMIT(0xAD);
1255 emit_operand(src, dst);
1256 }
1257
sub(Operand dst,const Immediate & x)1258 void Assembler::sub(Operand dst, const Immediate& x) {
1259 EnsureSpace ensure_space(this);
1260 emit_arith(5, dst, x);
1261 }
1262
sub(Register dst,Operand src)1263 void Assembler::sub(Register dst, Operand src) {
1264 EnsureSpace ensure_space(this);
1265 EMIT(0x2B);
1266 emit_operand(dst, src);
1267 }
1268
sub(Operand dst,Register src)1269 void Assembler::sub(Operand dst, Register src) {
1270 EnsureSpace ensure_space(this);
1271 EMIT(0x29);
1272 emit_operand(src, dst);
1273 }
1274
sub_sp_32(uint32_t imm)1275 void Assembler::sub_sp_32(uint32_t imm) {
1276 EnsureSpace ensure_space(this);
1277 EMIT(0x81); // using a literal 32-bit immediate.
1278 static constexpr Register ireg = Register::from_code<5>();
1279 emit_operand(ireg, Operand(esp));
1280 emit(imm);
1281 }
1282
test(Register reg,const Immediate & imm)1283 void Assembler::test(Register reg, const Immediate& imm) {
1284 if (imm.is_uint8()) {
1285 test_b(reg, imm);
1286 return;
1287 }
1288
1289 EnsureSpace ensure_space(this);
1290 // This is not using emit_arith because test doesn't support
1291 // sign-extension of 8-bit operands.
1292 if (reg == eax) {
1293 EMIT(0xA9);
1294 } else {
1295 EMIT(0xF7);
1296 EMIT(0xC0 | reg.code());
1297 }
1298 emit(imm);
1299 }
1300
test(Register reg,Operand op)1301 void Assembler::test(Register reg, Operand op) {
1302 EnsureSpace ensure_space(this);
1303 EMIT(0x85);
1304 emit_operand(reg, op);
1305 }
1306
test_b(Register reg,Operand op)1307 void Assembler::test_b(Register reg, Operand op) {
1308 CHECK(reg.is_byte_register());
1309 EnsureSpace ensure_space(this);
1310 EMIT(0x84);
1311 emit_operand(reg, op);
1312 }
1313
test(Operand op,const Immediate & imm)1314 void Assembler::test(Operand op, const Immediate& imm) {
1315 if (op.is_reg_only()) {
1316 test(op.reg(), imm);
1317 return;
1318 }
1319 if (imm.is_uint8()) {
1320 return test_b(op, imm);
1321 }
1322 EnsureSpace ensure_space(this);
1323 EMIT(0xF7);
1324 emit_operand(eax, op);
1325 emit(imm);
1326 }
1327
test_b(Register reg,Immediate imm8)1328 void Assembler::test_b(Register reg, Immediate imm8) {
1329 DCHECK(imm8.is_uint8());
1330 EnsureSpace ensure_space(this);
1331 // Only use test against byte for registers that have a byte
1332 // variant: eax, ebx, ecx, and edx.
1333 if (reg == eax) {
1334 EMIT(0xA8);
1335 emit_b(imm8);
1336 } else if (reg.is_byte_register()) {
1337 emit_arith_b(0xF6, 0xC0, reg, static_cast<uint8_t>(imm8.immediate()));
1338 } else {
1339 EMIT(0x66);
1340 EMIT(0xF7);
1341 EMIT(0xC0 | reg.code());
1342 emit_w(imm8);
1343 }
1344 }
1345
test_b(Operand op,Immediate imm8)1346 void Assembler::test_b(Operand op, Immediate imm8) {
1347 if (op.is_reg_only()) {
1348 test_b(op.reg(), imm8);
1349 return;
1350 }
1351 EnsureSpace ensure_space(this);
1352 EMIT(0xF6);
1353 emit_operand(eax, op);
1354 emit_b(imm8);
1355 }
1356
test_w(Register reg,Immediate imm16)1357 void Assembler::test_w(Register reg, Immediate imm16) {
1358 DCHECK(imm16.is_int16() || imm16.is_uint16());
1359 EnsureSpace ensure_space(this);
1360 if (reg == eax) {
1361 EMIT(0xA9);
1362 emit_w(imm16);
1363 } else {
1364 EMIT(0x66);
1365 EMIT(0xF7);
1366 EMIT(0xC0 | reg.code());
1367 emit_w(imm16);
1368 }
1369 }
1370
test_w(Register reg,Operand op)1371 void Assembler::test_w(Register reg, Operand op) {
1372 EnsureSpace ensure_space(this);
1373 EMIT(0x66);
1374 EMIT(0x85);
1375 emit_operand(reg, op);
1376 }
1377
test_w(Operand op,Immediate imm16)1378 void Assembler::test_w(Operand op, Immediate imm16) {
1379 DCHECK(imm16.is_int16() || imm16.is_uint16());
1380 if (op.is_reg_only()) {
1381 test_w(op.reg(), imm16);
1382 return;
1383 }
1384 EnsureSpace ensure_space(this);
1385 EMIT(0x66);
1386 EMIT(0xF7);
1387 emit_operand(eax, op);
1388 emit_w(imm16);
1389 }
1390
xor_(Register dst,int32_t imm32)1391 void Assembler::xor_(Register dst, int32_t imm32) {
1392 EnsureSpace ensure_space(this);
1393 emit_arith(6, Operand(dst), Immediate(imm32));
1394 }
1395
xor_(Register dst,Operand src)1396 void Assembler::xor_(Register dst, Operand src) {
1397 EnsureSpace ensure_space(this);
1398 EMIT(0x33);
1399 emit_operand(dst, src);
1400 }
1401
xor_(Operand dst,Register src)1402 void Assembler::xor_(Operand dst, Register src) {
1403 EnsureSpace ensure_space(this);
1404 EMIT(0x31);
1405 emit_operand(src, dst);
1406 }
1407
xor_(Operand dst,const Immediate & x)1408 void Assembler::xor_(Operand dst, const Immediate& x) {
1409 EnsureSpace ensure_space(this);
1410 emit_arith(6, dst, x);
1411 }
1412
bswap(Register dst)1413 void Assembler::bswap(Register dst) {
1414 EnsureSpace ensure_space(this);
1415 EMIT(0x0F);
1416 EMIT(0xC8 + dst.code());
1417 }
1418
bt(Operand dst,Register src)1419 void Assembler::bt(Operand dst, Register src) {
1420 EnsureSpace ensure_space(this);
1421 EMIT(0x0F);
1422 EMIT(0xA3);
1423 emit_operand(src, dst);
1424 }
1425
bts(Operand dst,Register src)1426 void Assembler::bts(Operand dst, Register src) {
1427 EnsureSpace ensure_space(this);
1428 EMIT(0x0F);
1429 EMIT(0xAB);
1430 emit_operand(src, dst);
1431 }
1432
bsr(Register dst,Operand src)1433 void Assembler::bsr(Register dst, Operand src) {
1434 EnsureSpace ensure_space(this);
1435 EMIT(0x0F);
1436 EMIT(0xBD);
1437 emit_operand(dst, src);
1438 }
1439
bsf(Register dst,Operand src)1440 void Assembler::bsf(Register dst, Operand src) {
1441 EnsureSpace ensure_space(this);
1442 EMIT(0x0F);
1443 EMIT(0xBC);
1444 emit_operand(dst, src);
1445 }
1446
1447
hlt()1448 void Assembler::hlt() {
1449 EnsureSpace ensure_space(this);
1450 EMIT(0xF4);
1451 }
1452
1453
int3()1454 void Assembler::int3() {
1455 EnsureSpace ensure_space(this);
1456 EMIT(0xCC);
1457 }
1458
1459
nop()1460 void Assembler::nop() {
1461 EnsureSpace ensure_space(this);
1462 EMIT(0x90);
1463 }
1464
1465
ret(int imm16)1466 void Assembler::ret(int imm16) {
1467 EnsureSpace ensure_space(this);
1468 DCHECK(is_uint16(imm16));
1469 if (imm16 == 0) {
1470 EMIT(0xC3);
1471 } else {
1472 EMIT(0xC2);
1473 EMIT(imm16 & 0xFF);
1474 EMIT((imm16 >> 8) & 0xFF);
1475 }
1476 }
1477
1478
ud2()1479 void Assembler::ud2() {
1480 EnsureSpace ensure_space(this);
1481 EMIT(0x0F);
1482 EMIT(0x0B);
1483 }
1484
1485
1486 // Labels refer to positions in the (to be) generated code.
1487 // There are bound, linked, and unused labels.
1488 //
1489 // Bound labels refer to known positions in the already
1490 // generated code. pos() is the position the label refers to.
1491 //
1492 // Linked labels refer to unknown positions in the code
1493 // to be generated; pos() is the position of the 32bit
1494 // Displacement of the last instruction using the label.
1495
print(const Label * L)1496 void Assembler::print(const Label* L) {
1497 if (L->is_unused()) {
1498 PrintF("unused label\n");
1499 } else if (L->is_bound()) {
1500 PrintF("bound label to %d\n", L->pos());
1501 } else if (L->is_linked()) {
1502 Label l;
1503 l.link_to(L->pos());
1504 PrintF("unbound label");
1505 while (l.is_linked()) {
1506 Displacement disp = disp_at(&l);
1507 PrintF("@ %d ", l.pos());
1508 disp.print();
1509 PrintF("\n");
1510 disp.next(&l);
1511 }
1512 } else {
1513 PrintF("label in inconsistent state (pos = %d)\n", L->pos_);
1514 }
1515 }
1516
1517
bind_to(Label * L,int pos)1518 void Assembler::bind_to(Label* L, int pos) {
1519 EnsureSpace ensure_space(this);
1520 DCHECK(0 <= pos && pos <= pc_offset()); // must have a valid binding position
1521 while (L->is_linked()) {
1522 Displacement disp = disp_at(L);
1523 int fixup_pos = L->pos();
1524 if (disp.type() == Displacement::CODE_ABSOLUTE) {
1525 long_at_put(fixup_pos, reinterpret_cast<int>(buffer_ + pos));
1526 internal_reference_positions_.push_back(fixup_pos);
1527 } else if (disp.type() == Displacement::CODE_RELATIVE) {
1528 // Relative to Code* heap object pointer.
1529 long_at_put(fixup_pos, pos + Code::kHeaderSize - kHeapObjectTag);
1530 } else {
1531 if (disp.type() == Displacement::UNCONDITIONAL_JUMP) {
1532 DCHECK_EQ(byte_at(fixup_pos - 1), 0xE9); // jmp expected
1533 }
1534 // Relative address, relative to point after address.
1535 int imm32 = pos - (fixup_pos + sizeof(int32_t));
1536 long_at_put(fixup_pos, imm32);
1537 }
1538 disp.next(L);
1539 }
1540 while (L->is_near_linked()) {
1541 int fixup_pos = L->near_link_pos();
1542 int offset_to_next =
1543 static_cast<int>(*reinterpret_cast<int8_t*>(addr_at(fixup_pos)));
1544 DCHECK_LE(offset_to_next, 0);
1545 // Relative address, relative to point after address.
1546 int disp = pos - fixup_pos - sizeof(int8_t);
1547 CHECK(0 <= disp && disp <= 127);
1548 set_byte_at(fixup_pos, disp);
1549 if (offset_to_next < 0) {
1550 L->link_to(fixup_pos + offset_to_next, Label::kNear);
1551 } else {
1552 L->UnuseNear();
1553 }
1554 }
1555
1556 // Optimization stage
1557 auto jump_opt = jump_optimization_info();
1558 if (jump_opt && jump_opt->is_optimizing()) {
1559 auto it = label_farjmp_maps_.find(L);
1560 if (it != label_farjmp_maps_.end()) {
1561 auto& pos_vector = it->second;
1562 for (auto fixup_pos : pos_vector) {
1563 int disp = pos - (fixup_pos + sizeof(int8_t));
1564 CHECK(is_int8(disp));
1565 set_byte_at(fixup_pos, disp);
1566 }
1567 label_farjmp_maps_.erase(it);
1568 }
1569 }
1570 L->bind_to(pos);
1571 }
1572
1573
bind(Label * L)1574 void Assembler::bind(Label* L) {
1575 EnsureSpace ensure_space(this);
1576 DCHECK(!L->is_bound()); // label can only be bound once
1577 bind_to(L, pc_offset());
1578 }
1579
record_farjmp_position(Label * L,int pos)1580 void Assembler::record_farjmp_position(Label* L, int pos) {
1581 auto& pos_vector = label_farjmp_maps_[L];
1582 pos_vector.push_back(pos);
1583 }
1584
is_optimizable_farjmp(int idx)1585 bool Assembler::is_optimizable_farjmp(int idx) {
1586 if (predictable_code_size()) return false;
1587
1588 auto jump_opt = jump_optimization_info();
1589 CHECK(jump_opt->is_optimizing());
1590
1591 auto& bitmap = jump_opt->farjmp_bitmap();
1592 CHECK(idx < static_cast<int>(bitmap.size() * 32));
1593 return !!(bitmap[idx / 32] & (1 << (idx & 31)));
1594 }
1595
call(Label * L)1596 void Assembler::call(Label* L) {
1597 EnsureSpace ensure_space(this);
1598 if (L->is_bound()) {
1599 const int long_size = 5;
1600 int offs = L->pos() - pc_offset();
1601 DCHECK_LE(offs, 0);
1602 // 1110 1000 #32-bit disp.
1603 EMIT(0xE8);
1604 emit(offs - long_size);
1605 } else {
1606 // 1110 1000 #32-bit disp.
1607 EMIT(0xE8);
1608 emit_disp(L, Displacement::OTHER);
1609 }
1610 }
1611
call(Address entry,RelocInfo::Mode rmode)1612 void Assembler::call(Address entry, RelocInfo::Mode rmode) {
1613 EnsureSpace ensure_space(this);
1614 DCHECK(!RelocInfo::IsCodeTarget(rmode));
1615 EMIT(0xE8);
1616 if (RelocInfo::IsRuntimeEntry(rmode)) {
1617 emit(entry, rmode);
1618 } else {
1619 emit(entry - (reinterpret_cast<Address>(pc_) + sizeof(int32_t)), rmode);
1620 }
1621 }
1622
wasm_call(Address entry,RelocInfo::Mode rmode)1623 void Assembler::wasm_call(Address entry, RelocInfo::Mode rmode) {
1624 EnsureSpace ensure_space(this);
1625 EMIT(0xE8);
1626 emit(entry, rmode);
1627 }
1628
call(Operand adr)1629 void Assembler::call(Operand adr) {
1630 EnsureSpace ensure_space(this);
1631 EMIT(0xFF);
1632 emit_operand(edx, adr);
1633 }
1634
call(Handle<Code> code,RelocInfo::Mode rmode)1635 void Assembler::call(Handle<Code> code, RelocInfo::Mode rmode) {
1636 EnsureSpace ensure_space(this);
1637 DCHECK(RelocInfo::IsCodeTarget(rmode));
1638 EMIT(0xE8);
1639 emit(code, rmode);
1640 }
1641
call(CodeStub * stub)1642 void Assembler::call(CodeStub* stub) {
1643 EnsureSpace ensure_space(this);
1644 EMIT(0xE8);
1645 emit(Immediate::EmbeddedCode(stub));
1646 }
1647
jmp_rel(int offset)1648 void Assembler::jmp_rel(int offset) {
1649 EnsureSpace ensure_space(this);
1650 const int short_size = 2;
1651 const int long_size = 5;
1652 if (is_int8(offset - short_size)) {
1653 // 1110 1011 #8-bit disp.
1654 EMIT(0xEB);
1655 EMIT((offset - short_size) & 0xFF);
1656 } else {
1657 // 1110 1001 #32-bit disp.
1658 EMIT(0xE9);
1659 emit(offset - long_size);
1660 }
1661 }
1662
jmp(Label * L,Label::Distance distance)1663 void Assembler::jmp(Label* L, Label::Distance distance) {
1664 if (L->is_bound()) {
1665 int offset = L->pos() - pc_offset();
1666 DCHECK_LE(offset, 0); // backward jump.
1667 jmp_rel(offset);
1668 return;
1669 }
1670
1671 EnsureSpace ensure_space(this);
1672 if (distance == Label::kNear) {
1673 EMIT(0xEB);
1674 emit_near_disp(L);
1675 } else {
1676 auto jump_opt = jump_optimization_info();
1677 if (V8_UNLIKELY(jump_opt)) {
1678 if (jump_opt->is_optimizing() && is_optimizable_farjmp(farjmp_num_++)) {
1679 EMIT(0xEB);
1680 record_farjmp_position(L, pc_offset());
1681 EMIT(0);
1682 return;
1683 }
1684 if (jump_opt->is_collecting()) {
1685 farjmp_positions_.push_back(pc_offset() + 1);
1686 }
1687 }
1688 // 1110 1001 #32-bit disp.
1689 EMIT(0xE9);
1690 emit_disp(L, Displacement::UNCONDITIONAL_JUMP);
1691 }
1692 }
1693
jmp(Address entry,RelocInfo::Mode rmode)1694 void Assembler::jmp(Address entry, RelocInfo::Mode rmode) {
1695 EnsureSpace ensure_space(this);
1696 DCHECK(!RelocInfo::IsCodeTarget(rmode));
1697 EMIT(0xE9);
1698 if (RelocInfo::IsRuntimeEntry(rmode)) {
1699 emit(entry, rmode);
1700 } else {
1701 emit(entry - (reinterpret_cast<Address>(pc_) + sizeof(int32_t)), rmode);
1702 }
1703 }
1704
jmp(Operand adr)1705 void Assembler::jmp(Operand adr) {
1706 EnsureSpace ensure_space(this);
1707 EMIT(0xFF);
1708 emit_operand(esp, adr);
1709 }
1710
1711
jmp(Handle<Code> code,RelocInfo::Mode rmode)1712 void Assembler::jmp(Handle<Code> code, RelocInfo::Mode rmode) {
1713 EnsureSpace ensure_space(this);
1714 DCHECK(RelocInfo::IsCodeTarget(rmode));
1715 EMIT(0xE9);
1716 emit(code, rmode);
1717 }
1718
1719
j(Condition cc,Label * L,Label::Distance distance)1720 void Assembler::j(Condition cc, Label* L, Label::Distance distance) {
1721 EnsureSpace ensure_space(this);
1722 DCHECK(0 <= cc && static_cast<int>(cc) < 16);
1723 if (L->is_bound()) {
1724 const int short_size = 2;
1725 const int long_size = 6;
1726 int offs = L->pos() - pc_offset();
1727 DCHECK_LE(offs, 0);
1728 if (is_int8(offs - short_size)) {
1729 // 0111 tttn #8-bit disp
1730 EMIT(0x70 | cc);
1731 EMIT((offs - short_size) & 0xFF);
1732 } else {
1733 // 0000 1111 1000 tttn #32-bit disp
1734 EMIT(0x0F);
1735 EMIT(0x80 | cc);
1736 emit(offs - long_size);
1737 }
1738 } else if (distance == Label::kNear) {
1739 EMIT(0x70 | cc);
1740 emit_near_disp(L);
1741 } else {
1742 auto jump_opt = jump_optimization_info();
1743 if (V8_UNLIKELY(jump_opt)) {
1744 if (jump_opt->is_optimizing() && is_optimizable_farjmp(farjmp_num_++)) {
1745 // 0111 tttn #8-bit disp
1746 EMIT(0x70 | cc);
1747 record_farjmp_position(L, pc_offset());
1748 EMIT(0);
1749 return;
1750 }
1751 if (jump_opt->is_collecting()) {
1752 farjmp_positions_.push_back(pc_offset() + 2);
1753 }
1754 }
1755 // 0000 1111 1000 tttn #32-bit disp
1756 // Note: could eliminate cond. jumps to this jump if condition
1757 // is the same however, seems to be rather unlikely case.
1758 EMIT(0x0F);
1759 EMIT(0x80 | cc);
1760 emit_disp(L, Displacement::OTHER);
1761 }
1762 }
1763
1764
j(Condition cc,byte * entry,RelocInfo::Mode rmode)1765 void Assembler::j(Condition cc, byte* entry, RelocInfo::Mode rmode) {
1766 EnsureSpace ensure_space(this);
1767 DCHECK((0 <= cc) && (static_cast<int>(cc) < 16));
1768 // 0000 1111 1000 tttn #32-bit disp.
1769 EMIT(0x0F);
1770 EMIT(0x80 | cc);
1771 if (RelocInfo::IsRuntimeEntry(rmode)) {
1772 emit(reinterpret_cast<uint32_t>(entry), rmode);
1773 } else {
1774 emit(entry - (pc_ + sizeof(int32_t)), rmode);
1775 }
1776 }
1777
1778
j(Condition cc,Handle<Code> code,RelocInfo::Mode rmode)1779 void Assembler::j(Condition cc, Handle<Code> code, RelocInfo::Mode rmode) {
1780 EnsureSpace ensure_space(this);
1781 // 0000 1111 1000 tttn #32-bit disp
1782 EMIT(0x0F);
1783 EMIT(0x80 | cc);
1784 emit(code, rmode);
1785 }
1786
1787
1788 // FPU instructions.
1789
fld(int i)1790 void Assembler::fld(int i) {
1791 EnsureSpace ensure_space(this);
1792 emit_farith(0xD9, 0xC0, i);
1793 }
1794
1795
fstp(int i)1796 void Assembler::fstp(int i) {
1797 EnsureSpace ensure_space(this);
1798 emit_farith(0xDD, 0xD8, i);
1799 }
1800
1801
fld1()1802 void Assembler::fld1() {
1803 EnsureSpace ensure_space(this);
1804 EMIT(0xD9);
1805 EMIT(0xE8);
1806 }
1807
1808
fldpi()1809 void Assembler::fldpi() {
1810 EnsureSpace ensure_space(this);
1811 EMIT(0xD9);
1812 EMIT(0xEB);
1813 }
1814
1815
fldz()1816 void Assembler::fldz() {
1817 EnsureSpace ensure_space(this);
1818 EMIT(0xD9);
1819 EMIT(0xEE);
1820 }
1821
1822
fldln2()1823 void Assembler::fldln2() {
1824 EnsureSpace ensure_space(this);
1825 EMIT(0xD9);
1826 EMIT(0xED);
1827 }
1828
fld_s(Operand adr)1829 void Assembler::fld_s(Operand adr) {
1830 EnsureSpace ensure_space(this);
1831 EMIT(0xD9);
1832 emit_operand(eax, adr);
1833 }
1834
fld_d(Operand adr)1835 void Assembler::fld_d(Operand adr) {
1836 EnsureSpace ensure_space(this);
1837 EMIT(0xDD);
1838 emit_operand(eax, adr);
1839 }
1840
fstp_s(Operand adr)1841 void Assembler::fstp_s(Operand adr) {
1842 EnsureSpace ensure_space(this);
1843 EMIT(0xD9);
1844 emit_operand(ebx, adr);
1845 }
1846
fst_s(Operand adr)1847 void Assembler::fst_s(Operand adr) {
1848 EnsureSpace ensure_space(this);
1849 EMIT(0xD9);
1850 emit_operand(edx, adr);
1851 }
1852
fstp_d(Operand adr)1853 void Assembler::fstp_d(Operand adr) {
1854 EnsureSpace ensure_space(this);
1855 EMIT(0xDD);
1856 emit_operand(ebx, adr);
1857 }
1858
fst_d(Operand adr)1859 void Assembler::fst_d(Operand adr) {
1860 EnsureSpace ensure_space(this);
1861 EMIT(0xDD);
1862 emit_operand(edx, adr);
1863 }
1864
fild_s(Operand adr)1865 void Assembler::fild_s(Operand adr) {
1866 EnsureSpace ensure_space(this);
1867 EMIT(0xDB);
1868 emit_operand(eax, adr);
1869 }
1870
fild_d(Operand adr)1871 void Assembler::fild_d(Operand adr) {
1872 EnsureSpace ensure_space(this);
1873 EMIT(0xDF);
1874 emit_operand(ebp, adr);
1875 }
1876
fistp_s(Operand adr)1877 void Assembler::fistp_s(Operand adr) {
1878 EnsureSpace ensure_space(this);
1879 EMIT(0xDB);
1880 emit_operand(ebx, adr);
1881 }
1882
fisttp_s(Operand adr)1883 void Assembler::fisttp_s(Operand adr) {
1884 DCHECK(IsEnabled(SSE3));
1885 EnsureSpace ensure_space(this);
1886 EMIT(0xDB);
1887 emit_operand(ecx, adr);
1888 }
1889
fisttp_d(Operand adr)1890 void Assembler::fisttp_d(Operand adr) {
1891 DCHECK(IsEnabled(SSE3));
1892 EnsureSpace ensure_space(this);
1893 EMIT(0xDD);
1894 emit_operand(ecx, adr);
1895 }
1896
fist_s(Operand adr)1897 void Assembler::fist_s(Operand adr) {
1898 EnsureSpace ensure_space(this);
1899 EMIT(0xDB);
1900 emit_operand(edx, adr);
1901 }
1902
fistp_d(Operand adr)1903 void Assembler::fistp_d(Operand adr) {
1904 EnsureSpace ensure_space(this);
1905 EMIT(0xDF);
1906 emit_operand(edi, adr);
1907 }
1908
1909
fabs()1910 void Assembler::fabs() {
1911 EnsureSpace ensure_space(this);
1912 EMIT(0xD9);
1913 EMIT(0xE1);
1914 }
1915
1916
fchs()1917 void Assembler::fchs() {
1918 EnsureSpace ensure_space(this);
1919 EMIT(0xD9);
1920 EMIT(0xE0);
1921 }
1922
1923
fcos()1924 void Assembler::fcos() {
1925 EnsureSpace ensure_space(this);
1926 EMIT(0xD9);
1927 EMIT(0xFF);
1928 }
1929
1930
fsin()1931 void Assembler::fsin() {
1932 EnsureSpace ensure_space(this);
1933 EMIT(0xD9);
1934 EMIT(0xFE);
1935 }
1936
1937
fptan()1938 void Assembler::fptan() {
1939 EnsureSpace ensure_space(this);
1940 EMIT(0xD9);
1941 EMIT(0xF2);
1942 }
1943
1944
fyl2x()1945 void Assembler::fyl2x() {
1946 EnsureSpace ensure_space(this);
1947 EMIT(0xD9);
1948 EMIT(0xF1);
1949 }
1950
1951
f2xm1()1952 void Assembler::f2xm1() {
1953 EnsureSpace ensure_space(this);
1954 EMIT(0xD9);
1955 EMIT(0xF0);
1956 }
1957
1958
fscale()1959 void Assembler::fscale() {
1960 EnsureSpace ensure_space(this);
1961 EMIT(0xD9);
1962 EMIT(0xFD);
1963 }
1964
1965
fninit()1966 void Assembler::fninit() {
1967 EnsureSpace ensure_space(this);
1968 EMIT(0xDB);
1969 EMIT(0xE3);
1970 }
1971
1972
fadd(int i)1973 void Assembler::fadd(int i) {
1974 EnsureSpace ensure_space(this);
1975 emit_farith(0xDC, 0xC0, i);
1976 }
1977
1978
fadd_i(int i)1979 void Assembler::fadd_i(int i) {
1980 EnsureSpace ensure_space(this);
1981 emit_farith(0xD8, 0xC0, i);
1982 }
1983
1984
fsub(int i)1985 void Assembler::fsub(int i) {
1986 EnsureSpace ensure_space(this);
1987 emit_farith(0xDC, 0xE8, i);
1988 }
1989
1990
fsub_i(int i)1991 void Assembler::fsub_i(int i) {
1992 EnsureSpace ensure_space(this);
1993 emit_farith(0xD8, 0xE0, i);
1994 }
1995
fisub_s(Operand adr)1996 void Assembler::fisub_s(Operand adr) {
1997 EnsureSpace ensure_space(this);
1998 EMIT(0xDA);
1999 emit_operand(esp, adr);
2000 }
2001
2002
fmul_i(int i)2003 void Assembler::fmul_i(int i) {
2004 EnsureSpace ensure_space(this);
2005 emit_farith(0xD8, 0xC8, i);
2006 }
2007
2008
fmul(int i)2009 void Assembler::fmul(int i) {
2010 EnsureSpace ensure_space(this);
2011 emit_farith(0xDC, 0xC8, i);
2012 }
2013
2014
fdiv(int i)2015 void Assembler::fdiv(int i) {
2016 EnsureSpace ensure_space(this);
2017 emit_farith(0xDC, 0xF8, i);
2018 }
2019
2020
fdiv_i(int i)2021 void Assembler::fdiv_i(int i) {
2022 EnsureSpace ensure_space(this);
2023 emit_farith(0xD8, 0xF0, i);
2024 }
2025
2026
faddp(int i)2027 void Assembler::faddp(int i) {
2028 EnsureSpace ensure_space(this);
2029 emit_farith(0xDE, 0xC0, i);
2030 }
2031
2032
fsubp(int i)2033 void Assembler::fsubp(int i) {
2034 EnsureSpace ensure_space(this);
2035 emit_farith(0xDE, 0xE8, i);
2036 }
2037
2038
fsubrp(int i)2039 void Assembler::fsubrp(int i) {
2040 EnsureSpace ensure_space(this);
2041 emit_farith(0xDE, 0xE0, i);
2042 }
2043
2044
fmulp(int i)2045 void Assembler::fmulp(int i) {
2046 EnsureSpace ensure_space(this);
2047 emit_farith(0xDE, 0xC8, i);
2048 }
2049
2050
fdivp(int i)2051 void Assembler::fdivp(int i) {
2052 EnsureSpace ensure_space(this);
2053 emit_farith(0xDE, 0xF8, i);
2054 }
2055
2056
fprem()2057 void Assembler::fprem() {
2058 EnsureSpace ensure_space(this);
2059 EMIT(0xD9);
2060 EMIT(0xF8);
2061 }
2062
2063
fprem1()2064 void Assembler::fprem1() {
2065 EnsureSpace ensure_space(this);
2066 EMIT(0xD9);
2067 EMIT(0xF5);
2068 }
2069
2070
fxch(int i)2071 void Assembler::fxch(int i) {
2072 EnsureSpace ensure_space(this);
2073 emit_farith(0xD9, 0xC8, i);
2074 }
2075
2076
fincstp()2077 void Assembler::fincstp() {
2078 EnsureSpace ensure_space(this);
2079 EMIT(0xD9);
2080 EMIT(0xF7);
2081 }
2082
2083
ffree(int i)2084 void Assembler::ffree(int i) {
2085 EnsureSpace ensure_space(this);
2086 emit_farith(0xDD, 0xC0, i);
2087 }
2088
2089
ftst()2090 void Assembler::ftst() {
2091 EnsureSpace ensure_space(this);
2092 EMIT(0xD9);
2093 EMIT(0xE4);
2094 }
2095
2096
fucomp(int i)2097 void Assembler::fucomp(int i) {
2098 EnsureSpace ensure_space(this);
2099 emit_farith(0xDD, 0xE8, i);
2100 }
2101
2102
fucompp()2103 void Assembler::fucompp() {
2104 EnsureSpace ensure_space(this);
2105 EMIT(0xDA);
2106 EMIT(0xE9);
2107 }
2108
2109
fucomi(int i)2110 void Assembler::fucomi(int i) {
2111 EnsureSpace ensure_space(this);
2112 EMIT(0xDB);
2113 EMIT(0xE8 + i);
2114 }
2115
2116
fucomip()2117 void Assembler::fucomip() {
2118 EnsureSpace ensure_space(this);
2119 EMIT(0xDF);
2120 EMIT(0xE9);
2121 }
2122
2123
fcompp()2124 void Assembler::fcompp() {
2125 EnsureSpace ensure_space(this);
2126 EMIT(0xDE);
2127 EMIT(0xD9);
2128 }
2129
2130
fnstsw_ax()2131 void Assembler::fnstsw_ax() {
2132 EnsureSpace ensure_space(this);
2133 EMIT(0xDF);
2134 EMIT(0xE0);
2135 }
2136
2137
fwait()2138 void Assembler::fwait() {
2139 EnsureSpace ensure_space(this);
2140 EMIT(0x9B);
2141 }
2142
2143
frndint()2144 void Assembler::frndint() {
2145 EnsureSpace ensure_space(this);
2146 EMIT(0xD9);
2147 EMIT(0xFC);
2148 }
2149
2150
fnclex()2151 void Assembler::fnclex() {
2152 EnsureSpace ensure_space(this);
2153 EMIT(0xDB);
2154 EMIT(0xE2);
2155 }
2156
2157
sahf()2158 void Assembler::sahf() {
2159 EnsureSpace ensure_space(this);
2160 EMIT(0x9E);
2161 }
2162
2163
setcc(Condition cc,Register reg)2164 void Assembler::setcc(Condition cc, Register reg) {
2165 DCHECK(reg.is_byte_register());
2166 EnsureSpace ensure_space(this);
2167 EMIT(0x0F);
2168 EMIT(0x90 | cc);
2169 EMIT(0xC0 | reg.code());
2170 }
2171
cvttss2si(Register dst,Operand src)2172 void Assembler::cvttss2si(Register dst, Operand src) {
2173 EnsureSpace ensure_space(this);
2174 EMIT(0xF3);
2175 EMIT(0x0F);
2176 EMIT(0x2C);
2177 emit_operand(dst, src);
2178 }
2179
cvttsd2si(Register dst,Operand src)2180 void Assembler::cvttsd2si(Register dst, Operand src) {
2181 EnsureSpace ensure_space(this);
2182 EMIT(0xF2);
2183 EMIT(0x0F);
2184 EMIT(0x2C);
2185 emit_operand(dst, src);
2186 }
2187
2188
cvtsd2si(Register dst,XMMRegister src)2189 void Assembler::cvtsd2si(Register dst, XMMRegister src) {
2190 EnsureSpace ensure_space(this);
2191 EMIT(0xF2);
2192 EMIT(0x0F);
2193 EMIT(0x2D);
2194 emit_sse_operand(dst, src);
2195 }
2196
cvtsi2ss(XMMRegister dst,Operand src)2197 void Assembler::cvtsi2ss(XMMRegister dst, Operand src) {
2198 EnsureSpace ensure_space(this);
2199 EMIT(0xF3);
2200 EMIT(0x0F);
2201 EMIT(0x2A);
2202 emit_sse_operand(dst, src);
2203 }
2204
cvtsi2sd(XMMRegister dst,Operand src)2205 void Assembler::cvtsi2sd(XMMRegister dst, Operand src) {
2206 EnsureSpace ensure_space(this);
2207 EMIT(0xF2);
2208 EMIT(0x0F);
2209 EMIT(0x2A);
2210 emit_sse_operand(dst, src);
2211 }
2212
cvtss2sd(XMMRegister dst,Operand src)2213 void Assembler::cvtss2sd(XMMRegister dst, Operand src) {
2214 EnsureSpace ensure_space(this);
2215 EMIT(0xF3);
2216 EMIT(0x0F);
2217 EMIT(0x5A);
2218 emit_sse_operand(dst, src);
2219 }
2220
cvtsd2ss(XMMRegister dst,Operand src)2221 void Assembler::cvtsd2ss(XMMRegister dst, Operand src) {
2222 EnsureSpace ensure_space(this);
2223 EMIT(0xF2);
2224 EMIT(0x0F);
2225 EMIT(0x5A);
2226 emit_sse_operand(dst, src);
2227 }
2228
cvtdq2ps(XMMRegister dst,Operand src)2229 void Assembler::cvtdq2ps(XMMRegister dst, Operand src) {
2230 EnsureSpace ensure_space(this);
2231 EMIT(0x0F);
2232 EMIT(0x5B);
2233 emit_sse_operand(dst, src);
2234 }
2235
cvttps2dq(XMMRegister dst,Operand src)2236 void Assembler::cvttps2dq(XMMRegister dst, Operand src) {
2237 EnsureSpace ensure_space(this);
2238 EMIT(0xF3);
2239 EMIT(0x0F);
2240 EMIT(0x5B);
2241 emit_sse_operand(dst, src);
2242 }
2243
addsd(XMMRegister dst,Operand src)2244 void Assembler::addsd(XMMRegister dst, Operand src) {
2245 EnsureSpace ensure_space(this);
2246 EMIT(0xF2);
2247 EMIT(0x0F);
2248 EMIT(0x58);
2249 emit_sse_operand(dst, src);
2250 }
2251
mulsd(XMMRegister dst,Operand src)2252 void Assembler::mulsd(XMMRegister dst, Operand src) {
2253 EnsureSpace ensure_space(this);
2254 EMIT(0xF2);
2255 EMIT(0x0F);
2256 EMIT(0x59);
2257 emit_sse_operand(dst, src);
2258 }
2259
subsd(XMMRegister dst,Operand src)2260 void Assembler::subsd(XMMRegister dst, Operand src) {
2261 EnsureSpace ensure_space(this);
2262 EMIT(0xF2);
2263 EMIT(0x0F);
2264 EMIT(0x5C);
2265 emit_sse_operand(dst, src);
2266 }
2267
divsd(XMMRegister dst,Operand src)2268 void Assembler::divsd(XMMRegister dst, Operand src) {
2269 EnsureSpace ensure_space(this);
2270 EMIT(0xF2);
2271 EMIT(0x0F);
2272 EMIT(0x5E);
2273 emit_sse_operand(dst, src);
2274 }
2275
xorpd(XMMRegister dst,Operand src)2276 void Assembler::xorpd(XMMRegister dst, Operand src) {
2277 EnsureSpace ensure_space(this);
2278 EMIT(0x66);
2279 EMIT(0x0F);
2280 EMIT(0x57);
2281 emit_sse_operand(dst, src);
2282 }
2283
andps(XMMRegister dst,Operand src)2284 void Assembler::andps(XMMRegister dst, Operand src) {
2285 EnsureSpace ensure_space(this);
2286 EMIT(0x0F);
2287 EMIT(0x54);
2288 emit_sse_operand(dst, src);
2289 }
2290
orps(XMMRegister dst,Operand src)2291 void Assembler::orps(XMMRegister dst, Operand src) {
2292 EnsureSpace ensure_space(this);
2293 EMIT(0x0F);
2294 EMIT(0x56);
2295 emit_sse_operand(dst, src);
2296 }
2297
xorps(XMMRegister dst,Operand src)2298 void Assembler::xorps(XMMRegister dst, Operand src) {
2299 EnsureSpace ensure_space(this);
2300 EMIT(0x0F);
2301 EMIT(0x57);
2302 emit_sse_operand(dst, src);
2303 }
2304
addps(XMMRegister dst,Operand src)2305 void Assembler::addps(XMMRegister dst, Operand src) {
2306 EnsureSpace ensure_space(this);
2307 EMIT(0x0F);
2308 EMIT(0x58);
2309 emit_sse_operand(dst, src);
2310 }
2311
subps(XMMRegister dst,Operand src)2312 void Assembler::subps(XMMRegister dst, Operand src) {
2313 EnsureSpace ensure_space(this);
2314 EMIT(0x0F);
2315 EMIT(0x5C);
2316 emit_sse_operand(dst, src);
2317 }
2318
mulps(XMMRegister dst,Operand src)2319 void Assembler::mulps(XMMRegister dst, Operand src) {
2320 EnsureSpace ensure_space(this);
2321 EMIT(0x0F);
2322 EMIT(0x59);
2323 emit_sse_operand(dst, src);
2324 }
2325
divps(XMMRegister dst,Operand src)2326 void Assembler::divps(XMMRegister dst, Operand src) {
2327 EnsureSpace ensure_space(this);
2328 EMIT(0x0F);
2329 EMIT(0x5E);
2330 emit_sse_operand(dst, src);
2331 }
2332
rcpps(XMMRegister dst,Operand src)2333 void Assembler::rcpps(XMMRegister dst, Operand src) {
2334 EnsureSpace ensure_space(this);
2335 EMIT(0x0F);
2336 EMIT(0x53);
2337 emit_sse_operand(dst, src);
2338 }
2339
rsqrtps(XMMRegister dst,Operand src)2340 void Assembler::rsqrtps(XMMRegister dst, Operand src) {
2341 EnsureSpace ensure_space(this);
2342 EMIT(0x0F);
2343 EMIT(0x52);
2344 emit_sse_operand(dst, src);
2345 }
2346
minps(XMMRegister dst,Operand src)2347 void Assembler::minps(XMMRegister dst, Operand src) {
2348 EnsureSpace ensure_space(this);
2349 EMIT(0x0F);
2350 EMIT(0x5D);
2351 emit_sse_operand(dst, src);
2352 }
2353
maxps(XMMRegister dst,Operand src)2354 void Assembler::maxps(XMMRegister dst, Operand src) {
2355 EnsureSpace ensure_space(this);
2356 EMIT(0x0F);
2357 EMIT(0x5F);
2358 emit_sse_operand(dst, src);
2359 }
2360
cmpps(XMMRegister dst,Operand src,int8_t cmp)2361 void Assembler::cmpps(XMMRegister dst, Operand src, int8_t cmp) {
2362 EnsureSpace ensure_space(this);
2363 EMIT(0x0F);
2364 EMIT(0xC2);
2365 emit_sse_operand(dst, src);
2366 EMIT(cmp);
2367 }
2368
sqrtsd(XMMRegister dst,Operand src)2369 void Assembler::sqrtsd(XMMRegister dst, Operand src) {
2370 EnsureSpace ensure_space(this);
2371 EMIT(0xF2);
2372 EMIT(0x0F);
2373 EMIT(0x51);
2374 emit_sse_operand(dst, src);
2375 }
2376
haddps(XMMRegister dst,Operand src)2377 void Assembler::haddps(XMMRegister dst, Operand src) {
2378 DCHECK(IsEnabled(SSE3));
2379 EnsureSpace ensure_space(this);
2380 EMIT(0xF2);
2381 EMIT(0x0F);
2382 EMIT(0x7C);
2383 emit_sse_operand(dst, src);
2384 }
2385
andpd(XMMRegister dst,Operand src)2386 void Assembler::andpd(XMMRegister dst, Operand src) {
2387 EnsureSpace ensure_space(this);
2388 EMIT(0x66);
2389 EMIT(0x0F);
2390 EMIT(0x54);
2391 emit_sse_operand(dst, src);
2392 }
2393
orpd(XMMRegister dst,Operand src)2394 void Assembler::orpd(XMMRegister dst, Operand src) {
2395 EnsureSpace ensure_space(this);
2396 EMIT(0x66);
2397 EMIT(0x0F);
2398 EMIT(0x56);
2399 emit_sse_operand(dst, src);
2400 }
2401
ucomisd(XMMRegister dst,Operand src)2402 void Assembler::ucomisd(XMMRegister dst, Operand src) {
2403 EnsureSpace ensure_space(this);
2404 EMIT(0x66);
2405 EMIT(0x0F);
2406 EMIT(0x2E);
2407 emit_sse_operand(dst, src);
2408 }
2409
2410
roundss(XMMRegister dst,XMMRegister src,RoundingMode mode)2411 void Assembler::roundss(XMMRegister dst, XMMRegister src, RoundingMode mode) {
2412 DCHECK(IsEnabled(SSE4_1));
2413 EnsureSpace ensure_space(this);
2414 EMIT(0x66);
2415 EMIT(0x0F);
2416 EMIT(0x3A);
2417 EMIT(0x0A);
2418 emit_sse_operand(dst, src);
2419 // Mask precision exeption.
2420 EMIT(static_cast<byte>(mode) | 0x8);
2421 }
2422
2423
roundsd(XMMRegister dst,XMMRegister src,RoundingMode mode)2424 void Assembler::roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode) {
2425 DCHECK(IsEnabled(SSE4_1));
2426 EnsureSpace ensure_space(this);
2427 EMIT(0x66);
2428 EMIT(0x0F);
2429 EMIT(0x3A);
2430 EMIT(0x0B);
2431 emit_sse_operand(dst, src);
2432 // Mask precision exeption.
2433 EMIT(static_cast<byte>(mode) | 0x8);
2434 }
2435
2436
movmskpd(Register dst,XMMRegister src)2437 void Assembler::movmskpd(Register dst, XMMRegister src) {
2438 EnsureSpace ensure_space(this);
2439 EMIT(0x66);
2440 EMIT(0x0F);
2441 EMIT(0x50);
2442 emit_sse_operand(dst, src);
2443 }
2444
2445
movmskps(Register dst,XMMRegister src)2446 void Assembler::movmskps(Register dst, XMMRegister src) {
2447 EnsureSpace ensure_space(this);
2448 EMIT(0x0F);
2449 EMIT(0x50);
2450 emit_sse_operand(dst, src);
2451 }
2452
maxsd(XMMRegister dst,Operand src)2453 void Assembler::maxsd(XMMRegister dst, Operand src) {
2454 EnsureSpace ensure_space(this);
2455 EMIT(0xF2);
2456 EMIT(0x0F);
2457 EMIT(0x5F);
2458 emit_sse_operand(dst, src);
2459 }
2460
minsd(XMMRegister dst,Operand src)2461 void Assembler::minsd(XMMRegister dst, Operand src) {
2462 EnsureSpace ensure_space(this);
2463 EMIT(0xF2);
2464 EMIT(0x0F);
2465 EMIT(0x5D);
2466 emit_sse_operand(dst, src);
2467 }
2468
2469
cmpltsd(XMMRegister dst,XMMRegister src)2470 void Assembler::cmpltsd(XMMRegister dst, XMMRegister src) {
2471 EnsureSpace ensure_space(this);
2472 EMIT(0xF2);
2473 EMIT(0x0F);
2474 EMIT(0xC2);
2475 emit_sse_operand(dst, src);
2476 EMIT(1); // LT == 1
2477 }
2478
2479
movaps(XMMRegister dst,XMMRegister src)2480 void Assembler::movaps(XMMRegister dst, XMMRegister src) {
2481 EnsureSpace ensure_space(this);
2482 EMIT(0x0F);
2483 EMIT(0x28);
2484 emit_sse_operand(dst, src);
2485 }
2486
movups(XMMRegister dst,XMMRegister src)2487 void Assembler::movups(XMMRegister dst, XMMRegister src) {
2488 EnsureSpace ensure_space(this);
2489 EMIT(0x0F);
2490 EMIT(0x10);
2491 emit_sse_operand(dst, src);
2492 }
2493
movups(XMMRegister dst,Operand src)2494 void Assembler::movups(XMMRegister dst, Operand src) {
2495 EnsureSpace ensure_space(this);
2496 EMIT(0x0F);
2497 EMIT(0x10);
2498 emit_sse_operand(dst, src);
2499 }
2500
movups(Operand dst,XMMRegister src)2501 void Assembler::movups(Operand dst, XMMRegister src) {
2502 EnsureSpace ensure_space(this);
2503 EMIT(0x0F);
2504 EMIT(0x11);
2505 emit_sse_operand(src, dst);
2506 }
2507
shufps(XMMRegister dst,XMMRegister src,byte imm8)2508 void Assembler::shufps(XMMRegister dst, XMMRegister src, byte imm8) {
2509 DCHECK(is_uint8(imm8));
2510 EnsureSpace ensure_space(this);
2511 EMIT(0x0F);
2512 EMIT(0xC6);
2513 emit_sse_operand(dst, src);
2514 EMIT(imm8);
2515 }
2516
movdqa(Operand dst,XMMRegister src)2517 void Assembler::movdqa(Operand dst, XMMRegister src) {
2518 EnsureSpace ensure_space(this);
2519 EMIT(0x66);
2520 EMIT(0x0F);
2521 EMIT(0x7F);
2522 emit_sse_operand(src, dst);
2523 }
2524
movdqa(XMMRegister dst,Operand src)2525 void Assembler::movdqa(XMMRegister dst, Operand src) {
2526 EnsureSpace ensure_space(this);
2527 EMIT(0x66);
2528 EMIT(0x0F);
2529 EMIT(0x6F);
2530 emit_sse_operand(dst, src);
2531 }
2532
movdqu(Operand dst,XMMRegister src)2533 void Assembler::movdqu(Operand dst, XMMRegister src) {
2534 EnsureSpace ensure_space(this);
2535 EMIT(0xF3);
2536 EMIT(0x0F);
2537 EMIT(0x7F);
2538 emit_sse_operand(src, dst);
2539 }
2540
movdqu(XMMRegister dst,Operand src)2541 void Assembler::movdqu(XMMRegister dst, Operand src) {
2542 EnsureSpace ensure_space(this);
2543 EMIT(0xF3);
2544 EMIT(0x0F);
2545 EMIT(0x6F);
2546 emit_sse_operand(dst, src);
2547 }
2548
prefetch(Operand src,int level)2549 void Assembler::prefetch(Operand src, int level) {
2550 DCHECK(is_uint2(level));
2551 EnsureSpace ensure_space(this);
2552 EMIT(0x0F);
2553 EMIT(0x18);
2554 // Emit hint number in Reg position of RegR/M.
2555 XMMRegister code = XMMRegister::from_code(level);
2556 emit_sse_operand(code, src);
2557 }
2558
movsd(Operand dst,XMMRegister src)2559 void Assembler::movsd(Operand dst, XMMRegister src) {
2560 EnsureSpace ensure_space(this);
2561 EMIT(0xF2); // double
2562 EMIT(0x0F);
2563 EMIT(0x11); // store
2564 emit_sse_operand(src, dst);
2565 }
2566
movsd(XMMRegister dst,Operand src)2567 void Assembler::movsd(XMMRegister dst, Operand src) {
2568 EnsureSpace ensure_space(this);
2569 EMIT(0xF2); // double
2570 EMIT(0x0F);
2571 EMIT(0x10); // load
2572 emit_sse_operand(dst, src);
2573 }
2574
movss(Operand dst,XMMRegister src)2575 void Assembler::movss(Operand dst, XMMRegister src) {
2576 EnsureSpace ensure_space(this);
2577 EMIT(0xF3); // float
2578 EMIT(0x0F);
2579 EMIT(0x11); // store
2580 emit_sse_operand(src, dst);
2581 }
2582
movss(XMMRegister dst,Operand src)2583 void Assembler::movss(XMMRegister dst, Operand src) {
2584 EnsureSpace ensure_space(this);
2585 EMIT(0xF3); // float
2586 EMIT(0x0F);
2587 EMIT(0x10); // load
2588 emit_sse_operand(dst, src);
2589 }
2590
movd(XMMRegister dst,Operand src)2591 void Assembler::movd(XMMRegister dst, Operand src) {
2592 EnsureSpace ensure_space(this);
2593 EMIT(0x66);
2594 EMIT(0x0F);
2595 EMIT(0x6E);
2596 emit_sse_operand(dst, src);
2597 }
2598
movd(Operand dst,XMMRegister src)2599 void Assembler::movd(Operand dst, XMMRegister src) {
2600 EnsureSpace ensure_space(this);
2601 EMIT(0x66);
2602 EMIT(0x0F);
2603 EMIT(0x7E);
2604 emit_sse_operand(src, dst);
2605 }
2606
2607
extractps(Register dst,XMMRegister src,byte imm8)2608 void Assembler::extractps(Register dst, XMMRegister src, byte imm8) {
2609 DCHECK(IsEnabled(SSE4_1));
2610 DCHECK(is_uint8(imm8));
2611 EnsureSpace ensure_space(this);
2612 EMIT(0x66);
2613 EMIT(0x0F);
2614 EMIT(0x3A);
2615 EMIT(0x17);
2616 emit_sse_operand(src, dst);
2617 EMIT(imm8);
2618 }
2619
psllw(XMMRegister reg,int8_t shift)2620 void Assembler::psllw(XMMRegister reg, int8_t shift) {
2621 EnsureSpace ensure_space(this);
2622 EMIT(0x66);
2623 EMIT(0x0F);
2624 EMIT(0x71);
2625 emit_sse_operand(esi, reg); // esi == 6
2626 EMIT(shift);
2627 }
2628
pslld(XMMRegister reg,int8_t shift)2629 void Assembler::pslld(XMMRegister reg, int8_t shift) {
2630 EnsureSpace ensure_space(this);
2631 EMIT(0x66);
2632 EMIT(0x0F);
2633 EMIT(0x72);
2634 emit_sse_operand(esi, reg); // esi == 6
2635 EMIT(shift);
2636 }
2637
psrlw(XMMRegister reg,int8_t shift)2638 void Assembler::psrlw(XMMRegister reg, int8_t shift) {
2639 EnsureSpace ensure_space(this);
2640 EMIT(0x66);
2641 EMIT(0x0F);
2642 EMIT(0x71);
2643 emit_sse_operand(edx, reg); // edx == 2
2644 EMIT(shift);
2645 }
2646
psrld(XMMRegister reg,int8_t shift)2647 void Assembler::psrld(XMMRegister reg, int8_t shift) {
2648 EnsureSpace ensure_space(this);
2649 EMIT(0x66);
2650 EMIT(0x0F);
2651 EMIT(0x72);
2652 emit_sse_operand(edx, reg); // edx == 2
2653 EMIT(shift);
2654 }
2655
psraw(XMMRegister reg,int8_t shift)2656 void Assembler::psraw(XMMRegister reg, int8_t shift) {
2657 EnsureSpace ensure_space(this);
2658 EMIT(0x66);
2659 EMIT(0x0F);
2660 EMIT(0x71);
2661 emit_sse_operand(esp, reg); // esp == 4
2662 EMIT(shift);
2663 }
2664
psrad(XMMRegister reg,int8_t shift)2665 void Assembler::psrad(XMMRegister reg, int8_t shift) {
2666 EnsureSpace ensure_space(this);
2667 EMIT(0x66);
2668 EMIT(0x0F);
2669 EMIT(0x72);
2670 emit_sse_operand(esp, reg); // esp == 4
2671 EMIT(shift);
2672 }
2673
psllq(XMMRegister reg,int8_t shift)2674 void Assembler::psllq(XMMRegister reg, int8_t shift) {
2675 EnsureSpace ensure_space(this);
2676 EMIT(0x66);
2677 EMIT(0x0F);
2678 EMIT(0x73);
2679 emit_sse_operand(esi, reg); // esi == 6
2680 EMIT(shift);
2681 }
2682
2683
psllq(XMMRegister dst,XMMRegister src)2684 void Assembler::psllq(XMMRegister dst, XMMRegister src) {
2685 EnsureSpace ensure_space(this);
2686 EMIT(0x66);
2687 EMIT(0x0F);
2688 EMIT(0xF3);
2689 emit_sse_operand(dst, src);
2690 }
2691
2692
psrlq(XMMRegister reg,int8_t shift)2693 void Assembler::psrlq(XMMRegister reg, int8_t shift) {
2694 EnsureSpace ensure_space(this);
2695 EMIT(0x66);
2696 EMIT(0x0F);
2697 EMIT(0x73);
2698 emit_sse_operand(edx, reg); // edx == 2
2699 EMIT(shift);
2700 }
2701
2702
psrlq(XMMRegister dst,XMMRegister src)2703 void Assembler::psrlq(XMMRegister dst, XMMRegister src) {
2704 EnsureSpace ensure_space(this);
2705 EMIT(0x66);
2706 EMIT(0x0F);
2707 EMIT(0xD3);
2708 emit_sse_operand(dst, src);
2709 }
2710
pshufhw(XMMRegister dst,Operand src,uint8_t shuffle)2711 void Assembler::pshufhw(XMMRegister dst, Operand src, uint8_t shuffle) {
2712 EnsureSpace ensure_space(this);
2713 EMIT(0xF3);
2714 EMIT(0x0F);
2715 EMIT(0x70);
2716 emit_sse_operand(dst, src);
2717 EMIT(shuffle);
2718 }
2719
pshuflw(XMMRegister dst,Operand src,uint8_t shuffle)2720 void Assembler::pshuflw(XMMRegister dst, Operand src, uint8_t shuffle) {
2721 EnsureSpace ensure_space(this);
2722 EMIT(0xF2);
2723 EMIT(0x0F);
2724 EMIT(0x70);
2725 emit_sse_operand(dst, src);
2726 EMIT(shuffle);
2727 }
2728
pshufd(XMMRegister dst,Operand src,uint8_t shuffle)2729 void Assembler::pshufd(XMMRegister dst, Operand src, uint8_t shuffle) {
2730 EnsureSpace ensure_space(this);
2731 EMIT(0x66);
2732 EMIT(0x0F);
2733 EMIT(0x70);
2734 emit_sse_operand(dst, src);
2735 EMIT(shuffle);
2736 }
2737
pblendw(XMMRegister dst,Operand src,uint8_t mask)2738 void Assembler::pblendw(XMMRegister dst, Operand src, uint8_t mask) {
2739 DCHECK(IsEnabled(SSE4_1));
2740 EnsureSpace ensure_space(this);
2741 EMIT(0x66);
2742 EMIT(0x0F);
2743 EMIT(0x3A);
2744 EMIT(0x0E);
2745 emit_sse_operand(dst, src);
2746 EMIT(mask);
2747 }
2748
palignr(XMMRegister dst,Operand src,uint8_t mask)2749 void Assembler::palignr(XMMRegister dst, Operand src, uint8_t mask) {
2750 DCHECK(IsEnabled(SSSE3));
2751 EnsureSpace ensure_space(this);
2752 EMIT(0x66);
2753 EMIT(0x0F);
2754 EMIT(0x3A);
2755 EMIT(0x0F);
2756 emit_sse_operand(dst, src);
2757 EMIT(mask);
2758 }
2759
pextrb(Operand dst,XMMRegister src,int8_t offset)2760 void Assembler::pextrb(Operand dst, XMMRegister src, int8_t offset) {
2761 DCHECK(IsEnabled(SSE4_1));
2762 EnsureSpace ensure_space(this);
2763 EMIT(0x66);
2764 EMIT(0x0F);
2765 EMIT(0x3A);
2766 EMIT(0x14);
2767 emit_sse_operand(src, dst);
2768 EMIT(offset);
2769 }
2770
pextrw(Operand dst,XMMRegister src,int8_t offset)2771 void Assembler::pextrw(Operand dst, XMMRegister src, int8_t offset) {
2772 DCHECK(IsEnabled(SSE4_1));
2773 EnsureSpace ensure_space(this);
2774 EMIT(0x66);
2775 EMIT(0x0F);
2776 EMIT(0x3A);
2777 EMIT(0x15);
2778 emit_sse_operand(src, dst);
2779 EMIT(offset);
2780 }
2781
pextrd(Operand dst,XMMRegister src,int8_t offset)2782 void Assembler::pextrd(Operand dst, XMMRegister src, int8_t offset) {
2783 DCHECK(IsEnabled(SSE4_1));
2784 EnsureSpace ensure_space(this);
2785 EMIT(0x66);
2786 EMIT(0x0F);
2787 EMIT(0x3A);
2788 EMIT(0x16);
2789 emit_sse_operand(src, dst);
2790 EMIT(offset);
2791 }
2792
insertps(XMMRegister dst,Operand src,int8_t offset)2793 void Assembler::insertps(XMMRegister dst, Operand src, int8_t offset) {
2794 DCHECK(IsEnabled(SSE4_1));
2795 EnsureSpace ensure_space(this);
2796 EMIT(0x66);
2797 EMIT(0x0F);
2798 EMIT(0x3A);
2799 EMIT(0x21);
2800 emit_sse_operand(dst, src);
2801 EMIT(offset);
2802 }
2803
pinsrb(XMMRegister dst,Operand src,int8_t offset)2804 void Assembler::pinsrb(XMMRegister dst, Operand src, int8_t offset) {
2805 DCHECK(IsEnabled(SSE4_1));
2806 EnsureSpace ensure_space(this);
2807 EMIT(0x66);
2808 EMIT(0x0F);
2809 EMIT(0x3A);
2810 EMIT(0x20);
2811 emit_sse_operand(dst, src);
2812 EMIT(offset);
2813 }
2814
pinsrw(XMMRegister dst,Operand src,int8_t offset)2815 void Assembler::pinsrw(XMMRegister dst, Operand src, int8_t offset) {
2816 DCHECK(is_uint8(offset));
2817 EnsureSpace ensure_space(this);
2818 EMIT(0x66);
2819 EMIT(0x0F);
2820 EMIT(0xC4);
2821 emit_sse_operand(dst, src);
2822 EMIT(offset);
2823 }
2824
pinsrd(XMMRegister dst,Operand src,int8_t offset)2825 void Assembler::pinsrd(XMMRegister dst, Operand src, int8_t offset) {
2826 DCHECK(IsEnabled(SSE4_1));
2827 EnsureSpace ensure_space(this);
2828 EMIT(0x66);
2829 EMIT(0x0F);
2830 EMIT(0x3A);
2831 EMIT(0x22);
2832 emit_sse_operand(dst, src);
2833 EMIT(offset);
2834 }
2835
addss(XMMRegister dst,Operand src)2836 void Assembler::addss(XMMRegister dst, Operand src) {
2837 EnsureSpace ensure_space(this);
2838 EMIT(0xF3);
2839 EMIT(0x0F);
2840 EMIT(0x58);
2841 emit_sse_operand(dst, src);
2842 }
2843
subss(XMMRegister dst,Operand src)2844 void Assembler::subss(XMMRegister dst, Operand src) {
2845 EnsureSpace ensure_space(this);
2846 EMIT(0xF3);
2847 EMIT(0x0F);
2848 EMIT(0x5C);
2849 emit_sse_operand(dst, src);
2850 }
2851
mulss(XMMRegister dst,Operand src)2852 void Assembler::mulss(XMMRegister dst, Operand src) {
2853 EnsureSpace ensure_space(this);
2854 EMIT(0xF3);
2855 EMIT(0x0F);
2856 EMIT(0x59);
2857 emit_sse_operand(dst, src);
2858 }
2859
divss(XMMRegister dst,Operand src)2860 void Assembler::divss(XMMRegister dst, Operand src) {
2861 EnsureSpace ensure_space(this);
2862 EMIT(0xF3);
2863 EMIT(0x0F);
2864 EMIT(0x5E);
2865 emit_sse_operand(dst, src);
2866 }
2867
sqrtss(XMMRegister dst,Operand src)2868 void Assembler::sqrtss(XMMRegister dst, Operand src) {
2869 EnsureSpace ensure_space(this);
2870 EMIT(0xF3);
2871 EMIT(0x0F);
2872 EMIT(0x51);
2873 emit_sse_operand(dst, src);
2874 }
2875
ucomiss(XMMRegister dst,Operand src)2876 void Assembler::ucomiss(XMMRegister dst, Operand src) {
2877 EnsureSpace ensure_space(this);
2878 EMIT(0x0F);
2879 EMIT(0x2E);
2880 emit_sse_operand(dst, src);
2881 }
2882
maxss(XMMRegister dst,Operand src)2883 void Assembler::maxss(XMMRegister dst, Operand src) {
2884 EnsureSpace ensure_space(this);
2885 EMIT(0xF3);
2886 EMIT(0x0F);
2887 EMIT(0x5F);
2888 emit_sse_operand(dst, src);
2889 }
2890
minss(XMMRegister dst,Operand src)2891 void Assembler::minss(XMMRegister dst, Operand src) {
2892 EnsureSpace ensure_space(this);
2893 EMIT(0xF3);
2894 EMIT(0x0F);
2895 EMIT(0x5D);
2896 emit_sse_operand(dst, src);
2897 }
2898
2899
2900 // AVX instructions
vfmasd(byte op,XMMRegister dst,XMMRegister src1,Operand src2)2901 void Assembler::vfmasd(byte op, XMMRegister dst, XMMRegister src1,
2902 Operand src2) {
2903 DCHECK(IsEnabled(FMA3));
2904 EnsureSpace ensure_space(this);
2905 emit_vex_prefix(src1, kLIG, k66, k0F38, kW1);
2906 EMIT(op);
2907 emit_sse_operand(dst, src2);
2908 }
2909
vfmass(byte op,XMMRegister dst,XMMRegister src1,Operand src2)2910 void Assembler::vfmass(byte op, XMMRegister dst, XMMRegister src1,
2911 Operand src2) {
2912 DCHECK(IsEnabled(FMA3));
2913 EnsureSpace ensure_space(this);
2914 emit_vex_prefix(src1, kLIG, k66, k0F38, kW0);
2915 EMIT(op);
2916 emit_sse_operand(dst, src2);
2917 }
2918
vsd(byte op,XMMRegister dst,XMMRegister src1,Operand src2)2919 void Assembler::vsd(byte op, XMMRegister dst, XMMRegister src1, Operand src2) {
2920 vinstr(op, dst, src1, src2, kF2, k0F, kWIG);
2921 }
2922
vss(byte op,XMMRegister dst,XMMRegister src1,Operand src2)2923 void Assembler::vss(byte op, XMMRegister dst, XMMRegister src1, Operand src2) {
2924 vinstr(op, dst, src1, src2, kF3, k0F, kWIG);
2925 }
2926
vps(byte op,XMMRegister dst,XMMRegister src1,Operand src2)2927 void Assembler::vps(byte op, XMMRegister dst, XMMRegister src1, Operand src2) {
2928 vinstr(op, dst, src1, src2, kNone, k0F, kWIG);
2929 }
2930
vpd(byte op,XMMRegister dst,XMMRegister src1,Operand src2)2931 void Assembler::vpd(byte op, XMMRegister dst, XMMRegister src1, Operand src2) {
2932 vinstr(op, dst, src1, src2, k66, k0F, kWIG);
2933 }
2934
vcmpps(XMMRegister dst,XMMRegister src1,Operand src2,int8_t cmp)2935 void Assembler::vcmpps(XMMRegister dst, XMMRegister src1, Operand src2,
2936 int8_t cmp) {
2937 vps(0xC2, dst, src1, src2);
2938 EMIT(cmp);
2939 }
2940
vshufps(XMMRegister dst,XMMRegister src1,Operand src2,byte imm8)2941 void Assembler::vshufps(XMMRegister dst, XMMRegister src1, Operand src2,
2942 byte imm8) {
2943 DCHECK(is_uint8(imm8));
2944 vps(0xC6, dst, src1, src2);
2945 EMIT(imm8);
2946 }
2947
vpsllw(XMMRegister dst,XMMRegister src,int8_t imm8)2948 void Assembler::vpsllw(XMMRegister dst, XMMRegister src, int8_t imm8) {
2949 XMMRegister iop = XMMRegister::from_code(6);
2950 vinstr(0x71, iop, dst, Operand(src), k66, k0F, kWIG);
2951 EMIT(imm8);
2952 }
2953
vpslld(XMMRegister dst,XMMRegister src,int8_t imm8)2954 void Assembler::vpslld(XMMRegister dst, XMMRegister src, int8_t imm8) {
2955 XMMRegister iop = XMMRegister::from_code(6);
2956 vinstr(0x72, iop, dst, Operand(src), k66, k0F, kWIG);
2957 EMIT(imm8);
2958 }
2959
vpsrlw(XMMRegister dst,XMMRegister src,int8_t imm8)2960 void Assembler::vpsrlw(XMMRegister dst, XMMRegister src, int8_t imm8) {
2961 XMMRegister iop = XMMRegister::from_code(2);
2962 vinstr(0x71, iop, dst, Operand(src), k66, k0F, kWIG);
2963 EMIT(imm8);
2964 }
2965
vpsrld(XMMRegister dst,XMMRegister src,int8_t imm8)2966 void Assembler::vpsrld(XMMRegister dst, XMMRegister src, int8_t imm8) {
2967 XMMRegister iop = XMMRegister::from_code(2);
2968 vinstr(0x72, iop, dst, Operand(src), k66, k0F, kWIG);
2969 EMIT(imm8);
2970 }
2971
vpsraw(XMMRegister dst,XMMRegister src,int8_t imm8)2972 void Assembler::vpsraw(XMMRegister dst, XMMRegister src, int8_t imm8) {
2973 XMMRegister iop = XMMRegister::from_code(4);
2974 vinstr(0x71, iop, dst, Operand(src), k66, k0F, kWIG);
2975 EMIT(imm8);
2976 }
2977
vpsrad(XMMRegister dst,XMMRegister src,int8_t imm8)2978 void Assembler::vpsrad(XMMRegister dst, XMMRegister src, int8_t imm8) {
2979 XMMRegister iop = XMMRegister::from_code(4);
2980 vinstr(0x72, iop, dst, Operand(src), k66, k0F, kWIG);
2981 EMIT(imm8);
2982 }
2983
vpshufhw(XMMRegister dst,Operand src,uint8_t shuffle)2984 void Assembler::vpshufhw(XMMRegister dst, Operand src, uint8_t shuffle) {
2985 vinstr(0x70, dst, xmm0, src, kF3, k0F, kWIG);
2986 EMIT(shuffle);
2987 }
2988
vpshuflw(XMMRegister dst,Operand src,uint8_t shuffle)2989 void Assembler::vpshuflw(XMMRegister dst, Operand src, uint8_t shuffle) {
2990 vinstr(0x70, dst, xmm0, src, kF2, k0F, kWIG);
2991 EMIT(shuffle);
2992 }
2993
vpshufd(XMMRegister dst,Operand src,uint8_t shuffle)2994 void Assembler::vpshufd(XMMRegister dst, Operand src, uint8_t shuffle) {
2995 vinstr(0x70, dst, xmm0, src, k66, k0F, kWIG);
2996 EMIT(shuffle);
2997 }
2998
vpblendw(XMMRegister dst,XMMRegister src1,Operand src2,uint8_t mask)2999 void Assembler::vpblendw(XMMRegister dst, XMMRegister src1, Operand src2,
3000 uint8_t mask) {
3001 vinstr(0x0E, dst, src1, src2, k66, k0F3A, kWIG);
3002 EMIT(mask);
3003 }
3004
vpalignr(XMMRegister dst,XMMRegister src1,Operand src2,uint8_t mask)3005 void Assembler::vpalignr(XMMRegister dst, XMMRegister src1, Operand src2,
3006 uint8_t mask) {
3007 vinstr(0x0F, dst, src1, src2, k66, k0F3A, kWIG);
3008 EMIT(mask);
3009 }
3010
vpextrb(Operand dst,XMMRegister src,int8_t offset)3011 void Assembler::vpextrb(Operand dst, XMMRegister src, int8_t offset) {
3012 vinstr(0x14, src, xmm0, dst, k66, k0F3A, kWIG);
3013 EMIT(offset);
3014 }
3015
vpextrw(Operand dst,XMMRegister src,int8_t offset)3016 void Assembler::vpextrw(Operand dst, XMMRegister src, int8_t offset) {
3017 vinstr(0x15, src, xmm0, dst, k66, k0F3A, kWIG);
3018 EMIT(offset);
3019 }
3020
vpextrd(Operand dst,XMMRegister src,int8_t offset)3021 void Assembler::vpextrd(Operand dst, XMMRegister src, int8_t offset) {
3022 vinstr(0x16, src, xmm0, dst, k66, k0F3A, kWIG);
3023 EMIT(offset);
3024 }
3025
vinsertps(XMMRegister dst,XMMRegister src1,Operand src2,int8_t offset)3026 void Assembler::vinsertps(XMMRegister dst, XMMRegister src1, Operand src2,
3027 int8_t offset) {
3028 vinstr(0x21, dst, src1, src2, k66, k0F3A, kWIG);
3029 EMIT(offset);
3030 }
3031
vpinsrb(XMMRegister dst,XMMRegister src1,Operand src2,int8_t offset)3032 void Assembler::vpinsrb(XMMRegister dst, XMMRegister src1, Operand src2,
3033 int8_t offset) {
3034 vinstr(0x20, dst, src1, src2, k66, k0F3A, kWIG);
3035 EMIT(offset);
3036 }
3037
vpinsrw(XMMRegister dst,XMMRegister src1,Operand src2,int8_t offset)3038 void Assembler::vpinsrw(XMMRegister dst, XMMRegister src1, Operand src2,
3039 int8_t offset) {
3040 vinstr(0xC4, dst, src1, src2, k66, k0F, kWIG);
3041 EMIT(offset);
3042 }
3043
vpinsrd(XMMRegister dst,XMMRegister src1,Operand src2,int8_t offset)3044 void Assembler::vpinsrd(XMMRegister dst, XMMRegister src1, Operand src2,
3045 int8_t offset) {
3046 vinstr(0x22, dst, src1, src2, k66, k0F3A, kWIG);
3047 EMIT(offset);
3048 }
3049
bmi1(byte op,Register reg,Register vreg,Operand rm)3050 void Assembler::bmi1(byte op, Register reg, Register vreg, Operand rm) {
3051 DCHECK(IsEnabled(BMI1));
3052 EnsureSpace ensure_space(this);
3053 emit_vex_prefix(vreg, kLZ, kNone, k0F38, kW0);
3054 EMIT(op);
3055 emit_operand(reg, rm);
3056 }
3057
tzcnt(Register dst,Operand src)3058 void Assembler::tzcnt(Register dst, Operand src) {
3059 DCHECK(IsEnabled(BMI1));
3060 EnsureSpace ensure_space(this);
3061 EMIT(0xF3);
3062 EMIT(0x0F);
3063 EMIT(0xBC);
3064 emit_operand(dst, src);
3065 }
3066
lzcnt(Register dst,Operand src)3067 void Assembler::lzcnt(Register dst, Operand src) {
3068 DCHECK(IsEnabled(LZCNT));
3069 EnsureSpace ensure_space(this);
3070 EMIT(0xF3);
3071 EMIT(0x0F);
3072 EMIT(0xBD);
3073 emit_operand(dst, src);
3074 }
3075
popcnt(Register dst,Operand src)3076 void Assembler::popcnt(Register dst, Operand src) {
3077 DCHECK(IsEnabled(POPCNT));
3078 EnsureSpace ensure_space(this);
3079 EMIT(0xF3);
3080 EMIT(0x0F);
3081 EMIT(0xB8);
3082 emit_operand(dst, src);
3083 }
3084
bmi2(SIMDPrefix pp,byte op,Register reg,Register vreg,Operand rm)3085 void Assembler::bmi2(SIMDPrefix pp, byte op, Register reg, Register vreg,
3086 Operand rm) {
3087 DCHECK(IsEnabled(BMI2));
3088 EnsureSpace ensure_space(this);
3089 emit_vex_prefix(vreg, kLZ, pp, k0F38, kW0);
3090 EMIT(op);
3091 emit_operand(reg, rm);
3092 }
3093
rorx(Register dst,Operand src,byte imm8)3094 void Assembler::rorx(Register dst, Operand src, byte imm8) {
3095 DCHECK(IsEnabled(BMI2));
3096 DCHECK(is_uint8(imm8));
3097 Register vreg = Register::from_code<0>(); // VEX.vvvv unused
3098 EnsureSpace ensure_space(this);
3099 emit_vex_prefix(vreg, kLZ, kF2, k0F3A, kW0);
3100 EMIT(0xF0);
3101 emit_operand(dst, src);
3102 EMIT(imm8);
3103 }
3104
sse2_instr(XMMRegister dst,Operand src,byte prefix,byte escape,byte opcode)3105 void Assembler::sse2_instr(XMMRegister dst, Operand src, byte prefix,
3106 byte escape, byte opcode) {
3107 EnsureSpace ensure_space(this);
3108 EMIT(prefix);
3109 EMIT(escape);
3110 EMIT(opcode);
3111 emit_sse_operand(dst, src);
3112 }
3113
ssse3_instr(XMMRegister dst,Operand src,byte prefix,byte escape1,byte escape2,byte opcode)3114 void Assembler::ssse3_instr(XMMRegister dst, Operand src, byte prefix,
3115 byte escape1, byte escape2, byte opcode) {
3116 DCHECK(IsEnabled(SSSE3));
3117 EnsureSpace ensure_space(this);
3118 EMIT(prefix);
3119 EMIT(escape1);
3120 EMIT(escape2);
3121 EMIT(opcode);
3122 emit_sse_operand(dst, src);
3123 }
3124
sse4_instr(XMMRegister dst,Operand src,byte prefix,byte escape1,byte escape2,byte opcode)3125 void Assembler::sse4_instr(XMMRegister dst, Operand src, byte prefix,
3126 byte escape1, byte escape2, byte opcode) {
3127 DCHECK(IsEnabled(SSE4_1));
3128 EnsureSpace ensure_space(this);
3129 EMIT(prefix);
3130 EMIT(escape1);
3131 EMIT(escape2);
3132 EMIT(opcode);
3133 emit_sse_operand(dst, src);
3134 }
3135
vinstr(byte op,XMMRegister dst,XMMRegister src1,Operand src2,SIMDPrefix pp,LeadingOpcode m,VexW w)3136 void Assembler::vinstr(byte op, XMMRegister dst, XMMRegister src1, Operand src2,
3137 SIMDPrefix pp, LeadingOpcode m, VexW w) {
3138 DCHECK(IsEnabled(AVX));
3139 EnsureSpace ensure_space(this);
3140 emit_vex_prefix(src1, kL128, pp, m, w);
3141 EMIT(op);
3142 emit_sse_operand(dst, src2);
3143 }
3144
emit_sse_operand(XMMRegister reg,Operand adr)3145 void Assembler::emit_sse_operand(XMMRegister reg, Operand adr) {
3146 Register ireg = Register::from_code(reg.code());
3147 emit_operand(ireg, adr);
3148 }
3149
3150
emit_sse_operand(XMMRegister dst,XMMRegister src)3151 void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) {
3152 EMIT(0xC0 | dst.code() << 3 | src.code());
3153 }
3154
3155
emit_sse_operand(Register dst,XMMRegister src)3156 void Assembler::emit_sse_operand(Register dst, XMMRegister src) {
3157 EMIT(0xC0 | dst.code() << 3 | src.code());
3158 }
3159
3160
emit_sse_operand(XMMRegister dst,Register src)3161 void Assembler::emit_sse_operand(XMMRegister dst, Register src) {
3162 EMIT(0xC0 | (dst.code() << 3) | src.code());
3163 }
3164
3165
emit_vex_prefix(XMMRegister vreg,VectorLength l,SIMDPrefix pp,LeadingOpcode mm,VexW w)3166 void Assembler::emit_vex_prefix(XMMRegister vreg, VectorLength l, SIMDPrefix pp,
3167 LeadingOpcode mm, VexW w) {
3168 if (mm != k0F || w != kW0) {
3169 EMIT(0xC4);
3170 // Change RXB from "110" to "111" to align with gdb disassembler.
3171 EMIT(0xE0 | mm);
3172 EMIT(w | ((~vreg.code() & 0xF) << 3) | l | pp);
3173 } else {
3174 EMIT(0xC5);
3175 EMIT(((~vreg.code()) << 3) | l | pp);
3176 }
3177 }
3178
3179
emit_vex_prefix(Register vreg,VectorLength l,SIMDPrefix pp,LeadingOpcode mm,VexW w)3180 void Assembler::emit_vex_prefix(Register vreg, VectorLength l, SIMDPrefix pp,
3181 LeadingOpcode mm, VexW w) {
3182 XMMRegister ivreg = XMMRegister::from_code(vreg.code());
3183 emit_vex_prefix(ivreg, l, pp, mm, w);
3184 }
3185
3186
GrowBuffer()3187 void Assembler::GrowBuffer() {
3188 DCHECK(buffer_overflow());
3189 if (!own_buffer_) FATAL("external code buffer is too small");
3190
3191 // Compute new buffer size.
3192 CodeDesc desc; // the new buffer
3193 desc.buffer_size = 2 * buffer_size_;
3194
3195 // Some internal data structures overflow for very large buffers,
3196 // they must ensure that kMaximalBufferSize is not too large.
3197 if (desc.buffer_size > kMaximalBufferSize) {
3198 V8::FatalProcessOutOfMemory(nullptr, "Assembler::GrowBuffer");
3199 }
3200
3201 // Set up new buffer.
3202 desc.buffer = NewArray<byte>(desc.buffer_size);
3203 desc.origin = this;
3204 desc.instr_size = pc_offset();
3205 desc.reloc_size = (buffer_ + buffer_size_) - (reloc_info_writer.pos());
3206
3207 // Clear the buffer in debug mode. Use 'int3' instructions to make
3208 // sure to get into problems if we ever run uninitialized code.
3209 #ifdef DEBUG
3210 ZapCode(reinterpret_cast<Address>(desc.buffer), desc.buffer_size);
3211 #endif
3212
3213 // Copy the data.
3214 int pc_delta = desc.buffer - buffer_;
3215 int rc_delta = (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_);
3216 MemMove(desc.buffer, buffer_, desc.instr_size);
3217 MemMove(rc_delta + reloc_info_writer.pos(), reloc_info_writer.pos(),
3218 desc.reloc_size);
3219
3220 // Switch buffers.
3221 DeleteArray(buffer_);
3222 buffer_ = desc.buffer;
3223 buffer_size_ = desc.buffer_size;
3224 pc_ += pc_delta;
3225 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
3226 reloc_info_writer.last_pc() + pc_delta);
3227
3228 // Relocate internal references.
3229 for (auto pos : internal_reference_positions_) {
3230 int32_t* p = reinterpret_cast<int32_t*>(buffer_ + pos);
3231 *p += pc_delta;
3232 }
3233
3234 // Relocate pc-relative references.
3235 int mode_mask = RelocInfo::ModeMask(RelocInfo::JS_TO_WASM_CALL) |
3236 RelocInfo::ModeMask(RelocInfo::OFF_HEAP_TARGET);
3237 DCHECK_EQ(mode_mask, RelocInfo::kApplyMask & mode_mask);
3238 for (RelocIterator it(desc, mode_mask); !it.done(); it.next()) {
3239 it.rinfo()->apply(pc_delta);
3240 }
3241
3242 DCHECK(!buffer_overflow());
3243 }
3244
3245
emit_arith_b(int op1,int op2,Register dst,int imm8)3246 void Assembler::emit_arith_b(int op1, int op2, Register dst, int imm8) {
3247 DCHECK(is_uint8(op1) && is_uint8(op2)); // wrong opcode
3248 DCHECK(is_uint8(imm8));
3249 DCHECK_EQ(op1 & 0x01, 0); // should be 8bit operation
3250 EMIT(op1);
3251 EMIT(op2 | dst.code());
3252 EMIT(imm8);
3253 }
3254
3255
emit_arith(int sel,Operand dst,const Immediate & x)3256 void Assembler::emit_arith(int sel, Operand dst, const Immediate& x) {
3257 DCHECK((0 <= sel) && (sel <= 7));
3258 Register ireg = Register::from_code(sel);
3259 if (x.is_int8()) {
3260 EMIT(0x83); // using a sign-extended 8-bit immediate.
3261 emit_operand(ireg, dst);
3262 EMIT(x.immediate() & 0xFF);
3263 } else if (dst.is_reg(eax)) {
3264 EMIT((sel << 3) | 0x05); // short form if the destination is eax.
3265 emit(x);
3266 } else {
3267 EMIT(0x81); // using a literal 32-bit immediate.
3268 emit_operand(ireg, dst);
3269 emit(x);
3270 }
3271 }
3272
emit_operand(Register reg,Operand adr)3273 void Assembler::emit_operand(Register reg, Operand adr) {
3274 emit_operand(reg.code(), adr);
3275 }
3276
emit_operand(XMMRegister reg,Operand adr)3277 void Assembler::emit_operand(XMMRegister reg, Operand adr) {
3278 Register ireg = Register::from_code(reg.code());
3279 emit_operand(ireg, adr);
3280 }
3281
emit_operand(int code,Operand adr)3282 void Assembler::emit_operand(int code, Operand adr) {
3283 // Isolate-independent code may not embed relocatable addresses.
3284 DCHECK(!options().isolate_independent_code ||
3285 adr.rmode_ != RelocInfo::CODE_TARGET);
3286 DCHECK(!options().isolate_independent_code ||
3287 adr.rmode_ != RelocInfo::EMBEDDED_OBJECT);
3288 // TODO(jgruber,v8:6666): Enable once kRootRegister exists.
3289 // DCHECK(!options().isolate_independent_code ||
3290 // adr.rmode_ != RelocInfo::EXTERNAL_REFERENCE);
3291
3292 const unsigned length = adr.len_;
3293 DCHECK_GT(length, 0);
3294
3295 // Emit updated ModRM byte containing the given register.
3296 pc_[0] = (adr.buf_[0] & ~0x38) | (code << 3);
3297
3298 // Emit the rest of the encoded operand.
3299 for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i];
3300 pc_ += length;
3301
3302 // Emit relocation information if necessary.
3303 if (length >= sizeof(int32_t) && !RelocInfo::IsNone(adr.rmode_)) {
3304 pc_ -= sizeof(int32_t); // pc_ must be *at* disp32
3305 RecordRelocInfo(adr.rmode_);
3306 if (adr.rmode_ == RelocInfo::INTERNAL_REFERENCE) { // Fixup for labels
3307 emit_label(*reinterpret_cast<Label**>(pc_));
3308 } else {
3309 pc_ += sizeof(int32_t);
3310 }
3311 }
3312 }
3313
3314
emit_label(Label * label)3315 void Assembler::emit_label(Label* label) {
3316 if (label->is_bound()) {
3317 internal_reference_positions_.push_back(pc_offset());
3318 emit(reinterpret_cast<uint32_t>(buffer_ + label->pos()));
3319 } else {
3320 emit_disp(label, Displacement::CODE_ABSOLUTE);
3321 }
3322 }
3323
3324
emit_farith(int b1,int b2,int i)3325 void Assembler::emit_farith(int b1, int b2, int i) {
3326 DCHECK(is_uint8(b1) && is_uint8(b2)); // wrong opcode
3327 DCHECK(0 <= i && i < 8); // illegal stack offset
3328 EMIT(b1);
3329 EMIT(b2 + i);
3330 }
3331
3332
db(uint8_t data)3333 void Assembler::db(uint8_t data) {
3334 EnsureSpace ensure_space(this);
3335 EMIT(data);
3336 }
3337
3338
dd(uint32_t data)3339 void Assembler::dd(uint32_t data) {
3340 EnsureSpace ensure_space(this);
3341 emit(data);
3342 }
3343
3344
dq(uint64_t data)3345 void Assembler::dq(uint64_t data) {
3346 EnsureSpace ensure_space(this);
3347 emit_q(data);
3348 }
3349
3350
dd(Label * label)3351 void Assembler::dd(Label* label) {
3352 EnsureSpace ensure_space(this);
3353 RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE);
3354 emit_label(label);
3355 }
3356
3357
RecordRelocInfo(RelocInfo::Mode rmode,intptr_t data)3358 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
3359 DCHECK(!RelocInfo::IsNone(rmode));
3360 if (options().disable_reloc_info_for_patching) return;
3361 // Don't record external references unless the heap will be serialized.
3362 if (RelocInfo::IsOnlyForSerializer(rmode) &&
3363 !options().record_reloc_info_for_serialization && !emit_debug_code()) {
3364 return;
3365 }
3366 RelocInfo rinfo(reinterpret_cast<Address>(pc_), rmode, data, nullptr);
3367 reloc_info_writer.Write(&rinfo);
3368 }
3369
3370
3371 } // namespace internal
3372 } // namespace v8
3373
3374 #endif // V8_TARGET_ARCH_IA32
3375